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() != NULL)) { 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() != NULL; 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() != NULL, "expected trailing membar"); 1597 } else { 1598 return ldst->trailing_membar() != NULL; 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 { 1648 return 6 * NativeInstruction::instruction_size; 1649 } 1650 } 1651 1652 //============================================================================= 1653 1654 #ifndef PRODUCT 1655 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1656 st->print("BREAKPOINT"); 1657 } 1658 #endif 1659 1660 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1661 C2_MacroAssembler _masm(&cbuf); 1662 __ brk(0); 1663 } 1664 1665 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1666 return MachNode::size(ra_); 1667 } 1668 1669 //============================================================================= 1670 1671 #ifndef PRODUCT 1672 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1673 st->print("nop \t# %d bytes pad for loops and calls", _count); 1674 } 1675 #endif 1676 1677 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1678 C2_MacroAssembler _masm(&cbuf); 1679 for (int i = 0; i < _count; i++) { 1680 __ nop(); 1681 } 1682 } 1683 1684 uint MachNopNode::size(PhaseRegAlloc*) const { 1685 return _count * NativeInstruction::instruction_size; 1686 } 1687 1688 //============================================================================= 1689 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1690 1691 int ConstantTable::calculate_table_base_offset() const { 1692 return 0; // absolute addressing, no offset 1693 } 1694 1695 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1696 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1697 ShouldNotReachHere(); 1698 } 1699 1700 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1701 // Empty encoding 1702 } 1703 1704 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1705 return 0; 1706 } 1707 1708 #ifndef PRODUCT 1709 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1710 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1711 } 1712 #endif 1713 1714 #ifndef PRODUCT 1715 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1716 Compile* C = ra_->C; 1717 1718 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1719 1720 if (C->output()->need_stack_bang(framesize)) 1721 st->print("# stack bang size=%d\n\t", framesize); 1722 1723 if (VM_Version::use_rop_protection()) { 1724 st->print("ldr zr, [lr]\n\t"); 1725 st->print("paciaz\n\t"); 1726 } 1727 if (framesize < ((1 << 9) + 2 * wordSize)) { 1728 st->print("sub sp, sp, #%d\n\t", framesize); 1729 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1730 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1731 } else { 1732 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1733 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1734 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1735 st->print("sub sp, sp, rscratch1"); 1736 } 1737 if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1738 st->print("\n\t"); 1739 st->print("ldr rscratch1, [guard]\n\t"); 1740 st->print("dmb ishld\n\t"); 1741 st->print("ldr rscratch2, [rthread, #thread_disarmed_guard_value_offset]\n\t"); 1742 st->print("cmp rscratch1, rscratch2\n\t"); 1743 st->print("b.eq skip"); 1744 st->print("\n\t"); 1745 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1746 st->print("b skip\n\t"); 1747 st->print("guard: int\n\t"); 1748 st->print("\n\t"); 1749 st->print("skip:\n\t"); 1750 } 1751 } 1752 #endif 1753 1754 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1755 Compile* C = ra_->C; 1756 C2_MacroAssembler _masm(&cbuf); 1757 1758 // n.b. frame size includes space for return pc and rfp 1759 const int framesize = C->output()->frame_size_in_bytes(); 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 if (C->clinit_barrier_on_entry()) { 1766 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1767 1768 Label L_skip_barrier; 1769 1770 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1771 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1772 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1773 __ bind(L_skip_barrier); 1774 } 1775 1776 if (C->max_vector_size() > 0) { 1777 __ reinitialize_ptrue(); 1778 } 1779 1780 int bangsize = C->output()->bang_size_in_bytes(); 1781 if (C->output()->need_stack_bang(bangsize)) 1782 __ generate_stack_overflow_check(bangsize); 1783 1784 __ build_frame(framesize); 1785 1786 if (C->stub_function() == NULL) { 1787 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1788 if (BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1789 // Dummy labels for just measuring the code size 1790 Label dummy_slow_path; 1791 Label dummy_continuation; 1792 Label dummy_guard; 1793 Label* slow_path = &dummy_slow_path; 1794 Label* continuation = &dummy_continuation; 1795 Label* guard = &dummy_guard; 1796 if (!Compile::current()->output()->in_scratch_emit_size()) { 1797 // Use real labels from actual stub when not emitting code for the purpose of measuring its size 1798 C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub(); 1799 Compile::current()->output()->add_stub(stub); 1800 slow_path = &stub->entry(); 1801 continuation = &stub->continuation(); 1802 guard = &stub->guard(); 1803 } 1804 // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub. 1805 bs->nmethod_entry_barrier(&_masm, slow_path, continuation, guard); 1806 } 1807 } 1808 1809 if (VerifyStackAtCalls) { 1810 Unimplemented(); 1811 } 1812 1813 C->output()->set_frame_complete(cbuf.insts_size()); 1814 1815 if (C->has_mach_constant_base_node()) { 1816 // NOTE: We set the table base offset here because users might be 1817 // emitted before MachConstantBaseNode. 1818 ConstantTable& constant_table = C->output()->constant_table(); 1819 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1820 } 1821 } 1822 1823 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1824 { 1825 return MachNode::size(ra_); // too many variables; just compute it 1826 // the hard way 1827 } 1828 1829 int MachPrologNode::reloc() const 1830 { 1831 return 0; 1832 } 1833 1834 //============================================================================= 1835 1836 #ifndef PRODUCT 1837 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1838 Compile* C = ra_->C; 1839 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1840 1841 st->print("# pop frame %d\n\t",framesize); 1842 1843 if (framesize == 0) { 1844 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1845 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1846 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1847 st->print("add sp, sp, #%d\n\t", framesize); 1848 } else { 1849 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1850 st->print("add sp, sp, rscratch1\n\t"); 1851 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1852 } 1853 if (VM_Version::use_rop_protection()) { 1854 st->print("autiaz\n\t"); 1855 st->print("ldr zr, [lr]\n\t"); 1856 } 1857 1858 if (do_polling() && C->is_method_compilation()) { 1859 st->print("# test polling word\n\t"); 1860 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset())); 1861 st->print("cmp sp, rscratch1\n\t"); 1862 st->print("bhi #slow_path"); 1863 } 1864 } 1865 #endif 1866 1867 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1868 Compile* C = ra_->C; 1869 C2_MacroAssembler _masm(&cbuf); 1870 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1871 1872 __ remove_frame(framesize); 1873 1874 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1875 __ reserved_stack_check(); 1876 } 1877 1878 if (do_polling() && C->is_method_compilation()) { 1879 Label dummy_label; 1880 Label* code_stub = &dummy_label; 1881 if (!C->output()->in_scratch_emit_size()) { 1882 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1883 C->output()->add_stub(stub); 1884 code_stub = &stub->entry(); 1885 } 1886 __ relocate(relocInfo::poll_return_type); 1887 __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); 1888 } 1889 } 1890 1891 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1892 // Variable size. Determine dynamically. 1893 return MachNode::size(ra_); 1894 } 1895 1896 int MachEpilogNode::reloc() const { 1897 // Return number of relocatable values contained in this instruction. 1898 return 1; // 1 for polling page. 1899 } 1900 1901 const Pipeline * MachEpilogNode::pipeline() const { 1902 return MachNode::pipeline_class(); 1903 } 1904 1905 //============================================================================= 1906 1907 // Figure out which register class each belongs in: rc_int, rc_float or 1908 // rc_stack. 1909 enum RC { rc_bad, rc_int, rc_float, rc_predicate, rc_stack }; 1910 1911 static enum RC rc_class(OptoReg::Name reg) { 1912 1913 if (reg == OptoReg::Bad) { 1914 return rc_bad; 1915 } 1916 1917 // we have 32 int registers * 2 halves 1918 int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register; 1919 1920 if (reg < slots_of_int_registers) { 1921 return rc_int; 1922 } 1923 1924 // we have 32 float register * 8 halves 1925 int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register; 1926 if (reg < slots_of_int_registers + slots_of_float_registers) { 1927 return rc_float; 1928 } 1929 1930 int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register; 1931 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) { 1932 return rc_predicate; 1933 } 1934 1935 // Between predicate regs & stack is the flags. 1936 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1937 1938 return rc_stack; 1939 } 1940 1941 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1942 Compile* C = ra_->C; 1943 1944 // Get registers to move. 1945 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1946 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1947 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1948 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1949 1950 enum RC src_hi_rc = rc_class(src_hi); 1951 enum RC src_lo_rc = rc_class(src_lo); 1952 enum RC dst_hi_rc = rc_class(dst_hi); 1953 enum RC dst_lo_rc = rc_class(dst_lo); 1954 1955 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1956 1957 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) { 1958 assert((src_lo&1)==0 && src_lo+1==src_hi && 1959 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1960 "expected aligned-adjacent pairs"); 1961 } 1962 1963 if (src_lo == dst_lo && src_hi == dst_hi) { 1964 return 0; // Self copy, no move. 1965 } 1966 1967 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1968 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1969 int src_offset = ra_->reg2offset(src_lo); 1970 int dst_offset = ra_->reg2offset(dst_lo); 1971 1972 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 1973 uint ireg = ideal_reg(); 1974 if (ireg == Op_VecA && cbuf) { 1975 C2_MacroAssembler _masm(cbuf); 1976 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); 1977 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1978 // stack->stack 1979 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset, 1980 sve_vector_reg_size_in_bytes); 1981 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1982 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 1983 sve_vector_reg_size_in_bytes); 1984 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1985 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 1986 sve_vector_reg_size_in_bytes); 1987 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1988 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1989 as_FloatRegister(Matcher::_regEncode[src_lo]), 1990 as_FloatRegister(Matcher::_regEncode[src_lo])); 1991 } else { 1992 ShouldNotReachHere(); 1993 } 1994 } else if (cbuf) { 1995 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1996 C2_MacroAssembler _masm(cbuf); 1997 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1998 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1999 // stack->stack 2000 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 2001 if (ireg == Op_VecD) { 2002 __ unspill(rscratch1, true, src_offset); 2003 __ spill(rscratch1, true, dst_offset); 2004 } else { 2005 __ spill_copy128(src_offset, dst_offset); 2006 } 2007 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2008 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2009 ireg == Op_VecD ? __ T8B : __ T16B, 2010 as_FloatRegister(Matcher::_regEncode[src_lo])); 2011 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2012 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2013 ireg == Op_VecD ? __ D : __ Q, 2014 ra_->reg2offset(dst_lo)); 2015 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 2016 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2017 ireg == Op_VecD ? __ D : __ Q, 2018 ra_->reg2offset(src_lo)); 2019 } else { 2020 ShouldNotReachHere(); 2021 } 2022 } 2023 } else if (cbuf) { 2024 C2_MacroAssembler _masm(cbuf); 2025 switch (src_lo_rc) { 2026 case rc_int: 2027 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 2028 if (is64) { 2029 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 2030 as_Register(Matcher::_regEncode[src_lo])); 2031 } else { 2032 C2_MacroAssembler _masm(cbuf); 2033 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 2034 as_Register(Matcher::_regEncode[src_lo])); 2035 } 2036 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 2037 if (is64) { 2038 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2039 as_Register(Matcher::_regEncode[src_lo])); 2040 } else { 2041 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2042 as_Register(Matcher::_regEncode[src_lo])); 2043 } 2044 } else { // gpr --> stack spill 2045 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2046 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 2047 } 2048 break; 2049 case rc_float: 2050 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2051 if (is64) { 2052 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2053 as_FloatRegister(Matcher::_regEncode[src_lo])); 2054 } else { 2055 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2056 as_FloatRegister(Matcher::_regEncode[src_lo])); 2057 } 2058 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2059 if (is64) { 2060 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2061 as_FloatRegister(Matcher::_regEncode[src_lo])); 2062 } else { 2063 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2064 as_FloatRegister(Matcher::_regEncode[src_lo])); 2065 } 2066 } else { // fpr --> stack spill 2067 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2068 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2069 is64 ? __ D : __ S, dst_offset); 2070 } 2071 break; 2072 case rc_stack: 2073 if (dst_lo_rc == rc_int) { // stack --> gpr load 2074 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 2075 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2076 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2077 is64 ? __ D : __ S, src_offset); 2078 } else if (dst_lo_rc == rc_predicate) { 2079 __ unspill_sve_predicate(as_PRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 2080 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2081 } else { // stack --> stack copy 2082 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2083 if (ideal_reg() == Op_RegVectMask) { 2084 __ spill_copy_sve_predicate_stack_to_stack(src_offset, dst_offset, 2085 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2086 } else { 2087 __ unspill(rscratch1, is64, src_offset); 2088 __ spill(rscratch1, is64, dst_offset); 2089 } 2090 } 2091 break; 2092 case rc_predicate: 2093 if (dst_lo_rc == rc_predicate) { 2094 __ sve_mov(as_PRegister(Matcher::_regEncode[dst_lo]), as_PRegister(Matcher::_regEncode[src_lo])); 2095 } else if (dst_lo_rc == rc_stack) { 2096 __ spill_sve_predicate(as_PRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 2097 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2098 } else { 2099 assert(false, "bad src and dst rc_class combination."); 2100 ShouldNotReachHere(); 2101 } 2102 break; 2103 default: 2104 assert(false, "bad rc_class for spill"); 2105 ShouldNotReachHere(); 2106 } 2107 } 2108 2109 if (st) { 2110 st->print("spill "); 2111 if (src_lo_rc == rc_stack) { 2112 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2113 } else { 2114 st->print("%s -> ", Matcher::regName[src_lo]); 2115 } 2116 if (dst_lo_rc == rc_stack) { 2117 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2118 } else { 2119 st->print("%s", Matcher::regName[dst_lo]); 2120 } 2121 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 2122 int vsize = 0; 2123 switch (ideal_reg()) { 2124 case Op_VecD: 2125 vsize = 64; 2126 break; 2127 case Op_VecX: 2128 vsize = 128; 2129 break; 2130 case Op_VecA: 2131 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; 2132 break; 2133 default: 2134 assert(false, "bad register type for spill"); 2135 ShouldNotReachHere(); 2136 } 2137 st->print("\t# vector spill size = %d", vsize); 2138 } else if (ideal_reg() == Op_RegVectMask) { 2139 assert(Matcher::supports_scalable_vector(), "bad register type for spill"); 2140 int vsize = Matcher::scalable_predicate_reg_slots() * 32; 2141 st->print("\t# predicate spill size = %d", vsize); 2142 } else { 2143 st->print("\t# spill size = %d", is64 ? 64 : 32); 2144 } 2145 } 2146 2147 return 0; 2148 2149 } 2150 2151 #ifndef PRODUCT 2152 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2153 if (!ra_) 2154 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2155 else 2156 implementation(NULL, ra_, false, st); 2157 } 2158 #endif 2159 2160 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2161 implementation(&cbuf, ra_, false, NULL); 2162 } 2163 2164 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2165 return MachNode::size(ra_); 2166 } 2167 2168 //============================================================================= 2169 2170 #ifndef PRODUCT 2171 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2172 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2173 int reg = ra_->get_reg_first(this); 2174 st->print("add %s, rsp, #%d]\t# box lock", 2175 Matcher::regName[reg], offset); 2176 } 2177 #endif 2178 2179 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2180 C2_MacroAssembler _masm(&cbuf); 2181 2182 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2183 int reg = ra_->get_encode(this); 2184 2185 // This add will handle any 24-bit signed offset. 24 bits allows an 2186 // 8 megabyte stack frame. 2187 __ add(as_Register(reg), sp, offset); 2188 } 2189 2190 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2191 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2192 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2193 2194 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2195 return NativeInstruction::instruction_size; 2196 } else { 2197 return 2 * NativeInstruction::instruction_size; 2198 } 2199 } 2200 2201 //============================================================================= 2202 2203 #ifndef PRODUCT 2204 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2205 { 2206 st->print_cr("# MachUEPNode"); 2207 if (UseCompressedClassPointers) { 2208 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2209 if (CompressedKlassPointers::shift() != 0) { 2210 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2211 } 2212 } else { 2213 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2214 } 2215 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2216 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2217 } 2218 #endif 2219 2220 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2221 { 2222 // This is the unverified entry point. 2223 C2_MacroAssembler _masm(&cbuf); 2224 2225 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2226 Label skip; 2227 // TODO 2228 // can we avoid this skip and still use a reloc? 2229 __ br(Assembler::EQ, skip); 2230 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2231 __ bind(skip); 2232 } 2233 2234 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2235 { 2236 return MachNode::size(ra_); 2237 } 2238 2239 // REQUIRED EMIT CODE 2240 2241 //============================================================================= 2242 2243 // Emit exception handler code. 2244 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2245 { 2246 // mov rscratch1 #exception_blob_entry_point 2247 // br rscratch1 2248 // Note that the code buffer's insts_mark is always relative to insts. 2249 // That's why we must use the macroassembler to generate a handler. 2250 C2_MacroAssembler _masm(&cbuf); 2251 address base = __ start_a_stub(size_exception_handler()); 2252 if (base == NULL) { 2253 ciEnv::current()->record_failure("CodeCache is full"); 2254 return 0; // CodeBuffer::expand failed 2255 } 2256 int offset = __ offset(); 2257 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2258 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2259 __ end_a_stub(); 2260 return offset; 2261 } 2262 2263 // Emit deopt handler code. 2264 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2265 { 2266 // Note that the code buffer's insts_mark is always relative to insts. 2267 // That's why we must use the macroassembler to generate a handler. 2268 C2_MacroAssembler _masm(&cbuf); 2269 address base = __ start_a_stub(size_deopt_handler()); 2270 if (base == NULL) { 2271 ciEnv::current()->record_failure("CodeCache is full"); 2272 return 0; // CodeBuffer::expand failed 2273 } 2274 int offset = __ offset(); 2275 2276 __ adr(lr, __ pc()); 2277 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2278 2279 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow"); 2280 __ end_a_stub(); 2281 return offset; 2282 } 2283 2284 // REQUIRED MATCHER CODE 2285 2286 //============================================================================= 2287 2288 bool Matcher::match_rule_supported(int opcode) { 2289 if (!has_match_rule(opcode)) 2290 return false; 2291 2292 switch (opcode) { 2293 case Op_OnSpinWait: 2294 return VM_Version::supports_on_spin_wait(); 2295 case Op_CacheWB: 2296 case Op_CacheWBPreSync: 2297 case Op_CacheWBPostSync: 2298 if (!VM_Version::supports_data_cache_line_flush()) { 2299 return false; 2300 } 2301 break; 2302 case Op_ExpandBits: 2303 case Op_CompressBits: 2304 if (!VM_Version::supports_svebitperm()) { 2305 return false; 2306 } 2307 break; 2308 case Op_FmaF: 2309 case Op_FmaD: 2310 case Op_FmaVF: 2311 case Op_FmaVD: 2312 if (!UseFMA) { 2313 return false; 2314 } 2315 break; 2316 } 2317 2318 return true; // Per default match rules are supported. 2319 } 2320 2321 const RegMask* Matcher::predicate_reg_mask(void) { 2322 return &_PR_REG_mask; 2323 } 2324 2325 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2326 return new TypeVectMask(elemTy, length); 2327 } 2328 2329 // Vector calling convention not yet implemented. 2330 bool Matcher::supports_vector_calling_convention(void) { 2331 return false; 2332 } 2333 2334 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2335 Unimplemented(); 2336 return OptoRegPair(0, 0); 2337 } 2338 2339 // Is this branch offset short enough that a short branch can be used? 2340 // 2341 // NOTE: If the platform does not provide any short branch variants, then 2342 // this method should return false for offset 0. 2343 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2344 // The passed offset is relative to address of the branch. 2345 2346 return (-32768 <= offset && offset < 32768); 2347 } 2348 2349 // Vector width in bytes. 2350 int Matcher::vector_width_in_bytes(BasicType bt) { 2351 // The MaxVectorSize should have been set by detecting SVE max vector register size. 2352 int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize); 2353 // Minimum 2 values in vector 2354 if (size < 2*type2aelembytes(bt)) size = 0; 2355 // But never < 4 2356 if (size < 4) size = 0; 2357 return size; 2358 } 2359 2360 // Limits on vector size (number of elements) loaded into vector. 2361 int Matcher::max_vector_size(const BasicType bt) { 2362 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2363 } 2364 2365 int Matcher::min_vector_size(const BasicType bt) { 2366 int max_size = max_vector_size(bt); 2367 // Limit the min vector size to 8 bytes. 2368 int size = 8 / type2aelembytes(bt); 2369 if (bt == T_BYTE) { 2370 // To support vector api shuffle/rearrange. 2371 size = 4; 2372 } else if (bt == T_BOOLEAN) { 2373 // To support vector api load/store mask. 2374 size = 2; 2375 } 2376 if (size < 2) size = 2; 2377 return MIN2(size, max_size); 2378 } 2379 2380 int Matcher::superword_max_vector_size(const BasicType bt) { 2381 return Matcher::max_vector_size(bt); 2382 } 2383 2384 // Actual max scalable vector register length. 2385 int Matcher::scalable_vector_reg_size(const BasicType bt) { 2386 return Matcher::max_vector_size(bt); 2387 } 2388 2389 // Vector ideal reg. 2390 uint Matcher::vector_ideal_reg(int len) { 2391 if (UseSVE > 0 && 16 < len && len <= 256) { 2392 return Op_VecA; 2393 } 2394 switch(len) { 2395 // For 16-bit/32-bit mask vector, reuse VecD. 2396 case 2: 2397 case 4: 2398 case 8: return Op_VecD; 2399 case 16: return Op_VecX; 2400 } 2401 ShouldNotReachHere(); 2402 return 0; 2403 } 2404 2405 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { 2406 assert(Matcher::is_generic_vector(generic_opnd), "not generic"); 2407 switch (ideal_reg) { 2408 case Op_VecA: return new vecAOper(); 2409 case Op_VecD: return new vecDOper(); 2410 case Op_VecX: return new vecXOper(); 2411 } 2412 ShouldNotReachHere(); 2413 return NULL; 2414 } 2415 2416 bool Matcher::is_reg2reg_move(MachNode* m) { 2417 return false; 2418 } 2419 2420 bool Matcher::is_generic_vector(MachOper* opnd) { 2421 return opnd->opcode() == VREG; 2422 } 2423 2424 // Return whether or not this register is ever used as an argument. 2425 // This function is used on startup to build the trampoline stubs in 2426 // generateOptoStub. Registers not mentioned will be killed by the VM 2427 // call in the trampoline, and arguments in those registers not be 2428 // available to the callee. 2429 bool Matcher::can_be_java_arg(int reg) 2430 { 2431 return 2432 reg == R0_num || reg == R0_H_num || 2433 reg == R1_num || reg == R1_H_num || 2434 reg == R2_num || reg == R2_H_num || 2435 reg == R3_num || reg == R3_H_num || 2436 reg == R4_num || reg == R4_H_num || 2437 reg == R5_num || reg == R5_H_num || 2438 reg == R6_num || reg == R6_H_num || 2439 reg == R7_num || reg == R7_H_num || 2440 reg == V0_num || reg == V0_H_num || 2441 reg == V1_num || reg == V1_H_num || 2442 reg == V2_num || reg == V2_H_num || 2443 reg == V3_num || reg == V3_H_num || 2444 reg == V4_num || reg == V4_H_num || 2445 reg == V5_num || reg == V5_H_num || 2446 reg == V6_num || reg == V6_H_num || 2447 reg == V7_num || reg == V7_H_num; 2448 } 2449 2450 bool Matcher::is_spillable_arg(int reg) 2451 { 2452 return can_be_java_arg(reg); 2453 } 2454 2455 uint Matcher::int_pressure_limit() 2456 { 2457 // JDK-8183543: When taking the number of available registers as int 2458 // register pressure threshold, the jtreg test: 2459 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java 2460 // failed due to C2 compilation failure with 2461 // "COMPILE SKIPPED: failed spill-split-recycle sanity check". 2462 // 2463 // A derived pointer is live at CallNode and then is flagged by RA 2464 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip 2465 // derived pointers and lastly fail to spill after reaching maximum 2466 // number of iterations. Lowering the default pressure threshold to 2467 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become 2468 // a high register pressure area of the code so that split_DEF can 2469 // generate DefinitionSpillCopy for the derived pointer. 2470 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; 2471 if (!PreserveFramePointer) { 2472 // When PreserveFramePointer is off, frame pointer is allocatable, 2473 // but different from other SOC registers, it is excluded from 2474 // fatproj's mask because its save type is No-Save. Decrease 1 to 2475 // ensure high pressure at fatproj when PreserveFramePointer is off. 2476 // See check_pressure_at_fatproj(). 2477 default_int_pressure_threshold--; 2478 } 2479 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; 2480 } 2481 2482 uint Matcher::float_pressure_limit() 2483 { 2484 // _FLOAT_REG_mask is generated by adlc from the float_reg register class. 2485 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; 2486 } 2487 2488 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2489 return false; 2490 } 2491 2492 RegMask Matcher::divI_proj_mask() { 2493 ShouldNotReachHere(); 2494 return RegMask(); 2495 } 2496 2497 // Register for MODI projection of divmodI. 2498 RegMask Matcher::modI_proj_mask() { 2499 ShouldNotReachHere(); 2500 return RegMask(); 2501 } 2502 2503 // Register for DIVL projection of divmodL. 2504 RegMask Matcher::divL_proj_mask() { 2505 ShouldNotReachHere(); 2506 return RegMask(); 2507 } 2508 2509 // Register for MODL projection of divmodL. 2510 RegMask Matcher::modL_proj_mask() { 2511 ShouldNotReachHere(); 2512 return RegMask(); 2513 } 2514 2515 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2516 return FP_REG_mask(); 2517 } 2518 2519 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2520 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2521 Node* u = addp->fast_out(i); 2522 if (u->is_LoadStore()) { 2523 // On AArch64, LoadStoreNodes (i.e. compare and swap 2524 // instructions) only take register indirect as an operand, so 2525 // any attempt to use an AddPNode as an input to a LoadStoreNode 2526 // must fail. 2527 return false; 2528 } 2529 if (u->is_Mem()) { 2530 int opsize = u->as_Mem()->memory_size(); 2531 assert(opsize > 0, "unexpected memory operand size"); 2532 if (u->as_Mem()->memory_size() != (1<<shift)) { 2533 return false; 2534 } 2535 } 2536 } 2537 return true; 2538 } 2539 2540 // Convert BootTest condition to Assembler condition. 2541 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 2542 Assembler::Condition to_assembler_cond(BoolTest::mask cond) { 2543 Assembler::Condition result; 2544 switch(cond) { 2545 case BoolTest::eq: 2546 result = Assembler::EQ; break; 2547 case BoolTest::ne: 2548 result = Assembler::NE; break; 2549 case BoolTest::le: 2550 result = Assembler::LE; break; 2551 case BoolTest::ge: 2552 result = Assembler::GE; break; 2553 case BoolTest::lt: 2554 result = Assembler::LT; break; 2555 case BoolTest::gt: 2556 result = Assembler::GT; break; 2557 case BoolTest::ule: 2558 result = Assembler::LS; break; 2559 case BoolTest::uge: 2560 result = Assembler::HS; break; 2561 case BoolTest::ult: 2562 result = Assembler::LO; break; 2563 case BoolTest::ugt: 2564 result = Assembler::HI; break; 2565 case BoolTest::overflow: 2566 result = Assembler::VS; break; 2567 case BoolTest::no_overflow: 2568 result = Assembler::VC; break; 2569 default: 2570 ShouldNotReachHere(); 2571 return Assembler::Condition(-1); 2572 } 2573 2574 // Check conversion 2575 if (cond & BoolTest::unsigned_compare) { 2576 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion"); 2577 } else { 2578 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion"); 2579 } 2580 2581 return result; 2582 } 2583 2584 // Binary src (Replicate con) 2585 bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) { 2586 if (n == NULL || m == NULL) { 2587 return false; 2588 } 2589 2590 if (UseSVE == 0 || m->Opcode() != Op_Replicate) { 2591 return false; 2592 } 2593 2594 Node* imm_node = m->in(1); 2595 if (!imm_node->is_Con()) { 2596 return false; 2597 } 2598 2599 const Type* t = imm_node->bottom_type(); 2600 if (!(t->isa_int() || t->isa_long())) { 2601 return false; 2602 } 2603 2604 switch (n->Opcode()) { 2605 case Op_AndV: 2606 case Op_OrV: 2607 case Op_XorV: { 2608 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n)); 2609 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int(); 2610 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value); 2611 } 2612 case Op_AddVB: 2613 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255); 2614 case Op_AddVS: 2615 case Op_AddVI: 2616 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int()); 2617 case Op_AddVL: 2618 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long()); 2619 default: 2620 return false; 2621 } 2622 } 2623 2624 // (XorV src (Replicate m1)) 2625 // (XorVMask src (MaskAll m1)) 2626 bool is_vector_bitwise_not_pattern(Node* n, Node* m) { 2627 if (n != NULL && m != NULL) { 2628 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) && 2629 VectorNode::is_all_ones_vector(m); 2630 } 2631 return false; 2632 } 2633 2634 // Should the matcher clone input 'm' of node 'n'? 2635 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2636 if (is_vshift_con_pattern(n, m) || 2637 is_vector_bitwise_not_pattern(n, m) || 2638 is_valid_sve_arith_imm_pattern(n, m)) { 2639 mstack.push(m, Visit); 2640 return true; 2641 } 2642 return false; 2643 } 2644 2645 // Should the Matcher clone shifts on addressing modes, expecting them 2646 // to be subsumed into complex addressing expressions or compute them 2647 // into registers? 2648 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2649 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2650 return true; 2651 } 2652 2653 Node *off = m->in(AddPNode::Offset); 2654 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2655 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2656 // Are there other uses besides address expressions? 2657 !is_visited(off)) { 2658 address_visited.set(off->_idx); // Flag as address_visited 2659 mstack.push(off->in(2), Visit); 2660 Node *conv = off->in(1); 2661 if (conv->Opcode() == Op_ConvI2L && 2662 // Are there other uses besides address expressions? 2663 !is_visited(conv)) { 2664 address_visited.set(conv->_idx); // Flag as address_visited 2665 mstack.push(conv->in(1), Pre_Visit); 2666 } else { 2667 mstack.push(conv, Pre_Visit); 2668 } 2669 address_visited.test_set(m->_idx); // Flag as address_visited 2670 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2671 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2672 return true; 2673 } else if (off->Opcode() == Op_ConvI2L && 2674 // Are there other uses besides address expressions? 2675 !is_visited(off)) { 2676 address_visited.test_set(m->_idx); // Flag as address_visited 2677 address_visited.set(off->_idx); // Flag as address_visited 2678 mstack.push(off->in(1), Pre_Visit); 2679 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2680 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2681 return true; 2682 } 2683 return false; 2684 } 2685 2686 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2687 C2_MacroAssembler _masm(&cbuf); \ 2688 { \ 2689 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2690 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2691 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2692 __ INSN(REG, as_Register(BASE)); \ 2693 } 2694 2695 2696 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2697 { 2698 Address::extend scale; 2699 2700 // Hooboy, this is fugly. We need a way to communicate to the 2701 // encoder that the index needs to be sign extended, so we have to 2702 // enumerate all the cases. 2703 switch (opcode) { 2704 case INDINDEXSCALEDI2L: 2705 case INDINDEXSCALEDI2LN: 2706 case INDINDEXI2L: 2707 case INDINDEXI2LN: 2708 scale = Address::sxtw(size); 2709 break; 2710 default: 2711 scale = Address::lsl(size); 2712 } 2713 2714 if (index == -1) { 2715 return Address(base, disp); 2716 } else { 2717 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2718 return Address(base, as_Register(index), scale); 2719 } 2720 } 2721 2722 2723 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2724 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2725 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2726 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2727 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2728 2729 // Used for all non-volatile memory accesses. The use of 2730 // $mem->opcode() to discover whether this pattern uses sign-extended 2731 // offsets is something of a kludge. 2732 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2733 Register reg, int opcode, 2734 Register base, int index, int scale, int disp, 2735 int size_in_memory) 2736 { 2737 Address addr = mem2address(opcode, base, index, scale, disp); 2738 if (addr.getMode() == Address::base_plus_offset) { 2739 /* If we get an out-of-range offset it is a bug in the compiler, 2740 so we assert here. */ 2741 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2742 "c2 compiler bug"); 2743 /* Fix up any out-of-range offsets. */ 2744 assert_different_registers(rscratch1, base); 2745 assert_different_registers(rscratch1, reg); 2746 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2747 } 2748 (masm.*insn)(reg, addr); 2749 } 2750 2751 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2752 FloatRegister reg, int opcode, 2753 Register base, int index, int size, int disp, 2754 int size_in_memory) 2755 { 2756 Address::extend scale; 2757 2758 switch (opcode) { 2759 case INDINDEXSCALEDI2L: 2760 case INDINDEXSCALEDI2LN: 2761 scale = Address::sxtw(size); 2762 break; 2763 default: 2764 scale = Address::lsl(size); 2765 } 2766 2767 if (index == -1) { 2768 /* If we get an out-of-range offset it is a bug in the compiler, 2769 so we assert here. */ 2770 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2771 /* Fix up any out-of-range offsets. */ 2772 assert_different_registers(rscratch1, base); 2773 Address addr = Address(base, disp); 2774 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2775 (masm.*insn)(reg, addr); 2776 } else { 2777 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2778 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2779 } 2780 } 2781 2782 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2783 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2784 int opcode, Register base, int index, int size, int disp) 2785 { 2786 if (index == -1) { 2787 (masm.*insn)(reg, T, Address(base, disp)); 2788 } else { 2789 assert(disp == 0, "unsupported address mode"); 2790 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2791 } 2792 } 2793 2794 %} 2795 2796 2797 2798 //----------ENCODING BLOCK----------------------------------------------------- 2799 // This block specifies the encoding classes used by the compiler to 2800 // output byte streams. Encoding classes are parameterized macros 2801 // used by Machine Instruction Nodes in order to generate the bit 2802 // encoding of the instruction. Operands specify their base encoding 2803 // interface with the interface keyword. There are currently 2804 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2805 // COND_INTER. REG_INTER causes an operand to generate a function 2806 // which returns its register number when queried. CONST_INTER causes 2807 // an operand to generate a function which returns the value of the 2808 // constant when queried. MEMORY_INTER causes an operand to generate 2809 // four functions which return the Base Register, the Index Register, 2810 // the Scale Value, and the Offset Value of the operand when queried. 2811 // COND_INTER causes an operand to generate six functions which return 2812 // the encoding code (ie - encoding bits for the instruction) 2813 // associated with each basic boolean condition for a conditional 2814 // instruction. 2815 // 2816 // Instructions specify two basic values for encoding. Again, a 2817 // function is available to check if the constant displacement is an 2818 // oop. They use the ins_encode keyword to specify their encoding 2819 // classes (which must be a sequence of enc_class names, and their 2820 // parameters, specified in the encoding block), and they use the 2821 // opcode keyword to specify, in order, their primary, secondary, and 2822 // tertiary opcode. Only the opcode sections which a particular 2823 // instruction needs for encoding need to be specified. 2824 encode %{ 2825 // Build emit functions for each basic byte or larger field in the 2826 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2827 // from C++ code in the enc_class source block. Emit functions will 2828 // live in the main source block for now. In future, we can 2829 // generalize this by adding a syntax that specifies the sizes of 2830 // fields in an order, so that the adlc can build the emit functions 2831 // automagically 2832 2833 // catch all for unimplemented encodings 2834 enc_class enc_unimplemented %{ 2835 C2_MacroAssembler _masm(&cbuf); 2836 __ unimplemented("C2 catch all"); 2837 %} 2838 2839 // BEGIN Non-volatile memory access 2840 2841 // This encoding class is generated automatically from ad_encode.m4. 2842 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2843 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2844 Register dst_reg = as_Register($dst$$reg); 2845 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2846 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2847 %} 2848 2849 // This encoding class is generated automatically from ad_encode.m4. 2850 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2851 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2852 Register dst_reg = as_Register($dst$$reg); 2853 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2854 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2855 %} 2856 2857 // This encoding class is generated automatically from ad_encode.m4. 2858 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2859 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2860 Register dst_reg = as_Register($dst$$reg); 2861 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2862 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2863 %} 2864 2865 // This encoding class is generated automatically from ad_encode.m4. 2866 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2867 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2868 Register dst_reg = as_Register($dst$$reg); 2869 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2870 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2871 %} 2872 2873 // This encoding class is generated automatically from ad_encode.m4. 2874 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2875 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2876 Register dst_reg = as_Register($dst$$reg); 2877 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2878 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2879 %} 2880 2881 // This encoding class is generated automatically from ad_encode.m4. 2882 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2883 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2884 Register dst_reg = as_Register($dst$$reg); 2885 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2886 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2887 %} 2888 2889 // This encoding class is generated automatically from ad_encode.m4. 2890 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2891 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2892 Register dst_reg = as_Register($dst$$reg); 2893 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2894 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2895 %} 2896 2897 // This encoding class is generated automatically from ad_encode.m4. 2898 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2899 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2900 Register dst_reg = as_Register($dst$$reg); 2901 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2902 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2903 %} 2904 2905 // This encoding class is generated automatically from ad_encode.m4. 2906 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2907 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2908 Register dst_reg = as_Register($dst$$reg); 2909 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2910 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2911 %} 2912 2913 // This encoding class is generated automatically from ad_encode.m4. 2914 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2915 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2916 Register dst_reg = as_Register($dst$$reg); 2917 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2918 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2919 %} 2920 2921 // This encoding class is generated automatically from ad_encode.m4. 2922 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2923 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2924 Register dst_reg = as_Register($dst$$reg); 2925 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2926 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2927 %} 2928 2929 // This encoding class is generated automatically from ad_encode.m4. 2930 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2931 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2932 Register dst_reg = as_Register($dst$$reg); 2933 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2934 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2935 %} 2936 2937 // This encoding class is generated automatically from ad_encode.m4. 2938 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2939 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2940 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2941 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2942 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2943 %} 2944 2945 // This encoding class is generated automatically from ad_encode.m4. 2946 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2947 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2948 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2949 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2950 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2951 %} 2952 2953 // This encoding class is generated automatically from ad_encode.m4. 2954 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2955 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2956 Register src_reg = as_Register($src$$reg); 2957 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2958 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2959 %} 2960 2961 // This encoding class is generated automatically from ad_encode.m4. 2962 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2963 enc_class aarch64_enc_strb0(memory1 mem) %{ 2964 C2_MacroAssembler _masm(&cbuf); 2965 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2966 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2967 %} 2968 2969 // This encoding class is generated automatically from ad_encode.m4. 2970 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2971 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2972 Register src_reg = as_Register($src$$reg); 2973 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2974 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2975 %} 2976 2977 // This encoding class is generated automatically from ad_encode.m4. 2978 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2979 enc_class aarch64_enc_strh0(memory2 mem) %{ 2980 C2_MacroAssembler _masm(&cbuf); 2981 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2982 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2983 %} 2984 2985 // This encoding class is generated automatically from ad_encode.m4. 2986 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2987 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2988 Register src_reg = as_Register($src$$reg); 2989 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2990 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2991 %} 2992 2993 // This encoding class is generated automatically from ad_encode.m4. 2994 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2995 enc_class aarch64_enc_strw0(memory4 mem) %{ 2996 C2_MacroAssembler _masm(&cbuf); 2997 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2998 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2999 %} 3000 3001 // This encoding class is generated automatically from ad_encode.m4. 3002 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3003 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 3004 Register src_reg = as_Register($src$$reg); 3005 // we sometimes get asked to store the stack pointer into the 3006 // current thread -- we cannot do that directly on AArch64 3007 if (src_reg == r31_sp) { 3008 C2_MacroAssembler _masm(&cbuf); 3009 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3010 __ mov(rscratch2, sp); 3011 src_reg = rscratch2; 3012 } 3013 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 3014 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3015 %} 3016 3017 // This encoding class is generated automatically from ad_encode.m4. 3018 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3019 enc_class aarch64_enc_str0(memory8 mem) %{ 3020 C2_MacroAssembler _masm(&cbuf); 3021 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 3022 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3023 %} 3024 3025 // This encoding class is generated automatically from ad_encode.m4. 3026 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3027 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 3028 FloatRegister src_reg = as_FloatRegister($src$$reg); 3029 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 3030 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3031 %} 3032 3033 // This encoding class is generated automatically from ad_encode.m4. 3034 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3035 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 3036 FloatRegister src_reg = as_FloatRegister($src$$reg); 3037 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 3038 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3039 %} 3040 3041 // This encoding class is generated automatically from ad_encode.m4. 3042 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3043 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 3044 C2_MacroAssembler _masm(&cbuf); 3045 __ membar(Assembler::StoreStore); 3046 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 3047 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 3048 %} 3049 3050 // END Non-volatile memory access 3051 3052 // Vector loads and stores 3053 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{ 3054 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3055 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 3056 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3057 %} 3058 3059 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{ 3060 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3061 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3062 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3063 %} 3064 3065 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{ 3066 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3067 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3068 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3069 %} 3070 3071 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{ 3072 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3073 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3074 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3075 %} 3076 3077 enc_class aarch64_enc_strvH(vReg src, memory mem) %{ 3078 FloatRegister src_reg = as_FloatRegister($src$$reg); 3079 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H, 3080 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3081 %} 3082 3083 enc_class aarch64_enc_strvS(vReg src, memory mem) %{ 3084 FloatRegister src_reg = as_FloatRegister($src$$reg); 3085 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 3086 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3087 %} 3088 3089 enc_class aarch64_enc_strvD(vReg src, memory mem) %{ 3090 FloatRegister src_reg = as_FloatRegister($src$$reg); 3091 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 3092 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3093 %} 3094 3095 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{ 3096 FloatRegister src_reg = as_FloatRegister($src$$reg); 3097 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 3098 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3099 %} 3100 3101 // volatile loads and stores 3102 3103 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3104 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3105 rscratch1, stlrb); 3106 %} 3107 3108 enc_class aarch64_enc_stlrb0(memory mem) %{ 3109 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3110 rscratch1, stlrb); 3111 %} 3112 3113 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3114 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3115 rscratch1, stlrh); 3116 %} 3117 3118 enc_class aarch64_enc_stlrh0(memory mem) %{ 3119 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3120 rscratch1, stlrh); 3121 %} 3122 3123 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3124 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3125 rscratch1, stlrw); 3126 %} 3127 3128 enc_class aarch64_enc_stlrw0(memory mem) %{ 3129 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3130 rscratch1, stlrw); 3131 %} 3132 3133 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3134 Register dst_reg = as_Register($dst$$reg); 3135 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3136 rscratch1, ldarb); 3137 __ sxtbw(dst_reg, dst_reg); 3138 %} 3139 3140 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3141 Register dst_reg = as_Register($dst$$reg); 3142 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3143 rscratch1, ldarb); 3144 __ sxtb(dst_reg, dst_reg); 3145 %} 3146 3147 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3148 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3149 rscratch1, ldarb); 3150 %} 3151 3152 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3153 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3154 rscratch1, ldarb); 3155 %} 3156 3157 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3158 Register dst_reg = as_Register($dst$$reg); 3159 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3160 rscratch1, ldarh); 3161 __ sxthw(dst_reg, dst_reg); 3162 %} 3163 3164 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3165 Register dst_reg = as_Register($dst$$reg); 3166 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3167 rscratch1, ldarh); 3168 __ sxth(dst_reg, dst_reg); 3169 %} 3170 3171 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3172 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3173 rscratch1, ldarh); 3174 %} 3175 3176 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3177 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3178 rscratch1, ldarh); 3179 %} 3180 3181 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3182 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3183 rscratch1, ldarw); 3184 %} 3185 3186 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3187 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3188 rscratch1, ldarw); 3189 %} 3190 3191 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3192 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3193 rscratch1, ldar); 3194 %} 3195 3196 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3197 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3198 rscratch1, ldarw); 3199 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3200 %} 3201 3202 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3203 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3204 rscratch1, ldar); 3205 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3206 %} 3207 3208 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3209 Register src_reg = as_Register($src$$reg); 3210 // we sometimes get asked to store the stack pointer into the 3211 // current thread -- we cannot do that directly on AArch64 3212 if (src_reg == r31_sp) { 3213 C2_MacroAssembler _masm(&cbuf); 3214 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3215 __ mov(rscratch2, sp); 3216 src_reg = rscratch2; 3217 } 3218 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3219 rscratch1, stlr); 3220 %} 3221 3222 enc_class aarch64_enc_stlr0(memory mem) %{ 3223 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3224 rscratch1, stlr); 3225 %} 3226 3227 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3228 { 3229 C2_MacroAssembler _masm(&cbuf); 3230 FloatRegister src_reg = as_FloatRegister($src$$reg); 3231 __ fmovs(rscratch2, src_reg); 3232 } 3233 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3234 rscratch1, stlrw); 3235 %} 3236 3237 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3238 { 3239 C2_MacroAssembler _masm(&cbuf); 3240 FloatRegister src_reg = as_FloatRegister($src$$reg); 3241 __ fmovd(rscratch2, src_reg); 3242 } 3243 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3244 rscratch1, stlr); 3245 %} 3246 3247 // synchronized read/update encodings 3248 3249 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3250 C2_MacroAssembler _masm(&cbuf); 3251 Register dst_reg = as_Register($dst$$reg); 3252 Register base = as_Register($mem$$base); 3253 int index = $mem$$index; 3254 int scale = $mem$$scale; 3255 int disp = $mem$$disp; 3256 if (index == -1) { 3257 if (disp != 0) { 3258 __ lea(rscratch1, Address(base, disp)); 3259 __ ldaxr(dst_reg, rscratch1); 3260 } else { 3261 // TODO 3262 // should we ever get anything other than this case? 3263 __ ldaxr(dst_reg, base); 3264 } 3265 } else { 3266 Register index_reg = as_Register(index); 3267 if (disp == 0) { 3268 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3269 __ ldaxr(dst_reg, rscratch1); 3270 } else { 3271 __ lea(rscratch1, Address(base, disp)); 3272 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3273 __ ldaxr(dst_reg, rscratch1); 3274 } 3275 } 3276 %} 3277 3278 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3279 C2_MacroAssembler _masm(&cbuf); 3280 Register src_reg = as_Register($src$$reg); 3281 Register base = as_Register($mem$$base); 3282 int index = $mem$$index; 3283 int scale = $mem$$scale; 3284 int disp = $mem$$disp; 3285 if (index == -1) { 3286 if (disp != 0) { 3287 __ lea(rscratch2, Address(base, disp)); 3288 __ stlxr(rscratch1, src_reg, rscratch2); 3289 } else { 3290 // TODO 3291 // should we ever get anything other than this case? 3292 __ stlxr(rscratch1, src_reg, base); 3293 } 3294 } else { 3295 Register index_reg = as_Register(index); 3296 if (disp == 0) { 3297 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3298 __ stlxr(rscratch1, src_reg, rscratch2); 3299 } else { 3300 __ lea(rscratch2, Address(base, disp)); 3301 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3302 __ stlxr(rscratch1, src_reg, rscratch2); 3303 } 3304 } 3305 __ cmpw(rscratch1, zr); 3306 %} 3307 3308 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3309 C2_MacroAssembler _masm(&cbuf); 3310 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3311 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3312 Assembler::xword, /*acquire*/ false, /*release*/ true, 3313 /*weak*/ false, noreg); 3314 %} 3315 3316 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3317 C2_MacroAssembler _masm(&cbuf); 3318 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3319 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3320 Assembler::word, /*acquire*/ false, /*release*/ true, 3321 /*weak*/ false, noreg); 3322 %} 3323 3324 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3325 C2_MacroAssembler _masm(&cbuf); 3326 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3327 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3328 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3329 /*weak*/ false, noreg); 3330 %} 3331 3332 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3333 C2_MacroAssembler _masm(&cbuf); 3334 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3335 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3336 Assembler::byte, /*acquire*/ false, /*release*/ true, 3337 /*weak*/ false, noreg); 3338 %} 3339 3340 3341 // The only difference between aarch64_enc_cmpxchg and 3342 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3343 // CompareAndSwap sequence to serve as a barrier on acquiring a 3344 // lock. 3345 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3346 C2_MacroAssembler _masm(&cbuf); 3347 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3348 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3349 Assembler::xword, /*acquire*/ true, /*release*/ true, 3350 /*weak*/ false, noreg); 3351 %} 3352 3353 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3354 C2_MacroAssembler _masm(&cbuf); 3355 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3356 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3357 Assembler::word, /*acquire*/ true, /*release*/ true, 3358 /*weak*/ false, noreg); 3359 %} 3360 3361 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3362 C2_MacroAssembler _masm(&cbuf); 3363 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3364 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3365 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3366 /*weak*/ false, noreg); 3367 %} 3368 3369 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3370 C2_MacroAssembler _masm(&cbuf); 3371 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3372 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3373 Assembler::byte, /*acquire*/ true, /*release*/ true, 3374 /*weak*/ false, noreg); 3375 %} 3376 3377 // auxiliary used for CompareAndSwapX to set result register 3378 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3379 C2_MacroAssembler _masm(&cbuf); 3380 Register res_reg = as_Register($res$$reg); 3381 __ cset(res_reg, Assembler::EQ); 3382 %} 3383 3384 // prefetch encodings 3385 3386 enc_class aarch64_enc_prefetchw(memory mem) %{ 3387 C2_MacroAssembler _masm(&cbuf); 3388 Register base = as_Register($mem$$base); 3389 int index = $mem$$index; 3390 int scale = $mem$$scale; 3391 int disp = $mem$$disp; 3392 if (index == -1) { 3393 __ prfm(Address(base, disp), PSTL1KEEP); 3394 } else { 3395 Register index_reg = as_Register(index); 3396 if (disp == 0) { 3397 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3398 } else { 3399 __ lea(rscratch1, Address(base, disp)); 3400 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3401 } 3402 } 3403 %} 3404 3405 /// mov envcodings 3406 3407 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3408 C2_MacroAssembler _masm(&cbuf); 3409 uint32_t con = (uint32_t)$src$$constant; 3410 Register dst_reg = as_Register($dst$$reg); 3411 if (con == 0) { 3412 __ movw(dst_reg, zr); 3413 } else { 3414 __ movw(dst_reg, con); 3415 } 3416 %} 3417 3418 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3419 C2_MacroAssembler _masm(&cbuf); 3420 Register dst_reg = as_Register($dst$$reg); 3421 uint64_t con = (uint64_t)$src$$constant; 3422 if (con == 0) { 3423 __ mov(dst_reg, zr); 3424 } else { 3425 __ mov(dst_reg, con); 3426 } 3427 %} 3428 3429 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3430 C2_MacroAssembler _masm(&cbuf); 3431 Register dst_reg = as_Register($dst$$reg); 3432 address con = (address)$src$$constant; 3433 if (con == NULL || con == (address)1) { 3434 ShouldNotReachHere(); 3435 } else { 3436 relocInfo::relocType rtype = $src->constant_reloc(); 3437 if (rtype == relocInfo::oop_type) { 3438 __ movoop(dst_reg, (jobject)con); 3439 } else if (rtype == relocInfo::metadata_type) { 3440 __ mov_metadata(dst_reg, (Metadata*)con); 3441 } else { 3442 assert(rtype == relocInfo::none, "unexpected reloc type"); 3443 if (! __ is_valid_AArch64_address(con) || 3444 con < (address)(uintptr_t)os::vm_page_size()) { 3445 __ mov(dst_reg, con); 3446 } else { 3447 uint64_t offset; 3448 __ adrp(dst_reg, con, offset); 3449 __ add(dst_reg, dst_reg, offset); 3450 } 3451 } 3452 } 3453 %} 3454 3455 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3456 C2_MacroAssembler _masm(&cbuf); 3457 Register dst_reg = as_Register($dst$$reg); 3458 __ mov(dst_reg, zr); 3459 %} 3460 3461 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3462 C2_MacroAssembler _masm(&cbuf); 3463 Register dst_reg = as_Register($dst$$reg); 3464 __ mov(dst_reg, (uint64_t)1); 3465 %} 3466 3467 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3468 C2_MacroAssembler _masm(&cbuf); 3469 __ load_byte_map_base($dst$$Register); 3470 %} 3471 3472 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3473 C2_MacroAssembler _masm(&cbuf); 3474 Register dst_reg = as_Register($dst$$reg); 3475 address con = (address)$src$$constant; 3476 if (con == NULL) { 3477 ShouldNotReachHere(); 3478 } else { 3479 relocInfo::relocType rtype = $src->constant_reloc(); 3480 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3481 __ set_narrow_oop(dst_reg, (jobject)con); 3482 } 3483 %} 3484 3485 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3486 C2_MacroAssembler _masm(&cbuf); 3487 Register dst_reg = as_Register($dst$$reg); 3488 __ mov(dst_reg, zr); 3489 %} 3490 3491 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3492 C2_MacroAssembler _masm(&cbuf); 3493 Register dst_reg = as_Register($dst$$reg); 3494 address con = (address)$src$$constant; 3495 if (con == NULL) { 3496 ShouldNotReachHere(); 3497 } else { 3498 relocInfo::relocType rtype = $src->constant_reloc(); 3499 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3500 __ set_narrow_klass(dst_reg, (Klass *)con); 3501 } 3502 %} 3503 3504 // arithmetic encodings 3505 3506 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3507 C2_MacroAssembler _masm(&cbuf); 3508 Register dst_reg = as_Register($dst$$reg); 3509 Register src_reg = as_Register($src1$$reg); 3510 int32_t con = (int32_t)$src2$$constant; 3511 // add has primary == 0, subtract has primary == 1 3512 if ($primary) { con = -con; } 3513 if (con < 0) { 3514 __ subw(dst_reg, src_reg, -con); 3515 } else { 3516 __ addw(dst_reg, src_reg, con); 3517 } 3518 %} 3519 3520 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3521 C2_MacroAssembler _masm(&cbuf); 3522 Register dst_reg = as_Register($dst$$reg); 3523 Register src_reg = as_Register($src1$$reg); 3524 int32_t con = (int32_t)$src2$$constant; 3525 // add has primary == 0, subtract has primary == 1 3526 if ($primary) { con = -con; } 3527 if (con < 0) { 3528 __ sub(dst_reg, src_reg, -con); 3529 } else { 3530 __ add(dst_reg, src_reg, con); 3531 } 3532 %} 3533 3534 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3535 C2_MacroAssembler _masm(&cbuf); 3536 Register dst_reg = as_Register($dst$$reg); 3537 Register src1_reg = as_Register($src1$$reg); 3538 Register src2_reg = as_Register($src2$$reg); 3539 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3540 %} 3541 3542 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3543 C2_MacroAssembler _masm(&cbuf); 3544 Register dst_reg = as_Register($dst$$reg); 3545 Register src1_reg = as_Register($src1$$reg); 3546 Register src2_reg = as_Register($src2$$reg); 3547 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3548 %} 3549 3550 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3551 C2_MacroAssembler _masm(&cbuf); 3552 Register dst_reg = as_Register($dst$$reg); 3553 Register src1_reg = as_Register($src1$$reg); 3554 Register src2_reg = as_Register($src2$$reg); 3555 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3556 %} 3557 3558 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3559 C2_MacroAssembler _masm(&cbuf); 3560 Register dst_reg = as_Register($dst$$reg); 3561 Register src1_reg = as_Register($src1$$reg); 3562 Register src2_reg = as_Register($src2$$reg); 3563 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3564 %} 3565 3566 // compare instruction encodings 3567 3568 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3569 C2_MacroAssembler _masm(&cbuf); 3570 Register reg1 = as_Register($src1$$reg); 3571 Register reg2 = as_Register($src2$$reg); 3572 __ cmpw(reg1, reg2); 3573 %} 3574 3575 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3576 C2_MacroAssembler _masm(&cbuf); 3577 Register reg = as_Register($src1$$reg); 3578 int32_t val = $src2$$constant; 3579 if (val >= 0) { 3580 __ subsw(zr, reg, val); 3581 } else { 3582 __ addsw(zr, reg, -val); 3583 } 3584 %} 3585 3586 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3587 C2_MacroAssembler _masm(&cbuf); 3588 Register reg1 = as_Register($src1$$reg); 3589 uint32_t val = (uint32_t)$src2$$constant; 3590 __ movw(rscratch1, val); 3591 __ cmpw(reg1, rscratch1); 3592 %} 3593 3594 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3595 C2_MacroAssembler _masm(&cbuf); 3596 Register reg1 = as_Register($src1$$reg); 3597 Register reg2 = as_Register($src2$$reg); 3598 __ cmp(reg1, reg2); 3599 %} 3600 3601 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3602 C2_MacroAssembler _masm(&cbuf); 3603 Register reg = as_Register($src1$$reg); 3604 int64_t val = $src2$$constant; 3605 if (val >= 0) { 3606 __ subs(zr, reg, val); 3607 } else if (val != -val) { 3608 __ adds(zr, reg, -val); 3609 } else { 3610 // aargh, Long.MIN_VALUE is a special case 3611 __ orr(rscratch1, zr, (uint64_t)val); 3612 __ subs(zr, reg, rscratch1); 3613 } 3614 %} 3615 3616 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3617 C2_MacroAssembler _masm(&cbuf); 3618 Register reg1 = as_Register($src1$$reg); 3619 uint64_t val = (uint64_t)$src2$$constant; 3620 __ mov(rscratch1, val); 3621 __ cmp(reg1, rscratch1); 3622 %} 3623 3624 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3625 C2_MacroAssembler _masm(&cbuf); 3626 Register reg1 = as_Register($src1$$reg); 3627 Register reg2 = as_Register($src2$$reg); 3628 __ cmp(reg1, reg2); 3629 %} 3630 3631 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3632 C2_MacroAssembler _masm(&cbuf); 3633 Register reg1 = as_Register($src1$$reg); 3634 Register reg2 = as_Register($src2$$reg); 3635 __ cmpw(reg1, reg2); 3636 %} 3637 3638 enc_class aarch64_enc_testp(iRegP src) %{ 3639 C2_MacroAssembler _masm(&cbuf); 3640 Register reg = as_Register($src$$reg); 3641 __ cmp(reg, zr); 3642 %} 3643 3644 enc_class aarch64_enc_testn(iRegN src) %{ 3645 C2_MacroAssembler _masm(&cbuf); 3646 Register reg = as_Register($src$$reg); 3647 __ cmpw(reg, zr); 3648 %} 3649 3650 enc_class aarch64_enc_b(label lbl) %{ 3651 C2_MacroAssembler _masm(&cbuf); 3652 Label *L = $lbl$$label; 3653 __ b(*L); 3654 %} 3655 3656 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3657 C2_MacroAssembler _masm(&cbuf); 3658 Label *L = $lbl$$label; 3659 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3660 %} 3661 3662 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3663 C2_MacroAssembler _masm(&cbuf); 3664 Label *L = $lbl$$label; 3665 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3666 %} 3667 3668 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3669 %{ 3670 Register sub_reg = as_Register($sub$$reg); 3671 Register super_reg = as_Register($super$$reg); 3672 Register temp_reg = as_Register($temp$$reg); 3673 Register result_reg = as_Register($result$$reg); 3674 3675 Label miss; 3676 C2_MacroAssembler _masm(&cbuf); 3677 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3678 NULL, &miss, 3679 /*set_cond_codes:*/ true); 3680 if ($primary) { 3681 __ mov(result_reg, zr); 3682 } 3683 __ bind(miss); 3684 %} 3685 3686 enc_class aarch64_enc_java_static_call(method meth) %{ 3687 C2_MacroAssembler _masm(&cbuf); 3688 3689 address addr = (address)$meth$$method; 3690 address call; 3691 if (!_method) { 3692 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3693 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type)); 3694 if (call == NULL) { 3695 ciEnv::current()->record_failure("CodeCache is full"); 3696 return; 3697 } 3698 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 3699 // The NOP here is purely to ensure that eliding a call to 3700 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 3701 __ nop(); 3702 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 3703 } else { 3704 int method_index = resolved_method_index(cbuf); 3705 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3706 : static_call_Relocation::spec(method_index); 3707 call = __ trampoline_call(Address(addr, rspec)); 3708 if (call == NULL) { 3709 ciEnv::current()->record_failure("CodeCache is full"); 3710 return; 3711 } 3712 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 3713 // Calls of the same statically bound method can share 3714 // a stub to the interpreter. 3715 cbuf.shared_stub_to_interp_for(_method, call - cbuf.insts_begin()); 3716 } else { 3717 // Emit stub for static call 3718 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, call); 3719 if (stub == NULL) { 3720 ciEnv::current()->record_failure("CodeCache is full"); 3721 return; 3722 } 3723 } 3724 } 3725 3726 __ post_call_nop(); 3727 3728 // Only non uncommon_trap calls need to reinitialize ptrue. 3729 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) { 3730 __ reinitialize_ptrue(); 3731 } 3732 %} 3733 3734 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3735 C2_MacroAssembler _masm(&cbuf); 3736 int method_index = resolved_method_index(cbuf); 3737 address call = __ ic_call((address)$meth$$method, method_index); 3738 if (call == NULL) { 3739 ciEnv::current()->record_failure("CodeCache is full"); 3740 return; 3741 } 3742 __ post_call_nop(); 3743 if (Compile::current()->max_vector_size() > 0) { 3744 __ reinitialize_ptrue(); 3745 } 3746 %} 3747 3748 enc_class aarch64_enc_call_epilog() %{ 3749 C2_MacroAssembler _masm(&cbuf); 3750 if (VerifyStackAtCalls) { 3751 // Check that stack depth is unchanged: find majik cookie on stack 3752 __ call_Unimplemented(); 3753 } 3754 %} 3755 3756 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3757 C2_MacroAssembler _masm(&cbuf); 3758 3759 // some calls to generated routines (arraycopy code) are scheduled 3760 // by C2 as runtime calls. if so we can call them using a br (they 3761 // will be in a reachable segment) otherwise we have to use a blr 3762 // which loads the absolute address into a register. 3763 address entry = (address)$meth$$method; 3764 CodeBlob *cb = CodeCache::find_blob(entry); 3765 if (cb) { 3766 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3767 if (call == NULL) { 3768 ciEnv::current()->record_failure("CodeCache is full"); 3769 return; 3770 } 3771 __ post_call_nop(); 3772 } else { 3773 Label retaddr; 3774 __ adr(rscratch2, retaddr); 3775 __ lea(rscratch1, RuntimeAddress(entry)); 3776 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3777 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3778 __ blr(rscratch1); 3779 __ bind(retaddr); 3780 __ post_call_nop(); 3781 __ add(sp, sp, 2 * wordSize); 3782 } 3783 if (Compile::current()->max_vector_size() > 0) { 3784 __ reinitialize_ptrue(); 3785 } 3786 %} 3787 3788 enc_class aarch64_enc_rethrow() %{ 3789 C2_MacroAssembler _masm(&cbuf); 3790 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3791 %} 3792 3793 enc_class aarch64_enc_ret() %{ 3794 C2_MacroAssembler _masm(&cbuf); 3795 #ifdef ASSERT 3796 if (Compile::current()->max_vector_size() > 0) { 3797 __ verify_ptrue(); 3798 } 3799 #endif 3800 __ ret(lr); 3801 %} 3802 3803 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3804 C2_MacroAssembler _masm(&cbuf); 3805 Register target_reg = as_Register($jump_target$$reg); 3806 __ br(target_reg); 3807 %} 3808 3809 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3810 C2_MacroAssembler _masm(&cbuf); 3811 Register target_reg = as_Register($jump_target$$reg); 3812 // exception oop should be in r0 3813 // ret addr has been popped into lr 3814 // callee expects it in r3 3815 __ mov(r3, lr); 3816 __ br(target_reg); 3817 %} 3818 3819 %} 3820 3821 //----------FRAME-------------------------------------------------------------- 3822 // Definition of frame structure and management information. 3823 // 3824 // S T A C K L A Y O U T Allocators stack-slot number 3825 // | (to get allocators register number 3826 // G Owned by | | v add OptoReg::stack0()) 3827 // r CALLER | | 3828 // o | +--------+ pad to even-align allocators stack-slot 3829 // w V | pad0 | numbers; owned by CALLER 3830 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3831 // h ^ | in | 5 3832 // | | args | 4 Holes in incoming args owned by SELF 3833 // | | | | 3 3834 // | | +--------+ 3835 // V | | old out| Empty on Intel, window on Sparc 3836 // | old |preserve| Must be even aligned. 3837 // | SP-+--------+----> Matcher::_old_SP, even aligned 3838 // | | in | 3 area for Intel ret address 3839 // Owned by |preserve| Empty on Sparc. 3840 // SELF +--------+ 3841 // | | pad2 | 2 pad to align old SP 3842 // | +--------+ 1 3843 // | | locks | 0 3844 // | +--------+----> OptoReg::stack0(), even aligned 3845 // | | pad1 | 11 pad to align new SP 3846 // | +--------+ 3847 // | | | 10 3848 // | | spills | 9 spills 3849 // V | | 8 (pad0 slot for callee) 3850 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3851 // ^ | out | 7 3852 // | | args | 6 Holes in outgoing args owned by CALLEE 3853 // Owned by +--------+ 3854 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3855 // | new |preserve| Must be even-aligned. 3856 // | SP-+--------+----> Matcher::_new_SP, even aligned 3857 // | | | 3858 // 3859 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3860 // known from SELF's arguments and the Java calling convention. 3861 // Region 6-7 is determined per call site. 3862 // Note 2: If the calling convention leaves holes in the incoming argument 3863 // area, those holes are owned by SELF. Holes in the outgoing area 3864 // are owned by the CALLEE. Holes should not be necessary in the 3865 // incoming area, as the Java calling convention is completely under 3866 // the control of the AD file. Doubles can be sorted and packed to 3867 // avoid holes. Holes in the outgoing arguments may be necessary for 3868 // varargs C calling conventions. 3869 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3870 // even aligned with pad0 as needed. 3871 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3872 // (the latter is true on Intel but is it false on AArch64?) 3873 // region 6-11 is even aligned; it may be padded out more so that 3874 // the region from SP to FP meets the minimum stack alignment. 3875 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3876 // alignment. Region 11, pad1, may be dynamically extended so that 3877 // SP meets the minimum alignment. 3878 3879 frame %{ 3880 // These three registers define part of the calling convention 3881 // between compiled code and the interpreter. 3882 3883 // Inline Cache Register or Method for I2C. 3884 inline_cache_reg(R12); 3885 3886 // Number of stack slots consumed by locking an object 3887 sync_stack_slots(2); 3888 3889 // Compiled code's Frame Pointer 3890 frame_pointer(R31); 3891 3892 // Interpreter stores its frame pointer in a register which is 3893 // stored to the stack by I2CAdaptors. 3894 // I2CAdaptors convert from interpreted java to compiled java. 3895 interpreter_frame_pointer(R29); 3896 3897 // Stack alignment requirement 3898 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3899 3900 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3901 // for calls to C. Supports the var-args backing area for register parms. 3902 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3903 3904 // The after-PROLOG location of the return address. Location of 3905 // return address specifies a type (REG or STACK) and a number 3906 // representing the register number (i.e. - use a register name) or 3907 // stack slot. 3908 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3909 // Otherwise, it is above the locks and verification slot and alignment word 3910 // TODO this may well be correct but need to check why that - 2 is there 3911 // ppc port uses 0 but we definitely need to allow for fixed_slots 3912 // which folds in the space used for monitors 3913 return_addr(STACK - 2 + 3914 align_up((Compile::current()->in_preserve_stack_slots() + 3915 Compile::current()->fixed_slots()), 3916 stack_alignment_in_slots())); 3917 3918 // Location of compiled Java return values. Same as C for now. 3919 return_value 3920 %{ 3921 // TODO do we allow ideal_reg == Op_RegN??? 3922 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3923 "only return normal values"); 3924 3925 static const int lo[Op_RegL + 1] = { // enum name 3926 0, // Op_Node 3927 0, // Op_Set 3928 R0_num, // Op_RegN 3929 R0_num, // Op_RegI 3930 R0_num, // Op_RegP 3931 V0_num, // Op_RegF 3932 V0_num, // Op_RegD 3933 R0_num // Op_RegL 3934 }; 3935 3936 static const int hi[Op_RegL + 1] = { // enum name 3937 0, // Op_Node 3938 0, // Op_Set 3939 OptoReg::Bad, // Op_RegN 3940 OptoReg::Bad, // Op_RegI 3941 R0_H_num, // Op_RegP 3942 OptoReg::Bad, // Op_RegF 3943 V0_H_num, // Op_RegD 3944 R0_H_num // Op_RegL 3945 }; 3946 3947 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3948 %} 3949 %} 3950 3951 //----------ATTRIBUTES--------------------------------------------------------- 3952 //----------Operand Attributes------------------------------------------------- 3953 op_attrib op_cost(1); // Required cost attribute 3954 3955 //----------Instruction Attributes--------------------------------------------- 3956 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3957 ins_attrib ins_size(32); // Required size attribute (in bits) 3958 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3959 // a non-matching short branch variant 3960 // of some long branch? 3961 ins_attrib ins_alignment(4); // Required alignment attribute (must 3962 // be a power of 2) specifies the 3963 // alignment that some part of the 3964 // instruction (not necessarily the 3965 // start) requires. If > 1, a 3966 // compute_padding() function must be 3967 // provided for the instruction 3968 3969 //----------OPERANDS----------------------------------------------------------- 3970 // Operand definitions must precede instruction definitions for correct parsing 3971 // in the ADLC because operands constitute user defined types which are used in 3972 // instruction definitions. 3973 3974 //----------Simple Operands---------------------------------------------------- 3975 3976 // Integer operands 32 bit 3977 // 32 bit immediate 3978 operand immI() 3979 %{ 3980 match(ConI); 3981 3982 op_cost(0); 3983 format %{ %} 3984 interface(CONST_INTER); 3985 %} 3986 3987 // 32 bit zero 3988 operand immI0() 3989 %{ 3990 predicate(n->get_int() == 0); 3991 match(ConI); 3992 3993 op_cost(0); 3994 format %{ %} 3995 interface(CONST_INTER); 3996 %} 3997 3998 // 32 bit unit increment 3999 operand immI_1() 4000 %{ 4001 predicate(n->get_int() == 1); 4002 match(ConI); 4003 4004 op_cost(0); 4005 format %{ %} 4006 interface(CONST_INTER); 4007 %} 4008 4009 // 32 bit unit decrement 4010 operand immI_M1() 4011 %{ 4012 predicate(n->get_int() == -1); 4013 match(ConI); 4014 4015 op_cost(0); 4016 format %{ %} 4017 interface(CONST_INTER); 4018 %} 4019 4020 // Shift values for add/sub extension shift 4021 operand immIExt() 4022 %{ 4023 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 4024 match(ConI); 4025 4026 op_cost(0); 4027 format %{ %} 4028 interface(CONST_INTER); 4029 %} 4030 4031 operand immI_gt_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 operand immI_le_4() 4042 %{ 4043 predicate(n->get_int() <= 4); 4044 match(ConI); 4045 4046 op_cost(0); 4047 format %{ %} 4048 interface(CONST_INTER); 4049 %} 4050 4051 operand immI_16() 4052 %{ 4053 predicate(n->get_int() == 16); 4054 match(ConI); 4055 4056 op_cost(0); 4057 format %{ %} 4058 interface(CONST_INTER); 4059 %} 4060 4061 operand immI_24() 4062 %{ 4063 predicate(n->get_int() == 24); 4064 match(ConI); 4065 4066 op_cost(0); 4067 format %{ %} 4068 interface(CONST_INTER); 4069 %} 4070 4071 operand immI_32() 4072 %{ 4073 predicate(n->get_int() == 32); 4074 match(ConI); 4075 4076 op_cost(0); 4077 format %{ %} 4078 interface(CONST_INTER); 4079 %} 4080 4081 operand immI_48() 4082 %{ 4083 predicate(n->get_int() == 48); 4084 match(ConI); 4085 4086 op_cost(0); 4087 format %{ %} 4088 interface(CONST_INTER); 4089 %} 4090 4091 operand immI_56() 4092 %{ 4093 predicate(n->get_int() == 56); 4094 match(ConI); 4095 4096 op_cost(0); 4097 format %{ %} 4098 interface(CONST_INTER); 4099 %} 4100 4101 operand immI_63() 4102 %{ 4103 predicate(n->get_int() == 63); 4104 match(ConI); 4105 4106 op_cost(0); 4107 format %{ %} 4108 interface(CONST_INTER); 4109 %} 4110 4111 operand immI_64() 4112 %{ 4113 predicate(n->get_int() == 64); 4114 match(ConI); 4115 4116 op_cost(0); 4117 format %{ %} 4118 interface(CONST_INTER); 4119 %} 4120 4121 operand immI_255() 4122 %{ 4123 predicate(n->get_int() == 255); 4124 match(ConI); 4125 4126 op_cost(0); 4127 format %{ %} 4128 interface(CONST_INTER); 4129 %} 4130 4131 operand immI_65535() 4132 %{ 4133 predicate(n->get_int() == 65535); 4134 match(ConI); 4135 4136 op_cost(0); 4137 format %{ %} 4138 interface(CONST_INTER); 4139 %} 4140 4141 operand immI_positive() 4142 %{ 4143 predicate(n->get_int() > 0); 4144 match(ConI); 4145 4146 op_cost(0); 4147 format %{ %} 4148 interface(CONST_INTER); 4149 %} 4150 4151 // BoolTest condition for signed compare 4152 operand immI_cmp_cond() 4153 %{ 4154 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int())); 4155 match(ConI); 4156 4157 op_cost(0); 4158 format %{ %} 4159 interface(CONST_INTER); 4160 %} 4161 4162 // BoolTest condition for unsigned compare 4163 operand immI_cmpU_cond() 4164 %{ 4165 predicate(Matcher::is_unsigned_booltest_pred(n->get_int())); 4166 match(ConI); 4167 4168 op_cost(0); 4169 format %{ %} 4170 interface(CONST_INTER); 4171 %} 4172 4173 operand immL_255() 4174 %{ 4175 predicate(n->get_long() == 255L); 4176 match(ConL); 4177 4178 op_cost(0); 4179 format %{ %} 4180 interface(CONST_INTER); 4181 %} 4182 4183 operand immL_65535() 4184 %{ 4185 predicate(n->get_long() == 65535L); 4186 match(ConL); 4187 4188 op_cost(0); 4189 format %{ %} 4190 interface(CONST_INTER); 4191 %} 4192 4193 operand immL_4294967295() 4194 %{ 4195 predicate(n->get_long() == 4294967295L); 4196 match(ConL); 4197 4198 op_cost(0); 4199 format %{ %} 4200 interface(CONST_INTER); 4201 %} 4202 4203 operand immL_bitmask() 4204 %{ 4205 predicate((n->get_long() != 0) 4206 && ((n->get_long() & 0xc000000000000000l) == 0) 4207 && is_power_of_2(n->get_long() + 1)); 4208 match(ConL); 4209 4210 op_cost(0); 4211 format %{ %} 4212 interface(CONST_INTER); 4213 %} 4214 4215 operand immI_bitmask() 4216 %{ 4217 predicate((n->get_int() != 0) 4218 && ((n->get_int() & 0xc0000000) == 0) 4219 && is_power_of_2(n->get_int() + 1)); 4220 match(ConI); 4221 4222 op_cost(0); 4223 format %{ %} 4224 interface(CONST_INTER); 4225 %} 4226 4227 operand immL_positive_bitmaskI() 4228 %{ 4229 predicate((n->get_long() != 0) 4230 && ((julong)n->get_long() < 0x80000000ULL) 4231 && is_power_of_2(n->get_long() + 1)); 4232 match(ConL); 4233 4234 op_cost(0); 4235 format %{ %} 4236 interface(CONST_INTER); 4237 %} 4238 4239 // Scale values for scaled offset addressing modes (up to long but not quad) 4240 operand immIScale() 4241 %{ 4242 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4243 match(ConI); 4244 4245 op_cost(0); 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 // 26 bit signed offset -- for pc-relative branches 4251 operand immI26() 4252 %{ 4253 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4254 match(ConI); 4255 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 // 19 bit signed offset -- for pc-relative loads 4262 operand immI19() 4263 %{ 4264 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4265 match(ConI); 4266 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // 5 bit signed integer 4273 operand immI5() 4274 %{ 4275 predicate(Assembler::is_simm(n->get_int(), 5)); 4276 match(ConI); 4277 4278 op_cost(0); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // 7 bit unsigned integer 4284 operand immIU7() 4285 %{ 4286 predicate(Assembler::is_uimm(n->get_int(), 7)); 4287 match(ConI); 4288 4289 op_cost(0); 4290 format %{ %} 4291 interface(CONST_INTER); 4292 %} 4293 4294 // 12 bit unsigned offset -- for base plus immediate loads 4295 operand immIU12() 4296 %{ 4297 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4298 match(ConI); 4299 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 operand immLU12() 4306 %{ 4307 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4308 match(ConL); 4309 4310 op_cost(0); 4311 format %{ %} 4312 interface(CONST_INTER); 4313 %} 4314 4315 // Offset for scaled or unscaled immediate loads and stores 4316 operand immIOffset() 4317 %{ 4318 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4319 match(ConI); 4320 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 operand immIOffset1() 4327 %{ 4328 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4329 match(ConI); 4330 4331 op_cost(0); 4332 format %{ %} 4333 interface(CONST_INTER); 4334 %} 4335 4336 operand immIOffset2() 4337 %{ 4338 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4339 match(ConI); 4340 4341 op_cost(0); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 operand immIOffset4() 4347 %{ 4348 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4349 match(ConI); 4350 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 operand immIOffset8() 4357 %{ 4358 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4359 match(ConI); 4360 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 operand immIOffset16() 4367 %{ 4368 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4369 match(ConI); 4370 4371 op_cost(0); 4372 format %{ %} 4373 interface(CONST_INTER); 4374 %} 4375 4376 operand immLoffset() 4377 %{ 4378 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4379 match(ConL); 4380 4381 op_cost(0); 4382 format %{ %} 4383 interface(CONST_INTER); 4384 %} 4385 4386 operand immLoffset1() 4387 %{ 4388 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4389 match(ConL); 4390 4391 op_cost(0); 4392 format %{ %} 4393 interface(CONST_INTER); 4394 %} 4395 4396 operand immLoffset2() 4397 %{ 4398 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4399 match(ConL); 4400 4401 op_cost(0); 4402 format %{ %} 4403 interface(CONST_INTER); 4404 %} 4405 4406 operand immLoffset4() 4407 %{ 4408 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4409 match(ConL); 4410 4411 op_cost(0); 4412 format %{ %} 4413 interface(CONST_INTER); 4414 %} 4415 4416 operand immLoffset8() 4417 %{ 4418 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4419 match(ConL); 4420 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 operand immLoffset16() 4427 %{ 4428 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4429 match(ConL); 4430 4431 op_cost(0); 4432 format %{ %} 4433 interface(CONST_INTER); 4434 %} 4435 4436 // 5 bit signed long integer 4437 operand immL5() 4438 %{ 4439 predicate(Assembler::is_simm(n->get_long(), 5)); 4440 match(ConL); 4441 4442 op_cost(0); 4443 format %{ %} 4444 interface(CONST_INTER); 4445 %} 4446 4447 // 7 bit unsigned long integer 4448 operand immLU7() 4449 %{ 4450 predicate(Assembler::is_uimm(n->get_long(), 7)); 4451 match(ConL); 4452 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // 8 bit signed value. 4459 operand immI8() 4460 %{ 4461 predicate(n->get_int() <= 127 && n->get_int() >= -128); 4462 match(ConI); 4463 4464 op_cost(0); 4465 format %{ %} 4466 interface(CONST_INTER); 4467 %} 4468 4469 // 8 bit signed value (simm8), or #simm8 LSL 8. 4470 operand immI8_shift8() 4471 %{ 4472 predicate((n->get_int() <= 127 && n->get_int() >= -128) || 4473 (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0)); 4474 match(ConI); 4475 4476 op_cost(0); 4477 format %{ %} 4478 interface(CONST_INTER); 4479 %} 4480 4481 // 8 bit signed value (simm8), or #simm8 LSL 8. 4482 operand immL8_shift8() 4483 %{ 4484 predicate((n->get_long() <= 127 && n->get_long() >= -128) || 4485 (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0)); 4486 match(ConL); 4487 4488 op_cost(0); 4489 format %{ %} 4490 interface(CONST_INTER); 4491 %} 4492 4493 // 8 bit integer valid for vector add sub immediate 4494 operand immBAddSubV() 4495 %{ 4496 predicate(n->get_int() <= 255 && n->get_int() >= -255); 4497 match(ConI); 4498 4499 op_cost(0); 4500 format %{ %} 4501 interface(CONST_INTER); 4502 %} 4503 4504 // 32 bit integer valid for add sub immediate 4505 operand immIAddSub() 4506 %{ 4507 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4508 match(ConI); 4509 op_cost(0); 4510 format %{ %} 4511 interface(CONST_INTER); 4512 %} 4513 4514 // 32 bit integer valid for vector add sub immediate 4515 operand immIAddSubV() 4516 %{ 4517 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int())); 4518 match(ConI); 4519 4520 op_cost(0); 4521 format %{ %} 4522 interface(CONST_INTER); 4523 %} 4524 4525 // 32 bit unsigned integer valid for logical immediate 4526 4527 operand immBLog() 4528 %{ 4529 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int())); 4530 match(ConI); 4531 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 operand immSLog() 4538 %{ 4539 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int())); 4540 match(ConI); 4541 4542 op_cost(0); 4543 format %{ %} 4544 interface(CONST_INTER); 4545 %} 4546 4547 operand immILog() 4548 %{ 4549 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4550 match(ConI); 4551 4552 op_cost(0); 4553 format %{ %} 4554 interface(CONST_INTER); 4555 %} 4556 4557 // Integer operands 64 bit 4558 // 64 bit immediate 4559 operand immL() 4560 %{ 4561 match(ConL); 4562 4563 op_cost(0); 4564 format %{ %} 4565 interface(CONST_INTER); 4566 %} 4567 4568 // 64 bit zero 4569 operand immL0() 4570 %{ 4571 predicate(n->get_long() == 0); 4572 match(ConL); 4573 4574 op_cost(0); 4575 format %{ %} 4576 interface(CONST_INTER); 4577 %} 4578 4579 // 64 bit unit increment 4580 operand immL_1() 4581 %{ 4582 predicate(n->get_long() == 1); 4583 match(ConL); 4584 4585 op_cost(0); 4586 format %{ %} 4587 interface(CONST_INTER); 4588 %} 4589 4590 // 64 bit unit decrement 4591 operand immL_M1() 4592 %{ 4593 predicate(n->get_long() == -1); 4594 match(ConL); 4595 4596 op_cost(0); 4597 format %{ %} 4598 interface(CONST_INTER); 4599 %} 4600 4601 // 32 bit offset of pc in thread anchor 4602 4603 operand immL_pc_off() 4604 %{ 4605 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4606 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4607 match(ConL); 4608 4609 op_cost(0); 4610 format %{ %} 4611 interface(CONST_INTER); 4612 %} 4613 4614 // 64 bit integer valid for add sub immediate 4615 operand immLAddSub() 4616 %{ 4617 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4618 match(ConL); 4619 op_cost(0); 4620 format %{ %} 4621 interface(CONST_INTER); 4622 %} 4623 4624 // 64 bit integer valid for addv subv immediate 4625 operand immLAddSubV() 4626 %{ 4627 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long())); 4628 match(ConL); 4629 4630 op_cost(0); 4631 format %{ %} 4632 interface(CONST_INTER); 4633 %} 4634 4635 // 64 bit integer valid for logical immediate 4636 operand immLLog() 4637 %{ 4638 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4639 match(ConL); 4640 op_cost(0); 4641 format %{ %} 4642 interface(CONST_INTER); 4643 %} 4644 4645 // Long Immediate: low 32-bit mask 4646 operand immL_32bits() 4647 %{ 4648 predicate(n->get_long() == 0xFFFFFFFFL); 4649 match(ConL); 4650 op_cost(0); 4651 format %{ %} 4652 interface(CONST_INTER); 4653 %} 4654 4655 // Pointer operands 4656 // Pointer Immediate 4657 operand immP() 4658 %{ 4659 match(ConP); 4660 4661 op_cost(0); 4662 format %{ %} 4663 interface(CONST_INTER); 4664 %} 4665 4666 // NULL Pointer Immediate 4667 operand immP0() 4668 %{ 4669 predicate(n->get_ptr() == 0); 4670 match(ConP); 4671 4672 op_cost(0); 4673 format %{ %} 4674 interface(CONST_INTER); 4675 %} 4676 4677 // Pointer Immediate One 4678 // this is used in object initialization (initial object header) 4679 operand immP_1() 4680 %{ 4681 predicate(n->get_ptr() == 1); 4682 match(ConP); 4683 4684 op_cost(0); 4685 format %{ %} 4686 interface(CONST_INTER); 4687 %} 4688 4689 // Card Table Byte Map Base 4690 operand immByteMapBase() 4691 %{ 4692 // Get base of card map 4693 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4694 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4695 match(ConP); 4696 4697 op_cost(0); 4698 format %{ %} 4699 interface(CONST_INTER); 4700 %} 4701 4702 // Pointer Immediate Minus One 4703 // this is used when we want to write the current PC to the thread anchor 4704 operand immP_M1() 4705 %{ 4706 predicate(n->get_ptr() == -1); 4707 match(ConP); 4708 4709 op_cost(0); 4710 format %{ %} 4711 interface(CONST_INTER); 4712 %} 4713 4714 // Pointer Immediate Minus Two 4715 // this is used when we want to write the current PC to the thread anchor 4716 operand immP_M2() 4717 %{ 4718 predicate(n->get_ptr() == -2); 4719 match(ConP); 4720 4721 op_cost(0); 4722 format %{ %} 4723 interface(CONST_INTER); 4724 %} 4725 4726 // Float and Double operands 4727 // Double Immediate 4728 operand immD() 4729 %{ 4730 match(ConD); 4731 op_cost(0); 4732 format %{ %} 4733 interface(CONST_INTER); 4734 %} 4735 4736 // Double Immediate: +0.0d 4737 operand immD0() 4738 %{ 4739 predicate(jlong_cast(n->getd()) == 0); 4740 match(ConD); 4741 4742 op_cost(0); 4743 format %{ %} 4744 interface(CONST_INTER); 4745 %} 4746 4747 // constant 'double +0.0'. 4748 operand immDPacked() 4749 %{ 4750 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4751 match(ConD); 4752 op_cost(0); 4753 format %{ %} 4754 interface(CONST_INTER); 4755 %} 4756 4757 // Float Immediate 4758 operand immF() 4759 %{ 4760 match(ConF); 4761 op_cost(0); 4762 format %{ %} 4763 interface(CONST_INTER); 4764 %} 4765 4766 // Float Immediate: +0.0f. 4767 operand immF0() 4768 %{ 4769 predicate(jint_cast(n->getf()) == 0); 4770 match(ConF); 4771 4772 op_cost(0); 4773 format %{ %} 4774 interface(CONST_INTER); 4775 %} 4776 4777 // 4778 operand immFPacked() 4779 %{ 4780 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4781 match(ConF); 4782 op_cost(0); 4783 format %{ %} 4784 interface(CONST_INTER); 4785 %} 4786 4787 // Narrow pointer operands 4788 // Narrow Pointer Immediate 4789 operand immN() 4790 %{ 4791 match(ConN); 4792 4793 op_cost(0); 4794 format %{ %} 4795 interface(CONST_INTER); 4796 %} 4797 4798 // Narrow NULL Pointer Immediate 4799 operand immN0() 4800 %{ 4801 predicate(n->get_narrowcon() == 0); 4802 match(ConN); 4803 4804 op_cost(0); 4805 format %{ %} 4806 interface(CONST_INTER); 4807 %} 4808 4809 operand immNKlass() 4810 %{ 4811 match(ConNKlass); 4812 4813 op_cost(0); 4814 format %{ %} 4815 interface(CONST_INTER); 4816 %} 4817 4818 // Integer 32 bit Register Operands 4819 // Integer 32 bitRegister (excludes SP) 4820 operand iRegI() 4821 %{ 4822 constraint(ALLOC_IN_RC(any_reg32)); 4823 match(RegI); 4824 match(iRegINoSp); 4825 op_cost(0); 4826 format %{ %} 4827 interface(REG_INTER); 4828 %} 4829 4830 // Integer 32 bit Register not Special 4831 operand iRegINoSp() 4832 %{ 4833 constraint(ALLOC_IN_RC(no_special_reg32)); 4834 match(RegI); 4835 op_cost(0); 4836 format %{ %} 4837 interface(REG_INTER); 4838 %} 4839 4840 // Integer 64 bit Register Operands 4841 // Integer 64 bit Register (includes SP) 4842 operand iRegL() 4843 %{ 4844 constraint(ALLOC_IN_RC(any_reg)); 4845 match(RegL); 4846 match(iRegLNoSp); 4847 op_cost(0); 4848 format %{ %} 4849 interface(REG_INTER); 4850 %} 4851 4852 // Integer 64 bit Register not Special 4853 operand iRegLNoSp() 4854 %{ 4855 constraint(ALLOC_IN_RC(no_special_reg)); 4856 match(RegL); 4857 match(iRegL_R0); 4858 format %{ %} 4859 interface(REG_INTER); 4860 %} 4861 4862 // Pointer Register Operands 4863 // Pointer Register 4864 operand iRegP() 4865 %{ 4866 constraint(ALLOC_IN_RC(ptr_reg)); 4867 match(RegP); 4868 match(iRegPNoSp); 4869 match(iRegP_R0); 4870 //match(iRegP_R2); 4871 //match(iRegP_R4); 4872 match(iRegP_R5); 4873 match(thread_RegP); 4874 op_cost(0); 4875 format %{ %} 4876 interface(REG_INTER); 4877 %} 4878 4879 // Pointer 64 bit Register not Special 4880 operand iRegPNoSp() 4881 %{ 4882 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4883 match(RegP); 4884 // match(iRegP); 4885 // match(iRegP_R0); 4886 // match(iRegP_R2); 4887 // match(iRegP_R4); 4888 // match(iRegP_R5); 4889 // match(thread_RegP); 4890 op_cost(0); 4891 format %{ %} 4892 interface(REG_INTER); 4893 %} 4894 4895 // Pointer 64 bit Register R0 only 4896 operand iRegP_R0() 4897 %{ 4898 constraint(ALLOC_IN_RC(r0_reg)); 4899 match(RegP); 4900 // match(iRegP); 4901 match(iRegPNoSp); 4902 op_cost(0); 4903 format %{ %} 4904 interface(REG_INTER); 4905 %} 4906 4907 // Pointer 64 bit Register R1 only 4908 operand iRegP_R1() 4909 %{ 4910 constraint(ALLOC_IN_RC(r1_reg)); 4911 match(RegP); 4912 // match(iRegP); 4913 match(iRegPNoSp); 4914 op_cost(0); 4915 format %{ %} 4916 interface(REG_INTER); 4917 %} 4918 4919 // Pointer 64 bit Register R2 only 4920 operand iRegP_R2() 4921 %{ 4922 constraint(ALLOC_IN_RC(r2_reg)); 4923 match(RegP); 4924 // match(iRegP); 4925 match(iRegPNoSp); 4926 op_cost(0); 4927 format %{ %} 4928 interface(REG_INTER); 4929 %} 4930 4931 // Pointer 64 bit Register R3 only 4932 operand iRegP_R3() 4933 %{ 4934 constraint(ALLOC_IN_RC(r3_reg)); 4935 match(RegP); 4936 // match(iRegP); 4937 match(iRegPNoSp); 4938 op_cost(0); 4939 format %{ %} 4940 interface(REG_INTER); 4941 %} 4942 4943 // Pointer 64 bit Register R4 only 4944 operand iRegP_R4() 4945 %{ 4946 constraint(ALLOC_IN_RC(r4_reg)); 4947 match(RegP); 4948 // match(iRegP); 4949 match(iRegPNoSp); 4950 op_cost(0); 4951 format %{ %} 4952 interface(REG_INTER); 4953 %} 4954 4955 // Pointer 64 bit Register R5 only 4956 operand iRegP_R5() 4957 %{ 4958 constraint(ALLOC_IN_RC(r5_reg)); 4959 match(RegP); 4960 // match(iRegP); 4961 match(iRegPNoSp); 4962 op_cost(0); 4963 format %{ %} 4964 interface(REG_INTER); 4965 %} 4966 4967 // Pointer 64 bit Register R10 only 4968 operand iRegP_R10() 4969 %{ 4970 constraint(ALLOC_IN_RC(r10_reg)); 4971 match(RegP); 4972 // match(iRegP); 4973 match(iRegPNoSp); 4974 op_cost(0); 4975 format %{ %} 4976 interface(REG_INTER); 4977 %} 4978 4979 // Long 64 bit Register R0 only 4980 operand iRegL_R0() 4981 %{ 4982 constraint(ALLOC_IN_RC(r0_reg)); 4983 match(RegL); 4984 match(iRegLNoSp); 4985 op_cost(0); 4986 format %{ %} 4987 interface(REG_INTER); 4988 %} 4989 4990 // Long 64 bit Register R2 only 4991 operand iRegL_R2() 4992 %{ 4993 constraint(ALLOC_IN_RC(r2_reg)); 4994 match(RegL); 4995 match(iRegLNoSp); 4996 op_cost(0); 4997 format %{ %} 4998 interface(REG_INTER); 4999 %} 5000 5001 // Long 64 bit Register R3 only 5002 operand iRegL_R3() 5003 %{ 5004 constraint(ALLOC_IN_RC(r3_reg)); 5005 match(RegL); 5006 match(iRegLNoSp); 5007 op_cost(0); 5008 format %{ %} 5009 interface(REG_INTER); 5010 %} 5011 5012 // Long 64 bit Register R11 only 5013 operand iRegL_R11() 5014 %{ 5015 constraint(ALLOC_IN_RC(r11_reg)); 5016 match(RegL); 5017 match(iRegLNoSp); 5018 op_cost(0); 5019 format %{ %} 5020 interface(REG_INTER); 5021 %} 5022 5023 // Pointer 64 bit Register FP only 5024 operand iRegP_FP() 5025 %{ 5026 constraint(ALLOC_IN_RC(fp_reg)); 5027 match(RegP); 5028 // match(iRegP); 5029 op_cost(0); 5030 format %{ %} 5031 interface(REG_INTER); 5032 %} 5033 5034 // Register R0 only 5035 operand iRegI_R0() 5036 %{ 5037 constraint(ALLOC_IN_RC(int_r0_reg)); 5038 match(RegI); 5039 match(iRegINoSp); 5040 op_cost(0); 5041 format %{ %} 5042 interface(REG_INTER); 5043 %} 5044 5045 // Register R2 only 5046 operand iRegI_R2() 5047 %{ 5048 constraint(ALLOC_IN_RC(int_r2_reg)); 5049 match(RegI); 5050 match(iRegINoSp); 5051 op_cost(0); 5052 format %{ %} 5053 interface(REG_INTER); 5054 %} 5055 5056 // Register R3 only 5057 operand iRegI_R3() 5058 %{ 5059 constraint(ALLOC_IN_RC(int_r3_reg)); 5060 match(RegI); 5061 match(iRegINoSp); 5062 op_cost(0); 5063 format %{ %} 5064 interface(REG_INTER); 5065 %} 5066 5067 5068 // Register R4 only 5069 operand iRegI_R4() 5070 %{ 5071 constraint(ALLOC_IN_RC(int_r4_reg)); 5072 match(RegI); 5073 match(iRegINoSp); 5074 op_cost(0); 5075 format %{ %} 5076 interface(REG_INTER); 5077 %} 5078 5079 5080 // Pointer Register Operands 5081 // Narrow Pointer Register 5082 operand iRegN() 5083 %{ 5084 constraint(ALLOC_IN_RC(any_reg32)); 5085 match(RegN); 5086 match(iRegNNoSp); 5087 op_cost(0); 5088 format %{ %} 5089 interface(REG_INTER); 5090 %} 5091 5092 operand iRegN_R0() 5093 %{ 5094 constraint(ALLOC_IN_RC(r0_reg)); 5095 match(iRegN); 5096 op_cost(0); 5097 format %{ %} 5098 interface(REG_INTER); 5099 %} 5100 5101 operand iRegN_R2() 5102 %{ 5103 constraint(ALLOC_IN_RC(r2_reg)); 5104 match(iRegN); 5105 op_cost(0); 5106 format %{ %} 5107 interface(REG_INTER); 5108 %} 5109 5110 operand iRegN_R3() 5111 %{ 5112 constraint(ALLOC_IN_RC(r3_reg)); 5113 match(iRegN); 5114 op_cost(0); 5115 format %{ %} 5116 interface(REG_INTER); 5117 %} 5118 5119 // Integer 64 bit Register not Special 5120 operand iRegNNoSp() 5121 %{ 5122 constraint(ALLOC_IN_RC(no_special_reg32)); 5123 match(RegN); 5124 op_cost(0); 5125 format %{ %} 5126 interface(REG_INTER); 5127 %} 5128 5129 // Float Register 5130 // Float register operands 5131 operand vRegF() 5132 %{ 5133 constraint(ALLOC_IN_RC(float_reg)); 5134 match(RegF); 5135 5136 op_cost(0); 5137 format %{ %} 5138 interface(REG_INTER); 5139 %} 5140 5141 // Double Register 5142 // Double register operands 5143 operand vRegD() 5144 %{ 5145 constraint(ALLOC_IN_RC(double_reg)); 5146 match(RegD); 5147 5148 op_cost(0); 5149 format %{ %} 5150 interface(REG_INTER); 5151 %} 5152 5153 // Generic vector class. This will be used for 5154 // all vector operands, including NEON and SVE. 5155 operand vReg() 5156 %{ 5157 constraint(ALLOC_IN_RC(dynamic)); 5158 match(VecA); 5159 match(VecD); 5160 match(VecX); 5161 5162 op_cost(0); 5163 format %{ %} 5164 interface(REG_INTER); 5165 %} 5166 5167 operand vecA() 5168 %{ 5169 constraint(ALLOC_IN_RC(vectora_reg)); 5170 match(VecA); 5171 5172 op_cost(0); 5173 format %{ %} 5174 interface(REG_INTER); 5175 %} 5176 5177 operand vecD() 5178 %{ 5179 constraint(ALLOC_IN_RC(vectord_reg)); 5180 match(VecD); 5181 5182 op_cost(0); 5183 format %{ %} 5184 interface(REG_INTER); 5185 %} 5186 5187 operand vecX() 5188 %{ 5189 constraint(ALLOC_IN_RC(vectorx_reg)); 5190 match(VecX); 5191 5192 op_cost(0); 5193 format %{ %} 5194 interface(REG_INTER); 5195 %} 5196 5197 operand vRegD_V0() 5198 %{ 5199 constraint(ALLOC_IN_RC(v0_reg)); 5200 match(RegD); 5201 op_cost(0); 5202 format %{ %} 5203 interface(REG_INTER); 5204 %} 5205 5206 operand vRegD_V1() 5207 %{ 5208 constraint(ALLOC_IN_RC(v1_reg)); 5209 match(RegD); 5210 op_cost(0); 5211 format %{ %} 5212 interface(REG_INTER); 5213 %} 5214 5215 operand vRegD_V2() 5216 %{ 5217 constraint(ALLOC_IN_RC(v2_reg)); 5218 match(RegD); 5219 op_cost(0); 5220 format %{ %} 5221 interface(REG_INTER); 5222 %} 5223 5224 operand vRegD_V3() 5225 %{ 5226 constraint(ALLOC_IN_RC(v3_reg)); 5227 match(RegD); 5228 op_cost(0); 5229 format %{ %} 5230 interface(REG_INTER); 5231 %} 5232 5233 operand vRegD_V4() 5234 %{ 5235 constraint(ALLOC_IN_RC(v4_reg)); 5236 match(RegD); 5237 op_cost(0); 5238 format %{ %} 5239 interface(REG_INTER); 5240 %} 5241 5242 operand vRegD_V5() 5243 %{ 5244 constraint(ALLOC_IN_RC(v5_reg)); 5245 match(RegD); 5246 op_cost(0); 5247 format %{ %} 5248 interface(REG_INTER); 5249 %} 5250 5251 operand vRegD_V6() 5252 %{ 5253 constraint(ALLOC_IN_RC(v6_reg)); 5254 match(RegD); 5255 op_cost(0); 5256 format %{ %} 5257 interface(REG_INTER); 5258 %} 5259 5260 operand vRegD_V7() 5261 %{ 5262 constraint(ALLOC_IN_RC(v7_reg)); 5263 match(RegD); 5264 op_cost(0); 5265 format %{ %} 5266 interface(REG_INTER); 5267 %} 5268 5269 operand vRegD_V8() 5270 %{ 5271 constraint(ALLOC_IN_RC(v8_reg)); 5272 match(RegD); 5273 op_cost(0); 5274 format %{ %} 5275 interface(REG_INTER); 5276 %} 5277 5278 operand vRegD_V9() 5279 %{ 5280 constraint(ALLOC_IN_RC(v9_reg)); 5281 match(RegD); 5282 op_cost(0); 5283 format %{ %} 5284 interface(REG_INTER); 5285 %} 5286 5287 operand vRegD_V10() 5288 %{ 5289 constraint(ALLOC_IN_RC(v10_reg)); 5290 match(RegD); 5291 op_cost(0); 5292 format %{ %} 5293 interface(REG_INTER); 5294 %} 5295 5296 operand vRegD_V11() 5297 %{ 5298 constraint(ALLOC_IN_RC(v11_reg)); 5299 match(RegD); 5300 op_cost(0); 5301 format %{ %} 5302 interface(REG_INTER); 5303 %} 5304 5305 operand vRegD_V12() 5306 %{ 5307 constraint(ALLOC_IN_RC(v12_reg)); 5308 match(RegD); 5309 op_cost(0); 5310 format %{ %} 5311 interface(REG_INTER); 5312 %} 5313 5314 operand vRegD_V13() 5315 %{ 5316 constraint(ALLOC_IN_RC(v13_reg)); 5317 match(RegD); 5318 op_cost(0); 5319 format %{ %} 5320 interface(REG_INTER); 5321 %} 5322 5323 operand vRegD_V14() 5324 %{ 5325 constraint(ALLOC_IN_RC(v14_reg)); 5326 match(RegD); 5327 op_cost(0); 5328 format %{ %} 5329 interface(REG_INTER); 5330 %} 5331 5332 operand vRegD_V15() 5333 %{ 5334 constraint(ALLOC_IN_RC(v15_reg)); 5335 match(RegD); 5336 op_cost(0); 5337 format %{ %} 5338 interface(REG_INTER); 5339 %} 5340 5341 operand vRegD_V16() 5342 %{ 5343 constraint(ALLOC_IN_RC(v16_reg)); 5344 match(RegD); 5345 op_cost(0); 5346 format %{ %} 5347 interface(REG_INTER); 5348 %} 5349 5350 operand vRegD_V17() 5351 %{ 5352 constraint(ALLOC_IN_RC(v17_reg)); 5353 match(RegD); 5354 op_cost(0); 5355 format %{ %} 5356 interface(REG_INTER); 5357 %} 5358 5359 operand vRegD_V18() 5360 %{ 5361 constraint(ALLOC_IN_RC(v18_reg)); 5362 match(RegD); 5363 op_cost(0); 5364 format %{ %} 5365 interface(REG_INTER); 5366 %} 5367 5368 operand vRegD_V19() 5369 %{ 5370 constraint(ALLOC_IN_RC(v19_reg)); 5371 match(RegD); 5372 op_cost(0); 5373 format %{ %} 5374 interface(REG_INTER); 5375 %} 5376 5377 operand vRegD_V20() 5378 %{ 5379 constraint(ALLOC_IN_RC(v20_reg)); 5380 match(RegD); 5381 op_cost(0); 5382 format %{ %} 5383 interface(REG_INTER); 5384 %} 5385 5386 operand vRegD_V21() 5387 %{ 5388 constraint(ALLOC_IN_RC(v21_reg)); 5389 match(RegD); 5390 op_cost(0); 5391 format %{ %} 5392 interface(REG_INTER); 5393 %} 5394 5395 operand vRegD_V22() 5396 %{ 5397 constraint(ALLOC_IN_RC(v22_reg)); 5398 match(RegD); 5399 op_cost(0); 5400 format %{ %} 5401 interface(REG_INTER); 5402 %} 5403 5404 operand vRegD_V23() 5405 %{ 5406 constraint(ALLOC_IN_RC(v23_reg)); 5407 match(RegD); 5408 op_cost(0); 5409 format %{ %} 5410 interface(REG_INTER); 5411 %} 5412 5413 operand vRegD_V24() 5414 %{ 5415 constraint(ALLOC_IN_RC(v24_reg)); 5416 match(RegD); 5417 op_cost(0); 5418 format %{ %} 5419 interface(REG_INTER); 5420 %} 5421 5422 operand vRegD_V25() 5423 %{ 5424 constraint(ALLOC_IN_RC(v25_reg)); 5425 match(RegD); 5426 op_cost(0); 5427 format %{ %} 5428 interface(REG_INTER); 5429 %} 5430 5431 operand vRegD_V26() 5432 %{ 5433 constraint(ALLOC_IN_RC(v26_reg)); 5434 match(RegD); 5435 op_cost(0); 5436 format %{ %} 5437 interface(REG_INTER); 5438 %} 5439 5440 operand vRegD_V27() 5441 %{ 5442 constraint(ALLOC_IN_RC(v27_reg)); 5443 match(RegD); 5444 op_cost(0); 5445 format %{ %} 5446 interface(REG_INTER); 5447 %} 5448 5449 operand vRegD_V28() 5450 %{ 5451 constraint(ALLOC_IN_RC(v28_reg)); 5452 match(RegD); 5453 op_cost(0); 5454 format %{ %} 5455 interface(REG_INTER); 5456 %} 5457 5458 operand vRegD_V29() 5459 %{ 5460 constraint(ALLOC_IN_RC(v29_reg)); 5461 match(RegD); 5462 op_cost(0); 5463 format %{ %} 5464 interface(REG_INTER); 5465 %} 5466 5467 operand vRegD_V30() 5468 %{ 5469 constraint(ALLOC_IN_RC(v30_reg)); 5470 match(RegD); 5471 op_cost(0); 5472 format %{ %} 5473 interface(REG_INTER); 5474 %} 5475 5476 operand vRegD_V31() 5477 %{ 5478 constraint(ALLOC_IN_RC(v31_reg)); 5479 match(RegD); 5480 op_cost(0); 5481 format %{ %} 5482 interface(REG_INTER); 5483 %} 5484 5485 operand pReg() 5486 %{ 5487 constraint(ALLOC_IN_RC(pr_reg)); 5488 match(RegVectMask); 5489 match(pRegGov); 5490 op_cost(0); 5491 format %{ %} 5492 interface(REG_INTER); 5493 %} 5494 5495 operand pRegGov() 5496 %{ 5497 constraint(ALLOC_IN_RC(gov_pr)); 5498 match(RegVectMask); 5499 match(pReg); 5500 op_cost(0); 5501 format %{ %} 5502 interface(REG_INTER); 5503 %} 5504 5505 operand pRegGov_P0() 5506 %{ 5507 constraint(ALLOC_IN_RC(p0_reg)); 5508 match(RegVectMask); 5509 op_cost(0); 5510 format %{ %} 5511 interface(REG_INTER); 5512 %} 5513 5514 operand pRegGov_P1() 5515 %{ 5516 constraint(ALLOC_IN_RC(p1_reg)); 5517 match(RegVectMask); 5518 op_cost(0); 5519 format %{ %} 5520 interface(REG_INTER); 5521 %} 5522 5523 // Flags register, used as output of signed compare instructions 5524 5525 // note that on AArch64 we also use this register as the output for 5526 // for floating point compare instructions (CmpF CmpD). this ensures 5527 // that ordered inequality tests use GT, GE, LT or LE none of which 5528 // pass through cases where the result is unordered i.e. one or both 5529 // inputs to the compare is a NaN. this means that the ideal code can 5530 // replace e.g. a GT with an LE and not end up capturing the NaN case 5531 // (where the comparison should always fail). EQ and NE tests are 5532 // always generated in ideal code so that unordered folds into the NE 5533 // case, matching the behaviour of AArch64 NE. 5534 // 5535 // This differs from x86 where the outputs of FP compares use a 5536 // special FP flags registers and where compares based on this 5537 // register are distinguished into ordered inequalities (cmpOpUCF) and 5538 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5539 // to explicitly handle the unordered case in branches. x86 also has 5540 // to include extra CMoveX rules to accept a cmpOpUCF input. 5541 5542 operand rFlagsReg() 5543 %{ 5544 constraint(ALLOC_IN_RC(int_flags)); 5545 match(RegFlags); 5546 5547 op_cost(0); 5548 format %{ "RFLAGS" %} 5549 interface(REG_INTER); 5550 %} 5551 5552 // Flags register, used as output of unsigned compare instructions 5553 operand rFlagsRegU() 5554 %{ 5555 constraint(ALLOC_IN_RC(int_flags)); 5556 match(RegFlags); 5557 5558 op_cost(0); 5559 format %{ "RFLAGSU" %} 5560 interface(REG_INTER); 5561 %} 5562 5563 // Special Registers 5564 5565 // Method Register 5566 operand inline_cache_RegP(iRegP reg) 5567 %{ 5568 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5569 match(reg); 5570 match(iRegPNoSp); 5571 op_cost(0); 5572 format %{ %} 5573 interface(REG_INTER); 5574 %} 5575 5576 // Thread Register 5577 operand thread_RegP(iRegP reg) 5578 %{ 5579 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5580 match(reg); 5581 op_cost(0); 5582 format %{ %} 5583 interface(REG_INTER); 5584 %} 5585 5586 operand lr_RegP(iRegP reg) 5587 %{ 5588 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5589 match(reg); 5590 op_cost(0); 5591 format %{ %} 5592 interface(REG_INTER); 5593 %} 5594 5595 //----------Memory Operands---------------------------------------------------- 5596 5597 operand indirect(iRegP reg) 5598 %{ 5599 constraint(ALLOC_IN_RC(ptr_reg)); 5600 match(reg); 5601 op_cost(0); 5602 format %{ "[$reg]" %} 5603 interface(MEMORY_INTER) %{ 5604 base($reg); 5605 index(0xffffffff); 5606 scale(0x0); 5607 disp(0x0); 5608 %} 5609 %} 5610 5611 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5612 %{ 5613 constraint(ALLOC_IN_RC(ptr_reg)); 5614 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5615 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5616 op_cost(0); 5617 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5618 interface(MEMORY_INTER) %{ 5619 base($reg); 5620 index($ireg); 5621 scale($scale); 5622 disp(0x0); 5623 %} 5624 %} 5625 5626 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5627 %{ 5628 constraint(ALLOC_IN_RC(ptr_reg)); 5629 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5630 match(AddP reg (LShiftL lreg scale)); 5631 op_cost(0); 5632 format %{ "$reg, $lreg lsl($scale)" %} 5633 interface(MEMORY_INTER) %{ 5634 base($reg); 5635 index($lreg); 5636 scale($scale); 5637 disp(0x0); 5638 %} 5639 %} 5640 5641 operand indIndexI2L(iRegP reg, iRegI ireg) 5642 %{ 5643 constraint(ALLOC_IN_RC(ptr_reg)); 5644 match(AddP reg (ConvI2L ireg)); 5645 op_cost(0); 5646 format %{ "$reg, $ireg, 0, I2L" %} 5647 interface(MEMORY_INTER) %{ 5648 base($reg); 5649 index($ireg); 5650 scale(0x0); 5651 disp(0x0); 5652 %} 5653 %} 5654 5655 operand indIndex(iRegP reg, iRegL lreg) 5656 %{ 5657 constraint(ALLOC_IN_RC(ptr_reg)); 5658 match(AddP reg lreg); 5659 op_cost(0); 5660 format %{ "$reg, $lreg" %} 5661 interface(MEMORY_INTER) %{ 5662 base($reg); 5663 index($lreg); 5664 scale(0x0); 5665 disp(0x0); 5666 %} 5667 %} 5668 5669 operand indOffI(iRegP reg, immIOffset off) 5670 %{ 5671 constraint(ALLOC_IN_RC(ptr_reg)); 5672 match(AddP reg off); 5673 op_cost(0); 5674 format %{ "[$reg, $off]" %} 5675 interface(MEMORY_INTER) %{ 5676 base($reg); 5677 index(0xffffffff); 5678 scale(0x0); 5679 disp($off); 5680 %} 5681 %} 5682 5683 operand indOffI1(iRegP reg, immIOffset1 off) 5684 %{ 5685 constraint(ALLOC_IN_RC(ptr_reg)); 5686 match(AddP reg off); 5687 op_cost(0); 5688 format %{ "[$reg, $off]" %} 5689 interface(MEMORY_INTER) %{ 5690 base($reg); 5691 index(0xffffffff); 5692 scale(0x0); 5693 disp($off); 5694 %} 5695 %} 5696 5697 operand indOffI2(iRegP reg, immIOffset2 off) 5698 %{ 5699 constraint(ALLOC_IN_RC(ptr_reg)); 5700 match(AddP reg off); 5701 op_cost(0); 5702 format %{ "[$reg, $off]" %} 5703 interface(MEMORY_INTER) %{ 5704 base($reg); 5705 index(0xffffffff); 5706 scale(0x0); 5707 disp($off); 5708 %} 5709 %} 5710 5711 operand indOffI4(iRegP reg, immIOffset4 off) 5712 %{ 5713 constraint(ALLOC_IN_RC(ptr_reg)); 5714 match(AddP reg off); 5715 op_cost(0); 5716 format %{ "[$reg, $off]" %} 5717 interface(MEMORY_INTER) %{ 5718 base($reg); 5719 index(0xffffffff); 5720 scale(0x0); 5721 disp($off); 5722 %} 5723 %} 5724 5725 operand indOffI8(iRegP reg, immIOffset8 off) 5726 %{ 5727 constraint(ALLOC_IN_RC(ptr_reg)); 5728 match(AddP reg off); 5729 op_cost(0); 5730 format %{ "[$reg, $off]" %} 5731 interface(MEMORY_INTER) %{ 5732 base($reg); 5733 index(0xffffffff); 5734 scale(0x0); 5735 disp($off); 5736 %} 5737 %} 5738 5739 operand indOffI16(iRegP reg, immIOffset16 off) 5740 %{ 5741 constraint(ALLOC_IN_RC(ptr_reg)); 5742 match(AddP reg off); 5743 op_cost(0); 5744 format %{ "[$reg, $off]" %} 5745 interface(MEMORY_INTER) %{ 5746 base($reg); 5747 index(0xffffffff); 5748 scale(0x0); 5749 disp($off); 5750 %} 5751 %} 5752 5753 operand indOffL(iRegP reg, immLoffset off) 5754 %{ 5755 constraint(ALLOC_IN_RC(ptr_reg)); 5756 match(AddP reg off); 5757 op_cost(0); 5758 format %{ "[$reg, $off]" %} 5759 interface(MEMORY_INTER) %{ 5760 base($reg); 5761 index(0xffffffff); 5762 scale(0x0); 5763 disp($off); 5764 %} 5765 %} 5766 5767 operand indOffL1(iRegP reg, immLoffset1 off) 5768 %{ 5769 constraint(ALLOC_IN_RC(ptr_reg)); 5770 match(AddP reg off); 5771 op_cost(0); 5772 format %{ "[$reg, $off]" %} 5773 interface(MEMORY_INTER) %{ 5774 base($reg); 5775 index(0xffffffff); 5776 scale(0x0); 5777 disp($off); 5778 %} 5779 %} 5780 5781 operand indOffL2(iRegP reg, immLoffset2 off) 5782 %{ 5783 constraint(ALLOC_IN_RC(ptr_reg)); 5784 match(AddP reg off); 5785 op_cost(0); 5786 format %{ "[$reg, $off]" %} 5787 interface(MEMORY_INTER) %{ 5788 base($reg); 5789 index(0xffffffff); 5790 scale(0x0); 5791 disp($off); 5792 %} 5793 %} 5794 5795 operand indOffL4(iRegP reg, immLoffset4 off) 5796 %{ 5797 constraint(ALLOC_IN_RC(ptr_reg)); 5798 match(AddP reg off); 5799 op_cost(0); 5800 format %{ "[$reg, $off]" %} 5801 interface(MEMORY_INTER) %{ 5802 base($reg); 5803 index(0xffffffff); 5804 scale(0x0); 5805 disp($off); 5806 %} 5807 %} 5808 5809 operand indOffL8(iRegP reg, immLoffset8 off) 5810 %{ 5811 constraint(ALLOC_IN_RC(ptr_reg)); 5812 match(AddP reg off); 5813 op_cost(0); 5814 format %{ "[$reg, $off]" %} 5815 interface(MEMORY_INTER) %{ 5816 base($reg); 5817 index(0xffffffff); 5818 scale(0x0); 5819 disp($off); 5820 %} 5821 %} 5822 5823 operand indOffL16(iRegP reg, immLoffset16 off) 5824 %{ 5825 constraint(ALLOC_IN_RC(ptr_reg)); 5826 match(AddP reg off); 5827 op_cost(0); 5828 format %{ "[$reg, $off]" %} 5829 interface(MEMORY_INTER) %{ 5830 base($reg); 5831 index(0xffffffff); 5832 scale(0x0); 5833 disp($off); 5834 %} 5835 %} 5836 5837 operand indirectN(iRegN reg) 5838 %{ 5839 predicate(CompressedOops::shift() == 0); 5840 constraint(ALLOC_IN_RC(ptr_reg)); 5841 match(DecodeN reg); 5842 op_cost(0); 5843 format %{ "[$reg]\t# narrow" %} 5844 interface(MEMORY_INTER) %{ 5845 base($reg); 5846 index(0xffffffff); 5847 scale(0x0); 5848 disp(0x0); 5849 %} 5850 %} 5851 5852 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5853 %{ 5854 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5855 constraint(ALLOC_IN_RC(ptr_reg)); 5856 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5857 op_cost(0); 5858 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5859 interface(MEMORY_INTER) %{ 5860 base($reg); 5861 index($ireg); 5862 scale($scale); 5863 disp(0x0); 5864 %} 5865 %} 5866 5867 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5868 %{ 5869 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5870 constraint(ALLOC_IN_RC(ptr_reg)); 5871 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5872 op_cost(0); 5873 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5874 interface(MEMORY_INTER) %{ 5875 base($reg); 5876 index($lreg); 5877 scale($scale); 5878 disp(0x0); 5879 %} 5880 %} 5881 5882 operand indIndexI2LN(iRegN reg, iRegI ireg) 5883 %{ 5884 predicate(CompressedOops::shift() == 0); 5885 constraint(ALLOC_IN_RC(ptr_reg)); 5886 match(AddP (DecodeN reg) (ConvI2L ireg)); 5887 op_cost(0); 5888 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5889 interface(MEMORY_INTER) %{ 5890 base($reg); 5891 index($ireg); 5892 scale(0x0); 5893 disp(0x0); 5894 %} 5895 %} 5896 5897 operand indIndexN(iRegN reg, iRegL lreg) 5898 %{ 5899 predicate(CompressedOops::shift() == 0); 5900 constraint(ALLOC_IN_RC(ptr_reg)); 5901 match(AddP (DecodeN reg) lreg); 5902 op_cost(0); 5903 format %{ "$reg, $lreg\t# narrow" %} 5904 interface(MEMORY_INTER) %{ 5905 base($reg); 5906 index($lreg); 5907 scale(0x0); 5908 disp(0x0); 5909 %} 5910 %} 5911 5912 operand indOffIN(iRegN reg, immIOffset off) 5913 %{ 5914 predicate(CompressedOops::shift() == 0); 5915 constraint(ALLOC_IN_RC(ptr_reg)); 5916 match(AddP (DecodeN reg) off); 5917 op_cost(0); 5918 format %{ "[$reg, $off]\t# narrow" %} 5919 interface(MEMORY_INTER) %{ 5920 base($reg); 5921 index(0xffffffff); 5922 scale(0x0); 5923 disp($off); 5924 %} 5925 %} 5926 5927 operand indOffLN(iRegN reg, immLoffset off) 5928 %{ 5929 predicate(CompressedOops::shift() == 0); 5930 constraint(ALLOC_IN_RC(ptr_reg)); 5931 match(AddP (DecodeN reg) off); 5932 op_cost(0); 5933 format %{ "[$reg, $off]\t# narrow" %} 5934 interface(MEMORY_INTER) %{ 5935 base($reg); 5936 index(0xffffffff); 5937 scale(0x0); 5938 disp($off); 5939 %} 5940 %} 5941 5942 5943 5944 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5945 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5946 %{ 5947 constraint(ALLOC_IN_RC(ptr_reg)); 5948 match(AddP reg off); 5949 op_cost(0); 5950 format %{ "[$reg, $off]" %} 5951 interface(MEMORY_INTER) %{ 5952 base($reg); 5953 index(0xffffffff); 5954 scale(0x0); 5955 disp($off); 5956 %} 5957 %} 5958 5959 //----------Special Memory Operands-------------------------------------------- 5960 // Stack Slot Operand - This operand is used for loading and storing temporary 5961 // values on the stack where a match requires a value to 5962 // flow through memory. 5963 operand stackSlotP(sRegP reg) 5964 %{ 5965 constraint(ALLOC_IN_RC(stack_slots)); 5966 op_cost(100); 5967 // No match rule because this operand is only generated in matching 5968 // match(RegP); 5969 format %{ "[$reg]" %} 5970 interface(MEMORY_INTER) %{ 5971 base(0x1e); // RSP 5972 index(0x0); // No Index 5973 scale(0x0); // No Scale 5974 disp($reg); // Stack Offset 5975 %} 5976 %} 5977 5978 operand stackSlotI(sRegI reg) 5979 %{ 5980 constraint(ALLOC_IN_RC(stack_slots)); 5981 // No match rule because this operand is only generated in matching 5982 // match(RegI); 5983 format %{ "[$reg]" %} 5984 interface(MEMORY_INTER) %{ 5985 base(0x1e); // RSP 5986 index(0x0); // No Index 5987 scale(0x0); // No Scale 5988 disp($reg); // Stack Offset 5989 %} 5990 %} 5991 5992 operand stackSlotF(sRegF reg) 5993 %{ 5994 constraint(ALLOC_IN_RC(stack_slots)); 5995 // No match rule because this operand is only generated in matching 5996 // match(RegF); 5997 format %{ "[$reg]" %} 5998 interface(MEMORY_INTER) %{ 5999 base(0x1e); // RSP 6000 index(0x0); // No Index 6001 scale(0x0); // No Scale 6002 disp($reg); // Stack Offset 6003 %} 6004 %} 6005 6006 operand stackSlotD(sRegD reg) 6007 %{ 6008 constraint(ALLOC_IN_RC(stack_slots)); 6009 // No match rule because this operand is only generated in matching 6010 // match(RegD); 6011 format %{ "[$reg]" %} 6012 interface(MEMORY_INTER) %{ 6013 base(0x1e); // RSP 6014 index(0x0); // No Index 6015 scale(0x0); // No Scale 6016 disp($reg); // Stack Offset 6017 %} 6018 %} 6019 6020 operand stackSlotL(sRegL reg) 6021 %{ 6022 constraint(ALLOC_IN_RC(stack_slots)); 6023 // No match rule because this operand is only generated in matching 6024 // match(RegL); 6025 format %{ "[$reg]" %} 6026 interface(MEMORY_INTER) %{ 6027 base(0x1e); // RSP 6028 index(0x0); // No Index 6029 scale(0x0); // No Scale 6030 disp($reg); // Stack Offset 6031 %} 6032 %} 6033 6034 // Operands for expressing Control Flow 6035 // NOTE: Label is a predefined operand which should not be redefined in 6036 // the AD file. It is generically handled within the ADLC. 6037 6038 //----------Conditional Branch Operands---------------------------------------- 6039 // Comparison Op - This is the operation of the comparison, and is limited to 6040 // the following set of codes: 6041 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 6042 // 6043 // Other attributes of the comparison, such as unsignedness, are specified 6044 // by the comparison instruction that sets a condition code flags register. 6045 // That result is represented by a flags operand whose subtype is appropriate 6046 // to the unsignedness (etc.) of the comparison. 6047 // 6048 // Later, the instruction which matches both the Comparison Op (a Bool) and 6049 // the flags (produced by the Cmp) specifies the coding of the comparison op 6050 // by matching a specific subtype of Bool operand below, such as cmpOpU. 6051 6052 // used for signed integral comparisons and fp comparisons 6053 6054 operand cmpOp() 6055 %{ 6056 match(Bool); 6057 6058 format %{ "" %} 6059 interface(COND_INTER) %{ 6060 equal(0x0, "eq"); 6061 not_equal(0x1, "ne"); 6062 less(0xb, "lt"); 6063 greater_equal(0xa, "ge"); 6064 less_equal(0xd, "le"); 6065 greater(0xc, "gt"); 6066 overflow(0x6, "vs"); 6067 no_overflow(0x7, "vc"); 6068 %} 6069 %} 6070 6071 // used for unsigned integral comparisons 6072 6073 operand cmpOpU() 6074 %{ 6075 match(Bool); 6076 6077 format %{ "" %} 6078 interface(COND_INTER) %{ 6079 equal(0x0, "eq"); 6080 not_equal(0x1, "ne"); 6081 less(0x3, "lo"); 6082 greater_equal(0x2, "hs"); 6083 less_equal(0x9, "ls"); 6084 greater(0x8, "hi"); 6085 overflow(0x6, "vs"); 6086 no_overflow(0x7, "vc"); 6087 %} 6088 %} 6089 6090 // used for certain integral comparisons which can be 6091 // converted to cbxx or tbxx instructions 6092 6093 operand cmpOpEqNe() 6094 %{ 6095 match(Bool); 6096 op_cost(0); 6097 predicate(n->as_Bool()->_test._test == BoolTest::ne 6098 || n->as_Bool()->_test._test == BoolTest::eq); 6099 6100 format %{ "" %} 6101 interface(COND_INTER) %{ 6102 equal(0x0, "eq"); 6103 not_equal(0x1, "ne"); 6104 less(0xb, "lt"); 6105 greater_equal(0xa, "ge"); 6106 less_equal(0xd, "le"); 6107 greater(0xc, "gt"); 6108 overflow(0x6, "vs"); 6109 no_overflow(0x7, "vc"); 6110 %} 6111 %} 6112 6113 // used for certain integral comparisons which can be 6114 // converted to cbxx or tbxx instructions 6115 6116 operand cmpOpLtGe() 6117 %{ 6118 match(Bool); 6119 op_cost(0); 6120 6121 predicate(n->as_Bool()->_test._test == BoolTest::lt 6122 || n->as_Bool()->_test._test == BoolTest::ge); 6123 6124 format %{ "" %} 6125 interface(COND_INTER) %{ 6126 equal(0x0, "eq"); 6127 not_equal(0x1, "ne"); 6128 less(0xb, "lt"); 6129 greater_equal(0xa, "ge"); 6130 less_equal(0xd, "le"); 6131 greater(0xc, "gt"); 6132 overflow(0x6, "vs"); 6133 no_overflow(0x7, "vc"); 6134 %} 6135 %} 6136 6137 // used for certain unsigned integral comparisons which can be 6138 // converted to cbxx or tbxx instructions 6139 6140 operand cmpOpUEqNeLtGe() 6141 %{ 6142 match(Bool); 6143 op_cost(0); 6144 6145 predicate(n->as_Bool()->_test._test == BoolTest::eq 6146 || n->as_Bool()->_test._test == BoolTest::ne 6147 || n->as_Bool()->_test._test == BoolTest::lt 6148 || n->as_Bool()->_test._test == BoolTest::ge); 6149 6150 format %{ "" %} 6151 interface(COND_INTER) %{ 6152 equal(0x0, "eq"); 6153 not_equal(0x1, "ne"); 6154 less(0xb, "lt"); 6155 greater_equal(0xa, "ge"); 6156 less_equal(0xd, "le"); 6157 greater(0xc, "gt"); 6158 overflow(0x6, "vs"); 6159 no_overflow(0x7, "vc"); 6160 %} 6161 %} 6162 6163 // Special operand allowing long args to int ops to be truncated for free 6164 6165 operand iRegL2I(iRegL reg) %{ 6166 6167 op_cost(0); 6168 6169 match(ConvL2I reg); 6170 6171 format %{ "l2i($reg)" %} 6172 6173 interface(REG_INTER) 6174 %} 6175 6176 opclass vmem2(indirect, indIndex, indOffI2, indOffL2); 6177 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 6178 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 6179 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 6180 6181 //----------OPERAND CLASSES---------------------------------------------------- 6182 // Operand Classes are groups of operands that are used as to simplify 6183 // instruction definitions by not requiring the AD writer to specify 6184 // separate instructions for every form of operand when the 6185 // instruction accepts multiple operand types with the same basic 6186 // encoding and format. The classic case of this is memory operands. 6187 6188 // memory is used to define read/write location for load/store 6189 // instruction defs. we can turn a memory op into an Address 6190 6191 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 6192 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6193 6194 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 6195 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6196 6197 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 6198 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6199 6200 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 6201 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6202 6203 // All of the memory operands. For the pipeline description. 6204 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 6205 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 6206 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6207 6208 6209 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 6210 // operations. it allows the src to be either an iRegI or a (ConvL2I 6211 // iRegL). in the latter case the l2i normally planted for a ConvL2I 6212 // can be elided because the 32-bit instruction will just employ the 6213 // lower 32 bits anyway. 6214 // 6215 // n.b. this does not elide all L2I conversions. if the truncated 6216 // value is consumed by more than one operation then the ConvL2I 6217 // cannot be bundled into the consuming nodes so an l2i gets planted 6218 // (actually a movw $dst $src) and the downstream instructions consume 6219 // the result of the l2i as an iRegI input. That's a shame since the 6220 // movw is actually redundant but its not too costly. 6221 6222 opclass iRegIorL2I(iRegI, iRegL2I); 6223 6224 //----------PIPELINE----------------------------------------------------------- 6225 // Rules which define the behavior of the target architectures pipeline. 6226 6227 // For specific pipelines, eg A53, define the stages of that pipeline 6228 //pipe_desc(ISS, EX1, EX2, WR); 6229 #define ISS S0 6230 #define EX1 S1 6231 #define EX2 S2 6232 #define WR S3 6233 6234 // Integer ALU reg operation 6235 pipeline %{ 6236 6237 attributes %{ 6238 // ARM instructions are of fixed length 6239 fixed_size_instructions; // Fixed size instructions TODO does 6240 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 6241 // ARM instructions come in 32-bit word units 6242 instruction_unit_size = 4; // An instruction is 4 bytes long 6243 instruction_fetch_unit_size = 64; // The processor fetches one line 6244 instruction_fetch_units = 1; // of 64 bytes 6245 6246 // List of nop instructions 6247 nops( MachNop ); 6248 %} 6249 6250 // We don't use an actual pipeline model so don't care about resources 6251 // or description. we do use pipeline classes to introduce fixed 6252 // latencies 6253 6254 //----------RESOURCES---------------------------------------------------------- 6255 // Resources are the functional units available to the machine 6256 6257 resources( INS0, INS1, INS01 = INS0 | INS1, 6258 ALU0, ALU1, ALU = ALU0 | ALU1, 6259 MAC, 6260 DIV, 6261 BRANCH, 6262 LDST, 6263 NEON_FP); 6264 6265 //----------PIPELINE DESCRIPTION----------------------------------------------- 6266 // Pipeline Description specifies the stages in the machine's pipeline 6267 6268 // Define the pipeline as a generic 6 stage pipeline 6269 pipe_desc(S0, S1, S2, S3, S4, S5); 6270 6271 //----------PIPELINE CLASSES--------------------------------------------------- 6272 // Pipeline Classes describe the stages in which input and output are 6273 // referenced by the hardware pipeline. 6274 6275 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 6276 %{ 6277 single_instruction; 6278 src1 : S1(read); 6279 src2 : S2(read); 6280 dst : S5(write); 6281 INS01 : ISS; 6282 NEON_FP : S5; 6283 %} 6284 6285 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 6286 %{ 6287 single_instruction; 6288 src1 : S1(read); 6289 src2 : S2(read); 6290 dst : S5(write); 6291 INS01 : ISS; 6292 NEON_FP : S5; 6293 %} 6294 6295 pipe_class fp_uop_s(vRegF dst, vRegF src) 6296 %{ 6297 single_instruction; 6298 src : S1(read); 6299 dst : S5(write); 6300 INS01 : ISS; 6301 NEON_FP : S5; 6302 %} 6303 6304 pipe_class fp_uop_d(vRegD dst, vRegD src) 6305 %{ 6306 single_instruction; 6307 src : S1(read); 6308 dst : S5(write); 6309 INS01 : ISS; 6310 NEON_FP : S5; 6311 %} 6312 6313 pipe_class fp_d2f(vRegF dst, vRegD src) 6314 %{ 6315 single_instruction; 6316 src : S1(read); 6317 dst : S5(write); 6318 INS01 : ISS; 6319 NEON_FP : S5; 6320 %} 6321 6322 pipe_class fp_f2d(vRegD dst, vRegF src) 6323 %{ 6324 single_instruction; 6325 src : S1(read); 6326 dst : S5(write); 6327 INS01 : ISS; 6328 NEON_FP : S5; 6329 %} 6330 6331 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 6332 %{ 6333 single_instruction; 6334 src : S1(read); 6335 dst : S5(write); 6336 INS01 : ISS; 6337 NEON_FP : S5; 6338 %} 6339 6340 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6341 %{ 6342 single_instruction; 6343 src : S1(read); 6344 dst : S5(write); 6345 INS01 : ISS; 6346 NEON_FP : S5; 6347 %} 6348 6349 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6350 %{ 6351 single_instruction; 6352 src : S1(read); 6353 dst : S5(write); 6354 INS01 : ISS; 6355 NEON_FP : S5; 6356 %} 6357 6358 pipe_class fp_l2f(vRegF dst, iRegL src) 6359 %{ 6360 single_instruction; 6361 src : S1(read); 6362 dst : S5(write); 6363 INS01 : ISS; 6364 NEON_FP : S5; 6365 %} 6366 6367 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6368 %{ 6369 single_instruction; 6370 src : S1(read); 6371 dst : S5(write); 6372 INS01 : ISS; 6373 NEON_FP : S5; 6374 %} 6375 6376 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6377 %{ 6378 single_instruction; 6379 src : S1(read); 6380 dst : S5(write); 6381 INS01 : ISS; 6382 NEON_FP : S5; 6383 %} 6384 6385 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6386 %{ 6387 single_instruction; 6388 src : S1(read); 6389 dst : S5(write); 6390 INS01 : ISS; 6391 NEON_FP : S5; 6392 %} 6393 6394 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6395 %{ 6396 single_instruction; 6397 src : S1(read); 6398 dst : S5(write); 6399 INS01 : ISS; 6400 NEON_FP : S5; 6401 %} 6402 6403 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6404 %{ 6405 single_instruction; 6406 src1 : S1(read); 6407 src2 : S2(read); 6408 dst : S5(write); 6409 INS0 : ISS; 6410 NEON_FP : S5; 6411 %} 6412 6413 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6414 %{ 6415 single_instruction; 6416 src1 : S1(read); 6417 src2 : S2(read); 6418 dst : S5(write); 6419 INS0 : ISS; 6420 NEON_FP : S5; 6421 %} 6422 6423 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6424 %{ 6425 single_instruction; 6426 cr : S1(read); 6427 src1 : S1(read); 6428 src2 : S1(read); 6429 dst : S3(write); 6430 INS01 : ISS; 6431 NEON_FP : S3; 6432 %} 6433 6434 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6435 %{ 6436 single_instruction; 6437 cr : S1(read); 6438 src1 : S1(read); 6439 src2 : S1(read); 6440 dst : S3(write); 6441 INS01 : ISS; 6442 NEON_FP : S3; 6443 %} 6444 6445 pipe_class fp_imm_s(vRegF dst) 6446 %{ 6447 single_instruction; 6448 dst : S3(write); 6449 INS01 : ISS; 6450 NEON_FP : S3; 6451 %} 6452 6453 pipe_class fp_imm_d(vRegD dst) 6454 %{ 6455 single_instruction; 6456 dst : S3(write); 6457 INS01 : ISS; 6458 NEON_FP : S3; 6459 %} 6460 6461 pipe_class fp_load_constant_s(vRegF dst) 6462 %{ 6463 single_instruction; 6464 dst : S4(write); 6465 INS01 : ISS; 6466 NEON_FP : S4; 6467 %} 6468 6469 pipe_class fp_load_constant_d(vRegD dst) 6470 %{ 6471 single_instruction; 6472 dst : S4(write); 6473 INS01 : ISS; 6474 NEON_FP : S4; 6475 %} 6476 6477 //------- Integer ALU operations -------------------------- 6478 6479 // Integer ALU reg-reg operation 6480 // Operands needed in EX1, result generated in EX2 6481 // Eg. ADD x0, x1, x2 6482 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6483 %{ 6484 single_instruction; 6485 dst : EX2(write); 6486 src1 : EX1(read); 6487 src2 : EX1(read); 6488 INS01 : ISS; // Dual issue as instruction 0 or 1 6489 ALU : EX2; 6490 %} 6491 6492 // Integer ALU reg-reg operation with constant shift 6493 // Shifted register must be available in LATE_ISS instead of EX1 6494 // Eg. ADD x0, x1, x2, LSL #2 6495 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6496 %{ 6497 single_instruction; 6498 dst : EX2(write); 6499 src1 : EX1(read); 6500 src2 : ISS(read); 6501 INS01 : ISS; 6502 ALU : EX2; 6503 %} 6504 6505 // Integer ALU reg operation with constant shift 6506 // Eg. LSL x0, x1, #shift 6507 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6508 %{ 6509 single_instruction; 6510 dst : EX2(write); 6511 src1 : ISS(read); 6512 INS01 : ISS; 6513 ALU : EX2; 6514 %} 6515 6516 // Integer ALU reg-reg operation with variable shift 6517 // Both operands must be available in LATE_ISS instead of EX1 6518 // Result is available in EX1 instead of EX2 6519 // Eg. LSLV x0, x1, x2 6520 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6521 %{ 6522 single_instruction; 6523 dst : EX1(write); 6524 src1 : ISS(read); 6525 src2 : ISS(read); 6526 INS01 : ISS; 6527 ALU : EX1; 6528 %} 6529 6530 // Integer ALU reg-reg operation with extract 6531 // As for _vshift above, but result generated in EX2 6532 // Eg. EXTR x0, x1, x2, #N 6533 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6534 %{ 6535 single_instruction; 6536 dst : EX2(write); 6537 src1 : ISS(read); 6538 src2 : ISS(read); 6539 INS1 : ISS; // Can only dual issue as Instruction 1 6540 ALU : EX1; 6541 %} 6542 6543 // Integer ALU reg operation 6544 // Eg. NEG x0, x1 6545 pipe_class ialu_reg(iRegI dst, iRegI src) 6546 %{ 6547 single_instruction; 6548 dst : EX2(write); 6549 src : EX1(read); 6550 INS01 : ISS; 6551 ALU : EX2; 6552 %} 6553 6554 // Integer ALU reg mmediate operation 6555 // Eg. ADD x0, x1, #N 6556 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6557 %{ 6558 single_instruction; 6559 dst : EX2(write); 6560 src1 : EX1(read); 6561 INS01 : ISS; 6562 ALU : EX2; 6563 %} 6564 6565 // Integer ALU immediate operation (no source operands) 6566 // Eg. MOV x0, #N 6567 pipe_class ialu_imm(iRegI dst) 6568 %{ 6569 single_instruction; 6570 dst : EX1(write); 6571 INS01 : ISS; 6572 ALU : EX1; 6573 %} 6574 6575 //------- Compare operation ------------------------------- 6576 6577 // Compare reg-reg 6578 // Eg. CMP x0, x1 6579 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6580 %{ 6581 single_instruction; 6582 // fixed_latency(16); 6583 cr : EX2(write); 6584 op1 : EX1(read); 6585 op2 : EX1(read); 6586 INS01 : ISS; 6587 ALU : EX2; 6588 %} 6589 6590 // Compare reg-reg 6591 // Eg. CMP x0, #N 6592 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6593 %{ 6594 single_instruction; 6595 // fixed_latency(16); 6596 cr : EX2(write); 6597 op1 : EX1(read); 6598 INS01 : ISS; 6599 ALU : EX2; 6600 %} 6601 6602 //------- Conditional instructions ------------------------ 6603 6604 // Conditional no operands 6605 // Eg. CSINC x0, zr, zr, <cond> 6606 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6607 %{ 6608 single_instruction; 6609 cr : EX1(read); 6610 dst : EX2(write); 6611 INS01 : ISS; 6612 ALU : EX2; 6613 %} 6614 6615 // Conditional 2 operand 6616 // EG. CSEL X0, X1, X2, <cond> 6617 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6618 %{ 6619 single_instruction; 6620 cr : EX1(read); 6621 src1 : EX1(read); 6622 src2 : EX1(read); 6623 dst : EX2(write); 6624 INS01 : ISS; 6625 ALU : EX2; 6626 %} 6627 6628 // Conditional 2 operand 6629 // EG. CSEL X0, X1, X2, <cond> 6630 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6631 %{ 6632 single_instruction; 6633 cr : EX1(read); 6634 src : EX1(read); 6635 dst : EX2(write); 6636 INS01 : ISS; 6637 ALU : EX2; 6638 %} 6639 6640 //------- Multiply pipeline operations -------------------- 6641 6642 // Multiply reg-reg 6643 // Eg. MUL w0, w1, w2 6644 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6645 %{ 6646 single_instruction; 6647 dst : WR(write); 6648 src1 : ISS(read); 6649 src2 : ISS(read); 6650 INS01 : ISS; 6651 MAC : WR; 6652 %} 6653 6654 // Multiply accumulate 6655 // Eg. MADD w0, w1, w2, w3 6656 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6657 %{ 6658 single_instruction; 6659 dst : WR(write); 6660 src1 : ISS(read); 6661 src2 : ISS(read); 6662 src3 : ISS(read); 6663 INS01 : ISS; 6664 MAC : WR; 6665 %} 6666 6667 // Eg. MUL w0, w1, w2 6668 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6669 %{ 6670 single_instruction; 6671 fixed_latency(3); // Maximum latency for 64 bit mul 6672 dst : WR(write); 6673 src1 : ISS(read); 6674 src2 : ISS(read); 6675 INS01 : ISS; 6676 MAC : WR; 6677 %} 6678 6679 // Multiply accumulate 6680 // Eg. MADD w0, w1, w2, w3 6681 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6682 %{ 6683 single_instruction; 6684 fixed_latency(3); // Maximum latency for 64 bit mul 6685 dst : WR(write); 6686 src1 : ISS(read); 6687 src2 : ISS(read); 6688 src3 : ISS(read); 6689 INS01 : ISS; 6690 MAC : WR; 6691 %} 6692 6693 //------- Divide pipeline operations -------------------- 6694 6695 // Eg. SDIV w0, w1, w2 6696 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6697 %{ 6698 single_instruction; 6699 fixed_latency(8); // Maximum latency for 32 bit divide 6700 dst : WR(write); 6701 src1 : ISS(read); 6702 src2 : ISS(read); 6703 INS0 : ISS; // Can only dual issue as instruction 0 6704 DIV : WR; 6705 %} 6706 6707 // Eg. SDIV x0, x1, x2 6708 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6709 %{ 6710 single_instruction; 6711 fixed_latency(16); // Maximum latency for 64 bit divide 6712 dst : WR(write); 6713 src1 : ISS(read); 6714 src2 : ISS(read); 6715 INS0 : ISS; // Can only dual issue as instruction 0 6716 DIV : WR; 6717 %} 6718 6719 //------- Load pipeline operations ------------------------ 6720 6721 // Load - prefetch 6722 // Eg. PFRM <mem> 6723 pipe_class iload_prefetch(memory mem) 6724 %{ 6725 single_instruction; 6726 mem : ISS(read); 6727 INS01 : ISS; 6728 LDST : WR; 6729 %} 6730 6731 // Load - reg, mem 6732 // Eg. LDR x0, <mem> 6733 pipe_class iload_reg_mem(iRegI dst, memory mem) 6734 %{ 6735 single_instruction; 6736 dst : WR(write); 6737 mem : ISS(read); 6738 INS01 : ISS; 6739 LDST : WR; 6740 %} 6741 6742 // Load - reg, reg 6743 // Eg. LDR x0, [sp, x1] 6744 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6745 %{ 6746 single_instruction; 6747 dst : WR(write); 6748 src : ISS(read); 6749 INS01 : ISS; 6750 LDST : WR; 6751 %} 6752 6753 //------- Store pipeline operations ----------------------- 6754 6755 // Store - zr, mem 6756 // Eg. STR zr, <mem> 6757 pipe_class istore_mem(memory mem) 6758 %{ 6759 single_instruction; 6760 mem : ISS(read); 6761 INS01 : ISS; 6762 LDST : WR; 6763 %} 6764 6765 // Store - reg, mem 6766 // Eg. STR x0, <mem> 6767 pipe_class istore_reg_mem(iRegI src, memory mem) 6768 %{ 6769 single_instruction; 6770 mem : ISS(read); 6771 src : EX2(read); 6772 INS01 : ISS; 6773 LDST : WR; 6774 %} 6775 6776 // Store - reg, reg 6777 // Eg. STR x0, [sp, x1] 6778 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6779 %{ 6780 single_instruction; 6781 dst : ISS(read); 6782 src : EX2(read); 6783 INS01 : ISS; 6784 LDST : WR; 6785 %} 6786 6787 //------- Store pipeline operations ----------------------- 6788 6789 // Branch 6790 pipe_class pipe_branch() 6791 %{ 6792 single_instruction; 6793 INS01 : ISS; 6794 BRANCH : EX1; 6795 %} 6796 6797 // Conditional branch 6798 pipe_class pipe_branch_cond(rFlagsReg cr) 6799 %{ 6800 single_instruction; 6801 cr : EX1(read); 6802 INS01 : ISS; 6803 BRANCH : EX1; 6804 %} 6805 6806 // Compare & Branch 6807 // EG. CBZ/CBNZ 6808 pipe_class pipe_cmp_branch(iRegI op1) 6809 %{ 6810 single_instruction; 6811 op1 : EX1(read); 6812 INS01 : ISS; 6813 BRANCH : EX1; 6814 %} 6815 6816 //------- Synchronisation operations ---------------------- 6817 6818 // Any operation requiring serialization. 6819 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6820 pipe_class pipe_serial() 6821 %{ 6822 single_instruction; 6823 force_serialization; 6824 fixed_latency(16); 6825 INS01 : ISS(2); // Cannot dual issue with any other instruction 6826 LDST : WR; 6827 %} 6828 6829 // Generic big/slow expanded idiom - also serialized 6830 pipe_class pipe_slow() 6831 %{ 6832 instruction_count(10); 6833 multiple_bundles; 6834 force_serialization; 6835 fixed_latency(16); 6836 INS01 : ISS(2); // Cannot dual issue with any other instruction 6837 LDST : WR; 6838 %} 6839 6840 // Empty pipeline class 6841 pipe_class pipe_class_empty() 6842 %{ 6843 single_instruction; 6844 fixed_latency(0); 6845 %} 6846 6847 // Default pipeline class. 6848 pipe_class pipe_class_default() 6849 %{ 6850 single_instruction; 6851 fixed_latency(2); 6852 %} 6853 6854 // Pipeline class for compares. 6855 pipe_class pipe_class_compare() 6856 %{ 6857 single_instruction; 6858 fixed_latency(16); 6859 %} 6860 6861 // Pipeline class for memory operations. 6862 pipe_class pipe_class_memory() 6863 %{ 6864 single_instruction; 6865 fixed_latency(16); 6866 %} 6867 6868 // Pipeline class for call. 6869 pipe_class pipe_class_call() 6870 %{ 6871 single_instruction; 6872 fixed_latency(100); 6873 %} 6874 6875 // Define the class for the Nop node. 6876 define %{ 6877 MachNop = pipe_class_empty; 6878 %} 6879 6880 %} 6881 //----------INSTRUCTIONS------------------------------------------------------- 6882 // 6883 // match -- States which machine-independent subtree may be replaced 6884 // by this instruction. 6885 // ins_cost -- The estimated cost of this instruction is used by instruction 6886 // selection to identify a minimum cost tree of machine 6887 // instructions that matches a tree of machine-independent 6888 // instructions. 6889 // format -- A string providing the disassembly for this instruction. 6890 // The value of an instruction's operand may be inserted 6891 // by referring to it with a '$' prefix. 6892 // opcode -- Three instruction opcodes may be provided. These are referred 6893 // to within an encode class as $primary, $secondary, and $tertiary 6894 // rrspectively. The primary opcode is commonly used to 6895 // indicate the type of machine instruction, while secondary 6896 // and tertiary are often used for prefix options or addressing 6897 // modes. 6898 // ins_encode -- A list of encode classes with parameters. The encode class 6899 // name must have been defined in an 'enc_class' specification 6900 // in the encode section of the architecture description. 6901 6902 // ============================================================================ 6903 // Memory (Load/Store) Instructions 6904 6905 // Load Instructions 6906 6907 // Load Byte (8 bit signed) 6908 instruct loadB(iRegINoSp dst, memory1 mem) 6909 %{ 6910 match(Set dst (LoadB mem)); 6911 predicate(!needs_acquiring_load(n)); 6912 6913 ins_cost(4 * INSN_COST); 6914 format %{ "ldrsbw $dst, $mem\t# byte" %} 6915 6916 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6917 6918 ins_pipe(iload_reg_mem); 6919 %} 6920 6921 // Load Byte (8 bit signed) into long 6922 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6923 %{ 6924 match(Set dst (ConvI2L (LoadB mem))); 6925 predicate(!needs_acquiring_load(n->in(1))); 6926 6927 ins_cost(4 * INSN_COST); 6928 format %{ "ldrsb $dst, $mem\t# byte" %} 6929 6930 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6931 6932 ins_pipe(iload_reg_mem); 6933 %} 6934 6935 // Load Byte (8 bit unsigned) 6936 instruct loadUB(iRegINoSp dst, memory1 mem) 6937 %{ 6938 match(Set dst (LoadUB mem)); 6939 predicate(!needs_acquiring_load(n)); 6940 6941 ins_cost(4 * INSN_COST); 6942 format %{ "ldrbw $dst, $mem\t# byte" %} 6943 6944 ins_encode(aarch64_enc_ldrb(dst, mem)); 6945 6946 ins_pipe(iload_reg_mem); 6947 %} 6948 6949 // Load Byte (8 bit unsigned) into long 6950 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6951 %{ 6952 match(Set dst (ConvI2L (LoadUB mem))); 6953 predicate(!needs_acquiring_load(n->in(1))); 6954 6955 ins_cost(4 * INSN_COST); 6956 format %{ "ldrb $dst, $mem\t# byte" %} 6957 6958 ins_encode(aarch64_enc_ldrb(dst, mem)); 6959 6960 ins_pipe(iload_reg_mem); 6961 %} 6962 6963 // Load Short (16 bit signed) 6964 instruct loadS(iRegINoSp dst, memory2 mem) 6965 %{ 6966 match(Set dst (LoadS mem)); 6967 predicate(!needs_acquiring_load(n)); 6968 6969 ins_cost(4 * INSN_COST); 6970 format %{ "ldrshw $dst, $mem\t# short" %} 6971 6972 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6973 6974 ins_pipe(iload_reg_mem); 6975 %} 6976 6977 // Load Short (16 bit signed) into long 6978 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6979 %{ 6980 match(Set dst (ConvI2L (LoadS mem))); 6981 predicate(!needs_acquiring_load(n->in(1))); 6982 6983 ins_cost(4 * INSN_COST); 6984 format %{ "ldrsh $dst, $mem\t# short" %} 6985 6986 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6987 6988 ins_pipe(iload_reg_mem); 6989 %} 6990 6991 // Load Char (16 bit unsigned) 6992 instruct loadUS(iRegINoSp dst, memory2 mem) 6993 %{ 6994 match(Set dst (LoadUS mem)); 6995 predicate(!needs_acquiring_load(n)); 6996 6997 ins_cost(4 * INSN_COST); 6998 format %{ "ldrh $dst, $mem\t# short" %} 6999 7000 ins_encode(aarch64_enc_ldrh(dst, mem)); 7001 7002 ins_pipe(iload_reg_mem); 7003 %} 7004 7005 // Load Short/Char (16 bit unsigned) into long 7006 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 7007 %{ 7008 match(Set dst (ConvI2L (LoadUS mem))); 7009 predicate(!needs_acquiring_load(n->in(1))); 7010 7011 ins_cost(4 * INSN_COST); 7012 format %{ "ldrh $dst, $mem\t# short" %} 7013 7014 ins_encode(aarch64_enc_ldrh(dst, mem)); 7015 7016 ins_pipe(iload_reg_mem); 7017 %} 7018 7019 // Load Integer (32 bit signed) 7020 instruct loadI(iRegINoSp dst, memory4 mem) 7021 %{ 7022 match(Set dst (LoadI mem)); 7023 predicate(!needs_acquiring_load(n)); 7024 7025 ins_cost(4 * INSN_COST); 7026 format %{ "ldrw $dst, $mem\t# int" %} 7027 7028 ins_encode(aarch64_enc_ldrw(dst, mem)); 7029 7030 ins_pipe(iload_reg_mem); 7031 %} 7032 7033 // Load Integer (32 bit signed) into long 7034 instruct loadI2L(iRegLNoSp dst, memory4 mem) 7035 %{ 7036 match(Set dst (ConvI2L (LoadI mem))); 7037 predicate(!needs_acquiring_load(n->in(1))); 7038 7039 ins_cost(4 * INSN_COST); 7040 format %{ "ldrsw $dst, $mem\t# int" %} 7041 7042 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7043 7044 ins_pipe(iload_reg_mem); 7045 %} 7046 7047 // Load Integer (32 bit unsigned) into long 7048 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7049 %{ 7050 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7051 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7052 7053 ins_cost(4 * INSN_COST); 7054 format %{ "ldrw $dst, $mem\t# int" %} 7055 7056 ins_encode(aarch64_enc_ldrw(dst, mem)); 7057 7058 ins_pipe(iload_reg_mem); 7059 %} 7060 7061 // Load Long (64 bit signed) 7062 instruct loadL(iRegLNoSp dst, memory8 mem) 7063 %{ 7064 match(Set dst (LoadL mem)); 7065 predicate(!needs_acquiring_load(n)); 7066 7067 ins_cost(4 * INSN_COST); 7068 format %{ "ldr $dst, $mem\t# int" %} 7069 7070 ins_encode(aarch64_enc_ldr(dst, mem)); 7071 7072 ins_pipe(iload_reg_mem); 7073 %} 7074 7075 // Load Range 7076 instruct loadRange(iRegINoSp dst, memory4 mem) 7077 %{ 7078 match(Set dst (LoadRange mem)); 7079 7080 ins_cost(4 * INSN_COST); 7081 format %{ "ldrw $dst, $mem\t# range" %} 7082 7083 ins_encode(aarch64_enc_ldrw(dst, mem)); 7084 7085 ins_pipe(iload_reg_mem); 7086 %} 7087 7088 // Load Pointer 7089 instruct loadP(iRegPNoSp dst, memory8 mem) 7090 %{ 7091 match(Set dst (LoadP mem)); 7092 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7093 7094 ins_cost(4 * INSN_COST); 7095 format %{ "ldr $dst, $mem\t# ptr" %} 7096 7097 ins_encode(aarch64_enc_ldr(dst, mem)); 7098 7099 ins_pipe(iload_reg_mem); 7100 %} 7101 7102 // Load Compressed Pointer 7103 instruct loadN(iRegNNoSp dst, memory4 mem) 7104 %{ 7105 match(Set dst (LoadN mem)); 7106 predicate(!needs_acquiring_load(n)); 7107 7108 ins_cost(4 * INSN_COST); 7109 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7110 7111 ins_encode(aarch64_enc_ldrw(dst, mem)); 7112 7113 ins_pipe(iload_reg_mem); 7114 %} 7115 7116 // Load Klass Pointer 7117 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7118 %{ 7119 match(Set dst (LoadKlass mem)); 7120 predicate(!needs_acquiring_load(n)); 7121 7122 ins_cost(4 * INSN_COST); 7123 format %{ "ldr $dst, $mem\t# class" %} 7124 7125 ins_encode(aarch64_enc_ldr(dst, mem)); 7126 7127 ins_pipe(iload_reg_mem); 7128 %} 7129 7130 // Load Narrow Klass Pointer 7131 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7132 %{ 7133 match(Set dst (LoadNKlass mem)); 7134 predicate(!needs_acquiring_load(n)); 7135 7136 ins_cost(4 * INSN_COST); 7137 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7138 7139 ins_encode(aarch64_enc_ldrw(dst, mem)); 7140 7141 ins_pipe(iload_reg_mem); 7142 %} 7143 7144 // Load Float 7145 instruct loadF(vRegF dst, memory4 mem) 7146 %{ 7147 match(Set dst (LoadF mem)); 7148 predicate(!needs_acquiring_load(n)); 7149 7150 ins_cost(4 * INSN_COST); 7151 format %{ "ldrs $dst, $mem\t# float" %} 7152 7153 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7154 7155 ins_pipe(pipe_class_memory); 7156 %} 7157 7158 // Load Double 7159 instruct loadD(vRegD dst, memory8 mem) 7160 %{ 7161 match(Set dst (LoadD mem)); 7162 predicate(!needs_acquiring_load(n)); 7163 7164 ins_cost(4 * INSN_COST); 7165 format %{ "ldrd $dst, $mem\t# double" %} 7166 7167 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7168 7169 ins_pipe(pipe_class_memory); 7170 %} 7171 7172 7173 // Load Int Constant 7174 instruct loadConI(iRegINoSp dst, immI src) 7175 %{ 7176 match(Set dst src); 7177 7178 ins_cost(INSN_COST); 7179 format %{ "mov $dst, $src\t# int" %} 7180 7181 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7182 7183 ins_pipe(ialu_imm); 7184 %} 7185 7186 // Load Long Constant 7187 instruct loadConL(iRegLNoSp dst, immL src) 7188 %{ 7189 match(Set dst src); 7190 7191 ins_cost(INSN_COST); 7192 format %{ "mov $dst, $src\t# long" %} 7193 7194 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7195 7196 ins_pipe(ialu_imm); 7197 %} 7198 7199 // Load Pointer Constant 7200 7201 instruct loadConP(iRegPNoSp dst, immP con) 7202 %{ 7203 match(Set dst con); 7204 7205 ins_cost(INSN_COST * 4); 7206 format %{ 7207 "mov $dst, $con\t# ptr\n\t" 7208 %} 7209 7210 ins_encode(aarch64_enc_mov_p(dst, con)); 7211 7212 ins_pipe(ialu_imm); 7213 %} 7214 7215 // Load Null Pointer Constant 7216 7217 instruct loadConP0(iRegPNoSp dst, immP0 con) 7218 %{ 7219 match(Set dst con); 7220 7221 ins_cost(INSN_COST); 7222 format %{ "mov $dst, $con\t# NULL ptr" %} 7223 7224 ins_encode(aarch64_enc_mov_p0(dst, con)); 7225 7226 ins_pipe(ialu_imm); 7227 %} 7228 7229 // Load Pointer Constant One 7230 7231 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7232 %{ 7233 match(Set dst con); 7234 7235 ins_cost(INSN_COST); 7236 format %{ "mov $dst, $con\t# NULL ptr" %} 7237 7238 ins_encode(aarch64_enc_mov_p1(dst, con)); 7239 7240 ins_pipe(ialu_imm); 7241 %} 7242 7243 // Load Byte Map Base Constant 7244 7245 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7246 %{ 7247 match(Set dst con); 7248 7249 ins_cost(INSN_COST); 7250 format %{ "adr $dst, $con\t# Byte Map Base" %} 7251 7252 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7253 7254 ins_pipe(ialu_imm); 7255 %} 7256 7257 // Load Narrow Pointer Constant 7258 7259 instruct loadConN(iRegNNoSp dst, immN con) 7260 %{ 7261 match(Set dst con); 7262 7263 ins_cost(INSN_COST * 4); 7264 format %{ "mov $dst, $con\t# compressed ptr" %} 7265 7266 ins_encode(aarch64_enc_mov_n(dst, con)); 7267 7268 ins_pipe(ialu_imm); 7269 %} 7270 7271 // Load Narrow Null Pointer Constant 7272 7273 instruct loadConN0(iRegNNoSp dst, immN0 con) 7274 %{ 7275 match(Set dst con); 7276 7277 ins_cost(INSN_COST); 7278 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7279 7280 ins_encode(aarch64_enc_mov_n0(dst, con)); 7281 7282 ins_pipe(ialu_imm); 7283 %} 7284 7285 // Load Narrow Klass Constant 7286 7287 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7288 %{ 7289 match(Set dst con); 7290 7291 ins_cost(INSN_COST); 7292 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7293 7294 ins_encode(aarch64_enc_mov_nk(dst, con)); 7295 7296 ins_pipe(ialu_imm); 7297 %} 7298 7299 // Load Packed Float Constant 7300 7301 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7302 match(Set dst con); 7303 ins_cost(INSN_COST * 4); 7304 format %{ "fmovs $dst, $con"%} 7305 ins_encode %{ 7306 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7307 %} 7308 7309 ins_pipe(fp_imm_s); 7310 %} 7311 7312 // Load Float Constant 7313 7314 instruct loadConF(vRegF dst, immF con) %{ 7315 match(Set dst con); 7316 7317 ins_cost(INSN_COST * 4); 7318 7319 format %{ 7320 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7321 %} 7322 7323 ins_encode %{ 7324 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7325 %} 7326 7327 ins_pipe(fp_load_constant_s); 7328 %} 7329 7330 // Load Packed Double Constant 7331 7332 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7333 match(Set dst con); 7334 ins_cost(INSN_COST); 7335 format %{ "fmovd $dst, $con"%} 7336 ins_encode %{ 7337 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7338 %} 7339 7340 ins_pipe(fp_imm_d); 7341 %} 7342 7343 // Load Double Constant 7344 7345 instruct loadConD(vRegD dst, immD con) %{ 7346 match(Set dst con); 7347 7348 ins_cost(INSN_COST * 5); 7349 format %{ 7350 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7351 %} 7352 7353 ins_encode %{ 7354 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7355 %} 7356 7357 ins_pipe(fp_load_constant_d); 7358 %} 7359 7360 // Store Instructions 7361 7362 // Store CMS card-mark Immediate 7363 instruct storeimmCM0(immI0 zero, memory1 mem) 7364 %{ 7365 match(Set mem (StoreCM mem zero)); 7366 7367 ins_cost(INSN_COST); 7368 format %{ "storestore (elided)\n\t" 7369 "strb zr, $mem\t# byte" %} 7370 7371 ins_encode(aarch64_enc_strb0(mem)); 7372 7373 ins_pipe(istore_mem); 7374 %} 7375 7376 // Store CMS card-mark Immediate with intervening StoreStore 7377 // needed when using CMS with no conditional card marking 7378 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7379 %{ 7380 match(Set mem (StoreCM mem zero)); 7381 7382 ins_cost(INSN_COST * 2); 7383 format %{ "storestore\n\t" 7384 "dmb ishst" 7385 "\n\tstrb zr, $mem\t# byte" %} 7386 7387 ins_encode(aarch64_enc_strb0_ordered(mem)); 7388 7389 ins_pipe(istore_mem); 7390 %} 7391 7392 // Store Byte 7393 instruct storeB(iRegIorL2I src, memory1 mem) 7394 %{ 7395 match(Set mem (StoreB mem src)); 7396 predicate(!needs_releasing_store(n)); 7397 7398 ins_cost(INSN_COST); 7399 format %{ "strb $src, $mem\t# byte" %} 7400 7401 ins_encode(aarch64_enc_strb(src, mem)); 7402 7403 ins_pipe(istore_reg_mem); 7404 %} 7405 7406 7407 instruct storeimmB0(immI0 zero, memory1 mem) 7408 %{ 7409 match(Set mem (StoreB mem zero)); 7410 predicate(!needs_releasing_store(n)); 7411 7412 ins_cost(INSN_COST); 7413 format %{ "strb rscractch2, $mem\t# byte" %} 7414 7415 ins_encode(aarch64_enc_strb0(mem)); 7416 7417 ins_pipe(istore_mem); 7418 %} 7419 7420 // Store Char/Short 7421 instruct storeC(iRegIorL2I src, memory2 mem) 7422 %{ 7423 match(Set mem (StoreC mem src)); 7424 predicate(!needs_releasing_store(n)); 7425 7426 ins_cost(INSN_COST); 7427 format %{ "strh $src, $mem\t# short" %} 7428 7429 ins_encode(aarch64_enc_strh(src, mem)); 7430 7431 ins_pipe(istore_reg_mem); 7432 %} 7433 7434 instruct storeimmC0(immI0 zero, memory2 mem) 7435 %{ 7436 match(Set mem (StoreC mem zero)); 7437 predicate(!needs_releasing_store(n)); 7438 7439 ins_cost(INSN_COST); 7440 format %{ "strh zr, $mem\t# short" %} 7441 7442 ins_encode(aarch64_enc_strh0(mem)); 7443 7444 ins_pipe(istore_mem); 7445 %} 7446 7447 // Store Integer 7448 7449 instruct storeI(iRegIorL2I src, memory4 mem) 7450 %{ 7451 match(Set mem(StoreI mem src)); 7452 predicate(!needs_releasing_store(n)); 7453 7454 ins_cost(INSN_COST); 7455 format %{ "strw $src, $mem\t# int" %} 7456 7457 ins_encode(aarch64_enc_strw(src, mem)); 7458 7459 ins_pipe(istore_reg_mem); 7460 %} 7461 7462 instruct storeimmI0(immI0 zero, memory4 mem) 7463 %{ 7464 match(Set mem(StoreI mem zero)); 7465 predicate(!needs_releasing_store(n)); 7466 7467 ins_cost(INSN_COST); 7468 format %{ "strw zr, $mem\t# int" %} 7469 7470 ins_encode(aarch64_enc_strw0(mem)); 7471 7472 ins_pipe(istore_mem); 7473 %} 7474 7475 // Store Long (64 bit signed) 7476 instruct storeL(iRegL src, memory8 mem) 7477 %{ 7478 match(Set mem (StoreL mem src)); 7479 predicate(!needs_releasing_store(n)); 7480 7481 ins_cost(INSN_COST); 7482 format %{ "str $src, $mem\t# int" %} 7483 7484 ins_encode(aarch64_enc_str(src, mem)); 7485 7486 ins_pipe(istore_reg_mem); 7487 %} 7488 7489 // Store Long (64 bit signed) 7490 instruct storeimmL0(immL0 zero, memory8 mem) 7491 %{ 7492 match(Set mem (StoreL mem zero)); 7493 predicate(!needs_releasing_store(n)); 7494 7495 ins_cost(INSN_COST); 7496 format %{ "str zr, $mem\t# int" %} 7497 7498 ins_encode(aarch64_enc_str0(mem)); 7499 7500 ins_pipe(istore_mem); 7501 %} 7502 7503 // Store Pointer 7504 instruct storeP(iRegP src, memory8 mem) 7505 %{ 7506 match(Set mem (StoreP mem src)); 7507 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7508 7509 ins_cost(INSN_COST); 7510 format %{ "str $src, $mem\t# ptr" %} 7511 7512 ins_encode(aarch64_enc_str(src, mem)); 7513 7514 ins_pipe(istore_reg_mem); 7515 %} 7516 7517 // Store Pointer 7518 instruct storeimmP0(immP0 zero, memory8 mem) 7519 %{ 7520 match(Set mem (StoreP mem zero)); 7521 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7522 7523 ins_cost(INSN_COST); 7524 format %{ "str zr, $mem\t# ptr" %} 7525 7526 ins_encode(aarch64_enc_str0(mem)); 7527 7528 ins_pipe(istore_mem); 7529 %} 7530 7531 // Store Compressed Pointer 7532 instruct storeN(iRegN src, memory4 mem) 7533 %{ 7534 match(Set mem (StoreN mem src)); 7535 predicate(!needs_releasing_store(n)); 7536 7537 ins_cost(INSN_COST); 7538 format %{ "strw $src, $mem\t# compressed ptr" %} 7539 7540 ins_encode(aarch64_enc_strw(src, mem)); 7541 7542 ins_pipe(istore_reg_mem); 7543 %} 7544 7545 instruct storeImmN0(immN0 zero, memory4 mem) 7546 %{ 7547 match(Set mem (StoreN mem zero)); 7548 predicate(!needs_releasing_store(n)); 7549 7550 ins_cost(INSN_COST); 7551 format %{ "strw zr, $mem\t# compressed ptr" %} 7552 7553 ins_encode(aarch64_enc_strw0(mem)); 7554 7555 ins_pipe(istore_mem); 7556 %} 7557 7558 // Store Float 7559 instruct storeF(vRegF src, memory4 mem) 7560 %{ 7561 match(Set mem (StoreF mem src)); 7562 predicate(!needs_releasing_store(n)); 7563 7564 ins_cost(INSN_COST); 7565 format %{ "strs $src, $mem\t# float" %} 7566 7567 ins_encode( aarch64_enc_strs(src, mem) ); 7568 7569 ins_pipe(pipe_class_memory); 7570 %} 7571 7572 // TODO 7573 // implement storeImmF0 and storeFImmPacked 7574 7575 // Store Double 7576 instruct storeD(vRegD src, memory8 mem) 7577 %{ 7578 match(Set mem (StoreD mem src)); 7579 predicate(!needs_releasing_store(n)); 7580 7581 ins_cost(INSN_COST); 7582 format %{ "strd $src, $mem\t# double" %} 7583 7584 ins_encode( aarch64_enc_strd(src, mem) ); 7585 7586 ins_pipe(pipe_class_memory); 7587 %} 7588 7589 // Store Compressed Klass Pointer 7590 instruct storeNKlass(iRegN src, memory4 mem) 7591 %{ 7592 predicate(!needs_releasing_store(n)); 7593 match(Set mem (StoreNKlass mem src)); 7594 7595 ins_cost(INSN_COST); 7596 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7597 7598 ins_encode(aarch64_enc_strw(src, mem)); 7599 7600 ins_pipe(istore_reg_mem); 7601 %} 7602 7603 // TODO 7604 // implement storeImmD0 and storeDImmPacked 7605 7606 // prefetch instructions 7607 // Must be safe to execute with invalid address (cannot fault). 7608 7609 instruct prefetchalloc( memory8 mem ) %{ 7610 match(PrefetchAllocation mem); 7611 7612 ins_cost(INSN_COST); 7613 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7614 7615 ins_encode( aarch64_enc_prefetchw(mem) ); 7616 7617 ins_pipe(iload_prefetch); 7618 %} 7619 7620 // ---------------- volatile loads and stores ---------------- 7621 7622 // Load Byte (8 bit signed) 7623 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7624 %{ 7625 match(Set dst (LoadB mem)); 7626 7627 ins_cost(VOLATILE_REF_COST); 7628 format %{ "ldarsb $dst, $mem\t# byte" %} 7629 7630 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7631 7632 ins_pipe(pipe_serial); 7633 %} 7634 7635 // Load Byte (8 bit signed) into long 7636 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7637 %{ 7638 match(Set dst (ConvI2L (LoadB mem))); 7639 7640 ins_cost(VOLATILE_REF_COST); 7641 format %{ "ldarsb $dst, $mem\t# byte" %} 7642 7643 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7644 7645 ins_pipe(pipe_serial); 7646 %} 7647 7648 // Load Byte (8 bit unsigned) 7649 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7650 %{ 7651 match(Set dst (LoadUB mem)); 7652 7653 ins_cost(VOLATILE_REF_COST); 7654 format %{ "ldarb $dst, $mem\t# byte" %} 7655 7656 ins_encode(aarch64_enc_ldarb(dst, mem)); 7657 7658 ins_pipe(pipe_serial); 7659 %} 7660 7661 // Load Byte (8 bit unsigned) into long 7662 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7663 %{ 7664 match(Set dst (ConvI2L (LoadUB mem))); 7665 7666 ins_cost(VOLATILE_REF_COST); 7667 format %{ "ldarb $dst, $mem\t# byte" %} 7668 7669 ins_encode(aarch64_enc_ldarb(dst, mem)); 7670 7671 ins_pipe(pipe_serial); 7672 %} 7673 7674 // Load Short (16 bit signed) 7675 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7676 %{ 7677 match(Set dst (LoadS mem)); 7678 7679 ins_cost(VOLATILE_REF_COST); 7680 format %{ "ldarshw $dst, $mem\t# short" %} 7681 7682 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7683 7684 ins_pipe(pipe_serial); 7685 %} 7686 7687 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7688 %{ 7689 match(Set dst (LoadUS mem)); 7690 7691 ins_cost(VOLATILE_REF_COST); 7692 format %{ "ldarhw $dst, $mem\t# short" %} 7693 7694 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7695 7696 ins_pipe(pipe_serial); 7697 %} 7698 7699 // Load Short/Char (16 bit unsigned) into long 7700 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7701 %{ 7702 match(Set dst (ConvI2L (LoadUS mem))); 7703 7704 ins_cost(VOLATILE_REF_COST); 7705 format %{ "ldarh $dst, $mem\t# short" %} 7706 7707 ins_encode(aarch64_enc_ldarh(dst, mem)); 7708 7709 ins_pipe(pipe_serial); 7710 %} 7711 7712 // Load Short/Char (16 bit signed) into long 7713 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7714 %{ 7715 match(Set dst (ConvI2L (LoadS mem))); 7716 7717 ins_cost(VOLATILE_REF_COST); 7718 format %{ "ldarh $dst, $mem\t# short" %} 7719 7720 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7721 7722 ins_pipe(pipe_serial); 7723 %} 7724 7725 // Load Integer (32 bit signed) 7726 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7727 %{ 7728 match(Set dst (LoadI mem)); 7729 7730 ins_cost(VOLATILE_REF_COST); 7731 format %{ "ldarw $dst, $mem\t# int" %} 7732 7733 ins_encode(aarch64_enc_ldarw(dst, mem)); 7734 7735 ins_pipe(pipe_serial); 7736 %} 7737 7738 // Load Integer (32 bit unsigned) into long 7739 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7740 %{ 7741 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7742 7743 ins_cost(VOLATILE_REF_COST); 7744 format %{ "ldarw $dst, $mem\t# int" %} 7745 7746 ins_encode(aarch64_enc_ldarw(dst, mem)); 7747 7748 ins_pipe(pipe_serial); 7749 %} 7750 7751 // Load Long (64 bit signed) 7752 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7753 %{ 7754 match(Set dst (LoadL mem)); 7755 7756 ins_cost(VOLATILE_REF_COST); 7757 format %{ "ldar $dst, $mem\t# int" %} 7758 7759 ins_encode(aarch64_enc_ldar(dst, mem)); 7760 7761 ins_pipe(pipe_serial); 7762 %} 7763 7764 // Load Pointer 7765 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7766 %{ 7767 match(Set dst (LoadP mem)); 7768 predicate(n->as_Load()->barrier_data() == 0); 7769 7770 ins_cost(VOLATILE_REF_COST); 7771 format %{ "ldar $dst, $mem\t# ptr" %} 7772 7773 ins_encode(aarch64_enc_ldar(dst, mem)); 7774 7775 ins_pipe(pipe_serial); 7776 %} 7777 7778 // Load Compressed Pointer 7779 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7780 %{ 7781 match(Set dst (LoadN mem)); 7782 7783 ins_cost(VOLATILE_REF_COST); 7784 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7785 7786 ins_encode(aarch64_enc_ldarw(dst, mem)); 7787 7788 ins_pipe(pipe_serial); 7789 %} 7790 7791 // Load Float 7792 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7793 %{ 7794 match(Set dst (LoadF mem)); 7795 7796 ins_cost(VOLATILE_REF_COST); 7797 format %{ "ldars $dst, $mem\t# float" %} 7798 7799 ins_encode( aarch64_enc_fldars(dst, mem) ); 7800 7801 ins_pipe(pipe_serial); 7802 %} 7803 7804 // Load Double 7805 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7806 %{ 7807 match(Set dst (LoadD mem)); 7808 7809 ins_cost(VOLATILE_REF_COST); 7810 format %{ "ldard $dst, $mem\t# double" %} 7811 7812 ins_encode( aarch64_enc_fldard(dst, mem) ); 7813 7814 ins_pipe(pipe_serial); 7815 %} 7816 7817 // Store Byte 7818 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7819 %{ 7820 match(Set mem (StoreB mem src)); 7821 7822 ins_cost(VOLATILE_REF_COST); 7823 format %{ "stlrb $src, $mem\t# byte" %} 7824 7825 ins_encode(aarch64_enc_stlrb(src, mem)); 7826 7827 ins_pipe(pipe_class_memory); 7828 %} 7829 7830 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7831 %{ 7832 match(Set mem (StoreB mem zero)); 7833 7834 ins_cost(VOLATILE_REF_COST); 7835 format %{ "stlrb zr, $mem\t# byte" %} 7836 7837 ins_encode(aarch64_enc_stlrb0(mem)); 7838 7839 ins_pipe(pipe_class_memory); 7840 %} 7841 7842 // Store Char/Short 7843 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7844 %{ 7845 match(Set mem (StoreC mem src)); 7846 7847 ins_cost(VOLATILE_REF_COST); 7848 format %{ "stlrh $src, $mem\t# short" %} 7849 7850 ins_encode(aarch64_enc_stlrh(src, mem)); 7851 7852 ins_pipe(pipe_class_memory); 7853 %} 7854 7855 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7856 %{ 7857 match(Set mem (StoreC mem zero)); 7858 7859 ins_cost(VOLATILE_REF_COST); 7860 format %{ "stlrh zr, $mem\t# short" %} 7861 7862 ins_encode(aarch64_enc_stlrh0(mem)); 7863 7864 ins_pipe(pipe_class_memory); 7865 %} 7866 7867 // Store Integer 7868 7869 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7870 %{ 7871 match(Set mem(StoreI mem src)); 7872 7873 ins_cost(VOLATILE_REF_COST); 7874 format %{ "stlrw $src, $mem\t# int" %} 7875 7876 ins_encode(aarch64_enc_stlrw(src, mem)); 7877 7878 ins_pipe(pipe_class_memory); 7879 %} 7880 7881 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7882 %{ 7883 match(Set mem(StoreI mem zero)); 7884 7885 ins_cost(VOLATILE_REF_COST); 7886 format %{ "stlrw zr, $mem\t# int" %} 7887 7888 ins_encode(aarch64_enc_stlrw0(mem)); 7889 7890 ins_pipe(pipe_class_memory); 7891 %} 7892 7893 // Store Long (64 bit signed) 7894 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7895 %{ 7896 match(Set mem (StoreL mem src)); 7897 7898 ins_cost(VOLATILE_REF_COST); 7899 format %{ "stlr $src, $mem\t# int" %} 7900 7901 ins_encode(aarch64_enc_stlr(src, mem)); 7902 7903 ins_pipe(pipe_class_memory); 7904 %} 7905 7906 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem) 7907 %{ 7908 match(Set mem (StoreL mem zero)); 7909 7910 ins_cost(VOLATILE_REF_COST); 7911 format %{ "stlr zr, $mem\t# int" %} 7912 7913 ins_encode(aarch64_enc_stlr0(mem)); 7914 7915 ins_pipe(pipe_class_memory); 7916 %} 7917 7918 // Store Pointer 7919 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7920 %{ 7921 match(Set mem (StoreP mem src)); 7922 predicate(n->as_Store()->barrier_data() == 0); 7923 7924 ins_cost(VOLATILE_REF_COST); 7925 format %{ "stlr $src, $mem\t# ptr" %} 7926 7927 ins_encode(aarch64_enc_stlr(src, mem)); 7928 7929 ins_pipe(pipe_class_memory); 7930 %} 7931 7932 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem) 7933 %{ 7934 match(Set mem (StoreP mem zero)); 7935 predicate(n->as_Store()->barrier_data() == 0); 7936 7937 ins_cost(VOLATILE_REF_COST); 7938 format %{ "stlr zr, $mem\t# ptr" %} 7939 7940 ins_encode(aarch64_enc_stlr0(mem)); 7941 7942 ins_pipe(pipe_class_memory); 7943 %} 7944 7945 // Store Compressed Pointer 7946 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7947 %{ 7948 match(Set mem (StoreN mem src)); 7949 7950 ins_cost(VOLATILE_REF_COST); 7951 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7952 7953 ins_encode(aarch64_enc_stlrw(src, mem)); 7954 7955 ins_pipe(pipe_class_memory); 7956 %} 7957 7958 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem) 7959 %{ 7960 match(Set mem (StoreN mem zero)); 7961 7962 ins_cost(VOLATILE_REF_COST); 7963 format %{ "stlrw zr, $mem\t# compressed ptr" %} 7964 7965 ins_encode(aarch64_enc_stlrw0(mem)); 7966 7967 ins_pipe(pipe_class_memory); 7968 %} 7969 7970 // Store Float 7971 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7972 %{ 7973 match(Set mem (StoreF mem src)); 7974 7975 ins_cost(VOLATILE_REF_COST); 7976 format %{ "stlrs $src, $mem\t# float" %} 7977 7978 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7979 7980 ins_pipe(pipe_class_memory); 7981 %} 7982 7983 // TODO 7984 // implement storeImmF0 and storeFImmPacked 7985 7986 // Store Double 7987 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7988 %{ 7989 match(Set mem (StoreD mem src)); 7990 7991 ins_cost(VOLATILE_REF_COST); 7992 format %{ "stlrd $src, $mem\t# double" %} 7993 7994 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7995 7996 ins_pipe(pipe_class_memory); 7997 %} 7998 7999 // ---------------- end of volatile loads and stores ---------------- 8000 8001 instruct cacheWB(indirect addr) 8002 %{ 8003 predicate(VM_Version::supports_data_cache_line_flush()); 8004 match(CacheWB addr); 8005 8006 ins_cost(100); 8007 format %{"cache wb $addr" %} 8008 ins_encode %{ 8009 assert($addr->index_position() < 0, "should be"); 8010 assert($addr$$disp == 0, "should be"); 8011 __ cache_wb(Address($addr$$base$$Register, 0)); 8012 %} 8013 ins_pipe(pipe_slow); // XXX 8014 %} 8015 8016 instruct cacheWBPreSync() 8017 %{ 8018 predicate(VM_Version::supports_data_cache_line_flush()); 8019 match(CacheWBPreSync); 8020 8021 ins_cost(100); 8022 format %{"cache wb presync" %} 8023 ins_encode %{ 8024 __ cache_wbsync(true); 8025 %} 8026 ins_pipe(pipe_slow); // XXX 8027 %} 8028 8029 instruct cacheWBPostSync() 8030 %{ 8031 predicate(VM_Version::supports_data_cache_line_flush()); 8032 match(CacheWBPostSync); 8033 8034 ins_cost(100); 8035 format %{"cache wb postsync" %} 8036 ins_encode %{ 8037 __ cache_wbsync(false); 8038 %} 8039 ins_pipe(pipe_slow); // XXX 8040 %} 8041 8042 // ============================================================================ 8043 // BSWAP Instructions 8044 8045 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 8046 match(Set dst (ReverseBytesI src)); 8047 8048 ins_cost(INSN_COST); 8049 format %{ "revw $dst, $src" %} 8050 8051 ins_encode %{ 8052 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 8053 %} 8054 8055 ins_pipe(ialu_reg); 8056 %} 8057 8058 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 8059 match(Set dst (ReverseBytesL src)); 8060 8061 ins_cost(INSN_COST); 8062 format %{ "rev $dst, $src" %} 8063 8064 ins_encode %{ 8065 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 8066 %} 8067 8068 ins_pipe(ialu_reg); 8069 %} 8070 8071 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 8072 match(Set dst (ReverseBytesUS src)); 8073 8074 ins_cost(INSN_COST); 8075 format %{ "rev16w $dst, $src" %} 8076 8077 ins_encode %{ 8078 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8079 %} 8080 8081 ins_pipe(ialu_reg); 8082 %} 8083 8084 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 8085 match(Set dst (ReverseBytesS src)); 8086 8087 ins_cost(INSN_COST); 8088 format %{ "rev16w $dst, $src\n\t" 8089 "sbfmw $dst, $dst, #0, #15" %} 8090 8091 ins_encode %{ 8092 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8093 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 8094 %} 8095 8096 ins_pipe(ialu_reg); 8097 %} 8098 8099 // ============================================================================ 8100 // Zero Count Instructions 8101 8102 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8103 match(Set dst (CountLeadingZerosI src)); 8104 8105 ins_cost(INSN_COST); 8106 format %{ "clzw $dst, $src" %} 8107 ins_encode %{ 8108 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8109 %} 8110 8111 ins_pipe(ialu_reg); 8112 %} 8113 8114 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8115 match(Set dst (CountLeadingZerosL src)); 8116 8117 ins_cost(INSN_COST); 8118 format %{ "clz $dst, $src" %} 8119 ins_encode %{ 8120 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8121 %} 8122 8123 ins_pipe(ialu_reg); 8124 %} 8125 8126 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8127 match(Set dst (CountTrailingZerosI src)); 8128 8129 ins_cost(INSN_COST * 2); 8130 format %{ "rbitw $dst, $src\n\t" 8131 "clzw $dst, $dst" %} 8132 ins_encode %{ 8133 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8134 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8135 %} 8136 8137 ins_pipe(ialu_reg); 8138 %} 8139 8140 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8141 match(Set dst (CountTrailingZerosL src)); 8142 8143 ins_cost(INSN_COST * 2); 8144 format %{ "rbit $dst, $src\n\t" 8145 "clz $dst, $dst" %} 8146 ins_encode %{ 8147 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8148 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8149 %} 8150 8151 ins_pipe(ialu_reg); 8152 %} 8153 8154 //---------- Population Count Instructions ------------------------------------- 8155 // 8156 8157 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8158 match(Set dst (PopCountI src)); 8159 effect(TEMP tmp); 8160 ins_cost(INSN_COST * 13); 8161 8162 format %{ "movw $src, $src\n\t" 8163 "mov $tmp, $src\t# vector (1D)\n\t" 8164 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8165 "addv $tmp, $tmp\t# vector (8B)\n\t" 8166 "mov $dst, $tmp\t# vector (1D)" %} 8167 ins_encode %{ 8168 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8169 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8170 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8171 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8172 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8173 %} 8174 8175 ins_pipe(pipe_class_default); 8176 %} 8177 8178 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8179 match(Set dst (PopCountI (LoadI mem))); 8180 effect(TEMP tmp); 8181 ins_cost(INSN_COST * 13); 8182 8183 format %{ "ldrs $tmp, $mem\n\t" 8184 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8185 "addv $tmp, $tmp\t# vector (8B)\n\t" 8186 "mov $dst, $tmp\t# vector (1D)" %} 8187 ins_encode %{ 8188 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8189 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8190 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8191 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8192 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8193 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8194 %} 8195 8196 ins_pipe(pipe_class_default); 8197 %} 8198 8199 // Note: Long.bitCount(long) returns an int. 8200 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8201 match(Set dst (PopCountL src)); 8202 effect(TEMP tmp); 8203 ins_cost(INSN_COST * 13); 8204 8205 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8206 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8207 "addv $tmp, $tmp\t# vector (8B)\n\t" 8208 "mov $dst, $tmp\t# vector (1D)" %} 8209 ins_encode %{ 8210 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8211 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8212 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8213 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8214 %} 8215 8216 ins_pipe(pipe_class_default); 8217 %} 8218 8219 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8220 match(Set dst (PopCountL (LoadL mem))); 8221 effect(TEMP tmp); 8222 ins_cost(INSN_COST * 13); 8223 8224 format %{ "ldrd $tmp, $mem\n\t" 8225 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8226 "addv $tmp, $tmp\t# vector (8B)\n\t" 8227 "mov $dst, $tmp\t# vector (1D)" %} 8228 ins_encode %{ 8229 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8230 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8231 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8232 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8233 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8234 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8235 %} 8236 8237 ins_pipe(pipe_class_default); 8238 %} 8239 8240 // ============================================================================ 8241 // MemBar Instruction 8242 8243 instruct load_fence() %{ 8244 match(LoadFence); 8245 ins_cost(VOLATILE_REF_COST); 8246 8247 format %{ "load_fence" %} 8248 8249 ins_encode %{ 8250 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8251 %} 8252 ins_pipe(pipe_serial); 8253 %} 8254 8255 instruct unnecessary_membar_acquire() %{ 8256 predicate(unnecessary_acquire(n)); 8257 match(MemBarAcquire); 8258 ins_cost(0); 8259 8260 format %{ "membar_acquire (elided)" %} 8261 8262 ins_encode %{ 8263 __ block_comment("membar_acquire (elided)"); 8264 %} 8265 8266 ins_pipe(pipe_class_empty); 8267 %} 8268 8269 instruct membar_acquire() %{ 8270 match(MemBarAcquire); 8271 ins_cost(VOLATILE_REF_COST); 8272 8273 format %{ "membar_acquire\n\t" 8274 "dmb ish" %} 8275 8276 ins_encode %{ 8277 __ block_comment("membar_acquire"); 8278 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8279 %} 8280 8281 ins_pipe(pipe_serial); 8282 %} 8283 8284 8285 instruct membar_acquire_lock() %{ 8286 match(MemBarAcquireLock); 8287 ins_cost(VOLATILE_REF_COST); 8288 8289 format %{ "membar_acquire_lock (elided)" %} 8290 8291 ins_encode %{ 8292 __ block_comment("membar_acquire_lock (elided)"); 8293 %} 8294 8295 ins_pipe(pipe_serial); 8296 %} 8297 8298 instruct store_fence() %{ 8299 match(StoreFence); 8300 ins_cost(VOLATILE_REF_COST); 8301 8302 format %{ "store_fence" %} 8303 8304 ins_encode %{ 8305 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8306 %} 8307 ins_pipe(pipe_serial); 8308 %} 8309 8310 instruct unnecessary_membar_release() %{ 8311 predicate(unnecessary_release(n)); 8312 match(MemBarRelease); 8313 ins_cost(0); 8314 8315 format %{ "membar_release (elided)" %} 8316 8317 ins_encode %{ 8318 __ block_comment("membar_release (elided)"); 8319 %} 8320 ins_pipe(pipe_serial); 8321 %} 8322 8323 instruct membar_release() %{ 8324 match(MemBarRelease); 8325 ins_cost(VOLATILE_REF_COST); 8326 8327 format %{ "membar_release\n\t" 8328 "dmb ish" %} 8329 8330 ins_encode %{ 8331 __ block_comment("membar_release"); 8332 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8333 %} 8334 ins_pipe(pipe_serial); 8335 %} 8336 8337 instruct membar_storestore() %{ 8338 match(MemBarStoreStore); 8339 match(StoreStoreFence); 8340 ins_cost(VOLATILE_REF_COST); 8341 8342 format %{ "MEMBAR-store-store" %} 8343 8344 ins_encode %{ 8345 __ membar(Assembler::StoreStore); 8346 %} 8347 ins_pipe(pipe_serial); 8348 %} 8349 8350 instruct membar_release_lock() %{ 8351 match(MemBarReleaseLock); 8352 ins_cost(VOLATILE_REF_COST); 8353 8354 format %{ "membar_release_lock (elided)" %} 8355 8356 ins_encode %{ 8357 __ block_comment("membar_release_lock (elided)"); 8358 %} 8359 8360 ins_pipe(pipe_serial); 8361 %} 8362 8363 instruct unnecessary_membar_volatile() %{ 8364 predicate(unnecessary_volatile(n)); 8365 match(MemBarVolatile); 8366 ins_cost(0); 8367 8368 format %{ "membar_volatile (elided)" %} 8369 8370 ins_encode %{ 8371 __ block_comment("membar_volatile (elided)"); 8372 %} 8373 8374 ins_pipe(pipe_serial); 8375 %} 8376 8377 instruct membar_volatile() %{ 8378 match(MemBarVolatile); 8379 ins_cost(VOLATILE_REF_COST*100); 8380 8381 format %{ "membar_volatile\n\t" 8382 "dmb ish"%} 8383 8384 ins_encode %{ 8385 __ block_comment("membar_volatile"); 8386 __ membar(Assembler::StoreLoad); 8387 %} 8388 8389 ins_pipe(pipe_serial); 8390 %} 8391 8392 // ============================================================================ 8393 // Cast/Convert Instructions 8394 8395 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8396 match(Set dst (CastX2P src)); 8397 8398 ins_cost(INSN_COST); 8399 format %{ "mov $dst, $src\t# long -> ptr" %} 8400 8401 ins_encode %{ 8402 if ($dst$$reg != $src$$reg) { 8403 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8404 } 8405 %} 8406 8407 ins_pipe(ialu_reg); 8408 %} 8409 8410 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8411 match(Set dst (CastP2X src)); 8412 8413 ins_cost(INSN_COST); 8414 format %{ "mov $dst, $src\t# ptr -> long" %} 8415 8416 ins_encode %{ 8417 if ($dst$$reg != $src$$reg) { 8418 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8419 } 8420 %} 8421 8422 ins_pipe(ialu_reg); 8423 %} 8424 8425 // Convert oop into int for vectors alignment masking 8426 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8427 match(Set dst (ConvL2I (CastP2X src))); 8428 8429 ins_cost(INSN_COST); 8430 format %{ "movw $dst, $src\t# ptr -> int" %} 8431 ins_encode %{ 8432 __ movw($dst$$Register, $src$$Register); 8433 %} 8434 8435 ins_pipe(ialu_reg); 8436 %} 8437 8438 // Convert compressed oop into int for vectors alignment masking 8439 // in case of 32bit oops (heap < 4Gb). 8440 instruct convN2I(iRegINoSp dst, iRegN src) 8441 %{ 8442 predicate(CompressedOops::shift() == 0); 8443 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8444 8445 ins_cost(INSN_COST); 8446 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8447 ins_encode %{ 8448 __ movw($dst$$Register, $src$$Register); 8449 %} 8450 8451 ins_pipe(ialu_reg); 8452 %} 8453 8454 8455 // Convert oop pointer into compressed form 8456 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8457 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8458 match(Set dst (EncodeP src)); 8459 effect(KILL cr); 8460 ins_cost(INSN_COST * 3); 8461 format %{ "encode_heap_oop $dst, $src" %} 8462 ins_encode %{ 8463 Register s = $src$$Register; 8464 Register d = $dst$$Register; 8465 __ encode_heap_oop(d, s); 8466 %} 8467 ins_pipe(ialu_reg); 8468 %} 8469 8470 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8471 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8472 match(Set dst (EncodeP src)); 8473 ins_cost(INSN_COST * 3); 8474 format %{ "encode_heap_oop_not_null $dst, $src" %} 8475 ins_encode %{ 8476 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8477 %} 8478 ins_pipe(ialu_reg); 8479 %} 8480 8481 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8482 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8483 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8484 match(Set dst (DecodeN src)); 8485 ins_cost(INSN_COST * 3); 8486 format %{ "decode_heap_oop $dst, $src" %} 8487 ins_encode %{ 8488 Register s = $src$$Register; 8489 Register d = $dst$$Register; 8490 __ decode_heap_oop(d, s); 8491 %} 8492 ins_pipe(ialu_reg); 8493 %} 8494 8495 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8496 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8497 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8498 match(Set dst (DecodeN src)); 8499 ins_cost(INSN_COST * 3); 8500 format %{ "decode_heap_oop_not_null $dst, $src" %} 8501 ins_encode %{ 8502 Register s = $src$$Register; 8503 Register d = $dst$$Register; 8504 __ decode_heap_oop_not_null(d, s); 8505 %} 8506 ins_pipe(ialu_reg); 8507 %} 8508 8509 // n.b. AArch64 implementations of encode_klass_not_null and 8510 // decode_klass_not_null do not modify the flags register so, unlike 8511 // Intel, we don't kill CR as a side effect here 8512 8513 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8514 match(Set dst (EncodePKlass src)); 8515 8516 ins_cost(INSN_COST * 3); 8517 format %{ "encode_klass_not_null $dst,$src" %} 8518 8519 ins_encode %{ 8520 Register src_reg = as_Register($src$$reg); 8521 Register dst_reg = as_Register($dst$$reg); 8522 __ encode_klass_not_null(dst_reg, src_reg); 8523 %} 8524 8525 ins_pipe(ialu_reg); 8526 %} 8527 8528 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8529 match(Set dst (DecodeNKlass src)); 8530 8531 ins_cost(INSN_COST * 3); 8532 format %{ "decode_klass_not_null $dst,$src" %} 8533 8534 ins_encode %{ 8535 Register src_reg = as_Register($src$$reg); 8536 Register dst_reg = as_Register($dst$$reg); 8537 if (dst_reg != src_reg) { 8538 __ decode_klass_not_null(dst_reg, src_reg); 8539 } else { 8540 __ decode_klass_not_null(dst_reg); 8541 } 8542 %} 8543 8544 ins_pipe(ialu_reg); 8545 %} 8546 8547 instruct checkCastPP(iRegPNoSp dst) 8548 %{ 8549 match(Set dst (CheckCastPP dst)); 8550 8551 size(0); 8552 format %{ "# checkcastPP of $dst" %} 8553 ins_encode(/* empty encoding */); 8554 ins_pipe(pipe_class_empty); 8555 %} 8556 8557 instruct castPP(iRegPNoSp dst) 8558 %{ 8559 match(Set dst (CastPP dst)); 8560 8561 size(0); 8562 format %{ "# castPP of $dst" %} 8563 ins_encode(/* empty encoding */); 8564 ins_pipe(pipe_class_empty); 8565 %} 8566 8567 instruct castII(iRegI dst) 8568 %{ 8569 match(Set dst (CastII dst)); 8570 8571 size(0); 8572 format %{ "# castII of $dst" %} 8573 ins_encode(/* empty encoding */); 8574 ins_cost(0); 8575 ins_pipe(pipe_class_empty); 8576 %} 8577 8578 instruct castLL(iRegL dst) 8579 %{ 8580 match(Set dst (CastLL dst)); 8581 8582 size(0); 8583 format %{ "# castLL of $dst" %} 8584 ins_encode(/* empty encoding */); 8585 ins_cost(0); 8586 ins_pipe(pipe_class_empty); 8587 %} 8588 8589 instruct castFF(vRegF dst) 8590 %{ 8591 match(Set dst (CastFF dst)); 8592 8593 size(0); 8594 format %{ "# castFF of $dst" %} 8595 ins_encode(/* empty encoding */); 8596 ins_cost(0); 8597 ins_pipe(pipe_class_empty); 8598 %} 8599 8600 instruct castDD(vRegD dst) 8601 %{ 8602 match(Set dst (CastDD dst)); 8603 8604 size(0); 8605 format %{ "# castDD of $dst" %} 8606 ins_encode(/* empty encoding */); 8607 ins_cost(0); 8608 ins_pipe(pipe_class_empty); 8609 %} 8610 8611 instruct castVV(vReg dst) 8612 %{ 8613 match(Set dst (CastVV dst)); 8614 8615 size(0); 8616 format %{ "# castVV of $dst" %} 8617 ins_encode(/* empty encoding */); 8618 ins_cost(0); 8619 ins_pipe(pipe_class_empty); 8620 %} 8621 8622 instruct castVVMask(pRegGov dst) 8623 %{ 8624 match(Set dst (CastVV dst)); 8625 8626 size(0); 8627 format %{ "# castVV of $dst" %} 8628 ins_encode(/* empty encoding */); 8629 ins_cost(0); 8630 ins_pipe(pipe_class_empty); 8631 %} 8632 8633 // ============================================================================ 8634 // Atomic operation instructions 8635 // 8636 8637 // standard CompareAndSwapX when we are using barriers 8638 // these have higher priority than the rules selected by a predicate 8639 8640 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8641 // can't match them 8642 8643 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8644 8645 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8646 ins_cost(2 * VOLATILE_REF_COST); 8647 8648 effect(KILL cr); 8649 8650 format %{ 8651 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8652 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8653 %} 8654 8655 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8656 aarch64_enc_cset_eq(res)); 8657 8658 ins_pipe(pipe_slow); 8659 %} 8660 8661 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8662 8663 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8664 ins_cost(2 * VOLATILE_REF_COST); 8665 8666 effect(KILL cr); 8667 8668 format %{ 8669 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8670 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8671 %} 8672 8673 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8674 aarch64_enc_cset_eq(res)); 8675 8676 ins_pipe(pipe_slow); 8677 %} 8678 8679 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8680 8681 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8682 ins_cost(2 * VOLATILE_REF_COST); 8683 8684 effect(KILL cr); 8685 8686 format %{ 8687 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8688 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8689 %} 8690 8691 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8692 aarch64_enc_cset_eq(res)); 8693 8694 ins_pipe(pipe_slow); 8695 %} 8696 8697 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8698 8699 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8700 ins_cost(2 * VOLATILE_REF_COST); 8701 8702 effect(KILL cr); 8703 8704 format %{ 8705 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8706 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8707 %} 8708 8709 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8710 aarch64_enc_cset_eq(res)); 8711 8712 ins_pipe(pipe_slow); 8713 %} 8714 8715 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8716 8717 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8718 predicate(n->as_LoadStore()->barrier_data() == 0); 8719 ins_cost(2 * VOLATILE_REF_COST); 8720 8721 effect(KILL cr); 8722 8723 format %{ 8724 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8725 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8726 %} 8727 8728 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8729 aarch64_enc_cset_eq(res)); 8730 8731 ins_pipe(pipe_slow); 8732 %} 8733 8734 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8735 8736 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8737 ins_cost(2 * VOLATILE_REF_COST); 8738 8739 effect(KILL cr); 8740 8741 format %{ 8742 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8743 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8744 %} 8745 8746 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8747 aarch64_enc_cset_eq(res)); 8748 8749 ins_pipe(pipe_slow); 8750 %} 8751 8752 // alternative CompareAndSwapX when we are eliding barriers 8753 8754 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8755 8756 predicate(needs_acquiring_load_exclusive(n)); 8757 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8758 ins_cost(VOLATILE_REF_COST); 8759 8760 effect(KILL cr); 8761 8762 format %{ 8763 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8764 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8765 %} 8766 8767 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8768 aarch64_enc_cset_eq(res)); 8769 8770 ins_pipe(pipe_slow); 8771 %} 8772 8773 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8774 8775 predicate(needs_acquiring_load_exclusive(n)); 8776 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8777 ins_cost(VOLATILE_REF_COST); 8778 8779 effect(KILL cr); 8780 8781 format %{ 8782 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8783 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8784 %} 8785 8786 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8787 aarch64_enc_cset_eq(res)); 8788 8789 ins_pipe(pipe_slow); 8790 %} 8791 8792 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8793 8794 predicate(needs_acquiring_load_exclusive(n)); 8795 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8796 ins_cost(VOLATILE_REF_COST); 8797 8798 effect(KILL cr); 8799 8800 format %{ 8801 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8802 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8803 %} 8804 8805 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8806 aarch64_enc_cset_eq(res)); 8807 8808 ins_pipe(pipe_slow); 8809 %} 8810 8811 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8812 8813 predicate(needs_acquiring_load_exclusive(n)); 8814 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8815 ins_cost(VOLATILE_REF_COST); 8816 8817 effect(KILL cr); 8818 8819 format %{ 8820 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8821 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8822 %} 8823 8824 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8825 aarch64_enc_cset_eq(res)); 8826 8827 ins_pipe(pipe_slow); 8828 %} 8829 8830 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8831 8832 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8833 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8834 ins_cost(VOLATILE_REF_COST); 8835 8836 effect(KILL cr); 8837 8838 format %{ 8839 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8840 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8841 %} 8842 8843 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8844 aarch64_enc_cset_eq(res)); 8845 8846 ins_pipe(pipe_slow); 8847 %} 8848 8849 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8850 8851 predicate(needs_acquiring_load_exclusive(n)); 8852 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8853 ins_cost(VOLATILE_REF_COST); 8854 8855 effect(KILL cr); 8856 8857 format %{ 8858 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8859 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8860 %} 8861 8862 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8863 aarch64_enc_cset_eq(res)); 8864 8865 ins_pipe(pipe_slow); 8866 %} 8867 8868 8869 // --------------------------------------------------------------------- 8870 8871 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8872 8873 // Sundry CAS operations. Note that release is always true, 8874 // regardless of the memory ordering of the CAS. This is because we 8875 // need the volatile case to be sequentially consistent but there is 8876 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8877 // can't check the type of memory ordering here, so we always emit a 8878 // STLXR. 8879 8880 // This section is generated from cas.m4 8881 8882 8883 // This pattern is generated automatically from cas.m4. 8884 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8885 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8886 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8887 ins_cost(2 * VOLATILE_REF_COST); 8888 effect(TEMP_DEF res, KILL cr); 8889 format %{ 8890 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8891 %} 8892 ins_encode %{ 8893 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8894 Assembler::byte, /*acquire*/ false, /*release*/ true, 8895 /*weak*/ false, $res$$Register); 8896 __ sxtbw($res$$Register, $res$$Register); 8897 %} 8898 ins_pipe(pipe_slow); 8899 %} 8900 8901 // This pattern is generated automatically from cas.m4. 8902 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8903 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8904 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8905 ins_cost(2 * VOLATILE_REF_COST); 8906 effect(TEMP_DEF res, KILL cr); 8907 format %{ 8908 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8909 %} 8910 ins_encode %{ 8911 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8912 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8913 /*weak*/ false, $res$$Register); 8914 __ sxthw($res$$Register, $res$$Register); 8915 %} 8916 ins_pipe(pipe_slow); 8917 %} 8918 8919 // This pattern is generated automatically from cas.m4. 8920 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8921 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8922 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8923 ins_cost(2 * VOLATILE_REF_COST); 8924 effect(TEMP_DEF res, KILL cr); 8925 format %{ 8926 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8927 %} 8928 ins_encode %{ 8929 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8930 Assembler::word, /*acquire*/ false, /*release*/ true, 8931 /*weak*/ false, $res$$Register); 8932 %} 8933 ins_pipe(pipe_slow); 8934 %} 8935 8936 // This pattern is generated automatically from cas.m4. 8937 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8938 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8939 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8940 ins_cost(2 * VOLATILE_REF_COST); 8941 effect(TEMP_DEF res, KILL cr); 8942 format %{ 8943 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8944 %} 8945 ins_encode %{ 8946 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8947 Assembler::xword, /*acquire*/ false, /*release*/ true, 8948 /*weak*/ false, $res$$Register); 8949 %} 8950 ins_pipe(pipe_slow); 8951 %} 8952 8953 // This pattern is generated automatically from cas.m4. 8954 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8955 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8956 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8957 ins_cost(2 * VOLATILE_REF_COST); 8958 effect(TEMP_DEF res, KILL cr); 8959 format %{ 8960 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8961 %} 8962 ins_encode %{ 8963 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8964 Assembler::word, /*acquire*/ false, /*release*/ true, 8965 /*weak*/ false, $res$$Register); 8966 %} 8967 ins_pipe(pipe_slow); 8968 %} 8969 8970 // This pattern is generated automatically from cas.m4. 8971 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8972 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8973 predicate(n->as_LoadStore()->barrier_data() == 0); 8974 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8975 ins_cost(2 * VOLATILE_REF_COST); 8976 effect(TEMP_DEF res, KILL cr); 8977 format %{ 8978 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8979 %} 8980 ins_encode %{ 8981 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8982 Assembler::xword, /*acquire*/ false, /*release*/ true, 8983 /*weak*/ false, $res$$Register); 8984 %} 8985 ins_pipe(pipe_slow); 8986 %} 8987 8988 // This pattern is generated automatically from cas.m4. 8989 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8990 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8991 predicate(needs_acquiring_load_exclusive(n)); 8992 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8993 ins_cost(VOLATILE_REF_COST); 8994 effect(TEMP_DEF res, KILL cr); 8995 format %{ 8996 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8997 %} 8998 ins_encode %{ 8999 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9000 Assembler::byte, /*acquire*/ true, /*release*/ true, 9001 /*weak*/ false, $res$$Register); 9002 __ sxtbw($res$$Register, $res$$Register); 9003 %} 9004 ins_pipe(pipe_slow); 9005 %} 9006 9007 // This pattern is generated automatically from cas.m4. 9008 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9009 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9010 predicate(needs_acquiring_load_exclusive(n)); 9011 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9012 ins_cost(VOLATILE_REF_COST); 9013 effect(TEMP_DEF res, KILL cr); 9014 format %{ 9015 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9016 %} 9017 ins_encode %{ 9018 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9019 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9020 /*weak*/ false, $res$$Register); 9021 __ sxthw($res$$Register, $res$$Register); 9022 %} 9023 ins_pipe(pipe_slow); 9024 %} 9025 9026 // This pattern is generated automatically from cas.m4. 9027 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9028 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9029 predicate(needs_acquiring_load_exclusive(n)); 9030 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9031 ins_cost(VOLATILE_REF_COST); 9032 effect(TEMP_DEF res, KILL cr); 9033 format %{ 9034 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9035 %} 9036 ins_encode %{ 9037 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9038 Assembler::word, /*acquire*/ true, /*release*/ true, 9039 /*weak*/ false, $res$$Register); 9040 %} 9041 ins_pipe(pipe_slow); 9042 %} 9043 9044 // This pattern is generated automatically from cas.m4. 9045 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9046 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9047 predicate(needs_acquiring_load_exclusive(n)); 9048 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9049 ins_cost(VOLATILE_REF_COST); 9050 effect(TEMP_DEF res, KILL cr); 9051 format %{ 9052 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9053 %} 9054 ins_encode %{ 9055 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9056 Assembler::xword, /*acquire*/ true, /*release*/ true, 9057 /*weak*/ false, $res$$Register); 9058 %} 9059 ins_pipe(pipe_slow); 9060 %} 9061 9062 // This pattern is generated automatically from cas.m4. 9063 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9064 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9065 predicate(needs_acquiring_load_exclusive(n)); 9066 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9067 ins_cost(VOLATILE_REF_COST); 9068 effect(TEMP_DEF res, KILL cr); 9069 format %{ 9070 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9071 %} 9072 ins_encode %{ 9073 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9074 Assembler::word, /*acquire*/ true, /*release*/ true, 9075 /*weak*/ false, $res$$Register); 9076 %} 9077 ins_pipe(pipe_slow); 9078 %} 9079 9080 // This pattern is generated automatically from cas.m4. 9081 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9082 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9083 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9084 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9085 ins_cost(VOLATILE_REF_COST); 9086 effect(TEMP_DEF res, KILL cr); 9087 format %{ 9088 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9089 %} 9090 ins_encode %{ 9091 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9092 Assembler::xword, /*acquire*/ true, /*release*/ true, 9093 /*weak*/ false, $res$$Register); 9094 %} 9095 ins_pipe(pipe_slow); 9096 %} 9097 9098 // This pattern is generated automatically from cas.m4. 9099 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9100 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9101 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9102 ins_cost(2 * VOLATILE_REF_COST); 9103 effect(KILL cr); 9104 format %{ 9105 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9106 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9107 %} 9108 ins_encode %{ 9109 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9110 Assembler::byte, /*acquire*/ false, /*release*/ true, 9111 /*weak*/ true, noreg); 9112 __ csetw($res$$Register, Assembler::EQ); 9113 %} 9114 ins_pipe(pipe_slow); 9115 %} 9116 9117 // This pattern is generated automatically from cas.m4. 9118 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9119 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9120 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9121 ins_cost(2 * VOLATILE_REF_COST); 9122 effect(KILL cr); 9123 format %{ 9124 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9125 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9126 %} 9127 ins_encode %{ 9128 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9129 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9130 /*weak*/ true, noreg); 9131 __ csetw($res$$Register, Assembler::EQ); 9132 %} 9133 ins_pipe(pipe_slow); 9134 %} 9135 9136 // This pattern is generated automatically from cas.m4. 9137 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9138 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9139 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9140 ins_cost(2 * VOLATILE_REF_COST); 9141 effect(KILL cr); 9142 format %{ 9143 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9144 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9145 %} 9146 ins_encode %{ 9147 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9148 Assembler::word, /*acquire*/ false, /*release*/ true, 9149 /*weak*/ true, noreg); 9150 __ csetw($res$$Register, Assembler::EQ); 9151 %} 9152 ins_pipe(pipe_slow); 9153 %} 9154 9155 // This pattern is generated automatically from cas.m4. 9156 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9157 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9158 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9159 ins_cost(2 * VOLATILE_REF_COST); 9160 effect(KILL cr); 9161 format %{ 9162 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9163 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9164 %} 9165 ins_encode %{ 9166 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9167 Assembler::xword, /*acquire*/ false, /*release*/ true, 9168 /*weak*/ true, noreg); 9169 __ csetw($res$$Register, Assembler::EQ); 9170 %} 9171 ins_pipe(pipe_slow); 9172 %} 9173 9174 // This pattern is generated automatically from cas.m4. 9175 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9176 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9177 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9178 ins_cost(2 * VOLATILE_REF_COST); 9179 effect(KILL cr); 9180 format %{ 9181 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9182 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9183 %} 9184 ins_encode %{ 9185 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9186 Assembler::word, /*acquire*/ false, /*release*/ true, 9187 /*weak*/ true, noreg); 9188 __ csetw($res$$Register, Assembler::EQ); 9189 %} 9190 ins_pipe(pipe_slow); 9191 %} 9192 9193 // This pattern is generated automatically from cas.m4. 9194 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9195 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9196 predicate(n->as_LoadStore()->barrier_data() == 0); 9197 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9198 ins_cost(2 * VOLATILE_REF_COST); 9199 effect(KILL cr); 9200 format %{ 9201 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9202 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9203 %} 9204 ins_encode %{ 9205 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9206 Assembler::xword, /*acquire*/ false, /*release*/ true, 9207 /*weak*/ true, noreg); 9208 __ csetw($res$$Register, Assembler::EQ); 9209 %} 9210 ins_pipe(pipe_slow); 9211 %} 9212 9213 // This pattern is generated automatically from cas.m4. 9214 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9215 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9216 predicate(needs_acquiring_load_exclusive(n)); 9217 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9218 ins_cost(VOLATILE_REF_COST); 9219 effect(KILL cr); 9220 format %{ 9221 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9222 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9223 %} 9224 ins_encode %{ 9225 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9226 Assembler::byte, /*acquire*/ true, /*release*/ true, 9227 /*weak*/ true, noreg); 9228 __ csetw($res$$Register, Assembler::EQ); 9229 %} 9230 ins_pipe(pipe_slow); 9231 %} 9232 9233 // This pattern is generated automatically from cas.m4. 9234 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9235 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9236 predicate(needs_acquiring_load_exclusive(n)); 9237 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9238 ins_cost(VOLATILE_REF_COST); 9239 effect(KILL cr); 9240 format %{ 9241 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9242 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9243 %} 9244 ins_encode %{ 9245 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9246 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9247 /*weak*/ true, noreg); 9248 __ csetw($res$$Register, Assembler::EQ); 9249 %} 9250 ins_pipe(pipe_slow); 9251 %} 9252 9253 // This pattern is generated automatically from cas.m4. 9254 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9255 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9256 predicate(needs_acquiring_load_exclusive(n)); 9257 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9258 ins_cost(VOLATILE_REF_COST); 9259 effect(KILL cr); 9260 format %{ 9261 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9262 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9263 %} 9264 ins_encode %{ 9265 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9266 Assembler::word, /*acquire*/ true, /*release*/ true, 9267 /*weak*/ true, noreg); 9268 __ csetw($res$$Register, Assembler::EQ); 9269 %} 9270 ins_pipe(pipe_slow); 9271 %} 9272 9273 // This pattern is generated automatically from cas.m4. 9274 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9275 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9276 predicate(needs_acquiring_load_exclusive(n)); 9277 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9278 ins_cost(VOLATILE_REF_COST); 9279 effect(KILL cr); 9280 format %{ 9281 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9282 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9283 %} 9284 ins_encode %{ 9285 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9286 Assembler::xword, /*acquire*/ true, /*release*/ true, 9287 /*weak*/ true, noreg); 9288 __ csetw($res$$Register, Assembler::EQ); 9289 %} 9290 ins_pipe(pipe_slow); 9291 %} 9292 9293 // This pattern is generated automatically from cas.m4. 9294 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9295 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9296 predicate(needs_acquiring_load_exclusive(n)); 9297 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9298 ins_cost(VOLATILE_REF_COST); 9299 effect(KILL cr); 9300 format %{ 9301 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9302 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9303 %} 9304 ins_encode %{ 9305 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9306 Assembler::word, /*acquire*/ true, /*release*/ true, 9307 /*weak*/ true, noreg); 9308 __ csetw($res$$Register, Assembler::EQ); 9309 %} 9310 ins_pipe(pipe_slow); 9311 %} 9312 9313 // This pattern is generated automatically from cas.m4. 9314 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9315 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9316 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9317 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9318 ins_cost(VOLATILE_REF_COST); 9319 effect(KILL cr); 9320 format %{ 9321 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9322 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9323 %} 9324 ins_encode %{ 9325 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9326 Assembler::xword, /*acquire*/ true, /*release*/ true, 9327 /*weak*/ true, noreg); 9328 __ csetw($res$$Register, Assembler::EQ); 9329 %} 9330 ins_pipe(pipe_slow); 9331 %} 9332 9333 // END This section of the file is automatically generated. Do not edit -------------- 9334 // --------------------------------------------------------------------- 9335 9336 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9337 match(Set prev (GetAndSetI mem newv)); 9338 ins_cost(2 * VOLATILE_REF_COST); 9339 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9340 ins_encode %{ 9341 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9342 %} 9343 ins_pipe(pipe_serial); 9344 %} 9345 9346 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9347 match(Set prev (GetAndSetL mem newv)); 9348 ins_cost(2 * VOLATILE_REF_COST); 9349 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9350 ins_encode %{ 9351 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9352 %} 9353 ins_pipe(pipe_serial); 9354 %} 9355 9356 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9357 match(Set prev (GetAndSetN mem newv)); 9358 ins_cost(2 * VOLATILE_REF_COST); 9359 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9360 ins_encode %{ 9361 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9362 %} 9363 ins_pipe(pipe_serial); 9364 %} 9365 9366 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9367 predicate(n->as_LoadStore()->barrier_data() == 0); 9368 match(Set prev (GetAndSetP mem newv)); 9369 ins_cost(2 * VOLATILE_REF_COST); 9370 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9371 ins_encode %{ 9372 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9373 %} 9374 ins_pipe(pipe_serial); 9375 %} 9376 9377 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9378 predicate(needs_acquiring_load_exclusive(n)); 9379 match(Set prev (GetAndSetI mem newv)); 9380 ins_cost(VOLATILE_REF_COST); 9381 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9382 ins_encode %{ 9383 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9384 %} 9385 ins_pipe(pipe_serial); 9386 %} 9387 9388 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9389 predicate(needs_acquiring_load_exclusive(n)); 9390 match(Set prev (GetAndSetL mem newv)); 9391 ins_cost(VOLATILE_REF_COST); 9392 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9393 ins_encode %{ 9394 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9395 %} 9396 ins_pipe(pipe_serial); 9397 %} 9398 9399 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9400 predicate(needs_acquiring_load_exclusive(n)); 9401 match(Set prev (GetAndSetN mem newv)); 9402 ins_cost(VOLATILE_REF_COST); 9403 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9404 ins_encode %{ 9405 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9406 %} 9407 ins_pipe(pipe_serial); 9408 %} 9409 9410 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9411 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9412 match(Set prev (GetAndSetP mem newv)); 9413 ins_cost(VOLATILE_REF_COST); 9414 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9415 ins_encode %{ 9416 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9417 %} 9418 ins_pipe(pipe_serial); 9419 %} 9420 9421 9422 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9423 match(Set newval (GetAndAddL mem incr)); 9424 ins_cost(2 * VOLATILE_REF_COST + 1); 9425 format %{ "get_and_addL $newval, [$mem], $incr" %} 9426 ins_encode %{ 9427 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9428 %} 9429 ins_pipe(pipe_serial); 9430 %} 9431 9432 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9433 predicate(n->as_LoadStore()->result_not_used()); 9434 match(Set dummy (GetAndAddL mem incr)); 9435 ins_cost(2 * VOLATILE_REF_COST); 9436 format %{ "get_and_addL [$mem], $incr" %} 9437 ins_encode %{ 9438 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9439 %} 9440 ins_pipe(pipe_serial); 9441 %} 9442 9443 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9444 match(Set newval (GetAndAddL mem incr)); 9445 ins_cost(2 * VOLATILE_REF_COST + 1); 9446 format %{ "get_and_addL $newval, [$mem], $incr" %} 9447 ins_encode %{ 9448 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9449 %} 9450 ins_pipe(pipe_serial); 9451 %} 9452 9453 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9454 predicate(n->as_LoadStore()->result_not_used()); 9455 match(Set dummy (GetAndAddL mem incr)); 9456 ins_cost(2 * VOLATILE_REF_COST); 9457 format %{ "get_and_addL [$mem], $incr" %} 9458 ins_encode %{ 9459 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9460 %} 9461 ins_pipe(pipe_serial); 9462 %} 9463 9464 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9465 match(Set newval (GetAndAddI mem incr)); 9466 ins_cost(2 * VOLATILE_REF_COST + 1); 9467 format %{ "get_and_addI $newval, [$mem], $incr" %} 9468 ins_encode %{ 9469 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9470 %} 9471 ins_pipe(pipe_serial); 9472 %} 9473 9474 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9475 predicate(n->as_LoadStore()->result_not_used()); 9476 match(Set dummy (GetAndAddI mem incr)); 9477 ins_cost(2 * VOLATILE_REF_COST); 9478 format %{ "get_and_addI [$mem], $incr" %} 9479 ins_encode %{ 9480 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9481 %} 9482 ins_pipe(pipe_serial); 9483 %} 9484 9485 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9486 match(Set newval (GetAndAddI mem incr)); 9487 ins_cost(2 * VOLATILE_REF_COST + 1); 9488 format %{ "get_and_addI $newval, [$mem], $incr" %} 9489 ins_encode %{ 9490 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9491 %} 9492 ins_pipe(pipe_serial); 9493 %} 9494 9495 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9496 predicate(n->as_LoadStore()->result_not_used()); 9497 match(Set dummy (GetAndAddI mem incr)); 9498 ins_cost(2 * VOLATILE_REF_COST); 9499 format %{ "get_and_addI [$mem], $incr" %} 9500 ins_encode %{ 9501 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9502 %} 9503 ins_pipe(pipe_serial); 9504 %} 9505 9506 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9507 predicate(needs_acquiring_load_exclusive(n)); 9508 match(Set newval (GetAndAddL mem incr)); 9509 ins_cost(VOLATILE_REF_COST + 1); 9510 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9511 ins_encode %{ 9512 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9513 %} 9514 ins_pipe(pipe_serial); 9515 %} 9516 9517 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9518 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9519 match(Set dummy (GetAndAddL mem incr)); 9520 ins_cost(VOLATILE_REF_COST); 9521 format %{ "get_and_addL_acq [$mem], $incr" %} 9522 ins_encode %{ 9523 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9524 %} 9525 ins_pipe(pipe_serial); 9526 %} 9527 9528 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9529 predicate(needs_acquiring_load_exclusive(n)); 9530 match(Set newval (GetAndAddL mem incr)); 9531 ins_cost(VOLATILE_REF_COST + 1); 9532 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9533 ins_encode %{ 9534 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9535 %} 9536 ins_pipe(pipe_serial); 9537 %} 9538 9539 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9540 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9541 match(Set dummy (GetAndAddL mem incr)); 9542 ins_cost(VOLATILE_REF_COST); 9543 format %{ "get_and_addL_acq [$mem], $incr" %} 9544 ins_encode %{ 9545 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9546 %} 9547 ins_pipe(pipe_serial); 9548 %} 9549 9550 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9551 predicate(needs_acquiring_load_exclusive(n)); 9552 match(Set newval (GetAndAddI mem incr)); 9553 ins_cost(VOLATILE_REF_COST + 1); 9554 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9555 ins_encode %{ 9556 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9557 %} 9558 ins_pipe(pipe_serial); 9559 %} 9560 9561 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9562 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9563 match(Set dummy (GetAndAddI mem incr)); 9564 ins_cost(VOLATILE_REF_COST); 9565 format %{ "get_and_addI_acq [$mem], $incr" %} 9566 ins_encode %{ 9567 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9568 %} 9569 ins_pipe(pipe_serial); 9570 %} 9571 9572 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9573 predicate(needs_acquiring_load_exclusive(n)); 9574 match(Set newval (GetAndAddI mem incr)); 9575 ins_cost(VOLATILE_REF_COST + 1); 9576 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9577 ins_encode %{ 9578 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9579 %} 9580 ins_pipe(pipe_serial); 9581 %} 9582 9583 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9584 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9585 match(Set dummy (GetAndAddI mem incr)); 9586 ins_cost(VOLATILE_REF_COST); 9587 format %{ "get_and_addI_acq [$mem], $incr" %} 9588 ins_encode %{ 9589 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9590 %} 9591 ins_pipe(pipe_serial); 9592 %} 9593 9594 // Manifest a CmpU result in an integer register. 9595 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9596 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags) 9597 %{ 9598 match(Set dst (CmpU3 src1 src2)); 9599 effect(KILL flags); 9600 9601 ins_cost(INSN_COST * 3); 9602 format %{ 9603 "cmpw $src1, $src2\n\t" 9604 "csetw $dst, ne\n\t" 9605 "cnegw $dst, lo\t# CmpU3(reg)" 9606 %} 9607 ins_encode %{ 9608 __ cmpw($src1$$Register, $src2$$Register); 9609 __ csetw($dst$$Register, Assembler::NE); 9610 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9611 %} 9612 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags) 9617 %{ 9618 match(Set dst (CmpU3 src1 src2)); 9619 effect(KILL flags); 9620 9621 ins_cost(INSN_COST * 3); 9622 format %{ 9623 "subsw zr, $src1, $src2\n\t" 9624 "csetw $dst, ne\n\t" 9625 "cnegw $dst, lo\t# CmpU3(imm)" 9626 %} 9627 ins_encode %{ 9628 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant); 9629 __ csetw($dst$$Register, Assembler::NE); 9630 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9631 %} 9632 9633 ins_pipe(pipe_class_default); 9634 %} 9635 9636 // Manifest a CmpUL result in an integer register. 9637 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9638 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9639 %{ 9640 match(Set dst (CmpUL3 src1 src2)); 9641 effect(KILL flags); 9642 9643 ins_cost(INSN_COST * 3); 9644 format %{ 9645 "cmp $src1, $src2\n\t" 9646 "csetw $dst, ne\n\t" 9647 "cnegw $dst, lo\t# CmpUL3(reg)" 9648 %} 9649 ins_encode %{ 9650 __ cmp($src1$$Register, $src2$$Register); 9651 __ csetw($dst$$Register, Assembler::NE); 9652 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9653 %} 9654 9655 ins_pipe(pipe_class_default); 9656 %} 9657 9658 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9659 %{ 9660 match(Set dst (CmpUL3 src1 src2)); 9661 effect(KILL flags); 9662 9663 ins_cost(INSN_COST * 3); 9664 format %{ 9665 "subs zr, $src1, $src2\n\t" 9666 "csetw $dst, ne\n\t" 9667 "cnegw $dst, lo\t# CmpUL3(imm)" 9668 %} 9669 ins_encode %{ 9670 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9671 __ csetw($dst$$Register, Assembler::NE); 9672 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9673 %} 9674 9675 ins_pipe(pipe_class_default); 9676 %} 9677 9678 // Manifest a CmpL result in an integer register. 9679 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9680 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9681 %{ 9682 match(Set dst (CmpL3 src1 src2)); 9683 effect(KILL flags); 9684 9685 ins_cost(INSN_COST * 3); 9686 format %{ 9687 "cmp $src1, $src2\n\t" 9688 "csetw $dst, ne\n\t" 9689 "cnegw $dst, lt\t# CmpL3(reg)" 9690 %} 9691 ins_encode %{ 9692 __ cmp($src1$$Register, $src2$$Register); 9693 __ csetw($dst$$Register, Assembler::NE); 9694 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9695 %} 9696 9697 ins_pipe(pipe_class_default); 9698 %} 9699 9700 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9701 %{ 9702 match(Set dst (CmpL3 src1 src2)); 9703 effect(KILL flags); 9704 9705 ins_cost(INSN_COST * 3); 9706 format %{ 9707 "subs zr, $src1, $src2\n\t" 9708 "csetw $dst, ne\n\t" 9709 "cnegw $dst, lt\t# CmpL3(imm)" 9710 %} 9711 ins_encode %{ 9712 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9713 __ csetw($dst$$Register, Assembler::NE); 9714 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9715 %} 9716 9717 ins_pipe(pipe_class_default); 9718 %} 9719 9720 // ============================================================================ 9721 // Conditional Move Instructions 9722 9723 // n.b. we have identical rules for both a signed compare op (cmpOp) 9724 // and an unsigned compare op (cmpOpU). it would be nice if we could 9725 // define an op class which merged both inputs and use it to type the 9726 // argument to a single rule. unfortunatelyt his fails because the 9727 // opclass does not live up to the COND_INTER interface of its 9728 // component operands. When the generic code tries to negate the 9729 // operand it ends up running the generci Machoper::negate method 9730 // which throws a ShouldNotHappen. So, we have to provide two flavours 9731 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9732 9733 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9734 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9735 9736 ins_cost(INSN_COST * 2); 9737 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9738 9739 ins_encode %{ 9740 __ cselw(as_Register($dst$$reg), 9741 as_Register($src2$$reg), 9742 as_Register($src1$$reg), 9743 (Assembler::Condition)$cmp$$cmpcode); 9744 %} 9745 9746 ins_pipe(icond_reg_reg); 9747 %} 9748 9749 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9750 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9751 9752 ins_cost(INSN_COST * 2); 9753 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9754 9755 ins_encode %{ 9756 __ cselw(as_Register($dst$$reg), 9757 as_Register($src2$$reg), 9758 as_Register($src1$$reg), 9759 (Assembler::Condition)$cmp$$cmpcode); 9760 %} 9761 9762 ins_pipe(icond_reg_reg); 9763 %} 9764 9765 // special cases where one arg is zero 9766 9767 // n.b. this is selected in preference to the rule above because it 9768 // avoids loading constant 0 into a source register 9769 9770 // TODO 9771 // we ought only to be able to cull one of these variants as the ideal 9772 // transforms ought always to order the zero consistently (to left/right?) 9773 9774 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9775 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9776 9777 ins_cost(INSN_COST * 2); 9778 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9779 9780 ins_encode %{ 9781 __ cselw(as_Register($dst$$reg), 9782 as_Register($src$$reg), 9783 zr, 9784 (Assembler::Condition)$cmp$$cmpcode); 9785 %} 9786 9787 ins_pipe(icond_reg); 9788 %} 9789 9790 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9791 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9792 9793 ins_cost(INSN_COST * 2); 9794 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9795 9796 ins_encode %{ 9797 __ cselw(as_Register($dst$$reg), 9798 as_Register($src$$reg), 9799 zr, 9800 (Assembler::Condition)$cmp$$cmpcode); 9801 %} 9802 9803 ins_pipe(icond_reg); 9804 %} 9805 9806 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9807 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9808 9809 ins_cost(INSN_COST * 2); 9810 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9811 9812 ins_encode %{ 9813 __ cselw(as_Register($dst$$reg), 9814 zr, 9815 as_Register($src$$reg), 9816 (Assembler::Condition)$cmp$$cmpcode); 9817 %} 9818 9819 ins_pipe(icond_reg); 9820 %} 9821 9822 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9823 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9824 9825 ins_cost(INSN_COST * 2); 9826 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9827 9828 ins_encode %{ 9829 __ cselw(as_Register($dst$$reg), 9830 zr, 9831 as_Register($src$$reg), 9832 (Assembler::Condition)$cmp$$cmpcode); 9833 %} 9834 9835 ins_pipe(icond_reg); 9836 %} 9837 9838 // special case for creating a boolean 0 or 1 9839 9840 // n.b. this is selected in preference to the rule above because it 9841 // avoids loading constants 0 and 1 into a source register 9842 9843 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9844 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9845 9846 ins_cost(INSN_COST * 2); 9847 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9848 9849 ins_encode %{ 9850 // equivalently 9851 // cset(as_Register($dst$$reg), 9852 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9853 __ csincw(as_Register($dst$$reg), 9854 zr, 9855 zr, 9856 (Assembler::Condition)$cmp$$cmpcode); 9857 %} 9858 9859 ins_pipe(icond_none); 9860 %} 9861 9862 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9863 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9864 9865 ins_cost(INSN_COST * 2); 9866 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9867 9868 ins_encode %{ 9869 // equivalently 9870 // cset(as_Register($dst$$reg), 9871 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9872 __ csincw(as_Register($dst$$reg), 9873 zr, 9874 zr, 9875 (Assembler::Condition)$cmp$$cmpcode); 9876 %} 9877 9878 ins_pipe(icond_none); 9879 %} 9880 9881 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9882 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9883 9884 ins_cost(INSN_COST * 2); 9885 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9886 9887 ins_encode %{ 9888 __ csel(as_Register($dst$$reg), 9889 as_Register($src2$$reg), 9890 as_Register($src1$$reg), 9891 (Assembler::Condition)$cmp$$cmpcode); 9892 %} 9893 9894 ins_pipe(icond_reg_reg); 9895 %} 9896 9897 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9898 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9899 9900 ins_cost(INSN_COST * 2); 9901 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9902 9903 ins_encode %{ 9904 __ csel(as_Register($dst$$reg), 9905 as_Register($src2$$reg), 9906 as_Register($src1$$reg), 9907 (Assembler::Condition)$cmp$$cmpcode); 9908 %} 9909 9910 ins_pipe(icond_reg_reg); 9911 %} 9912 9913 // special cases where one arg is zero 9914 9915 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9916 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9917 9918 ins_cost(INSN_COST * 2); 9919 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9920 9921 ins_encode %{ 9922 __ csel(as_Register($dst$$reg), 9923 zr, 9924 as_Register($src$$reg), 9925 (Assembler::Condition)$cmp$$cmpcode); 9926 %} 9927 9928 ins_pipe(icond_reg); 9929 %} 9930 9931 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9932 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9933 9934 ins_cost(INSN_COST * 2); 9935 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9936 9937 ins_encode %{ 9938 __ csel(as_Register($dst$$reg), 9939 zr, 9940 as_Register($src$$reg), 9941 (Assembler::Condition)$cmp$$cmpcode); 9942 %} 9943 9944 ins_pipe(icond_reg); 9945 %} 9946 9947 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9948 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9949 9950 ins_cost(INSN_COST * 2); 9951 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9952 9953 ins_encode %{ 9954 __ csel(as_Register($dst$$reg), 9955 as_Register($src$$reg), 9956 zr, 9957 (Assembler::Condition)$cmp$$cmpcode); 9958 %} 9959 9960 ins_pipe(icond_reg); 9961 %} 9962 9963 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9964 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9965 9966 ins_cost(INSN_COST * 2); 9967 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9968 9969 ins_encode %{ 9970 __ csel(as_Register($dst$$reg), 9971 as_Register($src$$reg), 9972 zr, 9973 (Assembler::Condition)$cmp$$cmpcode); 9974 %} 9975 9976 ins_pipe(icond_reg); 9977 %} 9978 9979 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9980 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9981 9982 ins_cost(INSN_COST * 2); 9983 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9984 9985 ins_encode %{ 9986 __ csel(as_Register($dst$$reg), 9987 as_Register($src2$$reg), 9988 as_Register($src1$$reg), 9989 (Assembler::Condition)$cmp$$cmpcode); 9990 %} 9991 9992 ins_pipe(icond_reg_reg); 9993 %} 9994 9995 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9996 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9997 9998 ins_cost(INSN_COST * 2); 9999 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 10000 10001 ins_encode %{ 10002 __ csel(as_Register($dst$$reg), 10003 as_Register($src2$$reg), 10004 as_Register($src1$$reg), 10005 (Assembler::Condition)$cmp$$cmpcode); 10006 %} 10007 10008 ins_pipe(icond_reg_reg); 10009 %} 10010 10011 // special cases where one arg is zero 10012 10013 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10014 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10015 10016 ins_cost(INSN_COST * 2); 10017 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 10018 10019 ins_encode %{ 10020 __ csel(as_Register($dst$$reg), 10021 zr, 10022 as_Register($src$$reg), 10023 (Assembler::Condition)$cmp$$cmpcode); 10024 %} 10025 10026 ins_pipe(icond_reg); 10027 %} 10028 10029 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10030 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10031 10032 ins_cost(INSN_COST * 2); 10033 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 10034 10035 ins_encode %{ 10036 __ csel(as_Register($dst$$reg), 10037 zr, 10038 as_Register($src$$reg), 10039 (Assembler::Condition)$cmp$$cmpcode); 10040 %} 10041 10042 ins_pipe(icond_reg); 10043 %} 10044 10045 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10046 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10047 10048 ins_cost(INSN_COST * 2); 10049 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 10050 10051 ins_encode %{ 10052 __ csel(as_Register($dst$$reg), 10053 as_Register($src$$reg), 10054 zr, 10055 (Assembler::Condition)$cmp$$cmpcode); 10056 %} 10057 10058 ins_pipe(icond_reg); 10059 %} 10060 10061 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10062 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10063 10064 ins_cost(INSN_COST * 2); 10065 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 10066 10067 ins_encode %{ 10068 __ csel(as_Register($dst$$reg), 10069 as_Register($src$$reg), 10070 zr, 10071 (Assembler::Condition)$cmp$$cmpcode); 10072 %} 10073 10074 ins_pipe(icond_reg); 10075 %} 10076 10077 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10078 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10079 10080 ins_cost(INSN_COST * 2); 10081 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10082 10083 ins_encode %{ 10084 __ cselw(as_Register($dst$$reg), 10085 as_Register($src2$$reg), 10086 as_Register($src1$$reg), 10087 (Assembler::Condition)$cmp$$cmpcode); 10088 %} 10089 10090 ins_pipe(icond_reg_reg); 10091 %} 10092 10093 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10094 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10095 10096 ins_cost(INSN_COST * 2); 10097 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10098 10099 ins_encode %{ 10100 __ cselw(as_Register($dst$$reg), 10101 as_Register($src2$$reg), 10102 as_Register($src1$$reg), 10103 (Assembler::Condition)$cmp$$cmpcode); 10104 %} 10105 10106 ins_pipe(icond_reg_reg); 10107 %} 10108 10109 // special cases where one arg is zero 10110 10111 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10112 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10113 10114 ins_cost(INSN_COST * 2); 10115 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 10116 10117 ins_encode %{ 10118 __ cselw(as_Register($dst$$reg), 10119 zr, 10120 as_Register($src$$reg), 10121 (Assembler::Condition)$cmp$$cmpcode); 10122 %} 10123 10124 ins_pipe(icond_reg); 10125 %} 10126 10127 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10128 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10129 10130 ins_cost(INSN_COST * 2); 10131 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 10132 10133 ins_encode %{ 10134 __ cselw(as_Register($dst$$reg), 10135 zr, 10136 as_Register($src$$reg), 10137 (Assembler::Condition)$cmp$$cmpcode); 10138 %} 10139 10140 ins_pipe(icond_reg); 10141 %} 10142 10143 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10144 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10145 10146 ins_cost(INSN_COST * 2); 10147 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 10148 10149 ins_encode %{ 10150 __ cselw(as_Register($dst$$reg), 10151 as_Register($src$$reg), 10152 zr, 10153 (Assembler::Condition)$cmp$$cmpcode); 10154 %} 10155 10156 ins_pipe(icond_reg); 10157 %} 10158 10159 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10160 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10161 10162 ins_cost(INSN_COST * 2); 10163 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 10164 10165 ins_encode %{ 10166 __ cselw(as_Register($dst$$reg), 10167 as_Register($src$$reg), 10168 zr, 10169 (Assembler::Condition)$cmp$$cmpcode); 10170 %} 10171 10172 ins_pipe(icond_reg); 10173 %} 10174 10175 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10176 %{ 10177 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10178 10179 ins_cost(INSN_COST * 3); 10180 10181 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10182 ins_encode %{ 10183 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10184 __ fcsels(as_FloatRegister($dst$$reg), 10185 as_FloatRegister($src2$$reg), 10186 as_FloatRegister($src1$$reg), 10187 cond); 10188 %} 10189 10190 ins_pipe(fp_cond_reg_reg_s); 10191 %} 10192 10193 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10194 %{ 10195 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10196 10197 ins_cost(INSN_COST * 3); 10198 10199 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10200 ins_encode %{ 10201 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10202 __ fcsels(as_FloatRegister($dst$$reg), 10203 as_FloatRegister($src2$$reg), 10204 as_FloatRegister($src1$$reg), 10205 cond); 10206 %} 10207 10208 ins_pipe(fp_cond_reg_reg_s); 10209 %} 10210 10211 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10212 %{ 10213 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10214 10215 ins_cost(INSN_COST * 3); 10216 10217 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10218 ins_encode %{ 10219 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10220 __ fcseld(as_FloatRegister($dst$$reg), 10221 as_FloatRegister($src2$$reg), 10222 as_FloatRegister($src1$$reg), 10223 cond); 10224 %} 10225 10226 ins_pipe(fp_cond_reg_reg_d); 10227 %} 10228 10229 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10230 %{ 10231 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10232 10233 ins_cost(INSN_COST * 3); 10234 10235 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10236 ins_encode %{ 10237 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10238 __ fcseld(as_FloatRegister($dst$$reg), 10239 as_FloatRegister($src2$$reg), 10240 as_FloatRegister($src1$$reg), 10241 cond); 10242 %} 10243 10244 ins_pipe(fp_cond_reg_reg_d); 10245 %} 10246 10247 // ============================================================================ 10248 // Arithmetic Instructions 10249 // 10250 10251 // Integer Addition 10252 10253 // TODO 10254 // these currently employ operations which do not set CR and hence are 10255 // not flagged as killing CR but we would like to isolate the cases 10256 // where we want to set flags from those where we don't. need to work 10257 // out how to do that. 10258 10259 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10260 match(Set dst (AddI src1 src2)); 10261 10262 ins_cost(INSN_COST); 10263 format %{ "addw $dst, $src1, $src2" %} 10264 10265 ins_encode %{ 10266 __ addw(as_Register($dst$$reg), 10267 as_Register($src1$$reg), 10268 as_Register($src2$$reg)); 10269 %} 10270 10271 ins_pipe(ialu_reg_reg); 10272 %} 10273 10274 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10275 match(Set dst (AddI src1 src2)); 10276 10277 ins_cost(INSN_COST); 10278 format %{ "addw $dst, $src1, $src2" %} 10279 10280 // use opcode to indicate that this is an add not a sub 10281 opcode(0x0); 10282 10283 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10284 10285 ins_pipe(ialu_reg_imm); 10286 %} 10287 10288 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10289 match(Set dst (AddI (ConvL2I src1) src2)); 10290 10291 ins_cost(INSN_COST); 10292 format %{ "addw $dst, $src1, $src2" %} 10293 10294 // use opcode to indicate that this is an add not a sub 10295 opcode(0x0); 10296 10297 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10298 10299 ins_pipe(ialu_reg_imm); 10300 %} 10301 10302 // Pointer Addition 10303 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10304 match(Set dst (AddP src1 src2)); 10305 10306 ins_cost(INSN_COST); 10307 format %{ "add $dst, $src1, $src2\t# ptr" %} 10308 10309 ins_encode %{ 10310 __ add(as_Register($dst$$reg), 10311 as_Register($src1$$reg), 10312 as_Register($src2$$reg)); 10313 %} 10314 10315 ins_pipe(ialu_reg_reg); 10316 %} 10317 10318 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10319 match(Set dst (AddP src1 (ConvI2L src2))); 10320 10321 ins_cost(1.9 * INSN_COST); 10322 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10323 10324 ins_encode %{ 10325 __ add(as_Register($dst$$reg), 10326 as_Register($src1$$reg), 10327 as_Register($src2$$reg), ext::sxtw); 10328 %} 10329 10330 ins_pipe(ialu_reg_reg); 10331 %} 10332 10333 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10334 match(Set dst (AddP src1 (LShiftL src2 scale))); 10335 10336 ins_cost(1.9 * INSN_COST); 10337 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10338 10339 ins_encode %{ 10340 __ lea(as_Register($dst$$reg), 10341 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10342 Address::lsl($scale$$constant))); 10343 %} 10344 10345 ins_pipe(ialu_reg_reg_shift); 10346 %} 10347 10348 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10349 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10350 10351 ins_cost(1.9 * INSN_COST); 10352 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10353 10354 ins_encode %{ 10355 __ lea(as_Register($dst$$reg), 10356 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10357 Address::sxtw($scale$$constant))); 10358 %} 10359 10360 ins_pipe(ialu_reg_reg_shift); 10361 %} 10362 10363 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10364 match(Set dst (LShiftL (ConvI2L src) scale)); 10365 10366 ins_cost(INSN_COST); 10367 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10368 10369 ins_encode %{ 10370 __ sbfiz(as_Register($dst$$reg), 10371 as_Register($src$$reg), 10372 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10373 %} 10374 10375 ins_pipe(ialu_reg_shift); 10376 %} 10377 10378 // Pointer Immediate Addition 10379 // n.b. this needs to be more expensive than using an indirect memory 10380 // operand 10381 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10382 match(Set dst (AddP src1 src2)); 10383 10384 ins_cost(INSN_COST); 10385 format %{ "add $dst, $src1, $src2\t# ptr" %} 10386 10387 // use opcode to indicate that this is an add not a sub 10388 opcode(0x0); 10389 10390 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10391 10392 ins_pipe(ialu_reg_imm); 10393 %} 10394 10395 // Long Addition 10396 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10397 10398 match(Set dst (AddL src1 src2)); 10399 10400 ins_cost(INSN_COST); 10401 format %{ "add $dst, $src1, $src2" %} 10402 10403 ins_encode %{ 10404 __ add(as_Register($dst$$reg), 10405 as_Register($src1$$reg), 10406 as_Register($src2$$reg)); 10407 %} 10408 10409 ins_pipe(ialu_reg_reg); 10410 %} 10411 10412 // No constant pool entries requiredLong Immediate Addition. 10413 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10414 match(Set dst (AddL src1 src2)); 10415 10416 ins_cost(INSN_COST); 10417 format %{ "add $dst, $src1, $src2" %} 10418 10419 // use opcode to indicate that this is an add not a sub 10420 opcode(0x0); 10421 10422 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10423 10424 ins_pipe(ialu_reg_imm); 10425 %} 10426 10427 // Integer Subtraction 10428 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10429 match(Set dst (SubI src1 src2)); 10430 10431 ins_cost(INSN_COST); 10432 format %{ "subw $dst, $src1, $src2" %} 10433 10434 ins_encode %{ 10435 __ subw(as_Register($dst$$reg), 10436 as_Register($src1$$reg), 10437 as_Register($src2$$reg)); 10438 %} 10439 10440 ins_pipe(ialu_reg_reg); 10441 %} 10442 10443 // Immediate Subtraction 10444 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10445 match(Set dst (SubI src1 src2)); 10446 10447 ins_cost(INSN_COST); 10448 format %{ "subw $dst, $src1, $src2" %} 10449 10450 // use opcode to indicate that this is a sub not an add 10451 opcode(0x1); 10452 10453 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10454 10455 ins_pipe(ialu_reg_imm); 10456 %} 10457 10458 // Long Subtraction 10459 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10460 10461 match(Set dst (SubL src1 src2)); 10462 10463 ins_cost(INSN_COST); 10464 format %{ "sub $dst, $src1, $src2" %} 10465 10466 ins_encode %{ 10467 __ sub(as_Register($dst$$reg), 10468 as_Register($src1$$reg), 10469 as_Register($src2$$reg)); 10470 %} 10471 10472 ins_pipe(ialu_reg_reg); 10473 %} 10474 10475 // No constant pool entries requiredLong Immediate Subtraction. 10476 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10477 match(Set dst (SubL src1 src2)); 10478 10479 ins_cost(INSN_COST); 10480 format %{ "sub$dst, $src1, $src2" %} 10481 10482 // use opcode to indicate that this is a sub not an add 10483 opcode(0x1); 10484 10485 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10486 10487 ins_pipe(ialu_reg_imm); 10488 %} 10489 10490 // Integer Negation (special case for sub) 10491 10492 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10493 match(Set dst (SubI zero src)); 10494 10495 ins_cost(INSN_COST); 10496 format %{ "negw $dst, $src\t# int" %} 10497 10498 ins_encode %{ 10499 __ negw(as_Register($dst$$reg), 10500 as_Register($src$$reg)); 10501 %} 10502 10503 ins_pipe(ialu_reg); 10504 %} 10505 10506 // Long Negation 10507 10508 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10509 match(Set dst (SubL zero src)); 10510 10511 ins_cost(INSN_COST); 10512 format %{ "neg $dst, $src\t# long" %} 10513 10514 ins_encode %{ 10515 __ neg(as_Register($dst$$reg), 10516 as_Register($src$$reg)); 10517 %} 10518 10519 ins_pipe(ialu_reg); 10520 %} 10521 10522 // Integer Multiply 10523 10524 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10525 match(Set dst (MulI src1 src2)); 10526 10527 ins_cost(INSN_COST * 3); 10528 format %{ "mulw $dst, $src1, $src2" %} 10529 10530 ins_encode %{ 10531 __ mulw(as_Register($dst$$reg), 10532 as_Register($src1$$reg), 10533 as_Register($src2$$reg)); 10534 %} 10535 10536 ins_pipe(imul_reg_reg); 10537 %} 10538 10539 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10540 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10541 10542 ins_cost(INSN_COST * 3); 10543 format %{ "smull $dst, $src1, $src2" %} 10544 10545 ins_encode %{ 10546 __ smull(as_Register($dst$$reg), 10547 as_Register($src1$$reg), 10548 as_Register($src2$$reg)); 10549 %} 10550 10551 ins_pipe(imul_reg_reg); 10552 %} 10553 10554 // Long Multiply 10555 10556 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10557 match(Set dst (MulL src1 src2)); 10558 10559 ins_cost(INSN_COST * 5); 10560 format %{ "mul $dst, $src1, $src2" %} 10561 10562 ins_encode %{ 10563 __ mul(as_Register($dst$$reg), 10564 as_Register($src1$$reg), 10565 as_Register($src2$$reg)); 10566 %} 10567 10568 ins_pipe(lmul_reg_reg); 10569 %} 10570 10571 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10572 %{ 10573 match(Set dst (MulHiL src1 src2)); 10574 10575 ins_cost(INSN_COST * 7); 10576 format %{ "smulh $dst, $src1, $src2\t# mulhi" %} 10577 10578 ins_encode %{ 10579 __ smulh(as_Register($dst$$reg), 10580 as_Register($src1$$reg), 10581 as_Register($src2$$reg)); 10582 %} 10583 10584 ins_pipe(lmul_reg_reg); 10585 %} 10586 10587 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10588 %{ 10589 match(Set dst (UMulHiL src1 src2)); 10590 10591 ins_cost(INSN_COST * 7); 10592 format %{ "umulh $dst, $src1, $src2\t# umulhi" %} 10593 10594 ins_encode %{ 10595 __ umulh(as_Register($dst$$reg), 10596 as_Register($src1$$reg), 10597 as_Register($src2$$reg)); 10598 %} 10599 10600 ins_pipe(lmul_reg_reg); 10601 %} 10602 10603 // Combined Integer Multiply & Add/Sub 10604 10605 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10606 match(Set dst (AddI src3 (MulI src1 src2))); 10607 10608 ins_cost(INSN_COST * 3); 10609 format %{ "madd $dst, $src1, $src2, $src3" %} 10610 10611 ins_encode %{ 10612 __ maddw(as_Register($dst$$reg), 10613 as_Register($src1$$reg), 10614 as_Register($src2$$reg), 10615 as_Register($src3$$reg)); 10616 %} 10617 10618 ins_pipe(imac_reg_reg); 10619 %} 10620 10621 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10622 match(Set dst (SubI src3 (MulI src1 src2))); 10623 10624 ins_cost(INSN_COST * 3); 10625 format %{ "msub $dst, $src1, $src2, $src3" %} 10626 10627 ins_encode %{ 10628 __ msubw(as_Register($dst$$reg), 10629 as_Register($src1$$reg), 10630 as_Register($src2$$reg), 10631 as_Register($src3$$reg)); 10632 %} 10633 10634 ins_pipe(imac_reg_reg); 10635 %} 10636 10637 // Combined Integer Multiply & Neg 10638 10639 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10640 match(Set dst (MulI (SubI zero src1) src2)); 10641 10642 ins_cost(INSN_COST * 3); 10643 format %{ "mneg $dst, $src1, $src2" %} 10644 10645 ins_encode %{ 10646 __ mnegw(as_Register($dst$$reg), 10647 as_Register($src1$$reg), 10648 as_Register($src2$$reg)); 10649 %} 10650 10651 ins_pipe(imac_reg_reg); 10652 %} 10653 10654 // Combined Long Multiply & Add/Sub 10655 10656 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10657 match(Set dst (AddL src3 (MulL src1 src2))); 10658 10659 ins_cost(INSN_COST * 5); 10660 format %{ "madd $dst, $src1, $src2, $src3" %} 10661 10662 ins_encode %{ 10663 __ madd(as_Register($dst$$reg), 10664 as_Register($src1$$reg), 10665 as_Register($src2$$reg), 10666 as_Register($src3$$reg)); 10667 %} 10668 10669 ins_pipe(lmac_reg_reg); 10670 %} 10671 10672 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10673 match(Set dst (SubL src3 (MulL src1 src2))); 10674 10675 ins_cost(INSN_COST * 5); 10676 format %{ "msub $dst, $src1, $src2, $src3" %} 10677 10678 ins_encode %{ 10679 __ msub(as_Register($dst$$reg), 10680 as_Register($src1$$reg), 10681 as_Register($src2$$reg), 10682 as_Register($src3$$reg)); 10683 %} 10684 10685 ins_pipe(lmac_reg_reg); 10686 %} 10687 10688 // Combined Long Multiply & Neg 10689 10690 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10691 match(Set dst (MulL (SubL zero src1) src2)); 10692 10693 ins_cost(INSN_COST * 5); 10694 format %{ "mneg $dst, $src1, $src2" %} 10695 10696 ins_encode %{ 10697 __ mneg(as_Register($dst$$reg), 10698 as_Register($src1$$reg), 10699 as_Register($src2$$reg)); 10700 %} 10701 10702 ins_pipe(lmac_reg_reg); 10703 %} 10704 10705 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10706 10707 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10708 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10709 10710 ins_cost(INSN_COST * 3); 10711 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10712 10713 ins_encode %{ 10714 __ smaddl(as_Register($dst$$reg), 10715 as_Register($src1$$reg), 10716 as_Register($src2$$reg), 10717 as_Register($src3$$reg)); 10718 %} 10719 10720 ins_pipe(imac_reg_reg); 10721 %} 10722 10723 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10724 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10725 10726 ins_cost(INSN_COST * 3); 10727 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10728 10729 ins_encode %{ 10730 __ smsubl(as_Register($dst$$reg), 10731 as_Register($src1$$reg), 10732 as_Register($src2$$reg), 10733 as_Register($src3$$reg)); 10734 %} 10735 10736 ins_pipe(imac_reg_reg); 10737 %} 10738 10739 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10740 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10741 10742 ins_cost(INSN_COST * 3); 10743 format %{ "smnegl $dst, $src1, $src2" %} 10744 10745 ins_encode %{ 10746 __ smnegl(as_Register($dst$$reg), 10747 as_Register($src1$$reg), 10748 as_Register($src2$$reg)); 10749 %} 10750 10751 ins_pipe(imac_reg_reg); 10752 %} 10753 10754 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10755 10756 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10757 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10758 10759 ins_cost(INSN_COST * 5); 10760 format %{ "mulw rscratch1, $src1, $src2\n\t" 10761 "maddw $dst, $src3, $src4, rscratch1" %} 10762 10763 ins_encode %{ 10764 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10765 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10766 10767 ins_pipe(imac_reg_reg); 10768 %} 10769 10770 // Integer Divide 10771 10772 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10773 match(Set dst (DivI src1 src2)); 10774 10775 ins_cost(INSN_COST * 19); 10776 format %{ "sdivw $dst, $src1, $src2" %} 10777 10778 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10779 ins_pipe(idiv_reg_reg); 10780 %} 10781 10782 // Long Divide 10783 10784 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10785 match(Set dst (DivL src1 src2)); 10786 10787 ins_cost(INSN_COST * 35); 10788 format %{ "sdiv $dst, $src1, $src2" %} 10789 10790 ins_encode(aarch64_enc_div(dst, src1, src2)); 10791 ins_pipe(ldiv_reg_reg); 10792 %} 10793 10794 // Integer Remainder 10795 10796 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10797 match(Set dst (ModI src1 src2)); 10798 10799 ins_cost(INSN_COST * 22); 10800 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10801 "msubw $dst, rscratch1, $src2, $src1" %} 10802 10803 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10804 ins_pipe(idiv_reg_reg); 10805 %} 10806 10807 // Long Remainder 10808 10809 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10810 match(Set dst (ModL src1 src2)); 10811 10812 ins_cost(INSN_COST * 38); 10813 format %{ "sdiv rscratch1, $src1, $src2\n" 10814 "msub $dst, rscratch1, $src2, $src1" %} 10815 10816 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10817 ins_pipe(ldiv_reg_reg); 10818 %} 10819 10820 // Unsigned Integer Divide 10821 10822 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10823 match(Set dst (UDivI src1 src2)); 10824 10825 ins_cost(INSN_COST * 19); 10826 format %{ "udivw $dst, $src1, $src2" %} 10827 10828 ins_encode %{ 10829 __ udivw($dst$$Register, $src1$$Register, $src2$$Register); 10830 %} 10831 10832 ins_pipe(idiv_reg_reg); 10833 %} 10834 10835 // Unsigned Long Divide 10836 10837 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10838 match(Set dst (UDivL src1 src2)); 10839 10840 ins_cost(INSN_COST * 35); 10841 format %{ "udiv $dst, $src1, $src2" %} 10842 10843 ins_encode %{ 10844 __ udiv($dst$$Register, $src1$$Register, $src2$$Register); 10845 %} 10846 10847 ins_pipe(ldiv_reg_reg); 10848 %} 10849 10850 // Unsigned Integer Remainder 10851 10852 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10853 match(Set dst (UModI src1 src2)); 10854 10855 ins_cost(INSN_COST * 22); 10856 format %{ "udivw rscratch1, $src1, $src2\n\t" 10857 "msubw $dst, rscratch1, $src2, $src1" %} 10858 10859 ins_encode %{ 10860 __ udivw(rscratch1, $src1$$Register, $src2$$Register); 10861 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10862 %} 10863 10864 ins_pipe(idiv_reg_reg); 10865 %} 10866 10867 // Unsigned Long Remainder 10868 10869 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10870 match(Set dst (UModL src1 src2)); 10871 10872 ins_cost(INSN_COST * 38); 10873 format %{ "udiv rscratch1, $src1, $src2\n" 10874 "msub $dst, rscratch1, $src2, $src1" %} 10875 10876 ins_encode %{ 10877 __ udiv(rscratch1, $src1$$Register, $src2$$Register); 10878 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10879 %} 10880 10881 ins_pipe(ldiv_reg_reg); 10882 %} 10883 10884 // Integer Shifts 10885 10886 // Shift Left Register 10887 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10888 match(Set dst (LShiftI src1 src2)); 10889 10890 ins_cost(INSN_COST * 2); 10891 format %{ "lslvw $dst, $src1, $src2" %} 10892 10893 ins_encode %{ 10894 __ lslvw(as_Register($dst$$reg), 10895 as_Register($src1$$reg), 10896 as_Register($src2$$reg)); 10897 %} 10898 10899 ins_pipe(ialu_reg_reg_vshift); 10900 %} 10901 10902 // Shift Left Immediate 10903 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10904 match(Set dst (LShiftI src1 src2)); 10905 10906 ins_cost(INSN_COST); 10907 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10908 10909 ins_encode %{ 10910 __ lslw(as_Register($dst$$reg), 10911 as_Register($src1$$reg), 10912 $src2$$constant & 0x1f); 10913 %} 10914 10915 ins_pipe(ialu_reg_shift); 10916 %} 10917 10918 // Shift Right Logical Register 10919 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10920 match(Set dst (URShiftI src1 src2)); 10921 10922 ins_cost(INSN_COST * 2); 10923 format %{ "lsrvw $dst, $src1, $src2" %} 10924 10925 ins_encode %{ 10926 __ lsrvw(as_Register($dst$$reg), 10927 as_Register($src1$$reg), 10928 as_Register($src2$$reg)); 10929 %} 10930 10931 ins_pipe(ialu_reg_reg_vshift); 10932 %} 10933 10934 // Shift Right Logical Immediate 10935 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10936 match(Set dst (URShiftI src1 src2)); 10937 10938 ins_cost(INSN_COST); 10939 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10940 10941 ins_encode %{ 10942 __ lsrw(as_Register($dst$$reg), 10943 as_Register($src1$$reg), 10944 $src2$$constant & 0x1f); 10945 %} 10946 10947 ins_pipe(ialu_reg_shift); 10948 %} 10949 10950 // Shift Right Arithmetic Register 10951 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10952 match(Set dst (RShiftI src1 src2)); 10953 10954 ins_cost(INSN_COST * 2); 10955 format %{ "asrvw $dst, $src1, $src2" %} 10956 10957 ins_encode %{ 10958 __ asrvw(as_Register($dst$$reg), 10959 as_Register($src1$$reg), 10960 as_Register($src2$$reg)); 10961 %} 10962 10963 ins_pipe(ialu_reg_reg_vshift); 10964 %} 10965 10966 // Shift Right Arithmetic Immediate 10967 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10968 match(Set dst (RShiftI src1 src2)); 10969 10970 ins_cost(INSN_COST); 10971 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10972 10973 ins_encode %{ 10974 __ asrw(as_Register($dst$$reg), 10975 as_Register($src1$$reg), 10976 $src2$$constant & 0x1f); 10977 %} 10978 10979 ins_pipe(ialu_reg_shift); 10980 %} 10981 10982 // Combined Int Mask and Right Shift (using UBFM) 10983 // TODO 10984 10985 // Long Shifts 10986 10987 // Shift Left Register 10988 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10989 match(Set dst (LShiftL src1 src2)); 10990 10991 ins_cost(INSN_COST * 2); 10992 format %{ "lslv $dst, $src1, $src2" %} 10993 10994 ins_encode %{ 10995 __ lslv(as_Register($dst$$reg), 10996 as_Register($src1$$reg), 10997 as_Register($src2$$reg)); 10998 %} 10999 11000 ins_pipe(ialu_reg_reg_vshift); 11001 %} 11002 11003 // Shift Left Immediate 11004 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11005 match(Set dst (LShiftL src1 src2)); 11006 11007 ins_cost(INSN_COST); 11008 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 11009 11010 ins_encode %{ 11011 __ lsl(as_Register($dst$$reg), 11012 as_Register($src1$$reg), 11013 $src2$$constant & 0x3f); 11014 %} 11015 11016 ins_pipe(ialu_reg_shift); 11017 %} 11018 11019 // Shift Right Logical Register 11020 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11021 match(Set dst (URShiftL src1 src2)); 11022 11023 ins_cost(INSN_COST * 2); 11024 format %{ "lsrv $dst, $src1, $src2" %} 11025 11026 ins_encode %{ 11027 __ lsrv(as_Register($dst$$reg), 11028 as_Register($src1$$reg), 11029 as_Register($src2$$reg)); 11030 %} 11031 11032 ins_pipe(ialu_reg_reg_vshift); 11033 %} 11034 11035 // Shift Right Logical Immediate 11036 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11037 match(Set dst (URShiftL src1 src2)); 11038 11039 ins_cost(INSN_COST); 11040 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 11041 11042 ins_encode %{ 11043 __ lsr(as_Register($dst$$reg), 11044 as_Register($src1$$reg), 11045 $src2$$constant & 0x3f); 11046 %} 11047 11048 ins_pipe(ialu_reg_shift); 11049 %} 11050 11051 // A special-case pattern for card table stores. 11052 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 11053 match(Set dst (URShiftL (CastP2X src1) src2)); 11054 11055 ins_cost(INSN_COST); 11056 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 11057 11058 ins_encode %{ 11059 __ lsr(as_Register($dst$$reg), 11060 as_Register($src1$$reg), 11061 $src2$$constant & 0x3f); 11062 %} 11063 11064 ins_pipe(ialu_reg_shift); 11065 %} 11066 11067 // Shift Right Arithmetic Register 11068 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11069 match(Set dst (RShiftL src1 src2)); 11070 11071 ins_cost(INSN_COST * 2); 11072 format %{ "asrv $dst, $src1, $src2" %} 11073 11074 ins_encode %{ 11075 __ asrv(as_Register($dst$$reg), 11076 as_Register($src1$$reg), 11077 as_Register($src2$$reg)); 11078 %} 11079 11080 ins_pipe(ialu_reg_reg_vshift); 11081 %} 11082 11083 // Shift Right Arithmetic Immediate 11084 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11085 match(Set dst (RShiftL src1 src2)); 11086 11087 ins_cost(INSN_COST); 11088 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 11089 11090 ins_encode %{ 11091 __ asr(as_Register($dst$$reg), 11092 as_Register($src1$$reg), 11093 $src2$$constant & 0x3f); 11094 %} 11095 11096 ins_pipe(ialu_reg_shift); 11097 %} 11098 11099 // BEGIN This section of the file is automatically generated. Do not edit -------------- 11100 // This section is generated from aarch64_ad.m4 11101 11102 // This pattern is automatically generated from aarch64_ad.m4 11103 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11104 instruct regL_not_reg(iRegLNoSp dst, 11105 iRegL src1, immL_M1 m1, 11106 rFlagsReg cr) %{ 11107 match(Set dst (XorL src1 m1)); 11108 ins_cost(INSN_COST); 11109 format %{ "eon $dst, $src1, zr" %} 11110 11111 ins_encode %{ 11112 __ eon(as_Register($dst$$reg), 11113 as_Register($src1$$reg), 11114 zr, 11115 Assembler::LSL, 0); 11116 %} 11117 11118 ins_pipe(ialu_reg); 11119 %} 11120 11121 // This pattern is automatically generated from aarch64_ad.m4 11122 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11123 instruct regI_not_reg(iRegINoSp dst, 11124 iRegIorL2I src1, immI_M1 m1, 11125 rFlagsReg cr) %{ 11126 match(Set dst (XorI src1 m1)); 11127 ins_cost(INSN_COST); 11128 format %{ "eonw $dst, $src1, zr" %} 11129 11130 ins_encode %{ 11131 __ eonw(as_Register($dst$$reg), 11132 as_Register($src1$$reg), 11133 zr, 11134 Assembler::LSL, 0); 11135 %} 11136 11137 ins_pipe(ialu_reg); 11138 %} 11139 11140 // This pattern is automatically generated from aarch64_ad.m4 11141 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11142 instruct NegI_reg_URShift_reg(iRegINoSp dst, 11143 immI0 zero, iRegIorL2I src1, immI src2) %{ 11144 match(Set dst (SubI zero (URShiftI src1 src2))); 11145 11146 ins_cost(1.9 * INSN_COST); 11147 format %{ "negw $dst, $src1, LSR $src2" %} 11148 11149 ins_encode %{ 11150 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11151 Assembler::LSR, $src2$$constant & 0x1f); 11152 %} 11153 11154 ins_pipe(ialu_reg_shift); 11155 %} 11156 11157 // This pattern is automatically generated from aarch64_ad.m4 11158 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11159 instruct NegI_reg_RShift_reg(iRegINoSp dst, 11160 immI0 zero, iRegIorL2I src1, immI src2) %{ 11161 match(Set dst (SubI zero (RShiftI src1 src2))); 11162 11163 ins_cost(1.9 * INSN_COST); 11164 format %{ "negw $dst, $src1, ASR $src2" %} 11165 11166 ins_encode %{ 11167 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11168 Assembler::ASR, $src2$$constant & 0x1f); 11169 %} 11170 11171 ins_pipe(ialu_reg_shift); 11172 %} 11173 11174 // This pattern is automatically generated from aarch64_ad.m4 11175 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11176 instruct NegI_reg_LShift_reg(iRegINoSp dst, 11177 immI0 zero, iRegIorL2I src1, immI src2) %{ 11178 match(Set dst (SubI zero (LShiftI src1 src2))); 11179 11180 ins_cost(1.9 * INSN_COST); 11181 format %{ "negw $dst, $src1, LSL $src2" %} 11182 11183 ins_encode %{ 11184 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11185 Assembler::LSL, $src2$$constant & 0x1f); 11186 %} 11187 11188 ins_pipe(ialu_reg_shift); 11189 %} 11190 11191 // This pattern is automatically generated from aarch64_ad.m4 11192 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11193 instruct NegL_reg_URShift_reg(iRegLNoSp dst, 11194 immL0 zero, iRegL src1, immI src2) %{ 11195 match(Set dst (SubL zero (URShiftL src1 src2))); 11196 11197 ins_cost(1.9 * INSN_COST); 11198 format %{ "neg $dst, $src1, LSR $src2" %} 11199 11200 ins_encode %{ 11201 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11202 Assembler::LSR, $src2$$constant & 0x3f); 11203 %} 11204 11205 ins_pipe(ialu_reg_shift); 11206 %} 11207 11208 // This pattern is automatically generated from aarch64_ad.m4 11209 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11210 instruct NegL_reg_RShift_reg(iRegLNoSp dst, 11211 immL0 zero, iRegL src1, immI src2) %{ 11212 match(Set dst (SubL zero (RShiftL src1 src2))); 11213 11214 ins_cost(1.9 * INSN_COST); 11215 format %{ "neg $dst, $src1, ASR $src2" %} 11216 11217 ins_encode %{ 11218 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11219 Assembler::ASR, $src2$$constant & 0x3f); 11220 %} 11221 11222 ins_pipe(ialu_reg_shift); 11223 %} 11224 11225 // This pattern is automatically generated from aarch64_ad.m4 11226 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11227 instruct NegL_reg_LShift_reg(iRegLNoSp dst, 11228 immL0 zero, iRegL src1, immI src2) %{ 11229 match(Set dst (SubL zero (LShiftL src1 src2))); 11230 11231 ins_cost(1.9 * INSN_COST); 11232 format %{ "neg $dst, $src1, LSL $src2" %} 11233 11234 ins_encode %{ 11235 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11236 Assembler::LSL, $src2$$constant & 0x3f); 11237 %} 11238 11239 ins_pipe(ialu_reg_shift); 11240 %} 11241 11242 // This pattern is automatically generated from aarch64_ad.m4 11243 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11244 instruct AndI_reg_not_reg(iRegINoSp dst, 11245 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11246 match(Set dst (AndI src1 (XorI src2 m1))); 11247 ins_cost(INSN_COST); 11248 format %{ "bicw $dst, $src1, $src2" %} 11249 11250 ins_encode %{ 11251 __ bicw(as_Register($dst$$reg), 11252 as_Register($src1$$reg), 11253 as_Register($src2$$reg), 11254 Assembler::LSL, 0); 11255 %} 11256 11257 ins_pipe(ialu_reg_reg); 11258 %} 11259 11260 // This pattern is automatically generated from aarch64_ad.m4 11261 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11262 instruct AndL_reg_not_reg(iRegLNoSp dst, 11263 iRegL src1, iRegL src2, immL_M1 m1) %{ 11264 match(Set dst (AndL src1 (XorL src2 m1))); 11265 ins_cost(INSN_COST); 11266 format %{ "bic $dst, $src1, $src2" %} 11267 11268 ins_encode %{ 11269 __ bic(as_Register($dst$$reg), 11270 as_Register($src1$$reg), 11271 as_Register($src2$$reg), 11272 Assembler::LSL, 0); 11273 %} 11274 11275 ins_pipe(ialu_reg_reg); 11276 %} 11277 11278 // This pattern is automatically generated from aarch64_ad.m4 11279 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11280 instruct OrI_reg_not_reg(iRegINoSp dst, 11281 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11282 match(Set dst (OrI src1 (XorI src2 m1))); 11283 ins_cost(INSN_COST); 11284 format %{ "ornw $dst, $src1, $src2" %} 11285 11286 ins_encode %{ 11287 __ ornw(as_Register($dst$$reg), 11288 as_Register($src1$$reg), 11289 as_Register($src2$$reg), 11290 Assembler::LSL, 0); 11291 %} 11292 11293 ins_pipe(ialu_reg_reg); 11294 %} 11295 11296 // This pattern is automatically generated from aarch64_ad.m4 11297 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11298 instruct OrL_reg_not_reg(iRegLNoSp dst, 11299 iRegL src1, iRegL src2, immL_M1 m1) %{ 11300 match(Set dst (OrL src1 (XorL src2 m1))); 11301 ins_cost(INSN_COST); 11302 format %{ "orn $dst, $src1, $src2" %} 11303 11304 ins_encode %{ 11305 __ orn(as_Register($dst$$reg), 11306 as_Register($src1$$reg), 11307 as_Register($src2$$reg), 11308 Assembler::LSL, 0); 11309 %} 11310 11311 ins_pipe(ialu_reg_reg); 11312 %} 11313 11314 // This pattern is automatically generated from aarch64_ad.m4 11315 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11316 instruct XorI_reg_not_reg(iRegINoSp dst, 11317 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11318 match(Set dst (XorI m1 (XorI src2 src1))); 11319 ins_cost(INSN_COST); 11320 format %{ "eonw $dst, $src1, $src2" %} 11321 11322 ins_encode %{ 11323 __ eonw(as_Register($dst$$reg), 11324 as_Register($src1$$reg), 11325 as_Register($src2$$reg), 11326 Assembler::LSL, 0); 11327 %} 11328 11329 ins_pipe(ialu_reg_reg); 11330 %} 11331 11332 // This pattern is automatically generated from aarch64_ad.m4 11333 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11334 instruct XorL_reg_not_reg(iRegLNoSp dst, 11335 iRegL src1, iRegL src2, immL_M1 m1) %{ 11336 match(Set dst (XorL m1 (XorL src2 src1))); 11337 ins_cost(INSN_COST); 11338 format %{ "eon $dst, $src1, $src2" %} 11339 11340 ins_encode %{ 11341 __ eon(as_Register($dst$$reg), 11342 as_Register($src1$$reg), 11343 as_Register($src2$$reg), 11344 Assembler::LSL, 0); 11345 %} 11346 11347 ins_pipe(ialu_reg_reg); 11348 %} 11349 11350 // This pattern is automatically generated from aarch64_ad.m4 11351 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11352 // val & (-1 ^ (val >>> shift)) ==> bicw 11353 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11354 iRegIorL2I src1, iRegIorL2I src2, 11355 immI src3, immI_M1 src4) %{ 11356 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11357 ins_cost(1.9 * INSN_COST); 11358 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11359 11360 ins_encode %{ 11361 __ bicw(as_Register($dst$$reg), 11362 as_Register($src1$$reg), 11363 as_Register($src2$$reg), 11364 Assembler::LSR, 11365 $src3$$constant & 0x1f); 11366 %} 11367 11368 ins_pipe(ialu_reg_reg_shift); 11369 %} 11370 11371 // This pattern is automatically generated from aarch64_ad.m4 11372 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11373 // val & (-1 ^ (val >>> shift)) ==> bic 11374 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11375 iRegL src1, iRegL src2, 11376 immI src3, immL_M1 src4) %{ 11377 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11378 ins_cost(1.9 * INSN_COST); 11379 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11380 11381 ins_encode %{ 11382 __ bic(as_Register($dst$$reg), 11383 as_Register($src1$$reg), 11384 as_Register($src2$$reg), 11385 Assembler::LSR, 11386 $src3$$constant & 0x3f); 11387 %} 11388 11389 ins_pipe(ialu_reg_reg_shift); 11390 %} 11391 11392 // This pattern is automatically generated from aarch64_ad.m4 11393 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11394 // val & (-1 ^ (val >> shift)) ==> bicw 11395 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11396 iRegIorL2I src1, iRegIorL2I src2, 11397 immI src3, immI_M1 src4) %{ 11398 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11399 ins_cost(1.9 * INSN_COST); 11400 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11401 11402 ins_encode %{ 11403 __ bicw(as_Register($dst$$reg), 11404 as_Register($src1$$reg), 11405 as_Register($src2$$reg), 11406 Assembler::ASR, 11407 $src3$$constant & 0x1f); 11408 %} 11409 11410 ins_pipe(ialu_reg_reg_shift); 11411 %} 11412 11413 // This pattern is automatically generated from aarch64_ad.m4 11414 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11415 // val & (-1 ^ (val >> shift)) ==> bic 11416 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11417 iRegL src1, iRegL src2, 11418 immI src3, immL_M1 src4) %{ 11419 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11420 ins_cost(1.9 * INSN_COST); 11421 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11422 11423 ins_encode %{ 11424 __ bic(as_Register($dst$$reg), 11425 as_Register($src1$$reg), 11426 as_Register($src2$$reg), 11427 Assembler::ASR, 11428 $src3$$constant & 0x3f); 11429 %} 11430 11431 ins_pipe(ialu_reg_reg_shift); 11432 %} 11433 11434 // This pattern is automatically generated from aarch64_ad.m4 11435 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11436 // val & (-1 ^ (val ror shift)) ==> bicw 11437 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst, 11438 iRegIorL2I src1, iRegIorL2I src2, 11439 immI src3, immI_M1 src4) %{ 11440 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4))); 11441 ins_cost(1.9 * INSN_COST); 11442 format %{ "bicw $dst, $src1, $src2, ROR $src3" %} 11443 11444 ins_encode %{ 11445 __ bicw(as_Register($dst$$reg), 11446 as_Register($src1$$reg), 11447 as_Register($src2$$reg), 11448 Assembler::ROR, 11449 $src3$$constant & 0x1f); 11450 %} 11451 11452 ins_pipe(ialu_reg_reg_shift); 11453 %} 11454 11455 // This pattern is automatically generated from aarch64_ad.m4 11456 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11457 // val & (-1 ^ (val ror shift)) ==> bic 11458 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst, 11459 iRegL src1, iRegL src2, 11460 immI src3, immL_M1 src4) %{ 11461 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4))); 11462 ins_cost(1.9 * INSN_COST); 11463 format %{ "bic $dst, $src1, $src2, ROR $src3" %} 11464 11465 ins_encode %{ 11466 __ bic(as_Register($dst$$reg), 11467 as_Register($src1$$reg), 11468 as_Register($src2$$reg), 11469 Assembler::ROR, 11470 $src3$$constant & 0x3f); 11471 %} 11472 11473 ins_pipe(ialu_reg_reg_shift); 11474 %} 11475 11476 // This pattern is automatically generated from aarch64_ad.m4 11477 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11478 // val & (-1 ^ (val << shift)) ==> bicw 11479 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11480 iRegIorL2I src1, iRegIorL2I src2, 11481 immI src3, immI_M1 src4) %{ 11482 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11483 ins_cost(1.9 * INSN_COST); 11484 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11485 11486 ins_encode %{ 11487 __ bicw(as_Register($dst$$reg), 11488 as_Register($src1$$reg), 11489 as_Register($src2$$reg), 11490 Assembler::LSL, 11491 $src3$$constant & 0x1f); 11492 %} 11493 11494 ins_pipe(ialu_reg_reg_shift); 11495 %} 11496 11497 // This pattern is automatically generated from aarch64_ad.m4 11498 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11499 // val & (-1 ^ (val << shift)) ==> bic 11500 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11501 iRegL src1, iRegL src2, 11502 immI src3, immL_M1 src4) %{ 11503 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11504 ins_cost(1.9 * INSN_COST); 11505 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11506 11507 ins_encode %{ 11508 __ bic(as_Register($dst$$reg), 11509 as_Register($src1$$reg), 11510 as_Register($src2$$reg), 11511 Assembler::LSL, 11512 $src3$$constant & 0x3f); 11513 %} 11514 11515 ins_pipe(ialu_reg_reg_shift); 11516 %} 11517 11518 // This pattern is automatically generated from aarch64_ad.m4 11519 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11520 // val ^ (-1 ^ (val >>> shift)) ==> eonw 11521 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11522 iRegIorL2I src1, iRegIorL2I src2, 11523 immI src3, immI_M1 src4) %{ 11524 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11525 ins_cost(1.9 * INSN_COST); 11526 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11527 11528 ins_encode %{ 11529 __ eonw(as_Register($dst$$reg), 11530 as_Register($src1$$reg), 11531 as_Register($src2$$reg), 11532 Assembler::LSR, 11533 $src3$$constant & 0x1f); 11534 %} 11535 11536 ins_pipe(ialu_reg_reg_shift); 11537 %} 11538 11539 // This pattern is automatically generated from aarch64_ad.m4 11540 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11541 // val ^ (-1 ^ (val >>> shift)) ==> eon 11542 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11543 iRegL src1, iRegL src2, 11544 immI src3, immL_M1 src4) %{ 11545 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11546 ins_cost(1.9 * INSN_COST); 11547 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11548 11549 ins_encode %{ 11550 __ eon(as_Register($dst$$reg), 11551 as_Register($src1$$reg), 11552 as_Register($src2$$reg), 11553 Assembler::LSR, 11554 $src3$$constant & 0x3f); 11555 %} 11556 11557 ins_pipe(ialu_reg_reg_shift); 11558 %} 11559 11560 // This pattern is automatically generated from aarch64_ad.m4 11561 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11562 // val ^ (-1 ^ (val >> shift)) ==> eonw 11563 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11564 iRegIorL2I src1, iRegIorL2I src2, 11565 immI src3, immI_M1 src4) %{ 11566 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11567 ins_cost(1.9 * INSN_COST); 11568 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11569 11570 ins_encode %{ 11571 __ eonw(as_Register($dst$$reg), 11572 as_Register($src1$$reg), 11573 as_Register($src2$$reg), 11574 Assembler::ASR, 11575 $src3$$constant & 0x1f); 11576 %} 11577 11578 ins_pipe(ialu_reg_reg_shift); 11579 %} 11580 11581 // This pattern is automatically generated from aarch64_ad.m4 11582 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11583 // val ^ (-1 ^ (val >> shift)) ==> eon 11584 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11585 iRegL src1, iRegL src2, 11586 immI src3, immL_M1 src4) %{ 11587 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11588 ins_cost(1.9 * INSN_COST); 11589 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11590 11591 ins_encode %{ 11592 __ eon(as_Register($dst$$reg), 11593 as_Register($src1$$reg), 11594 as_Register($src2$$reg), 11595 Assembler::ASR, 11596 $src3$$constant & 0x3f); 11597 %} 11598 11599 ins_pipe(ialu_reg_reg_shift); 11600 %} 11601 11602 // This pattern is automatically generated from aarch64_ad.m4 11603 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11604 // val ^ (-1 ^ (val ror shift)) ==> eonw 11605 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst, 11606 iRegIorL2I src1, iRegIorL2I src2, 11607 immI src3, immI_M1 src4) %{ 11608 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1))); 11609 ins_cost(1.9 * INSN_COST); 11610 format %{ "eonw $dst, $src1, $src2, ROR $src3" %} 11611 11612 ins_encode %{ 11613 __ eonw(as_Register($dst$$reg), 11614 as_Register($src1$$reg), 11615 as_Register($src2$$reg), 11616 Assembler::ROR, 11617 $src3$$constant & 0x1f); 11618 %} 11619 11620 ins_pipe(ialu_reg_reg_shift); 11621 %} 11622 11623 // This pattern is automatically generated from aarch64_ad.m4 11624 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11625 // val ^ (-1 ^ (val ror shift)) ==> eon 11626 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst, 11627 iRegL src1, iRegL src2, 11628 immI src3, immL_M1 src4) %{ 11629 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1))); 11630 ins_cost(1.9 * INSN_COST); 11631 format %{ "eon $dst, $src1, $src2, ROR $src3" %} 11632 11633 ins_encode %{ 11634 __ eon(as_Register($dst$$reg), 11635 as_Register($src1$$reg), 11636 as_Register($src2$$reg), 11637 Assembler::ROR, 11638 $src3$$constant & 0x3f); 11639 %} 11640 11641 ins_pipe(ialu_reg_reg_shift); 11642 %} 11643 11644 // This pattern is automatically generated from aarch64_ad.m4 11645 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11646 // val ^ (-1 ^ (val << shift)) ==> eonw 11647 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11648 iRegIorL2I src1, iRegIorL2I src2, 11649 immI src3, immI_M1 src4) %{ 11650 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11651 ins_cost(1.9 * INSN_COST); 11652 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11653 11654 ins_encode %{ 11655 __ eonw(as_Register($dst$$reg), 11656 as_Register($src1$$reg), 11657 as_Register($src2$$reg), 11658 Assembler::LSL, 11659 $src3$$constant & 0x1f); 11660 %} 11661 11662 ins_pipe(ialu_reg_reg_shift); 11663 %} 11664 11665 // This pattern is automatically generated from aarch64_ad.m4 11666 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11667 // val ^ (-1 ^ (val << shift)) ==> eon 11668 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11669 iRegL src1, iRegL src2, 11670 immI src3, immL_M1 src4) %{ 11671 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11672 ins_cost(1.9 * INSN_COST); 11673 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11674 11675 ins_encode %{ 11676 __ eon(as_Register($dst$$reg), 11677 as_Register($src1$$reg), 11678 as_Register($src2$$reg), 11679 Assembler::LSL, 11680 $src3$$constant & 0x3f); 11681 %} 11682 11683 ins_pipe(ialu_reg_reg_shift); 11684 %} 11685 11686 // This pattern is automatically generated from aarch64_ad.m4 11687 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11688 // val | (-1 ^ (val >>> shift)) ==> ornw 11689 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11690 iRegIorL2I src1, iRegIorL2I src2, 11691 immI src3, immI_M1 src4) %{ 11692 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11693 ins_cost(1.9 * INSN_COST); 11694 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11695 11696 ins_encode %{ 11697 __ ornw(as_Register($dst$$reg), 11698 as_Register($src1$$reg), 11699 as_Register($src2$$reg), 11700 Assembler::LSR, 11701 $src3$$constant & 0x1f); 11702 %} 11703 11704 ins_pipe(ialu_reg_reg_shift); 11705 %} 11706 11707 // This pattern is automatically generated from aarch64_ad.m4 11708 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11709 // val | (-1 ^ (val >>> shift)) ==> orn 11710 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11711 iRegL src1, iRegL src2, 11712 immI src3, immL_M1 src4) %{ 11713 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11714 ins_cost(1.9 * INSN_COST); 11715 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11716 11717 ins_encode %{ 11718 __ orn(as_Register($dst$$reg), 11719 as_Register($src1$$reg), 11720 as_Register($src2$$reg), 11721 Assembler::LSR, 11722 $src3$$constant & 0x3f); 11723 %} 11724 11725 ins_pipe(ialu_reg_reg_shift); 11726 %} 11727 11728 // This pattern is automatically generated from aarch64_ad.m4 11729 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11730 // val | (-1 ^ (val >> shift)) ==> ornw 11731 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11732 iRegIorL2I src1, iRegIorL2I src2, 11733 immI src3, immI_M1 src4) %{ 11734 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11735 ins_cost(1.9 * INSN_COST); 11736 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11737 11738 ins_encode %{ 11739 __ ornw(as_Register($dst$$reg), 11740 as_Register($src1$$reg), 11741 as_Register($src2$$reg), 11742 Assembler::ASR, 11743 $src3$$constant & 0x1f); 11744 %} 11745 11746 ins_pipe(ialu_reg_reg_shift); 11747 %} 11748 11749 // This pattern is automatically generated from aarch64_ad.m4 11750 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11751 // val | (-1 ^ (val >> shift)) ==> orn 11752 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11753 iRegL src1, iRegL src2, 11754 immI src3, immL_M1 src4) %{ 11755 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11756 ins_cost(1.9 * INSN_COST); 11757 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11758 11759 ins_encode %{ 11760 __ orn(as_Register($dst$$reg), 11761 as_Register($src1$$reg), 11762 as_Register($src2$$reg), 11763 Assembler::ASR, 11764 $src3$$constant & 0x3f); 11765 %} 11766 11767 ins_pipe(ialu_reg_reg_shift); 11768 %} 11769 11770 // This pattern is automatically generated from aarch64_ad.m4 11771 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11772 // val | (-1 ^ (val ror shift)) ==> ornw 11773 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst, 11774 iRegIorL2I src1, iRegIorL2I src2, 11775 immI src3, immI_M1 src4) %{ 11776 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4))); 11777 ins_cost(1.9 * INSN_COST); 11778 format %{ "ornw $dst, $src1, $src2, ROR $src3" %} 11779 11780 ins_encode %{ 11781 __ ornw(as_Register($dst$$reg), 11782 as_Register($src1$$reg), 11783 as_Register($src2$$reg), 11784 Assembler::ROR, 11785 $src3$$constant & 0x1f); 11786 %} 11787 11788 ins_pipe(ialu_reg_reg_shift); 11789 %} 11790 11791 // This pattern is automatically generated from aarch64_ad.m4 11792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11793 // val | (-1 ^ (val ror shift)) ==> orn 11794 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst, 11795 iRegL src1, iRegL src2, 11796 immI src3, immL_M1 src4) %{ 11797 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4))); 11798 ins_cost(1.9 * INSN_COST); 11799 format %{ "orn $dst, $src1, $src2, ROR $src3" %} 11800 11801 ins_encode %{ 11802 __ orn(as_Register($dst$$reg), 11803 as_Register($src1$$reg), 11804 as_Register($src2$$reg), 11805 Assembler::ROR, 11806 $src3$$constant & 0x3f); 11807 %} 11808 11809 ins_pipe(ialu_reg_reg_shift); 11810 %} 11811 11812 // This pattern is automatically generated from aarch64_ad.m4 11813 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11814 // val | (-1 ^ (val << shift)) ==> ornw 11815 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11816 iRegIorL2I src1, iRegIorL2I src2, 11817 immI src3, immI_M1 src4) %{ 11818 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11819 ins_cost(1.9 * INSN_COST); 11820 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11821 11822 ins_encode %{ 11823 __ ornw(as_Register($dst$$reg), 11824 as_Register($src1$$reg), 11825 as_Register($src2$$reg), 11826 Assembler::LSL, 11827 $src3$$constant & 0x1f); 11828 %} 11829 11830 ins_pipe(ialu_reg_reg_shift); 11831 %} 11832 11833 // This pattern is automatically generated from aarch64_ad.m4 11834 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11835 // val | (-1 ^ (val << shift)) ==> orn 11836 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11837 iRegL src1, iRegL src2, 11838 immI src3, immL_M1 src4) %{ 11839 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11840 ins_cost(1.9 * INSN_COST); 11841 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11842 11843 ins_encode %{ 11844 __ orn(as_Register($dst$$reg), 11845 as_Register($src1$$reg), 11846 as_Register($src2$$reg), 11847 Assembler::LSL, 11848 $src3$$constant & 0x3f); 11849 %} 11850 11851 ins_pipe(ialu_reg_reg_shift); 11852 %} 11853 11854 // This pattern is automatically generated from aarch64_ad.m4 11855 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11856 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11857 iRegIorL2I src1, iRegIorL2I src2, 11858 immI src3) %{ 11859 match(Set dst (AndI src1 (URShiftI src2 src3))); 11860 11861 ins_cost(1.9 * INSN_COST); 11862 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11863 11864 ins_encode %{ 11865 __ andw(as_Register($dst$$reg), 11866 as_Register($src1$$reg), 11867 as_Register($src2$$reg), 11868 Assembler::LSR, 11869 $src3$$constant & 0x1f); 11870 %} 11871 11872 ins_pipe(ialu_reg_reg_shift); 11873 %} 11874 11875 // This pattern is automatically generated from aarch64_ad.m4 11876 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11877 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11878 iRegL src1, iRegL src2, 11879 immI src3) %{ 11880 match(Set dst (AndL src1 (URShiftL src2 src3))); 11881 11882 ins_cost(1.9 * INSN_COST); 11883 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11884 11885 ins_encode %{ 11886 __ andr(as_Register($dst$$reg), 11887 as_Register($src1$$reg), 11888 as_Register($src2$$reg), 11889 Assembler::LSR, 11890 $src3$$constant & 0x3f); 11891 %} 11892 11893 ins_pipe(ialu_reg_reg_shift); 11894 %} 11895 11896 // This pattern is automatically generated from aarch64_ad.m4 11897 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11898 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11899 iRegIorL2I src1, iRegIorL2I src2, 11900 immI src3) %{ 11901 match(Set dst (AndI src1 (RShiftI src2 src3))); 11902 11903 ins_cost(1.9 * INSN_COST); 11904 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11905 11906 ins_encode %{ 11907 __ andw(as_Register($dst$$reg), 11908 as_Register($src1$$reg), 11909 as_Register($src2$$reg), 11910 Assembler::ASR, 11911 $src3$$constant & 0x1f); 11912 %} 11913 11914 ins_pipe(ialu_reg_reg_shift); 11915 %} 11916 11917 // This pattern is automatically generated from aarch64_ad.m4 11918 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11919 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11920 iRegL src1, iRegL src2, 11921 immI src3) %{ 11922 match(Set dst (AndL src1 (RShiftL src2 src3))); 11923 11924 ins_cost(1.9 * INSN_COST); 11925 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11926 11927 ins_encode %{ 11928 __ andr(as_Register($dst$$reg), 11929 as_Register($src1$$reg), 11930 as_Register($src2$$reg), 11931 Assembler::ASR, 11932 $src3$$constant & 0x3f); 11933 %} 11934 11935 ins_pipe(ialu_reg_reg_shift); 11936 %} 11937 11938 // This pattern is automatically generated from aarch64_ad.m4 11939 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11940 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11941 iRegIorL2I src1, iRegIorL2I src2, 11942 immI src3) %{ 11943 match(Set dst (AndI src1 (LShiftI src2 src3))); 11944 11945 ins_cost(1.9 * INSN_COST); 11946 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11947 11948 ins_encode %{ 11949 __ andw(as_Register($dst$$reg), 11950 as_Register($src1$$reg), 11951 as_Register($src2$$reg), 11952 Assembler::LSL, 11953 $src3$$constant & 0x1f); 11954 %} 11955 11956 ins_pipe(ialu_reg_reg_shift); 11957 %} 11958 11959 // This pattern is automatically generated from aarch64_ad.m4 11960 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11961 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11962 iRegL src1, iRegL src2, 11963 immI src3) %{ 11964 match(Set dst (AndL src1 (LShiftL src2 src3))); 11965 11966 ins_cost(1.9 * INSN_COST); 11967 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11968 11969 ins_encode %{ 11970 __ andr(as_Register($dst$$reg), 11971 as_Register($src1$$reg), 11972 as_Register($src2$$reg), 11973 Assembler::LSL, 11974 $src3$$constant & 0x3f); 11975 %} 11976 11977 ins_pipe(ialu_reg_reg_shift); 11978 %} 11979 11980 // This pattern is automatically generated from aarch64_ad.m4 11981 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11982 instruct AndI_reg_RotateRight_reg(iRegINoSp dst, 11983 iRegIorL2I src1, iRegIorL2I src2, 11984 immI src3) %{ 11985 match(Set dst (AndI src1 (RotateRight src2 src3))); 11986 11987 ins_cost(1.9 * INSN_COST); 11988 format %{ "andw $dst, $src1, $src2, ROR $src3" %} 11989 11990 ins_encode %{ 11991 __ andw(as_Register($dst$$reg), 11992 as_Register($src1$$reg), 11993 as_Register($src2$$reg), 11994 Assembler::ROR, 11995 $src3$$constant & 0x1f); 11996 %} 11997 11998 ins_pipe(ialu_reg_reg_shift); 11999 %} 12000 12001 // This pattern is automatically generated from aarch64_ad.m4 12002 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12003 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst, 12004 iRegL src1, iRegL src2, 12005 immI src3) %{ 12006 match(Set dst (AndL src1 (RotateRight src2 src3))); 12007 12008 ins_cost(1.9 * INSN_COST); 12009 format %{ "andr $dst, $src1, $src2, ROR $src3" %} 12010 12011 ins_encode %{ 12012 __ andr(as_Register($dst$$reg), 12013 as_Register($src1$$reg), 12014 as_Register($src2$$reg), 12015 Assembler::ROR, 12016 $src3$$constant & 0x3f); 12017 %} 12018 12019 ins_pipe(ialu_reg_reg_shift); 12020 %} 12021 12022 // This pattern is automatically generated from aarch64_ad.m4 12023 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12024 instruct XorI_reg_URShift_reg(iRegINoSp dst, 12025 iRegIorL2I src1, iRegIorL2I src2, 12026 immI src3) %{ 12027 match(Set dst (XorI src1 (URShiftI src2 src3))); 12028 12029 ins_cost(1.9 * INSN_COST); 12030 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 12031 12032 ins_encode %{ 12033 __ eorw(as_Register($dst$$reg), 12034 as_Register($src1$$reg), 12035 as_Register($src2$$reg), 12036 Assembler::LSR, 12037 $src3$$constant & 0x1f); 12038 %} 12039 12040 ins_pipe(ialu_reg_reg_shift); 12041 %} 12042 12043 // This pattern is automatically generated from aarch64_ad.m4 12044 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12045 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 12046 iRegL src1, iRegL src2, 12047 immI src3) %{ 12048 match(Set dst (XorL src1 (URShiftL src2 src3))); 12049 12050 ins_cost(1.9 * INSN_COST); 12051 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 12052 12053 ins_encode %{ 12054 __ eor(as_Register($dst$$reg), 12055 as_Register($src1$$reg), 12056 as_Register($src2$$reg), 12057 Assembler::LSR, 12058 $src3$$constant & 0x3f); 12059 %} 12060 12061 ins_pipe(ialu_reg_reg_shift); 12062 %} 12063 12064 // This pattern is automatically generated from aarch64_ad.m4 12065 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12066 instruct XorI_reg_RShift_reg(iRegINoSp dst, 12067 iRegIorL2I src1, iRegIorL2I src2, 12068 immI src3) %{ 12069 match(Set dst (XorI src1 (RShiftI src2 src3))); 12070 12071 ins_cost(1.9 * INSN_COST); 12072 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 12073 12074 ins_encode %{ 12075 __ eorw(as_Register($dst$$reg), 12076 as_Register($src1$$reg), 12077 as_Register($src2$$reg), 12078 Assembler::ASR, 12079 $src3$$constant & 0x1f); 12080 %} 12081 12082 ins_pipe(ialu_reg_reg_shift); 12083 %} 12084 12085 // This pattern is automatically generated from aarch64_ad.m4 12086 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12087 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 12088 iRegL src1, iRegL src2, 12089 immI src3) %{ 12090 match(Set dst (XorL src1 (RShiftL src2 src3))); 12091 12092 ins_cost(1.9 * INSN_COST); 12093 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 12094 12095 ins_encode %{ 12096 __ eor(as_Register($dst$$reg), 12097 as_Register($src1$$reg), 12098 as_Register($src2$$reg), 12099 Assembler::ASR, 12100 $src3$$constant & 0x3f); 12101 %} 12102 12103 ins_pipe(ialu_reg_reg_shift); 12104 %} 12105 12106 // This pattern is automatically generated from aarch64_ad.m4 12107 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12108 instruct XorI_reg_LShift_reg(iRegINoSp dst, 12109 iRegIorL2I src1, iRegIorL2I src2, 12110 immI src3) %{ 12111 match(Set dst (XorI src1 (LShiftI src2 src3))); 12112 12113 ins_cost(1.9 * INSN_COST); 12114 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 12115 12116 ins_encode %{ 12117 __ eorw(as_Register($dst$$reg), 12118 as_Register($src1$$reg), 12119 as_Register($src2$$reg), 12120 Assembler::LSL, 12121 $src3$$constant & 0x1f); 12122 %} 12123 12124 ins_pipe(ialu_reg_reg_shift); 12125 %} 12126 12127 // This pattern is automatically generated from aarch64_ad.m4 12128 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12129 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 12130 iRegL src1, iRegL src2, 12131 immI src3) %{ 12132 match(Set dst (XorL src1 (LShiftL src2 src3))); 12133 12134 ins_cost(1.9 * INSN_COST); 12135 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 12136 12137 ins_encode %{ 12138 __ eor(as_Register($dst$$reg), 12139 as_Register($src1$$reg), 12140 as_Register($src2$$reg), 12141 Assembler::LSL, 12142 $src3$$constant & 0x3f); 12143 %} 12144 12145 ins_pipe(ialu_reg_reg_shift); 12146 %} 12147 12148 // This pattern is automatically generated from aarch64_ad.m4 12149 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12150 instruct XorI_reg_RotateRight_reg(iRegINoSp dst, 12151 iRegIorL2I src1, iRegIorL2I src2, 12152 immI src3) %{ 12153 match(Set dst (XorI src1 (RotateRight src2 src3))); 12154 12155 ins_cost(1.9 * INSN_COST); 12156 format %{ "eorw $dst, $src1, $src2, ROR $src3" %} 12157 12158 ins_encode %{ 12159 __ eorw(as_Register($dst$$reg), 12160 as_Register($src1$$reg), 12161 as_Register($src2$$reg), 12162 Assembler::ROR, 12163 $src3$$constant & 0x1f); 12164 %} 12165 12166 ins_pipe(ialu_reg_reg_shift); 12167 %} 12168 12169 // This pattern is automatically generated from aarch64_ad.m4 12170 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12171 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst, 12172 iRegL src1, iRegL src2, 12173 immI src3) %{ 12174 match(Set dst (XorL src1 (RotateRight src2 src3))); 12175 12176 ins_cost(1.9 * INSN_COST); 12177 format %{ "eor $dst, $src1, $src2, ROR $src3" %} 12178 12179 ins_encode %{ 12180 __ eor(as_Register($dst$$reg), 12181 as_Register($src1$$reg), 12182 as_Register($src2$$reg), 12183 Assembler::ROR, 12184 $src3$$constant & 0x3f); 12185 %} 12186 12187 ins_pipe(ialu_reg_reg_shift); 12188 %} 12189 12190 // This pattern is automatically generated from aarch64_ad.m4 12191 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12192 instruct OrI_reg_URShift_reg(iRegINoSp dst, 12193 iRegIorL2I src1, iRegIorL2I src2, 12194 immI src3) %{ 12195 match(Set dst (OrI src1 (URShiftI src2 src3))); 12196 12197 ins_cost(1.9 * INSN_COST); 12198 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 12199 12200 ins_encode %{ 12201 __ orrw(as_Register($dst$$reg), 12202 as_Register($src1$$reg), 12203 as_Register($src2$$reg), 12204 Assembler::LSR, 12205 $src3$$constant & 0x1f); 12206 %} 12207 12208 ins_pipe(ialu_reg_reg_shift); 12209 %} 12210 12211 // This pattern is automatically generated from aarch64_ad.m4 12212 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12213 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 12214 iRegL src1, iRegL src2, 12215 immI src3) %{ 12216 match(Set dst (OrL src1 (URShiftL src2 src3))); 12217 12218 ins_cost(1.9 * INSN_COST); 12219 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 12220 12221 ins_encode %{ 12222 __ orr(as_Register($dst$$reg), 12223 as_Register($src1$$reg), 12224 as_Register($src2$$reg), 12225 Assembler::LSR, 12226 $src3$$constant & 0x3f); 12227 %} 12228 12229 ins_pipe(ialu_reg_reg_shift); 12230 %} 12231 12232 // This pattern is automatically generated from aarch64_ad.m4 12233 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12234 instruct OrI_reg_RShift_reg(iRegINoSp dst, 12235 iRegIorL2I src1, iRegIorL2I src2, 12236 immI src3) %{ 12237 match(Set dst (OrI src1 (RShiftI src2 src3))); 12238 12239 ins_cost(1.9 * INSN_COST); 12240 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 12241 12242 ins_encode %{ 12243 __ orrw(as_Register($dst$$reg), 12244 as_Register($src1$$reg), 12245 as_Register($src2$$reg), 12246 Assembler::ASR, 12247 $src3$$constant & 0x1f); 12248 %} 12249 12250 ins_pipe(ialu_reg_reg_shift); 12251 %} 12252 12253 // This pattern is automatically generated from aarch64_ad.m4 12254 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12255 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 12256 iRegL src1, iRegL src2, 12257 immI src3) %{ 12258 match(Set dst (OrL src1 (RShiftL src2 src3))); 12259 12260 ins_cost(1.9 * INSN_COST); 12261 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 12262 12263 ins_encode %{ 12264 __ orr(as_Register($dst$$reg), 12265 as_Register($src1$$reg), 12266 as_Register($src2$$reg), 12267 Assembler::ASR, 12268 $src3$$constant & 0x3f); 12269 %} 12270 12271 ins_pipe(ialu_reg_reg_shift); 12272 %} 12273 12274 // This pattern is automatically generated from aarch64_ad.m4 12275 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12276 instruct OrI_reg_LShift_reg(iRegINoSp dst, 12277 iRegIorL2I src1, iRegIorL2I src2, 12278 immI src3) %{ 12279 match(Set dst (OrI src1 (LShiftI src2 src3))); 12280 12281 ins_cost(1.9 * INSN_COST); 12282 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 12283 12284 ins_encode %{ 12285 __ orrw(as_Register($dst$$reg), 12286 as_Register($src1$$reg), 12287 as_Register($src2$$reg), 12288 Assembler::LSL, 12289 $src3$$constant & 0x1f); 12290 %} 12291 12292 ins_pipe(ialu_reg_reg_shift); 12293 %} 12294 12295 // This pattern is automatically generated from aarch64_ad.m4 12296 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12297 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 12298 iRegL src1, iRegL src2, 12299 immI src3) %{ 12300 match(Set dst (OrL src1 (LShiftL src2 src3))); 12301 12302 ins_cost(1.9 * INSN_COST); 12303 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 12304 12305 ins_encode %{ 12306 __ orr(as_Register($dst$$reg), 12307 as_Register($src1$$reg), 12308 as_Register($src2$$reg), 12309 Assembler::LSL, 12310 $src3$$constant & 0x3f); 12311 %} 12312 12313 ins_pipe(ialu_reg_reg_shift); 12314 %} 12315 12316 // This pattern is automatically generated from aarch64_ad.m4 12317 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12318 instruct OrI_reg_RotateRight_reg(iRegINoSp dst, 12319 iRegIorL2I src1, iRegIorL2I src2, 12320 immI src3) %{ 12321 match(Set dst (OrI src1 (RotateRight src2 src3))); 12322 12323 ins_cost(1.9 * INSN_COST); 12324 format %{ "orrw $dst, $src1, $src2, ROR $src3" %} 12325 12326 ins_encode %{ 12327 __ orrw(as_Register($dst$$reg), 12328 as_Register($src1$$reg), 12329 as_Register($src2$$reg), 12330 Assembler::ROR, 12331 $src3$$constant & 0x1f); 12332 %} 12333 12334 ins_pipe(ialu_reg_reg_shift); 12335 %} 12336 12337 // This pattern is automatically generated from aarch64_ad.m4 12338 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12339 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst, 12340 iRegL src1, iRegL src2, 12341 immI src3) %{ 12342 match(Set dst (OrL src1 (RotateRight src2 src3))); 12343 12344 ins_cost(1.9 * INSN_COST); 12345 format %{ "orr $dst, $src1, $src2, ROR $src3" %} 12346 12347 ins_encode %{ 12348 __ orr(as_Register($dst$$reg), 12349 as_Register($src1$$reg), 12350 as_Register($src2$$reg), 12351 Assembler::ROR, 12352 $src3$$constant & 0x3f); 12353 %} 12354 12355 ins_pipe(ialu_reg_reg_shift); 12356 %} 12357 12358 // This pattern is automatically generated from aarch64_ad.m4 12359 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12360 instruct AddI_reg_URShift_reg(iRegINoSp dst, 12361 iRegIorL2I src1, iRegIorL2I src2, 12362 immI src3) %{ 12363 match(Set dst (AddI src1 (URShiftI src2 src3))); 12364 12365 ins_cost(1.9 * INSN_COST); 12366 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 12367 12368 ins_encode %{ 12369 __ addw(as_Register($dst$$reg), 12370 as_Register($src1$$reg), 12371 as_Register($src2$$reg), 12372 Assembler::LSR, 12373 $src3$$constant & 0x1f); 12374 %} 12375 12376 ins_pipe(ialu_reg_reg_shift); 12377 %} 12378 12379 // This pattern is automatically generated from aarch64_ad.m4 12380 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12381 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 12382 iRegL src1, iRegL src2, 12383 immI src3) %{ 12384 match(Set dst (AddL src1 (URShiftL src2 src3))); 12385 12386 ins_cost(1.9 * INSN_COST); 12387 format %{ "add $dst, $src1, $src2, LSR $src3" %} 12388 12389 ins_encode %{ 12390 __ add(as_Register($dst$$reg), 12391 as_Register($src1$$reg), 12392 as_Register($src2$$reg), 12393 Assembler::LSR, 12394 $src3$$constant & 0x3f); 12395 %} 12396 12397 ins_pipe(ialu_reg_reg_shift); 12398 %} 12399 12400 // This pattern is automatically generated from aarch64_ad.m4 12401 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12402 instruct AddI_reg_RShift_reg(iRegINoSp dst, 12403 iRegIorL2I src1, iRegIorL2I src2, 12404 immI src3) %{ 12405 match(Set dst (AddI src1 (RShiftI src2 src3))); 12406 12407 ins_cost(1.9 * INSN_COST); 12408 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 12409 12410 ins_encode %{ 12411 __ addw(as_Register($dst$$reg), 12412 as_Register($src1$$reg), 12413 as_Register($src2$$reg), 12414 Assembler::ASR, 12415 $src3$$constant & 0x1f); 12416 %} 12417 12418 ins_pipe(ialu_reg_reg_shift); 12419 %} 12420 12421 // This pattern is automatically generated from aarch64_ad.m4 12422 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12423 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 12424 iRegL src1, iRegL src2, 12425 immI src3) %{ 12426 match(Set dst (AddL src1 (RShiftL src2 src3))); 12427 12428 ins_cost(1.9 * INSN_COST); 12429 format %{ "add $dst, $src1, $src2, ASR $src3" %} 12430 12431 ins_encode %{ 12432 __ add(as_Register($dst$$reg), 12433 as_Register($src1$$reg), 12434 as_Register($src2$$reg), 12435 Assembler::ASR, 12436 $src3$$constant & 0x3f); 12437 %} 12438 12439 ins_pipe(ialu_reg_reg_shift); 12440 %} 12441 12442 // This pattern is automatically generated from aarch64_ad.m4 12443 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12444 instruct AddI_reg_LShift_reg(iRegINoSp dst, 12445 iRegIorL2I src1, iRegIorL2I src2, 12446 immI src3) %{ 12447 match(Set dst (AddI src1 (LShiftI src2 src3))); 12448 12449 ins_cost(1.9 * INSN_COST); 12450 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 12451 12452 ins_encode %{ 12453 __ addw(as_Register($dst$$reg), 12454 as_Register($src1$$reg), 12455 as_Register($src2$$reg), 12456 Assembler::LSL, 12457 $src3$$constant & 0x1f); 12458 %} 12459 12460 ins_pipe(ialu_reg_reg_shift); 12461 %} 12462 12463 // This pattern is automatically generated from aarch64_ad.m4 12464 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12465 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 12466 iRegL src1, iRegL src2, 12467 immI src3) %{ 12468 match(Set dst (AddL src1 (LShiftL src2 src3))); 12469 12470 ins_cost(1.9 * INSN_COST); 12471 format %{ "add $dst, $src1, $src2, LSL $src3" %} 12472 12473 ins_encode %{ 12474 __ add(as_Register($dst$$reg), 12475 as_Register($src1$$reg), 12476 as_Register($src2$$reg), 12477 Assembler::LSL, 12478 $src3$$constant & 0x3f); 12479 %} 12480 12481 ins_pipe(ialu_reg_reg_shift); 12482 %} 12483 12484 // This pattern is automatically generated from aarch64_ad.m4 12485 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12486 instruct SubI_reg_URShift_reg(iRegINoSp dst, 12487 iRegIorL2I src1, iRegIorL2I src2, 12488 immI src3) %{ 12489 match(Set dst (SubI src1 (URShiftI src2 src3))); 12490 12491 ins_cost(1.9 * INSN_COST); 12492 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 12493 12494 ins_encode %{ 12495 __ subw(as_Register($dst$$reg), 12496 as_Register($src1$$reg), 12497 as_Register($src2$$reg), 12498 Assembler::LSR, 12499 $src3$$constant & 0x1f); 12500 %} 12501 12502 ins_pipe(ialu_reg_reg_shift); 12503 %} 12504 12505 // This pattern is automatically generated from aarch64_ad.m4 12506 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12507 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 12508 iRegL src1, iRegL src2, 12509 immI src3) %{ 12510 match(Set dst (SubL src1 (URShiftL src2 src3))); 12511 12512 ins_cost(1.9 * INSN_COST); 12513 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 12514 12515 ins_encode %{ 12516 __ sub(as_Register($dst$$reg), 12517 as_Register($src1$$reg), 12518 as_Register($src2$$reg), 12519 Assembler::LSR, 12520 $src3$$constant & 0x3f); 12521 %} 12522 12523 ins_pipe(ialu_reg_reg_shift); 12524 %} 12525 12526 // This pattern is automatically generated from aarch64_ad.m4 12527 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12528 instruct SubI_reg_RShift_reg(iRegINoSp dst, 12529 iRegIorL2I src1, iRegIorL2I src2, 12530 immI src3) %{ 12531 match(Set dst (SubI src1 (RShiftI src2 src3))); 12532 12533 ins_cost(1.9 * INSN_COST); 12534 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 12535 12536 ins_encode %{ 12537 __ subw(as_Register($dst$$reg), 12538 as_Register($src1$$reg), 12539 as_Register($src2$$reg), 12540 Assembler::ASR, 12541 $src3$$constant & 0x1f); 12542 %} 12543 12544 ins_pipe(ialu_reg_reg_shift); 12545 %} 12546 12547 // This pattern is automatically generated from aarch64_ad.m4 12548 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12549 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 12550 iRegL src1, iRegL src2, 12551 immI src3) %{ 12552 match(Set dst (SubL src1 (RShiftL src2 src3))); 12553 12554 ins_cost(1.9 * INSN_COST); 12555 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 12556 12557 ins_encode %{ 12558 __ sub(as_Register($dst$$reg), 12559 as_Register($src1$$reg), 12560 as_Register($src2$$reg), 12561 Assembler::ASR, 12562 $src3$$constant & 0x3f); 12563 %} 12564 12565 ins_pipe(ialu_reg_reg_shift); 12566 %} 12567 12568 // This pattern is automatically generated from aarch64_ad.m4 12569 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12570 instruct SubI_reg_LShift_reg(iRegINoSp dst, 12571 iRegIorL2I src1, iRegIorL2I src2, 12572 immI src3) %{ 12573 match(Set dst (SubI src1 (LShiftI src2 src3))); 12574 12575 ins_cost(1.9 * INSN_COST); 12576 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 12577 12578 ins_encode %{ 12579 __ subw(as_Register($dst$$reg), 12580 as_Register($src1$$reg), 12581 as_Register($src2$$reg), 12582 Assembler::LSL, 12583 $src3$$constant & 0x1f); 12584 %} 12585 12586 ins_pipe(ialu_reg_reg_shift); 12587 %} 12588 12589 // This pattern is automatically generated from aarch64_ad.m4 12590 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12591 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 12592 iRegL src1, iRegL src2, 12593 immI src3) %{ 12594 match(Set dst (SubL src1 (LShiftL src2 src3))); 12595 12596 ins_cost(1.9 * INSN_COST); 12597 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 12598 12599 ins_encode %{ 12600 __ sub(as_Register($dst$$reg), 12601 as_Register($src1$$reg), 12602 as_Register($src2$$reg), 12603 Assembler::LSL, 12604 $src3$$constant & 0x3f); 12605 %} 12606 12607 ins_pipe(ialu_reg_reg_shift); 12608 %} 12609 12610 // This pattern is automatically generated from aarch64_ad.m4 12611 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12612 12613 // Shift Left followed by Shift Right. 12614 // This idiom is used by the compiler for the i2b bytecode etc. 12615 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12616 %{ 12617 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12618 ins_cost(INSN_COST * 2); 12619 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12620 ins_encode %{ 12621 int lshift = $lshift_count$$constant & 63; 12622 int rshift = $rshift_count$$constant & 63; 12623 int s = 63 - lshift; 12624 int r = (rshift - lshift) & 63; 12625 __ sbfm(as_Register($dst$$reg), 12626 as_Register($src$$reg), 12627 r, s); 12628 %} 12629 12630 ins_pipe(ialu_reg_shift); 12631 %} 12632 12633 // This pattern is automatically generated from aarch64_ad.m4 12634 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12635 12636 // Shift Left followed by Shift Right. 12637 // This idiom is used by the compiler for the i2b bytecode etc. 12638 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12639 %{ 12640 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12641 ins_cost(INSN_COST * 2); 12642 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12643 ins_encode %{ 12644 int lshift = $lshift_count$$constant & 31; 12645 int rshift = $rshift_count$$constant & 31; 12646 int s = 31 - lshift; 12647 int r = (rshift - lshift) & 31; 12648 __ sbfmw(as_Register($dst$$reg), 12649 as_Register($src$$reg), 12650 r, s); 12651 %} 12652 12653 ins_pipe(ialu_reg_shift); 12654 %} 12655 12656 // This pattern is automatically generated from aarch64_ad.m4 12657 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12658 12659 // Shift Left followed by Shift Right. 12660 // This idiom is used by the compiler for the i2b bytecode etc. 12661 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12662 %{ 12663 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12664 ins_cost(INSN_COST * 2); 12665 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12666 ins_encode %{ 12667 int lshift = $lshift_count$$constant & 63; 12668 int rshift = $rshift_count$$constant & 63; 12669 int s = 63 - lshift; 12670 int r = (rshift - lshift) & 63; 12671 __ ubfm(as_Register($dst$$reg), 12672 as_Register($src$$reg), 12673 r, s); 12674 %} 12675 12676 ins_pipe(ialu_reg_shift); 12677 %} 12678 12679 // This pattern is automatically generated from aarch64_ad.m4 12680 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12681 12682 // Shift Left followed by Shift Right. 12683 // This idiom is used by the compiler for the i2b bytecode etc. 12684 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12685 %{ 12686 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12687 ins_cost(INSN_COST * 2); 12688 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12689 ins_encode %{ 12690 int lshift = $lshift_count$$constant & 31; 12691 int rshift = $rshift_count$$constant & 31; 12692 int s = 31 - lshift; 12693 int r = (rshift - lshift) & 31; 12694 __ ubfmw(as_Register($dst$$reg), 12695 as_Register($src$$reg), 12696 r, s); 12697 %} 12698 12699 ins_pipe(ialu_reg_shift); 12700 %} 12701 12702 // Bitfield extract with shift & mask 12703 12704 // This pattern is automatically generated from aarch64_ad.m4 12705 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12706 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12707 %{ 12708 match(Set dst (AndI (URShiftI src rshift) mask)); 12709 // Make sure we are not going to exceed what ubfxw can do. 12710 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12711 12712 ins_cost(INSN_COST); 12713 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12714 ins_encode %{ 12715 int rshift = $rshift$$constant & 31; 12716 intptr_t mask = $mask$$constant; 12717 int width = exact_log2(mask+1); 12718 __ ubfxw(as_Register($dst$$reg), 12719 as_Register($src$$reg), rshift, width); 12720 %} 12721 ins_pipe(ialu_reg_shift); 12722 %} 12723 12724 // This pattern is automatically generated from aarch64_ad.m4 12725 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12726 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12727 %{ 12728 match(Set dst (AndL (URShiftL src rshift) mask)); 12729 // Make sure we are not going to exceed what ubfx can do. 12730 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12731 12732 ins_cost(INSN_COST); 12733 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12734 ins_encode %{ 12735 int rshift = $rshift$$constant & 63; 12736 intptr_t mask = $mask$$constant; 12737 int width = exact_log2_long(mask+1); 12738 __ ubfx(as_Register($dst$$reg), 12739 as_Register($src$$reg), rshift, width); 12740 %} 12741 ins_pipe(ialu_reg_shift); 12742 %} 12743 12744 12745 // This pattern is automatically generated from aarch64_ad.m4 12746 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12747 12748 // We can use ubfx when extending an And with a mask when we know mask 12749 // is positive. We know that because immI_bitmask guarantees it. 12750 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12751 %{ 12752 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12753 // Make sure we are not going to exceed what ubfxw can do. 12754 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12755 12756 ins_cost(INSN_COST * 2); 12757 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12758 ins_encode %{ 12759 int rshift = $rshift$$constant & 31; 12760 intptr_t mask = $mask$$constant; 12761 int width = exact_log2(mask+1); 12762 __ ubfx(as_Register($dst$$reg), 12763 as_Register($src$$reg), rshift, width); 12764 %} 12765 ins_pipe(ialu_reg_shift); 12766 %} 12767 12768 12769 // This pattern is automatically generated from aarch64_ad.m4 12770 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12771 12772 // We can use ubfiz when masking by a positive number and then left shifting the result. 12773 // We know that the mask is positive because immI_bitmask guarantees it. 12774 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12775 %{ 12776 match(Set dst (LShiftI (AndI src mask) lshift)); 12777 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12778 12779 ins_cost(INSN_COST); 12780 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12781 ins_encode %{ 12782 int lshift = $lshift$$constant & 31; 12783 intptr_t mask = $mask$$constant; 12784 int width = exact_log2(mask+1); 12785 __ ubfizw(as_Register($dst$$reg), 12786 as_Register($src$$reg), lshift, width); 12787 %} 12788 ins_pipe(ialu_reg_shift); 12789 %} 12790 12791 // This pattern is automatically generated from aarch64_ad.m4 12792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12793 12794 // We can use ubfiz when masking by a positive number and then left shifting the result. 12795 // We know that the mask is positive because immL_bitmask guarantees it. 12796 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12797 %{ 12798 match(Set dst (LShiftL (AndL src mask) lshift)); 12799 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12800 12801 ins_cost(INSN_COST); 12802 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12803 ins_encode %{ 12804 int lshift = $lshift$$constant & 63; 12805 intptr_t mask = $mask$$constant; 12806 int width = exact_log2_long(mask+1); 12807 __ ubfiz(as_Register($dst$$reg), 12808 as_Register($src$$reg), lshift, width); 12809 %} 12810 ins_pipe(ialu_reg_shift); 12811 %} 12812 12813 // This pattern is automatically generated from aarch64_ad.m4 12814 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12815 12816 // We can use ubfiz when masking by a positive number and then left shifting the result. 12817 // We know that the mask is positive because immI_bitmask guarantees it. 12818 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12819 %{ 12820 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12821 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12822 12823 ins_cost(INSN_COST); 12824 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12825 ins_encode %{ 12826 int lshift = $lshift$$constant & 31; 12827 intptr_t mask = $mask$$constant; 12828 int width = exact_log2(mask+1); 12829 __ ubfizw(as_Register($dst$$reg), 12830 as_Register($src$$reg), lshift, width); 12831 %} 12832 ins_pipe(ialu_reg_shift); 12833 %} 12834 12835 // This pattern is automatically generated from aarch64_ad.m4 12836 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12837 12838 // We can use ubfiz when masking by a positive number and then left shifting the result. 12839 // We know that the mask is positive because immL_bitmask guarantees it. 12840 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12841 %{ 12842 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12843 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12844 12845 ins_cost(INSN_COST); 12846 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12847 ins_encode %{ 12848 int lshift = $lshift$$constant & 63; 12849 intptr_t mask = $mask$$constant; 12850 int width = exact_log2_long(mask+1); 12851 __ ubfiz(as_Register($dst$$reg), 12852 as_Register($src$$reg), lshift, width); 12853 %} 12854 ins_pipe(ialu_reg_shift); 12855 %} 12856 12857 12858 // This pattern is automatically generated from aarch64_ad.m4 12859 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12860 12861 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12862 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12863 %{ 12864 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12865 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12866 12867 ins_cost(INSN_COST); 12868 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12869 ins_encode %{ 12870 int lshift = $lshift$$constant & 63; 12871 intptr_t mask = $mask$$constant; 12872 int width = exact_log2(mask+1); 12873 __ ubfiz(as_Register($dst$$reg), 12874 as_Register($src$$reg), lshift, width); 12875 %} 12876 ins_pipe(ialu_reg_shift); 12877 %} 12878 12879 // This pattern is automatically generated from aarch64_ad.m4 12880 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12881 12882 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12883 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12884 %{ 12885 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12886 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12887 12888 ins_cost(INSN_COST); 12889 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12890 ins_encode %{ 12891 int lshift = $lshift$$constant & 31; 12892 intptr_t mask = $mask$$constant; 12893 int width = exact_log2(mask+1); 12894 __ ubfiz(as_Register($dst$$reg), 12895 as_Register($src$$reg), lshift, width); 12896 %} 12897 ins_pipe(ialu_reg_shift); 12898 %} 12899 12900 // This pattern is automatically generated from aarch64_ad.m4 12901 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12902 12903 // Can skip int2long conversions after AND with small bitmask 12904 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12905 %{ 12906 match(Set dst (ConvI2L (AndI src msk))); 12907 ins_cost(INSN_COST); 12908 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12909 ins_encode %{ 12910 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12911 %} 12912 ins_pipe(ialu_reg_shift); 12913 %} 12914 12915 12916 // Rotations 12917 12918 // This pattern is automatically generated from aarch64_ad.m4 12919 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12920 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12921 %{ 12922 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12923 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12924 12925 ins_cost(INSN_COST); 12926 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12927 12928 ins_encode %{ 12929 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12930 $rshift$$constant & 63); 12931 %} 12932 ins_pipe(ialu_reg_reg_extr); 12933 %} 12934 12935 12936 // This pattern is automatically generated from aarch64_ad.m4 12937 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12938 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12939 %{ 12940 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12941 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12942 12943 ins_cost(INSN_COST); 12944 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12945 12946 ins_encode %{ 12947 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12948 $rshift$$constant & 31); 12949 %} 12950 ins_pipe(ialu_reg_reg_extr); 12951 %} 12952 12953 12954 // This pattern is automatically generated from aarch64_ad.m4 12955 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12956 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12957 %{ 12958 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12959 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12960 12961 ins_cost(INSN_COST); 12962 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12963 12964 ins_encode %{ 12965 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12966 $rshift$$constant & 63); 12967 %} 12968 ins_pipe(ialu_reg_reg_extr); 12969 %} 12970 12971 12972 // This pattern is automatically generated from aarch64_ad.m4 12973 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12974 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12975 %{ 12976 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12977 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12978 12979 ins_cost(INSN_COST); 12980 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12981 12982 ins_encode %{ 12983 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12984 $rshift$$constant & 31); 12985 %} 12986 ins_pipe(ialu_reg_reg_extr); 12987 %} 12988 12989 // This pattern is automatically generated from aarch64_ad.m4 12990 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12991 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift) 12992 %{ 12993 match(Set dst (RotateRight src shift)); 12994 12995 ins_cost(INSN_COST); 12996 format %{ "ror $dst, $src, $shift" %} 12997 12998 ins_encode %{ 12999 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13000 $shift$$constant & 0x1f); 13001 %} 13002 ins_pipe(ialu_reg_reg_vshift); 13003 %} 13004 13005 // This pattern is automatically generated from aarch64_ad.m4 13006 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13007 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift) 13008 %{ 13009 match(Set dst (RotateRight src shift)); 13010 13011 ins_cost(INSN_COST); 13012 format %{ "ror $dst, $src, $shift" %} 13013 13014 ins_encode %{ 13015 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13016 $shift$$constant & 0x3f); 13017 %} 13018 ins_pipe(ialu_reg_reg_vshift); 13019 %} 13020 13021 // This pattern is automatically generated from aarch64_ad.m4 13022 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13023 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13024 %{ 13025 match(Set dst (RotateRight src shift)); 13026 13027 ins_cost(INSN_COST); 13028 format %{ "ror $dst, $src, $shift" %} 13029 13030 ins_encode %{ 13031 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13032 %} 13033 ins_pipe(ialu_reg_reg_vshift); 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 rorL_reg(iRegLNoSp dst, iRegL src, iRegI 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 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13047 %} 13048 ins_pipe(ialu_reg_reg_vshift); 13049 %} 13050 13051 // This pattern is automatically generated from aarch64_ad.m4 13052 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13053 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13054 %{ 13055 match(Set dst (RotateLeft src shift)); 13056 13057 ins_cost(INSN_COST); 13058 format %{ "rol $dst, $src, $shift" %} 13059 13060 ins_encode %{ 13061 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13062 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13063 %} 13064 ins_pipe(ialu_reg_reg_vshift); 13065 %} 13066 13067 // This pattern is automatically generated from aarch64_ad.m4 13068 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13069 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13070 %{ 13071 match(Set dst (RotateLeft src shift)); 13072 13073 ins_cost(INSN_COST); 13074 format %{ "rol $dst, $src, $shift" %} 13075 13076 ins_encode %{ 13077 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13078 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13079 %} 13080 ins_pipe(ialu_reg_reg_vshift); 13081 %} 13082 13083 13084 // Add/subtract (extended) 13085 13086 // This pattern is automatically generated from aarch64_ad.m4 13087 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13088 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13089 %{ 13090 match(Set dst (AddL src1 (ConvI2L src2))); 13091 ins_cost(INSN_COST); 13092 format %{ "add $dst, $src1, $src2, sxtw" %} 13093 13094 ins_encode %{ 13095 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13096 as_Register($src2$$reg), ext::sxtw); 13097 %} 13098 ins_pipe(ialu_reg_reg); 13099 %} 13100 13101 // This pattern is automatically generated from aarch64_ad.m4 13102 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13103 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13104 %{ 13105 match(Set dst (SubL src1 (ConvI2L src2))); 13106 ins_cost(INSN_COST); 13107 format %{ "sub $dst, $src1, $src2, sxtw" %} 13108 13109 ins_encode %{ 13110 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13111 as_Register($src2$$reg), ext::sxtw); 13112 %} 13113 ins_pipe(ialu_reg_reg); 13114 %} 13115 13116 // This pattern is automatically generated from aarch64_ad.m4 13117 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13118 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 13119 %{ 13120 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13121 ins_cost(INSN_COST); 13122 format %{ "add $dst, $src1, $src2, sxth" %} 13123 13124 ins_encode %{ 13125 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13126 as_Register($src2$$reg), ext::sxth); 13127 %} 13128 ins_pipe(ialu_reg_reg); 13129 %} 13130 13131 // This pattern is automatically generated from aarch64_ad.m4 13132 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13133 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13134 %{ 13135 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13136 ins_cost(INSN_COST); 13137 format %{ "add $dst, $src1, $src2, sxtb" %} 13138 13139 ins_encode %{ 13140 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13141 as_Register($src2$$reg), ext::sxtb); 13142 %} 13143 ins_pipe(ialu_reg_reg); 13144 %} 13145 13146 // This pattern is automatically generated from aarch64_ad.m4 13147 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13148 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13149 %{ 13150 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 13151 ins_cost(INSN_COST); 13152 format %{ "add $dst, $src1, $src2, uxtb" %} 13153 13154 ins_encode %{ 13155 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13156 as_Register($src2$$reg), ext::uxtb); 13157 %} 13158 ins_pipe(ialu_reg_reg); 13159 %} 13160 13161 // This pattern is automatically generated from aarch64_ad.m4 13162 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13163 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 13164 %{ 13165 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13166 ins_cost(INSN_COST); 13167 format %{ "add $dst, $src1, $src2, sxth" %} 13168 13169 ins_encode %{ 13170 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13171 as_Register($src2$$reg), ext::sxth); 13172 %} 13173 ins_pipe(ialu_reg_reg); 13174 %} 13175 13176 // This pattern is automatically generated from aarch64_ad.m4 13177 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13178 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 13179 %{ 13180 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13181 ins_cost(INSN_COST); 13182 format %{ "add $dst, $src1, $src2, sxtw" %} 13183 13184 ins_encode %{ 13185 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13186 as_Register($src2$$reg), ext::sxtw); 13187 %} 13188 ins_pipe(ialu_reg_reg); 13189 %} 13190 13191 // This pattern is automatically generated from aarch64_ad.m4 13192 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13193 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13194 %{ 13195 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13196 ins_cost(INSN_COST); 13197 format %{ "add $dst, $src1, $src2, sxtb" %} 13198 13199 ins_encode %{ 13200 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13201 as_Register($src2$$reg), ext::sxtb); 13202 %} 13203 ins_pipe(ialu_reg_reg); 13204 %} 13205 13206 // This pattern is automatically generated from aarch64_ad.m4 13207 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13208 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13209 %{ 13210 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 13211 ins_cost(INSN_COST); 13212 format %{ "add $dst, $src1, $src2, uxtb" %} 13213 13214 ins_encode %{ 13215 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13216 as_Register($src2$$reg), ext::uxtb); 13217 %} 13218 ins_pipe(ialu_reg_reg); 13219 %} 13220 13221 // This pattern is automatically generated from aarch64_ad.m4 13222 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13223 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13224 %{ 13225 match(Set dst (AddI src1 (AndI src2 mask))); 13226 ins_cost(INSN_COST); 13227 format %{ "addw $dst, $src1, $src2, uxtb" %} 13228 13229 ins_encode %{ 13230 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13231 as_Register($src2$$reg), ext::uxtb); 13232 %} 13233 ins_pipe(ialu_reg_reg); 13234 %} 13235 13236 // This pattern is automatically generated from aarch64_ad.m4 13237 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13238 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13239 %{ 13240 match(Set dst (AddI src1 (AndI src2 mask))); 13241 ins_cost(INSN_COST); 13242 format %{ "addw $dst, $src1, $src2, uxth" %} 13243 13244 ins_encode %{ 13245 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13246 as_Register($src2$$reg), ext::uxth); 13247 %} 13248 ins_pipe(ialu_reg_reg); 13249 %} 13250 13251 // This pattern is automatically generated from aarch64_ad.m4 13252 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13253 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13254 %{ 13255 match(Set dst (AddL src1 (AndL src2 mask))); 13256 ins_cost(INSN_COST); 13257 format %{ "add $dst, $src1, $src2, uxtb" %} 13258 13259 ins_encode %{ 13260 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13261 as_Register($src2$$reg), ext::uxtb); 13262 %} 13263 ins_pipe(ialu_reg_reg); 13264 %} 13265 13266 // This pattern is automatically generated from aarch64_ad.m4 13267 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13268 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13269 %{ 13270 match(Set dst (AddL src1 (AndL src2 mask))); 13271 ins_cost(INSN_COST); 13272 format %{ "add $dst, $src1, $src2, uxth" %} 13273 13274 ins_encode %{ 13275 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13276 as_Register($src2$$reg), ext::uxth); 13277 %} 13278 ins_pipe(ialu_reg_reg); 13279 %} 13280 13281 // This pattern is automatically generated from aarch64_ad.m4 13282 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13283 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13284 %{ 13285 match(Set dst (AddL src1 (AndL src2 mask))); 13286 ins_cost(INSN_COST); 13287 format %{ "add $dst, $src1, $src2, uxtw" %} 13288 13289 ins_encode %{ 13290 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13291 as_Register($src2$$reg), ext::uxtw); 13292 %} 13293 ins_pipe(ialu_reg_reg); 13294 %} 13295 13296 // This pattern is automatically generated from aarch64_ad.m4 13297 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13298 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13299 %{ 13300 match(Set dst (SubI src1 (AndI src2 mask))); 13301 ins_cost(INSN_COST); 13302 format %{ "subw $dst, $src1, $src2, uxtb" %} 13303 13304 ins_encode %{ 13305 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13306 as_Register($src2$$reg), ext::uxtb); 13307 %} 13308 ins_pipe(ialu_reg_reg); 13309 %} 13310 13311 // This pattern is automatically generated from aarch64_ad.m4 13312 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13313 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13314 %{ 13315 match(Set dst (SubI src1 (AndI src2 mask))); 13316 ins_cost(INSN_COST); 13317 format %{ "subw $dst, $src1, $src2, uxth" %} 13318 13319 ins_encode %{ 13320 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13321 as_Register($src2$$reg), ext::uxth); 13322 %} 13323 ins_pipe(ialu_reg_reg); 13324 %} 13325 13326 // This pattern is automatically generated from aarch64_ad.m4 13327 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13328 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13329 %{ 13330 match(Set dst (SubL src1 (AndL src2 mask))); 13331 ins_cost(INSN_COST); 13332 format %{ "sub $dst, $src1, $src2, uxtb" %} 13333 13334 ins_encode %{ 13335 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13336 as_Register($src2$$reg), ext::uxtb); 13337 %} 13338 ins_pipe(ialu_reg_reg); 13339 %} 13340 13341 // This pattern is automatically generated from aarch64_ad.m4 13342 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13343 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13344 %{ 13345 match(Set dst (SubL src1 (AndL src2 mask))); 13346 ins_cost(INSN_COST); 13347 format %{ "sub $dst, $src1, $src2, uxth" %} 13348 13349 ins_encode %{ 13350 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13351 as_Register($src2$$reg), ext::uxth); 13352 %} 13353 ins_pipe(ialu_reg_reg); 13354 %} 13355 13356 // This pattern is automatically generated from aarch64_ad.m4 13357 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13358 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13359 %{ 13360 match(Set dst (SubL src1 (AndL src2 mask))); 13361 ins_cost(INSN_COST); 13362 format %{ "sub $dst, $src1, $src2, uxtw" %} 13363 13364 ins_encode %{ 13365 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13366 as_Register($src2$$reg), ext::uxtw); 13367 %} 13368 ins_pipe(ialu_reg_reg); 13369 %} 13370 13371 13372 // This pattern is automatically generated from aarch64_ad.m4 13373 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13374 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13375 %{ 13376 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13377 ins_cost(1.9 * INSN_COST); 13378 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 13379 13380 ins_encode %{ 13381 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13382 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13383 %} 13384 ins_pipe(ialu_reg_reg_shift); 13385 %} 13386 13387 // This pattern is automatically generated from aarch64_ad.m4 13388 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13389 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13390 %{ 13391 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13392 ins_cost(1.9 * INSN_COST); 13393 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 13394 13395 ins_encode %{ 13396 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13397 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13398 %} 13399 ins_pipe(ialu_reg_reg_shift); 13400 %} 13401 13402 // This pattern is automatically generated from aarch64_ad.m4 13403 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13404 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13405 %{ 13406 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13407 ins_cost(1.9 * INSN_COST); 13408 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 13409 13410 ins_encode %{ 13411 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13412 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13413 %} 13414 ins_pipe(ialu_reg_reg_shift); 13415 %} 13416 13417 // This pattern is automatically generated from aarch64_ad.m4 13418 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13419 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13420 %{ 13421 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13422 ins_cost(1.9 * INSN_COST); 13423 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 13424 13425 ins_encode %{ 13426 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13427 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13428 %} 13429 ins_pipe(ialu_reg_reg_shift); 13430 %} 13431 13432 // This pattern is automatically generated from aarch64_ad.m4 13433 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13434 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13435 %{ 13436 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13437 ins_cost(1.9 * INSN_COST); 13438 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 13439 13440 ins_encode %{ 13441 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13442 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13443 %} 13444 ins_pipe(ialu_reg_reg_shift); 13445 %} 13446 13447 // This pattern is automatically generated from aarch64_ad.m4 13448 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13449 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13450 %{ 13451 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13452 ins_cost(1.9 * INSN_COST); 13453 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 13454 13455 ins_encode %{ 13456 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13457 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13458 %} 13459 ins_pipe(ialu_reg_reg_shift); 13460 %} 13461 13462 // This pattern is automatically generated from aarch64_ad.m4 13463 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13464 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13465 %{ 13466 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13467 ins_cost(1.9 * INSN_COST); 13468 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 13469 13470 ins_encode %{ 13471 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13472 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13473 %} 13474 ins_pipe(ialu_reg_reg_shift); 13475 %} 13476 13477 // This pattern is automatically generated from aarch64_ad.m4 13478 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13479 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13480 %{ 13481 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13482 ins_cost(1.9 * INSN_COST); 13483 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 13484 13485 ins_encode %{ 13486 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13487 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13488 %} 13489 ins_pipe(ialu_reg_reg_shift); 13490 %} 13491 13492 // This pattern is automatically generated from aarch64_ad.m4 13493 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13494 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13495 %{ 13496 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13497 ins_cost(1.9 * INSN_COST); 13498 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 13499 13500 ins_encode %{ 13501 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13502 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13503 %} 13504 ins_pipe(ialu_reg_reg_shift); 13505 %} 13506 13507 // This pattern is automatically generated from aarch64_ad.m4 13508 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13509 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13510 %{ 13511 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13512 ins_cost(1.9 * INSN_COST); 13513 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 13514 13515 ins_encode %{ 13516 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13517 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13518 %} 13519 ins_pipe(ialu_reg_reg_shift); 13520 %} 13521 13522 // This pattern is automatically generated from aarch64_ad.m4 13523 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13524 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13525 %{ 13526 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 13527 ins_cost(1.9 * INSN_COST); 13528 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 13529 13530 ins_encode %{ 13531 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13532 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13533 %} 13534 ins_pipe(ialu_reg_reg_shift); 13535 %} 13536 13537 // This pattern is automatically generated from aarch64_ad.m4 13538 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13539 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13540 %{ 13541 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 13542 ins_cost(1.9 * INSN_COST); 13543 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 13544 13545 ins_encode %{ 13546 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13547 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13548 %} 13549 ins_pipe(ialu_reg_reg_shift); 13550 %} 13551 13552 // This pattern is automatically generated from aarch64_ad.m4 13553 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13554 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13555 %{ 13556 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13557 ins_cost(1.9 * INSN_COST); 13558 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 13559 13560 ins_encode %{ 13561 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13562 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13563 %} 13564 ins_pipe(ialu_reg_reg_shift); 13565 %} 13566 13567 // This pattern is automatically generated from aarch64_ad.m4 13568 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13569 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13570 %{ 13571 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13572 ins_cost(1.9 * INSN_COST); 13573 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 13574 13575 ins_encode %{ 13576 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13577 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13578 %} 13579 ins_pipe(ialu_reg_reg_shift); 13580 %} 13581 13582 // This pattern is automatically generated from aarch64_ad.m4 13583 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13584 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13585 %{ 13586 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13587 ins_cost(1.9 * INSN_COST); 13588 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13589 13590 ins_encode %{ 13591 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13592 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13593 %} 13594 ins_pipe(ialu_reg_reg_shift); 13595 %} 13596 13597 // This pattern is automatically generated from aarch64_ad.m4 13598 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13599 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13600 %{ 13601 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13602 ins_cost(1.9 * INSN_COST); 13603 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13604 13605 ins_encode %{ 13606 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13607 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13608 %} 13609 ins_pipe(ialu_reg_reg_shift); 13610 %} 13611 13612 // This pattern is automatically generated from aarch64_ad.m4 13613 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13614 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13615 %{ 13616 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13617 ins_cost(1.9 * INSN_COST); 13618 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13619 13620 ins_encode %{ 13621 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13622 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13623 %} 13624 ins_pipe(ialu_reg_reg_shift); 13625 %} 13626 13627 // This pattern is automatically generated from aarch64_ad.m4 13628 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13629 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13630 %{ 13631 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13632 ins_cost(1.9 * INSN_COST); 13633 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13634 13635 ins_encode %{ 13636 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13637 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13638 %} 13639 ins_pipe(ialu_reg_reg_shift); 13640 %} 13641 13642 // This pattern is automatically generated from aarch64_ad.m4 13643 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13644 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13645 %{ 13646 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13647 ins_cost(1.9 * INSN_COST); 13648 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13649 13650 ins_encode %{ 13651 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13652 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13653 %} 13654 ins_pipe(ialu_reg_reg_shift); 13655 %} 13656 13657 // This pattern is automatically generated from aarch64_ad.m4 13658 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13659 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13660 %{ 13661 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13662 ins_cost(1.9 * INSN_COST); 13663 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13664 13665 ins_encode %{ 13666 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13667 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13668 %} 13669 ins_pipe(ialu_reg_reg_shift); 13670 %} 13671 13672 // This pattern is automatically generated from aarch64_ad.m4 13673 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13674 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13675 %{ 13676 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13677 ins_cost(1.9 * INSN_COST); 13678 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13679 13680 ins_encode %{ 13681 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13682 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13683 %} 13684 ins_pipe(ialu_reg_reg_shift); 13685 %} 13686 13687 // This pattern is automatically generated from aarch64_ad.m4 13688 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13689 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13690 %{ 13691 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13692 ins_cost(1.9 * INSN_COST); 13693 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13694 13695 ins_encode %{ 13696 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13697 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13698 %} 13699 ins_pipe(ialu_reg_reg_shift); 13700 %} 13701 13702 // This pattern is automatically generated from aarch64_ad.m4 13703 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13704 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13705 %{ 13706 effect(DEF dst, USE src1, USE src2, USE cr); 13707 ins_cost(INSN_COST * 2); 13708 format %{ "cselw $dst, $src1, $src2 lt\t" %} 13709 13710 ins_encode %{ 13711 __ cselw($dst$$Register, 13712 $src1$$Register, 13713 $src2$$Register, 13714 Assembler::LT); 13715 %} 13716 ins_pipe(icond_reg_reg); 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 cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13722 %{ 13723 effect(DEF dst, USE src1, USE src2, USE cr); 13724 ins_cost(INSN_COST * 2); 13725 format %{ "cselw $dst, $src1, $src2 gt\t" %} 13726 13727 ins_encode %{ 13728 __ cselw($dst$$Register, 13729 $src1$$Register, 13730 $src2$$Register, 13731 Assembler::GT); 13732 %} 13733 ins_pipe(icond_reg_reg); 13734 %} 13735 13736 // This pattern is automatically generated from aarch64_ad.m4 13737 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13738 instruct cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13739 %{ 13740 effect(DEF dst, USE src1, USE cr); 13741 ins_cost(INSN_COST * 2); 13742 format %{ "cselw $dst, $src1, zr lt\t" %} 13743 13744 ins_encode %{ 13745 __ cselw($dst$$Register, 13746 $src1$$Register, 13747 zr, 13748 Assembler::LT); 13749 %} 13750 ins_pipe(icond_reg); 13751 %} 13752 13753 // This pattern is automatically generated from aarch64_ad.m4 13754 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13755 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13756 %{ 13757 effect(DEF dst, USE src1, USE cr); 13758 ins_cost(INSN_COST * 2); 13759 format %{ "cselw $dst, $src1, zr gt\t" %} 13760 13761 ins_encode %{ 13762 __ cselw($dst$$Register, 13763 $src1$$Register, 13764 zr, 13765 Assembler::GT); 13766 %} 13767 ins_pipe(icond_reg); 13768 %} 13769 13770 // This pattern is automatically generated from aarch64_ad.m4 13771 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13772 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13773 %{ 13774 effect(DEF dst, USE src1, USE cr); 13775 ins_cost(INSN_COST * 2); 13776 format %{ "csincw $dst, $src1, zr le\t" %} 13777 13778 ins_encode %{ 13779 __ csincw($dst$$Register, 13780 $src1$$Register, 13781 zr, 13782 Assembler::LE); 13783 %} 13784 ins_pipe(icond_reg); 13785 %} 13786 13787 // This pattern is automatically generated from aarch64_ad.m4 13788 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13789 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13790 %{ 13791 effect(DEF dst, USE src1, USE cr); 13792 ins_cost(INSN_COST * 2); 13793 format %{ "csincw $dst, $src1, zr gt\t" %} 13794 13795 ins_encode %{ 13796 __ csincw($dst$$Register, 13797 $src1$$Register, 13798 zr, 13799 Assembler::GT); 13800 %} 13801 ins_pipe(icond_reg); 13802 %} 13803 13804 // This pattern is automatically generated from aarch64_ad.m4 13805 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13806 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13807 %{ 13808 effect(DEF dst, USE src1, USE cr); 13809 ins_cost(INSN_COST * 2); 13810 format %{ "csinvw $dst, $src1, zr lt\t" %} 13811 13812 ins_encode %{ 13813 __ csinvw($dst$$Register, 13814 $src1$$Register, 13815 zr, 13816 Assembler::LT); 13817 %} 13818 ins_pipe(icond_reg); 13819 %} 13820 13821 // This pattern is automatically generated from aarch64_ad.m4 13822 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13823 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13824 %{ 13825 effect(DEF dst, USE src1, USE cr); 13826 ins_cost(INSN_COST * 2); 13827 format %{ "csinvw $dst, $src1, zr ge\t" %} 13828 13829 ins_encode %{ 13830 __ csinvw($dst$$Register, 13831 $src1$$Register, 13832 zr, 13833 Assembler::GE); 13834 %} 13835 ins_pipe(icond_reg); 13836 %} 13837 13838 // This pattern is automatically generated from aarch64_ad.m4 13839 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13840 instruct minI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13841 %{ 13842 match(Set dst (MinI src imm)); 13843 ins_cost(INSN_COST * 3); 13844 expand %{ 13845 rFlagsReg cr; 13846 compI_reg_imm0(cr, src); 13847 cmovI_reg_imm0_lt(dst, src, cr); 13848 %} 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 minI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13854 %{ 13855 match(Set dst (MinI imm src)); 13856 ins_cost(INSN_COST * 3); 13857 expand %{ 13858 rFlagsReg cr; 13859 compI_reg_imm0(cr, src); 13860 cmovI_reg_imm0_lt(dst, src, cr); 13861 %} 13862 %} 13863 13864 // This pattern is automatically generated from aarch64_ad.m4 13865 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13866 instruct minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13867 %{ 13868 match(Set dst (MinI src imm)); 13869 ins_cost(INSN_COST * 3); 13870 expand %{ 13871 rFlagsReg cr; 13872 compI_reg_imm0(cr, src); 13873 cmovI_reg_imm1_le(dst, src, cr); 13874 %} 13875 %} 13876 13877 // This pattern is automatically generated from aarch64_ad.m4 13878 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13879 instruct minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13880 %{ 13881 match(Set dst (MinI imm src)); 13882 ins_cost(INSN_COST * 3); 13883 expand %{ 13884 rFlagsReg cr; 13885 compI_reg_imm0(cr, src); 13886 cmovI_reg_imm1_le(dst, src, cr); 13887 %} 13888 %} 13889 13890 // This pattern is automatically generated from aarch64_ad.m4 13891 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13892 instruct minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13893 %{ 13894 match(Set dst (MinI src imm)); 13895 ins_cost(INSN_COST * 3); 13896 expand %{ 13897 rFlagsReg cr; 13898 compI_reg_imm0(cr, src); 13899 cmovI_reg_immM1_lt(dst, src, cr); 13900 %} 13901 %} 13902 13903 // This pattern is automatically generated from aarch64_ad.m4 13904 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13905 instruct minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13906 %{ 13907 match(Set dst (MinI imm src)); 13908 ins_cost(INSN_COST * 3); 13909 expand %{ 13910 rFlagsReg cr; 13911 compI_reg_imm0(cr, src); 13912 cmovI_reg_immM1_lt(dst, src, cr); 13913 %} 13914 %} 13915 13916 // This pattern is automatically generated from aarch64_ad.m4 13917 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13918 instruct maxI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13919 %{ 13920 match(Set dst (MaxI src imm)); 13921 ins_cost(INSN_COST * 3); 13922 expand %{ 13923 rFlagsReg cr; 13924 compI_reg_imm0(cr, src); 13925 cmovI_reg_imm0_gt(dst, src, cr); 13926 %} 13927 %} 13928 13929 // This pattern is automatically generated from aarch64_ad.m4 13930 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13931 instruct maxI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13932 %{ 13933 match(Set dst (MaxI imm src)); 13934 ins_cost(INSN_COST * 3); 13935 expand %{ 13936 rFlagsReg cr; 13937 compI_reg_imm0(cr, src); 13938 cmovI_reg_imm0_gt(dst, src, cr); 13939 %} 13940 %} 13941 13942 // This pattern is automatically generated from aarch64_ad.m4 13943 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13944 instruct maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13945 %{ 13946 match(Set dst (MaxI src imm)); 13947 ins_cost(INSN_COST * 3); 13948 expand %{ 13949 rFlagsReg cr; 13950 compI_reg_imm0(cr, src); 13951 cmovI_reg_imm1_gt(dst, src, cr); 13952 %} 13953 %} 13954 13955 // This pattern is automatically generated from aarch64_ad.m4 13956 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13957 instruct maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13958 %{ 13959 match(Set dst (MaxI imm src)); 13960 ins_cost(INSN_COST * 3); 13961 expand %{ 13962 rFlagsReg cr; 13963 compI_reg_imm0(cr, src); 13964 cmovI_reg_imm1_gt(dst, src, cr); 13965 %} 13966 %} 13967 13968 // This pattern is automatically generated from aarch64_ad.m4 13969 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13970 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13971 %{ 13972 match(Set dst (MaxI src imm)); 13973 ins_cost(INSN_COST * 3); 13974 expand %{ 13975 rFlagsReg cr; 13976 compI_reg_imm0(cr, src); 13977 cmovI_reg_immM1_ge(dst, src, cr); 13978 %} 13979 %} 13980 13981 // This pattern is automatically generated from aarch64_ad.m4 13982 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13983 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13984 %{ 13985 match(Set dst (MaxI imm src)); 13986 ins_cost(INSN_COST * 3); 13987 expand %{ 13988 rFlagsReg cr; 13989 compI_reg_imm0(cr, src); 13990 cmovI_reg_immM1_ge(dst, src, cr); 13991 %} 13992 %} 13993 13994 // This pattern is automatically generated from aarch64_ad.m4 13995 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13996 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src) 13997 %{ 13998 match(Set dst (ReverseI src)); 13999 ins_cost(INSN_COST); 14000 format %{ "rbitw $dst, $src" %} 14001 ins_encode %{ 14002 __ rbitw($dst$$Register, $src$$Register); 14003 %} 14004 ins_pipe(ialu_reg); 14005 %} 14006 14007 // This pattern is automatically generated from aarch64_ad.m4 14008 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14009 instruct bits_reverse_L(iRegLNoSp dst, iRegL src) 14010 %{ 14011 match(Set dst (ReverseL src)); 14012 ins_cost(INSN_COST); 14013 format %{ "rbit $dst, $src" %} 14014 ins_encode %{ 14015 __ rbit($dst$$Register, $src$$Register); 14016 %} 14017 ins_pipe(ialu_reg); 14018 %} 14019 14020 14021 // END This section of the file is automatically generated. Do not edit -------------- 14022 14023 14024 // ============================================================================ 14025 // Floating Point Arithmetic Instructions 14026 14027 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14028 match(Set dst (AddF src1 src2)); 14029 14030 ins_cost(INSN_COST * 5); 14031 format %{ "fadds $dst, $src1, $src2" %} 14032 14033 ins_encode %{ 14034 __ fadds(as_FloatRegister($dst$$reg), 14035 as_FloatRegister($src1$$reg), 14036 as_FloatRegister($src2$$reg)); 14037 %} 14038 14039 ins_pipe(fp_dop_reg_reg_s); 14040 %} 14041 14042 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14043 match(Set dst (AddD src1 src2)); 14044 14045 ins_cost(INSN_COST * 5); 14046 format %{ "faddd $dst, $src1, $src2" %} 14047 14048 ins_encode %{ 14049 __ faddd(as_FloatRegister($dst$$reg), 14050 as_FloatRegister($src1$$reg), 14051 as_FloatRegister($src2$$reg)); 14052 %} 14053 14054 ins_pipe(fp_dop_reg_reg_d); 14055 %} 14056 14057 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14058 match(Set dst (SubF src1 src2)); 14059 14060 ins_cost(INSN_COST * 5); 14061 format %{ "fsubs $dst, $src1, $src2" %} 14062 14063 ins_encode %{ 14064 __ fsubs(as_FloatRegister($dst$$reg), 14065 as_FloatRegister($src1$$reg), 14066 as_FloatRegister($src2$$reg)); 14067 %} 14068 14069 ins_pipe(fp_dop_reg_reg_s); 14070 %} 14071 14072 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14073 match(Set dst (SubD src1 src2)); 14074 14075 ins_cost(INSN_COST * 5); 14076 format %{ "fsubd $dst, $src1, $src2" %} 14077 14078 ins_encode %{ 14079 __ fsubd(as_FloatRegister($dst$$reg), 14080 as_FloatRegister($src1$$reg), 14081 as_FloatRegister($src2$$reg)); 14082 %} 14083 14084 ins_pipe(fp_dop_reg_reg_d); 14085 %} 14086 14087 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14088 match(Set dst (MulF src1 src2)); 14089 14090 ins_cost(INSN_COST * 6); 14091 format %{ "fmuls $dst, $src1, $src2" %} 14092 14093 ins_encode %{ 14094 __ fmuls(as_FloatRegister($dst$$reg), 14095 as_FloatRegister($src1$$reg), 14096 as_FloatRegister($src2$$reg)); 14097 %} 14098 14099 ins_pipe(fp_dop_reg_reg_s); 14100 %} 14101 14102 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14103 match(Set dst (MulD src1 src2)); 14104 14105 ins_cost(INSN_COST * 6); 14106 format %{ "fmuld $dst, $src1, $src2" %} 14107 14108 ins_encode %{ 14109 __ fmuld(as_FloatRegister($dst$$reg), 14110 as_FloatRegister($src1$$reg), 14111 as_FloatRegister($src2$$reg)); 14112 %} 14113 14114 ins_pipe(fp_dop_reg_reg_d); 14115 %} 14116 14117 // src1 * src2 + src3 14118 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14119 match(Set dst (FmaF src3 (Binary src1 src2))); 14120 14121 format %{ "fmadds $dst, $src1, $src2, $src3" %} 14122 14123 ins_encode %{ 14124 assert(UseFMA, "Needs FMA instructions support."); 14125 __ fmadds(as_FloatRegister($dst$$reg), 14126 as_FloatRegister($src1$$reg), 14127 as_FloatRegister($src2$$reg), 14128 as_FloatRegister($src3$$reg)); 14129 %} 14130 14131 ins_pipe(pipe_class_default); 14132 %} 14133 14134 // src1 * src2 + src3 14135 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14136 match(Set dst (FmaD src3 (Binary src1 src2))); 14137 14138 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 14139 14140 ins_encode %{ 14141 assert(UseFMA, "Needs FMA instructions support."); 14142 __ fmaddd(as_FloatRegister($dst$$reg), 14143 as_FloatRegister($src1$$reg), 14144 as_FloatRegister($src2$$reg), 14145 as_FloatRegister($src3$$reg)); 14146 %} 14147 14148 ins_pipe(pipe_class_default); 14149 %} 14150 14151 // src1 * (-src2) + src3 14152 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14153 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14154 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 14155 14156 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 14157 14158 ins_encode %{ 14159 assert(UseFMA, "Needs FMA instructions support."); 14160 __ fmsubs(as_FloatRegister($dst$$reg), 14161 as_FloatRegister($src1$$reg), 14162 as_FloatRegister($src2$$reg), 14163 as_FloatRegister($src3$$reg)); 14164 %} 14165 14166 ins_pipe(pipe_class_default); 14167 %} 14168 14169 // src1 * (-src2) + src3 14170 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14171 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14172 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 14173 14174 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 14175 14176 ins_encode %{ 14177 assert(UseFMA, "Needs FMA instructions support."); 14178 __ fmsubd(as_FloatRegister($dst$$reg), 14179 as_FloatRegister($src1$$reg), 14180 as_FloatRegister($src2$$reg), 14181 as_FloatRegister($src3$$reg)); 14182 %} 14183 14184 ins_pipe(pipe_class_default); 14185 %} 14186 14187 // src1 * (-src2) - src3 14188 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14189 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14190 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 14191 14192 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 14193 14194 ins_encode %{ 14195 assert(UseFMA, "Needs FMA instructions support."); 14196 __ fnmadds(as_FloatRegister($dst$$reg), 14197 as_FloatRegister($src1$$reg), 14198 as_FloatRegister($src2$$reg), 14199 as_FloatRegister($src3$$reg)); 14200 %} 14201 14202 ins_pipe(pipe_class_default); 14203 %} 14204 14205 // src1 * (-src2) - src3 14206 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14207 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14208 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 14209 14210 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 14211 14212 ins_encode %{ 14213 assert(UseFMA, "Needs FMA instructions support."); 14214 __ fnmaddd(as_FloatRegister($dst$$reg), 14215 as_FloatRegister($src1$$reg), 14216 as_FloatRegister($src2$$reg), 14217 as_FloatRegister($src3$$reg)); 14218 %} 14219 14220 ins_pipe(pipe_class_default); 14221 %} 14222 14223 // src1 * src2 - src3 14224 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 14225 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 14226 14227 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 14228 14229 ins_encode %{ 14230 assert(UseFMA, "Needs FMA instructions support."); 14231 __ fnmsubs(as_FloatRegister($dst$$reg), 14232 as_FloatRegister($src1$$reg), 14233 as_FloatRegister($src2$$reg), 14234 as_FloatRegister($src3$$reg)); 14235 %} 14236 14237 ins_pipe(pipe_class_default); 14238 %} 14239 14240 // src1 * src2 - src3 14241 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 14242 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 14243 14244 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 14245 14246 ins_encode %{ 14247 assert(UseFMA, "Needs FMA instructions support."); 14248 // n.b. insn name should be fnmsubd 14249 __ fnmsub(as_FloatRegister($dst$$reg), 14250 as_FloatRegister($src1$$reg), 14251 as_FloatRegister($src2$$reg), 14252 as_FloatRegister($src3$$reg)); 14253 %} 14254 14255 ins_pipe(pipe_class_default); 14256 %} 14257 14258 14259 // Math.max(FF)F 14260 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14261 match(Set dst (MaxF src1 src2)); 14262 14263 format %{ "fmaxs $dst, $src1, $src2" %} 14264 ins_encode %{ 14265 __ fmaxs(as_FloatRegister($dst$$reg), 14266 as_FloatRegister($src1$$reg), 14267 as_FloatRegister($src2$$reg)); 14268 %} 14269 14270 ins_pipe(fp_dop_reg_reg_s); 14271 %} 14272 14273 // Math.min(FF)F 14274 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14275 match(Set dst (MinF src1 src2)); 14276 14277 format %{ "fmins $dst, $src1, $src2" %} 14278 ins_encode %{ 14279 __ fmins(as_FloatRegister($dst$$reg), 14280 as_FloatRegister($src1$$reg), 14281 as_FloatRegister($src2$$reg)); 14282 %} 14283 14284 ins_pipe(fp_dop_reg_reg_s); 14285 %} 14286 14287 // Math.max(DD)D 14288 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14289 match(Set dst (MaxD src1 src2)); 14290 14291 format %{ "fmaxd $dst, $src1, $src2" %} 14292 ins_encode %{ 14293 __ fmaxd(as_FloatRegister($dst$$reg), 14294 as_FloatRegister($src1$$reg), 14295 as_FloatRegister($src2$$reg)); 14296 %} 14297 14298 ins_pipe(fp_dop_reg_reg_d); 14299 %} 14300 14301 // Math.min(DD)D 14302 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14303 match(Set dst (MinD src1 src2)); 14304 14305 format %{ "fmind $dst, $src1, $src2" %} 14306 ins_encode %{ 14307 __ fmind(as_FloatRegister($dst$$reg), 14308 as_FloatRegister($src1$$reg), 14309 as_FloatRegister($src2$$reg)); 14310 %} 14311 14312 ins_pipe(fp_dop_reg_reg_d); 14313 %} 14314 14315 14316 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14317 match(Set dst (DivF src1 src2)); 14318 14319 ins_cost(INSN_COST * 18); 14320 format %{ "fdivs $dst, $src1, $src2" %} 14321 14322 ins_encode %{ 14323 __ fdivs(as_FloatRegister($dst$$reg), 14324 as_FloatRegister($src1$$reg), 14325 as_FloatRegister($src2$$reg)); 14326 %} 14327 14328 ins_pipe(fp_div_s); 14329 %} 14330 14331 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14332 match(Set dst (DivD src1 src2)); 14333 14334 ins_cost(INSN_COST * 32); 14335 format %{ "fdivd $dst, $src1, $src2" %} 14336 14337 ins_encode %{ 14338 __ fdivd(as_FloatRegister($dst$$reg), 14339 as_FloatRegister($src1$$reg), 14340 as_FloatRegister($src2$$reg)); 14341 %} 14342 14343 ins_pipe(fp_div_d); 14344 %} 14345 14346 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 14347 match(Set dst (NegF src)); 14348 14349 ins_cost(INSN_COST * 3); 14350 format %{ "fneg $dst, $src" %} 14351 14352 ins_encode %{ 14353 __ fnegs(as_FloatRegister($dst$$reg), 14354 as_FloatRegister($src$$reg)); 14355 %} 14356 14357 ins_pipe(fp_uop_s); 14358 %} 14359 14360 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 14361 match(Set dst (NegD src)); 14362 14363 ins_cost(INSN_COST * 3); 14364 format %{ "fnegd $dst, $src" %} 14365 14366 ins_encode %{ 14367 __ fnegd(as_FloatRegister($dst$$reg), 14368 as_FloatRegister($src$$reg)); 14369 %} 14370 14371 ins_pipe(fp_uop_d); 14372 %} 14373 14374 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 14375 %{ 14376 match(Set dst (AbsI src)); 14377 14378 effect(KILL cr); 14379 ins_cost(INSN_COST * 2); 14380 format %{ "cmpw $src, zr\n\t" 14381 "cnegw $dst, $src, Assembler::LT\t# int abs" 14382 %} 14383 14384 ins_encode %{ 14385 __ cmpw(as_Register($src$$reg), zr); 14386 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14387 %} 14388 ins_pipe(pipe_class_default); 14389 %} 14390 14391 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 14392 %{ 14393 match(Set dst (AbsL src)); 14394 14395 effect(KILL cr); 14396 ins_cost(INSN_COST * 2); 14397 format %{ "cmp $src, zr\n\t" 14398 "cneg $dst, $src, Assembler::LT\t# long abs" 14399 %} 14400 14401 ins_encode %{ 14402 __ cmp(as_Register($src$$reg), zr); 14403 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14404 %} 14405 ins_pipe(pipe_class_default); 14406 %} 14407 14408 instruct absF_reg(vRegF dst, vRegF src) %{ 14409 match(Set dst (AbsF src)); 14410 14411 ins_cost(INSN_COST * 3); 14412 format %{ "fabss $dst, $src" %} 14413 ins_encode %{ 14414 __ fabss(as_FloatRegister($dst$$reg), 14415 as_FloatRegister($src$$reg)); 14416 %} 14417 14418 ins_pipe(fp_uop_s); 14419 %} 14420 14421 instruct absD_reg(vRegD dst, vRegD src) %{ 14422 match(Set dst (AbsD src)); 14423 14424 ins_cost(INSN_COST * 3); 14425 format %{ "fabsd $dst, $src" %} 14426 ins_encode %{ 14427 __ fabsd(as_FloatRegister($dst$$reg), 14428 as_FloatRegister($src$$reg)); 14429 %} 14430 14431 ins_pipe(fp_uop_d); 14432 %} 14433 14434 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14435 match(Set dst (AbsF (SubF src1 src2))); 14436 14437 ins_cost(INSN_COST * 3); 14438 format %{ "fabds $dst, $src1, $src2" %} 14439 ins_encode %{ 14440 __ fabds(as_FloatRegister($dst$$reg), 14441 as_FloatRegister($src1$$reg), 14442 as_FloatRegister($src2$$reg)); 14443 %} 14444 14445 ins_pipe(fp_uop_s); 14446 %} 14447 14448 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14449 match(Set dst (AbsD (SubD src1 src2))); 14450 14451 ins_cost(INSN_COST * 3); 14452 format %{ "fabdd $dst, $src1, $src2" %} 14453 ins_encode %{ 14454 __ fabdd(as_FloatRegister($dst$$reg), 14455 as_FloatRegister($src1$$reg), 14456 as_FloatRegister($src2$$reg)); 14457 %} 14458 14459 ins_pipe(fp_uop_d); 14460 %} 14461 14462 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 14463 match(Set dst (SqrtD src)); 14464 14465 ins_cost(INSN_COST * 50); 14466 format %{ "fsqrtd $dst, $src" %} 14467 ins_encode %{ 14468 __ fsqrtd(as_FloatRegister($dst$$reg), 14469 as_FloatRegister($src$$reg)); 14470 %} 14471 14472 ins_pipe(fp_div_s); 14473 %} 14474 14475 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 14476 match(Set dst (SqrtF src)); 14477 14478 ins_cost(INSN_COST * 50); 14479 format %{ "fsqrts $dst, $src" %} 14480 ins_encode %{ 14481 __ fsqrts(as_FloatRegister($dst$$reg), 14482 as_FloatRegister($src$$reg)); 14483 %} 14484 14485 ins_pipe(fp_div_d); 14486 %} 14487 14488 // Math.rint, floor, ceil 14489 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 14490 match(Set dst (RoundDoubleMode src rmode)); 14491 format %{ "frint $dst, $src, $rmode" %} 14492 ins_encode %{ 14493 switch ($rmode$$constant) { 14494 case RoundDoubleModeNode::rmode_rint: 14495 __ frintnd(as_FloatRegister($dst$$reg), 14496 as_FloatRegister($src$$reg)); 14497 break; 14498 case RoundDoubleModeNode::rmode_floor: 14499 __ frintmd(as_FloatRegister($dst$$reg), 14500 as_FloatRegister($src$$reg)); 14501 break; 14502 case RoundDoubleModeNode::rmode_ceil: 14503 __ frintpd(as_FloatRegister($dst$$reg), 14504 as_FloatRegister($src$$reg)); 14505 break; 14506 } 14507 %} 14508 ins_pipe(fp_uop_d); 14509 %} 14510 14511 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 14512 match(Set dst (CopySignD src1 (Binary src2 zero))); 14513 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 14514 format %{ "CopySignD $dst $src1 $src2" %} 14515 ins_encode %{ 14516 FloatRegister dst = as_FloatRegister($dst$$reg), 14517 src1 = as_FloatRegister($src1$$reg), 14518 src2 = as_FloatRegister($src2$$reg), 14519 zero = as_FloatRegister($zero$$reg); 14520 __ fnegd(dst, zero); 14521 __ bsl(dst, __ T8B, src2, src1); 14522 %} 14523 ins_pipe(fp_uop_d); 14524 %} 14525 14526 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14527 match(Set dst (CopySignF src1 src2)); 14528 effect(TEMP_DEF dst, USE src1, USE src2); 14529 format %{ "CopySignF $dst $src1 $src2" %} 14530 ins_encode %{ 14531 FloatRegister dst = as_FloatRegister($dst$$reg), 14532 src1 = as_FloatRegister($src1$$reg), 14533 src2 = as_FloatRegister($src2$$reg); 14534 __ movi(dst, __ T2S, 0x80, 24); 14535 __ bsl(dst, __ T8B, src2, src1); 14536 %} 14537 ins_pipe(fp_uop_d); 14538 %} 14539 14540 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 14541 match(Set dst (SignumD src (Binary zero one))); 14542 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14543 format %{ "signumD $dst, $src" %} 14544 ins_encode %{ 14545 FloatRegister src = as_FloatRegister($src$$reg), 14546 dst = as_FloatRegister($dst$$reg), 14547 zero = as_FloatRegister($zero$$reg), 14548 one = as_FloatRegister($one$$reg); 14549 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14550 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14551 // Bit selection instruction gets bit from "one" for each enabled bit in 14552 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14553 // NaN the whole "src" will be copied because "dst" is zero. For all other 14554 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14555 // from "src", and all other bits are copied from 1.0. 14556 __ bsl(dst, __ T8B, one, src); 14557 %} 14558 ins_pipe(fp_uop_d); 14559 %} 14560 14561 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 14562 match(Set dst (SignumF src (Binary zero one))); 14563 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14564 format %{ "signumF $dst, $src" %} 14565 ins_encode %{ 14566 FloatRegister src = as_FloatRegister($src$$reg), 14567 dst = as_FloatRegister($dst$$reg), 14568 zero = as_FloatRegister($zero$$reg), 14569 one = as_FloatRegister($one$$reg); 14570 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14571 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14572 // Bit selection instruction gets bit from "one" for each enabled bit in 14573 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14574 // NaN the whole "src" will be copied because "dst" is zero. For all other 14575 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14576 // from "src", and all other bits are copied from 1.0. 14577 __ bsl(dst, __ T8B, one, src); 14578 %} 14579 ins_pipe(fp_uop_d); 14580 %} 14581 14582 instruct onspinwait() %{ 14583 match(OnSpinWait); 14584 ins_cost(INSN_COST); 14585 14586 format %{ "onspinwait" %} 14587 14588 ins_encode %{ 14589 __ spin_wait(); 14590 %} 14591 ins_pipe(pipe_class_empty); 14592 %} 14593 14594 // ============================================================================ 14595 // Logical Instructions 14596 14597 // Integer Logical Instructions 14598 14599 // And Instructions 14600 14601 14602 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 14603 match(Set dst (AndI src1 src2)); 14604 14605 format %{ "andw $dst, $src1, $src2\t# int" %} 14606 14607 ins_cost(INSN_COST); 14608 ins_encode %{ 14609 __ andw(as_Register($dst$$reg), 14610 as_Register($src1$$reg), 14611 as_Register($src2$$reg)); 14612 %} 14613 14614 ins_pipe(ialu_reg_reg); 14615 %} 14616 14617 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 14618 match(Set dst (AndI src1 src2)); 14619 14620 format %{ "andsw $dst, $src1, $src2\t# int" %} 14621 14622 ins_cost(INSN_COST); 14623 ins_encode %{ 14624 __ andw(as_Register($dst$$reg), 14625 as_Register($src1$$reg), 14626 (uint64_t)($src2$$constant)); 14627 %} 14628 14629 ins_pipe(ialu_reg_imm); 14630 %} 14631 14632 // Or Instructions 14633 14634 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14635 match(Set dst (OrI src1 src2)); 14636 14637 format %{ "orrw $dst, $src1, $src2\t# int" %} 14638 14639 ins_cost(INSN_COST); 14640 ins_encode %{ 14641 __ orrw(as_Register($dst$$reg), 14642 as_Register($src1$$reg), 14643 as_Register($src2$$reg)); 14644 %} 14645 14646 ins_pipe(ialu_reg_reg); 14647 %} 14648 14649 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14650 match(Set dst (OrI src1 src2)); 14651 14652 format %{ "orrw $dst, $src1, $src2\t# int" %} 14653 14654 ins_cost(INSN_COST); 14655 ins_encode %{ 14656 __ orrw(as_Register($dst$$reg), 14657 as_Register($src1$$reg), 14658 (uint64_t)($src2$$constant)); 14659 %} 14660 14661 ins_pipe(ialu_reg_imm); 14662 %} 14663 14664 // Xor Instructions 14665 14666 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14667 match(Set dst (XorI src1 src2)); 14668 14669 format %{ "eorw $dst, $src1, $src2\t# int" %} 14670 14671 ins_cost(INSN_COST); 14672 ins_encode %{ 14673 __ eorw(as_Register($dst$$reg), 14674 as_Register($src1$$reg), 14675 as_Register($src2$$reg)); 14676 %} 14677 14678 ins_pipe(ialu_reg_reg); 14679 %} 14680 14681 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14682 match(Set dst (XorI src1 src2)); 14683 14684 format %{ "eorw $dst, $src1, $src2\t# int" %} 14685 14686 ins_cost(INSN_COST); 14687 ins_encode %{ 14688 __ eorw(as_Register($dst$$reg), 14689 as_Register($src1$$reg), 14690 (uint64_t)($src2$$constant)); 14691 %} 14692 14693 ins_pipe(ialu_reg_imm); 14694 %} 14695 14696 // Long Logical Instructions 14697 // TODO 14698 14699 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 14700 match(Set dst (AndL src1 src2)); 14701 14702 format %{ "and $dst, $src1, $src2\t# int" %} 14703 14704 ins_cost(INSN_COST); 14705 ins_encode %{ 14706 __ andr(as_Register($dst$$reg), 14707 as_Register($src1$$reg), 14708 as_Register($src2$$reg)); 14709 %} 14710 14711 ins_pipe(ialu_reg_reg); 14712 %} 14713 14714 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 14715 match(Set dst (AndL src1 src2)); 14716 14717 format %{ "and $dst, $src1, $src2\t# int" %} 14718 14719 ins_cost(INSN_COST); 14720 ins_encode %{ 14721 __ andr(as_Register($dst$$reg), 14722 as_Register($src1$$reg), 14723 (uint64_t)($src2$$constant)); 14724 %} 14725 14726 ins_pipe(ialu_reg_imm); 14727 %} 14728 14729 // Or Instructions 14730 14731 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14732 match(Set dst (OrL src1 src2)); 14733 14734 format %{ "orr $dst, $src1, $src2\t# int" %} 14735 14736 ins_cost(INSN_COST); 14737 ins_encode %{ 14738 __ orr(as_Register($dst$$reg), 14739 as_Register($src1$$reg), 14740 as_Register($src2$$reg)); 14741 %} 14742 14743 ins_pipe(ialu_reg_reg); 14744 %} 14745 14746 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14747 match(Set dst (OrL src1 src2)); 14748 14749 format %{ "orr $dst, $src1, $src2\t# int" %} 14750 14751 ins_cost(INSN_COST); 14752 ins_encode %{ 14753 __ orr(as_Register($dst$$reg), 14754 as_Register($src1$$reg), 14755 (uint64_t)($src2$$constant)); 14756 %} 14757 14758 ins_pipe(ialu_reg_imm); 14759 %} 14760 14761 // Xor Instructions 14762 14763 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14764 match(Set dst (XorL src1 src2)); 14765 14766 format %{ "eor $dst, $src1, $src2\t# int" %} 14767 14768 ins_cost(INSN_COST); 14769 ins_encode %{ 14770 __ eor(as_Register($dst$$reg), 14771 as_Register($src1$$reg), 14772 as_Register($src2$$reg)); 14773 %} 14774 14775 ins_pipe(ialu_reg_reg); 14776 %} 14777 14778 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14779 match(Set dst (XorL src1 src2)); 14780 14781 ins_cost(INSN_COST); 14782 format %{ "eor $dst, $src1, $src2\t# int" %} 14783 14784 ins_encode %{ 14785 __ eor(as_Register($dst$$reg), 14786 as_Register($src1$$reg), 14787 (uint64_t)($src2$$constant)); 14788 %} 14789 14790 ins_pipe(ialu_reg_imm); 14791 %} 14792 14793 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 14794 %{ 14795 match(Set dst (ConvI2L src)); 14796 14797 ins_cost(INSN_COST); 14798 format %{ "sxtw $dst, $src\t# i2l" %} 14799 ins_encode %{ 14800 __ sbfm($dst$$Register, $src$$Register, 0, 31); 14801 %} 14802 ins_pipe(ialu_reg_shift); 14803 %} 14804 14805 // this pattern occurs in bigmath arithmetic 14806 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 14807 %{ 14808 match(Set dst (AndL (ConvI2L src) mask)); 14809 14810 ins_cost(INSN_COST); 14811 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 14812 ins_encode %{ 14813 __ ubfm($dst$$Register, $src$$Register, 0, 31); 14814 %} 14815 14816 ins_pipe(ialu_reg_shift); 14817 %} 14818 14819 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 14820 match(Set dst (ConvL2I src)); 14821 14822 ins_cost(INSN_COST); 14823 format %{ "movw $dst, $src \t// l2i" %} 14824 14825 ins_encode %{ 14826 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 14827 %} 14828 14829 ins_pipe(ialu_reg); 14830 %} 14831 14832 instruct convD2F_reg(vRegF dst, vRegD src) %{ 14833 match(Set dst (ConvD2F src)); 14834 14835 ins_cost(INSN_COST * 5); 14836 format %{ "fcvtd $dst, $src \t// d2f" %} 14837 14838 ins_encode %{ 14839 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14840 %} 14841 14842 ins_pipe(fp_d2f); 14843 %} 14844 14845 instruct convF2D_reg(vRegD dst, vRegF src) %{ 14846 match(Set dst (ConvF2D src)); 14847 14848 ins_cost(INSN_COST * 5); 14849 format %{ "fcvts $dst, $src \t// f2d" %} 14850 14851 ins_encode %{ 14852 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14853 %} 14854 14855 ins_pipe(fp_f2d); 14856 %} 14857 14858 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14859 match(Set dst (ConvF2I src)); 14860 14861 ins_cost(INSN_COST * 5); 14862 format %{ "fcvtzsw $dst, $src \t// f2i" %} 14863 14864 ins_encode %{ 14865 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14866 %} 14867 14868 ins_pipe(fp_f2i); 14869 %} 14870 14871 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 14872 match(Set dst (ConvF2L src)); 14873 14874 ins_cost(INSN_COST * 5); 14875 format %{ "fcvtzs $dst, $src \t// f2l" %} 14876 14877 ins_encode %{ 14878 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14879 %} 14880 14881 ins_pipe(fp_f2l); 14882 %} 14883 14884 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{ 14885 match(Set dst (ConvF2HF src)); 14886 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t" 14887 "smov $dst, $tmp\t# move result from $tmp to $dst" 14888 %} 14889 effect(TEMP tmp); 14890 ins_encode %{ 14891 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister); 14892 %} 14893 ins_pipe(pipe_slow); 14894 %} 14895 14896 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{ 14897 match(Set dst (ConvHF2F src)); 14898 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t" 14899 "fcvt $dst, $tmp\t# convert half to single precision" 14900 %} 14901 effect(TEMP tmp); 14902 ins_encode %{ 14903 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister); 14904 %} 14905 ins_pipe(pipe_slow); 14906 %} 14907 14908 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 14909 match(Set dst (ConvI2F src)); 14910 14911 ins_cost(INSN_COST * 5); 14912 format %{ "scvtfws $dst, $src \t// i2f" %} 14913 14914 ins_encode %{ 14915 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14916 %} 14917 14918 ins_pipe(fp_i2f); 14919 %} 14920 14921 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 14922 match(Set dst (ConvL2F src)); 14923 14924 ins_cost(INSN_COST * 5); 14925 format %{ "scvtfs $dst, $src \t// l2f" %} 14926 14927 ins_encode %{ 14928 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14929 %} 14930 14931 ins_pipe(fp_l2f); 14932 %} 14933 14934 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 14935 match(Set dst (ConvD2I src)); 14936 14937 ins_cost(INSN_COST * 5); 14938 format %{ "fcvtzdw $dst, $src \t// d2i" %} 14939 14940 ins_encode %{ 14941 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14942 %} 14943 14944 ins_pipe(fp_d2i); 14945 %} 14946 14947 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14948 match(Set dst (ConvD2L src)); 14949 14950 ins_cost(INSN_COST * 5); 14951 format %{ "fcvtzd $dst, $src \t// d2l" %} 14952 14953 ins_encode %{ 14954 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14955 %} 14956 14957 ins_pipe(fp_d2l); 14958 %} 14959 14960 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 14961 match(Set dst (ConvI2D src)); 14962 14963 ins_cost(INSN_COST * 5); 14964 format %{ "scvtfwd $dst, $src \t// i2d" %} 14965 14966 ins_encode %{ 14967 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14968 %} 14969 14970 ins_pipe(fp_i2d); 14971 %} 14972 14973 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 14974 match(Set dst (ConvL2D src)); 14975 14976 ins_cost(INSN_COST * 5); 14977 format %{ "scvtfd $dst, $src \t// l2d" %} 14978 14979 ins_encode %{ 14980 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14981 %} 14982 14983 ins_pipe(fp_l2d); 14984 %} 14985 14986 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr) 14987 %{ 14988 match(Set dst (RoundD src)); 14989 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 14990 format %{ "java_round_double $dst,$src"%} 14991 ins_encode %{ 14992 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), 14993 as_FloatRegister($ftmp$$reg)); 14994 %} 14995 ins_pipe(pipe_slow); 14996 %} 14997 14998 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr) 14999 %{ 15000 match(Set dst (RoundF src)); 15001 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 15002 format %{ "java_round_float $dst,$src"%} 15003 ins_encode %{ 15004 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), 15005 as_FloatRegister($ftmp$$reg)); 15006 %} 15007 ins_pipe(pipe_slow); 15008 %} 15009 15010 // stack <-> reg and reg <-> reg shuffles with no conversion 15011 15012 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 15013 15014 match(Set dst (MoveF2I src)); 15015 15016 effect(DEF dst, USE src); 15017 15018 ins_cost(4 * INSN_COST); 15019 15020 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 15021 15022 ins_encode %{ 15023 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 15024 %} 15025 15026 ins_pipe(iload_reg_reg); 15027 15028 %} 15029 15030 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 15031 15032 match(Set dst (MoveI2F src)); 15033 15034 effect(DEF dst, USE src); 15035 15036 ins_cost(4 * INSN_COST); 15037 15038 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 15039 15040 ins_encode %{ 15041 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15042 %} 15043 15044 ins_pipe(pipe_class_memory); 15045 15046 %} 15047 15048 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 15049 15050 match(Set dst (MoveD2L src)); 15051 15052 effect(DEF dst, USE src); 15053 15054 ins_cost(4 * INSN_COST); 15055 15056 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 15057 15058 ins_encode %{ 15059 __ ldr($dst$$Register, Address(sp, $src$$disp)); 15060 %} 15061 15062 ins_pipe(iload_reg_reg); 15063 15064 %} 15065 15066 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 15067 15068 match(Set dst (MoveL2D src)); 15069 15070 effect(DEF dst, USE src); 15071 15072 ins_cost(4 * INSN_COST); 15073 15074 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 15075 15076 ins_encode %{ 15077 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15078 %} 15079 15080 ins_pipe(pipe_class_memory); 15081 15082 %} 15083 15084 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 15085 15086 match(Set dst (MoveF2I src)); 15087 15088 effect(DEF dst, USE src); 15089 15090 ins_cost(INSN_COST); 15091 15092 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 15093 15094 ins_encode %{ 15095 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15096 %} 15097 15098 ins_pipe(pipe_class_memory); 15099 15100 %} 15101 15102 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 15103 15104 match(Set dst (MoveI2F src)); 15105 15106 effect(DEF dst, USE src); 15107 15108 ins_cost(INSN_COST); 15109 15110 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 15111 15112 ins_encode %{ 15113 __ strw($src$$Register, Address(sp, $dst$$disp)); 15114 %} 15115 15116 ins_pipe(istore_reg_reg); 15117 15118 %} 15119 15120 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 15121 15122 match(Set dst (MoveD2L src)); 15123 15124 effect(DEF dst, USE src); 15125 15126 ins_cost(INSN_COST); 15127 15128 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 15129 15130 ins_encode %{ 15131 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15132 %} 15133 15134 ins_pipe(pipe_class_memory); 15135 15136 %} 15137 15138 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 15139 15140 match(Set dst (MoveL2D src)); 15141 15142 effect(DEF dst, USE src); 15143 15144 ins_cost(INSN_COST); 15145 15146 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 15147 15148 ins_encode %{ 15149 __ str($src$$Register, Address(sp, $dst$$disp)); 15150 %} 15151 15152 ins_pipe(istore_reg_reg); 15153 15154 %} 15155 15156 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 15157 15158 match(Set dst (MoveF2I src)); 15159 15160 effect(DEF dst, USE src); 15161 15162 ins_cost(INSN_COST); 15163 15164 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 15165 15166 ins_encode %{ 15167 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 15168 %} 15169 15170 ins_pipe(fp_f2i); 15171 15172 %} 15173 15174 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 15175 15176 match(Set dst (MoveI2F src)); 15177 15178 effect(DEF dst, USE src); 15179 15180 ins_cost(INSN_COST); 15181 15182 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 15183 15184 ins_encode %{ 15185 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 15186 %} 15187 15188 ins_pipe(fp_i2f); 15189 15190 %} 15191 15192 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 15193 15194 match(Set dst (MoveD2L src)); 15195 15196 effect(DEF dst, USE src); 15197 15198 ins_cost(INSN_COST); 15199 15200 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 15201 15202 ins_encode %{ 15203 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 15204 %} 15205 15206 ins_pipe(fp_d2l); 15207 15208 %} 15209 15210 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 15211 15212 match(Set dst (MoveL2D src)); 15213 15214 effect(DEF dst, USE src); 15215 15216 ins_cost(INSN_COST); 15217 15218 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 15219 15220 ins_encode %{ 15221 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 15222 %} 15223 15224 ins_pipe(fp_l2d); 15225 15226 %} 15227 15228 // ============================================================================ 15229 // clearing of an array 15230 15231 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 15232 %{ 15233 match(Set dummy (ClearArray cnt base)); 15234 effect(USE_KILL cnt, USE_KILL base, KILL cr); 15235 15236 ins_cost(4 * INSN_COST); 15237 format %{ "ClearArray $cnt, $base" %} 15238 15239 ins_encode %{ 15240 address tpc = __ zero_words($base$$Register, $cnt$$Register); 15241 if (tpc == NULL) { 15242 ciEnv::current()->record_failure("CodeCache is full"); 15243 return; 15244 } 15245 %} 15246 15247 ins_pipe(pipe_class_memory); 15248 %} 15249 15250 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr) 15251 %{ 15252 predicate((uint64_t)n->in(2)->get_long() 15253 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 15254 match(Set dummy (ClearArray cnt base)); 15255 effect(TEMP temp, USE_KILL base, KILL cr); 15256 15257 ins_cost(4 * INSN_COST); 15258 format %{ "ClearArray $cnt, $base" %} 15259 15260 ins_encode %{ 15261 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 15262 if (tpc == NULL) { 15263 ciEnv::current()->record_failure("CodeCache is full"); 15264 return; 15265 } 15266 %} 15267 15268 ins_pipe(pipe_class_memory); 15269 %} 15270 15271 // ============================================================================ 15272 // Overflow Math Instructions 15273 15274 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15275 %{ 15276 match(Set cr (OverflowAddI op1 op2)); 15277 15278 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15279 ins_cost(INSN_COST); 15280 ins_encode %{ 15281 __ cmnw($op1$$Register, $op2$$Register); 15282 %} 15283 15284 ins_pipe(icmp_reg_reg); 15285 %} 15286 15287 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15288 %{ 15289 match(Set cr (OverflowAddI op1 op2)); 15290 15291 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15292 ins_cost(INSN_COST); 15293 ins_encode %{ 15294 __ cmnw($op1$$Register, $op2$$constant); 15295 %} 15296 15297 ins_pipe(icmp_reg_imm); 15298 %} 15299 15300 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15301 %{ 15302 match(Set cr (OverflowAddL op1 op2)); 15303 15304 format %{ "cmn $op1, $op2\t# overflow check long" %} 15305 ins_cost(INSN_COST); 15306 ins_encode %{ 15307 __ cmn($op1$$Register, $op2$$Register); 15308 %} 15309 15310 ins_pipe(icmp_reg_reg); 15311 %} 15312 15313 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15314 %{ 15315 match(Set cr (OverflowAddL op1 op2)); 15316 15317 format %{ "adds zr, $op1, $op2\t# overflow check long" %} 15318 ins_cost(INSN_COST); 15319 ins_encode %{ 15320 __ adds(zr, $op1$$Register, $op2$$constant); 15321 %} 15322 15323 ins_pipe(icmp_reg_imm); 15324 %} 15325 15326 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15327 %{ 15328 match(Set cr (OverflowSubI op1 op2)); 15329 15330 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15331 ins_cost(INSN_COST); 15332 ins_encode %{ 15333 __ cmpw($op1$$Register, $op2$$Register); 15334 %} 15335 15336 ins_pipe(icmp_reg_reg); 15337 %} 15338 15339 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15340 %{ 15341 match(Set cr (OverflowSubI op1 op2)); 15342 15343 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15344 ins_cost(INSN_COST); 15345 ins_encode %{ 15346 __ cmpw($op1$$Register, $op2$$constant); 15347 %} 15348 15349 ins_pipe(icmp_reg_imm); 15350 %} 15351 15352 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15353 %{ 15354 match(Set cr (OverflowSubL op1 op2)); 15355 15356 format %{ "cmp $op1, $op2\t# overflow check long" %} 15357 ins_cost(INSN_COST); 15358 ins_encode %{ 15359 __ cmp($op1$$Register, $op2$$Register); 15360 %} 15361 15362 ins_pipe(icmp_reg_reg); 15363 %} 15364 15365 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15366 %{ 15367 match(Set cr (OverflowSubL op1 op2)); 15368 15369 format %{ "cmp $op1, $op2\t# overflow check long" %} 15370 ins_cost(INSN_COST); 15371 ins_encode %{ 15372 __ subs(zr, $op1$$Register, $op2$$constant); 15373 %} 15374 15375 ins_pipe(icmp_reg_imm); 15376 %} 15377 15378 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 15379 %{ 15380 match(Set cr (OverflowSubI zero op1)); 15381 15382 format %{ "cmpw zr, $op1\t# overflow check int" %} 15383 ins_cost(INSN_COST); 15384 ins_encode %{ 15385 __ cmpw(zr, $op1$$Register); 15386 %} 15387 15388 ins_pipe(icmp_reg_imm); 15389 %} 15390 15391 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 15392 %{ 15393 match(Set cr (OverflowSubL zero op1)); 15394 15395 format %{ "cmp zr, $op1\t# overflow check long" %} 15396 ins_cost(INSN_COST); 15397 ins_encode %{ 15398 __ cmp(zr, $op1$$Register); 15399 %} 15400 15401 ins_pipe(icmp_reg_imm); 15402 %} 15403 15404 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15405 %{ 15406 match(Set cr (OverflowMulI op1 op2)); 15407 15408 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15409 "cmp rscratch1, rscratch1, sxtw\n\t" 15410 "movw rscratch1, #0x80000000\n\t" 15411 "cselw rscratch1, rscratch1, zr, NE\n\t" 15412 "cmpw rscratch1, #1" %} 15413 ins_cost(5 * INSN_COST); 15414 ins_encode %{ 15415 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15416 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15417 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15418 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15419 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15420 %} 15421 15422 ins_pipe(pipe_slow); 15423 %} 15424 15425 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 15426 %{ 15427 match(If cmp (OverflowMulI op1 op2)); 15428 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15429 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15430 effect(USE labl, KILL cr); 15431 15432 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15433 "cmp rscratch1, rscratch1, sxtw\n\t" 15434 "b$cmp $labl" %} 15435 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 15436 ins_encode %{ 15437 Label* L = $labl$$label; 15438 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15439 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15440 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15441 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15442 %} 15443 15444 ins_pipe(pipe_serial); 15445 %} 15446 15447 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15448 %{ 15449 match(Set cr (OverflowMulL op1 op2)); 15450 15451 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15452 "smulh rscratch2, $op1, $op2\n\t" 15453 "cmp rscratch2, rscratch1, ASR #63\n\t" 15454 "movw rscratch1, #0x80000000\n\t" 15455 "cselw rscratch1, rscratch1, zr, NE\n\t" 15456 "cmpw rscratch1, #1" %} 15457 ins_cost(6 * INSN_COST); 15458 ins_encode %{ 15459 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15460 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15461 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15462 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15463 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15464 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15465 %} 15466 15467 ins_pipe(pipe_slow); 15468 %} 15469 15470 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 15471 %{ 15472 match(If cmp (OverflowMulL op1 op2)); 15473 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15474 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15475 effect(USE labl, KILL cr); 15476 15477 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15478 "smulh rscratch2, $op1, $op2\n\t" 15479 "cmp rscratch2, rscratch1, ASR #63\n\t" 15480 "b$cmp $labl" %} 15481 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 15482 ins_encode %{ 15483 Label* L = $labl$$label; 15484 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15485 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15486 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15487 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15488 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15489 %} 15490 15491 ins_pipe(pipe_serial); 15492 %} 15493 15494 // ============================================================================ 15495 // Compare Instructions 15496 15497 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 15498 %{ 15499 match(Set cr (CmpI op1 op2)); 15500 15501 effect(DEF cr, USE op1, USE op2); 15502 15503 ins_cost(INSN_COST); 15504 format %{ "cmpw $op1, $op2" %} 15505 15506 ins_encode(aarch64_enc_cmpw(op1, op2)); 15507 15508 ins_pipe(icmp_reg_reg); 15509 %} 15510 15511 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 15512 %{ 15513 match(Set cr (CmpI op1 zero)); 15514 15515 effect(DEF cr, USE op1); 15516 15517 ins_cost(INSN_COST); 15518 format %{ "cmpw $op1, 0" %} 15519 15520 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15521 15522 ins_pipe(icmp_reg_imm); 15523 %} 15524 15525 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 15526 %{ 15527 match(Set cr (CmpI op1 op2)); 15528 15529 effect(DEF cr, USE op1); 15530 15531 ins_cost(INSN_COST); 15532 format %{ "cmpw $op1, $op2" %} 15533 15534 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15535 15536 ins_pipe(icmp_reg_imm); 15537 %} 15538 15539 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 15540 %{ 15541 match(Set cr (CmpI op1 op2)); 15542 15543 effect(DEF cr, USE op1); 15544 15545 ins_cost(INSN_COST * 2); 15546 format %{ "cmpw $op1, $op2" %} 15547 15548 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15549 15550 ins_pipe(icmp_reg_imm); 15551 %} 15552 15553 // Unsigned compare Instructions; really, same as signed compare 15554 // except it should only be used to feed an If or a CMovI which takes a 15555 // cmpOpU. 15556 15557 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 15558 %{ 15559 match(Set cr (CmpU op1 op2)); 15560 15561 effect(DEF cr, USE op1, USE op2); 15562 15563 ins_cost(INSN_COST); 15564 format %{ "cmpw $op1, $op2\t# unsigned" %} 15565 15566 ins_encode(aarch64_enc_cmpw(op1, op2)); 15567 15568 ins_pipe(icmp_reg_reg); 15569 %} 15570 15571 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 15572 %{ 15573 match(Set cr (CmpU op1 zero)); 15574 15575 effect(DEF cr, USE op1); 15576 15577 ins_cost(INSN_COST); 15578 format %{ "cmpw $op1, #0\t# unsigned" %} 15579 15580 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15581 15582 ins_pipe(icmp_reg_imm); 15583 %} 15584 15585 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 15586 %{ 15587 match(Set cr (CmpU op1 op2)); 15588 15589 effect(DEF cr, USE op1); 15590 15591 ins_cost(INSN_COST); 15592 format %{ "cmpw $op1, $op2\t# unsigned" %} 15593 15594 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15595 15596 ins_pipe(icmp_reg_imm); 15597 %} 15598 15599 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 15600 %{ 15601 match(Set cr (CmpU op1 op2)); 15602 15603 effect(DEF cr, USE op1); 15604 15605 ins_cost(INSN_COST * 2); 15606 format %{ "cmpw $op1, $op2\t# unsigned" %} 15607 15608 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15609 15610 ins_pipe(icmp_reg_imm); 15611 %} 15612 15613 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15614 %{ 15615 match(Set cr (CmpL op1 op2)); 15616 15617 effect(DEF cr, USE op1, USE op2); 15618 15619 ins_cost(INSN_COST); 15620 format %{ "cmp $op1, $op2" %} 15621 15622 ins_encode(aarch64_enc_cmp(op1, op2)); 15623 15624 ins_pipe(icmp_reg_reg); 15625 %} 15626 15627 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 15628 %{ 15629 match(Set cr (CmpL op1 zero)); 15630 15631 effect(DEF cr, USE op1); 15632 15633 ins_cost(INSN_COST); 15634 format %{ "tst $op1" %} 15635 15636 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15637 15638 ins_pipe(icmp_reg_imm); 15639 %} 15640 15641 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 15642 %{ 15643 match(Set cr (CmpL op1 op2)); 15644 15645 effect(DEF cr, USE op1); 15646 15647 ins_cost(INSN_COST); 15648 format %{ "cmp $op1, $op2" %} 15649 15650 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15651 15652 ins_pipe(icmp_reg_imm); 15653 %} 15654 15655 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 15656 %{ 15657 match(Set cr (CmpL op1 op2)); 15658 15659 effect(DEF cr, USE op1); 15660 15661 ins_cost(INSN_COST * 2); 15662 format %{ "cmp $op1, $op2" %} 15663 15664 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15665 15666 ins_pipe(icmp_reg_imm); 15667 %} 15668 15669 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 15670 %{ 15671 match(Set cr (CmpUL op1 op2)); 15672 15673 effect(DEF cr, USE op1, USE op2); 15674 15675 ins_cost(INSN_COST); 15676 format %{ "cmp $op1, $op2" %} 15677 15678 ins_encode(aarch64_enc_cmp(op1, op2)); 15679 15680 ins_pipe(icmp_reg_reg); 15681 %} 15682 15683 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 15684 %{ 15685 match(Set cr (CmpUL op1 zero)); 15686 15687 effect(DEF cr, USE op1); 15688 15689 ins_cost(INSN_COST); 15690 format %{ "tst $op1" %} 15691 15692 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15693 15694 ins_pipe(icmp_reg_imm); 15695 %} 15696 15697 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 15698 %{ 15699 match(Set cr (CmpUL op1 op2)); 15700 15701 effect(DEF cr, USE op1); 15702 15703 ins_cost(INSN_COST); 15704 format %{ "cmp $op1, $op2" %} 15705 15706 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15707 15708 ins_pipe(icmp_reg_imm); 15709 %} 15710 15711 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 15712 %{ 15713 match(Set cr (CmpUL op1 op2)); 15714 15715 effect(DEF cr, USE op1); 15716 15717 ins_cost(INSN_COST * 2); 15718 format %{ "cmp $op1, $op2" %} 15719 15720 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15721 15722 ins_pipe(icmp_reg_imm); 15723 %} 15724 15725 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 15726 %{ 15727 match(Set cr (CmpP op1 op2)); 15728 15729 effect(DEF cr, USE op1, USE op2); 15730 15731 ins_cost(INSN_COST); 15732 format %{ "cmp $op1, $op2\t // ptr" %} 15733 15734 ins_encode(aarch64_enc_cmpp(op1, op2)); 15735 15736 ins_pipe(icmp_reg_reg); 15737 %} 15738 15739 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 15740 %{ 15741 match(Set cr (CmpN op1 op2)); 15742 15743 effect(DEF cr, USE op1, USE op2); 15744 15745 ins_cost(INSN_COST); 15746 format %{ "cmp $op1, $op2\t // compressed ptr" %} 15747 15748 ins_encode(aarch64_enc_cmpn(op1, op2)); 15749 15750 ins_pipe(icmp_reg_reg); 15751 %} 15752 15753 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 15754 %{ 15755 match(Set cr (CmpP op1 zero)); 15756 15757 effect(DEF cr, USE op1, USE zero); 15758 15759 ins_cost(INSN_COST); 15760 format %{ "cmp $op1, 0\t // ptr" %} 15761 15762 ins_encode(aarch64_enc_testp(op1)); 15763 15764 ins_pipe(icmp_reg_imm); 15765 %} 15766 15767 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 15768 %{ 15769 match(Set cr (CmpN op1 zero)); 15770 15771 effect(DEF cr, USE op1, USE zero); 15772 15773 ins_cost(INSN_COST); 15774 format %{ "cmp $op1, 0\t // compressed ptr" %} 15775 15776 ins_encode(aarch64_enc_testn(op1)); 15777 15778 ins_pipe(icmp_reg_imm); 15779 %} 15780 15781 // FP comparisons 15782 // 15783 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 15784 // using normal cmpOp. See declaration of rFlagsReg for details. 15785 15786 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 15787 %{ 15788 match(Set cr (CmpF src1 src2)); 15789 15790 ins_cost(3 * INSN_COST); 15791 format %{ "fcmps $src1, $src2" %} 15792 15793 ins_encode %{ 15794 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15795 %} 15796 15797 ins_pipe(pipe_class_compare); 15798 %} 15799 15800 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 15801 %{ 15802 match(Set cr (CmpF src1 src2)); 15803 15804 ins_cost(3 * INSN_COST); 15805 format %{ "fcmps $src1, 0.0" %} 15806 15807 ins_encode %{ 15808 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 15809 %} 15810 15811 ins_pipe(pipe_class_compare); 15812 %} 15813 // FROM HERE 15814 15815 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 15816 %{ 15817 match(Set cr (CmpD src1 src2)); 15818 15819 ins_cost(3 * INSN_COST); 15820 format %{ "fcmpd $src1, $src2" %} 15821 15822 ins_encode %{ 15823 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15824 %} 15825 15826 ins_pipe(pipe_class_compare); 15827 %} 15828 15829 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 15830 %{ 15831 match(Set cr (CmpD src1 src2)); 15832 15833 ins_cost(3 * INSN_COST); 15834 format %{ "fcmpd $src1, 0.0" %} 15835 15836 ins_encode %{ 15837 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 15838 %} 15839 15840 ins_pipe(pipe_class_compare); 15841 %} 15842 15843 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 15844 %{ 15845 match(Set dst (CmpF3 src1 src2)); 15846 effect(KILL cr); 15847 15848 ins_cost(5 * INSN_COST); 15849 format %{ "fcmps $src1, $src2\n\t" 15850 "csinvw($dst, zr, zr, eq\n\t" 15851 "csnegw($dst, $dst, $dst, lt)" 15852 %} 15853 15854 ins_encode %{ 15855 Label done; 15856 FloatRegister s1 = as_FloatRegister($src1$$reg); 15857 FloatRegister s2 = as_FloatRegister($src2$$reg); 15858 Register d = as_Register($dst$$reg); 15859 __ fcmps(s1, s2); 15860 // installs 0 if EQ else -1 15861 __ csinvw(d, zr, zr, Assembler::EQ); 15862 // keeps -1 if less or unordered else installs 1 15863 __ csnegw(d, d, d, Assembler::LT); 15864 __ bind(done); 15865 %} 15866 15867 ins_pipe(pipe_class_default); 15868 15869 %} 15870 15871 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 15872 %{ 15873 match(Set dst (CmpD3 src1 src2)); 15874 effect(KILL cr); 15875 15876 ins_cost(5 * INSN_COST); 15877 format %{ "fcmpd $src1, $src2\n\t" 15878 "csinvw($dst, zr, zr, eq\n\t" 15879 "csnegw($dst, $dst, $dst, lt)" 15880 %} 15881 15882 ins_encode %{ 15883 Label done; 15884 FloatRegister s1 = as_FloatRegister($src1$$reg); 15885 FloatRegister s2 = as_FloatRegister($src2$$reg); 15886 Register d = as_Register($dst$$reg); 15887 __ fcmpd(s1, s2); 15888 // installs 0 if EQ else -1 15889 __ csinvw(d, zr, zr, Assembler::EQ); 15890 // keeps -1 if less or unordered else installs 1 15891 __ csnegw(d, d, d, Assembler::LT); 15892 __ bind(done); 15893 %} 15894 ins_pipe(pipe_class_default); 15895 15896 %} 15897 15898 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 15899 %{ 15900 match(Set dst (CmpF3 src1 zero)); 15901 effect(KILL cr); 15902 15903 ins_cost(5 * INSN_COST); 15904 format %{ "fcmps $src1, 0.0\n\t" 15905 "csinvw($dst, zr, zr, eq\n\t" 15906 "csnegw($dst, $dst, $dst, lt)" 15907 %} 15908 15909 ins_encode %{ 15910 Label done; 15911 FloatRegister s1 = as_FloatRegister($src1$$reg); 15912 Register d = as_Register($dst$$reg); 15913 __ fcmps(s1, 0.0); 15914 // installs 0 if EQ else -1 15915 __ csinvw(d, zr, zr, Assembler::EQ); 15916 // keeps -1 if less or unordered else installs 1 15917 __ csnegw(d, d, d, Assembler::LT); 15918 __ bind(done); 15919 %} 15920 15921 ins_pipe(pipe_class_default); 15922 15923 %} 15924 15925 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 15926 %{ 15927 match(Set dst (CmpD3 src1 zero)); 15928 effect(KILL cr); 15929 15930 ins_cost(5 * INSN_COST); 15931 format %{ "fcmpd $src1, 0.0\n\t" 15932 "csinvw($dst, zr, zr, eq\n\t" 15933 "csnegw($dst, $dst, $dst, lt)" 15934 %} 15935 15936 ins_encode %{ 15937 Label done; 15938 FloatRegister s1 = as_FloatRegister($src1$$reg); 15939 Register d = as_Register($dst$$reg); 15940 __ fcmpd(s1, 0.0); 15941 // installs 0 if EQ else -1 15942 __ csinvw(d, zr, zr, Assembler::EQ); 15943 // keeps -1 if less or unordered else installs 1 15944 __ csnegw(d, d, d, Assembler::LT); 15945 __ bind(done); 15946 %} 15947 ins_pipe(pipe_class_default); 15948 15949 %} 15950 15951 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 15952 %{ 15953 match(Set dst (CmpLTMask p q)); 15954 effect(KILL cr); 15955 15956 ins_cost(3 * INSN_COST); 15957 15958 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 15959 "csetw $dst, lt\n\t" 15960 "subw $dst, zr, $dst" 15961 %} 15962 15963 ins_encode %{ 15964 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 15965 __ csetw(as_Register($dst$$reg), Assembler::LT); 15966 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 15967 %} 15968 15969 ins_pipe(ialu_reg_reg); 15970 %} 15971 15972 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 15973 %{ 15974 match(Set dst (CmpLTMask src zero)); 15975 effect(KILL cr); 15976 15977 ins_cost(INSN_COST); 15978 15979 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 15980 15981 ins_encode %{ 15982 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 15983 %} 15984 15985 ins_pipe(ialu_reg_shift); 15986 %} 15987 15988 // ============================================================================ 15989 // Max and Min 15990 15991 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter. 15992 15993 instruct compI_reg_imm0(rFlagsReg cr, iRegI src) 15994 %{ 15995 effect(DEF cr, USE src); 15996 ins_cost(INSN_COST); 15997 format %{ "cmpw $src, 0" %} 15998 15999 ins_encode %{ 16000 __ cmpw($src$$Register, 0); 16001 %} 16002 ins_pipe(icmp_reg_imm); 16003 %} 16004 16005 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16006 %{ 16007 match(Set dst (MinI src1 src2)); 16008 ins_cost(INSN_COST * 3); 16009 16010 expand %{ 16011 rFlagsReg cr; 16012 compI_reg_reg(cr, src1, src2); 16013 cmovI_reg_reg_lt(dst, src1, src2, cr); 16014 %} 16015 %} 16016 16017 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16018 %{ 16019 match(Set dst (MaxI src1 src2)); 16020 ins_cost(INSN_COST * 3); 16021 16022 expand %{ 16023 rFlagsReg cr; 16024 compI_reg_reg(cr, src1, src2); 16025 cmovI_reg_reg_gt(dst, src1, src2, cr); 16026 %} 16027 %} 16028 16029 16030 // ============================================================================ 16031 // Branch Instructions 16032 16033 // Direct Branch. 16034 instruct branch(label lbl) 16035 %{ 16036 match(Goto); 16037 16038 effect(USE lbl); 16039 16040 ins_cost(BRANCH_COST); 16041 format %{ "b $lbl" %} 16042 16043 ins_encode(aarch64_enc_b(lbl)); 16044 16045 ins_pipe(pipe_branch); 16046 %} 16047 16048 // Conditional Near Branch 16049 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 16050 %{ 16051 // Same match rule as `branchConFar'. 16052 match(If cmp cr); 16053 16054 effect(USE lbl); 16055 16056 ins_cost(BRANCH_COST); 16057 // If set to 1 this indicates that the current instruction is a 16058 // short variant of a long branch. This avoids using this 16059 // instruction in first-pass matching. It will then only be used in 16060 // the `Shorten_branches' pass. 16061 // ins_short_branch(1); 16062 format %{ "b$cmp $lbl" %} 16063 16064 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16065 16066 ins_pipe(pipe_branch_cond); 16067 %} 16068 16069 // Conditional Near Branch Unsigned 16070 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 16071 %{ 16072 // Same match rule as `branchConFar'. 16073 match(If cmp cr); 16074 16075 effect(USE lbl); 16076 16077 ins_cost(BRANCH_COST); 16078 // If set to 1 this indicates that the current instruction is a 16079 // short variant of a long branch. This avoids using this 16080 // instruction in first-pass matching. It will then only be used in 16081 // the `Shorten_branches' pass. 16082 // ins_short_branch(1); 16083 format %{ "b$cmp $lbl\t# unsigned" %} 16084 16085 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 16086 16087 ins_pipe(pipe_branch_cond); 16088 %} 16089 16090 // Make use of CBZ and CBNZ. These instructions, as well as being 16091 // shorter than (cmp; branch), have the additional benefit of not 16092 // killing the flags. 16093 16094 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 16095 match(If cmp (CmpI op1 op2)); 16096 effect(USE labl); 16097 16098 ins_cost(BRANCH_COST); 16099 format %{ "cbw$cmp $op1, $labl" %} 16100 ins_encode %{ 16101 Label* L = $labl$$label; 16102 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16103 if (cond == Assembler::EQ) 16104 __ cbzw($op1$$Register, *L); 16105 else 16106 __ cbnzw($op1$$Register, *L); 16107 %} 16108 ins_pipe(pipe_cmp_branch); 16109 %} 16110 16111 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 16112 match(If cmp (CmpL op1 op2)); 16113 effect(USE labl); 16114 16115 ins_cost(BRANCH_COST); 16116 format %{ "cb$cmp $op1, $labl" %} 16117 ins_encode %{ 16118 Label* L = $labl$$label; 16119 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16120 if (cond == Assembler::EQ) 16121 __ cbz($op1$$Register, *L); 16122 else 16123 __ cbnz($op1$$Register, *L); 16124 %} 16125 ins_pipe(pipe_cmp_branch); 16126 %} 16127 16128 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 16129 match(If cmp (CmpP op1 op2)); 16130 effect(USE labl); 16131 16132 ins_cost(BRANCH_COST); 16133 format %{ "cb$cmp $op1, $labl" %} 16134 ins_encode %{ 16135 Label* L = $labl$$label; 16136 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16137 if (cond == Assembler::EQ) 16138 __ cbz($op1$$Register, *L); 16139 else 16140 __ cbnz($op1$$Register, *L); 16141 %} 16142 ins_pipe(pipe_cmp_branch); 16143 %} 16144 16145 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 16146 match(If cmp (CmpN op1 op2)); 16147 effect(USE labl); 16148 16149 ins_cost(BRANCH_COST); 16150 format %{ "cbw$cmp $op1, $labl" %} 16151 ins_encode %{ 16152 Label* L = $labl$$label; 16153 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16154 if (cond == Assembler::EQ) 16155 __ cbzw($op1$$Register, *L); 16156 else 16157 __ cbnzw($op1$$Register, *L); 16158 %} 16159 ins_pipe(pipe_cmp_branch); 16160 %} 16161 16162 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 16163 match(If cmp (CmpP (DecodeN oop) zero)); 16164 effect(USE labl); 16165 16166 ins_cost(BRANCH_COST); 16167 format %{ "cb$cmp $oop, $labl" %} 16168 ins_encode %{ 16169 Label* L = $labl$$label; 16170 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16171 if (cond == Assembler::EQ) 16172 __ cbzw($oop$$Register, *L); 16173 else 16174 __ cbnzw($oop$$Register, *L); 16175 %} 16176 ins_pipe(pipe_cmp_branch); 16177 %} 16178 16179 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 16180 match(If cmp (CmpU op1 op2)); 16181 effect(USE labl); 16182 16183 ins_cost(BRANCH_COST); 16184 format %{ "cbw$cmp $op1, $labl" %} 16185 ins_encode %{ 16186 Label* L = $labl$$label; 16187 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16188 if (cond == Assembler::EQ || cond == Assembler::LS) 16189 __ cbzw($op1$$Register, *L); 16190 else 16191 __ cbnzw($op1$$Register, *L); 16192 %} 16193 ins_pipe(pipe_cmp_branch); 16194 %} 16195 16196 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 16197 match(If cmp (CmpUL op1 op2)); 16198 effect(USE labl); 16199 16200 ins_cost(BRANCH_COST); 16201 format %{ "cb$cmp $op1, $labl" %} 16202 ins_encode %{ 16203 Label* L = $labl$$label; 16204 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16205 if (cond == Assembler::EQ || cond == Assembler::LS) 16206 __ cbz($op1$$Register, *L); 16207 else 16208 __ cbnz($op1$$Register, *L); 16209 %} 16210 ins_pipe(pipe_cmp_branch); 16211 %} 16212 16213 // Test bit and Branch 16214 16215 // Patterns for short (< 32KiB) variants 16216 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16217 match(If cmp (CmpL op1 op2)); 16218 effect(USE labl); 16219 16220 ins_cost(BRANCH_COST); 16221 format %{ "cb$cmp $op1, $labl # long" %} 16222 ins_encode %{ 16223 Label* L = $labl$$label; 16224 Assembler::Condition cond = 16225 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16226 __ tbr(cond, $op1$$Register, 63, *L); 16227 %} 16228 ins_pipe(pipe_cmp_branch); 16229 ins_short_branch(1); 16230 %} 16231 16232 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16233 match(If cmp (CmpI op1 op2)); 16234 effect(USE labl); 16235 16236 ins_cost(BRANCH_COST); 16237 format %{ "cb$cmp $op1, $labl # int" %} 16238 ins_encode %{ 16239 Label* L = $labl$$label; 16240 Assembler::Condition cond = 16241 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16242 __ tbr(cond, $op1$$Register, 31, *L); 16243 %} 16244 ins_pipe(pipe_cmp_branch); 16245 ins_short_branch(1); 16246 %} 16247 16248 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16249 match(If cmp (CmpL (AndL op1 op2) op3)); 16250 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16251 effect(USE labl); 16252 16253 ins_cost(BRANCH_COST); 16254 format %{ "tb$cmp $op1, $op2, $labl" %} 16255 ins_encode %{ 16256 Label* L = $labl$$label; 16257 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16258 int bit = exact_log2_long($op2$$constant); 16259 __ tbr(cond, $op1$$Register, bit, *L); 16260 %} 16261 ins_pipe(pipe_cmp_branch); 16262 ins_short_branch(1); 16263 %} 16264 16265 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16266 match(If cmp (CmpI (AndI op1 op2) op3)); 16267 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16268 effect(USE labl); 16269 16270 ins_cost(BRANCH_COST); 16271 format %{ "tb$cmp $op1, $op2, $labl" %} 16272 ins_encode %{ 16273 Label* L = $labl$$label; 16274 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16275 int bit = exact_log2((juint)$op2$$constant); 16276 __ tbr(cond, $op1$$Register, bit, *L); 16277 %} 16278 ins_pipe(pipe_cmp_branch); 16279 ins_short_branch(1); 16280 %} 16281 16282 // And far variants 16283 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16284 match(If cmp (CmpL op1 op2)); 16285 effect(USE labl); 16286 16287 ins_cost(BRANCH_COST); 16288 format %{ "cb$cmp $op1, $labl # long" %} 16289 ins_encode %{ 16290 Label* L = $labl$$label; 16291 Assembler::Condition cond = 16292 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16293 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 16294 %} 16295 ins_pipe(pipe_cmp_branch); 16296 %} 16297 16298 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16299 match(If cmp (CmpI op1 op2)); 16300 effect(USE labl); 16301 16302 ins_cost(BRANCH_COST); 16303 format %{ "cb$cmp $op1, $labl # int" %} 16304 ins_encode %{ 16305 Label* L = $labl$$label; 16306 Assembler::Condition cond = 16307 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16308 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 16309 %} 16310 ins_pipe(pipe_cmp_branch); 16311 %} 16312 16313 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16314 match(If cmp (CmpL (AndL op1 op2) op3)); 16315 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16316 effect(USE labl); 16317 16318 ins_cost(BRANCH_COST); 16319 format %{ "tb$cmp $op1, $op2, $labl" %} 16320 ins_encode %{ 16321 Label* L = $labl$$label; 16322 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16323 int bit = exact_log2_long($op2$$constant); 16324 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16325 %} 16326 ins_pipe(pipe_cmp_branch); 16327 %} 16328 16329 instruct far_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, /*far*/true); 16341 %} 16342 ins_pipe(pipe_cmp_branch); 16343 %} 16344 16345 // Test bits 16346 16347 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 16348 match(Set cr (CmpL (AndL op1 op2) op3)); 16349 predicate(Assembler::operand_valid_for_logical_immediate 16350 (/*is_32*/false, n->in(1)->in(2)->get_long())); 16351 16352 ins_cost(INSN_COST); 16353 format %{ "tst $op1, $op2 # long" %} 16354 ins_encode %{ 16355 __ tst($op1$$Register, $op2$$constant); 16356 %} 16357 ins_pipe(ialu_reg_reg); 16358 %} 16359 16360 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 16361 match(Set cr (CmpI (AndI op1 op2) op3)); 16362 predicate(Assembler::operand_valid_for_logical_immediate 16363 (/*is_32*/true, n->in(1)->in(2)->get_int())); 16364 16365 ins_cost(INSN_COST); 16366 format %{ "tst $op1, $op2 # int" %} 16367 ins_encode %{ 16368 __ tstw($op1$$Register, $op2$$constant); 16369 %} 16370 ins_pipe(ialu_reg_reg); 16371 %} 16372 16373 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 16374 match(Set cr (CmpL (AndL op1 op2) op3)); 16375 16376 ins_cost(INSN_COST); 16377 format %{ "tst $op1, $op2 # long" %} 16378 ins_encode %{ 16379 __ tst($op1$$Register, $op2$$Register); 16380 %} 16381 ins_pipe(ialu_reg_reg); 16382 %} 16383 16384 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 16385 match(Set cr (CmpI (AndI op1 op2) op3)); 16386 16387 ins_cost(INSN_COST); 16388 format %{ "tstw $op1, $op2 # int" %} 16389 ins_encode %{ 16390 __ tstw($op1$$Register, $op2$$Register); 16391 %} 16392 ins_pipe(ialu_reg_reg); 16393 %} 16394 16395 16396 // Conditional Far Branch 16397 // Conditional Far Branch Unsigned 16398 // TODO: fixme 16399 16400 // counted loop end branch near 16401 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 16402 %{ 16403 match(CountedLoopEnd cmp cr); 16404 16405 effect(USE lbl); 16406 16407 ins_cost(BRANCH_COST); 16408 // short variant. 16409 // ins_short_branch(1); 16410 format %{ "b$cmp $lbl \t// counted loop end" %} 16411 16412 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16413 16414 ins_pipe(pipe_branch); 16415 %} 16416 16417 // counted loop end branch far 16418 // TODO: fixme 16419 16420 // ============================================================================ 16421 // inlined locking and unlocking 16422 16423 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 16424 %{ 16425 match(Set cr (FastLock object box)); 16426 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 16427 16428 // TODO 16429 // identify correct cost 16430 ins_cost(5 * INSN_COST); 16431 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 16432 16433 ins_encode %{ 16434 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 16435 %} 16436 16437 ins_pipe(pipe_serial); 16438 %} 16439 16440 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16441 %{ 16442 match(Set cr (FastUnlock object box)); 16443 effect(TEMP tmp, TEMP tmp2); 16444 16445 ins_cost(5 * INSN_COST); 16446 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 16447 16448 ins_encode %{ 16449 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register); 16450 %} 16451 16452 ins_pipe(pipe_serial); 16453 %} 16454 16455 16456 // ============================================================================ 16457 // Safepoint Instructions 16458 16459 // TODO 16460 // provide a near and far version of this code 16461 16462 instruct safePoint(rFlagsReg cr, iRegP poll) 16463 %{ 16464 match(SafePoint poll); 16465 effect(KILL cr); 16466 16467 format %{ 16468 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 16469 %} 16470 ins_encode %{ 16471 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 16472 %} 16473 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 16474 %} 16475 16476 16477 // ============================================================================ 16478 // Procedure Call/Return Instructions 16479 16480 // Call Java Static Instruction 16481 16482 instruct CallStaticJavaDirect(method meth) 16483 %{ 16484 match(CallStaticJava); 16485 16486 effect(USE meth); 16487 16488 ins_cost(CALL_COST); 16489 16490 format %{ "call,static $meth \t// ==> " %} 16491 16492 ins_encode(aarch64_enc_java_static_call(meth), 16493 aarch64_enc_call_epilog); 16494 16495 ins_pipe(pipe_class_call); 16496 %} 16497 16498 // TO HERE 16499 16500 // Call Java Dynamic Instruction 16501 instruct CallDynamicJavaDirect(method meth) 16502 %{ 16503 match(CallDynamicJava); 16504 16505 effect(USE meth); 16506 16507 ins_cost(CALL_COST); 16508 16509 format %{ "CALL,dynamic $meth \t// ==> " %} 16510 16511 ins_encode(aarch64_enc_java_dynamic_call(meth), 16512 aarch64_enc_call_epilog); 16513 16514 ins_pipe(pipe_class_call); 16515 %} 16516 16517 // Call Runtime Instruction 16518 16519 instruct CallRuntimeDirect(method meth) 16520 %{ 16521 match(CallRuntime); 16522 16523 effect(USE meth); 16524 16525 ins_cost(CALL_COST); 16526 16527 format %{ "CALL, runtime $meth" %} 16528 16529 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16530 16531 ins_pipe(pipe_class_call); 16532 %} 16533 16534 // Call Runtime Instruction 16535 16536 instruct CallLeafDirect(method meth) 16537 %{ 16538 match(CallLeaf); 16539 16540 effect(USE meth); 16541 16542 ins_cost(CALL_COST); 16543 16544 format %{ "CALL, runtime leaf $meth" %} 16545 16546 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16547 16548 ins_pipe(pipe_class_call); 16549 %} 16550 16551 // Call Runtime Instruction 16552 16553 instruct CallLeafNoFPDirect(method meth) 16554 %{ 16555 match(CallLeafNoFP); 16556 16557 effect(USE meth); 16558 16559 ins_cost(CALL_COST); 16560 16561 format %{ "CALL, runtime leaf nofp $meth" %} 16562 16563 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16564 16565 ins_pipe(pipe_class_call); 16566 %} 16567 16568 // Tail Call; Jump from runtime stub to Java code. 16569 // Also known as an 'interprocedural jump'. 16570 // Target of jump will eventually return to caller. 16571 // TailJump below removes the return address. 16572 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr) 16573 %{ 16574 match(TailCall jump_target method_ptr); 16575 16576 ins_cost(CALL_COST); 16577 16578 format %{ "br $jump_target\t# $method_ptr holds method" %} 16579 16580 ins_encode(aarch64_enc_tail_call(jump_target)); 16581 16582 ins_pipe(pipe_class_call); 16583 %} 16584 16585 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 16586 %{ 16587 match(TailJump jump_target ex_oop); 16588 16589 ins_cost(CALL_COST); 16590 16591 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 16592 16593 ins_encode(aarch64_enc_tail_jmp(jump_target)); 16594 16595 ins_pipe(pipe_class_call); 16596 %} 16597 16598 // Create exception oop: created by stack-crawling runtime code. 16599 // Created exception is now available to this handler, and is setup 16600 // just prior to jumping to this handler. No code emitted. 16601 // TODO check 16602 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 16603 instruct CreateException(iRegP_R0 ex_oop) 16604 %{ 16605 match(Set ex_oop (CreateEx)); 16606 16607 format %{ " -- \t// exception oop; no code emitted" %} 16608 16609 size(0); 16610 16611 ins_encode( /*empty*/ ); 16612 16613 ins_pipe(pipe_class_empty); 16614 %} 16615 16616 // Rethrow exception: The exception oop will come in the first 16617 // argument position. Then JUMP (not call) to the rethrow stub code. 16618 instruct RethrowException() %{ 16619 match(Rethrow); 16620 ins_cost(CALL_COST); 16621 16622 format %{ "b rethrow_stub" %} 16623 16624 ins_encode( aarch64_enc_rethrow() ); 16625 16626 ins_pipe(pipe_class_call); 16627 %} 16628 16629 16630 // Return Instruction 16631 // epilog node loads ret address into lr as part of frame pop 16632 instruct Ret() 16633 %{ 16634 match(Return); 16635 16636 format %{ "ret\t// return register" %} 16637 16638 ins_encode( aarch64_enc_ret() ); 16639 16640 ins_pipe(pipe_branch); 16641 %} 16642 16643 // Die now. 16644 instruct ShouldNotReachHere() %{ 16645 match(Halt); 16646 16647 ins_cost(CALL_COST); 16648 format %{ "ShouldNotReachHere" %} 16649 16650 ins_encode %{ 16651 if (is_reachable()) { 16652 __ stop(_halt_reason); 16653 } 16654 %} 16655 16656 ins_pipe(pipe_class_default); 16657 %} 16658 16659 // ============================================================================ 16660 // Partial Subtype Check 16661 // 16662 // superklass array for an instance of the superklass. Set a hidden 16663 // internal cache on a hit (cache is checked with exposed code in 16664 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 16665 // encoding ALSO sets flags. 16666 16667 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 16668 %{ 16669 match(Set result (PartialSubtypeCheck sub super)); 16670 effect(KILL cr, KILL temp); 16671 16672 ins_cost(1100); // slightly larger than the next version 16673 format %{ "partialSubtypeCheck $result, $sub, $super" %} 16674 16675 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16676 16677 opcode(0x1); // Force zero of result reg on hit 16678 16679 ins_pipe(pipe_class_memory); 16680 %} 16681 16682 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 16683 %{ 16684 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 16685 effect(KILL temp, KILL result); 16686 16687 ins_cost(1100); // slightly larger than the next version 16688 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 16689 16690 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16691 16692 opcode(0x0); // Don't zero result reg on hit 16693 16694 ins_pipe(pipe_class_memory); 16695 %} 16696 16697 // Intrisics for String.compareTo() 16698 16699 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16700 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16701 %{ 16702 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16703 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16704 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16705 16706 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16707 ins_encode %{ 16708 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16709 __ string_compare($str1$$Register, $str2$$Register, 16710 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16711 $tmp1$$Register, $tmp2$$Register, 16712 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU); 16713 %} 16714 ins_pipe(pipe_class_memory); 16715 %} 16716 16717 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16718 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16719 %{ 16720 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16721 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16722 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16723 16724 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16725 ins_encode %{ 16726 __ string_compare($str1$$Register, $str2$$Register, 16727 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16728 $tmp1$$Register, $tmp2$$Register, 16729 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL); 16730 %} 16731 ins_pipe(pipe_class_memory); 16732 %} 16733 16734 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16735 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16736 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16737 %{ 16738 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16739 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16740 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16741 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16742 16743 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16744 ins_encode %{ 16745 __ string_compare($str1$$Register, $str2$$Register, 16746 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16747 $tmp1$$Register, $tmp2$$Register, 16748 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16749 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL); 16750 %} 16751 ins_pipe(pipe_class_memory); 16752 %} 16753 16754 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16755 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16756 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16757 %{ 16758 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16759 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16760 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16761 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16762 16763 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16764 ins_encode %{ 16765 __ string_compare($str1$$Register, $str2$$Register, 16766 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16767 $tmp1$$Register, $tmp2$$Register, 16768 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16769 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU); 16770 %} 16771 ins_pipe(pipe_class_memory); 16772 %} 16773 16774 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of 16775 // these string_compare variants as NEON register type for convenience so that the prototype of 16776 // string_compare can be shared with all variants. 16777 16778 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16779 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16780 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16781 pRegGov_P1 pgtmp2, rFlagsReg cr) 16782 %{ 16783 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16784 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16785 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16786 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16787 16788 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16789 ins_encode %{ 16790 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16791 __ string_compare($str1$$Register, $str2$$Register, 16792 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16793 $tmp1$$Register, $tmp2$$Register, 16794 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16795 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16796 StrIntrinsicNode::LL); 16797 %} 16798 ins_pipe(pipe_class_memory); 16799 %} 16800 16801 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16802 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16803 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16804 pRegGov_P1 pgtmp2, rFlagsReg cr) 16805 %{ 16806 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16807 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16808 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16809 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16810 16811 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16812 ins_encode %{ 16813 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16814 __ string_compare($str1$$Register, $str2$$Register, 16815 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16816 $tmp1$$Register, $tmp2$$Register, 16817 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16818 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16819 StrIntrinsicNode::LU); 16820 %} 16821 ins_pipe(pipe_class_memory); 16822 %} 16823 16824 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16825 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16826 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16827 pRegGov_P1 pgtmp2, rFlagsReg cr) 16828 %{ 16829 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16830 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16831 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16832 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16833 16834 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16835 ins_encode %{ 16836 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16837 __ string_compare($str1$$Register, $str2$$Register, 16838 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16839 $tmp1$$Register, $tmp2$$Register, 16840 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16841 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16842 StrIntrinsicNode::UL); 16843 %} 16844 ins_pipe(pipe_class_memory); 16845 %} 16846 16847 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16848 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16849 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16850 pRegGov_P1 pgtmp2, rFlagsReg cr) 16851 %{ 16852 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16853 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16854 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16855 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16856 16857 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16858 ins_encode %{ 16859 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16860 __ string_compare($str1$$Register, $str2$$Register, 16861 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16862 $tmp1$$Register, $tmp2$$Register, 16863 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16864 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16865 StrIntrinsicNode::UU); 16866 %} 16867 ins_pipe(pipe_class_memory); 16868 %} 16869 16870 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16871 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16872 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16873 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16874 %{ 16875 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16876 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16877 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16878 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16879 TEMP vtmp0, TEMP vtmp1, KILL cr); 16880 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) " 16881 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16882 16883 ins_encode %{ 16884 __ string_indexof($str1$$Register, $str2$$Register, 16885 $cnt1$$Register, $cnt2$$Register, 16886 $tmp1$$Register, $tmp2$$Register, 16887 $tmp3$$Register, $tmp4$$Register, 16888 $tmp5$$Register, $tmp6$$Register, 16889 -1, $result$$Register, StrIntrinsicNode::UU); 16890 %} 16891 ins_pipe(pipe_class_memory); 16892 %} 16893 16894 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16895 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16896 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16897 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16898 %{ 16899 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16900 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16901 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16902 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16903 TEMP vtmp0, TEMP vtmp1, KILL cr); 16904 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) " 16905 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16906 16907 ins_encode %{ 16908 __ string_indexof($str1$$Register, $str2$$Register, 16909 $cnt1$$Register, $cnt2$$Register, 16910 $tmp1$$Register, $tmp2$$Register, 16911 $tmp3$$Register, $tmp4$$Register, 16912 $tmp5$$Register, $tmp6$$Register, 16913 -1, $result$$Register, StrIntrinsicNode::LL); 16914 %} 16915 ins_pipe(pipe_class_memory); 16916 %} 16917 16918 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16919 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3, 16920 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16921 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16922 %{ 16923 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16924 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16925 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16926 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 16927 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr); 16928 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) " 16929 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16930 16931 ins_encode %{ 16932 __ string_indexof($str1$$Register, $str2$$Register, 16933 $cnt1$$Register, $cnt2$$Register, 16934 $tmp1$$Register, $tmp2$$Register, 16935 $tmp3$$Register, $tmp4$$Register, 16936 $tmp5$$Register, $tmp6$$Register, 16937 -1, $result$$Register, StrIntrinsicNode::UL); 16938 %} 16939 ins_pipe(pipe_class_memory); 16940 %} 16941 16942 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16943 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16944 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16945 %{ 16946 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16947 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16948 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16949 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16950 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) " 16951 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16952 16953 ins_encode %{ 16954 int icnt2 = (int)$int_cnt2$$constant; 16955 __ string_indexof($str1$$Register, $str2$$Register, 16956 $cnt1$$Register, zr, 16957 $tmp1$$Register, $tmp2$$Register, 16958 $tmp3$$Register, $tmp4$$Register, zr, zr, 16959 icnt2, $result$$Register, StrIntrinsicNode::UU); 16960 %} 16961 ins_pipe(pipe_class_memory); 16962 %} 16963 16964 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16965 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16966 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16967 %{ 16968 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16969 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16970 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16971 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16972 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) " 16973 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16974 16975 ins_encode %{ 16976 int icnt2 = (int)$int_cnt2$$constant; 16977 __ string_indexof($str1$$Register, $str2$$Register, 16978 $cnt1$$Register, zr, 16979 $tmp1$$Register, $tmp2$$Register, 16980 $tmp3$$Register, $tmp4$$Register, zr, zr, 16981 icnt2, $result$$Register, StrIntrinsicNode::LL); 16982 %} 16983 ins_pipe(pipe_class_memory); 16984 %} 16985 16986 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16987 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16988 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16989 %{ 16990 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16991 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16992 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16993 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16994 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) " 16995 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16996 16997 ins_encode %{ 16998 int icnt2 = (int)$int_cnt2$$constant; 16999 __ string_indexof($str1$$Register, $str2$$Register, 17000 $cnt1$$Register, zr, 17001 $tmp1$$Register, $tmp2$$Register, 17002 $tmp3$$Register, $tmp4$$Register, zr, zr, 17003 icnt2, $result$$Register, StrIntrinsicNode::UL); 17004 %} 17005 ins_pipe(pipe_class_memory); 17006 %} 17007 17008 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17009 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17010 iRegINoSp tmp3, rFlagsReg cr) 17011 %{ 17012 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17013 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 17014 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17015 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17016 17017 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17018 17019 ins_encode %{ 17020 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17021 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17022 $tmp3$$Register); 17023 %} 17024 ins_pipe(pipe_class_memory); 17025 %} 17026 17027 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17028 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17029 iRegINoSp tmp3, rFlagsReg cr) 17030 %{ 17031 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17032 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 17033 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17034 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17035 17036 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17037 17038 ins_encode %{ 17039 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17040 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17041 $tmp3$$Register); 17042 %} 17043 ins_pipe(pipe_class_memory); 17044 %} 17045 17046 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17047 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17048 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17049 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 17050 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17051 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17052 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17053 ins_encode %{ 17054 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17055 $result$$Register, $ztmp1$$FloatRegister, 17056 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17057 $ptmp$$PRegister, true /* isL */); 17058 %} 17059 ins_pipe(pipe_class_memory); 17060 %} 17061 17062 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17063 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17064 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17065 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 17066 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17067 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17068 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17069 ins_encode %{ 17070 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17071 $result$$Register, $ztmp1$$FloatRegister, 17072 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17073 $ptmp$$PRegister, false /* isL */); 17074 %} 17075 ins_pipe(pipe_class_memory); 17076 %} 17077 17078 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 17079 iRegI_R0 result, rFlagsReg cr) 17080 %{ 17081 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 17082 match(Set result (StrEquals (Binary str1 str2) cnt)); 17083 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 17084 17085 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 17086 ins_encode %{ 17087 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 17088 __ string_equals($str1$$Register, $str2$$Register, 17089 $result$$Register, $cnt$$Register, 1); 17090 %} 17091 ins_pipe(pipe_class_memory); 17092 %} 17093 17094 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 17095 iRegI_R0 result, rFlagsReg cr) 17096 %{ 17097 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 17098 match(Set result (StrEquals (Binary str1 str2) cnt)); 17099 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 17100 17101 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 17102 ins_encode %{ 17103 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 17104 __ string_equals($str1$$Register, $str2$$Register, 17105 $result$$Register, $cnt$$Register, 2); 17106 %} 17107 ins_pipe(pipe_class_memory); 17108 %} 17109 17110 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17111 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17112 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17113 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17114 iRegP_R10 tmp, rFlagsReg cr) 17115 %{ 17116 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 17117 match(Set result (AryEq ary1 ary2)); 17118 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17119 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17120 TEMP vtmp6, TEMP vtmp7, KILL cr); 17121 17122 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17123 ins_encode %{ 17124 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17125 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17126 $result$$Register, $tmp$$Register, 1); 17127 if (tpc == NULL) { 17128 ciEnv::current()->record_failure("CodeCache is full"); 17129 return; 17130 } 17131 %} 17132 ins_pipe(pipe_class_memory); 17133 %} 17134 17135 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17136 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17137 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17138 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17139 iRegP_R10 tmp, rFlagsReg cr) 17140 %{ 17141 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 17142 match(Set result (AryEq ary1 ary2)); 17143 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17144 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17145 TEMP vtmp6, TEMP vtmp7, KILL cr); 17146 17147 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17148 ins_encode %{ 17149 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17150 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17151 $result$$Register, $tmp$$Register, 2); 17152 if (tpc == NULL) { 17153 ciEnv::current()->record_failure("CodeCache is full"); 17154 return; 17155 } 17156 %} 17157 ins_pipe(pipe_class_memory); 17158 %} 17159 17160 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 17161 %{ 17162 match(Set result (CountPositives ary1 len)); 17163 effect(USE_KILL ary1, USE_KILL len, KILL cr); 17164 format %{ "count positives byte[] $ary1,$len -> $result" %} 17165 ins_encode %{ 17166 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register); 17167 if (tpc == NULL) { 17168 ciEnv::current()->record_failure("CodeCache is full"); 17169 return; 17170 } 17171 %} 17172 ins_pipe( pipe_slow ); 17173 %} 17174 17175 // fast char[] to byte[] compression 17176 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17177 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17178 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17179 iRegI_R0 result, rFlagsReg cr) 17180 %{ 17181 match(Set result (StrCompressedCopy src (Binary dst len))); 17182 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17183 USE_KILL src, USE_KILL dst, USE len, KILL cr); 17184 17185 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17186 ins_encode %{ 17187 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 17188 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17189 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17190 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17191 %} 17192 ins_pipe(pipe_slow); 17193 %} 17194 17195 // fast byte[] to char[] inflation 17196 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp, 17197 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17198 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr) 17199 %{ 17200 match(Set dummy (StrInflatedCopy src (Binary dst len))); 17201 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, 17202 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp, 17203 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 17204 17205 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %} 17206 ins_encode %{ 17207 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 17208 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17209 $vtmp2$$FloatRegister, $tmp$$Register); 17210 if (tpc == NULL) { 17211 ciEnv::current()->record_failure("CodeCache is full"); 17212 return; 17213 } 17214 %} 17215 ins_pipe(pipe_class_memory); 17216 %} 17217 17218 // encode char[] to byte[] in ISO_8859_1 17219 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17220 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17221 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17222 iRegI_R0 result, rFlagsReg cr) 17223 %{ 17224 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 17225 match(Set result (EncodeISOArray src (Binary dst len))); 17226 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17227 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17228 17229 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17230 ins_encode %{ 17231 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17232 $result$$Register, false, 17233 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17234 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17235 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17236 %} 17237 ins_pipe(pipe_class_memory); 17238 %} 17239 17240 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17241 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17242 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17243 iRegI_R0 result, rFlagsReg cr) 17244 %{ 17245 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 17246 match(Set result (EncodeISOArray src (Binary dst len))); 17247 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17248 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17249 17250 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17251 ins_encode %{ 17252 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17253 $result$$Register, true, 17254 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17255 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17256 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17257 %} 17258 ins_pipe(pipe_class_memory); 17259 %} 17260 17261 //----------------------------- CompressBits/ExpandBits ------------------------ 17262 17263 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17264 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17265 match(Set dst (CompressBits src mask)); 17266 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17267 format %{ "mov $tsrc, $src\n\t" 17268 "mov $tmask, $mask\n\t" 17269 "bext $tdst, $tsrc, $tmask\n\t" 17270 "mov $dst, $tdst" 17271 %} 17272 ins_encode %{ 17273 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17274 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17275 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17276 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17277 %} 17278 ins_pipe(pipe_slow); 17279 %} 17280 17281 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17282 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17283 match(Set dst (CompressBits (LoadI mem) mask)); 17284 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17285 format %{ "ldrs $tsrc, $mem\n\t" 17286 "ldrs $tmask, $mask\n\t" 17287 "bext $tdst, $tsrc, $tmask\n\t" 17288 "mov $dst, $tdst" 17289 %} 17290 ins_encode %{ 17291 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17292 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17293 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17294 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17295 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17296 %} 17297 ins_pipe(pipe_slow); 17298 %} 17299 17300 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17301 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17302 match(Set dst (CompressBits src mask)); 17303 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17304 format %{ "mov $tsrc, $src\n\t" 17305 "mov $tmask, $mask\n\t" 17306 "bext $tdst, $tsrc, $tmask\n\t" 17307 "mov $dst, $tdst" 17308 %} 17309 ins_encode %{ 17310 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17311 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17312 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17313 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17314 %} 17315 ins_pipe(pipe_slow); 17316 %} 17317 17318 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask, 17319 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17320 match(Set dst (CompressBits (LoadL mem) mask)); 17321 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17322 format %{ "ldrd $tsrc, $mem\n\t" 17323 "ldrd $tmask, $mask\n\t" 17324 "bext $tdst, $tsrc, $tmask\n\t" 17325 "mov $dst, $tdst" 17326 %} 17327 ins_encode %{ 17328 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17329 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17330 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17331 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17332 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17333 %} 17334 ins_pipe(pipe_slow); 17335 %} 17336 17337 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17338 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17339 match(Set dst (ExpandBits src mask)); 17340 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17341 format %{ "mov $tsrc, $src\n\t" 17342 "mov $tmask, $mask\n\t" 17343 "bdep $tdst, $tsrc, $tmask\n\t" 17344 "mov $dst, $tdst" 17345 %} 17346 ins_encode %{ 17347 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17348 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17349 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17350 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17351 %} 17352 ins_pipe(pipe_slow); 17353 %} 17354 17355 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17356 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17357 match(Set dst (ExpandBits (LoadI mem) mask)); 17358 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17359 format %{ "ldrs $tsrc, $mem\n\t" 17360 "ldrs $tmask, $mask\n\t" 17361 "bdep $tdst, $tsrc, $tmask\n\t" 17362 "mov $dst, $tdst" 17363 %} 17364 ins_encode %{ 17365 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17366 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17367 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17368 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17369 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17370 %} 17371 ins_pipe(pipe_slow); 17372 %} 17373 17374 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17375 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17376 match(Set dst (ExpandBits src mask)); 17377 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17378 format %{ "mov $tsrc, $src\n\t" 17379 "mov $tmask, $mask\n\t" 17380 "bdep $tdst, $tsrc, $tmask\n\t" 17381 "mov $dst, $tdst" 17382 %} 17383 ins_encode %{ 17384 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17385 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17386 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17387 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17388 %} 17389 ins_pipe(pipe_slow); 17390 %} 17391 17392 17393 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask, 17394 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17395 match(Set dst (ExpandBits (LoadL mem) mask)); 17396 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17397 format %{ "ldrd $tsrc, $mem\n\t" 17398 "ldrd $tmask, $mask\n\t" 17399 "bdep $tdst, $tsrc, $tmask\n\t" 17400 "mov $dst, $tdst" 17401 %} 17402 ins_encode %{ 17403 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17404 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17405 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17406 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17407 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17408 %} 17409 ins_pipe(pipe_slow); 17410 %} 17411 17412 // ============================================================================ 17413 // This name is KNOWN by the ADLC and cannot be changed. 17414 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 17415 // for this guy. 17416 instruct tlsLoadP(thread_RegP dst) 17417 %{ 17418 match(Set dst (ThreadLocal)); 17419 17420 ins_cost(0); 17421 17422 format %{ " -- \t// $dst=Thread::current(), empty" %} 17423 17424 size(0); 17425 17426 ins_encode( /*empty*/ ); 17427 17428 ins_pipe(pipe_class_empty); 17429 %} 17430 17431 //----------PEEPHOLE RULES----------------------------------------------------- 17432 // These must follow all instruction definitions as they use the names 17433 // defined in the instructions definitions. 17434 // 17435 // peepmatch ( root_instr_name [preceding_instruction]* ); 17436 // 17437 // peepconstraint %{ 17438 // (instruction_number.operand_name relational_op instruction_number.operand_name 17439 // [, ...] ); 17440 // // instruction numbers are zero-based using left to right order in peepmatch 17441 // 17442 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17443 // // provide an instruction_number.operand_name for each operand that appears 17444 // // in the replacement instruction's match rule 17445 // 17446 // ---------VM FLAGS--------------------------------------------------------- 17447 // 17448 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17449 // 17450 // Each peephole rule is given an identifying number starting with zero and 17451 // increasing by one in the order seen by the parser. An individual peephole 17452 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17453 // on the command-line. 17454 // 17455 // ---------CURRENT LIMITATIONS---------------------------------------------- 17456 // 17457 // Only match adjacent instructions in same basic block 17458 // Only equality constraints 17459 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17460 // Only one replacement instruction 17461 // 17462 // ---------EXAMPLE---------------------------------------------------------- 17463 // 17464 // // pertinent parts of existing instructions in architecture description 17465 // instruct movI(iRegINoSp dst, iRegI src) 17466 // %{ 17467 // match(Set dst (CopyI src)); 17468 // %} 17469 // 17470 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17471 // %{ 17472 // match(Set dst (AddI dst src)); 17473 // effect(KILL cr); 17474 // %} 17475 // 17476 // // Change (inc mov) to lea 17477 // peephole %{ 17478 // // increment preceded by register-register move 17479 // peepmatch ( incI_iReg movI ); 17480 // // require that the destination register of the increment 17481 // // match the destination register of the move 17482 // peepconstraint ( 0.dst == 1.dst ); 17483 // // construct a replacement instruction that sets 17484 // // the destination to ( move's source register + one ) 17485 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17486 // %} 17487 // 17488 17489 // Implementation no longer uses movX instructions since 17490 // machine-independent system no longer uses CopyX nodes. 17491 // 17492 // peephole 17493 // %{ 17494 // peepmatch (incI_iReg movI); 17495 // peepconstraint (0.dst == 1.dst); 17496 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17497 // %} 17498 17499 // peephole 17500 // %{ 17501 // peepmatch (decI_iReg movI); 17502 // peepconstraint (0.dst == 1.dst); 17503 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17504 // %} 17505 17506 // peephole 17507 // %{ 17508 // peepmatch (addI_iReg_imm movI); 17509 // peepconstraint (0.dst == 1.dst); 17510 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17511 // %} 17512 17513 // peephole 17514 // %{ 17515 // peepmatch (incL_iReg movL); 17516 // peepconstraint (0.dst == 1.dst); 17517 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17518 // %} 17519 17520 // peephole 17521 // %{ 17522 // peepmatch (decL_iReg movL); 17523 // peepconstraint (0.dst == 1.dst); 17524 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17525 // %} 17526 17527 // peephole 17528 // %{ 17529 // peepmatch (addL_iReg_imm movL); 17530 // peepconstraint (0.dst == 1.dst); 17531 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17532 // %} 17533 17534 // peephole 17535 // %{ 17536 // peepmatch (addP_iReg_imm movP); 17537 // peepconstraint (0.dst == 1.dst); 17538 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17539 // %} 17540 17541 // // Change load of spilled value to only a spill 17542 // instruct storeI(memory mem, iRegI src) 17543 // %{ 17544 // match(Set mem (StoreI mem src)); 17545 // %} 17546 // 17547 // instruct loadI(iRegINoSp dst, memory mem) 17548 // %{ 17549 // match(Set dst (LoadI mem)); 17550 // %} 17551 // 17552 17553 //----------SMARTSPILL RULES--------------------------------------------------- 17554 // These must follow all instruction definitions as they use the names 17555 // defined in the instructions definitions. 17556 17557 // Local Variables: 17558 // mode: c++ 17559 // End: