1 // 2 // Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2020, Red Hat, Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 167 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 168 169 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 170 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 171 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 172 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 173 174 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 175 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 176 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 177 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 178 179 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 180 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 181 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 182 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 183 184 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 185 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 186 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 187 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 188 189 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 190 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 191 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 192 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 193 194 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 195 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 196 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 197 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 198 199 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 200 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 201 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 202 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 203 204 reg_def V8 ( SOC, SOC, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next() ); 206 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 207 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 208 209 reg_def V9 ( SOC, SOC, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next() ); 211 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 212 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 213 214 reg_def V10 ( SOC, SOC, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() ); 216 reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2)); 217 reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3)); 218 219 reg_def V11 ( SOC, SOC, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() ); 221 reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2)); 222 reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3)); 223 224 reg_def V12 ( SOC, SOC, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() ); 226 reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2)); 227 reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3)); 228 229 reg_def V13 ( SOC, SOC, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() ); 231 reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2)); 232 reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3)); 233 234 reg_def V14 ( SOC, SOC, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() ); 236 reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2)); 237 reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3)); 238 239 reg_def V15 ( SOC, SOC, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() ); 241 reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2)); 242 reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3)); 243 244 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 245 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 246 reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2)); 247 reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3)); 248 249 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 250 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 251 reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2)); 252 reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3)); 253 254 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 255 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 256 reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2)); 257 reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3)); 258 259 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 260 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 261 reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2)); 262 reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3)); 263 264 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 265 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 266 reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2)); 267 reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3)); 268 269 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 270 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 271 reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2)); 272 reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3)); 273 274 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 275 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 276 reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2)); 277 reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3)); 278 279 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 280 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 281 reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2)); 282 reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3)); 283 284 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 285 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 286 reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2)); 287 reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3)); 288 289 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 290 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 291 reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2)); 292 reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3)); 293 294 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 295 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 296 reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2)); 297 reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3)); 298 299 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 300 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 301 reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2)); 302 reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3)); 303 304 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 305 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 306 reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2)); 307 reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3)); 308 309 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 310 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 311 reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2)); 312 reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3)); 313 314 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 315 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 316 reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2)); 317 reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3)); 318 319 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 320 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 321 reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2)); 322 reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3)); 323 324 // ---------------------------- 325 // Special Registers 326 // ---------------------------- 327 328 // the AArch64 CSPR status flag register is not directly acessible as 329 // instruction operand. the FPSR status flag register is a system 330 // register which can be written/read using MSR/MRS but again does not 331 // appear as an operand (a code identifying the FSPR occurs as an 332 // immediate value in the instruction). 333 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 335 336 337 // Specify priority of register selection within phases of register 338 // allocation. Highest priority is first. A useful heuristic is to 339 // give registers a low priority when they are required by machine 340 // instructions, like EAX and EDX on I486, and choose no-save registers 341 // before save-on-call, & save-on-call before save-on-entry. Registers 342 // which participate in fixed calling sequences should come last. 343 // Registers which are used as pairs must fall on an even boundary. 344 345 alloc_class chunk0( 346 // volatiles 347 R10, R10_H, 348 R11, R11_H, 349 R12, R12_H, 350 R13, R13_H, 351 R14, R14_H, 352 R15, R15_H, 353 R16, R16_H, 354 R17, R17_H, 355 R18, R18_H, 356 357 // arg registers 358 R0, R0_H, 359 R1, R1_H, 360 R2, R2_H, 361 R3, R3_H, 362 R4, R4_H, 363 R5, R5_H, 364 R6, R6_H, 365 R7, R7_H, 366 367 // non-volatiles 368 R19, R19_H, 369 R20, R20_H, 370 R21, R21_H, 371 R22, R22_H, 372 R23, R23_H, 373 R24, R24_H, 374 R25, R25_H, 375 R26, R26_H, 376 377 // non-allocatable registers 378 379 R27, R27_H, // heapbase 380 R28, R28_H, // thread 381 R29, R29_H, // fp 382 R30, R30_H, // lr 383 R31, R31_H, // sp 384 ); 385 386 alloc_class chunk1( 387 388 // no save 389 V16, V16_H, V16_J, V16_K, 390 V17, V17_H, V17_J, V17_K, 391 V18, V18_H, V18_J, V18_K, 392 V19, V19_H, V19_J, V19_K, 393 V20, V20_H, V20_J, V20_K, 394 V21, V21_H, V21_J, V21_K, 395 V22, V22_H, V22_J, V22_K, 396 V23, V23_H, V23_J, V23_K, 397 V24, V24_H, V24_J, V24_K, 398 V25, V25_H, V25_J, V25_K, 399 V26, V26_H, V26_J, V26_K, 400 V27, V27_H, V27_J, V27_K, 401 V28, V28_H, V28_J, V28_K, 402 V29, V29_H, V29_J, V29_K, 403 V30, V30_H, V30_J, V30_K, 404 V31, V31_H, V31_J, V31_K, 405 406 // arg registers 407 V0, V0_H, V0_J, V0_K, 408 V1, V1_H, V1_J, V1_K, 409 V2, V2_H, V2_J, V2_K, 410 V3, V3_H, V3_J, V3_K, 411 V4, V4_H, V4_J, V4_K, 412 V5, V5_H, V5_J, V5_K, 413 V6, V6_H, V6_J, V6_K, 414 V7, V7_H, V7_J, V7_K, 415 416 // non-volatiles 417 V8, V8_H, V8_J, V8_K, 418 V9, V9_H, V9_J, V9_K, 419 V10, V10_H, V10_J, V10_K, 420 V11, V11_H, V11_J, V11_K, 421 V12, V12_H, V12_J, V12_K, 422 V13, V13_H, V13_J, V13_K, 423 V14, V14_H, V14_J, V14_K, 424 V15, V15_H, V15_J, V15_K, 425 ); 426 427 alloc_class chunk2(RFLAGS); 428 429 //----------Architecture Description Register Classes-------------------------- 430 // Several register classes are automatically defined based upon information in 431 // this architecture description. 432 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 433 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 436 // 437 438 // Class for all 32 bit general purpose registers 439 reg_class all_reg32( 440 R0, 441 R1, 442 R2, 443 R3, 444 R4, 445 R5, 446 R6, 447 R7, 448 R10, 449 R11, 450 R12, 451 R13, 452 R14, 453 R15, 454 R16, 455 R17, 456 R18, 457 R19, 458 R20, 459 R21, 460 R22, 461 R23, 462 R24, 463 R25, 464 R26, 465 R27, 466 R28, 467 R29, 468 R30, 469 R31 470 ); 471 472 473 // Class for all 32 bit integer registers (excluding SP which 474 // will never be used as an integer register) 475 reg_class any_reg32 %{ 476 return _ANY_REG32_mask; 477 %} 478 479 // Singleton class for R0 int register 480 reg_class int_r0_reg(R0); 481 482 // Singleton class for R2 int register 483 reg_class int_r2_reg(R2); 484 485 // Singleton class for R3 int register 486 reg_class int_r3_reg(R3); 487 488 // Singleton class for R4 int register 489 reg_class int_r4_reg(R4); 490 491 // Singleton class for R31 int register 492 reg_class int_r31_reg(R31); 493 494 // Class for all 64 bit general purpose registers 495 reg_class all_reg( 496 R0, R0_H, 497 R1, R1_H, 498 R2, R2_H, 499 R3, R3_H, 500 R4, R4_H, 501 R5, R5_H, 502 R6, R6_H, 503 R7, R7_H, 504 R10, R10_H, 505 R11, R11_H, 506 R12, R12_H, 507 R13, R13_H, 508 R14, R14_H, 509 R15, R15_H, 510 R16, R16_H, 511 R17, R17_H, 512 R18, R18_H, 513 R19, R19_H, 514 R20, R20_H, 515 R21, R21_H, 516 R22, R22_H, 517 R23, R23_H, 518 R24, R24_H, 519 R25, R25_H, 520 R26, R26_H, 521 R27, R27_H, 522 R28, R28_H, 523 R29, R29_H, 524 R30, R30_H, 525 R31, R31_H 526 ); 527 528 // Class for all long integer registers (including SP) 529 reg_class any_reg %{ 530 return _ANY_REG_mask; 531 %} 532 533 // Class for non-allocatable 32 bit registers 534 reg_class non_allocatable_reg32( 535 #ifdef _WIN64 536 // See comment in register_aarch64.hpp 537 R18, // tls on Windows 538 #endif 539 R28, // thread 540 R30, // lr 541 R31 // sp 542 ); 543 544 // Class for non-allocatable 64 bit registers 545 reg_class non_allocatable_reg( 546 #ifdef _WIN64 547 // See comment in register_aarch64.hpp 548 R18, R18_H, // tls on Windows 549 #endif 550 R28, R28_H, // thread 551 R30, R30_H, // lr 552 R31, R31_H // sp 553 ); 554 555 // Class for all non-special integer registers 556 reg_class no_special_reg32 %{ 557 return _NO_SPECIAL_REG32_mask; 558 %} 559 560 // Class for all non-special long integer registers 561 reg_class no_special_reg %{ 562 return _NO_SPECIAL_REG_mask; 563 %} 564 565 // Class for 64 bit register r0 566 reg_class r0_reg( 567 R0, R0_H 568 ); 569 570 // Class for 64 bit register r1 571 reg_class r1_reg( 572 R1, R1_H 573 ); 574 575 // Class for 64 bit register r2 576 reg_class r2_reg( 577 R2, R2_H 578 ); 579 580 // Class for 64 bit register r3 581 reg_class r3_reg( 582 R3, R3_H 583 ); 584 585 // Class for 64 bit register r4 586 reg_class r4_reg( 587 R4, R4_H 588 ); 589 590 // Class for 64 bit register r5 591 reg_class r5_reg( 592 R5, R5_H 593 ); 594 595 // Class for 64 bit register r10 596 reg_class r10_reg( 597 R10, R10_H 598 ); 599 600 // Class for 64 bit register r11 601 reg_class r11_reg( 602 R11, R11_H 603 ); 604 605 // Class for method register 606 reg_class method_reg( 607 R12, R12_H 608 ); 609 610 // Class for heapbase register 611 reg_class heapbase_reg( 612 R27, R27_H 613 ); 614 615 // Class for thread register 616 reg_class thread_reg( 617 R28, R28_H 618 ); 619 620 // Class for frame pointer register 621 reg_class fp_reg( 622 R29, R29_H 623 ); 624 625 // Class for link register 626 reg_class lr_reg( 627 R30, R30_H 628 ); 629 630 // Class for long sp register 631 reg_class sp_reg( 632 R31, R31_H 633 ); 634 635 // Class for all pointer registers 636 reg_class ptr_reg %{ 637 return _PTR_REG_mask; 638 %} 639 640 // Class for all non_special pointer registers 641 reg_class no_special_ptr_reg %{ 642 return _NO_SPECIAL_PTR_REG_mask; 643 %} 644 645 // Class for all float registers 646 reg_class float_reg( 647 V0, 648 V1, 649 V2, 650 V3, 651 V4, 652 V5, 653 V6, 654 V7, 655 V8, 656 V9, 657 V10, 658 V11, 659 V12, 660 V13, 661 V14, 662 V15, 663 V16, 664 V17, 665 V18, 666 V19, 667 V20, 668 V21, 669 V22, 670 V23, 671 V24, 672 V25, 673 V26, 674 V27, 675 V28, 676 V29, 677 V30, 678 V31 679 ); 680 681 // Double precision float registers have virtual `high halves' that 682 // are needed by the allocator. 683 // Class for all double registers 684 reg_class double_reg( 685 V0, V0_H, 686 V1, V1_H, 687 V2, V2_H, 688 V3, V3_H, 689 V4, V4_H, 690 V5, V5_H, 691 V6, V6_H, 692 V7, V7_H, 693 V8, V8_H, 694 V9, V9_H, 695 V10, V10_H, 696 V11, V11_H, 697 V12, V12_H, 698 V13, V13_H, 699 V14, V14_H, 700 V15, V15_H, 701 V16, V16_H, 702 V17, V17_H, 703 V18, V18_H, 704 V19, V19_H, 705 V20, V20_H, 706 V21, V21_H, 707 V22, V22_H, 708 V23, V23_H, 709 V24, V24_H, 710 V25, V25_H, 711 V26, V26_H, 712 V27, V27_H, 713 V28, V28_H, 714 V29, V29_H, 715 V30, V30_H, 716 V31, V31_H 717 ); 718 719 // Class for all 64bit vector registers 720 reg_class vectord_reg( 721 V0, V0_H, 722 V1, V1_H, 723 V2, V2_H, 724 V3, V3_H, 725 V4, V4_H, 726 V5, V5_H, 727 V6, V6_H, 728 V7, V7_H, 729 V8, V8_H, 730 V9, V9_H, 731 V10, V10_H, 732 V11, V11_H, 733 V12, V12_H, 734 V13, V13_H, 735 V14, V14_H, 736 V15, V15_H, 737 V16, V16_H, 738 V17, V17_H, 739 V18, V18_H, 740 V19, V19_H, 741 V20, V20_H, 742 V21, V21_H, 743 V22, V22_H, 744 V23, V23_H, 745 V24, V24_H, 746 V25, V25_H, 747 V26, V26_H, 748 V27, V27_H, 749 V28, V28_H, 750 V29, V29_H, 751 V30, V30_H, 752 V31, V31_H 753 ); 754 755 // Class for all 128bit vector registers 756 reg_class vectorx_reg( 757 V0, V0_H, V0_J, V0_K, 758 V1, V1_H, V1_J, V1_K, 759 V2, V2_H, V2_J, V2_K, 760 V3, V3_H, V3_J, V3_K, 761 V4, V4_H, V4_J, V4_K, 762 V5, V5_H, V5_J, V5_K, 763 V6, V6_H, V6_J, V6_K, 764 V7, V7_H, V7_J, V7_K, 765 V8, V8_H, V8_J, V8_K, 766 V9, V9_H, V9_J, V9_K, 767 V10, V10_H, V10_J, V10_K, 768 V11, V11_H, V11_J, V11_K, 769 V12, V12_H, V12_J, V12_K, 770 V13, V13_H, V13_J, V13_K, 771 V14, V14_H, V14_J, V14_K, 772 V15, V15_H, V15_J, V15_K, 773 V16, V16_H, V16_J, V16_K, 774 V17, V17_H, V17_J, V17_K, 775 V18, V18_H, V18_J, V18_K, 776 V19, V19_H, V19_J, V19_K, 777 V20, V20_H, V20_J, V20_K, 778 V21, V21_H, V21_J, V21_K, 779 V22, V22_H, V22_J, V22_K, 780 V23, V23_H, V23_J, V23_K, 781 V24, V24_H, V24_J, V24_K, 782 V25, V25_H, V25_J, V25_K, 783 V26, V26_H, V26_J, V26_K, 784 V27, V27_H, V27_J, V27_K, 785 V28, V28_H, V28_J, V28_K, 786 V29, V29_H, V29_J, V29_K, 787 V30, V30_H, V30_J, V30_K, 788 V31, V31_H, V31_J, V31_K 789 ); 790 791 // Class for 128 bit register v0 792 reg_class v0_reg( 793 V0, V0_H 794 ); 795 796 // Class for 128 bit register v1 797 reg_class v1_reg( 798 V1, V1_H 799 ); 800 801 // Class for 128 bit register v2 802 reg_class v2_reg( 803 V2, V2_H 804 ); 805 806 // Class for 128 bit register v3 807 reg_class v3_reg( 808 V3, V3_H 809 ); 810 811 // Class for 128 bit register v4 812 reg_class v4_reg( 813 V4, V4_H 814 ); 815 816 // Class for 128 bit register v5 817 reg_class v5_reg( 818 V5, V5_H 819 ); 820 821 // Class for 128 bit register v6 822 reg_class v6_reg( 823 V6, V6_H 824 ); 825 826 // Class for 128 bit register v7 827 reg_class v7_reg( 828 V7, V7_H 829 ); 830 831 // Class for 128 bit register v8 832 reg_class v8_reg( 833 V8, V8_H 834 ); 835 836 // Class for 128 bit register v9 837 reg_class v9_reg( 838 V9, V9_H 839 ); 840 841 // Class for 128 bit register v10 842 reg_class v10_reg( 843 V10, V10_H 844 ); 845 846 // Class for 128 bit register v11 847 reg_class v11_reg( 848 V11, V11_H 849 ); 850 851 // Class for 128 bit register v12 852 reg_class v12_reg( 853 V12, V12_H 854 ); 855 856 // Class for 128 bit register v13 857 reg_class v13_reg( 858 V13, V13_H 859 ); 860 861 // Class for 128 bit register v14 862 reg_class v14_reg( 863 V14, V14_H 864 ); 865 866 // Class for 128 bit register v15 867 reg_class v15_reg( 868 V15, V15_H 869 ); 870 871 // Class for 128 bit register v16 872 reg_class v16_reg( 873 V16, V16_H 874 ); 875 876 // Class for 128 bit register v17 877 reg_class v17_reg( 878 V17, V17_H 879 ); 880 881 // Class for 128 bit register v18 882 reg_class v18_reg( 883 V18, V18_H 884 ); 885 886 // Class for 128 bit register v19 887 reg_class v19_reg( 888 V19, V19_H 889 ); 890 891 // Class for 128 bit register v20 892 reg_class v20_reg( 893 V20, V20_H 894 ); 895 896 // Class for 128 bit register v21 897 reg_class v21_reg( 898 V21, V21_H 899 ); 900 901 // Class for 128 bit register v22 902 reg_class v22_reg( 903 V22, V22_H 904 ); 905 906 // Class for 128 bit register v23 907 reg_class v23_reg( 908 V23, V23_H 909 ); 910 911 // Class for 128 bit register v24 912 reg_class v24_reg( 913 V24, V24_H 914 ); 915 916 // Class for 128 bit register v25 917 reg_class v25_reg( 918 V25, V25_H 919 ); 920 921 // Class for 128 bit register v26 922 reg_class v26_reg( 923 V26, V26_H 924 ); 925 926 // Class for 128 bit register v27 927 reg_class v27_reg( 928 V27, V27_H 929 ); 930 931 // Class for 128 bit register v28 932 reg_class v28_reg( 933 V28, V28_H 934 ); 935 936 // Class for 128 bit register v29 937 reg_class v29_reg( 938 V29, V29_H 939 ); 940 941 // Class for 128 bit register v30 942 reg_class v30_reg( 943 V30, V30_H 944 ); 945 946 // Class for 128 bit register v31 947 reg_class v31_reg( 948 V31, V31_H 949 ); 950 951 // Singleton class for condition codes 952 reg_class int_flags(RFLAGS); 953 954 %} 955 956 //----------DEFINITION BLOCK--------------------------------------------------- 957 // Define name --> value mappings to inform the ADLC of an integer valued name 958 // Current support includes integer values in the range [0, 0x7FFFFFFF] 959 // Format: 960 // int_def <name> ( <int_value>, <expression>); 961 // Generated Code in ad_<arch>.hpp 962 // #define <name> (<expression>) 963 // // value == <int_value> 964 // Generated code in ad_<arch>.cpp adlc_verification() 965 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 966 // 967 968 // we follow the ppc-aix port in using a simple cost model which ranks 969 // register operations as cheap, memory ops as more expensive and 970 // branches as most expensive. the first two have a low as well as a 971 // normal cost. huge cost appears to be a way of saying don't do 972 // something 973 974 definitions %{ 975 // The default cost (of a register move instruction). 976 int_def INSN_COST ( 100, 100); 977 int_def BRANCH_COST ( 200, 2 * INSN_COST); 978 int_def CALL_COST ( 200, 2 * INSN_COST); 979 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 980 %} 981 982 983 //----------SOURCE BLOCK------------------------------------------------------- 984 // This is a block of C++ code which provides values, functions, and 985 // definitions necessary in the rest of the architecture description 986 987 source_hpp %{ 988 989 #include "asm/macroAssembler.hpp" 990 #include "gc/shared/cardTable.hpp" 991 #include "gc/shared/cardTableBarrierSet.hpp" 992 #include "gc/shared/collectedHeap.hpp" 993 #include "opto/addnode.hpp" 994 #include "opto/convertnode.hpp" 995 996 extern RegMask _ANY_REG32_mask; 997 extern RegMask _ANY_REG_mask; 998 extern RegMask _PTR_REG_mask; 999 extern RegMask _NO_SPECIAL_REG32_mask; 1000 extern RegMask _NO_SPECIAL_REG_mask; 1001 extern RegMask _NO_SPECIAL_PTR_REG_mask; 1002 1003 class CallStubImpl { 1004 1005 //-------------------------------------------------------------- 1006 //---< Used for optimization in Compile::shorten_branches >--- 1007 //-------------------------------------------------------------- 1008 1009 public: 1010 // Size of call trampoline stub. 1011 static uint size_call_trampoline() { 1012 return 0; // no call trampolines on this platform 1013 } 1014 1015 // number of relocations needed by a call trampoline stub 1016 static uint reloc_call_trampoline() { 1017 return 0; // no call trampolines on this platform 1018 } 1019 }; 1020 1021 class HandlerImpl { 1022 1023 public: 1024 1025 static int emit_exception_handler(CodeBuffer &cbuf); 1026 static int emit_deopt_handler(CodeBuffer& cbuf); 1027 1028 static uint size_exception_handler() { 1029 return MacroAssembler::far_branch_size(); 1030 } 1031 1032 static uint size_deopt_handler() { 1033 // count one adr and one far branch instruction 1034 return 4 * NativeInstruction::instruction_size; 1035 } 1036 }; 1037 1038 class Node::PD { 1039 public: 1040 enum NodeFlags { 1041 _last_flag = Node::_last_flag 1042 }; 1043 }; 1044 1045 bool is_CAS(int opcode, bool maybe_volatile); 1046 1047 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1048 1049 bool unnecessary_acquire(const Node *barrier); 1050 bool needs_acquiring_load(const Node *load); 1051 1052 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1053 1054 bool unnecessary_release(const Node *barrier); 1055 bool unnecessary_volatile(const Node *barrier); 1056 bool needs_releasing_store(const Node *store); 1057 1058 // predicate controlling translation of CompareAndSwapX 1059 bool needs_acquiring_load_exclusive(const Node *load); 1060 1061 // predicate controlling addressing modes 1062 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1063 %} 1064 1065 source %{ 1066 1067 // Derived RegMask with conditionally allocatable registers 1068 1069 void PhaseOutput::pd_perform_mach_node_analysis() { 1070 } 1071 1072 int MachNode::pd_alignment_required() const { 1073 return 1; 1074 } 1075 1076 int MachNode::compute_padding(int current_offset) const { 1077 return 0; 1078 } 1079 1080 RegMask _ANY_REG32_mask; 1081 RegMask _ANY_REG_mask; 1082 RegMask _PTR_REG_mask; 1083 RegMask _NO_SPECIAL_REG32_mask; 1084 RegMask _NO_SPECIAL_REG_mask; 1085 RegMask _NO_SPECIAL_PTR_REG_mask; 1086 1087 void reg_mask_init() { 1088 // We derive below RegMask(s) from the ones which are auto-generated from 1089 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1090 // registers conditionally reserved. 1091 1092 _ANY_REG32_mask = _ALL_REG32_mask; 1093 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1094 1095 _ANY_REG_mask = _ALL_REG_mask; 1096 1097 _PTR_REG_mask = _ALL_REG_mask; 1098 1099 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1100 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1101 1102 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1103 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1104 1105 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1106 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1107 1108 // r27 is not allocatable when compressed oops is on and heapbase is not 1109 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1110 if (UseCompressedOops && (CompressedOops::ptrs_base() != NULL || UseAOT)) { 1111 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1112 _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1113 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1114 } 1115 1116 // r29 is not allocatable when PreserveFramePointer is on 1117 if (PreserveFramePointer) { 1118 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1119 _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); 1120 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); 1121 } 1122 } 1123 1124 // Optimizaton of volatile gets and puts 1125 // ------------------------------------- 1126 // 1127 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1128 // use to implement volatile reads and writes. For a volatile read 1129 // we simply need 1130 // 1131 // ldar<x> 1132 // 1133 // and for a volatile write we need 1134 // 1135 // stlr<x> 1136 // 1137 // Alternatively, we can implement them by pairing a normal 1138 // load/store with a memory barrier. For a volatile read we need 1139 // 1140 // ldr<x> 1141 // dmb ishld 1142 // 1143 // for a volatile write 1144 // 1145 // dmb ish 1146 // str<x> 1147 // dmb ish 1148 // 1149 // We can also use ldaxr and stlxr to implement compare and swap CAS 1150 // sequences. These are normally translated to an instruction 1151 // sequence like the following 1152 // 1153 // dmb ish 1154 // retry: 1155 // ldxr<x> rval raddr 1156 // cmp rval rold 1157 // b.ne done 1158 // stlxr<x> rval, rnew, rold 1159 // cbnz rval retry 1160 // done: 1161 // cset r0, eq 1162 // dmb ishld 1163 // 1164 // Note that the exclusive store is already using an stlxr 1165 // instruction. That is required to ensure visibility to other 1166 // threads of the exclusive write (assuming it succeeds) before that 1167 // of any subsequent writes. 1168 // 1169 // The following instruction sequence is an improvement on the above 1170 // 1171 // retry: 1172 // ldaxr<x> rval raddr 1173 // cmp rval rold 1174 // b.ne done 1175 // stlxr<x> rval, rnew, rold 1176 // cbnz rval retry 1177 // done: 1178 // cset r0, eq 1179 // 1180 // We don't need the leading dmb ish since the stlxr guarantees 1181 // visibility of prior writes in the case that the swap is 1182 // successful. Crucially we don't have to worry about the case where 1183 // the swap is not successful since no valid program should be 1184 // relying on visibility of prior changes by the attempting thread 1185 // in the case where the CAS fails. 1186 // 1187 // Similarly, we don't need the trailing dmb ishld if we substitute 1188 // an ldaxr instruction since that will provide all the guarantees we 1189 // require regarding observation of changes made by other threads 1190 // before any change to the CAS address observed by the load. 1191 // 1192 // In order to generate the desired instruction sequence we need to 1193 // be able to identify specific 'signature' ideal graph node 1194 // sequences which i) occur as a translation of a volatile reads or 1195 // writes or CAS operations and ii) do not occur through any other 1196 // translation or graph transformation. We can then provide 1197 // alternative aldc matching rules which translate these node 1198 // sequences to the desired machine code sequences. Selection of the 1199 // alternative rules can be implemented by predicates which identify 1200 // the relevant node sequences. 1201 // 1202 // The ideal graph generator translates a volatile read to the node 1203 // sequence 1204 // 1205 // LoadX[mo_acquire] 1206 // MemBarAcquire 1207 // 1208 // As a special case when using the compressed oops optimization we 1209 // may also see this variant 1210 // 1211 // LoadN[mo_acquire] 1212 // DecodeN 1213 // MemBarAcquire 1214 // 1215 // A volatile write is translated to the node sequence 1216 // 1217 // MemBarRelease 1218 // StoreX[mo_release] {CardMark}-optional 1219 // MemBarVolatile 1220 // 1221 // n.b. the above node patterns are generated with a strict 1222 // 'signature' configuration of input and output dependencies (see 1223 // the predicates below for exact details). The card mark may be as 1224 // simple as a few extra nodes or, in a few GC configurations, may 1225 // include more complex control flow between the leading and 1226 // trailing memory barriers. However, whatever the card mark 1227 // configuration these signatures are unique to translated volatile 1228 // reads/stores -- they will not appear as a result of any other 1229 // bytecode translation or inlining nor as a consequence of 1230 // optimizing transforms. 1231 // 1232 // We also want to catch inlined unsafe volatile gets and puts and 1233 // be able to implement them using either ldar<x>/stlr<x> or some 1234 // combination of ldr<x>/stlr<x> and dmb instructions. 1235 // 1236 // Inlined unsafe volatiles puts manifest as a minor variant of the 1237 // normal volatile put node sequence containing an extra cpuorder 1238 // membar 1239 // 1240 // MemBarRelease 1241 // MemBarCPUOrder 1242 // StoreX[mo_release] {CardMark}-optional 1243 // MemBarCPUOrder 1244 // MemBarVolatile 1245 // 1246 // n.b. as an aside, a cpuorder membar is not itself subject to 1247 // matching and translation by adlc rules. However, the rule 1248 // predicates need to detect its presence in order to correctly 1249 // select the desired adlc rules. 1250 // 1251 // Inlined unsafe volatile gets manifest as a slightly different 1252 // node sequence to a normal volatile get because of the 1253 // introduction of some CPUOrder memory barriers to bracket the 1254 // Load. However, but the same basic skeleton of a LoadX feeding a 1255 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1256 // present 1257 // 1258 // MemBarCPUOrder 1259 // || \\ 1260 // MemBarCPUOrder LoadX[mo_acquire] 1261 // || | 1262 // || {DecodeN} optional 1263 // || / 1264 // MemBarAcquire 1265 // 1266 // In this case the acquire membar does not directly depend on the 1267 // load. However, we can be sure that the load is generated from an 1268 // inlined unsafe volatile get if we see it dependent on this unique 1269 // sequence of membar nodes. Similarly, given an acquire membar we 1270 // can know that it was added because of an inlined unsafe volatile 1271 // get if it is fed and feeds a cpuorder membar and if its feed 1272 // membar also feeds an acquiring load. 1273 // 1274 // Finally an inlined (Unsafe) CAS operation is translated to the 1275 // following ideal graph 1276 // 1277 // MemBarRelease 1278 // MemBarCPUOrder 1279 // CompareAndSwapX {CardMark}-optional 1280 // MemBarCPUOrder 1281 // MemBarAcquire 1282 // 1283 // So, where we can identify these volatile read and write 1284 // signatures we can choose to plant either of the above two code 1285 // sequences. For a volatile read we can simply plant a normal 1286 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1287 // also choose to inhibit translation of the MemBarAcquire and 1288 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1289 // 1290 // When we recognise a volatile store signature we can choose to 1291 // plant at a dmb ish as a translation for the MemBarRelease, a 1292 // normal str<x> and then a dmb ish for the MemBarVolatile. 1293 // Alternatively, we can inhibit translation of the MemBarRelease 1294 // and MemBarVolatile and instead plant a simple stlr<x> 1295 // instruction. 1296 // 1297 // when we recognise a CAS signature we can choose to plant a dmb 1298 // ish as a translation for the MemBarRelease, the conventional 1299 // macro-instruction sequence for the CompareAndSwap node (which 1300 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1301 // Alternatively, we can elide generation of the dmb instructions 1302 // and plant the alternative CompareAndSwap macro-instruction 1303 // sequence (which uses ldaxr<x>). 1304 // 1305 // Of course, the above only applies when we see these signature 1306 // configurations. We still want to plant dmb instructions in any 1307 // other cases where we may see a MemBarAcquire, MemBarRelease or 1308 // MemBarVolatile. For example, at the end of a constructor which 1309 // writes final/volatile fields we will see a MemBarRelease 1310 // instruction and this needs a 'dmb ish' lest we risk the 1311 // constructed object being visible without making the 1312 // final/volatile field writes visible. 1313 // 1314 // n.b. the translation rules below which rely on detection of the 1315 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1316 // If we see anything other than the signature configurations we 1317 // always just translate the loads and stores to ldr<x> and str<x> 1318 // and translate acquire, release and volatile membars to the 1319 // relevant dmb instructions. 1320 // 1321 1322 // is_CAS(int opcode, bool maybe_volatile) 1323 // 1324 // return true if opcode is one of the possible CompareAndSwapX 1325 // values otherwise false. 1326 1327 bool is_CAS(int opcode, bool maybe_volatile) 1328 { 1329 switch(opcode) { 1330 // We handle these 1331 case Op_CompareAndSwapI: 1332 case Op_CompareAndSwapL: 1333 case Op_CompareAndSwapP: 1334 case Op_CompareAndSwapN: 1335 case Op_ShenandoahCompareAndSwapP: 1336 case Op_ShenandoahCompareAndSwapN: 1337 case Op_CompareAndSwapB: 1338 case Op_CompareAndSwapS: 1339 case Op_GetAndSetI: 1340 case Op_GetAndSetL: 1341 case Op_GetAndSetP: 1342 case Op_GetAndSetN: 1343 case Op_GetAndAddI: 1344 case Op_GetAndAddL: 1345 return true; 1346 case Op_CompareAndExchangeI: 1347 case Op_CompareAndExchangeN: 1348 case Op_CompareAndExchangeB: 1349 case Op_CompareAndExchangeS: 1350 case Op_CompareAndExchangeL: 1351 case Op_CompareAndExchangeP: 1352 case Op_WeakCompareAndSwapB: 1353 case Op_WeakCompareAndSwapS: 1354 case Op_WeakCompareAndSwapI: 1355 case Op_WeakCompareAndSwapL: 1356 case Op_WeakCompareAndSwapP: 1357 case Op_WeakCompareAndSwapN: 1358 case Op_ShenandoahWeakCompareAndSwapP: 1359 case Op_ShenandoahWeakCompareAndSwapN: 1360 case Op_ShenandoahCompareAndExchangeP: 1361 case Op_ShenandoahCompareAndExchangeN: 1362 return maybe_volatile; 1363 default: 1364 return false; 1365 } 1366 } 1367 1368 // helper to determine the maximum number of Phi nodes we may need to 1369 // traverse when searching from a card mark membar for the merge mem 1370 // feeding a trailing membar or vice versa 1371 1372 // predicates controlling emit of ldr<x>/ldar<x> 1373 1374 bool unnecessary_acquire(const Node *barrier) 1375 { 1376 assert(barrier->is_MemBar(), "expecting a membar"); 1377 1378 MemBarNode* mb = barrier->as_MemBar(); 1379 1380 if (mb->trailing_load()) { 1381 return true; 1382 } 1383 1384 if (mb->trailing_load_store()) { 1385 Node* load_store = mb->in(MemBarNode::Precedent); 1386 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1387 return is_CAS(load_store->Opcode(), true); 1388 } 1389 1390 return false; 1391 } 1392 1393 bool needs_acquiring_load(const Node *n) 1394 { 1395 assert(n->is_Load(), "expecting a load"); 1396 LoadNode *ld = n->as_Load(); 1397 return ld->is_acquire(); 1398 } 1399 1400 bool unnecessary_release(const Node *n) 1401 { 1402 assert((n->is_MemBar() && 1403 n->Opcode() == Op_MemBarRelease), 1404 "expecting a release membar"); 1405 1406 MemBarNode *barrier = n->as_MemBar(); 1407 if (!barrier->leading()) { 1408 return false; 1409 } else { 1410 Node* trailing = barrier->trailing_membar(); 1411 MemBarNode* trailing_mb = trailing->as_MemBar(); 1412 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1413 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1414 1415 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1416 if (mem->is_Store()) { 1417 assert(mem->as_Store()->is_release(), ""); 1418 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1419 return true; 1420 } else { 1421 assert(mem->is_LoadStore(), ""); 1422 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1423 return is_CAS(mem->Opcode(), true); 1424 } 1425 } 1426 return false; 1427 } 1428 1429 bool unnecessary_volatile(const Node *n) 1430 { 1431 // assert n->is_MemBar(); 1432 MemBarNode *mbvol = n->as_MemBar(); 1433 1434 bool release = mbvol->trailing_store(); 1435 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1436 #ifdef ASSERT 1437 if (release) { 1438 Node* leading = mbvol->leading_membar(); 1439 assert(leading->Opcode() == Op_MemBarRelease, ""); 1440 assert(leading->as_MemBar()->leading_store(), ""); 1441 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1442 } 1443 #endif 1444 1445 return release; 1446 } 1447 1448 // predicates controlling emit of str<x>/stlr<x> 1449 1450 bool needs_releasing_store(const Node *n) 1451 { 1452 // assert n->is_Store(); 1453 StoreNode *st = n->as_Store(); 1454 return st->trailing_membar() != NULL; 1455 } 1456 1457 // predicate controlling translation of CAS 1458 // 1459 // returns true if CAS needs to use an acquiring load otherwise false 1460 1461 bool needs_acquiring_load_exclusive(const Node *n) 1462 { 1463 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1464 LoadStoreNode* ldst = n->as_LoadStore(); 1465 if (is_CAS(n->Opcode(), false)) { 1466 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1467 } else { 1468 return ldst->trailing_membar() != NULL; 1469 } 1470 1471 // so we can just return true here 1472 return true; 1473 } 1474 1475 #define __ _masm. 1476 1477 // advance declarations for helper functions to convert register 1478 // indices to register objects 1479 1480 // the ad file has to provide implementations of certain methods 1481 // expected by the generic code 1482 // 1483 // REQUIRED FUNCTIONALITY 1484 1485 //============================================================================= 1486 1487 // !!!!! Special hack to get all types of calls to specify the byte offset 1488 // from the start of the call to the point where the return address 1489 // will point. 1490 1491 int MachCallStaticJavaNode::ret_addr_offset() 1492 { 1493 // call should be a simple bl 1494 int off = 4; 1495 return off; 1496 } 1497 1498 int MachCallDynamicJavaNode::ret_addr_offset() 1499 { 1500 return 16; // movz, movk, movk, bl 1501 } 1502 1503 int MachCallRuntimeNode::ret_addr_offset() { 1504 // for generated stubs the call will be 1505 // far_call(addr) 1506 // for real runtime callouts it will be six instructions 1507 // see aarch64_enc_java_to_runtime 1508 // adr(rscratch2, retaddr) 1509 // lea(rscratch1, RuntimeAddress(addr) 1510 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1511 // blr(rscratch1) 1512 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1513 if (cb) { 1514 return MacroAssembler::far_branch_size(); 1515 } else { 1516 return 6 * NativeInstruction::instruction_size; 1517 } 1518 } 1519 1520 // Indicate if the safepoint node needs the polling page as an input 1521 1522 // the shared code plants the oop data at the start of the generated 1523 // code for the safepoint node and that needs ot be at the load 1524 // instruction itself. so we cannot plant a mov of the safepoint poll 1525 // address followed by a load. setting this to true means the mov is 1526 // scheduled as a prior instruction. that's better for scheduling 1527 // anyway. 1528 1529 bool SafePointNode::needs_polling_address_input() 1530 { 1531 return true; 1532 } 1533 1534 //============================================================================= 1535 1536 #ifndef PRODUCT 1537 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1538 st->print("BREAKPOINT"); 1539 } 1540 #endif 1541 1542 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1543 C2_MacroAssembler _masm(&cbuf); 1544 __ brk(0); 1545 } 1546 1547 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1548 return MachNode::size(ra_); 1549 } 1550 1551 //============================================================================= 1552 1553 #ifndef PRODUCT 1554 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1555 st->print("nop \t# %d bytes pad for loops and calls", _count); 1556 } 1557 #endif 1558 1559 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1560 C2_MacroAssembler _masm(&cbuf); 1561 for (int i = 0; i < _count; i++) { 1562 __ nop(); 1563 } 1564 } 1565 1566 uint MachNopNode::size(PhaseRegAlloc*) const { 1567 return _count * NativeInstruction::instruction_size; 1568 } 1569 1570 //============================================================================= 1571 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1572 1573 int ConstantTable::calculate_table_base_offset() const { 1574 return 0; // absolute addressing, no offset 1575 } 1576 1577 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1578 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1579 ShouldNotReachHere(); 1580 } 1581 1582 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1583 // Empty encoding 1584 } 1585 1586 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1587 return 0; 1588 } 1589 1590 #ifndef PRODUCT 1591 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1592 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1593 } 1594 #endif 1595 1596 #ifndef PRODUCT 1597 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1598 Compile* C = ra_->C; 1599 1600 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1601 1602 if (C->output()->need_stack_bang(framesize)) 1603 st->print("# stack bang size=%d\n\t", framesize); 1604 1605 if (framesize < ((1 << 9) + 2 * wordSize)) { 1606 st->print("sub sp, sp, #%d\n\t", framesize); 1607 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1608 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1609 } else { 1610 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1611 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1612 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1613 st->print("sub sp, sp, rscratch1"); 1614 } 1615 if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1616 st->print("\n\t"); 1617 st->print("ldr rscratch1, [guard]\n\t"); 1618 st->print("dmb ishld\n\t"); 1619 st->print("ldr rscratch2, [rthread, #thread_disarmed_offset]\n\t"); 1620 st->print("cmp rscratch1, rscratch2\n\t"); 1621 st->print("b.eq skip"); 1622 st->print("\n\t"); 1623 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1624 st->print("b skip\n\t"); 1625 st->print("guard: int\n\t"); 1626 st->print("\n\t"); 1627 st->print("skip:\n\t"); 1628 } 1629 } 1630 #endif 1631 1632 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1633 Compile* C = ra_->C; 1634 C2_MacroAssembler _masm(&cbuf); 1635 1636 // n.b. frame size includes space for return pc and rfp 1637 const int framesize = C->output()->frame_size_in_bytes(); 1638 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1639 1640 // insert a nop at the start of the prolog so we can patch in a 1641 // branch if we need to invalidate the method later 1642 __ nop(); 1643 1644 if (C->clinit_barrier_on_entry()) { 1645 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1646 1647 Label L_skip_barrier; 1648 1649 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1650 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1651 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1652 __ bind(L_skip_barrier); 1653 } 1654 1655 int bangsize = C->output()->bang_size_in_bytes(); 1656 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) 1657 __ generate_stack_overflow_check(bangsize); 1658 1659 __ build_frame(framesize); 1660 1661 if (C->stub_function() == NULL) { 1662 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1663 bs->nmethod_entry_barrier(&_masm); 1664 } 1665 1666 if (VerifyStackAtCalls) { 1667 Unimplemented(); 1668 } 1669 1670 C->output()->set_frame_complete(cbuf.insts_size()); 1671 1672 if (C->has_mach_constant_base_node()) { 1673 // NOTE: We set the table base offset here because users might be 1674 // emitted before MachConstantBaseNode. 1675 ConstantTable& constant_table = C->output()->constant_table(); 1676 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1677 } 1678 } 1679 1680 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1681 { 1682 return MachNode::size(ra_); // too many variables; just compute it 1683 // the hard way 1684 } 1685 1686 int MachPrologNode::reloc() const 1687 { 1688 return 0; 1689 } 1690 1691 //============================================================================= 1692 1693 #ifndef PRODUCT 1694 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1695 Compile* C = ra_->C; 1696 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1697 1698 st->print("# pop frame %d\n\t",framesize); 1699 1700 if (framesize == 0) { 1701 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1702 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1703 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1704 st->print("add sp, sp, #%d\n\t", framesize); 1705 } else { 1706 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1707 st->print("add sp, sp, rscratch1\n\t"); 1708 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1709 } 1710 1711 if (do_polling() && C->is_method_compilation()) { 1712 st->print("# touch polling page\n\t"); 1713 st->print("ldr rscratch1, [rthread],#polling_page_offset\n\t"); 1714 st->print("ldr zr, [rscratch1]"); 1715 } 1716 } 1717 #endif 1718 1719 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1720 Compile* C = ra_->C; 1721 C2_MacroAssembler _masm(&cbuf); 1722 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1723 1724 __ remove_frame(framesize); 1725 1726 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1727 __ reserved_stack_check(); 1728 } 1729 1730 if (do_polling() && C->is_method_compilation()) { 1731 __ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type); 1732 } 1733 } 1734 1735 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1736 // Variable size. Determine dynamically. 1737 return MachNode::size(ra_); 1738 } 1739 1740 int MachEpilogNode::reloc() const { 1741 // Return number of relocatable values contained in this instruction. 1742 return 1; // 1 for polling page. 1743 } 1744 1745 const Pipeline * MachEpilogNode::pipeline() const { 1746 return MachNode::pipeline_class(); 1747 } 1748 1749 //============================================================================= 1750 1751 // Figure out which register class each belongs in: rc_int, rc_float or 1752 // rc_stack. 1753 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1754 1755 static enum RC rc_class(OptoReg::Name reg) { 1756 1757 if (reg == OptoReg::Bad) { 1758 return rc_bad; 1759 } 1760 1761 // we have 30 int registers * 2 halves 1762 // (rscratch1 and rscratch2 are omitted) 1763 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1764 1765 if (reg < slots_of_int_registers) { 1766 return rc_int; 1767 } 1768 1769 // we have 32 float register * 4 halves 1770 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1771 return rc_float; 1772 } 1773 1774 // Between float regs & stack is the flags regs. 1775 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1776 1777 return rc_stack; 1778 } 1779 1780 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1781 Compile* C = ra_->C; 1782 1783 // Get registers to move. 1784 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1785 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1786 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1787 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1788 1789 enum RC src_hi_rc = rc_class(src_hi); 1790 enum RC src_lo_rc = rc_class(src_lo); 1791 enum RC dst_hi_rc = rc_class(dst_hi); 1792 enum RC dst_lo_rc = rc_class(dst_lo); 1793 1794 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1795 1796 if (src_hi != OptoReg::Bad) { 1797 assert((src_lo&1)==0 && src_lo+1==src_hi && 1798 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1799 "expected aligned-adjacent pairs"); 1800 } 1801 1802 if (src_lo == dst_lo && src_hi == dst_hi) { 1803 return 0; // Self copy, no move. 1804 } 1805 1806 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1807 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1808 int src_offset = ra_->reg2offset(src_lo); 1809 int dst_offset = ra_->reg2offset(dst_lo); 1810 1811 if (bottom_type()->isa_vect() != NULL) { 1812 uint ireg = ideal_reg(); 1813 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1814 if (cbuf) { 1815 C2_MacroAssembler _masm(cbuf); 1816 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1817 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1818 // stack->stack 1819 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1820 if (ireg == Op_VecD) { 1821 __ unspill(rscratch1, true, src_offset); 1822 __ spill(rscratch1, true, dst_offset); 1823 } else { 1824 __ spill_copy128(src_offset, dst_offset); 1825 } 1826 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1827 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1828 ireg == Op_VecD ? __ T8B : __ T16B, 1829 as_FloatRegister(Matcher::_regEncode[src_lo])); 1830 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1831 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1832 ireg == Op_VecD ? __ D : __ Q, 1833 ra_->reg2offset(dst_lo)); 1834 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1835 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1836 ireg == Op_VecD ? __ D : __ Q, 1837 ra_->reg2offset(src_lo)); 1838 } else { 1839 ShouldNotReachHere(); 1840 } 1841 } 1842 } else if (cbuf) { 1843 C2_MacroAssembler _masm(cbuf); 1844 switch (src_lo_rc) { 1845 case rc_int: 1846 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1847 if (is64) { 1848 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1849 as_Register(Matcher::_regEncode[src_lo])); 1850 } else { 1851 C2_MacroAssembler _masm(cbuf); 1852 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1853 as_Register(Matcher::_regEncode[src_lo])); 1854 } 1855 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1856 if (is64) { 1857 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1858 as_Register(Matcher::_regEncode[src_lo])); 1859 } else { 1860 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1861 as_Register(Matcher::_regEncode[src_lo])); 1862 } 1863 } else { // gpr --> stack spill 1864 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1865 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1866 } 1867 break; 1868 case rc_float: 1869 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1870 if (is64) { 1871 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1872 as_FloatRegister(Matcher::_regEncode[src_lo])); 1873 } else { 1874 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1875 as_FloatRegister(Matcher::_regEncode[src_lo])); 1876 } 1877 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1878 if (cbuf) { 1879 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1880 as_FloatRegister(Matcher::_regEncode[src_lo])); 1881 } else { 1882 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1883 as_FloatRegister(Matcher::_regEncode[src_lo])); 1884 } 1885 } else { // fpr --> stack spill 1886 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1887 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1888 is64 ? __ D : __ S, dst_offset); 1889 } 1890 break; 1891 case rc_stack: 1892 if (dst_lo_rc == rc_int) { // stack --> gpr load 1893 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1894 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1895 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1896 is64 ? __ D : __ S, src_offset); 1897 } else { // stack --> stack copy 1898 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1899 __ unspill(rscratch1, is64, src_offset); 1900 __ spill(rscratch1, is64, dst_offset); 1901 } 1902 break; 1903 default: 1904 assert(false, "bad rc_class for spill"); 1905 ShouldNotReachHere(); 1906 } 1907 } 1908 1909 if (st) { 1910 st->print("spill "); 1911 if (src_lo_rc == rc_stack) { 1912 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1913 } else { 1914 st->print("%s -> ", Matcher::regName[src_lo]); 1915 } 1916 if (dst_lo_rc == rc_stack) { 1917 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1918 } else { 1919 st->print("%s", Matcher::regName[dst_lo]); 1920 } 1921 if (bottom_type()->isa_vect() != NULL) { 1922 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1923 } else { 1924 st->print("\t# spill size = %d", is64 ? 64:32); 1925 } 1926 } 1927 1928 return 0; 1929 1930 } 1931 1932 #ifndef PRODUCT 1933 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1934 if (!ra_) 1935 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1936 else 1937 implementation(NULL, ra_, false, st); 1938 } 1939 #endif 1940 1941 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1942 implementation(&cbuf, ra_, false, NULL); 1943 } 1944 1945 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1946 return MachNode::size(ra_); 1947 } 1948 1949 //============================================================================= 1950 1951 #ifndef PRODUCT 1952 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1953 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1954 int reg = ra_->get_reg_first(this); 1955 st->print("add %s, rsp, #%d]\t# box lock", 1956 Matcher::regName[reg], offset); 1957 } 1958 #endif 1959 1960 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1961 C2_MacroAssembler _masm(&cbuf); 1962 1963 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1964 int reg = ra_->get_encode(this); 1965 1966 // This add will handle any 24-bit signed offset. 24 bits allows an 1967 // 8 megabyte stack frame. 1968 __ add(as_Register(reg), sp, offset); 1969 } 1970 1971 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1972 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1973 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1974 1975 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1976 return NativeInstruction::instruction_size; 1977 } else { 1978 return 2 * NativeInstruction::instruction_size; 1979 } 1980 } 1981 1982 //============================================================================= 1983 1984 #ifndef PRODUCT 1985 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1986 { 1987 st->print_cr("# MachUEPNode"); 1988 if (UseCompressedClassPointers) { 1989 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1990 if (CompressedKlassPointers::shift() != 0) { 1991 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1992 } 1993 } else { 1994 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1995 } 1996 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1997 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1998 } 1999 #endif 2000 2001 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2002 { 2003 // This is the unverified entry point. 2004 C2_MacroAssembler _masm(&cbuf); 2005 2006 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2007 Label skip; 2008 // TODO 2009 // can we avoid this skip and still use a reloc? 2010 __ br(Assembler::EQ, skip); 2011 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2012 __ bind(skip); 2013 } 2014 2015 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2016 { 2017 return MachNode::size(ra_); 2018 } 2019 2020 // REQUIRED EMIT CODE 2021 2022 //============================================================================= 2023 2024 // Emit exception handler code. 2025 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2026 { 2027 // mov rscratch1 #exception_blob_entry_point 2028 // br rscratch1 2029 // Note that the code buffer's insts_mark is always relative to insts. 2030 // That's why we must use the macroassembler to generate a handler. 2031 C2_MacroAssembler _masm(&cbuf); 2032 address base = __ start_a_stub(size_exception_handler()); 2033 if (base == NULL) { 2034 ciEnv::current()->record_failure("CodeCache is full"); 2035 return 0; // CodeBuffer::expand failed 2036 } 2037 int offset = __ offset(); 2038 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2039 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2040 __ end_a_stub(); 2041 return offset; 2042 } 2043 2044 // Emit deopt handler code. 2045 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2046 { 2047 // Note that the code buffer's insts_mark is always relative to insts. 2048 // That's why we must use the macroassembler to generate a handler. 2049 C2_MacroAssembler _masm(&cbuf); 2050 address base = __ start_a_stub(size_deopt_handler()); 2051 if (base == NULL) { 2052 ciEnv::current()->record_failure("CodeCache is full"); 2053 return 0; // CodeBuffer::expand failed 2054 } 2055 int offset = __ offset(); 2056 2057 __ adr(lr, __ pc()); 2058 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2059 2060 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2061 __ end_a_stub(); 2062 return offset; 2063 } 2064 2065 // REQUIRED MATCHER CODE 2066 2067 //============================================================================= 2068 2069 const bool Matcher::match_rule_supported(int opcode) { 2070 if (!has_match_rule(opcode)) 2071 return false; 2072 2073 bool ret_value = true; 2074 switch (opcode) { 2075 case Op_CacheWB: 2076 case Op_CacheWBPreSync: 2077 case Op_CacheWBPostSync: 2078 if (!VM_Version::supports_data_cache_line_flush()) { 2079 ret_value = false; 2080 } 2081 break; 2082 } 2083 2084 return ret_value; // Per default match rules are supported. 2085 } 2086 2087 // Identify extra cases that we might want to provide match rules for vector nodes and 2088 // other intrinsics guarded with vector length (vlen) and element type (bt). 2089 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2090 if (!match_rule_supported(opcode)) { 2091 return false; 2092 } 2093 2094 // Special cases which require vector length 2095 switch (opcode) { 2096 case Op_MulAddVS2VI: { 2097 if (vlen != 4) { 2098 return false; 2099 } 2100 break; 2101 } 2102 } 2103 2104 return true; // Per default match rules are supported. 2105 } 2106 2107 const bool Matcher::has_predicated_vectors(void) { 2108 return false; 2109 } 2110 2111 const int Matcher::float_pressure(int default_pressure_threshold) { 2112 return default_pressure_threshold; 2113 } 2114 2115 int Matcher::regnum_to_fpu_offset(int regnum) 2116 { 2117 Unimplemented(); 2118 return 0; 2119 } 2120 2121 // Is this branch offset short enough that a short branch can be used? 2122 // 2123 // NOTE: If the platform does not provide any short branch variants, then 2124 // this method should return false for offset 0. 2125 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2126 // The passed offset is relative to address of the branch. 2127 2128 return (-32768 <= offset && offset < 32768); 2129 } 2130 2131 const bool Matcher::isSimpleConstant64(jlong value) { 2132 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2133 // Probably always true, even if a temp register is required. 2134 return true; 2135 } 2136 2137 // true just means we have fast l2f conversion 2138 const bool Matcher::convL2FSupported(void) { 2139 return true; 2140 } 2141 2142 // Vector width in bytes. 2143 const int Matcher::vector_width_in_bytes(BasicType bt) { 2144 int size = MIN2(16,(int)MaxVectorSize); 2145 // Minimum 2 values in vector 2146 if (size < 2*type2aelembytes(bt)) size = 0; 2147 // But never < 4 2148 if (size < 4) size = 0; 2149 return size; 2150 } 2151 2152 // Limits on vector size (number of elements) loaded into vector. 2153 const int Matcher::max_vector_size(const BasicType bt) { 2154 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2155 } 2156 const int Matcher::min_vector_size(const BasicType bt) { 2157 // For the moment limit the vector size to 8 bytes 2158 int size = 8 / type2aelembytes(bt); 2159 if (size < 2) size = 2; 2160 return size; 2161 } 2162 2163 // Vector ideal reg. 2164 const uint Matcher::vector_ideal_reg(int len) { 2165 switch(len) { 2166 case 8: return Op_VecD; 2167 case 16: return Op_VecX; 2168 } 2169 ShouldNotReachHere(); 2170 return 0; 2171 } 2172 2173 // AES support not yet implemented 2174 const bool Matcher::pass_original_key_for_aes() { 2175 return false; 2176 } 2177 2178 // aarch64 supports misaligned vectors store/load. 2179 const bool Matcher::misaligned_vectors_ok() { 2180 return true; 2181 } 2182 2183 // false => size gets scaled to BytesPerLong, ok. 2184 const bool Matcher::init_array_count_is_in_bytes = false; 2185 2186 // Use conditional move (CMOVL) 2187 const int Matcher::long_cmove_cost() { 2188 // long cmoves are no more expensive than int cmoves 2189 return 0; 2190 } 2191 2192 const int Matcher::float_cmove_cost() { 2193 // float cmoves are no more expensive than int cmoves 2194 return 0; 2195 } 2196 2197 // Does the CPU require late expand (see block.cpp for description of late expand)? 2198 const bool Matcher::require_postalloc_expand = false; 2199 2200 // Do we need to mask the count passed to shift instructions or does 2201 // the cpu only look at the lower 5/6 bits anyway? 2202 const bool Matcher::need_masked_shift_count = false; 2203 2204 // No support for generic vector operands. 2205 const bool Matcher::supports_generic_vector_operands = false; 2206 2207 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2208 ShouldNotReachHere(); // generic vector operands not supported 2209 return NULL; 2210 } 2211 2212 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2213 ShouldNotReachHere(); // generic vector operands not supported 2214 return false; 2215 } 2216 2217 bool Matcher::is_generic_vector(MachOper* opnd) { 2218 ShouldNotReachHere(); // generic vector operands not supported 2219 return false; 2220 } 2221 2222 // This affects two different things: 2223 // - how Decode nodes are matched 2224 // - how ImplicitNullCheck opportunities are recognized 2225 // If true, the matcher will try to remove all Decodes and match them 2226 // (as operands) into nodes. NullChecks are not prepared to deal with 2227 // Decodes by final_graph_reshaping(). 2228 // If false, final_graph_reshaping() forces the decode behind the Cmp 2229 // for a NullCheck. The matcher matches the Decode node into a register. 2230 // Implicit_null_check optimization moves the Decode along with the 2231 // memory operation back up before the NullCheck. 2232 bool Matcher::narrow_oop_use_complex_address() { 2233 return CompressedOops::shift() == 0; 2234 } 2235 2236 bool Matcher::narrow_klass_use_complex_address() { 2237 // TODO 2238 // decide whether we need to set this to true 2239 return false; 2240 } 2241 2242 bool Matcher::const_oop_prefer_decode() { 2243 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2244 return CompressedOops::base() == NULL; 2245 } 2246 2247 bool Matcher::const_klass_prefer_decode() { 2248 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2249 return CompressedKlassPointers::base() == NULL; 2250 } 2251 2252 // Is it better to copy float constants, or load them directly from 2253 // memory? Intel can load a float constant from a direct address, 2254 // requiring no extra registers. Most RISCs will have to materialize 2255 // an address into a register first, so they would do better to copy 2256 // the constant from stack. 2257 const bool Matcher::rematerialize_float_constants = false; 2258 2259 // If CPU can load and store mis-aligned doubles directly then no 2260 // fixup is needed. Else we split the double into 2 integer pieces 2261 // and move it piece-by-piece. Only happens when passing doubles into 2262 // C code as the Java calling convention forces doubles to be aligned. 2263 const bool Matcher::misaligned_doubles_ok = true; 2264 2265 // No-op on amd64 2266 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2267 Unimplemented(); 2268 } 2269 2270 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2271 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2272 2273 // Are floats converted to double when stored to stack during 2274 // deoptimization? 2275 bool Matcher::float_in_double() { return false; } 2276 2277 // Do ints take an entire long register or just half? 2278 // The relevant question is how the int is callee-saved: 2279 // the whole long is written but de-opt'ing will have to extract 2280 // the relevant 32 bits. 2281 const bool Matcher::int_in_long = true; 2282 2283 // Return whether or not this register is ever used as an argument. 2284 // This function is used on startup to build the trampoline stubs in 2285 // generateOptoStub. Registers not mentioned will be killed by the VM 2286 // call in the trampoline, and arguments in those registers not be 2287 // available to the callee. 2288 bool Matcher::can_be_java_arg(int reg) 2289 { 2290 return 2291 reg == R0_num || reg == R0_H_num || 2292 reg == R1_num || reg == R1_H_num || 2293 reg == R2_num || reg == R2_H_num || 2294 reg == R3_num || reg == R3_H_num || 2295 reg == R4_num || reg == R4_H_num || 2296 reg == R5_num || reg == R5_H_num || 2297 reg == R6_num || reg == R6_H_num || 2298 reg == R7_num || reg == R7_H_num || 2299 reg == V0_num || reg == V0_H_num || 2300 reg == V1_num || reg == V1_H_num || 2301 reg == V2_num || reg == V2_H_num || 2302 reg == V3_num || reg == V3_H_num || 2303 reg == V4_num || reg == V4_H_num || 2304 reg == V5_num || reg == V5_H_num || 2305 reg == V6_num || reg == V6_H_num || 2306 reg == V7_num || reg == V7_H_num; 2307 } 2308 2309 bool Matcher::is_spillable_arg(int reg) 2310 { 2311 return can_be_java_arg(reg); 2312 } 2313 2314 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2315 return false; 2316 } 2317 2318 RegMask Matcher::divI_proj_mask() { 2319 ShouldNotReachHere(); 2320 return RegMask(); 2321 } 2322 2323 // Register for MODI projection of divmodI. 2324 RegMask Matcher::modI_proj_mask() { 2325 ShouldNotReachHere(); 2326 return RegMask(); 2327 } 2328 2329 // Register for DIVL projection of divmodL. 2330 RegMask Matcher::divL_proj_mask() { 2331 ShouldNotReachHere(); 2332 return RegMask(); 2333 } 2334 2335 // Register for MODL projection of divmodL. 2336 RegMask Matcher::modL_proj_mask() { 2337 ShouldNotReachHere(); 2338 return RegMask(); 2339 } 2340 2341 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2342 return FP_REG_mask(); 2343 } 2344 2345 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2346 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2347 Node* u = addp->fast_out(i); 2348 if (u->is_Mem()) { 2349 int opsize = u->as_Mem()->memory_size(); 2350 assert(opsize > 0, "unexpected memory operand size"); 2351 if (u->as_Mem()->memory_size() != (1<<shift)) { 2352 return false; 2353 } 2354 } 2355 } 2356 return true; 2357 } 2358 2359 const bool Matcher::convi2l_type_required = false; 2360 2361 // Should the matcher clone input 'm' of node 'n'? 2362 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2363 if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) 2364 mstack.push(m, Visit); // m = ShiftCntV 2365 return true; 2366 } 2367 return false; 2368 } 2369 2370 // Should the Matcher clone shifts on addressing modes, expecting them 2371 // to be subsumed into complex addressing expressions or compute them 2372 // into registers? 2373 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2374 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2375 return true; 2376 } 2377 2378 Node *off = m->in(AddPNode::Offset); 2379 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2380 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2381 // Are there other uses besides address expressions? 2382 !is_visited(off)) { 2383 address_visited.set(off->_idx); // Flag as address_visited 2384 mstack.push(off->in(2), Visit); 2385 Node *conv = off->in(1); 2386 if (conv->Opcode() == Op_ConvI2L && 2387 // Are there other uses besides address expressions? 2388 !is_visited(conv)) { 2389 address_visited.set(conv->_idx); // Flag as address_visited 2390 mstack.push(conv->in(1), Pre_Visit); 2391 } else { 2392 mstack.push(conv, Pre_Visit); 2393 } 2394 address_visited.test_set(m->_idx); // Flag as address_visited 2395 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2396 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2397 return true; 2398 } else if (off->Opcode() == Op_ConvI2L && 2399 // Are there other uses besides address expressions? 2400 !is_visited(off)) { 2401 address_visited.test_set(m->_idx); // Flag as address_visited 2402 address_visited.set(off->_idx); // Flag as address_visited 2403 mstack.push(off->in(1), Pre_Visit); 2404 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2405 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2406 return true; 2407 } 2408 return false; 2409 } 2410 2411 void Compile::reshape_address(AddPNode* addp) { 2412 } 2413 2414 2415 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2416 C2_MacroAssembler _masm(&cbuf); \ 2417 { \ 2418 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2419 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2420 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2421 __ INSN(REG, as_Register(BASE)); \ 2422 } 2423 2424 2425 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2426 { 2427 Address::extend scale; 2428 2429 // Hooboy, this is fugly. We need a way to communicate to the 2430 // encoder that the index needs to be sign extended, so we have to 2431 // enumerate all the cases. 2432 switch (opcode) { 2433 case INDINDEXSCALEDI2L: 2434 case INDINDEXSCALEDI2LN: 2435 case INDINDEXI2L: 2436 case INDINDEXI2LN: 2437 scale = Address::sxtw(size); 2438 break; 2439 default: 2440 scale = Address::lsl(size); 2441 } 2442 2443 if (index == -1) { 2444 return Address(base, disp); 2445 } else { 2446 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2447 return Address(base, as_Register(index), scale); 2448 } 2449 } 2450 2451 2452 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2453 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2454 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2455 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2456 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2457 2458 // Used for all non-volatile memory accesses. The use of 2459 // $mem->opcode() to discover whether this pattern uses sign-extended 2460 // offsets is something of a kludge. 2461 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2462 Register reg, int opcode, 2463 Register base, int index, int scale, int disp, 2464 int size_in_memory) 2465 { 2466 Address addr = mem2address(opcode, base, index, scale, disp); 2467 if (addr.getMode() == Address::base_plus_offset) { 2468 /* If we get an out-of-range offset it is a bug in the compiler, 2469 so we assert here. */ 2470 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2471 "c2 compiler bug"); 2472 /* Fix up any out-of-range offsets. */ 2473 assert_different_registers(rscratch1, base); 2474 assert_different_registers(rscratch1, reg); 2475 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2476 } 2477 (masm.*insn)(reg, addr); 2478 } 2479 2480 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2481 FloatRegister reg, int opcode, 2482 Register base, int index, int size, int disp, 2483 int size_in_memory) 2484 { 2485 Address::extend scale; 2486 2487 switch (opcode) { 2488 case INDINDEXSCALEDI2L: 2489 case INDINDEXSCALEDI2LN: 2490 scale = Address::sxtw(size); 2491 break; 2492 default: 2493 scale = Address::lsl(size); 2494 } 2495 2496 if (index == -1) { 2497 /* If we get an out-of-range offset it is a bug in the compiler, 2498 so we assert here. */ 2499 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2500 /* Fix up any out-of-range offsets. */ 2501 assert_different_registers(rscratch1, base); 2502 Address addr = Address(base, disp); 2503 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2504 (masm.*insn)(reg, addr); 2505 } else { 2506 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2507 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2508 } 2509 } 2510 2511 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2512 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2513 int opcode, Register base, int index, int size, int disp) 2514 { 2515 if (index == -1) { 2516 (masm.*insn)(reg, T, Address(base, disp)); 2517 } else { 2518 assert(disp == 0, "unsupported address mode"); 2519 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2520 } 2521 } 2522 2523 %} 2524 2525 2526 2527 //----------ENCODING BLOCK----------------------------------------------------- 2528 // This block specifies the encoding classes used by the compiler to 2529 // output byte streams. Encoding classes are parameterized macros 2530 // used by Machine Instruction Nodes in order to generate the bit 2531 // encoding of the instruction. Operands specify their base encoding 2532 // interface with the interface keyword. There are currently 2533 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2534 // COND_INTER. REG_INTER causes an operand to generate a function 2535 // which returns its register number when queried. CONST_INTER causes 2536 // an operand to generate a function which returns the value of the 2537 // constant when queried. MEMORY_INTER causes an operand to generate 2538 // four functions which return the Base Register, the Index Register, 2539 // the Scale Value, and the Offset Value of the operand when queried. 2540 // COND_INTER causes an operand to generate six functions which return 2541 // the encoding code (ie - encoding bits for the instruction) 2542 // associated with each basic boolean condition for a conditional 2543 // instruction. 2544 // 2545 // Instructions specify two basic values for encoding. Again, a 2546 // function is available to check if the constant displacement is an 2547 // oop. They use the ins_encode keyword to specify their encoding 2548 // classes (which must be a sequence of enc_class names, and their 2549 // parameters, specified in the encoding block), and they use the 2550 // opcode keyword to specify, in order, their primary, secondary, and 2551 // tertiary opcode. Only the opcode sections which a particular 2552 // instruction needs for encoding need to be specified. 2553 encode %{ 2554 // Build emit functions for each basic byte or larger field in the 2555 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2556 // from C++ code in the enc_class source block. Emit functions will 2557 // live in the main source block for now. In future, we can 2558 // generalize this by adding a syntax that specifies the sizes of 2559 // fields in an order, so that the adlc can build the emit functions 2560 // automagically 2561 2562 // catch all for unimplemented encodings 2563 enc_class enc_unimplemented %{ 2564 C2_MacroAssembler _masm(&cbuf); 2565 __ unimplemented("C2 catch all"); 2566 %} 2567 2568 // BEGIN Non-volatile memory access 2569 2570 // This encoding class is generated automatically from ad_encode.m4. 2571 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2572 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2573 Register dst_reg = as_Register($dst$$reg); 2574 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2575 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2576 %} 2577 2578 // This encoding class is generated automatically from ad_encode.m4. 2579 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2580 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2581 Register dst_reg = as_Register($dst$$reg); 2582 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2583 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2584 %} 2585 2586 // This encoding class is generated automatically from ad_encode.m4. 2587 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2588 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2589 Register dst_reg = as_Register($dst$$reg); 2590 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2591 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2592 %} 2593 2594 // This encoding class is generated automatically from ad_encode.m4. 2595 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2596 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2597 Register dst_reg = as_Register($dst$$reg); 2598 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2599 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2600 %} 2601 2602 // This encoding class is generated automatically from ad_encode.m4. 2603 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2604 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2605 Register dst_reg = as_Register($dst$$reg); 2606 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2607 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2608 %} 2609 2610 // This encoding class is generated automatically from ad_encode.m4. 2611 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2612 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2613 Register dst_reg = as_Register($dst$$reg); 2614 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2615 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2616 %} 2617 2618 // This encoding class is generated automatically from ad_encode.m4. 2619 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2620 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2621 Register dst_reg = as_Register($dst$$reg); 2622 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2623 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2624 %} 2625 2626 // This encoding class is generated automatically from ad_encode.m4. 2627 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2628 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2629 Register dst_reg = as_Register($dst$$reg); 2630 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2631 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2632 %} 2633 2634 // This encoding class is generated automatically from ad_encode.m4. 2635 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2636 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2637 Register dst_reg = as_Register($dst$$reg); 2638 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2639 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2640 %} 2641 2642 // This encoding class is generated automatically from ad_encode.m4. 2643 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2644 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2645 Register dst_reg = as_Register($dst$$reg); 2646 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2647 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2648 %} 2649 2650 // This encoding class is generated automatically from ad_encode.m4. 2651 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2652 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2653 Register dst_reg = as_Register($dst$$reg); 2654 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2655 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2656 %} 2657 2658 // This encoding class is generated automatically from ad_encode.m4. 2659 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2660 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2661 Register dst_reg = as_Register($dst$$reg); 2662 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2663 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2664 %} 2665 2666 // This encoding class is generated automatically from ad_encode.m4. 2667 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2668 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2669 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2670 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2671 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2672 %} 2673 2674 // This encoding class is generated automatically from ad_encode.m4. 2675 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2676 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2677 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2678 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2679 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2680 %} 2681 2682 // This encoding class is generated automatically from ad_encode.m4. 2683 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2684 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2685 Register src_reg = as_Register($src$$reg); 2686 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2687 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2688 %} 2689 2690 // This encoding class is generated automatically from ad_encode.m4. 2691 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2692 enc_class aarch64_enc_strb0(memory1 mem) %{ 2693 C2_MacroAssembler _masm(&cbuf); 2694 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2695 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2696 %} 2697 2698 // This encoding class is generated automatically from ad_encode.m4. 2699 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2700 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2701 Register src_reg = as_Register($src$$reg); 2702 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2703 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2704 %} 2705 2706 // This encoding class is generated automatically from ad_encode.m4. 2707 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2708 enc_class aarch64_enc_strh0(memory2 mem) %{ 2709 C2_MacroAssembler _masm(&cbuf); 2710 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2711 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2712 %} 2713 2714 // This encoding class is generated automatically from ad_encode.m4. 2715 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2716 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2717 Register src_reg = as_Register($src$$reg); 2718 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2719 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2720 %} 2721 2722 // This encoding class is generated automatically from ad_encode.m4. 2723 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2724 enc_class aarch64_enc_strw0(memory4 mem) %{ 2725 C2_MacroAssembler _masm(&cbuf); 2726 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2727 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2728 %} 2729 2730 // This encoding class is generated automatically from ad_encode.m4. 2731 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2732 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2733 Register src_reg = as_Register($src$$reg); 2734 // we sometimes get asked to store the stack pointer into the 2735 // current thread -- we cannot do that directly on AArch64 2736 if (src_reg == r31_sp) { 2737 C2_MacroAssembler _masm(&cbuf); 2738 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2739 __ mov(rscratch2, sp); 2740 src_reg = rscratch2; 2741 } 2742 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2743 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2744 %} 2745 2746 // This encoding class is generated automatically from ad_encode.m4. 2747 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2748 enc_class aarch64_enc_str0(memory8 mem) %{ 2749 C2_MacroAssembler _masm(&cbuf); 2750 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2751 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2752 %} 2753 2754 // This encoding class is generated automatically from ad_encode.m4. 2755 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2756 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 2757 FloatRegister src_reg = as_FloatRegister($src$$reg); 2758 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2759 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2760 %} 2761 2762 // This encoding class is generated automatically from ad_encode.m4. 2763 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2764 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 2765 FloatRegister src_reg = as_FloatRegister($src$$reg); 2766 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2767 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2768 %} 2769 2770 // This encoding class is generated automatically from ad_encode.m4. 2771 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2772 enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{ 2773 C2_MacroAssembler _masm(&cbuf); 2774 address con = (address)$src$$constant; 2775 // need to do this the hard way until we can manage relocs 2776 // for 32 bit constants 2777 __ movoop(rscratch2, (jobject)con); 2778 if (con) __ encode_heap_oop_not_null(rscratch2); 2779 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2780 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2781 %} 2782 2783 // This encoding class is generated automatically from ad_encode.m4. 2784 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2785 enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{ 2786 C2_MacroAssembler _masm(&cbuf); 2787 address con = (address)$src$$constant; 2788 // need to do this the hard way until we can manage relocs 2789 // for 32 bit constants 2790 __ movoop(rscratch2, (jobject)con); 2791 __ encode_klass_not_null(rscratch2); 2792 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2793 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2794 %} 2795 2796 // This encoding class is generated automatically from ad_encode.m4. 2797 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2798 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 2799 C2_MacroAssembler _masm(&cbuf); 2800 __ membar(Assembler::StoreStore); 2801 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2802 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2803 %} 2804 2805 // END Non-volatile memory access 2806 2807 // Vector loads and stores 2808 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2809 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2810 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2811 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2812 %} 2813 2814 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2815 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2816 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2817 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2818 %} 2819 2820 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2821 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2822 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2823 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2824 %} 2825 2826 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2827 FloatRegister src_reg = as_FloatRegister($src$$reg); 2828 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2829 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2830 %} 2831 2832 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2833 FloatRegister src_reg = as_FloatRegister($src$$reg); 2834 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2835 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2836 %} 2837 2838 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2839 FloatRegister src_reg = as_FloatRegister($src$$reg); 2840 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2841 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2842 %} 2843 2844 // volatile loads and stores 2845 2846 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2847 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2848 rscratch1, stlrb); 2849 %} 2850 2851 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2852 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2853 rscratch1, stlrh); 2854 %} 2855 2856 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2857 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2858 rscratch1, stlrw); 2859 %} 2860 2861 2862 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2863 Register dst_reg = as_Register($dst$$reg); 2864 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2865 rscratch1, ldarb); 2866 __ sxtbw(dst_reg, dst_reg); 2867 %} 2868 2869 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2870 Register dst_reg = as_Register($dst$$reg); 2871 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2872 rscratch1, ldarb); 2873 __ sxtb(dst_reg, dst_reg); 2874 %} 2875 2876 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2877 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2878 rscratch1, ldarb); 2879 %} 2880 2881 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2882 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2883 rscratch1, ldarb); 2884 %} 2885 2886 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2887 Register dst_reg = as_Register($dst$$reg); 2888 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2889 rscratch1, ldarh); 2890 __ sxthw(dst_reg, dst_reg); 2891 %} 2892 2893 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2894 Register dst_reg = as_Register($dst$$reg); 2895 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2896 rscratch1, ldarh); 2897 __ sxth(dst_reg, dst_reg); 2898 %} 2899 2900 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2901 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2902 rscratch1, ldarh); 2903 %} 2904 2905 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2906 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2907 rscratch1, ldarh); 2908 %} 2909 2910 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2911 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2912 rscratch1, ldarw); 2913 %} 2914 2915 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2916 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2917 rscratch1, ldarw); 2918 %} 2919 2920 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2921 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2922 rscratch1, ldar); 2923 %} 2924 2925 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2926 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2927 rscratch1, ldarw); 2928 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2929 %} 2930 2931 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2932 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2933 rscratch1, ldar); 2934 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2935 %} 2936 2937 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2938 Register src_reg = as_Register($src$$reg); 2939 // we sometimes get asked to store the stack pointer into the 2940 // current thread -- we cannot do that directly on AArch64 2941 if (src_reg == r31_sp) { 2942 C2_MacroAssembler _masm(&cbuf); 2943 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2944 __ mov(rscratch2, sp); 2945 src_reg = rscratch2; 2946 } 2947 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2948 rscratch1, stlr); 2949 %} 2950 2951 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2952 { 2953 C2_MacroAssembler _masm(&cbuf); 2954 FloatRegister src_reg = as_FloatRegister($src$$reg); 2955 __ fmovs(rscratch2, src_reg); 2956 } 2957 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2958 rscratch1, stlrw); 2959 %} 2960 2961 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2962 { 2963 C2_MacroAssembler _masm(&cbuf); 2964 FloatRegister src_reg = as_FloatRegister($src$$reg); 2965 __ fmovd(rscratch2, src_reg); 2966 } 2967 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2968 rscratch1, stlr); 2969 %} 2970 2971 // synchronized read/update encodings 2972 2973 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 2974 C2_MacroAssembler _masm(&cbuf); 2975 Register dst_reg = as_Register($dst$$reg); 2976 Register base = as_Register($mem$$base); 2977 int index = $mem$$index; 2978 int scale = $mem$$scale; 2979 int disp = $mem$$disp; 2980 if (index == -1) { 2981 if (disp != 0) { 2982 __ lea(rscratch1, Address(base, disp)); 2983 __ ldaxr(dst_reg, rscratch1); 2984 } else { 2985 // TODO 2986 // should we ever get anything other than this case? 2987 __ ldaxr(dst_reg, base); 2988 } 2989 } else { 2990 Register index_reg = as_Register(index); 2991 if (disp == 0) { 2992 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2993 __ ldaxr(dst_reg, rscratch1); 2994 } else { 2995 __ lea(rscratch1, Address(base, disp)); 2996 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2997 __ ldaxr(dst_reg, rscratch1); 2998 } 2999 } 3000 %} 3001 3002 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3003 C2_MacroAssembler _masm(&cbuf); 3004 Register src_reg = as_Register($src$$reg); 3005 Register base = as_Register($mem$$base); 3006 int index = $mem$$index; 3007 int scale = $mem$$scale; 3008 int disp = $mem$$disp; 3009 if (index == -1) { 3010 if (disp != 0) { 3011 __ lea(rscratch2, Address(base, disp)); 3012 __ stlxr(rscratch1, src_reg, rscratch2); 3013 } else { 3014 // TODO 3015 // should we ever get anything other than this case? 3016 __ stlxr(rscratch1, src_reg, base); 3017 } 3018 } else { 3019 Register index_reg = as_Register(index); 3020 if (disp == 0) { 3021 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3022 __ stlxr(rscratch1, src_reg, rscratch2); 3023 } else { 3024 __ lea(rscratch2, Address(base, disp)); 3025 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3026 __ stlxr(rscratch1, src_reg, rscratch2); 3027 } 3028 } 3029 __ cmpw(rscratch1, zr); 3030 %} 3031 3032 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3033 C2_MacroAssembler _masm(&cbuf); 3034 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3035 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3036 Assembler::xword, /*acquire*/ false, /*release*/ true, 3037 /*weak*/ false, noreg); 3038 %} 3039 3040 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3041 C2_MacroAssembler _masm(&cbuf); 3042 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3043 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3044 Assembler::word, /*acquire*/ false, /*release*/ true, 3045 /*weak*/ false, noreg); 3046 %} 3047 3048 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3049 C2_MacroAssembler _masm(&cbuf); 3050 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3051 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3052 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3053 /*weak*/ false, noreg); 3054 %} 3055 3056 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3057 C2_MacroAssembler _masm(&cbuf); 3058 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3059 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3060 Assembler::byte, /*acquire*/ false, /*release*/ true, 3061 /*weak*/ false, noreg); 3062 %} 3063 3064 3065 // The only difference between aarch64_enc_cmpxchg and 3066 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3067 // CompareAndSwap sequence to serve as a barrier on acquiring a 3068 // lock. 3069 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3070 C2_MacroAssembler _masm(&cbuf); 3071 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3072 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3073 Assembler::xword, /*acquire*/ true, /*release*/ true, 3074 /*weak*/ false, noreg); 3075 %} 3076 3077 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3078 C2_MacroAssembler _masm(&cbuf); 3079 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3080 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3081 Assembler::word, /*acquire*/ true, /*release*/ true, 3082 /*weak*/ false, noreg); 3083 %} 3084 3085 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3086 C2_MacroAssembler _masm(&cbuf); 3087 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3088 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3089 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3090 /*weak*/ false, noreg); 3091 %} 3092 3093 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3094 C2_MacroAssembler _masm(&cbuf); 3095 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3096 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3097 Assembler::byte, /*acquire*/ true, /*release*/ true, 3098 /*weak*/ false, noreg); 3099 %} 3100 3101 // auxiliary used for CompareAndSwapX to set result register 3102 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3103 C2_MacroAssembler _masm(&cbuf); 3104 Register res_reg = as_Register($res$$reg); 3105 __ cset(res_reg, Assembler::EQ); 3106 %} 3107 3108 // prefetch encodings 3109 3110 enc_class aarch64_enc_prefetchw(memory mem) %{ 3111 C2_MacroAssembler _masm(&cbuf); 3112 Register base = as_Register($mem$$base); 3113 int index = $mem$$index; 3114 int scale = $mem$$scale; 3115 int disp = $mem$$disp; 3116 if (index == -1) { 3117 __ prfm(Address(base, disp), PSTL1KEEP); 3118 } else { 3119 Register index_reg = as_Register(index); 3120 if (disp == 0) { 3121 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3122 } else { 3123 __ lea(rscratch1, Address(base, disp)); 3124 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3125 } 3126 } 3127 %} 3128 3129 /// mov envcodings 3130 3131 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3132 C2_MacroAssembler _masm(&cbuf); 3133 uint32_t con = (uint32_t)$src$$constant; 3134 Register dst_reg = as_Register($dst$$reg); 3135 if (con == 0) { 3136 __ movw(dst_reg, zr); 3137 } else { 3138 __ movw(dst_reg, con); 3139 } 3140 %} 3141 3142 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3143 C2_MacroAssembler _masm(&cbuf); 3144 Register dst_reg = as_Register($dst$$reg); 3145 uint64_t con = (uint64_t)$src$$constant; 3146 if (con == 0) { 3147 __ mov(dst_reg, zr); 3148 } else { 3149 __ mov(dst_reg, con); 3150 } 3151 %} 3152 3153 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3154 C2_MacroAssembler _masm(&cbuf); 3155 Register dst_reg = as_Register($dst$$reg); 3156 address con = (address)$src$$constant; 3157 if (con == NULL || con == (address)1) { 3158 ShouldNotReachHere(); 3159 } else { 3160 relocInfo::relocType rtype = $src->constant_reloc(); 3161 if (rtype == relocInfo::oop_type) { 3162 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3163 } else if (rtype == relocInfo::metadata_type) { 3164 __ mov_metadata(dst_reg, (Metadata*)con); 3165 } else { 3166 assert(rtype == relocInfo::none, "unexpected reloc type"); 3167 if (con < (address)(uintptr_t)os::vm_page_size()) { 3168 __ mov(dst_reg, con); 3169 } else { 3170 uintptr_t offset; 3171 __ adrp(dst_reg, con, offset); 3172 __ add(dst_reg, dst_reg, offset); 3173 } 3174 } 3175 } 3176 %} 3177 3178 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3179 C2_MacroAssembler _masm(&cbuf); 3180 Register dst_reg = as_Register($dst$$reg); 3181 __ mov(dst_reg, zr); 3182 %} 3183 3184 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3185 C2_MacroAssembler _masm(&cbuf); 3186 Register dst_reg = as_Register($dst$$reg); 3187 __ mov(dst_reg, (uint64_t)1); 3188 %} 3189 3190 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3191 C2_MacroAssembler _masm(&cbuf); 3192 __ load_byte_map_base($dst$$Register); 3193 %} 3194 3195 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3196 C2_MacroAssembler _masm(&cbuf); 3197 Register dst_reg = as_Register($dst$$reg); 3198 address con = (address)$src$$constant; 3199 if (con == NULL) { 3200 ShouldNotReachHere(); 3201 } else { 3202 relocInfo::relocType rtype = $src->constant_reloc(); 3203 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3204 __ set_narrow_oop(dst_reg, (jobject)con); 3205 } 3206 %} 3207 3208 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3209 C2_MacroAssembler _masm(&cbuf); 3210 Register dst_reg = as_Register($dst$$reg); 3211 __ mov(dst_reg, zr); 3212 %} 3213 3214 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3215 C2_MacroAssembler _masm(&cbuf); 3216 Register dst_reg = as_Register($dst$$reg); 3217 address con = (address)$src$$constant; 3218 if (con == NULL) { 3219 ShouldNotReachHere(); 3220 } else { 3221 relocInfo::relocType rtype = $src->constant_reloc(); 3222 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3223 __ set_narrow_klass(dst_reg, (Klass *)con); 3224 } 3225 %} 3226 3227 // arithmetic encodings 3228 3229 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3230 C2_MacroAssembler _masm(&cbuf); 3231 Register dst_reg = as_Register($dst$$reg); 3232 Register src_reg = as_Register($src1$$reg); 3233 int32_t con = (int32_t)$src2$$constant; 3234 // add has primary == 0, subtract has primary == 1 3235 if ($primary) { con = -con; } 3236 if (con < 0) { 3237 __ subw(dst_reg, src_reg, -con); 3238 } else { 3239 __ addw(dst_reg, src_reg, con); 3240 } 3241 %} 3242 3243 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3244 C2_MacroAssembler _masm(&cbuf); 3245 Register dst_reg = as_Register($dst$$reg); 3246 Register src_reg = as_Register($src1$$reg); 3247 int32_t con = (int32_t)$src2$$constant; 3248 // add has primary == 0, subtract has primary == 1 3249 if ($primary) { con = -con; } 3250 if (con < 0) { 3251 __ sub(dst_reg, src_reg, -con); 3252 } else { 3253 __ add(dst_reg, src_reg, con); 3254 } 3255 %} 3256 3257 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3258 C2_MacroAssembler _masm(&cbuf); 3259 Register dst_reg = as_Register($dst$$reg); 3260 Register src1_reg = as_Register($src1$$reg); 3261 Register src2_reg = as_Register($src2$$reg); 3262 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3263 %} 3264 3265 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3266 C2_MacroAssembler _masm(&cbuf); 3267 Register dst_reg = as_Register($dst$$reg); 3268 Register src1_reg = as_Register($src1$$reg); 3269 Register src2_reg = as_Register($src2$$reg); 3270 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3271 %} 3272 3273 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3274 C2_MacroAssembler _masm(&cbuf); 3275 Register dst_reg = as_Register($dst$$reg); 3276 Register src1_reg = as_Register($src1$$reg); 3277 Register src2_reg = as_Register($src2$$reg); 3278 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3279 %} 3280 3281 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3282 C2_MacroAssembler _masm(&cbuf); 3283 Register dst_reg = as_Register($dst$$reg); 3284 Register src1_reg = as_Register($src1$$reg); 3285 Register src2_reg = as_Register($src2$$reg); 3286 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3287 %} 3288 3289 // compare instruction encodings 3290 3291 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3292 C2_MacroAssembler _masm(&cbuf); 3293 Register reg1 = as_Register($src1$$reg); 3294 Register reg2 = as_Register($src2$$reg); 3295 __ cmpw(reg1, reg2); 3296 %} 3297 3298 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3299 C2_MacroAssembler _masm(&cbuf); 3300 Register reg = as_Register($src1$$reg); 3301 int32_t val = $src2$$constant; 3302 if (val >= 0) { 3303 __ subsw(zr, reg, val); 3304 } else { 3305 __ addsw(zr, reg, -val); 3306 } 3307 %} 3308 3309 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3310 C2_MacroAssembler _masm(&cbuf); 3311 Register reg1 = as_Register($src1$$reg); 3312 uint32_t val = (uint32_t)$src2$$constant; 3313 __ movw(rscratch1, val); 3314 __ cmpw(reg1, rscratch1); 3315 %} 3316 3317 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3318 C2_MacroAssembler _masm(&cbuf); 3319 Register reg1 = as_Register($src1$$reg); 3320 Register reg2 = as_Register($src2$$reg); 3321 __ cmp(reg1, reg2); 3322 %} 3323 3324 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3325 C2_MacroAssembler _masm(&cbuf); 3326 Register reg = as_Register($src1$$reg); 3327 int64_t val = $src2$$constant; 3328 if (val >= 0) { 3329 __ subs(zr, reg, val); 3330 } else if (val != -val) { 3331 __ adds(zr, reg, -val); 3332 } else { 3333 // aargh, Long.MIN_VALUE is a special case 3334 __ orr(rscratch1, zr, (uint64_t)val); 3335 __ subs(zr, reg, rscratch1); 3336 } 3337 %} 3338 3339 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3340 C2_MacroAssembler _masm(&cbuf); 3341 Register reg1 = as_Register($src1$$reg); 3342 uint64_t val = (uint64_t)$src2$$constant; 3343 __ mov(rscratch1, val); 3344 __ cmp(reg1, rscratch1); 3345 %} 3346 3347 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3348 C2_MacroAssembler _masm(&cbuf); 3349 Register reg1 = as_Register($src1$$reg); 3350 Register reg2 = as_Register($src2$$reg); 3351 __ cmp(reg1, reg2); 3352 %} 3353 3354 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3355 C2_MacroAssembler _masm(&cbuf); 3356 Register reg1 = as_Register($src1$$reg); 3357 Register reg2 = as_Register($src2$$reg); 3358 __ cmpw(reg1, reg2); 3359 %} 3360 3361 enc_class aarch64_enc_testp(iRegP src) %{ 3362 C2_MacroAssembler _masm(&cbuf); 3363 Register reg = as_Register($src$$reg); 3364 __ cmp(reg, zr); 3365 %} 3366 3367 enc_class aarch64_enc_testn(iRegN src) %{ 3368 C2_MacroAssembler _masm(&cbuf); 3369 Register reg = as_Register($src$$reg); 3370 __ cmpw(reg, zr); 3371 %} 3372 3373 enc_class aarch64_enc_b(label lbl) %{ 3374 C2_MacroAssembler _masm(&cbuf); 3375 Label *L = $lbl$$label; 3376 __ b(*L); 3377 %} 3378 3379 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3380 C2_MacroAssembler _masm(&cbuf); 3381 Label *L = $lbl$$label; 3382 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3383 %} 3384 3385 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3386 C2_MacroAssembler _masm(&cbuf); 3387 Label *L = $lbl$$label; 3388 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3389 %} 3390 3391 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3392 %{ 3393 Register sub_reg = as_Register($sub$$reg); 3394 Register super_reg = as_Register($super$$reg); 3395 Register temp_reg = as_Register($temp$$reg); 3396 Register result_reg = as_Register($result$$reg); 3397 3398 Label miss; 3399 C2_MacroAssembler _masm(&cbuf); 3400 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3401 NULL, &miss, 3402 /*set_cond_codes:*/ true); 3403 if ($primary) { 3404 __ mov(result_reg, zr); 3405 } 3406 __ bind(miss); 3407 %} 3408 3409 enc_class aarch64_enc_java_static_call(method meth) %{ 3410 C2_MacroAssembler _masm(&cbuf); 3411 3412 address addr = (address)$meth$$method; 3413 address call; 3414 if (!_method) { 3415 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3416 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3417 } else { 3418 int method_index = resolved_method_index(cbuf); 3419 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3420 : static_call_Relocation::spec(method_index); 3421 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3422 3423 // Emit stub for static call 3424 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3425 if (stub == NULL) { 3426 ciEnv::current()->record_failure("CodeCache is full"); 3427 return; 3428 } 3429 } 3430 if (call == NULL) { 3431 ciEnv::current()->record_failure("CodeCache is full"); 3432 return; 3433 } 3434 %} 3435 3436 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3437 C2_MacroAssembler _masm(&cbuf); 3438 int method_index = resolved_method_index(cbuf); 3439 address call = __ ic_call((address)$meth$$method, method_index); 3440 if (call == NULL) { 3441 ciEnv::current()->record_failure("CodeCache is full"); 3442 return; 3443 } 3444 %} 3445 3446 enc_class aarch64_enc_call_epilog() %{ 3447 C2_MacroAssembler _masm(&cbuf); 3448 if (VerifyStackAtCalls) { 3449 // Check that stack depth is unchanged: find majik cookie on stack 3450 __ call_Unimplemented(); 3451 } 3452 %} 3453 3454 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3455 C2_MacroAssembler _masm(&cbuf); 3456 3457 // some calls to generated routines (arraycopy code) are scheduled 3458 // by C2 as runtime calls. if so we can call them using a br (they 3459 // will be in a reachable segment) otherwise we have to use a blr 3460 // which loads the absolute address into a register. 3461 address entry = (address)$meth$$method; 3462 CodeBlob *cb = CodeCache::find_blob(entry); 3463 if (cb) { 3464 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3465 if (call == NULL) { 3466 ciEnv::current()->record_failure("CodeCache is full"); 3467 return; 3468 } 3469 } else { 3470 Label retaddr; 3471 __ adr(rscratch2, retaddr); 3472 __ lea(rscratch1, RuntimeAddress(entry)); 3473 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3474 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3475 __ blr(rscratch1); 3476 __ bind(retaddr); 3477 __ add(sp, sp, 2 * wordSize); 3478 } 3479 %} 3480 3481 enc_class aarch64_enc_rethrow() %{ 3482 C2_MacroAssembler _masm(&cbuf); 3483 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3484 %} 3485 3486 enc_class aarch64_enc_ret() %{ 3487 C2_MacroAssembler _masm(&cbuf); 3488 __ ret(lr); 3489 %} 3490 3491 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3492 C2_MacroAssembler _masm(&cbuf); 3493 Register target_reg = as_Register($jump_target$$reg); 3494 __ br(target_reg); 3495 %} 3496 3497 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3498 C2_MacroAssembler _masm(&cbuf); 3499 Register target_reg = as_Register($jump_target$$reg); 3500 // exception oop should be in r0 3501 // ret addr has been popped into lr 3502 // callee expects it in r3 3503 __ mov(r3, lr); 3504 __ br(target_reg); 3505 %} 3506 3507 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3508 C2_MacroAssembler _masm(&cbuf); 3509 Register oop = as_Register($object$$reg); 3510 Register box = as_Register($box$$reg); 3511 Register disp_hdr = as_Register($tmp$$reg); 3512 Register tmp = as_Register($tmp2$$reg); 3513 Label cont; 3514 Label object_has_monitor; 3515 Label cas_failed; 3516 3517 assert_different_registers(oop, box, tmp, disp_hdr); 3518 3519 // Load markWord from object into displaced_header. 3520 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3521 3522 if (UseBiasedLocking && !UseOptoBiasInlining) { 3523 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3524 } 3525 3526 // Check for existing monitor 3527 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3528 3529 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3530 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3531 3532 // Initialize the box. (Must happen before we update the object mark!) 3533 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3534 3535 // Compare object markWord with an unlocked value (tmp) and if 3536 // equal exchange the stack address of our box with object markWord. 3537 // On failure disp_hdr contains the possibly locked markWord. 3538 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3539 /*release*/ true, /*weak*/ false, disp_hdr); 3540 __ br(Assembler::EQ, cont); 3541 3542 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3543 3544 // If the compare-and-exchange succeeded, then we found an unlocked 3545 // object, will have now locked it will continue at label cont 3546 3547 __ bind(cas_failed); 3548 // We did not see an unlocked object so try the fast recursive case. 3549 3550 // Check if the owner is self by comparing the value in the 3551 // markWord of object (disp_hdr) with the stack pointer. 3552 __ mov(rscratch1, sp); 3553 __ sub(disp_hdr, disp_hdr, rscratch1); 3554 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3555 // If condition is true we are cont and hence we can store 0 as the 3556 // displaced header in the box, which indicates that it is a recursive lock. 3557 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3558 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3559 3560 __ b(cont); 3561 3562 // Handle existing monitor. 3563 __ bind(object_has_monitor); 3564 3565 // The object's monitor m is unlocked iff m->owner == NULL, 3566 // otherwise m->owner may contain a thread or a stack address. 3567 // 3568 // Try to CAS m->owner from NULL to current thread. 3569 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3570 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3571 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3572 3573 // Store a non-null value into the box to avoid looking like a re-entrant 3574 // lock. The fast-path monitor unlock code checks for 3575 // markWord::monitor_value so use markWord::unused_mark which has the 3576 // relevant bit set, and also matches ObjectSynchronizer::enter. 3577 __ mov(tmp, (address)markWord::unused_mark().value()); 3578 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3579 3580 __ bind(cont); 3581 // flag == EQ indicates success 3582 // flag == NE indicates failure 3583 %} 3584 3585 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3586 C2_MacroAssembler _masm(&cbuf); 3587 Register oop = as_Register($object$$reg); 3588 Register box = as_Register($box$$reg); 3589 Register disp_hdr = as_Register($tmp$$reg); 3590 Register tmp = as_Register($tmp2$$reg); 3591 Label cont; 3592 Label object_has_monitor; 3593 3594 assert_different_registers(oop, box, tmp, disp_hdr); 3595 3596 if (UseBiasedLocking && !UseOptoBiasInlining) { 3597 __ biased_locking_exit(oop, tmp, cont); 3598 } 3599 3600 // Find the lock address and load the displaced header from the stack. 3601 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3602 3603 // If the displaced header is 0, we have a recursive unlock. 3604 __ cmp(disp_hdr, zr); 3605 __ br(Assembler::EQ, cont); 3606 3607 // Handle existing monitor. 3608 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3609 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3610 3611 // Check if it is still a light weight lock, this is is true if we 3612 // see the stack address of the basicLock in the markWord of the 3613 // object. 3614 3615 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3616 /*release*/ true, /*weak*/ false, tmp); 3617 __ b(cont); 3618 3619 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3620 3621 // Handle existing monitor. 3622 __ bind(object_has_monitor); 3623 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3624 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3625 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3626 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3627 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3628 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3629 __ cmp(rscratch1, zr); // Sets flags for result 3630 __ br(Assembler::NE, cont); 3631 3632 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3633 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3634 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3635 __ cmp(rscratch1, zr); // Sets flags for result 3636 __ cbnz(rscratch1, cont); 3637 // need a release store here 3638 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3639 __ stlr(zr, tmp); // set unowned 3640 3641 __ bind(cont); 3642 // flag == EQ indicates success 3643 // flag == NE indicates failure 3644 %} 3645 3646 %} 3647 3648 //----------FRAME-------------------------------------------------------------- 3649 // Definition of frame structure and management information. 3650 // 3651 // S T A C K L A Y O U T Allocators stack-slot number 3652 // | (to get allocators register number 3653 // G Owned by | | v add OptoReg::stack0()) 3654 // r CALLER | | 3655 // o | +--------+ pad to even-align allocators stack-slot 3656 // w V | pad0 | numbers; owned by CALLER 3657 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3658 // h ^ | in | 5 3659 // | | args | 4 Holes in incoming args owned by SELF 3660 // | | | | 3 3661 // | | +--------+ 3662 // V | | old out| Empty on Intel, window on Sparc 3663 // | old |preserve| Must be even aligned. 3664 // | SP-+--------+----> Matcher::_old_SP, even aligned 3665 // | | in | 3 area for Intel ret address 3666 // Owned by |preserve| Empty on Sparc. 3667 // SELF +--------+ 3668 // | | pad2 | 2 pad to align old SP 3669 // | +--------+ 1 3670 // | | locks | 0 3671 // | +--------+----> OptoReg::stack0(), even aligned 3672 // | | pad1 | 11 pad to align new SP 3673 // | +--------+ 3674 // | | | 10 3675 // | | spills | 9 spills 3676 // V | | 8 (pad0 slot for callee) 3677 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3678 // ^ | out | 7 3679 // | | args | 6 Holes in outgoing args owned by CALLEE 3680 // Owned by +--------+ 3681 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3682 // | new |preserve| Must be even-aligned. 3683 // | SP-+--------+----> Matcher::_new_SP, even aligned 3684 // | | | 3685 // 3686 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3687 // known from SELF's arguments and the Java calling convention. 3688 // Region 6-7 is determined per call site. 3689 // Note 2: If the calling convention leaves holes in the incoming argument 3690 // area, those holes are owned by SELF. Holes in the outgoing area 3691 // are owned by the CALLEE. Holes should not be nessecary in the 3692 // incoming area, as the Java calling convention is completely under 3693 // the control of the AD file. Doubles can be sorted and packed to 3694 // avoid holes. Holes in the outgoing arguments may be nessecary for 3695 // varargs C calling conventions. 3696 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3697 // even aligned with pad0 as needed. 3698 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3699 // (the latter is true on Intel but is it false on AArch64?) 3700 // region 6-11 is even aligned; it may be padded out more so that 3701 // the region from SP to FP meets the minimum stack alignment. 3702 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3703 // alignment. Region 11, pad1, may be dynamically extended so that 3704 // SP meets the minimum alignment. 3705 3706 frame %{ 3707 // What direction does stack grow in (assumed to be same for C & Java) 3708 stack_direction(TOWARDS_LOW); 3709 3710 // These three registers define part of the calling convention 3711 // between compiled code and the interpreter. 3712 3713 // Inline Cache Register or Method for I2C. 3714 inline_cache_reg(R12); 3715 3716 // Method Oop Register when calling interpreter. 3717 interpreter_method_oop_reg(R12); 3718 3719 // Number of stack slots consumed by locking an object 3720 sync_stack_slots(2); 3721 3722 // Compiled code's Frame Pointer 3723 frame_pointer(R31); 3724 3725 // Interpreter stores its frame pointer in a register which is 3726 // stored to the stack by I2CAdaptors. 3727 // I2CAdaptors convert from interpreted java to compiled java. 3728 interpreter_frame_pointer(R29); 3729 3730 // Stack alignment requirement 3731 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3732 3733 // Number of stack slots between incoming argument block and the start of 3734 // a new frame. The PROLOG must add this many slots to the stack. The 3735 // EPILOG must remove this many slots. aarch64 needs two slots for 3736 // return address and fp. 3737 // TODO think this is correct but check 3738 in_preserve_stack_slots(4); 3739 3740 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3741 // for calls to C. Supports the var-args backing area for register parms. 3742 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3743 3744 // The after-PROLOG location of the return address. Location of 3745 // return address specifies a type (REG or STACK) and a number 3746 // representing the register number (i.e. - use a register name) or 3747 // stack slot. 3748 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3749 // Otherwise, it is above the locks and verification slot and alignment word 3750 // TODO this may well be correct but need to check why that - 2 is there 3751 // ppc port uses 0 but we definitely need to allow for fixed_slots 3752 // which folds in the space used for monitors 3753 return_addr(STACK - 2 + 3754 align_up((Compile::current()->in_preserve_stack_slots() + 3755 Compile::current()->fixed_slots()), 3756 stack_alignment_in_slots())); 3757 3758 // Body of function which returns an integer array locating 3759 // arguments either in registers or in stack slots. Passed an array 3760 // of ideal registers called "sig" and a "length" count. Stack-slot 3761 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3762 // arguments for a CALLEE. Incoming stack arguments are 3763 // automatically biased by the preserve_stack_slots field above. 3764 3765 calling_convention 3766 %{ 3767 // No difference between ingoing/outgoing just pass false 3768 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3769 %} 3770 3771 c_calling_convention 3772 %{ 3773 // This is obviously always outgoing 3774 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3775 %} 3776 3777 // Location of compiled Java return values. Same as C for now. 3778 return_value 3779 %{ 3780 // TODO do we allow ideal_reg == Op_RegN??? 3781 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3782 "only return normal values"); 3783 3784 static const int lo[Op_RegL + 1] = { // enum name 3785 0, // Op_Node 3786 0, // Op_Set 3787 R0_num, // Op_RegN 3788 R0_num, // Op_RegI 3789 R0_num, // Op_RegP 3790 V0_num, // Op_RegF 3791 V0_num, // Op_RegD 3792 R0_num // Op_RegL 3793 }; 3794 3795 static const int hi[Op_RegL + 1] = { // enum name 3796 0, // Op_Node 3797 0, // Op_Set 3798 OptoReg::Bad, // Op_RegN 3799 OptoReg::Bad, // Op_RegI 3800 R0_H_num, // Op_RegP 3801 OptoReg::Bad, // Op_RegF 3802 V0_H_num, // Op_RegD 3803 R0_H_num // Op_RegL 3804 }; 3805 3806 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3807 %} 3808 %} 3809 3810 //----------ATTRIBUTES--------------------------------------------------------- 3811 //----------Operand Attributes------------------------------------------------- 3812 op_attrib op_cost(1); // Required cost attribute 3813 3814 //----------Instruction Attributes--------------------------------------------- 3815 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3816 ins_attrib ins_size(32); // Required size attribute (in bits) 3817 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3818 // a non-matching short branch variant 3819 // of some long branch? 3820 ins_attrib ins_alignment(4); // Required alignment attribute (must 3821 // be a power of 2) specifies the 3822 // alignment that some part of the 3823 // instruction (not necessarily the 3824 // start) requires. If > 1, a 3825 // compute_padding() function must be 3826 // provided for the instruction 3827 3828 //----------OPERANDS----------------------------------------------------------- 3829 // Operand definitions must precede instruction definitions for correct parsing 3830 // in the ADLC because operands constitute user defined types which are used in 3831 // instruction definitions. 3832 3833 //----------Simple Operands---------------------------------------------------- 3834 3835 // Integer operands 32 bit 3836 // 32 bit immediate 3837 operand immI() 3838 %{ 3839 match(ConI); 3840 3841 op_cost(0); 3842 format %{ %} 3843 interface(CONST_INTER); 3844 %} 3845 3846 // 32 bit zero 3847 operand immI0() 3848 %{ 3849 predicate(n->get_int() == 0); 3850 match(ConI); 3851 3852 op_cost(0); 3853 format %{ %} 3854 interface(CONST_INTER); 3855 %} 3856 3857 // 32 bit unit increment 3858 operand immI_1() 3859 %{ 3860 predicate(n->get_int() == 1); 3861 match(ConI); 3862 3863 op_cost(0); 3864 format %{ %} 3865 interface(CONST_INTER); 3866 %} 3867 3868 // 32 bit unit decrement 3869 operand immI_M1() 3870 %{ 3871 predicate(n->get_int() == -1); 3872 match(ConI); 3873 3874 op_cost(0); 3875 format %{ %} 3876 interface(CONST_INTER); 3877 %} 3878 3879 // Shift values for add/sub extension shift 3880 operand immIExt() 3881 %{ 3882 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3883 match(ConI); 3884 3885 op_cost(0); 3886 format %{ %} 3887 interface(CONST_INTER); 3888 %} 3889 3890 operand immI_le_4() 3891 %{ 3892 predicate(n->get_int() <= 4); 3893 match(ConI); 3894 3895 op_cost(0); 3896 format %{ %} 3897 interface(CONST_INTER); 3898 %} 3899 3900 operand immI_31() 3901 %{ 3902 predicate(n->get_int() == 31); 3903 match(ConI); 3904 3905 op_cost(0); 3906 format %{ %} 3907 interface(CONST_INTER); 3908 %} 3909 3910 operand immI_8() 3911 %{ 3912 predicate(n->get_int() == 8); 3913 match(ConI); 3914 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918 %} 3919 3920 operand immI_16() 3921 %{ 3922 predicate(n->get_int() == 16); 3923 match(ConI); 3924 3925 op_cost(0); 3926 format %{ %} 3927 interface(CONST_INTER); 3928 %} 3929 3930 operand immI_24() 3931 %{ 3932 predicate(n->get_int() == 24); 3933 match(ConI); 3934 3935 op_cost(0); 3936 format %{ %} 3937 interface(CONST_INTER); 3938 %} 3939 3940 operand immI_32() 3941 %{ 3942 predicate(n->get_int() == 32); 3943 match(ConI); 3944 3945 op_cost(0); 3946 format %{ %} 3947 interface(CONST_INTER); 3948 %} 3949 3950 operand immI_48() 3951 %{ 3952 predicate(n->get_int() == 48); 3953 match(ConI); 3954 3955 op_cost(0); 3956 format %{ %} 3957 interface(CONST_INTER); 3958 %} 3959 3960 operand immI_56() 3961 %{ 3962 predicate(n->get_int() == 56); 3963 match(ConI); 3964 3965 op_cost(0); 3966 format %{ %} 3967 interface(CONST_INTER); 3968 %} 3969 3970 operand immI_63() 3971 %{ 3972 predicate(n->get_int() == 63); 3973 match(ConI); 3974 3975 op_cost(0); 3976 format %{ %} 3977 interface(CONST_INTER); 3978 %} 3979 3980 operand immI_64() 3981 %{ 3982 predicate(n->get_int() == 64); 3983 match(ConI); 3984 3985 op_cost(0); 3986 format %{ %} 3987 interface(CONST_INTER); 3988 %} 3989 3990 operand immI_255() 3991 %{ 3992 predicate(n->get_int() == 255); 3993 match(ConI); 3994 3995 op_cost(0); 3996 format %{ %} 3997 interface(CONST_INTER); 3998 %} 3999 4000 operand immI_65535() 4001 %{ 4002 predicate(n->get_int() == 65535); 4003 match(ConI); 4004 4005 op_cost(0); 4006 format %{ %} 4007 interface(CONST_INTER); 4008 %} 4009 4010 operand immL_255() 4011 %{ 4012 predicate(n->get_long() == 255L); 4013 match(ConL); 4014 4015 op_cost(0); 4016 format %{ %} 4017 interface(CONST_INTER); 4018 %} 4019 4020 operand immL_65535() 4021 %{ 4022 predicate(n->get_long() == 65535L); 4023 match(ConL); 4024 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 operand immL_4294967295() 4031 %{ 4032 predicate(n->get_long() == 4294967295L); 4033 match(ConL); 4034 4035 op_cost(0); 4036 format %{ %} 4037 interface(CONST_INTER); 4038 %} 4039 4040 operand immL_bitmask() 4041 %{ 4042 predicate((n->get_long() != 0) 4043 && ((n->get_long() & 0xc000000000000000l) == 0) 4044 && is_power_of_2(n->get_long() + 1)); 4045 match(ConL); 4046 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 operand immI_bitmask() 4053 %{ 4054 predicate((n->get_int() != 0) 4055 && ((n->get_int() & 0xc0000000) == 0) 4056 && is_power_of_2(n->get_int() + 1)); 4057 match(ConI); 4058 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 operand immL_positive_bitmaskI() 4065 %{ 4066 predicate((n->get_long() != 0) 4067 && ((julong)n->get_long() < 0x80000000ULL) 4068 && is_power_of_2(n->get_long() + 1)); 4069 match(ConL); 4070 4071 op_cost(0); 4072 format %{ %} 4073 interface(CONST_INTER); 4074 %} 4075 4076 // Scale values for scaled offset addressing modes (up to long but not quad) 4077 operand immIScale() 4078 %{ 4079 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4080 match(ConI); 4081 4082 op_cost(0); 4083 format %{ %} 4084 interface(CONST_INTER); 4085 %} 4086 4087 // 26 bit signed offset -- for pc-relative branches 4088 operand immI26() 4089 %{ 4090 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4091 match(ConI); 4092 4093 op_cost(0); 4094 format %{ %} 4095 interface(CONST_INTER); 4096 %} 4097 4098 // 19 bit signed offset -- for pc-relative loads 4099 operand immI19() 4100 %{ 4101 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4102 match(ConI); 4103 4104 op_cost(0); 4105 format %{ %} 4106 interface(CONST_INTER); 4107 %} 4108 4109 // 12 bit unsigned offset -- for base plus immediate loads 4110 operand immIU12() 4111 %{ 4112 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4113 match(ConI); 4114 4115 op_cost(0); 4116 format %{ %} 4117 interface(CONST_INTER); 4118 %} 4119 4120 operand immLU12() 4121 %{ 4122 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4123 match(ConL); 4124 4125 op_cost(0); 4126 format %{ %} 4127 interface(CONST_INTER); 4128 %} 4129 4130 // Offset for scaled or unscaled immediate loads and stores 4131 operand immIOffset() 4132 %{ 4133 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4134 match(ConI); 4135 4136 op_cost(0); 4137 format %{ %} 4138 interface(CONST_INTER); 4139 %} 4140 4141 operand immIOffset1() 4142 %{ 4143 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4144 match(ConI); 4145 4146 op_cost(0); 4147 format %{ %} 4148 interface(CONST_INTER); 4149 %} 4150 4151 operand immIOffset2() 4152 %{ 4153 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4154 match(ConI); 4155 4156 op_cost(0); 4157 format %{ %} 4158 interface(CONST_INTER); 4159 %} 4160 4161 operand immIOffset4() 4162 %{ 4163 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4164 match(ConI); 4165 4166 op_cost(0); 4167 format %{ %} 4168 interface(CONST_INTER); 4169 %} 4170 4171 operand immIOffset8() 4172 %{ 4173 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4174 match(ConI); 4175 4176 op_cost(0); 4177 format %{ %} 4178 interface(CONST_INTER); 4179 %} 4180 4181 operand immIOffset16() 4182 %{ 4183 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4184 match(ConI); 4185 4186 op_cost(0); 4187 format %{ %} 4188 interface(CONST_INTER); 4189 %} 4190 4191 operand immLoffset() 4192 %{ 4193 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4194 match(ConL); 4195 4196 op_cost(0); 4197 format %{ %} 4198 interface(CONST_INTER); 4199 %} 4200 4201 operand immLoffset1() 4202 %{ 4203 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4204 match(ConL); 4205 4206 op_cost(0); 4207 format %{ %} 4208 interface(CONST_INTER); 4209 %} 4210 4211 operand immLoffset2() 4212 %{ 4213 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4214 match(ConL); 4215 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219 %} 4220 4221 operand immLoffset4() 4222 %{ 4223 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4224 match(ConL); 4225 4226 op_cost(0); 4227 format %{ %} 4228 interface(CONST_INTER); 4229 %} 4230 4231 operand immLoffset8() 4232 %{ 4233 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4234 match(ConL); 4235 4236 op_cost(0); 4237 format %{ %} 4238 interface(CONST_INTER); 4239 %} 4240 4241 operand immLoffset16() 4242 %{ 4243 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4244 match(ConL); 4245 4246 op_cost(0); 4247 format %{ %} 4248 interface(CONST_INTER); 4249 %} 4250 4251 // 32 bit integer valid for add sub immediate 4252 operand immIAddSub() 4253 %{ 4254 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4255 match(ConI); 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 // 32 bit unsigned integer valid for logical immediate 4262 // TODO -- check this is right when e.g the mask is 0x80000000 4263 operand immILog() 4264 %{ 4265 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4266 match(ConI); 4267 4268 op_cost(0); 4269 format %{ %} 4270 interface(CONST_INTER); 4271 %} 4272 4273 // Integer operands 64 bit 4274 // 64 bit immediate 4275 operand immL() 4276 %{ 4277 match(ConL); 4278 4279 op_cost(0); 4280 format %{ %} 4281 interface(CONST_INTER); 4282 %} 4283 4284 // 64 bit zero 4285 operand immL0() 4286 %{ 4287 predicate(n->get_long() == 0); 4288 match(ConL); 4289 4290 op_cost(0); 4291 format %{ %} 4292 interface(CONST_INTER); 4293 %} 4294 4295 // 64 bit unit increment 4296 operand immL_1() 4297 %{ 4298 predicate(n->get_long() == 1); 4299 match(ConL); 4300 4301 op_cost(0); 4302 format %{ %} 4303 interface(CONST_INTER); 4304 %} 4305 4306 // 64 bit unit decrement 4307 operand immL_M1() 4308 %{ 4309 predicate(n->get_long() == -1); 4310 match(ConL); 4311 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // 32 bit offset of pc in thread anchor 4318 4319 operand immL_pc_off() 4320 %{ 4321 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4322 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4323 match(ConL); 4324 4325 op_cost(0); 4326 format %{ %} 4327 interface(CONST_INTER); 4328 %} 4329 4330 // 64 bit integer valid for add sub immediate 4331 operand immLAddSub() 4332 %{ 4333 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4334 match(ConL); 4335 op_cost(0); 4336 format %{ %} 4337 interface(CONST_INTER); 4338 %} 4339 4340 // 64 bit integer valid for logical immediate 4341 operand immLLog() 4342 %{ 4343 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4344 match(ConL); 4345 op_cost(0); 4346 format %{ %} 4347 interface(CONST_INTER); 4348 %} 4349 4350 // Long Immediate: low 32-bit mask 4351 operand immL_32bits() 4352 %{ 4353 predicate(n->get_long() == 0xFFFFFFFFL); 4354 match(ConL); 4355 op_cost(0); 4356 format %{ %} 4357 interface(CONST_INTER); 4358 %} 4359 4360 // Pointer operands 4361 // Pointer Immediate 4362 operand immP() 4363 %{ 4364 match(ConP); 4365 4366 op_cost(0); 4367 format %{ %} 4368 interface(CONST_INTER); 4369 %} 4370 4371 // NULL Pointer Immediate 4372 operand immP0() 4373 %{ 4374 predicate(n->get_ptr() == 0); 4375 match(ConP); 4376 4377 op_cost(0); 4378 format %{ %} 4379 interface(CONST_INTER); 4380 %} 4381 4382 // Pointer Immediate One 4383 // this is used in object initialization (initial object header) 4384 operand immP_1() 4385 %{ 4386 predicate(n->get_ptr() == 1); 4387 match(ConP); 4388 4389 op_cost(0); 4390 format %{ %} 4391 interface(CONST_INTER); 4392 %} 4393 4394 // Card Table Byte Map Base 4395 operand immByteMapBase() 4396 %{ 4397 // Get base of card map 4398 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4399 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4400 match(ConP); 4401 4402 op_cost(0); 4403 format %{ %} 4404 interface(CONST_INTER); 4405 %} 4406 4407 // Pointer Immediate Minus One 4408 // this is used when we want to write the current PC to the thread anchor 4409 operand immP_M1() 4410 %{ 4411 predicate(n->get_ptr() == -1); 4412 match(ConP); 4413 4414 op_cost(0); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 // Pointer Immediate Minus Two 4420 // this is used when we want to write the current PC to the thread anchor 4421 operand immP_M2() 4422 %{ 4423 predicate(n->get_ptr() == -2); 4424 match(ConP); 4425 4426 op_cost(0); 4427 format %{ %} 4428 interface(CONST_INTER); 4429 %} 4430 4431 // Float and Double operands 4432 // Double Immediate 4433 operand immD() 4434 %{ 4435 match(ConD); 4436 op_cost(0); 4437 format %{ %} 4438 interface(CONST_INTER); 4439 %} 4440 4441 // Double Immediate: +0.0d 4442 operand immD0() 4443 %{ 4444 predicate(jlong_cast(n->getd()) == 0); 4445 match(ConD); 4446 4447 op_cost(0); 4448 format %{ %} 4449 interface(CONST_INTER); 4450 %} 4451 4452 // constant 'double +0.0'. 4453 operand immDPacked() 4454 %{ 4455 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4456 match(ConD); 4457 op_cost(0); 4458 format %{ %} 4459 interface(CONST_INTER); 4460 %} 4461 4462 // Float Immediate 4463 operand immF() 4464 %{ 4465 match(ConF); 4466 op_cost(0); 4467 format %{ %} 4468 interface(CONST_INTER); 4469 %} 4470 4471 // Float Immediate: +0.0f. 4472 operand immF0() 4473 %{ 4474 predicate(jint_cast(n->getf()) == 0); 4475 match(ConF); 4476 4477 op_cost(0); 4478 format %{ %} 4479 interface(CONST_INTER); 4480 %} 4481 4482 // 4483 operand immFPacked() 4484 %{ 4485 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4486 match(ConF); 4487 op_cost(0); 4488 format %{ %} 4489 interface(CONST_INTER); 4490 %} 4491 4492 // Narrow pointer operands 4493 // Narrow Pointer Immediate 4494 operand immN() 4495 %{ 4496 match(ConN); 4497 4498 op_cost(0); 4499 format %{ %} 4500 interface(CONST_INTER); 4501 %} 4502 4503 // Narrow NULL Pointer Immediate 4504 operand immN0() 4505 %{ 4506 predicate(n->get_narrowcon() == 0); 4507 match(ConN); 4508 4509 op_cost(0); 4510 format %{ %} 4511 interface(CONST_INTER); 4512 %} 4513 4514 operand immNKlass() 4515 %{ 4516 match(ConNKlass); 4517 4518 op_cost(0); 4519 format %{ %} 4520 interface(CONST_INTER); 4521 %} 4522 4523 // Integer 32 bit Register Operands 4524 // Integer 32 bitRegister (excludes SP) 4525 operand iRegI() 4526 %{ 4527 constraint(ALLOC_IN_RC(any_reg32)); 4528 match(RegI); 4529 match(iRegINoSp); 4530 op_cost(0); 4531 format %{ %} 4532 interface(REG_INTER); 4533 %} 4534 4535 // Integer 32 bit Register not Special 4536 operand iRegINoSp() 4537 %{ 4538 constraint(ALLOC_IN_RC(no_special_reg32)); 4539 match(RegI); 4540 op_cost(0); 4541 format %{ %} 4542 interface(REG_INTER); 4543 %} 4544 4545 // Integer 64 bit Register Operands 4546 // Integer 64 bit Register (includes SP) 4547 operand iRegL() 4548 %{ 4549 constraint(ALLOC_IN_RC(any_reg)); 4550 match(RegL); 4551 match(iRegLNoSp); 4552 op_cost(0); 4553 format %{ %} 4554 interface(REG_INTER); 4555 %} 4556 4557 // Integer 64 bit Register not Special 4558 operand iRegLNoSp() 4559 %{ 4560 constraint(ALLOC_IN_RC(no_special_reg)); 4561 match(RegL); 4562 match(iRegL_R0); 4563 format %{ %} 4564 interface(REG_INTER); 4565 %} 4566 4567 // Pointer Register Operands 4568 // Pointer Register 4569 operand iRegP() 4570 %{ 4571 constraint(ALLOC_IN_RC(ptr_reg)); 4572 match(RegP); 4573 match(iRegPNoSp); 4574 match(iRegP_R0); 4575 //match(iRegP_R2); 4576 //match(iRegP_R4); 4577 //match(iRegP_R5); 4578 match(thread_RegP); 4579 op_cost(0); 4580 format %{ %} 4581 interface(REG_INTER); 4582 %} 4583 4584 // Pointer 64 bit Register not Special 4585 operand iRegPNoSp() 4586 %{ 4587 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4588 match(RegP); 4589 // match(iRegP); 4590 // match(iRegP_R0); 4591 // match(iRegP_R2); 4592 // match(iRegP_R4); 4593 // match(iRegP_R5); 4594 // match(thread_RegP); 4595 op_cost(0); 4596 format %{ %} 4597 interface(REG_INTER); 4598 %} 4599 4600 // Pointer 64 bit Register R0 only 4601 operand iRegP_R0() 4602 %{ 4603 constraint(ALLOC_IN_RC(r0_reg)); 4604 match(RegP); 4605 // match(iRegP); 4606 match(iRegPNoSp); 4607 op_cost(0); 4608 format %{ %} 4609 interface(REG_INTER); 4610 %} 4611 4612 // Pointer 64 bit Register R1 only 4613 operand iRegP_R1() 4614 %{ 4615 constraint(ALLOC_IN_RC(r1_reg)); 4616 match(RegP); 4617 // match(iRegP); 4618 match(iRegPNoSp); 4619 op_cost(0); 4620 format %{ %} 4621 interface(REG_INTER); 4622 %} 4623 4624 // Pointer 64 bit Register R2 only 4625 operand iRegP_R2() 4626 %{ 4627 constraint(ALLOC_IN_RC(r2_reg)); 4628 match(RegP); 4629 // match(iRegP); 4630 match(iRegPNoSp); 4631 op_cost(0); 4632 format %{ %} 4633 interface(REG_INTER); 4634 %} 4635 4636 // Pointer 64 bit Register R3 only 4637 operand iRegP_R3() 4638 %{ 4639 constraint(ALLOC_IN_RC(r3_reg)); 4640 match(RegP); 4641 // match(iRegP); 4642 match(iRegPNoSp); 4643 op_cost(0); 4644 format %{ %} 4645 interface(REG_INTER); 4646 %} 4647 4648 // Pointer 64 bit Register R4 only 4649 operand iRegP_R4() 4650 %{ 4651 constraint(ALLOC_IN_RC(r4_reg)); 4652 match(RegP); 4653 // match(iRegP); 4654 match(iRegPNoSp); 4655 op_cost(0); 4656 format %{ %} 4657 interface(REG_INTER); 4658 %} 4659 4660 // Pointer 64 bit Register R5 only 4661 operand iRegP_R5() 4662 %{ 4663 constraint(ALLOC_IN_RC(r5_reg)); 4664 match(RegP); 4665 // match(iRegP); 4666 match(iRegPNoSp); 4667 op_cost(0); 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 // Pointer 64 bit Register R10 only 4673 operand iRegP_R10() 4674 %{ 4675 constraint(ALLOC_IN_RC(r10_reg)); 4676 match(RegP); 4677 // match(iRegP); 4678 match(iRegPNoSp); 4679 op_cost(0); 4680 format %{ %} 4681 interface(REG_INTER); 4682 %} 4683 4684 // Long 64 bit Register R0 only 4685 operand iRegL_R0() 4686 %{ 4687 constraint(ALLOC_IN_RC(r0_reg)); 4688 match(RegL); 4689 match(iRegLNoSp); 4690 op_cost(0); 4691 format %{ %} 4692 interface(REG_INTER); 4693 %} 4694 4695 // Long 64 bit Register R2 only 4696 operand iRegL_R2() 4697 %{ 4698 constraint(ALLOC_IN_RC(r2_reg)); 4699 match(RegL); 4700 match(iRegLNoSp); 4701 op_cost(0); 4702 format %{ %} 4703 interface(REG_INTER); 4704 %} 4705 4706 // Long 64 bit Register R3 only 4707 operand iRegL_R3() 4708 %{ 4709 constraint(ALLOC_IN_RC(r3_reg)); 4710 match(RegL); 4711 match(iRegLNoSp); 4712 op_cost(0); 4713 format %{ %} 4714 interface(REG_INTER); 4715 %} 4716 4717 // Long 64 bit Register R11 only 4718 operand iRegL_R11() 4719 %{ 4720 constraint(ALLOC_IN_RC(r11_reg)); 4721 match(RegL); 4722 match(iRegLNoSp); 4723 op_cost(0); 4724 format %{ %} 4725 interface(REG_INTER); 4726 %} 4727 4728 // Pointer 64 bit Register FP only 4729 operand iRegP_FP() 4730 %{ 4731 constraint(ALLOC_IN_RC(fp_reg)); 4732 match(RegP); 4733 // match(iRegP); 4734 op_cost(0); 4735 format %{ %} 4736 interface(REG_INTER); 4737 %} 4738 4739 // Register R0 only 4740 operand iRegI_R0() 4741 %{ 4742 constraint(ALLOC_IN_RC(int_r0_reg)); 4743 match(RegI); 4744 match(iRegINoSp); 4745 op_cost(0); 4746 format %{ %} 4747 interface(REG_INTER); 4748 %} 4749 4750 // Register R2 only 4751 operand iRegI_R2() 4752 %{ 4753 constraint(ALLOC_IN_RC(int_r2_reg)); 4754 match(RegI); 4755 match(iRegINoSp); 4756 op_cost(0); 4757 format %{ %} 4758 interface(REG_INTER); 4759 %} 4760 4761 // Register R3 only 4762 operand iRegI_R3() 4763 %{ 4764 constraint(ALLOC_IN_RC(int_r3_reg)); 4765 match(RegI); 4766 match(iRegINoSp); 4767 op_cost(0); 4768 format %{ %} 4769 interface(REG_INTER); 4770 %} 4771 4772 4773 // Register R4 only 4774 operand iRegI_R4() 4775 %{ 4776 constraint(ALLOC_IN_RC(int_r4_reg)); 4777 match(RegI); 4778 match(iRegINoSp); 4779 op_cost(0); 4780 format %{ %} 4781 interface(REG_INTER); 4782 %} 4783 4784 4785 // Pointer Register Operands 4786 // Narrow Pointer Register 4787 operand iRegN() 4788 %{ 4789 constraint(ALLOC_IN_RC(any_reg32)); 4790 match(RegN); 4791 match(iRegNNoSp); 4792 op_cost(0); 4793 format %{ %} 4794 interface(REG_INTER); 4795 %} 4796 4797 operand iRegN_R0() 4798 %{ 4799 constraint(ALLOC_IN_RC(r0_reg)); 4800 match(iRegN); 4801 op_cost(0); 4802 format %{ %} 4803 interface(REG_INTER); 4804 %} 4805 4806 operand iRegN_R2() 4807 %{ 4808 constraint(ALLOC_IN_RC(r2_reg)); 4809 match(iRegN); 4810 op_cost(0); 4811 format %{ %} 4812 interface(REG_INTER); 4813 %} 4814 4815 operand iRegN_R3() 4816 %{ 4817 constraint(ALLOC_IN_RC(r3_reg)); 4818 match(iRegN); 4819 op_cost(0); 4820 format %{ %} 4821 interface(REG_INTER); 4822 %} 4823 4824 // Integer 64 bit Register not Special 4825 operand iRegNNoSp() 4826 %{ 4827 constraint(ALLOC_IN_RC(no_special_reg32)); 4828 match(RegN); 4829 op_cost(0); 4830 format %{ %} 4831 interface(REG_INTER); 4832 %} 4833 4834 // heap base register -- used for encoding immN0 4835 4836 operand iRegIHeapbase() 4837 %{ 4838 constraint(ALLOC_IN_RC(heapbase_reg)); 4839 match(RegI); 4840 op_cost(0); 4841 format %{ %} 4842 interface(REG_INTER); 4843 %} 4844 4845 // Float Register 4846 // Float register operands 4847 operand vRegF() 4848 %{ 4849 constraint(ALLOC_IN_RC(float_reg)); 4850 match(RegF); 4851 4852 op_cost(0); 4853 format %{ %} 4854 interface(REG_INTER); 4855 %} 4856 4857 // Double Register 4858 // Double register operands 4859 operand vRegD() 4860 %{ 4861 constraint(ALLOC_IN_RC(double_reg)); 4862 match(RegD); 4863 4864 op_cost(0); 4865 format %{ %} 4866 interface(REG_INTER); 4867 %} 4868 4869 operand vecD() 4870 %{ 4871 constraint(ALLOC_IN_RC(vectord_reg)); 4872 match(VecD); 4873 4874 op_cost(0); 4875 format %{ %} 4876 interface(REG_INTER); 4877 %} 4878 4879 operand vecX() 4880 %{ 4881 constraint(ALLOC_IN_RC(vectorx_reg)); 4882 match(VecX); 4883 4884 op_cost(0); 4885 format %{ %} 4886 interface(REG_INTER); 4887 %} 4888 4889 operand vRegD_V0() 4890 %{ 4891 constraint(ALLOC_IN_RC(v0_reg)); 4892 match(RegD); 4893 op_cost(0); 4894 format %{ %} 4895 interface(REG_INTER); 4896 %} 4897 4898 operand vRegD_V1() 4899 %{ 4900 constraint(ALLOC_IN_RC(v1_reg)); 4901 match(RegD); 4902 op_cost(0); 4903 format %{ %} 4904 interface(REG_INTER); 4905 %} 4906 4907 operand vRegD_V2() 4908 %{ 4909 constraint(ALLOC_IN_RC(v2_reg)); 4910 match(RegD); 4911 op_cost(0); 4912 format %{ %} 4913 interface(REG_INTER); 4914 %} 4915 4916 operand vRegD_V3() 4917 %{ 4918 constraint(ALLOC_IN_RC(v3_reg)); 4919 match(RegD); 4920 op_cost(0); 4921 format %{ %} 4922 interface(REG_INTER); 4923 %} 4924 4925 operand vRegD_V4() 4926 %{ 4927 constraint(ALLOC_IN_RC(v4_reg)); 4928 match(RegD); 4929 op_cost(0); 4930 format %{ %} 4931 interface(REG_INTER); 4932 %} 4933 4934 operand vRegD_V5() 4935 %{ 4936 constraint(ALLOC_IN_RC(v5_reg)); 4937 match(RegD); 4938 op_cost(0); 4939 format %{ %} 4940 interface(REG_INTER); 4941 %} 4942 4943 operand vRegD_V6() 4944 %{ 4945 constraint(ALLOC_IN_RC(v6_reg)); 4946 match(RegD); 4947 op_cost(0); 4948 format %{ %} 4949 interface(REG_INTER); 4950 %} 4951 4952 operand vRegD_V7() 4953 %{ 4954 constraint(ALLOC_IN_RC(v7_reg)); 4955 match(RegD); 4956 op_cost(0); 4957 format %{ %} 4958 interface(REG_INTER); 4959 %} 4960 4961 operand vRegD_V8() 4962 %{ 4963 constraint(ALLOC_IN_RC(v8_reg)); 4964 match(RegD); 4965 op_cost(0); 4966 format %{ %} 4967 interface(REG_INTER); 4968 %} 4969 4970 operand vRegD_V9() 4971 %{ 4972 constraint(ALLOC_IN_RC(v9_reg)); 4973 match(RegD); 4974 op_cost(0); 4975 format %{ %} 4976 interface(REG_INTER); 4977 %} 4978 4979 operand vRegD_V10() 4980 %{ 4981 constraint(ALLOC_IN_RC(v10_reg)); 4982 match(RegD); 4983 op_cost(0); 4984 format %{ %} 4985 interface(REG_INTER); 4986 %} 4987 4988 operand vRegD_V11() 4989 %{ 4990 constraint(ALLOC_IN_RC(v11_reg)); 4991 match(RegD); 4992 op_cost(0); 4993 format %{ %} 4994 interface(REG_INTER); 4995 %} 4996 4997 operand vRegD_V12() 4998 %{ 4999 constraint(ALLOC_IN_RC(v12_reg)); 5000 match(RegD); 5001 op_cost(0); 5002 format %{ %} 5003 interface(REG_INTER); 5004 %} 5005 5006 operand vRegD_V13() 5007 %{ 5008 constraint(ALLOC_IN_RC(v13_reg)); 5009 match(RegD); 5010 op_cost(0); 5011 format %{ %} 5012 interface(REG_INTER); 5013 %} 5014 5015 operand vRegD_V14() 5016 %{ 5017 constraint(ALLOC_IN_RC(v14_reg)); 5018 match(RegD); 5019 op_cost(0); 5020 format %{ %} 5021 interface(REG_INTER); 5022 %} 5023 5024 operand vRegD_V15() 5025 %{ 5026 constraint(ALLOC_IN_RC(v15_reg)); 5027 match(RegD); 5028 op_cost(0); 5029 format %{ %} 5030 interface(REG_INTER); 5031 %} 5032 5033 operand vRegD_V16() 5034 %{ 5035 constraint(ALLOC_IN_RC(v16_reg)); 5036 match(RegD); 5037 op_cost(0); 5038 format %{ %} 5039 interface(REG_INTER); 5040 %} 5041 5042 operand vRegD_V17() 5043 %{ 5044 constraint(ALLOC_IN_RC(v17_reg)); 5045 match(RegD); 5046 op_cost(0); 5047 format %{ %} 5048 interface(REG_INTER); 5049 %} 5050 5051 operand vRegD_V18() 5052 %{ 5053 constraint(ALLOC_IN_RC(v18_reg)); 5054 match(RegD); 5055 op_cost(0); 5056 format %{ %} 5057 interface(REG_INTER); 5058 %} 5059 5060 operand vRegD_V19() 5061 %{ 5062 constraint(ALLOC_IN_RC(v19_reg)); 5063 match(RegD); 5064 op_cost(0); 5065 format %{ %} 5066 interface(REG_INTER); 5067 %} 5068 5069 operand vRegD_V20() 5070 %{ 5071 constraint(ALLOC_IN_RC(v20_reg)); 5072 match(RegD); 5073 op_cost(0); 5074 format %{ %} 5075 interface(REG_INTER); 5076 %} 5077 5078 operand vRegD_V21() 5079 %{ 5080 constraint(ALLOC_IN_RC(v21_reg)); 5081 match(RegD); 5082 op_cost(0); 5083 format %{ %} 5084 interface(REG_INTER); 5085 %} 5086 5087 operand vRegD_V22() 5088 %{ 5089 constraint(ALLOC_IN_RC(v22_reg)); 5090 match(RegD); 5091 op_cost(0); 5092 format %{ %} 5093 interface(REG_INTER); 5094 %} 5095 5096 operand vRegD_V23() 5097 %{ 5098 constraint(ALLOC_IN_RC(v23_reg)); 5099 match(RegD); 5100 op_cost(0); 5101 format %{ %} 5102 interface(REG_INTER); 5103 %} 5104 5105 operand vRegD_V24() 5106 %{ 5107 constraint(ALLOC_IN_RC(v24_reg)); 5108 match(RegD); 5109 op_cost(0); 5110 format %{ %} 5111 interface(REG_INTER); 5112 %} 5113 5114 operand vRegD_V25() 5115 %{ 5116 constraint(ALLOC_IN_RC(v25_reg)); 5117 match(RegD); 5118 op_cost(0); 5119 format %{ %} 5120 interface(REG_INTER); 5121 %} 5122 5123 operand vRegD_V26() 5124 %{ 5125 constraint(ALLOC_IN_RC(v26_reg)); 5126 match(RegD); 5127 op_cost(0); 5128 format %{ %} 5129 interface(REG_INTER); 5130 %} 5131 5132 operand vRegD_V27() 5133 %{ 5134 constraint(ALLOC_IN_RC(v27_reg)); 5135 match(RegD); 5136 op_cost(0); 5137 format %{ %} 5138 interface(REG_INTER); 5139 %} 5140 5141 operand vRegD_V28() 5142 %{ 5143 constraint(ALLOC_IN_RC(v28_reg)); 5144 match(RegD); 5145 op_cost(0); 5146 format %{ %} 5147 interface(REG_INTER); 5148 %} 5149 5150 operand vRegD_V29() 5151 %{ 5152 constraint(ALLOC_IN_RC(v29_reg)); 5153 match(RegD); 5154 op_cost(0); 5155 format %{ %} 5156 interface(REG_INTER); 5157 %} 5158 5159 operand vRegD_V30() 5160 %{ 5161 constraint(ALLOC_IN_RC(v30_reg)); 5162 match(RegD); 5163 op_cost(0); 5164 format %{ %} 5165 interface(REG_INTER); 5166 %} 5167 5168 operand vRegD_V31() 5169 %{ 5170 constraint(ALLOC_IN_RC(v31_reg)); 5171 match(RegD); 5172 op_cost(0); 5173 format %{ %} 5174 interface(REG_INTER); 5175 %} 5176 5177 // Flags register, used as output of signed compare instructions 5178 5179 // note that on AArch64 we also use this register as the output for 5180 // for floating point compare instructions (CmpF CmpD). this ensures 5181 // that ordered inequality tests use GT, GE, LT or LE none of which 5182 // pass through cases where the result is unordered i.e. one or both 5183 // inputs to the compare is a NaN. this means that the ideal code can 5184 // replace e.g. a GT with an LE and not end up capturing the NaN case 5185 // (where the comparison should always fail). EQ and NE tests are 5186 // always generated in ideal code so that unordered folds into the NE 5187 // case, matching the behaviour of AArch64 NE. 5188 // 5189 // This differs from x86 where the outputs of FP compares use a 5190 // special FP flags registers and where compares based on this 5191 // register are distinguished into ordered inequalities (cmpOpUCF) and 5192 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5193 // to explicitly handle the unordered case in branches. x86 also has 5194 // to include extra CMoveX rules to accept a cmpOpUCF input. 5195 5196 operand rFlagsReg() 5197 %{ 5198 constraint(ALLOC_IN_RC(int_flags)); 5199 match(RegFlags); 5200 5201 op_cost(0); 5202 format %{ "RFLAGS" %} 5203 interface(REG_INTER); 5204 %} 5205 5206 // Flags register, used as output of unsigned compare instructions 5207 operand rFlagsRegU() 5208 %{ 5209 constraint(ALLOC_IN_RC(int_flags)); 5210 match(RegFlags); 5211 5212 op_cost(0); 5213 format %{ "RFLAGSU" %} 5214 interface(REG_INTER); 5215 %} 5216 5217 // Special Registers 5218 5219 // Method Register 5220 operand inline_cache_RegP(iRegP reg) 5221 %{ 5222 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5223 match(reg); 5224 match(iRegPNoSp); 5225 op_cost(0); 5226 format %{ %} 5227 interface(REG_INTER); 5228 %} 5229 5230 operand interpreter_method_oop_RegP(iRegP reg) 5231 %{ 5232 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5233 match(reg); 5234 match(iRegPNoSp); 5235 op_cost(0); 5236 format %{ %} 5237 interface(REG_INTER); 5238 %} 5239 5240 // Thread Register 5241 operand thread_RegP(iRegP reg) 5242 %{ 5243 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5244 match(reg); 5245 op_cost(0); 5246 format %{ %} 5247 interface(REG_INTER); 5248 %} 5249 5250 operand lr_RegP(iRegP reg) 5251 %{ 5252 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5253 match(reg); 5254 op_cost(0); 5255 format %{ %} 5256 interface(REG_INTER); 5257 %} 5258 5259 //----------Memory Operands---------------------------------------------------- 5260 5261 operand indirect(iRegP reg) 5262 %{ 5263 constraint(ALLOC_IN_RC(ptr_reg)); 5264 match(reg); 5265 op_cost(0); 5266 format %{ "[$reg]" %} 5267 interface(MEMORY_INTER) %{ 5268 base($reg); 5269 index(0xffffffff); 5270 scale(0x0); 5271 disp(0x0); 5272 %} 5273 %} 5274 5275 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5276 %{ 5277 constraint(ALLOC_IN_RC(ptr_reg)); 5278 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5279 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5280 op_cost(0); 5281 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5282 interface(MEMORY_INTER) %{ 5283 base($reg); 5284 index($ireg); 5285 scale($scale); 5286 disp(0x0); 5287 %} 5288 %} 5289 5290 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5291 %{ 5292 constraint(ALLOC_IN_RC(ptr_reg)); 5293 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5294 match(AddP reg (LShiftL lreg scale)); 5295 op_cost(0); 5296 format %{ "$reg, $lreg lsl($scale)" %} 5297 interface(MEMORY_INTER) %{ 5298 base($reg); 5299 index($lreg); 5300 scale($scale); 5301 disp(0x0); 5302 %} 5303 %} 5304 5305 operand indIndexI2L(iRegP reg, iRegI ireg) 5306 %{ 5307 constraint(ALLOC_IN_RC(ptr_reg)); 5308 match(AddP reg (ConvI2L ireg)); 5309 op_cost(0); 5310 format %{ "$reg, $ireg, 0, I2L" %} 5311 interface(MEMORY_INTER) %{ 5312 base($reg); 5313 index($ireg); 5314 scale(0x0); 5315 disp(0x0); 5316 %} 5317 %} 5318 5319 operand indIndex(iRegP reg, iRegL lreg) 5320 %{ 5321 constraint(ALLOC_IN_RC(ptr_reg)); 5322 match(AddP reg lreg); 5323 op_cost(0); 5324 format %{ "$reg, $lreg" %} 5325 interface(MEMORY_INTER) %{ 5326 base($reg); 5327 index($lreg); 5328 scale(0x0); 5329 disp(0x0); 5330 %} 5331 %} 5332 5333 operand indOffI(iRegP reg, immIOffset off) 5334 %{ 5335 constraint(ALLOC_IN_RC(ptr_reg)); 5336 match(AddP reg off); 5337 op_cost(0); 5338 format %{ "[$reg, $off]" %} 5339 interface(MEMORY_INTER) %{ 5340 base($reg); 5341 index(0xffffffff); 5342 scale(0x0); 5343 disp($off); 5344 %} 5345 %} 5346 5347 operand indOffI1(iRegP reg, immIOffset1 off) 5348 %{ 5349 constraint(ALLOC_IN_RC(ptr_reg)); 5350 match(AddP reg off); 5351 op_cost(0); 5352 format %{ "[$reg, $off]" %} 5353 interface(MEMORY_INTER) %{ 5354 base($reg); 5355 index(0xffffffff); 5356 scale(0x0); 5357 disp($off); 5358 %} 5359 %} 5360 5361 operand indOffI2(iRegP reg, immIOffset2 off) 5362 %{ 5363 constraint(ALLOC_IN_RC(ptr_reg)); 5364 match(AddP reg off); 5365 op_cost(0); 5366 format %{ "[$reg, $off]" %} 5367 interface(MEMORY_INTER) %{ 5368 base($reg); 5369 index(0xffffffff); 5370 scale(0x0); 5371 disp($off); 5372 %} 5373 %} 5374 5375 operand indOffI4(iRegP reg, immIOffset4 off) 5376 %{ 5377 constraint(ALLOC_IN_RC(ptr_reg)); 5378 match(AddP reg off); 5379 op_cost(0); 5380 format %{ "[$reg, $off]" %} 5381 interface(MEMORY_INTER) %{ 5382 base($reg); 5383 index(0xffffffff); 5384 scale(0x0); 5385 disp($off); 5386 %} 5387 %} 5388 5389 operand indOffI8(iRegP reg, immIOffset8 off) 5390 %{ 5391 constraint(ALLOC_IN_RC(ptr_reg)); 5392 match(AddP reg off); 5393 op_cost(0); 5394 format %{ "[$reg, $off]" %} 5395 interface(MEMORY_INTER) %{ 5396 base($reg); 5397 index(0xffffffff); 5398 scale(0x0); 5399 disp($off); 5400 %} 5401 %} 5402 5403 operand indOffI16(iRegP reg, immIOffset16 off) 5404 %{ 5405 constraint(ALLOC_IN_RC(ptr_reg)); 5406 match(AddP reg off); 5407 op_cost(0); 5408 format %{ "[$reg, $off]" %} 5409 interface(MEMORY_INTER) %{ 5410 base($reg); 5411 index(0xffffffff); 5412 scale(0x0); 5413 disp($off); 5414 %} 5415 %} 5416 5417 operand indOffL(iRegP reg, immLoffset off) 5418 %{ 5419 constraint(ALLOC_IN_RC(ptr_reg)); 5420 match(AddP reg off); 5421 op_cost(0); 5422 format %{ "[$reg, $off]" %} 5423 interface(MEMORY_INTER) %{ 5424 base($reg); 5425 index(0xffffffff); 5426 scale(0x0); 5427 disp($off); 5428 %} 5429 %} 5430 5431 operand indOffL1(iRegP reg, immLoffset1 off) 5432 %{ 5433 constraint(ALLOC_IN_RC(ptr_reg)); 5434 match(AddP reg off); 5435 op_cost(0); 5436 format %{ "[$reg, $off]" %} 5437 interface(MEMORY_INTER) %{ 5438 base($reg); 5439 index(0xffffffff); 5440 scale(0x0); 5441 disp($off); 5442 %} 5443 %} 5444 5445 operand indOffL2(iRegP reg, immLoffset2 off) 5446 %{ 5447 constraint(ALLOC_IN_RC(ptr_reg)); 5448 match(AddP reg off); 5449 op_cost(0); 5450 format %{ "[$reg, $off]" %} 5451 interface(MEMORY_INTER) %{ 5452 base($reg); 5453 index(0xffffffff); 5454 scale(0x0); 5455 disp($off); 5456 %} 5457 %} 5458 5459 operand indOffL4(iRegP reg, immLoffset4 off) 5460 %{ 5461 constraint(ALLOC_IN_RC(ptr_reg)); 5462 match(AddP reg off); 5463 op_cost(0); 5464 format %{ "[$reg, $off]" %} 5465 interface(MEMORY_INTER) %{ 5466 base($reg); 5467 index(0xffffffff); 5468 scale(0x0); 5469 disp($off); 5470 %} 5471 %} 5472 5473 operand indOffL8(iRegP reg, immLoffset8 off) 5474 %{ 5475 constraint(ALLOC_IN_RC(ptr_reg)); 5476 match(AddP reg off); 5477 op_cost(0); 5478 format %{ "[$reg, $off]" %} 5479 interface(MEMORY_INTER) %{ 5480 base($reg); 5481 index(0xffffffff); 5482 scale(0x0); 5483 disp($off); 5484 %} 5485 %} 5486 5487 operand indOffL16(iRegP reg, immLoffset16 off) 5488 %{ 5489 constraint(ALLOC_IN_RC(ptr_reg)); 5490 match(AddP reg off); 5491 op_cost(0); 5492 format %{ "[$reg, $off]" %} 5493 interface(MEMORY_INTER) %{ 5494 base($reg); 5495 index(0xffffffff); 5496 scale(0x0); 5497 disp($off); 5498 %} 5499 %} 5500 5501 operand indirectN(iRegN reg) 5502 %{ 5503 predicate(CompressedOops::shift() == 0); 5504 constraint(ALLOC_IN_RC(ptr_reg)); 5505 match(DecodeN reg); 5506 op_cost(0); 5507 format %{ "[$reg]\t# narrow" %} 5508 interface(MEMORY_INTER) %{ 5509 base($reg); 5510 index(0xffffffff); 5511 scale(0x0); 5512 disp(0x0); 5513 %} 5514 %} 5515 5516 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5517 %{ 5518 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5519 constraint(ALLOC_IN_RC(ptr_reg)); 5520 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5521 op_cost(0); 5522 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5523 interface(MEMORY_INTER) %{ 5524 base($reg); 5525 index($ireg); 5526 scale($scale); 5527 disp(0x0); 5528 %} 5529 %} 5530 5531 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5532 %{ 5533 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5534 constraint(ALLOC_IN_RC(ptr_reg)); 5535 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5536 op_cost(0); 5537 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5538 interface(MEMORY_INTER) %{ 5539 base($reg); 5540 index($lreg); 5541 scale($scale); 5542 disp(0x0); 5543 %} 5544 %} 5545 5546 operand indIndexI2LN(iRegN reg, iRegI ireg) 5547 %{ 5548 predicate(CompressedOops::shift() == 0); 5549 constraint(ALLOC_IN_RC(ptr_reg)); 5550 match(AddP (DecodeN reg) (ConvI2L ireg)); 5551 op_cost(0); 5552 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5553 interface(MEMORY_INTER) %{ 5554 base($reg); 5555 index($ireg); 5556 scale(0x0); 5557 disp(0x0); 5558 %} 5559 %} 5560 5561 operand indIndexN(iRegN reg, iRegL lreg) 5562 %{ 5563 predicate(CompressedOops::shift() == 0); 5564 constraint(ALLOC_IN_RC(ptr_reg)); 5565 match(AddP (DecodeN reg) lreg); 5566 op_cost(0); 5567 format %{ "$reg, $lreg\t# narrow" %} 5568 interface(MEMORY_INTER) %{ 5569 base($reg); 5570 index($lreg); 5571 scale(0x0); 5572 disp(0x0); 5573 %} 5574 %} 5575 5576 operand indOffIN(iRegN reg, immIOffset off) 5577 %{ 5578 predicate(CompressedOops::shift() == 0); 5579 constraint(ALLOC_IN_RC(ptr_reg)); 5580 match(AddP (DecodeN reg) off); 5581 op_cost(0); 5582 format %{ "[$reg, $off]\t# narrow" %} 5583 interface(MEMORY_INTER) %{ 5584 base($reg); 5585 index(0xffffffff); 5586 scale(0x0); 5587 disp($off); 5588 %} 5589 %} 5590 5591 operand indOffLN(iRegN reg, immLoffset off) 5592 %{ 5593 predicate(CompressedOops::shift() == 0); 5594 constraint(ALLOC_IN_RC(ptr_reg)); 5595 match(AddP (DecodeN reg) off); 5596 op_cost(0); 5597 format %{ "[$reg, $off]\t# narrow" %} 5598 interface(MEMORY_INTER) %{ 5599 base($reg); 5600 index(0xffffffff); 5601 scale(0x0); 5602 disp($off); 5603 %} 5604 %} 5605 5606 5607 5608 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5609 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5610 %{ 5611 constraint(ALLOC_IN_RC(ptr_reg)); 5612 match(AddP reg off); 5613 op_cost(0); 5614 format %{ "[$reg, $off]" %} 5615 interface(MEMORY_INTER) %{ 5616 base($reg); 5617 index(0xffffffff); 5618 scale(0x0); 5619 disp($off); 5620 %} 5621 %} 5622 5623 //----------Special Memory Operands-------------------------------------------- 5624 // Stack Slot Operand - This operand is used for loading and storing temporary 5625 // values on the stack where a match requires a value to 5626 // flow through memory. 5627 operand stackSlotP(sRegP reg) 5628 %{ 5629 constraint(ALLOC_IN_RC(stack_slots)); 5630 op_cost(100); 5631 // No match rule because this operand is only generated in matching 5632 // match(RegP); 5633 format %{ "[$reg]" %} 5634 interface(MEMORY_INTER) %{ 5635 base(0x1e); // RSP 5636 index(0x0); // No Index 5637 scale(0x0); // No Scale 5638 disp($reg); // Stack Offset 5639 %} 5640 %} 5641 5642 operand stackSlotI(sRegI reg) 5643 %{ 5644 constraint(ALLOC_IN_RC(stack_slots)); 5645 // No match rule because this operand is only generated in matching 5646 // match(RegI); 5647 format %{ "[$reg]" %} 5648 interface(MEMORY_INTER) %{ 5649 base(0x1e); // RSP 5650 index(0x0); // No Index 5651 scale(0x0); // No Scale 5652 disp($reg); // Stack Offset 5653 %} 5654 %} 5655 5656 operand stackSlotF(sRegF reg) 5657 %{ 5658 constraint(ALLOC_IN_RC(stack_slots)); 5659 // No match rule because this operand is only generated in matching 5660 // match(RegF); 5661 format %{ "[$reg]" %} 5662 interface(MEMORY_INTER) %{ 5663 base(0x1e); // RSP 5664 index(0x0); // No Index 5665 scale(0x0); // No Scale 5666 disp($reg); // Stack Offset 5667 %} 5668 %} 5669 5670 operand stackSlotD(sRegD reg) 5671 %{ 5672 constraint(ALLOC_IN_RC(stack_slots)); 5673 // No match rule because this operand is only generated in matching 5674 // match(RegD); 5675 format %{ "[$reg]" %} 5676 interface(MEMORY_INTER) %{ 5677 base(0x1e); // RSP 5678 index(0x0); // No Index 5679 scale(0x0); // No Scale 5680 disp($reg); // Stack Offset 5681 %} 5682 %} 5683 5684 operand stackSlotL(sRegL reg) 5685 %{ 5686 constraint(ALLOC_IN_RC(stack_slots)); 5687 // No match rule because this operand is only generated in matching 5688 // match(RegL); 5689 format %{ "[$reg]" %} 5690 interface(MEMORY_INTER) %{ 5691 base(0x1e); // RSP 5692 index(0x0); // No Index 5693 scale(0x0); // No Scale 5694 disp($reg); // Stack Offset 5695 %} 5696 %} 5697 5698 // Operands for expressing Control Flow 5699 // NOTE: Label is a predefined operand which should not be redefined in 5700 // the AD file. It is generically handled within the ADLC. 5701 5702 //----------Conditional Branch Operands---------------------------------------- 5703 // Comparison Op - This is the operation of the comparison, and is limited to 5704 // the following set of codes: 5705 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5706 // 5707 // Other attributes of the comparison, such as unsignedness, are specified 5708 // by the comparison instruction that sets a condition code flags register. 5709 // That result is represented by a flags operand whose subtype is appropriate 5710 // to the unsignedness (etc.) of the comparison. 5711 // 5712 // Later, the instruction which matches both the Comparison Op (a Bool) and 5713 // the flags (produced by the Cmp) specifies the coding of the comparison op 5714 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5715 5716 // used for signed integral comparisons and fp comparisons 5717 5718 operand cmpOp() 5719 %{ 5720 match(Bool); 5721 5722 format %{ "" %} 5723 interface(COND_INTER) %{ 5724 equal(0x0, "eq"); 5725 not_equal(0x1, "ne"); 5726 less(0xb, "lt"); 5727 greater_equal(0xa, "ge"); 5728 less_equal(0xd, "le"); 5729 greater(0xc, "gt"); 5730 overflow(0x6, "vs"); 5731 no_overflow(0x7, "vc"); 5732 %} 5733 %} 5734 5735 // used for unsigned integral comparisons 5736 5737 operand cmpOpU() 5738 %{ 5739 match(Bool); 5740 5741 format %{ "" %} 5742 interface(COND_INTER) %{ 5743 equal(0x0, "eq"); 5744 not_equal(0x1, "ne"); 5745 less(0x3, "lo"); 5746 greater_equal(0x2, "hs"); 5747 less_equal(0x9, "ls"); 5748 greater(0x8, "hi"); 5749 overflow(0x6, "vs"); 5750 no_overflow(0x7, "vc"); 5751 %} 5752 %} 5753 5754 // used for certain integral comparisons which can be 5755 // converted to cbxx or tbxx instructions 5756 5757 operand cmpOpEqNe() 5758 %{ 5759 match(Bool); 5760 op_cost(0); 5761 predicate(n->as_Bool()->_test._test == BoolTest::ne 5762 || n->as_Bool()->_test._test == BoolTest::eq); 5763 5764 format %{ "" %} 5765 interface(COND_INTER) %{ 5766 equal(0x0, "eq"); 5767 not_equal(0x1, "ne"); 5768 less(0xb, "lt"); 5769 greater_equal(0xa, "ge"); 5770 less_equal(0xd, "le"); 5771 greater(0xc, "gt"); 5772 overflow(0x6, "vs"); 5773 no_overflow(0x7, "vc"); 5774 %} 5775 %} 5776 5777 // used for certain integral comparisons which can be 5778 // converted to cbxx or tbxx instructions 5779 5780 operand cmpOpLtGe() 5781 %{ 5782 match(Bool); 5783 op_cost(0); 5784 5785 predicate(n->as_Bool()->_test._test == BoolTest::lt 5786 || n->as_Bool()->_test._test == BoolTest::ge); 5787 5788 format %{ "" %} 5789 interface(COND_INTER) %{ 5790 equal(0x0, "eq"); 5791 not_equal(0x1, "ne"); 5792 less(0xb, "lt"); 5793 greater_equal(0xa, "ge"); 5794 less_equal(0xd, "le"); 5795 greater(0xc, "gt"); 5796 overflow(0x6, "vs"); 5797 no_overflow(0x7, "vc"); 5798 %} 5799 %} 5800 5801 // used for certain unsigned integral comparisons which can be 5802 // converted to cbxx or tbxx instructions 5803 5804 operand cmpOpUEqNeLtGe() 5805 %{ 5806 match(Bool); 5807 op_cost(0); 5808 5809 predicate(n->as_Bool()->_test._test == BoolTest::eq 5810 || n->as_Bool()->_test._test == BoolTest::ne 5811 || n->as_Bool()->_test._test == BoolTest::lt 5812 || n->as_Bool()->_test._test == BoolTest::ge); 5813 5814 format %{ "" %} 5815 interface(COND_INTER) %{ 5816 equal(0x0, "eq"); 5817 not_equal(0x1, "ne"); 5818 less(0xb, "lt"); 5819 greater_equal(0xa, "ge"); 5820 less_equal(0xd, "le"); 5821 greater(0xc, "gt"); 5822 overflow(0x6, "vs"); 5823 no_overflow(0x7, "vc"); 5824 %} 5825 %} 5826 5827 // Special operand allowing long args to int ops to be truncated for free 5828 5829 operand iRegL2I(iRegL reg) %{ 5830 5831 op_cost(0); 5832 5833 match(ConvL2I reg); 5834 5835 format %{ "l2i($reg)" %} 5836 5837 interface(REG_INTER) 5838 %} 5839 5840 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5841 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5842 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5843 5844 //----------OPERAND CLASSES---------------------------------------------------- 5845 // Operand Classes are groups of operands that are used as to simplify 5846 // instruction definitions by not requiring the AD writer to specify 5847 // separate instructions for every form of operand when the 5848 // instruction accepts multiple operand types with the same basic 5849 // encoding and format. The classic case of this is memory operands. 5850 5851 // memory is used to define read/write location for load/store 5852 // instruction defs. we can turn a memory op into an Address 5853 5854 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5855 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5856 5857 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5858 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5859 5860 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5861 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5862 5863 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5864 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5865 5866 // All of the memory operands. For the pipeline description. 5867 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5868 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5869 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5870 5871 5872 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5873 // operations. it allows the src to be either an iRegI or a (ConvL2I 5874 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5875 // can be elided because the 32-bit instruction will just employ the 5876 // lower 32 bits anyway. 5877 // 5878 // n.b. this does not elide all L2I conversions. if the truncated 5879 // value is consumed by more than one operation then the ConvL2I 5880 // cannot be bundled into the consuming nodes so an l2i gets planted 5881 // (actually a movw $dst $src) and the downstream instructions consume 5882 // the result of the l2i as an iRegI input. That's a shame since the 5883 // movw is actually redundant but its not too costly. 5884 5885 opclass iRegIorL2I(iRegI, iRegL2I); 5886 5887 //----------PIPELINE----------------------------------------------------------- 5888 // Rules which define the behavior of the target architectures pipeline. 5889 5890 // For specific pipelines, eg A53, define the stages of that pipeline 5891 //pipe_desc(ISS, EX1, EX2, WR); 5892 #define ISS S0 5893 #define EX1 S1 5894 #define EX2 S2 5895 #define WR S3 5896 5897 // Integer ALU reg operation 5898 pipeline %{ 5899 5900 attributes %{ 5901 // ARM instructions are of fixed length 5902 fixed_size_instructions; // Fixed size instructions TODO does 5903 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 5904 // ARM instructions come in 32-bit word units 5905 instruction_unit_size = 4; // An instruction is 4 bytes long 5906 instruction_fetch_unit_size = 64; // The processor fetches one line 5907 instruction_fetch_units = 1; // of 64 bytes 5908 5909 // List of nop instructions 5910 nops( MachNop ); 5911 %} 5912 5913 // We don't use an actual pipeline model so don't care about resources 5914 // or description. we do use pipeline classes to introduce fixed 5915 // latencies 5916 5917 //----------RESOURCES---------------------------------------------------------- 5918 // Resources are the functional units available to the machine 5919 5920 resources( INS0, INS1, INS01 = INS0 | INS1, 5921 ALU0, ALU1, ALU = ALU0 | ALU1, 5922 MAC, 5923 DIV, 5924 BRANCH, 5925 LDST, 5926 NEON_FP); 5927 5928 //----------PIPELINE DESCRIPTION----------------------------------------------- 5929 // Pipeline Description specifies the stages in the machine's pipeline 5930 5931 // Define the pipeline as a generic 6 stage pipeline 5932 pipe_desc(S0, S1, S2, S3, S4, S5); 5933 5934 //----------PIPELINE CLASSES--------------------------------------------------- 5935 // Pipeline Classes describe the stages in which input and output are 5936 // referenced by the hardware pipeline. 5937 5938 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5939 %{ 5940 single_instruction; 5941 src1 : S1(read); 5942 src2 : S2(read); 5943 dst : S5(write); 5944 INS01 : ISS; 5945 NEON_FP : S5; 5946 %} 5947 5948 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5949 %{ 5950 single_instruction; 5951 src1 : S1(read); 5952 src2 : S2(read); 5953 dst : S5(write); 5954 INS01 : ISS; 5955 NEON_FP : S5; 5956 %} 5957 5958 pipe_class fp_uop_s(vRegF dst, vRegF src) 5959 %{ 5960 single_instruction; 5961 src : S1(read); 5962 dst : S5(write); 5963 INS01 : ISS; 5964 NEON_FP : S5; 5965 %} 5966 5967 pipe_class fp_uop_d(vRegD dst, vRegD src) 5968 %{ 5969 single_instruction; 5970 src : S1(read); 5971 dst : S5(write); 5972 INS01 : ISS; 5973 NEON_FP : S5; 5974 %} 5975 5976 pipe_class fp_d2f(vRegF dst, vRegD src) 5977 %{ 5978 single_instruction; 5979 src : S1(read); 5980 dst : S5(write); 5981 INS01 : ISS; 5982 NEON_FP : S5; 5983 %} 5984 5985 pipe_class fp_f2d(vRegD dst, vRegF src) 5986 %{ 5987 single_instruction; 5988 src : S1(read); 5989 dst : S5(write); 5990 INS01 : ISS; 5991 NEON_FP : S5; 5992 %} 5993 5994 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5995 %{ 5996 single_instruction; 5997 src : S1(read); 5998 dst : S5(write); 5999 INS01 : ISS; 6000 NEON_FP : S5; 6001 %} 6002 6003 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6004 %{ 6005 single_instruction; 6006 src : S1(read); 6007 dst : S5(write); 6008 INS01 : ISS; 6009 NEON_FP : S5; 6010 %} 6011 6012 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6013 %{ 6014 single_instruction; 6015 src : S1(read); 6016 dst : S5(write); 6017 INS01 : ISS; 6018 NEON_FP : S5; 6019 %} 6020 6021 pipe_class fp_l2f(vRegF dst, iRegL src) 6022 %{ 6023 single_instruction; 6024 src : S1(read); 6025 dst : S5(write); 6026 INS01 : ISS; 6027 NEON_FP : S5; 6028 %} 6029 6030 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6031 %{ 6032 single_instruction; 6033 src : S1(read); 6034 dst : S5(write); 6035 INS01 : ISS; 6036 NEON_FP : S5; 6037 %} 6038 6039 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6040 %{ 6041 single_instruction; 6042 src : S1(read); 6043 dst : S5(write); 6044 INS01 : ISS; 6045 NEON_FP : S5; 6046 %} 6047 6048 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6049 %{ 6050 single_instruction; 6051 src : S1(read); 6052 dst : S5(write); 6053 INS01 : ISS; 6054 NEON_FP : S5; 6055 %} 6056 6057 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6058 %{ 6059 single_instruction; 6060 src : S1(read); 6061 dst : S5(write); 6062 INS01 : ISS; 6063 NEON_FP : S5; 6064 %} 6065 6066 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6067 %{ 6068 single_instruction; 6069 src1 : S1(read); 6070 src2 : S2(read); 6071 dst : S5(write); 6072 INS0 : ISS; 6073 NEON_FP : S5; 6074 %} 6075 6076 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6077 %{ 6078 single_instruction; 6079 src1 : S1(read); 6080 src2 : S2(read); 6081 dst : S5(write); 6082 INS0 : ISS; 6083 NEON_FP : S5; 6084 %} 6085 6086 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6087 %{ 6088 single_instruction; 6089 cr : S1(read); 6090 src1 : S1(read); 6091 src2 : S1(read); 6092 dst : S3(write); 6093 INS01 : ISS; 6094 NEON_FP : S3; 6095 %} 6096 6097 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6098 %{ 6099 single_instruction; 6100 cr : S1(read); 6101 src1 : S1(read); 6102 src2 : S1(read); 6103 dst : S3(write); 6104 INS01 : ISS; 6105 NEON_FP : S3; 6106 %} 6107 6108 pipe_class fp_imm_s(vRegF dst) 6109 %{ 6110 single_instruction; 6111 dst : S3(write); 6112 INS01 : ISS; 6113 NEON_FP : S3; 6114 %} 6115 6116 pipe_class fp_imm_d(vRegD dst) 6117 %{ 6118 single_instruction; 6119 dst : S3(write); 6120 INS01 : ISS; 6121 NEON_FP : S3; 6122 %} 6123 6124 pipe_class fp_load_constant_s(vRegF dst) 6125 %{ 6126 single_instruction; 6127 dst : S4(write); 6128 INS01 : ISS; 6129 NEON_FP : S4; 6130 %} 6131 6132 pipe_class fp_load_constant_d(vRegD dst) 6133 %{ 6134 single_instruction; 6135 dst : S4(write); 6136 INS01 : ISS; 6137 NEON_FP : S4; 6138 %} 6139 6140 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6141 %{ 6142 single_instruction; 6143 dst : S5(write); 6144 src1 : S1(read); 6145 src2 : S1(read); 6146 INS01 : ISS; 6147 NEON_FP : S5; 6148 %} 6149 6150 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6151 %{ 6152 single_instruction; 6153 dst : S5(write); 6154 src1 : S1(read); 6155 src2 : S1(read); 6156 INS0 : ISS; 6157 NEON_FP : S5; 6158 %} 6159 6160 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6161 %{ 6162 single_instruction; 6163 dst : S5(write); 6164 src1 : S1(read); 6165 src2 : S1(read); 6166 dst : S1(read); 6167 INS01 : ISS; 6168 NEON_FP : S5; 6169 %} 6170 6171 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6172 %{ 6173 single_instruction; 6174 dst : S5(write); 6175 src1 : S1(read); 6176 src2 : S1(read); 6177 dst : S1(read); 6178 INS0 : ISS; 6179 NEON_FP : S5; 6180 %} 6181 6182 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6183 %{ 6184 single_instruction; 6185 dst : S4(write); 6186 src1 : S2(read); 6187 src2 : S2(read); 6188 INS01 : ISS; 6189 NEON_FP : S4; 6190 %} 6191 6192 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6193 %{ 6194 single_instruction; 6195 dst : S4(write); 6196 src1 : S2(read); 6197 src2 : S2(read); 6198 INS0 : ISS; 6199 NEON_FP : S4; 6200 %} 6201 6202 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6203 %{ 6204 single_instruction; 6205 dst : S3(write); 6206 src1 : S2(read); 6207 src2 : S2(read); 6208 INS01 : ISS; 6209 NEON_FP : S3; 6210 %} 6211 6212 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6213 %{ 6214 single_instruction; 6215 dst : S3(write); 6216 src1 : S2(read); 6217 src2 : S2(read); 6218 INS0 : ISS; 6219 NEON_FP : S3; 6220 %} 6221 6222 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6223 %{ 6224 single_instruction; 6225 dst : S3(write); 6226 src : S1(read); 6227 shift : S1(read); 6228 INS01 : ISS; 6229 NEON_FP : S3; 6230 %} 6231 6232 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6233 %{ 6234 single_instruction; 6235 dst : S3(write); 6236 src : S1(read); 6237 shift : S1(read); 6238 INS0 : ISS; 6239 NEON_FP : S3; 6240 %} 6241 6242 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6243 %{ 6244 single_instruction; 6245 dst : S3(write); 6246 src : S1(read); 6247 INS01 : ISS; 6248 NEON_FP : S3; 6249 %} 6250 6251 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6252 %{ 6253 single_instruction; 6254 dst : S3(write); 6255 src : S1(read); 6256 INS0 : ISS; 6257 NEON_FP : S3; 6258 %} 6259 6260 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6261 %{ 6262 single_instruction; 6263 dst : S5(write); 6264 src1 : S1(read); 6265 src2 : S1(read); 6266 INS01 : ISS; 6267 NEON_FP : S5; 6268 %} 6269 6270 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6271 %{ 6272 single_instruction; 6273 dst : S5(write); 6274 src1 : S1(read); 6275 src2 : S1(read); 6276 INS0 : ISS; 6277 NEON_FP : S5; 6278 %} 6279 6280 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6281 %{ 6282 single_instruction; 6283 dst : S5(write); 6284 src1 : S1(read); 6285 src2 : S1(read); 6286 INS0 : ISS; 6287 NEON_FP : S5; 6288 %} 6289 6290 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6291 %{ 6292 single_instruction; 6293 dst : S5(write); 6294 src1 : S1(read); 6295 src2 : S1(read); 6296 INS0 : ISS; 6297 NEON_FP : S5; 6298 %} 6299 6300 pipe_class vsqrt_fp128(vecX dst, vecX src) 6301 %{ 6302 single_instruction; 6303 dst : S5(write); 6304 src : S1(read); 6305 INS0 : ISS; 6306 NEON_FP : S5; 6307 %} 6308 6309 pipe_class vunop_fp64(vecD dst, vecD src) 6310 %{ 6311 single_instruction; 6312 dst : S5(write); 6313 src : S1(read); 6314 INS01 : ISS; 6315 NEON_FP : S5; 6316 %} 6317 6318 pipe_class vunop_fp128(vecX dst, vecX src) 6319 %{ 6320 single_instruction; 6321 dst : S5(write); 6322 src : S1(read); 6323 INS0 : ISS; 6324 NEON_FP : S5; 6325 %} 6326 6327 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6328 %{ 6329 single_instruction; 6330 dst : S3(write); 6331 src : S1(read); 6332 INS01 : ISS; 6333 NEON_FP : S3; 6334 %} 6335 6336 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6337 %{ 6338 single_instruction; 6339 dst : S3(write); 6340 src : S1(read); 6341 INS01 : ISS; 6342 NEON_FP : S3; 6343 %} 6344 6345 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6346 %{ 6347 single_instruction; 6348 dst : S3(write); 6349 src : S1(read); 6350 INS01 : ISS; 6351 NEON_FP : S3; 6352 %} 6353 6354 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6355 %{ 6356 single_instruction; 6357 dst : S3(write); 6358 src : S1(read); 6359 INS01 : ISS; 6360 NEON_FP : S3; 6361 %} 6362 6363 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6364 %{ 6365 single_instruction; 6366 dst : S3(write); 6367 src : S1(read); 6368 INS01 : ISS; 6369 NEON_FP : S3; 6370 %} 6371 6372 pipe_class vmovi_reg_imm64(vecD dst) 6373 %{ 6374 single_instruction; 6375 dst : S3(write); 6376 INS01 : ISS; 6377 NEON_FP : S3; 6378 %} 6379 6380 pipe_class vmovi_reg_imm128(vecX dst) 6381 %{ 6382 single_instruction; 6383 dst : S3(write); 6384 INS0 : ISS; 6385 NEON_FP : S3; 6386 %} 6387 6388 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6389 %{ 6390 single_instruction; 6391 dst : S5(write); 6392 mem : ISS(read); 6393 INS01 : ISS; 6394 NEON_FP : S3; 6395 %} 6396 6397 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6398 %{ 6399 single_instruction; 6400 dst : S5(write); 6401 mem : ISS(read); 6402 INS01 : ISS; 6403 NEON_FP : S3; 6404 %} 6405 6406 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6407 %{ 6408 single_instruction; 6409 mem : ISS(read); 6410 src : S2(read); 6411 INS01 : ISS; 6412 NEON_FP : S3; 6413 %} 6414 6415 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6416 %{ 6417 single_instruction; 6418 mem : ISS(read); 6419 src : S2(read); 6420 INS01 : ISS; 6421 NEON_FP : S3; 6422 %} 6423 6424 //------- Integer ALU operations -------------------------- 6425 6426 // Integer ALU reg-reg operation 6427 // Operands needed in EX1, result generated in EX2 6428 // Eg. ADD x0, x1, x2 6429 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6430 %{ 6431 single_instruction; 6432 dst : EX2(write); 6433 src1 : EX1(read); 6434 src2 : EX1(read); 6435 INS01 : ISS; // Dual issue as instruction 0 or 1 6436 ALU : EX2; 6437 %} 6438 6439 // Integer ALU reg-reg operation with constant shift 6440 // Shifted register must be available in LATE_ISS instead of EX1 6441 // Eg. ADD x0, x1, x2, LSL #2 6442 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6443 %{ 6444 single_instruction; 6445 dst : EX2(write); 6446 src1 : EX1(read); 6447 src2 : ISS(read); 6448 INS01 : ISS; 6449 ALU : EX2; 6450 %} 6451 6452 // Integer ALU reg operation with constant shift 6453 // Eg. LSL x0, x1, #shift 6454 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6455 %{ 6456 single_instruction; 6457 dst : EX2(write); 6458 src1 : ISS(read); 6459 INS01 : ISS; 6460 ALU : EX2; 6461 %} 6462 6463 // Integer ALU reg-reg operation with variable shift 6464 // Both operands must be available in LATE_ISS instead of EX1 6465 // Result is available in EX1 instead of EX2 6466 // Eg. LSLV x0, x1, x2 6467 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6468 %{ 6469 single_instruction; 6470 dst : EX1(write); 6471 src1 : ISS(read); 6472 src2 : ISS(read); 6473 INS01 : ISS; 6474 ALU : EX1; 6475 %} 6476 6477 // Integer ALU reg-reg operation with extract 6478 // As for _vshift above, but result generated in EX2 6479 // Eg. EXTR x0, x1, x2, #N 6480 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6481 %{ 6482 single_instruction; 6483 dst : EX2(write); 6484 src1 : ISS(read); 6485 src2 : ISS(read); 6486 INS1 : ISS; // Can only dual issue as Instruction 1 6487 ALU : EX1; 6488 %} 6489 6490 // Integer ALU reg operation 6491 // Eg. NEG x0, x1 6492 pipe_class ialu_reg(iRegI dst, iRegI src) 6493 %{ 6494 single_instruction; 6495 dst : EX2(write); 6496 src : EX1(read); 6497 INS01 : ISS; 6498 ALU : EX2; 6499 %} 6500 6501 // Integer ALU reg mmediate operation 6502 // Eg. ADD x0, x1, #N 6503 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6504 %{ 6505 single_instruction; 6506 dst : EX2(write); 6507 src1 : EX1(read); 6508 INS01 : ISS; 6509 ALU : EX2; 6510 %} 6511 6512 // Integer ALU immediate operation (no source operands) 6513 // Eg. MOV x0, #N 6514 pipe_class ialu_imm(iRegI dst) 6515 %{ 6516 single_instruction; 6517 dst : EX1(write); 6518 INS01 : ISS; 6519 ALU : EX1; 6520 %} 6521 6522 //------- Compare operation ------------------------------- 6523 6524 // Compare reg-reg 6525 // Eg. CMP x0, x1 6526 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6527 %{ 6528 single_instruction; 6529 // fixed_latency(16); 6530 cr : EX2(write); 6531 op1 : EX1(read); 6532 op2 : EX1(read); 6533 INS01 : ISS; 6534 ALU : EX2; 6535 %} 6536 6537 // Compare reg-reg 6538 // Eg. CMP x0, #N 6539 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6540 %{ 6541 single_instruction; 6542 // fixed_latency(16); 6543 cr : EX2(write); 6544 op1 : EX1(read); 6545 INS01 : ISS; 6546 ALU : EX2; 6547 %} 6548 6549 //------- Conditional instructions ------------------------ 6550 6551 // Conditional no operands 6552 // Eg. CSINC x0, zr, zr, <cond> 6553 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6554 %{ 6555 single_instruction; 6556 cr : EX1(read); 6557 dst : EX2(write); 6558 INS01 : ISS; 6559 ALU : EX2; 6560 %} 6561 6562 // Conditional 2 operand 6563 // EG. CSEL X0, X1, X2, <cond> 6564 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6565 %{ 6566 single_instruction; 6567 cr : EX1(read); 6568 src1 : EX1(read); 6569 src2 : EX1(read); 6570 dst : EX2(write); 6571 INS01 : ISS; 6572 ALU : EX2; 6573 %} 6574 6575 // Conditional 2 operand 6576 // EG. CSEL X0, X1, X2, <cond> 6577 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6578 %{ 6579 single_instruction; 6580 cr : EX1(read); 6581 src : EX1(read); 6582 dst : EX2(write); 6583 INS01 : ISS; 6584 ALU : EX2; 6585 %} 6586 6587 //------- Multiply pipeline operations -------------------- 6588 6589 // Multiply reg-reg 6590 // Eg. MUL w0, w1, w2 6591 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6592 %{ 6593 single_instruction; 6594 dst : WR(write); 6595 src1 : ISS(read); 6596 src2 : ISS(read); 6597 INS01 : ISS; 6598 MAC : WR; 6599 %} 6600 6601 // Multiply accumulate 6602 // Eg. MADD w0, w1, w2, w3 6603 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6604 %{ 6605 single_instruction; 6606 dst : WR(write); 6607 src1 : ISS(read); 6608 src2 : ISS(read); 6609 src3 : ISS(read); 6610 INS01 : ISS; 6611 MAC : WR; 6612 %} 6613 6614 // Eg. MUL w0, w1, w2 6615 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6616 %{ 6617 single_instruction; 6618 fixed_latency(3); // Maximum latency for 64 bit mul 6619 dst : WR(write); 6620 src1 : ISS(read); 6621 src2 : ISS(read); 6622 INS01 : ISS; 6623 MAC : WR; 6624 %} 6625 6626 // Multiply accumulate 6627 // Eg. MADD w0, w1, w2, w3 6628 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6629 %{ 6630 single_instruction; 6631 fixed_latency(3); // Maximum latency for 64 bit mul 6632 dst : WR(write); 6633 src1 : ISS(read); 6634 src2 : ISS(read); 6635 src3 : ISS(read); 6636 INS01 : ISS; 6637 MAC : WR; 6638 %} 6639 6640 //------- Divide pipeline operations -------------------- 6641 6642 // Eg. SDIV w0, w1, w2 6643 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6644 %{ 6645 single_instruction; 6646 fixed_latency(8); // Maximum latency for 32 bit divide 6647 dst : WR(write); 6648 src1 : ISS(read); 6649 src2 : ISS(read); 6650 INS0 : ISS; // Can only dual issue as instruction 0 6651 DIV : WR; 6652 %} 6653 6654 // Eg. SDIV x0, x1, x2 6655 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6656 %{ 6657 single_instruction; 6658 fixed_latency(16); // Maximum latency for 64 bit divide 6659 dst : WR(write); 6660 src1 : ISS(read); 6661 src2 : ISS(read); 6662 INS0 : ISS; // Can only dual issue as instruction 0 6663 DIV : WR; 6664 %} 6665 6666 //------- Load pipeline operations ------------------------ 6667 6668 // Load - prefetch 6669 // Eg. PFRM <mem> 6670 pipe_class iload_prefetch(memory mem) 6671 %{ 6672 single_instruction; 6673 mem : ISS(read); 6674 INS01 : ISS; 6675 LDST : WR; 6676 %} 6677 6678 // Load - reg, mem 6679 // Eg. LDR x0, <mem> 6680 pipe_class iload_reg_mem(iRegI dst, memory mem) 6681 %{ 6682 single_instruction; 6683 dst : WR(write); 6684 mem : ISS(read); 6685 INS01 : ISS; 6686 LDST : WR; 6687 %} 6688 6689 // Load - reg, reg 6690 // Eg. LDR x0, [sp, x1] 6691 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6692 %{ 6693 single_instruction; 6694 dst : WR(write); 6695 src : ISS(read); 6696 INS01 : ISS; 6697 LDST : WR; 6698 %} 6699 6700 //------- Store pipeline operations ----------------------- 6701 6702 // Store - zr, mem 6703 // Eg. STR zr, <mem> 6704 pipe_class istore_mem(memory mem) 6705 %{ 6706 single_instruction; 6707 mem : ISS(read); 6708 INS01 : ISS; 6709 LDST : WR; 6710 %} 6711 6712 // Store - reg, mem 6713 // Eg. STR x0, <mem> 6714 pipe_class istore_reg_mem(iRegI src, memory mem) 6715 %{ 6716 single_instruction; 6717 mem : ISS(read); 6718 src : EX2(read); 6719 INS01 : ISS; 6720 LDST : WR; 6721 %} 6722 6723 // Store - reg, reg 6724 // Eg. STR x0, [sp, x1] 6725 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6726 %{ 6727 single_instruction; 6728 dst : ISS(read); 6729 src : EX2(read); 6730 INS01 : ISS; 6731 LDST : WR; 6732 %} 6733 6734 //------- Store pipeline operations ----------------------- 6735 6736 // Branch 6737 pipe_class pipe_branch() 6738 %{ 6739 single_instruction; 6740 INS01 : ISS; 6741 BRANCH : EX1; 6742 %} 6743 6744 // Conditional branch 6745 pipe_class pipe_branch_cond(rFlagsReg cr) 6746 %{ 6747 single_instruction; 6748 cr : EX1(read); 6749 INS01 : ISS; 6750 BRANCH : EX1; 6751 %} 6752 6753 // Compare & Branch 6754 // EG. CBZ/CBNZ 6755 pipe_class pipe_cmp_branch(iRegI op1) 6756 %{ 6757 single_instruction; 6758 op1 : EX1(read); 6759 INS01 : ISS; 6760 BRANCH : EX1; 6761 %} 6762 6763 //------- Synchronisation operations ---------------------- 6764 6765 // Any operation requiring serialization. 6766 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6767 pipe_class pipe_serial() 6768 %{ 6769 single_instruction; 6770 force_serialization; 6771 fixed_latency(16); 6772 INS01 : ISS(2); // Cannot dual issue with any other instruction 6773 LDST : WR; 6774 %} 6775 6776 // Generic big/slow expanded idiom - also serialized 6777 pipe_class pipe_slow() 6778 %{ 6779 instruction_count(10); 6780 multiple_bundles; 6781 force_serialization; 6782 fixed_latency(16); 6783 INS01 : ISS(2); // Cannot dual issue with any other instruction 6784 LDST : WR; 6785 %} 6786 6787 // Empty pipeline class 6788 pipe_class pipe_class_empty() 6789 %{ 6790 single_instruction; 6791 fixed_latency(0); 6792 %} 6793 6794 // Default pipeline class. 6795 pipe_class pipe_class_default() 6796 %{ 6797 single_instruction; 6798 fixed_latency(2); 6799 %} 6800 6801 // Pipeline class for compares. 6802 pipe_class pipe_class_compare() 6803 %{ 6804 single_instruction; 6805 fixed_latency(16); 6806 %} 6807 6808 // Pipeline class for memory operations. 6809 pipe_class pipe_class_memory() 6810 %{ 6811 single_instruction; 6812 fixed_latency(16); 6813 %} 6814 6815 // Pipeline class for call. 6816 pipe_class pipe_class_call() 6817 %{ 6818 single_instruction; 6819 fixed_latency(100); 6820 %} 6821 6822 // Define the class for the Nop node. 6823 define %{ 6824 MachNop = pipe_class_empty; 6825 %} 6826 6827 %} 6828 //----------INSTRUCTIONS------------------------------------------------------- 6829 // 6830 // match -- States which machine-independent subtree may be replaced 6831 // by this instruction. 6832 // ins_cost -- The estimated cost of this instruction is used by instruction 6833 // selection to identify a minimum cost tree of machine 6834 // instructions that matches a tree of machine-independent 6835 // instructions. 6836 // format -- A string providing the disassembly for this instruction. 6837 // The value of an instruction's operand may be inserted 6838 // by referring to it with a '$' prefix. 6839 // opcode -- Three instruction opcodes may be provided. These are referred 6840 // to within an encode class as $primary, $secondary, and $tertiary 6841 // rrspectively. The primary opcode is commonly used to 6842 // indicate the type of machine instruction, while secondary 6843 // and tertiary are often used for prefix options or addressing 6844 // modes. 6845 // ins_encode -- A list of encode classes with parameters. The encode class 6846 // name must have been defined in an 'enc_class' specification 6847 // in the encode section of the architecture description. 6848 6849 // ============================================================================ 6850 // Memory (Load/Store) Instructions 6851 6852 // Load Instructions 6853 6854 // Load Byte (8 bit signed) 6855 instruct loadB(iRegINoSp dst, memory1 mem) 6856 %{ 6857 match(Set dst (LoadB mem)); 6858 predicate(!needs_acquiring_load(n)); 6859 6860 ins_cost(4 * INSN_COST); 6861 format %{ "ldrsbw $dst, $mem\t# byte" %} 6862 6863 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6864 6865 ins_pipe(iload_reg_mem); 6866 %} 6867 6868 // Load Byte (8 bit signed) into long 6869 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6870 %{ 6871 match(Set dst (ConvI2L (LoadB mem))); 6872 predicate(!needs_acquiring_load(n->in(1))); 6873 6874 ins_cost(4 * INSN_COST); 6875 format %{ "ldrsb $dst, $mem\t# byte" %} 6876 6877 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6878 6879 ins_pipe(iload_reg_mem); 6880 %} 6881 6882 // Load Byte (8 bit unsigned) 6883 instruct loadUB(iRegINoSp dst, memory1 mem) 6884 %{ 6885 match(Set dst (LoadUB mem)); 6886 predicate(!needs_acquiring_load(n)); 6887 6888 ins_cost(4 * INSN_COST); 6889 format %{ "ldrbw $dst, $mem\t# byte" %} 6890 6891 ins_encode(aarch64_enc_ldrb(dst, mem)); 6892 6893 ins_pipe(iload_reg_mem); 6894 %} 6895 6896 // Load Byte (8 bit unsigned) into long 6897 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6898 %{ 6899 match(Set dst (ConvI2L (LoadUB mem))); 6900 predicate(!needs_acquiring_load(n->in(1))); 6901 6902 ins_cost(4 * INSN_COST); 6903 format %{ "ldrb $dst, $mem\t# byte" %} 6904 6905 ins_encode(aarch64_enc_ldrb(dst, mem)); 6906 6907 ins_pipe(iload_reg_mem); 6908 %} 6909 6910 // Load Short (16 bit signed) 6911 instruct loadS(iRegINoSp dst, memory2 mem) 6912 %{ 6913 match(Set dst (LoadS mem)); 6914 predicate(!needs_acquiring_load(n)); 6915 6916 ins_cost(4 * INSN_COST); 6917 format %{ "ldrshw $dst, $mem\t# short" %} 6918 6919 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6920 6921 ins_pipe(iload_reg_mem); 6922 %} 6923 6924 // Load Short (16 bit signed) into long 6925 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6926 %{ 6927 match(Set dst (ConvI2L (LoadS mem))); 6928 predicate(!needs_acquiring_load(n->in(1))); 6929 6930 ins_cost(4 * INSN_COST); 6931 format %{ "ldrsh $dst, $mem\t# short" %} 6932 6933 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6934 6935 ins_pipe(iload_reg_mem); 6936 %} 6937 6938 // Load Char (16 bit unsigned) 6939 instruct loadUS(iRegINoSp dst, memory2 mem) 6940 %{ 6941 match(Set dst (LoadUS mem)); 6942 predicate(!needs_acquiring_load(n)); 6943 6944 ins_cost(4 * INSN_COST); 6945 format %{ "ldrh $dst, $mem\t# short" %} 6946 6947 ins_encode(aarch64_enc_ldrh(dst, mem)); 6948 6949 ins_pipe(iload_reg_mem); 6950 %} 6951 6952 // Load Short/Char (16 bit unsigned) into long 6953 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6954 %{ 6955 match(Set dst (ConvI2L (LoadUS mem))); 6956 predicate(!needs_acquiring_load(n->in(1))); 6957 6958 ins_cost(4 * INSN_COST); 6959 format %{ "ldrh $dst, $mem\t# short" %} 6960 6961 ins_encode(aarch64_enc_ldrh(dst, mem)); 6962 6963 ins_pipe(iload_reg_mem); 6964 %} 6965 6966 // Load Integer (32 bit signed) 6967 instruct loadI(iRegINoSp dst, memory4 mem) 6968 %{ 6969 match(Set dst (LoadI mem)); 6970 predicate(!needs_acquiring_load(n)); 6971 6972 ins_cost(4 * INSN_COST); 6973 format %{ "ldrw $dst, $mem\t# int" %} 6974 6975 ins_encode(aarch64_enc_ldrw(dst, mem)); 6976 6977 ins_pipe(iload_reg_mem); 6978 %} 6979 6980 // Load Integer (32 bit signed) into long 6981 instruct loadI2L(iRegLNoSp dst, memory4 mem) 6982 %{ 6983 match(Set dst (ConvI2L (LoadI mem))); 6984 predicate(!needs_acquiring_load(n->in(1))); 6985 6986 ins_cost(4 * INSN_COST); 6987 format %{ "ldrsw $dst, $mem\t# int" %} 6988 6989 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6990 6991 ins_pipe(iload_reg_mem); 6992 %} 6993 6994 // Load Integer (32 bit unsigned) into long 6995 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 6996 %{ 6997 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6998 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6999 7000 ins_cost(4 * INSN_COST); 7001 format %{ "ldrw $dst, $mem\t# int" %} 7002 7003 ins_encode(aarch64_enc_ldrw(dst, mem)); 7004 7005 ins_pipe(iload_reg_mem); 7006 %} 7007 7008 // Load Long (64 bit signed) 7009 instruct loadL(iRegLNoSp dst, memory8 mem) 7010 %{ 7011 match(Set dst (LoadL mem)); 7012 predicate(!needs_acquiring_load(n)); 7013 7014 ins_cost(4 * INSN_COST); 7015 format %{ "ldr $dst, $mem\t# int" %} 7016 7017 ins_encode(aarch64_enc_ldr(dst, mem)); 7018 7019 ins_pipe(iload_reg_mem); 7020 %} 7021 7022 // Load Range 7023 instruct loadRange(iRegINoSp dst, memory4 mem) 7024 %{ 7025 match(Set dst (LoadRange mem)); 7026 7027 ins_cost(4 * INSN_COST); 7028 format %{ "ldrw $dst, $mem\t# range" %} 7029 7030 ins_encode(aarch64_enc_ldrw(dst, mem)); 7031 7032 ins_pipe(iload_reg_mem); 7033 %} 7034 7035 // Load Pointer 7036 instruct loadP(iRegPNoSp dst, memory8 mem) 7037 %{ 7038 match(Set dst (LoadP mem)); 7039 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7040 7041 ins_cost(4 * INSN_COST); 7042 format %{ "ldr $dst, $mem\t# ptr" %} 7043 7044 ins_encode(aarch64_enc_ldr(dst, mem)); 7045 7046 ins_pipe(iload_reg_mem); 7047 %} 7048 7049 // Load Compressed Pointer 7050 instruct loadN(iRegNNoSp dst, memory4 mem) 7051 %{ 7052 match(Set dst (LoadN mem)); 7053 predicate(!needs_acquiring_load(n)); 7054 7055 ins_cost(4 * INSN_COST); 7056 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7057 7058 ins_encode(aarch64_enc_ldrw(dst, mem)); 7059 7060 ins_pipe(iload_reg_mem); 7061 %} 7062 7063 // Load Klass Pointer 7064 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7065 %{ 7066 match(Set dst (LoadKlass mem)); 7067 predicate(!needs_acquiring_load(n)); 7068 7069 ins_cost(4 * INSN_COST); 7070 format %{ "ldr $dst, $mem\t# class" %} 7071 7072 ins_encode(aarch64_enc_ldr(dst, mem)); 7073 7074 ins_pipe(iload_reg_mem); 7075 %} 7076 7077 // Load Narrow Klass Pointer 7078 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7079 %{ 7080 match(Set dst (LoadNKlass mem)); 7081 predicate(!needs_acquiring_load(n)); 7082 7083 ins_cost(4 * INSN_COST); 7084 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7085 7086 ins_encode(aarch64_enc_ldrw(dst, mem)); 7087 7088 ins_pipe(iload_reg_mem); 7089 %} 7090 7091 // Load Float 7092 instruct loadF(vRegF dst, memory4 mem) 7093 %{ 7094 match(Set dst (LoadF mem)); 7095 predicate(!needs_acquiring_load(n)); 7096 7097 ins_cost(4 * INSN_COST); 7098 format %{ "ldrs $dst, $mem\t# float" %} 7099 7100 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7101 7102 ins_pipe(pipe_class_memory); 7103 %} 7104 7105 // Load Double 7106 instruct loadD(vRegD dst, memory8 mem) 7107 %{ 7108 match(Set dst (LoadD mem)); 7109 predicate(!needs_acquiring_load(n)); 7110 7111 ins_cost(4 * INSN_COST); 7112 format %{ "ldrd $dst, $mem\t# double" %} 7113 7114 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7115 7116 ins_pipe(pipe_class_memory); 7117 %} 7118 7119 7120 // Load Int Constant 7121 instruct loadConI(iRegINoSp dst, immI src) 7122 %{ 7123 match(Set dst src); 7124 7125 ins_cost(INSN_COST); 7126 format %{ "mov $dst, $src\t# int" %} 7127 7128 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7129 7130 ins_pipe(ialu_imm); 7131 %} 7132 7133 // Load Long Constant 7134 instruct loadConL(iRegLNoSp dst, immL src) 7135 %{ 7136 match(Set dst src); 7137 7138 ins_cost(INSN_COST); 7139 format %{ "mov $dst, $src\t# long" %} 7140 7141 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7142 7143 ins_pipe(ialu_imm); 7144 %} 7145 7146 // Load Pointer Constant 7147 7148 instruct loadConP(iRegPNoSp dst, immP con) 7149 %{ 7150 match(Set dst con); 7151 7152 ins_cost(INSN_COST * 4); 7153 format %{ 7154 "mov $dst, $con\t# ptr\n\t" 7155 %} 7156 7157 ins_encode(aarch64_enc_mov_p(dst, con)); 7158 7159 ins_pipe(ialu_imm); 7160 %} 7161 7162 // Load Null Pointer Constant 7163 7164 instruct loadConP0(iRegPNoSp dst, immP0 con) 7165 %{ 7166 match(Set dst con); 7167 7168 ins_cost(INSN_COST); 7169 format %{ "mov $dst, $con\t# NULL ptr" %} 7170 7171 ins_encode(aarch64_enc_mov_p0(dst, con)); 7172 7173 ins_pipe(ialu_imm); 7174 %} 7175 7176 // Load Pointer Constant One 7177 7178 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7179 %{ 7180 match(Set dst con); 7181 7182 ins_cost(INSN_COST); 7183 format %{ "mov $dst, $con\t# NULL ptr" %} 7184 7185 ins_encode(aarch64_enc_mov_p1(dst, con)); 7186 7187 ins_pipe(ialu_imm); 7188 %} 7189 7190 // Load Byte Map Base Constant 7191 7192 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7193 %{ 7194 match(Set dst con); 7195 7196 ins_cost(INSN_COST); 7197 format %{ "adr $dst, $con\t# Byte Map Base" %} 7198 7199 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7200 7201 ins_pipe(ialu_imm); 7202 %} 7203 7204 // Load Narrow Pointer Constant 7205 7206 instruct loadConN(iRegNNoSp dst, immN con) 7207 %{ 7208 match(Set dst con); 7209 7210 ins_cost(INSN_COST * 4); 7211 format %{ "mov $dst, $con\t# compressed ptr" %} 7212 7213 ins_encode(aarch64_enc_mov_n(dst, con)); 7214 7215 ins_pipe(ialu_imm); 7216 %} 7217 7218 // Load Narrow Null Pointer Constant 7219 7220 instruct loadConN0(iRegNNoSp dst, immN0 con) 7221 %{ 7222 match(Set dst con); 7223 7224 ins_cost(INSN_COST); 7225 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7226 7227 ins_encode(aarch64_enc_mov_n0(dst, con)); 7228 7229 ins_pipe(ialu_imm); 7230 %} 7231 7232 // Load Narrow Klass Constant 7233 7234 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7235 %{ 7236 match(Set dst con); 7237 7238 ins_cost(INSN_COST); 7239 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7240 7241 ins_encode(aarch64_enc_mov_nk(dst, con)); 7242 7243 ins_pipe(ialu_imm); 7244 %} 7245 7246 // Load Packed Float Constant 7247 7248 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7249 match(Set dst con); 7250 ins_cost(INSN_COST * 4); 7251 format %{ "fmovs $dst, $con"%} 7252 ins_encode %{ 7253 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7254 %} 7255 7256 ins_pipe(fp_imm_s); 7257 %} 7258 7259 // Load Float Constant 7260 7261 instruct loadConF(vRegF dst, immF con) %{ 7262 match(Set dst con); 7263 7264 ins_cost(INSN_COST * 4); 7265 7266 format %{ 7267 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7268 %} 7269 7270 ins_encode %{ 7271 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7272 %} 7273 7274 ins_pipe(fp_load_constant_s); 7275 %} 7276 7277 // Load Packed Double Constant 7278 7279 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7280 match(Set dst con); 7281 ins_cost(INSN_COST); 7282 format %{ "fmovd $dst, $con"%} 7283 ins_encode %{ 7284 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7285 %} 7286 7287 ins_pipe(fp_imm_d); 7288 %} 7289 7290 // Load Double Constant 7291 7292 instruct loadConD(vRegD dst, immD con) %{ 7293 match(Set dst con); 7294 7295 ins_cost(INSN_COST * 5); 7296 format %{ 7297 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7298 %} 7299 7300 ins_encode %{ 7301 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7302 %} 7303 7304 ins_pipe(fp_load_constant_d); 7305 %} 7306 7307 // Store Instructions 7308 7309 // Store CMS card-mark Immediate 7310 instruct storeimmCM0(immI0 zero, memory1 mem) 7311 %{ 7312 match(Set mem (StoreCM mem zero)); 7313 7314 ins_cost(INSN_COST); 7315 format %{ "storestore (elided)\n\t" 7316 "strb zr, $mem\t# byte" %} 7317 7318 ins_encode(aarch64_enc_strb0(mem)); 7319 7320 ins_pipe(istore_mem); 7321 %} 7322 7323 // Store CMS card-mark Immediate with intervening StoreStore 7324 // needed when using CMS with no conditional card marking 7325 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7326 %{ 7327 match(Set mem (StoreCM mem zero)); 7328 7329 ins_cost(INSN_COST * 2); 7330 format %{ "storestore\n\t" 7331 "dmb ishst" 7332 "\n\tstrb zr, $mem\t# byte" %} 7333 7334 ins_encode(aarch64_enc_strb0_ordered(mem)); 7335 7336 ins_pipe(istore_mem); 7337 %} 7338 7339 // Store Byte 7340 instruct storeB(iRegIorL2I src, memory1 mem) 7341 %{ 7342 match(Set mem (StoreB mem src)); 7343 predicate(!needs_releasing_store(n)); 7344 7345 ins_cost(INSN_COST); 7346 format %{ "strb $src, $mem\t# byte" %} 7347 7348 ins_encode(aarch64_enc_strb(src, mem)); 7349 7350 ins_pipe(istore_reg_mem); 7351 %} 7352 7353 7354 instruct storeimmB0(immI0 zero, memory1 mem) 7355 %{ 7356 match(Set mem (StoreB mem zero)); 7357 predicate(!needs_releasing_store(n)); 7358 7359 ins_cost(INSN_COST); 7360 format %{ "strb rscractch2, $mem\t# byte" %} 7361 7362 ins_encode(aarch64_enc_strb0(mem)); 7363 7364 ins_pipe(istore_mem); 7365 %} 7366 7367 // Store Char/Short 7368 instruct storeC(iRegIorL2I src, memory2 mem) 7369 %{ 7370 match(Set mem (StoreC mem src)); 7371 predicate(!needs_releasing_store(n)); 7372 7373 ins_cost(INSN_COST); 7374 format %{ "strh $src, $mem\t# short" %} 7375 7376 ins_encode(aarch64_enc_strh(src, mem)); 7377 7378 ins_pipe(istore_reg_mem); 7379 %} 7380 7381 instruct storeimmC0(immI0 zero, memory2 mem) 7382 %{ 7383 match(Set mem (StoreC mem zero)); 7384 predicate(!needs_releasing_store(n)); 7385 7386 ins_cost(INSN_COST); 7387 format %{ "strh zr, $mem\t# short" %} 7388 7389 ins_encode(aarch64_enc_strh0(mem)); 7390 7391 ins_pipe(istore_mem); 7392 %} 7393 7394 // Store Integer 7395 7396 instruct storeI(iRegIorL2I src, memory4 mem) 7397 %{ 7398 match(Set mem(StoreI mem src)); 7399 predicate(!needs_releasing_store(n)); 7400 7401 ins_cost(INSN_COST); 7402 format %{ "strw $src, $mem\t# int" %} 7403 7404 ins_encode(aarch64_enc_strw(src, mem)); 7405 7406 ins_pipe(istore_reg_mem); 7407 %} 7408 7409 instruct storeimmI0(immI0 zero, memory4 mem) 7410 %{ 7411 match(Set mem(StoreI mem zero)); 7412 predicate(!needs_releasing_store(n)); 7413 7414 ins_cost(INSN_COST); 7415 format %{ "strw zr, $mem\t# int" %} 7416 7417 ins_encode(aarch64_enc_strw0(mem)); 7418 7419 ins_pipe(istore_mem); 7420 %} 7421 7422 // Store Long (64 bit signed) 7423 instruct storeL(iRegL src, memory8 mem) 7424 %{ 7425 match(Set mem (StoreL mem src)); 7426 predicate(!needs_releasing_store(n)); 7427 7428 ins_cost(INSN_COST); 7429 format %{ "str $src, $mem\t# int" %} 7430 7431 ins_encode(aarch64_enc_str(src, mem)); 7432 7433 ins_pipe(istore_reg_mem); 7434 %} 7435 7436 // Store Long (64 bit signed) 7437 instruct storeimmL0(immL0 zero, memory8 mem) 7438 %{ 7439 match(Set mem (StoreL mem zero)); 7440 predicate(!needs_releasing_store(n)); 7441 7442 ins_cost(INSN_COST); 7443 format %{ "str zr, $mem\t# int" %} 7444 7445 ins_encode(aarch64_enc_str0(mem)); 7446 7447 ins_pipe(istore_mem); 7448 %} 7449 7450 // Store Pointer 7451 instruct storeP(iRegP src, memory8 mem) 7452 %{ 7453 match(Set mem (StoreP mem src)); 7454 predicate(!needs_releasing_store(n)); 7455 7456 ins_cost(INSN_COST); 7457 format %{ "str $src, $mem\t# ptr" %} 7458 7459 ins_encode(aarch64_enc_str(src, mem)); 7460 7461 ins_pipe(istore_reg_mem); 7462 %} 7463 7464 // Store Pointer 7465 instruct storeimmP0(immP0 zero, memory8 mem) 7466 %{ 7467 match(Set mem (StoreP mem zero)); 7468 predicate(!needs_releasing_store(n)); 7469 7470 ins_cost(INSN_COST); 7471 format %{ "str zr, $mem\t# ptr" %} 7472 7473 ins_encode(aarch64_enc_str0(mem)); 7474 7475 ins_pipe(istore_mem); 7476 %} 7477 7478 // Store Compressed Pointer 7479 instruct storeN(iRegN src, memory4 mem) 7480 %{ 7481 match(Set mem (StoreN mem src)); 7482 predicate(!needs_releasing_store(n)); 7483 7484 ins_cost(INSN_COST); 7485 format %{ "strw $src, $mem\t# compressed ptr" %} 7486 7487 ins_encode(aarch64_enc_strw(src, mem)); 7488 7489 ins_pipe(istore_reg_mem); 7490 %} 7491 7492 instruct storeImmN0(immN0 zero, memory4 mem) 7493 %{ 7494 match(Set mem (StoreN mem zero)); 7495 predicate(!needs_releasing_store(n)); 7496 7497 ins_cost(INSN_COST); 7498 format %{ "strw zr, $mem\t# compressed ptr" %} 7499 7500 ins_encode(aarch64_enc_strw0(mem)); 7501 7502 ins_pipe(istore_mem); 7503 %} 7504 7505 // Store Float 7506 instruct storeF(vRegF src, memory4 mem) 7507 %{ 7508 match(Set mem (StoreF mem src)); 7509 predicate(!needs_releasing_store(n)); 7510 7511 ins_cost(INSN_COST); 7512 format %{ "strs $src, $mem\t# float" %} 7513 7514 ins_encode( aarch64_enc_strs(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(vRegD src, memory8 mem) 7524 %{ 7525 match(Set mem (StoreD mem src)); 7526 predicate(!needs_releasing_store(n)); 7527 7528 ins_cost(INSN_COST); 7529 format %{ "strd $src, $mem\t# double" %} 7530 7531 ins_encode( aarch64_enc_strd(src, mem) ); 7532 7533 ins_pipe(pipe_class_memory); 7534 %} 7535 7536 // Store Compressed Klass Pointer 7537 instruct storeNKlass(iRegN src, memory4 mem) 7538 %{ 7539 predicate(!needs_releasing_store(n)); 7540 match(Set mem (StoreNKlass mem src)); 7541 7542 ins_cost(INSN_COST); 7543 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7544 7545 ins_encode(aarch64_enc_strw(src, mem)); 7546 7547 ins_pipe(istore_reg_mem); 7548 %} 7549 7550 // TODO 7551 // implement storeImmD0 and storeDImmPacked 7552 7553 // prefetch instructions 7554 // Must be safe to execute with invalid address (cannot fault). 7555 7556 instruct prefetchalloc( memory8 mem ) %{ 7557 match(PrefetchAllocation mem); 7558 7559 ins_cost(INSN_COST); 7560 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7561 7562 ins_encode( aarch64_enc_prefetchw(mem) ); 7563 7564 ins_pipe(iload_prefetch); 7565 %} 7566 7567 // ---------------- volatile loads and stores ---------------- 7568 7569 // Load Byte (8 bit signed) 7570 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7571 %{ 7572 match(Set dst (LoadB mem)); 7573 7574 ins_cost(VOLATILE_REF_COST); 7575 format %{ "ldarsb $dst, $mem\t# byte" %} 7576 7577 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7578 7579 ins_pipe(pipe_serial); 7580 %} 7581 7582 // Load Byte (8 bit signed) into long 7583 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7584 %{ 7585 match(Set dst (ConvI2L (LoadB mem))); 7586 7587 ins_cost(VOLATILE_REF_COST); 7588 format %{ "ldarsb $dst, $mem\t# byte" %} 7589 7590 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7591 7592 ins_pipe(pipe_serial); 7593 %} 7594 7595 // Load Byte (8 bit unsigned) 7596 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7597 %{ 7598 match(Set dst (LoadUB mem)); 7599 7600 ins_cost(VOLATILE_REF_COST); 7601 format %{ "ldarb $dst, $mem\t# byte" %} 7602 7603 ins_encode(aarch64_enc_ldarb(dst, mem)); 7604 7605 ins_pipe(pipe_serial); 7606 %} 7607 7608 // Load Byte (8 bit unsigned) into long 7609 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7610 %{ 7611 match(Set dst (ConvI2L (LoadUB mem))); 7612 7613 ins_cost(VOLATILE_REF_COST); 7614 format %{ "ldarb $dst, $mem\t# byte" %} 7615 7616 ins_encode(aarch64_enc_ldarb(dst, mem)); 7617 7618 ins_pipe(pipe_serial); 7619 %} 7620 7621 // Load Short (16 bit signed) 7622 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7623 %{ 7624 match(Set dst (LoadS mem)); 7625 7626 ins_cost(VOLATILE_REF_COST); 7627 format %{ "ldarshw $dst, $mem\t# short" %} 7628 7629 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7630 7631 ins_pipe(pipe_serial); 7632 %} 7633 7634 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7635 %{ 7636 match(Set dst (LoadUS mem)); 7637 7638 ins_cost(VOLATILE_REF_COST); 7639 format %{ "ldarhw $dst, $mem\t# short" %} 7640 7641 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7642 7643 ins_pipe(pipe_serial); 7644 %} 7645 7646 // Load Short/Char (16 bit unsigned) into long 7647 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7648 %{ 7649 match(Set dst (ConvI2L (LoadUS mem))); 7650 7651 ins_cost(VOLATILE_REF_COST); 7652 format %{ "ldarh $dst, $mem\t# short" %} 7653 7654 ins_encode(aarch64_enc_ldarh(dst, mem)); 7655 7656 ins_pipe(pipe_serial); 7657 %} 7658 7659 // Load Short/Char (16 bit signed) into long 7660 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7661 %{ 7662 match(Set dst (ConvI2L (LoadS mem))); 7663 7664 ins_cost(VOLATILE_REF_COST); 7665 format %{ "ldarh $dst, $mem\t# short" %} 7666 7667 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7668 7669 ins_pipe(pipe_serial); 7670 %} 7671 7672 // Load Integer (32 bit signed) 7673 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7674 %{ 7675 match(Set dst (LoadI mem)); 7676 7677 ins_cost(VOLATILE_REF_COST); 7678 format %{ "ldarw $dst, $mem\t# int" %} 7679 7680 ins_encode(aarch64_enc_ldarw(dst, mem)); 7681 7682 ins_pipe(pipe_serial); 7683 %} 7684 7685 // Load Integer (32 bit unsigned) into long 7686 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7687 %{ 7688 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7689 7690 ins_cost(VOLATILE_REF_COST); 7691 format %{ "ldarw $dst, $mem\t# int" %} 7692 7693 ins_encode(aarch64_enc_ldarw(dst, mem)); 7694 7695 ins_pipe(pipe_serial); 7696 %} 7697 7698 // Load Long (64 bit signed) 7699 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7700 %{ 7701 match(Set dst (LoadL mem)); 7702 7703 ins_cost(VOLATILE_REF_COST); 7704 format %{ "ldar $dst, $mem\t# int" %} 7705 7706 ins_encode(aarch64_enc_ldar(dst, mem)); 7707 7708 ins_pipe(pipe_serial); 7709 %} 7710 7711 // Load Pointer 7712 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7713 %{ 7714 match(Set dst (LoadP mem)); 7715 predicate(n->as_Load()->barrier_data() == 0); 7716 7717 ins_cost(VOLATILE_REF_COST); 7718 format %{ "ldar $dst, $mem\t# ptr" %} 7719 7720 ins_encode(aarch64_enc_ldar(dst, mem)); 7721 7722 ins_pipe(pipe_serial); 7723 %} 7724 7725 // Load Compressed Pointer 7726 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7727 %{ 7728 match(Set dst (LoadN mem)); 7729 7730 ins_cost(VOLATILE_REF_COST); 7731 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7732 7733 ins_encode(aarch64_enc_ldarw(dst, mem)); 7734 7735 ins_pipe(pipe_serial); 7736 %} 7737 7738 // Load Float 7739 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7740 %{ 7741 match(Set dst (LoadF mem)); 7742 7743 ins_cost(VOLATILE_REF_COST); 7744 format %{ "ldars $dst, $mem\t# float" %} 7745 7746 ins_encode( aarch64_enc_fldars(dst, mem) ); 7747 7748 ins_pipe(pipe_serial); 7749 %} 7750 7751 // Load Double 7752 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7753 %{ 7754 match(Set dst (LoadD mem)); 7755 7756 ins_cost(VOLATILE_REF_COST); 7757 format %{ "ldard $dst, $mem\t# double" %} 7758 7759 ins_encode( aarch64_enc_fldard(dst, mem) ); 7760 7761 ins_pipe(pipe_serial); 7762 %} 7763 7764 // Store Byte 7765 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7766 %{ 7767 match(Set mem (StoreB mem src)); 7768 7769 ins_cost(VOLATILE_REF_COST); 7770 format %{ "stlrb $src, $mem\t# byte" %} 7771 7772 ins_encode(aarch64_enc_stlrb(src, mem)); 7773 7774 ins_pipe(pipe_class_memory); 7775 %} 7776 7777 // Store Char/Short 7778 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7779 %{ 7780 match(Set mem (StoreC mem src)); 7781 7782 ins_cost(VOLATILE_REF_COST); 7783 format %{ "stlrh $src, $mem\t# short" %} 7784 7785 ins_encode(aarch64_enc_stlrh(src, mem)); 7786 7787 ins_pipe(pipe_class_memory); 7788 %} 7789 7790 // Store Integer 7791 7792 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7793 %{ 7794 match(Set mem(StoreI mem src)); 7795 7796 ins_cost(VOLATILE_REF_COST); 7797 format %{ "stlrw $src, $mem\t# int" %} 7798 7799 ins_encode(aarch64_enc_stlrw(src, mem)); 7800 7801 ins_pipe(pipe_class_memory); 7802 %} 7803 7804 // Store Long (64 bit signed) 7805 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7806 %{ 7807 match(Set mem (StoreL mem src)); 7808 7809 ins_cost(VOLATILE_REF_COST); 7810 format %{ "stlr $src, $mem\t# int" %} 7811 7812 ins_encode(aarch64_enc_stlr(src, mem)); 7813 7814 ins_pipe(pipe_class_memory); 7815 %} 7816 7817 // Store Pointer 7818 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7819 %{ 7820 match(Set mem (StoreP mem src)); 7821 7822 ins_cost(VOLATILE_REF_COST); 7823 format %{ "stlr $src, $mem\t# ptr" %} 7824 7825 ins_encode(aarch64_enc_stlr(src, mem)); 7826 7827 ins_pipe(pipe_class_memory); 7828 %} 7829 7830 // Store Compressed Pointer 7831 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7832 %{ 7833 match(Set mem (StoreN mem src)); 7834 7835 ins_cost(VOLATILE_REF_COST); 7836 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7837 7838 ins_encode(aarch64_enc_stlrw(src, mem)); 7839 7840 ins_pipe(pipe_class_memory); 7841 %} 7842 7843 // Store Float 7844 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7845 %{ 7846 match(Set mem (StoreF mem src)); 7847 7848 ins_cost(VOLATILE_REF_COST); 7849 format %{ "stlrs $src, $mem\t# float" %} 7850 7851 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7852 7853 ins_pipe(pipe_class_memory); 7854 %} 7855 7856 // TODO 7857 // implement storeImmF0 and storeFImmPacked 7858 7859 // Store Double 7860 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7861 %{ 7862 match(Set mem (StoreD mem src)); 7863 7864 ins_cost(VOLATILE_REF_COST); 7865 format %{ "stlrd $src, $mem\t# double" %} 7866 7867 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7868 7869 ins_pipe(pipe_class_memory); 7870 %} 7871 7872 // ---------------- end of volatile loads and stores ---------------- 7873 7874 instruct cacheWB(indirect addr) 7875 %{ 7876 predicate(VM_Version::supports_data_cache_line_flush()); 7877 match(CacheWB addr); 7878 7879 ins_cost(100); 7880 format %{"cache wb $addr" %} 7881 ins_encode %{ 7882 assert($addr->index_position() < 0, "should be"); 7883 assert($addr$$disp == 0, "should be"); 7884 __ cache_wb(Address($addr$$base$$Register, 0)); 7885 %} 7886 ins_pipe(pipe_slow); // XXX 7887 %} 7888 7889 instruct cacheWBPreSync() 7890 %{ 7891 predicate(VM_Version::supports_data_cache_line_flush()); 7892 match(CacheWBPreSync); 7893 7894 ins_cost(100); 7895 format %{"cache wb presync" %} 7896 ins_encode %{ 7897 __ cache_wbsync(true); 7898 %} 7899 ins_pipe(pipe_slow); // XXX 7900 %} 7901 7902 instruct cacheWBPostSync() 7903 %{ 7904 predicate(VM_Version::supports_data_cache_line_flush()); 7905 match(CacheWBPostSync); 7906 7907 ins_cost(100); 7908 format %{"cache wb postsync" %} 7909 ins_encode %{ 7910 __ cache_wbsync(false); 7911 %} 7912 ins_pipe(pipe_slow); // XXX 7913 %} 7914 7915 // ============================================================================ 7916 // BSWAP Instructions 7917 7918 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7919 match(Set dst (ReverseBytesI src)); 7920 7921 ins_cost(INSN_COST); 7922 format %{ "revw $dst, $src" %} 7923 7924 ins_encode %{ 7925 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7926 %} 7927 7928 ins_pipe(ialu_reg); 7929 %} 7930 7931 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7932 match(Set dst (ReverseBytesL src)); 7933 7934 ins_cost(INSN_COST); 7935 format %{ "rev $dst, $src" %} 7936 7937 ins_encode %{ 7938 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7939 %} 7940 7941 ins_pipe(ialu_reg); 7942 %} 7943 7944 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7945 match(Set dst (ReverseBytesUS src)); 7946 7947 ins_cost(INSN_COST); 7948 format %{ "rev16w $dst, $src" %} 7949 7950 ins_encode %{ 7951 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7952 %} 7953 7954 ins_pipe(ialu_reg); 7955 %} 7956 7957 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7958 match(Set dst (ReverseBytesS src)); 7959 7960 ins_cost(INSN_COST); 7961 format %{ "rev16w $dst, $src\n\t" 7962 "sbfmw $dst, $dst, #0, #15" %} 7963 7964 ins_encode %{ 7965 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7966 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7967 %} 7968 7969 ins_pipe(ialu_reg); 7970 %} 7971 7972 // ============================================================================ 7973 // Zero Count Instructions 7974 7975 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7976 match(Set dst (CountLeadingZerosI src)); 7977 7978 ins_cost(INSN_COST); 7979 format %{ "clzw $dst, $src" %} 7980 ins_encode %{ 7981 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7982 %} 7983 7984 ins_pipe(ialu_reg); 7985 %} 7986 7987 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7988 match(Set dst (CountLeadingZerosL src)); 7989 7990 ins_cost(INSN_COST); 7991 format %{ "clz $dst, $src" %} 7992 ins_encode %{ 7993 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7994 %} 7995 7996 ins_pipe(ialu_reg); 7997 %} 7998 7999 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8000 match(Set dst (CountTrailingZerosI src)); 8001 8002 ins_cost(INSN_COST * 2); 8003 format %{ "rbitw $dst, $src\n\t" 8004 "clzw $dst, $dst" %} 8005 ins_encode %{ 8006 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8007 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8008 %} 8009 8010 ins_pipe(ialu_reg); 8011 %} 8012 8013 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8014 match(Set dst (CountTrailingZerosL src)); 8015 8016 ins_cost(INSN_COST * 2); 8017 format %{ "rbit $dst, $src\n\t" 8018 "clz $dst, $dst" %} 8019 ins_encode %{ 8020 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8021 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8022 %} 8023 8024 ins_pipe(ialu_reg); 8025 %} 8026 8027 //---------- Population Count Instructions ------------------------------------- 8028 // 8029 8030 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8031 predicate(UsePopCountInstruction); 8032 match(Set dst (PopCountI src)); 8033 effect(TEMP tmp); 8034 ins_cost(INSN_COST * 13); 8035 8036 format %{ "movw $src, $src\n\t" 8037 "mov $tmp, $src\t# vector (1D)\n\t" 8038 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8039 "addv $tmp, $tmp\t# vector (8B)\n\t" 8040 "mov $dst, $tmp\t# vector (1D)" %} 8041 ins_encode %{ 8042 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8043 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8044 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8045 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8046 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8047 %} 8048 8049 ins_pipe(pipe_class_default); 8050 %} 8051 8052 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8053 predicate(UsePopCountInstruction); 8054 match(Set dst (PopCountI (LoadI mem))); 8055 effect(TEMP tmp); 8056 ins_cost(INSN_COST * 13); 8057 8058 format %{ "ldrs $tmp, $mem\n\t" 8059 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8060 "addv $tmp, $tmp\t# vector (8B)\n\t" 8061 "mov $dst, $tmp\t# vector (1D)" %} 8062 ins_encode %{ 8063 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8064 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8065 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8066 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8067 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8068 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8069 %} 8070 8071 ins_pipe(pipe_class_default); 8072 %} 8073 8074 // Note: Long.bitCount(long) returns an int. 8075 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8076 predicate(UsePopCountInstruction); 8077 match(Set dst (PopCountL src)); 8078 effect(TEMP tmp); 8079 ins_cost(INSN_COST * 13); 8080 8081 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8082 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8083 "addv $tmp, $tmp\t# vector (8B)\n\t" 8084 "mov $dst, $tmp\t# vector (1D)" %} 8085 ins_encode %{ 8086 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8087 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8088 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8089 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8090 %} 8091 8092 ins_pipe(pipe_class_default); 8093 %} 8094 8095 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8096 predicate(UsePopCountInstruction); 8097 match(Set dst (PopCountL (LoadL mem))); 8098 effect(TEMP tmp); 8099 ins_cost(INSN_COST * 13); 8100 8101 format %{ "ldrd $tmp, $mem\n\t" 8102 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8103 "addv $tmp, $tmp\t# vector (8B)\n\t" 8104 "mov $dst, $tmp\t# vector (1D)" %} 8105 ins_encode %{ 8106 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8107 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8108 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8109 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8110 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8111 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8112 %} 8113 8114 ins_pipe(pipe_class_default); 8115 %} 8116 8117 // ============================================================================ 8118 // MemBar Instruction 8119 8120 instruct load_fence() %{ 8121 match(LoadFence); 8122 ins_cost(VOLATILE_REF_COST); 8123 8124 format %{ "load_fence" %} 8125 8126 ins_encode %{ 8127 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8128 %} 8129 ins_pipe(pipe_serial); 8130 %} 8131 8132 instruct unnecessary_membar_acquire() %{ 8133 predicate(unnecessary_acquire(n)); 8134 match(MemBarAcquire); 8135 ins_cost(0); 8136 8137 format %{ "membar_acquire (elided)" %} 8138 8139 ins_encode %{ 8140 __ block_comment("membar_acquire (elided)"); 8141 %} 8142 8143 ins_pipe(pipe_class_empty); 8144 %} 8145 8146 instruct membar_acquire() %{ 8147 match(MemBarAcquire); 8148 ins_cost(VOLATILE_REF_COST); 8149 8150 format %{ "membar_acquire\n\t" 8151 "dmb ish" %} 8152 8153 ins_encode %{ 8154 __ block_comment("membar_acquire"); 8155 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8156 %} 8157 8158 ins_pipe(pipe_serial); 8159 %} 8160 8161 8162 instruct membar_acquire_lock() %{ 8163 match(MemBarAcquireLock); 8164 ins_cost(VOLATILE_REF_COST); 8165 8166 format %{ "membar_acquire_lock (elided)" %} 8167 8168 ins_encode %{ 8169 __ block_comment("membar_acquire_lock (elided)"); 8170 %} 8171 8172 ins_pipe(pipe_serial); 8173 %} 8174 8175 instruct store_fence() %{ 8176 match(StoreFence); 8177 ins_cost(VOLATILE_REF_COST); 8178 8179 format %{ "store_fence" %} 8180 8181 ins_encode %{ 8182 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8183 %} 8184 ins_pipe(pipe_serial); 8185 %} 8186 8187 instruct unnecessary_membar_release() %{ 8188 predicate(unnecessary_release(n)); 8189 match(MemBarRelease); 8190 ins_cost(0); 8191 8192 format %{ "membar_release (elided)" %} 8193 8194 ins_encode %{ 8195 __ block_comment("membar_release (elided)"); 8196 %} 8197 ins_pipe(pipe_serial); 8198 %} 8199 8200 instruct membar_release() %{ 8201 match(MemBarRelease); 8202 ins_cost(VOLATILE_REF_COST); 8203 8204 format %{ "membar_release\n\t" 8205 "dmb ish" %} 8206 8207 ins_encode %{ 8208 __ block_comment("membar_release"); 8209 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8210 %} 8211 ins_pipe(pipe_serial); 8212 %} 8213 8214 instruct membar_storestore() %{ 8215 match(MemBarStoreStore); 8216 ins_cost(VOLATILE_REF_COST); 8217 8218 format %{ "MEMBAR-store-store" %} 8219 8220 ins_encode %{ 8221 __ membar(Assembler::StoreStore); 8222 %} 8223 ins_pipe(pipe_serial); 8224 %} 8225 8226 instruct membar_release_lock() %{ 8227 match(MemBarReleaseLock); 8228 ins_cost(VOLATILE_REF_COST); 8229 8230 format %{ "membar_release_lock (elided)" %} 8231 8232 ins_encode %{ 8233 __ block_comment("membar_release_lock (elided)"); 8234 %} 8235 8236 ins_pipe(pipe_serial); 8237 %} 8238 8239 instruct unnecessary_membar_volatile() %{ 8240 predicate(unnecessary_volatile(n)); 8241 match(MemBarVolatile); 8242 ins_cost(0); 8243 8244 format %{ "membar_volatile (elided)" %} 8245 8246 ins_encode %{ 8247 __ block_comment("membar_volatile (elided)"); 8248 %} 8249 8250 ins_pipe(pipe_serial); 8251 %} 8252 8253 instruct membar_volatile() %{ 8254 match(MemBarVolatile); 8255 ins_cost(VOLATILE_REF_COST*100); 8256 8257 format %{ "membar_volatile\n\t" 8258 "dmb ish"%} 8259 8260 ins_encode %{ 8261 __ block_comment("membar_volatile"); 8262 __ membar(Assembler::StoreLoad); 8263 %} 8264 8265 ins_pipe(pipe_serial); 8266 %} 8267 8268 // ============================================================================ 8269 // Cast/Convert Instructions 8270 8271 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8272 match(Set dst (CastX2P src)); 8273 8274 ins_cost(INSN_COST); 8275 format %{ "mov $dst, $src\t# long -> ptr" %} 8276 8277 ins_encode %{ 8278 if ($dst$$reg != $src$$reg) { 8279 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8280 } 8281 %} 8282 8283 ins_pipe(ialu_reg); 8284 %} 8285 8286 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8287 match(Set dst (CastP2X src)); 8288 8289 ins_cost(INSN_COST); 8290 format %{ "mov $dst, $src\t# ptr -> long" %} 8291 8292 ins_encode %{ 8293 if ($dst$$reg != $src$$reg) { 8294 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8295 } 8296 %} 8297 8298 ins_pipe(ialu_reg); 8299 %} 8300 8301 // Convert oop into int for vectors alignment masking 8302 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8303 match(Set dst (ConvL2I (CastP2X src))); 8304 8305 ins_cost(INSN_COST); 8306 format %{ "movw $dst, $src\t# ptr -> int" %} 8307 ins_encode %{ 8308 __ movw($dst$$Register, $src$$Register); 8309 %} 8310 8311 ins_pipe(ialu_reg); 8312 %} 8313 8314 // Convert compressed oop into int for vectors alignment masking 8315 // in case of 32bit oops (heap < 4Gb). 8316 instruct convN2I(iRegINoSp dst, iRegN src) 8317 %{ 8318 predicate(CompressedOops::shift() == 0); 8319 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8320 8321 ins_cost(INSN_COST); 8322 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8323 ins_encode %{ 8324 __ movw($dst$$Register, $src$$Register); 8325 %} 8326 8327 ins_pipe(ialu_reg); 8328 %} 8329 8330 8331 // Convert oop pointer into compressed form 8332 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8333 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8334 match(Set dst (EncodeP src)); 8335 effect(KILL cr); 8336 ins_cost(INSN_COST * 3); 8337 format %{ "encode_heap_oop $dst, $src" %} 8338 ins_encode %{ 8339 Register s = $src$$Register; 8340 Register d = $dst$$Register; 8341 __ encode_heap_oop(d, s); 8342 %} 8343 ins_pipe(ialu_reg); 8344 %} 8345 8346 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8347 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8348 match(Set dst (EncodeP src)); 8349 ins_cost(INSN_COST * 3); 8350 format %{ "encode_heap_oop_not_null $dst, $src" %} 8351 ins_encode %{ 8352 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8353 %} 8354 ins_pipe(ialu_reg); 8355 %} 8356 8357 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8358 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8359 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8360 match(Set dst (DecodeN src)); 8361 ins_cost(INSN_COST * 3); 8362 format %{ "decode_heap_oop $dst, $src" %} 8363 ins_encode %{ 8364 Register s = $src$$Register; 8365 Register d = $dst$$Register; 8366 __ decode_heap_oop(d, s); 8367 %} 8368 ins_pipe(ialu_reg); 8369 %} 8370 8371 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8372 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8373 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8374 match(Set dst (DecodeN src)); 8375 ins_cost(INSN_COST * 3); 8376 format %{ "decode_heap_oop_not_null $dst, $src" %} 8377 ins_encode %{ 8378 Register s = $src$$Register; 8379 Register d = $dst$$Register; 8380 __ decode_heap_oop_not_null(d, s); 8381 %} 8382 ins_pipe(ialu_reg); 8383 %} 8384 8385 // n.b. AArch64 implementations of encode_klass_not_null and 8386 // decode_klass_not_null do not modify the flags register so, unlike 8387 // Intel, we don't kill CR as a side effect here 8388 8389 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8390 match(Set dst (EncodePKlass src)); 8391 8392 ins_cost(INSN_COST * 3); 8393 format %{ "encode_klass_not_null $dst,$src" %} 8394 8395 ins_encode %{ 8396 Register src_reg = as_Register($src$$reg); 8397 Register dst_reg = as_Register($dst$$reg); 8398 __ encode_klass_not_null(dst_reg, src_reg); 8399 %} 8400 8401 ins_pipe(ialu_reg); 8402 %} 8403 8404 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8405 match(Set dst (DecodeNKlass src)); 8406 8407 ins_cost(INSN_COST * 3); 8408 format %{ "decode_klass_not_null $dst,$src" %} 8409 8410 ins_encode %{ 8411 Register src_reg = as_Register($src$$reg); 8412 Register dst_reg = as_Register($dst$$reg); 8413 if (dst_reg != src_reg) { 8414 __ decode_klass_not_null(dst_reg, src_reg); 8415 } else { 8416 __ decode_klass_not_null(dst_reg); 8417 } 8418 %} 8419 8420 ins_pipe(ialu_reg); 8421 %} 8422 8423 instruct checkCastPP(iRegPNoSp dst) 8424 %{ 8425 match(Set dst (CheckCastPP dst)); 8426 8427 size(0); 8428 format %{ "# checkcastPP of $dst" %} 8429 ins_encode(/* empty encoding */); 8430 ins_pipe(pipe_class_empty); 8431 %} 8432 8433 instruct castPP(iRegPNoSp dst) 8434 %{ 8435 match(Set dst (CastPP dst)); 8436 8437 size(0); 8438 format %{ "# castPP of $dst" %} 8439 ins_encode(/* empty encoding */); 8440 ins_pipe(pipe_class_empty); 8441 %} 8442 8443 instruct castII(iRegI dst) 8444 %{ 8445 match(Set dst (CastII dst)); 8446 8447 size(0); 8448 format %{ "# castII of $dst" %} 8449 ins_encode(/* empty encoding */); 8450 ins_cost(0); 8451 ins_pipe(pipe_class_empty); 8452 %} 8453 8454 // ============================================================================ 8455 // Atomic operation instructions 8456 // 8457 // Intel and SPARC both implement Ideal Node LoadPLocked and 8458 // Store{PIL}Conditional instructions using a normal load for the 8459 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8460 // 8461 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8462 // pair to lock object allocations from Eden space when not using 8463 // TLABs. 8464 // 8465 // There does not appear to be a Load{IL}Locked Ideal Node and the 8466 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8467 // and to use StoreIConditional only for 32-bit and StoreLConditional 8468 // only for 64-bit. 8469 // 8470 // We implement LoadPLocked and StorePLocked instructions using, 8471 // respectively the AArch64 hw load-exclusive and store-conditional 8472 // instructions. Whereas we must implement each of 8473 // Store{IL}Conditional using a CAS which employs a pair of 8474 // instructions comprising a load-exclusive followed by a 8475 // store-conditional. 8476 8477 8478 // Locked-load (linked load) of the current heap-top 8479 // used when updating the eden heap top 8480 // implemented using ldaxr on AArch64 8481 8482 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8483 %{ 8484 match(Set dst (LoadPLocked mem)); 8485 8486 ins_cost(VOLATILE_REF_COST); 8487 8488 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8489 8490 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8491 8492 ins_pipe(pipe_serial); 8493 %} 8494 8495 // Conditional-store of the updated heap-top. 8496 // Used during allocation of the shared heap. 8497 // Sets flag (EQ) on success. 8498 // implemented using stlxr on AArch64. 8499 8500 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8501 %{ 8502 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8503 8504 ins_cost(VOLATILE_REF_COST); 8505 8506 // TODO 8507 // do we need to do a store-conditional release or can we just use a 8508 // plain store-conditional? 8509 8510 format %{ 8511 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8512 "cmpw rscratch1, zr\t# EQ on successful write" 8513 %} 8514 8515 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8516 8517 ins_pipe(pipe_serial); 8518 %} 8519 8520 8521 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8522 // when attempting to rebias a lock towards the current thread. We 8523 // must use the acquire form of cmpxchg in order to guarantee acquire 8524 // semantics in this case. 8525 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8526 %{ 8527 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8528 8529 ins_cost(VOLATILE_REF_COST); 8530 8531 format %{ 8532 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8533 "cmpw rscratch1, zr\t# EQ on successful write" 8534 %} 8535 8536 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8537 8538 ins_pipe(pipe_slow); 8539 %} 8540 8541 // storeIConditional also has acquire semantics, for no better reason 8542 // than matching storeLConditional. At the time of writing this 8543 // comment storeIConditional was not used anywhere by AArch64. 8544 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8545 %{ 8546 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8547 8548 ins_cost(VOLATILE_REF_COST); 8549 8550 format %{ 8551 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8552 "cmpw rscratch1, zr\t# EQ on successful write" 8553 %} 8554 8555 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8556 8557 ins_pipe(pipe_slow); 8558 %} 8559 8560 // standard CompareAndSwapX when we are using barriers 8561 // these have higher priority than the rules selected by a predicate 8562 8563 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8564 // can't match them 8565 8566 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8567 8568 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8569 ins_cost(2 * VOLATILE_REF_COST); 8570 8571 effect(KILL cr); 8572 8573 format %{ 8574 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8575 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8576 %} 8577 8578 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8579 aarch64_enc_cset_eq(res)); 8580 8581 ins_pipe(pipe_slow); 8582 %} 8583 8584 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8585 8586 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8587 ins_cost(2 * VOLATILE_REF_COST); 8588 8589 effect(KILL cr); 8590 8591 format %{ 8592 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8593 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8594 %} 8595 8596 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8597 aarch64_enc_cset_eq(res)); 8598 8599 ins_pipe(pipe_slow); 8600 %} 8601 8602 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8603 8604 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8605 ins_cost(2 * VOLATILE_REF_COST); 8606 8607 effect(KILL cr); 8608 8609 format %{ 8610 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8611 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8612 %} 8613 8614 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8615 aarch64_enc_cset_eq(res)); 8616 8617 ins_pipe(pipe_slow); 8618 %} 8619 8620 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8621 8622 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8623 ins_cost(2 * VOLATILE_REF_COST); 8624 8625 effect(KILL cr); 8626 8627 format %{ 8628 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8629 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8630 %} 8631 8632 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8633 aarch64_enc_cset_eq(res)); 8634 8635 ins_pipe(pipe_slow); 8636 %} 8637 8638 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8639 8640 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8641 predicate(n->as_LoadStore()->barrier_data() == 0); 8642 ins_cost(2 * VOLATILE_REF_COST); 8643 8644 effect(KILL cr); 8645 8646 format %{ 8647 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8648 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8649 %} 8650 8651 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8652 aarch64_enc_cset_eq(res)); 8653 8654 ins_pipe(pipe_slow); 8655 %} 8656 8657 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8658 8659 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8660 ins_cost(2 * VOLATILE_REF_COST); 8661 8662 effect(KILL cr); 8663 8664 format %{ 8665 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8666 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8667 %} 8668 8669 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8670 aarch64_enc_cset_eq(res)); 8671 8672 ins_pipe(pipe_slow); 8673 %} 8674 8675 // alternative CompareAndSwapX when we are eliding barriers 8676 8677 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8678 8679 predicate(needs_acquiring_load_exclusive(n)); 8680 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8681 ins_cost(VOLATILE_REF_COST); 8682 8683 effect(KILL cr); 8684 8685 format %{ 8686 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8687 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8688 %} 8689 8690 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8691 aarch64_enc_cset_eq(res)); 8692 8693 ins_pipe(pipe_slow); 8694 %} 8695 8696 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8697 8698 predicate(needs_acquiring_load_exclusive(n)); 8699 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8700 ins_cost(VOLATILE_REF_COST); 8701 8702 effect(KILL cr); 8703 8704 format %{ 8705 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8706 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8707 %} 8708 8709 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8710 aarch64_enc_cset_eq(res)); 8711 8712 ins_pipe(pipe_slow); 8713 %} 8714 8715 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8716 8717 predicate(needs_acquiring_load_exclusive(n)); 8718 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8719 ins_cost(VOLATILE_REF_COST); 8720 8721 effect(KILL cr); 8722 8723 format %{ 8724 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8725 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8726 %} 8727 8728 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8729 aarch64_enc_cset_eq(res)); 8730 8731 ins_pipe(pipe_slow); 8732 %} 8733 8734 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8735 8736 predicate(needs_acquiring_load_exclusive(n)); 8737 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8738 ins_cost(VOLATILE_REF_COST); 8739 8740 effect(KILL cr); 8741 8742 format %{ 8743 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8744 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8745 %} 8746 8747 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8748 aarch64_enc_cset_eq(res)); 8749 8750 ins_pipe(pipe_slow); 8751 %} 8752 8753 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8754 8755 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8756 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8757 ins_cost(VOLATILE_REF_COST); 8758 8759 effect(KILL cr); 8760 8761 format %{ 8762 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8763 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8764 %} 8765 8766 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8767 aarch64_enc_cset_eq(res)); 8768 8769 ins_pipe(pipe_slow); 8770 %} 8771 8772 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8773 8774 predicate(needs_acquiring_load_exclusive(n)); 8775 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8776 ins_cost(VOLATILE_REF_COST); 8777 8778 effect(KILL cr); 8779 8780 format %{ 8781 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8782 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8783 %} 8784 8785 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8786 aarch64_enc_cset_eq(res)); 8787 8788 ins_pipe(pipe_slow); 8789 %} 8790 8791 8792 // --------------------------------------------------------------------- 8793 8794 8795 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8796 8797 // Sundry CAS operations. Note that release is always true, 8798 // regardless of the memory ordering of the CAS. This is because we 8799 // need the volatile case to be sequentially consistent but there is 8800 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8801 // can't check the type of memory ordering here, so we always emit a 8802 // STLXR. 8803 8804 // This section is generated from aarch64_ad_cas.m4 8805 8806 8807 8808 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8809 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8810 ins_cost(2 * VOLATILE_REF_COST); 8811 effect(TEMP_DEF res, KILL cr); 8812 format %{ 8813 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8814 %} 8815 ins_encode %{ 8816 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8817 Assembler::byte, /*acquire*/ false, /*release*/ true, 8818 /*weak*/ false, $res$$Register); 8819 __ sxtbw($res$$Register, $res$$Register); 8820 %} 8821 ins_pipe(pipe_slow); 8822 %} 8823 8824 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8825 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8826 ins_cost(2 * VOLATILE_REF_COST); 8827 effect(TEMP_DEF res, KILL cr); 8828 format %{ 8829 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8830 %} 8831 ins_encode %{ 8832 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8833 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8834 /*weak*/ false, $res$$Register); 8835 __ sxthw($res$$Register, $res$$Register); 8836 %} 8837 ins_pipe(pipe_slow); 8838 %} 8839 8840 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8841 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8842 ins_cost(2 * VOLATILE_REF_COST); 8843 effect(TEMP_DEF res, KILL cr); 8844 format %{ 8845 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8846 %} 8847 ins_encode %{ 8848 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8849 Assembler::word, /*acquire*/ false, /*release*/ true, 8850 /*weak*/ false, $res$$Register); 8851 %} 8852 ins_pipe(pipe_slow); 8853 %} 8854 8855 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8856 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8857 ins_cost(2 * VOLATILE_REF_COST); 8858 effect(TEMP_DEF res, KILL cr); 8859 format %{ 8860 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8861 %} 8862 ins_encode %{ 8863 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8864 Assembler::xword, /*acquire*/ false, /*release*/ true, 8865 /*weak*/ false, $res$$Register); 8866 %} 8867 ins_pipe(pipe_slow); 8868 %} 8869 8870 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8871 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8872 ins_cost(2 * VOLATILE_REF_COST); 8873 effect(TEMP_DEF res, KILL cr); 8874 format %{ 8875 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8876 %} 8877 ins_encode %{ 8878 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8879 Assembler::word, /*acquire*/ false, /*release*/ true, 8880 /*weak*/ false, $res$$Register); 8881 %} 8882 ins_pipe(pipe_slow); 8883 %} 8884 8885 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8886 predicate(n->as_LoadStore()->barrier_data() == 0); 8887 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8888 ins_cost(2 * VOLATILE_REF_COST); 8889 effect(TEMP_DEF res, KILL cr); 8890 format %{ 8891 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8892 %} 8893 ins_encode %{ 8894 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8895 Assembler::xword, /*acquire*/ false, /*release*/ true, 8896 /*weak*/ false, $res$$Register); 8897 %} 8898 ins_pipe(pipe_slow); 8899 %} 8900 8901 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8902 predicate(needs_acquiring_load_exclusive(n)); 8903 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8904 ins_cost(VOLATILE_REF_COST); 8905 effect(TEMP_DEF res, KILL cr); 8906 format %{ 8907 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8908 %} 8909 ins_encode %{ 8910 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8911 Assembler::byte, /*acquire*/ true, /*release*/ true, 8912 /*weak*/ false, $res$$Register); 8913 __ sxtbw($res$$Register, $res$$Register); 8914 %} 8915 ins_pipe(pipe_slow); 8916 %} 8917 8918 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8919 predicate(needs_acquiring_load_exclusive(n)); 8920 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8921 ins_cost(VOLATILE_REF_COST); 8922 effect(TEMP_DEF res, KILL cr); 8923 format %{ 8924 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8925 %} 8926 ins_encode %{ 8927 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8928 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8929 /*weak*/ false, $res$$Register); 8930 __ sxthw($res$$Register, $res$$Register); 8931 %} 8932 ins_pipe(pipe_slow); 8933 %} 8934 8935 8936 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8937 predicate(needs_acquiring_load_exclusive(n)); 8938 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8939 ins_cost(VOLATILE_REF_COST); 8940 effect(TEMP_DEF res, KILL cr); 8941 format %{ 8942 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8943 %} 8944 ins_encode %{ 8945 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8946 Assembler::word, /*acquire*/ true, /*release*/ true, 8947 /*weak*/ false, $res$$Register); 8948 %} 8949 ins_pipe(pipe_slow); 8950 %} 8951 8952 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8953 predicate(needs_acquiring_load_exclusive(n)); 8954 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8955 ins_cost(VOLATILE_REF_COST); 8956 effect(TEMP_DEF res, KILL cr); 8957 format %{ 8958 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8959 %} 8960 ins_encode %{ 8961 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8962 Assembler::xword, /*acquire*/ true, /*release*/ true, 8963 /*weak*/ false, $res$$Register); 8964 %} 8965 ins_pipe(pipe_slow); 8966 %} 8967 8968 8969 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8970 predicate(needs_acquiring_load_exclusive(n)); 8971 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8972 ins_cost(VOLATILE_REF_COST); 8973 effect(TEMP_DEF res, KILL cr); 8974 format %{ 8975 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8976 %} 8977 ins_encode %{ 8978 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8979 Assembler::word, /*acquire*/ true, /*release*/ true, 8980 /*weak*/ false, $res$$Register); 8981 %} 8982 ins_pipe(pipe_slow); 8983 %} 8984 8985 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8986 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8987 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8988 ins_cost(VOLATILE_REF_COST); 8989 effect(TEMP_DEF res, KILL cr); 8990 format %{ 8991 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8992 %} 8993 ins_encode %{ 8994 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8995 Assembler::xword, /*acquire*/ true, /*release*/ true, 8996 /*weak*/ false, $res$$Register); 8997 %} 8998 ins_pipe(pipe_slow); 8999 %} 9000 9001 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9002 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9003 ins_cost(2 * VOLATILE_REF_COST); 9004 effect(KILL cr); 9005 format %{ 9006 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9007 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9008 %} 9009 ins_encode %{ 9010 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9011 Assembler::byte, /*acquire*/ false, /*release*/ true, 9012 /*weak*/ true, noreg); 9013 __ csetw($res$$Register, Assembler::EQ); 9014 %} 9015 ins_pipe(pipe_slow); 9016 %} 9017 9018 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9019 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9020 ins_cost(2 * VOLATILE_REF_COST); 9021 effect(KILL cr); 9022 format %{ 9023 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9024 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9025 %} 9026 ins_encode %{ 9027 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9028 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9029 /*weak*/ true, noreg); 9030 __ csetw($res$$Register, Assembler::EQ); 9031 %} 9032 ins_pipe(pipe_slow); 9033 %} 9034 9035 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9036 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9037 ins_cost(2 * VOLATILE_REF_COST); 9038 effect(KILL cr); 9039 format %{ 9040 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9041 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9042 %} 9043 ins_encode %{ 9044 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9045 Assembler::word, /*acquire*/ false, /*release*/ true, 9046 /*weak*/ true, noreg); 9047 __ csetw($res$$Register, Assembler::EQ); 9048 %} 9049 ins_pipe(pipe_slow); 9050 %} 9051 9052 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9053 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9054 ins_cost(2 * VOLATILE_REF_COST); 9055 effect(KILL cr); 9056 format %{ 9057 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9058 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9059 %} 9060 ins_encode %{ 9061 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9062 Assembler::xword, /*acquire*/ false, /*release*/ true, 9063 /*weak*/ true, noreg); 9064 __ csetw($res$$Register, Assembler::EQ); 9065 %} 9066 ins_pipe(pipe_slow); 9067 %} 9068 9069 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9070 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9071 ins_cost(2 * VOLATILE_REF_COST); 9072 effect(KILL cr); 9073 format %{ 9074 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9075 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9076 %} 9077 ins_encode %{ 9078 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9079 Assembler::word, /*acquire*/ false, /*release*/ true, 9080 /*weak*/ true, noreg); 9081 __ csetw($res$$Register, Assembler::EQ); 9082 %} 9083 ins_pipe(pipe_slow); 9084 %} 9085 9086 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9087 predicate(n->as_LoadStore()->barrier_data() == 0); 9088 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9089 ins_cost(2 * VOLATILE_REF_COST); 9090 effect(KILL cr); 9091 format %{ 9092 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9093 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9094 %} 9095 ins_encode %{ 9096 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9097 Assembler::xword, /*acquire*/ false, /*release*/ true, 9098 /*weak*/ true, noreg); 9099 __ csetw($res$$Register, Assembler::EQ); 9100 %} 9101 ins_pipe(pipe_slow); 9102 %} 9103 9104 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9105 predicate(needs_acquiring_load_exclusive(n)); 9106 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9107 ins_cost(VOLATILE_REF_COST); 9108 effect(KILL cr); 9109 format %{ 9110 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9111 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9112 %} 9113 ins_encode %{ 9114 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9115 Assembler::byte, /*acquire*/ true, /*release*/ true, 9116 /*weak*/ true, noreg); 9117 __ csetw($res$$Register, Assembler::EQ); 9118 %} 9119 ins_pipe(pipe_slow); 9120 %} 9121 9122 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9123 predicate(needs_acquiring_load_exclusive(n)); 9124 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9125 ins_cost(VOLATILE_REF_COST); 9126 effect(KILL cr); 9127 format %{ 9128 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9129 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9130 %} 9131 ins_encode %{ 9132 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9133 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9134 /*weak*/ true, noreg); 9135 __ csetw($res$$Register, Assembler::EQ); 9136 %} 9137 ins_pipe(pipe_slow); 9138 %} 9139 9140 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9141 predicate(needs_acquiring_load_exclusive(n)); 9142 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9143 ins_cost(VOLATILE_REF_COST); 9144 effect(KILL cr); 9145 format %{ 9146 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9147 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9148 %} 9149 ins_encode %{ 9150 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9151 Assembler::word, /*acquire*/ true, /*release*/ true, 9152 /*weak*/ true, noreg); 9153 __ csetw($res$$Register, Assembler::EQ); 9154 %} 9155 ins_pipe(pipe_slow); 9156 %} 9157 9158 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9159 predicate(needs_acquiring_load_exclusive(n)); 9160 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9161 ins_cost(VOLATILE_REF_COST); 9162 effect(KILL cr); 9163 format %{ 9164 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9165 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9166 %} 9167 ins_encode %{ 9168 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9169 Assembler::xword, /*acquire*/ true, /*release*/ true, 9170 /*weak*/ true, noreg); 9171 __ csetw($res$$Register, Assembler::EQ); 9172 %} 9173 ins_pipe(pipe_slow); 9174 %} 9175 9176 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9177 predicate(needs_acquiring_load_exclusive(n)); 9178 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9179 ins_cost(VOLATILE_REF_COST); 9180 effect(KILL cr); 9181 format %{ 9182 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9183 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9184 %} 9185 ins_encode %{ 9186 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9187 Assembler::word, /*acquire*/ true, /*release*/ true, 9188 /*weak*/ true, noreg); 9189 __ csetw($res$$Register, Assembler::EQ); 9190 %} 9191 ins_pipe(pipe_slow); 9192 %} 9193 9194 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9195 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9196 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9197 ins_cost(VOLATILE_REF_COST); 9198 effect(KILL cr); 9199 format %{ 9200 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9201 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9202 %} 9203 ins_encode %{ 9204 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9205 Assembler::xword, /*acquire*/ true, /*release*/ true, 9206 /*weak*/ true, noreg); 9207 __ csetw($res$$Register, Assembler::EQ); 9208 %} 9209 ins_pipe(pipe_slow); 9210 %} 9211 9212 // END This section of the file is automatically generated. Do not edit -------------- 9213 // --------------------------------------------------------------------- 9214 9215 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9216 match(Set prev (GetAndSetI mem newv)); 9217 ins_cost(2 * VOLATILE_REF_COST); 9218 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9219 ins_encode %{ 9220 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9221 %} 9222 ins_pipe(pipe_serial); 9223 %} 9224 9225 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9226 match(Set prev (GetAndSetL mem newv)); 9227 ins_cost(2 * VOLATILE_REF_COST); 9228 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9229 ins_encode %{ 9230 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9231 %} 9232 ins_pipe(pipe_serial); 9233 %} 9234 9235 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9236 match(Set prev (GetAndSetN mem newv)); 9237 ins_cost(2 * VOLATILE_REF_COST); 9238 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9239 ins_encode %{ 9240 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9241 %} 9242 ins_pipe(pipe_serial); 9243 %} 9244 9245 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9246 predicate(n->as_LoadStore()->barrier_data() == 0); 9247 match(Set prev (GetAndSetP mem newv)); 9248 ins_cost(2 * VOLATILE_REF_COST); 9249 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9250 ins_encode %{ 9251 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9252 %} 9253 ins_pipe(pipe_serial); 9254 %} 9255 9256 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9257 predicate(needs_acquiring_load_exclusive(n)); 9258 match(Set prev (GetAndSetI mem newv)); 9259 ins_cost(VOLATILE_REF_COST); 9260 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9261 ins_encode %{ 9262 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9263 %} 9264 ins_pipe(pipe_serial); 9265 %} 9266 9267 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9268 predicate(needs_acquiring_load_exclusive(n)); 9269 match(Set prev (GetAndSetL mem newv)); 9270 ins_cost(VOLATILE_REF_COST); 9271 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9272 ins_encode %{ 9273 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9274 %} 9275 ins_pipe(pipe_serial); 9276 %} 9277 9278 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9279 predicate(needs_acquiring_load_exclusive(n)); 9280 match(Set prev (GetAndSetN mem newv)); 9281 ins_cost(VOLATILE_REF_COST); 9282 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9283 ins_encode %{ 9284 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9285 %} 9286 ins_pipe(pipe_serial); 9287 %} 9288 9289 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9290 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9291 match(Set prev (GetAndSetP mem newv)); 9292 ins_cost(VOLATILE_REF_COST); 9293 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9294 ins_encode %{ 9295 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9296 %} 9297 ins_pipe(pipe_serial); 9298 %} 9299 9300 9301 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9302 match(Set newval (GetAndAddL mem incr)); 9303 ins_cost(2 * VOLATILE_REF_COST + 1); 9304 format %{ "get_and_addL $newval, [$mem], $incr" %} 9305 ins_encode %{ 9306 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9307 %} 9308 ins_pipe(pipe_serial); 9309 %} 9310 9311 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9312 predicate(n->as_LoadStore()->result_not_used()); 9313 match(Set dummy (GetAndAddL mem incr)); 9314 ins_cost(2 * VOLATILE_REF_COST); 9315 format %{ "get_and_addL [$mem], $incr" %} 9316 ins_encode %{ 9317 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9318 %} 9319 ins_pipe(pipe_serial); 9320 %} 9321 9322 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9323 match(Set newval (GetAndAddL mem incr)); 9324 ins_cost(2 * VOLATILE_REF_COST + 1); 9325 format %{ "get_and_addL $newval, [$mem], $incr" %} 9326 ins_encode %{ 9327 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9328 %} 9329 ins_pipe(pipe_serial); 9330 %} 9331 9332 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9333 predicate(n->as_LoadStore()->result_not_used()); 9334 match(Set dummy (GetAndAddL mem incr)); 9335 ins_cost(2 * VOLATILE_REF_COST); 9336 format %{ "get_and_addL [$mem], $incr" %} 9337 ins_encode %{ 9338 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9339 %} 9340 ins_pipe(pipe_serial); 9341 %} 9342 9343 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9344 match(Set newval (GetAndAddI mem incr)); 9345 ins_cost(2 * VOLATILE_REF_COST + 1); 9346 format %{ "get_and_addI $newval, [$mem], $incr" %} 9347 ins_encode %{ 9348 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9349 %} 9350 ins_pipe(pipe_serial); 9351 %} 9352 9353 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9354 predicate(n->as_LoadStore()->result_not_used()); 9355 match(Set dummy (GetAndAddI mem incr)); 9356 ins_cost(2 * VOLATILE_REF_COST); 9357 format %{ "get_and_addI [$mem], $incr" %} 9358 ins_encode %{ 9359 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9360 %} 9361 ins_pipe(pipe_serial); 9362 %} 9363 9364 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9365 match(Set newval (GetAndAddI mem incr)); 9366 ins_cost(2 * VOLATILE_REF_COST + 1); 9367 format %{ "get_and_addI $newval, [$mem], $incr" %} 9368 ins_encode %{ 9369 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9370 %} 9371 ins_pipe(pipe_serial); 9372 %} 9373 9374 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9375 predicate(n->as_LoadStore()->result_not_used()); 9376 match(Set dummy (GetAndAddI mem incr)); 9377 ins_cost(2 * VOLATILE_REF_COST); 9378 format %{ "get_and_addI [$mem], $incr" %} 9379 ins_encode %{ 9380 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9381 %} 9382 ins_pipe(pipe_serial); 9383 %} 9384 9385 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9386 predicate(needs_acquiring_load_exclusive(n)); 9387 match(Set newval (GetAndAddL mem incr)); 9388 ins_cost(VOLATILE_REF_COST + 1); 9389 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9390 ins_encode %{ 9391 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9392 %} 9393 ins_pipe(pipe_serial); 9394 %} 9395 9396 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9397 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9398 match(Set dummy (GetAndAddL mem incr)); 9399 ins_cost(VOLATILE_REF_COST); 9400 format %{ "get_and_addL_acq [$mem], $incr" %} 9401 ins_encode %{ 9402 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9403 %} 9404 ins_pipe(pipe_serial); 9405 %} 9406 9407 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9408 predicate(needs_acquiring_load_exclusive(n)); 9409 match(Set newval (GetAndAddL mem incr)); 9410 ins_cost(VOLATILE_REF_COST + 1); 9411 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9412 ins_encode %{ 9413 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9414 %} 9415 ins_pipe(pipe_serial); 9416 %} 9417 9418 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9419 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9420 match(Set dummy (GetAndAddL mem incr)); 9421 ins_cost(VOLATILE_REF_COST); 9422 format %{ "get_and_addL_acq [$mem], $incr" %} 9423 ins_encode %{ 9424 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9425 %} 9426 ins_pipe(pipe_serial); 9427 %} 9428 9429 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9430 predicate(needs_acquiring_load_exclusive(n)); 9431 match(Set newval (GetAndAddI mem incr)); 9432 ins_cost(VOLATILE_REF_COST + 1); 9433 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9434 ins_encode %{ 9435 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9436 %} 9437 ins_pipe(pipe_serial); 9438 %} 9439 9440 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9441 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9442 match(Set dummy (GetAndAddI mem incr)); 9443 ins_cost(VOLATILE_REF_COST); 9444 format %{ "get_and_addI_acq [$mem], $incr" %} 9445 ins_encode %{ 9446 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9447 %} 9448 ins_pipe(pipe_serial); 9449 %} 9450 9451 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9452 predicate(needs_acquiring_load_exclusive(n)); 9453 match(Set newval (GetAndAddI mem incr)); 9454 ins_cost(VOLATILE_REF_COST + 1); 9455 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9456 ins_encode %{ 9457 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9458 %} 9459 ins_pipe(pipe_serial); 9460 %} 9461 9462 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9463 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9464 match(Set dummy (GetAndAddI mem incr)); 9465 ins_cost(VOLATILE_REF_COST); 9466 format %{ "get_and_addI_acq [$mem], $incr" %} 9467 ins_encode %{ 9468 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9469 %} 9470 ins_pipe(pipe_serial); 9471 %} 9472 9473 // Manifest a CmpL result in an integer register. 9474 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9475 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9476 %{ 9477 match(Set dst (CmpL3 src1 src2)); 9478 effect(KILL flags); 9479 9480 ins_cost(INSN_COST * 6); 9481 format %{ 9482 "cmp $src1, $src2" 9483 "csetw $dst, ne" 9484 "cnegw $dst, lt" 9485 %} 9486 // format %{ "CmpL3 $dst, $src1, $src2" %} 9487 ins_encode %{ 9488 __ cmp($src1$$Register, $src2$$Register); 9489 __ csetw($dst$$Register, Assembler::NE); 9490 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9491 %} 9492 9493 ins_pipe(pipe_class_default); 9494 %} 9495 9496 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9497 %{ 9498 match(Set dst (CmpL3 src1 src2)); 9499 effect(KILL flags); 9500 9501 ins_cost(INSN_COST * 6); 9502 format %{ 9503 "cmp $src1, $src2" 9504 "csetw $dst, ne" 9505 "cnegw $dst, lt" 9506 %} 9507 ins_encode %{ 9508 int32_t con = (int32_t)$src2$$constant; 9509 if (con < 0) { 9510 __ adds(zr, $src1$$Register, -con); 9511 } else { 9512 __ subs(zr, $src1$$Register, con); 9513 } 9514 __ csetw($dst$$Register, Assembler::NE); 9515 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9516 %} 9517 9518 ins_pipe(pipe_class_default); 9519 %} 9520 9521 // ============================================================================ 9522 // Conditional Move Instructions 9523 9524 // n.b. we have identical rules for both a signed compare op (cmpOp) 9525 // and an unsigned compare op (cmpOpU). it would be nice if we could 9526 // define an op class which merged both inputs and use it to type the 9527 // argument to a single rule. unfortunatelyt his fails because the 9528 // opclass does not live up to the COND_INTER interface of its 9529 // component operands. When the generic code tries to negate the 9530 // operand it ends up running the generci Machoper::negate method 9531 // which throws a ShouldNotHappen. So, we have to provide two flavours 9532 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9533 9534 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9535 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9536 9537 ins_cost(INSN_COST * 2); 9538 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9539 9540 ins_encode %{ 9541 __ cselw(as_Register($dst$$reg), 9542 as_Register($src2$$reg), 9543 as_Register($src1$$reg), 9544 (Assembler::Condition)$cmp$$cmpcode); 9545 %} 9546 9547 ins_pipe(icond_reg_reg); 9548 %} 9549 9550 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9551 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9552 9553 ins_cost(INSN_COST * 2); 9554 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9555 9556 ins_encode %{ 9557 __ cselw(as_Register($dst$$reg), 9558 as_Register($src2$$reg), 9559 as_Register($src1$$reg), 9560 (Assembler::Condition)$cmp$$cmpcode); 9561 %} 9562 9563 ins_pipe(icond_reg_reg); 9564 %} 9565 9566 // special cases where one arg is zero 9567 9568 // n.b. this is selected in preference to the rule above because it 9569 // avoids loading constant 0 into a source register 9570 9571 // TODO 9572 // we ought only to be able to cull one of these variants as the ideal 9573 // transforms ought always to order the zero consistently (to left/right?) 9574 9575 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9576 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9577 9578 ins_cost(INSN_COST * 2); 9579 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9580 9581 ins_encode %{ 9582 __ cselw(as_Register($dst$$reg), 9583 as_Register($src$$reg), 9584 zr, 9585 (Assembler::Condition)$cmp$$cmpcode); 9586 %} 9587 9588 ins_pipe(icond_reg); 9589 %} 9590 9591 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9592 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9593 9594 ins_cost(INSN_COST * 2); 9595 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9596 9597 ins_encode %{ 9598 __ cselw(as_Register($dst$$reg), 9599 as_Register($src$$reg), 9600 zr, 9601 (Assembler::Condition)$cmp$$cmpcode); 9602 %} 9603 9604 ins_pipe(icond_reg); 9605 %} 9606 9607 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9608 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9609 9610 ins_cost(INSN_COST * 2); 9611 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9612 9613 ins_encode %{ 9614 __ cselw(as_Register($dst$$reg), 9615 zr, 9616 as_Register($src$$reg), 9617 (Assembler::Condition)$cmp$$cmpcode); 9618 %} 9619 9620 ins_pipe(icond_reg); 9621 %} 9622 9623 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9624 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9625 9626 ins_cost(INSN_COST * 2); 9627 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9628 9629 ins_encode %{ 9630 __ cselw(as_Register($dst$$reg), 9631 zr, 9632 as_Register($src$$reg), 9633 (Assembler::Condition)$cmp$$cmpcode); 9634 %} 9635 9636 ins_pipe(icond_reg); 9637 %} 9638 9639 // special case for creating a boolean 0 or 1 9640 9641 // n.b. this is selected in preference to the rule above because it 9642 // avoids loading constants 0 and 1 into a source register 9643 9644 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9645 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9646 9647 ins_cost(INSN_COST * 2); 9648 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9649 9650 ins_encode %{ 9651 // equivalently 9652 // cset(as_Register($dst$$reg), 9653 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9654 __ csincw(as_Register($dst$$reg), 9655 zr, 9656 zr, 9657 (Assembler::Condition)$cmp$$cmpcode); 9658 %} 9659 9660 ins_pipe(icond_none); 9661 %} 9662 9663 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9664 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9665 9666 ins_cost(INSN_COST * 2); 9667 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9668 9669 ins_encode %{ 9670 // equivalently 9671 // cset(as_Register($dst$$reg), 9672 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9673 __ csincw(as_Register($dst$$reg), 9674 zr, 9675 zr, 9676 (Assembler::Condition)$cmp$$cmpcode); 9677 %} 9678 9679 ins_pipe(icond_none); 9680 %} 9681 9682 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9683 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9684 9685 ins_cost(INSN_COST * 2); 9686 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9687 9688 ins_encode %{ 9689 __ csel(as_Register($dst$$reg), 9690 as_Register($src2$$reg), 9691 as_Register($src1$$reg), 9692 (Assembler::Condition)$cmp$$cmpcode); 9693 %} 9694 9695 ins_pipe(icond_reg_reg); 9696 %} 9697 9698 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9699 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9700 9701 ins_cost(INSN_COST * 2); 9702 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9703 9704 ins_encode %{ 9705 __ csel(as_Register($dst$$reg), 9706 as_Register($src2$$reg), 9707 as_Register($src1$$reg), 9708 (Assembler::Condition)$cmp$$cmpcode); 9709 %} 9710 9711 ins_pipe(icond_reg_reg); 9712 %} 9713 9714 // special cases where one arg is zero 9715 9716 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9717 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9718 9719 ins_cost(INSN_COST * 2); 9720 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9721 9722 ins_encode %{ 9723 __ csel(as_Register($dst$$reg), 9724 zr, 9725 as_Register($src$$reg), 9726 (Assembler::Condition)$cmp$$cmpcode); 9727 %} 9728 9729 ins_pipe(icond_reg); 9730 %} 9731 9732 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9733 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9734 9735 ins_cost(INSN_COST * 2); 9736 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9737 9738 ins_encode %{ 9739 __ csel(as_Register($dst$$reg), 9740 zr, 9741 as_Register($src$$reg), 9742 (Assembler::Condition)$cmp$$cmpcode); 9743 %} 9744 9745 ins_pipe(icond_reg); 9746 %} 9747 9748 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9749 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9750 9751 ins_cost(INSN_COST * 2); 9752 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9753 9754 ins_encode %{ 9755 __ csel(as_Register($dst$$reg), 9756 as_Register($src$$reg), 9757 zr, 9758 (Assembler::Condition)$cmp$$cmpcode); 9759 %} 9760 9761 ins_pipe(icond_reg); 9762 %} 9763 9764 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9765 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9766 9767 ins_cost(INSN_COST * 2); 9768 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9769 9770 ins_encode %{ 9771 __ csel(as_Register($dst$$reg), 9772 as_Register($src$$reg), 9773 zr, 9774 (Assembler::Condition)$cmp$$cmpcode); 9775 %} 9776 9777 ins_pipe(icond_reg); 9778 %} 9779 9780 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9781 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9782 9783 ins_cost(INSN_COST * 2); 9784 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9785 9786 ins_encode %{ 9787 __ csel(as_Register($dst$$reg), 9788 as_Register($src2$$reg), 9789 as_Register($src1$$reg), 9790 (Assembler::Condition)$cmp$$cmpcode); 9791 %} 9792 9793 ins_pipe(icond_reg_reg); 9794 %} 9795 9796 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9797 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9798 9799 ins_cost(INSN_COST * 2); 9800 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9801 9802 ins_encode %{ 9803 __ csel(as_Register($dst$$reg), 9804 as_Register($src2$$reg), 9805 as_Register($src1$$reg), 9806 (Assembler::Condition)$cmp$$cmpcode); 9807 %} 9808 9809 ins_pipe(icond_reg_reg); 9810 %} 9811 9812 // special cases where one arg is zero 9813 9814 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9815 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9816 9817 ins_cost(INSN_COST * 2); 9818 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9819 9820 ins_encode %{ 9821 __ csel(as_Register($dst$$reg), 9822 zr, 9823 as_Register($src$$reg), 9824 (Assembler::Condition)$cmp$$cmpcode); 9825 %} 9826 9827 ins_pipe(icond_reg); 9828 %} 9829 9830 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9831 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9832 9833 ins_cost(INSN_COST * 2); 9834 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9835 9836 ins_encode %{ 9837 __ csel(as_Register($dst$$reg), 9838 zr, 9839 as_Register($src$$reg), 9840 (Assembler::Condition)$cmp$$cmpcode); 9841 %} 9842 9843 ins_pipe(icond_reg); 9844 %} 9845 9846 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9847 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9848 9849 ins_cost(INSN_COST * 2); 9850 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9851 9852 ins_encode %{ 9853 __ csel(as_Register($dst$$reg), 9854 as_Register($src$$reg), 9855 zr, 9856 (Assembler::Condition)$cmp$$cmpcode); 9857 %} 9858 9859 ins_pipe(icond_reg); 9860 %} 9861 9862 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9863 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9864 9865 ins_cost(INSN_COST * 2); 9866 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9867 9868 ins_encode %{ 9869 __ csel(as_Register($dst$$reg), 9870 as_Register($src$$reg), 9871 zr, 9872 (Assembler::Condition)$cmp$$cmpcode); 9873 %} 9874 9875 ins_pipe(icond_reg); 9876 %} 9877 9878 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9879 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9880 9881 ins_cost(INSN_COST * 2); 9882 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9883 9884 ins_encode %{ 9885 __ cselw(as_Register($dst$$reg), 9886 as_Register($src2$$reg), 9887 as_Register($src1$$reg), 9888 (Assembler::Condition)$cmp$$cmpcode); 9889 %} 9890 9891 ins_pipe(icond_reg_reg); 9892 %} 9893 9894 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9895 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9896 9897 ins_cost(INSN_COST * 2); 9898 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9899 9900 ins_encode %{ 9901 __ cselw(as_Register($dst$$reg), 9902 as_Register($src2$$reg), 9903 as_Register($src1$$reg), 9904 (Assembler::Condition)$cmp$$cmpcode); 9905 %} 9906 9907 ins_pipe(icond_reg_reg); 9908 %} 9909 9910 // special cases where one arg is zero 9911 9912 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9913 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9914 9915 ins_cost(INSN_COST * 2); 9916 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9917 9918 ins_encode %{ 9919 __ cselw(as_Register($dst$$reg), 9920 zr, 9921 as_Register($src$$reg), 9922 (Assembler::Condition)$cmp$$cmpcode); 9923 %} 9924 9925 ins_pipe(icond_reg); 9926 %} 9927 9928 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9929 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9930 9931 ins_cost(INSN_COST * 2); 9932 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9933 9934 ins_encode %{ 9935 __ cselw(as_Register($dst$$reg), 9936 zr, 9937 as_Register($src$$reg), 9938 (Assembler::Condition)$cmp$$cmpcode); 9939 %} 9940 9941 ins_pipe(icond_reg); 9942 %} 9943 9944 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9945 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9946 9947 ins_cost(INSN_COST * 2); 9948 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9949 9950 ins_encode %{ 9951 __ cselw(as_Register($dst$$reg), 9952 as_Register($src$$reg), 9953 zr, 9954 (Assembler::Condition)$cmp$$cmpcode); 9955 %} 9956 9957 ins_pipe(icond_reg); 9958 %} 9959 9960 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9961 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9962 9963 ins_cost(INSN_COST * 2); 9964 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9965 9966 ins_encode %{ 9967 __ cselw(as_Register($dst$$reg), 9968 as_Register($src$$reg), 9969 zr, 9970 (Assembler::Condition)$cmp$$cmpcode); 9971 %} 9972 9973 ins_pipe(icond_reg); 9974 %} 9975 9976 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9977 %{ 9978 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9979 9980 ins_cost(INSN_COST * 3); 9981 9982 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9983 ins_encode %{ 9984 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9985 __ fcsels(as_FloatRegister($dst$$reg), 9986 as_FloatRegister($src2$$reg), 9987 as_FloatRegister($src1$$reg), 9988 cond); 9989 %} 9990 9991 ins_pipe(fp_cond_reg_reg_s); 9992 %} 9993 9994 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9995 %{ 9996 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9997 9998 ins_cost(INSN_COST * 3); 9999 10000 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10001 ins_encode %{ 10002 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10003 __ fcsels(as_FloatRegister($dst$$reg), 10004 as_FloatRegister($src2$$reg), 10005 as_FloatRegister($src1$$reg), 10006 cond); 10007 %} 10008 10009 ins_pipe(fp_cond_reg_reg_s); 10010 %} 10011 10012 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10013 %{ 10014 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10015 10016 ins_cost(INSN_COST * 3); 10017 10018 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10019 ins_encode %{ 10020 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10021 __ fcseld(as_FloatRegister($dst$$reg), 10022 as_FloatRegister($src2$$reg), 10023 as_FloatRegister($src1$$reg), 10024 cond); 10025 %} 10026 10027 ins_pipe(fp_cond_reg_reg_d); 10028 %} 10029 10030 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10031 %{ 10032 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10033 10034 ins_cost(INSN_COST * 3); 10035 10036 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10037 ins_encode %{ 10038 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10039 __ fcseld(as_FloatRegister($dst$$reg), 10040 as_FloatRegister($src2$$reg), 10041 as_FloatRegister($src1$$reg), 10042 cond); 10043 %} 10044 10045 ins_pipe(fp_cond_reg_reg_d); 10046 %} 10047 10048 // ============================================================================ 10049 // Arithmetic Instructions 10050 // 10051 10052 // Integer Addition 10053 10054 // TODO 10055 // these currently employ operations which do not set CR and hence are 10056 // not flagged as killing CR but we would like to isolate the cases 10057 // where we want to set flags from those where we don't. need to work 10058 // out how to do that. 10059 10060 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10061 match(Set dst (AddI src1 src2)); 10062 10063 ins_cost(INSN_COST); 10064 format %{ "addw $dst, $src1, $src2" %} 10065 10066 ins_encode %{ 10067 __ addw(as_Register($dst$$reg), 10068 as_Register($src1$$reg), 10069 as_Register($src2$$reg)); 10070 %} 10071 10072 ins_pipe(ialu_reg_reg); 10073 %} 10074 10075 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10076 match(Set dst (AddI src1 src2)); 10077 10078 ins_cost(INSN_COST); 10079 format %{ "addw $dst, $src1, $src2" %} 10080 10081 // use opcode to indicate that this is an add not a sub 10082 opcode(0x0); 10083 10084 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10085 10086 ins_pipe(ialu_reg_imm); 10087 %} 10088 10089 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10090 match(Set dst (AddI (ConvL2I src1) src2)); 10091 10092 ins_cost(INSN_COST); 10093 format %{ "addw $dst, $src1, $src2" %} 10094 10095 // use opcode to indicate that this is an add not a sub 10096 opcode(0x0); 10097 10098 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10099 10100 ins_pipe(ialu_reg_imm); 10101 %} 10102 10103 // Pointer Addition 10104 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10105 match(Set dst (AddP src1 src2)); 10106 10107 ins_cost(INSN_COST); 10108 format %{ "add $dst, $src1, $src2\t# ptr" %} 10109 10110 ins_encode %{ 10111 __ add(as_Register($dst$$reg), 10112 as_Register($src1$$reg), 10113 as_Register($src2$$reg)); 10114 %} 10115 10116 ins_pipe(ialu_reg_reg); 10117 %} 10118 10119 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10120 match(Set dst (AddP src1 (ConvI2L src2))); 10121 10122 ins_cost(1.9 * INSN_COST); 10123 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10124 10125 ins_encode %{ 10126 __ add(as_Register($dst$$reg), 10127 as_Register($src1$$reg), 10128 as_Register($src2$$reg), ext::sxtw); 10129 %} 10130 10131 ins_pipe(ialu_reg_reg); 10132 %} 10133 10134 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10135 match(Set dst (AddP src1 (LShiftL src2 scale))); 10136 10137 ins_cost(1.9 * INSN_COST); 10138 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10139 10140 ins_encode %{ 10141 __ lea(as_Register($dst$$reg), 10142 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10143 Address::lsl($scale$$constant))); 10144 %} 10145 10146 ins_pipe(ialu_reg_reg_shift); 10147 %} 10148 10149 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10150 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10151 10152 ins_cost(1.9 * INSN_COST); 10153 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10154 10155 ins_encode %{ 10156 __ lea(as_Register($dst$$reg), 10157 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10158 Address::sxtw($scale$$constant))); 10159 %} 10160 10161 ins_pipe(ialu_reg_reg_shift); 10162 %} 10163 10164 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10165 match(Set dst (LShiftL (ConvI2L src) scale)); 10166 10167 ins_cost(INSN_COST); 10168 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10169 10170 ins_encode %{ 10171 __ sbfiz(as_Register($dst$$reg), 10172 as_Register($src$$reg), 10173 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10174 %} 10175 10176 ins_pipe(ialu_reg_shift); 10177 %} 10178 10179 // Pointer Immediate Addition 10180 // n.b. this needs to be more expensive than using an indirect memory 10181 // operand 10182 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10183 match(Set dst (AddP src1 src2)); 10184 10185 ins_cost(INSN_COST); 10186 format %{ "add $dst, $src1, $src2\t# ptr" %} 10187 10188 // use opcode to indicate that this is an add not a sub 10189 opcode(0x0); 10190 10191 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10192 10193 ins_pipe(ialu_reg_imm); 10194 %} 10195 10196 // Long Addition 10197 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10198 10199 match(Set dst (AddL src1 src2)); 10200 10201 ins_cost(INSN_COST); 10202 format %{ "add $dst, $src1, $src2" %} 10203 10204 ins_encode %{ 10205 __ add(as_Register($dst$$reg), 10206 as_Register($src1$$reg), 10207 as_Register($src2$$reg)); 10208 %} 10209 10210 ins_pipe(ialu_reg_reg); 10211 %} 10212 10213 // No constant pool entries requiredLong Immediate Addition. 10214 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10215 match(Set dst (AddL src1 src2)); 10216 10217 ins_cost(INSN_COST); 10218 format %{ "add $dst, $src1, $src2" %} 10219 10220 // use opcode to indicate that this is an add not a sub 10221 opcode(0x0); 10222 10223 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10224 10225 ins_pipe(ialu_reg_imm); 10226 %} 10227 10228 // Integer Subtraction 10229 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10230 match(Set dst (SubI src1 src2)); 10231 10232 ins_cost(INSN_COST); 10233 format %{ "subw $dst, $src1, $src2" %} 10234 10235 ins_encode %{ 10236 __ subw(as_Register($dst$$reg), 10237 as_Register($src1$$reg), 10238 as_Register($src2$$reg)); 10239 %} 10240 10241 ins_pipe(ialu_reg_reg); 10242 %} 10243 10244 // Immediate Subtraction 10245 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10246 match(Set dst (SubI src1 src2)); 10247 10248 ins_cost(INSN_COST); 10249 format %{ "subw $dst, $src1, $src2" %} 10250 10251 // use opcode to indicate that this is a sub not an add 10252 opcode(0x1); 10253 10254 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10255 10256 ins_pipe(ialu_reg_imm); 10257 %} 10258 10259 // Long Subtraction 10260 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10261 10262 match(Set dst (SubL src1 src2)); 10263 10264 ins_cost(INSN_COST); 10265 format %{ "sub $dst, $src1, $src2" %} 10266 10267 ins_encode %{ 10268 __ sub(as_Register($dst$$reg), 10269 as_Register($src1$$reg), 10270 as_Register($src2$$reg)); 10271 %} 10272 10273 ins_pipe(ialu_reg_reg); 10274 %} 10275 10276 // No constant pool entries requiredLong Immediate Subtraction. 10277 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10278 match(Set dst (SubL src1 src2)); 10279 10280 ins_cost(INSN_COST); 10281 format %{ "sub$dst, $src1, $src2" %} 10282 10283 // use opcode to indicate that this is a sub not an add 10284 opcode(0x1); 10285 10286 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10287 10288 ins_pipe(ialu_reg_imm); 10289 %} 10290 10291 // Integer Negation (special case for sub) 10292 10293 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10294 match(Set dst (SubI zero src)); 10295 10296 ins_cost(INSN_COST); 10297 format %{ "negw $dst, $src\t# int" %} 10298 10299 ins_encode %{ 10300 __ negw(as_Register($dst$$reg), 10301 as_Register($src$$reg)); 10302 %} 10303 10304 ins_pipe(ialu_reg); 10305 %} 10306 10307 // Long Negation 10308 10309 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10310 match(Set dst (SubL zero src)); 10311 10312 ins_cost(INSN_COST); 10313 format %{ "neg $dst, $src\t# long" %} 10314 10315 ins_encode %{ 10316 __ neg(as_Register($dst$$reg), 10317 as_Register($src$$reg)); 10318 %} 10319 10320 ins_pipe(ialu_reg); 10321 %} 10322 10323 // Integer Multiply 10324 10325 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10326 match(Set dst (MulI src1 src2)); 10327 10328 ins_cost(INSN_COST * 3); 10329 format %{ "mulw $dst, $src1, $src2" %} 10330 10331 ins_encode %{ 10332 __ mulw(as_Register($dst$$reg), 10333 as_Register($src1$$reg), 10334 as_Register($src2$$reg)); 10335 %} 10336 10337 ins_pipe(imul_reg_reg); 10338 %} 10339 10340 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10341 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10342 10343 ins_cost(INSN_COST * 3); 10344 format %{ "smull $dst, $src1, $src2" %} 10345 10346 ins_encode %{ 10347 __ smull(as_Register($dst$$reg), 10348 as_Register($src1$$reg), 10349 as_Register($src2$$reg)); 10350 %} 10351 10352 ins_pipe(imul_reg_reg); 10353 %} 10354 10355 // Long Multiply 10356 10357 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10358 match(Set dst (MulL src1 src2)); 10359 10360 ins_cost(INSN_COST * 5); 10361 format %{ "mul $dst, $src1, $src2" %} 10362 10363 ins_encode %{ 10364 __ mul(as_Register($dst$$reg), 10365 as_Register($src1$$reg), 10366 as_Register($src2$$reg)); 10367 %} 10368 10369 ins_pipe(lmul_reg_reg); 10370 %} 10371 10372 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10373 %{ 10374 match(Set dst (MulHiL src1 src2)); 10375 10376 ins_cost(INSN_COST * 7); 10377 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10378 10379 ins_encode %{ 10380 __ smulh(as_Register($dst$$reg), 10381 as_Register($src1$$reg), 10382 as_Register($src2$$reg)); 10383 %} 10384 10385 ins_pipe(lmul_reg_reg); 10386 %} 10387 10388 // Combined Integer Multiply & Add/Sub 10389 10390 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10391 match(Set dst (AddI src3 (MulI src1 src2))); 10392 10393 ins_cost(INSN_COST * 3); 10394 format %{ "madd $dst, $src1, $src2, $src3" %} 10395 10396 ins_encode %{ 10397 __ maddw(as_Register($dst$$reg), 10398 as_Register($src1$$reg), 10399 as_Register($src2$$reg), 10400 as_Register($src3$$reg)); 10401 %} 10402 10403 ins_pipe(imac_reg_reg); 10404 %} 10405 10406 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10407 match(Set dst (SubI src3 (MulI src1 src2))); 10408 10409 ins_cost(INSN_COST * 3); 10410 format %{ "msub $dst, $src1, $src2, $src3" %} 10411 10412 ins_encode %{ 10413 __ msubw(as_Register($dst$$reg), 10414 as_Register($src1$$reg), 10415 as_Register($src2$$reg), 10416 as_Register($src3$$reg)); 10417 %} 10418 10419 ins_pipe(imac_reg_reg); 10420 %} 10421 10422 // Combined Integer Multiply & Neg 10423 10424 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10425 match(Set dst (MulI (SubI zero src1) src2)); 10426 match(Set dst (MulI src1 (SubI zero src2))); 10427 10428 ins_cost(INSN_COST * 3); 10429 format %{ "mneg $dst, $src1, $src2" %} 10430 10431 ins_encode %{ 10432 __ mnegw(as_Register($dst$$reg), 10433 as_Register($src1$$reg), 10434 as_Register($src2$$reg)); 10435 %} 10436 10437 ins_pipe(imac_reg_reg); 10438 %} 10439 10440 // Combined Long Multiply & Add/Sub 10441 10442 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10443 match(Set dst (AddL src3 (MulL src1 src2))); 10444 10445 ins_cost(INSN_COST * 5); 10446 format %{ "madd $dst, $src1, $src2, $src3" %} 10447 10448 ins_encode %{ 10449 __ madd(as_Register($dst$$reg), 10450 as_Register($src1$$reg), 10451 as_Register($src2$$reg), 10452 as_Register($src3$$reg)); 10453 %} 10454 10455 ins_pipe(lmac_reg_reg); 10456 %} 10457 10458 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10459 match(Set dst (SubL src3 (MulL src1 src2))); 10460 10461 ins_cost(INSN_COST * 5); 10462 format %{ "msub $dst, $src1, $src2, $src3" %} 10463 10464 ins_encode %{ 10465 __ msub(as_Register($dst$$reg), 10466 as_Register($src1$$reg), 10467 as_Register($src2$$reg), 10468 as_Register($src3$$reg)); 10469 %} 10470 10471 ins_pipe(lmac_reg_reg); 10472 %} 10473 10474 // Combined Long Multiply & Neg 10475 10476 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10477 match(Set dst (MulL (SubL zero src1) src2)); 10478 match(Set dst (MulL src1 (SubL zero src2))); 10479 10480 ins_cost(INSN_COST * 5); 10481 format %{ "mneg $dst, $src1, $src2" %} 10482 10483 ins_encode %{ 10484 __ mneg(as_Register($dst$$reg), 10485 as_Register($src1$$reg), 10486 as_Register($src2$$reg)); 10487 %} 10488 10489 ins_pipe(lmac_reg_reg); 10490 %} 10491 10492 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10493 10494 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10495 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10496 10497 ins_cost(INSN_COST * 3); 10498 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10499 10500 ins_encode %{ 10501 __ smaddl(as_Register($dst$$reg), 10502 as_Register($src1$$reg), 10503 as_Register($src2$$reg), 10504 as_Register($src3$$reg)); 10505 %} 10506 10507 ins_pipe(imac_reg_reg); 10508 %} 10509 10510 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10511 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10512 10513 ins_cost(INSN_COST * 3); 10514 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10515 10516 ins_encode %{ 10517 __ smsubl(as_Register($dst$$reg), 10518 as_Register($src1$$reg), 10519 as_Register($src2$$reg), 10520 as_Register($src3$$reg)); 10521 %} 10522 10523 ins_pipe(imac_reg_reg); 10524 %} 10525 10526 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10527 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10528 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10529 10530 ins_cost(INSN_COST * 3); 10531 format %{ "smnegl $dst, $src1, $src2" %} 10532 10533 ins_encode %{ 10534 __ smnegl(as_Register($dst$$reg), 10535 as_Register($src1$$reg), 10536 as_Register($src2$$reg)); 10537 %} 10538 10539 ins_pipe(imac_reg_reg); 10540 %} 10541 10542 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10543 10544 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10545 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10546 10547 ins_cost(INSN_COST * 5); 10548 format %{ "mulw rscratch1, $src1, $src2\n\t" 10549 "maddw $dst, $src3, $src4, rscratch1" %} 10550 10551 ins_encode %{ 10552 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10553 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10554 10555 ins_pipe(imac_reg_reg); 10556 %} 10557 10558 // Integer Divide 10559 10560 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10561 match(Set dst (DivI src1 src2)); 10562 10563 ins_cost(INSN_COST * 19); 10564 format %{ "sdivw $dst, $src1, $src2" %} 10565 10566 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10567 ins_pipe(idiv_reg_reg); 10568 %} 10569 10570 // Long Divide 10571 10572 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10573 match(Set dst (DivL src1 src2)); 10574 10575 ins_cost(INSN_COST * 35); 10576 format %{ "sdiv $dst, $src1, $src2" %} 10577 10578 ins_encode(aarch64_enc_div(dst, src1, src2)); 10579 ins_pipe(ldiv_reg_reg); 10580 %} 10581 10582 // Integer Remainder 10583 10584 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10585 match(Set dst (ModI src1 src2)); 10586 10587 ins_cost(INSN_COST * 22); 10588 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10589 "msubw($dst, rscratch1, $src2, $src1" %} 10590 10591 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10592 ins_pipe(idiv_reg_reg); 10593 %} 10594 10595 // Long Remainder 10596 10597 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10598 match(Set dst (ModL src1 src2)); 10599 10600 ins_cost(INSN_COST * 38); 10601 format %{ "sdiv rscratch1, $src1, $src2\n" 10602 "msub($dst, rscratch1, $src2, $src1" %} 10603 10604 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10605 ins_pipe(ldiv_reg_reg); 10606 %} 10607 10608 // Integer Shifts 10609 10610 // Shift Left Register 10611 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10612 match(Set dst (LShiftI src1 src2)); 10613 10614 ins_cost(INSN_COST * 2); 10615 format %{ "lslvw $dst, $src1, $src2" %} 10616 10617 ins_encode %{ 10618 __ lslvw(as_Register($dst$$reg), 10619 as_Register($src1$$reg), 10620 as_Register($src2$$reg)); 10621 %} 10622 10623 ins_pipe(ialu_reg_reg_vshift); 10624 %} 10625 10626 // Shift Left Immediate 10627 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10628 match(Set dst (LShiftI src1 src2)); 10629 10630 ins_cost(INSN_COST); 10631 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10632 10633 ins_encode %{ 10634 __ lslw(as_Register($dst$$reg), 10635 as_Register($src1$$reg), 10636 $src2$$constant & 0x1f); 10637 %} 10638 10639 ins_pipe(ialu_reg_shift); 10640 %} 10641 10642 // Shift Right Logical Register 10643 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10644 match(Set dst (URShiftI src1 src2)); 10645 10646 ins_cost(INSN_COST * 2); 10647 format %{ "lsrvw $dst, $src1, $src2" %} 10648 10649 ins_encode %{ 10650 __ lsrvw(as_Register($dst$$reg), 10651 as_Register($src1$$reg), 10652 as_Register($src2$$reg)); 10653 %} 10654 10655 ins_pipe(ialu_reg_reg_vshift); 10656 %} 10657 10658 // Shift Right Logical Immediate 10659 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10660 match(Set dst (URShiftI src1 src2)); 10661 10662 ins_cost(INSN_COST); 10663 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10664 10665 ins_encode %{ 10666 __ lsrw(as_Register($dst$$reg), 10667 as_Register($src1$$reg), 10668 $src2$$constant & 0x1f); 10669 %} 10670 10671 ins_pipe(ialu_reg_shift); 10672 %} 10673 10674 // Shift Right Arithmetic Register 10675 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10676 match(Set dst (RShiftI src1 src2)); 10677 10678 ins_cost(INSN_COST * 2); 10679 format %{ "asrvw $dst, $src1, $src2" %} 10680 10681 ins_encode %{ 10682 __ asrvw(as_Register($dst$$reg), 10683 as_Register($src1$$reg), 10684 as_Register($src2$$reg)); 10685 %} 10686 10687 ins_pipe(ialu_reg_reg_vshift); 10688 %} 10689 10690 // Shift Right Arithmetic Immediate 10691 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10692 match(Set dst (RShiftI src1 src2)); 10693 10694 ins_cost(INSN_COST); 10695 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10696 10697 ins_encode %{ 10698 __ asrw(as_Register($dst$$reg), 10699 as_Register($src1$$reg), 10700 $src2$$constant & 0x1f); 10701 %} 10702 10703 ins_pipe(ialu_reg_shift); 10704 %} 10705 10706 // Combined Int Mask and Right Shift (using UBFM) 10707 // TODO 10708 10709 // Long Shifts 10710 10711 // Shift Left Register 10712 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10713 match(Set dst (LShiftL src1 src2)); 10714 10715 ins_cost(INSN_COST * 2); 10716 format %{ "lslv $dst, $src1, $src2" %} 10717 10718 ins_encode %{ 10719 __ lslv(as_Register($dst$$reg), 10720 as_Register($src1$$reg), 10721 as_Register($src2$$reg)); 10722 %} 10723 10724 ins_pipe(ialu_reg_reg_vshift); 10725 %} 10726 10727 // Shift Left Immediate 10728 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10729 match(Set dst (LShiftL src1 src2)); 10730 10731 ins_cost(INSN_COST); 10732 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10733 10734 ins_encode %{ 10735 __ lsl(as_Register($dst$$reg), 10736 as_Register($src1$$reg), 10737 $src2$$constant & 0x3f); 10738 %} 10739 10740 ins_pipe(ialu_reg_shift); 10741 %} 10742 10743 // Shift Right Logical Register 10744 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10745 match(Set dst (URShiftL src1 src2)); 10746 10747 ins_cost(INSN_COST * 2); 10748 format %{ "lsrv $dst, $src1, $src2" %} 10749 10750 ins_encode %{ 10751 __ lsrv(as_Register($dst$$reg), 10752 as_Register($src1$$reg), 10753 as_Register($src2$$reg)); 10754 %} 10755 10756 ins_pipe(ialu_reg_reg_vshift); 10757 %} 10758 10759 // Shift Right Logical Immediate 10760 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10761 match(Set dst (URShiftL src1 src2)); 10762 10763 ins_cost(INSN_COST); 10764 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10765 10766 ins_encode %{ 10767 __ lsr(as_Register($dst$$reg), 10768 as_Register($src1$$reg), 10769 $src2$$constant & 0x3f); 10770 %} 10771 10772 ins_pipe(ialu_reg_shift); 10773 %} 10774 10775 // A special-case pattern for card table stores. 10776 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10777 match(Set dst (URShiftL (CastP2X src1) src2)); 10778 10779 ins_cost(INSN_COST); 10780 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10781 10782 ins_encode %{ 10783 __ lsr(as_Register($dst$$reg), 10784 as_Register($src1$$reg), 10785 $src2$$constant & 0x3f); 10786 %} 10787 10788 ins_pipe(ialu_reg_shift); 10789 %} 10790 10791 // Shift Right Arithmetic Register 10792 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10793 match(Set dst (RShiftL src1 src2)); 10794 10795 ins_cost(INSN_COST * 2); 10796 format %{ "asrv $dst, $src1, $src2" %} 10797 10798 ins_encode %{ 10799 __ asrv(as_Register($dst$$reg), 10800 as_Register($src1$$reg), 10801 as_Register($src2$$reg)); 10802 %} 10803 10804 ins_pipe(ialu_reg_reg_vshift); 10805 %} 10806 10807 // Shift Right Arithmetic Immediate 10808 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10809 match(Set dst (RShiftL src1 src2)); 10810 10811 ins_cost(INSN_COST); 10812 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10813 10814 ins_encode %{ 10815 __ asr(as_Register($dst$$reg), 10816 as_Register($src1$$reg), 10817 $src2$$constant & 0x3f); 10818 %} 10819 10820 ins_pipe(ialu_reg_shift); 10821 %} 10822 10823 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10824 10825 10826 // This pattern is automatically generated from aarch64_ad.m4 10827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10828 instruct regL_not_reg(iRegLNoSp dst, 10829 iRegL src1, immL_M1 m1, 10830 rFlagsReg cr) %{ 10831 match(Set dst (XorL src1 m1)); 10832 ins_cost(INSN_COST); 10833 format %{ "eon $dst, $src1, zr" %} 10834 10835 ins_encode %{ 10836 __ eon(as_Register($dst$$reg), 10837 as_Register($src1$$reg), 10838 zr, 10839 Assembler::LSL, 0); 10840 %} 10841 10842 ins_pipe(ialu_reg); 10843 %} 10844 10845 // This pattern is automatically generated from aarch64_ad.m4 10846 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10847 instruct regI_not_reg(iRegINoSp dst, 10848 iRegIorL2I src1, immI_M1 m1, 10849 rFlagsReg cr) %{ 10850 match(Set dst (XorI src1 m1)); 10851 ins_cost(INSN_COST); 10852 format %{ "eonw $dst, $src1, zr" %} 10853 10854 ins_encode %{ 10855 __ eonw(as_Register($dst$$reg), 10856 as_Register($src1$$reg), 10857 zr, 10858 Assembler::LSL, 0); 10859 %} 10860 10861 ins_pipe(ialu_reg); 10862 %} 10863 10864 // This pattern is automatically generated from aarch64_ad.m4 10865 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10866 instruct AndI_reg_not_reg(iRegINoSp dst, 10867 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10868 rFlagsReg cr) %{ 10869 match(Set dst (AndI src1 (XorI src2 m1))); 10870 ins_cost(INSN_COST); 10871 format %{ "bicw $dst, $src1, $src2" %} 10872 10873 ins_encode %{ 10874 __ bicw(as_Register($dst$$reg), 10875 as_Register($src1$$reg), 10876 as_Register($src2$$reg), 10877 Assembler::LSL, 0); 10878 %} 10879 10880 ins_pipe(ialu_reg_reg); 10881 %} 10882 10883 // This pattern is automatically generated from aarch64_ad.m4 10884 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10885 instruct AndL_reg_not_reg(iRegLNoSp dst, 10886 iRegL src1, iRegL src2, immL_M1 m1, 10887 rFlagsReg cr) %{ 10888 match(Set dst (AndL src1 (XorL src2 m1))); 10889 ins_cost(INSN_COST); 10890 format %{ "bic $dst, $src1, $src2" %} 10891 10892 ins_encode %{ 10893 __ bic(as_Register($dst$$reg), 10894 as_Register($src1$$reg), 10895 as_Register($src2$$reg), 10896 Assembler::LSL, 0); 10897 %} 10898 10899 ins_pipe(ialu_reg_reg); 10900 %} 10901 10902 // This pattern is automatically generated from aarch64_ad.m4 10903 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10904 instruct OrI_reg_not_reg(iRegINoSp dst, 10905 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10906 rFlagsReg cr) %{ 10907 match(Set dst (OrI src1 (XorI src2 m1))); 10908 ins_cost(INSN_COST); 10909 format %{ "ornw $dst, $src1, $src2" %} 10910 10911 ins_encode %{ 10912 __ ornw(as_Register($dst$$reg), 10913 as_Register($src1$$reg), 10914 as_Register($src2$$reg), 10915 Assembler::LSL, 0); 10916 %} 10917 10918 ins_pipe(ialu_reg_reg); 10919 %} 10920 10921 // This pattern is automatically generated from aarch64_ad.m4 10922 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10923 instruct OrL_reg_not_reg(iRegLNoSp dst, 10924 iRegL src1, iRegL src2, immL_M1 m1, 10925 rFlagsReg cr) %{ 10926 match(Set dst (OrL src1 (XorL src2 m1))); 10927 ins_cost(INSN_COST); 10928 format %{ "orn $dst, $src1, $src2" %} 10929 10930 ins_encode %{ 10931 __ orn(as_Register($dst$$reg), 10932 as_Register($src1$$reg), 10933 as_Register($src2$$reg), 10934 Assembler::LSL, 0); 10935 %} 10936 10937 ins_pipe(ialu_reg_reg); 10938 %} 10939 10940 // This pattern is automatically generated from aarch64_ad.m4 10941 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10942 instruct XorI_reg_not_reg(iRegINoSp dst, 10943 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10944 rFlagsReg cr) %{ 10945 match(Set dst (XorI m1 (XorI src2 src1))); 10946 ins_cost(INSN_COST); 10947 format %{ "eonw $dst, $src1, $src2" %} 10948 10949 ins_encode %{ 10950 __ eonw(as_Register($dst$$reg), 10951 as_Register($src1$$reg), 10952 as_Register($src2$$reg), 10953 Assembler::LSL, 0); 10954 %} 10955 10956 ins_pipe(ialu_reg_reg); 10957 %} 10958 10959 // This pattern is automatically generated from aarch64_ad.m4 10960 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10961 instruct XorL_reg_not_reg(iRegLNoSp dst, 10962 iRegL src1, iRegL src2, immL_M1 m1, 10963 rFlagsReg cr) %{ 10964 match(Set dst (XorL m1 (XorL src2 src1))); 10965 ins_cost(INSN_COST); 10966 format %{ "eon $dst, $src1, $src2" %} 10967 10968 ins_encode %{ 10969 __ eon(as_Register($dst$$reg), 10970 as_Register($src1$$reg), 10971 as_Register($src2$$reg), 10972 Assembler::LSL, 0); 10973 %} 10974 10975 ins_pipe(ialu_reg_reg); 10976 %} 10977 10978 // This pattern is automatically generated from aarch64_ad.m4 10979 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10980 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10981 iRegIorL2I src1, iRegIorL2I src2, 10982 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10983 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10984 ins_cost(1.9 * INSN_COST); 10985 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10986 10987 ins_encode %{ 10988 __ bicw(as_Register($dst$$reg), 10989 as_Register($src1$$reg), 10990 as_Register($src2$$reg), 10991 Assembler::LSR, 10992 $src3$$constant & 0x1f); 10993 %} 10994 10995 ins_pipe(ialu_reg_reg_shift); 10996 %} 10997 10998 // This pattern is automatically generated from aarch64_ad.m4 10999 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11000 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11001 iRegL src1, iRegL src2, 11002 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11003 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11004 ins_cost(1.9 * INSN_COST); 11005 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11006 11007 ins_encode %{ 11008 __ bic(as_Register($dst$$reg), 11009 as_Register($src1$$reg), 11010 as_Register($src2$$reg), 11011 Assembler::LSR, 11012 $src3$$constant & 0x3f); 11013 %} 11014 11015 ins_pipe(ialu_reg_reg_shift); 11016 %} 11017 11018 // This pattern is automatically generated from aarch64_ad.m4 11019 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11020 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11021 iRegIorL2I src1, iRegIorL2I src2, 11022 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11023 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11024 ins_cost(1.9 * INSN_COST); 11025 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11026 11027 ins_encode %{ 11028 __ bicw(as_Register($dst$$reg), 11029 as_Register($src1$$reg), 11030 as_Register($src2$$reg), 11031 Assembler::ASR, 11032 $src3$$constant & 0x1f); 11033 %} 11034 11035 ins_pipe(ialu_reg_reg_shift); 11036 %} 11037 11038 // This pattern is automatically generated from aarch64_ad.m4 11039 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11040 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11041 iRegL src1, iRegL src2, 11042 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11043 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11044 ins_cost(1.9 * INSN_COST); 11045 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11046 11047 ins_encode %{ 11048 __ bic(as_Register($dst$$reg), 11049 as_Register($src1$$reg), 11050 as_Register($src2$$reg), 11051 Assembler::ASR, 11052 $src3$$constant & 0x3f); 11053 %} 11054 11055 ins_pipe(ialu_reg_reg_shift); 11056 %} 11057 11058 // This pattern is automatically generated from aarch64_ad.m4 11059 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11060 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11061 iRegIorL2I src1, iRegIorL2I src2, 11062 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11063 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11064 ins_cost(1.9 * INSN_COST); 11065 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11066 11067 ins_encode %{ 11068 __ bicw(as_Register($dst$$reg), 11069 as_Register($src1$$reg), 11070 as_Register($src2$$reg), 11071 Assembler::LSL, 11072 $src3$$constant & 0x1f); 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 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11081 iRegL src1, iRegL src2, 11082 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11083 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11084 ins_cost(1.9 * INSN_COST); 11085 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11086 11087 ins_encode %{ 11088 __ bic(as_Register($dst$$reg), 11089 as_Register($src1$$reg), 11090 as_Register($src2$$reg), 11091 Assembler::LSL, 11092 $src3$$constant & 0x3f); 11093 %} 11094 11095 ins_pipe(ialu_reg_reg_shift); 11096 %} 11097 11098 // This pattern is automatically generated from aarch64_ad.m4 11099 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11100 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11101 iRegIorL2I src1, iRegIorL2I src2, 11102 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11103 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11104 ins_cost(1.9 * INSN_COST); 11105 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11106 11107 ins_encode %{ 11108 __ eonw(as_Register($dst$$reg), 11109 as_Register($src1$$reg), 11110 as_Register($src2$$reg), 11111 Assembler::LSR, 11112 $src3$$constant & 0x1f); 11113 %} 11114 11115 ins_pipe(ialu_reg_reg_shift); 11116 %} 11117 11118 // This pattern is automatically generated from aarch64_ad.m4 11119 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11120 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11121 iRegL src1, iRegL src2, 11122 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11123 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11124 ins_cost(1.9 * INSN_COST); 11125 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11126 11127 ins_encode %{ 11128 __ eon(as_Register($dst$$reg), 11129 as_Register($src1$$reg), 11130 as_Register($src2$$reg), 11131 Assembler::LSR, 11132 $src3$$constant & 0x3f); 11133 %} 11134 11135 ins_pipe(ialu_reg_reg_shift); 11136 %} 11137 11138 // This pattern is automatically generated from aarch64_ad.m4 11139 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11140 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11141 iRegIorL2I src1, iRegIorL2I src2, 11142 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11143 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11144 ins_cost(1.9 * INSN_COST); 11145 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11146 11147 ins_encode %{ 11148 __ eonw(as_Register($dst$$reg), 11149 as_Register($src1$$reg), 11150 as_Register($src2$$reg), 11151 Assembler::ASR, 11152 $src3$$constant & 0x1f); 11153 %} 11154 11155 ins_pipe(ialu_reg_reg_shift); 11156 %} 11157 11158 // This pattern is automatically generated from aarch64_ad.m4 11159 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11160 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11161 iRegL src1, iRegL src2, 11162 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11163 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11164 ins_cost(1.9 * INSN_COST); 11165 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11166 11167 ins_encode %{ 11168 __ eon(as_Register($dst$$reg), 11169 as_Register($src1$$reg), 11170 as_Register($src2$$reg), 11171 Assembler::ASR, 11172 $src3$$constant & 0x3f); 11173 %} 11174 11175 ins_pipe(ialu_reg_reg_shift); 11176 %} 11177 11178 // This pattern is automatically generated from aarch64_ad.m4 11179 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11180 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11181 iRegIorL2I src1, iRegIorL2I src2, 11182 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11183 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11184 ins_cost(1.9 * INSN_COST); 11185 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11186 11187 ins_encode %{ 11188 __ eonw(as_Register($dst$$reg), 11189 as_Register($src1$$reg), 11190 as_Register($src2$$reg), 11191 Assembler::LSL, 11192 $src3$$constant & 0x1f); 11193 %} 11194 11195 ins_pipe(ialu_reg_reg_shift); 11196 %} 11197 11198 // This pattern is automatically generated from aarch64_ad.m4 11199 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11200 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11201 iRegL src1, iRegL src2, 11202 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11203 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11204 ins_cost(1.9 * INSN_COST); 11205 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11206 11207 ins_encode %{ 11208 __ eon(as_Register($dst$$reg), 11209 as_Register($src1$$reg), 11210 as_Register($src2$$reg), 11211 Assembler::LSL, 11212 $src3$$constant & 0x3f); 11213 %} 11214 11215 ins_pipe(ialu_reg_reg_shift); 11216 %} 11217 11218 // This pattern is automatically generated from aarch64_ad.m4 11219 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11220 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11221 iRegIorL2I src1, iRegIorL2I src2, 11222 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11223 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11224 ins_cost(1.9 * INSN_COST); 11225 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11226 11227 ins_encode %{ 11228 __ ornw(as_Register($dst$$reg), 11229 as_Register($src1$$reg), 11230 as_Register($src2$$reg), 11231 Assembler::LSR, 11232 $src3$$constant & 0x1f); 11233 %} 11234 11235 ins_pipe(ialu_reg_reg_shift); 11236 %} 11237 11238 // This pattern is automatically generated from aarch64_ad.m4 11239 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11240 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11241 iRegL src1, iRegL src2, 11242 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11243 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11244 ins_cost(1.9 * INSN_COST); 11245 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11246 11247 ins_encode %{ 11248 __ orn(as_Register($dst$$reg), 11249 as_Register($src1$$reg), 11250 as_Register($src2$$reg), 11251 Assembler::LSR, 11252 $src3$$constant & 0x3f); 11253 %} 11254 11255 ins_pipe(ialu_reg_reg_shift); 11256 %} 11257 11258 // This pattern is automatically generated from aarch64_ad.m4 11259 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11260 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11261 iRegIorL2I src1, iRegIorL2I src2, 11262 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11263 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11264 ins_cost(1.9 * INSN_COST); 11265 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11266 11267 ins_encode %{ 11268 __ ornw(as_Register($dst$$reg), 11269 as_Register($src1$$reg), 11270 as_Register($src2$$reg), 11271 Assembler::ASR, 11272 $src3$$constant & 0x1f); 11273 %} 11274 11275 ins_pipe(ialu_reg_reg_shift); 11276 %} 11277 11278 // This pattern is automatically generated from aarch64_ad.m4 11279 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11280 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11281 iRegL src1, iRegL src2, 11282 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11283 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11284 ins_cost(1.9 * INSN_COST); 11285 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11286 11287 ins_encode %{ 11288 __ orn(as_Register($dst$$reg), 11289 as_Register($src1$$reg), 11290 as_Register($src2$$reg), 11291 Assembler::ASR, 11292 $src3$$constant & 0x3f); 11293 %} 11294 11295 ins_pipe(ialu_reg_reg_shift); 11296 %} 11297 11298 // This pattern is automatically generated from aarch64_ad.m4 11299 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11300 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11301 iRegIorL2I src1, iRegIorL2I src2, 11302 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11303 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11304 ins_cost(1.9 * INSN_COST); 11305 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11306 11307 ins_encode %{ 11308 __ ornw(as_Register($dst$$reg), 11309 as_Register($src1$$reg), 11310 as_Register($src2$$reg), 11311 Assembler::LSL, 11312 $src3$$constant & 0x1f); 11313 %} 11314 11315 ins_pipe(ialu_reg_reg_shift); 11316 %} 11317 11318 // This pattern is automatically generated from aarch64_ad.m4 11319 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11320 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11321 iRegL src1, iRegL src2, 11322 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11323 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11324 ins_cost(1.9 * INSN_COST); 11325 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11326 11327 ins_encode %{ 11328 __ orn(as_Register($dst$$reg), 11329 as_Register($src1$$reg), 11330 as_Register($src2$$reg), 11331 Assembler::LSL, 11332 $src3$$constant & 0x3f); 11333 %} 11334 11335 ins_pipe(ialu_reg_reg_shift); 11336 %} 11337 11338 // This pattern is automatically generated from aarch64_ad.m4 11339 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11340 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11341 iRegIorL2I src1, iRegIorL2I src2, 11342 immI src3, rFlagsReg cr) %{ 11343 match(Set dst (AndI src1 (URShiftI src2 src3))); 11344 11345 ins_cost(1.9 * INSN_COST); 11346 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11347 11348 ins_encode %{ 11349 __ andw(as_Register($dst$$reg), 11350 as_Register($src1$$reg), 11351 as_Register($src2$$reg), 11352 Assembler::LSR, 11353 $src3$$constant & 0x1f); 11354 %} 11355 11356 ins_pipe(ialu_reg_reg_shift); 11357 %} 11358 11359 // This pattern is automatically generated from aarch64_ad.m4 11360 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11361 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11362 iRegL src1, iRegL src2, 11363 immI src3, rFlagsReg cr) %{ 11364 match(Set dst (AndL src1 (URShiftL src2 src3))); 11365 11366 ins_cost(1.9 * INSN_COST); 11367 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11368 11369 ins_encode %{ 11370 __ andr(as_Register($dst$$reg), 11371 as_Register($src1$$reg), 11372 as_Register($src2$$reg), 11373 Assembler::LSR, 11374 $src3$$constant & 0x3f); 11375 %} 11376 11377 ins_pipe(ialu_reg_reg_shift); 11378 %} 11379 11380 // This pattern is automatically generated from aarch64_ad.m4 11381 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11382 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11383 iRegIorL2I src1, iRegIorL2I src2, 11384 immI src3, rFlagsReg cr) %{ 11385 match(Set dst (AndI src1 (RShiftI src2 src3))); 11386 11387 ins_cost(1.9 * INSN_COST); 11388 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11389 11390 ins_encode %{ 11391 __ andw(as_Register($dst$$reg), 11392 as_Register($src1$$reg), 11393 as_Register($src2$$reg), 11394 Assembler::ASR, 11395 $src3$$constant & 0x1f); 11396 %} 11397 11398 ins_pipe(ialu_reg_reg_shift); 11399 %} 11400 11401 // This pattern is automatically generated from aarch64_ad.m4 11402 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11403 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11404 iRegL src1, iRegL src2, 11405 immI src3, rFlagsReg cr) %{ 11406 match(Set dst (AndL src1 (RShiftL src2 src3))); 11407 11408 ins_cost(1.9 * INSN_COST); 11409 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11410 11411 ins_encode %{ 11412 __ andr(as_Register($dst$$reg), 11413 as_Register($src1$$reg), 11414 as_Register($src2$$reg), 11415 Assembler::ASR, 11416 $src3$$constant & 0x3f); 11417 %} 11418 11419 ins_pipe(ialu_reg_reg_shift); 11420 %} 11421 11422 // This pattern is automatically generated from aarch64_ad.m4 11423 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11424 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11425 iRegIorL2I src1, iRegIorL2I src2, 11426 immI src3, rFlagsReg cr) %{ 11427 match(Set dst (AndI src1 (LShiftI src2 src3))); 11428 11429 ins_cost(1.9 * INSN_COST); 11430 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11431 11432 ins_encode %{ 11433 __ andw(as_Register($dst$$reg), 11434 as_Register($src1$$reg), 11435 as_Register($src2$$reg), 11436 Assembler::LSL, 11437 $src3$$constant & 0x1f); 11438 %} 11439 11440 ins_pipe(ialu_reg_reg_shift); 11441 %} 11442 11443 // This pattern is automatically generated from aarch64_ad.m4 11444 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11445 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11446 iRegL src1, iRegL src2, 11447 immI src3, rFlagsReg cr) %{ 11448 match(Set dst (AndL src1 (LShiftL src2 src3))); 11449 11450 ins_cost(1.9 * INSN_COST); 11451 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11452 11453 ins_encode %{ 11454 __ andr(as_Register($dst$$reg), 11455 as_Register($src1$$reg), 11456 as_Register($src2$$reg), 11457 Assembler::LSL, 11458 $src3$$constant & 0x3f); 11459 %} 11460 11461 ins_pipe(ialu_reg_reg_shift); 11462 %} 11463 11464 // This pattern is automatically generated from aarch64_ad.m4 11465 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11466 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11467 iRegIorL2I src1, iRegIorL2I src2, 11468 immI src3, rFlagsReg cr) %{ 11469 match(Set dst (XorI src1 (URShiftI src2 src3))); 11470 11471 ins_cost(1.9 * INSN_COST); 11472 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11473 11474 ins_encode %{ 11475 __ eorw(as_Register($dst$$reg), 11476 as_Register($src1$$reg), 11477 as_Register($src2$$reg), 11478 Assembler::LSR, 11479 $src3$$constant & 0x1f); 11480 %} 11481 11482 ins_pipe(ialu_reg_reg_shift); 11483 %} 11484 11485 // This pattern is automatically generated from aarch64_ad.m4 11486 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11487 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11488 iRegL src1, iRegL src2, 11489 immI src3, rFlagsReg cr) %{ 11490 match(Set dst (XorL src1 (URShiftL src2 src3))); 11491 11492 ins_cost(1.9 * INSN_COST); 11493 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11494 11495 ins_encode %{ 11496 __ eor(as_Register($dst$$reg), 11497 as_Register($src1$$reg), 11498 as_Register($src2$$reg), 11499 Assembler::LSR, 11500 $src3$$constant & 0x3f); 11501 %} 11502 11503 ins_pipe(ialu_reg_reg_shift); 11504 %} 11505 11506 // This pattern is automatically generated from aarch64_ad.m4 11507 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11508 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11509 iRegIorL2I src1, iRegIorL2I src2, 11510 immI src3, rFlagsReg cr) %{ 11511 match(Set dst (XorI src1 (RShiftI src2 src3))); 11512 11513 ins_cost(1.9 * INSN_COST); 11514 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11515 11516 ins_encode %{ 11517 __ eorw(as_Register($dst$$reg), 11518 as_Register($src1$$reg), 11519 as_Register($src2$$reg), 11520 Assembler::ASR, 11521 $src3$$constant & 0x1f); 11522 %} 11523 11524 ins_pipe(ialu_reg_reg_shift); 11525 %} 11526 11527 // This pattern is automatically generated from aarch64_ad.m4 11528 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11529 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11530 iRegL src1, iRegL src2, 11531 immI src3, rFlagsReg cr) %{ 11532 match(Set dst (XorL src1 (RShiftL src2 src3))); 11533 11534 ins_cost(1.9 * INSN_COST); 11535 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11536 11537 ins_encode %{ 11538 __ eor(as_Register($dst$$reg), 11539 as_Register($src1$$reg), 11540 as_Register($src2$$reg), 11541 Assembler::ASR, 11542 $src3$$constant & 0x3f); 11543 %} 11544 11545 ins_pipe(ialu_reg_reg_shift); 11546 %} 11547 11548 // This pattern is automatically generated from aarch64_ad.m4 11549 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11550 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11551 iRegIorL2I src1, iRegIorL2I src2, 11552 immI src3, rFlagsReg cr) %{ 11553 match(Set dst (XorI src1 (LShiftI src2 src3))); 11554 11555 ins_cost(1.9 * INSN_COST); 11556 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11557 11558 ins_encode %{ 11559 __ eorw(as_Register($dst$$reg), 11560 as_Register($src1$$reg), 11561 as_Register($src2$$reg), 11562 Assembler::LSL, 11563 $src3$$constant & 0x1f); 11564 %} 11565 11566 ins_pipe(ialu_reg_reg_shift); 11567 %} 11568 11569 // This pattern is automatically generated from aarch64_ad.m4 11570 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11571 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11572 iRegL src1, iRegL src2, 11573 immI src3, rFlagsReg cr) %{ 11574 match(Set dst (XorL src1 (LShiftL src2 src3))); 11575 11576 ins_cost(1.9 * INSN_COST); 11577 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11578 11579 ins_encode %{ 11580 __ eor(as_Register($dst$$reg), 11581 as_Register($src1$$reg), 11582 as_Register($src2$$reg), 11583 Assembler::LSL, 11584 $src3$$constant & 0x3f); 11585 %} 11586 11587 ins_pipe(ialu_reg_reg_shift); 11588 %} 11589 11590 // This pattern is automatically generated from aarch64_ad.m4 11591 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11592 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11593 iRegIorL2I src1, iRegIorL2I src2, 11594 immI src3, rFlagsReg cr) %{ 11595 match(Set dst (OrI src1 (URShiftI src2 src3))); 11596 11597 ins_cost(1.9 * INSN_COST); 11598 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11599 11600 ins_encode %{ 11601 __ orrw(as_Register($dst$$reg), 11602 as_Register($src1$$reg), 11603 as_Register($src2$$reg), 11604 Assembler::LSR, 11605 $src3$$constant & 0x1f); 11606 %} 11607 11608 ins_pipe(ialu_reg_reg_shift); 11609 %} 11610 11611 // This pattern is automatically generated from aarch64_ad.m4 11612 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11613 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11614 iRegL src1, iRegL src2, 11615 immI src3, rFlagsReg cr) %{ 11616 match(Set dst (OrL src1 (URShiftL src2 src3))); 11617 11618 ins_cost(1.9 * INSN_COST); 11619 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11620 11621 ins_encode %{ 11622 __ orr(as_Register($dst$$reg), 11623 as_Register($src1$$reg), 11624 as_Register($src2$$reg), 11625 Assembler::LSR, 11626 $src3$$constant & 0x3f); 11627 %} 11628 11629 ins_pipe(ialu_reg_reg_shift); 11630 %} 11631 11632 // This pattern is automatically generated from aarch64_ad.m4 11633 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11634 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11635 iRegIorL2I src1, iRegIorL2I src2, 11636 immI src3, rFlagsReg cr) %{ 11637 match(Set dst (OrI src1 (RShiftI src2 src3))); 11638 11639 ins_cost(1.9 * INSN_COST); 11640 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11641 11642 ins_encode %{ 11643 __ orrw(as_Register($dst$$reg), 11644 as_Register($src1$$reg), 11645 as_Register($src2$$reg), 11646 Assembler::ASR, 11647 $src3$$constant & 0x1f); 11648 %} 11649 11650 ins_pipe(ialu_reg_reg_shift); 11651 %} 11652 11653 // This pattern is automatically generated from aarch64_ad.m4 11654 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11655 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11656 iRegL src1, iRegL src2, 11657 immI src3, rFlagsReg cr) %{ 11658 match(Set dst (OrL src1 (RShiftL src2 src3))); 11659 11660 ins_cost(1.9 * INSN_COST); 11661 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11662 11663 ins_encode %{ 11664 __ orr(as_Register($dst$$reg), 11665 as_Register($src1$$reg), 11666 as_Register($src2$$reg), 11667 Assembler::ASR, 11668 $src3$$constant & 0x3f); 11669 %} 11670 11671 ins_pipe(ialu_reg_reg_shift); 11672 %} 11673 11674 // This pattern is automatically generated from aarch64_ad.m4 11675 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11676 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11677 iRegIorL2I src1, iRegIorL2I src2, 11678 immI src3, rFlagsReg cr) %{ 11679 match(Set dst (OrI src1 (LShiftI src2 src3))); 11680 11681 ins_cost(1.9 * INSN_COST); 11682 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11683 11684 ins_encode %{ 11685 __ orrw(as_Register($dst$$reg), 11686 as_Register($src1$$reg), 11687 as_Register($src2$$reg), 11688 Assembler::LSL, 11689 $src3$$constant & 0x1f); 11690 %} 11691 11692 ins_pipe(ialu_reg_reg_shift); 11693 %} 11694 11695 // This pattern is automatically generated from aarch64_ad.m4 11696 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11697 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11698 iRegL src1, iRegL src2, 11699 immI src3, rFlagsReg cr) %{ 11700 match(Set dst (OrL src1 (LShiftL src2 src3))); 11701 11702 ins_cost(1.9 * INSN_COST); 11703 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11704 11705 ins_encode %{ 11706 __ orr(as_Register($dst$$reg), 11707 as_Register($src1$$reg), 11708 as_Register($src2$$reg), 11709 Assembler::LSL, 11710 $src3$$constant & 0x3f); 11711 %} 11712 11713 ins_pipe(ialu_reg_reg_shift); 11714 %} 11715 11716 // This pattern is automatically generated from aarch64_ad.m4 11717 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11718 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11719 iRegIorL2I src1, iRegIorL2I src2, 11720 immI src3, rFlagsReg cr) %{ 11721 match(Set dst (AddI src1 (URShiftI src2 src3))); 11722 11723 ins_cost(1.9 * INSN_COST); 11724 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11725 11726 ins_encode %{ 11727 __ addw(as_Register($dst$$reg), 11728 as_Register($src1$$reg), 11729 as_Register($src2$$reg), 11730 Assembler::LSR, 11731 $src3$$constant & 0x1f); 11732 %} 11733 11734 ins_pipe(ialu_reg_reg_shift); 11735 %} 11736 11737 // This pattern is automatically generated from aarch64_ad.m4 11738 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11739 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11740 iRegL src1, iRegL src2, 11741 immI src3, rFlagsReg cr) %{ 11742 match(Set dst (AddL src1 (URShiftL src2 src3))); 11743 11744 ins_cost(1.9 * INSN_COST); 11745 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11746 11747 ins_encode %{ 11748 __ add(as_Register($dst$$reg), 11749 as_Register($src1$$reg), 11750 as_Register($src2$$reg), 11751 Assembler::LSR, 11752 $src3$$constant & 0x3f); 11753 %} 11754 11755 ins_pipe(ialu_reg_reg_shift); 11756 %} 11757 11758 // This pattern is automatically generated from aarch64_ad.m4 11759 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11760 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11761 iRegIorL2I src1, iRegIorL2I src2, 11762 immI src3, rFlagsReg cr) %{ 11763 match(Set dst (AddI src1 (RShiftI src2 src3))); 11764 11765 ins_cost(1.9 * INSN_COST); 11766 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11767 11768 ins_encode %{ 11769 __ addw(as_Register($dst$$reg), 11770 as_Register($src1$$reg), 11771 as_Register($src2$$reg), 11772 Assembler::ASR, 11773 $src3$$constant & 0x1f); 11774 %} 11775 11776 ins_pipe(ialu_reg_reg_shift); 11777 %} 11778 11779 // This pattern is automatically generated from aarch64_ad.m4 11780 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11781 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11782 iRegL src1, iRegL src2, 11783 immI src3, rFlagsReg cr) %{ 11784 match(Set dst (AddL src1 (RShiftL src2 src3))); 11785 11786 ins_cost(1.9 * INSN_COST); 11787 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11788 11789 ins_encode %{ 11790 __ add(as_Register($dst$$reg), 11791 as_Register($src1$$reg), 11792 as_Register($src2$$reg), 11793 Assembler::ASR, 11794 $src3$$constant & 0x3f); 11795 %} 11796 11797 ins_pipe(ialu_reg_reg_shift); 11798 %} 11799 11800 // This pattern is automatically generated from aarch64_ad.m4 11801 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11802 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11803 iRegIorL2I src1, iRegIorL2I src2, 11804 immI src3, rFlagsReg cr) %{ 11805 match(Set dst (AddI src1 (LShiftI src2 src3))); 11806 11807 ins_cost(1.9 * INSN_COST); 11808 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11809 11810 ins_encode %{ 11811 __ addw(as_Register($dst$$reg), 11812 as_Register($src1$$reg), 11813 as_Register($src2$$reg), 11814 Assembler::LSL, 11815 $src3$$constant & 0x1f); 11816 %} 11817 11818 ins_pipe(ialu_reg_reg_shift); 11819 %} 11820 11821 // This pattern is automatically generated from aarch64_ad.m4 11822 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11823 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11824 iRegL src1, iRegL src2, 11825 immI src3, rFlagsReg cr) %{ 11826 match(Set dst (AddL src1 (LShiftL src2 src3))); 11827 11828 ins_cost(1.9 * INSN_COST); 11829 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11830 11831 ins_encode %{ 11832 __ add(as_Register($dst$$reg), 11833 as_Register($src1$$reg), 11834 as_Register($src2$$reg), 11835 Assembler::LSL, 11836 $src3$$constant & 0x3f); 11837 %} 11838 11839 ins_pipe(ialu_reg_reg_shift); 11840 %} 11841 11842 // This pattern is automatically generated from aarch64_ad.m4 11843 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11844 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11845 iRegIorL2I src1, iRegIorL2I src2, 11846 immI src3, rFlagsReg cr) %{ 11847 match(Set dst (SubI src1 (URShiftI src2 src3))); 11848 11849 ins_cost(1.9 * INSN_COST); 11850 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11851 11852 ins_encode %{ 11853 __ subw(as_Register($dst$$reg), 11854 as_Register($src1$$reg), 11855 as_Register($src2$$reg), 11856 Assembler::LSR, 11857 $src3$$constant & 0x1f); 11858 %} 11859 11860 ins_pipe(ialu_reg_reg_shift); 11861 %} 11862 11863 // This pattern is automatically generated from aarch64_ad.m4 11864 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11865 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11866 iRegL src1, iRegL src2, 11867 immI src3, rFlagsReg cr) %{ 11868 match(Set dst (SubL src1 (URShiftL src2 src3))); 11869 11870 ins_cost(1.9 * INSN_COST); 11871 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11872 11873 ins_encode %{ 11874 __ sub(as_Register($dst$$reg), 11875 as_Register($src1$$reg), 11876 as_Register($src2$$reg), 11877 Assembler::LSR, 11878 $src3$$constant & 0x3f); 11879 %} 11880 11881 ins_pipe(ialu_reg_reg_shift); 11882 %} 11883 11884 // This pattern is automatically generated from aarch64_ad.m4 11885 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11886 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11887 iRegIorL2I src1, iRegIorL2I src2, 11888 immI src3, rFlagsReg cr) %{ 11889 match(Set dst (SubI src1 (RShiftI src2 src3))); 11890 11891 ins_cost(1.9 * INSN_COST); 11892 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11893 11894 ins_encode %{ 11895 __ subw(as_Register($dst$$reg), 11896 as_Register($src1$$reg), 11897 as_Register($src2$$reg), 11898 Assembler::ASR, 11899 $src3$$constant & 0x1f); 11900 %} 11901 11902 ins_pipe(ialu_reg_reg_shift); 11903 %} 11904 11905 // This pattern is automatically generated from aarch64_ad.m4 11906 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11907 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11908 iRegL src1, iRegL src2, 11909 immI src3, rFlagsReg cr) %{ 11910 match(Set dst (SubL src1 (RShiftL src2 src3))); 11911 11912 ins_cost(1.9 * INSN_COST); 11913 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11914 11915 ins_encode %{ 11916 __ sub(as_Register($dst$$reg), 11917 as_Register($src1$$reg), 11918 as_Register($src2$$reg), 11919 Assembler::ASR, 11920 $src3$$constant & 0x3f); 11921 %} 11922 11923 ins_pipe(ialu_reg_reg_shift); 11924 %} 11925 11926 // This pattern is automatically generated from aarch64_ad.m4 11927 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11928 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11929 iRegIorL2I src1, iRegIorL2I src2, 11930 immI src3, rFlagsReg cr) %{ 11931 match(Set dst (SubI src1 (LShiftI src2 src3))); 11932 11933 ins_cost(1.9 * INSN_COST); 11934 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11935 11936 ins_encode %{ 11937 __ subw(as_Register($dst$$reg), 11938 as_Register($src1$$reg), 11939 as_Register($src2$$reg), 11940 Assembler::LSL, 11941 $src3$$constant & 0x1f); 11942 %} 11943 11944 ins_pipe(ialu_reg_reg_shift); 11945 %} 11946 11947 // This pattern is automatically generated from aarch64_ad.m4 11948 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11949 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11950 iRegL src1, iRegL src2, 11951 immI src3, rFlagsReg cr) %{ 11952 match(Set dst (SubL src1 (LShiftL src2 src3))); 11953 11954 ins_cost(1.9 * INSN_COST); 11955 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11956 11957 ins_encode %{ 11958 __ sub(as_Register($dst$$reg), 11959 as_Register($src1$$reg), 11960 as_Register($src2$$reg), 11961 Assembler::LSL, 11962 $src3$$constant & 0x3f); 11963 %} 11964 11965 ins_pipe(ialu_reg_reg_shift); 11966 %} 11967 11968 11969 // This pattern is automatically generated from aarch64_ad.m4 11970 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11971 11972 // Shift Left followed by Shift Right. 11973 // This idiom is used by the compiler for the i2b bytecode etc. 11974 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11975 %{ 11976 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11977 ins_cost(INSN_COST * 2); 11978 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11979 ins_encode %{ 11980 int lshift = $lshift_count$$constant & 63; 11981 int rshift = $rshift_count$$constant & 63; 11982 int s = 63 - lshift; 11983 int r = (rshift - lshift) & 63; 11984 __ sbfm(as_Register($dst$$reg), 11985 as_Register($src$$reg), 11986 r, s); 11987 %} 11988 11989 ins_pipe(ialu_reg_shift); 11990 %} 11991 11992 // This pattern is automatically generated from aarch64_ad.m4 11993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11994 11995 // Shift Left followed by Shift Right. 11996 // This idiom is used by the compiler for the i2b bytecode etc. 11997 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11998 %{ 11999 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12000 ins_cost(INSN_COST * 2); 12001 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12002 ins_encode %{ 12003 int lshift = $lshift_count$$constant & 31; 12004 int rshift = $rshift_count$$constant & 31; 12005 int s = 31 - lshift; 12006 int r = (rshift - lshift) & 31; 12007 __ sbfmw(as_Register($dst$$reg), 12008 as_Register($src$$reg), 12009 r, s); 12010 %} 12011 12012 ins_pipe(ialu_reg_shift); 12013 %} 12014 12015 // This pattern is automatically generated from aarch64_ad.m4 12016 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12017 12018 // Shift Left followed by Shift Right. 12019 // This idiom is used by the compiler for the i2b bytecode etc. 12020 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12021 %{ 12022 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12023 ins_cost(INSN_COST * 2); 12024 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12025 ins_encode %{ 12026 int lshift = $lshift_count$$constant & 63; 12027 int rshift = $rshift_count$$constant & 63; 12028 int s = 63 - lshift; 12029 int r = (rshift - lshift) & 63; 12030 __ ubfm(as_Register($dst$$reg), 12031 as_Register($src$$reg), 12032 r, s); 12033 %} 12034 12035 ins_pipe(ialu_reg_shift); 12036 %} 12037 12038 // This pattern is automatically generated from aarch64_ad.m4 12039 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12040 12041 // Shift Left followed by Shift Right. 12042 // This idiom is used by the compiler for the i2b bytecode etc. 12043 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12044 %{ 12045 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12046 ins_cost(INSN_COST * 2); 12047 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12048 ins_encode %{ 12049 int lshift = $lshift_count$$constant & 31; 12050 int rshift = $rshift_count$$constant & 31; 12051 int s = 31 - lshift; 12052 int r = (rshift - lshift) & 31; 12053 __ ubfmw(as_Register($dst$$reg), 12054 as_Register($src$$reg), 12055 r, s); 12056 %} 12057 12058 ins_pipe(ialu_reg_shift); 12059 %} 12060 12061 // Bitfield extract with shift & mask 12062 12063 // This pattern is automatically generated from aarch64_ad.m4 12064 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12065 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12066 %{ 12067 match(Set dst (AndI (URShiftI src rshift) mask)); 12068 // Make sure we are not going to exceed what ubfxw can do. 12069 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12070 12071 ins_cost(INSN_COST); 12072 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12073 ins_encode %{ 12074 int rshift = $rshift$$constant & 31; 12075 intptr_t mask = $mask$$constant; 12076 int width = exact_log2(mask+1); 12077 __ ubfxw(as_Register($dst$$reg), 12078 as_Register($src$$reg), rshift, width); 12079 %} 12080 ins_pipe(ialu_reg_shift); 12081 %} 12082 12083 // This pattern is automatically generated from aarch64_ad.m4 12084 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12085 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12086 %{ 12087 match(Set dst (AndL (URShiftL src rshift) mask)); 12088 // Make sure we are not going to exceed what ubfx can do. 12089 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12090 12091 ins_cost(INSN_COST); 12092 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12093 ins_encode %{ 12094 int rshift = $rshift$$constant & 63; 12095 intptr_t mask = $mask$$constant; 12096 int width = exact_log2_long(mask+1); 12097 __ ubfx(as_Register($dst$$reg), 12098 as_Register($src$$reg), rshift, width); 12099 %} 12100 ins_pipe(ialu_reg_shift); 12101 %} 12102 12103 12104 // This pattern is automatically generated from aarch64_ad.m4 12105 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12106 12107 // We can use ubfx when extending an And with a mask when we know mask 12108 // is positive. We know that because immI_bitmask guarantees it. 12109 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12110 %{ 12111 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12112 // Make sure we are not going to exceed what ubfxw can do. 12113 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12114 12115 ins_cost(INSN_COST * 2); 12116 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12117 ins_encode %{ 12118 int rshift = $rshift$$constant & 31; 12119 intptr_t mask = $mask$$constant; 12120 int width = exact_log2(mask+1); 12121 __ ubfx(as_Register($dst$$reg), 12122 as_Register($src$$reg), rshift, width); 12123 %} 12124 ins_pipe(ialu_reg_shift); 12125 %} 12126 12127 12128 // This pattern is automatically generated from aarch64_ad.m4 12129 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12130 12131 // We can use ubfiz when masking by a positive number and then left shifting the result. 12132 // We know that the mask is positive because immI_bitmask guarantees it. 12133 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12134 %{ 12135 match(Set dst (LShiftI (AndI src mask) lshift)); 12136 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12137 12138 ins_cost(INSN_COST); 12139 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12140 ins_encode %{ 12141 int lshift = $lshift$$constant & 31; 12142 intptr_t mask = $mask$$constant; 12143 int width = exact_log2(mask+1); 12144 __ ubfizw(as_Register($dst$$reg), 12145 as_Register($src$$reg), lshift, width); 12146 %} 12147 ins_pipe(ialu_reg_shift); 12148 %} 12149 12150 // This pattern is automatically generated from aarch64_ad.m4 12151 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12152 12153 // We can use ubfiz when masking by a positive number and then left shifting the result. 12154 // We know that the mask is positive because immL_bitmask guarantees it. 12155 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12156 %{ 12157 match(Set dst (LShiftL (AndL src mask) lshift)); 12158 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12159 12160 ins_cost(INSN_COST); 12161 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12162 ins_encode %{ 12163 int lshift = $lshift$$constant & 63; 12164 intptr_t mask = $mask$$constant; 12165 int width = exact_log2_long(mask+1); 12166 __ ubfiz(as_Register($dst$$reg), 12167 as_Register($src$$reg), lshift, width); 12168 %} 12169 ins_pipe(ialu_reg_shift); 12170 %} 12171 12172 // This pattern is automatically generated from aarch64_ad.m4 12173 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12174 12175 // We can use ubfiz when masking by a positive number and then left shifting the result. 12176 // We know that the mask is positive because immI_bitmask guarantees it. 12177 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12178 %{ 12179 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12180 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12181 12182 ins_cost(INSN_COST); 12183 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12184 ins_encode %{ 12185 int lshift = $lshift$$constant & 31; 12186 intptr_t mask = $mask$$constant; 12187 int width = exact_log2(mask+1); 12188 __ ubfizw(as_Register($dst$$reg), 12189 as_Register($src$$reg), lshift, width); 12190 %} 12191 ins_pipe(ialu_reg_shift); 12192 %} 12193 12194 // This pattern is automatically generated from aarch64_ad.m4 12195 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12196 12197 // We can use ubfiz when masking by a positive number and then left shifting the result. 12198 // We know that the mask is positive because immL_bitmask guarantees it. 12199 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12200 %{ 12201 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12202 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12203 12204 ins_cost(INSN_COST); 12205 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12206 ins_encode %{ 12207 int lshift = $lshift$$constant & 63; 12208 intptr_t mask = $mask$$constant; 12209 int width = exact_log2_long(mask+1); 12210 __ ubfiz(as_Register($dst$$reg), 12211 as_Register($src$$reg), lshift, width); 12212 %} 12213 ins_pipe(ialu_reg_shift); 12214 %} 12215 12216 12217 // This pattern is automatically generated from aarch64_ad.m4 12218 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12219 12220 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12221 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12222 %{ 12223 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12224 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12225 12226 ins_cost(INSN_COST); 12227 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12228 ins_encode %{ 12229 int lshift = $lshift$$constant & 63; 12230 intptr_t mask = $mask$$constant; 12231 int width = exact_log2(mask+1); 12232 __ ubfiz(as_Register($dst$$reg), 12233 as_Register($src$$reg), lshift, width); 12234 %} 12235 ins_pipe(ialu_reg_shift); 12236 %} 12237 12238 // This pattern is automatically generated from aarch64_ad.m4 12239 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12240 12241 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12242 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12243 %{ 12244 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12245 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12246 12247 ins_cost(INSN_COST); 12248 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12249 ins_encode %{ 12250 int lshift = $lshift$$constant & 31; 12251 intptr_t mask = $mask$$constant; 12252 int width = exact_log2(mask+1); 12253 __ ubfiz(as_Register($dst$$reg), 12254 as_Register($src$$reg), lshift, width); 12255 %} 12256 ins_pipe(ialu_reg_shift); 12257 %} 12258 12259 // This pattern is automatically generated from aarch64_ad.m4 12260 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12261 12262 // Can skip int2long conversions after AND with small bitmask 12263 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12264 %{ 12265 match(Set dst (ConvI2L (AndI src msk))); 12266 ins_cost(INSN_COST); 12267 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12268 ins_encode %{ 12269 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12270 %} 12271 ins_pipe(ialu_reg_shift); 12272 %} 12273 12274 12275 // Rotations 12276 // This pattern is automatically generated from aarch64_ad.m4 12277 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12278 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12279 %{ 12280 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12281 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12282 12283 ins_cost(INSN_COST); 12284 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12285 12286 ins_encode %{ 12287 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12288 $rshift$$constant & 63); 12289 %} 12290 ins_pipe(ialu_reg_reg_extr); 12291 %} 12292 12293 12294 // This pattern is automatically generated from aarch64_ad.m4 12295 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12296 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12297 %{ 12298 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12299 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12300 12301 ins_cost(INSN_COST); 12302 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12303 12304 ins_encode %{ 12305 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12306 $rshift$$constant & 31); 12307 %} 12308 ins_pipe(ialu_reg_reg_extr); 12309 %} 12310 12311 12312 // This pattern is automatically generated from aarch64_ad.m4 12313 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12314 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12315 %{ 12316 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12317 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12318 12319 ins_cost(INSN_COST); 12320 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12321 12322 ins_encode %{ 12323 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12324 $rshift$$constant & 63); 12325 %} 12326 ins_pipe(ialu_reg_reg_extr); 12327 %} 12328 12329 12330 // This pattern is automatically generated from aarch64_ad.m4 12331 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12332 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12333 %{ 12334 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12335 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12336 12337 ins_cost(INSN_COST); 12338 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12339 12340 ins_encode %{ 12341 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12342 $rshift$$constant & 31); 12343 %} 12344 ins_pipe(ialu_reg_reg_extr); 12345 %} 12346 12347 12348 // This pattern is automatically generated from aarch64_ad.m4 12349 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12350 12351 // rol expander 12352 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12353 %{ 12354 effect(DEF dst, USE src, USE shift); 12355 12356 format %{ "rol $dst, $src, $shift" %} 12357 ins_cost(INSN_COST * 3); 12358 ins_encode %{ 12359 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12360 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12361 rscratch1); 12362 %} 12363 ins_pipe(ialu_reg_reg_vshift); 12364 %} 12365 12366 // This pattern is automatically generated from aarch64_ad.m4 12367 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12368 12369 // rol expander 12370 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12371 %{ 12372 effect(DEF dst, USE src, USE shift); 12373 12374 format %{ "rol $dst, $src, $shift" %} 12375 ins_cost(INSN_COST * 3); 12376 ins_encode %{ 12377 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12378 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12379 rscratch1); 12380 %} 12381 ins_pipe(ialu_reg_reg_vshift); 12382 %} 12383 12384 // This pattern is automatically generated from aarch64_ad.m4 12385 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12386 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12387 %{ 12388 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12389 12390 expand %{ 12391 rolL_rReg(dst, src, shift, cr); 12392 %} 12393 %} 12394 12395 // This pattern is automatically generated from aarch64_ad.m4 12396 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12397 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12398 %{ 12399 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12400 12401 expand %{ 12402 rolL_rReg(dst, src, shift, cr); 12403 %} 12404 %} 12405 12406 // This pattern is automatically generated from aarch64_ad.m4 12407 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12408 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12409 %{ 12410 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12411 12412 expand %{ 12413 rolI_rReg(dst, src, shift, cr); 12414 %} 12415 %} 12416 12417 // This pattern is automatically generated from aarch64_ad.m4 12418 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12419 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12420 %{ 12421 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12422 12423 expand %{ 12424 rolI_rReg(dst, src, shift, cr); 12425 %} 12426 %} 12427 12428 // This pattern is automatically generated from aarch64_ad.m4 12429 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12430 12431 // ror expander 12432 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12433 %{ 12434 effect(DEF dst, USE src, USE shift); 12435 12436 format %{ "ror $dst, $src, $shift" %} 12437 ins_cost(INSN_COST); 12438 ins_encode %{ 12439 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12440 as_Register($shift$$reg)); 12441 %} 12442 ins_pipe(ialu_reg_reg_vshift); 12443 %} 12444 12445 // This pattern is automatically generated from aarch64_ad.m4 12446 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12447 12448 // ror expander 12449 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12450 %{ 12451 effect(DEF dst, USE src, USE shift); 12452 12453 format %{ "ror $dst, $src, $shift" %} 12454 ins_cost(INSN_COST); 12455 ins_encode %{ 12456 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12457 as_Register($shift$$reg)); 12458 %} 12459 ins_pipe(ialu_reg_reg_vshift); 12460 %} 12461 12462 // This pattern is automatically generated from aarch64_ad.m4 12463 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12464 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12465 %{ 12466 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12467 12468 expand %{ 12469 rorL_rReg(dst, src, shift, cr); 12470 %} 12471 %} 12472 12473 // This pattern is automatically generated from aarch64_ad.m4 12474 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12475 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12476 %{ 12477 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12478 12479 expand %{ 12480 rorL_rReg(dst, src, shift, cr); 12481 %} 12482 %} 12483 12484 // This pattern is automatically generated from aarch64_ad.m4 12485 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12486 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12487 %{ 12488 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12489 12490 expand %{ 12491 rorI_rReg(dst, src, shift, cr); 12492 %} 12493 %} 12494 12495 // This pattern is automatically generated from aarch64_ad.m4 12496 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12497 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12498 %{ 12499 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12500 12501 expand %{ 12502 rorI_rReg(dst, src, shift, cr); 12503 %} 12504 %} 12505 12506 12507 // Add/subtract (extended) 12508 12509 // This pattern is automatically generated from aarch64_ad.m4 12510 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12511 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12512 %{ 12513 match(Set dst (AddL src1 (ConvI2L src2))); 12514 ins_cost(INSN_COST); 12515 format %{ "add $dst, $src1, $src2, sxtw" %} 12516 12517 ins_encode %{ 12518 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12519 as_Register($src2$$reg), ext::sxtw); 12520 %} 12521 ins_pipe(ialu_reg_reg); 12522 %} 12523 12524 // This pattern is automatically generated from aarch64_ad.m4 12525 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12526 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12527 %{ 12528 match(Set dst (SubL src1 (ConvI2L src2))); 12529 ins_cost(INSN_COST); 12530 format %{ "sub $dst, $src1, $src2, sxtw" %} 12531 12532 ins_encode %{ 12533 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12534 as_Register($src2$$reg), ext::sxtw); 12535 %} 12536 ins_pipe(ialu_reg_reg); 12537 %} 12538 12539 // This pattern is automatically generated from aarch64_ad.m4 12540 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12541 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12542 %{ 12543 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12544 ins_cost(INSN_COST); 12545 format %{ "add $dst, $src1, $src2, sxth" %} 12546 12547 ins_encode %{ 12548 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12549 as_Register($src2$$reg), ext::sxth); 12550 %} 12551 ins_pipe(ialu_reg_reg); 12552 %} 12553 12554 // This pattern is automatically generated from aarch64_ad.m4 12555 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12556 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12557 %{ 12558 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12559 ins_cost(INSN_COST); 12560 format %{ "add $dst, $src1, $src2, sxtb" %} 12561 12562 ins_encode %{ 12563 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12564 as_Register($src2$$reg), ext::sxtb); 12565 %} 12566 ins_pipe(ialu_reg_reg); 12567 %} 12568 12569 // This pattern is automatically generated from aarch64_ad.m4 12570 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12571 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12572 %{ 12573 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12574 ins_cost(INSN_COST); 12575 format %{ "add $dst, $src1, $src2, uxtb" %} 12576 12577 ins_encode %{ 12578 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12579 as_Register($src2$$reg), ext::uxtb); 12580 %} 12581 ins_pipe(ialu_reg_reg); 12582 %} 12583 12584 // This pattern is automatically generated from aarch64_ad.m4 12585 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12586 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12587 %{ 12588 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12589 ins_cost(INSN_COST); 12590 format %{ "add $dst, $src1, $src2, sxth" %} 12591 12592 ins_encode %{ 12593 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12594 as_Register($src2$$reg), ext::sxth); 12595 %} 12596 ins_pipe(ialu_reg_reg); 12597 %} 12598 12599 // This pattern is automatically generated from aarch64_ad.m4 12600 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12601 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12602 %{ 12603 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12604 ins_cost(INSN_COST); 12605 format %{ "add $dst, $src1, $src2, sxtw" %} 12606 12607 ins_encode %{ 12608 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12609 as_Register($src2$$reg), ext::sxtw); 12610 %} 12611 ins_pipe(ialu_reg_reg); 12612 %} 12613 12614 // This pattern is automatically generated from aarch64_ad.m4 12615 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12616 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12617 %{ 12618 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12619 ins_cost(INSN_COST); 12620 format %{ "add $dst, $src1, $src2, sxtb" %} 12621 12622 ins_encode %{ 12623 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12624 as_Register($src2$$reg), ext::sxtb); 12625 %} 12626 ins_pipe(ialu_reg_reg); 12627 %} 12628 12629 // This pattern is automatically generated from aarch64_ad.m4 12630 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12631 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12632 %{ 12633 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12634 ins_cost(INSN_COST); 12635 format %{ "add $dst, $src1, $src2, uxtb" %} 12636 12637 ins_encode %{ 12638 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12639 as_Register($src2$$reg), ext::uxtb); 12640 %} 12641 ins_pipe(ialu_reg_reg); 12642 %} 12643 12644 // This pattern is automatically generated from aarch64_ad.m4 12645 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12646 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12647 %{ 12648 match(Set dst (AddI src1 (AndI src2 mask))); 12649 ins_cost(INSN_COST); 12650 format %{ "addw $dst, $src1, $src2, uxtb" %} 12651 12652 ins_encode %{ 12653 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12654 as_Register($src2$$reg), ext::uxtb); 12655 %} 12656 ins_pipe(ialu_reg_reg); 12657 %} 12658 12659 // This pattern is automatically generated from aarch64_ad.m4 12660 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12661 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12662 %{ 12663 match(Set dst (AddI src1 (AndI src2 mask))); 12664 ins_cost(INSN_COST); 12665 format %{ "addw $dst, $src1, $src2, uxth" %} 12666 12667 ins_encode %{ 12668 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12669 as_Register($src2$$reg), ext::uxth); 12670 %} 12671 ins_pipe(ialu_reg_reg); 12672 %} 12673 12674 // This pattern is automatically generated from aarch64_ad.m4 12675 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12676 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12677 %{ 12678 match(Set dst (AddL src1 (AndL src2 mask))); 12679 ins_cost(INSN_COST); 12680 format %{ "add $dst, $src1, $src2, uxtb" %} 12681 12682 ins_encode %{ 12683 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12684 as_Register($src2$$reg), ext::uxtb); 12685 %} 12686 ins_pipe(ialu_reg_reg); 12687 %} 12688 12689 // This pattern is automatically generated from aarch64_ad.m4 12690 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12691 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12692 %{ 12693 match(Set dst (AddL src1 (AndL src2 mask))); 12694 ins_cost(INSN_COST); 12695 format %{ "add $dst, $src1, $src2, uxth" %} 12696 12697 ins_encode %{ 12698 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12699 as_Register($src2$$reg), ext::uxth); 12700 %} 12701 ins_pipe(ialu_reg_reg); 12702 %} 12703 12704 // This pattern is automatically generated from aarch64_ad.m4 12705 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12706 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12707 %{ 12708 match(Set dst (AddL src1 (AndL src2 mask))); 12709 ins_cost(INSN_COST); 12710 format %{ "add $dst, $src1, $src2, uxtw" %} 12711 12712 ins_encode %{ 12713 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12714 as_Register($src2$$reg), ext::uxtw); 12715 %} 12716 ins_pipe(ialu_reg_reg); 12717 %} 12718 12719 // This pattern is automatically generated from aarch64_ad.m4 12720 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12721 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12722 %{ 12723 match(Set dst (SubI src1 (AndI src2 mask))); 12724 ins_cost(INSN_COST); 12725 format %{ "subw $dst, $src1, $src2, uxtb" %} 12726 12727 ins_encode %{ 12728 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12729 as_Register($src2$$reg), ext::uxtb); 12730 %} 12731 ins_pipe(ialu_reg_reg); 12732 %} 12733 12734 // This pattern is automatically generated from aarch64_ad.m4 12735 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12736 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12737 %{ 12738 match(Set dst (SubI src1 (AndI src2 mask))); 12739 ins_cost(INSN_COST); 12740 format %{ "subw $dst, $src1, $src2, uxth" %} 12741 12742 ins_encode %{ 12743 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12744 as_Register($src2$$reg), ext::uxth); 12745 %} 12746 ins_pipe(ialu_reg_reg); 12747 %} 12748 12749 // This pattern is automatically generated from aarch64_ad.m4 12750 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12751 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12752 %{ 12753 match(Set dst (SubL src1 (AndL src2 mask))); 12754 ins_cost(INSN_COST); 12755 format %{ "sub $dst, $src1, $src2, uxtb" %} 12756 12757 ins_encode %{ 12758 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12759 as_Register($src2$$reg), ext::uxtb); 12760 %} 12761 ins_pipe(ialu_reg_reg); 12762 %} 12763 12764 // This pattern is automatically generated from aarch64_ad.m4 12765 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12766 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12767 %{ 12768 match(Set dst (SubL src1 (AndL src2 mask))); 12769 ins_cost(INSN_COST); 12770 format %{ "sub $dst, $src1, $src2, uxth" %} 12771 12772 ins_encode %{ 12773 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12774 as_Register($src2$$reg), ext::uxth); 12775 %} 12776 ins_pipe(ialu_reg_reg); 12777 %} 12778 12779 // This pattern is automatically generated from aarch64_ad.m4 12780 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12781 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12782 %{ 12783 match(Set dst (SubL src1 (AndL src2 mask))); 12784 ins_cost(INSN_COST); 12785 format %{ "sub $dst, $src1, $src2, uxtw" %} 12786 12787 ins_encode %{ 12788 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12789 as_Register($src2$$reg), ext::uxtw); 12790 %} 12791 ins_pipe(ialu_reg_reg); 12792 %} 12793 12794 12795 // This pattern is automatically generated from aarch64_ad.m4 12796 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12797 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12798 %{ 12799 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12800 ins_cost(1.9 * INSN_COST); 12801 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12802 12803 ins_encode %{ 12804 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12805 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12806 %} 12807 ins_pipe(ialu_reg_reg_shift); 12808 %} 12809 12810 // This pattern is automatically generated from aarch64_ad.m4 12811 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12812 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12813 %{ 12814 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12815 ins_cost(1.9 * INSN_COST); 12816 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12817 12818 ins_encode %{ 12819 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12820 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12821 %} 12822 ins_pipe(ialu_reg_reg_shift); 12823 %} 12824 12825 // This pattern is automatically generated from aarch64_ad.m4 12826 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12827 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12828 %{ 12829 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12830 ins_cost(1.9 * INSN_COST); 12831 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12832 12833 ins_encode %{ 12834 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12835 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12836 %} 12837 ins_pipe(ialu_reg_reg_shift); 12838 %} 12839 12840 // This pattern is automatically generated from aarch64_ad.m4 12841 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12842 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12843 %{ 12844 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12845 ins_cost(1.9 * INSN_COST); 12846 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12847 12848 ins_encode %{ 12849 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12850 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12851 %} 12852 ins_pipe(ialu_reg_reg_shift); 12853 %} 12854 12855 // This pattern is automatically generated from aarch64_ad.m4 12856 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12857 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12858 %{ 12859 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12860 ins_cost(1.9 * INSN_COST); 12861 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12862 12863 ins_encode %{ 12864 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12865 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12866 %} 12867 ins_pipe(ialu_reg_reg_shift); 12868 %} 12869 12870 // This pattern is automatically generated from aarch64_ad.m4 12871 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12872 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12873 %{ 12874 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12875 ins_cost(1.9 * INSN_COST); 12876 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12877 12878 ins_encode %{ 12879 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12880 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12881 %} 12882 ins_pipe(ialu_reg_reg_shift); 12883 %} 12884 12885 // This pattern is automatically generated from aarch64_ad.m4 12886 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12887 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12888 %{ 12889 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12890 ins_cost(1.9 * INSN_COST); 12891 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12892 12893 ins_encode %{ 12894 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12895 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12896 %} 12897 ins_pipe(ialu_reg_reg_shift); 12898 %} 12899 12900 // This pattern is automatically generated from aarch64_ad.m4 12901 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12902 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12903 %{ 12904 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12905 ins_cost(1.9 * INSN_COST); 12906 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12907 12908 ins_encode %{ 12909 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12910 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12911 %} 12912 ins_pipe(ialu_reg_reg_shift); 12913 %} 12914 12915 // This pattern is automatically generated from aarch64_ad.m4 12916 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12917 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12918 %{ 12919 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12920 ins_cost(1.9 * INSN_COST); 12921 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12922 12923 ins_encode %{ 12924 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12925 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12926 %} 12927 ins_pipe(ialu_reg_reg_shift); 12928 %} 12929 12930 // This pattern is automatically generated from aarch64_ad.m4 12931 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12932 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12933 %{ 12934 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12935 ins_cost(1.9 * INSN_COST); 12936 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12937 12938 ins_encode %{ 12939 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12940 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12941 %} 12942 ins_pipe(ialu_reg_reg_shift); 12943 %} 12944 12945 // This pattern is automatically generated from aarch64_ad.m4 12946 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12947 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12948 %{ 12949 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12950 ins_cost(1.9 * INSN_COST); 12951 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12952 12953 ins_encode %{ 12954 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12955 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12956 %} 12957 ins_pipe(ialu_reg_reg_shift); 12958 %} 12959 12960 // This pattern is automatically generated from aarch64_ad.m4 12961 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12962 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12963 %{ 12964 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12965 ins_cost(1.9 * INSN_COST); 12966 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12967 12968 ins_encode %{ 12969 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12970 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12971 %} 12972 ins_pipe(ialu_reg_reg_shift); 12973 %} 12974 12975 // This pattern is automatically generated from aarch64_ad.m4 12976 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12977 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12978 %{ 12979 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12980 ins_cost(1.9 * INSN_COST); 12981 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12982 12983 ins_encode %{ 12984 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12985 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12986 %} 12987 ins_pipe(ialu_reg_reg_shift); 12988 %} 12989 12990 // This pattern is automatically generated from aarch64_ad.m4 12991 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12992 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12993 %{ 12994 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12995 ins_cost(1.9 * INSN_COST); 12996 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12997 12998 ins_encode %{ 12999 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13000 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13001 %} 13002 ins_pipe(ialu_reg_reg_shift); 13003 %} 13004 13005 // This pattern is automatically generated from aarch64_ad.m4 13006 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13007 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13008 %{ 13009 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13010 ins_cost(1.9 * INSN_COST); 13011 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13012 13013 ins_encode %{ 13014 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13015 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13016 %} 13017 ins_pipe(ialu_reg_reg_shift); 13018 %} 13019 13020 // This pattern is automatically generated from aarch64_ad.m4 13021 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13022 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13023 %{ 13024 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13025 ins_cost(1.9 * INSN_COST); 13026 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13027 13028 ins_encode %{ 13029 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13030 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13031 %} 13032 ins_pipe(ialu_reg_reg_shift); 13033 %} 13034 13035 // This pattern is automatically generated from aarch64_ad.m4 13036 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13037 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13038 %{ 13039 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13040 ins_cost(1.9 * INSN_COST); 13041 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13042 13043 ins_encode %{ 13044 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13045 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13046 %} 13047 ins_pipe(ialu_reg_reg_shift); 13048 %} 13049 13050 // This pattern is automatically generated from aarch64_ad.m4 13051 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13052 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13053 %{ 13054 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13055 ins_cost(1.9 * INSN_COST); 13056 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13057 13058 ins_encode %{ 13059 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13060 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13061 %} 13062 ins_pipe(ialu_reg_reg_shift); 13063 %} 13064 13065 // This pattern is automatically generated from aarch64_ad.m4 13066 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13067 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13068 %{ 13069 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13070 ins_cost(1.9 * INSN_COST); 13071 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13072 13073 ins_encode %{ 13074 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13075 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13076 %} 13077 ins_pipe(ialu_reg_reg_shift); 13078 %} 13079 13080 // This pattern is automatically generated from aarch64_ad.m4 13081 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13082 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13083 %{ 13084 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13085 ins_cost(1.9 * INSN_COST); 13086 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13087 13088 ins_encode %{ 13089 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13090 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13091 %} 13092 ins_pipe(ialu_reg_reg_shift); 13093 %} 13094 13095 // This pattern is automatically generated from aarch64_ad.m4 13096 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13097 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13098 %{ 13099 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13100 ins_cost(1.9 * INSN_COST); 13101 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13102 13103 ins_encode %{ 13104 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13105 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13106 %} 13107 ins_pipe(ialu_reg_reg_shift); 13108 %} 13109 13110 // This pattern is automatically generated from aarch64_ad.m4 13111 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13112 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13113 %{ 13114 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13115 ins_cost(1.9 * INSN_COST); 13116 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13117 13118 ins_encode %{ 13119 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13120 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13121 %} 13122 ins_pipe(ialu_reg_reg_shift); 13123 %} 13124 13125 13126 13127 // END This section of the file is automatically generated. Do not edit -------------- 13128 13129 13130 // ============================================================================ 13131 // Floating Point Arithmetic Instructions 13132 13133 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13134 match(Set dst (AddF src1 src2)); 13135 13136 ins_cost(INSN_COST * 5); 13137 format %{ "fadds $dst, $src1, $src2" %} 13138 13139 ins_encode %{ 13140 __ fadds(as_FloatRegister($dst$$reg), 13141 as_FloatRegister($src1$$reg), 13142 as_FloatRegister($src2$$reg)); 13143 %} 13144 13145 ins_pipe(fp_dop_reg_reg_s); 13146 %} 13147 13148 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13149 match(Set dst (AddD src1 src2)); 13150 13151 ins_cost(INSN_COST * 5); 13152 format %{ "faddd $dst, $src1, $src2" %} 13153 13154 ins_encode %{ 13155 __ faddd(as_FloatRegister($dst$$reg), 13156 as_FloatRegister($src1$$reg), 13157 as_FloatRegister($src2$$reg)); 13158 %} 13159 13160 ins_pipe(fp_dop_reg_reg_d); 13161 %} 13162 13163 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13164 match(Set dst (SubF src1 src2)); 13165 13166 ins_cost(INSN_COST * 5); 13167 format %{ "fsubs $dst, $src1, $src2" %} 13168 13169 ins_encode %{ 13170 __ fsubs(as_FloatRegister($dst$$reg), 13171 as_FloatRegister($src1$$reg), 13172 as_FloatRegister($src2$$reg)); 13173 %} 13174 13175 ins_pipe(fp_dop_reg_reg_s); 13176 %} 13177 13178 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13179 match(Set dst (SubD src1 src2)); 13180 13181 ins_cost(INSN_COST * 5); 13182 format %{ "fsubd $dst, $src1, $src2" %} 13183 13184 ins_encode %{ 13185 __ fsubd(as_FloatRegister($dst$$reg), 13186 as_FloatRegister($src1$$reg), 13187 as_FloatRegister($src2$$reg)); 13188 %} 13189 13190 ins_pipe(fp_dop_reg_reg_d); 13191 %} 13192 13193 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13194 match(Set dst (MulF src1 src2)); 13195 13196 ins_cost(INSN_COST * 6); 13197 format %{ "fmuls $dst, $src1, $src2" %} 13198 13199 ins_encode %{ 13200 __ fmuls(as_FloatRegister($dst$$reg), 13201 as_FloatRegister($src1$$reg), 13202 as_FloatRegister($src2$$reg)); 13203 %} 13204 13205 ins_pipe(fp_dop_reg_reg_s); 13206 %} 13207 13208 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13209 match(Set dst (MulD src1 src2)); 13210 13211 ins_cost(INSN_COST * 6); 13212 format %{ "fmuld $dst, $src1, $src2" %} 13213 13214 ins_encode %{ 13215 __ fmuld(as_FloatRegister($dst$$reg), 13216 as_FloatRegister($src1$$reg), 13217 as_FloatRegister($src2$$reg)); 13218 %} 13219 13220 ins_pipe(fp_dop_reg_reg_d); 13221 %} 13222 13223 // src1 * src2 + src3 13224 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13225 predicate(UseFMA); 13226 match(Set dst (FmaF src3 (Binary src1 src2))); 13227 13228 format %{ "fmadds $dst, $src1, $src2, $src3" %} 13229 13230 ins_encode %{ 13231 __ fmadds(as_FloatRegister($dst$$reg), 13232 as_FloatRegister($src1$$reg), 13233 as_FloatRegister($src2$$reg), 13234 as_FloatRegister($src3$$reg)); 13235 %} 13236 13237 ins_pipe(pipe_class_default); 13238 %} 13239 13240 // src1 * src2 + src3 13241 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13242 predicate(UseFMA); 13243 match(Set dst (FmaD src3 (Binary src1 src2))); 13244 13245 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 13246 13247 ins_encode %{ 13248 __ fmaddd(as_FloatRegister($dst$$reg), 13249 as_FloatRegister($src1$$reg), 13250 as_FloatRegister($src2$$reg), 13251 as_FloatRegister($src3$$reg)); 13252 %} 13253 13254 ins_pipe(pipe_class_default); 13255 %} 13256 13257 // -src1 * src2 + src3 13258 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13259 predicate(UseFMA); 13260 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 13261 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 13262 13263 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 13264 13265 ins_encode %{ 13266 __ fmsubs(as_FloatRegister($dst$$reg), 13267 as_FloatRegister($src1$$reg), 13268 as_FloatRegister($src2$$reg), 13269 as_FloatRegister($src3$$reg)); 13270 %} 13271 13272 ins_pipe(pipe_class_default); 13273 %} 13274 13275 // -src1 * src2 + src3 13276 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13277 predicate(UseFMA); 13278 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 13279 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 13280 13281 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 13282 13283 ins_encode %{ 13284 __ fmsubd(as_FloatRegister($dst$$reg), 13285 as_FloatRegister($src1$$reg), 13286 as_FloatRegister($src2$$reg), 13287 as_FloatRegister($src3$$reg)); 13288 %} 13289 13290 ins_pipe(pipe_class_default); 13291 %} 13292 13293 // -src1 * src2 - src3 13294 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13295 predicate(UseFMA); 13296 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 13297 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13298 13299 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13300 13301 ins_encode %{ 13302 __ fnmadds(as_FloatRegister($dst$$reg), 13303 as_FloatRegister($src1$$reg), 13304 as_FloatRegister($src2$$reg), 13305 as_FloatRegister($src3$$reg)); 13306 %} 13307 13308 ins_pipe(pipe_class_default); 13309 %} 13310 13311 // -src1 * src2 - src3 13312 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13313 predicate(UseFMA); 13314 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13315 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13316 13317 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13318 13319 ins_encode %{ 13320 __ fnmaddd(as_FloatRegister($dst$$reg), 13321 as_FloatRegister($src1$$reg), 13322 as_FloatRegister($src2$$reg), 13323 as_FloatRegister($src3$$reg)); 13324 %} 13325 13326 ins_pipe(pipe_class_default); 13327 %} 13328 13329 // src1 * src2 - src3 13330 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13331 predicate(UseFMA); 13332 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13333 13334 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13335 13336 ins_encode %{ 13337 __ fnmsubs(as_FloatRegister($dst$$reg), 13338 as_FloatRegister($src1$$reg), 13339 as_FloatRegister($src2$$reg), 13340 as_FloatRegister($src3$$reg)); 13341 %} 13342 13343 ins_pipe(pipe_class_default); 13344 %} 13345 13346 // src1 * src2 - src3 13347 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13348 predicate(UseFMA); 13349 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13350 13351 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13352 13353 ins_encode %{ 13354 // n.b. insn name should be fnmsubd 13355 __ fnmsub(as_FloatRegister($dst$$reg), 13356 as_FloatRegister($src1$$reg), 13357 as_FloatRegister($src2$$reg), 13358 as_FloatRegister($src3$$reg)); 13359 %} 13360 13361 ins_pipe(pipe_class_default); 13362 %} 13363 13364 13365 // Math.max(FF)F 13366 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13367 match(Set dst (MaxF src1 src2)); 13368 13369 format %{ "fmaxs $dst, $src1, $src2" %} 13370 ins_encode %{ 13371 __ fmaxs(as_FloatRegister($dst$$reg), 13372 as_FloatRegister($src1$$reg), 13373 as_FloatRegister($src2$$reg)); 13374 %} 13375 13376 ins_pipe(fp_dop_reg_reg_s); 13377 %} 13378 13379 // Math.min(FF)F 13380 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13381 match(Set dst (MinF src1 src2)); 13382 13383 format %{ "fmins $dst, $src1, $src2" %} 13384 ins_encode %{ 13385 __ fmins(as_FloatRegister($dst$$reg), 13386 as_FloatRegister($src1$$reg), 13387 as_FloatRegister($src2$$reg)); 13388 %} 13389 13390 ins_pipe(fp_dop_reg_reg_s); 13391 %} 13392 13393 // Math.max(DD)D 13394 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13395 match(Set dst (MaxD src1 src2)); 13396 13397 format %{ "fmaxd $dst, $src1, $src2" %} 13398 ins_encode %{ 13399 __ fmaxd(as_FloatRegister($dst$$reg), 13400 as_FloatRegister($src1$$reg), 13401 as_FloatRegister($src2$$reg)); 13402 %} 13403 13404 ins_pipe(fp_dop_reg_reg_d); 13405 %} 13406 13407 // Math.min(DD)D 13408 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13409 match(Set dst (MinD src1 src2)); 13410 13411 format %{ "fmind $dst, $src1, $src2" %} 13412 ins_encode %{ 13413 __ fmind(as_FloatRegister($dst$$reg), 13414 as_FloatRegister($src1$$reg), 13415 as_FloatRegister($src2$$reg)); 13416 %} 13417 13418 ins_pipe(fp_dop_reg_reg_d); 13419 %} 13420 13421 13422 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13423 match(Set dst (DivF src1 src2)); 13424 13425 ins_cost(INSN_COST * 18); 13426 format %{ "fdivs $dst, $src1, $src2" %} 13427 13428 ins_encode %{ 13429 __ fdivs(as_FloatRegister($dst$$reg), 13430 as_FloatRegister($src1$$reg), 13431 as_FloatRegister($src2$$reg)); 13432 %} 13433 13434 ins_pipe(fp_div_s); 13435 %} 13436 13437 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13438 match(Set dst (DivD src1 src2)); 13439 13440 ins_cost(INSN_COST * 32); 13441 format %{ "fdivd $dst, $src1, $src2" %} 13442 13443 ins_encode %{ 13444 __ fdivd(as_FloatRegister($dst$$reg), 13445 as_FloatRegister($src1$$reg), 13446 as_FloatRegister($src2$$reg)); 13447 %} 13448 13449 ins_pipe(fp_div_d); 13450 %} 13451 13452 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13453 match(Set dst (NegF src)); 13454 13455 ins_cost(INSN_COST * 3); 13456 format %{ "fneg $dst, $src" %} 13457 13458 ins_encode %{ 13459 __ fnegs(as_FloatRegister($dst$$reg), 13460 as_FloatRegister($src$$reg)); 13461 %} 13462 13463 ins_pipe(fp_uop_s); 13464 %} 13465 13466 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13467 match(Set dst (NegD src)); 13468 13469 ins_cost(INSN_COST * 3); 13470 format %{ "fnegd $dst, $src" %} 13471 13472 ins_encode %{ 13473 __ fnegd(as_FloatRegister($dst$$reg), 13474 as_FloatRegister($src$$reg)); 13475 %} 13476 13477 ins_pipe(fp_uop_d); 13478 %} 13479 13480 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13481 %{ 13482 match(Set dst (AbsI src)); 13483 13484 effect(KILL cr); 13485 ins_cost(INSN_COST * 2); 13486 format %{ "cmpw $src, zr\n\t" 13487 "cnegw $dst, $src, Assembler::LT\t# int abs" 13488 %} 13489 13490 ins_encode %{ 13491 __ cmpw(as_Register($src$$reg), zr); 13492 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13493 %} 13494 ins_pipe(pipe_class_default); 13495 %} 13496 13497 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 13498 %{ 13499 match(Set dst (AbsL src)); 13500 13501 effect(KILL cr); 13502 ins_cost(INSN_COST * 2); 13503 format %{ "cmp $src, zr\n\t" 13504 "cneg $dst, $src, Assembler::LT\t# long abs" 13505 %} 13506 13507 ins_encode %{ 13508 __ cmp(as_Register($src$$reg), zr); 13509 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13510 %} 13511 ins_pipe(pipe_class_default); 13512 %} 13513 13514 instruct absF_reg(vRegF dst, vRegF src) %{ 13515 match(Set dst (AbsF src)); 13516 13517 ins_cost(INSN_COST * 3); 13518 format %{ "fabss $dst, $src" %} 13519 ins_encode %{ 13520 __ fabss(as_FloatRegister($dst$$reg), 13521 as_FloatRegister($src$$reg)); 13522 %} 13523 13524 ins_pipe(fp_uop_s); 13525 %} 13526 13527 instruct absD_reg(vRegD dst, vRegD src) %{ 13528 match(Set dst (AbsD src)); 13529 13530 ins_cost(INSN_COST * 3); 13531 format %{ "fabsd $dst, $src" %} 13532 ins_encode %{ 13533 __ fabsd(as_FloatRegister($dst$$reg), 13534 as_FloatRegister($src$$reg)); 13535 %} 13536 13537 ins_pipe(fp_uop_d); 13538 %} 13539 13540 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13541 match(Set dst (SqrtD src)); 13542 13543 ins_cost(INSN_COST * 50); 13544 format %{ "fsqrtd $dst, $src" %} 13545 ins_encode %{ 13546 __ fsqrtd(as_FloatRegister($dst$$reg), 13547 as_FloatRegister($src$$reg)); 13548 %} 13549 13550 ins_pipe(fp_div_s); 13551 %} 13552 13553 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13554 match(Set dst (SqrtF src)); 13555 13556 ins_cost(INSN_COST * 50); 13557 format %{ "fsqrts $dst, $src" %} 13558 ins_encode %{ 13559 __ fsqrts(as_FloatRegister($dst$$reg), 13560 as_FloatRegister($src$$reg)); 13561 %} 13562 13563 ins_pipe(fp_div_d); 13564 %} 13565 13566 // Math.rint, floor, ceil 13567 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 13568 match(Set dst (RoundDoubleMode src rmode)); 13569 format %{ "frint $dst, $src, $rmode" %} 13570 ins_encode %{ 13571 switch ($rmode$$constant) { 13572 case RoundDoubleModeNode::rmode_rint: 13573 __ frintnd(as_FloatRegister($dst$$reg), 13574 as_FloatRegister($src$$reg)); 13575 break; 13576 case RoundDoubleModeNode::rmode_floor: 13577 __ frintmd(as_FloatRegister($dst$$reg), 13578 as_FloatRegister($src$$reg)); 13579 break; 13580 case RoundDoubleModeNode::rmode_ceil: 13581 __ frintpd(as_FloatRegister($dst$$reg), 13582 as_FloatRegister($src$$reg)); 13583 break; 13584 } 13585 %} 13586 ins_pipe(fp_uop_d); 13587 %} 13588 13589 // ============================================================================ 13590 // Logical Instructions 13591 13592 // Integer Logical Instructions 13593 13594 // And Instructions 13595 13596 13597 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13598 match(Set dst (AndI src1 src2)); 13599 13600 format %{ "andw $dst, $src1, $src2\t# int" %} 13601 13602 ins_cost(INSN_COST); 13603 ins_encode %{ 13604 __ andw(as_Register($dst$$reg), 13605 as_Register($src1$$reg), 13606 as_Register($src2$$reg)); 13607 %} 13608 13609 ins_pipe(ialu_reg_reg); 13610 %} 13611 13612 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13613 match(Set dst (AndI src1 src2)); 13614 13615 format %{ "andsw $dst, $src1, $src2\t# int" %} 13616 13617 ins_cost(INSN_COST); 13618 ins_encode %{ 13619 __ andw(as_Register($dst$$reg), 13620 as_Register($src1$$reg), 13621 (uint64_t)($src2$$constant)); 13622 %} 13623 13624 ins_pipe(ialu_reg_imm); 13625 %} 13626 13627 // Or Instructions 13628 13629 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13630 match(Set dst (OrI src1 src2)); 13631 13632 format %{ "orrw $dst, $src1, $src2\t# int" %} 13633 13634 ins_cost(INSN_COST); 13635 ins_encode %{ 13636 __ orrw(as_Register($dst$$reg), 13637 as_Register($src1$$reg), 13638 as_Register($src2$$reg)); 13639 %} 13640 13641 ins_pipe(ialu_reg_reg); 13642 %} 13643 13644 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13645 match(Set dst (OrI src1 src2)); 13646 13647 format %{ "orrw $dst, $src1, $src2\t# int" %} 13648 13649 ins_cost(INSN_COST); 13650 ins_encode %{ 13651 __ orrw(as_Register($dst$$reg), 13652 as_Register($src1$$reg), 13653 (uint64_t)($src2$$constant)); 13654 %} 13655 13656 ins_pipe(ialu_reg_imm); 13657 %} 13658 13659 // Xor Instructions 13660 13661 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13662 match(Set dst (XorI src1 src2)); 13663 13664 format %{ "eorw $dst, $src1, $src2\t# int" %} 13665 13666 ins_cost(INSN_COST); 13667 ins_encode %{ 13668 __ eorw(as_Register($dst$$reg), 13669 as_Register($src1$$reg), 13670 as_Register($src2$$reg)); 13671 %} 13672 13673 ins_pipe(ialu_reg_reg); 13674 %} 13675 13676 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13677 match(Set dst (XorI src1 src2)); 13678 13679 format %{ "eorw $dst, $src1, $src2\t# int" %} 13680 13681 ins_cost(INSN_COST); 13682 ins_encode %{ 13683 __ eorw(as_Register($dst$$reg), 13684 as_Register($src1$$reg), 13685 (uint64_t)($src2$$constant)); 13686 %} 13687 13688 ins_pipe(ialu_reg_imm); 13689 %} 13690 13691 // Long Logical Instructions 13692 // TODO 13693 13694 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13695 match(Set dst (AndL src1 src2)); 13696 13697 format %{ "and $dst, $src1, $src2\t# int" %} 13698 13699 ins_cost(INSN_COST); 13700 ins_encode %{ 13701 __ andr(as_Register($dst$$reg), 13702 as_Register($src1$$reg), 13703 as_Register($src2$$reg)); 13704 %} 13705 13706 ins_pipe(ialu_reg_reg); 13707 %} 13708 13709 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13710 match(Set dst (AndL src1 src2)); 13711 13712 format %{ "and $dst, $src1, $src2\t# int" %} 13713 13714 ins_cost(INSN_COST); 13715 ins_encode %{ 13716 __ andr(as_Register($dst$$reg), 13717 as_Register($src1$$reg), 13718 (uint64_t)($src2$$constant)); 13719 %} 13720 13721 ins_pipe(ialu_reg_imm); 13722 %} 13723 13724 // Or Instructions 13725 13726 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13727 match(Set dst (OrL src1 src2)); 13728 13729 format %{ "orr $dst, $src1, $src2\t# int" %} 13730 13731 ins_cost(INSN_COST); 13732 ins_encode %{ 13733 __ orr(as_Register($dst$$reg), 13734 as_Register($src1$$reg), 13735 as_Register($src2$$reg)); 13736 %} 13737 13738 ins_pipe(ialu_reg_reg); 13739 %} 13740 13741 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13742 match(Set dst (OrL src1 src2)); 13743 13744 format %{ "orr $dst, $src1, $src2\t# int" %} 13745 13746 ins_cost(INSN_COST); 13747 ins_encode %{ 13748 __ orr(as_Register($dst$$reg), 13749 as_Register($src1$$reg), 13750 (uint64_t)($src2$$constant)); 13751 %} 13752 13753 ins_pipe(ialu_reg_imm); 13754 %} 13755 13756 // Xor Instructions 13757 13758 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13759 match(Set dst (XorL src1 src2)); 13760 13761 format %{ "eor $dst, $src1, $src2\t# int" %} 13762 13763 ins_cost(INSN_COST); 13764 ins_encode %{ 13765 __ eor(as_Register($dst$$reg), 13766 as_Register($src1$$reg), 13767 as_Register($src2$$reg)); 13768 %} 13769 13770 ins_pipe(ialu_reg_reg); 13771 %} 13772 13773 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13774 match(Set dst (XorL src1 src2)); 13775 13776 ins_cost(INSN_COST); 13777 format %{ "eor $dst, $src1, $src2\t# int" %} 13778 13779 ins_encode %{ 13780 __ eor(as_Register($dst$$reg), 13781 as_Register($src1$$reg), 13782 (uint64_t)($src2$$constant)); 13783 %} 13784 13785 ins_pipe(ialu_reg_imm); 13786 %} 13787 13788 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13789 %{ 13790 match(Set dst (ConvI2L src)); 13791 13792 ins_cost(INSN_COST); 13793 format %{ "sxtw $dst, $src\t# i2l" %} 13794 ins_encode %{ 13795 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13796 %} 13797 ins_pipe(ialu_reg_shift); 13798 %} 13799 13800 // this pattern occurs in bigmath arithmetic 13801 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13802 %{ 13803 match(Set dst (AndL (ConvI2L src) mask)); 13804 13805 ins_cost(INSN_COST); 13806 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13807 ins_encode %{ 13808 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13809 %} 13810 13811 ins_pipe(ialu_reg_shift); 13812 %} 13813 13814 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13815 match(Set dst (ConvL2I src)); 13816 13817 ins_cost(INSN_COST); 13818 format %{ "movw $dst, $src \t// l2i" %} 13819 13820 ins_encode %{ 13821 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13822 %} 13823 13824 ins_pipe(ialu_reg); 13825 %} 13826 13827 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13828 %{ 13829 match(Set dst (Conv2B src)); 13830 effect(KILL cr); 13831 13832 format %{ 13833 "cmpw $src, zr\n\t" 13834 "cset $dst, ne" 13835 %} 13836 13837 ins_encode %{ 13838 __ cmpw(as_Register($src$$reg), zr); 13839 __ cset(as_Register($dst$$reg), Assembler::NE); 13840 %} 13841 13842 ins_pipe(ialu_reg); 13843 %} 13844 13845 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13846 %{ 13847 match(Set dst (Conv2B src)); 13848 effect(KILL cr); 13849 13850 format %{ 13851 "cmp $src, zr\n\t" 13852 "cset $dst, ne" 13853 %} 13854 13855 ins_encode %{ 13856 __ cmp(as_Register($src$$reg), zr); 13857 __ cset(as_Register($dst$$reg), Assembler::NE); 13858 %} 13859 13860 ins_pipe(ialu_reg); 13861 %} 13862 13863 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13864 match(Set dst (ConvD2F src)); 13865 13866 ins_cost(INSN_COST * 5); 13867 format %{ "fcvtd $dst, $src \t// d2f" %} 13868 13869 ins_encode %{ 13870 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13871 %} 13872 13873 ins_pipe(fp_d2f); 13874 %} 13875 13876 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13877 match(Set dst (ConvF2D src)); 13878 13879 ins_cost(INSN_COST * 5); 13880 format %{ "fcvts $dst, $src \t// f2d" %} 13881 13882 ins_encode %{ 13883 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13884 %} 13885 13886 ins_pipe(fp_f2d); 13887 %} 13888 13889 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13890 match(Set dst (ConvF2I src)); 13891 13892 ins_cost(INSN_COST * 5); 13893 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13894 13895 ins_encode %{ 13896 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13897 %} 13898 13899 ins_pipe(fp_f2i); 13900 %} 13901 13902 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13903 match(Set dst (ConvF2L src)); 13904 13905 ins_cost(INSN_COST * 5); 13906 format %{ "fcvtzs $dst, $src \t// f2l" %} 13907 13908 ins_encode %{ 13909 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13910 %} 13911 13912 ins_pipe(fp_f2l); 13913 %} 13914 13915 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13916 match(Set dst (ConvI2F src)); 13917 13918 ins_cost(INSN_COST * 5); 13919 format %{ "scvtfws $dst, $src \t// i2f" %} 13920 13921 ins_encode %{ 13922 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13923 %} 13924 13925 ins_pipe(fp_i2f); 13926 %} 13927 13928 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13929 match(Set dst (ConvL2F src)); 13930 13931 ins_cost(INSN_COST * 5); 13932 format %{ "scvtfs $dst, $src \t// l2f" %} 13933 13934 ins_encode %{ 13935 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13936 %} 13937 13938 ins_pipe(fp_l2f); 13939 %} 13940 13941 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13942 match(Set dst (ConvD2I src)); 13943 13944 ins_cost(INSN_COST * 5); 13945 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13946 13947 ins_encode %{ 13948 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13949 %} 13950 13951 ins_pipe(fp_d2i); 13952 %} 13953 13954 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13955 match(Set dst (ConvD2L src)); 13956 13957 ins_cost(INSN_COST * 5); 13958 format %{ "fcvtzd $dst, $src \t// d2l" %} 13959 13960 ins_encode %{ 13961 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13962 %} 13963 13964 ins_pipe(fp_d2l); 13965 %} 13966 13967 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13968 match(Set dst (ConvI2D src)); 13969 13970 ins_cost(INSN_COST * 5); 13971 format %{ "scvtfwd $dst, $src \t// i2d" %} 13972 13973 ins_encode %{ 13974 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13975 %} 13976 13977 ins_pipe(fp_i2d); 13978 %} 13979 13980 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13981 match(Set dst (ConvL2D src)); 13982 13983 ins_cost(INSN_COST * 5); 13984 format %{ "scvtfd $dst, $src \t// l2d" %} 13985 13986 ins_encode %{ 13987 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13988 %} 13989 13990 ins_pipe(fp_l2d); 13991 %} 13992 13993 // stack <-> reg and reg <-> reg shuffles with no conversion 13994 13995 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13996 13997 match(Set dst (MoveF2I src)); 13998 13999 effect(DEF dst, USE src); 14000 14001 ins_cost(4 * INSN_COST); 14002 14003 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 14004 14005 ins_encode %{ 14006 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 14007 %} 14008 14009 ins_pipe(iload_reg_reg); 14010 14011 %} 14012 14013 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 14014 14015 match(Set dst (MoveI2F src)); 14016 14017 effect(DEF dst, USE src); 14018 14019 ins_cost(4 * INSN_COST); 14020 14021 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 14022 14023 ins_encode %{ 14024 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14025 %} 14026 14027 ins_pipe(pipe_class_memory); 14028 14029 %} 14030 14031 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 14032 14033 match(Set dst (MoveD2L src)); 14034 14035 effect(DEF dst, USE src); 14036 14037 ins_cost(4 * INSN_COST); 14038 14039 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 14040 14041 ins_encode %{ 14042 __ ldr($dst$$Register, Address(sp, $src$$disp)); 14043 %} 14044 14045 ins_pipe(iload_reg_reg); 14046 14047 %} 14048 14049 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 14050 14051 match(Set dst (MoveL2D src)); 14052 14053 effect(DEF dst, USE src); 14054 14055 ins_cost(4 * INSN_COST); 14056 14057 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 14058 14059 ins_encode %{ 14060 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14061 %} 14062 14063 ins_pipe(pipe_class_memory); 14064 14065 %} 14066 14067 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 14068 14069 match(Set dst (MoveF2I src)); 14070 14071 effect(DEF dst, USE src); 14072 14073 ins_cost(INSN_COST); 14074 14075 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 14076 14077 ins_encode %{ 14078 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14079 %} 14080 14081 ins_pipe(pipe_class_memory); 14082 14083 %} 14084 14085 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 14086 14087 match(Set dst (MoveI2F src)); 14088 14089 effect(DEF dst, USE src); 14090 14091 ins_cost(INSN_COST); 14092 14093 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 14094 14095 ins_encode %{ 14096 __ strw($src$$Register, Address(sp, $dst$$disp)); 14097 %} 14098 14099 ins_pipe(istore_reg_reg); 14100 14101 %} 14102 14103 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 14104 14105 match(Set dst (MoveD2L src)); 14106 14107 effect(DEF dst, USE src); 14108 14109 ins_cost(INSN_COST); 14110 14111 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 14112 14113 ins_encode %{ 14114 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14115 %} 14116 14117 ins_pipe(pipe_class_memory); 14118 14119 %} 14120 14121 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 14122 14123 match(Set dst (MoveL2D src)); 14124 14125 effect(DEF dst, USE src); 14126 14127 ins_cost(INSN_COST); 14128 14129 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 14130 14131 ins_encode %{ 14132 __ str($src$$Register, Address(sp, $dst$$disp)); 14133 %} 14134 14135 ins_pipe(istore_reg_reg); 14136 14137 %} 14138 14139 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14140 14141 match(Set dst (MoveF2I src)); 14142 14143 effect(DEF dst, USE src); 14144 14145 ins_cost(INSN_COST); 14146 14147 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 14148 14149 ins_encode %{ 14150 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 14151 %} 14152 14153 ins_pipe(fp_f2i); 14154 14155 %} 14156 14157 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 14158 14159 match(Set dst (MoveI2F src)); 14160 14161 effect(DEF dst, USE src); 14162 14163 ins_cost(INSN_COST); 14164 14165 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 14166 14167 ins_encode %{ 14168 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 14169 %} 14170 14171 ins_pipe(fp_i2f); 14172 14173 %} 14174 14175 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14176 14177 match(Set dst (MoveD2L src)); 14178 14179 effect(DEF dst, USE src); 14180 14181 ins_cost(INSN_COST); 14182 14183 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 14184 14185 ins_encode %{ 14186 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 14187 %} 14188 14189 ins_pipe(fp_d2l); 14190 14191 %} 14192 14193 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 14194 14195 match(Set dst (MoveL2D src)); 14196 14197 effect(DEF dst, USE src); 14198 14199 ins_cost(INSN_COST); 14200 14201 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 14202 14203 ins_encode %{ 14204 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 14205 %} 14206 14207 ins_pipe(fp_l2d); 14208 14209 %} 14210 14211 // ============================================================================ 14212 // clearing of an array 14213 14214 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 14215 %{ 14216 match(Set dummy (ClearArray cnt base)); 14217 effect(USE_KILL cnt, USE_KILL base, KILL cr); 14218 14219 ins_cost(4 * INSN_COST); 14220 format %{ "ClearArray $cnt, $base" %} 14221 14222 ins_encode %{ 14223 __ zero_words($base$$Register, $cnt$$Register); 14224 %} 14225 14226 ins_pipe(pipe_class_memory); 14227 %} 14228 14229 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 14230 %{ 14231 predicate((uint64_t)n->in(2)->get_long() 14232 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 14233 match(Set dummy (ClearArray cnt base)); 14234 effect(USE_KILL base); 14235 14236 ins_cost(4 * INSN_COST); 14237 format %{ "ClearArray $cnt, $base" %} 14238 14239 ins_encode %{ 14240 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 14241 %} 14242 14243 ins_pipe(pipe_class_memory); 14244 %} 14245 14246 // ============================================================================ 14247 // Overflow Math Instructions 14248 14249 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14250 %{ 14251 match(Set cr (OverflowAddI op1 op2)); 14252 14253 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14254 ins_cost(INSN_COST); 14255 ins_encode %{ 14256 __ cmnw($op1$$Register, $op2$$Register); 14257 %} 14258 14259 ins_pipe(icmp_reg_reg); 14260 %} 14261 14262 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14263 %{ 14264 match(Set cr (OverflowAddI op1 op2)); 14265 14266 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14267 ins_cost(INSN_COST); 14268 ins_encode %{ 14269 __ cmnw($op1$$Register, $op2$$constant); 14270 %} 14271 14272 ins_pipe(icmp_reg_imm); 14273 %} 14274 14275 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14276 %{ 14277 match(Set cr (OverflowAddL op1 op2)); 14278 14279 format %{ "cmn $op1, $op2\t# overflow check long" %} 14280 ins_cost(INSN_COST); 14281 ins_encode %{ 14282 __ cmn($op1$$Register, $op2$$Register); 14283 %} 14284 14285 ins_pipe(icmp_reg_reg); 14286 %} 14287 14288 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14289 %{ 14290 match(Set cr (OverflowAddL op1 op2)); 14291 14292 format %{ "cmn $op1, $op2\t# overflow check long" %} 14293 ins_cost(INSN_COST); 14294 ins_encode %{ 14295 __ cmn($op1$$Register, $op2$$constant); 14296 %} 14297 14298 ins_pipe(icmp_reg_imm); 14299 %} 14300 14301 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14302 %{ 14303 match(Set cr (OverflowSubI op1 op2)); 14304 14305 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14306 ins_cost(INSN_COST); 14307 ins_encode %{ 14308 __ cmpw($op1$$Register, $op2$$Register); 14309 %} 14310 14311 ins_pipe(icmp_reg_reg); 14312 %} 14313 14314 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14315 %{ 14316 match(Set cr (OverflowSubI op1 op2)); 14317 14318 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14319 ins_cost(INSN_COST); 14320 ins_encode %{ 14321 __ cmpw($op1$$Register, $op2$$constant); 14322 %} 14323 14324 ins_pipe(icmp_reg_imm); 14325 %} 14326 14327 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14328 %{ 14329 match(Set cr (OverflowSubL op1 op2)); 14330 14331 format %{ "cmp $op1, $op2\t# overflow check long" %} 14332 ins_cost(INSN_COST); 14333 ins_encode %{ 14334 __ cmp($op1$$Register, $op2$$Register); 14335 %} 14336 14337 ins_pipe(icmp_reg_reg); 14338 %} 14339 14340 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14341 %{ 14342 match(Set cr (OverflowSubL op1 op2)); 14343 14344 format %{ "cmp $op1, $op2\t# overflow check long" %} 14345 ins_cost(INSN_COST); 14346 ins_encode %{ 14347 __ subs(zr, $op1$$Register, $op2$$constant); 14348 %} 14349 14350 ins_pipe(icmp_reg_imm); 14351 %} 14352 14353 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14354 %{ 14355 match(Set cr (OverflowSubI zero op1)); 14356 14357 format %{ "cmpw zr, $op1\t# overflow check int" %} 14358 ins_cost(INSN_COST); 14359 ins_encode %{ 14360 __ cmpw(zr, $op1$$Register); 14361 %} 14362 14363 ins_pipe(icmp_reg_imm); 14364 %} 14365 14366 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14367 %{ 14368 match(Set cr (OverflowSubL zero op1)); 14369 14370 format %{ "cmp zr, $op1\t# overflow check long" %} 14371 ins_cost(INSN_COST); 14372 ins_encode %{ 14373 __ cmp(zr, $op1$$Register); 14374 %} 14375 14376 ins_pipe(icmp_reg_imm); 14377 %} 14378 14379 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14380 %{ 14381 match(Set cr (OverflowMulI op1 op2)); 14382 14383 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14384 "cmp rscratch1, rscratch1, sxtw\n\t" 14385 "movw rscratch1, #0x80000000\n\t" 14386 "cselw rscratch1, rscratch1, zr, NE\n\t" 14387 "cmpw rscratch1, #1" %} 14388 ins_cost(5 * INSN_COST); 14389 ins_encode %{ 14390 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14391 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14392 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14393 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14394 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14395 %} 14396 14397 ins_pipe(pipe_slow); 14398 %} 14399 14400 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14401 %{ 14402 match(If cmp (OverflowMulI op1 op2)); 14403 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14404 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14405 effect(USE labl, KILL cr); 14406 14407 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14408 "cmp rscratch1, rscratch1, sxtw\n\t" 14409 "b$cmp $labl" %} 14410 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14411 ins_encode %{ 14412 Label* L = $labl$$label; 14413 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14414 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14415 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14416 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14417 %} 14418 14419 ins_pipe(pipe_serial); 14420 %} 14421 14422 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14423 %{ 14424 match(Set cr (OverflowMulL op1 op2)); 14425 14426 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14427 "smulh rscratch2, $op1, $op2\n\t" 14428 "cmp rscratch2, rscratch1, ASR #63\n\t" 14429 "movw rscratch1, #0x80000000\n\t" 14430 "cselw rscratch1, rscratch1, zr, NE\n\t" 14431 "cmpw rscratch1, #1" %} 14432 ins_cost(6 * INSN_COST); 14433 ins_encode %{ 14434 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14435 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14436 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14437 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14438 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14439 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14440 %} 14441 14442 ins_pipe(pipe_slow); 14443 %} 14444 14445 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14446 %{ 14447 match(If cmp (OverflowMulL op1 op2)); 14448 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14449 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14450 effect(USE labl, KILL cr); 14451 14452 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14453 "smulh rscratch2, $op1, $op2\n\t" 14454 "cmp rscratch2, rscratch1, ASR #63\n\t" 14455 "b$cmp $labl" %} 14456 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14457 ins_encode %{ 14458 Label* L = $labl$$label; 14459 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14460 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14461 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14462 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14463 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14464 %} 14465 14466 ins_pipe(pipe_serial); 14467 %} 14468 14469 // ============================================================================ 14470 // Compare Instructions 14471 14472 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14473 %{ 14474 match(Set cr (CmpI op1 op2)); 14475 14476 effect(DEF cr, USE op1, USE op2); 14477 14478 ins_cost(INSN_COST); 14479 format %{ "cmpw $op1, $op2" %} 14480 14481 ins_encode(aarch64_enc_cmpw(op1, op2)); 14482 14483 ins_pipe(icmp_reg_reg); 14484 %} 14485 14486 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14487 %{ 14488 match(Set cr (CmpI op1 zero)); 14489 14490 effect(DEF cr, USE op1); 14491 14492 ins_cost(INSN_COST); 14493 format %{ "cmpw $op1, 0" %} 14494 14495 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14496 14497 ins_pipe(icmp_reg_imm); 14498 %} 14499 14500 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14501 %{ 14502 match(Set cr (CmpI op1 op2)); 14503 14504 effect(DEF cr, USE op1); 14505 14506 ins_cost(INSN_COST); 14507 format %{ "cmpw $op1, $op2" %} 14508 14509 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14510 14511 ins_pipe(icmp_reg_imm); 14512 %} 14513 14514 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14515 %{ 14516 match(Set cr (CmpI op1 op2)); 14517 14518 effect(DEF cr, USE op1); 14519 14520 ins_cost(INSN_COST * 2); 14521 format %{ "cmpw $op1, $op2" %} 14522 14523 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14524 14525 ins_pipe(icmp_reg_imm); 14526 %} 14527 14528 // Unsigned compare Instructions; really, same as signed compare 14529 // except it should only be used to feed an If or a CMovI which takes a 14530 // cmpOpU. 14531 14532 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14533 %{ 14534 match(Set cr (CmpU op1 op2)); 14535 14536 effect(DEF cr, USE op1, USE op2); 14537 14538 ins_cost(INSN_COST); 14539 format %{ "cmpw $op1, $op2\t# unsigned" %} 14540 14541 ins_encode(aarch64_enc_cmpw(op1, op2)); 14542 14543 ins_pipe(icmp_reg_reg); 14544 %} 14545 14546 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14547 %{ 14548 match(Set cr (CmpU op1 zero)); 14549 14550 effect(DEF cr, USE op1); 14551 14552 ins_cost(INSN_COST); 14553 format %{ "cmpw $op1, #0\t# unsigned" %} 14554 14555 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14556 14557 ins_pipe(icmp_reg_imm); 14558 %} 14559 14560 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14561 %{ 14562 match(Set cr (CmpU op1 op2)); 14563 14564 effect(DEF cr, USE op1); 14565 14566 ins_cost(INSN_COST); 14567 format %{ "cmpw $op1, $op2\t# unsigned" %} 14568 14569 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14570 14571 ins_pipe(icmp_reg_imm); 14572 %} 14573 14574 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14575 %{ 14576 match(Set cr (CmpU op1 op2)); 14577 14578 effect(DEF cr, USE op1); 14579 14580 ins_cost(INSN_COST * 2); 14581 format %{ "cmpw $op1, $op2\t# unsigned" %} 14582 14583 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14584 14585 ins_pipe(icmp_reg_imm); 14586 %} 14587 14588 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14589 %{ 14590 match(Set cr (CmpL op1 op2)); 14591 14592 effect(DEF cr, USE op1, USE op2); 14593 14594 ins_cost(INSN_COST); 14595 format %{ "cmp $op1, $op2" %} 14596 14597 ins_encode(aarch64_enc_cmp(op1, op2)); 14598 14599 ins_pipe(icmp_reg_reg); 14600 %} 14601 14602 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14603 %{ 14604 match(Set cr (CmpL op1 zero)); 14605 14606 effect(DEF cr, USE op1); 14607 14608 ins_cost(INSN_COST); 14609 format %{ "tst $op1" %} 14610 14611 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14612 14613 ins_pipe(icmp_reg_imm); 14614 %} 14615 14616 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14617 %{ 14618 match(Set cr (CmpL op1 op2)); 14619 14620 effect(DEF cr, USE op1); 14621 14622 ins_cost(INSN_COST); 14623 format %{ "cmp $op1, $op2" %} 14624 14625 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14626 14627 ins_pipe(icmp_reg_imm); 14628 %} 14629 14630 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14631 %{ 14632 match(Set cr (CmpL op1 op2)); 14633 14634 effect(DEF cr, USE op1); 14635 14636 ins_cost(INSN_COST * 2); 14637 format %{ "cmp $op1, $op2" %} 14638 14639 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14640 14641 ins_pipe(icmp_reg_imm); 14642 %} 14643 14644 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14645 %{ 14646 match(Set cr (CmpUL op1 op2)); 14647 14648 effect(DEF cr, USE op1, USE op2); 14649 14650 ins_cost(INSN_COST); 14651 format %{ "cmp $op1, $op2" %} 14652 14653 ins_encode(aarch64_enc_cmp(op1, op2)); 14654 14655 ins_pipe(icmp_reg_reg); 14656 %} 14657 14658 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14659 %{ 14660 match(Set cr (CmpUL op1 zero)); 14661 14662 effect(DEF cr, USE op1); 14663 14664 ins_cost(INSN_COST); 14665 format %{ "tst $op1" %} 14666 14667 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14668 14669 ins_pipe(icmp_reg_imm); 14670 %} 14671 14672 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14673 %{ 14674 match(Set cr (CmpUL op1 op2)); 14675 14676 effect(DEF cr, USE op1); 14677 14678 ins_cost(INSN_COST); 14679 format %{ "cmp $op1, $op2" %} 14680 14681 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14682 14683 ins_pipe(icmp_reg_imm); 14684 %} 14685 14686 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14687 %{ 14688 match(Set cr (CmpUL op1 op2)); 14689 14690 effect(DEF cr, USE op1); 14691 14692 ins_cost(INSN_COST * 2); 14693 format %{ "cmp $op1, $op2" %} 14694 14695 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14696 14697 ins_pipe(icmp_reg_imm); 14698 %} 14699 14700 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14701 %{ 14702 match(Set cr (CmpP op1 op2)); 14703 14704 effect(DEF cr, USE op1, USE op2); 14705 14706 ins_cost(INSN_COST); 14707 format %{ "cmp $op1, $op2\t // ptr" %} 14708 14709 ins_encode(aarch64_enc_cmpp(op1, op2)); 14710 14711 ins_pipe(icmp_reg_reg); 14712 %} 14713 14714 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14715 %{ 14716 match(Set cr (CmpN op1 op2)); 14717 14718 effect(DEF cr, USE op1, USE op2); 14719 14720 ins_cost(INSN_COST); 14721 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14722 14723 ins_encode(aarch64_enc_cmpn(op1, op2)); 14724 14725 ins_pipe(icmp_reg_reg); 14726 %} 14727 14728 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14729 %{ 14730 match(Set cr (CmpP op1 zero)); 14731 14732 effect(DEF cr, USE op1, USE zero); 14733 14734 ins_cost(INSN_COST); 14735 format %{ "cmp $op1, 0\t // ptr" %} 14736 14737 ins_encode(aarch64_enc_testp(op1)); 14738 14739 ins_pipe(icmp_reg_imm); 14740 %} 14741 14742 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14743 %{ 14744 match(Set cr (CmpN op1 zero)); 14745 14746 effect(DEF cr, USE op1, USE zero); 14747 14748 ins_cost(INSN_COST); 14749 format %{ "cmp $op1, 0\t // compressed ptr" %} 14750 14751 ins_encode(aarch64_enc_testn(op1)); 14752 14753 ins_pipe(icmp_reg_imm); 14754 %} 14755 14756 // FP comparisons 14757 // 14758 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14759 // using normal cmpOp. See declaration of rFlagsReg for details. 14760 14761 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14762 %{ 14763 match(Set cr (CmpF src1 src2)); 14764 14765 ins_cost(3 * INSN_COST); 14766 format %{ "fcmps $src1, $src2" %} 14767 14768 ins_encode %{ 14769 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14770 %} 14771 14772 ins_pipe(pipe_class_compare); 14773 %} 14774 14775 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14776 %{ 14777 match(Set cr (CmpF src1 src2)); 14778 14779 ins_cost(3 * INSN_COST); 14780 format %{ "fcmps $src1, 0.0" %} 14781 14782 ins_encode %{ 14783 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14784 %} 14785 14786 ins_pipe(pipe_class_compare); 14787 %} 14788 // FROM HERE 14789 14790 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14791 %{ 14792 match(Set cr (CmpD src1 src2)); 14793 14794 ins_cost(3 * INSN_COST); 14795 format %{ "fcmpd $src1, $src2" %} 14796 14797 ins_encode %{ 14798 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14799 %} 14800 14801 ins_pipe(pipe_class_compare); 14802 %} 14803 14804 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14805 %{ 14806 match(Set cr (CmpD src1 src2)); 14807 14808 ins_cost(3 * INSN_COST); 14809 format %{ "fcmpd $src1, 0.0" %} 14810 14811 ins_encode %{ 14812 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14813 %} 14814 14815 ins_pipe(pipe_class_compare); 14816 %} 14817 14818 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14819 %{ 14820 match(Set dst (CmpF3 src1 src2)); 14821 effect(KILL cr); 14822 14823 ins_cost(5 * INSN_COST); 14824 format %{ "fcmps $src1, $src2\n\t" 14825 "csinvw($dst, zr, zr, eq\n\t" 14826 "csnegw($dst, $dst, $dst, lt)" 14827 %} 14828 14829 ins_encode %{ 14830 Label done; 14831 FloatRegister s1 = as_FloatRegister($src1$$reg); 14832 FloatRegister s2 = as_FloatRegister($src2$$reg); 14833 Register d = as_Register($dst$$reg); 14834 __ fcmps(s1, s2); 14835 // installs 0 if EQ else -1 14836 __ csinvw(d, zr, zr, Assembler::EQ); 14837 // keeps -1 if less or unordered else installs 1 14838 __ csnegw(d, d, d, Assembler::LT); 14839 __ bind(done); 14840 %} 14841 14842 ins_pipe(pipe_class_default); 14843 14844 %} 14845 14846 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14847 %{ 14848 match(Set dst (CmpD3 src1 src2)); 14849 effect(KILL cr); 14850 14851 ins_cost(5 * INSN_COST); 14852 format %{ "fcmpd $src1, $src2\n\t" 14853 "csinvw($dst, zr, zr, eq\n\t" 14854 "csnegw($dst, $dst, $dst, lt)" 14855 %} 14856 14857 ins_encode %{ 14858 Label done; 14859 FloatRegister s1 = as_FloatRegister($src1$$reg); 14860 FloatRegister s2 = as_FloatRegister($src2$$reg); 14861 Register d = as_Register($dst$$reg); 14862 __ fcmpd(s1, s2); 14863 // installs 0 if EQ else -1 14864 __ csinvw(d, zr, zr, Assembler::EQ); 14865 // keeps -1 if less or unordered else installs 1 14866 __ csnegw(d, d, d, Assembler::LT); 14867 __ bind(done); 14868 %} 14869 ins_pipe(pipe_class_default); 14870 14871 %} 14872 14873 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14874 %{ 14875 match(Set dst (CmpF3 src1 zero)); 14876 effect(KILL cr); 14877 14878 ins_cost(5 * INSN_COST); 14879 format %{ "fcmps $src1, 0.0\n\t" 14880 "csinvw($dst, zr, zr, eq\n\t" 14881 "csnegw($dst, $dst, $dst, lt)" 14882 %} 14883 14884 ins_encode %{ 14885 Label done; 14886 FloatRegister s1 = as_FloatRegister($src1$$reg); 14887 Register d = as_Register($dst$$reg); 14888 __ fcmps(s1, 0.0); 14889 // installs 0 if EQ else -1 14890 __ csinvw(d, zr, zr, Assembler::EQ); 14891 // keeps -1 if less or unordered else installs 1 14892 __ csnegw(d, d, d, Assembler::LT); 14893 __ bind(done); 14894 %} 14895 14896 ins_pipe(pipe_class_default); 14897 14898 %} 14899 14900 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14901 %{ 14902 match(Set dst (CmpD3 src1 zero)); 14903 effect(KILL cr); 14904 14905 ins_cost(5 * INSN_COST); 14906 format %{ "fcmpd $src1, 0.0\n\t" 14907 "csinvw($dst, zr, zr, eq\n\t" 14908 "csnegw($dst, $dst, $dst, lt)" 14909 %} 14910 14911 ins_encode %{ 14912 Label done; 14913 FloatRegister s1 = as_FloatRegister($src1$$reg); 14914 Register d = as_Register($dst$$reg); 14915 __ fcmpd(s1, 0.0); 14916 // installs 0 if EQ else -1 14917 __ csinvw(d, zr, zr, Assembler::EQ); 14918 // keeps -1 if less or unordered else installs 1 14919 __ csnegw(d, d, d, Assembler::LT); 14920 __ bind(done); 14921 %} 14922 ins_pipe(pipe_class_default); 14923 14924 %} 14925 14926 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14927 %{ 14928 match(Set dst (CmpLTMask p q)); 14929 effect(KILL cr); 14930 14931 ins_cost(3 * INSN_COST); 14932 14933 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14934 "csetw $dst, lt\n\t" 14935 "subw $dst, zr, $dst" 14936 %} 14937 14938 ins_encode %{ 14939 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14940 __ csetw(as_Register($dst$$reg), Assembler::LT); 14941 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14942 %} 14943 14944 ins_pipe(ialu_reg_reg); 14945 %} 14946 14947 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14948 %{ 14949 match(Set dst (CmpLTMask src zero)); 14950 effect(KILL cr); 14951 14952 ins_cost(INSN_COST); 14953 14954 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14955 14956 ins_encode %{ 14957 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14958 %} 14959 14960 ins_pipe(ialu_reg_shift); 14961 %} 14962 14963 // ============================================================================ 14964 // Max and Min 14965 14966 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14967 %{ 14968 effect( DEF dst, USE src1, USE src2, USE cr ); 14969 14970 ins_cost(INSN_COST * 2); 14971 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14972 14973 ins_encode %{ 14974 __ cselw(as_Register($dst$$reg), 14975 as_Register($src1$$reg), 14976 as_Register($src2$$reg), 14977 Assembler::LT); 14978 %} 14979 14980 ins_pipe(icond_reg_reg); 14981 %} 14982 14983 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14984 %{ 14985 match(Set dst (MinI src1 src2)); 14986 ins_cost(INSN_COST * 3); 14987 14988 expand %{ 14989 rFlagsReg cr; 14990 compI_reg_reg(cr, src1, src2); 14991 cmovI_reg_reg_lt(dst, src1, src2, cr); 14992 %} 14993 14994 %} 14995 // FROM HERE 14996 14997 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14998 %{ 14999 effect( DEF dst, USE src1, USE src2, USE cr ); 15000 15001 ins_cost(INSN_COST * 2); 15002 format %{ "cselw $dst, $src1, $src2 gt\t" %} 15003 15004 ins_encode %{ 15005 __ cselw(as_Register($dst$$reg), 15006 as_Register($src1$$reg), 15007 as_Register($src2$$reg), 15008 Assembler::GT); 15009 %} 15010 15011 ins_pipe(icond_reg_reg); 15012 %} 15013 15014 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 15015 %{ 15016 match(Set dst (MaxI src1 src2)); 15017 ins_cost(INSN_COST * 3); 15018 expand %{ 15019 rFlagsReg cr; 15020 compI_reg_reg(cr, src1, src2); 15021 cmovI_reg_reg_gt(dst, src1, src2, cr); 15022 %} 15023 %} 15024 15025 // ============================================================================ 15026 // Branch Instructions 15027 15028 // Direct Branch. 15029 instruct branch(label lbl) 15030 %{ 15031 match(Goto); 15032 15033 effect(USE lbl); 15034 15035 ins_cost(BRANCH_COST); 15036 format %{ "b $lbl" %} 15037 15038 ins_encode(aarch64_enc_b(lbl)); 15039 15040 ins_pipe(pipe_branch); 15041 %} 15042 15043 // Conditional Near Branch 15044 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 15045 %{ 15046 // Same match rule as `branchConFar'. 15047 match(If cmp cr); 15048 15049 effect(USE lbl); 15050 15051 ins_cost(BRANCH_COST); 15052 // If set to 1 this indicates that the current instruction is a 15053 // short variant of a long branch. This avoids using this 15054 // instruction in first-pass matching. It will then only be used in 15055 // the `Shorten_branches' pass. 15056 // ins_short_branch(1); 15057 format %{ "b$cmp $lbl" %} 15058 15059 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15060 15061 ins_pipe(pipe_branch_cond); 15062 %} 15063 15064 // Conditional Near Branch Unsigned 15065 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15066 %{ 15067 // Same match rule as `branchConFar'. 15068 match(If cmp cr); 15069 15070 effect(USE lbl); 15071 15072 ins_cost(BRANCH_COST); 15073 // If set to 1 this indicates that the current instruction is a 15074 // short variant of a long branch. This avoids using this 15075 // instruction in first-pass matching. It will then only be used in 15076 // the `Shorten_branches' pass. 15077 // ins_short_branch(1); 15078 format %{ "b$cmp $lbl\t# unsigned" %} 15079 15080 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15081 15082 ins_pipe(pipe_branch_cond); 15083 %} 15084 15085 // Make use of CBZ and CBNZ. These instructions, as well as being 15086 // shorter than (cmp; branch), have the additional benefit of not 15087 // killing the flags. 15088 15089 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 15090 match(If cmp (CmpI op1 op2)); 15091 effect(USE labl); 15092 15093 ins_cost(BRANCH_COST); 15094 format %{ "cbw$cmp $op1, $labl" %} 15095 ins_encode %{ 15096 Label* L = $labl$$label; 15097 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15098 if (cond == Assembler::EQ) 15099 __ cbzw($op1$$Register, *L); 15100 else 15101 __ cbnzw($op1$$Register, *L); 15102 %} 15103 ins_pipe(pipe_cmp_branch); 15104 %} 15105 15106 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 15107 match(If cmp (CmpL op1 op2)); 15108 effect(USE labl); 15109 15110 ins_cost(BRANCH_COST); 15111 format %{ "cb$cmp $op1, $labl" %} 15112 ins_encode %{ 15113 Label* L = $labl$$label; 15114 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15115 if (cond == Assembler::EQ) 15116 __ cbz($op1$$Register, *L); 15117 else 15118 __ cbnz($op1$$Register, *L); 15119 %} 15120 ins_pipe(pipe_cmp_branch); 15121 %} 15122 15123 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 15124 match(If cmp (CmpP op1 op2)); 15125 effect(USE labl); 15126 15127 ins_cost(BRANCH_COST); 15128 format %{ "cb$cmp $op1, $labl" %} 15129 ins_encode %{ 15130 Label* L = $labl$$label; 15131 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15132 if (cond == Assembler::EQ) 15133 __ cbz($op1$$Register, *L); 15134 else 15135 __ cbnz($op1$$Register, *L); 15136 %} 15137 ins_pipe(pipe_cmp_branch); 15138 %} 15139 15140 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 15141 match(If cmp (CmpN op1 op2)); 15142 effect(USE labl); 15143 15144 ins_cost(BRANCH_COST); 15145 format %{ "cbw$cmp $op1, $labl" %} 15146 ins_encode %{ 15147 Label* L = $labl$$label; 15148 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15149 if (cond == Assembler::EQ) 15150 __ cbzw($op1$$Register, *L); 15151 else 15152 __ cbnzw($op1$$Register, *L); 15153 %} 15154 ins_pipe(pipe_cmp_branch); 15155 %} 15156 15157 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 15158 match(If cmp (CmpP (DecodeN oop) zero)); 15159 effect(USE labl); 15160 15161 ins_cost(BRANCH_COST); 15162 format %{ "cb$cmp $oop, $labl" %} 15163 ins_encode %{ 15164 Label* L = $labl$$label; 15165 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15166 if (cond == Assembler::EQ) 15167 __ cbzw($oop$$Register, *L); 15168 else 15169 __ cbnzw($oop$$Register, *L); 15170 %} 15171 ins_pipe(pipe_cmp_branch); 15172 %} 15173 15174 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 15175 match(If cmp (CmpU op1 op2)); 15176 effect(USE labl); 15177 15178 ins_cost(BRANCH_COST); 15179 format %{ "cbw$cmp $op1, $labl" %} 15180 ins_encode %{ 15181 Label* L = $labl$$label; 15182 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15183 if (cond == Assembler::EQ || cond == Assembler::LS) 15184 __ cbzw($op1$$Register, *L); 15185 else 15186 __ cbnzw($op1$$Register, *L); 15187 %} 15188 ins_pipe(pipe_cmp_branch); 15189 %} 15190 15191 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 15192 match(If cmp (CmpUL op1 op2)); 15193 effect(USE labl); 15194 15195 ins_cost(BRANCH_COST); 15196 format %{ "cb$cmp $op1, $labl" %} 15197 ins_encode %{ 15198 Label* L = $labl$$label; 15199 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15200 if (cond == Assembler::EQ || cond == Assembler::LS) 15201 __ cbz($op1$$Register, *L); 15202 else 15203 __ cbnz($op1$$Register, *L); 15204 %} 15205 ins_pipe(pipe_cmp_branch); 15206 %} 15207 15208 // Test bit and Branch 15209 15210 // Patterns for short (< 32KiB) variants 15211 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15212 match(If cmp (CmpL op1 op2)); 15213 effect(USE labl); 15214 15215 ins_cost(BRANCH_COST); 15216 format %{ "cb$cmp $op1, $labl # long" %} 15217 ins_encode %{ 15218 Label* L = $labl$$label; 15219 Assembler::Condition cond = 15220 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15221 __ tbr(cond, $op1$$Register, 63, *L); 15222 %} 15223 ins_pipe(pipe_cmp_branch); 15224 ins_short_branch(1); 15225 %} 15226 15227 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15228 match(If cmp (CmpI op1 op2)); 15229 effect(USE labl); 15230 15231 ins_cost(BRANCH_COST); 15232 format %{ "cb$cmp $op1, $labl # int" %} 15233 ins_encode %{ 15234 Label* L = $labl$$label; 15235 Assembler::Condition cond = 15236 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15237 __ tbr(cond, $op1$$Register, 31, *L); 15238 %} 15239 ins_pipe(pipe_cmp_branch); 15240 ins_short_branch(1); 15241 %} 15242 15243 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15244 match(If cmp (CmpL (AndL op1 op2) op3)); 15245 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15246 effect(USE labl); 15247 15248 ins_cost(BRANCH_COST); 15249 format %{ "tb$cmp $op1, $op2, $labl" %} 15250 ins_encode %{ 15251 Label* L = $labl$$label; 15252 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15253 int bit = exact_log2_long($op2$$constant); 15254 __ tbr(cond, $op1$$Register, bit, *L); 15255 %} 15256 ins_pipe(pipe_cmp_branch); 15257 ins_short_branch(1); 15258 %} 15259 15260 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15261 match(If cmp (CmpI (AndI op1 op2) op3)); 15262 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15263 effect(USE labl); 15264 15265 ins_cost(BRANCH_COST); 15266 format %{ "tb$cmp $op1, $op2, $labl" %} 15267 ins_encode %{ 15268 Label* L = $labl$$label; 15269 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15270 int bit = exact_log2((juint)$op2$$constant); 15271 __ tbr(cond, $op1$$Register, bit, *L); 15272 %} 15273 ins_pipe(pipe_cmp_branch); 15274 ins_short_branch(1); 15275 %} 15276 15277 // And far variants 15278 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15279 match(If cmp (CmpL op1 op2)); 15280 effect(USE labl); 15281 15282 ins_cost(BRANCH_COST); 15283 format %{ "cb$cmp $op1, $labl # long" %} 15284 ins_encode %{ 15285 Label* L = $labl$$label; 15286 Assembler::Condition cond = 15287 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15288 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 15289 %} 15290 ins_pipe(pipe_cmp_branch); 15291 %} 15292 15293 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15294 match(If cmp (CmpI op1 op2)); 15295 effect(USE labl); 15296 15297 ins_cost(BRANCH_COST); 15298 format %{ "cb$cmp $op1, $labl # int" %} 15299 ins_encode %{ 15300 Label* L = $labl$$label; 15301 Assembler::Condition cond = 15302 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15303 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 15304 %} 15305 ins_pipe(pipe_cmp_branch); 15306 %} 15307 15308 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15309 match(If cmp (CmpL (AndL op1 op2) op3)); 15310 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15311 effect(USE labl); 15312 15313 ins_cost(BRANCH_COST); 15314 format %{ "tb$cmp $op1, $op2, $labl" %} 15315 ins_encode %{ 15316 Label* L = $labl$$label; 15317 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15318 int bit = exact_log2_long($op2$$constant); 15319 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15320 %} 15321 ins_pipe(pipe_cmp_branch); 15322 %} 15323 15324 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15325 match(If cmp (CmpI (AndI op1 op2) op3)); 15326 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15327 effect(USE labl); 15328 15329 ins_cost(BRANCH_COST); 15330 format %{ "tb$cmp $op1, $op2, $labl" %} 15331 ins_encode %{ 15332 Label* L = $labl$$label; 15333 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15334 int bit = exact_log2((juint)$op2$$constant); 15335 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15336 %} 15337 ins_pipe(pipe_cmp_branch); 15338 %} 15339 15340 // Test bits 15341 15342 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15343 match(Set cr (CmpL (AndL op1 op2) op3)); 15344 predicate(Assembler::operand_valid_for_logical_immediate 15345 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15346 15347 ins_cost(INSN_COST); 15348 format %{ "tst $op1, $op2 # long" %} 15349 ins_encode %{ 15350 __ tst($op1$$Register, $op2$$constant); 15351 %} 15352 ins_pipe(ialu_reg_reg); 15353 %} 15354 15355 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15356 match(Set cr (CmpI (AndI op1 op2) op3)); 15357 predicate(Assembler::operand_valid_for_logical_immediate 15358 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15359 15360 ins_cost(INSN_COST); 15361 format %{ "tst $op1, $op2 # int" %} 15362 ins_encode %{ 15363 __ tstw($op1$$Register, $op2$$constant); 15364 %} 15365 ins_pipe(ialu_reg_reg); 15366 %} 15367 15368 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15369 match(Set cr (CmpL (AndL op1 op2) op3)); 15370 15371 ins_cost(INSN_COST); 15372 format %{ "tst $op1, $op2 # long" %} 15373 ins_encode %{ 15374 __ tst($op1$$Register, $op2$$Register); 15375 %} 15376 ins_pipe(ialu_reg_reg); 15377 %} 15378 15379 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15380 match(Set cr (CmpI (AndI op1 op2) op3)); 15381 15382 ins_cost(INSN_COST); 15383 format %{ "tstw $op1, $op2 # int" %} 15384 ins_encode %{ 15385 __ tstw($op1$$Register, $op2$$Register); 15386 %} 15387 ins_pipe(ialu_reg_reg); 15388 %} 15389 15390 15391 // Conditional Far Branch 15392 // Conditional Far Branch Unsigned 15393 // TODO: fixme 15394 15395 // counted loop end branch near 15396 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15397 %{ 15398 match(CountedLoopEnd cmp cr); 15399 15400 effect(USE lbl); 15401 15402 ins_cost(BRANCH_COST); 15403 // short variant. 15404 // ins_short_branch(1); 15405 format %{ "b$cmp $lbl \t// counted loop end" %} 15406 15407 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15408 15409 ins_pipe(pipe_branch); 15410 %} 15411 15412 // counted loop end branch near Unsigned 15413 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15414 %{ 15415 match(CountedLoopEnd cmp cr); 15416 15417 effect(USE lbl); 15418 15419 ins_cost(BRANCH_COST); 15420 // short variant. 15421 // ins_short_branch(1); 15422 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15423 15424 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15425 15426 ins_pipe(pipe_branch); 15427 %} 15428 15429 // counted loop end branch far 15430 // counted loop end branch far unsigned 15431 // TODO: fixme 15432 15433 // ============================================================================ 15434 // inlined locking and unlocking 15435 15436 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15437 %{ 15438 match(Set cr (FastLock object box)); 15439 effect(TEMP tmp, TEMP tmp2); 15440 15441 // TODO 15442 // identify correct cost 15443 ins_cost(5 * INSN_COST); 15444 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15445 15446 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15447 15448 ins_pipe(pipe_serial); 15449 %} 15450 15451 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15452 %{ 15453 match(Set cr (FastUnlock object box)); 15454 effect(TEMP tmp, TEMP tmp2); 15455 15456 ins_cost(5 * INSN_COST); 15457 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15458 15459 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15460 15461 ins_pipe(pipe_serial); 15462 %} 15463 15464 15465 // ============================================================================ 15466 // Safepoint Instructions 15467 15468 // TODO 15469 // provide a near and far version of this code 15470 15471 instruct safePoint(rFlagsReg cr, iRegP poll) 15472 %{ 15473 match(SafePoint poll); 15474 effect(KILL cr); 15475 15476 format %{ 15477 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15478 %} 15479 ins_encode %{ 15480 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15481 %} 15482 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15483 %} 15484 15485 15486 // ============================================================================ 15487 // Procedure Call/Return Instructions 15488 15489 // Call Java Static Instruction 15490 15491 instruct CallStaticJavaDirect(method meth) 15492 %{ 15493 match(CallStaticJava); 15494 15495 effect(USE meth); 15496 15497 ins_cost(CALL_COST); 15498 15499 format %{ "call,static $meth \t// ==> " %} 15500 15501 ins_encode( aarch64_enc_java_static_call(meth), 15502 aarch64_enc_call_epilog ); 15503 15504 ins_pipe(pipe_class_call); 15505 %} 15506 15507 // TO HERE 15508 15509 // Call Java Dynamic Instruction 15510 instruct CallDynamicJavaDirect(method meth) 15511 %{ 15512 match(CallDynamicJava); 15513 15514 effect(USE meth); 15515 15516 ins_cost(CALL_COST); 15517 15518 format %{ "CALL,dynamic $meth \t// ==> " %} 15519 15520 ins_encode( aarch64_enc_java_dynamic_call(meth), 15521 aarch64_enc_call_epilog ); 15522 15523 ins_pipe(pipe_class_call); 15524 %} 15525 15526 // Call Runtime Instruction 15527 15528 instruct CallRuntimeDirect(method meth) 15529 %{ 15530 match(CallRuntime); 15531 15532 effect(USE meth); 15533 15534 ins_cost(CALL_COST); 15535 15536 format %{ "CALL, runtime $meth" %} 15537 15538 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15539 15540 ins_pipe(pipe_class_call); 15541 %} 15542 15543 // Call Runtime Instruction 15544 15545 instruct CallLeafDirect(method meth) 15546 %{ 15547 match(CallLeaf); 15548 15549 effect(USE meth); 15550 15551 ins_cost(CALL_COST); 15552 15553 format %{ "CALL, runtime leaf $meth" %} 15554 15555 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15556 15557 ins_pipe(pipe_class_call); 15558 %} 15559 15560 // Call Runtime Instruction 15561 15562 instruct CallLeafNoFPDirect(method meth) 15563 %{ 15564 match(CallLeafNoFP); 15565 15566 effect(USE meth); 15567 15568 ins_cost(CALL_COST); 15569 15570 format %{ "CALL, runtime leaf nofp $meth" %} 15571 15572 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15573 15574 ins_pipe(pipe_class_call); 15575 %} 15576 15577 // Tail Call; Jump from runtime stub to Java code. 15578 // Also known as an 'interprocedural jump'. 15579 // Target of jump will eventually return to caller. 15580 // TailJump below removes the return address. 15581 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr) 15582 %{ 15583 match(TailCall jump_target method_ptr); 15584 15585 ins_cost(CALL_COST); 15586 15587 format %{ "br $jump_target\t# $method_ptr holds method" %} 15588 15589 ins_encode(aarch64_enc_tail_call(jump_target)); 15590 15591 ins_pipe(pipe_class_call); 15592 %} 15593 15594 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15595 %{ 15596 match(TailJump jump_target ex_oop); 15597 15598 ins_cost(CALL_COST); 15599 15600 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15601 15602 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15603 15604 ins_pipe(pipe_class_call); 15605 %} 15606 15607 // Create exception oop: created by stack-crawling runtime code. 15608 // Created exception is now available to this handler, and is setup 15609 // just prior to jumping to this handler. No code emitted. 15610 // TODO check 15611 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15612 instruct CreateException(iRegP_R0 ex_oop) 15613 %{ 15614 match(Set ex_oop (CreateEx)); 15615 15616 format %{ " -- \t// exception oop; no code emitted" %} 15617 15618 size(0); 15619 15620 ins_encode( /*empty*/ ); 15621 15622 ins_pipe(pipe_class_empty); 15623 %} 15624 15625 // Rethrow exception: The exception oop will come in the first 15626 // argument position. Then JUMP (not call) to the rethrow stub code. 15627 instruct RethrowException() %{ 15628 match(Rethrow); 15629 ins_cost(CALL_COST); 15630 15631 format %{ "b rethrow_stub" %} 15632 15633 ins_encode( aarch64_enc_rethrow() ); 15634 15635 ins_pipe(pipe_class_call); 15636 %} 15637 15638 15639 // Return Instruction 15640 // epilog node loads ret address into lr as part of frame pop 15641 instruct Ret() 15642 %{ 15643 match(Return); 15644 15645 format %{ "ret\t// return register" %} 15646 15647 ins_encode( aarch64_enc_ret() ); 15648 15649 ins_pipe(pipe_branch); 15650 %} 15651 15652 // Die now. 15653 instruct ShouldNotReachHere() %{ 15654 match(Halt); 15655 15656 ins_cost(CALL_COST); 15657 format %{ "ShouldNotReachHere" %} 15658 15659 ins_encode %{ 15660 if (is_reachable()) { 15661 __ stop(_halt_reason); 15662 } 15663 %} 15664 15665 ins_pipe(pipe_class_default); 15666 %} 15667 15668 // ============================================================================ 15669 // Partial Subtype Check 15670 // 15671 // superklass array for an instance of the superklass. Set a hidden 15672 // internal cache on a hit (cache is checked with exposed code in 15673 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15674 // encoding ALSO sets flags. 15675 15676 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15677 %{ 15678 match(Set result (PartialSubtypeCheck sub super)); 15679 effect(KILL cr, KILL temp); 15680 15681 ins_cost(1100); // slightly larger than the next version 15682 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15683 15684 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15685 15686 opcode(0x1); // Force zero of result reg on hit 15687 15688 ins_pipe(pipe_class_memory); 15689 %} 15690 15691 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15692 %{ 15693 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15694 effect(KILL temp, KILL result); 15695 15696 ins_cost(1100); // slightly larger than the next version 15697 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15698 15699 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15700 15701 opcode(0x0); // Don't zero result reg on hit 15702 15703 ins_pipe(pipe_class_memory); 15704 %} 15705 15706 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15707 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15708 %{ 15709 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15710 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15711 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15712 15713 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15714 ins_encode %{ 15715 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15716 __ string_compare($str1$$Register, $str2$$Register, 15717 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15718 $tmp1$$Register, $tmp2$$Register, 15719 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15720 %} 15721 ins_pipe(pipe_class_memory); 15722 %} 15723 15724 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15725 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15726 %{ 15727 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15728 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15729 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15730 15731 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15732 ins_encode %{ 15733 __ string_compare($str1$$Register, $str2$$Register, 15734 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15735 $tmp1$$Register, $tmp2$$Register, 15736 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15737 %} 15738 ins_pipe(pipe_class_memory); 15739 %} 15740 15741 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15742 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15743 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15744 %{ 15745 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15746 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15747 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15748 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15749 15750 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15751 ins_encode %{ 15752 __ string_compare($str1$$Register, $str2$$Register, 15753 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15754 $tmp1$$Register, $tmp2$$Register, 15755 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15756 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15757 %} 15758 ins_pipe(pipe_class_memory); 15759 %} 15760 15761 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15762 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15763 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15764 %{ 15765 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15766 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15767 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15768 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15769 15770 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15771 ins_encode %{ 15772 __ string_compare($str1$$Register, $str2$$Register, 15773 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15774 $tmp1$$Register, $tmp2$$Register, 15775 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15776 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15777 %} 15778 ins_pipe(pipe_class_memory); 15779 %} 15780 15781 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15782 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15783 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15784 %{ 15785 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15786 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15787 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15788 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15789 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15790 15791 ins_encode %{ 15792 __ string_indexof($str1$$Register, $str2$$Register, 15793 $cnt1$$Register, $cnt2$$Register, 15794 $tmp1$$Register, $tmp2$$Register, 15795 $tmp3$$Register, $tmp4$$Register, 15796 $tmp5$$Register, $tmp6$$Register, 15797 -1, $result$$Register, StrIntrinsicNode::UU); 15798 %} 15799 ins_pipe(pipe_class_memory); 15800 %} 15801 15802 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15803 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15804 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15805 %{ 15806 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15807 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15808 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15809 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15810 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15811 15812 ins_encode %{ 15813 __ string_indexof($str1$$Register, $str2$$Register, 15814 $cnt1$$Register, $cnt2$$Register, 15815 $tmp1$$Register, $tmp2$$Register, 15816 $tmp3$$Register, $tmp4$$Register, 15817 $tmp5$$Register, $tmp6$$Register, 15818 -1, $result$$Register, StrIntrinsicNode::LL); 15819 %} 15820 ins_pipe(pipe_class_memory); 15821 %} 15822 15823 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15824 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15825 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15826 %{ 15827 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15828 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15829 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15830 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15831 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15832 15833 ins_encode %{ 15834 __ string_indexof($str1$$Register, $str2$$Register, 15835 $cnt1$$Register, $cnt2$$Register, 15836 $tmp1$$Register, $tmp2$$Register, 15837 $tmp3$$Register, $tmp4$$Register, 15838 $tmp5$$Register, $tmp6$$Register, 15839 -1, $result$$Register, StrIntrinsicNode::UL); 15840 %} 15841 ins_pipe(pipe_class_memory); 15842 %} 15843 15844 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15845 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15846 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15847 %{ 15848 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15849 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15850 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15851 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15852 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15853 15854 ins_encode %{ 15855 int icnt2 = (int)$int_cnt2$$constant; 15856 __ string_indexof($str1$$Register, $str2$$Register, 15857 $cnt1$$Register, zr, 15858 $tmp1$$Register, $tmp2$$Register, 15859 $tmp3$$Register, $tmp4$$Register, zr, zr, 15860 icnt2, $result$$Register, StrIntrinsicNode::UU); 15861 %} 15862 ins_pipe(pipe_class_memory); 15863 %} 15864 15865 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15866 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15867 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15868 %{ 15869 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15870 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15871 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15872 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15873 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15874 15875 ins_encode %{ 15876 int icnt2 = (int)$int_cnt2$$constant; 15877 __ string_indexof($str1$$Register, $str2$$Register, 15878 $cnt1$$Register, zr, 15879 $tmp1$$Register, $tmp2$$Register, 15880 $tmp3$$Register, $tmp4$$Register, zr, zr, 15881 icnt2, $result$$Register, StrIntrinsicNode::LL); 15882 %} 15883 ins_pipe(pipe_class_memory); 15884 %} 15885 15886 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15887 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15888 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15889 %{ 15890 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15891 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15892 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15893 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15894 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15895 15896 ins_encode %{ 15897 int icnt2 = (int)$int_cnt2$$constant; 15898 __ string_indexof($str1$$Register, $str2$$Register, 15899 $cnt1$$Register, zr, 15900 $tmp1$$Register, $tmp2$$Register, 15901 $tmp3$$Register, $tmp4$$Register, zr, zr, 15902 icnt2, $result$$Register, StrIntrinsicNode::UL); 15903 %} 15904 ins_pipe(pipe_class_memory); 15905 %} 15906 15907 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15908 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15909 iRegINoSp tmp3, rFlagsReg cr) 15910 %{ 15911 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15912 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15913 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15914 15915 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15916 15917 ins_encode %{ 15918 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15919 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15920 $tmp3$$Register); 15921 %} 15922 ins_pipe(pipe_class_memory); 15923 %} 15924 15925 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15926 iRegI_R0 result, rFlagsReg cr) 15927 %{ 15928 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15929 match(Set result (StrEquals (Binary str1 str2) cnt)); 15930 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15931 15932 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15933 ins_encode %{ 15934 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15935 __ string_equals($str1$$Register, $str2$$Register, 15936 $result$$Register, $cnt$$Register, 1); 15937 %} 15938 ins_pipe(pipe_class_memory); 15939 %} 15940 15941 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15942 iRegI_R0 result, rFlagsReg cr) 15943 %{ 15944 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15945 match(Set result (StrEquals (Binary str1 str2) cnt)); 15946 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15947 15948 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15949 ins_encode %{ 15950 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15951 __ string_equals($str1$$Register, $str2$$Register, 15952 $result$$Register, $cnt$$Register, 2); 15953 %} 15954 ins_pipe(pipe_class_memory); 15955 %} 15956 15957 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15958 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15959 iRegP_R10 tmp, rFlagsReg cr) 15960 %{ 15961 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15962 match(Set result (AryEq ary1 ary2)); 15963 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15964 15965 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15966 ins_encode %{ 15967 __ arrays_equals($ary1$$Register, $ary2$$Register, 15968 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15969 $result$$Register, $tmp$$Register, 1); 15970 %} 15971 ins_pipe(pipe_class_memory); 15972 %} 15973 15974 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15975 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15976 iRegP_R10 tmp, rFlagsReg cr) 15977 %{ 15978 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15979 match(Set result (AryEq ary1 ary2)); 15980 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15981 15982 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15983 ins_encode %{ 15984 __ arrays_equals($ary1$$Register, $ary2$$Register, 15985 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15986 $result$$Register, $tmp$$Register, 2); 15987 %} 15988 ins_pipe(pipe_class_memory); 15989 %} 15990 15991 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15992 %{ 15993 match(Set result (HasNegatives ary1 len)); 15994 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15995 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15996 ins_encode %{ 15997 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15998 %} 15999 ins_pipe( pipe_slow ); 16000 %} 16001 16002 // fast char[] to byte[] compression 16003 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16004 vRegD_V0 tmp1, vRegD_V1 tmp2, 16005 vRegD_V2 tmp3, vRegD_V3 tmp4, 16006 iRegI_R0 result, rFlagsReg cr) 16007 %{ 16008 match(Set result (StrCompressedCopy src (Binary dst len))); 16009 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 16010 16011 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 16012 ins_encode %{ 16013 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 16014 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 16015 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 16016 $result$$Register); 16017 %} 16018 ins_pipe( pipe_slow ); 16019 %} 16020 16021 // fast byte[] to char[] inflation 16022 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 16023 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 16024 %{ 16025 match(Set dummy (StrInflatedCopy src (Binary dst len))); 16026 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 16027 16028 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 16029 ins_encode %{ 16030 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 16031 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 16032 %} 16033 ins_pipe(pipe_class_memory); 16034 %} 16035 16036 // encode char[] to byte[] in ISO_8859_1 16037 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16038 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 16039 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 16040 iRegI_R0 result, rFlagsReg cr) 16041 %{ 16042 match(Set result (EncodeISOArray src (Binary dst len))); 16043 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 16044 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 16045 16046 format %{ "Encode array $src,$dst,$len -> $result" %} 16047 ins_encode %{ 16048 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 16049 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 16050 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 16051 %} 16052 ins_pipe( pipe_class_memory ); 16053 %} 16054 16055 // ============================================================================ 16056 // This name is KNOWN by the ADLC and cannot be changed. 16057 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 16058 // for this guy. 16059 instruct tlsLoadP(thread_RegP dst) 16060 %{ 16061 match(Set dst (ThreadLocal)); 16062 16063 ins_cost(0); 16064 16065 format %{ " -- \t// $dst=Thread::current(), empty" %} 16066 16067 size(0); 16068 16069 ins_encode( /*empty*/ ); 16070 16071 ins_pipe(pipe_class_empty); 16072 %} 16073 16074 // ====================VECTOR INSTRUCTIONS===================================== 16075 16076 // Load vector (32 bits) 16077 instruct loadV4(vecD dst, vmem4 mem) 16078 %{ 16079 predicate(n->as_LoadVector()->memory_size() == 4); 16080 match(Set dst (LoadVector mem)); 16081 ins_cost(4 * INSN_COST); 16082 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 16083 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 16084 ins_pipe(vload_reg_mem64); 16085 %} 16086 16087 // Load vector (64 bits) 16088 instruct loadV8(vecD dst, vmem8 mem) 16089 %{ 16090 predicate(n->as_LoadVector()->memory_size() == 8); 16091 match(Set dst (LoadVector mem)); 16092 ins_cost(4 * INSN_COST); 16093 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 16094 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 16095 ins_pipe(vload_reg_mem64); 16096 %} 16097 16098 // Load Vector (128 bits) 16099 instruct loadV16(vecX dst, vmem16 mem) 16100 %{ 16101 predicate(n->as_LoadVector()->memory_size() == 16); 16102 match(Set dst (LoadVector mem)); 16103 ins_cost(4 * INSN_COST); 16104 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 16105 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 16106 ins_pipe(vload_reg_mem128); 16107 %} 16108 16109 // Store Vector (32 bits) 16110 instruct storeV4(vecD src, vmem4 mem) 16111 %{ 16112 predicate(n->as_StoreVector()->memory_size() == 4); 16113 match(Set mem (StoreVector mem src)); 16114 ins_cost(4 * INSN_COST); 16115 format %{ "strs $mem,$src\t# vector (32 bits)" %} 16116 ins_encode( aarch64_enc_strvS(src, mem) ); 16117 ins_pipe(vstore_reg_mem64); 16118 %} 16119 16120 // Store Vector (64 bits) 16121 instruct storeV8(vecD src, vmem8 mem) 16122 %{ 16123 predicate(n->as_StoreVector()->memory_size() == 8); 16124 match(Set mem (StoreVector mem src)); 16125 ins_cost(4 * INSN_COST); 16126 format %{ "strd $mem,$src\t# vector (64 bits)" %} 16127 ins_encode( aarch64_enc_strvD(src, mem) ); 16128 ins_pipe(vstore_reg_mem64); 16129 %} 16130 16131 // Store Vector (128 bits) 16132 instruct storeV16(vecX src, vmem16 mem) 16133 %{ 16134 predicate(n->as_StoreVector()->memory_size() == 16); 16135 match(Set mem (StoreVector mem src)); 16136 ins_cost(4 * INSN_COST); 16137 format %{ "strq $mem,$src\t# vector (128 bits)" %} 16138 ins_encode( aarch64_enc_strvQ(src, mem) ); 16139 ins_pipe(vstore_reg_mem128); 16140 %} 16141 16142 instruct replicate8B(vecD dst, iRegIorL2I src) 16143 %{ 16144 predicate(n->as_Vector()->length() == 4 || 16145 n->as_Vector()->length() == 8); 16146 match(Set dst (ReplicateB src)); 16147 ins_cost(INSN_COST); 16148 format %{ "dup $dst, $src\t# vector (8B)" %} 16149 ins_encode %{ 16150 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 16151 %} 16152 ins_pipe(vdup_reg_reg64); 16153 %} 16154 16155 instruct replicate16B(vecX dst, iRegIorL2I src) 16156 %{ 16157 predicate(n->as_Vector()->length() == 16); 16158 match(Set dst (ReplicateB src)); 16159 ins_cost(INSN_COST); 16160 format %{ "dup $dst, $src\t# vector (16B)" %} 16161 ins_encode %{ 16162 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 16163 %} 16164 ins_pipe(vdup_reg_reg128); 16165 %} 16166 16167 instruct replicate8B_imm(vecD dst, immI con) 16168 %{ 16169 predicate(n->as_Vector()->length() == 4 || 16170 n->as_Vector()->length() == 8); 16171 match(Set dst (ReplicateB con)); 16172 ins_cost(INSN_COST); 16173 format %{ "movi $dst, $con\t# vector(8B)" %} 16174 ins_encode %{ 16175 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 16176 %} 16177 ins_pipe(vmovi_reg_imm64); 16178 %} 16179 16180 instruct replicate16B_imm(vecX dst, immI con) 16181 %{ 16182 predicate(n->as_Vector()->length() == 16); 16183 match(Set dst (ReplicateB con)); 16184 ins_cost(INSN_COST); 16185 format %{ "movi $dst, $con\t# vector(16B)" %} 16186 ins_encode %{ 16187 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 16188 %} 16189 ins_pipe(vmovi_reg_imm128); 16190 %} 16191 16192 instruct replicate4S(vecD dst, iRegIorL2I src) 16193 %{ 16194 predicate(n->as_Vector()->length() == 2 || 16195 n->as_Vector()->length() == 4); 16196 match(Set dst (ReplicateS src)); 16197 ins_cost(INSN_COST); 16198 format %{ "dup $dst, $src\t# vector (4S)" %} 16199 ins_encode %{ 16200 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 16201 %} 16202 ins_pipe(vdup_reg_reg64); 16203 %} 16204 16205 instruct replicate8S(vecX dst, iRegIorL2I src) 16206 %{ 16207 predicate(n->as_Vector()->length() == 8); 16208 match(Set dst (ReplicateS src)); 16209 ins_cost(INSN_COST); 16210 format %{ "dup $dst, $src\t# vector (8S)" %} 16211 ins_encode %{ 16212 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 16213 %} 16214 ins_pipe(vdup_reg_reg128); 16215 %} 16216 16217 instruct replicate4S_imm(vecD dst, immI con) 16218 %{ 16219 predicate(n->as_Vector()->length() == 2 || 16220 n->as_Vector()->length() == 4); 16221 match(Set dst (ReplicateS con)); 16222 ins_cost(INSN_COST); 16223 format %{ "movi $dst, $con\t# vector(4H)" %} 16224 ins_encode %{ 16225 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 16226 %} 16227 ins_pipe(vmovi_reg_imm64); 16228 %} 16229 16230 instruct replicate8S_imm(vecX dst, immI con) 16231 %{ 16232 predicate(n->as_Vector()->length() == 8); 16233 match(Set dst (ReplicateS con)); 16234 ins_cost(INSN_COST); 16235 format %{ "movi $dst, $con\t# vector(8H)" %} 16236 ins_encode %{ 16237 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 16238 %} 16239 ins_pipe(vmovi_reg_imm128); 16240 %} 16241 16242 instruct replicate2I(vecD dst, iRegIorL2I src) 16243 %{ 16244 predicate(n->as_Vector()->length() == 2); 16245 match(Set dst (ReplicateI src)); 16246 ins_cost(INSN_COST); 16247 format %{ "dup $dst, $src\t# vector (2I)" %} 16248 ins_encode %{ 16249 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 16250 %} 16251 ins_pipe(vdup_reg_reg64); 16252 %} 16253 16254 instruct replicate4I(vecX dst, iRegIorL2I src) 16255 %{ 16256 predicate(n->as_Vector()->length() == 4); 16257 match(Set dst (ReplicateI src)); 16258 ins_cost(INSN_COST); 16259 format %{ "dup $dst, $src\t# vector (4I)" %} 16260 ins_encode %{ 16261 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 16262 %} 16263 ins_pipe(vdup_reg_reg128); 16264 %} 16265 16266 instruct replicate2I_imm(vecD dst, immI con) 16267 %{ 16268 predicate(n->as_Vector()->length() == 2); 16269 match(Set dst (ReplicateI con)); 16270 ins_cost(INSN_COST); 16271 format %{ "movi $dst, $con\t# vector(2I)" %} 16272 ins_encode %{ 16273 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 16274 %} 16275 ins_pipe(vmovi_reg_imm64); 16276 %} 16277 16278 instruct replicate4I_imm(vecX dst, immI con) 16279 %{ 16280 predicate(n->as_Vector()->length() == 4); 16281 match(Set dst (ReplicateI con)); 16282 ins_cost(INSN_COST); 16283 format %{ "movi $dst, $con\t# vector(4I)" %} 16284 ins_encode %{ 16285 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 16286 %} 16287 ins_pipe(vmovi_reg_imm128); 16288 %} 16289 16290 instruct replicate2L(vecX dst, iRegL src) 16291 %{ 16292 predicate(n->as_Vector()->length() == 2); 16293 match(Set dst (ReplicateL src)); 16294 ins_cost(INSN_COST); 16295 format %{ "dup $dst, $src\t# vector (2L)" %} 16296 ins_encode %{ 16297 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 16298 %} 16299 ins_pipe(vdup_reg_reg128); 16300 %} 16301 16302 instruct replicate2L_zero(vecX dst, immI0 zero) 16303 %{ 16304 predicate(n->as_Vector()->length() == 2); 16305 match(Set dst (ReplicateI zero)); 16306 ins_cost(INSN_COST); 16307 format %{ "movi $dst, $zero\t# vector(4I)" %} 16308 ins_encode %{ 16309 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16310 as_FloatRegister($dst$$reg), 16311 as_FloatRegister($dst$$reg)); 16312 %} 16313 ins_pipe(vmovi_reg_imm128); 16314 %} 16315 16316 instruct replicate2F(vecD dst, vRegF src) 16317 %{ 16318 predicate(n->as_Vector()->length() == 2); 16319 match(Set dst (ReplicateF src)); 16320 ins_cost(INSN_COST); 16321 format %{ "dup $dst, $src\t# vector (2F)" %} 16322 ins_encode %{ 16323 __ dup(as_FloatRegister($dst$$reg), __ T2S, 16324 as_FloatRegister($src$$reg)); 16325 %} 16326 ins_pipe(vdup_reg_freg64); 16327 %} 16328 16329 instruct replicate4F(vecX dst, vRegF src) 16330 %{ 16331 predicate(n->as_Vector()->length() == 4); 16332 match(Set dst (ReplicateF src)); 16333 ins_cost(INSN_COST); 16334 format %{ "dup $dst, $src\t# vector (4F)" %} 16335 ins_encode %{ 16336 __ dup(as_FloatRegister($dst$$reg), __ T4S, 16337 as_FloatRegister($src$$reg)); 16338 %} 16339 ins_pipe(vdup_reg_freg128); 16340 %} 16341 16342 instruct replicate2D(vecX dst, vRegD src) 16343 %{ 16344 predicate(n->as_Vector()->length() == 2); 16345 match(Set dst (ReplicateD src)); 16346 ins_cost(INSN_COST); 16347 format %{ "dup $dst, $src\t# vector (2D)" %} 16348 ins_encode %{ 16349 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16350 as_FloatRegister($src$$reg)); 16351 %} 16352 ins_pipe(vdup_reg_dreg128); 16353 %} 16354 16355 // ====================REDUCTION ARITHMETIC==================================== 16356 16357 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp, iRegINoSp tmp2) 16358 %{ 16359 match(Set dst (AddReductionVI isrc vsrc)); 16360 ins_cost(INSN_COST); 16361 effect(TEMP tmp, TEMP tmp2); 16362 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16363 "umov $tmp2, $vsrc, S, 1\n\t" 16364 "addw $tmp, $isrc, $tmp\n\t" 16365 "addw $dst, $tmp, $tmp2\t# add reduction2I" 16366 %} 16367 ins_encode %{ 16368 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16369 __ umov($tmp2$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16370 __ addw($tmp$$Register, $isrc$$Register, $tmp$$Register); 16371 __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); 16372 %} 16373 ins_pipe(pipe_class_default); 16374 %} 16375 16376 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16377 %{ 16378 match(Set dst (AddReductionVI isrc vsrc)); 16379 ins_cost(INSN_COST); 16380 effect(TEMP vtmp, TEMP itmp); 16381 format %{ "addv $vtmp, T4S, $vsrc\n\t" 16382 "umov $itmp, $vtmp, S, 0\n\t" 16383 "addw $dst, $itmp, $isrc\t# add reduction4I" 16384 %} 16385 ins_encode %{ 16386 __ addv(as_FloatRegister($vtmp$$reg), __ T4S, 16387 as_FloatRegister($vsrc$$reg)); 16388 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16389 __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); 16390 %} 16391 ins_pipe(pipe_class_default); 16392 %} 16393 16394 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) 16395 %{ 16396 match(Set dst (MulReductionVI isrc vsrc)); 16397 ins_cost(INSN_COST); 16398 effect(TEMP tmp, TEMP dst); 16399 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16400 "mul $dst, $tmp, $isrc\n\t" 16401 "umov $tmp, $vsrc, S, 1\n\t" 16402 "mul $dst, $tmp, $dst\t# mul reduction2I" 16403 %} 16404 ins_encode %{ 16405 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16406 __ mul($dst$$Register, $tmp$$Register, $isrc$$Register); 16407 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16408 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16409 %} 16410 ins_pipe(pipe_class_default); 16411 %} 16412 16413 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16414 %{ 16415 match(Set dst (MulReductionVI isrc vsrc)); 16416 ins_cost(INSN_COST); 16417 effect(TEMP vtmp, TEMP itmp, TEMP dst); 16418 format %{ "ins $vtmp, D, $vsrc, 0, 1\n\t" 16419 "mulv $vtmp, T2S, $vtmp, $vsrc\n\t" 16420 "umov $itmp, $vtmp, S, 0\n\t" 16421 "mul $dst, $itmp, $isrc\n\t" 16422 "umov $itmp, $vtmp, S, 1\n\t" 16423 "mul $dst, $itmp, $dst\t# mul reduction4I" 16424 %} 16425 ins_encode %{ 16426 __ ins(as_FloatRegister($vtmp$$reg), __ D, 16427 as_FloatRegister($vsrc$$reg), 0, 1); 16428 __ mulv(as_FloatRegister($vtmp$$reg), __ T2S, 16429 as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); 16430 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16431 __ mul($dst$$Register, $itmp$$Register, $isrc$$Register); 16432 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 1); 16433 __ mul($dst$$Register, $itmp$$Register, $dst$$Register); 16434 %} 16435 ins_pipe(pipe_class_default); 16436 %} 16437 16438 instruct reduce_add2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16439 %{ 16440 match(Set dst (AddReductionVF fsrc vsrc)); 16441 ins_cost(INSN_COST); 16442 effect(TEMP tmp, TEMP dst); 16443 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16444 "ins $tmp, S, $vsrc, 0, 1\n\t" 16445 "fadds $dst, $dst, $tmp\t# add reduction2F" 16446 %} 16447 ins_encode %{ 16448 __ fadds(as_FloatRegister($dst$$reg), 16449 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16450 __ ins(as_FloatRegister($tmp$$reg), __ S, 16451 as_FloatRegister($vsrc$$reg), 0, 1); 16452 __ fadds(as_FloatRegister($dst$$reg), 16453 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16454 %} 16455 ins_pipe(pipe_class_default); 16456 %} 16457 16458 instruct reduce_add4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16459 %{ 16460 match(Set dst (AddReductionVF fsrc vsrc)); 16461 ins_cost(INSN_COST); 16462 effect(TEMP tmp, TEMP dst); 16463 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16464 "ins $tmp, S, $vsrc, 0, 1\n\t" 16465 "fadds $dst, $dst, $tmp\n\t" 16466 "ins $tmp, S, $vsrc, 0, 2\n\t" 16467 "fadds $dst, $dst, $tmp\n\t" 16468 "ins $tmp, S, $vsrc, 0, 3\n\t" 16469 "fadds $dst, $dst, $tmp\t# add reduction4F" 16470 %} 16471 ins_encode %{ 16472 __ fadds(as_FloatRegister($dst$$reg), 16473 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16474 __ ins(as_FloatRegister($tmp$$reg), __ S, 16475 as_FloatRegister($vsrc$$reg), 0, 1); 16476 __ fadds(as_FloatRegister($dst$$reg), 16477 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16478 __ ins(as_FloatRegister($tmp$$reg), __ S, 16479 as_FloatRegister($vsrc$$reg), 0, 2); 16480 __ fadds(as_FloatRegister($dst$$reg), 16481 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16482 __ ins(as_FloatRegister($tmp$$reg), __ S, 16483 as_FloatRegister($vsrc$$reg), 0, 3); 16484 __ fadds(as_FloatRegister($dst$$reg), 16485 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16486 %} 16487 ins_pipe(pipe_class_default); 16488 %} 16489 16490 instruct reduce_mul2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16491 %{ 16492 match(Set dst (MulReductionVF fsrc vsrc)); 16493 ins_cost(INSN_COST); 16494 effect(TEMP tmp, TEMP dst); 16495 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16496 "ins $tmp, S, $vsrc, 0, 1\n\t" 16497 "fmuls $dst, $dst, $tmp\t# mul reduction2F" 16498 %} 16499 ins_encode %{ 16500 __ fmuls(as_FloatRegister($dst$$reg), 16501 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16502 __ ins(as_FloatRegister($tmp$$reg), __ S, 16503 as_FloatRegister($vsrc$$reg), 0, 1); 16504 __ fmuls(as_FloatRegister($dst$$reg), 16505 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16506 %} 16507 ins_pipe(pipe_class_default); 16508 %} 16509 16510 instruct reduce_mul4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16511 %{ 16512 match(Set dst (MulReductionVF fsrc vsrc)); 16513 ins_cost(INSN_COST); 16514 effect(TEMP tmp, TEMP dst); 16515 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16516 "ins $tmp, S, $vsrc, 0, 1\n\t" 16517 "fmuls $dst, $dst, $tmp\n\t" 16518 "ins $tmp, S, $vsrc, 0, 2\n\t" 16519 "fmuls $dst, $dst, $tmp\n\t" 16520 "ins $tmp, S, $vsrc, 0, 3\n\t" 16521 "fmuls $dst, $dst, $tmp\t# mul reduction4F" 16522 %} 16523 ins_encode %{ 16524 __ fmuls(as_FloatRegister($dst$$reg), 16525 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16526 __ ins(as_FloatRegister($tmp$$reg), __ S, 16527 as_FloatRegister($vsrc$$reg), 0, 1); 16528 __ fmuls(as_FloatRegister($dst$$reg), 16529 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16530 __ ins(as_FloatRegister($tmp$$reg), __ S, 16531 as_FloatRegister($vsrc$$reg), 0, 2); 16532 __ fmuls(as_FloatRegister($dst$$reg), 16533 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16534 __ ins(as_FloatRegister($tmp$$reg), __ S, 16535 as_FloatRegister($vsrc$$reg), 0, 3); 16536 __ fmuls(as_FloatRegister($dst$$reg), 16537 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16538 %} 16539 ins_pipe(pipe_class_default); 16540 %} 16541 16542 instruct reduce_add2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16543 %{ 16544 match(Set dst (AddReductionVD dsrc vsrc)); 16545 ins_cost(INSN_COST); 16546 effect(TEMP tmp, TEMP dst); 16547 format %{ "faddd $dst, $dsrc, $vsrc\n\t" 16548 "ins $tmp, D, $vsrc, 0, 1\n\t" 16549 "faddd $dst, $dst, $tmp\t# add reduction2D" 16550 %} 16551 ins_encode %{ 16552 __ faddd(as_FloatRegister($dst$$reg), 16553 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16554 __ ins(as_FloatRegister($tmp$$reg), __ D, 16555 as_FloatRegister($vsrc$$reg), 0, 1); 16556 __ faddd(as_FloatRegister($dst$$reg), 16557 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16558 %} 16559 ins_pipe(pipe_class_default); 16560 %} 16561 16562 instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16563 %{ 16564 match(Set dst (MulReductionVD dsrc vsrc)); 16565 ins_cost(INSN_COST); 16566 effect(TEMP tmp, TEMP dst); 16567 format %{ "fmuld $dst, $dsrc, $vsrc\n\t" 16568 "ins $tmp, D, $vsrc, 0, 1\n\t" 16569 "fmuld $dst, $dst, $tmp\t# mul reduction2D" 16570 %} 16571 ins_encode %{ 16572 __ fmuld(as_FloatRegister($dst$$reg), 16573 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16574 __ ins(as_FloatRegister($tmp$$reg), __ D, 16575 as_FloatRegister($vsrc$$reg), 0, 1); 16576 __ fmuld(as_FloatRegister($dst$$reg), 16577 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16578 %} 16579 ins_pipe(pipe_class_default); 16580 %} 16581 16582 instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16583 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16584 match(Set dst (MaxReductionV fsrc vsrc)); 16585 ins_cost(INSN_COST); 16586 effect(TEMP_DEF dst, TEMP tmp); 16587 format %{ "fmaxs $dst, $fsrc, $vsrc\n\t" 16588 "ins $tmp, S, $vsrc, 0, 1\n\t" 16589 "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} 16590 ins_encode %{ 16591 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16592 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16593 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16594 %} 16595 ins_pipe(pipe_class_default); 16596 %} 16597 16598 instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16599 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16600 match(Set dst (MaxReductionV fsrc vsrc)); 16601 ins_cost(INSN_COST); 16602 effect(TEMP_DEF dst); 16603 format %{ "fmaxv $dst, T4S, $vsrc\n\t" 16604 "fmaxs $dst, $dst, $fsrc\t# max reduction4F" %} 16605 ins_encode %{ 16606 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16607 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16608 %} 16609 ins_pipe(pipe_class_default); 16610 %} 16611 16612 instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16613 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16614 match(Set dst (MaxReductionV dsrc vsrc)); 16615 ins_cost(INSN_COST); 16616 effect(TEMP_DEF dst, TEMP tmp); 16617 format %{ "fmaxd $dst, $dsrc, $vsrc\n\t" 16618 "ins $tmp, D, $vsrc, 0, 1\n\t" 16619 "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} 16620 ins_encode %{ 16621 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16622 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16623 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16624 %} 16625 ins_pipe(pipe_class_default); 16626 %} 16627 16628 instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16629 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16630 match(Set dst (MinReductionV fsrc vsrc)); 16631 ins_cost(INSN_COST); 16632 effect(TEMP_DEF dst, TEMP tmp); 16633 format %{ "fmins $dst, $fsrc, $vsrc\n\t" 16634 "ins $tmp, S, $vsrc, 0, 1\n\t" 16635 "fmins $dst, $dst, $tmp\t# min reduction2F" %} 16636 ins_encode %{ 16637 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16638 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16639 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16640 %} 16641 ins_pipe(pipe_class_default); 16642 %} 16643 16644 instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16645 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16646 match(Set dst (MinReductionV fsrc vsrc)); 16647 ins_cost(INSN_COST); 16648 effect(TEMP_DEF dst); 16649 format %{ "fminv $dst, T4S, $vsrc\n\t" 16650 "fmins $dst, $dst, $fsrc\t# min reduction4F" %} 16651 ins_encode %{ 16652 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16653 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16654 %} 16655 ins_pipe(pipe_class_default); 16656 %} 16657 16658 instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16659 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16660 match(Set dst (MinReductionV dsrc vsrc)); 16661 ins_cost(INSN_COST); 16662 effect(TEMP_DEF dst, TEMP tmp); 16663 format %{ "fmind $dst, $dsrc, $vsrc\n\t" 16664 "ins $tmp, D, $vsrc, 0, 1\n\t" 16665 "fmind $dst, $dst, $tmp\t# min reduction2D" %} 16666 ins_encode %{ 16667 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16668 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16669 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16670 %} 16671 ins_pipe(pipe_class_default); 16672 %} 16673 16674 // ====================VECTOR ARITHMETIC======================================= 16675 16676 // --------------------------------- ADD -------------------------------------- 16677 16678 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16679 %{ 16680 predicate(n->as_Vector()->length() == 4 || 16681 n->as_Vector()->length() == 8); 16682 match(Set dst (AddVB src1 src2)); 16683 ins_cost(INSN_COST); 16684 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16685 ins_encode %{ 16686 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16687 as_FloatRegister($src1$$reg), 16688 as_FloatRegister($src2$$reg)); 16689 %} 16690 ins_pipe(vdop64); 16691 %} 16692 16693 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16694 %{ 16695 predicate(n->as_Vector()->length() == 16); 16696 match(Set dst (AddVB src1 src2)); 16697 ins_cost(INSN_COST); 16698 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16699 ins_encode %{ 16700 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16701 as_FloatRegister($src1$$reg), 16702 as_FloatRegister($src2$$reg)); 16703 %} 16704 ins_pipe(vdop128); 16705 %} 16706 16707 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16708 %{ 16709 predicate(n->as_Vector()->length() == 2 || 16710 n->as_Vector()->length() == 4); 16711 match(Set dst (AddVS src1 src2)); 16712 ins_cost(INSN_COST); 16713 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16714 ins_encode %{ 16715 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16716 as_FloatRegister($src1$$reg), 16717 as_FloatRegister($src2$$reg)); 16718 %} 16719 ins_pipe(vdop64); 16720 %} 16721 16722 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16723 %{ 16724 predicate(n->as_Vector()->length() == 8); 16725 match(Set dst (AddVS src1 src2)); 16726 ins_cost(INSN_COST); 16727 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16728 ins_encode %{ 16729 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16730 as_FloatRegister($src1$$reg), 16731 as_FloatRegister($src2$$reg)); 16732 %} 16733 ins_pipe(vdop128); 16734 %} 16735 16736 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16737 %{ 16738 predicate(n->as_Vector()->length() == 2); 16739 match(Set dst (AddVI src1 src2)); 16740 ins_cost(INSN_COST); 16741 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16742 ins_encode %{ 16743 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16744 as_FloatRegister($src1$$reg), 16745 as_FloatRegister($src2$$reg)); 16746 %} 16747 ins_pipe(vdop64); 16748 %} 16749 16750 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16751 %{ 16752 predicate(n->as_Vector()->length() == 4); 16753 match(Set dst (AddVI src1 src2)); 16754 ins_cost(INSN_COST); 16755 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16756 ins_encode %{ 16757 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16758 as_FloatRegister($src1$$reg), 16759 as_FloatRegister($src2$$reg)); 16760 %} 16761 ins_pipe(vdop128); 16762 %} 16763 16764 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16765 %{ 16766 predicate(n->as_Vector()->length() == 2); 16767 match(Set dst (AddVL src1 src2)); 16768 ins_cost(INSN_COST); 16769 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16770 ins_encode %{ 16771 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16772 as_FloatRegister($src1$$reg), 16773 as_FloatRegister($src2$$reg)); 16774 %} 16775 ins_pipe(vdop128); 16776 %} 16777 16778 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16779 %{ 16780 predicate(n->as_Vector()->length() == 2); 16781 match(Set dst (AddVF src1 src2)); 16782 ins_cost(INSN_COST); 16783 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16784 ins_encode %{ 16785 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16786 as_FloatRegister($src1$$reg), 16787 as_FloatRegister($src2$$reg)); 16788 %} 16789 ins_pipe(vdop_fp64); 16790 %} 16791 16792 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16793 %{ 16794 predicate(n->as_Vector()->length() == 4); 16795 match(Set dst (AddVF src1 src2)); 16796 ins_cost(INSN_COST); 16797 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16798 ins_encode %{ 16799 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16800 as_FloatRegister($src1$$reg), 16801 as_FloatRegister($src2$$reg)); 16802 %} 16803 ins_pipe(vdop_fp128); 16804 %} 16805 16806 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16807 %{ 16808 match(Set dst (AddVD src1 src2)); 16809 ins_cost(INSN_COST); 16810 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16811 ins_encode %{ 16812 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16813 as_FloatRegister($src1$$reg), 16814 as_FloatRegister($src2$$reg)); 16815 %} 16816 ins_pipe(vdop_fp128); 16817 %} 16818 16819 // --------------------------------- SUB -------------------------------------- 16820 16821 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16822 %{ 16823 predicate(n->as_Vector()->length() == 4 || 16824 n->as_Vector()->length() == 8); 16825 match(Set dst (SubVB src1 src2)); 16826 ins_cost(INSN_COST); 16827 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16828 ins_encode %{ 16829 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16830 as_FloatRegister($src1$$reg), 16831 as_FloatRegister($src2$$reg)); 16832 %} 16833 ins_pipe(vdop64); 16834 %} 16835 16836 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16837 %{ 16838 predicate(n->as_Vector()->length() == 16); 16839 match(Set dst (SubVB src1 src2)); 16840 ins_cost(INSN_COST); 16841 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16842 ins_encode %{ 16843 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16844 as_FloatRegister($src1$$reg), 16845 as_FloatRegister($src2$$reg)); 16846 %} 16847 ins_pipe(vdop128); 16848 %} 16849 16850 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16851 %{ 16852 predicate(n->as_Vector()->length() == 2 || 16853 n->as_Vector()->length() == 4); 16854 match(Set dst (SubVS src1 src2)); 16855 ins_cost(INSN_COST); 16856 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16857 ins_encode %{ 16858 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16859 as_FloatRegister($src1$$reg), 16860 as_FloatRegister($src2$$reg)); 16861 %} 16862 ins_pipe(vdop64); 16863 %} 16864 16865 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16866 %{ 16867 predicate(n->as_Vector()->length() == 8); 16868 match(Set dst (SubVS src1 src2)); 16869 ins_cost(INSN_COST); 16870 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16871 ins_encode %{ 16872 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16873 as_FloatRegister($src1$$reg), 16874 as_FloatRegister($src2$$reg)); 16875 %} 16876 ins_pipe(vdop128); 16877 %} 16878 16879 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16880 %{ 16881 predicate(n->as_Vector()->length() == 2); 16882 match(Set dst (SubVI src1 src2)); 16883 ins_cost(INSN_COST); 16884 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16885 ins_encode %{ 16886 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16887 as_FloatRegister($src1$$reg), 16888 as_FloatRegister($src2$$reg)); 16889 %} 16890 ins_pipe(vdop64); 16891 %} 16892 16893 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16894 %{ 16895 predicate(n->as_Vector()->length() == 4); 16896 match(Set dst (SubVI src1 src2)); 16897 ins_cost(INSN_COST); 16898 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16899 ins_encode %{ 16900 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16901 as_FloatRegister($src1$$reg), 16902 as_FloatRegister($src2$$reg)); 16903 %} 16904 ins_pipe(vdop128); 16905 %} 16906 16907 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16908 %{ 16909 predicate(n->as_Vector()->length() == 2); 16910 match(Set dst (SubVL src1 src2)); 16911 ins_cost(INSN_COST); 16912 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16913 ins_encode %{ 16914 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16915 as_FloatRegister($src1$$reg), 16916 as_FloatRegister($src2$$reg)); 16917 %} 16918 ins_pipe(vdop128); 16919 %} 16920 16921 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16922 %{ 16923 predicate(n->as_Vector()->length() == 2); 16924 match(Set dst (SubVF src1 src2)); 16925 ins_cost(INSN_COST); 16926 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16927 ins_encode %{ 16928 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16929 as_FloatRegister($src1$$reg), 16930 as_FloatRegister($src2$$reg)); 16931 %} 16932 ins_pipe(vdop_fp64); 16933 %} 16934 16935 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16936 %{ 16937 predicate(n->as_Vector()->length() == 4); 16938 match(Set dst (SubVF src1 src2)); 16939 ins_cost(INSN_COST); 16940 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16941 ins_encode %{ 16942 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16943 as_FloatRegister($src1$$reg), 16944 as_FloatRegister($src2$$reg)); 16945 %} 16946 ins_pipe(vdop_fp128); 16947 %} 16948 16949 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16950 %{ 16951 predicate(n->as_Vector()->length() == 2); 16952 match(Set dst (SubVD src1 src2)); 16953 ins_cost(INSN_COST); 16954 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16955 ins_encode %{ 16956 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16957 as_FloatRegister($src1$$reg), 16958 as_FloatRegister($src2$$reg)); 16959 %} 16960 ins_pipe(vdop_fp128); 16961 %} 16962 16963 // --------------------------------- MUL -------------------------------------- 16964 16965 instruct vmul8B(vecD dst, vecD src1, vecD src2) 16966 %{ 16967 predicate(n->as_Vector()->length() == 4 || 16968 n->as_Vector()->length() == 8); 16969 match(Set dst (MulVB src1 src2)); 16970 ins_cost(INSN_COST); 16971 format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %} 16972 ins_encode %{ 16973 __ mulv(as_FloatRegister($dst$$reg), __ T8B, 16974 as_FloatRegister($src1$$reg), 16975 as_FloatRegister($src2$$reg)); 16976 %} 16977 ins_pipe(vmul64); 16978 %} 16979 16980 instruct vmul16B(vecX dst, vecX src1, vecX src2) 16981 %{ 16982 predicate(n->as_Vector()->length() == 16); 16983 match(Set dst (MulVB src1 src2)); 16984 ins_cost(INSN_COST); 16985 format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %} 16986 ins_encode %{ 16987 __ mulv(as_FloatRegister($dst$$reg), __ T16B, 16988 as_FloatRegister($src1$$reg), 16989 as_FloatRegister($src2$$reg)); 16990 %} 16991 ins_pipe(vmul128); 16992 %} 16993 16994 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16995 %{ 16996 predicate(n->as_Vector()->length() == 2 || 16997 n->as_Vector()->length() == 4); 16998 match(Set dst (MulVS src1 src2)); 16999 ins_cost(INSN_COST); 17000 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 17001 ins_encode %{ 17002 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 17003 as_FloatRegister($src1$$reg), 17004 as_FloatRegister($src2$$reg)); 17005 %} 17006 ins_pipe(vmul64); 17007 %} 17008 17009 instruct vmul8S(vecX dst, vecX src1, vecX src2) 17010 %{ 17011 predicate(n->as_Vector()->length() == 8); 17012 match(Set dst (MulVS src1 src2)); 17013 ins_cost(INSN_COST); 17014 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 17015 ins_encode %{ 17016 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 17017 as_FloatRegister($src1$$reg), 17018 as_FloatRegister($src2$$reg)); 17019 %} 17020 ins_pipe(vmul128); 17021 %} 17022 17023 instruct vmul2I(vecD dst, vecD src1, vecD src2) 17024 %{ 17025 predicate(n->as_Vector()->length() == 2); 17026 match(Set dst (MulVI src1 src2)); 17027 ins_cost(INSN_COST); 17028 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 17029 ins_encode %{ 17030 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 17031 as_FloatRegister($src1$$reg), 17032 as_FloatRegister($src2$$reg)); 17033 %} 17034 ins_pipe(vmul64); 17035 %} 17036 17037 instruct vmul4I(vecX dst, vecX src1, vecX src2) 17038 %{ 17039 predicate(n->as_Vector()->length() == 4); 17040 match(Set dst (MulVI src1 src2)); 17041 ins_cost(INSN_COST); 17042 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 17043 ins_encode %{ 17044 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 17045 as_FloatRegister($src1$$reg), 17046 as_FloatRegister($src2$$reg)); 17047 %} 17048 ins_pipe(vmul128); 17049 %} 17050 17051 instruct vmul2F(vecD dst, vecD src1, vecD src2) 17052 %{ 17053 predicate(n->as_Vector()->length() == 2); 17054 match(Set dst (MulVF src1 src2)); 17055 ins_cost(INSN_COST); 17056 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 17057 ins_encode %{ 17058 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 17059 as_FloatRegister($src1$$reg), 17060 as_FloatRegister($src2$$reg)); 17061 %} 17062 ins_pipe(vmuldiv_fp64); 17063 %} 17064 17065 instruct vmul4F(vecX dst, vecX src1, vecX src2) 17066 %{ 17067 predicate(n->as_Vector()->length() == 4); 17068 match(Set dst (MulVF src1 src2)); 17069 ins_cost(INSN_COST); 17070 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 17071 ins_encode %{ 17072 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 17073 as_FloatRegister($src1$$reg), 17074 as_FloatRegister($src2$$reg)); 17075 %} 17076 ins_pipe(vmuldiv_fp128); 17077 %} 17078 17079 instruct vmul2D(vecX dst, vecX src1, vecX src2) 17080 %{ 17081 predicate(n->as_Vector()->length() == 2); 17082 match(Set dst (MulVD src1 src2)); 17083 ins_cost(INSN_COST); 17084 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 17085 ins_encode %{ 17086 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 17087 as_FloatRegister($src1$$reg), 17088 as_FloatRegister($src2$$reg)); 17089 %} 17090 ins_pipe(vmuldiv_fp128); 17091 %} 17092 17093 // --------------------------------- MLA -------------------------------------- 17094 17095 instruct vmla4S(vecD dst, vecD src1, vecD src2) 17096 %{ 17097 predicate(n->as_Vector()->length() == 2 || 17098 n->as_Vector()->length() == 4); 17099 match(Set dst (AddVS dst (MulVS src1 src2))); 17100 ins_cost(INSN_COST); 17101 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 17102 ins_encode %{ 17103 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 17104 as_FloatRegister($src1$$reg), 17105 as_FloatRegister($src2$$reg)); 17106 %} 17107 ins_pipe(vmla64); 17108 %} 17109 17110 instruct vmla8S(vecX dst, vecX src1, vecX src2) 17111 %{ 17112 predicate(n->as_Vector()->length() == 8); 17113 match(Set dst (AddVS dst (MulVS src1 src2))); 17114 ins_cost(INSN_COST); 17115 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 17116 ins_encode %{ 17117 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 17118 as_FloatRegister($src1$$reg), 17119 as_FloatRegister($src2$$reg)); 17120 %} 17121 ins_pipe(vmla128); 17122 %} 17123 17124 instruct vmla2I(vecD dst, vecD src1, vecD src2) 17125 %{ 17126 predicate(n->as_Vector()->length() == 2); 17127 match(Set dst (AddVI dst (MulVI src1 src2))); 17128 ins_cost(INSN_COST); 17129 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 17130 ins_encode %{ 17131 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 17132 as_FloatRegister($src1$$reg), 17133 as_FloatRegister($src2$$reg)); 17134 %} 17135 ins_pipe(vmla64); 17136 %} 17137 17138 instruct vmla4I(vecX dst, vecX src1, vecX src2) 17139 %{ 17140 predicate(n->as_Vector()->length() == 4); 17141 match(Set dst (AddVI dst (MulVI src1 src2))); 17142 ins_cost(INSN_COST); 17143 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 17144 ins_encode %{ 17145 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 17146 as_FloatRegister($src1$$reg), 17147 as_FloatRegister($src2$$reg)); 17148 %} 17149 ins_pipe(vmla128); 17150 %} 17151 17152 // dst + src1 * src2 17153 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 17154 predicate(UseFMA && n->as_Vector()->length() == 2); 17155 match(Set dst (FmaVF dst (Binary src1 src2))); 17156 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 17157 ins_cost(INSN_COST); 17158 ins_encode %{ 17159 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 17160 as_FloatRegister($src1$$reg), 17161 as_FloatRegister($src2$$reg)); 17162 %} 17163 ins_pipe(vmuldiv_fp64); 17164 %} 17165 17166 // dst + src1 * src2 17167 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 17168 predicate(UseFMA && n->as_Vector()->length() == 4); 17169 match(Set dst (FmaVF dst (Binary src1 src2))); 17170 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 17171 ins_cost(INSN_COST); 17172 ins_encode %{ 17173 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 17174 as_FloatRegister($src1$$reg), 17175 as_FloatRegister($src2$$reg)); 17176 %} 17177 ins_pipe(vmuldiv_fp128); 17178 %} 17179 17180 // dst + src1 * src2 17181 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 17182 predicate(UseFMA && n->as_Vector()->length() == 2); 17183 match(Set dst (FmaVD dst (Binary src1 src2))); 17184 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 17185 ins_cost(INSN_COST); 17186 ins_encode %{ 17187 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 17188 as_FloatRegister($src1$$reg), 17189 as_FloatRegister($src2$$reg)); 17190 %} 17191 ins_pipe(vmuldiv_fp128); 17192 %} 17193 17194 // --------------------------------- MLS -------------------------------------- 17195 17196 instruct vmls4S(vecD dst, vecD src1, vecD src2) 17197 %{ 17198 predicate(n->as_Vector()->length() == 2 || 17199 n->as_Vector()->length() == 4); 17200 match(Set dst (SubVS dst (MulVS src1 src2))); 17201 ins_cost(INSN_COST); 17202 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 17203 ins_encode %{ 17204 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 17205 as_FloatRegister($src1$$reg), 17206 as_FloatRegister($src2$$reg)); 17207 %} 17208 ins_pipe(vmla64); 17209 %} 17210 17211 instruct vmls8S(vecX dst, vecX src1, vecX src2) 17212 %{ 17213 predicate(n->as_Vector()->length() == 8); 17214 match(Set dst (SubVS dst (MulVS src1 src2))); 17215 ins_cost(INSN_COST); 17216 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 17217 ins_encode %{ 17218 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 17219 as_FloatRegister($src1$$reg), 17220 as_FloatRegister($src2$$reg)); 17221 %} 17222 ins_pipe(vmla128); 17223 %} 17224 17225 instruct vmls2I(vecD dst, vecD src1, vecD src2) 17226 %{ 17227 predicate(n->as_Vector()->length() == 2); 17228 match(Set dst (SubVI dst (MulVI src1 src2))); 17229 ins_cost(INSN_COST); 17230 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 17231 ins_encode %{ 17232 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 17233 as_FloatRegister($src1$$reg), 17234 as_FloatRegister($src2$$reg)); 17235 %} 17236 ins_pipe(vmla64); 17237 %} 17238 17239 instruct vmls4I(vecX dst, vecX src1, vecX src2) 17240 %{ 17241 predicate(n->as_Vector()->length() == 4); 17242 match(Set dst (SubVI dst (MulVI src1 src2))); 17243 ins_cost(INSN_COST); 17244 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 17245 ins_encode %{ 17246 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 17247 as_FloatRegister($src1$$reg), 17248 as_FloatRegister($src2$$reg)); 17249 %} 17250 ins_pipe(vmla128); 17251 %} 17252 17253 // dst - src1 * src2 17254 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 17255 predicate(UseFMA && n->as_Vector()->length() == 2); 17256 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 17257 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 17258 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 17259 ins_cost(INSN_COST); 17260 ins_encode %{ 17261 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 17262 as_FloatRegister($src1$$reg), 17263 as_FloatRegister($src2$$reg)); 17264 %} 17265 ins_pipe(vmuldiv_fp64); 17266 %} 17267 17268 // dst - src1 * src2 17269 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 17270 predicate(UseFMA && n->as_Vector()->length() == 4); 17271 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 17272 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 17273 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 17274 ins_cost(INSN_COST); 17275 ins_encode %{ 17276 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 17277 as_FloatRegister($src1$$reg), 17278 as_FloatRegister($src2$$reg)); 17279 %} 17280 ins_pipe(vmuldiv_fp128); 17281 %} 17282 17283 // dst - src1 * src2 17284 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 17285 predicate(UseFMA && n->as_Vector()->length() == 2); 17286 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 17287 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 17288 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 17289 ins_cost(INSN_COST); 17290 ins_encode %{ 17291 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 17292 as_FloatRegister($src1$$reg), 17293 as_FloatRegister($src2$$reg)); 17294 %} 17295 ins_pipe(vmuldiv_fp128); 17296 %} 17297 17298 // --------------- Vector Multiply-Add Shorts into Integer -------------------- 17299 17300 instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 17301 predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 17302 match(Set dst (MulAddVS2VI src1 src2)); 17303 ins_cost(INSN_COST); 17304 effect(TEMP_DEF dst, TEMP tmp); 17305 format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" 17306 "smullv $dst, $src1, $src2\t# vector (8H)\n\t" 17307 "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} 17308 ins_encode %{ 17309 __ smullv(as_FloatRegister($tmp$$reg), __ T4H, 17310 as_FloatRegister($src1$$reg), 17311 as_FloatRegister($src2$$reg)); 17312 __ smullv(as_FloatRegister($dst$$reg), __ T8H, 17313 as_FloatRegister($src1$$reg), 17314 as_FloatRegister($src2$$reg)); 17315 __ addpv(as_FloatRegister($dst$$reg), __ T4S, 17316 as_FloatRegister($tmp$$reg), 17317 as_FloatRegister($dst$$reg)); 17318 %} 17319 ins_pipe(vmuldiv_fp128); 17320 %} 17321 17322 // --------------------------------- DIV -------------------------------------- 17323 17324 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 17325 %{ 17326 predicate(n->as_Vector()->length() == 2); 17327 match(Set dst (DivVF src1 src2)); 17328 ins_cost(INSN_COST); 17329 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 17330 ins_encode %{ 17331 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 17332 as_FloatRegister($src1$$reg), 17333 as_FloatRegister($src2$$reg)); 17334 %} 17335 ins_pipe(vmuldiv_fp64); 17336 %} 17337 17338 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 17339 %{ 17340 predicate(n->as_Vector()->length() == 4); 17341 match(Set dst (DivVF src1 src2)); 17342 ins_cost(INSN_COST); 17343 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 17344 ins_encode %{ 17345 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 17346 as_FloatRegister($src1$$reg), 17347 as_FloatRegister($src2$$reg)); 17348 %} 17349 ins_pipe(vmuldiv_fp128); 17350 %} 17351 17352 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17353 %{ 17354 predicate(n->as_Vector()->length() == 2); 17355 match(Set dst (DivVD src1 src2)); 17356 ins_cost(INSN_COST); 17357 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17358 ins_encode %{ 17359 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17360 as_FloatRegister($src1$$reg), 17361 as_FloatRegister($src2$$reg)); 17362 %} 17363 ins_pipe(vmuldiv_fp128); 17364 %} 17365 17366 // --------------------------------- SQRT ------------------------------------- 17367 17368 instruct vsqrt2F(vecD dst, vecD src) 17369 %{ 17370 predicate(n->as_Vector()->length() == 2); 17371 match(Set dst (SqrtVF src)); 17372 format %{ "fsqrt $dst, $src\t# vector (2F)" %} 17373 ins_encode %{ 17374 __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17375 %} 17376 ins_pipe(vunop_fp64); 17377 %} 17378 17379 instruct vsqrt4F(vecX dst, vecX src) 17380 %{ 17381 predicate(n->as_Vector()->length() == 4); 17382 match(Set dst (SqrtVF src)); 17383 format %{ "fsqrt $dst, $src\t# vector (4F)" %} 17384 ins_encode %{ 17385 __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17386 %} 17387 ins_pipe(vsqrt_fp128); 17388 %} 17389 17390 instruct vsqrt2D(vecX dst, vecX src) 17391 %{ 17392 predicate(n->as_Vector()->length() == 2); 17393 match(Set dst (SqrtVD src)); 17394 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17395 ins_encode %{ 17396 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17397 as_FloatRegister($src$$reg)); 17398 %} 17399 ins_pipe(vsqrt_fp128); 17400 %} 17401 17402 // --------------------------------- ABS -------------------------------------- 17403 17404 instruct vabs8B(vecD dst, vecD src) 17405 %{ 17406 predicate(n->as_Vector()->length() == 4 || 17407 n->as_Vector()->length() == 8); 17408 match(Set dst (AbsVB src)); 17409 ins_cost(INSN_COST); 17410 format %{ "abs $dst, $src\t# vector (8B)" %} 17411 ins_encode %{ 17412 __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); 17413 %} 17414 ins_pipe(vlogical64); 17415 %} 17416 17417 instruct vabs16B(vecX dst, vecX src) 17418 %{ 17419 predicate(n->as_Vector()->length() == 16); 17420 match(Set dst (AbsVB src)); 17421 ins_cost(INSN_COST); 17422 format %{ "abs $dst, $src\t# vector (16B)" %} 17423 ins_encode %{ 17424 __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); 17425 %} 17426 ins_pipe(vlogical128); 17427 %} 17428 17429 instruct vabs4S(vecD dst, vecD src) 17430 %{ 17431 predicate(n->as_Vector()->length() == 4); 17432 match(Set dst (AbsVS src)); 17433 ins_cost(INSN_COST); 17434 format %{ "abs $dst, $src\t# vector (4H)" %} 17435 ins_encode %{ 17436 __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg)); 17437 %} 17438 ins_pipe(vlogical64); 17439 %} 17440 17441 instruct vabs8S(vecX dst, vecX src) 17442 %{ 17443 predicate(n->as_Vector()->length() == 8); 17444 match(Set dst (AbsVS src)); 17445 ins_cost(INSN_COST); 17446 format %{ "abs $dst, $src\t# vector (8H)" %} 17447 ins_encode %{ 17448 __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg)); 17449 %} 17450 ins_pipe(vlogical128); 17451 %} 17452 17453 instruct vabs2I(vecD dst, vecD src) 17454 %{ 17455 predicate(n->as_Vector()->length() == 2); 17456 match(Set dst (AbsVI src)); 17457 ins_cost(INSN_COST); 17458 format %{ "abs $dst, $src\t# vector (2S)" %} 17459 ins_encode %{ 17460 __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17461 %} 17462 ins_pipe(vlogical64); 17463 %} 17464 17465 instruct vabs4I(vecX dst, vecX src) 17466 %{ 17467 predicate(n->as_Vector()->length() == 4); 17468 match(Set dst (AbsVI src)); 17469 ins_cost(INSN_COST); 17470 format %{ "abs $dst, $src\t# vector (4S)" %} 17471 ins_encode %{ 17472 __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17473 %} 17474 ins_pipe(vlogical128); 17475 %} 17476 17477 instruct vabs2L(vecX dst, vecX src) 17478 %{ 17479 predicate(n->as_Vector()->length() == 2); 17480 match(Set dst (AbsVL src)); 17481 ins_cost(INSN_COST); 17482 format %{ "abs $dst, $src\t# vector (2D)" %} 17483 ins_encode %{ 17484 __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); 17485 %} 17486 ins_pipe(vlogical128); 17487 %} 17488 17489 instruct vabs2F(vecD dst, vecD src) 17490 %{ 17491 predicate(n->as_Vector()->length() == 2); 17492 match(Set dst (AbsVF src)); 17493 ins_cost(INSN_COST * 3); 17494 format %{ "fabs $dst,$src\t# vector (2S)" %} 17495 ins_encode %{ 17496 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 17497 as_FloatRegister($src$$reg)); 17498 %} 17499 ins_pipe(vunop_fp64); 17500 %} 17501 17502 instruct vabs4F(vecX dst, vecX src) 17503 %{ 17504 predicate(n->as_Vector()->length() == 4); 17505 match(Set dst (AbsVF src)); 17506 ins_cost(INSN_COST * 3); 17507 format %{ "fabs $dst,$src\t# vector (4S)" %} 17508 ins_encode %{ 17509 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 17510 as_FloatRegister($src$$reg)); 17511 %} 17512 ins_pipe(vunop_fp128); 17513 %} 17514 17515 instruct vabs2D(vecX dst, vecX src) 17516 %{ 17517 predicate(n->as_Vector()->length() == 2); 17518 match(Set dst (AbsVD src)); 17519 ins_cost(INSN_COST * 3); 17520 format %{ "fabs $dst,$src\t# vector (2D)" %} 17521 ins_encode %{ 17522 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17523 as_FloatRegister($src$$reg)); 17524 %} 17525 ins_pipe(vunop_fp128); 17526 %} 17527 17528 // --------------------------------- NEG -------------------------------------- 17529 17530 instruct vneg2F(vecD dst, vecD src) 17531 %{ 17532 predicate(n->as_Vector()->length() == 2); 17533 match(Set dst (NegVF src)); 17534 ins_cost(INSN_COST * 3); 17535 format %{ "fneg $dst,$src\t# vector (2S)" %} 17536 ins_encode %{ 17537 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17538 as_FloatRegister($src$$reg)); 17539 %} 17540 ins_pipe(vunop_fp64); 17541 %} 17542 17543 instruct vneg4F(vecX dst, vecX src) 17544 %{ 17545 predicate(n->as_Vector()->length() == 4); 17546 match(Set dst (NegVF src)); 17547 ins_cost(INSN_COST * 3); 17548 format %{ "fneg $dst,$src\t# vector (4S)" %} 17549 ins_encode %{ 17550 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17551 as_FloatRegister($src$$reg)); 17552 %} 17553 ins_pipe(vunop_fp128); 17554 %} 17555 17556 instruct vneg2D(vecX dst, vecX src) 17557 %{ 17558 predicate(n->as_Vector()->length() == 2); 17559 match(Set dst (NegVD src)); 17560 ins_cost(INSN_COST * 3); 17561 format %{ "fneg $dst,$src\t# vector (2D)" %} 17562 ins_encode %{ 17563 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17564 as_FloatRegister($src$$reg)); 17565 %} 17566 ins_pipe(vunop_fp128); 17567 %} 17568 17569 // --------------------------------- AND -------------------------------------- 17570 17571 instruct vand8B(vecD dst, vecD src1, vecD src2) 17572 %{ 17573 predicate(n->as_Vector()->length_in_bytes() == 4 || 17574 n->as_Vector()->length_in_bytes() == 8); 17575 match(Set dst (AndV src1 src2)); 17576 ins_cost(INSN_COST); 17577 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17578 ins_encode %{ 17579 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17580 as_FloatRegister($src1$$reg), 17581 as_FloatRegister($src2$$reg)); 17582 %} 17583 ins_pipe(vlogical64); 17584 %} 17585 17586 instruct vand16B(vecX dst, vecX src1, vecX src2) 17587 %{ 17588 predicate(n->as_Vector()->length_in_bytes() == 16); 17589 match(Set dst (AndV src1 src2)); 17590 ins_cost(INSN_COST); 17591 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17592 ins_encode %{ 17593 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17594 as_FloatRegister($src1$$reg), 17595 as_FloatRegister($src2$$reg)); 17596 %} 17597 ins_pipe(vlogical128); 17598 %} 17599 17600 // --------------------------------- OR --------------------------------------- 17601 17602 instruct vor8B(vecD dst, vecD src1, vecD src2) 17603 %{ 17604 predicate(n->as_Vector()->length_in_bytes() == 4 || 17605 n->as_Vector()->length_in_bytes() == 8); 17606 match(Set dst (OrV src1 src2)); 17607 ins_cost(INSN_COST); 17608 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17609 ins_encode %{ 17610 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17611 as_FloatRegister($src1$$reg), 17612 as_FloatRegister($src2$$reg)); 17613 %} 17614 ins_pipe(vlogical64); 17615 %} 17616 17617 instruct vor16B(vecX dst, vecX src1, vecX src2) 17618 %{ 17619 predicate(n->as_Vector()->length_in_bytes() == 16); 17620 match(Set dst (OrV src1 src2)); 17621 ins_cost(INSN_COST); 17622 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17623 ins_encode %{ 17624 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17625 as_FloatRegister($src1$$reg), 17626 as_FloatRegister($src2$$reg)); 17627 %} 17628 ins_pipe(vlogical128); 17629 %} 17630 17631 // --------------------------------- XOR -------------------------------------- 17632 17633 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17634 %{ 17635 predicate(n->as_Vector()->length_in_bytes() == 4 || 17636 n->as_Vector()->length_in_bytes() == 8); 17637 match(Set dst (XorV src1 src2)); 17638 ins_cost(INSN_COST); 17639 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17640 ins_encode %{ 17641 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17642 as_FloatRegister($src1$$reg), 17643 as_FloatRegister($src2$$reg)); 17644 %} 17645 ins_pipe(vlogical64); 17646 %} 17647 17648 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17649 %{ 17650 predicate(n->as_Vector()->length_in_bytes() == 16); 17651 match(Set dst (XorV src1 src2)); 17652 ins_cost(INSN_COST); 17653 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17654 ins_encode %{ 17655 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17656 as_FloatRegister($src1$$reg), 17657 as_FloatRegister($src2$$reg)); 17658 %} 17659 ins_pipe(vlogical128); 17660 %} 17661 17662 // ------------------------------ Shift --------------------------------------- 17663 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17664 predicate(n->as_Vector()->length_in_bytes() == 8); 17665 match(Set dst (LShiftCntV cnt)); 17666 match(Set dst (RShiftCntV cnt)); 17667 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17668 ins_encode %{ 17669 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17670 %} 17671 ins_pipe(vdup_reg_reg64); 17672 %} 17673 17674 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17675 predicate(n->as_Vector()->length_in_bytes() == 16); 17676 match(Set dst (LShiftCntV cnt)); 17677 match(Set dst (RShiftCntV cnt)); 17678 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17679 ins_encode %{ 17680 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17681 %} 17682 ins_pipe(vdup_reg_reg128); 17683 %} 17684 17685 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17686 predicate(n->as_Vector()->length() == 4 || 17687 n->as_Vector()->length() == 8); 17688 match(Set dst (LShiftVB src shift)); 17689 ins_cost(INSN_COST); 17690 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17691 ins_encode %{ 17692 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17693 as_FloatRegister($src$$reg), 17694 as_FloatRegister($shift$$reg)); 17695 %} 17696 ins_pipe(vshift64); 17697 %} 17698 17699 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17700 predicate(n->as_Vector()->length() == 16); 17701 match(Set dst (LShiftVB src shift)); 17702 ins_cost(INSN_COST); 17703 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17704 ins_encode %{ 17705 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17706 as_FloatRegister($src$$reg), 17707 as_FloatRegister($shift$$reg)); 17708 %} 17709 ins_pipe(vshift128); 17710 %} 17711 17712 // Right shifts with vector shift count on aarch64 SIMD are implemented 17713 // as left shift by negative shift count. 17714 // There are two cases for vector shift count. 17715 // 17716 // Case 1: The vector shift count is from replication. 17717 // | | 17718 // LoadVector RShiftCntV 17719 // | / 17720 // RShiftVI 17721 // Note: In inner loop, multiple neg instructions are used, which can be 17722 // moved to outer loop and merge into one neg instruction. 17723 // 17724 // Case 2: The vector shift count is from loading. 17725 // This case isn't supported by middle-end now. But it's supported by 17726 // panama/vectorIntrinsics(JEP 338: Vector API). 17727 // | | 17728 // LoadVector LoadVector 17729 // | / 17730 // RShiftVI 17731 // 17732 17733 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17734 predicate(n->as_Vector()->length() == 4 || 17735 n->as_Vector()->length() == 8); 17736 match(Set dst (RShiftVB src shift)); 17737 ins_cost(INSN_COST); 17738 effect(TEMP tmp); 17739 format %{ "negr $tmp,$shift\t" 17740 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17741 ins_encode %{ 17742 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17743 as_FloatRegister($shift$$reg)); 17744 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17745 as_FloatRegister($src$$reg), 17746 as_FloatRegister($tmp$$reg)); 17747 %} 17748 ins_pipe(vshift64); 17749 %} 17750 17751 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17752 predicate(n->as_Vector()->length() == 16); 17753 match(Set dst (RShiftVB src shift)); 17754 ins_cost(INSN_COST); 17755 effect(TEMP tmp); 17756 format %{ "negr $tmp,$shift\t" 17757 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17758 ins_encode %{ 17759 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17760 as_FloatRegister($shift$$reg)); 17761 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17762 as_FloatRegister($src$$reg), 17763 as_FloatRegister($tmp$$reg)); 17764 %} 17765 ins_pipe(vshift128); 17766 %} 17767 17768 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17769 predicate(n->as_Vector()->length() == 4 || 17770 n->as_Vector()->length() == 8); 17771 match(Set dst (URShiftVB src shift)); 17772 ins_cost(INSN_COST); 17773 effect(TEMP tmp); 17774 format %{ "negr $tmp,$shift\t" 17775 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17776 ins_encode %{ 17777 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17778 as_FloatRegister($shift$$reg)); 17779 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17780 as_FloatRegister($src$$reg), 17781 as_FloatRegister($tmp$$reg)); 17782 %} 17783 ins_pipe(vshift64); 17784 %} 17785 17786 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17787 predicate(n->as_Vector()->length() == 16); 17788 match(Set dst (URShiftVB src shift)); 17789 ins_cost(INSN_COST); 17790 effect(TEMP tmp); 17791 format %{ "negr $tmp,$shift\t" 17792 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17793 ins_encode %{ 17794 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17795 as_FloatRegister($shift$$reg)); 17796 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17797 as_FloatRegister($src$$reg), 17798 as_FloatRegister($tmp$$reg)); 17799 %} 17800 ins_pipe(vshift128); 17801 %} 17802 17803 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17804 predicate(n->as_Vector()->length() == 4 || 17805 n->as_Vector()->length() == 8); 17806 match(Set dst (LShiftVB src (LShiftCntV shift))); 17807 ins_cost(INSN_COST); 17808 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17809 ins_encode %{ 17810 int sh = (int)$shift$$constant; 17811 if (sh >= 8) { 17812 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17813 as_FloatRegister($src$$reg), 17814 as_FloatRegister($src$$reg)); 17815 } else { 17816 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17817 as_FloatRegister($src$$reg), sh); 17818 } 17819 %} 17820 ins_pipe(vshift64_imm); 17821 %} 17822 17823 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17824 predicate(n->as_Vector()->length() == 16); 17825 match(Set dst (LShiftVB src (LShiftCntV shift))); 17826 ins_cost(INSN_COST); 17827 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17828 ins_encode %{ 17829 int sh = (int)$shift$$constant; 17830 if (sh >= 8) { 17831 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17832 as_FloatRegister($src$$reg), 17833 as_FloatRegister($src$$reg)); 17834 } else { 17835 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17836 as_FloatRegister($src$$reg), sh); 17837 } 17838 %} 17839 ins_pipe(vshift128_imm); 17840 %} 17841 17842 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17843 predicate(n->as_Vector()->length() == 4 || 17844 n->as_Vector()->length() == 8); 17845 match(Set dst (RShiftVB src (RShiftCntV shift))); 17846 ins_cost(INSN_COST); 17847 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17848 ins_encode %{ 17849 int sh = (int)$shift$$constant; 17850 if (sh >= 8) sh = 7; 17851 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17852 as_FloatRegister($src$$reg), sh); 17853 %} 17854 ins_pipe(vshift64_imm); 17855 %} 17856 17857 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17858 predicate(n->as_Vector()->length() == 16); 17859 match(Set dst (RShiftVB src (RShiftCntV shift))); 17860 ins_cost(INSN_COST); 17861 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17862 ins_encode %{ 17863 int sh = (int)$shift$$constant; 17864 if (sh >= 8) sh = 7; 17865 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17866 as_FloatRegister($src$$reg), sh); 17867 %} 17868 ins_pipe(vshift128_imm); 17869 %} 17870 17871 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17872 predicate(n->as_Vector()->length() == 4 || 17873 n->as_Vector()->length() == 8); 17874 match(Set dst (URShiftVB src (RShiftCntV shift))); 17875 ins_cost(INSN_COST); 17876 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17877 ins_encode %{ 17878 int sh = (int)$shift$$constant; 17879 if (sh >= 8) { 17880 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17881 as_FloatRegister($src$$reg), 17882 as_FloatRegister($src$$reg)); 17883 } else { 17884 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17885 as_FloatRegister($src$$reg), sh); 17886 } 17887 %} 17888 ins_pipe(vshift64_imm); 17889 %} 17890 17891 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17892 predicate(n->as_Vector()->length() == 16); 17893 match(Set dst (URShiftVB src (RShiftCntV shift))); 17894 ins_cost(INSN_COST); 17895 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17896 ins_encode %{ 17897 int sh = (int)$shift$$constant; 17898 if (sh >= 8) { 17899 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17900 as_FloatRegister($src$$reg), 17901 as_FloatRegister($src$$reg)); 17902 } else { 17903 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17904 as_FloatRegister($src$$reg), sh); 17905 } 17906 %} 17907 ins_pipe(vshift128_imm); 17908 %} 17909 17910 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17911 predicate(n->as_Vector()->length() == 2 || 17912 n->as_Vector()->length() == 4); 17913 match(Set dst (LShiftVS src shift)); 17914 ins_cost(INSN_COST); 17915 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17916 ins_encode %{ 17917 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17918 as_FloatRegister($src$$reg), 17919 as_FloatRegister($shift$$reg)); 17920 %} 17921 ins_pipe(vshift64); 17922 %} 17923 17924 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17925 predicate(n->as_Vector()->length() == 8); 17926 match(Set dst (LShiftVS src shift)); 17927 ins_cost(INSN_COST); 17928 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17929 ins_encode %{ 17930 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17931 as_FloatRegister($src$$reg), 17932 as_FloatRegister($shift$$reg)); 17933 %} 17934 ins_pipe(vshift128); 17935 %} 17936 17937 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17938 predicate(n->as_Vector()->length() == 2 || 17939 n->as_Vector()->length() == 4); 17940 match(Set dst (RShiftVS src shift)); 17941 ins_cost(INSN_COST); 17942 effect(TEMP tmp); 17943 format %{ "negr $tmp,$shift\t" 17944 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17945 ins_encode %{ 17946 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17947 as_FloatRegister($shift$$reg)); 17948 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17949 as_FloatRegister($src$$reg), 17950 as_FloatRegister($tmp$$reg)); 17951 %} 17952 ins_pipe(vshift64); 17953 %} 17954 17955 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17956 predicate(n->as_Vector()->length() == 8); 17957 match(Set dst (RShiftVS src shift)); 17958 ins_cost(INSN_COST); 17959 effect(TEMP tmp); 17960 format %{ "negr $tmp,$shift\t" 17961 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17962 ins_encode %{ 17963 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17964 as_FloatRegister($shift$$reg)); 17965 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17966 as_FloatRegister($src$$reg), 17967 as_FloatRegister($tmp$$reg)); 17968 %} 17969 ins_pipe(vshift128); 17970 %} 17971 17972 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17973 predicate(n->as_Vector()->length() == 2 || 17974 n->as_Vector()->length() == 4); 17975 match(Set dst (URShiftVS src shift)); 17976 ins_cost(INSN_COST); 17977 effect(TEMP tmp); 17978 format %{ "negr $tmp,$shift\t" 17979 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17980 ins_encode %{ 17981 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17982 as_FloatRegister($shift$$reg)); 17983 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17984 as_FloatRegister($src$$reg), 17985 as_FloatRegister($tmp$$reg)); 17986 %} 17987 ins_pipe(vshift64); 17988 %} 17989 17990 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17991 predicate(n->as_Vector()->length() == 8); 17992 match(Set dst (URShiftVS src shift)); 17993 ins_cost(INSN_COST); 17994 effect(TEMP tmp); 17995 format %{ "negr $tmp,$shift\t" 17996 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17997 ins_encode %{ 17998 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17999 as_FloatRegister($shift$$reg)); 18000 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 18001 as_FloatRegister($src$$reg), 18002 as_FloatRegister($tmp$$reg)); 18003 %} 18004 ins_pipe(vshift128); 18005 %} 18006 18007 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 18008 predicate(n->as_Vector()->length() == 2 || 18009 n->as_Vector()->length() == 4); 18010 match(Set dst (LShiftVS src (LShiftCntV shift))); 18011 ins_cost(INSN_COST); 18012 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 18013 ins_encode %{ 18014 int sh = (int)$shift$$constant; 18015 if (sh >= 16) { 18016 __ eor(as_FloatRegister($dst$$reg), __ T8B, 18017 as_FloatRegister($src$$reg), 18018 as_FloatRegister($src$$reg)); 18019 } else { 18020 __ shl(as_FloatRegister($dst$$reg), __ T4H, 18021 as_FloatRegister($src$$reg), sh); 18022 } 18023 %} 18024 ins_pipe(vshift64_imm); 18025 %} 18026 18027 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 18028 predicate(n->as_Vector()->length() == 8); 18029 match(Set dst (LShiftVS src (LShiftCntV shift))); 18030 ins_cost(INSN_COST); 18031 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 18032 ins_encode %{ 18033 int sh = (int)$shift$$constant; 18034 if (sh >= 16) { 18035 __ eor(as_FloatRegister($dst$$reg), __ T16B, 18036 as_FloatRegister($src$$reg), 18037 as_FloatRegister($src$$reg)); 18038 } else { 18039 __ shl(as_FloatRegister($dst$$reg), __ T8H, 18040 as_FloatRegister($src$$reg), sh); 18041 } 18042 %} 18043 ins_pipe(vshift128_imm); 18044 %} 18045 18046 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 18047 predicate(n->as_Vector()->length() == 2 || 18048 n->as_Vector()->length() == 4); 18049 match(Set dst (RShiftVS src (RShiftCntV shift))); 18050 ins_cost(INSN_COST); 18051 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 18052 ins_encode %{ 18053 int sh = (int)$shift$$constant; 18054 if (sh >= 16) sh = 15; 18055 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 18056 as_FloatRegister($src$$reg), sh); 18057 %} 18058 ins_pipe(vshift64_imm); 18059 %} 18060 18061 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 18062 predicate(n->as_Vector()->length() == 8); 18063 match(Set dst (RShiftVS src (RShiftCntV shift))); 18064 ins_cost(INSN_COST); 18065 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 18066 ins_encode %{ 18067 int sh = (int)$shift$$constant; 18068 if (sh >= 16) sh = 15; 18069 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 18070 as_FloatRegister($src$$reg), sh); 18071 %} 18072 ins_pipe(vshift128_imm); 18073 %} 18074 18075 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 18076 predicate(n->as_Vector()->length() == 2 || 18077 n->as_Vector()->length() == 4); 18078 match(Set dst (URShiftVS src (RShiftCntV shift))); 18079 ins_cost(INSN_COST); 18080 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 18081 ins_encode %{ 18082 int sh = (int)$shift$$constant; 18083 if (sh >= 16) { 18084 __ eor(as_FloatRegister($dst$$reg), __ T8B, 18085 as_FloatRegister($src$$reg), 18086 as_FloatRegister($src$$reg)); 18087 } else { 18088 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 18089 as_FloatRegister($src$$reg), sh); 18090 } 18091 %} 18092 ins_pipe(vshift64_imm); 18093 %} 18094 18095 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 18096 predicate(n->as_Vector()->length() == 8); 18097 match(Set dst (URShiftVS src (RShiftCntV shift))); 18098 ins_cost(INSN_COST); 18099 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 18100 ins_encode %{ 18101 int sh = (int)$shift$$constant; 18102 if (sh >= 16) { 18103 __ eor(as_FloatRegister($dst$$reg), __ T16B, 18104 as_FloatRegister($src$$reg), 18105 as_FloatRegister($src$$reg)); 18106 } else { 18107 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 18108 as_FloatRegister($src$$reg), sh); 18109 } 18110 %} 18111 ins_pipe(vshift128_imm); 18112 %} 18113 18114 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 18115 predicate(n->as_Vector()->length() == 2); 18116 match(Set dst (LShiftVI src shift)); 18117 ins_cost(INSN_COST); 18118 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 18119 ins_encode %{ 18120 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 18121 as_FloatRegister($src$$reg), 18122 as_FloatRegister($shift$$reg)); 18123 %} 18124 ins_pipe(vshift64); 18125 %} 18126 18127 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 18128 predicate(n->as_Vector()->length() == 4); 18129 match(Set dst (LShiftVI src shift)); 18130 ins_cost(INSN_COST); 18131 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 18132 ins_encode %{ 18133 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 18134 as_FloatRegister($src$$reg), 18135 as_FloatRegister($shift$$reg)); 18136 %} 18137 ins_pipe(vshift128); 18138 %} 18139 18140 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 18141 predicate(n->as_Vector()->length() == 2); 18142 match(Set dst (RShiftVI src shift)); 18143 ins_cost(INSN_COST); 18144 effect(TEMP tmp); 18145 format %{ "negr $tmp,$shift\t" 18146 "sshl $dst,$src,$tmp\t# vector (2S)" %} 18147 ins_encode %{ 18148 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 18149 as_FloatRegister($shift$$reg)); 18150 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 18151 as_FloatRegister($src$$reg), 18152 as_FloatRegister($tmp$$reg)); 18153 %} 18154 ins_pipe(vshift64); 18155 %} 18156 18157 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 18158 predicate(n->as_Vector()->length() == 4); 18159 match(Set dst (RShiftVI src shift)); 18160 ins_cost(INSN_COST); 18161 effect(TEMP tmp); 18162 format %{ "negr $tmp,$shift\t" 18163 "sshl $dst,$src,$tmp\t# vector (4S)" %} 18164 ins_encode %{ 18165 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 18166 as_FloatRegister($shift$$reg)); 18167 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 18168 as_FloatRegister($src$$reg), 18169 as_FloatRegister($tmp$$reg)); 18170 %} 18171 ins_pipe(vshift128); 18172 %} 18173 18174 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 18175 predicate(n->as_Vector()->length() == 2); 18176 match(Set dst (URShiftVI src shift)); 18177 ins_cost(INSN_COST); 18178 effect(TEMP tmp); 18179 format %{ "negr $tmp,$shift\t" 18180 "ushl $dst,$src,$tmp\t# vector (2S)" %} 18181 ins_encode %{ 18182 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 18183 as_FloatRegister($shift$$reg)); 18184 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 18185 as_FloatRegister($src$$reg), 18186 as_FloatRegister($tmp$$reg)); 18187 %} 18188 ins_pipe(vshift64); 18189 %} 18190 18191 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 18192 predicate(n->as_Vector()->length() == 4); 18193 match(Set dst (URShiftVI src shift)); 18194 ins_cost(INSN_COST); 18195 effect(TEMP tmp); 18196 format %{ "negr $tmp,$shift\t" 18197 "ushl $dst,$src,$tmp\t# vector (4S)" %} 18198 ins_encode %{ 18199 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 18200 as_FloatRegister($shift$$reg)); 18201 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 18202 as_FloatRegister($src$$reg), 18203 as_FloatRegister($tmp$$reg)); 18204 %} 18205 ins_pipe(vshift128); 18206 %} 18207 18208 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 18209 predicate(n->as_Vector()->length() == 2); 18210 match(Set dst (LShiftVI src (LShiftCntV shift))); 18211 ins_cost(INSN_COST); 18212 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 18213 ins_encode %{ 18214 __ shl(as_FloatRegister($dst$$reg), __ T2S, 18215 as_FloatRegister($src$$reg), 18216 (int)$shift$$constant); 18217 %} 18218 ins_pipe(vshift64_imm); 18219 %} 18220 18221 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 18222 predicate(n->as_Vector()->length() == 4); 18223 match(Set dst (LShiftVI src (LShiftCntV shift))); 18224 ins_cost(INSN_COST); 18225 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 18226 ins_encode %{ 18227 __ shl(as_FloatRegister($dst$$reg), __ T4S, 18228 as_FloatRegister($src$$reg), 18229 (int)$shift$$constant); 18230 %} 18231 ins_pipe(vshift128_imm); 18232 %} 18233 18234 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 18235 predicate(n->as_Vector()->length() == 2); 18236 match(Set dst (RShiftVI src (RShiftCntV shift))); 18237 ins_cost(INSN_COST); 18238 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 18239 ins_encode %{ 18240 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 18241 as_FloatRegister($src$$reg), 18242 (int)$shift$$constant); 18243 %} 18244 ins_pipe(vshift64_imm); 18245 %} 18246 18247 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 18248 predicate(n->as_Vector()->length() == 4); 18249 match(Set dst (RShiftVI src (RShiftCntV shift))); 18250 ins_cost(INSN_COST); 18251 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 18252 ins_encode %{ 18253 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 18254 as_FloatRegister($src$$reg), 18255 (int)$shift$$constant); 18256 %} 18257 ins_pipe(vshift128_imm); 18258 %} 18259 18260 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 18261 predicate(n->as_Vector()->length() == 2); 18262 match(Set dst (URShiftVI src (RShiftCntV shift))); 18263 ins_cost(INSN_COST); 18264 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 18265 ins_encode %{ 18266 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 18267 as_FloatRegister($src$$reg), 18268 (int)$shift$$constant); 18269 %} 18270 ins_pipe(vshift64_imm); 18271 %} 18272 18273 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 18274 predicate(n->as_Vector()->length() == 4); 18275 match(Set dst (URShiftVI src (RShiftCntV shift))); 18276 ins_cost(INSN_COST); 18277 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 18278 ins_encode %{ 18279 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 18280 as_FloatRegister($src$$reg), 18281 (int)$shift$$constant); 18282 %} 18283 ins_pipe(vshift128_imm); 18284 %} 18285 18286 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 18287 predicate(n->as_Vector()->length() == 2); 18288 match(Set dst (LShiftVL src shift)); 18289 ins_cost(INSN_COST); 18290 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 18291 ins_encode %{ 18292 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 18293 as_FloatRegister($src$$reg), 18294 as_FloatRegister($shift$$reg)); 18295 %} 18296 ins_pipe(vshift128); 18297 %} 18298 18299 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 18300 predicate(n->as_Vector()->length() == 2); 18301 match(Set dst (RShiftVL src shift)); 18302 ins_cost(INSN_COST); 18303 effect(TEMP tmp); 18304 format %{ "negr $tmp,$shift\t" 18305 "sshl $dst,$src,$tmp\t# vector (2D)" %} 18306 ins_encode %{ 18307 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 18308 as_FloatRegister($shift$$reg)); 18309 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 18310 as_FloatRegister($src$$reg), 18311 as_FloatRegister($tmp$$reg)); 18312 %} 18313 ins_pipe(vshift128); 18314 %} 18315 18316 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 18317 predicate(n->as_Vector()->length() == 2); 18318 match(Set dst (URShiftVL src shift)); 18319 ins_cost(INSN_COST); 18320 effect(TEMP tmp); 18321 format %{ "negr $tmp,$shift\t" 18322 "ushl $dst,$src,$tmp\t# vector (2D)" %} 18323 ins_encode %{ 18324 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 18325 as_FloatRegister($shift$$reg)); 18326 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 18327 as_FloatRegister($src$$reg), 18328 as_FloatRegister($tmp$$reg)); 18329 %} 18330 ins_pipe(vshift128); 18331 %} 18332 18333 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 18334 predicate(n->as_Vector()->length() == 2); 18335 match(Set dst (LShiftVL src (LShiftCntV shift))); 18336 ins_cost(INSN_COST); 18337 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 18338 ins_encode %{ 18339 __ shl(as_FloatRegister($dst$$reg), __ T2D, 18340 as_FloatRegister($src$$reg), 18341 (int)$shift$$constant); 18342 %} 18343 ins_pipe(vshift128_imm); 18344 %} 18345 18346 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 18347 predicate(n->as_Vector()->length() == 2); 18348 match(Set dst (RShiftVL src (RShiftCntV shift))); 18349 ins_cost(INSN_COST); 18350 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 18351 ins_encode %{ 18352 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 18353 as_FloatRegister($src$$reg), 18354 (int)$shift$$constant); 18355 %} 18356 ins_pipe(vshift128_imm); 18357 %} 18358 18359 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 18360 predicate(n->as_Vector()->length() == 2); 18361 match(Set dst (URShiftVL src (RShiftCntV shift))); 18362 ins_cost(INSN_COST); 18363 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 18364 ins_encode %{ 18365 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 18366 as_FloatRegister($src$$reg), 18367 (int)$shift$$constant); 18368 %} 18369 ins_pipe(vshift128_imm); 18370 %} 18371 18372 instruct vmax2F(vecD dst, vecD src1, vecD src2) 18373 %{ 18374 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18375 match(Set dst (MaxV src1 src2)); 18376 ins_cost(INSN_COST); 18377 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 18378 ins_encode %{ 18379 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 18380 as_FloatRegister($src1$$reg), 18381 as_FloatRegister($src2$$reg)); 18382 %} 18383 ins_pipe(vdop_fp64); 18384 %} 18385 18386 instruct vmax4F(vecX dst, vecX src1, vecX src2) 18387 %{ 18388 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18389 match(Set dst (MaxV src1 src2)); 18390 ins_cost(INSN_COST); 18391 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 18392 ins_encode %{ 18393 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 18394 as_FloatRegister($src1$$reg), 18395 as_FloatRegister($src2$$reg)); 18396 %} 18397 ins_pipe(vdop_fp128); 18398 %} 18399 18400 instruct vmax2D(vecX dst, vecX src1, vecX src2) 18401 %{ 18402 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18403 match(Set dst (MaxV src1 src2)); 18404 ins_cost(INSN_COST); 18405 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 18406 ins_encode %{ 18407 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 18408 as_FloatRegister($src1$$reg), 18409 as_FloatRegister($src2$$reg)); 18410 %} 18411 ins_pipe(vdop_fp128); 18412 %} 18413 18414 instruct vmin2F(vecD dst, vecD src1, vecD src2) 18415 %{ 18416 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18417 match(Set dst (MinV src1 src2)); 18418 ins_cost(INSN_COST); 18419 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 18420 ins_encode %{ 18421 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 18422 as_FloatRegister($src1$$reg), 18423 as_FloatRegister($src2$$reg)); 18424 %} 18425 ins_pipe(vdop_fp64); 18426 %} 18427 18428 instruct vmin4F(vecX dst, vecX src1, vecX src2) 18429 %{ 18430 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18431 match(Set dst (MinV src1 src2)); 18432 ins_cost(INSN_COST); 18433 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 18434 ins_encode %{ 18435 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 18436 as_FloatRegister($src1$$reg), 18437 as_FloatRegister($src2$$reg)); 18438 %} 18439 ins_pipe(vdop_fp128); 18440 %} 18441 18442 instruct vmin2D(vecX dst, vecX src1, vecX src2) 18443 %{ 18444 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18445 match(Set dst (MinV src1 src2)); 18446 ins_cost(INSN_COST); 18447 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 18448 ins_encode %{ 18449 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 18450 as_FloatRegister($src1$$reg), 18451 as_FloatRegister($src2$$reg)); 18452 %} 18453 ins_pipe(vdop_fp128); 18454 %} 18455 18456 instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ 18457 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18458 match(Set dst (RoundDoubleModeV src rmode)); 18459 format %{ "frint $dst, $src, $rmode" %} 18460 ins_encode %{ 18461 switch ($rmode$$constant) { 18462 case RoundDoubleModeNode::rmode_rint: 18463 __ frintn(as_FloatRegister($dst$$reg), __ T2D, 18464 as_FloatRegister($src$$reg)); 18465 break; 18466 case RoundDoubleModeNode::rmode_floor: 18467 __ frintm(as_FloatRegister($dst$$reg), __ T2D, 18468 as_FloatRegister($src$$reg)); 18469 break; 18470 case RoundDoubleModeNode::rmode_ceil: 18471 __ frintp(as_FloatRegister($dst$$reg), __ T2D, 18472 as_FloatRegister($src$$reg)); 18473 break; 18474 } 18475 %} 18476 ins_pipe(vdop_fp128); 18477 %} 18478 18479 instruct vpopcount4I(vecX dst, vecX src) %{ 18480 predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); 18481 match(Set dst (PopCountVI src)); 18482 format %{ 18483 "cnt $dst, $src\t# vector (16B)\n\t" 18484 "uaddlp $dst, $dst\t# vector (16B)\n\t" 18485 "uaddlp $dst, $dst\t# vector (8H)" 18486 %} 18487 ins_encode %{ 18488 __ cnt(as_FloatRegister($dst$$reg), __ T16B, 18489 as_FloatRegister($src$$reg)); 18490 __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, 18491 as_FloatRegister($dst$$reg)); 18492 __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, 18493 as_FloatRegister($dst$$reg)); 18494 %} 18495 ins_pipe(pipe_class_default); 18496 %} 18497 18498 instruct vpopcount2I(vecD dst, vecD src) %{ 18499 predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); 18500 match(Set dst (PopCountVI src)); 18501 format %{ 18502 "cnt $dst, $src\t# vector (8B)\n\t" 18503 "uaddlp $dst, $dst\t# vector (8B)\n\t" 18504 "uaddlp $dst, $dst\t# vector (4H)" 18505 %} 18506 ins_encode %{ 18507 __ cnt(as_FloatRegister($dst$$reg), __ T8B, 18508 as_FloatRegister($src$$reg)); 18509 __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, 18510 as_FloatRegister($dst$$reg)); 18511 __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, 18512 as_FloatRegister($dst$$reg)); 18513 %} 18514 ins_pipe(pipe_class_default); 18515 %} 18516 18517 //----------PEEPHOLE RULES----------------------------------------------------- 18518 // These must follow all instruction definitions as they use the names 18519 // defined in the instructions definitions. 18520 // 18521 // peepmatch ( root_instr_name [preceding_instruction]* ); 18522 // 18523 // peepconstraint %{ 18524 // (instruction_number.operand_name relational_op instruction_number.operand_name 18525 // [, ...] ); 18526 // // instruction numbers are zero-based using left to right order in peepmatch 18527 // 18528 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18529 // // provide an instruction_number.operand_name for each operand that appears 18530 // // in the replacement instruction's match rule 18531 // 18532 // ---------VM FLAGS--------------------------------------------------------- 18533 // 18534 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18535 // 18536 // Each peephole rule is given an identifying number starting with zero and 18537 // increasing by one in the order seen by the parser. An individual peephole 18538 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18539 // on the command-line. 18540 // 18541 // ---------CURRENT LIMITATIONS---------------------------------------------- 18542 // 18543 // Only match adjacent instructions in same basic block 18544 // Only equality constraints 18545 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18546 // Only one replacement instruction 18547 // 18548 // ---------EXAMPLE---------------------------------------------------------- 18549 // 18550 // // pertinent parts of existing instructions in architecture description 18551 // instruct movI(iRegINoSp dst, iRegI src) 18552 // %{ 18553 // match(Set dst (CopyI src)); 18554 // %} 18555 // 18556 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18557 // %{ 18558 // match(Set dst (AddI dst src)); 18559 // effect(KILL cr); 18560 // %} 18561 // 18562 // // Change (inc mov) to lea 18563 // peephole %{ 18564 // // increment preceeded by register-register move 18565 // peepmatch ( incI_iReg movI ); 18566 // // require that the destination register of the increment 18567 // // match the destination register of the move 18568 // peepconstraint ( 0.dst == 1.dst ); 18569 // // construct a replacement instruction that sets 18570 // // the destination to ( move's source register + one ) 18571 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18572 // %} 18573 // 18574 18575 // Implementation no longer uses movX instructions since 18576 // machine-independent system no longer uses CopyX nodes. 18577 // 18578 // peephole 18579 // %{ 18580 // peepmatch (incI_iReg movI); 18581 // peepconstraint (0.dst == 1.dst); 18582 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18583 // %} 18584 18585 // peephole 18586 // %{ 18587 // peepmatch (decI_iReg movI); 18588 // peepconstraint (0.dst == 1.dst); 18589 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18590 // %} 18591 18592 // peephole 18593 // %{ 18594 // peepmatch (addI_iReg_imm movI); 18595 // peepconstraint (0.dst == 1.dst); 18596 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18597 // %} 18598 18599 // peephole 18600 // %{ 18601 // peepmatch (incL_iReg movL); 18602 // peepconstraint (0.dst == 1.dst); 18603 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18604 // %} 18605 18606 // peephole 18607 // %{ 18608 // peepmatch (decL_iReg movL); 18609 // peepconstraint (0.dst == 1.dst); 18610 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18611 // %} 18612 18613 // peephole 18614 // %{ 18615 // peepmatch (addL_iReg_imm movL); 18616 // peepconstraint (0.dst == 1.dst); 18617 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18618 // %} 18619 18620 // peephole 18621 // %{ 18622 // peepmatch (addP_iReg_imm movP); 18623 // peepconstraint (0.dst == 1.dst); 18624 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18625 // %} 18626 18627 // // Change load of spilled value to only a spill 18628 // instruct storeI(memory mem, iRegI src) 18629 // %{ 18630 // match(Set mem (StoreI mem src)); 18631 // %} 18632 // 18633 // instruct loadI(iRegINoSp dst, memory mem) 18634 // %{ 18635 // match(Set dst (LoadI mem)); 18636 // %} 18637 // 18638 18639 //----------SMARTSPILL RULES--------------------------------------------------- 18640 // These must follow all instruction definitions as they use the names 18641 // defined in the instructions definitions. 18642 18643 // Local Variables: 18644 // mode: c++ 18645 // End: