1 // 2 // Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2024, 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 non_special pointer registers (excluding rfp) 698 reg_class no_special_no_rfp_ptr_reg %{ 699 return _NO_SPECIAL_NO_RFP_PTR_REG_mask; 700 %} 701 702 // Class for all float registers 703 reg_class float_reg( 704 V0, 705 V1, 706 V2, 707 V3, 708 V4, 709 V5, 710 V6, 711 V7, 712 V8, 713 V9, 714 V10, 715 V11, 716 V12, 717 V13, 718 V14, 719 V15, 720 V16, 721 V17, 722 V18, 723 V19, 724 V20, 725 V21, 726 V22, 727 V23, 728 V24, 729 V25, 730 V26, 731 V27, 732 V28, 733 V29, 734 V30, 735 V31 736 ); 737 738 // Double precision float registers have virtual `high halves' that 739 // are needed by the allocator. 740 // Class for all double registers 741 reg_class double_reg( 742 V0, V0_H, 743 V1, V1_H, 744 V2, V2_H, 745 V3, V3_H, 746 V4, V4_H, 747 V5, V5_H, 748 V6, V6_H, 749 V7, V7_H, 750 V8, V8_H, 751 V9, V9_H, 752 V10, V10_H, 753 V11, V11_H, 754 V12, V12_H, 755 V13, V13_H, 756 V14, V14_H, 757 V15, V15_H, 758 V16, V16_H, 759 V17, V17_H, 760 V18, V18_H, 761 V19, V19_H, 762 V20, V20_H, 763 V21, V21_H, 764 V22, V22_H, 765 V23, V23_H, 766 V24, V24_H, 767 V25, V25_H, 768 V26, V26_H, 769 V27, V27_H, 770 V28, V28_H, 771 V29, V29_H, 772 V30, V30_H, 773 V31, V31_H 774 ); 775 776 // Class for all SVE vector registers. 777 reg_class vectora_reg ( 778 V0, V0_H, V0_J, V0_K, 779 V1, V1_H, V1_J, V1_K, 780 V2, V2_H, V2_J, V2_K, 781 V3, V3_H, V3_J, V3_K, 782 V4, V4_H, V4_J, V4_K, 783 V5, V5_H, V5_J, V5_K, 784 V6, V6_H, V6_J, V6_K, 785 V7, V7_H, V7_J, V7_K, 786 V8, V8_H, V8_J, V8_K, 787 V9, V9_H, V9_J, V9_K, 788 V10, V10_H, V10_J, V10_K, 789 V11, V11_H, V11_J, V11_K, 790 V12, V12_H, V12_J, V12_K, 791 V13, V13_H, V13_J, V13_K, 792 V14, V14_H, V14_J, V14_K, 793 V15, V15_H, V15_J, V15_K, 794 V16, V16_H, V16_J, V16_K, 795 V17, V17_H, V17_J, V17_K, 796 V18, V18_H, V18_J, V18_K, 797 V19, V19_H, V19_J, V19_K, 798 V20, V20_H, V20_J, V20_K, 799 V21, V21_H, V21_J, V21_K, 800 V22, V22_H, V22_J, V22_K, 801 V23, V23_H, V23_J, V23_K, 802 V24, V24_H, V24_J, V24_K, 803 V25, V25_H, V25_J, V25_K, 804 V26, V26_H, V26_J, V26_K, 805 V27, V27_H, V27_J, V27_K, 806 V28, V28_H, V28_J, V28_K, 807 V29, V29_H, V29_J, V29_K, 808 V30, V30_H, V30_J, V30_K, 809 V31, V31_H, V31_J, V31_K, 810 ); 811 812 // Class for all 64bit vector registers 813 reg_class vectord_reg( 814 V0, V0_H, 815 V1, V1_H, 816 V2, V2_H, 817 V3, V3_H, 818 V4, V4_H, 819 V5, V5_H, 820 V6, V6_H, 821 V7, V7_H, 822 V8, V8_H, 823 V9, V9_H, 824 V10, V10_H, 825 V11, V11_H, 826 V12, V12_H, 827 V13, V13_H, 828 V14, V14_H, 829 V15, V15_H, 830 V16, V16_H, 831 V17, V17_H, 832 V18, V18_H, 833 V19, V19_H, 834 V20, V20_H, 835 V21, V21_H, 836 V22, V22_H, 837 V23, V23_H, 838 V24, V24_H, 839 V25, V25_H, 840 V26, V26_H, 841 V27, V27_H, 842 V28, V28_H, 843 V29, V29_H, 844 V30, V30_H, 845 V31, V31_H 846 ); 847 848 // Class for all 128bit vector registers 849 reg_class vectorx_reg( 850 V0, V0_H, V0_J, V0_K, 851 V1, V1_H, V1_J, V1_K, 852 V2, V2_H, V2_J, V2_K, 853 V3, V3_H, V3_J, V3_K, 854 V4, V4_H, V4_J, V4_K, 855 V5, V5_H, V5_J, V5_K, 856 V6, V6_H, V6_J, V6_K, 857 V7, V7_H, V7_J, V7_K, 858 V8, V8_H, V8_J, V8_K, 859 V9, V9_H, V9_J, V9_K, 860 V10, V10_H, V10_J, V10_K, 861 V11, V11_H, V11_J, V11_K, 862 V12, V12_H, V12_J, V12_K, 863 V13, V13_H, V13_J, V13_K, 864 V14, V14_H, V14_J, V14_K, 865 V15, V15_H, V15_J, V15_K, 866 V16, V16_H, V16_J, V16_K, 867 V17, V17_H, V17_J, V17_K, 868 V18, V18_H, V18_J, V18_K, 869 V19, V19_H, V19_J, V19_K, 870 V20, V20_H, V20_J, V20_K, 871 V21, V21_H, V21_J, V21_K, 872 V22, V22_H, V22_J, V22_K, 873 V23, V23_H, V23_J, V23_K, 874 V24, V24_H, V24_J, V24_K, 875 V25, V25_H, V25_J, V25_K, 876 V26, V26_H, V26_J, V26_K, 877 V27, V27_H, V27_J, V27_K, 878 V28, V28_H, V28_J, V28_K, 879 V29, V29_H, V29_J, V29_K, 880 V30, V30_H, V30_J, V30_K, 881 V31, V31_H, V31_J, V31_K 882 ); 883 884 // Class for 128 bit register v0 885 reg_class v0_reg( 886 V0, V0_H 887 ); 888 889 // Class for 128 bit register v1 890 reg_class v1_reg( 891 V1, V1_H 892 ); 893 894 // Class for 128 bit register v2 895 reg_class v2_reg( 896 V2, V2_H 897 ); 898 899 // Class for 128 bit register v3 900 reg_class v3_reg( 901 V3, V3_H 902 ); 903 904 // Class for 128 bit register v4 905 reg_class v4_reg( 906 V4, V4_H 907 ); 908 909 // Class for 128 bit register v5 910 reg_class v5_reg( 911 V5, V5_H 912 ); 913 914 // Class for 128 bit register v6 915 reg_class v6_reg( 916 V6, V6_H 917 ); 918 919 // Class for 128 bit register v7 920 reg_class v7_reg( 921 V7, V7_H 922 ); 923 924 // Class for 128 bit register v8 925 reg_class v8_reg( 926 V8, V8_H 927 ); 928 929 // Class for 128 bit register v9 930 reg_class v9_reg( 931 V9, V9_H 932 ); 933 934 // Class for 128 bit register v10 935 reg_class v10_reg( 936 V10, V10_H 937 ); 938 939 // Class for 128 bit register v11 940 reg_class v11_reg( 941 V11, V11_H 942 ); 943 944 // Class for 128 bit register v12 945 reg_class v12_reg( 946 V12, V12_H 947 ); 948 949 // Class for 128 bit register v13 950 reg_class v13_reg( 951 V13, V13_H 952 ); 953 954 // Class for 128 bit register v14 955 reg_class v14_reg( 956 V14, V14_H 957 ); 958 959 // Class for 128 bit register v15 960 reg_class v15_reg( 961 V15, V15_H 962 ); 963 964 // Class for 128 bit register v16 965 reg_class v16_reg( 966 V16, V16_H 967 ); 968 969 // Class for 128 bit register v17 970 reg_class v17_reg( 971 V17, V17_H 972 ); 973 974 // Class for 128 bit register v18 975 reg_class v18_reg( 976 V18, V18_H 977 ); 978 979 // Class for 128 bit register v19 980 reg_class v19_reg( 981 V19, V19_H 982 ); 983 984 // Class for 128 bit register v20 985 reg_class v20_reg( 986 V20, V20_H 987 ); 988 989 // Class for 128 bit register v21 990 reg_class v21_reg( 991 V21, V21_H 992 ); 993 994 // Class for 128 bit register v22 995 reg_class v22_reg( 996 V22, V22_H 997 ); 998 999 // Class for 128 bit register v23 1000 reg_class v23_reg( 1001 V23, V23_H 1002 ); 1003 1004 // Class for 128 bit register v24 1005 reg_class v24_reg( 1006 V24, V24_H 1007 ); 1008 1009 // Class for 128 bit register v25 1010 reg_class v25_reg( 1011 V25, V25_H 1012 ); 1013 1014 // Class for 128 bit register v26 1015 reg_class v26_reg( 1016 V26, V26_H 1017 ); 1018 1019 // Class for 128 bit register v27 1020 reg_class v27_reg( 1021 V27, V27_H 1022 ); 1023 1024 // Class for 128 bit register v28 1025 reg_class v28_reg( 1026 V28, V28_H 1027 ); 1028 1029 // Class for 128 bit register v29 1030 reg_class v29_reg( 1031 V29, V29_H 1032 ); 1033 1034 // Class for 128 bit register v30 1035 reg_class v30_reg( 1036 V30, V30_H 1037 ); 1038 1039 // Class for 128 bit register v31 1040 reg_class v31_reg( 1041 V31, V31_H 1042 ); 1043 1044 // Class for all SVE predicate registers. 1045 reg_class pr_reg ( 1046 P0, 1047 P1, 1048 P2, 1049 P3, 1050 P4, 1051 P5, 1052 P6, 1053 // P7, non-allocatable, preserved with all elements preset to TRUE. 1054 P8, 1055 P9, 1056 P10, 1057 P11, 1058 P12, 1059 P13, 1060 P14, 1061 P15 1062 ); 1063 1064 // Class for SVE governing predicate registers, which are used 1065 // to determine the active elements of a predicated instruction. 1066 reg_class gov_pr ( 1067 P0, 1068 P1, 1069 P2, 1070 P3, 1071 P4, 1072 P5, 1073 P6, 1074 // P7, non-allocatable, preserved with all elements preset to TRUE. 1075 ); 1076 1077 reg_class p0_reg(P0); 1078 reg_class p1_reg(P1); 1079 1080 // Singleton class for condition codes 1081 reg_class int_flags(RFLAGS); 1082 1083 %} 1084 1085 //----------DEFINITION BLOCK--------------------------------------------------- 1086 // Define name --> value mappings to inform the ADLC of an integer valued name 1087 // Current support includes integer values in the range [0, 0x7FFFFFFF] 1088 // Format: 1089 // int_def <name> ( <int_value>, <expression>); 1090 // Generated Code in ad_<arch>.hpp 1091 // #define <name> (<expression>) 1092 // // value == <int_value> 1093 // Generated code in ad_<arch>.cpp adlc_verification() 1094 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 1095 // 1096 1097 // we follow the ppc-aix port in using a simple cost model which ranks 1098 // register operations as cheap, memory ops as more expensive and 1099 // branches as most expensive. the first two have a low as well as a 1100 // normal cost. huge cost appears to be a way of saying don't do 1101 // something 1102 1103 definitions %{ 1104 // The default cost (of a register move instruction). 1105 int_def INSN_COST ( 100, 100); 1106 int_def BRANCH_COST ( 200, 2 * INSN_COST); 1107 int_def CALL_COST ( 200, 2 * INSN_COST); 1108 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 1109 %} 1110 1111 1112 //----------SOURCE BLOCK------------------------------------------------------- 1113 // This is a block of C++ code which provides values, functions, and 1114 // definitions necessary in the rest of the architecture description 1115 1116 source_hpp %{ 1117 1118 #include "asm/macroAssembler.hpp" 1119 #include "gc/shared/barrierSetAssembler.hpp" 1120 #include "gc/shared/cardTable.hpp" 1121 #include "gc/shared/cardTableBarrierSet.hpp" 1122 #include "gc/shared/collectedHeap.hpp" 1123 #include "opto/addnode.hpp" 1124 #include "opto/convertnode.hpp" 1125 #include "runtime/objectMonitor.hpp" 1126 1127 extern RegMask _ANY_REG32_mask; 1128 extern RegMask _ANY_REG_mask; 1129 extern RegMask _PTR_REG_mask; 1130 extern RegMask _NO_SPECIAL_REG32_mask; 1131 extern RegMask _NO_SPECIAL_REG_mask; 1132 extern RegMask _NO_SPECIAL_PTR_REG_mask; 1133 extern RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask; 1134 1135 class CallStubImpl { 1136 1137 //-------------------------------------------------------------- 1138 //---< Used for optimization in Compile::shorten_branches >--- 1139 //-------------------------------------------------------------- 1140 1141 public: 1142 // Size of call trampoline stub. 1143 static uint size_call_trampoline() { 1144 return 0; // no call trampolines on this platform 1145 } 1146 1147 // number of relocations needed by a call trampoline stub 1148 static uint reloc_call_trampoline() { 1149 return 0; // no call trampolines on this platform 1150 } 1151 }; 1152 1153 class HandlerImpl { 1154 1155 public: 1156 1157 static int emit_exception_handler(C2_MacroAssembler *masm); 1158 static int emit_deopt_handler(C2_MacroAssembler* masm); 1159 1160 static uint size_exception_handler() { 1161 return MacroAssembler::far_codestub_branch_size(); 1162 } 1163 1164 static uint size_deopt_handler() { 1165 // count one adr and one far branch instruction 1166 return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size(); 1167 } 1168 }; 1169 1170 class Node::PD { 1171 public: 1172 enum NodeFlags { 1173 _last_flag = Node::_last_flag 1174 }; 1175 }; 1176 1177 bool is_CAS(int opcode, bool maybe_volatile); 1178 1179 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1180 1181 bool unnecessary_acquire(const Node *barrier); 1182 bool needs_acquiring_load(const Node *load); 1183 1184 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1185 1186 bool unnecessary_release(const Node *barrier); 1187 bool unnecessary_volatile(const Node *barrier); 1188 bool needs_releasing_store(const Node *store); 1189 1190 // predicate controlling translation of CompareAndSwapX 1191 bool needs_acquiring_load_exclusive(const Node *load); 1192 1193 // predicate controlling addressing modes 1194 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1195 1196 // Convert BootTest condition to Assembler condition. 1197 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 1198 Assembler::Condition to_assembler_cond(BoolTest::mask cond); 1199 %} 1200 1201 source %{ 1202 1203 // Derived RegMask with conditionally allocatable registers 1204 1205 void PhaseOutput::pd_perform_mach_node_analysis() { 1206 } 1207 1208 int MachNode::pd_alignment_required() const { 1209 return 1; 1210 } 1211 1212 int MachNode::compute_padding(int current_offset) const { 1213 return 0; 1214 } 1215 1216 RegMask _ANY_REG32_mask; 1217 RegMask _ANY_REG_mask; 1218 RegMask _PTR_REG_mask; 1219 RegMask _NO_SPECIAL_REG32_mask; 1220 RegMask _NO_SPECIAL_REG_mask; 1221 RegMask _NO_SPECIAL_PTR_REG_mask; 1222 RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask; 1223 1224 void reg_mask_init() { 1225 // We derive below RegMask(s) from the ones which are auto-generated from 1226 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1227 // registers conditionally reserved. 1228 1229 _ANY_REG32_mask = _ALL_REG32_mask; 1230 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1231 1232 _ANY_REG_mask = _ALL_REG_mask; 1233 1234 _PTR_REG_mask = _ALL_REG_mask; 1235 1236 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1237 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1238 1239 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1240 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1241 1242 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1243 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1244 1245 // r27 is not allocatable when compressed oops is on and heapbase is not 1246 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1247 if (UseCompressedOops && (CompressedOops::base() != nullptr)) { 1248 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1249 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1250 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1251 } 1252 1253 // r29 is not allocatable when PreserveFramePointer is on 1254 if (PreserveFramePointer) { 1255 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1256 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1257 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1258 } 1259 1260 _NO_SPECIAL_NO_RFP_PTR_REG_mask = _NO_SPECIAL_PTR_REG_mask; 1261 _NO_SPECIAL_NO_RFP_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1262 } 1263 1264 // Optimizaton of volatile gets and puts 1265 // ------------------------------------- 1266 // 1267 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1268 // use to implement volatile reads and writes. For a volatile read 1269 // we simply need 1270 // 1271 // ldar<x> 1272 // 1273 // and for a volatile write we need 1274 // 1275 // stlr<x> 1276 // 1277 // Alternatively, we can implement them by pairing a normal 1278 // load/store with a memory barrier. For a volatile read we need 1279 // 1280 // ldr<x> 1281 // dmb ishld 1282 // 1283 // for a volatile write 1284 // 1285 // dmb ish 1286 // str<x> 1287 // dmb ish 1288 // 1289 // We can also use ldaxr and stlxr to implement compare and swap CAS 1290 // sequences. These are normally translated to an instruction 1291 // sequence like the following 1292 // 1293 // dmb ish 1294 // retry: 1295 // ldxr<x> rval raddr 1296 // cmp rval rold 1297 // b.ne done 1298 // stlxr<x> rval, rnew, rold 1299 // cbnz rval retry 1300 // done: 1301 // cset r0, eq 1302 // dmb ishld 1303 // 1304 // Note that the exclusive store is already using an stlxr 1305 // instruction. That is required to ensure visibility to other 1306 // threads of the exclusive write (assuming it succeeds) before that 1307 // of any subsequent writes. 1308 // 1309 // The following instruction sequence is an improvement on the above 1310 // 1311 // retry: 1312 // ldaxr<x> rval raddr 1313 // cmp rval rold 1314 // b.ne done 1315 // stlxr<x> rval, rnew, rold 1316 // cbnz rval retry 1317 // done: 1318 // cset r0, eq 1319 // 1320 // We don't need the leading dmb ish since the stlxr guarantees 1321 // visibility of prior writes in the case that the swap is 1322 // successful. Crucially we don't have to worry about the case where 1323 // the swap is not successful since no valid program should be 1324 // relying on visibility of prior changes by the attempting thread 1325 // in the case where the CAS fails. 1326 // 1327 // Similarly, we don't need the trailing dmb ishld if we substitute 1328 // an ldaxr instruction since that will provide all the guarantees we 1329 // require regarding observation of changes made by other threads 1330 // before any change to the CAS address observed by the load. 1331 // 1332 // In order to generate the desired instruction sequence we need to 1333 // be able to identify specific 'signature' ideal graph node 1334 // sequences which i) occur as a translation of a volatile reads or 1335 // writes or CAS operations and ii) do not occur through any other 1336 // translation or graph transformation. We can then provide 1337 // alternative aldc matching rules which translate these node 1338 // sequences to the desired machine code sequences. Selection of the 1339 // alternative rules can be implemented by predicates which identify 1340 // the relevant node sequences. 1341 // 1342 // The ideal graph generator translates a volatile read to the node 1343 // sequence 1344 // 1345 // LoadX[mo_acquire] 1346 // MemBarAcquire 1347 // 1348 // As a special case when using the compressed oops optimization we 1349 // may also see this variant 1350 // 1351 // LoadN[mo_acquire] 1352 // DecodeN 1353 // MemBarAcquire 1354 // 1355 // A volatile write is translated to the node sequence 1356 // 1357 // MemBarRelease 1358 // StoreX[mo_release] {CardMark}-optional 1359 // MemBarVolatile 1360 // 1361 // n.b. the above node patterns are generated with a strict 1362 // 'signature' configuration of input and output dependencies (see 1363 // the predicates below for exact details). The card mark may be as 1364 // simple as a few extra nodes or, in a few GC configurations, may 1365 // include more complex control flow between the leading and 1366 // trailing memory barriers. However, whatever the card mark 1367 // configuration these signatures are unique to translated volatile 1368 // reads/stores -- they will not appear as a result of any other 1369 // bytecode translation or inlining nor as a consequence of 1370 // optimizing transforms. 1371 // 1372 // We also want to catch inlined unsafe volatile gets and puts and 1373 // be able to implement them using either ldar<x>/stlr<x> or some 1374 // combination of ldr<x>/stlr<x> and dmb instructions. 1375 // 1376 // Inlined unsafe volatiles puts manifest as a minor variant of the 1377 // normal volatile put node sequence containing an extra cpuorder 1378 // membar 1379 // 1380 // MemBarRelease 1381 // MemBarCPUOrder 1382 // StoreX[mo_release] {CardMark}-optional 1383 // MemBarCPUOrder 1384 // MemBarVolatile 1385 // 1386 // n.b. as an aside, a cpuorder membar is not itself subject to 1387 // matching and translation by adlc rules. However, the rule 1388 // predicates need to detect its presence in order to correctly 1389 // select the desired adlc rules. 1390 // 1391 // Inlined unsafe volatile gets manifest as a slightly different 1392 // node sequence to a normal volatile get because of the 1393 // introduction of some CPUOrder memory barriers to bracket the 1394 // Load. However, but the same basic skeleton of a LoadX feeding a 1395 // MemBarAcquire, possibly through an optional DecodeN, is still 1396 // present 1397 // 1398 // MemBarCPUOrder 1399 // || \\ 1400 // MemBarCPUOrder LoadX[mo_acquire] 1401 // || | 1402 // || {DecodeN} optional 1403 // || / 1404 // MemBarAcquire 1405 // 1406 // In this case the acquire membar does not directly depend on the 1407 // load. However, we can be sure that the load is generated from an 1408 // inlined unsafe volatile get if we see it dependent on this unique 1409 // sequence of membar nodes. Similarly, given an acquire membar we 1410 // can know that it was added because of an inlined unsafe volatile 1411 // get if it is fed and feeds a cpuorder membar and if its feed 1412 // membar also feeds an acquiring load. 1413 // 1414 // Finally an inlined (Unsafe) CAS operation is translated to the 1415 // following ideal graph 1416 // 1417 // MemBarRelease 1418 // MemBarCPUOrder 1419 // CompareAndSwapX {CardMark}-optional 1420 // MemBarCPUOrder 1421 // MemBarAcquire 1422 // 1423 // So, where we can identify these volatile read and write 1424 // signatures we can choose to plant either of the above two code 1425 // sequences. For a volatile read we can simply plant a normal 1426 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1427 // also choose to inhibit translation of the MemBarAcquire and 1428 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1429 // 1430 // When we recognise a volatile store signature we can choose to 1431 // plant at a dmb ish as a translation for the MemBarRelease, a 1432 // normal str<x> and then a dmb ish for the MemBarVolatile. 1433 // Alternatively, we can inhibit translation of the MemBarRelease 1434 // and MemBarVolatile and instead plant a simple stlr<x> 1435 // instruction. 1436 // 1437 // when we recognise a CAS signature we can choose to plant a dmb 1438 // ish as a translation for the MemBarRelease, the conventional 1439 // macro-instruction sequence for the CompareAndSwap node (which 1440 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1441 // Alternatively, we can elide generation of the dmb instructions 1442 // and plant the alternative CompareAndSwap macro-instruction 1443 // sequence (which uses ldaxr<x>). 1444 // 1445 // Of course, the above only applies when we see these signature 1446 // configurations. We still want to plant dmb instructions in any 1447 // other cases where we may see a MemBarAcquire, MemBarRelease or 1448 // MemBarVolatile. For example, at the end of a constructor which 1449 // writes final/volatile fields we will see a MemBarRelease 1450 // instruction and this needs a 'dmb ish' lest we risk the 1451 // constructed object being visible without making the 1452 // final/volatile field writes visible. 1453 // 1454 // n.b. the translation rules below which rely on detection of the 1455 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1456 // If we see anything other than the signature configurations we 1457 // always just translate the loads and stores to ldr<x> and str<x> 1458 // and translate acquire, release and volatile membars to the 1459 // relevant dmb instructions. 1460 // 1461 1462 // is_CAS(int opcode, bool maybe_volatile) 1463 // 1464 // return true if opcode is one of the possible CompareAndSwapX 1465 // values otherwise false. 1466 1467 bool is_CAS(int opcode, bool maybe_volatile) 1468 { 1469 switch(opcode) { 1470 // We handle these 1471 case Op_CompareAndSwapI: 1472 case Op_CompareAndSwapL: 1473 case Op_CompareAndSwapP: 1474 case Op_CompareAndSwapN: 1475 case Op_ShenandoahCompareAndSwapP: 1476 case Op_ShenandoahCompareAndSwapN: 1477 case Op_CompareAndSwapB: 1478 case Op_CompareAndSwapS: 1479 case Op_GetAndSetI: 1480 case Op_GetAndSetL: 1481 case Op_GetAndSetP: 1482 case Op_GetAndSetN: 1483 case Op_GetAndAddI: 1484 case Op_GetAndAddL: 1485 return true; 1486 case Op_CompareAndExchangeI: 1487 case Op_CompareAndExchangeN: 1488 case Op_CompareAndExchangeB: 1489 case Op_CompareAndExchangeS: 1490 case Op_CompareAndExchangeL: 1491 case Op_CompareAndExchangeP: 1492 case Op_WeakCompareAndSwapB: 1493 case Op_WeakCompareAndSwapS: 1494 case Op_WeakCompareAndSwapI: 1495 case Op_WeakCompareAndSwapL: 1496 case Op_WeakCompareAndSwapP: 1497 case Op_WeakCompareAndSwapN: 1498 case Op_ShenandoahWeakCompareAndSwapP: 1499 case Op_ShenandoahWeakCompareAndSwapN: 1500 case Op_ShenandoahCompareAndExchangeP: 1501 case Op_ShenandoahCompareAndExchangeN: 1502 return maybe_volatile; 1503 default: 1504 return false; 1505 } 1506 } 1507 1508 // helper to determine the maximum number of Phi nodes we may need to 1509 // traverse when searching from a card mark membar for the merge mem 1510 // feeding a trailing membar or vice versa 1511 1512 // predicates controlling emit of ldr<x>/ldar<x> 1513 1514 bool unnecessary_acquire(const Node *barrier) 1515 { 1516 assert(barrier->is_MemBar(), "expecting a membar"); 1517 1518 MemBarNode* mb = barrier->as_MemBar(); 1519 1520 if (mb->trailing_load()) { 1521 return true; 1522 } 1523 1524 if (mb->trailing_load_store()) { 1525 Node* load_store = mb->in(MemBarNode::Precedent); 1526 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1527 return is_CAS(load_store->Opcode(), true); 1528 } 1529 1530 return false; 1531 } 1532 1533 bool needs_acquiring_load(const Node *n) 1534 { 1535 assert(n->is_Load(), "expecting a load"); 1536 LoadNode *ld = n->as_Load(); 1537 return ld->is_acquire(); 1538 } 1539 1540 bool unnecessary_release(const Node *n) 1541 { 1542 assert((n->is_MemBar() && 1543 n->Opcode() == Op_MemBarRelease), 1544 "expecting a release membar"); 1545 1546 MemBarNode *barrier = n->as_MemBar(); 1547 if (!barrier->leading()) { 1548 return false; 1549 } else { 1550 Node* trailing = barrier->trailing_membar(); 1551 MemBarNode* trailing_mb = trailing->as_MemBar(); 1552 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1553 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1554 1555 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1556 if (mem->is_Store()) { 1557 assert(mem->as_Store()->is_release(), ""); 1558 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1559 return true; 1560 } else { 1561 assert(mem->is_LoadStore(), ""); 1562 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1563 return is_CAS(mem->Opcode(), true); 1564 } 1565 } 1566 return false; 1567 } 1568 1569 bool unnecessary_volatile(const Node *n) 1570 { 1571 // assert n->is_MemBar(); 1572 MemBarNode *mbvol = n->as_MemBar(); 1573 1574 bool release = mbvol->trailing_store(); 1575 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1576 #ifdef ASSERT 1577 if (release) { 1578 Node* leading = mbvol->leading_membar(); 1579 assert(leading->Opcode() == Op_MemBarRelease, ""); 1580 assert(leading->as_MemBar()->leading_store(), ""); 1581 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1582 } 1583 #endif 1584 1585 return release; 1586 } 1587 1588 // predicates controlling emit of str<x>/stlr<x> 1589 1590 bool needs_releasing_store(const Node *n) 1591 { 1592 // assert n->is_Store(); 1593 StoreNode *st = n->as_Store(); 1594 return st->trailing_membar() != nullptr; 1595 } 1596 1597 // predicate controlling translation of CAS 1598 // 1599 // returns true if CAS needs to use an acquiring load otherwise false 1600 1601 bool needs_acquiring_load_exclusive(const Node *n) 1602 { 1603 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1604 LoadStoreNode* ldst = n->as_LoadStore(); 1605 if (is_CAS(n->Opcode(), false)) { 1606 assert(ldst->trailing_membar() != nullptr, "expected trailing membar"); 1607 } else { 1608 return ldst->trailing_membar() != nullptr; 1609 } 1610 1611 // so we can just return true here 1612 return true; 1613 } 1614 1615 #define __ masm-> 1616 1617 // advance declarations for helper functions to convert register 1618 // indices to register objects 1619 1620 // the ad file has to provide implementations of certain methods 1621 // expected by the generic code 1622 // 1623 // REQUIRED FUNCTIONALITY 1624 1625 //============================================================================= 1626 1627 // !!!!! Special hack to get all types of calls to specify the byte offset 1628 // from the start of the call to the point where the return address 1629 // will point. 1630 1631 int MachCallStaticJavaNode::ret_addr_offset() 1632 { 1633 // call should be a simple bl 1634 int off = 4; 1635 return off; 1636 } 1637 1638 int MachCallDynamicJavaNode::ret_addr_offset() 1639 { 1640 return 16; // movz, movk, movk, bl 1641 } 1642 1643 int MachCallRuntimeNode::ret_addr_offset() { 1644 // for generated stubs the call will be 1645 // bl(addr) 1646 // or with far branches 1647 // bl(trampoline_stub) 1648 // for real runtime callouts it will be six instructions 1649 // see aarch64_enc_java_to_runtime 1650 // adr(rscratch2, retaddr) 1651 // lea(rscratch1, RuntimeAddress(addr) 1652 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1653 // blr(rscratch1) 1654 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1655 if (cb) { 1656 return 1 * NativeInstruction::instruction_size; 1657 } else { 1658 return 6 * NativeInstruction::instruction_size; 1659 } 1660 } 1661 1662 //============================================================================= 1663 1664 #ifndef PRODUCT 1665 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1666 st->print("BREAKPOINT"); 1667 } 1668 #endif 1669 1670 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1671 __ brk(0); 1672 } 1673 1674 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1675 return MachNode::size(ra_); 1676 } 1677 1678 //============================================================================= 1679 1680 #ifndef PRODUCT 1681 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1682 st->print("nop \t# %d bytes pad for loops and calls", _count); 1683 } 1684 #endif 1685 1686 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc*) const { 1687 for (int i = 0; i < _count; i++) { 1688 __ nop(); 1689 } 1690 } 1691 1692 uint MachNopNode::size(PhaseRegAlloc*) const { 1693 return _count * NativeInstruction::instruction_size; 1694 } 1695 1696 //============================================================================= 1697 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1698 1699 int ConstantTable::calculate_table_base_offset() const { 1700 return 0; // absolute addressing, no offset 1701 } 1702 1703 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1704 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1705 ShouldNotReachHere(); 1706 } 1707 1708 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 1709 // Empty encoding 1710 } 1711 1712 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1713 return 0; 1714 } 1715 1716 #ifndef PRODUCT 1717 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1718 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1719 } 1720 #endif 1721 1722 #ifndef PRODUCT 1723 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1724 Compile* C = ra_->C; 1725 1726 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1727 1728 if (C->output()->need_stack_bang(framesize)) 1729 st->print("# stack bang size=%d\n\t", framesize); 1730 1731 if (VM_Version::use_rop_protection()) { 1732 st->print("ldr zr, [lr]\n\t"); 1733 st->print("paciaz\n\t"); 1734 } 1735 if (framesize < ((1 << 9) + 2 * wordSize)) { 1736 st->print("sub sp, sp, #%d\n\t", framesize); 1737 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1738 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1739 } else { 1740 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1741 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1742 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1743 st->print("sub sp, sp, rscratch1"); 1744 } 1745 if (C->stub_function() == nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 1746 st->print("\n\t"); 1747 st->print("ldr rscratch1, [guard]\n\t"); 1748 st->print("dmb ishld\n\t"); 1749 st->print("ldr rscratch2, [rthread, #thread_disarmed_guard_value_offset]\n\t"); 1750 st->print("cmp rscratch1, rscratch2\n\t"); 1751 st->print("b.eq skip"); 1752 st->print("\n\t"); 1753 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1754 st->print("b skip\n\t"); 1755 st->print("guard: int\n\t"); 1756 st->print("\n\t"); 1757 st->print("skip:\n\t"); 1758 } 1759 } 1760 #endif 1761 1762 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1763 Compile* C = ra_->C; 1764 1765 // n.b. frame size includes space for return pc and rfp 1766 const int framesize = C->output()->frame_size_in_bytes(); 1767 1768 // insert a nop at the start of the prolog so we can patch in a 1769 // branch if we need to invalidate the method later 1770 __ nop(); 1771 1772 if (C->clinit_barrier_on_entry()) { 1773 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1774 1775 Label L_skip_barrier; 1776 1777 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1778 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1779 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1780 __ bind(L_skip_barrier); 1781 } 1782 1783 if (C->max_vector_size() > 0) { 1784 __ reinitialize_ptrue(); 1785 } 1786 1787 int bangsize = C->output()->bang_size_in_bytes(); 1788 if (C->output()->need_stack_bang(bangsize)) 1789 __ generate_stack_overflow_check(bangsize); 1790 1791 __ build_frame(framesize); 1792 1793 if (C->stub_function() == nullptr) { 1794 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1795 if (BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 1796 // Dummy labels for just measuring the code size 1797 Label dummy_slow_path; 1798 Label dummy_continuation; 1799 Label dummy_guard; 1800 Label* slow_path = &dummy_slow_path; 1801 Label* continuation = &dummy_continuation; 1802 Label* guard = &dummy_guard; 1803 if (!Compile::current()->output()->in_scratch_emit_size()) { 1804 // Use real labels from actual stub when not emitting code for the purpose of measuring its size 1805 C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub(); 1806 Compile::current()->output()->add_stub(stub); 1807 slow_path = &stub->entry(); 1808 continuation = &stub->continuation(); 1809 guard = &stub->guard(); 1810 } 1811 // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub. 1812 bs->nmethod_entry_barrier(masm, slow_path, continuation, guard); 1813 } 1814 } 1815 1816 if (VerifyStackAtCalls) { 1817 Unimplemented(); 1818 } 1819 1820 C->output()->set_frame_complete(__ offset()); 1821 1822 if (C->has_mach_constant_base_node()) { 1823 // NOTE: We set the table base offset here because users might be 1824 // emitted before MachConstantBaseNode. 1825 ConstantTable& constant_table = C->output()->constant_table(); 1826 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1827 } 1828 } 1829 1830 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1831 { 1832 return MachNode::size(ra_); // too many variables; just compute it 1833 // the hard way 1834 } 1835 1836 int MachPrologNode::reloc() const 1837 { 1838 return 0; 1839 } 1840 1841 //============================================================================= 1842 1843 #ifndef PRODUCT 1844 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1845 Compile* C = ra_->C; 1846 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1847 1848 st->print("# pop frame %d\n\t",framesize); 1849 1850 if (framesize == 0) { 1851 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1852 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1853 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1854 st->print("add sp, sp, #%d\n\t", framesize); 1855 } else { 1856 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1857 st->print("add sp, sp, rscratch1\n\t"); 1858 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1859 } 1860 if (VM_Version::use_rop_protection()) { 1861 st->print("autiaz\n\t"); 1862 st->print("ldr zr, [lr]\n\t"); 1863 } 1864 1865 if (do_polling() && C->is_method_compilation()) { 1866 st->print("# test polling word\n\t"); 1867 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset())); 1868 st->print("cmp sp, rscratch1\n\t"); 1869 st->print("bhi #slow_path"); 1870 } 1871 } 1872 #endif 1873 1874 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1875 Compile* C = ra_->C; 1876 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1877 1878 __ remove_frame(framesize); 1879 1880 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1881 __ reserved_stack_check(); 1882 } 1883 1884 if (do_polling() && C->is_method_compilation()) { 1885 Label dummy_label; 1886 Label* code_stub = &dummy_label; 1887 if (!C->output()->in_scratch_emit_size()) { 1888 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1889 C->output()->add_stub(stub); 1890 code_stub = &stub->entry(); 1891 } 1892 __ relocate(relocInfo::poll_return_type); 1893 __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); 1894 } 1895 } 1896 1897 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1898 // Variable size. Determine dynamically. 1899 return MachNode::size(ra_); 1900 } 1901 1902 int MachEpilogNode::reloc() const { 1903 // Return number of relocatable values contained in this instruction. 1904 return 1; // 1 for polling page. 1905 } 1906 1907 const Pipeline * MachEpilogNode::pipeline() const { 1908 return MachNode::pipeline_class(); 1909 } 1910 1911 //============================================================================= 1912 1913 static enum RC rc_class(OptoReg::Name reg) { 1914 1915 if (reg == OptoReg::Bad) { 1916 return rc_bad; 1917 } 1918 1919 // we have 32 int registers * 2 halves 1920 int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register; 1921 1922 if (reg < slots_of_int_registers) { 1923 return rc_int; 1924 } 1925 1926 // we have 32 float register * 8 halves 1927 int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register; 1928 if (reg < slots_of_int_registers + slots_of_float_registers) { 1929 return rc_float; 1930 } 1931 1932 int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register; 1933 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) { 1934 return rc_predicate; 1935 } 1936 1937 // Between predicate regs & stack is the flags. 1938 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1939 1940 return rc_stack; 1941 } 1942 1943 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1944 Compile* C = ra_->C; 1945 1946 // Get registers to move. 1947 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1948 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1949 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1950 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1951 1952 enum RC src_hi_rc = rc_class(src_hi); 1953 enum RC src_lo_rc = rc_class(src_lo); 1954 enum RC dst_hi_rc = rc_class(dst_hi); 1955 enum RC dst_lo_rc = rc_class(dst_lo); 1956 1957 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1958 1959 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) { 1960 assert((src_lo&1)==0 && src_lo+1==src_hi && 1961 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1962 "expected aligned-adjacent pairs"); 1963 } 1964 1965 if (src_lo == dst_lo && src_hi == dst_hi) { 1966 return 0; // Self copy, no move. 1967 } 1968 1969 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1970 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1971 int src_offset = ra_->reg2offset(src_lo); 1972 int dst_offset = ra_->reg2offset(dst_lo); 1973 1974 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 1975 uint ireg = ideal_reg(); 1976 if (ireg == Op_VecA && masm) { 1977 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); 1978 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1979 // stack->stack 1980 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset, 1981 sve_vector_reg_size_in_bytes); 1982 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1983 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 1984 sve_vector_reg_size_in_bytes); 1985 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1986 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 1987 sve_vector_reg_size_in_bytes); 1988 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1989 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1990 as_FloatRegister(Matcher::_regEncode[src_lo]), 1991 as_FloatRegister(Matcher::_regEncode[src_lo])); 1992 } else { 1993 ShouldNotReachHere(); 1994 } 1995 } else if (masm) { 1996 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 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 (masm) { 2024 switch (src_lo_rc) { 2025 case rc_int: 2026 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 2027 if (is64) { 2028 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 2029 as_Register(Matcher::_regEncode[src_lo])); 2030 } else { 2031 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 2032 as_Register(Matcher::_regEncode[src_lo])); 2033 } 2034 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 2035 if (is64) { 2036 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2037 as_Register(Matcher::_regEncode[src_lo])); 2038 } else { 2039 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2040 as_Register(Matcher::_regEncode[src_lo])); 2041 } 2042 } else { // gpr --> stack spill 2043 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2044 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 2045 } 2046 break; 2047 case rc_float: 2048 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2049 if (is64) { 2050 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2051 as_FloatRegister(Matcher::_regEncode[src_lo])); 2052 } else { 2053 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2054 as_FloatRegister(Matcher::_regEncode[src_lo])); 2055 } 2056 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2057 if (is64) { 2058 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2059 as_FloatRegister(Matcher::_regEncode[src_lo])); 2060 } else { 2061 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2062 as_FloatRegister(Matcher::_regEncode[src_lo])); 2063 } 2064 } else { // fpr --> stack spill 2065 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2066 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2067 is64 ? __ D : __ S, dst_offset); 2068 } 2069 break; 2070 case rc_stack: 2071 if (dst_lo_rc == rc_int) { // stack --> gpr load 2072 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 2073 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2074 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2075 is64 ? __ D : __ S, src_offset); 2076 } else if (dst_lo_rc == rc_predicate) { 2077 __ unspill_sve_predicate(as_PRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 2078 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2079 } else { // stack --> stack copy 2080 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2081 if (ideal_reg() == Op_RegVectMask) { 2082 __ spill_copy_sve_predicate_stack_to_stack(src_offset, dst_offset, 2083 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2084 } else { 2085 __ unspill(rscratch1, is64, src_offset); 2086 __ spill(rscratch1, is64, dst_offset); 2087 } 2088 } 2089 break; 2090 case rc_predicate: 2091 if (dst_lo_rc == rc_predicate) { 2092 __ sve_mov(as_PRegister(Matcher::_regEncode[dst_lo]), as_PRegister(Matcher::_regEncode[src_lo])); 2093 } else if (dst_lo_rc == rc_stack) { 2094 __ spill_sve_predicate(as_PRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 2095 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2096 } else { 2097 assert(false, "bad src and dst rc_class combination."); 2098 ShouldNotReachHere(); 2099 } 2100 break; 2101 default: 2102 assert(false, "bad rc_class for spill"); 2103 ShouldNotReachHere(); 2104 } 2105 } 2106 2107 if (st) { 2108 st->print("spill "); 2109 if (src_lo_rc == rc_stack) { 2110 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2111 } else { 2112 st->print("%s -> ", Matcher::regName[src_lo]); 2113 } 2114 if (dst_lo_rc == rc_stack) { 2115 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2116 } else { 2117 st->print("%s", Matcher::regName[dst_lo]); 2118 } 2119 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 2120 int vsize = 0; 2121 switch (ideal_reg()) { 2122 case Op_VecD: 2123 vsize = 64; 2124 break; 2125 case Op_VecX: 2126 vsize = 128; 2127 break; 2128 case Op_VecA: 2129 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; 2130 break; 2131 default: 2132 assert(false, "bad register type for spill"); 2133 ShouldNotReachHere(); 2134 } 2135 st->print("\t# vector spill size = %d", vsize); 2136 } else if (ideal_reg() == Op_RegVectMask) { 2137 assert(Matcher::supports_scalable_vector(), "bad register type for spill"); 2138 int vsize = Matcher::scalable_predicate_reg_slots() * 32; 2139 st->print("\t# predicate spill size = %d", vsize); 2140 } else { 2141 st->print("\t# spill size = %d", is64 ? 64 : 32); 2142 } 2143 } 2144 2145 return 0; 2146 2147 } 2148 2149 #ifndef PRODUCT 2150 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2151 if (!ra_) 2152 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2153 else 2154 implementation(nullptr, ra_, false, st); 2155 } 2156 #endif 2157 2158 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 2159 implementation(masm, ra_, false, nullptr); 2160 } 2161 2162 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2163 return MachNode::size(ra_); 2164 } 2165 2166 //============================================================================= 2167 2168 #ifndef PRODUCT 2169 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2170 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2171 int reg = ra_->get_reg_first(this); 2172 st->print("add %s, rsp, #%d]\t# box lock", 2173 Matcher::regName[reg], offset); 2174 } 2175 #endif 2176 2177 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 2178 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2179 int reg = ra_->get_encode(this); 2180 2181 // This add will handle any 24-bit signed offset. 24 bits allows an 2182 // 8 megabyte stack frame. 2183 __ add(as_Register(reg), sp, offset); 2184 } 2185 2186 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2187 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2188 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2189 2190 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2191 return NativeInstruction::instruction_size; 2192 } else { 2193 return 2 * NativeInstruction::instruction_size; 2194 } 2195 } 2196 2197 //============================================================================= 2198 2199 #ifndef PRODUCT 2200 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2201 { 2202 st->print_cr("# MachUEPNode"); 2203 if (UseCompressedClassPointers) { 2204 st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2205 st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 2206 st->print_cr("\tcmpw rscratch1, r10"); 2207 } else { 2208 st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2209 st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 2210 st->print_cr("\tcmp rscratch1, r10"); 2211 } 2212 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2213 } 2214 #endif 2215 2216 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 2217 { 2218 __ ic_check(InteriorEntryAlignment); 2219 } 2220 2221 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2222 { 2223 return MachNode::size(ra_); 2224 } 2225 2226 // REQUIRED EMIT CODE 2227 2228 //============================================================================= 2229 2230 // Emit exception handler code. 2231 int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm) 2232 { 2233 // mov rscratch1 #exception_blob_entry_point 2234 // br rscratch1 2235 // Note that the code buffer's insts_mark is always relative to insts. 2236 // That's why we must use the macroassembler to generate a handler. 2237 address base = __ start_a_stub(size_exception_handler()); 2238 if (base == nullptr) { 2239 ciEnv::current()->record_failure("CodeCache is full"); 2240 return 0; // CodeBuffer::expand failed 2241 } 2242 int offset = __ offset(); 2243 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2244 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2245 __ end_a_stub(); 2246 return offset; 2247 } 2248 2249 // Emit deopt handler code. 2250 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) 2251 { 2252 // Note that the code buffer's insts_mark is always relative to insts. 2253 // That's why we must use the macroassembler to generate a handler. 2254 address base = __ start_a_stub(size_deopt_handler()); 2255 if (base == nullptr) { 2256 ciEnv::current()->record_failure("CodeCache is full"); 2257 return 0; // CodeBuffer::expand failed 2258 } 2259 int offset = __ offset(); 2260 2261 __ adr(lr, __ pc()); 2262 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2263 2264 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow"); 2265 __ end_a_stub(); 2266 return offset; 2267 } 2268 2269 // REQUIRED MATCHER CODE 2270 2271 //============================================================================= 2272 2273 bool Matcher::match_rule_supported(int opcode) { 2274 if (!has_match_rule(opcode)) 2275 return false; 2276 2277 switch (opcode) { 2278 case Op_OnSpinWait: 2279 return VM_Version::supports_on_spin_wait(); 2280 case Op_CacheWB: 2281 case Op_CacheWBPreSync: 2282 case Op_CacheWBPostSync: 2283 if (!VM_Version::supports_data_cache_line_flush()) { 2284 return false; 2285 } 2286 break; 2287 case Op_ExpandBits: 2288 case Op_CompressBits: 2289 if (!VM_Version::supports_svebitperm()) { 2290 return false; 2291 } 2292 break; 2293 case Op_FmaF: 2294 case Op_FmaD: 2295 case Op_FmaVF: 2296 case Op_FmaVD: 2297 if (!UseFMA) { 2298 return false; 2299 } 2300 break; 2301 } 2302 2303 return true; // Per default match rules are supported. 2304 } 2305 2306 const RegMask* Matcher::predicate_reg_mask(void) { 2307 return &_PR_REG_mask; 2308 } 2309 2310 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2311 return new TypeVectMask(elemTy, length); 2312 } 2313 2314 // Vector calling convention not yet implemented. 2315 bool Matcher::supports_vector_calling_convention(void) { 2316 return false; 2317 } 2318 2319 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2320 Unimplemented(); 2321 return OptoRegPair(0, 0); 2322 } 2323 2324 // Is this branch offset short enough that a short branch can be used? 2325 // 2326 // NOTE: If the platform does not provide any short branch variants, then 2327 // this method should return false for offset 0. 2328 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2329 // The passed offset is relative to address of the branch. 2330 2331 return (-32768 <= offset && offset < 32768); 2332 } 2333 2334 // Vector width in bytes. 2335 int Matcher::vector_width_in_bytes(BasicType bt) { 2336 // The MaxVectorSize should have been set by detecting SVE max vector register size. 2337 int size = MIN2((UseSVE > 0) ? (int)FloatRegister::sve_vl_max : (int)FloatRegister::neon_vl, (int)MaxVectorSize); 2338 // Minimum 2 values in vector 2339 if (size < 2*type2aelembytes(bt)) size = 0; 2340 // But never < 4 2341 if (size < 4) size = 0; 2342 return size; 2343 } 2344 2345 // Limits on vector size (number of elements) loaded into vector. 2346 int Matcher::max_vector_size(const BasicType bt) { 2347 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2348 } 2349 2350 int Matcher::min_vector_size(const BasicType bt) { 2351 int max_size = max_vector_size(bt); 2352 // Limit the min vector size to 8 bytes. 2353 int size = 8 / type2aelembytes(bt); 2354 if (bt == T_BYTE) { 2355 // To support vector api shuffle/rearrange. 2356 size = 4; 2357 } else if (bt == T_BOOLEAN) { 2358 // To support vector api load/store mask. 2359 size = 2; 2360 } 2361 if (size < 2) size = 2; 2362 return MIN2(size, max_size); 2363 } 2364 2365 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) { 2366 return Matcher::max_vector_size(bt); 2367 } 2368 2369 // Actual max scalable vector register length. 2370 int Matcher::scalable_vector_reg_size(const BasicType bt) { 2371 return Matcher::max_vector_size(bt); 2372 } 2373 2374 // Vector ideal reg. 2375 uint Matcher::vector_ideal_reg(int len) { 2376 if (UseSVE > 0 && FloatRegister::neon_vl < len && len <= FloatRegister::sve_vl_max) { 2377 return Op_VecA; 2378 } 2379 switch(len) { 2380 // For 16-bit/32-bit mask vector, reuse VecD. 2381 case 2: 2382 case 4: 2383 case 8: return Op_VecD; 2384 case 16: return Op_VecX; 2385 } 2386 ShouldNotReachHere(); 2387 return 0; 2388 } 2389 2390 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { 2391 assert(Matcher::is_generic_vector(generic_opnd), "not generic"); 2392 switch (ideal_reg) { 2393 case Op_VecA: return new vecAOper(); 2394 case Op_VecD: return new vecDOper(); 2395 case Op_VecX: return new vecXOper(); 2396 } 2397 ShouldNotReachHere(); 2398 return nullptr; 2399 } 2400 2401 bool Matcher::is_reg2reg_move(MachNode* m) { 2402 return false; 2403 } 2404 2405 bool Matcher::is_generic_vector(MachOper* opnd) { 2406 return opnd->opcode() == VREG; 2407 } 2408 2409 // Return whether or not this register is ever used as an argument. 2410 // This function is used on startup to build the trampoline stubs in 2411 // generateOptoStub. Registers not mentioned will be killed by the VM 2412 // call in the trampoline, and arguments in those registers not be 2413 // available to the callee. 2414 bool Matcher::can_be_java_arg(int reg) 2415 { 2416 return 2417 reg == R0_num || reg == R0_H_num || 2418 reg == R1_num || reg == R1_H_num || 2419 reg == R2_num || reg == R2_H_num || 2420 reg == R3_num || reg == R3_H_num || 2421 reg == R4_num || reg == R4_H_num || 2422 reg == R5_num || reg == R5_H_num || 2423 reg == R6_num || reg == R6_H_num || 2424 reg == R7_num || reg == R7_H_num || 2425 reg == V0_num || reg == V0_H_num || 2426 reg == V1_num || reg == V1_H_num || 2427 reg == V2_num || reg == V2_H_num || 2428 reg == V3_num || reg == V3_H_num || 2429 reg == V4_num || reg == V4_H_num || 2430 reg == V5_num || reg == V5_H_num || 2431 reg == V6_num || reg == V6_H_num || 2432 reg == V7_num || reg == V7_H_num; 2433 } 2434 2435 bool Matcher::is_spillable_arg(int reg) 2436 { 2437 return can_be_java_arg(reg); 2438 } 2439 2440 uint Matcher::int_pressure_limit() 2441 { 2442 // JDK-8183543: When taking the number of available registers as int 2443 // register pressure threshold, the jtreg test: 2444 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java 2445 // failed due to C2 compilation failure with 2446 // "COMPILE SKIPPED: failed spill-split-recycle sanity check". 2447 // 2448 // A derived pointer is live at CallNode and then is flagged by RA 2449 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip 2450 // derived pointers and lastly fail to spill after reaching maximum 2451 // number of iterations. Lowering the default pressure threshold to 2452 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become 2453 // a high register pressure area of the code so that split_DEF can 2454 // generate DefinitionSpillCopy for the derived pointer. 2455 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; 2456 if (!PreserveFramePointer) { 2457 // When PreserveFramePointer is off, frame pointer is allocatable, 2458 // but different from other SOC registers, it is excluded from 2459 // fatproj's mask because its save type is No-Save. Decrease 1 to 2460 // ensure high pressure at fatproj when PreserveFramePointer is off. 2461 // See check_pressure_at_fatproj(). 2462 default_int_pressure_threshold--; 2463 } 2464 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; 2465 } 2466 2467 uint Matcher::float_pressure_limit() 2468 { 2469 // _FLOAT_REG_mask is generated by adlc from the float_reg register class. 2470 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; 2471 } 2472 2473 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2474 return false; 2475 } 2476 2477 RegMask Matcher::divI_proj_mask() { 2478 ShouldNotReachHere(); 2479 return RegMask(); 2480 } 2481 2482 // Register for MODI projection of divmodI. 2483 RegMask Matcher::modI_proj_mask() { 2484 ShouldNotReachHere(); 2485 return RegMask(); 2486 } 2487 2488 // Register for DIVL projection of divmodL. 2489 RegMask Matcher::divL_proj_mask() { 2490 ShouldNotReachHere(); 2491 return RegMask(); 2492 } 2493 2494 // Register for MODL projection of divmodL. 2495 RegMask Matcher::modL_proj_mask() { 2496 ShouldNotReachHere(); 2497 return RegMask(); 2498 } 2499 2500 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2501 return FP_REG_mask(); 2502 } 2503 2504 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2505 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2506 Node* u = addp->fast_out(i); 2507 if (u->is_LoadStore()) { 2508 // On AArch64, LoadStoreNodes (i.e. compare and swap 2509 // instructions) only take register indirect as an operand, so 2510 // any attempt to use an AddPNode as an input to a LoadStoreNode 2511 // must fail. 2512 return false; 2513 } 2514 if (u->is_Mem()) { 2515 int opsize = u->as_Mem()->memory_size(); 2516 assert(opsize > 0, "unexpected memory operand size"); 2517 if (u->as_Mem()->memory_size() != (1<<shift)) { 2518 return false; 2519 } 2520 } 2521 } 2522 return true; 2523 } 2524 2525 // Convert BootTest condition to Assembler condition. 2526 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 2527 Assembler::Condition to_assembler_cond(BoolTest::mask cond) { 2528 Assembler::Condition result; 2529 switch(cond) { 2530 case BoolTest::eq: 2531 result = Assembler::EQ; break; 2532 case BoolTest::ne: 2533 result = Assembler::NE; break; 2534 case BoolTest::le: 2535 result = Assembler::LE; break; 2536 case BoolTest::ge: 2537 result = Assembler::GE; break; 2538 case BoolTest::lt: 2539 result = Assembler::LT; break; 2540 case BoolTest::gt: 2541 result = Assembler::GT; break; 2542 case BoolTest::ule: 2543 result = Assembler::LS; break; 2544 case BoolTest::uge: 2545 result = Assembler::HS; break; 2546 case BoolTest::ult: 2547 result = Assembler::LO; break; 2548 case BoolTest::ugt: 2549 result = Assembler::HI; break; 2550 case BoolTest::overflow: 2551 result = Assembler::VS; break; 2552 case BoolTest::no_overflow: 2553 result = Assembler::VC; break; 2554 default: 2555 ShouldNotReachHere(); 2556 return Assembler::Condition(-1); 2557 } 2558 2559 // Check conversion 2560 if (cond & BoolTest::unsigned_compare) { 2561 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion"); 2562 } else { 2563 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion"); 2564 } 2565 2566 return result; 2567 } 2568 2569 // Binary src (Replicate con) 2570 static bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) { 2571 if (n == nullptr || m == nullptr) { 2572 return false; 2573 } 2574 2575 if (UseSVE == 0 || m->Opcode() != Op_Replicate) { 2576 return false; 2577 } 2578 2579 Node* imm_node = m->in(1); 2580 if (!imm_node->is_Con()) { 2581 return false; 2582 } 2583 2584 const Type* t = imm_node->bottom_type(); 2585 if (!(t->isa_int() || t->isa_long())) { 2586 return false; 2587 } 2588 2589 switch (n->Opcode()) { 2590 case Op_AndV: 2591 case Op_OrV: 2592 case Op_XorV: { 2593 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n)); 2594 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int(); 2595 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value); 2596 } 2597 case Op_AddVB: 2598 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255); 2599 case Op_AddVS: 2600 case Op_AddVI: 2601 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int()); 2602 case Op_AddVL: 2603 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long()); 2604 default: 2605 return false; 2606 } 2607 } 2608 2609 // (XorV src (Replicate m1)) 2610 // (XorVMask src (MaskAll m1)) 2611 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) { 2612 if (n != nullptr && m != nullptr) { 2613 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) && 2614 VectorNode::is_all_ones_vector(m); 2615 } 2616 return false; 2617 } 2618 2619 // Should the matcher clone input 'm' of node 'n'? 2620 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2621 if (is_vshift_con_pattern(n, m) || 2622 is_vector_bitwise_not_pattern(n, m) || 2623 is_valid_sve_arith_imm_pattern(n, m) || 2624 is_encode_and_store_pattern(n, m)) { 2625 mstack.push(m, Visit); 2626 return true; 2627 } 2628 return false; 2629 } 2630 2631 // Should the Matcher clone shifts on addressing modes, expecting them 2632 // to be subsumed into complex addressing expressions or compute them 2633 // into registers? 2634 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2635 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2636 return true; 2637 } 2638 2639 Node *off = m->in(AddPNode::Offset); 2640 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2641 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2642 // Are there other uses besides address expressions? 2643 !is_visited(off)) { 2644 address_visited.set(off->_idx); // Flag as address_visited 2645 mstack.push(off->in(2), Visit); 2646 Node *conv = off->in(1); 2647 if (conv->Opcode() == Op_ConvI2L && 2648 // Are there other uses besides address expressions? 2649 !is_visited(conv)) { 2650 address_visited.set(conv->_idx); // Flag as address_visited 2651 mstack.push(conv->in(1), Pre_Visit); 2652 } else { 2653 mstack.push(conv, Pre_Visit); 2654 } 2655 address_visited.test_set(m->_idx); // Flag as address_visited 2656 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2657 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2658 return true; 2659 } else if (off->Opcode() == Op_ConvI2L && 2660 // Are there other uses besides address expressions? 2661 !is_visited(off)) { 2662 address_visited.test_set(m->_idx); // Flag as address_visited 2663 address_visited.set(off->_idx); // Flag as address_visited 2664 mstack.push(off->in(1), Pre_Visit); 2665 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2666 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2667 return true; 2668 } 2669 return false; 2670 } 2671 2672 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2673 { \ 2674 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2675 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2676 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2677 __ INSN(REG, as_Register(BASE)); \ 2678 } 2679 2680 2681 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2682 { 2683 Address::extend scale; 2684 2685 // Hooboy, this is fugly. We need a way to communicate to the 2686 // encoder that the index needs to be sign extended, so we have to 2687 // enumerate all the cases. 2688 switch (opcode) { 2689 case INDINDEXSCALEDI2L: 2690 case INDINDEXSCALEDI2LN: 2691 case INDINDEXI2L: 2692 case INDINDEXI2LN: 2693 scale = Address::sxtw(size); 2694 break; 2695 default: 2696 scale = Address::lsl(size); 2697 } 2698 2699 if (index == -1) { 2700 return Address(base, disp); 2701 } else { 2702 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2703 return Address(base, as_Register(index), scale); 2704 } 2705 } 2706 2707 2708 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2709 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2710 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2711 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2712 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2713 2714 // Used for all non-volatile memory accesses. The use of 2715 // $mem->opcode() to discover whether this pattern uses sign-extended 2716 // offsets is something of a kludge. 2717 static void loadStore(C2_MacroAssembler* masm, mem_insn insn, 2718 Register reg, int opcode, 2719 Register base, int index, int scale, int disp, 2720 int size_in_memory) 2721 { 2722 Address addr = mem2address(opcode, base, index, scale, disp); 2723 if (addr.getMode() == Address::base_plus_offset) { 2724 /* Fix up any out-of-range offsets. */ 2725 assert_different_registers(rscratch1, base); 2726 assert_different_registers(rscratch1, reg); 2727 addr = __ legitimize_address(addr, size_in_memory, rscratch1); 2728 } 2729 (masm->*insn)(reg, addr); 2730 } 2731 2732 static void loadStore(C2_MacroAssembler* masm, mem_float_insn insn, 2733 FloatRegister reg, int opcode, 2734 Register base, int index, int size, int disp, 2735 int size_in_memory) 2736 { 2737 Address::extend scale; 2738 2739 switch (opcode) { 2740 case INDINDEXSCALEDI2L: 2741 case INDINDEXSCALEDI2LN: 2742 scale = Address::sxtw(size); 2743 break; 2744 default: 2745 scale = Address::lsl(size); 2746 } 2747 2748 if (index == -1) { 2749 // Fix up any out-of-range offsets. 2750 assert_different_registers(rscratch1, base); 2751 Address addr = Address(base, disp); 2752 addr = __ legitimize_address(addr, size_in_memory, rscratch1); 2753 (masm->*insn)(reg, addr); 2754 } else { 2755 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2756 (masm->*insn)(reg, Address(base, as_Register(index), scale)); 2757 } 2758 } 2759 2760 static void loadStore(C2_MacroAssembler* masm, mem_vector_insn insn, 2761 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2762 int opcode, Register base, int index, int size, int disp) 2763 { 2764 if (index == -1) { 2765 (masm->*insn)(reg, T, Address(base, disp)); 2766 } else { 2767 assert(disp == 0, "unsupported address mode"); 2768 (masm->*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2769 } 2770 } 2771 2772 %} 2773 2774 2775 2776 //----------ENCODING BLOCK----------------------------------------------------- 2777 // This block specifies the encoding classes used by the compiler to 2778 // output byte streams. Encoding classes are parameterized macros 2779 // used by Machine Instruction Nodes in order to generate the bit 2780 // encoding of the instruction. Operands specify their base encoding 2781 // interface with the interface keyword. There are currently 2782 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2783 // COND_INTER. REG_INTER causes an operand to generate a function 2784 // which returns its register number when queried. CONST_INTER causes 2785 // an operand to generate a function which returns the value of the 2786 // constant when queried. MEMORY_INTER causes an operand to generate 2787 // four functions which return the Base Register, the Index Register, 2788 // the Scale Value, and the Offset Value of the operand when queried. 2789 // COND_INTER causes an operand to generate six functions which return 2790 // the encoding code (ie - encoding bits for the instruction) 2791 // associated with each basic boolean condition for a conditional 2792 // instruction. 2793 // 2794 // Instructions specify two basic values for encoding. Again, a 2795 // function is available to check if the constant displacement is an 2796 // oop. They use the ins_encode keyword to specify their encoding 2797 // classes (which must be a sequence of enc_class names, and their 2798 // parameters, specified in the encoding block), and they use the 2799 // opcode keyword to specify, in order, their primary, secondary, and 2800 // tertiary opcode. Only the opcode sections which a particular 2801 // instruction needs for encoding need to be specified. 2802 encode %{ 2803 // Build emit functions for each basic byte or larger field in the 2804 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2805 // from C++ code in the enc_class source block. Emit functions will 2806 // live in the main source block for now. In future, we can 2807 // generalize this by adding a syntax that specifies the sizes of 2808 // fields in an order, so that the adlc can build the emit functions 2809 // automagically 2810 2811 // catch all for unimplemented encodings 2812 enc_class enc_unimplemented %{ 2813 __ unimplemented("C2 catch all"); 2814 %} 2815 2816 // BEGIN Non-volatile memory access 2817 2818 // This encoding class is generated automatically from ad_encode.m4. 2819 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2820 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2821 Register dst_reg = as_Register($dst$$reg); 2822 loadStore(masm, &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2823 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2824 %} 2825 2826 // This encoding class is generated automatically from ad_encode.m4. 2827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2828 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2829 Register dst_reg = as_Register($dst$$reg); 2830 loadStore(masm, &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2831 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2832 %} 2833 2834 // This encoding class is generated automatically from ad_encode.m4. 2835 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2836 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2837 Register dst_reg = as_Register($dst$$reg); 2838 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2839 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2840 %} 2841 2842 // This encoding class is generated automatically from ad_encode.m4. 2843 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2844 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2845 Register dst_reg = as_Register($dst$$reg); 2846 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2847 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2848 %} 2849 2850 // This encoding class is generated automatically from ad_encode.m4. 2851 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2852 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2853 Register dst_reg = as_Register($dst$$reg); 2854 loadStore(masm, &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2855 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2856 %} 2857 2858 // This encoding class is generated automatically from ad_encode.m4. 2859 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2860 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2861 Register dst_reg = as_Register($dst$$reg); 2862 loadStore(masm, &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2863 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2864 %} 2865 2866 // This encoding class is generated automatically from ad_encode.m4. 2867 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2868 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2869 Register dst_reg = as_Register($dst$$reg); 2870 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2871 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2872 %} 2873 2874 // This encoding class is generated automatically from ad_encode.m4. 2875 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2876 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2877 Register dst_reg = as_Register($dst$$reg); 2878 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2879 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2880 %} 2881 2882 // This encoding class is generated automatically from ad_encode.m4. 2883 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2884 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2885 Register dst_reg = as_Register($dst$$reg); 2886 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2887 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2888 %} 2889 2890 // This encoding class is generated automatically from ad_encode.m4. 2891 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2892 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2893 Register dst_reg = as_Register($dst$$reg); 2894 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2895 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2896 %} 2897 2898 // This encoding class is generated automatically from ad_encode.m4. 2899 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2900 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2901 Register dst_reg = as_Register($dst$$reg); 2902 loadStore(masm, &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2903 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2904 %} 2905 2906 // This encoding class is generated automatically from ad_encode.m4. 2907 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2908 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2909 Register dst_reg = as_Register($dst$$reg); 2910 loadStore(masm, &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2911 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2912 %} 2913 2914 // This encoding class is generated automatically from ad_encode.m4. 2915 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2916 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2917 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2918 loadStore(masm, &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2919 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2920 %} 2921 2922 // This encoding class is generated automatically from ad_encode.m4. 2923 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2924 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2925 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2926 loadStore(masm, &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2927 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2928 %} 2929 2930 // This encoding class is generated automatically from ad_encode.m4. 2931 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2932 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2933 Register src_reg = as_Register($src$$reg); 2934 loadStore(masm, &MacroAssembler::strb, src_reg, $mem->opcode(), 2935 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2936 %} 2937 2938 // This encoding class is generated automatically from ad_encode.m4. 2939 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2940 enc_class aarch64_enc_strb0(memory1 mem) %{ 2941 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(), 2942 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 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_strh(iRegI src, memory2 mem) %{ 2948 Register src_reg = as_Register($src$$reg); 2949 loadStore(masm, &MacroAssembler::strh, src_reg, $mem->opcode(), 2950 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 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_strh0(memory2 mem) %{ 2956 loadStore(masm, &MacroAssembler::strh, zr, $mem->opcode(), 2957 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2958 %} 2959 2960 // This encoding class is generated automatically from ad_encode.m4. 2961 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2962 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2963 Register src_reg = as_Register($src$$reg); 2964 loadStore(masm, &MacroAssembler::strw, src_reg, $mem->opcode(), 2965 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2966 %} 2967 2968 // This encoding class is generated automatically from ad_encode.m4. 2969 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2970 enc_class aarch64_enc_strw0(memory4 mem) %{ 2971 loadStore(masm, &MacroAssembler::strw, zr, $mem->opcode(), 2972 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2973 %} 2974 2975 // This encoding class is generated automatically from ad_encode.m4. 2976 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2977 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2978 Register src_reg = as_Register($src$$reg); 2979 // we sometimes get asked to store the stack pointer into the 2980 // current thread -- we cannot do that directly on AArch64 2981 if (src_reg == r31_sp) { 2982 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2983 __ mov(rscratch2, sp); 2984 src_reg = rscratch2; 2985 } 2986 loadStore(masm, &MacroAssembler::str, src_reg, $mem->opcode(), 2987 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2988 %} 2989 2990 // This encoding class is generated automatically from ad_encode.m4. 2991 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2992 enc_class aarch64_enc_str0(memory8 mem) %{ 2993 loadStore(masm, &MacroAssembler::str, zr, $mem->opcode(), 2994 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2995 %} 2996 2997 // This encoding class is generated automatically from ad_encode.m4. 2998 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2999 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 3000 FloatRegister src_reg = as_FloatRegister($src$$reg); 3001 loadStore(masm, &MacroAssembler::strs, src_reg, $mem->opcode(), 3002 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3003 %} 3004 3005 // This encoding class is generated automatically from ad_encode.m4. 3006 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3007 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 3008 FloatRegister src_reg = as_FloatRegister($src$$reg); 3009 loadStore(masm, &MacroAssembler::strd, src_reg, $mem->opcode(), 3010 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3011 %} 3012 3013 // This encoding class is generated automatically from ad_encode.m4. 3014 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3015 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 3016 __ membar(Assembler::StoreStore); 3017 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(), 3018 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 3019 %} 3020 3021 // END Non-volatile memory access 3022 3023 // Vector loads and stores 3024 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{ 3025 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3026 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 3027 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3028 %} 3029 3030 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{ 3031 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3032 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3033 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3034 %} 3035 3036 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{ 3037 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3038 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3039 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3040 %} 3041 3042 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{ 3043 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3044 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3045 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3046 %} 3047 3048 enc_class aarch64_enc_strvH(vReg src, memory mem) %{ 3049 FloatRegister src_reg = as_FloatRegister($src$$reg); 3050 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::H, 3051 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3052 %} 3053 3054 enc_class aarch64_enc_strvS(vReg src, memory mem) %{ 3055 FloatRegister src_reg = as_FloatRegister($src$$reg); 3056 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::S, 3057 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3058 %} 3059 3060 enc_class aarch64_enc_strvD(vReg src, memory mem) %{ 3061 FloatRegister src_reg = as_FloatRegister($src$$reg); 3062 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::D, 3063 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3064 %} 3065 3066 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{ 3067 FloatRegister src_reg = as_FloatRegister($src$$reg); 3068 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::Q, 3069 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3070 %} 3071 3072 // volatile loads and stores 3073 3074 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3075 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3076 rscratch1, stlrb); 3077 %} 3078 3079 enc_class aarch64_enc_stlrb0(memory mem) %{ 3080 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3081 rscratch1, stlrb); 3082 %} 3083 3084 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3085 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3086 rscratch1, stlrh); 3087 %} 3088 3089 enc_class aarch64_enc_stlrh0(memory mem) %{ 3090 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3091 rscratch1, stlrh); 3092 %} 3093 3094 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3095 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3096 rscratch1, stlrw); 3097 %} 3098 3099 enc_class aarch64_enc_stlrw0(memory mem) %{ 3100 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3101 rscratch1, stlrw); 3102 %} 3103 3104 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3105 Register dst_reg = as_Register($dst$$reg); 3106 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3107 rscratch1, ldarb); 3108 __ sxtbw(dst_reg, dst_reg); 3109 %} 3110 3111 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3112 Register dst_reg = as_Register($dst$$reg); 3113 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3114 rscratch1, ldarb); 3115 __ sxtb(dst_reg, dst_reg); 3116 %} 3117 3118 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3119 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3120 rscratch1, ldarb); 3121 %} 3122 3123 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3124 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3125 rscratch1, ldarb); 3126 %} 3127 3128 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3129 Register dst_reg = as_Register($dst$$reg); 3130 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3131 rscratch1, ldarh); 3132 __ sxthw(dst_reg, dst_reg); 3133 %} 3134 3135 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3136 Register dst_reg = as_Register($dst$$reg); 3137 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3138 rscratch1, ldarh); 3139 __ sxth(dst_reg, dst_reg); 3140 %} 3141 3142 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3143 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3144 rscratch1, ldarh); 3145 %} 3146 3147 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3148 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3149 rscratch1, ldarh); 3150 %} 3151 3152 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3153 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3154 rscratch1, ldarw); 3155 %} 3156 3157 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3158 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3159 rscratch1, ldarw); 3160 %} 3161 3162 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3163 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3164 rscratch1, ldar); 3165 %} 3166 3167 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3168 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3169 rscratch1, ldarw); 3170 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3171 %} 3172 3173 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3174 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3175 rscratch1, ldar); 3176 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3177 %} 3178 3179 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3180 Register src_reg = as_Register($src$$reg); 3181 // we sometimes get asked to store the stack pointer into the 3182 // current thread -- we cannot do that directly on AArch64 3183 if (src_reg == r31_sp) { 3184 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3185 __ mov(rscratch2, sp); 3186 src_reg = rscratch2; 3187 } 3188 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3189 rscratch1, stlr); 3190 %} 3191 3192 enc_class aarch64_enc_stlr0(memory mem) %{ 3193 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3194 rscratch1, stlr); 3195 %} 3196 3197 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3198 { 3199 FloatRegister src_reg = as_FloatRegister($src$$reg); 3200 __ fmovs(rscratch2, src_reg); 3201 } 3202 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3203 rscratch1, stlrw); 3204 %} 3205 3206 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3207 { 3208 FloatRegister src_reg = as_FloatRegister($src$$reg); 3209 __ fmovd(rscratch2, src_reg); 3210 } 3211 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3212 rscratch1, stlr); 3213 %} 3214 3215 // synchronized read/update encodings 3216 3217 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3218 Register dst_reg = as_Register($dst$$reg); 3219 Register base = as_Register($mem$$base); 3220 int index = $mem$$index; 3221 int scale = $mem$$scale; 3222 int disp = $mem$$disp; 3223 if (index == -1) { 3224 if (disp != 0) { 3225 __ lea(rscratch1, Address(base, disp)); 3226 __ ldaxr(dst_reg, rscratch1); 3227 } else { 3228 // TODO 3229 // should we ever get anything other than this case? 3230 __ ldaxr(dst_reg, base); 3231 } 3232 } else { 3233 Register index_reg = as_Register(index); 3234 if (disp == 0) { 3235 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3236 __ ldaxr(dst_reg, rscratch1); 3237 } else { 3238 __ lea(rscratch1, Address(base, disp)); 3239 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3240 __ ldaxr(dst_reg, rscratch1); 3241 } 3242 } 3243 %} 3244 3245 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3246 Register src_reg = as_Register($src$$reg); 3247 Register base = as_Register($mem$$base); 3248 int index = $mem$$index; 3249 int scale = $mem$$scale; 3250 int disp = $mem$$disp; 3251 if (index == -1) { 3252 if (disp != 0) { 3253 __ lea(rscratch2, Address(base, disp)); 3254 __ stlxr(rscratch1, src_reg, rscratch2); 3255 } else { 3256 // TODO 3257 // should we ever get anything other than this case? 3258 __ stlxr(rscratch1, src_reg, base); 3259 } 3260 } else { 3261 Register index_reg = as_Register(index); 3262 if (disp == 0) { 3263 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3264 __ stlxr(rscratch1, src_reg, rscratch2); 3265 } else { 3266 __ lea(rscratch2, Address(base, disp)); 3267 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3268 __ stlxr(rscratch1, src_reg, rscratch2); 3269 } 3270 } 3271 __ cmpw(rscratch1, zr); 3272 %} 3273 3274 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3275 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3276 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3277 Assembler::xword, /*acquire*/ false, /*release*/ true, 3278 /*weak*/ false, noreg); 3279 %} 3280 3281 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3282 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3283 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3284 Assembler::word, /*acquire*/ false, /*release*/ true, 3285 /*weak*/ false, noreg); 3286 %} 3287 3288 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3289 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3290 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3291 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3292 /*weak*/ false, noreg); 3293 %} 3294 3295 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3296 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3297 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3298 Assembler::byte, /*acquire*/ false, /*release*/ true, 3299 /*weak*/ false, noreg); 3300 %} 3301 3302 3303 // The only difference between aarch64_enc_cmpxchg and 3304 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3305 // CompareAndSwap sequence to serve as a barrier on acquiring a 3306 // lock. 3307 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3308 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3309 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3310 Assembler::xword, /*acquire*/ true, /*release*/ true, 3311 /*weak*/ false, noreg); 3312 %} 3313 3314 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3315 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3316 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3317 Assembler::word, /*acquire*/ true, /*release*/ true, 3318 /*weak*/ false, noreg); 3319 %} 3320 3321 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3322 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3323 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3324 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3325 /*weak*/ false, noreg); 3326 %} 3327 3328 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3329 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3330 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3331 Assembler::byte, /*acquire*/ true, /*release*/ true, 3332 /*weak*/ false, noreg); 3333 %} 3334 3335 // auxiliary used for CompareAndSwapX to set result register 3336 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3337 Register res_reg = as_Register($res$$reg); 3338 __ cset(res_reg, Assembler::EQ); 3339 %} 3340 3341 // prefetch encodings 3342 3343 enc_class aarch64_enc_prefetchw(memory mem) %{ 3344 Register base = as_Register($mem$$base); 3345 int index = $mem$$index; 3346 int scale = $mem$$scale; 3347 int disp = $mem$$disp; 3348 if (index == -1) { 3349 // Fix up any out-of-range offsets. 3350 assert_different_registers(rscratch1, base); 3351 Address addr = Address(base, disp); 3352 addr = __ legitimize_address(addr, 8, rscratch1); 3353 __ prfm(addr, PSTL1KEEP); 3354 } else { 3355 Register index_reg = as_Register(index); 3356 if (disp == 0) { 3357 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3358 } else { 3359 __ lea(rscratch1, Address(base, disp)); 3360 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3361 } 3362 } 3363 %} 3364 3365 // mov encodings 3366 3367 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3368 uint32_t con = (uint32_t)$src$$constant; 3369 Register dst_reg = as_Register($dst$$reg); 3370 if (con == 0) { 3371 __ movw(dst_reg, zr); 3372 } else { 3373 __ movw(dst_reg, con); 3374 } 3375 %} 3376 3377 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3378 Register dst_reg = as_Register($dst$$reg); 3379 uint64_t con = (uint64_t)$src$$constant; 3380 if (con == 0) { 3381 __ mov(dst_reg, zr); 3382 } else { 3383 __ mov(dst_reg, con); 3384 } 3385 %} 3386 3387 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3388 Register dst_reg = as_Register($dst$$reg); 3389 address con = (address)$src$$constant; 3390 if (con == nullptr || con == (address)1) { 3391 ShouldNotReachHere(); 3392 } else { 3393 relocInfo::relocType rtype = $src->constant_reloc(); 3394 if (rtype == relocInfo::oop_type) { 3395 __ movoop(dst_reg, (jobject)con); 3396 } else if (rtype == relocInfo::metadata_type) { 3397 __ mov_metadata(dst_reg, (Metadata*)con); 3398 } else { 3399 assert(rtype == relocInfo::none, "unexpected reloc type"); 3400 if (! __ is_valid_AArch64_address(con) || 3401 con < (address)(uintptr_t)os::vm_page_size()) { 3402 __ mov(dst_reg, con); 3403 } else { 3404 uint64_t offset; 3405 __ adrp(dst_reg, con, offset); 3406 __ add(dst_reg, dst_reg, offset); 3407 } 3408 } 3409 } 3410 %} 3411 3412 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3413 Register dst_reg = as_Register($dst$$reg); 3414 __ mov(dst_reg, zr); 3415 %} 3416 3417 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3418 Register dst_reg = as_Register($dst$$reg); 3419 __ mov(dst_reg, (uint64_t)1); 3420 %} 3421 3422 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3423 __ load_byte_map_base($dst$$Register); 3424 %} 3425 3426 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3427 Register dst_reg = as_Register($dst$$reg); 3428 address con = (address)$src$$constant; 3429 if (con == nullptr) { 3430 ShouldNotReachHere(); 3431 } else { 3432 relocInfo::relocType rtype = $src->constant_reloc(); 3433 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3434 __ set_narrow_oop(dst_reg, (jobject)con); 3435 } 3436 %} 3437 3438 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3439 Register dst_reg = as_Register($dst$$reg); 3440 __ mov(dst_reg, zr); 3441 %} 3442 3443 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3444 Register dst_reg = as_Register($dst$$reg); 3445 address con = (address)$src$$constant; 3446 if (con == nullptr) { 3447 ShouldNotReachHere(); 3448 } else { 3449 relocInfo::relocType rtype = $src->constant_reloc(); 3450 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3451 __ set_narrow_klass(dst_reg, (Klass *)con); 3452 } 3453 %} 3454 3455 // arithmetic encodings 3456 3457 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3458 Register dst_reg = as_Register($dst$$reg); 3459 Register src_reg = as_Register($src1$$reg); 3460 int32_t con = (int32_t)$src2$$constant; 3461 // add has primary == 0, subtract has primary == 1 3462 if ($primary) { con = -con; } 3463 if (con < 0) { 3464 __ subw(dst_reg, src_reg, -con); 3465 } else { 3466 __ addw(dst_reg, src_reg, con); 3467 } 3468 %} 3469 3470 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3471 Register dst_reg = as_Register($dst$$reg); 3472 Register src_reg = as_Register($src1$$reg); 3473 int32_t con = (int32_t)$src2$$constant; 3474 // add has primary == 0, subtract has primary == 1 3475 if ($primary) { con = -con; } 3476 if (con < 0) { 3477 __ sub(dst_reg, src_reg, -con); 3478 } else { 3479 __ add(dst_reg, src_reg, con); 3480 } 3481 %} 3482 3483 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3484 Register dst_reg = as_Register($dst$$reg); 3485 Register src1_reg = as_Register($src1$$reg); 3486 Register src2_reg = as_Register($src2$$reg); 3487 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3488 %} 3489 3490 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3491 Register dst_reg = as_Register($dst$$reg); 3492 Register src1_reg = as_Register($src1$$reg); 3493 Register src2_reg = as_Register($src2$$reg); 3494 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3495 %} 3496 3497 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3498 Register dst_reg = as_Register($dst$$reg); 3499 Register src1_reg = as_Register($src1$$reg); 3500 Register src2_reg = as_Register($src2$$reg); 3501 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3502 %} 3503 3504 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3505 Register dst_reg = as_Register($dst$$reg); 3506 Register src1_reg = as_Register($src1$$reg); 3507 Register src2_reg = as_Register($src2$$reg); 3508 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3509 %} 3510 3511 // compare instruction encodings 3512 3513 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3514 Register reg1 = as_Register($src1$$reg); 3515 Register reg2 = as_Register($src2$$reg); 3516 __ cmpw(reg1, reg2); 3517 %} 3518 3519 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3520 Register reg = as_Register($src1$$reg); 3521 int32_t val = $src2$$constant; 3522 if (val >= 0) { 3523 __ subsw(zr, reg, val); 3524 } else { 3525 __ addsw(zr, reg, -val); 3526 } 3527 %} 3528 3529 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3530 Register reg1 = as_Register($src1$$reg); 3531 uint32_t val = (uint32_t)$src2$$constant; 3532 __ movw(rscratch1, val); 3533 __ cmpw(reg1, rscratch1); 3534 %} 3535 3536 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3537 Register reg1 = as_Register($src1$$reg); 3538 Register reg2 = as_Register($src2$$reg); 3539 __ cmp(reg1, reg2); 3540 %} 3541 3542 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3543 Register reg = as_Register($src1$$reg); 3544 int64_t val = $src2$$constant; 3545 if (val >= 0) { 3546 __ subs(zr, reg, val); 3547 } else if (val != -val) { 3548 __ adds(zr, reg, -val); 3549 } else { 3550 // aargh, Long.MIN_VALUE is a special case 3551 __ orr(rscratch1, zr, (uint64_t)val); 3552 __ subs(zr, reg, rscratch1); 3553 } 3554 %} 3555 3556 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3557 Register reg1 = as_Register($src1$$reg); 3558 uint64_t val = (uint64_t)$src2$$constant; 3559 __ mov(rscratch1, val); 3560 __ cmp(reg1, rscratch1); 3561 %} 3562 3563 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3564 Register reg1 = as_Register($src1$$reg); 3565 Register reg2 = as_Register($src2$$reg); 3566 __ cmp(reg1, reg2); 3567 %} 3568 3569 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 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_testp(iRegP src) %{ 3576 Register reg = as_Register($src$$reg); 3577 __ cmp(reg, zr); 3578 %} 3579 3580 enc_class aarch64_enc_testn(iRegN src) %{ 3581 Register reg = as_Register($src$$reg); 3582 __ cmpw(reg, zr); 3583 %} 3584 3585 enc_class aarch64_enc_b(label lbl) %{ 3586 Label *L = $lbl$$label; 3587 __ b(*L); 3588 %} 3589 3590 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3591 Label *L = $lbl$$label; 3592 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3593 %} 3594 3595 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3596 Label *L = $lbl$$label; 3597 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3598 %} 3599 3600 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3601 %{ 3602 Register sub_reg = as_Register($sub$$reg); 3603 Register super_reg = as_Register($super$$reg); 3604 Register temp_reg = as_Register($temp$$reg); 3605 Register result_reg = as_Register($result$$reg); 3606 3607 Label miss; 3608 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3609 nullptr, &miss, 3610 /*set_cond_codes:*/ true); 3611 if ($primary) { 3612 __ mov(result_reg, zr); 3613 } 3614 __ bind(miss); 3615 %} 3616 3617 enc_class aarch64_enc_java_static_call(method meth) %{ 3618 address addr = (address)$meth$$method; 3619 address call; 3620 if (!_method) { 3621 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3622 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type)); 3623 if (call == nullptr) { 3624 ciEnv::current()->record_failure("CodeCache is full"); 3625 return; 3626 } 3627 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 3628 // The NOP here is purely to ensure that eliding a call to 3629 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 3630 __ nop(); 3631 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 3632 } else { 3633 int method_index = resolved_method_index(masm); 3634 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3635 : static_call_Relocation::spec(method_index); 3636 call = __ trampoline_call(Address(addr, rspec)); 3637 if (call == nullptr) { 3638 ciEnv::current()->record_failure("CodeCache is full"); 3639 return; 3640 } 3641 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 3642 // Calls of the same statically bound method can share 3643 // a stub to the interpreter. 3644 __ code()->shared_stub_to_interp_for(_method, call - __ begin()); 3645 } else { 3646 // Emit stub for static call 3647 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call); 3648 if (stub == nullptr) { 3649 ciEnv::current()->record_failure("CodeCache is full"); 3650 return; 3651 } 3652 } 3653 } 3654 3655 __ post_call_nop(); 3656 3657 // Only non uncommon_trap calls need to reinitialize ptrue. 3658 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) { 3659 __ reinitialize_ptrue(); 3660 } 3661 %} 3662 3663 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3664 int method_index = resolved_method_index(masm); 3665 address call = __ ic_call((address)$meth$$method, method_index); 3666 if (call == nullptr) { 3667 ciEnv::current()->record_failure("CodeCache is full"); 3668 return; 3669 } 3670 __ post_call_nop(); 3671 if (Compile::current()->max_vector_size() > 0) { 3672 __ reinitialize_ptrue(); 3673 } 3674 %} 3675 3676 enc_class aarch64_enc_call_epilog() %{ 3677 if (VerifyStackAtCalls) { 3678 // Check that stack depth is unchanged: find majik cookie on stack 3679 __ call_Unimplemented(); 3680 } 3681 %} 3682 3683 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3684 // some calls to generated routines (arraycopy code) are scheduled 3685 // by C2 as runtime calls. if so we can call them using a br (they 3686 // will be in a reachable segment) otherwise we have to use a blr 3687 // which loads the absolute address into a register. 3688 address entry = (address)$meth$$method; 3689 CodeBlob *cb = CodeCache::find_blob(entry); 3690 if (cb) { 3691 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3692 if (call == nullptr) { 3693 ciEnv::current()->record_failure("CodeCache is full"); 3694 return; 3695 } 3696 __ post_call_nop(); 3697 } else { 3698 Label retaddr; 3699 __ adr(rscratch2, retaddr); 3700 __ lea(rscratch1, RuntimeAddress(entry)); 3701 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3702 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3703 __ blr(rscratch1); 3704 __ bind(retaddr); 3705 __ post_call_nop(); 3706 __ add(sp, sp, 2 * wordSize); 3707 } 3708 if (Compile::current()->max_vector_size() > 0) { 3709 __ reinitialize_ptrue(); 3710 } 3711 %} 3712 3713 enc_class aarch64_enc_rethrow() %{ 3714 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3715 %} 3716 3717 enc_class aarch64_enc_ret() %{ 3718 #ifdef ASSERT 3719 if (Compile::current()->max_vector_size() > 0) { 3720 __ verify_ptrue(); 3721 } 3722 #endif 3723 __ ret(lr); 3724 %} 3725 3726 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3727 Register target_reg = as_Register($jump_target$$reg); 3728 __ br(target_reg); 3729 %} 3730 3731 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3732 Register target_reg = as_Register($jump_target$$reg); 3733 // exception oop should be in r0 3734 // ret addr has been popped into lr 3735 // callee expects it in r3 3736 __ mov(r3, lr); 3737 __ br(target_reg); 3738 %} 3739 3740 %} 3741 3742 //----------FRAME-------------------------------------------------------------- 3743 // Definition of frame structure and management information. 3744 // 3745 // S T A C K L A Y O U T Allocators stack-slot number 3746 // | (to get allocators register number 3747 // G Owned by | | v add OptoReg::stack0()) 3748 // r CALLER | | 3749 // o | +--------+ pad to even-align allocators stack-slot 3750 // w V | pad0 | numbers; owned by CALLER 3751 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3752 // h ^ | in | 5 3753 // | | args | 4 Holes in incoming args owned by SELF 3754 // | | | | 3 3755 // | | +--------+ 3756 // V | | old out| Empty on Intel, window on Sparc 3757 // | old |preserve| Must be even aligned. 3758 // | SP-+--------+----> Matcher::_old_SP, even aligned 3759 // | | in | 3 area for Intel ret address 3760 // Owned by |preserve| Empty on Sparc. 3761 // SELF +--------+ 3762 // | | pad2 | 2 pad to align old SP 3763 // | +--------+ 1 3764 // | | locks | 0 3765 // | +--------+----> OptoReg::stack0(), even aligned 3766 // | | pad1 | 11 pad to align new SP 3767 // | +--------+ 3768 // | | | 10 3769 // | | spills | 9 spills 3770 // V | | 8 (pad0 slot for callee) 3771 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3772 // ^ | out | 7 3773 // | | args | 6 Holes in outgoing args owned by CALLEE 3774 // Owned by +--------+ 3775 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3776 // | new |preserve| Must be even-aligned. 3777 // | SP-+--------+----> Matcher::_new_SP, even aligned 3778 // | | | 3779 // 3780 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3781 // known from SELF's arguments and the Java calling convention. 3782 // Region 6-7 is determined per call site. 3783 // Note 2: If the calling convention leaves holes in the incoming argument 3784 // area, those holes are owned by SELF. Holes in the outgoing area 3785 // are owned by the CALLEE. Holes should not be necessary in the 3786 // incoming area, as the Java calling convention is completely under 3787 // the control of the AD file. Doubles can be sorted and packed to 3788 // avoid holes. Holes in the outgoing arguments may be necessary for 3789 // varargs C calling conventions. 3790 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3791 // even aligned with pad0 as needed. 3792 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3793 // (the latter is true on Intel but is it false on AArch64?) 3794 // region 6-11 is even aligned; it may be padded out more so that 3795 // the region from SP to FP meets the minimum stack alignment. 3796 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3797 // alignment. Region 11, pad1, may be dynamically extended so that 3798 // SP meets the minimum alignment. 3799 3800 frame %{ 3801 // These three registers define part of the calling convention 3802 // between compiled code and the interpreter. 3803 3804 // Inline Cache Register or Method for I2C. 3805 inline_cache_reg(R12); 3806 3807 // Number of stack slots consumed by locking an object 3808 sync_stack_slots(2); 3809 3810 // Compiled code's Frame Pointer 3811 frame_pointer(R31); 3812 3813 // Interpreter stores its frame pointer in a register which is 3814 // stored to the stack by I2CAdaptors. 3815 // I2CAdaptors convert from interpreted java to compiled java. 3816 interpreter_frame_pointer(R29); 3817 3818 // Stack alignment requirement 3819 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3820 3821 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3822 // for calls to C. Supports the var-args backing area for register parms. 3823 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3824 3825 // The after-PROLOG location of the return address. Location of 3826 // return address specifies a type (REG or STACK) and a number 3827 // representing the register number (i.e. - use a register name) or 3828 // stack slot. 3829 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3830 // Otherwise, it is above the locks and verification slot and alignment word 3831 // TODO this may well be correct but need to check why that - 2 is there 3832 // ppc port uses 0 but we definitely need to allow for fixed_slots 3833 // which folds in the space used for monitors 3834 return_addr(STACK - 2 + 3835 align_up((Compile::current()->in_preserve_stack_slots() + 3836 Compile::current()->fixed_slots()), 3837 stack_alignment_in_slots())); 3838 3839 // Location of compiled Java return values. Same as C for now. 3840 return_value 3841 %{ 3842 // TODO do we allow ideal_reg == Op_RegN??? 3843 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3844 "only return normal values"); 3845 3846 static const int lo[Op_RegL + 1] = { // enum name 3847 0, // Op_Node 3848 0, // Op_Set 3849 R0_num, // Op_RegN 3850 R0_num, // Op_RegI 3851 R0_num, // Op_RegP 3852 V0_num, // Op_RegF 3853 V0_num, // Op_RegD 3854 R0_num // Op_RegL 3855 }; 3856 3857 static const int hi[Op_RegL + 1] = { // enum name 3858 0, // Op_Node 3859 0, // Op_Set 3860 OptoReg::Bad, // Op_RegN 3861 OptoReg::Bad, // Op_RegI 3862 R0_H_num, // Op_RegP 3863 OptoReg::Bad, // Op_RegF 3864 V0_H_num, // Op_RegD 3865 R0_H_num // Op_RegL 3866 }; 3867 3868 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3869 %} 3870 %} 3871 3872 //----------ATTRIBUTES--------------------------------------------------------- 3873 //----------Operand Attributes------------------------------------------------- 3874 op_attrib op_cost(1); // Required cost attribute 3875 3876 //----------Instruction Attributes--------------------------------------------- 3877 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3878 ins_attrib ins_size(32); // Required size attribute (in bits) 3879 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3880 // a non-matching short branch variant 3881 // of some long branch? 3882 ins_attrib ins_alignment(4); // Required alignment attribute (must 3883 // be a power of 2) specifies the 3884 // alignment that some part of the 3885 // instruction (not necessarily the 3886 // start) requires. If > 1, a 3887 // compute_padding() function must be 3888 // provided for the instruction 3889 3890 //----------OPERANDS----------------------------------------------------------- 3891 // Operand definitions must precede instruction definitions for correct parsing 3892 // in the ADLC because operands constitute user defined types which are used in 3893 // instruction definitions. 3894 3895 //----------Simple Operands---------------------------------------------------- 3896 3897 // Integer operands 32 bit 3898 // 32 bit immediate 3899 operand immI() 3900 %{ 3901 match(ConI); 3902 3903 op_cost(0); 3904 format %{ %} 3905 interface(CONST_INTER); 3906 %} 3907 3908 // 32 bit zero 3909 operand immI0() 3910 %{ 3911 predicate(n->get_int() == 0); 3912 match(ConI); 3913 3914 op_cost(0); 3915 format %{ %} 3916 interface(CONST_INTER); 3917 %} 3918 3919 // 32 bit unit increment 3920 operand immI_1() 3921 %{ 3922 predicate(n->get_int() == 1); 3923 match(ConI); 3924 3925 op_cost(0); 3926 format %{ %} 3927 interface(CONST_INTER); 3928 %} 3929 3930 // 32 bit unit decrement 3931 operand immI_M1() 3932 %{ 3933 predicate(n->get_int() == -1); 3934 match(ConI); 3935 3936 op_cost(0); 3937 format %{ %} 3938 interface(CONST_INTER); 3939 %} 3940 3941 // Shift values for add/sub extension shift 3942 operand immIExt() 3943 %{ 3944 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3945 match(ConI); 3946 3947 op_cost(0); 3948 format %{ %} 3949 interface(CONST_INTER); 3950 %} 3951 3952 operand immI_gt_1() 3953 %{ 3954 predicate(n->get_int() > 1); 3955 match(ConI); 3956 3957 op_cost(0); 3958 format %{ %} 3959 interface(CONST_INTER); 3960 %} 3961 3962 operand immI_le_4() 3963 %{ 3964 predicate(n->get_int() <= 4); 3965 match(ConI); 3966 3967 op_cost(0); 3968 format %{ %} 3969 interface(CONST_INTER); 3970 %} 3971 3972 operand immI_16() 3973 %{ 3974 predicate(n->get_int() == 16); 3975 match(ConI); 3976 3977 op_cost(0); 3978 format %{ %} 3979 interface(CONST_INTER); 3980 %} 3981 3982 operand immI_24() 3983 %{ 3984 predicate(n->get_int() == 24); 3985 match(ConI); 3986 3987 op_cost(0); 3988 format %{ %} 3989 interface(CONST_INTER); 3990 %} 3991 3992 operand immI_32() 3993 %{ 3994 predicate(n->get_int() == 32); 3995 match(ConI); 3996 3997 op_cost(0); 3998 format %{ %} 3999 interface(CONST_INTER); 4000 %} 4001 4002 operand immI_48() 4003 %{ 4004 predicate(n->get_int() == 48); 4005 match(ConI); 4006 4007 op_cost(0); 4008 format %{ %} 4009 interface(CONST_INTER); 4010 %} 4011 4012 operand immI_56() 4013 %{ 4014 predicate(n->get_int() == 56); 4015 match(ConI); 4016 4017 op_cost(0); 4018 format %{ %} 4019 interface(CONST_INTER); 4020 %} 4021 4022 operand immI_255() 4023 %{ 4024 predicate(n->get_int() == 255); 4025 match(ConI); 4026 4027 op_cost(0); 4028 format %{ %} 4029 interface(CONST_INTER); 4030 %} 4031 4032 operand immI_65535() 4033 %{ 4034 predicate(n->get_int() == 65535); 4035 match(ConI); 4036 4037 op_cost(0); 4038 format %{ %} 4039 interface(CONST_INTER); 4040 %} 4041 4042 operand immI_positive() 4043 %{ 4044 predicate(n->get_int() > 0); 4045 match(ConI); 4046 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // BoolTest condition for signed compare 4053 operand immI_cmp_cond() 4054 %{ 4055 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int())); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 // BoolTest condition for unsigned compare 4064 operand immI_cmpU_cond() 4065 %{ 4066 predicate(Matcher::is_unsigned_booltest_pred(n->get_int())); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 operand immL_255() 4075 %{ 4076 predicate(n->get_long() == 255L); 4077 match(ConL); 4078 4079 op_cost(0); 4080 format %{ %} 4081 interface(CONST_INTER); 4082 %} 4083 4084 operand immL_65535() 4085 %{ 4086 predicate(n->get_long() == 65535L); 4087 match(ConL); 4088 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 operand immL_4294967295() 4095 %{ 4096 predicate(n->get_long() == 4294967295L); 4097 match(ConL); 4098 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 operand immL_bitmask() 4105 %{ 4106 predicate((n->get_long() != 0) 4107 && ((n->get_long() & 0xc000000000000000l) == 0) 4108 && is_power_of_2(n->get_long() + 1)); 4109 match(ConL); 4110 4111 op_cost(0); 4112 format %{ %} 4113 interface(CONST_INTER); 4114 %} 4115 4116 operand immI_bitmask() 4117 %{ 4118 predicate((n->get_int() != 0) 4119 && ((n->get_int() & 0xc0000000) == 0) 4120 && is_power_of_2(n->get_int() + 1)); 4121 match(ConI); 4122 4123 op_cost(0); 4124 format %{ %} 4125 interface(CONST_INTER); 4126 %} 4127 4128 operand immL_positive_bitmaskI() 4129 %{ 4130 predicate((n->get_long() != 0) 4131 && ((julong)n->get_long() < 0x80000000ULL) 4132 && is_power_of_2(n->get_long() + 1)); 4133 match(ConL); 4134 4135 op_cost(0); 4136 format %{ %} 4137 interface(CONST_INTER); 4138 %} 4139 4140 // Scale values for scaled offset addressing modes (up to long but not quad) 4141 operand immIScale() 4142 %{ 4143 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4144 match(ConI); 4145 4146 op_cost(0); 4147 format %{ %} 4148 interface(CONST_INTER); 4149 %} 4150 4151 // 5 bit signed integer 4152 operand immI5() 4153 %{ 4154 predicate(Assembler::is_simm(n->get_int(), 5)); 4155 match(ConI); 4156 4157 op_cost(0); 4158 format %{ %} 4159 interface(CONST_INTER); 4160 %} 4161 4162 // 7 bit unsigned integer 4163 operand immIU7() 4164 %{ 4165 predicate(Assembler::is_uimm(n->get_int(), 7)); 4166 match(ConI); 4167 4168 op_cost(0); 4169 format %{ %} 4170 interface(CONST_INTER); 4171 %} 4172 4173 // Offset for scaled or unscaled immediate loads and stores 4174 operand immIOffset() 4175 %{ 4176 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4177 match(ConI); 4178 4179 op_cost(0); 4180 format %{ %} 4181 interface(CONST_INTER); 4182 %} 4183 4184 operand immIOffset1() 4185 %{ 4186 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4187 match(ConI); 4188 4189 op_cost(0); 4190 format %{ %} 4191 interface(CONST_INTER); 4192 %} 4193 4194 operand immIOffset2() 4195 %{ 4196 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4197 match(ConI); 4198 4199 op_cost(0); 4200 format %{ %} 4201 interface(CONST_INTER); 4202 %} 4203 4204 operand immIOffset4() 4205 %{ 4206 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4207 match(ConI); 4208 4209 op_cost(0); 4210 format %{ %} 4211 interface(CONST_INTER); 4212 %} 4213 4214 operand immIOffset8() 4215 %{ 4216 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4217 match(ConI); 4218 4219 op_cost(0); 4220 format %{ %} 4221 interface(CONST_INTER); 4222 %} 4223 4224 operand immIOffset16() 4225 %{ 4226 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4227 match(ConI); 4228 4229 op_cost(0); 4230 format %{ %} 4231 interface(CONST_INTER); 4232 %} 4233 4234 operand immLOffset() 4235 %{ 4236 predicate(n->get_long() >= -256 && n->get_long() <= 65520); 4237 match(ConL); 4238 4239 op_cost(0); 4240 format %{ %} 4241 interface(CONST_INTER); 4242 %} 4243 4244 operand immLoffset1() 4245 %{ 4246 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4247 match(ConL); 4248 4249 op_cost(0); 4250 format %{ %} 4251 interface(CONST_INTER); 4252 %} 4253 4254 operand immLoffset2() 4255 %{ 4256 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4257 match(ConL); 4258 4259 op_cost(0); 4260 format %{ %} 4261 interface(CONST_INTER); 4262 %} 4263 4264 operand immLoffset4() 4265 %{ 4266 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4267 match(ConL); 4268 4269 op_cost(0); 4270 format %{ %} 4271 interface(CONST_INTER); 4272 %} 4273 4274 operand immLoffset8() 4275 %{ 4276 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4277 match(ConL); 4278 4279 op_cost(0); 4280 format %{ %} 4281 interface(CONST_INTER); 4282 %} 4283 4284 operand immLoffset16() 4285 %{ 4286 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4287 match(ConL); 4288 4289 op_cost(0); 4290 format %{ %} 4291 interface(CONST_INTER); 4292 %} 4293 4294 // 5 bit signed long integer 4295 operand immL5() 4296 %{ 4297 predicate(Assembler::is_simm(n->get_long(), 5)); 4298 match(ConL); 4299 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 // 7 bit unsigned long integer 4306 operand immLU7() 4307 %{ 4308 predicate(Assembler::is_uimm(n->get_long(), 7)); 4309 match(ConL); 4310 4311 op_cost(0); 4312 format %{ %} 4313 interface(CONST_INTER); 4314 %} 4315 4316 // 8 bit signed value. 4317 operand immI8() 4318 %{ 4319 predicate(n->get_int() <= 127 && n->get_int() >= -128); 4320 match(ConI); 4321 4322 op_cost(0); 4323 format %{ %} 4324 interface(CONST_INTER); 4325 %} 4326 4327 // 8 bit signed value (simm8), or #simm8 LSL 8. 4328 operand immI8_shift8() 4329 %{ 4330 predicate((n->get_int() <= 127 && n->get_int() >= -128) || 4331 (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0)); 4332 match(ConI); 4333 4334 op_cost(0); 4335 format %{ %} 4336 interface(CONST_INTER); 4337 %} 4338 4339 // 8 bit signed value (simm8), or #simm8 LSL 8. 4340 operand immL8_shift8() 4341 %{ 4342 predicate((n->get_long() <= 127 && n->get_long() >= -128) || 4343 (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0)); 4344 match(ConL); 4345 4346 op_cost(0); 4347 format %{ %} 4348 interface(CONST_INTER); 4349 %} 4350 4351 // 8 bit integer valid for vector add sub immediate 4352 operand immBAddSubV() 4353 %{ 4354 predicate(n->get_int() <= 255 && n->get_int() >= -255); 4355 match(ConI); 4356 4357 op_cost(0); 4358 format %{ %} 4359 interface(CONST_INTER); 4360 %} 4361 4362 // 32 bit integer valid for add sub immediate 4363 operand immIAddSub() 4364 %{ 4365 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4366 match(ConI); 4367 op_cost(0); 4368 format %{ %} 4369 interface(CONST_INTER); 4370 %} 4371 4372 // 32 bit integer valid for vector add sub immediate 4373 operand immIAddSubV() 4374 %{ 4375 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int())); 4376 match(ConI); 4377 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // 32 bit unsigned integer valid for logical immediate 4384 4385 operand immBLog() 4386 %{ 4387 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int())); 4388 match(ConI); 4389 4390 op_cost(0); 4391 format %{ %} 4392 interface(CONST_INTER); 4393 %} 4394 4395 operand immSLog() 4396 %{ 4397 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int())); 4398 match(ConI); 4399 4400 op_cost(0); 4401 format %{ %} 4402 interface(CONST_INTER); 4403 %} 4404 4405 operand immILog() 4406 %{ 4407 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4408 match(ConI); 4409 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413 %} 4414 4415 // Integer operands 64 bit 4416 // 64 bit immediate 4417 operand immL() 4418 %{ 4419 match(ConL); 4420 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 // 64 bit zero 4427 operand immL0() 4428 %{ 4429 predicate(n->get_long() == 0); 4430 match(ConL); 4431 4432 op_cost(0); 4433 format %{ %} 4434 interface(CONST_INTER); 4435 %} 4436 4437 // 64 bit unit decrement 4438 operand immL_M1() 4439 %{ 4440 predicate(n->get_long() == -1); 4441 match(ConL); 4442 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 // 64 bit integer valid for add sub immediate 4449 operand immLAddSub() 4450 %{ 4451 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4452 match(ConL); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // 64 bit integer valid for addv subv immediate 4459 operand immLAddSubV() 4460 %{ 4461 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long())); 4462 match(ConL); 4463 4464 op_cost(0); 4465 format %{ %} 4466 interface(CONST_INTER); 4467 %} 4468 4469 // 64 bit integer valid for logical immediate 4470 operand immLLog() 4471 %{ 4472 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4473 match(ConL); 4474 op_cost(0); 4475 format %{ %} 4476 interface(CONST_INTER); 4477 %} 4478 4479 // Long Immediate: low 32-bit mask 4480 operand immL_32bits() 4481 %{ 4482 predicate(n->get_long() == 0xFFFFFFFFL); 4483 match(ConL); 4484 op_cost(0); 4485 format %{ %} 4486 interface(CONST_INTER); 4487 %} 4488 4489 // Pointer operands 4490 // Pointer Immediate 4491 operand immP() 4492 %{ 4493 match(ConP); 4494 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // nullptr Pointer Immediate 4501 operand immP0() 4502 %{ 4503 predicate(n->get_ptr() == 0); 4504 match(ConP); 4505 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 // Pointer Immediate One 4512 // this is used in object initialization (initial object header) 4513 operand immP_1() 4514 %{ 4515 predicate(n->get_ptr() == 1); 4516 match(ConP); 4517 4518 op_cost(0); 4519 format %{ %} 4520 interface(CONST_INTER); 4521 %} 4522 4523 // Card Table Byte Map Base 4524 operand immByteMapBase() 4525 %{ 4526 // Get base of card map 4527 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4528 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4529 match(ConP); 4530 4531 op_cost(0); 4532 format %{ %} 4533 interface(CONST_INTER); 4534 %} 4535 4536 // Float and Double operands 4537 // Double Immediate 4538 operand immD() 4539 %{ 4540 match(ConD); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 // Double Immediate: +0.0d 4547 operand immD0() 4548 %{ 4549 predicate(jlong_cast(n->getd()) == 0); 4550 match(ConD); 4551 4552 op_cost(0); 4553 format %{ %} 4554 interface(CONST_INTER); 4555 %} 4556 4557 // constant 'double +0.0'. 4558 operand immDPacked() 4559 %{ 4560 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4561 match(ConD); 4562 op_cost(0); 4563 format %{ %} 4564 interface(CONST_INTER); 4565 %} 4566 4567 // Float Immediate 4568 operand immF() 4569 %{ 4570 match(ConF); 4571 op_cost(0); 4572 format %{ %} 4573 interface(CONST_INTER); 4574 %} 4575 4576 // Float Immediate: +0.0f. 4577 operand immF0() 4578 %{ 4579 predicate(jint_cast(n->getf()) == 0); 4580 match(ConF); 4581 4582 op_cost(0); 4583 format %{ %} 4584 interface(CONST_INTER); 4585 %} 4586 4587 // 4588 operand immFPacked() 4589 %{ 4590 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4591 match(ConF); 4592 op_cost(0); 4593 format %{ %} 4594 interface(CONST_INTER); 4595 %} 4596 4597 // Narrow pointer operands 4598 // Narrow Pointer Immediate 4599 operand immN() 4600 %{ 4601 match(ConN); 4602 4603 op_cost(0); 4604 format %{ %} 4605 interface(CONST_INTER); 4606 %} 4607 4608 // Narrow nullptr Pointer Immediate 4609 operand immN0() 4610 %{ 4611 predicate(n->get_narrowcon() == 0); 4612 match(ConN); 4613 4614 op_cost(0); 4615 format %{ %} 4616 interface(CONST_INTER); 4617 %} 4618 4619 operand immNKlass() 4620 %{ 4621 match(ConNKlass); 4622 4623 op_cost(0); 4624 format %{ %} 4625 interface(CONST_INTER); 4626 %} 4627 4628 // Integer 32 bit Register Operands 4629 // Integer 32 bitRegister (excludes SP) 4630 operand iRegI() 4631 %{ 4632 constraint(ALLOC_IN_RC(any_reg32)); 4633 match(RegI); 4634 match(iRegINoSp); 4635 op_cost(0); 4636 format %{ %} 4637 interface(REG_INTER); 4638 %} 4639 4640 // Integer 32 bit Register not Special 4641 operand iRegINoSp() 4642 %{ 4643 constraint(ALLOC_IN_RC(no_special_reg32)); 4644 match(RegI); 4645 op_cost(0); 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 // Integer 64 bit Register Operands 4651 // Integer 64 bit Register (includes SP) 4652 operand iRegL() 4653 %{ 4654 constraint(ALLOC_IN_RC(any_reg)); 4655 match(RegL); 4656 match(iRegLNoSp); 4657 op_cost(0); 4658 format %{ %} 4659 interface(REG_INTER); 4660 %} 4661 4662 // Integer 64 bit Register not Special 4663 operand iRegLNoSp() 4664 %{ 4665 constraint(ALLOC_IN_RC(no_special_reg)); 4666 match(RegL); 4667 match(iRegL_R0); 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 // Pointer Register Operands 4673 // Pointer Register 4674 operand iRegP() 4675 %{ 4676 constraint(ALLOC_IN_RC(ptr_reg)); 4677 match(RegP); 4678 match(iRegPNoSp); 4679 match(iRegP_R0); 4680 //match(iRegP_R2); 4681 //match(iRegP_R4); 4682 match(iRegP_R5); 4683 match(thread_RegP); 4684 op_cost(0); 4685 format %{ %} 4686 interface(REG_INTER); 4687 %} 4688 4689 // Pointer 64 bit Register not Special 4690 operand iRegPNoSp() 4691 %{ 4692 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4693 match(RegP); 4694 // match(iRegP); 4695 // match(iRegP_R0); 4696 // match(iRegP_R2); 4697 // match(iRegP_R4); 4698 // match(iRegP_R5); 4699 // match(thread_RegP); 4700 op_cost(0); 4701 format %{ %} 4702 interface(REG_INTER); 4703 %} 4704 4705 // This operand is not allowed to use rfp even if 4706 // rfp is not used to hold the frame pointer. 4707 operand iRegPNoSpNoRfp() 4708 %{ 4709 constraint(ALLOC_IN_RC(no_special_no_rfp_ptr_reg)); 4710 match(RegP); 4711 match(iRegPNoSp); 4712 op_cost(0); 4713 format %{ %} 4714 interface(REG_INTER); 4715 %} 4716 4717 // Pointer 64 bit Register R0 only 4718 operand iRegP_R0() 4719 %{ 4720 constraint(ALLOC_IN_RC(r0_reg)); 4721 match(RegP); 4722 // match(iRegP); 4723 match(iRegPNoSp); 4724 op_cost(0); 4725 format %{ %} 4726 interface(REG_INTER); 4727 %} 4728 4729 // Pointer 64 bit Register R1 only 4730 operand iRegP_R1() 4731 %{ 4732 constraint(ALLOC_IN_RC(r1_reg)); 4733 match(RegP); 4734 // match(iRegP); 4735 match(iRegPNoSp); 4736 op_cost(0); 4737 format %{ %} 4738 interface(REG_INTER); 4739 %} 4740 4741 // Pointer 64 bit Register R2 only 4742 operand iRegP_R2() 4743 %{ 4744 constraint(ALLOC_IN_RC(r2_reg)); 4745 match(RegP); 4746 // match(iRegP); 4747 match(iRegPNoSp); 4748 op_cost(0); 4749 format %{ %} 4750 interface(REG_INTER); 4751 %} 4752 4753 // Pointer 64 bit Register R3 only 4754 operand iRegP_R3() 4755 %{ 4756 constraint(ALLOC_IN_RC(r3_reg)); 4757 match(RegP); 4758 // match(iRegP); 4759 match(iRegPNoSp); 4760 op_cost(0); 4761 format %{ %} 4762 interface(REG_INTER); 4763 %} 4764 4765 // Pointer 64 bit Register R4 only 4766 operand iRegP_R4() 4767 %{ 4768 constraint(ALLOC_IN_RC(r4_reg)); 4769 match(RegP); 4770 // match(iRegP); 4771 match(iRegPNoSp); 4772 op_cost(0); 4773 format %{ %} 4774 interface(REG_INTER); 4775 %} 4776 4777 // Pointer 64 bit Register R5 only 4778 operand iRegP_R5() 4779 %{ 4780 constraint(ALLOC_IN_RC(r5_reg)); 4781 match(RegP); 4782 // match(iRegP); 4783 match(iRegPNoSp); 4784 op_cost(0); 4785 format %{ %} 4786 interface(REG_INTER); 4787 %} 4788 4789 // Pointer 64 bit Register R10 only 4790 operand iRegP_R10() 4791 %{ 4792 constraint(ALLOC_IN_RC(r10_reg)); 4793 match(RegP); 4794 // match(iRegP); 4795 match(iRegPNoSp); 4796 op_cost(0); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 // Long 64 bit Register R0 only 4802 operand iRegL_R0() 4803 %{ 4804 constraint(ALLOC_IN_RC(r0_reg)); 4805 match(RegL); 4806 match(iRegLNoSp); 4807 op_cost(0); 4808 format %{ %} 4809 interface(REG_INTER); 4810 %} 4811 4812 // Long 64 bit Register R11 only 4813 operand iRegL_R11() 4814 %{ 4815 constraint(ALLOC_IN_RC(r11_reg)); 4816 match(RegL); 4817 match(iRegLNoSp); 4818 op_cost(0); 4819 format %{ %} 4820 interface(REG_INTER); 4821 %} 4822 4823 // Register R0 only 4824 operand iRegI_R0() 4825 %{ 4826 constraint(ALLOC_IN_RC(int_r0_reg)); 4827 match(RegI); 4828 match(iRegINoSp); 4829 op_cost(0); 4830 format %{ %} 4831 interface(REG_INTER); 4832 %} 4833 4834 // Register R2 only 4835 operand iRegI_R2() 4836 %{ 4837 constraint(ALLOC_IN_RC(int_r2_reg)); 4838 match(RegI); 4839 match(iRegINoSp); 4840 op_cost(0); 4841 format %{ %} 4842 interface(REG_INTER); 4843 %} 4844 4845 // Register R3 only 4846 operand iRegI_R3() 4847 %{ 4848 constraint(ALLOC_IN_RC(int_r3_reg)); 4849 match(RegI); 4850 match(iRegINoSp); 4851 op_cost(0); 4852 format %{ %} 4853 interface(REG_INTER); 4854 %} 4855 4856 4857 // Register R4 only 4858 operand iRegI_R4() 4859 %{ 4860 constraint(ALLOC_IN_RC(int_r4_reg)); 4861 match(RegI); 4862 match(iRegINoSp); 4863 op_cost(0); 4864 format %{ %} 4865 interface(REG_INTER); 4866 %} 4867 4868 4869 // Pointer Register Operands 4870 // Narrow Pointer Register 4871 operand iRegN() 4872 %{ 4873 constraint(ALLOC_IN_RC(any_reg32)); 4874 match(RegN); 4875 match(iRegNNoSp); 4876 op_cost(0); 4877 format %{ %} 4878 interface(REG_INTER); 4879 %} 4880 4881 // Integer 64 bit Register not Special 4882 operand iRegNNoSp() 4883 %{ 4884 constraint(ALLOC_IN_RC(no_special_reg32)); 4885 match(RegN); 4886 op_cost(0); 4887 format %{ %} 4888 interface(REG_INTER); 4889 %} 4890 4891 // Float Register 4892 // Float register operands 4893 operand vRegF() 4894 %{ 4895 constraint(ALLOC_IN_RC(float_reg)); 4896 match(RegF); 4897 4898 op_cost(0); 4899 format %{ %} 4900 interface(REG_INTER); 4901 %} 4902 4903 // Double Register 4904 // Double register operands 4905 operand vRegD() 4906 %{ 4907 constraint(ALLOC_IN_RC(double_reg)); 4908 match(RegD); 4909 4910 op_cost(0); 4911 format %{ %} 4912 interface(REG_INTER); 4913 %} 4914 4915 // Generic vector class. This will be used for 4916 // all vector operands, including NEON and SVE. 4917 operand vReg() 4918 %{ 4919 constraint(ALLOC_IN_RC(dynamic)); 4920 match(VecA); 4921 match(VecD); 4922 match(VecX); 4923 4924 op_cost(0); 4925 format %{ %} 4926 interface(REG_INTER); 4927 %} 4928 4929 operand vecA() 4930 %{ 4931 constraint(ALLOC_IN_RC(vectora_reg)); 4932 match(VecA); 4933 4934 op_cost(0); 4935 format %{ %} 4936 interface(REG_INTER); 4937 %} 4938 4939 operand vecD() 4940 %{ 4941 constraint(ALLOC_IN_RC(vectord_reg)); 4942 match(VecD); 4943 4944 op_cost(0); 4945 format %{ %} 4946 interface(REG_INTER); 4947 %} 4948 4949 operand vecX() 4950 %{ 4951 constraint(ALLOC_IN_RC(vectorx_reg)); 4952 match(VecX); 4953 4954 op_cost(0); 4955 format %{ %} 4956 interface(REG_INTER); 4957 %} 4958 4959 operand vRegD_V0() 4960 %{ 4961 constraint(ALLOC_IN_RC(v0_reg)); 4962 match(RegD); 4963 op_cost(0); 4964 format %{ %} 4965 interface(REG_INTER); 4966 %} 4967 4968 operand vRegD_V1() 4969 %{ 4970 constraint(ALLOC_IN_RC(v1_reg)); 4971 match(RegD); 4972 op_cost(0); 4973 format %{ %} 4974 interface(REG_INTER); 4975 %} 4976 4977 operand vRegD_V2() 4978 %{ 4979 constraint(ALLOC_IN_RC(v2_reg)); 4980 match(RegD); 4981 op_cost(0); 4982 format %{ %} 4983 interface(REG_INTER); 4984 %} 4985 4986 operand vRegD_V3() 4987 %{ 4988 constraint(ALLOC_IN_RC(v3_reg)); 4989 match(RegD); 4990 op_cost(0); 4991 format %{ %} 4992 interface(REG_INTER); 4993 %} 4994 4995 operand vRegD_V4() 4996 %{ 4997 constraint(ALLOC_IN_RC(v4_reg)); 4998 match(RegD); 4999 op_cost(0); 5000 format %{ %} 5001 interface(REG_INTER); 5002 %} 5003 5004 operand vRegD_V5() 5005 %{ 5006 constraint(ALLOC_IN_RC(v5_reg)); 5007 match(RegD); 5008 op_cost(0); 5009 format %{ %} 5010 interface(REG_INTER); 5011 %} 5012 5013 operand vRegD_V6() 5014 %{ 5015 constraint(ALLOC_IN_RC(v6_reg)); 5016 match(RegD); 5017 op_cost(0); 5018 format %{ %} 5019 interface(REG_INTER); 5020 %} 5021 5022 operand vRegD_V7() 5023 %{ 5024 constraint(ALLOC_IN_RC(v7_reg)); 5025 match(RegD); 5026 op_cost(0); 5027 format %{ %} 5028 interface(REG_INTER); 5029 %} 5030 5031 operand pReg() 5032 %{ 5033 constraint(ALLOC_IN_RC(pr_reg)); 5034 match(RegVectMask); 5035 match(pRegGov); 5036 op_cost(0); 5037 format %{ %} 5038 interface(REG_INTER); 5039 %} 5040 5041 operand pRegGov() 5042 %{ 5043 constraint(ALLOC_IN_RC(gov_pr)); 5044 match(RegVectMask); 5045 match(pReg); 5046 op_cost(0); 5047 format %{ %} 5048 interface(REG_INTER); 5049 %} 5050 5051 operand pRegGov_P0() 5052 %{ 5053 constraint(ALLOC_IN_RC(p0_reg)); 5054 match(RegVectMask); 5055 op_cost(0); 5056 format %{ %} 5057 interface(REG_INTER); 5058 %} 5059 5060 operand pRegGov_P1() 5061 %{ 5062 constraint(ALLOC_IN_RC(p1_reg)); 5063 match(RegVectMask); 5064 op_cost(0); 5065 format %{ %} 5066 interface(REG_INTER); 5067 %} 5068 5069 // Flags register, used as output of signed compare instructions 5070 5071 // note that on AArch64 we also use this register as the output for 5072 // for floating point compare instructions (CmpF CmpD). this ensures 5073 // that ordered inequality tests use GT, GE, LT or LE none of which 5074 // pass through cases where the result is unordered i.e. one or both 5075 // inputs to the compare is a NaN. this means that the ideal code can 5076 // replace e.g. a GT with an LE and not end up capturing the NaN case 5077 // (where the comparison should always fail). EQ and NE tests are 5078 // always generated in ideal code so that unordered folds into the NE 5079 // case, matching the behaviour of AArch64 NE. 5080 // 5081 // This differs from x86 where the outputs of FP compares use a 5082 // special FP flags registers and where compares based on this 5083 // register are distinguished into ordered inequalities (cmpOpUCF) and 5084 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5085 // to explicitly handle the unordered case in branches. x86 also has 5086 // to include extra CMoveX rules to accept a cmpOpUCF input. 5087 5088 operand rFlagsReg() 5089 %{ 5090 constraint(ALLOC_IN_RC(int_flags)); 5091 match(RegFlags); 5092 5093 op_cost(0); 5094 format %{ "RFLAGS" %} 5095 interface(REG_INTER); 5096 %} 5097 5098 // Flags register, used as output of unsigned compare instructions 5099 operand rFlagsRegU() 5100 %{ 5101 constraint(ALLOC_IN_RC(int_flags)); 5102 match(RegFlags); 5103 5104 op_cost(0); 5105 format %{ "RFLAGSU" %} 5106 interface(REG_INTER); 5107 %} 5108 5109 // Special Registers 5110 5111 // Method Register 5112 operand inline_cache_RegP(iRegP reg) 5113 %{ 5114 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5115 match(reg); 5116 match(iRegPNoSp); 5117 op_cost(0); 5118 format %{ %} 5119 interface(REG_INTER); 5120 %} 5121 5122 // Thread Register 5123 operand thread_RegP(iRegP reg) 5124 %{ 5125 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5126 match(reg); 5127 op_cost(0); 5128 format %{ %} 5129 interface(REG_INTER); 5130 %} 5131 5132 //----------Memory Operands---------------------------------------------------- 5133 5134 operand indirect(iRegP reg) 5135 %{ 5136 constraint(ALLOC_IN_RC(ptr_reg)); 5137 match(reg); 5138 op_cost(0); 5139 format %{ "[$reg]" %} 5140 interface(MEMORY_INTER) %{ 5141 base($reg); 5142 index(0xffffffff); 5143 scale(0x0); 5144 disp(0x0); 5145 %} 5146 %} 5147 5148 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5149 %{ 5150 constraint(ALLOC_IN_RC(ptr_reg)); 5151 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5152 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5153 op_cost(0); 5154 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5155 interface(MEMORY_INTER) %{ 5156 base($reg); 5157 index($ireg); 5158 scale($scale); 5159 disp(0x0); 5160 %} 5161 %} 5162 5163 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5164 %{ 5165 constraint(ALLOC_IN_RC(ptr_reg)); 5166 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5167 match(AddP reg (LShiftL lreg scale)); 5168 op_cost(0); 5169 format %{ "$reg, $lreg lsl($scale)" %} 5170 interface(MEMORY_INTER) %{ 5171 base($reg); 5172 index($lreg); 5173 scale($scale); 5174 disp(0x0); 5175 %} 5176 %} 5177 5178 operand indIndexI2L(iRegP reg, iRegI ireg) 5179 %{ 5180 constraint(ALLOC_IN_RC(ptr_reg)); 5181 match(AddP reg (ConvI2L ireg)); 5182 op_cost(0); 5183 format %{ "$reg, $ireg, 0, I2L" %} 5184 interface(MEMORY_INTER) %{ 5185 base($reg); 5186 index($ireg); 5187 scale(0x0); 5188 disp(0x0); 5189 %} 5190 %} 5191 5192 operand indIndex(iRegP reg, iRegL lreg) 5193 %{ 5194 constraint(ALLOC_IN_RC(ptr_reg)); 5195 match(AddP reg lreg); 5196 op_cost(0); 5197 format %{ "$reg, $lreg" %} 5198 interface(MEMORY_INTER) %{ 5199 base($reg); 5200 index($lreg); 5201 scale(0x0); 5202 disp(0x0); 5203 %} 5204 %} 5205 5206 operand indOffI1(iRegP reg, immIOffset1 off) 5207 %{ 5208 constraint(ALLOC_IN_RC(ptr_reg)); 5209 match(AddP reg off); 5210 op_cost(0); 5211 format %{ "[$reg, $off]" %} 5212 interface(MEMORY_INTER) %{ 5213 base($reg); 5214 index(0xffffffff); 5215 scale(0x0); 5216 disp($off); 5217 %} 5218 %} 5219 5220 operand indOffI2(iRegP reg, immIOffset2 off) 5221 %{ 5222 constraint(ALLOC_IN_RC(ptr_reg)); 5223 match(AddP reg off); 5224 op_cost(0); 5225 format %{ "[$reg, $off]" %} 5226 interface(MEMORY_INTER) %{ 5227 base($reg); 5228 index(0xffffffff); 5229 scale(0x0); 5230 disp($off); 5231 %} 5232 %} 5233 5234 operand indOffI4(iRegP reg, immIOffset4 off) 5235 %{ 5236 constraint(ALLOC_IN_RC(ptr_reg)); 5237 match(AddP reg off); 5238 op_cost(0); 5239 format %{ "[$reg, $off]" %} 5240 interface(MEMORY_INTER) %{ 5241 base($reg); 5242 index(0xffffffff); 5243 scale(0x0); 5244 disp($off); 5245 %} 5246 %} 5247 5248 operand indOffI8(iRegP reg, immIOffset8 off) 5249 %{ 5250 constraint(ALLOC_IN_RC(ptr_reg)); 5251 match(AddP reg off); 5252 op_cost(0); 5253 format %{ "[$reg, $off]" %} 5254 interface(MEMORY_INTER) %{ 5255 base($reg); 5256 index(0xffffffff); 5257 scale(0x0); 5258 disp($off); 5259 %} 5260 %} 5261 5262 operand indOffI16(iRegP reg, immIOffset16 off) 5263 %{ 5264 constraint(ALLOC_IN_RC(ptr_reg)); 5265 match(AddP reg off); 5266 op_cost(0); 5267 format %{ "[$reg, $off]" %} 5268 interface(MEMORY_INTER) %{ 5269 base($reg); 5270 index(0xffffffff); 5271 scale(0x0); 5272 disp($off); 5273 %} 5274 %} 5275 5276 operand indOffL1(iRegP reg, immLoffset1 off) 5277 %{ 5278 constraint(ALLOC_IN_RC(ptr_reg)); 5279 match(AddP reg off); 5280 op_cost(0); 5281 format %{ "[$reg, $off]" %} 5282 interface(MEMORY_INTER) %{ 5283 base($reg); 5284 index(0xffffffff); 5285 scale(0x0); 5286 disp($off); 5287 %} 5288 %} 5289 5290 operand indOffL2(iRegP reg, immLoffset2 off) 5291 %{ 5292 constraint(ALLOC_IN_RC(ptr_reg)); 5293 match(AddP reg off); 5294 op_cost(0); 5295 format %{ "[$reg, $off]" %} 5296 interface(MEMORY_INTER) %{ 5297 base($reg); 5298 index(0xffffffff); 5299 scale(0x0); 5300 disp($off); 5301 %} 5302 %} 5303 5304 operand indOffL4(iRegP reg, immLoffset4 off) 5305 %{ 5306 constraint(ALLOC_IN_RC(ptr_reg)); 5307 match(AddP reg off); 5308 op_cost(0); 5309 format %{ "[$reg, $off]" %} 5310 interface(MEMORY_INTER) %{ 5311 base($reg); 5312 index(0xffffffff); 5313 scale(0x0); 5314 disp($off); 5315 %} 5316 %} 5317 5318 operand indOffL8(iRegP reg, immLoffset8 off) 5319 %{ 5320 constraint(ALLOC_IN_RC(ptr_reg)); 5321 match(AddP reg off); 5322 op_cost(0); 5323 format %{ "[$reg, $off]" %} 5324 interface(MEMORY_INTER) %{ 5325 base($reg); 5326 index(0xffffffff); 5327 scale(0x0); 5328 disp($off); 5329 %} 5330 %} 5331 5332 operand indOffL16(iRegP reg, immLoffset16 off) 5333 %{ 5334 constraint(ALLOC_IN_RC(ptr_reg)); 5335 match(AddP reg off); 5336 op_cost(0); 5337 format %{ "[$reg, $off]" %} 5338 interface(MEMORY_INTER) %{ 5339 base($reg); 5340 index(0xffffffff); 5341 scale(0x0); 5342 disp($off); 5343 %} 5344 %} 5345 5346 operand indirectX2P(iRegL reg) 5347 %{ 5348 constraint(ALLOC_IN_RC(ptr_reg)); 5349 match(CastX2P reg); 5350 op_cost(0); 5351 format %{ "[$reg]\t# long -> ptr" %} 5352 interface(MEMORY_INTER) %{ 5353 base($reg); 5354 index(0xffffffff); 5355 scale(0x0); 5356 disp(0x0); 5357 %} 5358 %} 5359 5360 operand indOffX2P(iRegL reg, immLOffset off) 5361 %{ 5362 constraint(ALLOC_IN_RC(ptr_reg)); 5363 match(AddP (CastX2P reg) off); 5364 op_cost(0); 5365 format %{ "[$reg, $off]\t# long -> ptr" %} 5366 interface(MEMORY_INTER) %{ 5367 base($reg); 5368 index(0xffffffff); 5369 scale(0x0); 5370 disp($off); 5371 %} 5372 %} 5373 5374 operand indirectN(iRegN reg) 5375 %{ 5376 predicate(CompressedOops::shift() == 0); 5377 constraint(ALLOC_IN_RC(ptr_reg)); 5378 match(DecodeN reg); 5379 op_cost(0); 5380 format %{ "[$reg]\t# narrow" %} 5381 interface(MEMORY_INTER) %{ 5382 base($reg); 5383 index(0xffffffff); 5384 scale(0x0); 5385 disp(0x0); 5386 %} 5387 %} 5388 5389 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5390 %{ 5391 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5392 constraint(ALLOC_IN_RC(ptr_reg)); 5393 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5394 op_cost(0); 5395 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5396 interface(MEMORY_INTER) %{ 5397 base($reg); 5398 index($ireg); 5399 scale($scale); 5400 disp(0x0); 5401 %} 5402 %} 5403 5404 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5405 %{ 5406 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5407 constraint(ALLOC_IN_RC(ptr_reg)); 5408 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5409 op_cost(0); 5410 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5411 interface(MEMORY_INTER) %{ 5412 base($reg); 5413 index($lreg); 5414 scale($scale); 5415 disp(0x0); 5416 %} 5417 %} 5418 5419 operand indIndexI2LN(iRegN reg, iRegI ireg) 5420 %{ 5421 predicate(CompressedOops::shift() == 0); 5422 constraint(ALLOC_IN_RC(ptr_reg)); 5423 match(AddP (DecodeN reg) (ConvI2L ireg)); 5424 op_cost(0); 5425 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5426 interface(MEMORY_INTER) %{ 5427 base($reg); 5428 index($ireg); 5429 scale(0x0); 5430 disp(0x0); 5431 %} 5432 %} 5433 5434 operand indIndexN(iRegN reg, iRegL lreg) 5435 %{ 5436 predicate(CompressedOops::shift() == 0); 5437 constraint(ALLOC_IN_RC(ptr_reg)); 5438 match(AddP (DecodeN reg) lreg); 5439 op_cost(0); 5440 format %{ "$reg, $lreg\t# narrow" %} 5441 interface(MEMORY_INTER) %{ 5442 base($reg); 5443 index($lreg); 5444 scale(0x0); 5445 disp(0x0); 5446 %} 5447 %} 5448 5449 operand indOffIN(iRegN reg, immIOffset off) 5450 %{ 5451 predicate(CompressedOops::shift() == 0); 5452 constraint(ALLOC_IN_RC(ptr_reg)); 5453 match(AddP (DecodeN reg) off); 5454 op_cost(0); 5455 format %{ "[$reg, $off]\t# narrow" %} 5456 interface(MEMORY_INTER) %{ 5457 base($reg); 5458 index(0xffffffff); 5459 scale(0x0); 5460 disp($off); 5461 %} 5462 %} 5463 5464 operand indOffLN(iRegN reg, immLOffset off) 5465 %{ 5466 predicate(CompressedOops::shift() == 0); 5467 constraint(ALLOC_IN_RC(ptr_reg)); 5468 match(AddP (DecodeN reg) off); 5469 op_cost(0); 5470 format %{ "[$reg, $off]\t# narrow" %} 5471 interface(MEMORY_INTER) %{ 5472 base($reg); 5473 index(0xffffffff); 5474 scale(0x0); 5475 disp($off); 5476 %} 5477 %} 5478 5479 5480 //----------Special Memory Operands-------------------------------------------- 5481 // Stack Slot Operand - This operand is used for loading and storing temporary 5482 // values on the stack where a match requires a value to 5483 // flow through memory. 5484 operand stackSlotP(sRegP reg) 5485 %{ 5486 constraint(ALLOC_IN_RC(stack_slots)); 5487 op_cost(100); 5488 // No match rule because this operand is only generated in matching 5489 // match(RegP); 5490 format %{ "[$reg]" %} 5491 interface(MEMORY_INTER) %{ 5492 base(0x1e); // RSP 5493 index(0x0); // No Index 5494 scale(0x0); // No Scale 5495 disp($reg); // Stack Offset 5496 %} 5497 %} 5498 5499 operand stackSlotI(sRegI reg) 5500 %{ 5501 constraint(ALLOC_IN_RC(stack_slots)); 5502 // No match rule because this operand is only generated in matching 5503 // match(RegI); 5504 format %{ "[$reg]" %} 5505 interface(MEMORY_INTER) %{ 5506 base(0x1e); // RSP 5507 index(0x0); // No Index 5508 scale(0x0); // No Scale 5509 disp($reg); // Stack Offset 5510 %} 5511 %} 5512 5513 operand stackSlotF(sRegF reg) 5514 %{ 5515 constraint(ALLOC_IN_RC(stack_slots)); 5516 // No match rule because this operand is only generated in matching 5517 // match(RegF); 5518 format %{ "[$reg]" %} 5519 interface(MEMORY_INTER) %{ 5520 base(0x1e); // RSP 5521 index(0x0); // No Index 5522 scale(0x0); // No Scale 5523 disp($reg); // Stack Offset 5524 %} 5525 %} 5526 5527 operand stackSlotD(sRegD reg) 5528 %{ 5529 constraint(ALLOC_IN_RC(stack_slots)); 5530 // No match rule because this operand is only generated in matching 5531 // match(RegD); 5532 format %{ "[$reg]" %} 5533 interface(MEMORY_INTER) %{ 5534 base(0x1e); // RSP 5535 index(0x0); // No Index 5536 scale(0x0); // No Scale 5537 disp($reg); // Stack Offset 5538 %} 5539 %} 5540 5541 operand stackSlotL(sRegL reg) 5542 %{ 5543 constraint(ALLOC_IN_RC(stack_slots)); 5544 // No match rule because this operand is only generated in matching 5545 // match(RegL); 5546 format %{ "[$reg]" %} 5547 interface(MEMORY_INTER) %{ 5548 base(0x1e); // RSP 5549 index(0x0); // No Index 5550 scale(0x0); // No Scale 5551 disp($reg); // Stack Offset 5552 %} 5553 %} 5554 5555 // Operands for expressing Control Flow 5556 // NOTE: Label is a predefined operand which should not be redefined in 5557 // the AD file. It is generically handled within the ADLC. 5558 5559 //----------Conditional Branch Operands---------------------------------------- 5560 // Comparison Op - This is the operation of the comparison, and is limited to 5561 // the following set of codes: 5562 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5563 // 5564 // Other attributes of the comparison, such as unsignedness, are specified 5565 // by the comparison instruction that sets a condition code flags register. 5566 // That result is represented by a flags operand whose subtype is appropriate 5567 // to the unsignedness (etc.) of the comparison. 5568 // 5569 // Later, the instruction which matches both the Comparison Op (a Bool) and 5570 // the flags (produced by the Cmp) specifies the coding of the comparison op 5571 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5572 5573 // used for signed integral comparisons and fp comparisons 5574 5575 operand cmpOp() 5576 %{ 5577 match(Bool); 5578 5579 format %{ "" %} 5580 interface(COND_INTER) %{ 5581 equal(0x0, "eq"); 5582 not_equal(0x1, "ne"); 5583 less(0xb, "lt"); 5584 greater_equal(0xa, "ge"); 5585 less_equal(0xd, "le"); 5586 greater(0xc, "gt"); 5587 overflow(0x6, "vs"); 5588 no_overflow(0x7, "vc"); 5589 %} 5590 %} 5591 5592 // used for unsigned integral comparisons 5593 5594 operand cmpOpU() 5595 %{ 5596 match(Bool); 5597 5598 format %{ "" %} 5599 interface(COND_INTER) %{ 5600 equal(0x0, "eq"); 5601 not_equal(0x1, "ne"); 5602 less(0x3, "lo"); 5603 greater_equal(0x2, "hs"); 5604 less_equal(0x9, "ls"); 5605 greater(0x8, "hi"); 5606 overflow(0x6, "vs"); 5607 no_overflow(0x7, "vc"); 5608 %} 5609 %} 5610 5611 // used for certain integral comparisons which can be 5612 // converted to cbxx or tbxx instructions 5613 5614 operand cmpOpEqNe() 5615 %{ 5616 match(Bool); 5617 op_cost(0); 5618 predicate(n->as_Bool()->_test._test == BoolTest::ne 5619 || n->as_Bool()->_test._test == BoolTest::eq); 5620 5621 format %{ "" %} 5622 interface(COND_INTER) %{ 5623 equal(0x0, "eq"); 5624 not_equal(0x1, "ne"); 5625 less(0xb, "lt"); 5626 greater_equal(0xa, "ge"); 5627 less_equal(0xd, "le"); 5628 greater(0xc, "gt"); 5629 overflow(0x6, "vs"); 5630 no_overflow(0x7, "vc"); 5631 %} 5632 %} 5633 5634 // used for certain integral comparisons which can be 5635 // converted to cbxx or tbxx instructions 5636 5637 operand cmpOpLtGe() 5638 %{ 5639 match(Bool); 5640 op_cost(0); 5641 5642 predicate(n->as_Bool()->_test._test == BoolTest::lt 5643 || n->as_Bool()->_test._test == BoolTest::ge); 5644 5645 format %{ "" %} 5646 interface(COND_INTER) %{ 5647 equal(0x0, "eq"); 5648 not_equal(0x1, "ne"); 5649 less(0xb, "lt"); 5650 greater_equal(0xa, "ge"); 5651 less_equal(0xd, "le"); 5652 greater(0xc, "gt"); 5653 overflow(0x6, "vs"); 5654 no_overflow(0x7, "vc"); 5655 %} 5656 %} 5657 5658 // used for certain unsigned integral comparisons which can be 5659 // converted to cbxx or tbxx instructions 5660 5661 operand cmpOpUEqNeLeGt() 5662 %{ 5663 match(Bool); 5664 op_cost(0); 5665 5666 predicate(n->as_Bool()->_test._test == BoolTest::eq || 5667 n->as_Bool()->_test._test == BoolTest::ne || 5668 n->as_Bool()->_test._test == BoolTest::le || 5669 n->as_Bool()->_test._test == BoolTest::gt); 5670 5671 format %{ "" %} 5672 interface(COND_INTER) %{ 5673 equal(0x0, "eq"); 5674 not_equal(0x1, "ne"); 5675 less(0x3, "lo"); 5676 greater_equal(0x2, "hs"); 5677 less_equal(0x9, "ls"); 5678 greater(0x8, "hi"); 5679 overflow(0x6, "vs"); 5680 no_overflow(0x7, "vc"); 5681 %} 5682 %} 5683 5684 // Special operand allowing long args to int ops to be truncated for free 5685 5686 operand iRegL2I(iRegL reg) %{ 5687 5688 op_cost(0); 5689 5690 match(ConvL2I reg); 5691 5692 format %{ "l2i($reg)" %} 5693 5694 interface(REG_INTER) 5695 %} 5696 5697 operand iRegL2P(iRegL reg) %{ 5698 5699 op_cost(0); 5700 5701 match(CastX2P reg); 5702 5703 format %{ "l2p($reg)" %} 5704 5705 interface(REG_INTER) 5706 %} 5707 5708 opclass vmem2(indirect, indIndex, indOffI2, indOffL2); 5709 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5710 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5711 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5712 5713 //----------OPERAND CLASSES---------------------------------------------------- 5714 // Operand Classes are groups of operands that are used as to simplify 5715 // instruction definitions by not requiring the AD writer to specify 5716 // separate instructions for every form of operand when the 5717 // instruction accepts multiple operand types with the same basic 5718 // encoding and format. The classic case of this is memory operands. 5719 5720 // memory is used to define read/write location for load/store 5721 // instruction defs. we can turn a memory op into an Address 5722 5723 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5724 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P); 5725 5726 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5727 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P); 5728 5729 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5730 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P); 5731 5732 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5733 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P); 5734 5735 // All of the memory operands. For the pipeline description. 5736 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5737 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5738 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P); 5739 5740 5741 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5742 // operations. it allows the src to be either an iRegI or a (ConvL2I 5743 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5744 // can be elided because the 32-bit instruction will just employ the 5745 // lower 32 bits anyway. 5746 // 5747 // n.b. this does not elide all L2I conversions. if the truncated 5748 // value is consumed by more than one operation then the ConvL2I 5749 // cannot be bundled into the consuming nodes so an l2i gets planted 5750 // (actually a movw $dst $src) and the downstream instructions consume 5751 // the result of the l2i as an iRegI input. That's a shame since the 5752 // movw is actually redundant but its not too costly. 5753 5754 opclass iRegIorL2I(iRegI, iRegL2I); 5755 opclass iRegPorL2P(iRegP, iRegL2P); 5756 5757 //----------PIPELINE----------------------------------------------------------- 5758 // Rules which define the behavior of the target architectures pipeline. 5759 5760 // For specific pipelines, eg A53, define the stages of that pipeline 5761 //pipe_desc(ISS, EX1, EX2, WR); 5762 #define ISS S0 5763 #define EX1 S1 5764 #define EX2 S2 5765 #define WR S3 5766 5767 // Integer ALU reg operation 5768 pipeline %{ 5769 5770 attributes %{ 5771 // ARM instructions are of fixed length 5772 fixed_size_instructions; // Fixed size instructions TODO does 5773 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 5774 // ARM instructions come in 32-bit word units 5775 instruction_unit_size = 4; // An instruction is 4 bytes long 5776 instruction_fetch_unit_size = 64; // The processor fetches one line 5777 instruction_fetch_units = 1; // of 64 bytes 5778 5779 // List of nop instructions 5780 nops( MachNop ); 5781 %} 5782 5783 // We don't use an actual pipeline model so don't care about resources 5784 // or description. we do use pipeline classes to introduce fixed 5785 // latencies 5786 5787 //----------RESOURCES---------------------------------------------------------- 5788 // Resources are the functional units available to the machine 5789 5790 resources( INS0, INS1, INS01 = INS0 | INS1, 5791 ALU0, ALU1, ALU = ALU0 | ALU1, 5792 MAC, 5793 DIV, 5794 BRANCH, 5795 LDST, 5796 NEON_FP); 5797 5798 //----------PIPELINE DESCRIPTION----------------------------------------------- 5799 // Pipeline Description specifies the stages in the machine's pipeline 5800 5801 // Define the pipeline as a generic 6 stage pipeline 5802 pipe_desc(S0, S1, S2, S3, S4, S5); 5803 5804 //----------PIPELINE CLASSES--------------------------------------------------- 5805 // Pipeline Classes describe the stages in which input and output are 5806 // referenced by the hardware pipeline. 5807 5808 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5809 %{ 5810 single_instruction; 5811 src1 : S1(read); 5812 src2 : S2(read); 5813 dst : S5(write); 5814 INS01 : ISS; 5815 NEON_FP : S5; 5816 %} 5817 5818 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5819 %{ 5820 single_instruction; 5821 src1 : S1(read); 5822 src2 : S2(read); 5823 dst : S5(write); 5824 INS01 : ISS; 5825 NEON_FP : S5; 5826 %} 5827 5828 pipe_class fp_uop_s(vRegF dst, vRegF src) 5829 %{ 5830 single_instruction; 5831 src : S1(read); 5832 dst : S5(write); 5833 INS01 : ISS; 5834 NEON_FP : S5; 5835 %} 5836 5837 pipe_class fp_uop_d(vRegD dst, vRegD src) 5838 %{ 5839 single_instruction; 5840 src : S1(read); 5841 dst : S5(write); 5842 INS01 : ISS; 5843 NEON_FP : S5; 5844 %} 5845 5846 pipe_class fp_d2f(vRegF dst, vRegD src) 5847 %{ 5848 single_instruction; 5849 src : S1(read); 5850 dst : S5(write); 5851 INS01 : ISS; 5852 NEON_FP : S5; 5853 %} 5854 5855 pipe_class fp_f2d(vRegD dst, vRegF src) 5856 %{ 5857 single_instruction; 5858 src : S1(read); 5859 dst : S5(write); 5860 INS01 : ISS; 5861 NEON_FP : S5; 5862 %} 5863 5864 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5865 %{ 5866 single_instruction; 5867 src : S1(read); 5868 dst : S5(write); 5869 INS01 : ISS; 5870 NEON_FP : S5; 5871 %} 5872 5873 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5874 %{ 5875 single_instruction; 5876 src : S1(read); 5877 dst : S5(write); 5878 INS01 : ISS; 5879 NEON_FP : S5; 5880 %} 5881 5882 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5883 %{ 5884 single_instruction; 5885 src : S1(read); 5886 dst : S5(write); 5887 INS01 : ISS; 5888 NEON_FP : S5; 5889 %} 5890 5891 pipe_class fp_l2f(vRegF dst, iRegL src) 5892 %{ 5893 single_instruction; 5894 src : S1(read); 5895 dst : S5(write); 5896 INS01 : ISS; 5897 NEON_FP : S5; 5898 %} 5899 5900 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5901 %{ 5902 single_instruction; 5903 src : S1(read); 5904 dst : S5(write); 5905 INS01 : ISS; 5906 NEON_FP : S5; 5907 %} 5908 5909 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5910 %{ 5911 single_instruction; 5912 src : S1(read); 5913 dst : S5(write); 5914 INS01 : ISS; 5915 NEON_FP : S5; 5916 %} 5917 5918 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5919 %{ 5920 single_instruction; 5921 src : S1(read); 5922 dst : S5(write); 5923 INS01 : ISS; 5924 NEON_FP : S5; 5925 %} 5926 5927 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5928 %{ 5929 single_instruction; 5930 src : S1(read); 5931 dst : S5(write); 5932 INS01 : ISS; 5933 NEON_FP : S5; 5934 %} 5935 5936 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5937 %{ 5938 single_instruction; 5939 src1 : S1(read); 5940 src2 : S2(read); 5941 dst : S5(write); 5942 INS0 : ISS; 5943 NEON_FP : S5; 5944 %} 5945 5946 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5947 %{ 5948 single_instruction; 5949 src1 : S1(read); 5950 src2 : S2(read); 5951 dst : S5(write); 5952 INS0 : ISS; 5953 NEON_FP : S5; 5954 %} 5955 5956 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5957 %{ 5958 single_instruction; 5959 cr : S1(read); 5960 src1 : S1(read); 5961 src2 : S1(read); 5962 dst : S3(write); 5963 INS01 : ISS; 5964 NEON_FP : S3; 5965 %} 5966 5967 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5968 %{ 5969 single_instruction; 5970 cr : S1(read); 5971 src1 : S1(read); 5972 src2 : S1(read); 5973 dst : S3(write); 5974 INS01 : ISS; 5975 NEON_FP : S3; 5976 %} 5977 5978 pipe_class fp_imm_s(vRegF dst) 5979 %{ 5980 single_instruction; 5981 dst : S3(write); 5982 INS01 : ISS; 5983 NEON_FP : S3; 5984 %} 5985 5986 pipe_class fp_imm_d(vRegD dst) 5987 %{ 5988 single_instruction; 5989 dst : S3(write); 5990 INS01 : ISS; 5991 NEON_FP : S3; 5992 %} 5993 5994 pipe_class fp_load_constant_s(vRegF dst) 5995 %{ 5996 single_instruction; 5997 dst : S4(write); 5998 INS01 : ISS; 5999 NEON_FP : S4; 6000 %} 6001 6002 pipe_class fp_load_constant_d(vRegD dst) 6003 %{ 6004 single_instruction; 6005 dst : S4(write); 6006 INS01 : ISS; 6007 NEON_FP : S4; 6008 %} 6009 6010 //------- Integer ALU operations -------------------------- 6011 6012 // Integer ALU reg-reg operation 6013 // Operands needed in EX1, result generated in EX2 6014 // Eg. ADD x0, x1, x2 6015 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6016 %{ 6017 single_instruction; 6018 dst : EX2(write); 6019 src1 : EX1(read); 6020 src2 : EX1(read); 6021 INS01 : ISS; // Dual issue as instruction 0 or 1 6022 ALU : EX2; 6023 %} 6024 6025 // Integer ALU reg-reg operation with constant shift 6026 // Shifted register must be available in LATE_ISS instead of EX1 6027 // Eg. ADD x0, x1, x2, LSL #2 6028 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6029 %{ 6030 single_instruction; 6031 dst : EX2(write); 6032 src1 : EX1(read); 6033 src2 : ISS(read); 6034 INS01 : ISS; 6035 ALU : EX2; 6036 %} 6037 6038 // Integer ALU reg operation with constant shift 6039 // Eg. LSL x0, x1, #shift 6040 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6041 %{ 6042 single_instruction; 6043 dst : EX2(write); 6044 src1 : ISS(read); 6045 INS01 : ISS; 6046 ALU : EX2; 6047 %} 6048 6049 // Integer ALU reg-reg operation with variable shift 6050 // Both operands must be available in LATE_ISS instead of EX1 6051 // Result is available in EX1 instead of EX2 6052 // Eg. LSLV x0, x1, x2 6053 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6054 %{ 6055 single_instruction; 6056 dst : EX1(write); 6057 src1 : ISS(read); 6058 src2 : ISS(read); 6059 INS01 : ISS; 6060 ALU : EX1; 6061 %} 6062 6063 // Integer ALU reg-reg operation with extract 6064 // As for _vshift above, but result generated in EX2 6065 // Eg. EXTR x0, x1, x2, #N 6066 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6067 %{ 6068 single_instruction; 6069 dst : EX2(write); 6070 src1 : ISS(read); 6071 src2 : ISS(read); 6072 INS1 : ISS; // Can only dual issue as Instruction 1 6073 ALU : EX1; 6074 %} 6075 6076 // Integer ALU reg operation 6077 // Eg. NEG x0, x1 6078 pipe_class ialu_reg(iRegI dst, iRegI src) 6079 %{ 6080 single_instruction; 6081 dst : EX2(write); 6082 src : EX1(read); 6083 INS01 : ISS; 6084 ALU : EX2; 6085 %} 6086 6087 // Integer ALU reg mmediate operation 6088 // Eg. ADD x0, x1, #N 6089 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6090 %{ 6091 single_instruction; 6092 dst : EX2(write); 6093 src1 : EX1(read); 6094 INS01 : ISS; 6095 ALU : EX2; 6096 %} 6097 6098 // Integer ALU immediate operation (no source operands) 6099 // Eg. MOV x0, #N 6100 pipe_class ialu_imm(iRegI dst) 6101 %{ 6102 single_instruction; 6103 dst : EX1(write); 6104 INS01 : ISS; 6105 ALU : EX1; 6106 %} 6107 6108 //------- Compare operation ------------------------------- 6109 6110 // Compare reg-reg 6111 // Eg. CMP x0, x1 6112 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6113 %{ 6114 single_instruction; 6115 // fixed_latency(16); 6116 cr : EX2(write); 6117 op1 : EX1(read); 6118 op2 : EX1(read); 6119 INS01 : ISS; 6120 ALU : EX2; 6121 %} 6122 6123 // Compare reg-reg 6124 // Eg. CMP x0, #N 6125 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6126 %{ 6127 single_instruction; 6128 // fixed_latency(16); 6129 cr : EX2(write); 6130 op1 : EX1(read); 6131 INS01 : ISS; 6132 ALU : EX2; 6133 %} 6134 6135 //------- Conditional instructions ------------------------ 6136 6137 // Conditional no operands 6138 // Eg. CSINC x0, zr, zr, <cond> 6139 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6140 %{ 6141 single_instruction; 6142 cr : EX1(read); 6143 dst : EX2(write); 6144 INS01 : ISS; 6145 ALU : EX2; 6146 %} 6147 6148 // Conditional 2 operand 6149 // EG. CSEL X0, X1, X2, <cond> 6150 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6151 %{ 6152 single_instruction; 6153 cr : EX1(read); 6154 src1 : EX1(read); 6155 src2 : EX1(read); 6156 dst : EX2(write); 6157 INS01 : ISS; 6158 ALU : EX2; 6159 %} 6160 6161 // Conditional 2 operand 6162 // EG. CSEL X0, X1, X2, <cond> 6163 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6164 %{ 6165 single_instruction; 6166 cr : EX1(read); 6167 src : EX1(read); 6168 dst : EX2(write); 6169 INS01 : ISS; 6170 ALU : EX2; 6171 %} 6172 6173 //------- Multiply pipeline operations -------------------- 6174 6175 // Multiply reg-reg 6176 // Eg. MUL w0, w1, w2 6177 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6178 %{ 6179 single_instruction; 6180 dst : WR(write); 6181 src1 : ISS(read); 6182 src2 : ISS(read); 6183 INS01 : ISS; 6184 MAC : WR; 6185 %} 6186 6187 // Multiply accumulate 6188 // Eg. MADD w0, w1, w2, w3 6189 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6190 %{ 6191 single_instruction; 6192 dst : WR(write); 6193 src1 : ISS(read); 6194 src2 : ISS(read); 6195 src3 : ISS(read); 6196 INS01 : ISS; 6197 MAC : WR; 6198 %} 6199 6200 // Eg. MUL w0, w1, w2 6201 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6202 %{ 6203 single_instruction; 6204 fixed_latency(3); // Maximum latency for 64 bit mul 6205 dst : WR(write); 6206 src1 : ISS(read); 6207 src2 : ISS(read); 6208 INS01 : ISS; 6209 MAC : WR; 6210 %} 6211 6212 // Multiply accumulate 6213 // Eg. MADD w0, w1, w2, w3 6214 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6215 %{ 6216 single_instruction; 6217 fixed_latency(3); // Maximum latency for 64 bit mul 6218 dst : WR(write); 6219 src1 : ISS(read); 6220 src2 : ISS(read); 6221 src3 : ISS(read); 6222 INS01 : ISS; 6223 MAC : WR; 6224 %} 6225 6226 //------- Divide pipeline operations -------------------- 6227 6228 // Eg. SDIV w0, w1, w2 6229 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6230 %{ 6231 single_instruction; 6232 fixed_latency(8); // Maximum latency for 32 bit divide 6233 dst : WR(write); 6234 src1 : ISS(read); 6235 src2 : ISS(read); 6236 INS0 : ISS; // Can only dual issue as instruction 0 6237 DIV : WR; 6238 %} 6239 6240 // Eg. SDIV x0, x1, x2 6241 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6242 %{ 6243 single_instruction; 6244 fixed_latency(16); // Maximum latency for 64 bit divide 6245 dst : WR(write); 6246 src1 : ISS(read); 6247 src2 : ISS(read); 6248 INS0 : ISS; // Can only dual issue as instruction 0 6249 DIV : WR; 6250 %} 6251 6252 //------- Load pipeline operations ------------------------ 6253 6254 // Load - prefetch 6255 // Eg. PFRM <mem> 6256 pipe_class iload_prefetch(memory mem) 6257 %{ 6258 single_instruction; 6259 mem : ISS(read); 6260 INS01 : ISS; 6261 LDST : WR; 6262 %} 6263 6264 // Load - reg, mem 6265 // Eg. LDR x0, <mem> 6266 pipe_class iload_reg_mem(iRegI dst, memory mem) 6267 %{ 6268 single_instruction; 6269 dst : WR(write); 6270 mem : ISS(read); 6271 INS01 : ISS; 6272 LDST : WR; 6273 %} 6274 6275 // Load - reg, reg 6276 // Eg. LDR x0, [sp, x1] 6277 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6278 %{ 6279 single_instruction; 6280 dst : WR(write); 6281 src : ISS(read); 6282 INS01 : ISS; 6283 LDST : WR; 6284 %} 6285 6286 //------- Store pipeline operations ----------------------- 6287 6288 // Store - zr, mem 6289 // Eg. STR zr, <mem> 6290 pipe_class istore_mem(memory mem) 6291 %{ 6292 single_instruction; 6293 mem : ISS(read); 6294 INS01 : ISS; 6295 LDST : WR; 6296 %} 6297 6298 // Store - reg, mem 6299 // Eg. STR x0, <mem> 6300 pipe_class istore_reg_mem(iRegI src, memory mem) 6301 %{ 6302 single_instruction; 6303 mem : ISS(read); 6304 src : EX2(read); 6305 INS01 : ISS; 6306 LDST : WR; 6307 %} 6308 6309 // Store - reg, reg 6310 // Eg. STR x0, [sp, x1] 6311 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6312 %{ 6313 single_instruction; 6314 dst : ISS(read); 6315 src : EX2(read); 6316 INS01 : ISS; 6317 LDST : WR; 6318 %} 6319 6320 //------- Store pipeline operations ----------------------- 6321 6322 // Branch 6323 pipe_class pipe_branch() 6324 %{ 6325 single_instruction; 6326 INS01 : ISS; 6327 BRANCH : EX1; 6328 %} 6329 6330 // Conditional branch 6331 pipe_class pipe_branch_cond(rFlagsReg cr) 6332 %{ 6333 single_instruction; 6334 cr : EX1(read); 6335 INS01 : ISS; 6336 BRANCH : EX1; 6337 %} 6338 6339 // Compare & Branch 6340 // EG. CBZ/CBNZ 6341 pipe_class pipe_cmp_branch(iRegI op1) 6342 %{ 6343 single_instruction; 6344 op1 : EX1(read); 6345 INS01 : ISS; 6346 BRANCH : EX1; 6347 %} 6348 6349 //------- Synchronisation operations ---------------------- 6350 6351 // Any operation requiring serialization. 6352 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6353 pipe_class pipe_serial() 6354 %{ 6355 single_instruction; 6356 force_serialization; 6357 fixed_latency(16); 6358 INS01 : ISS(2); // Cannot dual issue with any other instruction 6359 LDST : WR; 6360 %} 6361 6362 // Generic big/slow expanded idiom - also serialized 6363 pipe_class pipe_slow() 6364 %{ 6365 instruction_count(10); 6366 multiple_bundles; 6367 force_serialization; 6368 fixed_latency(16); 6369 INS01 : ISS(2); // Cannot dual issue with any other instruction 6370 LDST : WR; 6371 %} 6372 6373 // Empty pipeline class 6374 pipe_class pipe_class_empty() 6375 %{ 6376 single_instruction; 6377 fixed_latency(0); 6378 %} 6379 6380 // Default pipeline class. 6381 pipe_class pipe_class_default() 6382 %{ 6383 single_instruction; 6384 fixed_latency(2); 6385 %} 6386 6387 // Pipeline class for compares. 6388 pipe_class pipe_class_compare() 6389 %{ 6390 single_instruction; 6391 fixed_latency(16); 6392 %} 6393 6394 // Pipeline class for memory operations. 6395 pipe_class pipe_class_memory() 6396 %{ 6397 single_instruction; 6398 fixed_latency(16); 6399 %} 6400 6401 // Pipeline class for call. 6402 pipe_class pipe_class_call() 6403 %{ 6404 single_instruction; 6405 fixed_latency(100); 6406 %} 6407 6408 // Define the class for the Nop node. 6409 define %{ 6410 MachNop = pipe_class_empty; 6411 %} 6412 6413 %} 6414 //----------INSTRUCTIONS------------------------------------------------------- 6415 // 6416 // match -- States which machine-independent subtree may be replaced 6417 // by this instruction. 6418 // ins_cost -- The estimated cost of this instruction is used by instruction 6419 // selection to identify a minimum cost tree of machine 6420 // instructions that matches a tree of machine-independent 6421 // instructions. 6422 // format -- A string providing the disassembly for this instruction. 6423 // The value of an instruction's operand may be inserted 6424 // by referring to it with a '$' prefix. 6425 // opcode -- Three instruction opcodes may be provided. These are referred 6426 // to within an encode class as $primary, $secondary, and $tertiary 6427 // rrspectively. The primary opcode is commonly used to 6428 // indicate the type of machine instruction, while secondary 6429 // and tertiary are often used for prefix options or addressing 6430 // modes. 6431 // ins_encode -- A list of encode classes with parameters. The encode class 6432 // name must have been defined in an 'enc_class' specification 6433 // in the encode section of the architecture description. 6434 6435 // ============================================================================ 6436 // Memory (Load/Store) Instructions 6437 6438 // Load Instructions 6439 6440 // Load Byte (8 bit signed) 6441 instruct loadB(iRegINoSp dst, memory1 mem) 6442 %{ 6443 match(Set dst (LoadB mem)); 6444 predicate(!needs_acquiring_load(n)); 6445 6446 ins_cost(4 * INSN_COST); 6447 format %{ "ldrsbw $dst, $mem\t# byte" %} 6448 6449 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6450 6451 ins_pipe(iload_reg_mem); 6452 %} 6453 6454 // Load Byte (8 bit signed) into long 6455 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6456 %{ 6457 match(Set dst (ConvI2L (LoadB mem))); 6458 predicate(!needs_acquiring_load(n->in(1))); 6459 6460 ins_cost(4 * INSN_COST); 6461 format %{ "ldrsb $dst, $mem\t# byte" %} 6462 6463 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6464 6465 ins_pipe(iload_reg_mem); 6466 %} 6467 6468 // Load Byte (8 bit unsigned) 6469 instruct loadUB(iRegINoSp dst, memory1 mem) 6470 %{ 6471 match(Set dst (LoadUB mem)); 6472 predicate(!needs_acquiring_load(n)); 6473 6474 ins_cost(4 * INSN_COST); 6475 format %{ "ldrbw $dst, $mem\t# byte" %} 6476 6477 ins_encode(aarch64_enc_ldrb(dst, mem)); 6478 6479 ins_pipe(iload_reg_mem); 6480 %} 6481 6482 // Load Byte (8 bit unsigned) into long 6483 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6484 %{ 6485 match(Set dst (ConvI2L (LoadUB mem))); 6486 predicate(!needs_acquiring_load(n->in(1))); 6487 6488 ins_cost(4 * INSN_COST); 6489 format %{ "ldrb $dst, $mem\t# byte" %} 6490 6491 ins_encode(aarch64_enc_ldrb(dst, mem)); 6492 6493 ins_pipe(iload_reg_mem); 6494 %} 6495 6496 // Load Short (16 bit signed) 6497 instruct loadS(iRegINoSp dst, memory2 mem) 6498 %{ 6499 match(Set dst (LoadS mem)); 6500 predicate(!needs_acquiring_load(n)); 6501 6502 ins_cost(4 * INSN_COST); 6503 format %{ "ldrshw $dst, $mem\t# short" %} 6504 6505 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6506 6507 ins_pipe(iload_reg_mem); 6508 %} 6509 6510 // Load Short (16 bit signed) into long 6511 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6512 %{ 6513 match(Set dst (ConvI2L (LoadS mem))); 6514 predicate(!needs_acquiring_load(n->in(1))); 6515 6516 ins_cost(4 * INSN_COST); 6517 format %{ "ldrsh $dst, $mem\t# short" %} 6518 6519 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6520 6521 ins_pipe(iload_reg_mem); 6522 %} 6523 6524 // Load Char (16 bit unsigned) 6525 instruct loadUS(iRegINoSp dst, memory2 mem) 6526 %{ 6527 match(Set dst (LoadUS mem)); 6528 predicate(!needs_acquiring_load(n)); 6529 6530 ins_cost(4 * INSN_COST); 6531 format %{ "ldrh $dst, $mem\t# short" %} 6532 6533 ins_encode(aarch64_enc_ldrh(dst, mem)); 6534 6535 ins_pipe(iload_reg_mem); 6536 %} 6537 6538 // Load Short/Char (16 bit unsigned) into long 6539 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6540 %{ 6541 match(Set dst (ConvI2L (LoadUS mem))); 6542 predicate(!needs_acquiring_load(n->in(1))); 6543 6544 ins_cost(4 * INSN_COST); 6545 format %{ "ldrh $dst, $mem\t# short" %} 6546 6547 ins_encode(aarch64_enc_ldrh(dst, mem)); 6548 6549 ins_pipe(iload_reg_mem); 6550 %} 6551 6552 // Load Integer (32 bit signed) 6553 instruct loadI(iRegINoSp dst, memory4 mem) 6554 %{ 6555 match(Set dst (LoadI mem)); 6556 predicate(!needs_acquiring_load(n)); 6557 6558 ins_cost(4 * INSN_COST); 6559 format %{ "ldrw $dst, $mem\t# int" %} 6560 6561 ins_encode(aarch64_enc_ldrw(dst, mem)); 6562 6563 ins_pipe(iload_reg_mem); 6564 %} 6565 6566 // Load Integer (32 bit signed) into long 6567 instruct loadI2L(iRegLNoSp dst, memory4 mem) 6568 %{ 6569 match(Set dst (ConvI2L (LoadI mem))); 6570 predicate(!needs_acquiring_load(n->in(1))); 6571 6572 ins_cost(4 * INSN_COST); 6573 format %{ "ldrsw $dst, $mem\t# int" %} 6574 6575 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6576 6577 ins_pipe(iload_reg_mem); 6578 %} 6579 6580 // Load Integer (32 bit unsigned) into long 6581 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 6582 %{ 6583 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6584 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6585 6586 ins_cost(4 * INSN_COST); 6587 format %{ "ldrw $dst, $mem\t# int" %} 6588 6589 ins_encode(aarch64_enc_ldrw(dst, mem)); 6590 6591 ins_pipe(iload_reg_mem); 6592 %} 6593 6594 // Load Long (64 bit signed) 6595 instruct loadL(iRegLNoSp dst, memory8 mem) 6596 %{ 6597 match(Set dst (LoadL mem)); 6598 predicate(!needs_acquiring_load(n)); 6599 6600 ins_cost(4 * INSN_COST); 6601 format %{ "ldr $dst, $mem\t# int" %} 6602 6603 ins_encode(aarch64_enc_ldr(dst, mem)); 6604 6605 ins_pipe(iload_reg_mem); 6606 %} 6607 6608 // Load Range 6609 instruct loadRange(iRegINoSp dst, memory4 mem) 6610 %{ 6611 match(Set dst (LoadRange mem)); 6612 6613 ins_cost(4 * INSN_COST); 6614 format %{ "ldrw $dst, $mem\t# range" %} 6615 6616 ins_encode(aarch64_enc_ldrw(dst, mem)); 6617 6618 ins_pipe(iload_reg_mem); 6619 %} 6620 6621 // Load Pointer 6622 instruct loadP(iRegPNoSp dst, memory8 mem) 6623 %{ 6624 match(Set dst (LoadP mem)); 6625 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 6626 6627 ins_cost(4 * INSN_COST); 6628 format %{ "ldr $dst, $mem\t# ptr" %} 6629 6630 ins_encode(aarch64_enc_ldr(dst, mem)); 6631 6632 ins_pipe(iload_reg_mem); 6633 %} 6634 6635 // Load Compressed Pointer 6636 instruct loadN(iRegNNoSp dst, memory4 mem) 6637 %{ 6638 match(Set dst (LoadN mem)); 6639 predicate(!needs_acquiring_load(n) && n->as_Load()->barrier_data() == 0); 6640 6641 ins_cost(4 * INSN_COST); 6642 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6643 6644 ins_encode(aarch64_enc_ldrw(dst, mem)); 6645 6646 ins_pipe(iload_reg_mem); 6647 %} 6648 6649 // Load Klass Pointer 6650 instruct loadKlass(iRegPNoSp dst, memory8 mem) 6651 %{ 6652 match(Set dst (LoadKlass mem)); 6653 predicate(!needs_acquiring_load(n)); 6654 6655 ins_cost(4 * INSN_COST); 6656 format %{ "ldr $dst, $mem\t# class" %} 6657 6658 ins_encode(aarch64_enc_ldr(dst, mem)); 6659 6660 ins_pipe(iload_reg_mem); 6661 %} 6662 6663 // Load Narrow Klass Pointer 6664 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 6665 %{ 6666 match(Set dst (LoadNKlass mem)); 6667 predicate(!needs_acquiring_load(n)); 6668 6669 ins_cost(4 * INSN_COST); 6670 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6671 6672 ins_encode(aarch64_enc_ldrw(dst, mem)); 6673 6674 ins_pipe(iload_reg_mem); 6675 %} 6676 6677 // Load Float 6678 instruct loadF(vRegF dst, memory4 mem) 6679 %{ 6680 match(Set dst (LoadF mem)); 6681 predicate(!needs_acquiring_load(n)); 6682 6683 ins_cost(4 * INSN_COST); 6684 format %{ "ldrs $dst, $mem\t# float" %} 6685 6686 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6687 6688 ins_pipe(pipe_class_memory); 6689 %} 6690 6691 // Load Double 6692 instruct loadD(vRegD dst, memory8 mem) 6693 %{ 6694 match(Set dst (LoadD mem)); 6695 predicate(!needs_acquiring_load(n)); 6696 6697 ins_cost(4 * INSN_COST); 6698 format %{ "ldrd $dst, $mem\t# double" %} 6699 6700 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6701 6702 ins_pipe(pipe_class_memory); 6703 %} 6704 6705 6706 // Load Int Constant 6707 instruct loadConI(iRegINoSp dst, immI src) 6708 %{ 6709 match(Set dst src); 6710 6711 ins_cost(INSN_COST); 6712 format %{ "mov $dst, $src\t# int" %} 6713 6714 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6715 6716 ins_pipe(ialu_imm); 6717 %} 6718 6719 // Load Long Constant 6720 instruct loadConL(iRegLNoSp dst, immL src) 6721 %{ 6722 match(Set dst src); 6723 6724 ins_cost(INSN_COST); 6725 format %{ "mov $dst, $src\t# long" %} 6726 6727 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6728 6729 ins_pipe(ialu_imm); 6730 %} 6731 6732 // Load Pointer Constant 6733 6734 instruct loadConP(iRegPNoSp dst, immP con) 6735 %{ 6736 match(Set dst con); 6737 6738 ins_cost(INSN_COST * 4); 6739 format %{ 6740 "mov $dst, $con\t# ptr\n\t" 6741 %} 6742 6743 ins_encode(aarch64_enc_mov_p(dst, con)); 6744 6745 ins_pipe(ialu_imm); 6746 %} 6747 6748 // Load Null Pointer Constant 6749 6750 instruct loadConP0(iRegPNoSp dst, immP0 con) 6751 %{ 6752 match(Set dst con); 6753 6754 ins_cost(INSN_COST); 6755 format %{ "mov $dst, $con\t# nullptr ptr" %} 6756 6757 ins_encode(aarch64_enc_mov_p0(dst, con)); 6758 6759 ins_pipe(ialu_imm); 6760 %} 6761 6762 // Load Pointer Constant One 6763 6764 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6765 %{ 6766 match(Set dst con); 6767 6768 ins_cost(INSN_COST); 6769 format %{ "mov $dst, $con\t# nullptr ptr" %} 6770 6771 ins_encode(aarch64_enc_mov_p1(dst, con)); 6772 6773 ins_pipe(ialu_imm); 6774 %} 6775 6776 // Load Byte Map Base Constant 6777 6778 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6779 %{ 6780 match(Set dst con); 6781 6782 ins_cost(INSN_COST); 6783 format %{ "adr $dst, $con\t# Byte Map Base" %} 6784 6785 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6786 6787 ins_pipe(ialu_imm); 6788 %} 6789 6790 // Load Narrow Pointer Constant 6791 6792 instruct loadConN(iRegNNoSp dst, immN con) 6793 %{ 6794 match(Set dst con); 6795 6796 ins_cost(INSN_COST * 4); 6797 format %{ "mov $dst, $con\t# compressed ptr" %} 6798 6799 ins_encode(aarch64_enc_mov_n(dst, con)); 6800 6801 ins_pipe(ialu_imm); 6802 %} 6803 6804 // Load Narrow Null Pointer Constant 6805 6806 instruct loadConN0(iRegNNoSp dst, immN0 con) 6807 %{ 6808 match(Set dst con); 6809 6810 ins_cost(INSN_COST); 6811 format %{ "mov $dst, $con\t# compressed nullptr ptr" %} 6812 6813 ins_encode(aarch64_enc_mov_n0(dst, con)); 6814 6815 ins_pipe(ialu_imm); 6816 %} 6817 6818 // Load Narrow Klass Constant 6819 6820 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6821 %{ 6822 match(Set dst con); 6823 6824 ins_cost(INSN_COST); 6825 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6826 6827 ins_encode(aarch64_enc_mov_nk(dst, con)); 6828 6829 ins_pipe(ialu_imm); 6830 %} 6831 6832 // Load Packed Float Constant 6833 6834 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6835 match(Set dst con); 6836 ins_cost(INSN_COST * 4); 6837 format %{ "fmovs $dst, $con"%} 6838 ins_encode %{ 6839 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6840 %} 6841 6842 ins_pipe(fp_imm_s); 6843 %} 6844 6845 // Load Float Constant 6846 6847 instruct loadConF(vRegF dst, immF con) %{ 6848 match(Set dst con); 6849 6850 ins_cost(INSN_COST * 4); 6851 6852 format %{ 6853 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6854 %} 6855 6856 ins_encode %{ 6857 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6858 %} 6859 6860 ins_pipe(fp_load_constant_s); 6861 %} 6862 6863 // Load Packed Double Constant 6864 6865 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6866 match(Set dst con); 6867 ins_cost(INSN_COST); 6868 format %{ "fmovd $dst, $con"%} 6869 ins_encode %{ 6870 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6871 %} 6872 6873 ins_pipe(fp_imm_d); 6874 %} 6875 6876 // Load Double Constant 6877 6878 instruct loadConD(vRegD dst, immD con) %{ 6879 match(Set dst con); 6880 6881 ins_cost(INSN_COST * 5); 6882 format %{ 6883 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6884 %} 6885 6886 ins_encode %{ 6887 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6888 %} 6889 6890 ins_pipe(fp_load_constant_d); 6891 %} 6892 6893 // Store Instructions 6894 6895 // Store CMS card-mark Immediate 6896 instruct storeimmCM0(immI0 zero, memory1 mem) 6897 %{ 6898 match(Set mem (StoreCM mem zero)); 6899 6900 ins_cost(INSN_COST); 6901 format %{ "storestore (elided)\n\t" 6902 "strb zr, $mem\t# byte" %} 6903 6904 ins_encode(aarch64_enc_strb0(mem)); 6905 6906 ins_pipe(istore_mem); 6907 %} 6908 6909 // Store CMS card-mark Immediate with intervening StoreStore 6910 // needed when using CMS with no conditional card marking 6911 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 6912 %{ 6913 match(Set mem (StoreCM mem zero)); 6914 6915 ins_cost(INSN_COST * 2); 6916 format %{ "storestore\n\t" 6917 "dmb ishst" 6918 "\n\tstrb zr, $mem\t# byte" %} 6919 6920 ins_encode(aarch64_enc_strb0_ordered(mem)); 6921 6922 ins_pipe(istore_mem); 6923 %} 6924 6925 // Store Byte 6926 instruct storeB(iRegIorL2I src, memory1 mem) 6927 %{ 6928 match(Set mem (StoreB mem src)); 6929 predicate(!needs_releasing_store(n)); 6930 6931 ins_cost(INSN_COST); 6932 format %{ "strb $src, $mem\t# byte" %} 6933 6934 ins_encode(aarch64_enc_strb(src, mem)); 6935 6936 ins_pipe(istore_reg_mem); 6937 %} 6938 6939 6940 instruct storeimmB0(immI0 zero, memory1 mem) 6941 %{ 6942 match(Set mem (StoreB mem zero)); 6943 predicate(!needs_releasing_store(n)); 6944 6945 ins_cost(INSN_COST); 6946 format %{ "strb rscractch2, $mem\t# byte" %} 6947 6948 ins_encode(aarch64_enc_strb0(mem)); 6949 6950 ins_pipe(istore_mem); 6951 %} 6952 6953 // Store Char/Short 6954 instruct storeC(iRegIorL2I src, memory2 mem) 6955 %{ 6956 match(Set mem (StoreC mem src)); 6957 predicate(!needs_releasing_store(n)); 6958 6959 ins_cost(INSN_COST); 6960 format %{ "strh $src, $mem\t# short" %} 6961 6962 ins_encode(aarch64_enc_strh(src, mem)); 6963 6964 ins_pipe(istore_reg_mem); 6965 %} 6966 6967 instruct storeimmC0(immI0 zero, memory2 mem) 6968 %{ 6969 match(Set mem (StoreC mem zero)); 6970 predicate(!needs_releasing_store(n)); 6971 6972 ins_cost(INSN_COST); 6973 format %{ "strh zr, $mem\t# short" %} 6974 6975 ins_encode(aarch64_enc_strh0(mem)); 6976 6977 ins_pipe(istore_mem); 6978 %} 6979 6980 // Store Integer 6981 6982 instruct storeI(iRegIorL2I src, memory4 mem) 6983 %{ 6984 match(Set mem(StoreI mem src)); 6985 predicate(!needs_releasing_store(n)); 6986 6987 ins_cost(INSN_COST); 6988 format %{ "strw $src, $mem\t# int" %} 6989 6990 ins_encode(aarch64_enc_strw(src, mem)); 6991 6992 ins_pipe(istore_reg_mem); 6993 %} 6994 6995 instruct storeimmI0(immI0 zero, memory4 mem) 6996 %{ 6997 match(Set mem(StoreI mem zero)); 6998 predicate(!needs_releasing_store(n)); 6999 7000 ins_cost(INSN_COST); 7001 format %{ "strw zr, $mem\t# int" %} 7002 7003 ins_encode(aarch64_enc_strw0(mem)); 7004 7005 ins_pipe(istore_mem); 7006 %} 7007 7008 // Store Long (64 bit signed) 7009 instruct storeL(iRegL src, memory8 mem) 7010 %{ 7011 match(Set mem (StoreL mem src)); 7012 predicate(!needs_releasing_store(n)); 7013 7014 ins_cost(INSN_COST); 7015 format %{ "str $src, $mem\t# int" %} 7016 7017 ins_encode(aarch64_enc_str(src, mem)); 7018 7019 ins_pipe(istore_reg_mem); 7020 %} 7021 7022 // Store Long (64 bit signed) 7023 instruct storeimmL0(immL0 zero, memory8 mem) 7024 %{ 7025 match(Set mem (StoreL mem zero)); 7026 predicate(!needs_releasing_store(n)); 7027 7028 ins_cost(INSN_COST); 7029 format %{ "str zr, $mem\t# int" %} 7030 7031 ins_encode(aarch64_enc_str0(mem)); 7032 7033 ins_pipe(istore_mem); 7034 %} 7035 7036 // Store Pointer 7037 instruct storeP(iRegP src, memory8 mem) 7038 %{ 7039 match(Set mem (StoreP mem src)); 7040 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7041 7042 ins_cost(INSN_COST); 7043 format %{ "str $src, $mem\t# ptr" %} 7044 7045 ins_encode(aarch64_enc_str(src, mem)); 7046 7047 ins_pipe(istore_reg_mem); 7048 %} 7049 7050 // Store Pointer 7051 instruct storeimmP0(immP0 zero, memory8 mem) 7052 %{ 7053 match(Set mem (StoreP mem zero)); 7054 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7055 7056 ins_cost(INSN_COST); 7057 format %{ "str zr, $mem\t# ptr" %} 7058 7059 ins_encode(aarch64_enc_str0(mem)); 7060 7061 ins_pipe(istore_mem); 7062 %} 7063 7064 // Store Compressed Pointer 7065 instruct storeN(iRegN src, memory4 mem) 7066 %{ 7067 match(Set mem (StoreN mem src)); 7068 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7069 7070 ins_cost(INSN_COST); 7071 format %{ "strw $src, $mem\t# compressed ptr" %} 7072 7073 ins_encode(aarch64_enc_strw(src, mem)); 7074 7075 ins_pipe(istore_reg_mem); 7076 %} 7077 7078 instruct storeImmN0(immN0 zero, memory4 mem) 7079 %{ 7080 match(Set mem (StoreN mem zero)); 7081 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7082 7083 ins_cost(INSN_COST); 7084 format %{ "strw zr, $mem\t# compressed ptr" %} 7085 7086 ins_encode(aarch64_enc_strw0(mem)); 7087 7088 ins_pipe(istore_mem); 7089 %} 7090 7091 // Store Float 7092 instruct storeF(vRegF src, memory4 mem) 7093 %{ 7094 match(Set mem (StoreF mem src)); 7095 predicate(!needs_releasing_store(n)); 7096 7097 ins_cost(INSN_COST); 7098 format %{ "strs $src, $mem\t# float" %} 7099 7100 ins_encode( aarch64_enc_strs(src, mem) ); 7101 7102 ins_pipe(pipe_class_memory); 7103 %} 7104 7105 // TODO 7106 // implement storeImmF0 and storeFImmPacked 7107 7108 // Store Double 7109 instruct storeD(vRegD src, memory8 mem) 7110 %{ 7111 match(Set mem (StoreD mem src)); 7112 predicate(!needs_releasing_store(n)); 7113 7114 ins_cost(INSN_COST); 7115 format %{ "strd $src, $mem\t# double" %} 7116 7117 ins_encode( aarch64_enc_strd(src, mem) ); 7118 7119 ins_pipe(pipe_class_memory); 7120 %} 7121 7122 // Store Compressed Klass Pointer 7123 instruct storeNKlass(iRegN src, memory4 mem) 7124 %{ 7125 predicate(!needs_releasing_store(n)); 7126 match(Set mem (StoreNKlass mem src)); 7127 7128 ins_cost(INSN_COST); 7129 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7130 7131 ins_encode(aarch64_enc_strw(src, mem)); 7132 7133 ins_pipe(istore_reg_mem); 7134 %} 7135 7136 // TODO 7137 // implement storeImmD0 and storeDImmPacked 7138 7139 // prefetch instructions 7140 // Must be safe to execute with invalid address (cannot fault). 7141 7142 instruct prefetchalloc( memory8 mem ) %{ 7143 match(PrefetchAllocation mem); 7144 7145 ins_cost(INSN_COST); 7146 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7147 7148 ins_encode( aarch64_enc_prefetchw(mem) ); 7149 7150 ins_pipe(iload_prefetch); 7151 %} 7152 7153 // ---------------- volatile loads and stores ---------------- 7154 7155 // Load Byte (8 bit signed) 7156 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7157 %{ 7158 match(Set dst (LoadB mem)); 7159 7160 ins_cost(VOLATILE_REF_COST); 7161 format %{ "ldarsb $dst, $mem\t# byte" %} 7162 7163 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7164 7165 ins_pipe(pipe_serial); 7166 %} 7167 7168 // Load Byte (8 bit signed) into long 7169 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7170 %{ 7171 match(Set dst (ConvI2L (LoadB mem))); 7172 7173 ins_cost(VOLATILE_REF_COST); 7174 format %{ "ldarsb $dst, $mem\t# byte" %} 7175 7176 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7177 7178 ins_pipe(pipe_serial); 7179 %} 7180 7181 // Load Byte (8 bit unsigned) 7182 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7183 %{ 7184 match(Set dst (LoadUB mem)); 7185 7186 ins_cost(VOLATILE_REF_COST); 7187 format %{ "ldarb $dst, $mem\t# byte" %} 7188 7189 ins_encode(aarch64_enc_ldarb(dst, mem)); 7190 7191 ins_pipe(pipe_serial); 7192 %} 7193 7194 // Load Byte (8 bit unsigned) into long 7195 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7196 %{ 7197 match(Set dst (ConvI2L (LoadUB mem))); 7198 7199 ins_cost(VOLATILE_REF_COST); 7200 format %{ "ldarb $dst, $mem\t# byte" %} 7201 7202 ins_encode(aarch64_enc_ldarb(dst, mem)); 7203 7204 ins_pipe(pipe_serial); 7205 %} 7206 7207 // Load Short (16 bit signed) 7208 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7209 %{ 7210 match(Set dst (LoadS mem)); 7211 7212 ins_cost(VOLATILE_REF_COST); 7213 format %{ "ldarshw $dst, $mem\t# short" %} 7214 7215 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7216 7217 ins_pipe(pipe_serial); 7218 %} 7219 7220 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7221 %{ 7222 match(Set dst (LoadUS mem)); 7223 7224 ins_cost(VOLATILE_REF_COST); 7225 format %{ "ldarhw $dst, $mem\t# short" %} 7226 7227 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7228 7229 ins_pipe(pipe_serial); 7230 %} 7231 7232 // Load Short/Char (16 bit unsigned) into long 7233 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7234 %{ 7235 match(Set dst (ConvI2L (LoadUS mem))); 7236 7237 ins_cost(VOLATILE_REF_COST); 7238 format %{ "ldarh $dst, $mem\t# short" %} 7239 7240 ins_encode(aarch64_enc_ldarh(dst, mem)); 7241 7242 ins_pipe(pipe_serial); 7243 %} 7244 7245 // Load Short/Char (16 bit signed) into long 7246 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7247 %{ 7248 match(Set dst (ConvI2L (LoadS mem))); 7249 7250 ins_cost(VOLATILE_REF_COST); 7251 format %{ "ldarh $dst, $mem\t# short" %} 7252 7253 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7254 7255 ins_pipe(pipe_serial); 7256 %} 7257 7258 // Load Integer (32 bit signed) 7259 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7260 %{ 7261 match(Set dst (LoadI mem)); 7262 7263 ins_cost(VOLATILE_REF_COST); 7264 format %{ "ldarw $dst, $mem\t# int" %} 7265 7266 ins_encode(aarch64_enc_ldarw(dst, mem)); 7267 7268 ins_pipe(pipe_serial); 7269 %} 7270 7271 // Load Integer (32 bit unsigned) into long 7272 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7273 %{ 7274 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7275 7276 ins_cost(VOLATILE_REF_COST); 7277 format %{ "ldarw $dst, $mem\t# int" %} 7278 7279 ins_encode(aarch64_enc_ldarw(dst, mem)); 7280 7281 ins_pipe(pipe_serial); 7282 %} 7283 7284 // Load Long (64 bit signed) 7285 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7286 %{ 7287 match(Set dst (LoadL mem)); 7288 7289 ins_cost(VOLATILE_REF_COST); 7290 format %{ "ldar $dst, $mem\t# int" %} 7291 7292 ins_encode(aarch64_enc_ldar(dst, mem)); 7293 7294 ins_pipe(pipe_serial); 7295 %} 7296 7297 // Load Pointer 7298 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7299 %{ 7300 match(Set dst (LoadP mem)); 7301 predicate(n->as_Load()->barrier_data() == 0); 7302 7303 ins_cost(VOLATILE_REF_COST); 7304 format %{ "ldar $dst, $mem\t# ptr" %} 7305 7306 ins_encode(aarch64_enc_ldar(dst, mem)); 7307 7308 ins_pipe(pipe_serial); 7309 %} 7310 7311 // Load Compressed Pointer 7312 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7313 %{ 7314 match(Set dst (LoadN mem)); 7315 predicate(n->as_Load()->barrier_data() == 0); 7316 7317 ins_cost(VOLATILE_REF_COST); 7318 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7319 7320 ins_encode(aarch64_enc_ldarw(dst, mem)); 7321 7322 ins_pipe(pipe_serial); 7323 %} 7324 7325 // Load Float 7326 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7327 %{ 7328 match(Set dst (LoadF mem)); 7329 7330 ins_cost(VOLATILE_REF_COST); 7331 format %{ "ldars $dst, $mem\t# float" %} 7332 7333 ins_encode( aarch64_enc_fldars(dst, mem) ); 7334 7335 ins_pipe(pipe_serial); 7336 %} 7337 7338 // Load Double 7339 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7340 %{ 7341 match(Set dst (LoadD mem)); 7342 7343 ins_cost(VOLATILE_REF_COST); 7344 format %{ "ldard $dst, $mem\t# double" %} 7345 7346 ins_encode( aarch64_enc_fldard(dst, mem) ); 7347 7348 ins_pipe(pipe_serial); 7349 %} 7350 7351 // Store Byte 7352 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7353 %{ 7354 match(Set mem (StoreB mem src)); 7355 7356 ins_cost(VOLATILE_REF_COST); 7357 format %{ "stlrb $src, $mem\t# byte" %} 7358 7359 ins_encode(aarch64_enc_stlrb(src, mem)); 7360 7361 ins_pipe(pipe_class_memory); 7362 %} 7363 7364 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7365 %{ 7366 match(Set mem (StoreB mem zero)); 7367 7368 ins_cost(VOLATILE_REF_COST); 7369 format %{ "stlrb zr, $mem\t# byte" %} 7370 7371 ins_encode(aarch64_enc_stlrb0(mem)); 7372 7373 ins_pipe(pipe_class_memory); 7374 %} 7375 7376 // Store Char/Short 7377 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7378 %{ 7379 match(Set mem (StoreC mem src)); 7380 7381 ins_cost(VOLATILE_REF_COST); 7382 format %{ "stlrh $src, $mem\t# short" %} 7383 7384 ins_encode(aarch64_enc_stlrh(src, mem)); 7385 7386 ins_pipe(pipe_class_memory); 7387 %} 7388 7389 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7390 %{ 7391 match(Set mem (StoreC mem zero)); 7392 7393 ins_cost(VOLATILE_REF_COST); 7394 format %{ "stlrh zr, $mem\t# short" %} 7395 7396 ins_encode(aarch64_enc_stlrh0(mem)); 7397 7398 ins_pipe(pipe_class_memory); 7399 %} 7400 7401 // Store Integer 7402 7403 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7404 %{ 7405 match(Set mem(StoreI mem src)); 7406 7407 ins_cost(VOLATILE_REF_COST); 7408 format %{ "stlrw $src, $mem\t# int" %} 7409 7410 ins_encode(aarch64_enc_stlrw(src, mem)); 7411 7412 ins_pipe(pipe_class_memory); 7413 %} 7414 7415 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7416 %{ 7417 match(Set mem(StoreI mem zero)); 7418 7419 ins_cost(VOLATILE_REF_COST); 7420 format %{ "stlrw zr, $mem\t# int" %} 7421 7422 ins_encode(aarch64_enc_stlrw0(mem)); 7423 7424 ins_pipe(pipe_class_memory); 7425 %} 7426 7427 // Store Long (64 bit signed) 7428 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7429 %{ 7430 match(Set mem (StoreL mem src)); 7431 7432 ins_cost(VOLATILE_REF_COST); 7433 format %{ "stlr $src, $mem\t# int" %} 7434 7435 ins_encode(aarch64_enc_stlr(src, mem)); 7436 7437 ins_pipe(pipe_class_memory); 7438 %} 7439 7440 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem) 7441 %{ 7442 match(Set mem (StoreL mem zero)); 7443 7444 ins_cost(VOLATILE_REF_COST); 7445 format %{ "stlr zr, $mem\t# int" %} 7446 7447 ins_encode(aarch64_enc_stlr0(mem)); 7448 7449 ins_pipe(pipe_class_memory); 7450 %} 7451 7452 // Store Pointer 7453 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7454 %{ 7455 match(Set mem (StoreP mem src)); 7456 predicate(n->as_Store()->barrier_data() == 0); 7457 7458 ins_cost(VOLATILE_REF_COST); 7459 format %{ "stlr $src, $mem\t# ptr" %} 7460 7461 ins_encode(aarch64_enc_stlr(src, mem)); 7462 7463 ins_pipe(pipe_class_memory); 7464 %} 7465 7466 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem) 7467 %{ 7468 match(Set mem (StoreP mem zero)); 7469 predicate(n->as_Store()->barrier_data() == 0); 7470 7471 ins_cost(VOLATILE_REF_COST); 7472 format %{ "stlr zr, $mem\t# ptr" %} 7473 7474 ins_encode(aarch64_enc_stlr0(mem)); 7475 7476 ins_pipe(pipe_class_memory); 7477 %} 7478 7479 // Store Compressed Pointer 7480 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7481 %{ 7482 match(Set mem (StoreN mem src)); 7483 predicate(n->as_Store()->barrier_data() == 0); 7484 7485 ins_cost(VOLATILE_REF_COST); 7486 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7487 7488 ins_encode(aarch64_enc_stlrw(src, mem)); 7489 7490 ins_pipe(pipe_class_memory); 7491 %} 7492 7493 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem) 7494 %{ 7495 match(Set mem (StoreN mem zero)); 7496 predicate(n->as_Store()->barrier_data() == 0); 7497 7498 ins_cost(VOLATILE_REF_COST); 7499 format %{ "stlrw zr, $mem\t# compressed ptr" %} 7500 7501 ins_encode(aarch64_enc_stlrw0(mem)); 7502 7503 ins_pipe(pipe_class_memory); 7504 %} 7505 7506 // Store Float 7507 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7508 %{ 7509 match(Set mem (StoreF mem src)); 7510 7511 ins_cost(VOLATILE_REF_COST); 7512 format %{ "stlrs $src, $mem\t# float" %} 7513 7514 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7515 7516 ins_pipe(pipe_class_memory); 7517 %} 7518 7519 // TODO 7520 // implement storeImmF0 and storeFImmPacked 7521 7522 // Store Double 7523 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7524 %{ 7525 match(Set mem (StoreD mem src)); 7526 7527 ins_cost(VOLATILE_REF_COST); 7528 format %{ "stlrd $src, $mem\t# double" %} 7529 7530 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7531 7532 ins_pipe(pipe_class_memory); 7533 %} 7534 7535 // ---------------- end of volatile loads and stores ---------------- 7536 7537 instruct cacheWB(indirect addr) 7538 %{ 7539 predicate(VM_Version::supports_data_cache_line_flush()); 7540 match(CacheWB addr); 7541 7542 ins_cost(100); 7543 format %{"cache wb $addr" %} 7544 ins_encode %{ 7545 assert($addr->index_position() < 0, "should be"); 7546 assert($addr$$disp == 0, "should be"); 7547 __ cache_wb(Address($addr$$base$$Register, 0)); 7548 %} 7549 ins_pipe(pipe_slow); // XXX 7550 %} 7551 7552 instruct cacheWBPreSync() 7553 %{ 7554 predicate(VM_Version::supports_data_cache_line_flush()); 7555 match(CacheWBPreSync); 7556 7557 ins_cost(100); 7558 format %{"cache wb presync" %} 7559 ins_encode %{ 7560 __ cache_wbsync(true); 7561 %} 7562 ins_pipe(pipe_slow); // XXX 7563 %} 7564 7565 instruct cacheWBPostSync() 7566 %{ 7567 predicate(VM_Version::supports_data_cache_line_flush()); 7568 match(CacheWBPostSync); 7569 7570 ins_cost(100); 7571 format %{"cache wb postsync" %} 7572 ins_encode %{ 7573 __ cache_wbsync(false); 7574 %} 7575 ins_pipe(pipe_slow); // XXX 7576 %} 7577 7578 // ============================================================================ 7579 // BSWAP Instructions 7580 7581 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7582 match(Set dst (ReverseBytesI src)); 7583 7584 ins_cost(INSN_COST); 7585 format %{ "revw $dst, $src" %} 7586 7587 ins_encode %{ 7588 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7589 %} 7590 7591 ins_pipe(ialu_reg); 7592 %} 7593 7594 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7595 match(Set dst (ReverseBytesL src)); 7596 7597 ins_cost(INSN_COST); 7598 format %{ "rev $dst, $src" %} 7599 7600 ins_encode %{ 7601 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7602 %} 7603 7604 ins_pipe(ialu_reg); 7605 %} 7606 7607 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7608 match(Set dst (ReverseBytesUS src)); 7609 7610 ins_cost(INSN_COST); 7611 format %{ "rev16w $dst, $src" %} 7612 7613 ins_encode %{ 7614 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7615 %} 7616 7617 ins_pipe(ialu_reg); 7618 %} 7619 7620 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7621 match(Set dst (ReverseBytesS src)); 7622 7623 ins_cost(INSN_COST); 7624 format %{ "rev16w $dst, $src\n\t" 7625 "sbfmw $dst, $dst, #0, #15" %} 7626 7627 ins_encode %{ 7628 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7629 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7630 %} 7631 7632 ins_pipe(ialu_reg); 7633 %} 7634 7635 // ============================================================================ 7636 // Zero Count Instructions 7637 7638 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7639 match(Set dst (CountLeadingZerosI src)); 7640 7641 ins_cost(INSN_COST); 7642 format %{ "clzw $dst, $src" %} 7643 ins_encode %{ 7644 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7645 %} 7646 7647 ins_pipe(ialu_reg); 7648 %} 7649 7650 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7651 match(Set dst (CountLeadingZerosL src)); 7652 7653 ins_cost(INSN_COST); 7654 format %{ "clz $dst, $src" %} 7655 ins_encode %{ 7656 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7657 %} 7658 7659 ins_pipe(ialu_reg); 7660 %} 7661 7662 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7663 match(Set dst (CountTrailingZerosI src)); 7664 7665 ins_cost(INSN_COST * 2); 7666 format %{ "rbitw $dst, $src\n\t" 7667 "clzw $dst, $dst" %} 7668 ins_encode %{ 7669 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7670 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7671 %} 7672 7673 ins_pipe(ialu_reg); 7674 %} 7675 7676 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7677 match(Set dst (CountTrailingZerosL src)); 7678 7679 ins_cost(INSN_COST * 2); 7680 format %{ "rbit $dst, $src\n\t" 7681 "clz $dst, $dst" %} 7682 ins_encode %{ 7683 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7684 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7685 %} 7686 7687 ins_pipe(ialu_reg); 7688 %} 7689 7690 //---------- Population Count Instructions ------------------------------------- 7691 // 7692 7693 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7694 match(Set dst (PopCountI src)); 7695 effect(TEMP tmp); 7696 ins_cost(INSN_COST * 13); 7697 7698 format %{ "movw $src, $src\n\t" 7699 "mov $tmp, $src\t# vector (1D)\n\t" 7700 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7701 "addv $tmp, $tmp\t# vector (8B)\n\t" 7702 "mov $dst, $tmp\t# vector (1D)" %} 7703 ins_encode %{ 7704 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7705 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 7706 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7707 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7708 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 7709 %} 7710 7711 ins_pipe(pipe_class_default); 7712 %} 7713 7714 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 7715 match(Set dst (PopCountI (LoadI mem))); 7716 effect(TEMP tmp); 7717 ins_cost(INSN_COST * 13); 7718 7719 format %{ "ldrs $tmp, $mem\n\t" 7720 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7721 "addv $tmp, $tmp\t# vector (8B)\n\t" 7722 "mov $dst, $tmp\t# vector (1D)" %} 7723 ins_encode %{ 7724 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7725 loadStore(masm, &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7726 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 7727 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7728 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7729 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 7730 %} 7731 7732 ins_pipe(pipe_class_default); 7733 %} 7734 7735 // Note: Long.bitCount(long) returns an int. 7736 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7737 match(Set dst (PopCountL src)); 7738 effect(TEMP tmp); 7739 ins_cost(INSN_COST * 13); 7740 7741 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7742 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7743 "addv $tmp, $tmp\t# vector (8B)\n\t" 7744 "mov $dst, $tmp\t# vector (1D)" %} 7745 ins_encode %{ 7746 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 7747 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7748 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7749 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 7750 %} 7751 7752 ins_pipe(pipe_class_default); 7753 %} 7754 7755 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 7756 match(Set dst (PopCountL (LoadL mem))); 7757 effect(TEMP tmp); 7758 ins_cost(INSN_COST * 13); 7759 7760 format %{ "ldrd $tmp, $mem\n\t" 7761 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7762 "addv $tmp, $tmp\t# vector (8B)\n\t" 7763 "mov $dst, $tmp\t# vector (1D)" %} 7764 ins_encode %{ 7765 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7766 loadStore(masm, &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7767 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 7768 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7769 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7770 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 7771 %} 7772 7773 ins_pipe(pipe_class_default); 7774 %} 7775 7776 // ============================================================================ 7777 // VerifyVectorAlignment Instruction 7778 7779 instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{ 7780 match(Set addr (VerifyVectorAlignment addr mask)); 7781 effect(KILL cr); 7782 format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %} 7783 ins_encode %{ 7784 Label Lskip; 7785 // check if masked bits of addr are zero 7786 __ tst($addr$$Register, $mask$$constant); 7787 __ br(Assembler::EQ, Lskip); 7788 __ stop("verify_vector_alignment found a misaligned vector memory access"); 7789 __ bind(Lskip); 7790 %} 7791 ins_pipe(pipe_slow); 7792 %} 7793 7794 // ============================================================================ 7795 // MemBar Instruction 7796 7797 instruct load_fence() %{ 7798 match(LoadFence); 7799 ins_cost(VOLATILE_REF_COST); 7800 7801 format %{ "load_fence" %} 7802 7803 ins_encode %{ 7804 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7805 %} 7806 ins_pipe(pipe_serial); 7807 %} 7808 7809 instruct unnecessary_membar_acquire() %{ 7810 predicate(unnecessary_acquire(n)); 7811 match(MemBarAcquire); 7812 ins_cost(0); 7813 7814 format %{ "membar_acquire (elided)" %} 7815 7816 ins_encode %{ 7817 __ block_comment("membar_acquire (elided)"); 7818 %} 7819 7820 ins_pipe(pipe_class_empty); 7821 %} 7822 7823 instruct membar_acquire() %{ 7824 match(MemBarAcquire); 7825 ins_cost(VOLATILE_REF_COST); 7826 7827 format %{ "membar_acquire\n\t" 7828 "dmb ishld" %} 7829 7830 ins_encode %{ 7831 __ block_comment("membar_acquire"); 7832 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7833 %} 7834 7835 ins_pipe(pipe_serial); 7836 %} 7837 7838 7839 instruct membar_acquire_lock() %{ 7840 match(MemBarAcquireLock); 7841 ins_cost(VOLATILE_REF_COST); 7842 7843 format %{ "membar_acquire_lock (elided)" %} 7844 7845 ins_encode %{ 7846 __ block_comment("membar_acquire_lock (elided)"); 7847 %} 7848 7849 ins_pipe(pipe_serial); 7850 %} 7851 7852 instruct store_fence() %{ 7853 match(StoreFence); 7854 ins_cost(VOLATILE_REF_COST); 7855 7856 format %{ "store_fence" %} 7857 7858 ins_encode %{ 7859 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7860 %} 7861 ins_pipe(pipe_serial); 7862 %} 7863 7864 instruct unnecessary_membar_release() %{ 7865 predicate(unnecessary_release(n)); 7866 match(MemBarRelease); 7867 ins_cost(0); 7868 7869 format %{ "membar_release (elided)" %} 7870 7871 ins_encode %{ 7872 __ block_comment("membar_release (elided)"); 7873 %} 7874 ins_pipe(pipe_serial); 7875 %} 7876 7877 instruct membar_release() %{ 7878 match(MemBarRelease); 7879 ins_cost(VOLATILE_REF_COST); 7880 7881 format %{ "membar_release\n\t" 7882 "dmb ishst\n\tdmb ishld" %} 7883 7884 ins_encode %{ 7885 __ block_comment("membar_release"); 7886 // These will be merged if AlwaysMergeDMB is enabled. 7887 __ membar(Assembler::StoreStore); 7888 __ membar(Assembler::LoadStore); 7889 %} 7890 ins_pipe(pipe_serial); 7891 %} 7892 7893 instruct membar_storestore() %{ 7894 match(MemBarStoreStore); 7895 match(StoreStoreFence); 7896 ins_cost(VOLATILE_REF_COST); 7897 7898 format %{ "MEMBAR-store-store" %} 7899 7900 ins_encode %{ 7901 __ membar(Assembler::StoreStore); 7902 %} 7903 ins_pipe(pipe_serial); 7904 %} 7905 7906 instruct membar_release_lock() %{ 7907 match(MemBarReleaseLock); 7908 ins_cost(VOLATILE_REF_COST); 7909 7910 format %{ "membar_release_lock (elided)" %} 7911 7912 ins_encode %{ 7913 __ block_comment("membar_release_lock (elided)"); 7914 %} 7915 7916 ins_pipe(pipe_serial); 7917 %} 7918 7919 instruct unnecessary_membar_volatile() %{ 7920 predicate(unnecessary_volatile(n)); 7921 match(MemBarVolatile); 7922 ins_cost(0); 7923 7924 format %{ "membar_volatile (elided)" %} 7925 7926 ins_encode %{ 7927 __ block_comment("membar_volatile (elided)"); 7928 %} 7929 7930 ins_pipe(pipe_serial); 7931 %} 7932 7933 instruct membar_volatile() %{ 7934 match(MemBarVolatile); 7935 ins_cost(VOLATILE_REF_COST*100); 7936 7937 format %{ "membar_volatile\n\t" 7938 "dmb ish"%} 7939 7940 ins_encode %{ 7941 __ block_comment("membar_volatile"); 7942 __ membar(Assembler::StoreLoad); 7943 %} 7944 7945 ins_pipe(pipe_serial); 7946 %} 7947 7948 // ============================================================================ 7949 // Cast/Convert Instructions 7950 7951 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7952 match(Set dst (CastX2P src)); 7953 7954 ins_cost(INSN_COST); 7955 format %{ "mov $dst, $src\t# long -> ptr" %} 7956 7957 ins_encode %{ 7958 if ($dst$$reg != $src$$reg) { 7959 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7960 } 7961 %} 7962 7963 ins_pipe(ialu_reg); 7964 %} 7965 7966 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7967 match(Set dst (CastP2X src)); 7968 7969 ins_cost(INSN_COST); 7970 format %{ "mov $dst, $src\t# ptr -> long" %} 7971 7972 ins_encode %{ 7973 if ($dst$$reg != $src$$reg) { 7974 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7975 } 7976 %} 7977 7978 ins_pipe(ialu_reg); 7979 %} 7980 7981 // Convert oop into int for vectors alignment masking 7982 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7983 match(Set dst (ConvL2I (CastP2X src))); 7984 7985 ins_cost(INSN_COST); 7986 format %{ "movw $dst, $src\t# ptr -> int" %} 7987 ins_encode %{ 7988 __ movw($dst$$Register, $src$$Register); 7989 %} 7990 7991 ins_pipe(ialu_reg); 7992 %} 7993 7994 // Convert compressed oop into int for vectors alignment masking 7995 // in case of 32bit oops (heap < 4Gb). 7996 instruct convN2I(iRegINoSp dst, iRegN src) 7997 %{ 7998 predicate(CompressedOops::shift() == 0); 7999 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8000 8001 ins_cost(INSN_COST); 8002 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8003 ins_encode %{ 8004 __ movw($dst$$Register, $src$$Register); 8005 %} 8006 8007 ins_pipe(ialu_reg); 8008 %} 8009 8010 8011 // Convert oop pointer into compressed form 8012 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8013 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8014 match(Set dst (EncodeP src)); 8015 effect(KILL cr); 8016 ins_cost(INSN_COST * 3); 8017 format %{ "encode_heap_oop $dst, $src" %} 8018 ins_encode %{ 8019 Register s = $src$$Register; 8020 Register d = $dst$$Register; 8021 __ encode_heap_oop(d, s); 8022 %} 8023 ins_pipe(ialu_reg); 8024 %} 8025 8026 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8027 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8028 match(Set dst (EncodeP src)); 8029 ins_cost(INSN_COST * 3); 8030 format %{ "encode_heap_oop_not_null $dst, $src" %} 8031 ins_encode %{ 8032 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8033 %} 8034 ins_pipe(ialu_reg); 8035 %} 8036 8037 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8038 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8039 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8040 match(Set dst (DecodeN src)); 8041 ins_cost(INSN_COST * 3); 8042 format %{ "decode_heap_oop $dst, $src" %} 8043 ins_encode %{ 8044 Register s = $src$$Register; 8045 Register d = $dst$$Register; 8046 __ decode_heap_oop(d, s); 8047 %} 8048 ins_pipe(ialu_reg); 8049 %} 8050 8051 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8052 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8053 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8054 match(Set dst (DecodeN src)); 8055 ins_cost(INSN_COST * 3); 8056 format %{ "decode_heap_oop_not_null $dst, $src" %} 8057 ins_encode %{ 8058 Register s = $src$$Register; 8059 Register d = $dst$$Register; 8060 __ decode_heap_oop_not_null(d, s); 8061 %} 8062 ins_pipe(ialu_reg); 8063 %} 8064 8065 // n.b. AArch64 implementations of encode_klass_not_null and 8066 // decode_klass_not_null do not modify the flags register so, unlike 8067 // Intel, we don't kill CR as a side effect here 8068 8069 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8070 match(Set dst (EncodePKlass src)); 8071 8072 ins_cost(INSN_COST * 3); 8073 format %{ "encode_klass_not_null $dst,$src" %} 8074 8075 ins_encode %{ 8076 Register src_reg = as_Register($src$$reg); 8077 Register dst_reg = as_Register($dst$$reg); 8078 __ encode_klass_not_null(dst_reg, src_reg); 8079 %} 8080 8081 ins_pipe(ialu_reg); 8082 %} 8083 8084 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8085 match(Set dst (DecodeNKlass src)); 8086 8087 ins_cost(INSN_COST * 3); 8088 format %{ "decode_klass_not_null $dst,$src" %} 8089 8090 ins_encode %{ 8091 Register src_reg = as_Register($src$$reg); 8092 Register dst_reg = as_Register($dst$$reg); 8093 if (dst_reg != src_reg) { 8094 __ decode_klass_not_null(dst_reg, src_reg); 8095 } else { 8096 __ decode_klass_not_null(dst_reg); 8097 } 8098 %} 8099 8100 ins_pipe(ialu_reg); 8101 %} 8102 8103 instruct checkCastPP(iRegPNoSp dst) 8104 %{ 8105 match(Set dst (CheckCastPP dst)); 8106 8107 size(0); 8108 format %{ "# checkcastPP of $dst" %} 8109 ins_encode(/* empty encoding */); 8110 ins_pipe(pipe_class_empty); 8111 %} 8112 8113 instruct castPP(iRegPNoSp dst) 8114 %{ 8115 match(Set dst (CastPP dst)); 8116 8117 size(0); 8118 format %{ "# castPP of $dst" %} 8119 ins_encode(/* empty encoding */); 8120 ins_pipe(pipe_class_empty); 8121 %} 8122 8123 instruct castII(iRegI dst) 8124 %{ 8125 match(Set dst (CastII dst)); 8126 8127 size(0); 8128 format %{ "# castII of $dst" %} 8129 ins_encode(/* empty encoding */); 8130 ins_cost(0); 8131 ins_pipe(pipe_class_empty); 8132 %} 8133 8134 instruct castLL(iRegL dst) 8135 %{ 8136 match(Set dst (CastLL dst)); 8137 8138 size(0); 8139 format %{ "# castLL of $dst" %} 8140 ins_encode(/* empty encoding */); 8141 ins_cost(0); 8142 ins_pipe(pipe_class_empty); 8143 %} 8144 8145 instruct castFF(vRegF dst) 8146 %{ 8147 match(Set dst (CastFF dst)); 8148 8149 size(0); 8150 format %{ "# castFF of $dst" %} 8151 ins_encode(/* empty encoding */); 8152 ins_cost(0); 8153 ins_pipe(pipe_class_empty); 8154 %} 8155 8156 instruct castDD(vRegD dst) 8157 %{ 8158 match(Set dst (CastDD dst)); 8159 8160 size(0); 8161 format %{ "# castDD of $dst" %} 8162 ins_encode(/* empty encoding */); 8163 ins_cost(0); 8164 ins_pipe(pipe_class_empty); 8165 %} 8166 8167 instruct castVV(vReg dst) 8168 %{ 8169 match(Set dst (CastVV dst)); 8170 8171 size(0); 8172 format %{ "# castVV of $dst" %} 8173 ins_encode(/* empty encoding */); 8174 ins_cost(0); 8175 ins_pipe(pipe_class_empty); 8176 %} 8177 8178 instruct castVVMask(pRegGov dst) 8179 %{ 8180 match(Set dst (CastVV dst)); 8181 8182 size(0); 8183 format %{ "# castVV of $dst" %} 8184 ins_encode(/* empty encoding */); 8185 ins_cost(0); 8186 ins_pipe(pipe_class_empty); 8187 %} 8188 8189 // ============================================================================ 8190 // Atomic operation instructions 8191 // 8192 8193 // standard CompareAndSwapX when we are using barriers 8194 // these have higher priority than the rules selected by a predicate 8195 8196 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8197 // can't match them 8198 8199 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8200 8201 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8202 ins_cost(2 * VOLATILE_REF_COST); 8203 8204 effect(KILL cr); 8205 8206 format %{ 8207 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8208 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8209 %} 8210 8211 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8212 aarch64_enc_cset_eq(res)); 8213 8214 ins_pipe(pipe_slow); 8215 %} 8216 8217 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8218 8219 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8220 ins_cost(2 * VOLATILE_REF_COST); 8221 8222 effect(KILL cr); 8223 8224 format %{ 8225 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8226 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8227 %} 8228 8229 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8230 aarch64_enc_cset_eq(res)); 8231 8232 ins_pipe(pipe_slow); 8233 %} 8234 8235 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8236 8237 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8238 ins_cost(2 * VOLATILE_REF_COST); 8239 8240 effect(KILL cr); 8241 8242 format %{ 8243 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8244 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8245 %} 8246 8247 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8248 aarch64_enc_cset_eq(res)); 8249 8250 ins_pipe(pipe_slow); 8251 %} 8252 8253 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8254 8255 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8256 ins_cost(2 * VOLATILE_REF_COST); 8257 8258 effect(KILL cr); 8259 8260 format %{ 8261 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8262 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8263 %} 8264 8265 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8266 aarch64_enc_cset_eq(res)); 8267 8268 ins_pipe(pipe_slow); 8269 %} 8270 8271 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8272 8273 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8274 predicate(n->as_LoadStore()->barrier_data() == 0); 8275 ins_cost(2 * VOLATILE_REF_COST); 8276 8277 effect(KILL cr); 8278 8279 format %{ 8280 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8281 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8282 %} 8283 8284 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8285 aarch64_enc_cset_eq(res)); 8286 8287 ins_pipe(pipe_slow); 8288 %} 8289 8290 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8291 8292 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8293 predicate(n->as_LoadStore()->barrier_data() == 0); 8294 ins_cost(2 * VOLATILE_REF_COST); 8295 8296 effect(KILL cr); 8297 8298 format %{ 8299 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8300 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8301 %} 8302 8303 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8304 aarch64_enc_cset_eq(res)); 8305 8306 ins_pipe(pipe_slow); 8307 %} 8308 8309 // alternative CompareAndSwapX when we are eliding barriers 8310 8311 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8312 8313 predicate(needs_acquiring_load_exclusive(n)); 8314 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8315 ins_cost(VOLATILE_REF_COST); 8316 8317 effect(KILL cr); 8318 8319 format %{ 8320 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8321 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8322 %} 8323 8324 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8325 aarch64_enc_cset_eq(res)); 8326 8327 ins_pipe(pipe_slow); 8328 %} 8329 8330 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8331 8332 predicate(needs_acquiring_load_exclusive(n)); 8333 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8334 ins_cost(VOLATILE_REF_COST); 8335 8336 effect(KILL cr); 8337 8338 format %{ 8339 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8340 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8341 %} 8342 8343 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8344 aarch64_enc_cset_eq(res)); 8345 8346 ins_pipe(pipe_slow); 8347 %} 8348 8349 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8350 8351 predicate(needs_acquiring_load_exclusive(n)); 8352 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8353 ins_cost(VOLATILE_REF_COST); 8354 8355 effect(KILL cr); 8356 8357 format %{ 8358 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8359 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8360 %} 8361 8362 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8363 aarch64_enc_cset_eq(res)); 8364 8365 ins_pipe(pipe_slow); 8366 %} 8367 8368 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8369 8370 predicate(needs_acquiring_load_exclusive(n)); 8371 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8372 ins_cost(VOLATILE_REF_COST); 8373 8374 effect(KILL cr); 8375 8376 format %{ 8377 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8378 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8379 %} 8380 8381 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8382 aarch64_enc_cset_eq(res)); 8383 8384 ins_pipe(pipe_slow); 8385 %} 8386 8387 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8388 8389 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8390 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8391 ins_cost(VOLATILE_REF_COST); 8392 8393 effect(KILL cr); 8394 8395 format %{ 8396 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8397 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8398 %} 8399 8400 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8401 aarch64_enc_cset_eq(res)); 8402 8403 ins_pipe(pipe_slow); 8404 %} 8405 8406 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8407 8408 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0); 8409 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8410 ins_cost(VOLATILE_REF_COST); 8411 8412 effect(KILL cr); 8413 8414 format %{ 8415 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8416 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8417 %} 8418 8419 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8420 aarch64_enc_cset_eq(res)); 8421 8422 ins_pipe(pipe_slow); 8423 %} 8424 8425 8426 // --------------------------------------------------------------------- 8427 8428 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8429 8430 // Sundry CAS operations. Note that release is always true, 8431 // regardless of the memory ordering of the CAS. This is because we 8432 // need the volatile case to be sequentially consistent but there is 8433 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8434 // can't check the type of memory ordering here, so we always emit a 8435 // STLXR. 8436 8437 // This section is generated from cas.m4 8438 8439 8440 // This pattern is generated automatically from cas.m4. 8441 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8442 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8443 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8444 ins_cost(2 * VOLATILE_REF_COST); 8445 effect(TEMP_DEF res, KILL cr); 8446 format %{ 8447 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8448 %} 8449 ins_encode %{ 8450 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8451 Assembler::byte, /*acquire*/ false, /*release*/ true, 8452 /*weak*/ false, $res$$Register); 8453 __ sxtbw($res$$Register, $res$$Register); 8454 %} 8455 ins_pipe(pipe_slow); 8456 %} 8457 8458 // This pattern is generated automatically from cas.m4. 8459 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8460 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8461 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8462 ins_cost(2 * VOLATILE_REF_COST); 8463 effect(TEMP_DEF res, KILL cr); 8464 format %{ 8465 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8466 %} 8467 ins_encode %{ 8468 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8469 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8470 /*weak*/ false, $res$$Register); 8471 __ sxthw($res$$Register, $res$$Register); 8472 %} 8473 ins_pipe(pipe_slow); 8474 %} 8475 8476 // This pattern is generated automatically from cas.m4. 8477 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8478 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8479 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8480 ins_cost(2 * VOLATILE_REF_COST); 8481 effect(TEMP_DEF res, KILL cr); 8482 format %{ 8483 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8484 %} 8485 ins_encode %{ 8486 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8487 Assembler::word, /*acquire*/ false, /*release*/ true, 8488 /*weak*/ false, $res$$Register); 8489 %} 8490 ins_pipe(pipe_slow); 8491 %} 8492 8493 // This pattern is generated automatically from cas.m4. 8494 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8495 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8496 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8497 ins_cost(2 * VOLATILE_REF_COST); 8498 effect(TEMP_DEF res, KILL cr); 8499 format %{ 8500 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8501 %} 8502 ins_encode %{ 8503 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8504 Assembler::xword, /*acquire*/ false, /*release*/ true, 8505 /*weak*/ false, $res$$Register); 8506 %} 8507 ins_pipe(pipe_slow); 8508 %} 8509 8510 // This pattern is generated automatically from cas.m4. 8511 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8512 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8513 predicate(n->as_LoadStore()->barrier_data() == 0); 8514 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8515 ins_cost(2 * VOLATILE_REF_COST); 8516 effect(TEMP_DEF res, KILL cr); 8517 format %{ 8518 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8519 %} 8520 ins_encode %{ 8521 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8522 Assembler::word, /*acquire*/ false, /*release*/ true, 8523 /*weak*/ false, $res$$Register); 8524 %} 8525 ins_pipe(pipe_slow); 8526 %} 8527 8528 // This pattern is generated automatically from cas.m4. 8529 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8530 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8531 predicate(n->as_LoadStore()->barrier_data() == 0); 8532 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8533 ins_cost(2 * VOLATILE_REF_COST); 8534 effect(TEMP_DEF res, KILL cr); 8535 format %{ 8536 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8537 %} 8538 ins_encode %{ 8539 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8540 Assembler::xword, /*acquire*/ false, /*release*/ true, 8541 /*weak*/ false, $res$$Register); 8542 %} 8543 ins_pipe(pipe_slow); 8544 %} 8545 8546 // This pattern is generated automatically from cas.m4. 8547 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8548 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8549 predicate(needs_acquiring_load_exclusive(n)); 8550 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8551 ins_cost(VOLATILE_REF_COST); 8552 effect(TEMP_DEF res, KILL cr); 8553 format %{ 8554 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8555 %} 8556 ins_encode %{ 8557 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8558 Assembler::byte, /*acquire*/ true, /*release*/ true, 8559 /*weak*/ false, $res$$Register); 8560 __ sxtbw($res$$Register, $res$$Register); 8561 %} 8562 ins_pipe(pipe_slow); 8563 %} 8564 8565 // This pattern is generated automatically from cas.m4. 8566 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8567 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8568 predicate(needs_acquiring_load_exclusive(n)); 8569 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8570 ins_cost(VOLATILE_REF_COST); 8571 effect(TEMP_DEF res, KILL cr); 8572 format %{ 8573 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8574 %} 8575 ins_encode %{ 8576 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8577 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8578 /*weak*/ false, $res$$Register); 8579 __ sxthw($res$$Register, $res$$Register); 8580 %} 8581 ins_pipe(pipe_slow); 8582 %} 8583 8584 // This pattern is generated automatically from cas.m4. 8585 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8586 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8587 predicate(needs_acquiring_load_exclusive(n)); 8588 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8589 ins_cost(VOLATILE_REF_COST); 8590 effect(TEMP_DEF res, KILL cr); 8591 format %{ 8592 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8593 %} 8594 ins_encode %{ 8595 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8596 Assembler::word, /*acquire*/ true, /*release*/ true, 8597 /*weak*/ false, $res$$Register); 8598 %} 8599 ins_pipe(pipe_slow); 8600 %} 8601 8602 // This pattern is generated automatically from cas.m4. 8603 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8604 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8605 predicate(needs_acquiring_load_exclusive(n)); 8606 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8607 ins_cost(VOLATILE_REF_COST); 8608 effect(TEMP_DEF res, KILL cr); 8609 format %{ 8610 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8611 %} 8612 ins_encode %{ 8613 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8614 Assembler::xword, /*acquire*/ true, /*release*/ true, 8615 /*weak*/ false, $res$$Register); 8616 %} 8617 ins_pipe(pipe_slow); 8618 %} 8619 8620 // This pattern is generated automatically from cas.m4. 8621 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8622 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8623 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0); 8624 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8625 ins_cost(VOLATILE_REF_COST); 8626 effect(TEMP_DEF res, KILL cr); 8627 format %{ 8628 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8629 %} 8630 ins_encode %{ 8631 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8632 Assembler::word, /*acquire*/ true, /*release*/ true, 8633 /*weak*/ false, $res$$Register); 8634 %} 8635 ins_pipe(pipe_slow); 8636 %} 8637 8638 // This pattern is generated automatically from cas.m4. 8639 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8640 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8641 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8642 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8643 ins_cost(VOLATILE_REF_COST); 8644 effect(TEMP_DEF res, KILL cr); 8645 format %{ 8646 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8647 %} 8648 ins_encode %{ 8649 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8650 Assembler::xword, /*acquire*/ true, /*release*/ true, 8651 /*weak*/ false, $res$$Register); 8652 %} 8653 ins_pipe(pipe_slow); 8654 %} 8655 8656 // This pattern is generated automatically from cas.m4. 8657 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8658 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8659 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8660 ins_cost(2 * VOLATILE_REF_COST); 8661 effect(KILL cr); 8662 format %{ 8663 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8664 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8665 %} 8666 ins_encode %{ 8667 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8668 Assembler::byte, /*acquire*/ false, /*release*/ true, 8669 /*weak*/ true, noreg); 8670 __ csetw($res$$Register, Assembler::EQ); 8671 %} 8672 ins_pipe(pipe_slow); 8673 %} 8674 8675 // This pattern is generated automatically from cas.m4. 8676 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8677 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8678 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8679 ins_cost(2 * VOLATILE_REF_COST); 8680 effect(KILL cr); 8681 format %{ 8682 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8683 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8684 %} 8685 ins_encode %{ 8686 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8687 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8688 /*weak*/ true, noreg); 8689 __ csetw($res$$Register, Assembler::EQ); 8690 %} 8691 ins_pipe(pipe_slow); 8692 %} 8693 8694 // This pattern is generated automatically from cas.m4. 8695 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8696 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8697 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8698 ins_cost(2 * VOLATILE_REF_COST); 8699 effect(KILL cr); 8700 format %{ 8701 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8702 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8703 %} 8704 ins_encode %{ 8705 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8706 Assembler::word, /*acquire*/ false, /*release*/ true, 8707 /*weak*/ true, noreg); 8708 __ csetw($res$$Register, Assembler::EQ); 8709 %} 8710 ins_pipe(pipe_slow); 8711 %} 8712 8713 // This pattern is generated automatically from cas.m4. 8714 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8715 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8716 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8717 ins_cost(2 * VOLATILE_REF_COST); 8718 effect(KILL cr); 8719 format %{ 8720 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8721 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8722 %} 8723 ins_encode %{ 8724 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8725 Assembler::xword, /*acquire*/ false, /*release*/ true, 8726 /*weak*/ true, noreg); 8727 __ csetw($res$$Register, Assembler::EQ); 8728 %} 8729 ins_pipe(pipe_slow); 8730 %} 8731 8732 // This pattern is generated automatically from cas.m4. 8733 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8734 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8735 predicate(n->as_LoadStore()->barrier_data() == 0); 8736 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8737 ins_cost(2 * VOLATILE_REF_COST); 8738 effect(KILL cr); 8739 format %{ 8740 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8741 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8742 %} 8743 ins_encode %{ 8744 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8745 Assembler::word, /*acquire*/ false, /*release*/ true, 8746 /*weak*/ true, noreg); 8747 __ csetw($res$$Register, Assembler::EQ); 8748 %} 8749 ins_pipe(pipe_slow); 8750 %} 8751 8752 // This pattern is generated automatically from cas.m4. 8753 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8754 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8755 predicate(n->as_LoadStore()->barrier_data() == 0); 8756 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8757 ins_cost(2 * VOLATILE_REF_COST); 8758 effect(KILL cr); 8759 format %{ 8760 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8761 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8762 %} 8763 ins_encode %{ 8764 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8765 Assembler::xword, /*acquire*/ false, /*release*/ true, 8766 /*weak*/ true, noreg); 8767 __ csetw($res$$Register, Assembler::EQ); 8768 %} 8769 ins_pipe(pipe_slow); 8770 %} 8771 8772 // This pattern is generated automatically from cas.m4. 8773 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8774 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8775 predicate(needs_acquiring_load_exclusive(n)); 8776 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8777 ins_cost(VOLATILE_REF_COST); 8778 effect(KILL cr); 8779 format %{ 8780 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8781 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8782 %} 8783 ins_encode %{ 8784 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8785 Assembler::byte, /*acquire*/ true, /*release*/ true, 8786 /*weak*/ true, noreg); 8787 __ csetw($res$$Register, Assembler::EQ); 8788 %} 8789 ins_pipe(pipe_slow); 8790 %} 8791 8792 // This pattern is generated automatically from cas.m4. 8793 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8794 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8795 predicate(needs_acquiring_load_exclusive(n)); 8796 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8797 ins_cost(VOLATILE_REF_COST); 8798 effect(KILL cr); 8799 format %{ 8800 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8801 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8802 %} 8803 ins_encode %{ 8804 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8805 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8806 /*weak*/ true, noreg); 8807 __ csetw($res$$Register, Assembler::EQ); 8808 %} 8809 ins_pipe(pipe_slow); 8810 %} 8811 8812 // This pattern is generated automatically from cas.m4. 8813 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8814 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8815 predicate(needs_acquiring_load_exclusive(n)); 8816 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8817 ins_cost(VOLATILE_REF_COST); 8818 effect(KILL cr); 8819 format %{ 8820 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8821 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8822 %} 8823 ins_encode %{ 8824 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8825 Assembler::word, /*acquire*/ true, /*release*/ true, 8826 /*weak*/ true, noreg); 8827 __ csetw($res$$Register, Assembler::EQ); 8828 %} 8829 ins_pipe(pipe_slow); 8830 %} 8831 8832 // This pattern is generated automatically from cas.m4. 8833 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8834 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8835 predicate(needs_acquiring_load_exclusive(n)); 8836 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8837 ins_cost(VOLATILE_REF_COST); 8838 effect(KILL cr); 8839 format %{ 8840 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8841 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8842 %} 8843 ins_encode %{ 8844 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8845 Assembler::xword, /*acquire*/ true, /*release*/ true, 8846 /*weak*/ true, noreg); 8847 __ csetw($res$$Register, Assembler::EQ); 8848 %} 8849 ins_pipe(pipe_slow); 8850 %} 8851 8852 // This pattern is generated automatically from cas.m4. 8853 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8854 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8855 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0); 8856 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8857 ins_cost(VOLATILE_REF_COST); 8858 effect(KILL cr); 8859 format %{ 8860 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8861 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8862 %} 8863 ins_encode %{ 8864 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8865 Assembler::word, /*acquire*/ true, /*release*/ true, 8866 /*weak*/ true, noreg); 8867 __ csetw($res$$Register, Assembler::EQ); 8868 %} 8869 ins_pipe(pipe_slow); 8870 %} 8871 8872 // This pattern is generated automatically from cas.m4. 8873 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8874 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8875 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8876 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8877 ins_cost(VOLATILE_REF_COST); 8878 effect(KILL cr); 8879 format %{ 8880 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8881 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8882 %} 8883 ins_encode %{ 8884 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8885 Assembler::xword, /*acquire*/ true, /*release*/ true, 8886 /*weak*/ true, noreg); 8887 __ csetw($res$$Register, Assembler::EQ); 8888 %} 8889 ins_pipe(pipe_slow); 8890 %} 8891 8892 // END This section of the file is automatically generated. Do not edit -------------- 8893 // --------------------------------------------------------------------- 8894 8895 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8896 match(Set prev (GetAndSetI mem newv)); 8897 ins_cost(2 * VOLATILE_REF_COST); 8898 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8899 ins_encode %{ 8900 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8901 %} 8902 ins_pipe(pipe_serial); 8903 %} 8904 8905 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8906 match(Set prev (GetAndSetL mem newv)); 8907 ins_cost(2 * VOLATILE_REF_COST); 8908 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8909 ins_encode %{ 8910 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8911 %} 8912 ins_pipe(pipe_serial); 8913 %} 8914 8915 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8916 predicate(n->as_LoadStore()->barrier_data() == 0); 8917 match(Set prev (GetAndSetN mem newv)); 8918 ins_cost(2 * VOLATILE_REF_COST); 8919 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8920 ins_encode %{ 8921 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8922 %} 8923 ins_pipe(pipe_serial); 8924 %} 8925 8926 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8927 predicate(n->as_LoadStore()->barrier_data() == 0); 8928 match(Set prev (GetAndSetP mem newv)); 8929 ins_cost(2 * VOLATILE_REF_COST); 8930 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8931 ins_encode %{ 8932 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8933 %} 8934 ins_pipe(pipe_serial); 8935 %} 8936 8937 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 8938 predicate(needs_acquiring_load_exclusive(n)); 8939 match(Set prev (GetAndSetI mem newv)); 8940 ins_cost(VOLATILE_REF_COST); 8941 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8942 ins_encode %{ 8943 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8944 %} 8945 ins_pipe(pipe_serial); 8946 %} 8947 8948 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8949 predicate(needs_acquiring_load_exclusive(n)); 8950 match(Set prev (GetAndSetL mem newv)); 8951 ins_cost(VOLATILE_REF_COST); 8952 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8953 ins_encode %{ 8954 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8955 %} 8956 ins_pipe(pipe_serial); 8957 %} 8958 8959 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 8960 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0); 8961 match(Set prev (GetAndSetN mem newv)); 8962 ins_cost(VOLATILE_REF_COST); 8963 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8964 ins_encode %{ 8965 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8966 %} 8967 ins_pipe(pipe_serial); 8968 %} 8969 8970 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8971 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8972 match(Set prev (GetAndSetP mem newv)); 8973 ins_cost(VOLATILE_REF_COST); 8974 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8975 ins_encode %{ 8976 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8977 %} 8978 ins_pipe(pipe_serial); 8979 %} 8980 8981 8982 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8983 match(Set newval (GetAndAddL mem incr)); 8984 ins_cost(2 * VOLATILE_REF_COST + 1); 8985 format %{ "get_and_addL $newval, [$mem], $incr" %} 8986 ins_encode %{ 8987 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8988 %} 8989 ins_pipe(pipe_serial); 8990 %} 8991 8992 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8993 predicate(n->as_LoadStore()->result_not_used()); 8994 match(Set dummy (GetAndAddL mem incr)); 8995 ins_cost(2 * VOLATILE_REF_COST); 8996 format %{ "get_and_addL [$mem], $incr" %} 8997 ins_encode %{ 8998 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8999 %} 9000 ins_pipe(pipe_serial); 9001 %} 9002 9003 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9004 match(Set newval (GetAndAddL mem incr)); 9005 ins_cost(2 * VOLATILE_REF_COST + 1); 9006 format %{ "get_and_addL $newval, [$mem], $incr" %} 9007 ins_encode %{ 9008 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9009 %} 9010 ins_pipe(pipe_serial); 9011 %} 9012 9013 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9014 predicate(n->as_LoadStore()->result_not_used()); 9015 match(Set dummy (GetAndAddL mem incr)); 9016 ins_cost(2 * VOLATILE_REF_COST); 9017 format %{ "get_and_addL [$mem], $incr" %} 9018 ins_encode %{ 9019 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9020 %} 9021 ins_pipe(pipe_serial); 9022 %} 9023 9024 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9025 match(Set newval (GetAndAddI mem incr)); 9026 ins_cost(2 * VOLATILE_REF_COST + 1); 9027 format %{ "get_and_addI $newval, [$mem], $incr" %} 9028 ins_encode %{ 9029 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9030 %} 9031 ins_pipe(pipe_serial); 9032 %} 9033 9034 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9035 predicate(n->as_LoadStore()->result_not_used()); 9036 match(Set dummy (GetAndAddI mem incr)); 9037 ins_cost(2 * VOLATILE_REF_COST); 9038 format %{ "get_and_addI [$mem], $incr" %} 9039 ins_encode %{ 9040 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9041 %} 9042 ins_pipe(pipe_serial); 9043 %} 9044 9045 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9046 match(Set newval (GetAndAddI mem incr)); 9047 ins_cost(2 * VOLATILE_REF_COST + 1); 9048 format %{ "get_and_addI $newval, [$mem], $incr" %} 9049 ins_encode %{ 9050 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9051 %} 9052 ins_pipe(pipe_serial); 9053 %} 9054 9055 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9056 predicate(n->as_LoadStore()->result_not_used()); 9057 match(Set dummy (GetAndAddI mem incr)); 9058 ins_cost(2 * VOLATILE_REF_COST); 9059 format %{ "get_and_addI [$mem], $incr" %} 9060 ins_encode %{ 9061 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9062 %} 9063 ins_pipe(pipe_serial); 9064 %} 9065 9066 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9067 predicate(needs_acquiring_load_exclusive(n)); 9068 match(Set newval (GetAndAddL mem incr)); 9069 ins_cost(VOLATILE_REF_COST + 1); 9070 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9071 ins_encode %{ 9072 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9073 %} 9074 ins_pipe(pipe_serial); 9075 %} 9076 9077 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9078 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9079 match(Set dummy (GetAndAddL mem incr)); 9080 ins_cost(VOLATILE_REF_COST); 9081 format %{ "get_and_addL_acq [$mem], $incr" %} 9082 ins_encode %{ 9083 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9084 %} 9085 ins_pipe(pipe_serial); 9086 %} 9087 9088 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9089 predicate(needs_acquiring_load_exclusive(n)); 9090 match(Set newval (GetAndAddL mem incr)); 9091 ins_cost(VOLATILE_REF_COST + 1); 9092 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9093 ins_encode %{ 9094 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9095 %} 9096 ins_pipe(pipe_serial); 9097 %} 9098 9099 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9100 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9101 match(Set dummy (GetAndAddL mem incr)); 9102 ins_cost(VOLATILE_REF_COST); 9103 format %{ "get_and_addL_acq [$mem], $incr" %} 9104 ins_encode %{ 9105 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9106 %} 9107 ins_pipe(pipe_serial); 9108 %} 9109 9110 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9111 predicate(needs_acquiring_load_exclusive(n)); 9112 match(Set newval (GetAndAddI mem incr)); 9113 ins_cost(VOLATILE_REF_COST + 1); 9114 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9115 ins_encode %{ 9116 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9117 %} 9118 ins_pipe(pipe_serial); 9119 %} 9120 9121 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9122 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9123 match(Set dummy (GetAndAddI mem incr)); 9124 ins_cost(VOLATILE_REF_COST); 9125 format %{ "get_and_addI_acq [$mem], $incr" %} 9126 ins_encode %{ 9127 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9128 %} 9129 ins_pipe(pipe_serial); 9130 %} 9131 9132 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9133 predicate(needs_acquiring_load_exclusive(n)); 9134 match(Set newval (GetAndAddI mem incr)); 9135 ins_cost(VOLATILE_REF_COST + 1); 9136 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9137 ins_encode %{ 9138 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9139 %} 9140 ins_pipe(pipe_serial); 9141 %} 9142 9143 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9144 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9145 match(Set dummy (GetAndAddI mem incr)); 9146 ins_cost(VOLATILE_REF_COST); 9147 format %{ "get_and_addI_acq [$mem], $incr" %} 9148 ins_encode %{ 9149 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9150 %} 9151 ins_pipe(pipe_serial); 9152 %} 9153 9154 // Manifest a CmpU result in an integer register. 9155 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9156 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags) 9157 %{ 9158 match(Set dst (CmpU3 src1 src2)); 9159 effect(KILL flags); 9160 9161 ins_cost(INSN_COST * 3); 9162 format %{ 9163 "cmpw $src1, $src2\n\t" 9164 "csetw $dst, ne\n\t" 9165 "cnegw $dst, lo\t# CmpU3(reg)" 9166 %} 9167 ins_encode %{ 9168 __ cmpw($src1$$Register, $src2$$Register); 9169 __ csetw($dst$$Register, Assembler::NE); 9170 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9171 %} 9172 9173 ins_pipe(pipe_class_default); 9174 %} 9175 9176 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags) 9177 %{ 9178 match(Set dst (CmpU3 src1 src2)); 9179 effect(KILL flags); 9180 9181 ins_cost(INSN_COST * 3); 9182 format %{ 9183 "subsw zr, $src1, $src2\n\t" 9184 "csetw $dst, ne\n\t" 9185 "cnegw $dst, lo\t# CmpU3(imm)" 9186 %} 9187 ins_encode %{ 9188 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant); 9189 __ csetw($dst$$Register, Assembler::NE); 9190 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9191 %} 9192 9193 ins_pipe(pipe_class_default); 9194 %} 9195 9196 // Manifest a CmpUL result in an integer register. 9197 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9198 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9199 %{ 9200 match(Set dst (CmpUL3 src1 src2)); 9201 effect(KILL flags); 9202 9203 ins_cost(INSN_COST * 3); 9204 format %{ 9205 "cmp $src1, $src2\n\t" 9206 "csetw $dst, ne\n\t" 9207 "cnegw $dst, lo\t# CmpUL3(reg)" 9208 %} 9209 ins_encode %{ 9210 __ cmp($src1$$Register, $src2$$Register); 9211 __ csetw($dst$$Register, Assembler::NE); 9212 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9213 %} 9214 9215 ins_pipe(pipe_class_default); 9216 %} 9217 9218 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9219 %{ 9220 match(Set dst (CmpUL3 src1 src2)); 9221 effect(KILL flags); 9222 9223 ins_cost(INSN_COST * 3); 9224 format %{ 9225 "subs zr, $src1, $src2\n\t" 9226 "csetw $dst, ne\n\t" 9227 "cnegw $dst, lo\t# CmpUL3(imm)" 9228 %} 9229 ins_encode %{ 9230 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9231 __ csetw($dst$$Register, Assembler::NE); 9232 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9233 %} 9234 9235 ins_pipe(pipe_class_default); 9236 %} 9237 9238 // Manifest a CmpL result in an integer register. 9239 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9240 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9241 %{ 9242 match(Set dst (CmpL3 src1 src2)); 9243 effect(KILL flags); 9244 9245 ins_cost(INSN_COST * 3); 9246 format %{ 9247 "cmp $src1, $src2\n\t" 9248 "csetw $dst, ne\n\t" 9249 "cnegw $dst, lt\t# CmpL3(reg)" 9250 %} 9251 ins_encode %{ 9252 __ cmp($src1$$Register, $src2$$Register); 9253 __ csetw($dst$$Register, Assembler::NE); 9254 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9255 %} 9256 9257 ins_pipe(pipe_class_default); 9258 %} 9259 9260 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9261 %{ 9262 match(Set dst (CmpL3 src1 src2)); 9263 effect(KILL flags); 9264 9265 ins_cost(INSN_COST * 3); 9266 format %{ 9267 "subs zr, $src1, $src2\n\t" 9268 "csetw $dst, ne\n\t" 9269 "cnegw $dst, lt\t# CmpL3(imm)" 9270 %} 9271 ins_encode %{ 9272 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9273 __ csetw($dst$$Register, Assembler::NE); 9274 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9275 %} 9276 9277 ins_pipe(pipe_class_default); 9278 %} 9279 9280 // ============================================================================ 9281 // Conditional Move Instructions 9282 9283 // n.b. we have identical rules for both a signed compare op (cmpOp) 9284 // and an unsigned compare op (cmpOpU). it would be nice if we could 9285 // define an op class which merged both inputs and use it to type the 9286 // argument to a single rule. unfortunatelyt his fails because the 9287 // opclass does not live up to the COND_INTER interface of its 9288 // component operands. When the generic code tries to negate the 9289 // operand it ends up running the generci Machoper::negate method 9290 // which throws a ShouldNotHappen. So, we have to provide two flavours 9291 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9292 9293 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9294 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9295 9296 ins_cost(INSN_COST * 2); 9297 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9298 9299 ins_encode %{ 9300 __ cselw(as_Register($dst$$reg), 9301 as_Register($src2$$reg), 9302 as_Register($src1$$reg), 9303 (Assembler::Condition)$cmp$$cmpcode); 9304 %} 9305 9306 ins_pipe(icond_reg_reg); 9307 %} 9308 9309 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9310 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9311 9312 ins_cost(INSN_COST * 2); 9313 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9314 9315 ins_encode %{ 9316 __ cselw(as_Register($dst$$reg), 9317 as_Register($src2$$reg), 9318 as_Register($src1$$reg), 9319 (Assembler::Condition)$cmp$$cmpcode); 9320 %} 9321 9322 ins_pipe(icond_reg_reg); 9323 %} 9324 9325 // special cases where one arg is zero 9326 9327 // n.b. this is selected in preference to the rule above because it 9328 // avoids loading constant 0 into a source register 9329 9330 // TODO 9331 // we ought only to be able to cull one of these variants as the ideal 9332 // transforms ought always to order the zero consistently (to left/right?) 9333 9334 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9335 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9336 9337 ins_cost(INSN_COST * 2); 9338 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9339 9340 ins_encode %{ 9341 __ cselw(as_Register($dst$$reg), 9342 as_Register($src$$reg), 9343 zr, 9344 (Assembler::Condition)$cmp$$cmpcode); 9345 %} 9346 9347 ins_pipe(icond_reg); 9348 %} 9349 9350 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9351 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9352 9353 ins_cost(INSN_COST * 2); 9354 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9355 9356 ins_encode %{ 9357 __ cselw(as_Register($dst$$reg), 9358 as_Register($src$$reg), 9359 zr, 9360 (Assembler::Condition)$cmp$$cmpcode); 9361 %} 9362 9363 ins_pipe(icond_reg); 9364 %} 9365 9366 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9367 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9368 9369 ins_cost(INSN_COST * 2); 9370 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9371 9372 ins_encode %{ 9373 __ cselw(as_Register($dst$$reg), 9374 zr, 9375 as_Register($src$$reg), 9376 (Assembler::Condition)$cmp$$cmpcode); 9377 %} 9378 9379 ins_pipe(icond_reg); 9380 %} 9381 9382 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9383 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9384 9385 ins_cost(INSN_COST * 2); 9386 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9387 9388 ins_encode %{ 9389 __ cselw(as_Register($dst$$reg), 9390 zr, 9391 as_Register($src$$reg), 9392 (Assembler::Condition)$cmp$$cmpcode); 9393 %} 9394 9395 ins_pipe(icond_reg); 9396 %} 9397 9398 // special case for creating a boolean 0 or 1 9399 9400 // n.b. this is selected in preference to the rule above because it 9401 // avoids loading constants 0 and 1 into a source register 9402 9403 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9404 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9405 9406 ins_cost(INSN_COST * 2); 9407 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9408 9409 ins_encode %{ 9410 // equivalently 9411 // cset(as_Register($dst$$reg), 9412 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9413 __ csincw(as_Register($dst$$reg), 9414 zr, 9415 zr, 9416 (Assembler::Condition)$cmp$$cmpcode); 9417 %} 9418 9419 ins_pipe(icond_none); 9420 %} 9421 9422 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9423 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9424 9425 ins_cost(INSN_COST * 2); 9426 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9427 9428 ins_encode %{ 9429 // equivalently 9430 // cset(as_Register($dst$$reg), 9431 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9432 __ csincw(as_Register($dst$$reg), 9433 zr, 9434 zr, 9435 (Assembler::Condition)$cmp$$cmpcode); 9436 %} 9437 9438 ins_pipe(icond_none); 9439 %} 9440 9441 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9442 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9443 9444 ins_cost(INSN_COST * 2); 9445 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9446 9447 ins_encode %{ 9448 __ csel(as_Register($dst$$reg), 9449 as_Register($src2$$reg), 9450 as_Register($src1$$reg), 9451 (Assembler::Condition)$cmp$$cmpcode); 9452 %} 9453 9454 ins_pipe(icond_reg_reg); 9455 %} 9456 9457 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9458 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9459 9460 ins_cost(INSN_COST * 2); 9461 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9462 9463 ins_encode %{ 9464 __ csel(as_Register($dst$$reg), 9465 as_Register($src2$$reg), 9466 as_Register($src1$$reg), 9467 (Assembler::Condition)$cmp$$cmpcode); 9468 %} 9469 9470 ins_pipe(icond_reg_reg); 9471 %} 9472 9473 // special cases where one arg is zero 9474 9475 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9476 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9477 9478 ins_cost(INSN_COST * 2); 9479 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9480 9481 ins_encode %{ 9482 __ csel(as_Register($dst$$reg), 9483 zr, 9484 as_Register($src$$reg), 9485 (Assembler::Condition)$cmp$$cmpcode); 9486 %} 9487 9488 ins_pipe(icond_reg); 9489 %} 9490 9491 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9492 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9493 9494 ins_cost(INSN_COST * 2); 9495 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9496 9497 ins_encode %{ 9498 __ csel(as_Register($dst$$reg), 9499 zr, 9500 as_Register($src$$reg), 9501 (Assembler::Condition)$cmp$$cmpcode); 9502 %} 9503 9504 ins_pipe(icond_reg); 9505 %} 9506 9507 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9508 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9509 9510 ins_cost(INSN_COST * 2); 9511 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9512 9513 ins_encode %{ 9514 __ csel(as_Register($dst$$reg), 9515 as_Register($src$$reg), 9516 zr, 9517 (Assembler::Condition)$cmp$$cmpcode); 9518 %} 9519 9520 ins_pipe(icond_reg); 9521 %} 9522 9523 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9524 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9525 9526 ins_cost(INSN_COST * 2); 9527 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9528 9529 ins_encode %{ 9530 __ csel(as_Register($dst$$reg), 9531 as_Register($src$$reg), 9532 zr, 9533 (Assembler::Condition)$cmp$$cmpcode); 9534 %} 9535 9536 ins_pipe(icond_reg); 9537 %} 9538 9539 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9540 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9541 9542 ins_cost(INSN_COST * 2); 9543 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9544 9545 ins_encode %{ 9546 __ csel(as_Register($dst$$reg), 9547 as_Register($src2$$reg), 9548 as_Register($src1$$reg), 9549 (Assembler::Condition)$cmp$$cmpcode); 9550 %} 9551 9552 ins_pipe(icond_reg_reg); 9553 %} 9554 9555 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9556 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9557 9558 ins_cost(INSN_COST * 2); 9559 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9560 9561 ins_encode %{ 9562 __ csel(as_Register($dst$$reg), 9563 as_Register($src2$$reg), 9564 as_Register($src1$$reg), 9565 (Assembler::Condition)$cmp$$cmpcode); 9566 %} 9567 9568 ins_pipe(icond_reg_reg); 9569 %} 9570 9571 // special cases where one arg is zero 9572 9573 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9574 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9575 9576 ins_cost(INSN_COST * 2); 9577 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9578 9579 ins_encode %{ 9580 __ csel(as_Register($dst$$reg), 9581 zr, 9582 as_Register($src$$reg), 9583 (Assembler::Condition)$cmp$$cmpcode); 9584 %} 9585 9586 ins_pipe(icond_reg); 9587 %} 9588 9589 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9590 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9591 9592 ins_cost(INSN_COST * 2); 9593 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9594 9595 ins_encode %{ 9596 __ csel(as_Register($dst$$reg), 9597 zr, 9598 as_Register($src$$reg), 9599 (Assembler::Condition)$cmp$$cmpcode); 9600 %} 9601 9602 ins_pipe(icond_reg); 9603 %} 9604 9605 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9606 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9607 9608 ins_cost(INSN_COST * 2); 9609 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9610 9611 ins_encode %{ 9612 __ csel(as_Register($dst$$reg), 9613 as_Register($src$$reg), 9614 zr, 9615 (Assembler::Condition)$cmp$$cmpcode); 9616 %} 9617 9618 ins_pipe(icond_reg); 9619 %} 9620 9621 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9622 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9623 9624 ins_cost(INSN_COST * 2); 9625 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9626 9627 ins_encode %{ 9628 __ csel(as_Register($dst$$reg), 9629 as_Register($src$$reg), 9630 zr, 9631 (Assembler::Condition)$cmp$$cmpcode); 9632 %} 9633 9634 ins_pipe(icond_reg); 9635 %} 9636 9637 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9638 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9639 9640 ins_cost(INSN_COST * 2); 9641 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9642 9643 ins_encode %{ 9644 __ cselw(as_Register($dst$$reg), 9645 as_Register($src2$$reg), 9646 as_Register($src1$$reg), 9647 (Assembler::Condition)$cmp$$cmpcode); 9648 %} 9649 9650 ins_pipe(icond_reg_reg); 9651 %} 9652 9653 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9654 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9655 9656 ins_cost(INSN_COST * 2); 9657 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9658 9659 ins_encode %{ 9660 __ cselw(as_Register($dst$$reg), 9661 as_Register($src2$$reg), 9662 as_Register($src1$$reg), 9663 (Assembler::Condition)$cmp$$cmpcode); 9664 %} 9665 9666 ins_pipe(icond_reg_reg); 9667 %} 9668 9669 // special cases where one arg is zero 9670 9671 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9672 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9673 9674 ins_cost(INSN_COST * 2); 9675 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9676 9677 ins_encode %{ 9678 __ cselw(as_Register($dst$$reg), 9679 zr, 9680 as_Register($src$$reg), 9681 (Assembler::Condition)$cmp$$cmpcode); 9682 %} 9683 9684 ins_pipe(icond_reg); 9685 %} 9686 9687 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9688 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9689 9690 ins_cost(INSN_COST * 2); 9691 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9692 9693 ins_encode %{ 9694 __ cselw(as_Register($dst$$reg), 9695 zr, 9696 as_Register($src$$reg), 9697 (Assembler::Condition)$cmp$$cmpcode); 9698 %} 9699 9700 ins_pipe(icond_reg); 9701 %} 9702 9703 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9704 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9705 9706 ins_cost(INSN_COST * 2); 9707 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9708 9709 ins_encode %{ 9710 __ cselw(as_Register($dst$$reg), 9711 as_Register($src$$reg), 9712 zr, 9713 (Assembler::Condition)$cmp$$cmpcode); 9714 %} 9715 9716 ins_pipe(icond_reg); 9717 %} 9718 9719 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9720 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9721 9722 ins_cost(INSN_COST * 2); 9723 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9724 9725 ins_encode %{ 9726 __ cselw(as_Register($dst$$reg), 9727 as_Register($src$$reg), 9728 zr, 9729 (Assembler::Condition)$cmp$$cmpcode); 9730 %} 9731 9732 ins_pipe(icond_reg); 9733 %} 9734 9735 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9736 %{ 9737 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9738 9739 ins_cost(INSN_COST * 3); 9740 9741 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9742 ins_encode %{ 9743 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9744 __ fcsels(as_FloatRegister($dst$$reg), 9745 as_FloatRegister($src2$$reg), 9746 as_FloatRegister($src1$$reg), 9747 cond); 9748 %} 9749 9750 ins_pipe(fp_cond_reg_reg_s); 9751 %} 9752 9753 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9754 %{ 9755 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9756 9757 ins_cost(INSN_COST * 3); 9758 9759 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9760 ins_encode %{ 9761 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9762 __ fcsels(as_FloatRegister($dst$$reg), 9763 as_FloatRegister($src2$$reg), 9764 as_FloatRegister($src1$$reg), 9765 cond); 9766 %} 9767 9768 ins_pipe(fp_cond_reg_reg_s); 9769 %} 9770 9771 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9772 %{ 9773 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9774 9775 ins_cost(INSN_COST * 3); 9776 9777 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9778 ins_encode %{ 9779 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9780 __ fcseld(as_FloatRegister($dst$$reg), 9781 as_FloatRegister($src2$$reg), 9782 as_FloatRegister($src1$$reg), 9783 cond); 9784 %} 9785 9786 ins_pipe(fp_cond_reg_reg_d); 9787 %} 9788 9789 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9790 %{ 9791 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9792 9793 ins_cost(INSN_COST * 3); 9794 9795 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9796 ins_encode %{ 9797 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9798 __ fcseld(as_FloatRegister($dst$$reg), 9799 as_FloatRegister($src2$$reg), 9800 as_FloatRegister($src1$$reg), 9801 cond); 9802 %} 9803 9804 ins_pipe(fp_cond_reg_reg_d); 9805 %} 9806 9807 // ============================================================================ 9808 // Arithmetic Instructions 9809 // 9810 9811 // Integer Addition 9812 9813 // TODO 9814 // these currently employ operations which do not set CR and hence are 9815 // not flagged as killing CR but we would like to isolate the cases 9816 // where we want to set flags from those where we don't. need to work 9817 // out how to do that. 9818 9819 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9820 match(Set dst (AddI src1 src2)); 9821 9822 ins_cost(INSN_COST); 9823 format %{ "addw $dst, $src1, $src2" %} 9824 9825 ins_encode %{ 9826 __ addw(as_Register($dst$$reg), 9827 as_Register($src1$$reg), 9828 as_Register($src2$$reg)); 9829 %} 9830 9831 ins_pipe(ialu_reg_reg); 9832 %} 9833 9834 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9835 match(Set dst (AddI src1 src2)); 9836 9837 ins_cost(INSN_COST); 9838 format %{ "addw $dst, $src1, $src2" %} 9839 9840 // use opcode to indicate that this is an add not a sub 9841 opcode(0x0); 9842 9843 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9844 9845 ins_pipe(ialu_reg_imm); 9846 %} 9847 9848 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9849 match(Set dst (AddI (ConvL2I src1) src2)); 9850 9851 ins_cost(INSN_COST); 9852 format %{ "addw $dst, $src1, $src2" %} 9853 9854 // use opcode to indicate that this is an add not a sub 9855 opcode(0x0); 9856 9857 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9858 9859 ins_pipe(ialu_reg_imm); 9860 %} 9861 9862 // Pointer Addition 9863 instruct addP_reg_reg(iRegPNoSp dst, iRegPorL2P src1, iRegL src2) %{ 9864 match(Set dst (AddP src1 src2)); 9865 9866 ins_cost(INSN_COST); 9867 format %{ "add $dst, $src1, $src2\t# ptr" %} 9868 9869 ins_encode %{ 9870 __ add(as_Register($dst$$reg), 9871 as_Register($src1$$reg), 9872 as_Register($src2$$reg)); 9873 %} 9874 9875 ins_pipe(ialu_reg_reg); 9876 %} 9877 9878 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2) %{ 9879 match(Set dst (AddP src1 (ConvI2L src2))); 9880 9881 ins_cost(1.9 * INSN_COST); 9882 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9883 9884 ins_encode %{ 9885 __ add(as_Register($dst$$reg), 9886 as_Register($src1$$reg), 9887 as_Register($src2$$reg), ext::sxtw); 9888 %} 9889 9890 ins_pipe(ialu_reg_reg); 9891 %} 9892 9893 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegPorL2P src1, iRegL src2, immIScale scale) %{ 9894 match(Set dst (AddP src1 (LShiftL src2 scale))); 9895 9896 ins_cost(1.9 * INSN_COST); 9897 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9898 9899 ins_encode %{ 9900 __ lea(as_Register($dst$$reg), 9901 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9902 Address::lsl($scale$$constant))); 9903 %} 9904 9905 ins_pipe(ialu_reg_reg_shift); 9906 %} 9907 9908 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2, immIScale scale) %{ 9909 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9910 9911 ins_cost(1.9 * INSN_COST); 9912 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9913 9914 ins_encode %{ 9915 __ lea(as_Register($dst$$reg), 9916 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9917 Address::sxtw($scale$$constant))); 9918 %} 9919 9920 ins_pipe(ialu_reg_reg_shift); 9921 %} 9922 9923 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9924 match(Set dst (LShiftL (ConvI2L src) scale)); 9925 9926 ins_cost(INSN_COST); 9927 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9928 9929 ins_encode %{ 9930 __ sbfiz(as_Register($dst$$reg), 9931 as_Register($src$$reg), 9932 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 9933 %} 9934 9935 ins_pipe(ialu_reg_shift); 9936 %} 9937 9938 // Pointer Immediate Addition 9939 // n.b. this needs to be more expensive than using an indirect memory 9940 // operand 9941 instruct addP_reg_imm(iRegPNoSp dst, iRegPorL2P src1, immLAddSub src2) %{ 9942 match(Set dst (AddP src1 src2)); 9943 9944 ins_cost(INSN_COST); 9945 format %{ "add $dst, $src1, $src2\t# ptr" %} 9946 9947 // use opcode to indicate that this is an add not a sub 9948 opcode(0x0); 9949 9950 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9951 9952 ins_pipe(ialu_reg_imm); 9953 %} 9954 9955 // Long Addition 9956 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9957 9958 match(Set dst (AddL src1 src2)); 9959 9960 ins_cost(INSN_COST); 9961 format %{ "add $dst, $src1, $src2" %} 9962 9963 ins_encode %{ 9964 __ add(as_Register($dst$$reg), 9965 as_Register($src1$$reg), 9966 as_Register($src2$$reg)); 9967 %} 9968 9969 ins_pipe(ialu_reg_reg); 9970 %} 9971 9972 // No constant pool entries requiredLong Immediate Addition. 9973 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9974 match(Set dst (AddL src1 src2)); 9975 9976 ins_cost(INSN_COST); 9977 format %{ "add $dst, $src1, $src2" %} 9978 9979 // use opcode to indicate that this is an add not a sub 9980 opcode(0x0); 9981 9982 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9983 9984 ins_pipe(ialu_reg_imm); 9985 %} 9986 9987 // Integer Subtraction 9988 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9989 match(Set dst (SubI src1 src2)); 9990 9991 ins_cost(INSN_COST); 9992 format %{ "subw $dst, $src1, $src2" %} 9993 9994 ins_encode %{ 9995 __ subw(as_Register($dst$$reg), 9996 as_Register($src1$$reg), 9997 as_Register($src2$$reg)); 9998 %} 9999 10000 ins_pipe(ialu_reg_reg); 10001 %} 10002 10003 // Immediate Subtraction 10004 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10005 match(Set dst (SubI src1 src2)); 10006 10007 ins_cost(INSN_COST); 10008 format %{ "subw $dst, $src1, $src2" %} 10009 10010 // use opcode to indicate that this is a sub not an add 10011 opcode(0x1); 10012 10013 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10014 10015 ins_pipe(ialu_reg_imm); 10016 %} 10017 10018 // Long Subtraction 10019 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10020 10021 match(Set dst (SubL src1 src2)); 10022 10023 ins_cost(INSN_COST); 10024 format %{ "sub $dst, $src1, $src2" %} 10025 10026 ins_encode %{ 10027 __ sub(as_Register($dst$$reg), 10028 as_Register($src1$$reg), 10029 as_Register($src2$$reg)); 10030 %} 10031 10032 ins_pipe(ialu_reg_reg); 10033 %} 10034 10035 // No constant pool entries requiredLong Immediate Subtraction. 10036 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10037 match(Set dst (SubL src1 src2)); 10038 10039 ins_cost(INSN_COST); 10040 format %{ "sub$dst, $src1, $src2" %} 10041 10042 // use opcode to indicate that this is a sub not an add 10043 opcode(0x1); 10044 10045 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10046 10047 ins_pipe(ialu_reg_imm); 10048 %} 10049 10050 // Integer Negation (special case for sub) 10051 10052 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10053 match(Set dst (SubI zero src)); 10054 10055 ins_cost(INSN_COST); 10056 format %{ "negw $dst, $src\t# int" %} 10057 10058 ins_encode %{ 10059 __ negw(as_Register($dst$$reg), 10060 as_Register($src$$reg)); 10061 %} 10062 10063 ins_pipe(ialu_reg); 10064 %} 10065 10066 // Long Negation 10067 10068 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10069 match(Set dst (SubL zero src)); 10070 10071 ins_cost(INSN_COST); 10072 format %{ "neg $dst, $src\t# long" %} 10073 10074 ins_encode %{ 10075 __ neg(as_Register($dst$$reg), 10076 as_Register($src$$reg)); 10077 %} 10078 10079 ins_pipe(ialu_reg); 10080 %} 10081 10082 // Integer Multiply 10083 10084 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10085 match(Set dst (MulI src1 src2)); 10086 10087 ins_cost(INSN_COST * 3); 10088 format %{ "mulw $dst, $src1, $src2" %} 10089 10090 ins_encode %{ 10091 __ mulw(as_Register($dst$$reg), 10092 as_Register($src1$$reg), 10093 as_Register($src2$$reg)); 10094 %} 10095 10096 ins_pipe(imul_reg_reg); 10097 %} 10098 10099 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10100 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10101 10102 ins_cost(INSN_COST * 3); 10103 format %{ "smull $dst, $src1, $src2" %} 10104 10105 ins_encode %{ 10106 __ smull(as_Register($dst$$reg), 10107 as_Register($src1$$reg), 10108 as_Register($src2$$reg)); 10109 %} 10110 10111 ins_pipe(imul_reg_reg); 10112 %} 10113 10114 // Long Multiply 10115 10116 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10117 match(Set dst (MulL src1 src2)); 10118 10119 ins_cost(INSN_COST * 5); 10120 format %{ "mul $dst, $src1, $src2" %} 10121 10122 ins_encode %{ 10123 __ mul(as_Register($dst$$reg), 10124 as_Register($src1$$reg), 10125 as_Register($src2$$reg)); 10126 %} 10127 10128 ins_pipe(lmul_reg_reg); 10129 %} 10130 10131 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10132 %{ 10133 match(Set dst (MulHiL src1 src2)); 10134 10135 ins_cost(INSN_COST * 7); 10136 format %{ "smulh $dst, $src1, $src2\t# mulhi" %} 10137 10138 ins_encode %{ 10139 __ smulh(as_Register($dst$$reg), 10140 as_Register($src1$$reg), 10141 as_Register($src2$$reg)); 10142 %} 10143 10144 ins_pipe(lmul_reg_reg); 10145 %} 10146 10147 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10148 %{ 10149 match(Set dst (UMulHiL src1 src2)); 10150 10151 ins_cost(INSN_COST * 7); 10152 format %{ "umulh $dst, $src1, $src2\t# umulhi" %} 10153 10154 ins_encode %{ 10155 __ umulh(as_Register($dst$$reg), 10156 as_Register($src1$$reg), 10157 as_Register($src2$$reg)); 10158 %} 10159 10160 ins_pipe(lmul_reg_reg); 10161 %} 10162 10163 // Combined Integer Multiply & Add/Sub 10164 10165 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10166 match(Set dst (AddI src3 (MulI src1 src2))); 10167 10168 ins_cost(INSN_COST * 3); 10169 format %{ "madd $dst, $src1, $src2, $src3" %} 10170 10171 ins_encode %{ 10172 __ maddw(as_Register($dst$$reg), 10173 as_Register($src1$$reg), 10174 as_Register($src2$$reg), 10175 as_Register($src3$$reg)); 10176 %} 10177 10178 ins_pipe(imac_reg_reg); 10179 %} 10180 10181 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10182 match(Set dst (SubI src3 (MulI src1 src2))); 10183 10184 ins_cost(INSN_COST * 3); 10185 format %{ "msub $dst, $src1, $src2, $src3" %} 10186 10187 ins_encode %{ 10188 __ msubw(as_Register($dst$$reg), 10189 as_Register($src1$$reg), 10190 as_Register($src2$$reg), 10191 as_Register($src3$$reg)); 10192 %} 10193 10194 ins_pipe(imac_reg_reg); 10195 %} 10196 10197 // Combined Integer Multiply & Neg 10198 10199 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10200 match(Set dst (MulI (SubI zero src1) src2)); 10201 10202 ins_cost(INSN_COST * 3); 10203 format %{ "mneg $dst, $src1, $src2" %} 10204 10205 ins_encode %{ 10206 __ mnegw(as_Register($dst$$reg), 10207 as_Register($src1$$reg), 10208 as_Register($src2$$reg)); 10209 %} 10210 10211 ins_pipe(imac_reg_reg); 10212 %} 10213 10214 // Combined Long Multiply & Add/Sub 10215 10216 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10217 match(Set dst (AddL src3 (MulL src1 src2))); 10218 10219 ins_cost(INSN_COST * 5); 10220 format %{ "madd $dst, $src1, $src2, $src3" %} 10221 10222 ins_encode %{ 10223 __ madd(as_Register($dst$$reg), 10224 as_Register($src1$$reg), 10225 as_Register($src2$$reg), 10226 as_Register($src3$$reg)); 10227 %} 10228 10229 ins_pipe(lmac_reg_reg); 10230 %} 10231 10232 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10233 match(Set dst (SubL src3 (MulL src1 src2))); 10234 10235 ins_cost(INSN_COST * 5); 10236 format %{ "msub $dst, $src1, $src2, $src3" %} 10237 10238 ins_encode %{ 10239 __ msub(as_Register($dst$$reg), 10240 as_Register($src1$$reg), 10241 as_Register($src2$$reg), 10242 as_Register($src3$$reg)); 10243 %} 10244 10245 ins_pipe(lmac_reg_reg); 10246 %} 10247 10248 // Combined Long Multiply & Neg 10249 10250 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10251 match(Set dst (MulL (SubL zero src1) src2)); 10252 10253 ins_cost(INSN_COST * 5); 10254 format %{ "mneg $dst, $src1, $src2" %} 10255 10256 ins_encode %{ 10257 __ mneg(as_Register($dst$$reg), 10258 as_Register($src1$$reg), 10259 as_Register($src2$$reg)); 10260 %} 10261 10262 ins_pipe(lmac_reg_reg); 10263 %} 10264 10265 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10266 10267 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10268 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10269 10270 ins_cost(INSN_COST * 3); 10271 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10272 10273 ins_encode %{ 10274 __ smaddl(as_Register($dst$$reg), 10275 as_Register($src1$$reg), 10276 as_Register($src2$$reg), 10277 as_Register($src3$$reg)); 10278 %} 10279 10280 ins_pipe(imac_reg_reg); 10281 %} 10282 10283 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10284 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10285 10286 ins_cost(INSN_COST * 3); 10287 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10288 10289 ins_encode %{ 10290 __ smsubl(as_Register($dst$$reg), 10291 as_Register($src1$$reg), 10292 as_Register($src2$$reg), 10293 as_Register($src3$$reg)); 10294 %} 10295 10296 ins_pipe(imac_reg_reg); 10297 %} 10298 10299 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10300 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10301 10302 ins_cost(INSN_COST * 3); 10303 format %{ "smnegl $dst, $src1, $src2" %} 10304 10305 ins_encode %{ 10306 __ smnegl(as_Register($dst$$reg), 10307 as_Register($src1$$reg), 10308 as_Register($src2$$reg)); 10309 %} 10310 10311 ins_pipe(imac_reg_reg); 10312 %} 10313 10314 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10315 10316 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10317 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10318 10319 ins_cost(INSN_COST * 5); 10320 format %{ "mulw rscratch1, $src1, $src2\n\t" 10321 "maddw $dst, $src3, $src4, rscratch1" %} 10322 10323 ins_encode %{ 10324 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10325 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10326 10327 ins_pipe(imac_reg_reg); 10328 %} 10329 10330 // Integer Divide 10331 10332 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10333 match(Set dst (DivI src1 src2)); 10334 10335 ins_cost(INSN_COST * 19); 10336 format %{ "sdivw $dst, $src1, $src2" %} 10337 10338 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10339 ins_pipe(idiv_reg_reg); 10340 %} 10341 10342 // Long Divide 10343 10344 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10345 match(Set dst (DivL src1 src2)); 10346 10347 ins_cost(INSN_COST * 35); 10348 format %{ "sdiv $dst, $src1, $src2" %} 10349 10350 ins_encode(aarch64_enc_div(dst, src1, src2)); 10351 ins_pipe(ldiv_reg_reg); 10352 %} 10353 10354 // Integer Remainder 10355 10356 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10357 match(Set dst (ModI src1 src2)); 10358 10359 ins_cost(INSN_COST * 22); 10360 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10361 "msubw $dst, rscratch1, $src2, $src1" %} 10362 10363 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10364 ins_pipe(idiv_reg_reg); 10365 %} 10366 10367 // Long Remainder 10368 10369 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10370 match(Set dst (ModL src1 src2)); 10371 10372 ins_cost(INSN_COST * 38); 10373 format %{ "sdiv rscratch1, $src1, $src2\n" 10374 "msub $dst, rscratch1, $src2, $src1" %} 10375 10376 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10377 ins_pipe(ldiv_reg_reg); 10378 %} 10379 10380 // Unsigned Integer Divide 10381 10382 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10383 match(Set dst (UDivI src1 src2)); 10384 10385 ins_cost(INSN_COST * 19); 10386 format %{ "udivw $dst, $src1, $src2" %} 10387 10388 ins_encode %{ 10389 __ udivw($dst$$Register, $src1$$Register, $src2$$Register); 10390 %} 10391 10392 ins_pipe(idiv_reg_reg); 10393 %} 10394 10395 // Unsigned Long Divide 10396 10397 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10398 match(Set dst (UDivL src1 src2)); 10399 10400 ins_cost(INSN_COST * 35); 10401 format %{ "udiv $dst, $src1, $src2" %} 10402 10403 ins_encode %{ 10404 __ udiv($dst$$Register, $src1$$Register, $src2$$Register); 10405 %} 10406 10407 ins_pipe(ldiv_reg_reg); 10408 %} 10409 10410 // Unsigned Integer Remainder 10411 10412 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10413 match(Set dst (UModI src1 src2)); 10414 10415 ins_cost(INSN_COST * 22); 10416 format %{ "udivw rscratch1, $src1, $src2\n\t" 10417 "msubw $dst, rscratch1, $src2, $src1" %} 10418 10419 ins_encode %{ 10420 __ udivw(rscratch1, $src1$$Register, $src2$$Register); 10421 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10422 %} 10423 10424 ins_pipe(idiv_reg_reg); 10425 %} 10426 10427 // Unsigned Long Remainder 10428 10429 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10430 match(Set dst (UModL src1 src2)); 10431 10432 ins_cost(INSN_COST * 38); 10433 format %{ "udiv rscratch1, $src1, $src2\n" 10434 "msub $dst, rscratch1, $src2, $src1" %} 10435 10436 ins_encode %{ 10437 __ udiv(rscratch1, $src1$$Register, $src2$$Register); 10438 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10439 %} 10440 10441 ins_pipe(ldiv_reg_reg); 10442 %} 10443 10444 // Integer Shifts 10445 10446 // Shift Left Register 10447 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10448 match(Set dst (LShiftI src1 src2)); 10449 10450 ins_cost(INSN_COST * 2); 10451 format %{ "lslvw $dst, $src1, $src2" %} 10452 10453 ins_encode %{ 10454 __ lslvw(as_Register($dst$$reg), 10455 as_Register($src1$$reg), 10456 as_Register($src2$$reg)); 10457 %} 10458 10459 ins_pipe(ialu_reg_reg_vshift); 10460 %} 10461 10462 // Shift Left Immediate 10463 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10464 match(Set dst (LShiftI src1 src2)); 10465 10466 ins_cost(INSN_COST); 10467 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10468 10469 ins_encode %{ 10470 __ lslw(as_Register($dst$$reg), 10471 as_Register($src1$$reg), 10472 $src2$$constant & 0x1f); 10473 %} 10474 10475 ins_pipe(ialu_reg_shift); 10476 %} 10477 10478 // Shift Right Logical Register 10479 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10480 match(Set dst (URShiftI src1 src2)); 10481 10482 ins_cost(INSN_COST * 2); 10483 format %{ "lsrvw $dst, $src1, $src2" %} 10484 10485 ins_encode %{ 10486 __ lsrvw(as_Register($dst$$reg), 10487 as_Register($src1$$reg), 10488 as_Register($src2$$reg)); 10489 %} 10490 10491 ins_pipe(ialu_reg_reg_vshift); 10492 %} 10493 10494 // Shift Right Logical Immediate 10495 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10496 match(Set dst (URShiftI src1 src2)); 10497 10498 ins_cost(INSN_COST); 10499 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10500 10501 ins_encode %{ 10502 __ lsrw(as_Register($dst$$reg), 10503 as_Register($src1$$reg), 10504 $src2$$constant & 0x1f); 10505 %} 10506 10507 ins_pipe(ialu_reg_shift); 10508 %} 10509 10510 // Shift Right Arithmetic Register 10511 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10512 match(Set dst (RShiftI src1 src2)); 10513 10514 ins_cost(INSN_COST * 2); 10515 format %{ "asrvw $dst, $src1, $src2" %} 10516 10517 ins_encode %{ 10518 __ asrvw(as_Register($dst$$reg), 10519 as_Register($src1$$reg), 10520 as_Register($src2$$reg)); 10521 %} 10522 10523 ins_pipe(ialu_reg_reg_vshift); 10524 %} 10525 10526 // Shift Right Arithmetic Immediate 10527 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10528 match(Set dst (RShiftI src1 src2)); 10529 10530 ins_cost(INSN_COST); 10531 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10532 10533 ins_encode %{ 10534 __ asrw(as_Register($dst$$reg), 10535 as_Register($src1$$reg), 10536 $src2$$constant & 0x1f); 10537 %} 10538 10539 ins_pipe(ialu_reg_shift); 10540 %} 10541 10542 // Combined Int Mask and Right Shift (using UBFM) 10543 // TODO 10544 10545 // Long Shifts 10546 10547 // Shift Left Register 10548 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10549 match(Set dst (LShiftL src1 src2)); 10550 10551 ins_cost(INSN_COST * 2); 10552 format %{ "lslv $dst, $src1, $src2" %} 10553 10554 ins_encode %{ 10555 __ lslv(as_Register($dst$$reg), 10556 as_Register($src1$$reg), 10557 as_Register($src2$$reg)); 10558 %} 10559 10560 ins_pipe(ialu_reg_reg_vshift); 10561 %} 10562 10563 // Shift Left Immediate 10564 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10565 match(Set dst (LShiftL src1 src2)); 10566 10567 ins_cost(INSN_COST); 10568 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10569 10570 ins_encode %{ 10571 __ lsl(as_Register($dst$$reg), 10572 as_Register($src1$$reg), 10573 $src2$$constant & 0x3f); 10574 %} 10575 10576 ins_pipe(ialu_reg_shift); 10577 %} 10578 10579 // Shift Right Logical Register 10580 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10581 match(Set dst (URShiftL src1 src2)); 10582 10583 ins_cost(INSN_COST * 2); 10584 format %{ "lsrv $dst, $src1, $src2" %} 10585 10586 ins_encode %{ 10587 __ lsrv(as_Register($dst$$reg), 10588 as_Register($src1$$reg), 10589 as_Register($src2$$reg)); 10590 %} 10591 10592 ins_pipe(ialu_reg_reg_vshift); 10593 %} 10594 10595 // Shift Right Logical Immediate 10596 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10597 match(Set dst (URShiftL src1 src2)); 10598 10599 ins_cost(INSN_COST); 10600 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10601 10602 ins_encode %{ 10603 __ lsr(as_Register($dst$$reg), 10604 as_Register($src1$$reg), 10605 $src2$$constant & 0x3f); 10606 %} 10607 10608 ins_pipe(ialu_reg_shift); 10609 %} 10610 10611 // A special-case pattern for card table stores. 10612 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10613 match(Set dst (URShiftL (CastP2X src1) src2)); 10614 10615 ins_cost(INSN_COST); 10616 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10617 10618 ins_encode %{ 10619 __ lsr(as_Register($dst$$reg), 10620 as_Register($src1$$reg), 10621 $src2$$constant & 0x3f); 10622 %} 10623 10624 ins_pipe(ialu_reg_shift); 10625 %} 10626 10627 // Shift Right Arithmetic Register 10628 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10629 match(Set dst (RShiftL src1 src2)); 10630 10631 ins_cost(INSN_COST * 2); 10632 format %{ "asrv $dst, $src1, $src2" %} 10633 10634 ins_encode %{ 10635 __ asrv(as_Register($dst$$reg), 10636 as_Register($src1$$reg), 10637 as_Register($src2$$reg)); 10638 %} 10639 10640 ins_pipe(ialu_reg_reg_vshift); 10641 %} 10642 10643 // Shift Right Arithmetic Immediate 10644 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10645 match(Set dst (RShiftL src1 src2)); 10646 10647 ins_cost(INSN_COST); 10648 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10649 10650 ins_encode %{ 10651 __ asr(as_Register($dst$$reg), 10652 as_Register($src1$$reg), 10653 $src2$$constant & 0x3f); 10654 %} 10655 10656 ins_pipe(ialu_reg_shift); 10657 %} 10658 10659 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10660 // This section is generated from aarch64_ad.m4 10661 10662 // This pattern is automatically generated from aarch64_ad.m4 10663 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10664 instruct regL_not_reg(iRegLNoSp dst, 10665 iRegL src1, immL_M1 m1, 10666 rFlagsReg cr) %{ 10667 match(Set dst (XorL src1 m1)); 10668 ins_cost(INSN_COST); 10669 format %{ "eon $dst, $src1, zr" %} 10670 10671 ins_encode %{ 10672 __ eon(as_Register($dst$$reg), 10673 as_Register($src1$$reg), 10674 zr, 10675 Assembler::LSL, 0); 10676 %} 10677 10678 ins_pipe(ialu_reg); 10679 %} 10680 10681 // This pattern is automatically generated from aarch64_ad.m4 10682 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10683 instruct regI_not_reg(iRegINoSp dst, 10684 iRegIorL2I src1, immI_M1 m1, 10685 rFlagsReg cr) %{ 10686 match(Set dst (XorI src1 m1)); 10687 ins_cost(INSN_COST); 10688 format %{ "eonw $dst, $src1, zr" %} 10689 10690 ins_encode %{ 10691 __ eonw(as_Register($dst$$reg), 10692 as_Register($src1$$reg), 10693 zr, 10694 Assembler::LSL, 0); 10695 %} 10696 10697 ins_pipe(ialu_reg); 10698 %} 10699 10700 // This pattern is automatically generated from aarch64_ad.m4 10701 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10702 instruct NegI_reg_URShift_reg(iRegINoSp dst, 10703 immI0 zero, iRegIorL2I src1, immI src2) %{ 10704 match(Set dst (SubI zero (URShiftI src1 src2))); 10705 10706 ins_cost(1.9 * INSN_COST); 10707 format %{ "negw $dst, $src1, LSR $src2" %} 10708 10709 ins_encode %{ 10710 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 10711 Assembler::LSR, $src2$$constant & 0x1f); 10712 %} 10713 10714 ins_pipe(ialu_reg_shift); 10715 %} 10716 10717 // This pattern is automatically generated from aarch64_ad.m4 10718 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10719 instruct NegI_reg_RShift_reg(iRegINoSp dst, 10720 immI0 zero, iRegIorL2I src1, immI src2) %{ 10721 match(Set dst (SubI zero (RShiftI src1 src2))); 10722 10723 ins_cost(1.9 * INSN_COST); 10724 format %{ "negw $dst, $src1, ASR $src2" %} 10725 10726 ins_encode %{ 10727 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 10728 Assembler::ASR, $src2$$constant & 0x1f); 10729 %} 10730 10731 ins_pipe(ialu_reg_shift); 10732 %} 10733 10734 // This pattern is automatically generated from aarch64_ad.m4 10735 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10736 instruct NegI_reg_LShift_reg(iRegINoSp dst, 10737 immI0 zero, iRegIorL2I src1, immI src2) %{ 10738 match(Set dst (SubI zero (LShiftI src1 src2))); 10739 10740 ins_cost(1.9 * INSN_COST); 10741 format %{ "negw $dst, $src1, LSL $src2" %} 10742 10743 ins_encode %{ 10744 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 10745 Assembler::LSL, $src2$$constant & 0x1f); 10746 %} 10747 10748 ins_pipe(ialu_reg_shift); 10749 %} 10750 10751 // This pattern is automatically generated from aarch64_ad.m4 10752 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10753 instruct NegL_reg_URShift_reg(iRegLNoSp dst, 10754 immL0 zero, iRegL src1, immI src2) %{ 10755 match(Set dst (SubL zero (URShiftL src1 src2))); 10756 10757 ins_cost(1.9 * INSN_COST); 10758 format %{ "neg $dst, $src1, LSR $src2" %} 10759 10760 ins_encode %{ 10761 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 10762 Assembler::LSR, $src2$$constant & 0x3f); 10763 %} 10764 10765 ins_pipe(ialu_reg_shift); 10766 %} 10767 10768 // This pattern is automatically generated from aarch64_ad.m4 10769 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10770 instruct NegL_reg_RShift_reg(iRegLNoSp dst, 10771 immL0 zero, iRegL src1, immI src2) %{ 10772 match(Set dst (SubL zero (RShiftL src1 src2))); 10773 10774 ins_cost(1.9 * INSN_COST); 10775 format %{ "neg $dst, $src1, ASR $src2" %} 10776 10777 ins_encode %{ 10778 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 10779 Assembler::ASR, $src2$$constant & 0x3f); 10780 %} 10781 10782 ins_pipe(ialu_reg_shift); 10783 %} 10784 10785 // This pattern is automatically generated from aarch64_ad.m4 10786 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10787 instruct NegL_reg_LShift_reg(iRegLNoSp dst, 10788 immL0 zero, iRegL src1, immI src2) %{ 10789 match(Set dst (SubL zero (LShiftL src1 src2))); 10790 10791 ins_cost(1.9 * INSN_COST); 10792 format %{ "neg $dst, $src1, LSL $src2" %} 10793 10794 ins_encode %{ 10795 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 10796 Assembler::LSL, $src2$$constant & 0x3f); 10797 %} 10798 10799 ins_pipe(ialu_reg_shift); 10800 %} 10801 10802 // This pattern is automatically generated from aarch64_ad.m4 10803 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10804 instruct AndI_reg_not_reg(iRegINoSp dst, 10805 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 10806 match(Set dst (AndI src1 (XorI src2 m1))); 10807 ins_cost(INSN_COST); 10808 format %{ "bicw $dst, $src1, $src2" %} 10809 10810 ins_encode %{ 10811 __ bicw(as_Register($dst$$reg), 10812 as_Register($src1$$reg), 10813 as_Register($src2$$reg), 10814 Assembler::LSL, 0); 10815 %} 10816 10817 ins_pipe(ialu_reg_reg); 10818 %} 10819 10820 // This pattern is automatically generated from aarch64_ad.m4 10821 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10822 instruct AndL_reg_not_reg(iRegLNoSp dst, 10823 iRegL src1, iRegL src2, immL_M1 m1) %{ 10824 match(Set dst (AndL src1 (XorL src2 m1))); 10825 ins_cost(INSN_COST); 10826 format %{ "bic $dst, $src1, $src2" %} 10827 10828 ins_encode %{ 10829 __ bic(as_Register($dst$$reg), 10830 as_Register($src1$$reg), 10831 as_Register($src2$$reg), 10832 Assembler::LSL, 0); 10833 %} 10834 10835 ins_pipe(ialu_reg_reg); 10836 %} 10837 10838 // This pattern is automatically generated from aarch64_ad.m4 10839 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10840 instruct OrI_reg_not_reg(iRegINoSp dst, 10841 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 10842 match(Set dst (OrI src1 (XorI src2 m1))); 10843 ins_cost(INSN_COST); 10844 format %{ "ornw $dst, $src1, $src2" %} 10845 10846 ins_encode %{ 10847 __ ornw(as_Register($dst$$reg), 10848 as_Register($src1$$reg), 10849 as_Register($src2$$reg), 10850 Assembler::LSL, 0); 10851 %} 10852 10853 ins_pipe(ialu_reg_reg); 10854 %} 10855 10856 // This pattern is automatically generated from aarch64_ad.m4 10857 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10858 instruct OrL_reg_not_reg(iRegLNoSp dst, 10859 iRegL src1, iRegL src2, immL_M1 m1) %{ 10860 match(Set dst (OrL src1 (XorL src2 m1))); 10861 ins_cost(INSN_COST); 10862 format %{ "orn $dst, $src1, $src2" %} 10863 10864 ins_encode %{ 10865 __ orn(as_Register($dst$$reg), 10866 as_Register($src1$$reg), 10867 as_Register($src2$$reg), 10868 Assembler::LSL, 0); 10869 %} 10870 10871 ins_pipe(ialu_reg_reg); 10872 %} 10873 10874 // This pattern is automatically generated from aarch64_ad.m4 10875 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10876 instruct XorI_reg_not_reg(iRegINoSp dst, 10877 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 10878 match(Set dst (XorI m1 (XorI src2 src1))); 10879 ins_cost(INSN_COST); 10880 format %{ "eonw $dst, $src1, $src2" %} 10881 10882 ins_encode %{ 10883 __ eonw(as_Register($dst$$reg), 10884 as_Register($src1$$reg), 10885 as_Register($src2$$reg), 10886 Assembler::LSL, 0); 10887 %} 10888 10889 ins_pipe(ialu_reg_reg); 10890 %} 10891 10892 // This pattern is automatically generated from aarch64_ad.m4 10893 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10894 instruct XorL_reg_not_reg(iRegLNoSp dst, 10895 iRegL src1, iRegL src2, immL_M1 m1) %{ 10896 match(Set dst (XorL m1 (XorL src2 src1))); 10897 ins_cost(INSN_COST); 10898 format %{ "eon $dst, $src1, $src2" %} 10899 10900 ins_encode %{ 10901 __ eon(as_Register($dst$$reg), 10902 as_Register($src1$$reg), 10903 as_Register($src2$$reg), 10904 Assembler::LSL, 0); 10905 %} 10906 10907 ins_pipe(ialu_reg_reg); 10908 %} 10909 10910 // This pattern is automatically generated from aarch64_ad.m4 10911 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10912 // val & (-1 ^ (val >>> shift)) ==> bicw 10913 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10914 iRegIorL2I src1, iRegIorL2I src2, 10915 immI src3, immI_M1 src4) %{ 10916 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10917 ins_cost(1.9 * INSN_COST); 10918 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10919 10920 ins_encode %{ 10921 __ bicw(as_Register($dst$$reg), 10922 as_Register($src1$$reg), 10923 as_Register($src2$$reg), 10924 Assembler::LSR, 10925 $src3$$constant & 0x1f); 10926 %} 10927 10928 ins_pipe(ialu_reg_reg_shift); 10929 %} 10930 10931 // This pattern is automatically generated from aarch64_ad.m4 10932 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10933 // val & (-1 ^ (val >>> shift)) ==> bic 10934 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10935 iRegL src1, iRegL src2, 10936 immI src3, immL_M1 src4) %{ 10937 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10938 ins_cost(1.9 * INSN_COST); 10939 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10940 10941 ins_encode %{ 10942 __ bic(as_Register($dst$$reg), 10943 as_Register($src1$$reg), 10944 as_Register($src2$$reg), 10945 Assembler::LSR, 10946 $src3$$constant & 0x3f); 10947 %} 10948 10949 ins_pipe(ialu_reg_reg_shift); 10950 %} 10951 10952 // This pattern is automatically generated from aarch64_ad.m4 10953 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10954 // val & (-1 ^ (val >> shift)) ==> bicw 10955 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10956 iRegIorL2I src1, iRegIorL2I src2, 10957 immI src3, immI_M1 src4) %{ 10958 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10959 ins_cost(1.9 * INSN_COST); 10960 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10961 10962 ins_encode %{ 10963 __ bicw(as_Register($dst$$reg), 10964 as_Register($src1$$reg), 10965 as_Register($src2$$reg), 10966 Assembler::ASR, 10967 $src3$$constant & 0x1f); 10968 %} 10969 10970 ins_pipe(ialu_reg_reg_shift); 10971 %} 10972 10973 // This pattern is automatically generated from aarch64_ad.m4 10974 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10975 // val & (-1 ^ (val >> shift)) ==> bic 10976 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10977 iRegL src1, iRegL src2, 10978 immI src3, immL_M1 src4) %{ 10979 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10980 ins_cost(1.9 * INSN_COST); 10981 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10982 10983 ins_encode %{ 10984 __ bic(as_Register($dst$$reg), 10985 as_Register($src1$$reg), 10986 as_Register($src2$$reg), 10987 Assembler::ASR, 10988 $src3$$constant & 0x3f); 10989 %} 10990 10991 ins_pipe(ialu_reg_reg_shift); 10992 %} 10993 10994 // This pattern is automatically generated from aarch64_ad.m4 10995 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10996 // val & (-1 ^ (val ror shift)) ==> bicw 10997 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst, 10998 iRegIorL2I src1, iRegIorL2I src2, 10999 immI src3, immI_M1 src4) %{ 11000 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4))); 11001 ins_cost(1.9 * INSN_COST); 11002 format %{ "bicw $dst, $src1, $src2, ROR $src3" %} 11003 11004 ins_encode %{ 11005 __ bicw(as_Register($dst$$reg), 11006 as_Register($src1$$reg), 11007 as_Register($src2$$reg), 11008 Assembler::ROR, 11009 $src3$$constant & 0x1f); 11010 %} 11011 11012 ins_pipe(ialu_reg_reg_shift); 11013 %} 11014 11015 // This pattern is automatically generated from aarch64_ad.m4 11016 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11017 // val & (-1 ^ (val ror shift)) ==> bic 11018 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst, 11019 iRegL src1, iRegL src2, 11020 immI src3, immL_M1 src4) %{ 11021 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4))); 11022 ins_cost(1.9 * INSN_COST); 11023 format %{ "bic $dst, $src1, $src2, ROR $src3" %} 11024 11025 ins_encode %{ 11026 __ bic(as_Register($dst$$reg), 11027 as_Register($src1$$reg), 11028 as_Register($src2$$reg), 11029 Assembler::ROR, 11030 $src3$$constant & 0x3f); 11031 %} 11032 11033 ins_pipe(ialu_reg_reg_shift); 11034 %} 11035 11036 // This pattern is automatically generated from aarch64_ad.m4 11037 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11038 // val & (-1 ^ (val << shift)) ==> bicw 11039 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11040 iRegIorL2I src1, iRegIorL2I src2, 11041 immI src3, immI_M1 src4) %{ 11042 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11043 ins_cost(1.9 * INSN_COST); 11044 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11045 11046 ins_encode %{ 11047 __ bicw(as_Register($dst$$reg), 11048 as_Register($src1$$reg), 11049 as_Register($src2$$reg), 11050 Assembler::LSL, 11051 $src3$$constant & 0x1f); 11052 %} 11053 11054 ins_pipe(ialu_reg_reg_shift); 11055 %} 11056 11057 // This pattern is automatically generated from aarch64_ad.m4 11058 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11059 // val & (-1 ^ (val << shift)) ==> bic 11060 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11061 iRegL src1, iRegL src2, 11062 immI src3, immL_M1 src4) %{ 11063 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11064 ins_cost(1.9 * INSN_COST); 11065 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11066 11067 ins_encode %{ 11068 __ bic(as_Register($dst$$reg), 11069 as_Register($src1$$reg), 11070 as_Register($src2$$reg), 11071 Assembler::LSL, 11072 $src3$$constant & 0x3f); 11073 %} 11074 11075 ins_pipe(ialu_reg_reg_shift); 11076 %} 11077 11078 // This pattern is automatically generated from aarch64_ad.m4 11079 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11080 // val ^ (-1 ^ (val >>> shift)) ==> eonw 11081 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11082 iRegIorL2I src1, iRegIorL2I src2, 11083 immI src3, immI_M1 src4) %{ 11084 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11085 ins_cost(1.9 * INSN_COST); 11086 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11087 11088 ins_encode %{ 11089 __ eonw(as_Register($dst$$reg), 11090 as_Register($src1$$reg), 11091 as_Register($src2$$reg), 11092 Assembler::LSR, 11093 $src3$$constant & 0x1f); 11094 %} 11095 11096 ins_pipe(ialu_reg_reg_shift); 11097 %} 11098 11099 // This pattern is automatically generated from aarch64_ad.m4 11100 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11101 // val ^ (-1 ^ (val >>> shift)) ==> eon 11102 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11103 iRegL src1, iRegL src2, 11104 immI src3, immL_M1 src4) %{ 11105 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11106 ins_cost(1.9 * INSN_COST); 11107 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11108 11109 ins_encode %{ 11110 __ eon(as_Register($dst$$reg), 11111 as_Register($src1$$reg), 11112 as_Register($src2$$reg), 11113 Assembler::LSR, 11114 $src3$$constant & 0x3f); 11115 %} 11116 11117 ins_pipe(ialu_reg_reg_shift); 11118 %} 11119 11120 // This pattern is automatically generated from aarch64_ad.m4 11121 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11122 // val ^ (-1 ^ (val >> shift)) ==> eonw 11123 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11124 iRegIorL2I src1, iRegIorL2I src2, 11125 immI src3, immI_M1 src4) %{ 11126 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11127 ins_cost(1.9 * INSN_COST); 11128 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11129 11130 ins_encode %{ 11131 __ eonw(as_Register($dst$$reg), 11132 as_Register($src1$$reg), 11133 as_Register($src2$$reg), 11134 Assembler::ASR, 11135 $src3$$constant & 0x1f); 11136 %} 11137 11138 ins_pipe(ialu_reg_reg_shift); 11139 %} 11140 11141 // This pattern is automatically generated from aarch64_ad.m4 11142 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11143 // val ^ (-1 ^ (val >> shift)) ==> eon 11144 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11145 iRegL src1, iRegL src2, 11146 immI src3, immL_M1 src4) %{ 11147 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11148 ins_cost(1.9 * INSN_COST); 11149 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11150 11151 ins_encode %{ 11152 __ eon(as_Register($dst$$reg), 11153 as_Register($src1$$reg), 11154 as_Register($src2$$reg), 11155 Assembler::ASR, 11156 $src3$$constant & 0x3f); 11157 %} 11158 11159 ins_pipe(ialu_reg_reg_shift); 11160 %} 11161 11162 // This pattern is automatically generated from aarch64_ad.m4 11163 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11164 // val ^ (-1 ^ (val ror shift)) ==> eonw 11165 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst, 11166 iRegIorL2I src1, iRegIorL2I src2, 11167 immI src3, immI_M1 src4) %{ 11168 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1))); 11169 ins_cost(1.9 * INSN_COST); 11170 format %{ "eonw $dst, $src1, $src2, ROR $src3" %} 11171 11172 ins_encode %{ 11173 __ eonw(as_Register($dst$$reg), 11174 as_Register($src1$$reg), 11175 as_Register($src2$$reg), 11176 Assembler::ROR, 11177 $src3$$constant & 0x1f); 11178 %} 11179 11180 ins_pipe(ialu_reg_reg_shift); 11181 %} 11182 11183 // This pattern is automatically generated from aarch64_ad.m4 11184 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11185 // val ^ (-1 ^ (val ror shift)) ==> eon 11186 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst, 11187 iRegL src1, iRegL src2, 11188 immI src3, immL_M1 src4) %{ 11189 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1))); 11190 ins_cost(1.9 * INSN_COST); 11191 format %{ "eon $dst, $src1, $src2, ROR $src3" %} 11192 11193 ins_encode %{ 11194 __ eon(as_Register($dst$$reg), 11195 as_Register($src1$$reg), 11196 as_Register($src2$$reg), 11197 Assembler::ROR, 11198 $src3$$constant & 0x3f); 11199 %} 11200 11201 ins_pipe(ialu_reg_reg_shift); 11202 %} 11203 11204 // This pattern is automatically generated from aarch64_ad.m4 11205 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11206 // val ^ (-1 ^ (val << shift)) ==> eonw 11207 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11208 iRegIorL2I src1, iRegIorL2I src2, 11209 immI src3, immI_M1 src4) %{ 11210 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11211 ins_cost(1.9 * INSN_COST); 11212 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11213 11214 ins_encode %{ 11215 __ eonw(as_Register($dst$$reg), 11216 as_Register($src1$$reg), 11217 as_Register($src2$$reg), 11218 Assembler::LSL, 11219 $src3$$constant & 0x1f); 11220 %} 11221 11222 ins_pipe(ialu_reg_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 // val ^ (-1 ^ (val << shift)) ==> eon 11228 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11229 iRegL src1, iRegL src2, 11230 immI src3, immL_M1 src4) %{ 11231 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11232 ins_cost(1.9 * INSN_COST); 11233 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11234 11235 ins_encode %{ 11236 __ eon(as_Register($dst$$reg), 11237 as_Register($src1$$reg), 11238 as_Register($src2$$reg), 11239 Assembler::LSL, 11240 $src3$$constant & 0x3f); 11241 %} 11242 11243 ins_pipe(ialu_reg_reg_shift); 11244 %} 11245 11246 // This pattern is automatically generated from aarch64_ad.m4 11247 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11248 // val | (-1 ^ (val >>> shift)) ==> ornw 11249 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11250 iRegIorL2I src1, iRegIorL2I src2, 11251 immI src3, immI_M1 src4) %{ 11252 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11253 ins_cost(1.9 * INSN_COST); 11254 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11255 11256 ins_encode %{ 11257 __ ornw(as_Register($dst$$reg), 11258 as_Register($src1$$reg), 11259 as_Register($src2$$reg), 11260 Assembler::LSR, 11261 $src3$$constant & 0x1f); 11262 %} 11263 11264 ins_pipe(ialu_reg_reg_shift); 11265 %} 11266 11267 // This pattern is automatically generated from aarch64_ad.m4 11268 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11269 // val | (-1 ^ (val >>> shift)) ==> orn 11270 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11271 iRegL src1, iRegL src2, 11272 immI src3, immL_M1 src4) %{ 11273 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11274 ins_cost(1.9 * INSN_COST); 11275 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11276 11277 ins_encode %{ 11278 __ orn(as_Register($dst$$reg), 11279 as_Register($src1$$reg), 11280 as_Register($src2$$reg), 11281 Assembler::LSR, 11282 $src3$$constant & 0x3f); 11283 %} 11284 11285 ins_pipe(ialu_reg_reg_shift); 11286 %} 11287 11288 // This pattern is automatically generated from aarch64_ad.m4 11289 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11290 // val | (-1 ^ (val >> shift)) ==> ornw 11291 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11292 iRegIorL2I src1, iRegIorL2I src2, 11293 immI src3, immI_M1 src4) %{ 11294 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11295 ins_cost(1.9 * INSN_COST); 11296 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11297 11298 ins_encode %{ 11299 __ ornw(as_Register($dst$$reg), 11300 as_Register($src1$$reg), 11301 as_Register($src2$$reg), 11302 Assembler::ASR, 11303 $src3$$constant & 0x1f); 11304 %} 11305 11306 ins_pipe(ialu_reg_reg_shift); 11307 %} 11308 11309 // This pattern is automatically generated from aarch64_ad.m4 11310 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11311 // val | (-1 ^ (val >> shift)) ==> orn 11312 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11313 iRegL src1, iRegL src2, 11314 immI src3, immL_M1 src4) %{ 11315 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11316 ins_cost(1.9 * INSN_COST); 11317 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11318 11319 ins_encode %{ 11320 __ orn(as_Register($dst$$reg), 11321 as_Register($src1$$reg), 11322 as_Register($src2$$reg), 11323 Assembler::ASR, 11324 $src3$$constant & 0x3f); 11325 %} 11326 11327 ins_pipe(ialu_reg_reg_shift); 11328 %} 11329 11330 // This pattern is automatically generated from aarch64_ad.m4 11331 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11332 // val | (-1 ^ (val ror shift)) ==> ornw 11333 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst, 11334 iRegIorL2I src1, iRegIorL2I src2, 11335 immI src3, immI_M1 src4) %{ 11336 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4))); 11337 ins_cost(1.9 * INSN_COST); 11338 format %{ "ornw $dst, $src1, $src2, ROR $src3" %} 11339 11340 ins_encode %{ 11341 __ ornw(as_Register($dst$$reg), 11342 as_Register($src1$$reg), 11343 as_Register($src2$$reg), 11344 Assembler::ROR, 11345 $src3$$constant & 0x1f); 11346 %} 11347 11348 ins_pipe(ialu_reg_reg_shift); 11349 %} 11350 11351 // This pattern is automatically generated from aarch64_ad.m4 11352 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11353 // val | (-1 ^ (val ror shift)) ==> orn 11354 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst, 11355 iRegL src1, iRegL src2, 11356 immI src3, immL_M1 src4) %{ 11357 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4))); 11358 ins_cost(1.9 * INSN_COST); 11359 format %{ "orn $dst, $src1, $src2, ROR $src3" %} 11360 11361 ins_encode %{ 11362 __ orn(as_Register($dst$$reg), 11363 as_Register($src1$$reg), 11364 as_Register($src2$$reg), 11365 Assembler::ROR, 11366 $src3$$constant & 0x3f); 11367 %} 11368 11369 ins_pipe(ialu_reg_reg_shift); 11370 %} 11371 11372 // This pattern is automatically generated from aarch64_ad.m4 11373 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11374 // val | (-1 ^ (val << shift)) ==> ornw 11375 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11376 iRegIorL2I src1, iRegIorL2I src2, 11377 immI src3, immI_M1 src4) %{ 11378 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11379 ins_cost(1.9 * INSN_COST); 11380 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11381 11382 ins_encode %{ 11383 __ ornw(as_Register($dst$$reg), 11384 as_Register($src1$$reg), 11385 as_Register($src2$$reg), 11386 Assembler::LSL, 11387 $src3$$constant & 0x1f); 11388 %} 11389 11390 ins_pipe(ialu_reg_reg_shift); 11391 %} 11392 11393 // This pattern is automatically generated from aarch64_ad.m4 11394 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11395 // val | (-1 ^ (val << shift)) ==> orn 11396 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11397 iRegL src1, iRegL src2, 11398 immI src3, immL_M1 src4) %{ 11399 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11400 ins_cost(1.9 * INSN_COST); 11401 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11402 11403 ins_encode %{ 11404 __ orn(as_Register($dst$$reg), 11405 as_Register($src1$$reg), 11406 as_Register($src2$$reg), 11407 Assembler::LSL, 11408 $src3$$constant & 0x3f); 11409 %} 11410 11411 ins_pipe(ialu_reg_reg_shift); 11412 %} 11413 11414 // This pattern is automatically generated from aarch64_ad.m4 11415 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11416 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11417 iRegIorL2I src1, iRegIorL2I src2, 11418 immI src3) %{ 11419 match(Set dst (AndI src1 (URShiftI src2 src3))); 11420 11421 ins_cost(1.9 * INSN_COST); 11422 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11423 11424 ins_encode %{ 11425 __ andw(as_Register($dst$$reg), 11426 as_Register($src1$$reg), 11427 as_Register($src2$$reg), 11428 Assembler::LSR, 11429 $src3$$constant & 0x1f); 11430 %} 11431 11432 ins_pipe(ialu_reg_reg_shift); 11433 %} 11434 11435 // This pattern is automatically generated from aarch64_ad.m4 11436 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11437 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11438 iRegL src1, iRegL src2, 11439 immI src3) %{ 11440 match(Set dst (AndL src1 (URShiftL src2 src3))); 11441 11442 ins_cost(1.9 * INSN_COST); 11443 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11444 11445 ins_encode %{ 11446 __ andr(as_Register($dst$$reg), 11447 as_Register($src1$$reg), 11448 as_Register($src2$$reg), 11449 Assembler::LSR, 11450 $src3$$constant & 0x3f); 11451 %} 11452 11453 ins_pipe(ialu_reg_reg_shift); 11454 %} 11455 11456 // This pattern is automatically generated from aarch64_ad.m4 11457 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11458 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11459 iRegIorL2I src1, iRegIorL2I src2, 11460 immI src3) %{ 11461 match(Set dst (AndI src1 (RShiftI src2 src3))); 11462 11463 ins_cost(1.9 * INSN_COST); 11464 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11465 11466 ins_encode %{ 11467 __ andw(as_Register($dst$$reg), 11468 as_Register($src1$$reg), 11469 as_Register($src2$$reg), 11470 Assembler::ASR, 11471 $src3$$constant & 0x1f); 11472 %} 11473 11474 ins_pipe(ialu_reg_reg_shift); 11475 %} 11476 11477 // This pattern is automatically generated from aarch64_ad.m4 11478 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11479 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11480 iRegL src1, iRegL src2, 11481 immI src3) %{ 11482 match(Set dst (AndL src1 (RShiftL src2 src3))); 11483 11484 ins_cost(1.9 * INSN_COST); 11485 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11486 11487 ins_encode %{ 11488 __ andr(as_Register($dst$$reg), 11489 as_Register($src1$$reg), 11490 as_Register($src2$$reg), 11491 Assembler::ASR, 11492 $src3$$constant & 0x3f); 11493 %} 11494 11495 ins_pipe(ialu_reg_reg_shift); 11496 %} 11497 11498 // This pattern is automatically generated from aarch64_ad.m4 11499 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11500 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11501 iRegIorL2I src1, iRegIorL2I src2, 11502 immI src3) %{ 11503 match(Set dst (AndI src1 (LShiftI src2 src3))); 11504 11505 ins_cost(1.9 * INSN_COST); 11506 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11507 11508 ins_encode %{ 11509 __ andw(as_Register($dst$$reg), 11510 as_Register($src1$$reg), 11511 as_Register($src2$$reg), 11512 Assembler::LSL, 11513 $src3$$constant & 0x1f); 11514 %} 11515 11516 ins_pipe(ialu_reg_reg_shift); 11517 %} 11518 11519 // This pattern is automatically generated from aarch64_ad.m4 11520 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11521 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11522 iRegL src1, iRegL src2, 11523 immI src3) %{ 11524 match(Set dst (AndL src1 (LShiftL src2 src3))); 11525 11526 ins_cost(1.9 * INSN_COST); 11527 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11528 11529 ins_encode %{ 11530 __ andr(as_Register($dst$$reg), 11531 as_Register($src1$$reg), 11532 as_Register($src2$$reg), 11533 Assembler::LSL, 11534 $src3$$constant & 0x3f); 11535 %} 11536 11537 ins_pipe(ialu_reg_reg_shift); 11538 %} 11539 11540 // This pattern is automatically generated from aarch64_ad.m4 11541 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11542 instruct AndI_reg_RotateRight_reg(iRegINoSp dst, 11543 iRegIorL2I src1, iRegIorL2I src2, 11544 immI src3) %{ 11545 match(Set dst (AndI src1 (RotateRight src2 src3))); 11546 11547 ins_cost(1.9 * INSN_COST); 11548 format %{ "andw $dst, $src1, $src2, ROR $src3" %} 11549 11550 ins_encode %{ 11551 __ andw(as_Register($dst$$reg), 11552 as_Register($src1$$reg), 11553 as_Register($src2$$reg), 11554 Assembler::ROR, 11555 $src3$$constant & 0x1f); 11556 %} 11557 11558 ins_pipe(ialu_reg_reg_shift); 11559 %} 11560 11561 // This pattern is automatically generated from aarch64_ad.m4 11562 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11563 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst, 11564 iRegL src1, iRegL src2, 11565 immI src3) %{ 11566 match(Set dst (AndL src1 (RotateRight src2 src3))); 11567 11568 ins_cost(1.9 * INSN_COST); 11569 format %{ "andr $dst, $src1, $src2, ROR $src3" %} 11570 11571 ins_encode %{ 11572 __ andr(as_Register($dst$$reg), 11573 as_Register($src1$$reg), 11574 as_Register($src2$$reg), 11575 Assembler::ROR, 11576 $src3$$constant & 0x3f); 11577 %} 11578 11579 ins_pipe(ialu_reg_reg_shift); 11580 %} 11581 11582 // This pattern is automatically generated from aarch64_ad.m4 11583 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11584 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11585 iRegIorL2I src1, iRegIorL2I src2, 11586 immI src3) %{ 11587 match(Set dst (XorI src1 (URShiftI src2 src3))); 11588 11589 ins_cost(1.9 * INSN_COST); 11590 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11591 11592 ins_encode %{ 11593 __ eorw(as_Register($dst$$reg), 11594 as_Register($src1$$reg), 11595 as_Register($src2$$reg), 11596 Assembler::LSR, 11597 $src3$$constant & 0x1f); 11598 %} 11599 11600 ins_pipe(ialu_reg_reg_shift); 11601 %} 11602 11603 // This pattern is automatically generated from aarch64_ad.m4 11604 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11605 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11606 iRegL src1, iRegL src2, 11607 immI src3) %{ 11608 match(Set dst (XorL src1 (URShiftL src2 src3))); 11609 11610 ins_cost(1.9 * INSN_COST); 11611 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11612 11613 ins_encode %{ 11614 __ eor(as_Register($dst$$reg), 11615 as_Register($src1$$reg), 11616 as_Register($src2$$reg), 11617 Assembler::LSR, 11618 $src3$$constant & 0x3f); 11619 %} 11620 11621 ins_pipe(ialu_reg_reg_shift); 11622 %} 11623 11624 // This pattern is automatically generated from aarch64_ad.m4 11625 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11626 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11627 iRegIorL2I src1, iRegIorL2I src2, 11628 immI src3) %{ 11629 match(Set dst (XorI src1 (RShiftI src2 src3))); 11630 11631 ins_cost(1.9 * INSN_COST); 11632 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11633 11634 ins_encode %{ 11635 __ eorw(as_Register($dst$$reg), 11636 as_Register($src1$$reg), 11637 as_Register($src2$$reg), 11638 Assembler::ASR, 11639 $src3$$constant & 0x1f); 11640 %} 11641 11642 ins_pipe(ialu_reg_reg_shift); 11643 %} 11644 11645 // This pattern is automatically generated from aarch64_ad.m4 11646 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11647 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11648 iRegL src1, iRegL src2, 11649 immI src3) %{ 11650 match(Set dst (XorL src1 (RShiftL src2 src3))); 11651 11652 ins_cost(1.9 * INSN_COST); 11653 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11654 11655 ins_encode %{ 11656 __ eor(as_Register($dst$$reg), 11657 as_Register($src1$$reg), 11658 as_Register($src2$$reg), 11659 Assembler::ASR, 11660 $src3$$constant & 0x3f); 11661 %} 11662 11663 ins_pipe(ialu_reg_reg_shift); 11664 %} 11665 11666 // This pattern is automatically generated from aarch64_ad.m4 11667 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11668 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11669 iRegIorL2I src1, iRegIorL2I src2, 11670 immI src3) %{ 11671 match(Set dst (XorI src1 (LShiftI src2 src3))); 11672 11673 ins_cost(1.9 * INSN_COST); 11674 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11675 11676 ins_encode %{ 11677 __ eorw(as_Register($dst$$reg), 11678 as_Register($src1$$reg), 11679 as_Register($src2$$reg), 11680 Assembler::LSL, 11681 $src3$$constant & 0x1f); 11682 %} 11683 11684 ins_pipe(ialu_reg_reg_shift); 11685 %} 11686 11687 // This pattern is automatically generated from aarch64_ad.m4 11688 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11689 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11690 iRegL src1, iRegL src2, 11691 immI src3) %{ 11692 match(Set dst (XorL src1 (LShiftL src2 src3))); 11693 11694 ins_cost(1.9 * INSN_COST); 11695 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11696 11697 ins_encode %{ 11698 __ eor(as_Register($dst$$reg), 11699 as_Register($src1$$reg), 11700 as_Register($src2$$reg), 11701 Assembler::LSL, 11702 $src3$$constant & 0x3f); 11703 %} 11704 11705 ins_pipe(ialu_reg_reg_shift); 11706 %} 11707 11708 // This pattern is automatically generated from aarch64_ad.m4 11709 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11710 instruct XorI_reg_RotateRight_reg(iRegINoSp dst, 11711 iRegIorL2I src1, iRegIorL2I src2, 11712 immI src3) %{ 11713 match(Set dst (XorI src1 (RotateRight src2 src3))); 11714 11715 ins_cost(1.9 * INSN_COST); 11716 format %{ "eorw $dst, $src1, $src2, ROR $src3" %} 11717 11718 ins_encode %{ 11719 __ eorw(as_Register($dst$$reg), 11720 as_Register($src1$$reg), 11721 as_Register($src2$$reg), 11722 Assembler::ROR, 11723 $src3$$constant & 0x1f); 11724 %} 11725 11726 ins_pipe(ialu_reg_reg_shift); 11727 %} 11728 11729 // This pattern is automatically generated from aarch64_ad.m4 11730 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11731 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst, 11732 iRegL src1, iRegL src2, 11733 immI src3) %{ 11734 match(Set dst (XorL src1 (RotateRight src2 src3))); 11735 11736 ins_cost(1.9 * INSN_COST); 11737 format %{ "eor $dst, $src1, $src2, ROR $src3" %} 11738 11739 ins_encode %{ 11740 __ eor(as_Register($dst$$reg), 11741 as_Register($src1$$reg), 11742 as_Register($src2$$reg), 11743 Assembler::ROR, 11744 $src3$$constant & 0x3f); 11745 %} 11746 11747 ins_pipe(ialu_reg_reg_shift); 11748 %} 11749 11750 // This pattern is automatically generated from aarch64_ad.m4 11751 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11752 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11753 iRegIorL2I src1, iRegIorL2I src2, 11754 immI src3) %{ 11755 match(Set dst (OrI src1 (URShiftI src2 src3))); 11756 11757 ins_cost(1.9 * INSN_COST); 11758 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11759 11760 ins_encode %{ 11761 __ orrw(as_Register($dst$$reg), 11762 as_Register($src1$$reg), 11763 as_Register($src2$$reg), 11764 Assembler::LSR, 11765 $src3$$constant & 0x1f); 11766 %} 11767 11768 ins_pipe(ialu_reg_reg_shift); 11769 %} 11770 11771 // This pattern is automatically generated from aarch64_ad.m4 11772 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11773 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11774 iRegL src1, iRegL src2, 11775 immI src3) %{ 11776 match(Set dst (OrL src1 (URShiftL src2 src3))); 11777 11778 ins_cost(1.9 * INSN_COST); 11779 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11780 11781 ins_encode %{ 11782 __ orr(as_Register($dst$$reg), 11783 as_Register($src1$$reg), 11784 as_Register($src2$$reg), 11785 Assembler::LSR, 11786 $src3$$constant & 0x3f); 11787 %} 11788 11789 ins_pipe(ialu_reg_reg_shift); 11790 %} 11791 11792 // This pattern is automatically generated from aarch64_ad.m4 11793 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11794 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11795 iRegIorL2I src1, iRegIorL2I src2, 11796 immI src3) %{ 11797 match(Set dst (OrI src1 (RShiftI src2 src3))); 11798 11799 ins_cost(1.9 * INSN_COST); 11800 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11801 11802 ins_encode %{ 11803 __ orrw(as_Register($dst$$reg), 11804 as_Register($src1$$reg), 11805 as_Register($src2$$reg), 11806 Assembler::ASR, 11807 $src3$$constant & 0x1f); 11808 %} 11809 11810 ins_pipe(ialu_reg_reg_shift); 11811 %} 11812 11813 // This pattern is automatically generated from aarch64_ad.m4 11814 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11815 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11816 iRegL src1, iRegL src2, 11817 immI src3) %{ 11818 match(Set dst (OrL src1 (RShiftL src2 src3))); 11819 11820 ins_cost(1.9 * INSN_COST); 11821 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11822 11823 ins_encode %{ 11824 __ orr(as_Register($dst$$reg), 11825 as_Register($src1$$reg), 11826 as_Register($src2$$reg), 11827 Assembler::ASR, 11828 $src3$$constant & 0x3f); 11829 %} 11830 11831 ins_pipe(ialu_reg_reg_shift); 11832 %} 11833 11834 // This pattern is automatically generated from aarch64_ad.m4 11835 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11836 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11837 iRegIorL2I src1, iRegIorL2I src2, 11838 immI src3) %{ 11839 match(Set dst (OrI src1 (LShiftI src2 src3))); 11840 11841 ins_cost(1.9 * INSN_COST); 11842 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11843 11844 ins_encode %{ 11845 __ orrw(as_Register($dst$$reg), 11846 as_Register($src1$$reg), 11847 as_Register($src2$$reg), 11848 Assembler::LSL, 11849 $src3$$constant & 0x1f); 11850 %} 11851 11852 ins_pipe(ialu_reg_reg_shift); 11853 %} 11854 11855 // This pattern is automatically generated from aarch64_ad.m4 11856 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11857 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11858 iRegL src1, iRegL src2, 11859 immI src3) %{ 11860 match(Set dst (OrL src1 (LShiftL src2 src3))); 11861 11862 ins_cost(1.9 * INSN_COST); 11863 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11864 11865 ins_encode %{ 11866 __ orr(as_Register($dst$$reg), 11867 as_Register($src1$$reg), 11868 as_Register($src2$$reg), 11869 Assembler::LSL, 11870 $src3$$constant & 0x3f); 11871 %} 11872 11873 ins_pipe(ialu_reg_reg_shift); 11874 %} 11875 11876 // This pattern is automatically generated from aarch64_ad.m4 11877 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11878 instruct OrI_reg_RotateRight_reg(iRegINoSp dst, 11879 iRegIorL2I src1, iRegIorL2I src2, 11880 immI src3) %{ 11881 match(Set dst (OrI src1 (RotateRight src2 src3))); 11882 11883 ins_cost(1.9 * INSN_COST); 11884 format %{ "orrw $dst, $src1, $src2, ROR $src3" %} 11885 11886 ins_encode %{ 11887 __ orrw(as_Register($dst$$reg), 11888 as_Register($src1$$reg), 11889 as_Register($src2$$reg), 11890 Assembler::ROR, 11891 $src3$$constant & 0x1f); 11892 %} 11893 11894 ins_pipe(ialu_reg_reg_shift); 11895 %} 11896 11897 // This pattern is automatically generated from aarch64_ad.m4 11898 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11899 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst, 11900 iRegL src1, iRegL src2, 11901 immI src3) %{ 11902 match(Set dst (OrL src1 (RotateRight src2 src3))); 11903 11904 ins_cost(1.9 * INSN_COST); 11905 format %{ "orr $dst, $src1, $src2, ROR $src3" %} 11906 11907 ins_encode %{ 11908 __ orr(as_Register($dst$$reg), 11909 as_Register($src1$$reg), 11910 as_Register($src2$$reg), 11911 Assembler::ROR, 11912 $src3$$constant & 0x3f); 11913 %} 11914 11915 ins_pipe(ialu_reg_reg_shift); 11916 %} 11917 11918 // This pattern is automatically generated from aarch64_ad.m4 11919 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11920 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11921 iRegIorL2I src1, iRegIorL2I src2, 11922 immI src3) %{ 11923 match(Set dst (AddI src1 (URShiftI src2 src3))); 11924 11925 ins_cost(1.9 * INSN_COST); 11926 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11927 11928 ins_encode %{ 11929 __ addw(as_Register($dst$$reg), 11930 as_Register($src1$$reg), 11931 as_Register($src2$$reg), 11932 Assembler::LSR, 11933 $src3$$constant & 0x1f); 11934 %} 11935 11936 ins_pipe(ialu_reg_reg_shift); 11937 %} 11938 11939 // This pattern is automatically generated from aarch64_ad.m4 11940 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11941 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11942 iRegL src1, iRegL src2, 11943 immI src3) %{ 11944 match(Set dst (AddL src1 (URShiftL src2 src3))); 11945 11946 ins_cost(1.9 * INSN_COST); 11947 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11948 11949 ins_encode %{ 11950 __ add(as_Register($dst$$reg), 11951 as_Register($src1$$reg), 11952 as_Register($src2$$reg), 11953 Assembler::LSR, 11954 $src3$$constant & 0x3f); 11955 %} 11956 11957 ins_pipe(ialu_reg_reg_shift); 11958 %} 11959 11960 // This pattern is automatically generated from aarch64_ad.m4 11961 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11962 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11963 iRegIorL2I src1, iRegIorL2I src2, 11964 immI src3) %{ 11965 match(Set dst (AddI src1 (RShiftI src2 src3))); 11966 11967 ins_cost(1.9 * INSN_COST); 11968 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11969 11970 ins_encode %{ 11971 __ addw(as_Register($dst$$reg), 11972 as_Register($src1$$reg), 11973 as_Register($src2$$reg), 11974 Assembler::ASR, 11975 $src3$$constant & 0x1f); 11976 %} 11977 11978 ins_pipe(ialu_reg_reg_shift); 11979 %} 11980 11981 // This pattern is automatically generated from aarch64_ad.m4 11982 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11983 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11984 iRegL src1, iRegL src2, 11985 immI src3) %{ 11986 match(Set dst (AddL src1 (RShiftL src2 src3))); 11987 11988 ins_cost(1.9 * INSN_COST); 11989 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11990 11991 ins_encode %{ 11992 __ add(as_Register($dst$$reg), 11993 as_Register($src1$$reg), 11994 as_Register($src2$$reg), 11995 Assembler::ASR, 11996 $src3$$constant & 0x3f); 11997 %} 11998 11999 ins_pipe(ialu_reg_reg_shift); 12000 %} 12001 12002 // This pattern is automatically generated from aarch64_ad.m4 12003 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12004 instruct AddI_reg_LShift_reg(iRegINoSp dst, 12005 iRegIorL2I src1, iRegIorL2I src2, 12006 immI src3) %{ 12007 match(Set dst (AddI src1 (LShiftI src2 src3))); 12008 12009 ins_cost(1.9 * INSN_COST); 12010 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 12011 12012 ins_encode %{ 12013 __ addw(as_Register($dst$$reg), 12014 as_Register($src1$$reg), 12015 as_Register($src2$$reg), 12016 Assembler::LSL, 12017 $src3$$constant & 0x1f); 12018 %} 12019 12020 ins_pipe(ialu_reg_reg_shift); 12021 %} 12022 12023 // This pattern is automatically generated from aarch64_ad.m4 12024 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12025 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 12026 iRegL src1, iRegL src2, 12027 immI src3) %{ 12028 match(Set dst (AddL src1 (LShiftL src2 src3))); 12029 12030 ins_cost(1.9 * INSN_COST); 12031 format %{ "add $dst, $src1, $src2, LSL $src3" %} 12032 12033 ins_encode %{ 12034 __ add(as_Register($dst$$reg), 12035 as_Register($src1$$reg), 12036 as_Register($src2$$reg), 12037 Assembler::LSL, 12038 $src3$$constant & 0x3f); 12039 %} 12040 12041 ins_pipe(ialu_reg_reg_shift); 12042 %} 12043 12044 // This pattern is automatically generated from aarch64_ad.m4 12045 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12046 instruct SubI_reg_URShift_reg(iRegINoSp dst, 12047 iRegIorL2I src1, iRegIorL2I src2, 12048 immI src3) %{ 12049 match(Set dst (SubI src1 (URShiftI src2 src3))); 12050 12051 ins_cost(1.9 * INSN_COST); 12052 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 12053 12054 ins_encode %{ 12055 __ subw(as_Register($dst$$reg), 12056 as_Register($src1$$reg), 12057 as_Register($src2$$reg), 12058 Assembler::LSR, 12059 $src3$$constant & 0x1f); 12060 %} 12061 12062 ins_pipe(ialu_reg_reg_shift); 12063 %} 12064 12065 // This pattern is automatically generated from aarch64_ad.m4 12066 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12067 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 12068 iRegL src1, iRegL src2, 12069 immI src3) %{ 12070 match(Set dst (SubL src1 (URShiftL src2 src3))); 12071 12072 ins_cost(1.9 * INSN_COST); 12073 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 12074 12075 ins_encode %{ 12076 __ sub(as_Register($dst$$reg), 12077 as_Register($src1$$reg), 12078 as_Register($src2$$reg), 12079 Assembler::LSR, 12080 $src3$$constant & 0x3f); 12081 %} 12082 12083 ins_pipe(ialu_reg_reg_shift); 12084 %} 12085 12086 // This pattern is automatically generated from aarch64_ad.m4 12087 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12088 instruct SubI_reg_RShift_reg(iRegINoSp dst, 12089 iRegIorL2I src1, iRegIorL2I src2, 12090 immI src3) %{ 12091 match(Set dst (SubI src1 (RShiftI src2 src3))); 12092 12093 ins_cost(1.9 * INSN_COST); 12094 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 12095 12096 ins_encode %{ 12097 __ subw(as_Register($dst$$reg), 12098 as_Register($src1$$reg), 12099 as_Register($src2$$reg), 12100 Assembler::ASR, 12101 $src3$$constant & 0x1f); 12102 %} 12103 12104 ins_pipe(ialu_reg_reg_shift); 12105 %} 12106 12107 // This pattern is automatically generated from aarch64_ad.m4 12108 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12109 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 12110 iRegL src1, iRegL src2, 12111 immI src3) %{ 12112 match(Set dst (SubL src1 (RShiftL src2 src3))); 12113 12114 ins_cost(1.9 * INSN_COST); 12115 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 12116 12117 ins_encode %{ 12118 __ sub(as_Register($dst$$reg), 12119 as_Register($src1$$reg), 12120 as_Register($src2$$reg), 12121 Assembler::ASR, 12122 $src3$$constant & 0x3f); 12123 %} 12124 12125 ins_pipe(ialu_reg_reg_shift); 12126 %} 12127 12128 // This pattern is automatically generated from aarch64_ad.m4 12129 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12130 instruct SubI_reg_LShift_reg(iRegINoSp dst, 12131 iRegIorL2I src1, iRegIorL2I src2, 12132 immI src3) %{ 12133 match(Set dst (SubI src1 (LShiftI src2 src3))); 12134 12135 ins_cost(1.9 * INSN_COST); 12136 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 12137 12138 ins_encode %{ 12139 __ subw(as_Register($dst$$reg), 12140 as_Register($src1$$reg), 12141 as_Register($src2$$reg), 12142 Assembler::LSL, 12143 $src3$$constant & 0x1f); 12144 %} 12145 12146 ins_pipe(ialu_reg_reg_shift); 12147 %} 12148 12149 // This pattern is automatically generated from aarch64_ad.m4 12150 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12151 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 12152 iRegL src1, iRegL src2, 12153 immI src3) %{ 12154 match(Set dst (SubL src1 (LShiftL src2 src3))); 12155 12156 ins_cost(1.9 * INSN_COST); 12157 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 12158 12159 ins_encode %{ 12160 __ sub(as_Register($dst$$reg), 12161 as_Register($src1$$reg), 12162 as_Register($src2$$reg), 12163 Assembler::LSL, 12164 $src3$$constant & 0x3f); 12165 %} 12166 12167 ins_pipe(ialu_reg_reg_shift); 12168 %} 12169 12170 // This pattern is automatically generated from aarch64_ad.m4 12171 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12172 12173 // Shift Left followed by Shift Right. 12174 // This idiom is used by the compiler for the i2b bytecode etc. 12175 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12176 %{ 12177 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12178 ins_cost(INSN_COST * 2); 12179 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12180 ins_encode %{ 12181 int lshift = $lshift_count$$constant & 63; 12182 int rshift = $rshift_count$$constant & 63; 12183 int s = 63 - lshift; 12184 int r = (rshift - lshift) & 63; 12185 __ sbfm(as_Register($dst$$reg), 12186 as_Register($src$$reg), 12187 r, s); 12188 %} 12189 12190 ins_pipe(ialu_reg_shift); 12191 %} 12192 12193 // This pattern is automatically generated from aarch64_ad.m4 12194 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12195 12196 // Shift Left followed by Shift Right. 12197 // This idiom is used by the compiler for the i2b bytecode etc. 12198 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12199 %{ 12200 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12201 ins_cost(INSN_COST * 2); 12202 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12203 ins_encode %{ 12204 int lshift = $lshift_count$$constant & 31; 12205 int rshift = $rshift_count$$constant & 31; 12206 int s = 31 - lshift; 12207 int r = (rshift - lshift) & 31; 12208 __ sbfmw(as_Register($dst$$reg), 12209 as_Register($src$$reg), 12210 r, s); 12211 %} 12212 12213 ins_pipe(ialu_reg_shift); 12214 %} 12215 12216 // This pattern is automatically generated from aarch64_ad.m4 12217 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12218 12219 // Shift Left followed by Shift Right. 12220 // This idiom is used by the compiler for the i2b bytecode etc. 12221 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12222 %{ 12223 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12224 ins_cost(INSN_COST * 2); 12225 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12226 ins_encode %{ 12227 int lshift = $lshift_count$$constant & 63; 12228 int rshift = $rshift_count$$constant & 63; 12229 int s = 63 - lshift; 12230 int r = (rshift - lshift) & 63; 12231 __ ubfm(as_Register($dst$$reg), 12232 as_Register($src$$reg), 12233 r, s); 12234 %} 12235 12236 ins_pipe(ialu_reg_shift); 12237 %} 12238 12239 // This pattern is automatically generated from aarch64_ad.m4 12240 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12241 12242 // Shift Left followed by Shift Right. 12243 // This idiom is used by the compiler for the i2b bytecode etc. 12244 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12245 %{ 12246 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12247 ins_cost(INSN_COST * 2); 12248 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12249 ins_encode %{ 12250 int lshift = $lshift_count$$constant & 31; 12251 int rshift = $rshift_count$$constant & 31; 12252 int s = 31 - lshift; 12253 int r = (rshift - lshift) & 31; 12254 __ ubfmw(as_Register($dst$$reg), 12255 as_Register($src$$reg), 12256 r, s); 12257 %} 12258 12259 ins_pipe(ialu_reg_shift); 12260 %} 12261 12262 // Bitfield extract with shift & mask 12263 12264 // This pattern is automatically generated from aarch64_ad.m4 12265 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12266 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12267 %{ 12268 match(Set dst (AndI (URShiftI src rshift) mask)); 12269 // Make sure we are not going to exceed what ubfxw can do. 12270 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12271 12272 ins_cost(INSN_COST); 12273 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12274 ins_encode %{ 12275 int rshift = $rshift$$constant & 31; 12276 intptr_t mask = $mask$$constant; 12277 int width = exact_log2(mask+1); 12278 __ ubfxw(as_Register($dst$$reg), 12279 as_Register($src$$reg), rshift, width); 12280 %} 12281 ins_pipe(ialu_reg_shift); 12282 %} 12283 12284 // This pattern is automatically generated from aarch64_ad.m4 12285 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12286 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12287 %{ 12288 match(Set dst (AndL (URShiftL src rshift) mask)); 12289 // Make sure we are not going to exceed what ubfx can do. 12290 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12291 12292 ins_cost(INSN_COST); 12293 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12294 ins_encode %{ 12295 int rshift = $rshift$$constant & 63; 12296 intptr_t mask = $mask$$constant; 12297 int width = exact_log2_long(mask+1); 12298 __ ubfx(as_Register($dst$$reg), 12299 as_Register($src$$reg), rshift, width); 12300 %} 12301 ins_pipe(ialu_reg_shift); 12302 %} 12303 12304 12305 // This pattern is automatically generated from aarch64_ad.m4 12306 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12307 12308 // We can use ubfx when extending an And with a mask when we know mask 12309 // is positive. We know that because immI_bitmask guarantees it. 12310 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12311 %{ 12312 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12313 // Make sure we are not going to exceed what ubfxw can do. 12314 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12315 12316 ins_cost(INSN_COST * 2); 12317 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12318 ins_encode %{ 12319 int rshift = $rshift$$constant & 31; 12320 intptr_t mask = $mask$$constant; 12321 int width = exact_log2(mask+1); 12322 __ ubfx(as_Register($dst$$reg), 12323 as_Register($src$$reg), rshift, width); 12324 %} 12325 ins_pipe(ialu_reg_shift); 12326 %} 12327 12328 12329 // This pattern is automatically generated from aarch64_ad.m4 12330 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12331 12332 // We can use ubfiz when masking by a positive number and then left shifting the result. 12333 // We know that the mask is positive because immI_bitmask guarantees it. 12334 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12335 %{ 12336 match(Set dst (LShiftI (AndI src mask) lshift)); 12337 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12338 12339 ins_cost(INSN_COST); 12340 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12341 ins_encode %{ 12342 int lshift = $lshift$$constant & 31; 12343 intptr_t mask = $mask$$constant; 12344 int width = exact_log2(mask+1); 12345 __ ubfizw(as_Register($dst$$reg), 12346 as_Register($src$$reg), lshift, width); 12347 %} 12348 ins_pipe(ialu_reg_shift); 12349 %} 12350 12351 // This pattern is automatically generated from aarch64_ad.m4 12352 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12353 12354 // We can use ubfiz when masking by a positive number and then left shifting the result. 12355 // We know that the mask is positive because immL_bitmask guarantees it. 12356 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12357 %{ 12358 match(Set dst (LShiftL (AndL src mask) lshift)); 12359 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12360 12361 ins_cost(INSN_COST); 12362 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12363 ins_encode %{ 12364 int lshift = $lshift$$constant & 63; 12365 intptr_t mask = $mask$$constant; 12366 int width = exact_log2_long(mask+1); 12367 __ ubfiz(as_Register($dst$$reg), 12368 as_Register($src$$reg), lshift, width); 12369 %} 12370 ins_pipe(ialu_reg_shift); 12371 %} 12372 12373 // This pattern is automatically generated from aarch64_ad.m4 12374 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12375 12376 // We can use ubfiz when masking by a positive number and then left shifting the result. 12377 // We know that the mask is positive because immI_bitmask guarantees it. 12378 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12379 %{ 12380 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12381 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12382 12383 ins_cost(INSN_COST); 12384 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12385 ins_encode %{ 12386 int lshift = $lshift$$constant & 31; 12387 intptr_t mask = $mask$$constant; 12388 int width = exact_log2(mask+1); 12389 __ ubfizw(as_Register($dst$$reg), 12390 as_Register($src$$reg), lshift, width); 12391 %} 12392 ins_pipe(ialu_reg_shift); 12393 %} 12394 12395 // This pattern is automatically generated from aarch64_ad.m4 12396 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12397 12398 // We can use ubfiz when masking by a positive number and then left shifting the result. 12399 // We know that the mask is positive because immL_bitmask guarantees it. 12400 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12401 %{ 12402 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12403 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12404 12405 ins_cost(INSN_COST); 12406 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12407 ins_encode %{ 12408 int lshift = $lshift$$constant & 63; 12409 intptr_t mask = $mask$$constant; 12410 int width = exact_log2_long(mask+1); 12411 __ ubfiz(as_Register($dst$$reg), 12412 as_Register($src$$reg), lshift, width); 12413 %} 12414 ins_pipe(ialu_reg_shift); 12415 %} 12416 12417 12418 // This pattern is automatically generated from aarch64_ad.m4 12419 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12420 12421 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12422 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12423 %{ 12424 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12425 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12426 12427 ins_cost(INSN_COST); 12428 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12429 ins_encode %{ 12430 int lshift = $lshift$$constant & 63; 12431 intptr_t mask = $mask$$constant; 12432 int width = exact_log2(mask+1); 12433 __ ubfiz(as_Register($dst$$reg), 12434 as_Register($src$$reg), lshift, width); 12435 %} 12436 ins_pipe(ialu_reg_shift); 12437 %} 12438 12439 // This pattern is automatically generated from aarch64_ad.m4 12440 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12441 12442 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12443 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12444 %{ 12445 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12446 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12447 12448 ins_cost(INSN_COST); 12449 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12450 ins_encode %{ 12451 int lshift = $lshift$$constant & 31; 12452 intptr_t mask = $mask$$constant; 12453 int width = exact_log2(mask+1); 12454 __ ubfiz(as_Register($dst$$reg), 12455 as_Register($src$$reg), lshift, width); 12456 %} 12457 ins_pipe(ialu_reg_shift); 12458 %} 12459 12460 // This pattern is automatically generated from aarch64_ad.m4 12461 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12462 12463 // Can skip int2long conversions after AND with small bitmask 12464 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12465 %{ 12466 match(Set dst (ConvI2L (AndI src msk))); 12467 ins_cost(INSN_COST); 12468 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12469 ins_encode %{ 12470 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12471 %} 12472 ins_pipe(ialu_reg_shift); 12473 %} 12474 12475 12476 // Rotations 12477 12478 // This pattern is automatically generated from aarch64_ad.m4 12479 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12480 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12481 %{ 12482 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12483 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12484 12485 ins_cost(INSN_COST); 12486 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12487 12488 ins_encode %{ 12489 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12490 $rshift$$constant & 63); 12491 %} 12492 ins_pipe(ialu_reg_reg_extr); 12493 %} 12494 12495 12496 // This pattern is automatically generated from aarch64_ad.m4 12497 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12498 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12499 %{ 12500 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12501 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12502 12503 ins_cost(INSN_COST); 12504 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12505 12506 ins_encode %{ 12507 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12508 $rshift$$constant & 31); 12509 %} 12510 ins_pipe(ialu_reg_reg_extr); 12511 %} 12512 12513 12514 // This pattern is automatically generated from aarch64_ad.m4 12515 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12516 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12517 %{ 12518 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12519 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12520 12521 ins_cost(INSN_COST); 12522 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12523 12524 ins_encode %{ 12525 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12526 $rshift$$constant & 63); 12527 %} 12528 ins_pipe(ialu_reg_reg_extr); 12529 %} 12530 12531 12532 // This pattern is automatically generated from aarch64_ad.m4 12533 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12534 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12535 %{ 12536 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12537 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12538 12539 ins_cost(INSN_COST); 12540 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12541 12542 ins_encode %{ 12543 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12544 $rshift$$constant & 31); 12545 %} 12546 ins_pipe(ialu_reg_reg_extr); 12547 %} 12548 12549 // This pattern is automatically generated from aarch64_ad.m4 12550 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12551 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift) 12552 %{ 12553 match(Set dst (RotateRight src shift)); 12554 12555 ins_cost(INSN_COST); 12556 format %{ "ror $dst, $src, $shift" %} 12557 12558 ins_encode %{ 12559 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 12560 $shift$$constant & 0x1f); 12561 %} 12562 ins_pipe(ialu_reg_reg_vshift); 12563 %} 12564 12565 // This pattern is automatically generated from aarch64_ad.m4 12566 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12567 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift) 12568 %{ 12569 match(Set dst (RotateRight src shift)); 12570 12571 ins_cost(INSN_COST); 12572 format %{ "ror $dst, $src, $shift" %} 12573 12574 ins_encode %{ 12575 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 12576 $shift$$constant & 0x3f); 12577 %} 12578 ins_pipe(ialu_reg_reg_vshift); 12579 %} 12580 12581 // This pattern is automatically generated from aarch64_ad.m4 12582 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12583 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift) 12584 %{ 12585 match(Set dst (RotateRight src shift)); 12586 12587 ins_cost(INSN_COST); 12588 format %{ "ror $dst, $src, $shift" %} 12589 12590 ins_encode %{ 12591 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 12592 %} 12593 ins_pipe(ialu_reg_reg_vshift); 12594 %} 12595 12596 // This pattern is automatically generated from aarch64_ad.m4 12597 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12598 instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 12599 %{ 12600 match(Set dst (RotateRight src shift)); 12601 12602 ins_cost(INSN_COST); 12603 format %{ "ror $dst, $src, $shift" %} 12604 12605 ins_encode %{ 12606 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 12607 %} 12608 ins_pipe(ialu_reg_reg_vshift); 12609 %} 12610 12611 // This pattern is automatically generated from aarch64_ad.m4 12612 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12613 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift) 12614 %{ 12615 match(Set dst (RotateLeft src shift)); 12616 12617 ins_cost(INSN_COST); 12618 format %{ "rol $dst, $src, $shift" %} 12619 12620 ins_encode %{ 12621 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12622 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 12623 %} 12624 ins_pipe(ialu_reg_reg_vshift); 12625 %} 12626 12627 // This pattern is automatically generated from aarch64_ad.m4 12628 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12629 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 12630 %{ 12631 match(Set dst (RotateLeft src shift)); 12632 12633 ins_cost(INSN_COST); 12634 format %{ "rol $dst, $src, $shift" %} 12635 12636 ins_encode %{ 12637 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12638 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 12639 %} 12640 ins_pipe(ialu_reg_reg_vshift); 12641 %} 12642 12643 12644 // Add/subtract (extended) 12645 12646 // This pattern is automatically generated from aarch64_ad.m4 12647 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12648 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12649 %{ 12650 match(Set dst (AddL src1 (ConvI2L src2))); 12651 ins_cost(INSN_COST); 12652 format %{ "add $dst, $src1, $src2, sxtw" %} 12653 12654 ins_encode %{ 12655 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12656 as_Register($src2$$reg), ext::sxtw); 12657 %} 12658 ins_pipe(ialu_reg_reg); 12659 %} 12660 12661 // This pattern is automatically generated from aarch64_ad.m4 12662 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12663 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12664 %{ 12665 match(Set dst (SubL src1 (ConvI2L src2))); 12666 ins_cost(INSN_COST); 12667 format %{ "sub $dst, $src1, $src2, sxtw" %} 12668 12669 ins_encode %{ 12670 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12671 as_Register($src2$$reg), ext::sxtw); 12672 %} 12673 ins_pipe(ialu_reg_reg); 12674 %} 12675 12676 // This pattern is automatically generated from aarch64_ad.m4 12677 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12678 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12679 %{ 12680 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12681 ins_cost(INSN_COST); 12682 format %{ "add $dst, $src1, $src2, sxth" %} 12683 12684 ins_encode %{ 12685 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12686 as_Register($src2$$reg), ext::sxth); 12687 %} 12688 ins_pipe(ialu_reg_reg); 12689 %} 12690 12691 // This pattern is automatically generated from aarch64_ad.m4 12692 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12693 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12694 %{ 12695 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12696 ins_cost(INSN_COST); 12697 format %{ "add $dst, $src1, $src2, sxtb" %} 12698 12699 ins_encode %{ 12700 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12701 as_Register($src2$$reg), ext::sxtb); 12702 %} 12703 ins_pipe(ialu_reg_reg); 12704 %} 12705 12706 // This pattern is automatically generated from aarch64_ad.m4 12707 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12708 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12709 %{ 12710 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12711 ins_cost(INSN_COST); 12712 format %{ "add $dst, $src1, $src2, uxtb" %} 12713 12714 ins_encode %{ 12715 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12716 as_Register($src2$$reg), ext::uxtb); 12717 %} 12718 ins_pipe(ialu_reg_reg); 12719 %} 12720 12721 // This pattern is automatically generated from aarch64_ad.m4 12722 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12723 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12724 %{ 12725 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12726 ins_cost(INSN_COST); 12727 format %{ "add $dst, $src1, $src2, sxth" %} 12728 12729 ins_encode %{ 12730 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12731 as_Register($src2$$reg), ext::sxth); 12732 %} 12733 ins_pipe(ialu_reg_reg); 12734 %} 12735 12736 // This pattern is automatically generated from aarch64_ad.m4 12737 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12738 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12739 %{ 12740 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12741 ins_cost(INSN_COST); 12742 format %{ "add $dst, $src1, $src2, sxtw" %} 12743 12744 ins_encode %{ 12745 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12746 as_Register($src2$$reg), ext::sxtw); 12747 %} 12748 ins_pipe(ialu_reg_reg); 12749 %} 12750 12751 // This pattern is automatically generated from aarch64_ad.m4 12752 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12753 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12754 %{ 12755 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12756 ins_cost(INSN_COST); 12757 format %{ "add $dst, $src1, $src2, sxtb" %} 12758 12759 ins_encode %{ 12760 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12761 as_Register($src2$$reg), ext::sxtb); 12762 %} 12763 ins_pipe(ialu_reg_reg); 12764 %} 12765 12766 // This pattern is automatically generated from aarch64_ad.m4 12767 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12768 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12769 %{ 12770 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12771 ins_cost(INSN_COST); 12772 format %{ "add $dst, $src1, $src2, uxtb" %} 12773 12774 ins_encode %{ 12775 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12776 as_Register($src2$$reg), ext::uxtb); 12777 %} 12778 ins_pipe(ialu_reg_reg); 12779 %} 12780 12781 // This pattern is automatically generated from aarch64_ad.m4 12782 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12783 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12784 %{ 12785 match(Set dst (AddI src1 (AndI src2 mask))); 12786 ins_cost(INSN_COST); 12787 format %{ "addw $dst, $src1, $src2, uxtb" %} 12788 12789 ins_encode %{ 12790 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12791 as_Register($src2$$reg), ext::uxtb); 12792 %} 12793 ins_pipe(ialu_reg_reg); 12794 %} 12795 12796 // This pattern is automatically generated from aarch64_ad.m4 12797 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12798 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12799 %{ 12800 match(Set dst (AddI src1 (AndI src2 mask))); 12801 ins_cost(INSN_COST); 12802 format %{ "addw $dst, $src1, $src2, uxth" %} 12803 12804 ins_encode %{ 12805 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12806 as_Register($src2$$reg), ext::uxth); 12807 %} 12808 ins_pipe(ialu_reg_reg); 12809 %} 12810 12811 // This pattern is automatically generated from aarch64_ad.m4 12812 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12813 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12814 %{ 12815 match(Set dst (AddL src1 (AndL src2 mask))); 12816 ins_cost(INSN_COST); 12817 format %{ "add $dst, $src1, $src2, uxtb" %} 12818 12819 ins_encode %{ 12820 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12821 as_Register($src2$$reg), ext::uxtb); 12822 %} 12823 ins_pipe(ialu_reg_reg); 12824 %} 12825 12826 // This pattern is automatically generated from aarch64_ad.m4 12827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12828 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12829 %{ 12830 match(Set dst (AddL src1 (AndL src2 mask))); 12831 ins_cost(INSN_COST); 12832 format %{ "add $dst, $src1, $src2, uxth" %} 12833 12834 ins_encode %{ 12835 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12836 as_Register($src2$$reg), ext::uxth); 12837 %} 12838 ins_pipe(ialu_reg_reg); 12839 %} 12840 12841 // This pattern is automatically generated from aarch64_ad.m4 12842 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12843 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12844 %{ 12845 match(Set dst (AddL src1 (AndL src2 mask))); 12846 ins_cost(INSN_COST); 12847 format %{ "add $dst, $src1, $src2, uxtw" %} 12848 12849 ins_encode %{ 12850 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12851 as_Register($src2$$reg), ext::uxtw); 12852 %} 12853 ins_pipe(ialu_reg_reg); 12854 %} 12855 12856 // This pattern is automatically generated from aarch64_ad.m4 12857 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12858 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12859 %{ 12860 match(Set dst (SubI src1 (AndI src2 mask))); 12861 ins_cost(INSN_COST); 12862 format %{ "subw $dst, $src1, $src2, uxtb" %} 12863 12864 ins_encode %{ 12865 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12866 as_Register($src2$$reg), ext::uxtb); 12867 %} 12868 ins_pipe(ialu_reg_reg); 12869 %} 12870 12871 // This pattern is automatically generated from aarch64_ad.m4 12872 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12873 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12874 %{ 12875 match(Set dst (SubI src1 (AndI src2 mask))); 12876 ins_cost(INSN_COST); 12877 format %{ "subw $dst, $src1, $src2, uxth" %} 12878 12879 ins_encode %{ 12880 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12881 as_Register($src2$$reg), ext::uxth); 12882 %} 12883 ins_pipe(ialu_reg_reg); 12884 %} 12885 12886 // This pattern is automatically generated from aarch64_ad.m4 12887 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12888 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12889 %{ 12890 match(Set dst (SubL src1 (AndL src2 mask))); 12891 ins_cost(INSN_COST); 12892 format %{ "sub $dst, $src1, $src2, uxtb" %} 12893 12894 ins_encode %{ 12895 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12896 as_Register($src2$$reg), ext::uxtb); 12897 %} 12898 ins_pipe(ialu_reg_reg); 12899 %} 12900 12901 // This pattern is automatically generated from aarch64_ad.m4 12902 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12903 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12904 %{ 12905 match(Set dst (SubL src1 (AndL src2 mask))); 12906 ins_cost(INSN_COST); 12907 format %{ "sub $dst, $src1, $src2, uxth" %} 12908 12909 ins_encode %{ 12910 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12911 as_Register($src2$$reg), ext::uxth); 12912 %} 12913 ins_pipe(ialu_reg_reg); 12914 %} 12915 12916 // This pattern is automatically generated from aarch64_ad.m4 12917 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12918 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12919 %{ 12920 match(Set dst (SubL src1 (AndL src2 mask))); 12921 ins_cost(INSN_COST); 12922 format %{ "sub $dst, $src1, $src2, uxtw" %} 12923 12924 ins_encode %{ 12925 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12926 as_Register($src2$$reg), ext::uxtw); 12927 %} 12928 ins_pipe(ialu_reg_reg); 12929 %} 12930 12931 12932 // This pattern is automatically generated from aarch64_ad.m4 12933 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12934 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12935 %{ 12936 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12937 ins_cost(1.9 * INSN_COST); 12938 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12939 12940 ins_encode %{ 12941 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12942 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12943 %} 12944 ins_pipe(ialu_reg_reg_shift); 12945 %} 12946 12947 // This pattern is automatically generated from aarch64_ad.m4 12948 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12949 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12950 %{ 12951 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12952 ins_cost(1.9 * INSN_COST); 12953 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12954 12955 ins_encode %{ 12956 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12957 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12958 %} 12959 ins_pipe(ialu_reg_reg_shift); 12960 %} 12961 12962 // This pattern is automatically generated from aarch64_ad.m4 12963 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12964 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12965 %{ 12966 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12967 ins_cost(1.9 * INSN_COST); 12968 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12969 12970 ins_encode %{ 12971 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12972 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12973 %} 12974 ins_pipe(ialu_reg_reg_shift); 12975 %} 12976 12977 // This pattern is automatically generated from aarch64_ad.m4 12978 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12979 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12980 %{ 12981 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12982 ins_cost(1.9 * INSN_COST); 12983 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12984 12985 ins_encode %{ 12986 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12987 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12988 %} 12989 ins_pipe(ialu_reg_reg_shift); 12990 %} 12991 12992 // This pattern is automatically generated from aarch64_ad.m4 12993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12994 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12995 %{ 12996 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12997 ins_cost(1.9 * INSN_COST); 12998 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12999 13000 ins_encode %{ 13001 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13002 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13003 %} 13004 ins_pipe(ialu_reg_reg_shift); 13005 %} 13006 13007 // This pattern is automatically generated from aarch64_ad.m4 13008 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13009 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13010 %{ 13011 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13012 ins_cost(1.9 * INSN_COST); 13013 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 13014 13015 ins_encode %{ 13016 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13017 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13018 %} 13019 ins_pipe(ialu_reg_reg_shift); 13020 %} 13021 13022 // This pattern is automatically generated from aarch64_ad.m4 13023 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13024 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13025 %{ 13026 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13027 ins_cost(1.9 * INSN_COST); 13028 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 13029 13030 ins_encode %{ 13031 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13032 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13033 %} 13034 ins_pipe(ialu_reg_reg_shift); 13035 %} 13036 13037 // This pattern is automatically generated from aarch64_ad.m4 13038 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13039 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13040 %{ 13041 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13042 ins_cost(1.9 * INSN_COST); 13043 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 13044 13045 ins_encode %{ 13046 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13047 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13048 %} 13049 ins_pipe(ialu_reg_reg_shift); 13050 %} 13051 13052 // This pattern is automatically generated from aarch64_ad.m4 13053 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13054 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13055 %{ 13056 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13057 ins_cost(1.9 * INSN_COST); 13058 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 13059 13060 ins_encode %{ 13061 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13062 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13063 %} 13064 ins_pipe(ialu_reg_reg_shift); 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 SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13070 %{ 13071 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13072 ins_cost(1.9 * INSN_COST); 13073 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 13074 13075 ins_encode %{ 13076 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13077 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13078 %} 13079 ins_pipe(ialu_reg_reg_shift); 13080 %} 13081 13082 // This pattern is automatically generated from aarch64_ad.m4 13083 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13084 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13085 %{ 13086 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 13087 ins_cost(1.9 * INSN_COST); 13088 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 13089 13090 ins_encode %{ 13091 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13092 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13093 %} 13094 ins_pipe(ialu_reg_reg_shift); 13095 %} 13096 13097 // This pattern is automatically generated from aarch64_ad.m4 13098 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13099 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13100 %{ 13101 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 13102 ins_cost(1.9 * INSN_COST); 13103 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 13104 13105 ins_encode %{ 13106 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13107 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13108 %} 13109 ins_pipe(ialu_reg_reg_shift); 13110 %} 13111 13112 // This pattern is automatically generated from aarch64_ad.m4 13113 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13114 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13115 %{ 13116 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13117 ins_cost(1.9 * INSN_COST); 13118 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 13119 13120 ins_encode %{ 13121 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13122 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13123 %} 13124 ins_pipe(ialu_reg_reg_shift); 13125 %} 13126 13127 // This pattern is automatically generated from aarch64_ad.m4 13128 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13129 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13130 %{ 13131 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13132 ins_cost(1.9 * INSN_COST); 13133 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 13134 13135 ins_encode %{ 13136 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13137 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13138 %} 13139 ins_pipe(ialu_reg_reg_shift); 13140 %} 13141 13142 // This pattern is automatically generated from aarch64_ad.m4 13143 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13144 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13145 %{ 13146 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13147 ins_cost(1.9 * INSN_COST); 13148 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13149 13150 ins_encode %{ 13151 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13152 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13153 %} 13154 ins_pipe(ialu_reg_reg_shift); 13155 %} 13156 13157 // This pattern is automatically generated from aarch64_ad.m4 13158 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13159 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13160 %{ 13161 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13162 ins_cost(1.9 * INSN_COST); 13163 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13164 13165 ins_encode %{ 13166 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13167 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13168 %} 13169 ins_pipe(ialu_reg_reg_shift); 13170 %} 13171 13172 // This pattern is automatically generated from aarch64_ad.m4 13173 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13174 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13175 %{ 13176 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13177 ins_cost(1.9 * INSN_COST); 13178 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13179 13180 ins_encode %{ 13181 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13182 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13183 %} 13184 ins_pipe(ialu_reg_reg_shift); 13185 %} 13186 13187 // This pattern is automatically generated from aarch64_ad.m4 13188 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13189 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13190 %{ 13191 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13192 ins_cost(1.9 * INSN_COST); 13193 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13194 13195 ins_encode %{ 13196 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13197 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13198 %} 13199 ins_pipe(ialu_reg_reg_shift); 13200 %} 13201 13202 // This pattern is automatically generated from aarch64_ad.m4 13203 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13204 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13205 %{ 13206 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13207 ins_cost(1.9 * INSN_COST); 13208 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13209 13210 ins_encode %{ 13211 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13212 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13213 %} 13214 ins_pipe(ialu_reg_reg_shift); 13215 %} 13216 13217 // This pattern is automatically generated from aarch64_ad.m4 13218 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13219 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13220 %{ 13221 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13222 ins_cost(1.9 * INSN_COST); 13223 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13224 13225 ins_encode %{ 13226 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13227 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13228 %} 13229 ins_pipe(ialu_reg_reg_shift); 13230 %} 13231 13232 // This pattern is automatically generated from aarch64_ad.m4 13233 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13234 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13235 %{ 13236 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13237 ins_cost(1.9 * INSN_COST); 13238 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13239 13240 ins_encode %{ 13241 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13242 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13243 %} 13244 ins_pipe(ialu_reg_reg_shift); 13245 %} 13246 13247 // This pattern is automatically generated from aarch64_ad.m4 13248 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13249 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13250 %{ 13251 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13252 ins_cost(1.9 * INSN_COST); 13253 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13254 13255 ins_encode %{ 13256 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13257 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13258 %} 13259 ins_pipe(ialu_reg_reg_shift); 13260 %} 13261 13262 // This pattern is automatically generated from aarch64_ad.m4 13263 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13264 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13265 %{ 13266 effect(DEF dst, USE src1, USE src2, USE cr); 13267 ins_cost(INSN_COST * 2); 13268 format %{ "cselw $dst, $src1, $src2 lt\t" %} 13269 13270 ins_encode %{ 13271 __ cselw($dst$$Register, 13272 $src1$$Register, 13273 $src2$$Register, 13274 Assembler::LT); 13275 %} 13276 ins_pipe(icond_reg_reg); 13277 %} 13278 13279 // This pattern is automatically generated from aarch64_ad.m4 13280 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13281 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13282 %{ 13283 effect(DEF dst, USE src1, USE src2, USE cr); 13284 ins_cost(INSN_COST * 2); 13285 format %{ "cselw $dst, $src1, $src2 gt\t" %} 13286 13287 ins_encode %{ 13288 __ cselw($dst$$Register, 13289 $src1$$Register, 13290 $src2$$Register, 13291 Assembler::GT); 13292 %} 13293 ins_pipe(icond_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 cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13299 %{ 13300 effect(DEF dst, USE src1, USE cr); 13301 ins_cost(INSN_COST * 2); 13302 format %{ "cselw $dst, $src1, zr lt\t" %} 13303 13304 ins_encode %{ 13305 __ cselw($dst$$Register, 13306 $src1$$Register, 13307 zr, 13308 Assembler::LT); 13309 %} 13310 ins_pipe(icond_reg); 13311 %} 13312 13313 // This pattern is automatically generated from aarch64_ad.m4 13314 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13315 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13316 %{ 13317 effect(DEF dst, USE src1, USE cr); 13318 ins_cost(INSN_COST * 2); 13319 format %{ "cselw $dst, $src1, zr gt\t" %} 13320 13321 ins_encode %{ 13322 __ cselw($dst$$Register, 13323 $src1$$Register, 13324 zr, 13325 Assembler::GT); 13326 %} 13327 ins_pipe(icond_reg); 13328 %} 13329 13330 // This pattern is automatically generated from aarch64_ad.m4 13331 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13332 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13333 %{ 13334 effect(DEF dst, USE src1, USE cr); 13335 ins_cost(INSN_COST * 2); 13336 format %{ "csincw $dst, $src1, zr le\t" %} 13337 13338 ins_encode %{ 13339 __ csincw($dst$$Register, 13340 $src1$$Register, 13341 zr, 13342 Assembler::LE); 13343 %} 13344 ins_pipe(icond_reg); 13345 %} 13346 13347 // This pattern is automatically generated from aarch64_ad.m4 13348 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13349 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13350 %{ 13351 effect(DEF dst, USE src1, USE cr); 13352 ins_cost(INSN_COST * 2); 13353 format %{ "csincw $dst, $src1, zr gt\t" %} 13354 13355 ins_encode %{ 13356 __ csincw($dst$$Register, 13357 $src1$$Register, 13358 zr, 13359 Assembler::GT); 13360 %} 13361 ins_pipe(icond_reg); 13362 %} 13363 13364 // This pattern is automatically generated from aarch64_ad.m4 13365 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13366 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13367 %{ 13368 effect(DEF dst, USE src1, USE cr); 13369 ins_cost(INSN_COST * 2); 13370 format %{ "csinvw $dst, $src1, zr lt\t" %} 13371 13372 ins_encode %{ 13373 __ csinvw($dst$$Register, 13374 $src1$$Register, 13375 zr, 13376 Assembler::LT); 13377 %} 13378 ins_pipe(icond_reg); 13379 %} 13380 13381 // This pattern is automatically generated from aarch64_ad.m4 13382 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13383 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13384 %{ 13385 effect(DEF dst, USE src1, USE cr); 13386 ins_cost(INSN_COST * 2); 13387 format %{ "csinvw $dst, $src1, zr ge\t" %} 13388 13389 ins_encode %{ 13390 __ csinvw($dst$$Register, 13391 $src1$$Register, 13392 zr, 13393 Assembler::GE); 13394 %} 13395 ins_pipe(icond_reg); 13396 %} 13397 13398 // This pattern is automatically generated from aarch64_ad.m4 13399 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13400 instruct minI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13401 %{ 13402 match(Set dst (MinI src imm)); 13403 ins_cost(INSN_COST * 3); 13404 expand %{ 13405 rFlagsReg cr; 13406 compI_reg_imm0(cr, src); 13407 cmovI_reg_imm0_lt(dst, src, cr); 13408 %} 13409 %} 13410 13411 // This pattern is automatically generated from aarch64_ad.m4 13412 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13413 instruct minI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13414 %{ 13415 match(Set dst (MinI imm src)); 13416 ins_cost(INSN_COST * 3); 13417 expand %{ 13418 rFlagsReg cr; 13419 compI_reg_imm0(cr, src); 13420 cmovI_reg_imm0_lt(dst, src, cr); 13421 %} 13422 %} 13423 13424 // This pattern is automatically generated from aarch64_ad.m4 13425 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13426 instruct minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13427 %{ 13428 match(Set dst (MinI src imm)); 13429 ins_cost(INSN_COST * 3); 13430 expand %{ 13431 rFlagsReg cr; 13432 compI_reg_imm0(cr, src); 13433 cmovI_reg_imm1_le(dst, src, cr); 13434 %} 13435 %} 13436 13437 // This pattern is automatically generated from aarch64_ad.m4 13438 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13439 instruct minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13440 %{ 13441 match(Set dst (MinI imm src)); 13442 ins_cost(INSN_COST * 3); 13443 expand %{ 13444 rFlagsReg cr; 13445 compI_reg_imm0(cr, src); 13446 cmovI_reg_imm1_le(dst, src, cr); 13447 %} 13448 %} 13449 13450 // This pattern is automatically generated from aarch64_ad.m4 13451 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13452 instruct minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13453 %{ 13454 match(Set dst (MinI src imm)); 13455 ins_cost(INSN_COST * 3); 13456 expand %{ 13457 rFlagsReg cr; 13458 compI_reg_imm0(cr, src); 13459 cmovI_reg_immM1_lt(dst, src, cr); 13460 %} 13461 %} 13462 13463 // This pattern is automatically generated from aarch64_ad.m4 13464 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13465 instruct minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13466 %{ 13467 match(Set dst (MinI imm src)); 13468 ins_cost(INSN_COST * 3); 13469 expand %{ 13470 rFlagsReg cr; 13471 compI_reg_imm0(cr, src); 13472 cmovI_reg_immM1_lt(dst, src, cr); 13473 %} 13474 %} 13475 13476 // This pattern is automatically generated from aarch64_ad.m4 13477 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13478 instruct maxI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13479 %{ 13480 match(Set dst (MaxI src imm)); 13481 ins_cost(INSN_COST * 3); 13482 expand %{ 13483 rFlagsReg cr; 13484 compI_reg_imm0(cr, src); 13485 cmovI_reg_imm0_gt(dst, src, cr); 13486 %} 13487 %} 13488 13489 // This pattern is automatically generated from aarch64_ad.m4 13490 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13491 instruct maxI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13492 %{ 13493 match(Set dst (MaxI imm src)); 13494 ins_cost(INSN_COST * 3); 13495 expand %{ 13496 rFlagsReg cr; 13497 compI_reg_imm0(cr, src); 13498 cmovI_reg_imm0_gt(dst, src, cr); 13499 %} 13500 %} 13501 13502 // This pattern is automatically generated from aarch64_ad.m4 13503 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13504 instruct maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13505 %{ 13506 match(Set dst (MaxI src imm)); 13507 ins_cost(INSN_COST * 3); 13508 expand %{ 13509 rFlagsReg cr; 13510 compI_reg_imm0(cr, src); 13511 cmovI_reg_imm1_gt(dst, src, cr); 13512 %} 13513 %} 13514 13515 // This pattern is automatically generated from aarch64_ad.m4 13516 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13517 instruct maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13518 %{ 13519 match(Set dst (MaxI imm src)); 13520 ins_cost(INSN_COST * 3); 13521 expand %{ 13522 rFlagsReg cr; 13523 compI_reg_imm0(cr, src); 13524 cmovI_reg_imm1_gt(dst, src, cr); 13525 %} 13526 %} 13527 13528 // This pattern is automatically generated from aarch64_ad.m4 13529 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13530 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13531 %{ 13532 match(Set dst (MaxI src imm)); 13533 ins_cost(INSN_COST * 3); 13534 expand %{ 13535 rFlagsReg cr; 13536 compI_reg_imm0(cr, src); 13537 cmovI_reg_immM1_ge(dst, src, cr); 13538 %} 13539 %} 13540 13541 // This pattern is automatically generated from aarch64_ad.m4 13542 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13543 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13544 %{ 13545 match(Set dst (MaxI imm src)); 13546 ins_cost(INSN_COST * 3); 13547 expand %{ 13548 rFlagsReg cr; 13549 compI_reg_imm0(cr, src); 13550 cmovI_reg_immM1_ge(dst, src, cr); 13551 %} 13552 %} 13553 13554 // This pattern is automatically generated from aarch64_ad.m4 13555 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13556 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src) 13557 %{ 13558 match(Set dst (ReverseI src)); 13559 ins_cost(INSN_COST); 13560 format %{ "rbitw $dst, $src" %} 13561 ins_encode %{ 13562 __ rbitw($dst$$Register, $src$$Register); 13563 %} 13564 ins_pipe(ialu_reg); 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 bits_reverse_L(iRegLNoSp dst, iRegL src) 13570 %{ 13571 match(Set dst (ReverseL src)); 13572 ins_cost(INSN_COST); 13573 format %{ "rbit $dst, $src" %} 13574 ins_encode %{ 13575 __ rbit($dst$$Register, $src$$Register); 13576 %} 13577 ins_pipe(ialu_reg); 13578 %} 13579 13580 13581 // END This section of the file is automatically generated. Do not edit -------------- 13582 13583 13584 // ============================================================================ 13585 // Floating Point Arithmetic Instructions 13586 13587 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13588 match(Set dst (AddF src1 src2)); 13589 13590 ins_cost(INSN_COST * 5); 13591 format %{ "fadds $dst, $src1, $src2" %} 13592 13593 ins_encode %{ 13594 __ fadds(as_FloatRegister($dst$$reg), 13595 as_FloatRegister($src1$$reg), 13596 as_FloatRegister($src2$$reg)); 13597 %} 13598 13599 ins_pipe(fp_dop_reg_reg_s); 13600 %} 13601 13602 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13603 match(Set dst (AddD src1 src2)); 13604 13605 ins_cost(INSN_COST * 5); 13606 format %{ "faddd $dst, $src1, $src2" %} 13607 13608 ins_encode %{ 13609 __ faddd(as_FloatRegister($dst$$reg), 13610 as_FloatRegister($src1$$reg), 13611 as_FloatRegister($src2$$reg)); 13612 %} 13613 13614 ins_pipe(fp_dop_reg_reg_d); 13615 %} 13616 13617 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13618 match(Set dst (SubF src1 src2)); 13619 13620 ins_cost(INSN_COST * 5); 13621 format %{ "fsubs $dst, $src1, $src2" %} 13622 13623 ins_encode %{ 13624 __ fsubs(as_FloatRegister($dst$$reg), 13625 as_FloatRegister($src1$$reg), 13626 as_FloatRegister($src2$$reg)); 13627 %} 13628 13629 ins_pipe(fp_dop_reg_reg_s); 13630 %} 13631 13632 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13633 match(Set dst (SubD src1 src2)); 13634 13635 ins_cost(INSN_COST * 5); 13636 format %{ "fsubd $dst, $src1, $src2" %} 13637 13638 ins_encode %{ 13639 __ fsubd(as_FloatRegister($dst$$reg), 13640 as_FloatRegister($src1$$reg), 13641 as_FloatRegister($src2$$reg)); 13642 %} 13643 13644 ins_pipe(fp_dop_reg_reg_d); 13645 %} 13646 13647 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13648 match(Set dst (MulF src1 src2)); 13649 13650 ins_cost(INSN_COST * 6); 13651 format %{ "fmuls $dst, $src1, $src2" %} 13652 13653 ins_encode %{ 13654 __ fmuls(as_FloatRegister($dst$$reg), 13655 as_FloatRegister($src1$$reg), 13656 as_FloatRegister($src2$$reg)); 13657 %} 13658 13659 ins_pipe(fp_dop_reg_reg_s); 13660 %} 13661 13662 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13663 match(Set dst (MulD src1 src2)); 13664 13665 ins_cost(INSN_COST * 6); 13666 format %{ "fmuld $dst, $src1, $src2" %} 13667 13668 ins_encode %{ 13669 __ fmuld(as_FloatRegister($dst$$reg), 13670 as_FloatRegister($src1$$reg), 13671 as_FloatRegister($src2$$reg)); 13672 %} 13673 13674 ins_pipe(fp_dop_reg_reg_d); 13675 %} 13676 13677 // src1 * src2 + src3 13678 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13679 match(Set dst (FmaF src3 (Binary src1 src2))); 13680 13681 format %{ "fmadds $dst, $src1, $src2, $src3" %} 13682 13683 ins_encode %{ 13684 assert(UseFMA, "Needs FMA instructions support."); 13685 __ fmadds(as_FloatRegister($dst$$reg), 13686 as_FloatRegister($src1$$reg), 13687 as_FloatRegister($src2$$reg), 13688 as_FloatRegister($src3$$reg)); 13689 %} 13690 13691 ins_pipe(pipe_class_default); 13692 %} 13693 13694 // src1 * src2 + src3 13695 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13696 match(Set dst (FmaD src3 (Binary src1 src2))); 13697 13698 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 13699 13700 ins_encode %{ 13701 assert(UseFMA, "Needs FMA instructions support."); 13702 __ fmaddd(as_FloatRegister($dst$$reg), 13703 as_FloatRegister($src1$$reg), 13704 as_FloatRegister($src2$$reg), 13705 as_FloatRegister($src3$$reg)); 13706 %} 13707 13708 ins_pipe(pipe_class_default); 13709 %} 13710 13711 // src1 * (-src2) + src3 13712 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 13713 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13714 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 13715 13716 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 13717 13718 ins_encode %{ 13719 assert(UseFMA, "Needs FMA instructions support."); 13720 __ fmsubs(as_FloatRegister($dst$$reg), 13721 as_FloatRegister($src1$$reg), 13722 as_FloatRegister($src2$$reg), 13723 as_FloatRegister($src3$$reg)); 13724 %} 13725 13726 ins_pipe(pipe_class_default); 13727 %} 13728 13729 // src1 * (-src2) + src3 13730 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 13731 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13732 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 13733 13734 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 13735 13736 ins_encode %{ 13737 assert(UseFMA, "Needs FMA instructions support."); 13738 __ fmsubd(as_FloatRegister($dst$$reg), 13739 as_FloatRegister($src1$$reg), 13740 as_FloatRegister($src2$$reg), 13741 as_FloatRegister($src3$$reg)); 13742 %} 13743 13744 ins_pipe(pipe_class_default); 13745 %} 13746 13747 // src1 * (-src2) - src3 13748 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 13749 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13750 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13751 13752 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13753 13754 ins_encode %{ 13755 assert(UseFMA, "Needs FMA instructions support."); 13756 __ fnmadds(as_FloatRegister($dst$$reg), 13757 as_FloatRegister($src1$$reg), 13758 as_FloatRegister($src2$$reg), 13759 as_FloatRegister($src3$$reg)); 13760 %} 13761 13762 ins_pipe(pipe_class_default); 13763 %} 13764 13765 // src1 * (-src2) - src3 13766 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 13767 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13768 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13769 13770 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13771 13772 ins_encode %{ 13773 assert(UseFMA, "Needs FMA instructions support."); 13774 __ fnmaddd(as_FloatRegister($dst$$reg), 13775 as_FloatRegister($src1$$reg), 13776 as_FloatRegister($src2$$reg), 13777 as_FloatRegister($src3$$reg)); 13778 %} 13779 13780 ins_pipe(pipe_class_default); 13781 %} 13782 13783 // src1 * src2 - src3 13784 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13785 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13786 13787 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13788 13789 ins_encode %{ 13790 assert(UseFMA, "Needs FMA instructions support."); 13791 __ fnmsubs(as_FloatRegister($dst$$reg), 13792 as_FloatRegister($src1$$reg), 13793 as_FloatRegister($src2$$reg), 13794 as_FloatRegister($src3$$reg)); 13795 %} 13796 13797 ins_pipe(pipe_class_default); 13798 %} 13799 13800 // src1 * src2 - src3 13801 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13802 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13803 13804 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13805 13806 ins_encode %{ 13807 assert(UseFMA, "Needs FMA instructions support."); 13808 // n.b. insn name should be fnmsubd 13809 __ fnmsub(as_FloatRegister($dst$$reg), 13810 as_FloatRegister($src1$$reg), 13811 as_FloatRegister($src2$$reg), 13812 as_FloatRegister($src3$$reg)); 13813 %} 13814 13815 ins_pipe(pipe_class_default); 13816 %} 13817 13818 13819 // Math.max(FF)F 13820 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13821 match(Set dst (MaxF src1 src2)); 13822 13823 format %{ "fmaxs $dst, $src1, $src2" %} 13824 ins_encode %{ 13825 __ fmaxs(as_FloatRegister($dst$$reg), 13826 as_FloatRegister($src1$$reg), 13827 as_FloatRegister($src2$$reg)); 13828 %} 13829 13830 ins_pipe(fp_dop_reg_reg_s); 13831 %} 13832 13833 // Math.min(FF)F 13834 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13835 match(Set dst (MinF src1 src2)); 13836 13837 format %{ "fmins $dst, $src1, $src2" %} 13838 ins_encode %{ 13839 __ fmins(as_FloatRegister($dst$$reg), 13840 as_FloatRegister($src1$$reg), 13841 as_FloatRegister($src2$$reg)); 13842 %} 13843 13844 ins_pipe(fp_dop_reg_reg_s); 13845 %} 13846 13847 // Math.max(DD)D 13848 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13849 match(Set dst (MaxD src1 src2)); 13850 13851 format %{ "fmaxd $dst, $src1, $src2" %} 13852 ins_encode %{ 13853 __ fmaxd(as_FloatRegister($dst$$reg), 13854 as_FloatRegister($src1$$reg), 13855 as_FloatRegister($src2$$reg)); 13856 %} 13857 13858 ins_pipe(fp_dop_reg_reg_d); 13859 %} 13860 13861 // Math.min(DD)D 13862 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13863 match(Set dst (MinD src1 src2)); 13864 13865 format %{ "fmind $dst, $src1, $src2" %} 13866 ins_encode %{ 13867 __ fmind(as_FloatRegister($dst$$reg), 13868 as_FloatRegister($src1$$reg), 13869 as_FloatRegister($src2$$reg)); 13870 %} 13871 13872 ins_pipe(fp_dop_reg_reg_d); 13873 %} 13874 13875 13876 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13877 match(Set dst (DivF src1 src2)); 13878 13879 ins_cost(INSN_COST * 18); 13880 format %{ "fdivs $dst, $src1, $src2" %} 13881 13882 ins_encode %{ 13883 __ fdivs(as_FloatRegister($dst$$reg), 13884 as_FloatRegister($src1$$reg), 13885 as_FloatRegister($src2$$reg)); 13886 %} 13887 13888 ins_pipe(fp_div_s); 13889 %} 13890 13891 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13892 match(Set dst (DivD src1 src2)); 13893 13894 ins_cost(INSN_COST * 32); 13895 format %{ "fdivd $dst, $src1, $src2" %} 13896 13897 ins_encode %{ 13898 __ fdivd(as_FloatRegister($dst$$reg), 13899 as_FloatRegister($src1$$reg), 13900 as_FloatRegister($src2$$reg)); 13901 %} 13902 13903 ins_pipe(fp_div_d); 13904 %} 13905 13906 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13907 match(Set dst (NegF src)); 13908 13909 ins_cost(INSN_COST * 3); 13910 format %{ "fneg $dst, $src" %} 13911 13912 ins_encode %{ 13913 __ fnegs(as_FloatRegister($dst$$reg), 13914 as_FloatRegister($src$$reg)); 13915 %} 13916 13917 ins_pipe(fp_uop_s); 13918 %} 13919 13920 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13921 match(Set dst (NegD src)); 13922 13923 ins_cost(INSN_COST * 3); 13924 format %{ "fnegd $dst, $src" %} 13925 13926 ins_encode %{ 13927 __ fnegd(as_FloatRegister($dst$$reg), 13928 as_FloatRegister($src$$reg)); 13929 %} 13930 13931 ins_pipe(fp_uop_d); 13932 %} 13933 13934 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13935 %{ 13936 match(Set dst (AbsI src)); 13937 13938 effect(KILL cr); 13939 ins_cost(INSN_COST * 2); 13940 format %{ "cmpw $src, zr\n\t" 13941 "cnegw $dst, $src, Assembler::LT\t# int abs" 13942 %} 13943 13944 ins_encode %{ 13945 __ cmpw(as_Register($src$$reg), zr); 13946 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13947 %} 13948 ins_pipe(pipe_class_default); 13949 %} 13950 13951 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 13952 %{ 13953 match(Set dst (AbsL src)); 13954 13955 effect(KILL cr); 13956 ins_cost(INSN_COST * 2); 13957 format %{ "cmp $src, zr\n\t" 13958 "cneg $dst, $src, Assembler::LT\t# long abs" 13959 %} 13960 13961 ins_encode %{ 13962 __ cmp(as_Register($src$$reg), zr); 13963 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13964 %} 13965 ins_pipe(pipe_class_default); 13966 %} 13967 13968 instruct absF_reg(vRegF dst, vRegF src) %{ 13969 match(Set dst (AbsF src)); 13970 13971 ins_cost(INSN_COST * 3); 13972 format %{ "fabss $dst, $src" %} 13973 ins_encode %{ 13974 __ fabss(as_FloatRegister($dst$$reg), 13975 as_FloatRegister($src$$reg)); 13976 %} 13977 13978 ins_pipe(fp_uop_s); 13979 %} 13980 13981 instruct absD_reg(vRegD dst, vRegD src) %{ 13982 match(Set dst (AbsD src)); 13983 13984 ins_cost(INSN_COST * 3); 13985 format %{ "fabsd $dst, $src" %} 13986 ins_encode %{ 13987 __ fabsd(as_FloatRegister($dst$$reg), 13988 as_FloatRegister($src$$reg)); 13989 %} 13990 13991 ins_pipe(fp_uop_d); 13992 %} 13993 13994 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13995 match(Set dst (AbsF (SubF src1 src2))); 13996 13997 ins_cost(INSN_COST * 3); 13998 format %{ "fabds $dst, $src1, $src2" %} 13999 ins_encode %{ 14000 __ fabds(as_FloatRegister($dst$$reg), 14001 as_FloatRegister($src1$$reg), 14002 as_FloatRegister($src2$$reg)); 14003 %} 14004 14005 ins_pipe(fp_uop_s); 14006 %} 14007 14008 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14009 match(Set dst (AbsD (SubD src1 src2))); 14010 14011 ins_cost(INSN_COST * 3); 14012 format %{ "fabdd $dst, $src1, $src2" %} 14013 ins_encode %{ 14014 __ fabdd(as_FloatRegister($dst$$reg), 14015 as_FloatRegister($src1$$reg), 14016 as_FloatRegister($src2$$reg)); 14017 %} 14018 14019 ins_pipe(fp_uop_d); 14020 %} 14021 14022 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 14023 match(Set dst (SqrtD src)); 14024 14025 ins_cost(INSN_COST * 50); 14026 format %{ "fsqrtd $dst, $src" %} 14027 ins_encode %{ 14028 __ fsqrtd(as_FloatRegister($dst$$reg), 14029 as_FloatRegister($src$$reg)); 14030 %} 14031 14032 ins_pipe(fp_div_s); 14033 %} 14034 14035 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 14036 match(Set dst (SqrtF src)); 14037 14038 ins_cost(INSN_COST * 50); 14039 format %{ "fsqrts $dst, $src" %} 14040 ins_encode %{ 14041 __ fsqrts(as_FloatRegister($dst$$reg), 14042 as_FloatRegister($src$$reg)); 14043 %} 14044 14045 ins_pipe(fp_div_d); 14046 %} 14047 14048 // Math.rint, floor, ceil 14049 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 14050 match(Set dst (RoundDoubleMode src rmode)); 14051 format %{ "frint $dst, $src, $rmode" %} 14052 ins_encode %{ 14053 switch ($rmode$$constant) { 14054 case RoundDoubleModeNode::rmode_rint: 14055 __ frintnd(as_FloatRegister($dst$$reg), 14056 as_FloatRegister($src$$reg)); 14057 break; 14058 case RoundDoubleModeNode::rmode_floor: 14059 __ frintmd(as_FloatRegister($dst$$reg), 14060 as_FloatRegister($src$$reg)); 14061 break; 14062 case RoundDoubleModeNode::rmode_ceil: 14063 __ frintpd(as_FloatRegister($dst$$reg), 14064 as_FloatRegister($src$$reg)); 14065 break; 14066 } 14067 %} 14068 ins_pipe(fp_uop_d); 14069 %} 14070 14071 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 14072 match(Set dst (CopySignD src1 (Binary src2 zero))); 14073 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 14074 format %{ "CopySignD $dst $src1 $src2" %} 14075 ins_encode %{ 14076 FloatRegister dst = as_FloatRegister($dst$$reg), 14077 src1 = as_FloatRegister($src1$$reg), 14078 src2 = as_FloatRegister($src2$$reg), 14079 zero = as_FloatRegister($zero$$reg); 14080 __ fnegd(dst, zero); 14081 __ bsl(dst, __ T8B, src2, src1); 14082 %} 14083 ins_pipe(fp_uop_d); 14084 %} 14085 14086 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14087 match(Set dst (CopySignF src1 src2)); 14088 effect(TEMP_DEF dst, USE src1, USE src2); 14089 format %{ "CopySignF $dst $src1 $src2" %} 14090 ins_encode %{ 14091 FloatRegister dst = as_FloatRegister($dst$$reg), 14092 src1 = as_FloatRegister($src1$$reg), 14093 src2 = as_FloatRegister($src2$$reg); 14094 __ movi(dst, __ T2S, 0x80, 24); 14095 __ bsl(dst, __ T8B, src2, src1); 14096 %} 14097 ins_pipe(fp_uop_d); 14098 %} 14099 14100 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 14101 match(Set dst (SignumD src (Binary zero one))); 14102 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14103 format %{ "signumD $dst, $src" %} 14104 ins_encode %{ 14105 FloatRegister src = as_FloatRegister($src$$reg), 14106 dst = as_FloatRegister($dst$$reg), 14107 zero = as_FloatRegister($zero$$reg), 14108 one = as_FloatRegister($one$$reg); 14109 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14110 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14111 // Bit selection instruction gets bit from "one" for each enabled bit in 14112 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14113 // NaN the whole "src" will be copied because "dst" is zero. For all other 14114 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14115 // from "src", and all other bits are copied from 1.0. 14116 __ bsl(dst, __ T8B, one, src); 14117 %} 14118 ins_pipe(fp_uop_d); 14119 %} 14120 14121 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 14122 match(Set dst (SignumF src (Binary zero one))); 14123 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14124 format %{ "signumF $dst, $src" %} 14125 ins_encode %{ 14126 FloatRegister src = as_FloatRegister($src$$reg), 14127 dst = as_FloatRegister($dst$$reg), 14128 zero = as_FloatRegister($zero$$reg), 14129 one = as_FloatRegister($one$$reg); 14130 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14131 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14132 // Bit selection instruction gets bit from "one" for each enabled bit in 14133 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14134 // NaN the whole "src" will be copied because "dst" is zero. For all other 14135 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14136 // from "src", and all other bits are copied from 1.0. 14137 __ bsl(dst, __ T8B, one, src); 14138 %} 14139 ins_pipe(fp_uop_d); 14140 %} 14141 14142 instruct onspinwait() %{ 14143 match(OnSpinWait); 14144 ins_cost(INSN_COST); 14145 14146 format %{ "onspinwait" %} 14147 14148 ins_encode %{ 14149 __ spin_wait(); 14150 %} 14151 ins_pipe(pipe_class_empty); 14152 %} 14153 14154 // ============================================================================ 14155 // Logical Instructions 14156 14157 // Integer Logical Instructions 14158 14159 // And Instructions 14160 14161 14162 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 14163 match(Set dst (AndI src1 src2)); 14164 14165 format %{ "andw $dst, $src1, $src2\t# int" %} 14166 14167 ins_cost(INSN_COST); 14168 ins_encode %{ 14169 __ andw(as_Register($dst$$reg), 14170 as_Register($src1$$reg), 14171 as_Register($src2$$reg)); 14172 %} 14173 14174 ins_pipe(ialu_reg_reg); 14175 %} 14176 14177 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 14178 match(Set dst (AndI src1 src2)); 14179 14180 format %{ "andsw $dst, $src1, $src2\t# int" %} 14181 14182 ins_cost(INSN_COST); 14183 ins_encode %{ 14184 __ andw(as_Register($dst$$reg), 14185 as_Register($src1$$reg), 14186 (uint64_t)($src2$$constant)); 14187 %} 14188 14189 ins_pipe(ialu_reg_imm); 14190 %} 14191 14192 // Or Instructions 14193 14194 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14195 match(Set dst (OrI src1 src2)); 14196 14197 format %{ "orrw $dst, $src1, $src2\t# int" %} 14198 14199 ins_cost(INSN_COST); 14200 ins_encode %{ 14201 __ orrw(as_Register($dst$$reg), 14202 as_Register($src1$$reg), 14203 as_Register($src2$$reg)); 14204 %} 14205 14206 ins_pipe(ialu_reg_reg); 14207 %} 14208 14209 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14210 match(Set dst (OrI src1 src2)); 14211 14212 format %{ "orrw $dst, $src1, $src2\t# int" %} 14213 14214 ins_cost(INSN_COST); 14215 ins_encode %{ 14216 __ orrw(as_Register($dst$$reg), 14217 as_Register($src1$$reg), 14218 (uint64_t)($src2$$constant)); 14219 %} 14220 14221 ins_pipe(ialu_reg_imm); 14222 %} 14223 14224 // Xor Instructions 14225 14226 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14227 match(Set dst (XorI src1 src2)); 14228 14229 format %{ "eorw $dst, $src1, $src2\t# int" %} 14230 14231 ins_cost(INSN_COST); 14232 ins_encode %{ 14233 __ eorw(as_Register($dst$$reg), 14234 as_Register($src1$$reg), 14235 as_Register($src2$$reg)); 14236 %} 14237 14238 ins_pipe(ialu_reg_reg); 14239 %} 14240 14241 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14242 match(Set dst (XorI src1 src2)); 14243 14244 format %{ "eorw $dst, $src1, $src2\t# int" %} 14245 14246 ins_cost(INSN_COST); 14247 ins_encode %{ 14248 __ eorw(as_Register($dst$$reg), 14249 as_Register($src1$$reg), 14250 (uint64_t)($src2$$constant)); 14251 %} 14252 14253 ins_pipe(ialu_reg_imm); 14254 %} 14255 14256 // Long Logical Instructions 14257 // TODO 14258 14259 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 14260 match(Set dst (AndL src1 src2)); 14261 14262 format %{ "and $dst, $src1, $src2\t# int" %} 14263 14264 ins_cost(INSN_COST); 14265 ins_encode %{ 14266 __ andr(as_Register($dst$$reg), 14267 as_Register($src1$$reg), 14268 as_Register($src2$$reg)); 14269 %} 14270 14271 ins_pipe(ialu_reg_reg); 14272 %} 14273 14274 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 14275 match(Set dst (AndL src1 src2)); 14276 14277 format %{ "and $dst, $src1, $src2\t# int" %} 14278 14279 ins_cost(INSN_COST); 14280 ins_encode %{ 14281 __ andr(as_Register($dst$$reg), 14282 as_Register($src1$$reg), 14283 (uint64_t)($src2$$constant)); 14284 %} 14285 14286 ins_pipe(ialu_reg_imm); 14287 %} 14288 14289 // Or Instructions 14290 14291 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14292 match(Set dst (OrL src1 src2)); 14293 14294 format %{ "orr $dst, $src1, $src2\t# int" %} 14295 14296 ins_cost(INSN_COST); 14297 ins_encode %{ 14298 __ orr(as_Register($dst$$reg), 14299 as_Register($src1$$reg), 14300 as_Register($src2$$reg)); 14301 %} 14302 14303 ins_pipe(ialu_reg_reg); 14304 %} 14305 14306 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14307 match(Set dst (OrL src1 src2)); 14308 14309 format %{ "orr $dst, $src1, $src2\t# int" %} 14310 14311 ins_cost(INSN_COST); 14312 ins_encode %{ 14313 __ orr(as_Register($dst$$reg), 14314 as_Register($src1$$reg), 14315 (uint64_t)($src2$$constant)); 14316 %} 14317 14318 ins_pipe(ialu_reg_imm); 14319 %} 14320 14321 // Xor Instructions 14322 14323 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14324 match(Set dst (XorL src1 src2)); 14325 14326 format %{ "eor $dst, $src1, $src2\t# int" %} 14327 14328 ins_cost(INSN_COST); 14329 ins_encode %{ 14330 __ eor(as_Register($dst$$reg), 14331 as_Register($src1$$reg), 14332 as_Register($src2$$reg)); 14333 %} 14334 14335 ins_pipe(ialu_reg_reg); 14336 %} 14337 14338 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14339 match(Set dst (XorL src1 src2)); 14340 14341 ins_cost(INSN_COST); 14342 format %{ "eor $dst, $src1, $src2\t# int" %} 14343 14344 ins_encode %{ 14345 __ eor(as_Register($dst$$reg), 14346 as_Register($src1$$reg), 14347 (uint64_t)($src2$$constant)); 14348 %} 14349 14350 ins_pipe(ialu_reg_imm); 14351 %} 14352 14353 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 14354 %{ 14355 match(Set dst (ConvI2L src)); 14356 14357 ins_cost(INSN_COST); 14358 format %{ "sxtw $dst, $src\t# i2l" %} 14359 ins_encode %{ 14360 __ sbfm($dst$$Register, $src$$Register, 0, 31); 14361 %} 14362 ins_pipe(ialu_reg_shift); 14363 %} 14364 14365 // this pattern occurs in bigmath arithmetic 14366 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 14367 %{ 14368 match(Set dst (AndL (ConvI2L src) mask)); 14369 14370 ins_cost(INSN_COST); 14371 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 14372 ins_encode %{ 14373 __ ubfm($dst$$Register, $src$$Register, 0, 31); 14374 %} 14375 14376 ins_pipe(ialu_reg_shift); 14377 %} 14378 14379 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 14380 match(Set dst (ConvL2I src)); 14381 14382 ins_cost(INSN_COST); 14383 format %{ "movw $dst, $src \t// l2i" %} 14384 14385 ins_encode %{ 14386 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 14387 %} 14388 14389 ins_pipe(ialu_reg); 14390 %} 14391 14392 instruct convD2F_reg(vRegF dst, vRegD src) %{ 14393 match(Set dst (ConvD2F src)); 14394 14395 ins_cost(INSN_COST * 5); 14396 format %{ "fcvtd $dst, $src \t// d2f" %} 14397 14398 ins_encode %{ 14399 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14400 %} 14401 14402 ins_pipe(fp_d2f); 14403 %} 14404 14405 instruct convF2D_reg(vRegD dst, vRegF src) %{ 14406 match(Set dst (ConvF2D src)); 14407 14408 ins_cost(INSN_COST * 5); 14409 format %{ "fcvts $dst, $src \t// f2d" %} 14410 14411 ins_encode %{ 14412 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14413 %} 14414 14415 ins_pipe(fp_f2d); 14416 %} 14417 14418 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14419 match(Set dst (ConvF2I src)); 14420 14421 ins_cost(INSN_COST * 5); 14422 format %{ "fcvtzsw $dst, $src \t// f2i" %} 14423 14424 ins_encode %{ 14425 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14426 %} 14427 14428 ins_pipe(fp_f2i); 14429 %} 14430 14431 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 14432 match(Set dst (ConvF2L src)); 14433 14434 ins_cost(INSN_COST * 5); 14435 format %{ "fcvtzs $dst, $src \t// f2l" %} 14436 14437 ins_encode %{ 14438 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14439 %} 14440 14441 ins_pipe(fp_f2l); 14442 %} 14443 14444 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{ 14445 match(Set dst (ConvF2HF src)); 14446 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t" 14447 "smov $dst, $tmp\t# move result from $tmp to $dst" 14448 %} 14449 effect(TEMP tmp); 14450 ins_encode %{ 14451 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister); 14452 %} 14453 ins_pipe(pipe_slow); 14454 %} 14455 14456 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{ 14457 match(Set dst (ConvHF2F src)); 14458 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t" 14459 "fcvt $dst, $tmp\t# convert half to single precision" 14460 %} 14461 effect(TEMP tmp); 14462 ins_encode %{ 14463 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister); 14464 %} 14465 ins_pipe(pipe_slow); 14466 %} 14467 14468 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 14469 match(Set dst (ConvI2F src)); 14470 14471 ins_cost(INSN_COST * 5); 14472 format %{ "scvtfws $dst, $src \t// i2f" %} 14473 14474 ins_encode %{ 14475 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14476 %} 14477 14478 ins_pipe(fp_i2f); 14479 %} 14480 14481 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 14482 match(Set dst (ConvL2F src)); 14483 14484 ins_cost(INSN_COST * 5); 14485 format %{ "scvtfs $dst, $src \t// l2f" %} 14486 14487 ins_encode %{ 14488 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14489 %} 14490 14491 ins_pipe(fp_l2f); 14492 %} 14493 14494 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 14495 match(Set dst (ConvD2I src)); 14496 14497 ins_cost(INSN_COST * 5); 14498 format %{ "fcvtzdw $dst, $src \t// d2i" %} 14499 14500 ins_encode %{ 14501 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14502 %} 14503 14504 ins_pipe(fp_d2i); 14505 %} 14506 14507 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14508 match(Set dst (ConvD2L src)); 14509 14510 ins_cost(INSN_COST * 5); 14511 format %{ "fcvtzd $dst, $src \t// d2l" %} 14512 14513 ins_encode %{ 14514 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14515 %} 14516 14517 ins_pipe(fp_d2l); 14518 %} 14519 14520 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 14521 match(Set dst (ConvI2D src)); 14522 14523 ins_cost(INSN_COST * 5); 14524 format %{ "scvtfwd $dst, $src \t// i2d" %} 14525 14526 ins_encode %{ 14527 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14528 %} 14529 14530 ins_pipe(fp_i2d); 14531 %} 14532 14533 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 14534 match(Set dst (ConvL2D src)); 14535 14536 ins_cost(INSN_COST * 5); 14537 format %{ "scvtfd $dst, $src \t// l2d" %} 14538 14539 ins_encode %{ 14540 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14541 %} 14542 14543 ins_pipe(fp_l2d); 14544 %} 14545 14546 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr) 14547 %{ 14548 match(Set dst (RoundD src)); 14549 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 14550 format %{ "java_round_double $dst,$src"%} 14551 ins_encode %{ 14552 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), 14553 as_FloatRegister($ftmp$$reg)); 14554 %} 14555 ins_pipe(pipe_slow); 14556 %} 14557 14558 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr) 14559 %{ 14560 match(Set dst (RoundF src)); 14561 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 14562 format %{ "java_round_float $dst,$src"%} 14563 ins_encode %{ 14564 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), 14565 as_FloatRegister($ftmp$$reg)); 14566 %} 14567 ins_pipe(pipe_slow); 14568 %} 14569 14570 // stack <-> reg and reg <-> reg shuffles with no conversion 14571 14572 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 14573 14574 match(Set dst (MoveF2I src)); 14575 14576 effect(DEF dst, USE src); 14577 14578 ins_cost(4 * INSN_COST); 14579 14580 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 14581 14582 ins_encode %{ 14583 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 14584 %} 14585 14586 ins_pipe(iload_reg_reg); 14587 14588 %} 14589 14590 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 14591 14592 match(Set dst (MoveI2F src)); 14593 14594 effect(DEF dst, USE src); 14595 14596 ins_cost(4 * INSN_COST); 14597 14598 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 14599 14600 ins_encode %{ 14601 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14602 %} 14603 14604 ins_pipe(pipe_class_memory); 14605 14606 %} 14607 14608 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 14609 14610 match(Set dst (MoveD2L src)); 14611 14612 effect(DEF dst, USE src); 14613 14614 ins_cost(4 * INSN_COST); 14615 14616 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 14617 14618 ins_encode %{ 14619 __ ldr($dst$$Register, Address(sp, $src$$disp)); 14620 %} 14621 14622 ins_pipe(iload_reg_reg); 14623 14624 %} 14625 14626 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 14627 14628 match(Set dst (MoveL2D src)); 14629 14630 effect(DEF dst, USE src); 14631 14632 ins_cost(4 * INSN_COST); 14633 14634 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 14635 14636 ins_encode %{ 14637 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14638 %} 14639 14640 ins_pipe(pipe_class_memory); 14641 14642 %} 14643 14644 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 14645 14646 match(Set dst (MoveF2I src)); 14647 14648 effect(DEF dst, USE src); 14649 14650 ins_cost(INSN_COST); 14651 14652 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 14653 14654 ins_encode %{ 14655 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14656 %} 14657 14658 ins_pipe(pipe_class_memory); 14659 14660 %} 14661 14662 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 14663 14664 match(Set dst (MoveI2F src)); 14665 14666 effect(DEF dst, USE src); 14667 14668 ins_cost(INSN_COST); 14669 14670 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 14671 14672 ins_encode %{ 14673 __ strw($src$$Register, Address(sp, $dst$$disp)); 14674 %} 14675 14676 ins_pipe(istore_reg_reg); 14677 14678 %} 14679 14680 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 14681 14682 match(Set dst (MoveD2L src)); 14683 14684 effect(DEF dst, USE src); 14685 14686 ins_cost(INSN_COST); 14687 14688 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 14689 14690 ins_encode %{ 14691 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14692 %} 14693 14694 ins_pipe(pipe_class_memory); 14695 14696 %} 14697 14698 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 14699 14700 match(Set dst (MoveL2D src)); 14701 14702 effect(DEF dst, USE src); 14703 14704 ins_cost(INSN_COST); 14705 14706 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 14707 14708 ins_encode %{ 14709 __ str($src$$Register, Address(sp, $dst$$disp)); 14710 %} 14711 14712 ins_pipe(istore_reg_reg); 14713 14714 %} 14715 14716 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14717 14718 match(Set dst (MoveF2I src)); 14719 14720 effect(DEF dst, USE src); 14721 14722 ins_cost(INSN_COST); 14723 14724 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 14725 14726 ins_encode %{ 14727 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 14728 %} 14729 14730 ins_pipe(fp_f2i); 14731 14732 %} 14733 14734 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 14735 14736 match(Set dst (MoveI2F src)); 14737 14738 effect(DEF dst, USE src); 14739 14740 ins_cost(INSN_COST); 14741 14742 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 14743 14744 ins_encode %{ 14745 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 14746 %} 14747 14748 ins_pipe(fp_i2f); 14749 14750 %} 14751 14752 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14753 14754 match(Set dst (MoveD2L src)); 14755 14756 effect(DEF dst, USE src); 14757 14758 ins_cost(INSN_COST); 14759 14760 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 14761 14762 ins_encode %{ 14763 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 14764 %} 14765 14766 ins_pipe(fp_d2l); 14767 14768 %} 14769 14770 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 14771 14772 match(Set dst (MoveL2D src)); 14773 14774 effect(DEF dst, USE src); 14775 14776 ins_cost(INSN_COST); 14777 14778 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 14779 14780 ins_encode %{ 14781 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 14782 %} 14783 14784 ins_pipe(fp_l2d); 14785 14786 %} 14787 14788 // ============================================================================ 14789 // clearing of an array 14790 14791 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 14792 %{ 14793 match(Set dummy (ClearArray cnt base)); 14794 effect(USE_KILL cnt, USE_KILL base, KILL cr); 14795 14796 ins_cost(4 * INSN_COST); 14797 format %{ "ClearArray $cnt, $base" %} 14798 14799 ins_encode %{ 14800 address tpc = __ zero_words($base$$Register, $cnt$$Register); 14801 if (tpc == nullptr) { 14802 ciEnv::current()->record_failure("CodeCache is full"); 14803 return; 14804 } 14805 %} 14806 14807 ins_pipe(pipe_class_memory); 14808 %} 14809 14810 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr) 14811 %{ 14812 predicate((uint64_t)n->in(2)->get_long() 14813 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 14814 match(Set dummy (ClearArray cnt base)); 14815 effect(TEMP temp, USE_KILL base, KILL cr); 14816 14817 ins_cost(4 * INSN_COST); 14818 format %{ "ClearArray $cnt, $base" %} 14819 14820 ins_encode %{ 14821 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 14822 if (tpc == nullptr) { 14823 ciEnv::current()->record_failure("CodeCache is full"); 14824 return; 14825 } 14826 %} 14827 14828 ins_pipe(pipe_class_memory); 14829 %} 14830 14831 // ============================================================================ 14832 // Overflow Math Instructions 14833 14834 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14835 %{ 14836 match(Set cr (OverflowAddI op1 op2)); 14837 14838 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14839 ins_cost(INSN_COST); 14840 ins_encode %{ 14841 __ cmnw($op1$$Register, $op2$$Register); 14842 %} 14843 14844 ins_pipe(icmp_reg_reg); 14845 %} 14846 14847 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14848 %{ 14849 match(Set cr (OverflowAddI op1 op2)); 14850 14851 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14852 ins_cost(INSN_COST); 14853 ins_encode %{ 14854 __ cmnw($op1$$Register, $op2$$constant); 14855 %} 14856 14857 ins_pipe(icmp_reg_imm); 14858 %} 14859 14860 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14861 %{ 14862 match(Set cr (OverflowAddL op1 op2)); 14863 14864 format %{ "cmn $op1, $op2\t# overflow check long" %} 14865 ins_cost(INSN_COST); 14866 ins_encode %{ 14867 __ cmn($op1$$Register, $op2$$Register); 14868 %} 14869 14870 ins_pipe(icmp_reg_reg); 14871 %} 14872 14873 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14874 %{ 14875 match(Set cr (OverflowAddL op1 op2)); 14876 14877 format %{ "adds zr, $op1, $op2\t# overflow check long" %} 14878 ins_cost(INSN_COST); 14879 ins_encode %{ 14880 __ adds(zr, $op1$$Register, $op2$$constant); 14881 %} 14882 14883 ins_pipe(icmp_reg_imm); 14884 %} 14885 14886 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14887 %{ 14888 match(Set cr (OverflowSubI op1 op2)); 14889 14890 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14891 ins_cost(INSN_COST); 14892 ins_encode %{ 14893 __ cmpw($op1$$Register, $op2$$Register); 14894 %} 14895 14896 ins_pipe(icmp_reg_reg); 14897 %} 14898 14899 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14900 %{ 14901 match(Set cr (OverflowSubI op1 op2)); 14902 14903 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14904 ins_cost(INSN_COST); 14905 ins_encode %{ 14906 __ cmpw($op1$$Register, $op2$$constant); 14907 %} 14908 14909 ins_pipe(icmp_reg_imm); 14910 %} 14911 14912 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14913 %{ 14914 match(Set cr (OverflowSubL op1 op2)); 14915 14916 format %{ "cmp $op1, $op2\t# overflow check long" %} 14917 ins_cost(INSN_COST); 14918 ins_encode %{ 14919 __ cmp($op1$$Register, $op2$$Register); 14920 %} 14921 14922 ins_pipe(icmp_reg_reg); 14923 %} 14924 14925 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14926 %{ 14927 match(Set cr (OverflowSubL op1 op2)); 14928 14929 format %{ "cmp $op1, $op2\t# overflow check long" %} 14930 ins_cost(INSN_COST); 14931 ins_encode %{ 14932 __ subs(zr, $op1$$Register, $op2$$constant); 14933 %} 14934 14935 ins_pipe(icmp_reg_imm); 14936 %} 14937 14938 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14939 %{ 14940 match(Set cr (OverflowSubI zero op1)); 14941 14942 format %{ "cmpw zr, $op1\t# overflow check int" %} 14943 ins_cost(INSN_COST); 14944 ins_encode %{ 14945 __ cmpw(zr, $op1$$Register); 14946 %} 14947 14948 ins_pipe(icmp_reg_imm); 14949 %} 14950 14951 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14952 %{ 14953 match(Set cr (OverflowSubL zero op1)); 14954 14955 format %{ "cmp zr, $op1\t# overflow check long" %} 14956 ins_cost(INSN_COST); 14957 ins_encode %{ 14958 __ cmp(zr, $op1$$Register); 14959 %} 14960 14961 ins_pipe(icmp_reg_imm); 14962 %} 14963 14964 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14965 %{ 14966 match(Set cr (OverflowMulI op1 op2)); 14967 14968 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14969 "cmp rscratch1, rscratch1, sxtw\n\t" 14970 "movw rscratch1, #0x80000000\n\t" 14971 "cselw rscratch1, rscratch1, zr, NE\n\t" 14972 "cmpw rscratch1, #1" %} 14973 ins_cost(5 * INSN_COST); 14974 ins_encode %{ 14975 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14976 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14977 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14978 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14979 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14980 %} 14981 14982 ins_pipe(pipe_slow); 14983 %} 14984 14985 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14986 %{ 14987 match(If cmp (OverflowMulI op1 op2)); 14988 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14989 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14990 effect(USE labl, KILL cr); 14991 14992 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14993 "cmp rscratch1, rscratch1, sxtw\n\t" 14994 "b$cmp $labl" %} 14995 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14996 ins_encode %{ 14997 Label* L = $labl$$label; 14998 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14999 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15000 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15001 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15002 %} 15003 15004 ins_pipe(pipe_serial); 15005 %} 15006 15007 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15008 %{ 15009 match(Set cr (OverflowMulL op1 op2)); 15010 15011 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15012 "smulh rscratch2, $op1, $op2\n\t" 15013 "cmp rscratch2, rscratch1, ASR #63\n\t" 15014 "movw rscratch1, #0x80000000\n\t" 15015 "cselw rscratch1, rscratch1, zr, NE\n\t" 15016 "cmpw rscratch1, #1" %} 15017 ins_cost(6 * INSN_COST); 15018 ins_encode %{ 15019 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15020 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15021 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15022 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15023 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15024 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15025 %} 15026 15027 ins_pipe(pipe_slow); 15028 %} 15029 15030 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 15031 %{ 15032 match(If cmp (OverflowMulL op1 op2)); 15033 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15034 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15035 effect(USE labl, KILL cr); 15036 15037 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15038 "smulh rscratch2, $op1, $op2\n\t" 15039 "cmp rscratch2, rscratch1, ASR #63\n\t" 15040 "b$cmp $labl" %} 15041 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 15042 ins_encode %{ 15043 Label* L = $labl$$label; 15044 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15045 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15046 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15047 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15048 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15049 %} 15050 15051 ins_pipe(pipe_serial); 15052 %} 15053 15054 // ============================================================================ 15055 // Compare Instructions 15056 15057 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 15058 %{ 15059 match(Set cr (CmpI op1 op2)); 15060 15061 effect(DEF cr, USE op1, USE op2); 15062 15063 ins_cost(INSN_COST); 15064 format %{ "cmpw $op1, $op2" %} 15065 15066 ins_encode(aarch64_enc_cmpw(op1, op2)); 15067 15068 ins_pipe(icmp_reg_reg); 15069 %} 15070 15071 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 15072 %{ 15073 match(Set cr (CmpI op1 zero)); 15074 15075 effect(DEF cr, USE op1); 15076 15077 ins_cost(INSN_COST); 15078 format %{ "cmpw $op1, 0" %} 15079 15080 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15081 15082 ins_pipe(icmp_reg_imm); 15083 %} 15084 15085 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 15086 %{ 15087 match(Set cr (CmpI op1 op2)); 15088 15089 effect(DEF cr, USE op1); 15090 15091 ins_cost(INSN_COST); 15092 format %{ "cmpw $op1, $op2" %} 15093 15094 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15095 15096 ins_pipe(icmp_reg_imm); 15097 %} 15098 15099 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 15100 %{ 15101 match(Set cr (CmpI op1 op2)); 15102 15103 effect(DEF cr, USE op1); 15104 15105 ins_cost(INSN_COST * 2); 15106 format %{ "cmpw $op1, $op2" %} 15107 15108 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15109 15110 ins_pipe(icmp_reg_imm); 15111 %} 15112 15113 // Unsigned compare Instructions; really, same as signed compare 15114 // except it should only be used to feed an If or a CMovI which takes a 15115 // cmpOpU. 15116 15117 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 15118 %{ 15119 match(Set cr (CmpU op1 op2)); 15120 15121 effect(DEF cr, USE op1, USE op2); 15122 15123 ins_cost(INSN_COST); 15124 format %{ "cmpw $op1, $op2\t# unsigned" %} 15125 15126 ins_encode(aarch64_enc_cmpw(op1, op2)); 15127 15128 ins_pipe(icmp_reg_reg); 15129 %} 15130 15131 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 15132 %{ 15133 match(Set cr (CmpU op1 zero)); 15134 15135 effect(DEF cr, USE op1); 15136 15137 ins_cost(INSN_COST); 15138 format %{ "cmpw $op1, #0\t# unsigned" %} 15139 15140 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15141 15142 ins_pipe(icmp_reg_imm); 15143 %} 15144 15145 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 15146 %{ 15147 match(Set cr (CmpU op1 op2)); 15148 15149 effect(DEF cr, USE op1); 15150 15151 ins_cost(INSN_COST); 15152 format %{ "cmpw $op1, $op2\t# unsigned" %} 15153 15154 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15155 15156 ins_pipe(icmp_reg_imm); 15157 %} 15158 15159 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 15160 %{ 15161 match(Set cr (CmpU op1 op2)); 15162 15163 effect(DEF cr, USE op1); 15164 15165 ins_cost(INSN_COST * 2); 15166 format %{ "cmpw $op1, $op2\t# unsigned" %} 15167 15168 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15169 15170 ins_pipe(icmp_reg_imm); 15171 %} 15172 15173 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15174 %{ 15175 match(Set cr (CmpL op1 op2)); 15176 15177 effect(DEF cr, USE op1, USE op2); 15178 15179 ins_cost(INSN_COST); 15180 format %{ "cmp $op1, $op2" %} 15181 15182 ins_encode(aarch64_enc_cmp(op1, op2)); 15183 15184 ins_pipe(icmp_reg_reg); 15185 %} 15186 15187 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 15188 %{ 15189 match(Set cr (CmpL op1 zero)); 15190 15191 effect(DEF cr, USE op1); 15192 15193 ins_cost(INSN_COST); 15194 format %{ "tst $op1" %} 15195 15196 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15197 15198 ins_pipe(icmp_reg_imm); 15199 %} 15200 15201 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 15202 %{ 15203 match(Set cr (CmpL op1 op2)); 15204 15205 effect(DEF cr, USE op1); 15206 15207 ins_cost(INSN_COST); 15208 format %{ "cmp $op1, $op2" %} 15209 15210 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15211 15212 ins_pipe(icmp_reg_imm); 15213 %} 15214 15215 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 15216 %{ 15217 match(Set cr (CmpL op1 op2)); 15218 15219 effect(DEF cr, USE op1); 15220 15221 ins_cost(INSN_COST * 2); 15222 format %{ "cmp $op1, $op2" %} 15223 15224 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15225 15226 ins_pipe(icmp_reg_imm); 15227 %} 15228 15229 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 15230 %{ 15231 match(Set cr (CmpUL op1 op2)); 15232 15233 effect(DEF cr, USE op1, USE op2); 15234 15235 ins_cost(INSN_COST); 15236 format %{ "cmp $op1, $op2" %} 15237 15238 ins_encode(aarch64_enc_cmp(op1, op2)); 15239 15240 ins_pipe(icmp_reg_reg); 15241 %} 15242 15243 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 15244 %{ 15245 match(Set cr (CmpUL op1 zero)); 15246 15247 effect(DEF cr, USE op1); 15248 15249 ins_cost(INSN_COST); 15250 format %{ "tst $op1" %} 15251 15252 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15253 15254 ins_pipe(icmp_reg_imm); 15255 %} 15256 15257 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 15258 %{ 15259 match(Set cr (CmpUL op1 op2)); 15260 15261 effect(DEF cr, USE op1); 15262 15263 ins_cost(INSN_COST); 15264 format %{ "cmp $op1, $op2" %} 15265 15266 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15267 15268 ins_pipe(icmp_reg_imm); 15269 %} 15270 15271 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 15272 %{ 15273 match(Set cr (CmpUL op1 op2)); 15274 15275 effect(DEF cr, USE op1); 15276 15277 ins_cost(INSN_COST * 2); 15278 format %{ "cmp $op1, $op2" %} 15279 15280 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15281 15282 ins_pipe(icmp_reg_imm); 15283 %} 15284 15285 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 15286 %{ 15287 match(Set cr (CmpP op1 op2)); 15288 15289 effect(DEF cr, USE op1, USE op2); 15290 15291 ins_cost(INSN_COST); 15292 format %{ "cmp $op1, $op2\t // ptr" %} 15293 15294 ins_encode(aarch64_enc_cmpp(op1, op2)); 15295 15296 ins_pipe(icmp_reg_reg); 15297 %} 15298 15299 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 15300 %{ 15301 match(Set cr (CmpN op1 op2)); 15302 15303 effect(DEF cr, USE op1, USE op2); 15304 15305 ins_cost(INSN_COST); 15306 format %{ "cmp $op1, $op2\t // compressed ptr" %} 15307 15308 ins_encode(aarch64_enc_cmpn(op1, op2)); 15309 15310 ins_pipe(icmp_reg_reg); 15311 %} 15312 15313 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 15314 %{ 15315 match(Set cr (CmpP op1 zero)); 15316 15317 effect(DEF cr, USE op1, USE zero); 15318 15319 ins_cost(INSN_COST); 15320 format %{ "cmp $op1, 0\t // ptr" %} 15321 15322 ins_encode(aarch64_enc_testp(op1)); 15323 15324 ins_pipe(icmp_reg_imm); 15325 %} 15326 15327 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 15328 %{ 15329 match(Set cr (CmpN op1 zero)); 15330 15331 effect(DEF cr, USE op1, USE zero); 15332 15333 ins_cost(INSN_COST); 15334 format %{ "cmp $op1, 0\t // compressed ptr" %} 15335 15336 ins_encode(aarch64_enc_testn(op1)); 15337 15338 ins_pipe(icmp_reg_imm); 15339 %} 15340 15341 // FP comparisons 15342 // 15343 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 15344 // using normal cmpOp. See declaration of rFlagsReg for details. 15345 15346 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 15347 %{ 15348 match(Set cr (CmpF src1 src2)); 15349 15350 ins_cost(3 * INSN_COST); 15351 format %{ "fcmps $src1, $src2" %} 15352 15353 ins_encode %{ 15354 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15355 %} 15356 15357 ins_pipe(pipe_class_compare); 15358 %} 15359 15360 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 15361 %{ 15362 match(Set cr (CmpF src1 src2)); 15363 15364 ins_cost(3 * INSN_COST); 15365 format %{ "fcmps $src1, 0.0" %} 15366 15367 ins_encode %{ 15368 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 15369 %} 15370 15371 ins_pipe(pipe_class_compare); 15372 %} 15373 // FROM HERE 15374 15375 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 15376 %{ 15377 match(Set cr (CmpD src1 src2)); 15378 15379 ins_cost(3 * INSN_COST); 15380 format %{ "fcmpd $src1, $src2" %} 15381 15382 ins_encode %{ 15383 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15384 %} 15385 15386 ins_pipe(pipe_class_compare); 15387 %} 15388 15389 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 15390 %{ 15391 match(Set cr (CmpD src1 src2)); 15392 15393 ins_cost(3 * INSN_COST); 15394 format %{ "fcmpd $src1, 0.0" %} 15395 15396 ins_encode %{ 15397 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 15398 %} 15399 15400 ins_pipe(pipe_class_compare); 15401 %} 15402 15403 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 15404 %{ 15405 match(Set dst (CmpF3 src1 src2)); 15406 effect(KILL cr); 15407 15408 ins_cost(5 * INSN_COST); 15409 format %{ "fcmps $src1, $src2\n\t" 15410 "csinvw($dst, zr, zr, eq\n\t" 15411 "csnegw($dst, $dst, $dst, lt)" 15412 %} 15413 15414 ins_encode %{ 15415 Label done; 15416 FloatRegister s1 = as_FloatRegister($src1$$reg); 15417 FloatRegister s2 = as_FloatRegister($src2$$reg); 15418 Register d = as_Register($dst$$reg); 15419 __ fcmps(s1, s2); 15420 // installs 0 if EQ else -1 15421 __ csinvw(d, zr, zr, Assembler::EQ); 15422 // keeps -1 if less or unordered else installs 1 15423 __ csnegw(d, d, d, Assembler::LT); 15424 __ bind(done); 15425 %} 15426 15427 ins_pipe(pipe_class_default); 15428 15429 %} 15430 15431 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 15432 %{ 15433 match(Set dst (CmpD3 src1 src2)); 15434 effect(KILL cr); 15435 15436 ins_cost(5 * INSN_COST); 15437 format %{ "fcmpd $src1, $src2\n\t" 15438 "csinvw($dst, zr, zr, eq\n\t" 15439 "csnegw($dst, $dst, $dst, lt)" 15440 %} 15441 15442 ins_encode %{ 15443 Label done; 15444 FloatRegister s1 = as_FloatRegister($src1$$reg); 15445 FloatRegister s2 = as_FloatRegister($src2$$reg); 15446 Register d = as_Register($dst$$reg); 15447 __ fcmpd(s1, s2); 15448 // installs 0 if EQ else -1 15449 __ csinvw(d, zr, zr, Assembler::EQ); 15450 // keeps -1 if less or unordered else installs 1 15451 __ csnegw(d, d, d, Assembler::LT); 15452 __ bind(done); 15453 %} 15454 ins_pipe(pipe_class_default); 15455 15456 %} 15457 15458 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 15459 %{ 15460 match(Set dst (CmpF3 src1 zero)); 15461 effect(KILL cr); 15462 15463 ins_cost(5 * INSN_COST); 15464 format %{ "fcmps $src1, 0.0\n\t" 15465 "csinvw($dst, zr, zr, eq\n\t" 15466 "csnegw($dst, $dst, $dst, lt)" 15467 %} 15468 15469 ins_encode %{ 15470 Label done; 15471 FloatRegister s1 = as_FloatRegister($src1$$reg); 15472 Register d = as_Register($dst$$reg); 15473 __ fcmps(s1, 0.0); 15474 // installs 0 if EQ else -1 15475 __ csinvw(d, zr, zr, Assembler::EQ); 15476 // keeps -1 if less or unordered else installs 1 15477 __ csnegw(d, d, d, Assembler::LT); 15478 __ bind(done); 15479 %} 15480 15481 ins_pipe(pipe_class_default); 15482 15483 %} 15484 15485 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 15486 %{ 15487 match(Set dst (CmpD3 src1 zero)); 15488 effect(KILL cr); 15489 15490 ins_cost(5 * INSN_COST); 15491 format %{ "fcmpd $src1, 0.0\n\t" 15492 "csinvw($dst, zr, zr, eq\n\t" 15493 "csnegw($dst, $dst, $dst, lt)" 15494 %} 15495 15496 ins_encode %{ 15497 Label done; 15498 FloatRegister s1 = as_FloatRegister($src1$$reg); 15499 Register d = as_Register($dst$$reg); 15500 __ fcmpd(s1, 0.0); 15501 // installs 0 if EQ else -1 15502 __ csinvw(d, zr, zr, Assembler::EQ); 15503 // keeps -1 if less or unordered else installs 1 15504 __ csnegw(d, d, d, Assembler::LT); 15505 __ bind(done); 15506 %} 15507 ins_pipe(pipe_class_default); 15508 15509 %} 15510 15511 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 15512 %{ 15513 match(Set dst (CmpLTMask p q)); 15514 effect(KILL cr); 15515 15516 ins_cost(3 * INSN_COST); 15517 15518 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 15519 "csetw $dst, lt\n\t" 15520 "subw $dst, zr, $dst" 15521 %} 15522 15523 ins_encode %{ 15524 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 15525 __ csetw(as_Register($dst$$reg), Assembler::LT); 15526 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 15527 %} 15528 15529 ins_pipe(ialu_reg_reg); 15530 %} 15531 15532 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 15533 %{ 15534 match(Set dst (CmpLTMask src zero)); 15535 effect(KILL cr); 15536 15537 ins_cost(INSN_COST); 15538 15539 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 15540 15541 ins_encode %{ 15542 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 15543 %} 15544 15545 ins_pipe(ialu_reg_shift); 15546 %} 15547 15548 // ============================================================================ 15549 // Max and Min 15550 15551 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter. 15552 15553 instruct compI_reg_imm0(rFlagsReg cr, iRegI src) 15554 %{ 15555 effect(DEF cr, USE src); 15556 ins_cost(INSN_COST); 15557 format %{ "cmpw $src, 0" %} 15558 15559 ins_encode %{ 15560 __ cmpw($src$$Register, 0); 15561 %} 15562 ins_pipe(icmp_reg_imm); 15563 %} 15564 15565 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 15566 %{ 15567 match(Set dst (MinI src1 src2)); 15568 ins_cost(INSN_COST * 3); 15569 15570 expand %{ 15571 rFlagsReg cr; 15572 compI_reg_reg(cr, src1, src2); 15573 cmovI_reg_reg_lt(dst, src1, src2, cr); 15574 %} 15575 %} 15576 15577 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 15578 %{ 15579 match(Set dst (MaxI src1 src2)); 15580 ins_cost(INSN_COST * 3); 15581 15582 expand %{ 15583 rFlagsReg cr; 15584 compI_reg_reg(cr, src1, src2); 15585 cmovI_reg_reg_gt(dst, src1, src2, cr); 15586 %} 15587 %} 15588 15589 15590 // ============================================================================ 15591 // Branch Instructions 15592 15593 // Direct Branch. 15594 instruct branch(label lbl) 15595 %{ 15596 match(Goto); 15597 15598 effect(USE lbl); 15599 15600 ins_cost(BRANCH_COST); 15601 format %{ "b $lbl" %} 15602 15603 ins_encode(aarch64_enc_b(lbl)); 15604 15605 ins_pipe(pipe_branch); 15606 %} 15607 15608 // Conditional Near Branch 15609 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 15610 %{ 15611 // Same match rule as `branchConFar'. 15612 match(If cmp cr); 15613 15614 effect(USE lbl); 15615 15616 ins_cost(BRANCH_COST); 15617 // If set to 1 this indicates that the current instruction is a 15618 // short variant of a long branch. This avoids using this 15619 // instruction in first-pass matching. It will then only be used in 15620 // the `Shorten_branches' pass. 15621 // ins_short_branch(1); 15622 format %{ "b$cmp $lbl" %} 15623 15624 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15625 15626 ins_pipe(pipe_branch_cond); 15627 %} 15628 15629 // Conditional Near Branch Unsigned 15630 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15631 %{ 15632 // Same match rule as `branchConFar'. 15633 match(If cmp cr); 15634 15635 effect(USE lbl); 15636 15637 ins_cost(BRANCH_COST); 15638 // If set to 1 this indicates that the current instruction is a 15639 // short variant of a long branch. This avoids using this 15640 // instruction in first-pass matching. It will then only be used in 15641 // the `Shorten_branches' pass. 15642 // ins_short_branch(1); 15643 format %{ "b$cmp $lbl\t# unsigned" %} 15644 15645 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15646 15647 ins_pipe(pipe_branch_cond); 15648 %} 15649 15650 // Make use of CBZ and CBNZ. These instructions, as well as being 15651 // shorter than (cmp; branch), have the additional benefit of not 15652 // killing the flags. 15653 15654 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 15655 match(If cmp (CmpI op1 op2)); 15656 effect(USE labl); 15657 15658 ins_cost(BRANCH_COST); 15659 format %{ "cbw$cmp $op1, $labl" %} 15660 ins_encode %{ 15661 Label* L = $labl$$label; 15662 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15663 if (cond == Assembler::EQ) 15664 __ cbzw($op1$$Register, *L); 15665 else 15666 __ cbnzw($op1$$Register, *L); 15667 %} 15668 ins_pipe(pipe_cmp_branch); 15669 %} 15670 15671 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 15672 match(If cmp (CmpL op1 op2)); 15673 effect(USE labl); 15674 15675 ins_cost(BRANCH_COST); 15676 format %{ "cb$cmp $op1, $labl" %} 15677 ins_encode %{ 15678 Label* L = $labl$$label; 15679 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15680 if (cond == Assembler::EQ) 15681 __ cbz($op1$$Register, *L); 15682 else 15683 __ cbnz($op1$$Register, *L); 15684 %} 15685 ins_pipe(pipe_cmp_branch); 15686 %} 15687 15688 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 15689 match(If cmp (CmpP op1 op2)); 15690 effect(USE labl); 15691 15692 ins_cost(BRANCH_COST); 15693 format %{ "cb$cmp $op1, $labl" %} 15694 ins_encode %{ 15695 Label* L = $labl$$label; 15696 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15697 if (cond == Assembler::EQ) 15698 __ cbz($op1$$Register, *L); 15699 else 15700 __ cbnz($op1$$Register, *L); 15701 %} 15702 ins_pipe(pipe_cmp_branch); 15703 %} 15704 15705 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 15706 match(If cmp (CmpN op1 op2)); 15707 effect(USE labl); 15708 15709 ins_cost(BRANCH_COST); 15710 format %{ "cbw$cmp $op1, $labl" %} 15711 ins_encode %{ 15712 Label* L = $labl$$label; 15713 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15714 if (cond == Assembler::EQ) 15715 __ cbzw($op1$$Register, *L); 15716 else 15717 __ cbnzw($op1$$Register, *L); 15718 %} 15719 ins_pipe(pipe_cmp_branch); 15720 %} 15721 15722 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 15723 match(If cmp (CmpP (DecodeN oop) zero)); 15724 effect(USE labl); 15725 15726 ins_cost(BRANCH_COST); 15727 format %{ "cb$cmp $oop, $labl" %} 15728 ins_encode %{ 15729 Label* L = $labl$$label; 15730 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15731 if (cond == Assembler::EQ) 15732 __ cbzw($oop$$Register, *L); 15733 else 15734 __ cbnzw($oop$$Register, *L); 15735 %} 15736 ins_pipe(pipe_cmp_branch); 15737 %} 15738 15739 instruct cmpUI_imm0_branch(cmpOpUEqNeLeGt cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15740 match(If cmp (CmpU op1 op2)); 15741 effect(USE labl); 15742 15743 ins_cost(BRANCH_COST); 15744 format %{ "cbw$cmp $op1, $labl" %} 15745 ins_encode %{ 15746 Label* L = $labl$$label; 15747 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15748 if (cond == Assembler::EQ || cond == Assembler::LS) { 15749 __ cbzw($op1$$Register, *L); 15750 } else { 15751 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition"); 15752 __ cbnzw($op1$$Register, *L); 15753 } 15754 %} 15755 ins_pipe(pipe_cmp_branch); 15756 %} 15757 15758 instruct cmpUL_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 op2, label labl) %{ 15759 match(If cmp (CmpUL op1 op2)); 15760 effect(USE labl); 15761 15762 ins_cost(BRANCH_COST); 15763 format %{ "cb$cmp $op1, $labl" %} 15764 ins_encode %{ 15765 Label* L = $labl$$label; 15766 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15767 if (cond == Assembler::EQ || cond == Assembler::LS) { 15768 __ cbz($op1$$Register, *L); 15769 } else { 15770 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition"); 15771 __ cbnz($op1$$Register, *L); 15772 } 15773 %} 15774 ins_pipe(pipe_cmp_branch); 15775 %} 15776 15777 // Test bit and Branch 15778 15779 // Patterns for short (< 32KiB) variants 15780 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15781 match(If cmp (CmpL op1 op2)); 15782 effect(USE labl); 15783 15784 ins_cost(BRANCH_COST); 15785 format %{ "cb$cmp $op1, $labl # long" %} 15786 ins_encode %{ 15787 Label* L = $labl$$label; 15788 Assembler::Condition cond = 15789 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15790 __ tbr(cond, $op1$$Register, 63, *L); 15791 %} 15792 ins_pipe(pipe_cmp_branch); 15793 ins_short_branch(1); 15794 %} 15795 15796 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15797 match(If cmp (CmpI op1 op2)); 15798 effect(USE labl); 15799 15800 ins_cost(BRANCH_COST); 15801 format %{ "cb$cmp $op1, $labl # int" %} 15802 ins_encode %{ 15803 Label* L = $labl$$label; 15804 Assembler::Condition cond = 15805 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15806 __ tbr(cond, $op1$$Register, 31, *L); 15807 %} 15808 ins_pipe(pipe_cmp_branch); 15809 ins_short_branch(1); 15810 %} 15811 15812 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15813 match(If cmp (CmpL (AndL op1 op2) op3)); 15814 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15815 effect(USE labl); 15816 15817 ins_cost(BRANCH_COST); 15818 format %{ "tb$cmp $op1, $op2, $labl" %} 15819 ins_encode %{ 15820 Label* L = $labl$$label; 15821 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15822 int bit = exact_log2_long($op2$$constant); 15823 __ tbr(cond, $op1$$Register, bit, *L); 15824 %} 15825 ins_pipe(pipe_cmp_branch); 15826 ins_short_branch(1); 15827 %} 15828 15829 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15830 match(If cmp (CmpI (AndI op1 op2) op3)); 15831 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15832 effect(USE labl); 15833 15834 ins_cost(BRANCH_COST); 15835 format %{ "tb$cmp $op1, $op2, $labl" %} 15836 ins_encode %{ 15837 Label* L = $labl$$label; 15838 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15839 int bit = exact_log2((juint)$op2$$constant); 15840 __ tbr(cond, $op1$$Register, bit, *L); 15841 %} 15842 ins_pipe(pipe_cmp_branch); 15843 ins_short_branch(1); 15844 %} 15845 15846 // And far variants 15847 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15848 match(If cmp (CmpL op1 op2)); 15849 effect(USE labl); 15850 15851 ins_cost(BRANCH_COST); 15852 format %{ "cb$cmp $op1, $labl # long" %} 15853 ins_encode %{ 15854 Label* L = $labl$$label; 15855 Assembler::Condition cond = 15856 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15857 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 15858 %} 15859 ins_pipe(pipe_cmp_branch); 15860 %} 15861 15862 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15863 match(If cmp (CmpI op1 op2)); 15864 effect(USE labl); 15865 15866 ins_cost(BRANCH_COST); 15867 format %{ "cb$cmp $op1, $labl # int" %} 15868 ins_encode %{ 15869 Label* L = $labl$$label; 15870 Assembler::Condition cond = 15871 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15872 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 15873 %} 15874 ins_pipe(pipe_cmp_branch); 15875 %} 15876 15877 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15878 match(If cmp (CmpL (AndL op1 op2) op3)); 15879 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15880 effect(USE labl); 15881 15882 ins_cost(BRANCH_COST); 15883 format %{ "tb$cmp $op1, $op2, $labl" %} 15884 ins_encode %{ 15885 Label* L = $labl$$label; 15886 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15887 int bit = exact_log2_long($op2$$constant); 15888 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15889 %} 15890 ins_pipe(pipe_cmp_branch); 15891 %} 15892 15893 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15894 match(If cmp (CmpI (AndI op1 op2) op3)); 15895 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15896 effect(USE labl); 15897 15898 ins_cost(BRANCH_COST); 15899 format %{ "tb$cmp $op1, $op2, $labl" %} 15900 ins_encode %{ 15901 Label* L = $labl$$label; 15902 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15903 int bit = exact_log2((juint)$op2$$constant); 15904 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15905 %} 15906 ins_pipe(pipe_cmp_branch); 15907 %} 15908 15909 // Test bits 15910 15911 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15912 match(Set cr (CmpL (AndL op1 op2) op3)); 15913 predicate(Assembler::operand_valid_for_logical_immediate 15914 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15915 15916 ins_cost(INSN_COST); 15917 format %{ "tst $op1, $op2 # long" %} 15918 ins_encode %{ 15919 __ tst($op1$$Register, $op2$$constant); 15920 %} 15921 ins_pipe(ialu_reg_reg); 15922 %} 15923 15924 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15925 match(Set cr (CmpI (AndI op1 op2) op3)); 15926 predicate(Assembler::operand_valid_for_logical_immediate 15927 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15928 15929 ins_cost(INSN_COST); 15930 format %{ "tst $op1, $op2 # int" %} 15931 ins_encode %{ 15932 __ tstw($op1$$Register, $op2$$constant); 15933 %} 15934 ins_pipe(ialu_reg_reg); 15935 %} 15936 15937 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15938 match(Set cr (CmpL (AndL op1 op2) op3)); 15939 15940 ins_cost(INSN_COST); 15941 format %{ "tst $op1, $op2 # long" %} 15942 ins_encode %{ 15943 __ tst($op1$$Register, $op2$$Register); 15944 %} 15945 ins_pipe(ialu_reg_reg); 15946 %} 15947 15948 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15949 match(Set cr (CmpI (AndI op1 op2) op3)); 15950 15951 ins_cost(INSN_COST); 15952 format %{ "tstw $op1, $op2 # int" %} 15953 ins_encode %{ 15954 __ tstw($op1$$Register, $op2$$Register); 15955 %} 15956 ins_pipe(ialu_reg_reg); 15957 %} 15958 15959 15960 // Conditional Far Branch 15961 // Conditional Far Branch Unsigned 15962 // TODO: fixme 15963 15964 // counted loop end branch near 15965 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15966 %{ 15967 match(CountedLoopEnd cmp cr); 15968 15969 effect(USE lbl); 15970 15971 ins_cost(BRANCH_COST); 15972 // short variant. 15973 // ins_short_branch(1); 15974 format %{ "b$cmp $lbl \t// counted loop end" %} 15975 15976 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15977 15978 ins_pipe(pipe_branch); 15979 %} 15980 15981 // counted loop end branch far 15982 // TODO: fixme 15983 15984 // ============================================================================ 15985 // inlined locking and unlocking 15986 15987 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 15988 %{ 15989 predicate(LockingMode != LM_LIGHTWEIGHT); 15990 match(Set cr (FastLock object box)); 15991 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 15992 15993 ins_cost(5 * INSN_COST); 15994 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %} 15995 15996 ins_encode %{ 15997 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 15998 %} 15999 16000 ins_pipe(pipe_serial); 16001 %} 16002 16003 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16004 %{ 16005 predicate(LockingMode != LM_LIGHTWEIGHT); 16006 match(Set cr (FastUnlock object box)); 16007 effect(TEMP tmp, TEMP tmp2); 16008 16009 ins_cost(5 * INSN_COST); 16010 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 16011 16012 ins_encode %{ 16013 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register); 16014 %} 16015 16016 ins_pipe(pipe_serial); 16017 %} 16018 16019 instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 16020 %{ 16021 predicate(LockingMode == LM_LIGHTWEIGHT); 16022 match(Set cr (FastLock object box)); 16023 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 16024 16025 ins_cost(5 * INSN_COST); 16026 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %} 16027 16028 ins_encode %{ 16029 __ fast_lock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 16030 %} 16031 16032 ins_pipe(pipe_serial); 16033 %} 16034 16035 instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 16036 %{ 16037 predicate(LockingMode == LM_LIGHTWEIGHT); 16038 match(Set cr (FastUnlock object box)); 16039 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 16040 16041 ins_cost(5 * INSN_COST); 16042 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2, $tmp3" %} 16043 16044 ins_encode %{ 16045 __ fast_unlock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 16046 %} 16047 16048 ins_pipe(pipe_serial); 16049 %} 16050 16051 // ============================================================================ 16052 // Safepoint Instructions 16053 16054 // TODO 16055 // provide a near and far version of this code 16056 16057 instruct safePoint(rFlagsReg cr, iRegP poll) 16058 %{ 16059 match(SafePoint poll); 16060 effect(KILL cr); 16061 16062 format %{ 16063 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 16064 %} 16065 ins_encode %{ 16066 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 16067 %} 16068 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 16069 %} 16070 16071 16072 // ============================================================================ 16073 // Procedure Call/Return Instructions 16074 16075 // Call Java Static Instruction 16076 16077 instruct CallStaticJavaDirect(method meth) 16078 %{ 16079 match(CallStaticJava); 16080 16081 effect(USE meth); 16082 16083 ins_cost(CALL_COST); 16084 16085 format %{ "call,static $meth \t// ==> " %} 16086 16087 ins_encode(aarch64_enc_java_static_call(meth), 16088 aarch64_enc_call_epilog); 16089 16090 ins_pipe(pipe_class_call); 16091 %} 16092 16093 // TO HERE 16094 16095 // Call Java Dynamic Instruction 16096 instruct CallDynamicJavaDirect(method meth) 16097 %{ 16098 match(CallDynamicJava); 16099 16100 effect(USE meth); 16101 16102 ins_cost(CALL_COST); 16103 16104 format %{ "CALL,dynamic $meth \t// ==> " %} 16105 16106 ins_encode(aarch64_enc_java_dynamic_call(meth), 16107 aarch64_enc_call_epilog); 16108 16109 ins_pipe(pipe_class_call); 16110 %} 16111 16112 // Call Runtime Instruction 16113 16114 instruct CallRuntimeDirect(method meth) 16115 %{ 16116 match(CallRuntime); 16117 16118 effect(USE meth); 16119 16120 ins_cost(CALL_COST); 16121 16122 format %{ "CALL, runtime $meth" %} 16123 16124 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16125 16126 ins_pipe(pipe_class_call); 16127 %} 16128 16129 // Call Runtime Instruction 16130 16131 instruct CallLeafDirect(method meth) 16132 %{ 16133 match(CallLeaf); 16134 16135 effect(USE meth); 16136 16137 ins_cost(CALL_COST); 16138 16139 format %{ "CALL, runtime leaf $meth" %} 16140 16141 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16142 16143 ins_pipe(pipe_class_call); 16144 %} 16145 16146 // Call Runtime Instruction 16147 16148 instruct CallLeafNoFPDirect(method meth) 16149 %{ 16150 match(CallLeafNoFP); 16151 16152 effect(USE meth); 16153 16154 ins_cost(CALL_COST); 16155 16156 format %{ "CALL, runtime leaf nofp $meth" %} 16157 16158 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16159 16160 ins_pipe(pipe_class_call); 16161 %} 16162 16163 // Tail Call; Jump from runtime stub to Java code. 16164 // Also known as an 'interprocedural jump'. 16165 // Target of jump will eventually return to caller. 16166 // TailJump below removes the return address. 16167 // Don't use rfp for 'jump_target' because a MachEpilogNode has already been 16168 // emitted just above the TailCall which has reset rfp to the caller state. 16169 instruct TailCalljmpInd(iRegPNoSpNoRfp jump_target, inline_cache_RegP method_ptr) 16170 %{ 16171 match(TailCall jump_target method_ptr); 16172 16173 ins_cost(CALL_COST); 16174 16175 format %{ "br $jump_target\t# $method_ptr holds method" %} 16176 16177 ins_encode(aarch64_enc_tail_call(jump_target)); 16178 16179 ins_pipe(pipe_class_call); 16180 %} 16181 16182 instruct TailjmpInd(iRegPNoSpNoRfp jump_target, iRegP_R0 ex_oop) 16183 %{ 16184 match(TailJump jump_target ex_oop); 16185 16186 ins_cost(CALL_COST); 16187 16188 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 16189 16190 ins_encode(aarch64_enc_tail_jmp(jump_target)); 16191 16192 ins_pipe(pipe_class_call); 16193 %} 16194 16195 // Forward exception. 16196 instruct ForwardExceptionjmp() 16197 %{ 16198 match(ForwardException); 16199 ins_cost(CALL_COST); 16200 16201 format %{ "b forward_exception_stub" %} 16202 ins_encode %{ 16203 __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); 16204 %} 16205 ins_pipe(pipe_class_call); 16206 %} 16207 16208 // Create exception oop: created by stack-crawling runtime code. 16209 // Created exception is now available to this handler, and is setup 16210 // just prior to jumping to this handler. No code emitted. 16211 // TODO check 16212 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 16213 instruct CreateException(iRegP_R0 ex_oop) 16214 %{ 16215 match(Set ex_oop (CreateEx)); 16216 16217 format %{ " -- \t// exception oop; no code emitted" %} 16218 16219 size(0); 16220 16221 ins_encode( /*empty*/ ); 16222 16223 ins_pipe(pipe_class_empty); 16224 %} 16225 16226 // Rethrow exception: The exception oop will come in the first 16227 // argument position. Then JUMP (not call) to the rethrow stub code. 16228 instruct RethrowException() %{ 16229 match(Rethrow); 16230 ins_cost(CALL_COST); 16231 16232 format %{ "b rethrow_stub" %} 16233 16234 ins_encode( aarch64_enc_rethrow() ); 16235 16236 ins_pipe(pipe_class_call); 16237 %} 16238 16239 16240 // Return Instruction 16241 // epilog node loads ret address into lr as part of frame pop 16242 instruct Ret() 16243 %{ 16244 match(Return); 16245 16246 format %{ "ret\t// return register" %} 16247 16248 ins_encode( aarch64_enc_ret() ); 16249 16250 ins_pipe(pipe_branch); 16251 %} 16252 16253 // Die now. 16254 instruct ShouldNotReachHere() %{ 16255 match(Halt); 16256 16257 ins_cost(CALL_COST); 16258 format %{ "ShouldNotReachHere" %} 16259 16260 ins_encode %{ 16261 if (is_reachable()) { 16262 __ stop(_halt_reason); 16263 } 16264 %} 16265 16266 ins_pipe(pipe_class_default); 16267 %} 16268 16269 // ============================================================================ 16270 // Partial Subtype Check 16271 // 16272 // superklass array for an instance of the superklass. Set a hidden 16273 // internal cache on a hit (cache is checked with exposed code in 16274 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 16275 // encoding ALSO sets flags. 16276 16277 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 16278 %{ 16279 match(Set result (PartialSubtypeCheck sub super)); 16280 effect(KILL cr, KILL temp); 16281 16282 ins_cost(1100); // slightly larger than the next version 16283 format %{ "partialSubtypeCheck $result, $sub, $super" %} 16284 16285 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16286 16287 opcode(0x1); // Force zero of result reg on hit 16288 16289 ins_pipe(pipe_class_memory); 16290 %} 16291 16292 instruct partialSubtypeCheckConstSuper(iRegP_R4 sub, iRegP_R0 super_reg, immP super_con, vRegD_V0 vtemp, iRegP_R5 result, 16293 iRegP_R1 tempR1, iRegP_R2 tempR2, iRegP_R3 tempR3, 16294 rFlagsReg cr) 16295 %{ 16296 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 16297 predicate(UseSecondarySupersTable); 16298 effect(KILL cr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP vtemp); 16299 16300 ins_cost(700); // smaller than the next version 16301 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 16302 16303 ins_encode %{ 16304 bool success = false; 16305 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 16306 if (InlineSecondarySupersTest) { 16307 success = __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, 16308 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, 16309 $vtemp$$FloatRegister, 16310 $result$$Register, 16311 super_klass_slot); 16312 } else { 16313 address call = __ trampoline_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 16314 success = (call != nullptr); 16315 } 16316 if (!success) { 16317 ciEnv::current()->record_failure("CodeCache is full"); 16318 return; 16319 } 16320 %} 16321 16322 ins_pipe(pipe_class_memory); 16323 %} 16324 16325 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 16326 %{ 16327 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 16328 effect(KILL temp, KILL result); 16329 16330 ins_cost(1100); // slightly larger than the next version 16331 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 16332 16333 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16334 16335 opcode(0x0); // Don't zero result reg on hit 16336 16337 ins_pipe(pipe_class_memory); 16338 %} 16339 16340 // Intrisics for String.compareTo() 16341 16342 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16343 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16344 %{ 16345 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16346 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16347 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16348 16349 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16350 ins_encode %{ 16351 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16352 __ string_compare($str1$$Register, $str2$$Register, 16353 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16354 $tmp1$$Register, $tmp2$$Register, 16355 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU); 16356 %} 16357 ins_pipe(pipe_class_memory); 16358 %} 16359 16360 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16361 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16362 %{ 16363 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16364 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16365 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16366 16367 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16368 ins_encode %{ 16369 __ string_compare($str1$$Register, $str2$$Register, 16370 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16371 $tmp1$$Register, $tmp2$$Register, 16372 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL); 16373 %} 16374 ins_pipe(pipe_class_memory); 16375 %} 16376 16377 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16378 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16379 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16380 %{ 16381 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16382 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16383 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16384 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16385 16386 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16387 ins_encode %{ 16388 __ string_compare($str1$$Register, $str2$$Register, 16389 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16390 $tmp1$$Register, $tmp2$$Register, 16391 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16392 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL); 16393 %} 16394 ins_pipe(pipe_class_memory); 16395 %} 16396 16397 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16398 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16399 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16400 %{ 16401 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16402 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16403 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16404 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16405 16406 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16407 ins_encode %{ 16408 __ string_compare($str1$$Register, $str2$$Register, 16409 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16410 $tmp1$$Register, $tmp2$$Register, 16411 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16412 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU); 16413 %} 16414 ins_pipe(pipe_class_memory); 16415 %} 16416 16417 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of 16418 // these string_compare variants as NEON register type for convenience so that the prototype of 16419 // string_compare can be shared with all variants. 16420 16421 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16422 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16423 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16424 pRegGov_P1 pgtmp2, rFlagsReg cr) 16425 %{ 16426 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16427 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16428 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16429 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16430 16431 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16432 ins_encode %{ 16433 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16434 __ string_compare($str1$$Register, $str2$$Register, 16435 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16436 $tmp1$$Register, $tmp2$$Register, 16437 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16438 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16439 StrIntrinsicNode::LL); 16440 %} 16441 ins_pipe(pipe_class_memory); 16442 %} 16443 16444 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16445 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16446 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16447 pRegGov_P1 pgtmp2, rFlagsReg cr) 16448 %{ 16449 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16450 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16451 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16452 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16453 16454 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16455 ins_encode %{ 16456 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16457 __ string_compare($str1$$Register, $str2$$Register, 16458 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16459 $tmp1$$Register, $tmp2$$Register, 16460 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16461 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16462 StrIntrinsicNode::LU); 16463 %} 16464 ins_pipe(pipe_class_memory); 16465 %} 16466 16467 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16468 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16469 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16470 pRegGov_P1 pgtmp2, rFlagsReg cr) 16471 %{ 16472 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16473 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16474 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16475 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16476 16477 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16478 ins_encode %{ 16479 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16480 __ string_compare($str1$$Register, $str2$$Register, 16481 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16482 $tmp1$$Register, $tmp2$$Register, 16483 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16484 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16485 StrIntrinsicNode::UL); 16486 %} 16487 ins_pipe(pipe_class_memory); 16488 %} 16489 16490 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16491 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16492 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16493 pRegGov_P1 pgtmp2, rFlagsReg cr) 16494 %{ 16495 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16496 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16497 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16498 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16499 16500 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16501 ins_encode %{ 16502 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16503 __ string_compare($str1$$Register, $str2$$Register, 16504 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16505 $tmp1$$Register, $tmp2$$Register, 16506 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16507 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16508 StrIntrinsicNode::UU); 16509 %} 16510 ins_pipe(pipe_class_memory); 16511 %} 16512 16513 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16514 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16515 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16516 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16517 %{ 16518 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16519 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16520 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16521 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16522 TEMP vtmp0, TEMP vtmp1, KILL cr); 16523 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) " 16524 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16525 16526 ins_encode %{ 16527 __ string_indexof($str1$$Register, $str2$$Register, 16528 $cnt1$$Register, $cnt2$$Register, 16529 $tmp1$$Register, $tmp2$$Register, 16530 $tmp3$$Register, $tmp4$$Register, 16531 $tmp5$$Register, $tmp6$$Register, 16532 -1, $result$$Register, StrIntrinsicNode::UU); 16533 %} 16534 ins_pipe(pipe_class_memory); 16535 %} 16536 16537 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16538 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16539 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16540 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16541 %{ 16542 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16543 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16544 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16545 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16546 TEMP vtmp0, TEMP vtmp1, KILL cr); 16547 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) " 16548 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16549 16550 ins_encode %{ 16551 __ string_indexof($str1$$Register, $str2$$Register, 16552 $cnt1$$Register, $cnt2$$Register, 16553 $tmp1$$Register, $tmp2$$Register, 16554 $tmp3$$Register, $tmp4$$Register, 16555 $tmp5$$Register, $tmp6$$Register, 16556 -1, $result$$Register, StrIntrinsicNode::LL); 16557 %} 16558 ins_pipe(pipe_class_memory); 16559 %} 16560 16561 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16562 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3, 16563 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16564 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16565 %{ 16566 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16567 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16568 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16569 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 16570 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr); 16571 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) " 16572 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16573 16574 ins_encode %{ 16575 __ string_indexof($str1$$Register, $str2$$Register, 16576 $cnt1$$Register, $cnt2$$Register, 16577 $tmp1$$Register, $tmp2$$Register, 16578 $tmp3$$Register, $tmp4$$Register, 16579 $tmp5$$Register, $tmp6$$Register, 16580 -1, $result$$Register, StrIntrinsicNode::UL); 16581 %} 16582 ins_pipe(pipe_class_memory); 16583 %} 16584 16585 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16586 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16587 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16588 %{ 16589 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16590 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16591 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16592 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16593 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) " 16594 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16595 16596 ins_encode %{ 16597 int icnt2 = (int)$int_cnt2$$constant; 16598 __ string_indexof($str1$$Register, $str2$$Register, 16599 $cnt1$$Register, zr, 16600 $tmp1$$Register, $tmp2$$Register, 16601 $tmp3$$Register, $tmp4$$Register, zr, zr, 16602 icnt2, $result$$Register, StrIntrinsicNode::UU); 16603 %} 16604 ins_pipe(pipe_class_memory); 16605 %} 16606 16607 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16608 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16609 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16610 %{ 16611 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16612 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16613 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16614 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16615 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) " 16616 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16617 16618 ins_encode %{ 16619 int icnt2 = (int)$int_cnt2$$constant; 16620 __ string_indexof($str1$$Register, $str2$$Register, 16621 $cnt1$$Register, zr, 16622 $tmp1$$Register, $tmp2$$Register, 16623 $tmp3$$Register, $tmp4$$Register, zr, zr, 16624 icnt2, $result$$Register, StrIntrinsicNode::LL); 16625 %} 16626 ins_pipe(pipe_class_memory); 16627 %} 16628 16629 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16630 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 16631 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16632 %{ 16633 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16634 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16635 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16636 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16637 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) " 16638 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 16639 16640 ins_encode %{ 16641 int icnt2 = (int)$int_cnt2$$constant; 16642 __ string_indexof($str1$$Register, $str2$$Register, 16643 $cnt1$$Register, zr, 16644 $tmp1$$Register, $tmp2$$Register, 16645 $tmp3$$Register, $tmp4$$Register, zr, zr, 16646 icnt2, $result$$Register, StrIntrinsicNode::UL); 16647 %} 16648 ins_pipe(pipe_class_memory); 16649 %} 16650 16651 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16652 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16653 iRegINoSp tmp3, rFlagsReg cr) 16654 %{ 16655 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16656 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 16657 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 16658 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16659 16660 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 16661 16662 ins_encode %{ 16663 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 16664 $result$$Register, $tmp1$$Register, $tmp2$$Register, 16665 $tmp3$$Register); 16666 %} 16667 ins_pipe(pipe_class_memory); 16668 %} 16669 16670 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16671 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16672 iRegINoSp tmp3, rFlagsReg cr) 16673 %{ 16674 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16675 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 16676 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 16677 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16678 16679 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 16680 16681 ins_encode %{ 16682 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 16683 $result$$Register, $tmp1$$Register, $tmp2$$Register, 16684 $tmp3$$Register); 16685 %} 16686 ins_pipe(pipe_class_memory); 16687 %} 16688 16689 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16690 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 16691 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 16692 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 16693 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16694 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 16695 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 16696 ins_encode %{ 16697 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 16698 $result$$Register, $ztmp1$$FloatRegister, 16699 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 16700 $ptmp$$PRegister, true /* isL */); 16701 %} 16702 ins_pipe(pipe_class_memory); 16703 %} 16704 16705 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16706 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 16707 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 16708 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 16709 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16710 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 16711 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 16712 ins_encode %{ 16713 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 16714 $result$$Register, $ztmp1$$FloatRegister, 16715 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 16716 $ptmp$$PRegister, false /* isL */); 16717 %} 16718 ins_pipe(pipe_class_memory); 16719 %} 16720 16721 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 16722 iRegI_R0 result, rFlagsReg cr) 16723 %{ 16724 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 16725 match(Set result (StrEquals (Binary str1 str2) cnt)); 16726 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 16727 16728 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 16729 ins_encode %{ 16730 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16731 __ string_equals($str1$$Register, $str2$$Register, 16732 $result$$Register, $cnt$$Register); 16733 %} 16734 ins_pipe(pipe_class_memory); 16735 %} 16736 16737 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 16738 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 16739 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 16740 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 16741 iRegP_R10 tmp, rFlagsReg cr) 16742 %{ 16743 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 16744 match(Set result (AryEq ary1 ary2)); 16745 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 16746 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 16747 TEMP vtmp6, TEMP vtmp7, KILL cr); 16748 16749 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 16750 ins_encode %{ 16751 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 16752 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 16753 $result$$Register, $tmp$$Register, 1); 16754 if (tpc == nullptr) { 16755 ciEnv::current()->record_failure("CodeCache is full"); 16756 return; 16757 } 16758 %} 16759 ins_pipe(pipe_class_memory); 16760 %} 16761 16762 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 16763 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 16764 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 16765 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 16766 iRegP_R10 tmp, rFlagsReg cr) 16767 %{ 16768 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 16769 match(Set result (AryEq ary1 ary2)); 16770 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 16771 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 16772 TEMP vtmp6, TEMP vtmp7, KILL cr); 16773 16774 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 16775 ins_encode %{ 16776 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 16777 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 16778 $result$$Register, $tmp$$Register, 2); 16779 if (tpc == nullptr) { 16780 ciEnv::current()->record_failure("CodeCache is full"); 16781 return; 16782 } 16783 %} 16784 ins_pipe(pipe_class_memory); 16785 %} 16786 16787 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 16788 %{ 16789 match(Set result (CountPositives ary1 len)); 16790 effect(USE_KILL ary1, USE_KILL len, KILL cr); 16791 format %{ "count positives byte[] $ary1,$len -> $result" %} 16792 ins_encode %{ 16793 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register); 16794 if (tpc == nullptr) { 16795 ciEnv::current()->record_failure("CodeCache is full"); 16796 return; 16797 } 16798 %} 16799 ins_pipe( pipe_slow ); 16800 %} 16801 16802 // fast char[] to byte[] compression 16803 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16804 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 16805 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 16806 iRegI_R0 result, rFlagsReg cr) 16807 %{ 16808 match(Set result (StrCompressedCopy src (Binary dst len))); 16809 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 16810 USE_KILL src, USE_KILL dst, USE len, KILL cr); 16811 16812 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 16813 ins_encode %{ 16814 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 16815 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 16816 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 16817 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 16818 %} 16819 ins_pipe(pipe_slow); 16820 %} 16821 16822 // fast byte[] to char[] inflation 16823 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp, 16824 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 16825 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr) 16826 %{ 16827 match(Set dummy (StrInflatedCopy src (Binary dst len))); 16828 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, 16829 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp, 16830 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 16831 16832 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %} 16833 ins_encode %{ 16834 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 16835 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 16836 $vtmp2$$FloatRegister, $tmp$$Register); 16837 if (tpc == nullptr) { 16838 ciEnv::current()->record_failure("CodeCache is full"); 16839 return; 16840 } 16841 %} 16842 ins_pipe(pipe_class_memory); 16843 %} 16844 16845 // encode char[] to byte[] in ISO_8859_1 16846 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16847 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 16848 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 16849 iRegI_R0 result, rFlagsReg cr) 16850 %{ 16851 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 16852 match(Set result (EncodeISOArray src (Binary dst len))); 16853 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 16854 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 16855 16856 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 16857 ins_encode %{ 16858 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 16859 $result$$Register, false, 16860 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 16861 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 16862 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 16863 %} 16864 ins_pipe(pipe_class_memory); 16865 %} 16866 16867 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16868 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 16869 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 16870 iRegI_R0 result, rFlagsReg cr) 16871 %{ 16872 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 16873 match(Set result (EncodeISOArray src (Binary dst len))); 16874 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 16875 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 16876 16877 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 16878 ins_encode %{ 16879 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 16880 $result$$Register, true, 16881 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 16882 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 16883 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 16884 %} 16885 ins_pipe(pipe_class_memory); 16886 %} 16887 16888 //----------------------------- CompressBits/ExpandBits ------------------------ 16889 16890 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 16891 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 16892 match(Set dst (CompressBits src mask)); 16893 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16894 format %{ "mov $tsrc, $src\n\t" 16895 "mov $tmask, $mask\n\t" 16896 "bext $tdst, $tsrc, $tmask\n\t" 16897 "mov $dst, $tdst" 16898 %} 16899 ins_encode %{ 16900 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 16901 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 16902 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16903 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 16904 %} 16905 ins_pipe(pipe_slow); 16906 %} 16907 16908 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 16909 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 16910 match(Set dst (CompressBits (LoadI mem) mask)); 16911 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16912 format %{ "ldrs $tsrc, $mem\n\t" 16913 "ldrs $tmask, $mask\n\t" 16914 "bext $tdst, $tsrc, $tmask\n\t" 16915 "mov $dst, $tdst" 16916 %} 16917 ins_encode %{ 16918 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 16919 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 16920 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 16921 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16922 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 16923 %} 16924 ins_pipe(pipe_slow); 16925 %} 16926 16927 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 16928 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 16929 match(Set dst (CompressBits src mask)); 16930 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16931 format %{ "mov $tsrc, $src\n\t" 16932 "mov $tmask, $mask\n\t" 16933 "bext $tdst, $tsrc, $tmask\n\t" 16934 "mov $dst, $tdst" 16935 %} 16936 ins_encode %{ 16937 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 16938 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 16939 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16940 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 16941 %} 16942 ins_pipe(pipe_slow); 16943 %} 16944 16945 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask, 16946 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 16947 match(Set dst (CompressBits (LoadL mem) mask)); 16948 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16949 format %{ "ldrd $tsrc, $mem\n\t" 16950 "ldrd $tmask, $mask\n\t" 16951 "bext $tdst, $tsrc, $tmask\n\t" 16952 "mov $dst, $tdst" 16953 %} 16954 ins_encode %{ 16955 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 16956 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 16957 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 16958 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16959 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 16960 %} 16961 ins_pipe(pipe_slow); 16962 %} 16963 16964 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 16965 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 16966 match(Set dst (ExpandBits src mask)); 16967 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16968 format %{ "mov $tsrc, $src\n\t" 16969 "mov $tmask, $mask\n\t" 16970 "bdep $tdst, $tsrc, $tmask\n\t" 16971 "mov $dst, $tdst" 16972 %} 16973 ins_encode %{ 16974 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 16975 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 16976 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16977 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 16978 %} 16979 ins_pipe(pipe_slow); 16980 %} 16981 16982 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 16983 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 16984 match(Set dst (ExpandBits (LoadI mem) mask)); 16985 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 16986 format %{ "ldrs $tsrc, $mem\n\t" 16987 "ldrs $tmask, $mask\n\t" 16988 "bdep $tdst, $tsrc, $tmask\n\t" 16989 "mov $dst, $tdst" 16990 %} 16991 ins_encode %{ 16992 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 16993 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 16994 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 16995 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 16996 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 16997 %} 16998 ins_pipe(pipe_slow); 16999 %} 17000 17001 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17002 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17003 match(Set dst (ExpandBits src mask)); 17004 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17005 format %{ "mov $tsrc, $src\n\t" 17006 "mov $tmask, $mask\n\t" 17007 "bdep $tdst, $tsrc, $tmask\n\t" 17008 "mov $dst, $tdst" 17009 %} 17010 ins_encode %{ 17011 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17012 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17013 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17014 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17015 %} 17016 ins_pipe(pipe_slow); 17017 %} 17018 17019 17020 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask, 17021 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17022 match(Set dst (ExpandBits (LoadL mem) mask)); 17023 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17024 format %{ "ldrd $tsrc, $mem\n\t" 17025 "ldrd $tmask, $mask\n\t" 17026 "bdep $tdst, $tsrc, $tmask\n\t" 17027 "mov $dst, $tdst" 17028 %} 17029 ins_encode %{ 17030 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17031 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17032 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17033 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17034 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17035 %} 17036 ins_pipe(pipe_slow); 17037 %} 17038 17039 // ============================================================================ 17040 // This name is KNOWN by the ADLC and cannot be changed. 17041 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 17042 // for this guy. 17043 instruct tlsLoadP(thread_RegP dst) 17044 %{ 17045 match(Set dst (ThreadLocal)); 17046 17047 ins_cost(0); 17048 17049 format %{ " -- \t// $dst=Thread::current(), empty" %} 17050 17051 size(0); 17052 17053 ins_encode( /*empty*/ ); 17054 17055 ins_pipe(pipe_class_empty); 17056 %} 17057 17058 //----------PEEPHOLE RULES----------------------------------------------------- 17059 // These must follow all instruction definitions as they use the names 17060 // defined in the instructions definitions. 17061 // 17062 // peepmatch ( root_instr_name [preceding_instruction]* ); 17063 // 17064 // peepconstraint %{ 17065 // (instruction_number.operand_name relational_op instruction_number.operand_name 17066 // [, ...] ); 17067 // // instruction numbers are zero-based using left to right order in peepmatch 17068 // 17069 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17070 // // provide an instruction_number.operand_name for each operand that appears 17071 // // in the replacement instruction's match rule 17072 // 17073 // ---------VM FLAGS--------------------------------------------------------- 17074 // 17075 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17076 // 17077 // Each peephole rule is given an identifying number starting with zero and 17078 // increasing by one in the order seen by the parser. An individual peephole 17079 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17080 // on the command-line. 17081 // 17082 // ---------CURRENT LIMITATIONS---------------------------------------------- 17083 // 17084 // Only match adjacent instructions in same basic block 17085 // Only equality constraints 17086 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17087 // Only one replacement instruction 17088 // 17089 // ---------EXAMPLE---------------------------------------------------------- 17090 // 17091 // // pertinent parts of existing instructions in architecture description 17092 // instruct movI(iRegINoSp dst, iRegI src) 17093 // %{ 17094 // match(Set dst (CopyI src)); 17095 // %} 17096 // 17097 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17098 // %{ 17099 // match(Set dst (AddI dst src)); 17100 // effect(KILL cr); 17101 // %} 17102 // 17103 // // Change (inc mov) to lea 17104 // peephole %{ 17105 // // increment preceded by register-register move 17106 // peepmatch ( incI_iReg movI ); 17107 // // require that the destination register of the increment 17108 // // match the destination register of the move 17109 // peepconstraint ( 0.dst == 1.dst ); 17110 // // construct a replacement instruction that sets 17111 // // the destination to ( move's source register + one ) 17112 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17113 // %} 17114 // 17115 17116 // Implementation no longer uses movX instructions since 17117 // machine-independent system no longer uses CopyX nodes. 17118 // 17119 // peephole 17120 // %{ 17121 // peepmatch (incI_iReg movI); 17122 // peepconstraint (0.dst == 1.dst); 17123 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17124 // %} 17125 17126 // peephole 17127 // %{ 17128 // peepmatch (decI_iReg movI); 17129 // peepconstraint (0.dst == 1.dst); 17130 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17131 // %} 17132 17133 // peephole 17134 // %{ 17135 // peepmatch (addI_iReg_imm movI); 17136 // peepconstraint (0.dst == 1.dst); 17137 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17138 // %} 17139 17140 // peephole 17141 // %{ 17142 // peepmatch (incL_iReg movL); 17143 // peepconstraint (0.dst == 1.dst); 17144 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17145 // %} 17146 17147 // peephole 17148 // %{ 17149 // peepmatch (decL_iReg movL); 17150 // peepconstraint (0.dst == 1.dst); 17151 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17152 // %} 17153 17154 // peephole 17155 // %{ 17156 // peepmatch (addL_iReg_imm movL); 17157 // peepconstraint (0.dst == 1.dst); 17158 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17159 // %} 17160 17161 // peephole 17162 // %{ 17163 // peepmatch (addP_iReg_imm movP); 17164 // peepconstraint (0.dst == 1.dst); 17165 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17166 // %} 17167 17168 // // Change load of spilled value to only a spill 17169 // instruct storeI(memory mem, iRegI src) 17170 // %{ 17171 // match(Set mem (StoreI mem src)); 17172 // %} 17173 // 17174 // instruct loadI(iRegINoSp dst, memory mem) 17175 // %{ 17176 // match(Set dst (LoadI mem)); 17177 // %} 17178 // 17179 17180 //----------SMARTSPILL RULES--------------------------------------------------- 17181 // These must follow all instruction definitions as they use the names 17182 // defined in the instructions definitions. 17183 17184 // Local Variables: 17185 // mode: c++ 17186 // End: