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->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->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 R28, // thread 536 R30, // lr 537 R31 // sp 538 ); 539 540 // Class for non-allocatable 64 bit registers 541 reg_class non_allocatable_reg( 542 R28, R28_H, // thread 543 R30, R30_H, // lr 544 R31, R31_H // sp 545 ); 546 547 // Class for all non-special integer registers 548 reg_class no_special_reg32 %{ 549 return _NO_SPECIAL_REG32_mask; 550 %} 551 552 // Class for all non-special long integer registers 553 reg_class no_special_reg %{ 554 return _NO_SPECIAL_REG_mask; 555 %} 556 557 // Class for 64 bit register r0 558 reg_class r0_reg( 559 R0, R0_H 560 ); 561 562 // Class for 64 bit register r1 563 reg_class r1_reg( 564 R1, R1_H 565 ); 566 567 // Class for 64 bit register r2 568 reg_class r2_reg( 569 R2, R2_H 570 ); 571 572 // Class for 64 bit register r3 573 reg_class r3_reg( 574 R3, R3_H 575 ); 576 577 // Class for 64 bit register r4 578 reg_class r4_reg( 579 R4, R4_H 580 ); 581 582 // Class for 64 bit register r5 583 reg_class r5_reg( 584 R5, R5_H 585 ); 586 587 // Class for 64 bit register r10 588 reg_class r10_reg( 589 R10, R10_H 590 ); 591 592 // Class for 64 bit register r11 593 reg_class r11_reg( 594 R11, R11_H 595 ); 596 597 // Class for method register 598 reg_class method_reg( 599 R12, R12_H 600 ); 601 602 // Class for heapbase register 603 reg_class heapbase_reg( 604 R27, R27_H 605 ); 606 607 // Class for thread register 608 reg_class thread_reg( 609 R28, R28_H 610 ); 611 612 // Class for frame pointer register 613 reg_class fp_reg( 614 R29, R29_H 615 ); 616 617 // Class for link register 618 reg_class lr_reg( 619 R30, R30_H 620 ); 621 622 // Class for long sp register 623 reg_class sp_reg( 624 R31, R31_H 625 ); 626 627 // Class for all pointer registers 628 reg_class ptr_reg %{ 629 return _PTR_REG_mask; 630 %} 631 632 // Class for all non_special pointer registers 633 reg_class no_special_ptr_reg %{ 634 return _NO_SPECIAL_PTR_REG_mask; 635 %} 636 637 // Class for all float registers 638 reg_class float_reg( 639 V0, 640 V1, 641 V2, 642 V3, 643 V4, 644 V5, 645 V6, 646 V7, 647 V8, 648 V9, 649 V10, 650 V11, 651 V12, 652 V13, 653 V14, 654 V15, 655 V16, 656 V17, 657 V18, 658 V19, 659 V20, 660 V21, 661 V22, 662 V23, 663 V24, 664 V25, 665 V26, 666 V27, 667 V28, 668 V29, 669 V30, 670 V31 671 ); 672 673 // Double precision float registers have virtual `high halves' that 674 // are needed by the allocator. 675 // Class for all double registers 676 reg_class double_reg( 677 V0, V0_H, 678 V1, V1_H, 679 V2, V2_H, 680 V3, V3_H, 681 V4, V4_H, 682 V5, V5_H, 683 V6, V6_H, 684 V7, V7_H, 685 V8, V8_H, 686 V9, V9_H, 687 V10, V10_H, 688 V11, V11_H, 689 V12, V12_H, 690 V13, V13_H, 691 V14, V14_H, 692 V15, V15_H, 693 V16, V16_H, 694 V17, V17_H, 695 V18, V18_H, 696 V19, V19_H, 697 V20, V20_H, 698 V21, V21_H, 699 V22, V22_H, 700 V23, V23_H, 701 V24, V24_H, 702 V25, V25_H, 703 V26, V26_H, 704 V27, V27_H, 705 V28, V28_H, 706 V29, V29_H, 707 V30, V30_H, 708 V31, V31_H 709 ); 710 711 // Class for all 64bit vector registers 712 reg_class vectord_reg( 713 V0, V0_H, 714 V1, V1_H, 715 V2, V2_H, 716 V3, V3_H, 717 V4, V4_H, 718 V5, V5_H, 719 V6, V6_H, 720 V7, V7_H, 721 V8, V8_H, 722 V9, V9_H, 723 V10, V10_H, 724 V11, V11_H, 725 V12, V12_H, 726 V13, V13_H, 727 V14, V14_H, 728 V15, V15_H, 729 V16, V16_H, 730 V17, V17_H, 731 V18, V18_H, 732 V19, V19_H, 733 V20, V20_H, 734 V21, V21_H, 735 V22, V22_H, 736 V23, V23_H, 737 V24, V24_H, 738 V25, V25_H, 739 V26, V26_H, 740 V27, V27_H, 741 V28, V28_H, 742 V29, V29_H, 743 V30, V30_H, 744 V31, V31_H 745 ); 746 747 // Class for all 128bit vector registers 748 reg_class vectorx_reg( 749 V0, V0_H, V0_J, V0_K, 750 V1, V1_H, V1_J, V1_K, 751 V2, V2_H, V2_J, V2_K, 752 V3, V3_H, V3_J, V3_K, 753 V4, V4_H, V4_J, V4_K, 754 V5, V5_H, V5_J, V5_K, 755 V6, V6_H, V6_J, V6_K, 756 V7, V7_H, V7_J, V7_K, 757 V8, V8_H, V8_J, V8_K, 758 V9, V9_H, V9_J, V9_K, 759 V10, V10_H, V10_J, V10_K, 760 V11, V11_H, V11_J, V11_K, 761 V12, V12_H, V12_J, V12_K, 762 V13, V13_H, V13_J, V13_K, 763 V14, V14_H, V14_J, V14_K, 764 V15, V15_H, V15_J, V15_K, 765 V16, V16_H, V16_J, V16_K, 766 V17, V17_H, V17_J, V17_K, 767 V18, V18_H, V18_J, V18_K, 768 V19, V19_H, V19_J, V19_K, 769 V20, V20_H, V20_J, V20_K, 770 V21, V21_H, V21_J, V21_K, 771 V22, V22_H, V22_J, V22_K, 772 V23, V23_H, V23_J, V23_K, 773 V24, V24_H, V24_J, V24_K, 774 V25, V25_H, V25_J, V25_K, 775 V26, V26_H, V26_J, V26_K, 776 V27, V27_H, V27_J, V27_K, 777 V28, V28_H, V28_J, V28_K, 778 V29, V29_H, V29_J, V29_K, 779 V30, V30_H, V30_J, V30_K, 780 V31, V31_H, V31_J, V31_K 781 ); 782 783 // Class for 128 bit register v0 784 reg_class v0_reg( 785 V0, V0_H 786 ); 787 788 // Class for 128 bit register v1 789 reg_class v1_reg( 790 V1, V1_H 791 ); 792 793 // Class for 128 bit register v2 794 reg_class v2_reg( 795 V2, V2_H 796 ); 797 798 // Class for 128 bit register v3 799 reg_class v3_reg( 800 V3, V3_H 801 ); 802 803 // Class for 128 bit register v4 804 reg_class v4_reg( 805 V4, V4_H 806 ); 807 808 // Class for 128 bit register v5 809 reg_class v5_reg( 810 V5, V5_H 811 ); 812 813 // Class for 128 bit register v6 814 reg_class v6_reg( 815 V6, V6_H 816 ); 817 818 // Class for 128 bit register v7 819 reg_class v7_reg( 820 V7, V7_H 821 ); 822 823 // Class for 128 bit register v8 824 reg_class v8_reg( 825 V8, V8_H 826 ); 827 828 // Class for 128 bit register v9 829 reg_class v9_reg( 830 V9, V9_H 831 ); 832 833 // Class for 128 bit register v10 834 reg_class v10_reg( 835 V10, V10_H 836 ); 837 838 // Class for 128 bit register v11 839 reg_class v11_reg( 840 V11, V11_H 841 ); 842 843 // Class for 128 bit register v12 844 reg_class v12_reg( 845 V12, V12_H 846 ); 847 848 // Class for 128 bit register v13 849 reg_class v13_reg( 850 V13, V13_H 851 ); 852 853 // Class for 128 bit register v14 854 reg_class v14_reg( 855 V14, V14_H 856 ); 857 858 // Class for 128 bit register v15 859 reg_class v15_reg( 860 V15, V15_H 861 ); 862 863 // Class for 128 bit register v16 864 reg_class v16_reg( 865 V16, V16_H 866 ); 867 868 // Class for 128 bit register v17 869 reg_class v17_reg( 870 V17, V17_H 871 ); 872 873 // Class for 128 bit register v18 874 reg_class v18_reg( 875 V18, V18_H 876 ); 877 878 // Class for 128 bit register v19 879 reg_class v19_reg( 880 V19, V19_H 881 ); 882 883 // Class for 128 bit register v20 884 reg_class v20_reg( 885 V20, V20_H 886 ); 887 888 // Class for 128 bit register v21 889 reg_class v21_reg( 890 V21, V21_H 891 ); 892 893 // Class for 128 bit register v22 894 reg_class v22_reg( 895 V22, V22_H 896 ); 897 898 // Class for 128 bit register v23 899 reg_class v23_reg( 900 V23, V23_H 901 ); 902 903 // Class for 128 bit register v24 904 reg_class v24_reg( 905 V24, V24_H 906 ); 907 908 // Class for 128 bit register v25 909 reg_class v25_reg( 910 V25, V25_H 911 ); 912 913 // Class for 128 bit register v26 914 reg_class v26_reg( 915 V26, V26_H 916 ); 917 918 // Class for 128 bit register v27 919 reg_class v27_reg( 920 V27, V27_H 921 ); 922 923 // Class for 128 bit register v28 924 reg_class v28_reg( 925 V28, V28_H 926 ); 927 928 // Class for 128 bit register v29 929 reg_class v29_reg( 930 V29, V29_H 931 ); 932 933 // Class for 128 bit register v30 934 reg_class v30_reg( 935 V30, V30_H 936 ); 937 938 // Class for 128 bit register v31 939 reg_class v31_reg( 940 V31, V31_H 941 ); 942 943 // Singleton class for condition codes 944 reg_class int_flags(RFLAGS); 945 946 %} 947 948 //----------DEFINITION BLOCK--------------------------------------------------- 949 // Define name --> value mappings to inform the ADLC of an integer valued name 950 // Current support includes integer values in the range [0, 0x7FFFFFFF] 951 // Format: 952 // int_def <name> ( <int_value>, <expression>); 953 // Generated Code in ad_<arch>.hpp 954 // #define <name> (<expression>) 955 // // value == <int_value> 956 // Generated code in ad_<arch>.cpp adlc_verification() 957 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 958 // 959 960 // we follow the ppc-aix port in using a simple cost model which ranks 961 // register operations as cheap, memory ops as more expensive and 962 // branches as most expensive. the first two have a low as well as a 963 // normal cost. huge cost appears to be a way of saying don't do 964 // something 965 966 definitions %{ 967 // The default cost (of a register move instruction). 968 int_def INSN_COST ( 100, 100); 969 int_def BRANCH_COST ( 200, 2 * INSN_COST); 970 int_def CALL_COST ( 200, 2 * INSN_COST); 971 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 972 %} 973 974 975 //----------SOURCE BLOCK------------------------------------------------------- 976 // This is a block of C++ code which provides values, functions, and 977 // definitions necessary in the rest of the architecture description 978 979 source_hpp %{ 980 981 #include "asm/macroAssembler.hpp" 982 #include "gc/shared/cardTable.hpp" 983 #include "gc/shared/cardTableBarrierSet.hpp" 984 #include "gc/shared/collectedHeap.hpp" 985 #include "opto/addnode.hpp" 986 #include "opto/convertnode.hpp" 987 988 extern RegMask _ANY_REG32_mask; 989 extern RegMask _ANY_REG_mask; 990 extern RegMask _PTR_REG_mask; 991 extern RegMask _NO_SPECIAL_REG32_mask; 992 extern RegMask _NO_SPECIAL_REG_mask; 993 extern RegMask _NO_SPECIAL_PTR_REG_mask; 994 995 class CallStubImpl { 996 997 //-------------------------------------------------------------- 998 //---< Used for optimization in Compile::shorten_branches >--- 999 //-------------------------------------------------------------- 1000 1001 public: 1002 // Size of call trampoline stub. 1003 static uint size_call_trampoline() { 1004 return 0; // no call trampolines on this platform 1005 } 1006 1007 // number of relocations needed by a call trampoline stub 1008 static uint reloc_call_trampoline() { 1009 return 0; // no call trampolines on this platform 1010 } 1011 }; 1012 1013 class HandlerImpl { 1014 1015 public: 1016 1017 static int emit_exception_handler(CodeBuffer &cbuf); 1018 static int emit_deopt_handler(CodeBuffer& cbuf); 1019 1020 static uint size_exception_handler() { 1021 return MacroAssembler::far_branch_size(); 1022 } 1023 1024 static uint size_deopt_handler() { 1025 // count one adr and one far branch instruction 1026 return 4 * NativeInstruction::instruction_size; 1027 } 1028 }; 1029 1030 class Node::PD { 1031 public: 1032 enum NodeFlags { 1033 _last_flag = Node::_last_flag 1034 }; 1035 }; 1036 1037 bool is_CAS(int opcode, bool maybe_volatile); 1038 1039 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1040 1041 bool unnecessary_acquire(const Node *barrier); 1042 bool needs_acquiring_load(const Node *load); 1043 1044 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1045 1046 bool unnecessary_release(const Node *barrier); 1047 bool unnecessary_volatile(const Node *barrier); 1048 bool needs_releasing_store(const Node *store); 1049 1050 // predicate controlling translation of CompareAndSwapX 1051 bool needs_acquiring_load_exclusive(const Node *load); 1052 1053 // predicate controlling addressing modes 1054 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1055 %} 1056 1057 source %{ 1058 1059 // Derived RegMask with conditionally allocatable registers 1060 1061 void PhaseOutput::pd_perform_mach_node_analysis() { 1062 } 1063 1064 int MachNode::pd_alignment_required() const { 1065 return 1; 1066 } 1067 1068 int MachNode::compute_padding(int current_offset) const { 1069 return 0; 1070 } 1071 1072 RegMask _ANY_REG32_mask; 1073 RegMask _ANY_REG_mask; 1074 RegMask _PTR_REG_mask; 1075 RegMask _NO_SPECIAL_REG32_mask; 1076 RegMask _NO_SPECIAL_REG_mask; 1077 RegMask _NO_SPECIAL_PTR_REG_mask; 1078 1079 void reg_mask_init() { 1080 // We derive below RegMask(s) from the ones which are auto-generated from 1081 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1082 // registers conditionally reserved. 1083 1084 _ANY_REG32_mask = _ALL_REG32_mask; 1085 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1086 1087 _ANY_REG_mask = _ALL_REG_mask; 1088 1089 _PTR_REG_mask = _ALL_REG_mask; 1090 1091 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1092 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1093 1094 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1095 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1096 1097 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1098 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1099 1100 // r27 is not allocatable when compressed oops is on and heapbase is not 1101 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1102 if (UseCompressedOops && CompressedOops::ptrs_base() != NULL) { 1103 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1104 _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1105 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1106 } 1107 1108 // r29 is not allocatable when PreserveFramePointer is on 1109 if (PreserveFramePointer) { 1110 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1111 _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); 1112 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); 1113 } 1114 } 1115 1116 // Optimizaton of volatile gets and puts 1117 // ------------------------------------- 1118 // 1119 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1120 // use to implement volatile reads and writes. For a volatile read 1121 // we simply need 1122 // 1123 // ldar<x> 1124 // 1125 // and for a volatile write we need 1126 // 1127 // stlr<x> 1128 // 1129 // Alternatively, we can implement them by pairing a normal 1130 // load/store with a memory barrier. For a volatile read we need 1131 // 1132 // ldr<x> 1133 // dmb ishld 1134 // 1135 // for a volatile write 1136 // 1137 // dmb ish 1138 // str<x> 1139 // dmb ish 1140 // 1141 // We can also use ldaxr and stlxr to implement compare and swap CAS 1142 // sequences. These are normally translated to an instruction 1143 // sequence like the following 1144 // 1145 // dmb ish 1146 // retry: 1147 // ldxr<x> rval raddr 1148 // cmp rval rold 1149 // b.ne done 1150 // stlxr<x> rval, rnew, rold 1151 // cbnz rval retry 1152 // done: 1153 // cset r0, eq 1154 // dmb ishld 1155 // 1156 // Note that the exclusive store is already using an stlxr 1157 // instruction. That is required to ensure visibility to other 1158 // threads of the exclusive write (assuming it succeeds) before that 1159 // of any subsequent writes. 1160 // 1161 // The following instruction sequence is an improvement on the above 1162 // 1163 // retry: 1164 // ldaxr<x> rval raddr 1165 // cmp rval rold 1166 // b.ne done 1167 // stlxr<x> rval, rnew, rold 1168 // cbnz rval retry 1169 // done: 1170 // cset r0, eq 1171 // 1172 // We don't need the leading dmb ish since the stlxr guarantees 1173 // visibility of prior writes in the case that the swap is 1174 // successful. Crucially we don't have to worry about the case where 1175 // the swap is not successful since no valid program should be 1176 // relying on visibility of prior changes by the attempting thread 1177 // in the case where the CAS fails. 1178 // 1179 // Similarly, we don't need the trailing dmb ishld if we substitute 1180 // an ldaxr instruction since that will provide all the guarantees we 1181 // require regarding observation of changes made by other threads 1182 // before any change to the CAS address observed by the load. 1183 // 1184 // In order to generate the desired instruction sequence we need to 1185 // be able to identify specific 'signature' ideal graph node 1186 // sequences which i) occur as a translation of a volatile reads or 1187 // writes or CAS operations and ii) do not occur through any other 1188 // translation or graph transformation. We can then provide 1189 // alternative aldc matching rules which translate these node 1190 // sequences to the desired machine code sequences. Selection of the 1191 // alternative rules can be implemented by predicates which identify 1192 // the relevant node sequences. 1193 // 1194 // The ideal graph generator translates a volatile read to the node 1195 // sequence 1196 // 1197 // LoadX[mo_acquire] 1198 // MemBarAcquire 1199 // 1200 // As a special case when using the compressed oops optimization we 1201 // may also see this variant 1202 // 1203 // LoadN[mo_acquire] 1204 // DecodeN 1205 // MemBarAcquire 1206 // 1207 // A volatile write is translated to the node sequence 1208 // 1209 // MemBarRelease 1210 // StoreX[mo_release] {CardMark}-optional 1211 // MemBarVolatile 1212 // 1213 // n.b. the above node patterns are generated with a strict 1214 // 'signature' configuration of input and output dependencies (see 1215 // the predicates below for exact details). The card mark may be as 1216 // simple as a few extra nodes or, in a few GC configurations, may 1217 // include more complex control flow between the leading and 1218 // trailing memory barriers. However, whatever the card mark 1219 // configuration these signatures are unique to translated volatile 1220 // reads/stores -- they will not appear as a result of any other 1221 // bytecode translation or inlining nor as a consequence of 1222 // optimizing transforms. 1223 // 1224 // We also want to catch inlined unsafe volatile gets and puts and 1225 // be able to implement them using either ldar<x>/stlr<x> or some 1226 // combination of ldr<x>/stlr<x> and dmb instructions. 1227 // 1228 // Inlined unsafe volatiles puts manifest as a minor variant of the 1229 // normal volatile put node sequence containing an extra cpuorder 1230 // membar 1231 // 1232 // MemBarRelease 1233 // MemBarCPUOrder 1234 // StoreX[mo_release] {CardMark}-optional 1235 // MemBarCPUOrder 1236 // MemBarVolatile 1237 // 1238 // n.b. as an aside, a cpuorder membar is not itself subject to 1239 // matching and translation by adlc rules. However, the rule 1240 // predicates need to detect its presence in order to correctly 1241 // select the desired adlc rules. 1242 // 1243 // Inlined unsafe volatile gets manifest as a slightly different 1244 // node sequence to a normal volatile get because of the 1245 // introduction of some CPUOrder memory barriers to bracket the 1246 // Load. However, but the same basic skeleton of a LoadX feeding a 1247 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1248 // present 1249 // 1250 // MemBarCPUOrder 1251 // || \\ 1252 // MemBarCPUOrder LoadX[mo_acquire] 1253 // || | 1254 // || {DecodeN} optional 1255 // || / 1256 // MemBarAcquire 1257 // 1258 // In this case the acquire membar does not directly depend on the 1259 // load. However, we can be sure that the load is generated from an 1260 // inlined unsafe volatile get if we see it dependent on this unique 1261 // sequence of membar nodes. Similarly, given an acquire membar we 1262 // can know that it was added because of an inlined unsafe volatile 1263 // get if it is fed and feeds a cpuorder membar and if its feed 1264 // membar also feeds an acquiring load. 1265 // 1266 // Finally an inlined (Unsafe) CAS operation is translated to the 1267 // following ideal graph 1268 // 1269 // MemBarRelease 1270 // MemBarCPUOrder 1271 // CompareAndSwapX {CardMark}-optional 1272 // MemBarCPUOrder 1273 // MemBarAcquire 1274 // 1275 // So, where we can identify these volatile read and write 1276 // signatures we can choose to plant either of the above two code 1277 // sequences. For a volatile read we can simply plant a normal 1278 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1279 // also choose to inhibit translation of the MemBarAcquire and 1280 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1281 // 1282 // When we recognise a volatile store signature we can choose to 1283 // plant at a dmb ish as a translation for the MemBarRelease, a 1284 // normal str<x> and then a dmb ish for the MemBarVolatile. 1285 // Alternatively, we can inhibit translation of the MemBarRelease 1286 // and MemBarVolatile and instead plant a simple stlr<x> 1287 // instruction. 1288 // 1289 // when we recognise a CAS signature we can choose to plant a dmb 1290 // ish as a translation for the MemBarRelease, the conventional 1291 // macro-instruction sequence for the CompareAndSwap node (which 1292 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1293 // Alternatively, we can elide generation of the dmb instructions 1294 // and plant the alternative CompareAndSwap macro-instruction 1295 // sequence (which uses ldaxr<x>). 1296 // 1297 // Of course, the above only applies when we see these signature 1298 // configurations. We still want to plant dmb instructions in any 1299 // other cases where we may see a MemBarAcquire, MemBarRelease or 1300 // MemBarVolatile. For example, at the end of a constructor which 1301 // writes final/volatile fields we will see a MemBarRelease 1302 // instruction and this needs a 'dmb ish' lest we risk the 1303 // constructed object being visible without making the 1304 // final/volatile field writes visible. 1305 // 1306 // n.b. the translation rules below which rely on detection of the 1307 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1308 // If we see anything other than the signature configurations we 1309 // always just translate the loads and stores to ldr<x> and str<x> 1310 // and translate acquire, release and volatile membars to the 1311 // relevant dmb instructions. 1312 // 1313 1314 // is_CAS(int opcode, bool maybe_volatile) 1315 // 1316 // return true if opcode is one of the possible CompareAndSwapX 1317 // values otherwise false. 1318 1319 bool is_CAS(int opcode, bool maybe_volatile) 1320 { 1321 switch(opcode) { 1322 // We handle these 1323 case Op_CompareAndSwapI: 1324 case Op_CompareAndSwapL: 1325 case Op_CompareAndSwapP: 1326 case Op_CompareAndSwapN: 1327 case Op_ShenandoahCompareAndSwapP: 1328 case Op_ShenandoahCompareAndSwapN: 1329 case Op_CompareAndSwapB: 1330 case Op_CompareAndSwapS: 1331 case Op_GetAndSetI: 1332 case Op_GetAndSetL: 1333 case Op_GetAndSetP: 1334 case Op_GetAndSetN: 1335 case Op_GetAndAddI: 1336 case Op_GetAndAddL: 1337 return true; 1338 case Op_CompareAndExchangeI: 1339 case Op_CompareAndExchangeN: 1340 case Op_CompareAndExchangeB: 1341 case Op_CompareAndExchangeS: 1342 case Op_CompareAndExchangeL: 1343 case Op_CompareAndExchangeP: 1344 case Op_WeakCompareAndSwapB: 1345 case Op_WeakCompareAndSwapS: 1346 case Op_WeakCompareAndSwapI: 1347 case Op_WeakCompareAndSwapL: 1348 case Op_WeakCompareAndSwapP: 1349 case Op_WeakCompareAndSwapN: 1350 case Op_ShenandoahWeakCompareAndSwapP: 1351 case Op_ShenandoahWeakCompareAndSwapN: 1352 case Op_ShenandoahCompareAndExchangeP: 1353 case Op_ShenandoahCompareAndExchangeN: 1354 return maybe_volatile; 1355 default: 1356 return false; 1357 } 1358 } 1359 1360 // helper to determine the maximum number of Phi nodes we may need to 1361 // traverse when searching from a card mark membar for the merge mem 1362 // feeding a trailing membar or vice versa 1363 1364 // predicates controlling emit of ldr<x>/ldar<x> 1365 1366 bool unnecessary_acquire(const Node *barrier) 1367 { 1368 assert(barrier->is_MemBar(), "expecting a membar"); 1369 1370 MemBarNode* mb = barrier->as_MemBar(); 1371 1372 if (mb->trailing_load()) { 1373 return true; 1374 } 1375 1376 if (mb->trailing_load_store()) { 1377 Node* load_store = mb->in(MemBarNode::Precedent); 1378 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1379 return is_CAS(load_store->Opcode(), true); 1380 } 1381 1382 return false; 1383 } 1384 1385 bool needs_acquiring_load(const Node *n) 1386 { 1387 assert(n->is_Load(), "expecting a load"); 1388 LoadNode *ld = n->as_Load(); 1389 return ld->is_acquire(); 1390 } 1391 1392 bool unnecessary_release(const Node *n) 1393 { 1394 assert((n->is_MemBar() && 1395 n->Opcode() == Op_MemBarRelease), 1396 "expecting a release membar"); 1397 1398 MemBarNode *barrier = n->as_MemBar(); 1399 if (!barrier->leading()) { 1400 return false; 1401 } else { 1402 Node* trailing = barrier->trailing_membar(); 1403 MemBarNode* trailing_mb = trailing->as_MemBar(); 1404 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1405 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1406 1407 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1408 if (mem->is_Store()) { 1409 assert(mem->as_Store()->is_release(), ""); 1410 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1411 return true; 1412 } else { 1413 assert(mem->is_LoadStore(), ""); 1414 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1415 return is_CAS(mem->Opcode(), true); 1416 } 1417 } 1418 return false; 1419 } 1420 1421 bool unnecessary_volatile(const Node *n) 1422 { 1423 // assert n->is_MemBar(); 1424 MemBarNode *mbvol = n->as_MemBar(); 1425 1426 bool release = mbvol->trailing_store(); 1427 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1428 #ifdef ASSERT 1429 if (release) { 1430 Node* leading = mbvol->leading_membar(); 1431 assert(leading->Opcode() == Op_MemBarRelease, ""); 1432 assert(leading->as_MemBar()->leading_store(), ""); 1433 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1434 } 1435 #endif 1436 1437 return release; 1438 } 1439 1440 // predicates controlling emit of str<x>/stlr<x> 1441 1442 bool needs_releasing_store(const Node *n) 1443 { 1444 // assert n->is_Store(); 1445 StoreNode *st = n->as_Store(); 1446 return st->trailing_membar() != NULL; 1447 } 1448 1449 // predicate controlling translation of CAS 1450 // 1451 // returns true if CAS needs to use an acquiring load otherwise false 1452 1453 bool needs_acquiring_load_exclusive(const Node *n) 1454 { 1455 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1456 LoadStoreNode* ldst = n->as_LoadStore(); 1457 if (is_CAS(n->Opcode(), false)) { 1458 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1459 } else { 1460 return ldst->trailing_membar() != NULL; 1461 } 1462 1463 // so we can just return true here 1464 return true; 1465 } 1466 1467 #define __ _masm. 1468 1469 // advance declarations for helper functions to convert register 1470 // indices to register objects 1471 1472 // the ad file has to provide implementations of certain methods 1473 // expected by the generic code 1474 // 1475 // REQUIRED FUNCTIONALITY 1476 1477 //============================================================================= 1478 1479 // !!!!! Special hack to get all types of calls to specify the byte offset 1480 // from the start of the call to the point where the return address 1481 // will point. 1482 1483 int MachCallStaticJavaNode::ret_addr_offset() 1484 { 1485 // call should be a simple bl 1486 int off = 4; 1487 return off; 1488 } 1489 1490 int MachCallDynamicJavaNode::ret_addr_offset() 1491 { 1492 return 16; // movz, movk, movk, bl 1493 } 1494 1495 int MachCallRuntimeNode::ret_addr_offset() { 1496 // for generated stubs the call will be 1497 // far_call(addr) 1498 // for real runtime callouts it will be six instructions 1499 // see aarch64_enc_java_to_runtime 1500 // adr(rscratch2, retaddr) 1501 // lea(rscratch1, RuntimeAddress(addr) 1502 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1503 // blr(rscratch1) 1504 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1505 if (cb) { 1506 return MacroAssembler::far_branch_size(); 1507 } else { 1508 return 6 * NativeInstruction::instruction_size; 1509 } 1510 } 1511 1512 // Indicate if the safepoint node needs the polling page as an input 1513 1514 // the shared code plants the oop data at the start of the generated 1515 // code for the safepoint node and that needs ot be at the load 1516 // instruction itself. so we cannot plant a mov of the safepoint poll 1517 // address followed by a load. setting this to true means the mov is 1518 // scheduled as a prior instruction. that's better for scheduling 1519 // anyway. 1520 1521 bool SafePointNode::needs_polling_address_input() 1522 { 1523 return true; 1524 } 1525 1526 //============================================================================= 1527 1528 #ifndef PRODUCT 1529 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1530 st->print("BREAKPOINT"); 1531 } 1532 #endif 1533 1534 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1535 C2_MacroAssembler _masm(&cbuf); 1536 __ brk(0); 1537 } 1538 1539 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1540 return MachNode::size(ra_); 1541 } 1542 1543 //============================================================================= 1544 1545 #ifndef PRODUCT 1546 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1547 st->print("nop \t# %d bytes pad for loops and calls", _count); 1548 } 1549 #endif 1550 1551 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1552 C2_MacroAssembler _masm(&cbuf); 1553 for (int i = 0; i < _count; i++) { 1554 __ nop(); 1555 } 1556 } 1557 1558 uint MachNopNode::size(PhaseRegAlloc*) const { 1559 return _count * NativeInstruction::instruction_size; 1560 } 1561 1562 //============================================================================= 1563 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1564 1565 int ConstantTable::calculate_table_base_offset() const { 1566 return 0; // absolute addressing, no offset 1567 } 1568 1569 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1570 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1571 ShouldNotReachHere(); 1572 } 1573 1574 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1575 // Empty encoding 1576 } 1577 1578 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1579 return 0; 1580 } 1581 1582 #ifndef PRODUCT 1583 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1584 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1585 } 1586 #endif 1587 1588 #ifndef PRODUCT 1589 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1590 Compile* C = ra_->C; 1591 1592 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1593 1594 if (C->output()->need_stack_bang(framesize)) 1595 st->print("# stack bang size=%d\n\t", framesize); 1596 1597 if (framesize < ((1 << 9) + 2 * wordSize)) { 1598 st->print("sub sp, sp, #%d\n\t", framesize); 1599 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1600 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1601 } else { 1602 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1603 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1604 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1605 st->print("sub sp, sp, rscratch1"); 1606 } 1607 if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1608 st->print("\n\t"); 1609 st->print("ldr rscratch1, [guard]\n\t"); 1610 st->print("dmb ishld\n\t"); 1611 st->print("ldr rscratch2, [rthread, #thread_disarmed_offset]\n\t"); 1612 st->print("cmp rscratch1, rscratch2\n\t"); 1613 st->print("b.eq skip"); 1614 st->print("\n\t"); 1615 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1616 st->print("b skip\n\t"); 1617 st->print("guard: int\n\t"); 1618 st->print("\n\t"); 1619 st->print("skip:\n\t"); 1620 } 1621 } 1622 #endif 1623 1624 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1625 Compile* C = ra_->C; 1626 C2_MacroAssembler _masm(&cbuf); 1627 1628 // n.b. frame size includes space for return pc and rfp 1629 const long framesize = C->output()->frame_size_in_bytes(); 1630 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1631 1632 // insert a nop at the start of the prolog so we can patch in a 1633 // branch if we need to invalidate the method later 1634 __ nop(); 1635 1636 if (C->clinit_barrier_on_entry()) { 1637 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1638 1639 Label L_skip_barrier; 1640 1641 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1642 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1643 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1644 __ bind(L_skip_barrier); 1645 } 1646 1647 int bangsize = C->output()->bang_size_in_bytes(); 1648 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) 1649 __ generate_stack_overflow_check(bangsize); 1650 1651 __ build_frame(framesize); 1652 1653 if (C->stub_function() == NULL) { 1654 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1655 bs->nmethod_entry_barrier(&_masm); 1656 } 1657 1658 if (VerifyStackAtCalls) { 1659 Unimplemented(); 1660 } 1661 1662 C->output()->set_frame_complete(cbuf.insts_size()); 1663 1664 if (C->has_mach_constant_base_node()) { 1665 // NOTE: We set the table base offset here because users might be 1666 // emitted before MachConstantBaseNode. 1667 ConstantTable& constant_table = C->output()->constant_table(); 1668 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1669 } 1670 } 1671 1672 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1673 { 1674 return MachNode::size(ra_); // too many variables; just compute it 1675 // the hard way 1676 } 1677 1678 int MachPrologNode::reloc() const 1679 { 1680 return 0; 1681 } 1682 1683 //============================================================================= 1684 1685 #ifndef PRODUCT 1686 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1687 Compile* C = ra_->C; 1688 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1689 1690 st->print("# pop frame %d\n\t",framesize); 1691 1692 if (framesize == 0) { 1693 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1694 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1695 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1696 st->print("add sp, sp, #%d\n\t", framesize); 1697 } else { 1698 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1699 st->print("add sp, sp, rscratch1\n\t"); 1700 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1701 } 1702 1703 if (do_polling() && C->is_method_compilation()) { 1704 st->print("# touch polling page\n\t"); 1705 st->print("ldr rscratch1, [rthread],#polling_page_offset\n\t"); 1706 st->print("ldr zr, [rscratch1]"); 1707 } 1708 } 1709 #endif 1710 1711 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1712 Compile* C = ra_->C; 1713 C2_MacroAssembler _masm(&cbuf); 1714 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1715 1716 __ remove_frame(framesize); 1717 1718 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1719 __ reserved_stack_check(); 1720 } 1721 1722 if (do_polling() && C->is_method_compilation()) { 1723 __ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type); 1724 } 1725 } 1726 1727 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1728 // Variable size. Determine dynamically. 1729 return MachNode::size(ra_); 1730 } 1731 1732 int MachEpilogNode::reloc() const { 1733 // Return number of relocatable values contained in this instruction. 1734 return 1; // 1 for polling page. 1735 } 1736 1737 const Pipeline * MachEpilogNode::pipeline() const { 1738 return MachNode::pipeline_class(); 1739 } 1740 1741 //============================================================================= 1742 1743 // Figure out which register class each belongs in: rc_int, rc_float or 1744 // rc_stack. 1745 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1746 1747 static enum RC rc_class(OptoReg::Name reg) { 1748 1749 if (reg == OptoReg::Bad) { 1750 return rc_bad; 1751 } 1752 1753 // we have 30 int registers * 2 halves 1754 // (rscratch1 and rscratch2 are omitted) 1755 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1756 1757 if (reg < slots_of_int_registers) { 1758 return rc_int; 1759 } 1760 1761 // we have 32 float register * 4 halves 1762 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1763 return rc_float; 1764 } 1765 1766 // Between float regs & stack is the flags regs. 1767 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1768 1769 return rc_stack; 1770 } 1771 1772 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1773 Compile* C = ra_->C; 1774 1775 // Get registers to move. 1776 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1777 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1778 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1779 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1780 1781 enum RC src_hi_rc = rc_class(src_hi); 1782 enum RC src_lo_rc = rc_class(src_lo); 1783 enum RC dst_hi_rc = rc_class(dst_hi); 1784 enum RC dst_lo_rc = rc_class(dst_lo); 1785 1786 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1787 1788 if (src_hi != OptoReg::Bad) { 1789 assert((src_lo&1)==0 && src_lo+1==src_hi && 1790 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1791 "expected aligned-adjacent pairs"); 1792 } 1793 1794 if (src_lo == dst_lo && src_hi == dst_hi) { 1795 return 0; // Self copy, no move. 1796 } 1797 1798 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1799 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1800 int src_offset = ra_->reg2offset(src_lo); 1801 int dst_offset = ra_->reg2offset(dst_lo); 1802 1803 if (bottom_type()->isa_vect() != NULL) { 1804 uint ireg = ideal_reg(); 1805 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1806 if (cbuf) { 1807 C2_MacroAssembler _masm(cbuf); 1808 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1809 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1810 // stack->stack 1811 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1812 if (ireg == Op_VecD) { 1813 __ unspill(rscratch1, true, src_offset); 1814 __ spill(rscratch1, true, dst_offset); 1815 } else { 1816 __ spill_copy128(src_offset, dst_offset); 1817 } 1818 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1819 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1820 ireg == Op_VecD ? __ T8B : __ T16B, 1821 as_FloatRegister(Matcher::_regEncode[src_lo])); 1822 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1823 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1824 ireg == Op_VecD ? __ D : __ Q, 1825 ra_->reg2offset(dst_lo)); 1826 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1827 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1828 ireg == Op_VecD ? __ D : __ Q, 1829 ra_->reg2offset(src_lo)); 1830 } else { 1831 ShouldNotReachHere(); 1832 } 1833 } 1834 } else if (cbuf) { 1835 C2_MacroAssembler _masm(cbuf); 1836 switch (src_lo_rc) { 1837 case rc_int: 1838 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1839 if (is64) { 1840 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1841 as_Register(Matcher::_regEncode[src_lo])); 1842 } else { 1843 C2_MacroAssembler _masm(cbuf); 1844 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1845 as_Register(Matcher::_regEncode[src_lo])); 1846 } 1847 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1848 if (is64) { 1849 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1850 as_Register(Matcher::_regEncode[src_lo])); 1851 } else { 1852 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1853 as_Register(Matcher::_regEncode[src_lo])); 1854 } 1855 } else { // gpr --> stack spill 1856 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1857 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1858 } 1859 break; 1860 case rc_float: 1861 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1862 if (is64) { 1863 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1864 as_FloatRegister(Matcher::_regEncode[src_lo])); 1865 } else { 1866 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1867 as_FloatRegister(Matcher::_regEncode[src_lo])); 1868 } 1869 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1870 if (cbuf) { 1871 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1872 as_FloatRegister(Matcher::_regEncode[src_lo])); 1873 } else { 1874 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1875 as_FloatRegister(Matcher::_regEncode[src_lo])); 1876 } 1877 } else { // fpr --> stack spill 1878 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1879 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1880 is64 ? __ D : __ S, dst_offset); 1881 } 1882 break; 1883 case rc_stack: 1884 if (dst_lo_rc == rc_int) { // stack --> gpr load 1885 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1886 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1887 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1888 is64 ? __ D : __ S, src_offset); 1889 } else { // stack --> stack copy 1890 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1891 __ unspill(rscratch1, is64, src_offset); 1892 __ spill(rscratch1, is64, dst_offset); 1893 } 1894 break; 1895 default: 1896 assert(false, "bad rc_class for spill"); 1897 ShouldNotReachHere(); 1898 } 1899 } 1900 1901 if (st) { 1902 st->print("spill "); 1903 if (src_lo_rc == rc_stack) { 1904 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1905 } else { 1906 st->print("%s -> ", Matcher::regName[src_lo]); 1907 } 1908 if (dst_lo_rc == rc_stack) { 1909 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1910 } else { 1911 st->print("%s", Matcher::regName[dst_lo]); 1912 } 1913 if (bottom_type()->isa_vect() != NULL) { 1914 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1915 } else { 1916 st->print("\t# spill size = %d", is64 ? 64:32); 1917 } 1918 } 1919 1920 return 0; 1921 1922 } 1923 1924 #ifndef PRODUCT 1925 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1926 if (!ra_) 1927 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1928 else 1929 implementation(NULL, ra_, false, st); 1930 } 1931 #endif 1932 1933 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1934 implementation(&cbuf, ra_, false, NULL); 1935 } 1936 1937 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1938 return MachNode::size(ra_); 1939 } 1940 1941 //============================================================================= 1942 1943 #ifndef PRODUCT 1944 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1945 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1946 int reg = ra_->get_reg_first(this); 1947 st->print("add %s, rsp, #%d]\t# box lock", 1948 Matcher::regName[reg], offset); 1949 } 1950 #endif 1951 1952 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1953 C2_MacroAssembler _masm(&cbuf); 1954 1955 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1956 int reg = ra_->get_encode(this); 1957 1958 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1959 __ add(as_Register(reg), sp, offset); 1960 } else { 1961 ShouldNotReachHere(); 1962 } 1963 } 1964 1965 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1966 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1967 return 4; 1968 } 1969 1970 //============================================================================= 1971 1972 #ifndef PRODUCT 1973 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1974 { 1975 st->print_cr("# MachUEPNode"); 1976 if (UseCompressedClassPointers) { 1977 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1978 if (CompressedKlassPointers::shift() != 0) { 1979 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1980 } 1981 } else { 1982 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1983 } 1984 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1985 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1986 } 1987 #endif 1988 1989 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1990 { 1991 // This is the unverified entry point. 1992 C2_MacroAssembler _masm(&cbuf); 1993 1994 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1995 Label skip; 1996 // TODO 1997 // can we avoid this skip and still use a reloc? 1998 __ br(Assembler::EQ, skip); 1999 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2000 __ bind(skip); 2001 } 2002 2003 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2004 { 2005 return MachNode::size(ra_); 2006 } 2007 2008 // REQUIRED EMIT CODE 2009 2010 //============================================================================= 2011 2012 // Emit exception handler code. 2013 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2014 { 2015 // mov rscratch1 #exception_blob_entry_point 2016 // br rscratch1 2017 // Note that the code buffer's insts_mark is always relative to insts. 2018 // That's why we must use the macroassembler to generate a handler. 2019 C2_MacroAssembler _masm(&cbuf); 2020 address base = __ start_a_stub(size_exception_handler()); 2021 if (base == NULL) { 2022 ciEnv::current()->record_failure("CodeCache is full"); 2023 return 0; // CodeBuffer::expand failed 2024 } 2025 int offset = __ offset(); 2026 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2027 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2028 __ end_a_stub(); 2029 return offset; 2030 } 2031 2032 // Emit deopt handler code. 2033 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2034 { 2035 // Note that the code buffer's insts_mark is always relative to insts. 2036 // That's why we must use the macroassembler to generate a handler. 2037 C2_MacroAssembler _masm(&cbuf); 2038 address base = __ start_a_stub(size_deopt_handler()); 2039 if (base == NULL) { 2040 ciEnv::current()->record_failure("CodeCache is full"); 2041 return 0; // CodeBuffer::expand failed 2042 } 2043 int offset = __ offset(); 2044 2045 __ adr(lr, __ pc()); 2046 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2047 2048 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2049 __ end_a_stub(); 2050 return offset; 2051 } 2052 2053 // REQUIRED MATCHER CODE 2054 2055 //============================================================================= 2056 2057 const bool Matcher::match_rule_supported(int opcode) { 2058 if (!has_match_rule(opcode)) 2059 return false; 2060 2061 bool ret_value = true; 2062 switch (opcode) { 2063 case Op_CacheWB: 2064 case Op_CacheWBPreSync: 2065 case Op_CacheWBPostSync: 2066 if (!VM_Version::supports_data_cache_line_flush()) { 2067 ret_value = false; 2068 } 2069 break; 2070 } 2071 2072 return ret_value; // Per default match rules are supported. 2073 } 2074 2075 // Identify extra cases that we might want to provide match rules for vector nodes and 2076 // other intrinsics guarded with vector length (vlen) and element type (bt). 2077 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2078 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { 2079 return false; 2080 } 2081 2082 // Special cases which require vector length 2083 switch (opcode) { 2084 case Op_MulAddVS2VI: { 2085 if (vlen != 4) { 2086 return false; 2087 } 2088 break; 2089 } 2090 case Op_VectorLoadShuffle: 2091 case Op_VectorRearrange: 2092 if (vlen < 4) { 2093 return false; 2094 } 2095 break; 2096 } 2097 2098 return true; // Per default match rules are supported. 2099 } 2100 2101 const bool Matcher::has_predicated_vectors(void) { 2102 return false; 2103 } 2104 2105 bool Matcher::supports_vector_variable_shifts(void) { 2106 return true; 2107 } 2108 2109 const int Matcher::float_pressure(int default_pressure_threshold) { 2110 return default_pressure_threshold; 2111 } 2112 2113 int Matcher::regnum_to_fpu_offset(int regnum) 2114 { 2115 Unimplemented(); 2116 return 0; 2117 } 2118 2119 // Is this branch offset short enough that a short branch can be used? 2120 // 2121 // NOTE: If the platform does not provide any short branch variants, then 2122 // this method should return false for offset 0. 2123 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2124 // The passed offset is relative to address of the branch. 2125 2126 return (-32768 <= offset && offset < 32768); 2127 } 2128 2129 const bool Matcher::isSimpleConstant64(jlong value) { 2130 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2131 // Probably always true, even if a temp register is required. 2132 return true; 2133 } 2134 2135 // true just means we have fast l2f conversion 2136 const bool Matcher::convL2FSupported(void) { 2137 return true; 2138 } 2139 2140 // Vector width in bytes. 2141 const int Matcher::vector_width_in_bytes(BasicType bt) { 2142 int size = MIN2(16,(int)MaxVectorSize); 2143 // Minimum 2 values in vector 2144 if (size < 2*type2aelembytes(bt)) size = 0; 2145 // But never < 4 2146 if (size < 4) size = 0; 2147 return size; 2148 } 2149 2150 // Limits on vector size (number of elements) loaded into vector. 2151 const int Matcher::max_vector_size(const BasicType bt) { 2152 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2153 } 2154 const int Matcher::min_vector_size(const BasicType bt) { 2155 int max_size = max_vector_size(bt); 2156 // Limit the vector size to 8 bytes 2157 int size = 8 / type2aelembytes(bt); 2158 if (bt == T_BYTE) { 2159 // To support vector api shuffle/rearrange. 2160 size = 4; 2161 } else if (bt == T_BOOLEAN) { 2162 // To support vector api load/store mask. 2163 size = 2; 2164 } 2165 if (size < 2) size = 2; 2166 return MIN2(size,max_size); 2167 } 2168 2169 // Vector ideal reg. 2170 const uint Matcher::vector_ideal_reg(int len) { 2171 switch(len) { 2172 // For 16-bit/32-bit mask vector, reuse VecD. 2173 case 2: 2174 case 4: 2175 case 8: return Op_VecD; 2176 case 16: return Op_VecX; 2177 } 2178 ShouldNotReachHere(); 2179 return 0; 2180 } 2181 2182 // AES support not yet implemented 2183 const bool Matcher::pass_original_key_for_aes() { 2184 return false; 2185 } 2186 2187 // aarch64 supports misaligned vectors store/load. 2188 const bool Matcher::misaligned_vectors_ok() { 2189 return true; 2190 } 2191 2192 // false => size gets scaled to BytesPerLong, ok. 2193 const bool Matcher::init_array_count_is_in_bytes = false; 2194 2195 // Use conditional move (CMOVL) 2196 const int Matcher::long_cmove_cost() { 2197 // long cmoves are no more expensive than int cmoves 2198 return 0; 2199 } 2200 2201 const int Matcher::float_cmove_cost() { 2202 // float cmoves are no more expensive than int cmoves 2203 return 0; 2204 } 2205 2206 // Does the CPU require late expand (see block.cpp for description of late expand)? 2207 const bool Matcher::require_postalloc_expand = false; 2208 2209 // Do we need to mask the count passed to shift instructions or does 2210 // the cpu only look at the lower 5/6 bits anyway? 2211 const bool Matcher::need_masked_shift_count = false; 2212 2213 // No support for generic vector operands. 2214 const bool Matcher::supports_generic_vector_operands = false; 2215 2216 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2217 ShouldNotReachHere(); // generic vector operands not supported 2218 return NULL; 2219 } 2220 2221 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2222 ShouldNotReachHere(); // generic vector operands not supported 2223 return false; 2224 } 2225 2226 bool Matcher::is_generic_vector(MachOper* opnd) { 2227 ShouldNotReachHere(); // generic vector operands not supported 2228 return false; 2229 } 2230 2231 // This affects two different things: 2232 // - how Decode nodes are matched 2233 // - how ImplicitNullCheck opportunities are recognized 2234 // If true, the matcher will try to remove all Decodes and match them 2235 // (as operands) into nodes. NullChecks are not prepared to deal with 2236 // Decodes by final_graph_reshaping(). 2237 // If false, final_graph_reshaping() forces the decode behind the Cmp 2238 // for a NullCheck. The matcher matches the Decode node into a register. 2239 // Implicit_null_check optimization moves the Decode along with the 2240 // memory operation back up before the NullCheck. 2241 bool Matcher::narrow_oop_use_complex_address() { 2242 return CompressedOops::shift() == 0; 2243 } 2244 2245 bool Matcher::narrow_klass_use_complex_address() { 2246 // TODO 2247 // decide whether we need to set this to true 2248 return false; 2249 } 2250 2251 bool Matcher::const_oop_prefer_decode() { 2252 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2253 return CompressedOops::base() == NULL; 2254 } 2255 2256 bool Matcher::const_klass_prefer_decode() { 2257 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2258 return CompressedKlassPointers::base() == NULL; 2259 } 2260 2261 // Is it better to copy float constants, or load them directly from 2262 // memory? Intel can load a float constant from a direct address, 2263 // requiring no extra registers. Most RISCs will have to materialize 2264 // an address into a register first, so they would do better to copy 2265 // the constant from stack. 2266 const bool Matcher::rematerialize_float_constants = false; 2267 2268 // If CPU can load and store mis-aligned doubles directly then no 2269 // fixup is needed. Else we split the double into 2 integer pieces 2270 // and move it piece-by-piece. Only happens when passing doubles into 2271 // C code as the Java calling convention forces doubles to be aligned. 2272 const bool Matcher::misaligned_doubles_ok = true; 2273 2274 // No-op on amd64 2275 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2276 Unimplemented(); 2277 } 2278 2279 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2280 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2281 2282 // Are floats converted to double when stored to stack during 2283 // deoptimization? 2284 bool Matcher::float_in_double() { return false; } 2285 2286 // Do ints take an entire long register or just half? 2287 // The relevant question is how the int is callee-saved: 2288 // the whole long is written but de-opt'ing will have to extract 2289 // the relevant 32 bits. 2290 const bool Matcher::int_in_long = true; 2291 2292 // Return whether or not this register is ever used as an argument. 2293 // This function is used on startup to build the trampoline stubs in 2294 // generateOptoStub. Registers not mentioned will be killed by the VM 2295 // call in the trampoline, and arguments in those registers not be 2296 // available to the callee. 2297 bool Matcher::can_be_java_arg(int reg) 2298 { 2299 return 2300 reg == R0_num || reg == R0_H_num || 2301 reg == R1_num || reg == R1_H_num || 2302 reg == R2_num || reg == R2_H_num || 2303 reg == R3_num || reg == R3_H_num || 2304 reg == R4_num || reg == R4_H_num || 2305 reg == R5_num || reg == R5_H_num || 2306 reg == R6_num || reg == R6_H_num || 2307 reg == R7_num || reg == R7_H_num || 2308 reg == V0_num || reg == V0_H_num || 2309 reg == V1_num || reg == V1_H_num || 2310 reg == V2_num || reg == V2_H_num || 2311 reg == V3_num || reg == V3_H_num || 2312 reg == V4_num || reg == V4_H_num || 2313 reg == V5_num || reg == V5_H_num || 2314 reg == V6_num || reg == V6_H_num || 2315 reg == V7_num || reg == V7_H_num; 2316 } 2317 2318 bool Matcher::is_spillable_arg(int reg) 2319 { 2320 return can_be_java_arg(reg); 2321 } 2322 2323 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2324 return false; 2325 } 2326 2327 RegMask Matcher::divI_proj_mask() { 2328 ShouldNotReachHere(); 2329 return RegMask(); 2330 } 2331 2332 // Register for MODI projection of divmodI. 2333 RegMask Matcher::modI_proj_mask() { 2334 ShouldNotReachHere(); 2335 return RegMask(); 2336 } 2337 2338 // Register for DIVL projection of divmodL. 2339 RegMask Matcher::divL_proj_mask() { 2340 ShouldNotReachHere(); 2341 return RegMask(); 2342 } 2343 2344 // Register for MODL projection of divmodL. 2345 RegMask Matcher::modL_proj_mask() { 2346 ShouldNotReachHere(); 2347 return RegMask(); 2348 } 2349 2350 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2351 return FP_REG_mask(); 2352 } 2353 2354 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2355 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2356 Node* u = addp->fast_out(i); 2357 if (u->is_Mem()) { 2358 int opsize = u->as_Mem()->memory_size(); 2359 assert(opsize > 0, "unexpected memory operand size"); 2360 if (u->as_Mem()->memory_size() != (1<<shift)) { 2361 return false; 2362 } 2363 } 2364 } 2365 return true; 2366 } 2367 2368 const bool Matcher::convi2l_type_required = false; 2369 2370 // Should the matcher clone input 'm' of node 'n'? 2371 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2372 if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) 2373 mstack.push(m, Visit); // m = ShiftCntV 2374 return true; 2375 } 2376 return false; 2377 } 2378 2379 // Should the Matcher clone shifts on addressing modes, expecting them 2380 // to be subsumed into complex addressing expressions or compute them 2381 // into registers? 2382 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2383 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2384 return true; 2385 } 2386 2387 Node *off = m->in(AddPNode::Offset); 2388 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2389 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2390 // Are there other uses besides address expressions? 2391 !is_visited(off)) { 2392 address_visited.set(off->_idx); // Flag as address_visited 2393 mstack.push(off->in(2), Visit); 2394 Node *conv = off->in(1); 2395 if (conv->Opcode() == Op_ConvI2L && 2396 // Are there other uses besides address expressions? 2397 !is_visited(conv)) { 2398 address_visited.set(conv->_idx); // Flag as address_visited 2399 mstack.push(conv->in(1), Pre_Visit); 2400 } else { 2401 mstack.push(conv, Pre_Visit); 2402 } 2403 address_visited.test_set(m->_idx); // Flag as address_visited 2404 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2405 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2406 return true; 2407 } else if (off->Opcode() == Op_ConvI2L && 2408 // Are there other uses besides address expressions? 2409 !is_visited(off)) { 2410 address_visited.test_set(m->_idx); // Flag as address_visited 2411 address_visited.set(off->_idx); // Flag as address_visited 2412 mstack.push(off->in(1), Pre_Visit); 2413 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2414 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2415 return true; 2416 } 2417 return false; 2418 } 2419 2420 void Compile::reshape_address(AddPNode* addp) { 2421 } 2422 2423 2424 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2425 C2_MacroAssembler _masm(&cbuf); \ 2426 { \ 2427 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2428 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2429 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2430 __ INSN(REG, as_Register(BASE)); \ 2431 } 2432 2433 2434 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2435 { 2436 Address::extend scale; 2437 2438 // Hooboy, this is fugly. We need a way to communicate to the 2439 // encoder that the index needs to be sign extended, so we have to 2440 // enumerate all the cases. 2441 switch (opcode) { 2442 case INDINDEXSCALEDI2L: 2443 case INDINDEXSCALEDI2LN: 2444 case INDINDEXI2L: 2445 case INDINDEXI2LN: 2446 scale = Address::sxtw(size); 2447 break; 2448 default: 2449 scale = Address::lsl(size); 2450 } 2451 2452 if (index == -1) { 2453 return Address(base, disp); 2454 } else { 2455 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2456 return Address(base, as_Register(index), scale); 2457 } 2458 } 2459 2460 2461 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2462 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2463 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2464 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2465 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2466 2467 // Used for all non-volatile memory accesses. The use of 2468 // $mem->opcode() to discover whether this pattern uses sign-extended 2469 // offsets is something of a kludge. 2470 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2471 Register reg, int opcode, 2472 Register base, int index, int scale, int disp, 2473 int size_in_memory) 2474 { 2475 Address addr = mem2address(opcode, base, index, scale, disp); 2476 if (addr.getMode() == Address::base_plus_offset) { 2477 /* If we get an out-of-range offset it is a bug in the compiler, 2478 so we assert here. */ 2479 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2480 "c2 compiler bug"); 2481 /* Fix up any out-of-range offsets. */ 2482 assert_different_registers(rscratch1, base); 2483 assert_different_registers(rscratch1, reg); 2484 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2485 } 2486 (masm.*insn)(reg, addr); 2487 } 2488 2489 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2490 FloatRegister reg, int opcode, 2491 Register base, int index, int size, int disp, 2492 int size_in_memory) 2493 { 2494 Address::extend scale; 2495 2496 switch (opcode) { 2497 case INDINDEXSCALEDI2L: 2498 case INDINDEXSCALEDI2LN: 2499 scale = Address::sxtw(size); 2500 break; 2501 default: 2502 scale = Address::lsl(size); 2503 } 2504 2505 if (index == -1) { 2506 /* If we get an out-of-range offset it is a bug in the compiler, 2507 so we assert here. */ 2508 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2509 /* Fix up any out-of-range offsets. */ 2510 assert_different_registers(rscratch1, base); 2511 Address addr = Address(base, disp); 2512 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2513 (masm.*insn)(reg, addr); 2514 } else { 2515 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2516 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2517 } 2518 } 2519 2520 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2521 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2522 int opcode, Register base, int index, int size, int disp) 2523 { 2524 if (index == -1) { 2525 (masm.*insn)(reg, T, Address(base, disp)); 2526 } else { 2527 assert(disp == 0, "unsupported address mode"); 2528 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2529 } 2530 } 2531 2532 %} 2533 2534 2535 2536 //----------ENCODING BLOCK----------------------------------------------------- 2537 // This block specifies the encoding classes used by the compiler to 2538 // output byte streams. Encoding classes are parameterized macros 2539 // used by Machine Instruction Nodes in order to generate the bit 2540 // encoding of the instruction. Operands specify their base encoding 2541 // interface with the interface keyword. There are currently 2542 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2543 // COND_INTER. REG_INTER causes an operand to generate a function 2544 // which returns its register number when queried. CONST_INTER causes 2545 // an operand to generate a function which returns the value of the 2546 // constant when queried. MEMORY_INTER causes an operand to generate 2547 // four functions which return the Base Register, the Index Register, 2548 // the Scale Value, and the Offset Value of the operand when queried. 2549 // COND_INTER causes an operand to generate six functions which return 2550 // the encoding code (ie - encoding bits for the instruction) 2551 // associated with each basic boolean condition for a conditional 2552 // instruction. 2553 // 2554 // Instructions specify two basic values for encoding. Again, a 2555 // function is available to check if the constant displacement is an 2556 // oop. They use the ins_encode keyword to specify their encoding 2557 // classes (which must be a sequence of enc_class names, and their 2558 // parameters, specified in the encoding block), and they use the 2559 // opcode keyword to specify, in order, their primary, secondary, and 2560 // tertiary opcode. Only the opcode sections which a particular 2561 // instruction needs for encoding need to be specified. 2562 encode %{ 2563 // Build emit functions for each basic byte or larger field in the 2564 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2565 // from C++ code in the enc_class source block. Emit functions will 2566 // live in the main source block for now. In future, we can 2567 // generalize this by adding a syntax that specifies the sizes of 2568 // fields in an order, so that the adlc can build the emit functions 2569 // automagically 2570 2571 // catch all for unimplemented encodings 2572 enc_class enc_unimplemented %{ 2573 C2_MacroAssembler _masm(&cbuf); 2574 __ unimplemented("C2 catch all"); 2575 %} 2576 2577 // BEGIN Non-volatile memory access 2578 2579 // This encoding class is generated automatically from ad_encode.m4. 2580 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2581 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2582 Register dst_reg = as_Register($dst$$reg); 2583 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2584 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2585 %} 2586 2587 // This encoding class is generated automatically from ad_encode.m4. 2588 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2589 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2590 Register dst_reg = as_Register($dst$$reg); 2591 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2592 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2593 %} 2594 2595 // This encoding class is generated automatically from ad_encode.m4. 2596 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2597 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2598 Register dst_reg = as_Register($dst$$reg); 2599 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2600 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2601 %} 2602 2603 // This encoding class is generated automatically from ad_encode.m4. 2604 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2605 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2606 Register dst_reg = as_Register($dst$$reg); 2607 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2608 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2609 %} 2610 2611 // This encoding class is generated automatically from ad_encode.m4. 2612 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2613 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2614 Register dst_reg = as_Register($dst$$reg); 2615 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2616 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2617 %} 2618 2619 // This encoding class is generated automatically from ad_encode.m4. 2620 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2621 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2622 Register dst_reg = as_Register($dst$$reg); 2623 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2624 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2625 %} 2626 2627 // This encoding class is generated automatically from ad_encode.m4. 2628 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2629 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2630 Register dst_reg = as_Register($dst$$reg); 2631 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2632 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2633 %} 2634 2635 // This encoding class is generated automatically from ad_encode.m4. 2636 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2637 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2638 Register dst_reg = as_Register($dst$$reg); 2639 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2640 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2641 %} 2642 2643 // This encoding class is generated automatically from ad_encode.m4. 2644 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2645 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2646 Register dst_reg = as_Register($dst$$reg); 2647 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2648 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2649 %} 2650 2651 // This encoding class is generated automatically from ad_encode.m4. 2652 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2653 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2654 Register dst_reg = as_Register($dst$$reg); 2655 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2656 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2657 %} 2658 2659 // This encoding class is generated automatically from ad_encode.m4. 2660 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2661 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2662 Register dst_reg = as_Register($dst$$reg); 2663 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2664 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2665 %} 2666 2667 // This encoding class is generated automatically from ad_encode.m4. 2668 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2669 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2670 Register dst_reg = as_Register($dst$$reg); 2671 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2672 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2673 %} 2674 2675 // This encoding class is generated automatically from ad_encode.m4. 2676 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2677 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2678 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2679 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2680 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2681 %} 2682 2683 // This encoding class is generated automatically from ad_encode.m4. 2684 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2685 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2686 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2687 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2688 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2689 %} 2690 2691 // This encoding class is generated automatically from ad_encode.m4. 2692 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2693 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2694 Register src_reg = as_Register($src$$reg); 2695 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2696 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2697 %} 2698 2699 // This encoding class is generated automatically from ad_encode.m4. 2700 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2701 enc_class aarch64_enc_strb0(memory1 mem) %{ 2702 C2_MacroAssembler _masm(&cbuf); 2703 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2704 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2705 %} 2706 2707 // This encoding class is generated automatically from ad_encode.m4. 2708 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2709 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2710 Register src_reg = as_Register($src$$reg); 2711 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2712 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2713 %} 2714 2715 // This encoding class is generated automatically from ad_encode.m4. 2716 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2717 enc_class aarch64_enc_strh0(memory2 mem) %{ 2718 C2_MacroAssembler _masm(&cbuf); 2719 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2720 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2721 %} 2722 2723 // This encoding class is generated automatically from ad_encode.m4. 2724 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2725 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2726 Register src_reg = as_Register($src$$reg); 2727 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2728 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2729 %} 2730 2731 // This encoding class is generated automatically from ad_encode.m4. 2732 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2733 enc_class aarch64_enc_strw0(memory4 mem) %{ 2734 C2_MacroAssembler _masm(&cbuf); 2735 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2736 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2737 %} 2738 2739 // This encoding class is generated automatically from ad_encode.m4. 2740 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2741 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2742 Register src_reg = as_Register($src$$reg); 2743 // we sometimes get asked to store the stack pointer into the 2744 // current thread -- we cannot do that directly on AArch64 2745 if (src_reg == r31_sp) { 2746 C2_MacroAssembler _masm(&cbuf); 2747 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2748 __ mov(rscratch2, sp); 2749 src_reg = rscratch2; 2750 } 2751 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2752 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2753 %} 2754 2755 // This encoding class is generated automatically from ad_encode.m4. 2756 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2757 enc_class aarch64_enc_str0(memory8 mem) %{ 2758 C2_MacroAssembler _masm(&cbuf); 2759 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2760 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2761 %} 2762 2763 // This encoding class is generated automatically from ad_encode.m4. 2764 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2765 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 2766 FloatRegister src_reg = as_FloatRegister($src$$reg); 2767 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2768 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2769 %} 2770 2771 // This encoding class is generated automatically from ad_encode.m4. 2772 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2773 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 2774 FloatRegister src_reg = as_FloatRegister($src$$reg); 2775 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2776 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2777 %} 2778 2779 // This encoding class is generated automatically from ad_encode.m4. 2780 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2781 enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{ 2782 C2_MacroAssembler _masm(&cbuf); 2783 address con = (address)$src$$constant; 2784 // need to do this the hard way until we can manage relocs 2785 // for 32 bit constants 2786 __ movoop(rscratch2, (jobject)con); 2787 if (con) __ encode_heap_oop_not_null(rscratch2); 2788 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2789 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2790 %} 2791 2792 // This encoding class is generated automatically from ad_encode.m4. 2793 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2794 enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{ 2795 C2_MacroAssembler _masm(&cbuf); 2796 address con = (address)$src$$constant; 2797 // need to do this the hard way until we can manage relocs 2798 // for 32 bit constants 2799 __ movoop(rscratch2, (jobject)con); 2800 __ encode_klass_not_null(rscratch2); 2801 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2802 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2803 %} 2804 2805 // This encoding class is generated automatically from ad_encode.m4. 2806 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2807 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 2808 C2_MacroAssembler _masm(&cbuf); 2809 __ membar(Assembler::StoreStore); 2810 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2811 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2812 %} 2813 2814 // END Non-volatile memory access 2815 2816 // Vector loads and stores 2817 enc_class aarch64_enc_ldrvH(vecD dst, memory mem) %{ 2818 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2819 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 2820 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2821 %} 2822 2823 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2824 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2825 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2826 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2827 %} 2828 2829 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2830 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2831 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2832 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2833 %} 2834 2835 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2836 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2837 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2838 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2839 %} 2840 2841 enc_class aarch64_enc_strvH(vecD src, memory mem) %{ 2842 FloatRegister src_reg = as_FloatRegister($src$$reg); 2843 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H, 2844 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2845 %} 2846 2847 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2848 FloatRegister src_reg = as_FloatRegister($src$$reg); 2849 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2850 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2851 %} 2852 2853 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2854 FloatRegister src_reg = as_FloatRegister($src$$reg); 2855 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2856 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2857 %} 2858 2859 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2860 FloatRegister src_reg = as_FloatRegister($src$$reg); 2861 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2862 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2863 %} 2864 2865 // volatile loads and stores 2866 2867 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2868 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2869 rscratch1, stlrb); 2870 %} 2871 2872 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2873 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2874 rscratch1, stlrh); 2875 %} 2876 2877 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2878 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2879 rscratch1, stlrw); 2880 %} 2881 2882 2883 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2884 Register dst_reg = as_Register($dst$$reg); 2885 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2886 rscratch1, ldarb); 2887 __ sxtbw(dst_reg, dst_reg); 2888 %} 2889 2890 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2891 Register dst_reg = as_Register($dst$$reg); 2892 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2893 rscratch1, ldarb); 2894 __ sxtb(dst_reg, dst_reg); 2895 %} 2896 2897 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2898 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2899 rscratch1, ldarb); 2900 %} 2901 2902 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2903 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2904 rscratch1, ldarb); 2905 %} 2906 2907 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2908 Register dst_reg = as_Register($dst$$reg); 2909 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2910 rscratch1, ldarh); 2911 __ sxthw(dst_reg, dst_reg); 2912 %} 2913 2914 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2915 Register dst_reg = as_Register($dst$$reg); 2916 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2917 rscratch1, ldarh); 2918 __ sxth(dst_reg, dst_reg); 2919 %} 2920 2921 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2922 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2923 rscratch1, ldarh); 2924 %} 2925 2926 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2927 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2928 rscratch1, ldarh); 2929 %} 2930 2931 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2932 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2933 rscratch1, ldarw); 2934 %} 2935 2936 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2937 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2938 rscratch1, ldarw); 2939 %} 2940 2941 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2942 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2943 rscratch1, ldar); 2944 %} 2945 2946 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2947 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2948 rscratch1, ldarw); 2949 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2950 %} 2951 2952 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2953 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2954 rscratch1, ldar); 2955 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2956 %} 2957 2958 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2959 Register src_reg = as_Register($src$$reg); 2960 // we sometimes get asked to store the stack pointer into the 2961 // current thread -- we cannot do that directly on AArch64 2962 if (src_reg == r31_sp) { 2963 C2_MacroAssembler _masm(&cbuf); 2964 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2965 __ mov(rscratch2, sp); 2966 src_reg = rscratch2; 2967 } 2968 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2969 rscratch1, stlr); 2970 %} 2971 2972 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2973 { 2974 C2_MacroAssembler _masm(&cbuf); 2975 FloatRegister src_reg = as_FloatRegister($src$$reg); 2976 __ fmovs(rscratch2, src_reg); 2977 } 2978 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2979 rscratch1, stlrw); 2980 %} 2981 2982 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2983 { 2984 C2_MacroAssembler _masm(&cbuf); 2985 FloatRegister src_reg = as_FloatRegister($src$$reg); 2986 __ fmovd(rscratch2, src_reg); 2987 } 2988 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2989 rscratch1, stlr); 2990 %} 2991 2992 // synchronized read/update encodings 2993 2994 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 2995 C2_MacroAssembler _masm(&cbuf); 2996 Register dst_reg = as_Register($dst$$reg); 2997 Register base = as_Register($mem$$base); 2998 int index = $mem$$index; 2999 int scale = $mem$$scale; 3000 int disp = $mem$$disp; 3001 if (index == -1) { 3002 if (disp != 0) { 3003 __ lea(rscratch1, Address(base, disp)); 3004 __ ldaxr(dst_reg, rscratch1); 3005 } else { 3006 // TODO 3007 // should we ever get anything other than this case? 3008 __ ldaxr(dst_reg, base); 3009 } 3010 } else { 3011 Register index_reg = as_Register(index); 3012 if (disp == 0) { 3013 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3014 __ ldaxr(dst_reg, rscratch1); 3015 } else { 3016 __ lea(rscratch1, Address(base, disp)); 3017 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3018 __ ldaxr(dst_reg, rscratch1); 3019 } 3020 } 3021 %} 3022 3023 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3024 C2_MacroAssembler _masm(&cbuf); 3025 Register src_reg = as_Register($src$$reg); 3026 Register base = as_Register($mem$$base); 3027 int index = $mem$$index; 3028 int scale = $mem$$scale; 3029 int disp = $mem$$disp; 3030 if (index == -1) { 3031 if (disp != 0) { 3032 __ lea(rscratch2, Address(base, disp)); 3033 __ stlxr(rscratch1, src_reg, rscratch2); 3034 } else { 3035 // TODO 3036 // should we ever get anything other than this case? 3037 __ stlxr(rscratch1, src_reg, base); 3038 } 3039 } else { 3040 Register index_reg = as_Register(index); 3041 if (disp == 0) { 3042 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3043 __ stlxr(rscratch1, src_reg, rscratch2); 3044 } else { 3045 __ lea(rscratch2, Address(base, disp)); 3046 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3047 __ stlxr(rscratch1, src_reg, rscratch2); 3048 } 3049 } 3050 __ cmpw(rscratch1, zr); 3051 %} 3052 3053 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3054 C2_MacroAssembler _masm(&cbuf); 3055 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3056 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3057 Assembler::xword, /*acquire*/ false, /*release*/ true, 3058 /*weak*/ false, noreg); 3059 %} 3060 3061 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3062 C2_MacroAssembler _masm(&cbuf); 3063 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3064 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3065 Assembler::word, /*acquire*/ false, /*release*/ true, 3066 /*weak*/ false, noreg); 3067 %} 3068 3069 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp 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::halfword, /*acquire*/ false, /*release*/ true, 3074 /*weak*/ false, noreg); 3075 %} 3076 3077 enc_class aarch64_enc_cmpxchgb(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::byte, /*acquire*/ false, /*release*/ true, 3082 /*weak*/ false, noreg); 3083 %} 3084 3085 3086 // The only difference between aarch64_enc_cmpxchg and 3087 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3088 // CompareAndSwap sequence to serve as a barrier on acquiring a 3089 // lock. 3090 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3091 C2_MacroAssembler _masm(&cbuf); 3092 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3093 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3094 Assembler::xword, /*acquire*/ true, /*release*/ true, 3095 /*weak*/ false, noreg); 3096 %} 3097 3098 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3099 C2_MacroAssembler _masm(&cbuf); 3100 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3101 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3102 Assembler::word, /*acquire*/ true, /*release*/ true, 3103 /*weak*/ false, noreg); 3104 %} 3105 3106 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3107 C2_MacroAssembler _masm(&cbuf); 3108 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3109 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3110 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3111 /*weak*/ false, noreg); 3112 %} 3113 3114 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3115 C2_MacroAssembler _masm(&cbuf); 3116 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3117 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3118 Assembler::byte, /*acquire*/ true, /*release*/ true, 3119 /*weak*/ false, noreg); 3120 %} 3121 3122 // auxiliary used for CompareAndSwapX to set result register 3123 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3124 C2_MacroAssembler _masm(&cbuf); 3125 Register res_reg = as_Register($res$$reg); 3126 __ cset(res_reg, Assembler::EQ); 3127 %} 3128 3129 // prefetch encodings 3130 3131 enc_class aarch64_enc_prefetchw(memory mem) %{ 3132 C2_MacroAssembler _masm(&cbuf); 3133 Register base = as_Register($mem$$base); 3134 int index = $mem$$index; 3135 int scale = $mem$$scale; 3136 int disp = $mem$$disp; 3137 if (index == -1) { 3138 __ prfm(Address(base, disp), PSTL1KEEP); 3139 } else { 3140 Register index_reg = as_Register(index); 3141 if (disp == 0) { 3142 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3143 } else { 3144 __ lea(rscratch1, Address(base, disp)); 3145 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3146 } 3147 } 3148 %} 3149 3150 /// mov envcodings 3151 3152 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3153 C2_MacroAssembler _masm(&cbuf); 3154 u_int32_t con = (u_int32_t)$src$$constant; 3155 Register dst_reg = as_Register($dst$$reg); 3156 if (con == 0) { 3157 __ movw(dst_reg, zr); 3158 } else { 3159 __ movw(dst_reg, con); 3160 } 3161 %} 3162 3163 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3164 C2_MacroAssembler _masm(&cbuf); 3165 Register dst_reg = as_Register($dst$$reg); 3166 u_int64_t con = (u_int64_t)$src$$constant; 3167 if (con == 0) { 3168 __ mov(dst_reg, zr); 3169 } else { 3170 __ mov(dst_reg, con); 3171 } 3172 %} 3173 3174 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3175 C2_MacroAssembler _masm(&cbuf); 3176 Register dst_reg = as_Register($dst$$reg); 3177 address con = (address)$src$$constant; 3178 if (con == NULL || con == (address)1) { 3179 ShouldNotReachHere(); 3180 } else { 3181 relocInfo::relocType rtype = $src->constant_reloc(); 3182 if (rtype == relocInfo::oop_type) { 3183 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3184 } else if (rtype == relocInfo::metadata_type) { 3185 __ mov_metadata(dst_reg, (Metadata*)con); 3186 } else { 3187 assert(rtype == relocInfo::none, "unexpected reloc type"); 3188 if (con < (address)(uintptr_t)os::vm_page_size()) { 3189 __ mov(dst_reg, con); 3190 } else { 3191 unsigned long offset; 3192 __ adrp(dst_reg, con, offset); 3193 __ add(dst_reg, dst_reg, offset); 3194 } 3195 } 3196 } 3197 %} 3198 3199 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3200 C2_MacroAssembler _masm(&cbuf); 3201 Register dst_reg = as_Register($dst$$reg); 3202 __ mov(dst_reg, zr); 3203 %} 3204 3205 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3206 C2_MacroAssembler _masm(&cbuf); 3207 Register dst_reg = as_Register($dst$$reg); 3208 __ mov(dst_reg, (u_int64_t)1); 3209 %} 3210 3211 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3212 C2_MacroAssembler _masm(&cbuf); 3213 __ load_byte_map_base($dst$$Register); 3214 %} 3215 3216 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3217 C2_MacroAssembler _masm(&cbuf); 3218 Register dst_reg = as_Register($dst$$reg); 3219 address con = (address)$src$$constant; 3220 if (con == NULL) { 3221 ShouldNotReachHere(); 3222 } else { 3223 relocInfo::relocType rtype = $src->constant_reloc(); 3224 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3225 __ set_narrow_oop(dst_reg, (jobject)con); 3226 } 3227 %} 3228 3229 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3230 C2_MacroAssembler _masm(&cbuf); 3231 Register dst_reg = as_Register($dst$$reg); 3232 __ mov(dst_reg, zr); 3233 %} 3234 3235 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3236 C2_MacroAssembler _masm(&cbuf); 3237 Register dst_reg = as_Register($dst$$reg); 3238 address con = (address)$src$$constant; 3239 if (con == NULL) { 3240 ShouldNotReachHere(); 3241 } else { 3242 relocInfo::relocType rtype = $src->constant_reloc(); 3243 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3244 __ set_narrow_klass(dst_reg, (Klass *)con); 3245 } 3246 %} 3247 3248 // arithmetic encodings 3249 3250 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3251 C2_MacroAssembler _masm(&cbuf); 3252 Register dst_reg = as_Register($dst$$reg); 3253 Register src_reg = as_Register($src1$$reg); 3254 int32_t con = (int32_t)$src2$$constant; 3255 // add has primary == 0, subtract has primary == 1 3256 if ($primary) { con = -con; } 3257 if (con < 0) { 3258 __ subw(dst_reg, src_reg, -con); 3259 } else { 3260 __ addw(dst_reg, src_reg, con); 3261 } 3262 %} 3263 3264 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3265 C2_MacroAssembler _masm(&cbuf); 3266 Register dst_reg = as_Register($dst$$reg); 3267 Register src_reg = as_Register($src1$$reg); 3268 int32_t con = (int32_t)$src2$$constant; 3269 // add has primary == 0, subtract has primary == 1 3270 if ($primary) { con = -con; } 3271 if (con < 0) { 3272 __ sub(dst_reg, src_reg, -con); 3273 } else { 3274 __ add(dst_reg, src_reg, con); 3275 } 3276 %} 3277 3278 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3279 C2_MacroAssembler _masm(&cbuf); 3280 Register dst_reg = as_Register($dst$$reg); 3281 Register src1_reg = as_Register($src1$$reg); 3282 Register src2_reg = as_Register($src2$$reg); 3283 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3284 %} 3285 3286 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3287 C2_MacroAssembler _masm(&cbuf); 3288 Register dst_reg = as_Register($dst$$reg); 3289 Register src1_reg = as_Register($src1$$reg); 3290 Register src2_reg = as_Register($src2$$reg); 3291 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3292 %} 3293 3294 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3295 C2_MacroAssembler _masm(&cbuf); 3296 Register dst_reg = as_Register($dst$$reg); 3297 Register src1_reg = as_Register($src1$$reg); 3298 Register src2_reg = as_Register($src2$$reg); 3299 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3300 %} 3301 3302 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3303 C2_MacroAssembler _masm(&cbuf); 3304 Register dst_reg = as_Register($dst$$reg); 3305 Register src1_reg = as_Register($src1$$reg); 3306 Register src2_reg = as_Register($src2$$reg); 3307 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3308 %} 3309 3310 // compare instruction encodings 3311 3312 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3313 C2_MacroAssembler _masm(&cbuf); 3314 Register reg1 = as_Register($src1$$reg); 3315 Register reg2 = as_Register($src2$$reg); 3316 __ cmpw(reg1, reg2); 3317 %} 3318 3319 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3320 C2_MacroAssembler _masm(&cbuf); 3321 Register reg = as_Register($src1$$reg); 3322 int32_t val = $src2$$constant; 3323 if (val >= 0) { 3324 __ subsw(zr, reg, val); 3325 } else { 3326 __ addsw(zr, reg, -val); 3327 } 3328 %} 3329 3330 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3331 C2_MacroAssembler _masm(&cbuf); 3332 Register reg1 = as_Register($src1$$reg); 3333 u_int32_t val = (u_int32_t)$src2$$constant; 3334 __ movw(rscratch1, val); 3335 __ cmpw(reg1, rscratch1); 3336 %} 3337 3338 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3339 C2_MacroAssembler _masm(&cbuf); 3340 Register reg1 = as_Register($src1$$reg); 3341 Register reg2 = as_Register($src2$$reg); 3342 __ cmp(reg1, reg2); 3343 %} 3344 3345 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3346 C2_MacroAssembler _masm(&cbuf); 3347 Register reg = as_Register($src1$$reg); 3348 int64_t val = $src2$$constant; 3349 if (val >= 0) { 3350 __ subs(zr, reg, val); 3351 } else if (val != -val) { 3352 __ adds(zr, reg, -val); 3353 } else { 3354 // aargh, Long.MIN_VALUE is a special case 3355 __ orr(rscratch1, zr, (u_int64_t)val); 3356 __ subs(zr, reg, rscratch1); 3357 } 3358 %} 3359 3360 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3361 C2_MacroAssembler _masm(&cbuf); 3362 Register reg1 = as_Register($src1$$reg); 3363 u_int64_t val = (u_int64_t)$src2$$constant; 3364 __ mov(rscratch1, val); 3365 __ cmp(reg1, rscratch1); 3366 %} 3367 3368 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3369 C2_MacroAssembler _masm(&cbuf); 3370 Register reg1 = as_Register($src1$$reg); 3371 Register reg2 = as_Register($src2$$reg); 3372 __ cmp(reg1, reg2); 3373 %} 3374 3375 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3376 C2_MacroAssembler _masm(&cbuf); 3377 Register reg1 = as_Register($src1$$reg); 3378 Register reg2 = as_Register($src2$$reg); 3379 __ cmpw(reg1, reg2); 3380 %} 3381 3382 enc_class aarch64_enc_testp(iRegP src) %{ 3383 C2_MacroAssembler _masm(&cbuf); 3384 Register reg = as_Register($src$$reg); 3385 __ cmp(reg, zr); 3386 %} 3387 3388 enc_class aarch64_enc_testn(iRegN src) %{ 3389 C2_MacroAssembler _masm(&cbuf); 3390 Register reg = as_Register($src$$reg); 3391 __ cmpw(reg, zr); 3392 %} 3393 3394 enc_class aarch64_enc_b(label lbl) %{ 3395 C2_MacroAssembler _masm(&cbuf); 3396 Label *L = $lbl$$label; 3397 __ b(*L); 3398 %} 3399 3400 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3401 C2_MacroAssembler _masm(&cbuf); 3402 Label *L = $lbl$$label; 3403 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3404 %} 3405 3406 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3407 C2_MacroAssembler _masm(&cbuf); 3408 Label *L = $lbl$$label; 3409 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3410 %} 3411 3412 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3413 %{ 3414 Register sub_reg = as_Register($sub$$reg); 3415 Register super_reg = as_Register($super$$reg); 3416 Register temp_reg = as_Register($temp$$reg); 3417 Register result_reg = as_Register($result$$reg); 3418 3419 Label miss; 3420 C2_MacroAssembler _masm(&cbuf); 3421 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3422 NULL, &miss, 3423 /*set_cond_codes:*/ true); 3424 if ($primary) { 3425 __ mov(result_reg, zr); 3426 } 3427 __ bind(miss); 3428 %} 3429 3430 enc_class aarch64_enc_java_static_call(method meth) %{ 3431 C2_MacroAssembler _masm(&cbuf); 3432 3433 address addr = (address)$meth$$method; 3434 address call; 3435 if (!_method) { 3436 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3437 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3438 } else { 3439 int method_index = resolved_method_index(cbuf); 3440 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3441 : static_call_Relocation::spec(method_index); 3442 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3443 3444 // Emit stub for static call 3445 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3446 if (stub == NULL) { 3447 ciEnv::current()->record_failure("CodeCache is full"); 3448 return; 3449 } 3450 } 3451 if (call == NULL) { 3452 ciEnv::current()->record_failure("CodeCache is full"); 3453 return; 3454 } 3455 %} 3456 3457 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3458 C2_MacroAssembler _masm(&cbuf); 3459 int method_index = resolved_method_index(cbuf); 3460 address call = __ ic_call((address)$meth$$method, method_index); 3461 if (call == NULL) { 3462 ciEnv::current()->record_failure("CodeCache is full"); 3463 return; 3464 } 3465 %} 3466 3467 enc_class aarch64_enc_call_epilog() %{ 3468 C2_MacroAssembler _masm(&cbuf); 3469 if (VerifyStackAtCalls) { 3470 // Check that stack depth is unchanged: find majik cookie on stack 3471 __ call_Unimplemented(); 3472 } 3473 %} 3474 3475 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3476 C2_MacroAssembler _masm(&cbuf); 3477 3478 // some calls to generated routines (arraycopy code) are scheduled 3479 // by C2 as runtime calls. if so we can call them using a br (they 3480 // will be in a reachable segment) otherwise we have to use a blr 3481 // which loads the absolute address into a register. 3482 address entry = (address)$meth$$method; 3483 CodeBlob *cb = CodeCache::find_blob(entry); 3484 if (cb) { 3485 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3486 if (call == NULL) { 3487 ciEnv::current()->record_failure("CodeCache is full"); 3488 return; 3489 } 3490 } else { 3491 Label retaddr; 3492 __ adr(rscratch2, retaddr); 3493 __ lea(rscratch1, RuntimeAddress(entry)); 3494 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3495 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3496 __ blr(rscratch1); 3497 __ bind(retaddr); 3498 __ add(sp, sp, 2 * wordSize); 3499 } 3500 %} 3501 3502 enc_class aarch64_enc_rethrow() %{ 3503 C2_MacroAssembler _masm(&cbuf); 3504 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3505 %} 3506 3507 enc_class aarch64_enc_ret() %{ 3508 C2_MacroAssembler _masm(&cbuf); 3509 __ ret(lr); 3510 %} 3511 3512 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3513 C2_MacroAssembler _masm(&cbuf); 3514 Register target_reg = as_Register($jump_target$$reg); 3515 __ br(target_reg); 3516 %} 3517 3518 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3519 C2_MacroAssembler _masm(&cbuf); 3520 Register target_reg = as_Register($jump_target$$reg); 3521 // exception oop should be in r0 3522 // ret addr has been popped into lr 3523 // callee expects it in r3 3524 __ mov(r3, lr); 3525 __ br(target_reg); 3526 %} 3527 3528 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3529 C2_MacroAssembler _masm(&cbuf); 3530 Register oop = as_Register($object$$reg); 3531 Register box = as_Register($box$$reg); 3532 Register disp_hdr = as_Register($tmp$$reg); 3533 Register tmp = as_Register($tmp2$$reg); 3534 Label cont; 3535 Label object_has_monitor; 3536 Label cas_failed; 3537 3538 assert_different_registers(oop, box, tmp, disp_hdr); 3539 3540 // Load markWord from object into displaced_header. 3541 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3542 3543 if (UseBiasedLocking && !UseOptoBiasInlining) { 3544 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3545 } 3546 3547 // Check for existing monitor 3548 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3549 3550 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3551 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3552 3553 // Initialize the box. (Must happen before we update the object mark!) 3554 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3555 3556 // Compare object markWord with an unlocked value (tmp) and if 3557 // equal exchange the stack address of our box with object markWord. 3558 // On failure disp_hdr contains the possibly locked markWord. 3559 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3560 /*release*/ true, /*weak*/ false, disp_hdr); 3561 __ br(Assembler::EQ, cont); 3562 3563 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3564 3565 // If the compare-and-exchange succeeded, then we found an unlocked 3566 // object, will have now locked it will continue at label cont 3567 3568 __ bind(cas_failed); 3569 // We did not see an unlocked object so try the fast recursive case. 3570 3571 // Check if the owner is self by comparing the value in the 3572 // markWord of object (disp_hdr) with the stack pointer. 3573 __ mov(rscratch1, sp); 3574 __ sub(disp_hdr, disp_hdr, rscratch1); 3575 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3576 // If condition is true we are cont and hence we can store 0 as the 3577 // displaced header in the box, which indicates that it is a recursive lock. 3578 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3579 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3580 3581 __ b(cont); 3582 3583 // Handle existing monitor. 3584 __ bind(object_has_monitor); 3585 3586 // The object's monitor m is unlocked iff m->owner == NULL, 3587 // otherwise m->owner may contain a thread or a stack address. 3588 // 3589 // Try to CAS m->owner from NULL to current thread. 3590 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3591 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3592 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3593 3594 // Store a non-null value into the box to avoid looking like a re-entrant 3595 // lock. The fast-path monitor unlock code checks for 3596 // markWord::monitor_value so use markWord::unused_mark which has the 3597 // relevant bit set, and also matches ObjectSynchronizer::enter. 3598 __ mov(tmp, (address)markWord::unused_mark().value()); 3599 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3600 3601 __ bind(cont); 3602 // flag == EQ indicates success 3603 // flag == NE indicates failure 3604 %} 3605 3606 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3607 C2_MacroAssembler _masm(&cbuf); 3608 Register oop = as_Register($object$$reg); 3609 Register box = as_Register($box$$reg); 3610 Register disp_hdr = as_Register($tmp$$reg); 3611 Register tmp = as_Register($tmp2$$reg); 3612 Label cont; 3613 Label object_has_monitor; 3614 3615 assert_different_registers(oop, box, tmp, disp_hdr); 3616 3617 if (UseBiasedLocking && !UseOptoBiasInlining) { 3618 __ biased_locking_exit(oop, tmp, cont); 3619 } 3620 3621 // Find the lock address and load the displaced header from the stack. 3622 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3623 3624 // If the displaced header is 0, we have a recursive unlock. 3625 __ cmp(disp_hdr, zr); 3626 __ br(Assembler::EQ, cont); 3627 3628 // Handle existing monitor. 3629 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3630 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3631 3632 // Check if it is still a light weight lock, this is is true if we 3633 // see the stack address of the basicLock in the markWord of the 3634 // object. 3635 3636 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3637 /*release*/ true, /*weak*/ false, tmp); 3638 __ b(cont); 3639 3640 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3641 3642 // Handle existing monitor. 3643 __ bind(object_has_monitor); 3644 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3645 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3646 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3647 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3648 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3649 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3650 __ cmp(rscratch1, zr); // Sets flags for result 3651 __ br(Assembler::NE, cont); 3652 3653 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3654 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3655 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3656 __ cmp(rscratch1, zr); // Sets flags for result 3657 __ cbnz(rscratch1, cont); 3658 // need a release store here 3659 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3660 __ stlr(zr, tmp); // set unowned 3661 3662 __ bind(cont); 3663 // flag == EQ indicates success 3664 // flag == NE indicates failure 3665 %} 3666 3667 %} 3668 3669 //----------FRAME-------------------------------------------------------------- 3670 // Definition of frame structure and management information. 3671 // 3672 // S T A C K L A Y O U T Allocators stack-slot number 3673 // | (to get allocators register number 3674 // G Owned by | | v add OptoReg::stack0()) 3675 // r CALLER | | 3676 // o | +--------+ pad to even-align allocators stack-slot 3677 // w V | pad0 | numbers; owned by CALLER 3678 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3679 // h ^ | in | 5 3680 // | | args | 4 Holes in incoming args owned by SELF 3681 // | | | | 3 3682 // | | +--------+ 3683 // V | | old out| Empty on Intel, window on Sparc 3684 // | old |preserve| Must be even aligned. 3685 // | SP-+--------+----> Matcher::_old_SP, even aligned 3686 // | | in | 3 area for Intel ret address 3687 // Owned by |preserve| Empty on Sparc. 3688 // SELF +--------+ 3689 // | | pad2 | 2 pad to align old SP 3690 // | +--------+ 1 3691 // | | locks | 0 3692 // | +--------+----> OptoReg::stack0(), even aligned 3693 // | | pad1 | 11 pad to align new SP 3694 // | +--------+ 3695 // | | | 10 3696 // | | spills | 9 spills 3697 // V | | 8 (pad0 slot for callee) 3698 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3699 // ^ | out | 7 3700 // | | args | 6 Holes in outgoing args owned by CALLEE 3701 // Owned by +--------+ 3702 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3703 // | new |preserve| Must be even-aligned. 3704 // | SP-+--------+----> Matcher::_new_SP, even aligned 3705 // | | | 3706 // 3707 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3708 // known from SELF's arguments and the Java calling convention. 3709 // Region 6-7 is determined per call site. 3710 // Note 2: If the calling convention leaves holes in the incoming argument 3711 // area, those holes are owned by SELF. Holes in the outgoing area 3712 // are owned by the CALLEE. Holes should not be nessecary in the 3713 // incoming area, as the Java calling convention is completely under 3714 // the control of the AD file. Doubles can be sorted and packed to 3715 // avoid holes. Holes in the outgoing arguments may be nessecary for 3716 // varargs C calling conventions. 3717 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3718 // even aligned with pad0 as needed. 3719 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3720 // (the latter is true on Intel but is it false on AArch64?) 3721 // region 6-11 is even aligned; it may be padded out more so that 3722 // the region from SP to FP meets the minimum stack alignment. 3723 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3724 // alignment. Region 11, pad1, may be dynamically extended so that 3725 // SP meets the minimum alignment. 3726 3727 frame %{ 3728 // What direction does stack grow in (assumed to be same for C & Java) 3729 stack_direction(TOWARDS_LOW); 3730 3731 // These three registers define part of the calling convention 3732 // between compiled code and the interpreter. 3733 3734 // Inline Cache Register or methodOop for I2C. 3735 inline_cache_reg(R12); 3736 3737 // Method Oop Register when calling interpreter. 3738 interpreter_method_oop_reg(R12); 3739 3740 // Number of stack slots consumed by locking an object 3741 sync_stack_slots(2); 3742 3743 // Compiled code's Frame Pointer 3744 frame_pointer(R31); 3745 3746 // Interpreter stores its frame pointer in a register which is 3747 // stored to the stack by I2CAdaptors. 3748 // I2CAdaptors convert from interpreted java to compiled java. 3749 interpreter_frame_pointer(R29); 3750 3751 // Stack alignment requirement 3752 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3753 3754 // Number of stack slots between incoming argument block and the start of 3755 // a new frame. The PROLOG must add this many slots to the stack. The 3756 // EPILOG must remove this many slots. aarch64 needs two slots for 3757 // return address and fp. 3758 // TODO think this is correct but check 3759 in_preserve_stack_slots(4); 3760 3761 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3762 // for calls to C. Supports the var-args backing area for register parms. 3763 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3764 3765 // The after-PROLOG location of the return address. Location of 3766 // return address specifies a type (REG or STACK) and a number 3767 // representing the register number (i.e. - use a register name) or 3768 // stack slot. 3769 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3770 // Otherwise, it is above the locks and verification slot and alignment word 3771 // TODO this may well be correct but need to check why that - 2 is there 3772 // ppc port uses 0 but we definitely need to allow for fixed_slots 3773 // which folds in the space used for monitors 3774 return_addr(STACK - 2 + 3775 align_up((Compile::current()->in_preserve_stack_slots() + 3776 Compile::current()->fixed_slots()), 3777 stack_alignment_in_slots())); 3778 3779 // Body of function which returns an integer array locating 3780 // arguments either in registers or in stack slots. Passed an array 3781 // of ideal registers called "sig" and a "length" count. Stack-slot 3782 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3783 // arguments for a CALLEE. Incoming stack arguments are 3784 // automatically biased by the preserve_stack_slots field above. 3785 3786 calling_convention 3787 %{ 3788 // No difference between ingoing/outgoing just pass false 3789 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3790 %} 3791 3792 c_calling_convention 3793 %{ 3794 // This is obviously always outgoing 3795 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3796 %} 3797 3798 // Location of compiled Java return values. Same as C for now. 3799 return_value 3800 %{ 3801 // TODO do we allow ideal_reg == Op_RegN??? 3802 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3803 "only return normal values"); 3804 3805 static const int lo[Op_RegL + 1] = { // enum name 3806 0, // Op_Node 3807 0, // Op_Set 3808 R0_num, // Op_RegN 3809 R0_num, // Op_RegI 3810 R0_num, // Op_RegP 3811 V0_num, // Op_RegF 3812 V0_num, // Op_RegD 3813 R0_num // Op_RegL 3814 }; 3815 3816 static const int hi[Op_RegL + 1] = { // enum name 3817 0, // Op_Node 3818 0, // Op_Set 3819 OptoReg::Bad, // Op_RegN 3820 OptoReg::Bad, // Op_RegI 3821 R0_H_num, // Op_RegP 3822 OptoReg::Bad, // Op_RegF 3823 V0_H_num, // Op_RegD 3824 R0_H_num // Op_RegL 3825 }; 3826 3827 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3828 %} 3829 %} 3830 3831 //----------ATTRIBUTES--------------------------------------------------------- 3832 //----------Operand Attributes------------------------------------------------- 3833 op_attrib op_cost(1); // Required cost attribute 3834 3835 //----------Instruction Attributes--------------------------------------------- 3836 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3837 ins_attrib ins_size(32); // Required size attribute (in bits) 3838 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3839 // a non-matching short branch variant 3840 // of some long branch? 3841 ins_attrib ins_alignment(4); // Required alignment attribute (must 3842 // be a power of 2) specifies the 3843 // alignment that some part of the 3844 // instruction (not necessarily the 3845 // start) requires. If > 1, a 3846 // compute_padding() function must be 3847 // provided for the instruction 3848 3849 //----------OPERANDS----------------------------------------------------------- 3850 // Operand definitions must precede instruction definitions for correct parsing 3851 // in the ADLC because operands constitute user defined types which are used in 3852 // instruction definitions. 3853 3854 //----------Simple Operands---------------------------------------------------- 3855 3856 // Integer operands 32 bit 3857 // 32 bit immediate 3858 operand immI() 3859 %{ 3860 match(ConI); 3861 3862 op_cost(0); 3863 format %{ %} 3864 interface(CONST_INTER); 3865 %} 3866 3867 // 32 bit zero 3868 operand immI0() 3869 %{ 3870 predicate(n->get_int() == 0); 3871 match(ConI); 3872 3873 op_cost(0); 3874 format %{ %} 3875 interface(CONST_INTER); 3876 %} 3877 3878 // 32 bit unit increment 3879 operand immI_1() 3880 %{ 3881 predicate(n->get_int() == 1); 3882 match(ConI); 3883 3884 op_cost(0); 3885 format %{ %} 3886 interface(CONST_INTER); 3887 %} 3888 3889 // 32 bit unit decrement 3890 operand immI_M1() 3891 %{ 3892 predicate(n->get_int() == -1); 3893 match(ConI); 3894 3895 op_cost(0); 3896 format %{ %} 3897 interface(CONST_INTER); 3898 %} 3899 3900 // Shift values for add/sub extension shift 3901 operand immIExt() 3902 %{ 3903 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3904 match(ConI); 3905 3906 op_cost(0); 3907 format %{ %} 3908 interface(CONST_INTER); 3909 %} 3910 3911 operand immI_le_4() 3912 %{ 3913 predicate(n->get_int() <= 4); 3914 match(ConI); 3915 3916 op_cost(0); 3917 format %{ %} 3918 interface(CONST_INTER); 3919 %} 3920 3921 operand immI_31() 3922 %{ 3923 predicate(n->get_int() == 31); 3924 match(ConI); 3925 3926 op_cost(0); 3927 format %{ %} 3928 interface(CONST_INTER); 3929 %} 3930 3931 operand immI_2() 3932 %{ 3933 predicate(n->get_int() == 2); 3934 match(ConI); 3935 3936 op_cost(0); 3937 format %{ %} 3938 interface(CONST_INTER); 3939 %} 3940 3941 operand immI_4() 3942 %{ 3943 predicate(n->get_int() == 4); 3944 match(ConI); 3945 3946 op_cost(0); 3947 format %{ %} 3948 interface(CONST_INTER); 3949 %} 3950 3951 operand immI_8() 3952 %{ 3953 predicate(n->get_int() == 8); 3954 match(ConI); 3955 3956 op_cost(0); 3957 format %{ %} 3958 interface(CONST_INTER); 3959 %} 3960 3961 operand immI_16() 3962 %{ 3963 predicate(n->get_int() == 16); 3964 match(ConI); 3965 3966 op_cost(0); 3967 format %{ %} 3968 interface(CONST_INTER); 3969 %} 3970 3971 operand immI_24() 3972 %{ 3973 predicate(n->get_int() == 24); 3974 match(ConI); 3975 3976 op_cost(0); 3977 format %{ %} 3978 interface(CONST_INTER); 3979 %} 3980 3981 operand immI_32() 3982 %{ 3983 predicate(n->get_int() == 32); 3984 match(ConI); 3985 3986 op_cost(0); 3987 format %{ %} 3988 interface(CONST_INTER); 3989 %} 3990 3991 operand immI_48() 3992 %{ 3993 predicate(n->get_int() == 48); 3994 match(ConI); 3995 3996 op_cost(0); 3997 format %{ %} 3998 interface(CONST_INTER); 3999 %} 4000 4001 operand immI_56() 4002 %{ 4003 predicate(n->get_int() == 56); 4004 match(ConI); 4005 4006 op_cost(0); 4007 format %{ %} 4008 interface(CONST_INTER); 4009 %} 4010 4011 operand immI_63() 4012 %{ 4013 predicate(n->get_int() == 63); 4014 match(ConI); 4015 4016 op_cost(0); 4017 format %{ %} 4018 interface(CONST_INTER); 4019 %} 4020 4021 operand immI_64() 4022 %{ 4023 predicate(n->get_int() == 64); 4024 match(ConI); 4025 4026 op_cost(0); 4027 format %{ %} 4028 interface(CONST_INTER); 4029 %} 4030 4031 operand immI_255() 4032 %{ 4033 predicate(n->get_int() == 255); 4034 match(ConI); 4035 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 operand immI_65535() 4042 %{ 4043 predicate(n->get_int() == 65535); 4044 match(ConI); 4045 4046 op_cost(0); 4047 format %{ %} 4048 interface(CONST_INTER); 4049 %} 4050 4051 operand immL_255() 4052 %{ 4053 predicate(n->get_long() == 255L); 4054 match(ConL); 4055 4056 op_cost(0); 4057 format %{ %} 4058 interface(CONST_INTER); 4059 %} 4060 4061 operand immL_65535() 4062 %{ 4063 predicate(n->get_long() == 65535L); 4064 match(ConL); 4065 4066 op_cost(0); 4067 format %{ %} 4068 interface(CONST_INTER); 4069 %} 4070 4071 operand immL_4294967295() 4072 %{ 4073 predicate(n->get_long() == 4294967295L); 4074 match(ConL); 4075 4076 op_cost(0); 4077 format %{ %} 4078 interface(CONST_INTER); 4079 %} 4080 4081 operand immL_bitmask() 4082 %{ 4083 predicate((n->get_long() != 0) 4084 && ((n->get_long() & 0xc000000000000000l) == 0) 4085 && is_power_of_2(n->get_long() + 1)); 4086 match(ConL); 4087 4088 op_cost(0); 4089 format %{ %} 4090 interface(CONST_INTER); 4091 %} 4092 4093 operand immI_bitmask() 4094 %{ 4095 predicate((n->get_int() != 0) 4096 && ((n->get_int() & 0xc0000000) == 0) 4097 && is_power_of_2(n->get_int() + 1)); 4098 match(ConI); 4099 4100 op_cost(0); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 // Scale values for scaled offset addressing modes (up to long but not quad) 4106 operand immIScale() 4107 %{ 4108 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4109 match(ConI); 4110 4111 op_cost(0); 4112 format %{ %} 4113 interface(CONST_INTER); 4114 %} 4115 4116 // 26 bit signed offset -- for pc-relative branches 4117 operand immI26() 4118 %{ 4119 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4120 match(ConI); 4121 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125 %} 4126 4127 // 19 bit signed offset -- for pc-relative loads 4128 operand immI19() 4129 %{ 4130 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4131 match(ConI); 4132 4133 op_cost(0); 4134 format %{ %} 4135 interface(CONST_INTER); 4136 %} 4137 4138 // 12 bit unsigned offset -- for base plus immediate loads 4139 operand immIU12() 4140 %{ 4141 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4142 match(ConI); 4143 4144 op_cost(0); 4145 format %{ %} 4146 interface(CONST_INTER); 4147 %} 4148 4149 operand immLU12() 4150 %{ 4151 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4152 match(ConL); 4153 4154 op_cost(0); 4155 format %{ %} 4156 interface(CONST_INTER); 4157 %} 4158 4159 // Offset for scaled or unscaled immediate loads and stores 4160 operand immIOffset() 4161 %{ 4162 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4163 match(ConI); 4164 4165 op_cost(0); 4166 format %{ %} 4167 interface(CONST_INTER); 4168 %} 4169 4170 operand immIOffset1() 4171 %{ 4172 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4173 match(ConI); 4174 4175 op_cost(0); 4176 format %{ %} 4177 interface(CONST_INTER); 4178 %} 4179 4180 operand immIOffset2() 4181 %{ 4182 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4183 match(ConI); 4184 4185 op_cost(0); 4186 format %{ %} 4187 interface(CONST_INTER); 4188 %} 4189 4190 operand immIOffset4() 4191 %{ 4192 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4193 match(ConI); 4194 4195 op_cost(0); 4196 format %{ %} 4197 interface(CONST_INTER); 4198 %} 4199 4200 operand immIOffset8() 4201 %{ 4202 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4203 match(ConI); 4204 4205 op_cost(0); 4206 format %{ %} 4207 interface(CONST_INTER); 4208 %} 4209 4210 operand immIOffset16() 4211 %{ 4212 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4213 match(ConI); 4214 4215 op_cost(0); 4216 format %{ %} 4217 interface(CONST_INTER); 4218 %} 4219 4220 operand immLoffset() 4221 %{ 4222 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4223 match(ConL); 4224 4225 op_cost(0); 4226 format %{ %} 4227 interface(CONST_INTER); 4228 %} 4229 4230 operand immLoffset1() 4231 %{ 4232 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4233 match(ConL); 4234 4235 op_cost(0); 4236 format %{ %} 4237 interface(CONST_INTER); 4238 %} 4239 4240 operand immLoffset2() 4241 %{ 4242 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4243 match(ConL); 4244 4245 op_cost(0); 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 operand immLoffset4() 4251 %{ 4252 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4253 match(ConL); 4254 4255 op_cost(0); 4256 format %{ %} 4257 interface(CONST_INTER); 4258 %} 4259 4260 operand immLoffset8() 4261 %{ 4262 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4263 match(ConL); 4264 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 operand immLoffset16() 4271 %{ 4272 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4273 match(ConL); 4274 4275 op_cost(0); 4276 format %{ %} 4277 interface(CONST_INTER); 4278 %} 4279 4280 // 32 bit integer valid for add sub immediate 4281 operand immIAddSub() 4282 %{ 4283 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4284 match(ConI); 4285 op_cost(0); 4286 format %{ %} 4287 interface(CONST_INTER); 4288 %} 4289 4290 // 32 bit unsigned integer valid for logical immediate 4291 // TODO -- check this is right when e.g the mask is 0x80000000 4292 operand immILog() 4293 %{ 4294 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4295 match(ConI); 4296 4297 op_cost(0); 4298 format %{ %} 4299 interface(CONST_INTER); 4300 %} 4301 4302 // Integer operands 64 bit 4303 // 64 bit immediate 4304 operand immL() 4305 %{ 4306 match(ConL); 4307 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 // 64 bit zero 4314 operand immL0() 4315 %{ 4316 predicate(n->get_long() == 0); 4317 match(ConL); 4318 4319 op_cost(0); 4320 format %{ %} 4321 interface(CONST_INTER); 4322 %} 4323 4324 // 64 bit unit increment 4325 operand immL_1() 4326 %{ 4327 predicate(n->get_long() == 1); 4328 match(ConL); 4329 4330 op_cost(0); 4331 format %{ %} 4332 interface(CONST_INTER); 4333 %} 4334 4335 // 64 bit unit decrement 4336 operand immL_M1() 4337 %{ 4338 predicate(n->get_long() == -1); 4339 match(ConL); 4340 4341 op_cost(0); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // 32 bit offset of pc in thread anchor 4347 4348 operand immL_pc_off() 4349 %{ 4350 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4351 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4352 match(ConL); 4353 4354 op_cost(0); 4355 format %{ %} 4356 interface(CONST_INTER); 4357 %} 4358 4359 // 64 bit integer valid for add sub immediate 4360 operand immLAddSub() 4361 %{ 4362 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4363 match(ConL); 4364 op_cost(0); 4365 format %{ %} 4366 interface(CONST_INTER); 4367 %} 4368 4369 // 64 bit integer valid for logical immediate 4370 operand immLLog() 4371 %{ 4372 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4373 match(ConL); 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 // Long Immediate: low 32-bit mask 4380 operand immL_32bits() 4381 %{ 4382 predicate(n->get_long() == 0xFFFFFFFFL); 4383 match(ConL); 4384 op_cost(0); 4385 format %{ %} 4386 interface(CONST_INTER); 4387 %} 4388 4389 // Pointer operands 4390 // Pointer Immediate 4391 operand immP() 4392 %{ 4393 match(ConP); 4394 4395 op_cost(0); 4396 format %{ %} 4397 interface(CONST_INTER); 4398 %} 4399 4400 // NULL Pointer Immediate 4401 operand immP0() 4402 %{ 4403 predicate(n->get_ptr() == 0); 4404 match(ConP); 4405 4406 op_cost(0); 4407 format %{ %} 4408 interface(CONST_INTER); 4409 %} 4410 4411 // Pointer Immediate One 4412 // this is used in object initialization (initial object header) 4413 operand immP_1() 4414 %{ 4415 predicate(n->get_ptr() == 1); 4416 match(ConP); 4417 4418 op_cost(0); 4419 format %{ %} 4420 interface(CONST_INTER); 4421 %} 4422 4423 // Card Table Byte Map Base 4424 operand immByteMapBase() 4425 %{ 4426 // Get base of card map 4427 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4428 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4429 match(ConP); 4430 4431 op_cost(0); 4432 format %{ %} 4433 interface(CONST_INTER); 4434 %} 4435 4436 // Pointer Immediate Minus One 4437 // this is used when we want to write the current PC to the thread anchor 4438 operand immP_M1() 4439 %{ 4440 predicate(n->get_ptr() == -1); 4441 match(ConP); 4442 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 // Pointer Immediate Minus Two 4449 // this is used when we want to write the current PC to the thread anchor 4450 operand immP_M2() 4451 %{ 4452 predicate(n->get_ptr() == -2); 4453 match(ConP); 4454 4455 op_cost(0); 4456 format %{ %} 4457 interface(CONST_INTER); 4458 %} 4459 4460 // Float and Double operands 4461 // Double Immediate 4462 operand immD() 4463 %{ 4464 match(ConD); 4465 op_cost(0); 4466 format %{ %} 4467 interface(CONST_INTER); 4468 %} 4469 4470 // Double Immediate: +0.0d 4471 operand immD0() 4472 %{ 4473 predicate(jlong_cast(n->getd()) == 0); 4474 match(ConD); 4475 4476 op_cost(0); 4477 format %{ %} 4478 interface(CONST_INTER); 4479 %} 4480 4481 // constant 'double +0.0'. 4482 operand immDPacked() 4483 %{ 4484 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4485 match(ConD); 4486 op_cost(0); 4487 format %{ %} 4488 interface(CONST_INTER); 4489 %} 4490 4491 // Float Immediate 4492 operand immF() 4493 %{ 4494 match(ConF); 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // Float Immediate: +0.0f. 4501 operand immF0() 4502 %{ 4503 predicate(jint_cast(n->getf()) == 0); 4504 match(ConF); 4505 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 // 4512 operand immFPacked() 4513 %{ 4514 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4515 match(ConF); 4516 op_cost(0); 4517 format %{ %} 4518 interface(CONST_INTER); 4519 %} 4520 4521 // Narrow pointer operands 4522 // Narrow Pointer Immediate 4523 operand immN() 4524 %{ 4525 match(ConN); 4526 4527 op_cost(0); 4528 format %{ %} 4529 interface(CONST_INTER); 4530 %} 4531 4532 // Narrow NULL Pointer Immediate 4533 operand immN0() 4534 %{ 4535 predicate(n->get_narrowcon() == 0); 4536 match(ConN); 4537 4538 op_cost(0); 4539 format %{ %} 4540 interface(CONST_INTER); 4541 %} 4542 4543 operand immNKlass() 4544 %{ 4545 match(ConNKlass); 4546 4547 op_cost(0); 4548 format %{ %} 4549 interface(CONST_INTER); 4550 %} 4551 4552 // Integer 32 bit Register Operands 4553 // Integer 32 bitRegister (excludes SP) 4554 operand iRegI() 4555 %{ 4556 constraint(ALLOC_IN_RC(any_reg32)); 4557 match(RegI); 4558 match(iRegINoSp); 4559 op_cost(0); 4560 format %{ %} 4561 interface(REG_INTER); 4562 %} 4563 4564 // Integer 32 bit Register not Special 4565 operand iRegINoSp() 4566 %{ 4567 constraint(ALLOC_IN_RC(no_special_reg32)); 4568 match(RegI); 4569 op_cost(0); 4570 format %{ %} 4571 interface(REG_INTER); 4572 %} 4573 4574 // Integer 64 bit Register Operands 4575 // Integer 64 bit Register (includes SP) 4576 operand iRegL() 4577 %{ 4578 constraint(ALLOC_IN_RC(any_reg)); 4579 match(RegL); 4580 match(iRegLNoSp); 4581 op_cost(0); 4582 format %{ %} 4583 interface(REG_INTER); 4584 %} 4585 4586 // Integer 64 bit Register not Special 4587 operand iRegLNoSp() 4588 %{ 4589 constraint(ALLOC_IN_RC(no_special_reg)); 4590 match(RegL); 4591 match(iRegL_R0); 4592 format %{ %} 4593 interface(REG_INTER); 4594 %} 4595 4596 // Pointer Register Operands 4597 // Pointer Register 4598 operand iRegP() 4599 %{ 4600 constraint(ALLOC_IN_RC(ptr_reg)); 4601 match(RegP); 4602 match(iRegPNoSp); 4603 match(iRegP_R0); 4604 //match(iRegP_R2); 4605 //match(iRegP_R4); 4606 //match(iRegP_R5); 4607 match(thread_RegP); 4608 op_cost(0); 4609 format %{ %} 4610 interface(REG_INTER); 4611 %} 4612 4613 // Pointer 64 bit Register not Special 4614 operand iRegPNoSp() 4615 %{ 4616 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4617 match(RegP); 4618 // match(iRegP); 4619 // match(iRegP_R0); 4620 // match(iRegP_R2); 4621 // match(iRegP_R4); 4622 // match(iRegP_R5); 4623 // match(thread_RegP); 4624 op_cost(0); 4625 format %{ %} 4626 interface(REG_INTER); 4627 %} 4628 4629 // Pointer 64 bit Register R0 only 4630 operand iRegP_R0() 4631 %{ 4632 constraint(ALLOC_IN_RC(r0_reg)); 4633 match(RegP); 4634 // match(iRegP); 4635 match(iRegPNoSp); 4636 op_cost(0); 4637 format %{ %} 4638 interface(REG_INTER); 4639 %} 4640 4641 // Pointer 64 bit Register R1 only 4642 operand iRegP_R1() 4643 %{ 4644 constraint(ALLOC_IN_RC(r1_reg)); 4645 match(RegP); 4646 // match(iRegP); 4647 match(iRegPNoSp); 4648 op_cost(0); 4649 format %{ %} 4650 interface(REG_INTER); 4651 %} 4652 4653 // Pointer 64 bit Register R2 only 4654 operand iRegP_R2() 4655 %{ 4656 constraint(ALLOC_IN_RC(r2_reg)); 4657 match(RegP); 4658 // match(iRegP); 4659 match(iRegPNoSp); 4660 op_cost(0); 4661 format %{ %} 4662 interface(REG_INTER); 4663 %} 4664 4665 // Pointer 64 bit Register R3 only 4666 operand iRegP_R3() 4667 %{ 4668 constraint(ALLOC_IN_RC(r3_reg)); 4669 match(RegP); 4670 // match(iRegP); 4671 match(iRegPNoSp); 4672 op_cost(0); 4673 format %{ %} 4674 interface(REG_INTER); 4675 %} 4676 4677 // Pointer 64 bit Register R4 only 4678 operand iRegP_R4() 4679 %{ 4680 constraint(ALLOC_IN_RC(r4_reg)); 4681 match(RegP); 4682 // match(iRegP); 4683 match(iRegPNoSp); 4684 op_cost(0); 4685 format %{ %} 4686 interface(REG_INTER); 4687 %} 4688 4689 // Pointer 64 bit Register R5 only 4690 operand iRegP_R5() 4691 %{ 4692 constraint(ALLOC_IN_RC(r5_reg)); 4693 match(RegP); 4694 // match(iRegP); 4695 match(iRegPNoSp); 4696 op_cost(0); 4697 format %{ %} 4698 interface(REG_INTER); 4699 %} 4700 4701 // Pointer 64 bit Register R10 only 4702 operand iRegP_R10() 4703 %{ 4704 constraint(ALLOC_IN_RC(r10_reg)); 4705 match(RegP); 4706 // match(iRegP); 4707 match(iRegPNoSp); 4708 op_cost(0); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 // Long 64 bit Register R0 only 4714 operand iRegL_R0() 4715 %{ 4716 constraint(ALLOC_IN_RC(r0_reg)); 4717 match(RegL); 4718 match(iRegLNoSp); 4719 op_cost(0); 4720 format %{ %} 4721 interface(REG_INTER); 4722 %} 4723 4724 // Long 64 bit Register R2 only 4725 operand iRegL_R2() 4726 %{ 4727 constraint(ALLOC_IN_RC(r2_reg)); 4728 match(RegL); 4729 match(iRegLNoSp); 4730 op_cost(0); 4731 format %{ %} 4732 interface(REG_INTER); 4733 %} 4734 4735 // Long 64 bit Register R3 only 4736 operand iRegL_R3() 4737 %{ 4738 constraint(ALLOC_IN_RC(r3_reg)); 4739 match(RegL); 4740 match(iRegLNoSp); 4741 op_cost(0); 4742 format %{ %} 4743 interface(REG_INTER); 4744 %} 4745 4746 // Long 64 bit Register R11 only 4747 operand iRegL_R11() 4748 %{ 4749 constraint(ALLOC_IN_RC(r11_reg)); 4750 match(RegL); 4751 match(iRegLNoSp); 4752 op_cost(0); 4753 format %{ %} 4754 interface(REG_INTER); 4755 %} 4756 4757 // Pointer 64 bit Register FP only 4758 operand iRegP_FP() 4759 %{ 4760 constraint(ALLOC_IN_RC(fp_reg)); 4761 match(RegP); 4762 // match(iRegP); 4763 op_cost(0); 4764 format %{ %} 4765 interface(REG_INTER); 4766 %} 4767 4768 // Register R0 only 4769 operand iRegI_R0() 4770 %{ 4771 constraint(ALLOC_IN_RC(int_r0_reg)); 4772 match(RegI); 4773 match(iRegINoSp); 4774 op_cost(0); 4775 format %{ %} 4776 interface(REG_INTER); 4777 %} 4778 4779 // Register R2 only 4780 operand iRegI_R2() 4781 %{ 4782 constraint(ALLOC_IN_RC(int_r2_reg)); 4783 match(RegI); 4784 match(iRegINoSp); 4785 op_cost(0); 4786 format %{ %} 4787 interface(REG_INTER); 4788 %} 4789 4790 // Register R3 only 4791 operand iRegI_R3() 4792 %{ 4793 constraint(ALLOC_IN_RC(int_r3_reg)); 4794 match(RegI); 4795 match(iRegINoSp); 4796 op_cost(0); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 4802 // Register R4 only 4803 operand iRegI_R4() 4804 %{ 4805 constraint(ALLOC_IN_RC(int_r4_reg)); 4806 match(RegI); 4807 match(iRegINoSp); 4808 op_cost(0); 4809 format %{ %} 4810 interface(REG_INTER); 4811 %} 4812 4813 4814 // Pointer Register Operands 4815 // Narrow Pointer Register 4816 operand iRegN() 4817 %{ 4818 constraint(ALLOC_IN_RC(any_reg32)); 4819 match(RegN); 4820 match(iRegNNoSp); 4821 op_cost(0); 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 operand iRegN_R0() 4827 %{ 4828 constraint(ALLOC_IN_RC(r0_reg)); 4829 match(iRegN); 4830 op_cost(0); 4831 format %{ %} 4832 interface(REG_INTER); 4833 %} 4834 4835 operand iRegN_R2() 4836 %{ 4837 constraint(ALLOC_IN_RC(r2_reg)); 4838 match(iRegN); 4839 op_cost(0); 4840 format %{ %} 4841 interface(REG_INTER); 4842 %} 4843 4844 operand iRegN_R3() 4845 %{ 4846 constraint(ALLOC_IN_RC(r3_reg)); 4847 match(iRegN); 4848 op_cost(0); 4849 format %{ %} 4850 interface(REG_INTER); 4851 %} 4852 4853 // Integer 64 bit Register not Special 4854 operand iRegNNoSp() 4855 %{ 4856 constraint(ALLOC_IN_RC(no_special_reg32)); 4857 match(RegN); 4858 op_cost(0); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 // heap base register -- used for encoding immN0 4864 4865 operand iRegIHeapbase() 4866 %{ 4867 constraint(ALLOC_IN_RC(heapbase_reg)); 4868 match(RegI); 4869 op_cost(0); 4870 format %{ %} 4871 interface(REG_INTER); 4872 %} 4873 4874 // Float Register 4875 // Float register operands 4876 operand vRegF() 4877 %{ 4878 constraint(ALLOC_IN_RC(float_reg)); 4879 match(RegF); 4880 4881 op_cost(0); 4882 format %{ %} 4883 interface(REG_INTER); 4884 %} 4885 4886 // Double Register 4887 // Double register operands 4888 operand vRegD() 4889 %{ 4890 constraint(ALLOC_IN_RC(double_reg)); 4891 match(RegD); 4892 4893 op_cost(0); 4894 format %{ %} 4895 interface(REG_INTER); 4896 %} 4897 4898 operand vecD() 4899 %{ 4900 constraint(ALLOC_IN_RC(vectord_reg)); 4901 match(VecD); 4902 4903 op_cost(0); 4904 format %{ %} 4905 interface(REG_INTER); 4906 %} 4907 4908 operand vecX() 4909 %{ 4910 constraint(ALLOC_IN_RC(vectorx_reg)); 4911 match(VecX); 4912 4913 op_cost(0); 4914 format %{ %} 4915 interface(REG_INTER); 4916 %} 4917 4918 operand vRegD_V0() 4919 %{ 4920 constraint(ALLOC_IN_RC(v0_reg)); 4921 match(RegD); 4922 op_cost(0); 4923 format %{ %} 4924 interface(REG_INTER); 4925 %} 4926 4927 operand vRegD_V1() 4928 %{ 4929 constraint(ALLOC_IN_RC(v1_reg)); 4930 match(RegD); 4931 op_cost(0); 4932 format %{ %} 4933 interface(REG_INTER); 4934 %} 4935 4936 operand vRegD_V2() 4937 %{ 4938 constraint(ALLOC_IN_RC(v2_reg)); 4939 match(RegD); 4940 op_cost(0); 4941 format %{ %} 4942 interface(REG_INTER); 4943 %} 4944 4945 operand vRegD_V3() 4946 %{ 4947 constraint(ALLOC_IN_RC(v3_reg)); 4948 match(RegD); 4949 op_cost(0); 4950 format %{ %} 4951 interface(REG_INTER); 4952 %} 4953 4954 operand vRegD_V4() 4955 %{ 4956 constraint(ALLOC_IN_RC(v4_reg)); 4957 match(RegD); 4958 op_cost(0); 4959 format %{ %} 4960 interface(REG_INTER); 4961 %} 4962 4963 operand vRegD_V5() 4964 %{ 4965 constraint(ALLOC_IN_RC(v5_reg)); 4966 match(RegD); 4967 op_cost(0); 4968 format %{ %} 4969 interface(REG_INTER); 4970 %} 4971 4972 operand vRegD_V6() 4973 %{ 4974 constraint(ALLOC_IN_RC(v6_reg)); 4975 match(RegD); 4976 op_cost(0); 4977 format %{ %} 4978 interface(REG_INTER); 4979 %} 4980 4981 operand vRegD_V7() 4982 %{ 4983 constraint(ALLOC_IN_RC(v7_reg)); 4984 match(RegD); 4985 op_cost(0); 4986 format %{ %} 4987 interface(REG_INTER); 4988 %} 4989 4990 operand vRegD_V8() 4991 %{ 4992 constraint(ALLOC_IN_RC(v8_reg)); 4993 match(RegD); 4994 op_cost(0); 4995 format %{ %} 4996 interface(REG_INTER); 4997 %} 4998 4999 operand vRegD_V9() 5000 %{ 5001 constraint(ALLOC_IN_RC(v9_reg)); 5002 match(RegD); 5003 op_cost(0); 5004 format %{ %} 5005 interface(REG_INTER); 5006 %} 5007 5008 operand vRegD_V10() 5009 %{ 5010 constraint(ALLOC_IN_RC(v10_reg)); 5011 match(RegD); 5012 op_cost(0); 5013 format %{ %} 5014 interface(REG_INTER); 5015 %} 5016 5017 operand vRegD_V11() 5018 %{ 5019 constraint(ALLOC_IN_RC(v11_reg)); 5020 match(RegD); 5021 op_cost(0); 5022 format %{ %} 5023 interface(REG_INTER); 5024 %} 5025 5026 operand vRegD_V12() 5027 %{ 5028 constraint(ALLOC_IN_RC(v12_reg)); 5029 match(RegD); 5030 op_cost(0); 5031 format %{ %} 5032 interface(REG_INTER); 5033 %} 5034 5035 operand vRegD_V13() 5036 %{ 5037 constraint(ALLOC_IN_RC(v13_reg)); 5038 match(RegD); 5039 op_cost(0); 5040 format %{ %} 5041 interface(REG_INTER); 5042 %} 5043 5044 operand vRegD_V14() 5045 %{ 5046 constraint(ALLOC_IN_RC(v14_reg)); 5047 match(RegD); 5048 op_cost(0); 5049 format %{ %} 5050 interface(REG_INTER); 5051 %} 5052 5053 operand vRegD_V15() 5054 %{ 5055 constraint(ALLOC_IN_RC(v15_reg)); 5056 match(RegD); 5057 op_cost(0); 5058 format %{ %} 5059 interface(REG_INTER); 5060 %} 5061 5062 operand vRegD_V16() 5063 %{ 5064 constraint(ALLOC_IN_RC(v16_reg)); 5065 match(RegD); 5066 op_cost(0); 5067 format %{ %} 5068 interface(REG_INTER); 5069 %} 5070 5071 operand vRegD_V17() 5072 %{ 5073 constraint(ALLOC_IN_RC(v17_reg)); 5074 match(RegD); 5075 op_cost(0); 5076 format %{ %} 5077 interface(REG_INTER); 5078 %} 5079 5080 operand vRegD_V18() 5081 %{ 5082 constraint(ALLOC_IN_RC(v18_reg)); 5083 match(RegD); 5084 op_cost(0); 5085 format %{ %} 5086 interface(REG_INTER); 5087 %} 5088 5089 operand vRegD_V19() 5090 %{ 5091 constraint(ALLOC_IN_RC(v19_reg)); 5092 match(RegD); 5093 op_cost(0); 5094 format %{ %} 5095 interface(REG_INTER); 5096 %} 5097 5098 operand vRegD_V20() 5099 %{ 5100 constraint(ALLOC_IN_RC(v20_reg)); 5101 match(RegD); 5102 op_cost(0); 5103 format %{ %} 5104 interface(REG_INTER); 5105 %} 5106 5107 operand vRegD_V21() 5108 %{ 5109 constraint(ALLOC_IN_RC(v21_reg)); 5110 match(RegD); 5111 op_cost(0); 5112 format %{ %} 5113 interface(REG_INTER); 5114 %} 5115 5116 operand vRegD_V22() 5117 %{ 5118 constraint(ALLOC_IN_RC(v22_reg)); 5119 match(RegD); 5120 op_cost(0); 5121 format %{ %} 5122 interface(REG_INTER); 5123 %} 5124 5125 operand vRegD_V23() 5126 %{ 5127 constraint(ALLOC_IN_RC(v23_reg)); 5128 match(RegD); 5129 op_cost(0); 5130 format %{ %} 5131 interface(REG_INTER); 5132 %} 5133 5134 operand vRegD_V24() 5135 %{ 5136 constraint(ALLOC_IN_RC(v24_reg)); 5137 match(RegD); 5138 op_cost(0); 5139 format %{ %} 5140 interface(REG_INTER); 5141 %} 5142 5143 operand vRegD_V25() 5144 %{ 5145 constraint(ALLOC_IN_RC(v25_reg)); 5146 match(RegD); 5147 op_cost(0); 5148 format %{ %} 5149 interface(REG_INTER); 5150 %} 5151 5152 operand vRegD_V26() 5153 %{ 5154 constraint(ALLOC_IN_RC(v26_reg)); 5155 match(RegD); 5156 op_cost(0); 5157 format %{ %} 5158 interface(REG_INTER); 5159 %} 5160 5161 operand vRegD_V27() 5162 %{ 5163 constraint(ALLOC_IN_RC(v27_reg)); 5164 match(RegD); 5165 op_cost(0); 5166 format %{ %} 5167 interface(REG_INTER); 5168 %} 5169 5170 operand vRegD_V28() 5171 %{ 5172 constraint(ALLOC_IN_RC(v28_reg)); 5173 match(RegD); 5174 op_cost(0); 5175 format %{ %} 5176 interface(REG_INTER); 5177 %} 5178 5179 operand vRegD_V29() 5180 %{ 5181 constraint(ALLOC_IN_RC(v29_reg)); 5182 match(RegD); 5183 op_cost(0); 5184 format %{ %} 5185 interface(REG_INTER); 5186 %} 5187 5188 operand vRegD_V30() 5189 %{ 5190 constraint(ALLOC_IN_RC(v30_reg)); 5191 match(RegD); 5192 op_cost(0); 5193 format %{ %} 5194 interface(REG_INTER); 5195 %} 5196 5197 operand vRegD_V31() 5198 %{ 5199 constraint(ALLOC_IN_RC(v31_reg)); 5200 match(RegD); 5201 op_cost(0); 5202 format %{ %} 5203 interface(REG_INTER); 5204 %} 5205 5206 // Flags register, used as output of signed compare instructions 5207 5208 // note that on AArch64 we also use this register as the output for 5209 // for floating point compare instructions (CmpF CmpD). this ensures 5210 // that ordered inequality tests use GT, GE, LT or LE none of which 5211 // pass through cases where the result is unordered i.e. one or both 5212 // inputs to the compare is a NaN. this means that the ideal code can 5213 // replace e.g. a GT with an LE and not end up capturing the NaN case 5214 // (where the comparison should always fail). EQ and NE tests are 5215 // always generated in ideal code so that unordered folds into the NE 5216 // case, matching the behaviour of AArch64 NE. 5217 // 5218 // This differs from x86 where the outputs of FP compares use a 5219 // special FP flags registers and where compares based on this 5220 // register are distinguished into ordered inequalities (cmpOpUCF) and 5221 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5222 // to explicitly handle the unordered case in branches. x86 also has 5223 // to include extra CMoveX rules to accept a cmpOpUCF input. 5224 5225 operand rFlagsReg() 5226 %{ 5227 constraint(ALLOC_IN_RC(int_flags)); 5228 match(RegFlags); 5229 5230 op_cost(0); 5231 format %{ "RFLAGS" %} 5232 interface(REG_INTER); 5233 %} 5234 5235 // Flags register, used as output of unsigned compare instructions 5236 operand rFlagsRegU() 5237 %{ 5238 constraint(ALLOC_IN_RC(int_flags)); 5239 match(RegFlags); 5240 5241 op_cost(0); 5242 format %{ "RFLAGSU" %} 5243 interface(REG_INTER); 5244 %} 5245 5246 // Special Registers 5247 5248 // Method Register 5249 operand inline_cache_RegP(iRegP reg) 5250 %{ 5251 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5252 match(reg); 5253 match(iRegPNoSp); 5254 op_cost(0); 5255 format %{ %} 5256 interface(REG_INTER); 5257 %} 5258 5259 operand interpreter_method_oop_RegP(iRegP reg) 5260 %{ 5261 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5262 match(reg); 5263 match(iRegPNoSp); 5264 op_cost(0); 5265 format %{ %} 5266 interface(REG_INTER); 5267 %} 5268 5269 // Thread Register 5270 operand thread_RegP(iRegP reg) 5271 %{ 5272 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5273 match(reg); 5274 op_cost(0); 5275 format %{ %} 5276 interface(REG_INTER); 5277 %} 5278 5279 operand lr_RegP(iRegP reg) 5280 %{ 5281 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5282 match(reg); 5283 op_cost(0); 5284 format %{ %} 5285 interface(REG_INTER); 5286 %} 5287 5288 //----------Memory Operands---------------------------------------------------- 5289 5290 operand indirect(iRegP reg) 5291 %{ 5292 constraint(ALLOC_IN_RC(ptr_reg)); 5293 match(reg); 5294 op_cost(0); 5295 format %{ "[$reg]" %} 5296 interface(MEMORY_INTER) %{ 5297 base($reg); 5298 index(0xffffffff); 5299 scale(0x0); 5300 disp(0x0); 5301 %} 5302 %} 5303 5304 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5305 %{ 5306 constraint(ALLOC_IN_RC(ptr_reg)); 5307 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5308 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5309 op_cost(0); 5310 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5311 interface(MEMORY_INTER) %{ 5312 base($reg); 5313 index($ireg); 5314 scale($scale); 5315 disp(0x0); 5316 %} 5317 %} 5318 5319 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5320 %{ 5321 constraint(ALLOC_IN_RC(ptr_reg)); 5322 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5323 match(AddP reg (LShiftL lreg scale)); 5324 op_cost(0); 5325 format %{ "$reg, $lreg lsl($scale)" %} 5326 interface(MEMORY_INTER) %{ 5327 base($reg); 5328 index($lreg); 5329 scale($scale); 5330 disp(0x0); 5331 %} 5332 %} 5333 5334 operand indIndexI2L(iRegP reg, iRegI ireg) 5335 %{ 5336 constraint(ALLOC_IN_RC(ptr_reg)); 5337 match(AddP reg (ConvI2L ireg)); 5338 op_cost(0); 5339 format %{ "$reg, $ireg, 0, I2L" %} 5340 interface(MEMORY_INTER) %{ 5341 base($reg); 5342 index($ireg); 5343 scale(0x0); 5344 disp(0x0); 5345 %} 5346 %} 5347 5348 operand indIndex(iRegP reg, iRegL lreg) 5349 %{ 5350 constraint(ALLOC_IN_RC(ptr_reg)); 5351 match(AddP reg lreg); 5352 op_cost(0); 5353 format %{ "$reg, $lreg" %} 5354 interface(MEMORY_INTER) %{ 5355 base($reg); 5356 index($lreg); 5357 scale(0x0); 5358 disp(0x0); 5359 %} 5360 %} 5361 5362 operand indOffI(iRegP reg, immIOffset off) 5363 %{ 5364 constraint(ALLOC_IN_RC(ptr_reg)); 5365 match(AddP reg off); 5366 op_cost(0); 5367 format %{ "[$reg, $off]" %} 5368 interface(MEMORY_INTER) %{ 5369 base($reg); 5370 index(0xffffffff); 5371 scale(0x0); 5372 disp($off); 5373 %} 5374 %} 5375 5376 operand indOffI1(iRegP reg, immIOffset1 off) 5377 %{ 5378 constraint(ALLOC_IN_RC(ptr_reg)); 5379 match(AddP reg off); 5380 op_cost(0); 5381 format %{ "[$reg, $off]" %} 5382 interface(MEMORY_INTER) %{ 5383 base($reg); 5384 index(0xffffffff); 5385 scale(0x0); 5386 disp($off); 5387 %} 5388 %} 5389 5390 operand indOffI2(iRegP reg, immIOffset2 off) 5391 %{ 5392 constraint(ALLOC_IN_RC(ptr_reg)); 5393 match(AddP reg off); 5394 op_cost(0); 5395 format %{ "[$reg, $off]" %} 5396 interface(MEMORY_INTER) %{ 5397 base($reg); 5398 index(0xffffffff); 5399 scale(0x0); 5400 disp($off); 5401 %} 5402 %} 5403 5404 operand indOffI4(iRegP reg, immIOffset4 off) 5405 %{ 5406 constraint(ALLOC_IN_RC(ptr_reg)); 5407 match(AddP reg off); 5408 op_cost(0); 5409 format %{ "[$reg, $off]" %} 5410 interface(MEMORY_INTER) %{ 5411 base($reg); 5412 index(0xffffffff); 5413 scale(0x0); 5414 disp($off); 5415 %} 5416 %} 5417 5418 operand indOffI8(iRegP reg, immIOffset8 off) 5419 %{ 5420 constraint(ALLOC_IN_RC(ptr_reg)); 5421 match(AddP reg off); 5422 op_cost(0); 5423 format %{ "[$reg, $off]" %} 5424 interface(MEMORY_INTER) %{ 5425 base($reg); 5426 index(0xffffffff); 5427 scale(0x0); 5428 disp($off); 5429 %} 5430 %} 5431 5432 operand indOffI16(iRegP reg, immIOffset16 off) 5433 %{ 5434 constraint(ALLOC_IN_RC(ptr_reg)); 5435 match(AddP reg off); 5436 op_cost(0); 5437 format %{ "[$reg, $off]" %} 5438 interface(MEMORY_INTER) %{ 5439 base($reg); 5440 index(0xffffffff); 5441 scale(0x0); 5442 disp($off); 5443 %} 5444 %} 5445 5446 operand indOffL(iRegP reg, immLoffset off) 5447 %{ 5448 constraint(ALLOC_IN_RC(ptr_reg)); 5449 match(AddP reg off); 5450 op_cost(0); 5451 format %{ "[$reg, $off]" %} 5452 interface(MEMORY_INTER) %{ 5453 base($reg); 5454 index(0xffffffff); 5455 scale(0x0); 5456 disp($off); 5457 %} 5458 %} 5459 5460 operand indOffL1(iRegP reg, immLoffset1 off) 5461 %{ 5462 constraint(ALLOC_IN_RC(ptr_reg)); 5463 match(AddP reg off); 5464 op_cost(0); 5465 format %{ "[$reg, $off]" %} 5466 interface(MEMORY_INTER) %{ 5467 base($reg); 5468 index(0xffffffff); 5469 scale(0x0); 5470 disp($off); 5471 %} 5472 %} 5473 5474 operand indOffL2(iRegP reg, immLoffset2 off) 5475 %{ 5476 constraint(ALLOC_IN_RC(ptr_reg)); 5477 match(AddP reg off); 5478 op_cost(0); 5479 format %{ "[$reg, $off]" %} 5480 interface(MEMORY_INTER) %{ 5481 base($reg); 5482 index(0xffffffff); 5483 scale(0x0); 5484 disp($off); 5485 %} 5486 %} 5487 5488 operand indOffL4(iRegP reg, immLoffset4 off) 5489 %{ 5490 constraint(ALLOC_IN_RC(ptr_reg)); 5491 match(AddP reg off); 5492 op_cost(0); 5493 format %{ "[$reg, $off]" %} 5494 interface(MEMORY_INTER) %{ 5495 base($reg); 5496 index(0xffffffff); 5497 scale(0x0); 5498 disp($off); 5499 %} 5500 %} 5501 5502 operand indOffL8(iRegP reg, immLoffset8 off) 5503 %{ 5504 constraint(ALLOC_IN_RC(ptr_reg)); 5505 match(AddP reg off); 5506 op_cost(0); 5507 format %{ "[$reg, $off]" %} 5508 interface(MEMORY_INTER) %{ 5509 base($reg); 5510 index(0xffffffff); 5511 scale(0x0); 5512 disp($off); 5513 %} 5514 %} 5515 5516 operand indOffL16(iRegP reg, immLoffset16 off) 5517 %{ 5518 constraint(ALLOC_IN_RC(ptr_reg)); 5519 match(AddP reg off); 5520 op_cost(0); 5521 format %{ "[$reg, $off]" %} 5522 interface(MEMORY_INTER) %{ 5523 base($reg); 5524 index(0xffffffff); 5525 scale(0x0); 5526 disp($off); 5527 %} 5528 %} 5529 5530 operand indirectN(iRegN reg) 5531 %{ 5532 predicate(CompressedOops::shift() == 0); 5533 constraint(ALLOC_IN_RC(ptr_reg)); 5534 match(DecodeN reg); 5535 op_cost(0); 5536 format %{ "[$reg]\t# narrow" %} 5537 interface(MEMORY_INTER) %{ 5538 base($reg); 5539 index(0xffffffff); 5540 scale(0x0); 5541 disp(0x0); 5542 %} 5543 %} 5544 5545 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5546 %{ 5547 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5548 constraint(ALLOC_IN_RC(ptr_reg)); 5549 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5550 op_cost(0); 5551 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5552 interface(MEMORY_INTER) %{ 5553 base($reg); 5554 index($ireg); 5555 scale($scale); 5556 disp(0x0); 5557 %} 5558 %} 5559 5560 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5561 %{ 5562 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5563 constraint(ALLOC_IN_RC(ptr_reg)); 5564 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5565 op_cost(0); 5566 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5567 interface(MEMORY_INTER) %{ 5568 base($reg); 5569 index($lreg); 5570 scale($scale); 5571 disp(0x0); 5572 %} 5573 %} 5574 5575 operand indIndexI2LN(iRegN reg, iRegI ireg) 5576 %{ 5577 predicate(CompressedOops::shift() == 0); 5578 constraint(ALLOC_IN_RC(ptr_reg)); 5579 match(AddP (DecodeN reg) (ConvI2L ireg)); 5580 op_cost(0); 5581 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5582 interface(MEMORY_INTER) %{ 5583 base($reg); 5584 index($ireg); 5585 scale(0x0); 5586 disp(0x0); 5587 %} 5588 %} 5589 5590 operand indIndexN(iRegN reg, iRegL lreg) 5591 %{ 5592 predicate(CompressedOops::shift() == 0); 5593 constraint(ALLOC_IN_RC(ptr_reg)); 5594 match(AddP (DecodeN reg) lreg); 5595 op_cost(0); 5596 format %{ "$reg, $lreg\t# narrow" %} 5597 interface(MEMORY_INTER) %{ 5598 base($reg); 5599 index($lreg); 5600 scale(0x0); 5601 disp(0x0); 5602 %} 5603 %} 5604 5605 operand indOffIN(iRegN reg, immIOffset off) 5606 %{ 5607 predicate(CompressedOops::shift() == 0); 5608 constraint(ALLOC_IN_RC(ptr_reg)); 5609 match(AddP (DecodeN reg) off); 5610 op_cost(0); 5611 format %{ "[$reg, $off]\t# narrow" %} 5612 interface(MEMORY_INTER) %{ 5613 base($reg); 5614 index(0xffffffff); 5615 scale(0x0); 5616 disp($off); 5617 %} 5618 %} 5619 5620 operand indOffLN(iRegN reg, immLoffset off) 5621 %{ 5622 predicate(CompressedOops::shift() == 0); 5623 constraint(ALLOC_IN_RC(ptr_reg)); 5624 match(AddP (DecodeN reg) off); 5625 op_cost(0); 5626 format %{ "[$reg, $off]\t# narrow" %} 5627 interface(MEMORY_INTER) %{ 5628 base($reg); 5629 index(0xffffffff); 5630 scale(0x0); 5631 disp($off); 5632 %} 5633 %} 5634 5635 5636 5637 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5638 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5639 %{ 5640 constraint(ALLOC_IN_RC(ptr_reg)); 5641 match(AddP reg off); 5642 op_cost(0); 5643 format %{ "[$reg, $off]" %} 5644 interface(MEMORY_INTER) %{ 5645 base($reg); 5646 index(0xffffffff); 5647 scale(0x0); 5648 disp($off); 5649 %} 5650 %} 5651 5652 //----------Special Memory Operands-------------------------------------------- 5653 // Stack Slot Operand - This operand is used for loading and storing temporary 5654 // values on the stack where a match requires a value to 5655 // flow through memory. 5656 operand stackSlotP(sRegP reg) 5657 %{ 5658 constraint(ALLOC_IN_RC(stack_slots)); 5659 op_cost(100); 5660 // No match rule because this operand is only generated in matching 5661 // match(RegP); 5662 format %{ "[$reg]" %} 5663 interface(MEMORY_INTER) %{ 5664 base(0x1e); // RSP 5665 index(0x0); // No Index 5666 scale(0x0); // No Scale 5667 disp($reg); // Stack Offset 5668 %} 5669 %} 5670 5671 operand stackSlotI(sRegI reg) 5672 %{ 5673 constraint(ALLOC_IN_RC(stack_slots)); 5674 // No match rule because this operand is only generated in matching 5675 // match(RegI); 5676 format %{ "[$reg]" %} 5677 interface(MEMORY_INTER) %{ 5678 base(0x1e); // RSP 5679 index(0x0); // No Index 5680 scale(0x0); // No Scale 5681 disp($reg); // Stack Offset 5682 %} 5683 %} 5684 5685 operand stackSlotF(sRegF reg) 5686 %{ 5687 constraint(ALLOC_IN_RC(stack_slots)); 5688 // No match rule because this operand is only generated in matching 5689 // match(RegF); 5690 format %{ "[$reg]" %} 5691 interface(MEMORY_INTER) %{ 5692 base(0x1e); // RSP 5693 index(0x0); // No Index 5694 scale(0x0); // No Scale 5695 disp($reg); // Stack Offset 5696 %} 5697 %} 5698 5699 operand stackSlotD(sRegD reg) 5700 %{ 5701 constraint(ALLOC_IN_RC(stack_slots)); 5702 // No match rule because this operand is only generated in matching 5703 // match(RegD); 5704 format %{ "[$reg]" %} 5705 interface(MEMORY_INTER) %{ 5706 base(0x1e); // RSP 5707 index(0x0); // No Index 5708 scale(0x0); // No Scale 5709 disp($reg); // Stack Offset 5710 %} 5711 %} 5712 5713 operand stackSlotL(sRegL reg) 5714 %{ 5715 constraint(ALLOC_IN_RC(stack_slots)); 5716 // No match rule because this operand is only generated in matching 5717 // match(RegL); 5718 format %{ "[$reg]" %} 5719 interface(MEMORY_INTER) %{ 5720 base(0x1e); // RSP 5721 index(0x0); // No Index 5722 scale(0x0); // No Scale 5723 disp($reg); // Stack Offset 5724 %} 5725 %} 5726 5727 // Operands for expressing Control Flow 5728 // NOTE: Label is a predefined operand which should not be redefined in 5729 // the AD file. It is generically handled within the ADLC. 5730 5731 //----------Conditional Branch Operands---------------------------------------- 5732 // Comparison Op - This is the operation of the comparison, and is limited to 5733 // the following set of codes: 5734 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5735 // 5736 // Other attributes of the comparison, such as unsignedness, are specified 5737 // by the comparison instruction that sets a condition code flags register. 5738 // That result is represented by a flags operand whose subtype is appropriate 5739 // to the unsignedness (etc.) of the comparison. 5740 // 5741 // Later, the instruction which matches both the Comparison Op (a Bool) and 5742 // the flags (produced by the Cmp) specifies the coding of the comparison op 5743 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5744 5745 // used for signed integral comparisons and fp comparisons 5746 5747 operand cmpOp() 5748 %{ 5749 match(Bool); 5750 5751 format %{ "" %} 5752 interface(COND_INTER) %{ 5753 equal(0x0, "eq"); 5754 not_equal(0x1, "ne"); 5755 less(0xb, "lt"); 5756 greater_equal(0xa, "ge"); 5757 less_equal(0xd, "le"); 5758 greater(0xc, "gt"); 5759 overflow(0x6, "vs"); 5760 no_overflow(0x7, "vc"); 5761 %} 5762 %} 5763 5764 // used for unsigned integral comparisons 5765 5766 operand cmpOpU() 5767 %{ 5768 match(Bool); 5769 5770 format %{ "" %} 5771 interface(COND_INTER) %{ 5772 equal(0x0, "eq"); 5773 not_equal(0x1, "ne"); 5774 less(0x3, "lo"); 5775 greater_equal(0x2, "hs"); 5776 less_equal(0x9, "ls"); 5777 greater(0x8, "hi"); 5778 overflow(0x6, "vs"); 5779 no_overflow(0x7, "vc"); 5780 %} 5781 %} 5782 5783 // used for certain integral comparisons which can be 5784 // converted to cbxx or tbxx instructions 5785 5786 operand cmpOpEqNe() 5787 %{ 5788 match(Bool); 5789 op_cost(0); 5790 predicate(n->as_Bool()->_test._test == BoolTest::ne 5791 || n->as_Bool()->_test._test == BoolTest::eq); 5792 5793 format %{ "" %} 5794 interface(COND_INTER) %{ 5795 equal(0x0, "eq"); 5796 not_equal(0x1, "ne"); 5797 less(0xb, "lt"); 5798 greater_equal(0xa, "ge"); 5799 less_equal(0xd, "le"); 5800 greater(0xc, "gt"); 5801 overflow(0x6, "vs"); 5802 no_overflow(0x7, "vc"); 5803 %} 5804 %} 5805 5806 // used for certain integral comparisons which can be 5807 // converted to cbxx or tbxx instructions 5808 5809 operand cmpOpLtGe() 5810 %{ 5811 match(Bool); 5812 op_cost(0); 5813 5814 predicate(n->as_Bool()->_test._test == BoolTest::lt 5815 || n->as_Bool()->_test._test == BoolTest::ge); 5816 5817 format %{ "" %} 5818 interface(COND_INTER) %{ 5819 equal(0x0, "eq"); 5820 not_equal(0x1, "ne"); 5821 less(0xb, "lt"); 5822 greater_equal(0xa, "ge"); 5823 less_equal(0xd, "le"); 5824 greater(0xc, "gt"); 5825 overflow(0x6, "vs"); 5826 no_overflow(0x7, "vc"); 5827 %} 5828 %} 5829 5830 // used for certain unsigned integral comparisons which can be 5831 // converted to cbxx or tbxx instructions 5832 5833 operand cmpOpUEqNeLtGe() 5834 %{ 5835 match(Bool); 5836 op_cost(0); 5837 5838 predicate(n->as_Bool()->_test._test == BoolTest::eq 5839 || n->as_Bool()->_test._test == BoolTest::ne 5840 || n->as_Bool()->_test._test == BoolTest::lt 5841 || n->as_Bool()->_test._test == BoolTest::ge); 5842 5843 format %{ "" %} 5844 interface(COND_INTER) %{ 5845 equal(0x0, "eq"); 5846 not_equal(0x1, "ne"); 5847 less(0xb, "lt"); 5848 greater_equal(0xa, "ge"); 5849 less_equal(0xd, "le"); 5850 greater(0xc, "gt"); 5851 overflow(0x6, "vs"); 5852 no_overflow(0x7, "vc"); 5853 %} 5854 %} 5855 5856 // Special operand allowing long args to int ops to be truncated for free 5857 5858 operand iRegL2I(iRegL reg) %{ 5859 5860 op_cost(0); 5861 5862 match(ConvL2I reg); 5863 5864 format %{ "l2i($reg)" %} 5865 5866 interface(REG_INTER) 5867 %} 5868 5869 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5870 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5871 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5872 5873 //----------OPERAND CLASSES---------------------------------------------------- 5874 // Operand Classes are groups of operands that are used as to simplify 5875 // instruction definitions by not requiring the AD writer to specify 5876 // separate instructions for every form of operand when the 5877 // instruction accepts multiple operand types with the same basic 5878 // encoding and format. The classic case of this is memory operands. 5879 5880 // memory is used to define read/write location for load/store 5881 // instruction defs. we can turn a memory op into an Address 5882 5883 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5884 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5885 5886 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5887 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5888 5889 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5890 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5891 5892 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5893 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5894 5895 // All of the memory operands. For the pipeline description. 5896 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5897 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5898 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5899 5900 5901 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5902 // operations. it allows the src to be either an iRegI or a (ConvL2I 5903 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5904 // can be elided because the 32-bit instruction will just employ the 5905 // lower 32 bits anyway. 5906 // 5907 // n.b. this does not elide all L2I conversions. if the truncated 5908 // value is consumed by more than one operation then the ConvL2I 5909 // cannot be bundled into the consuming nodes so an l2i gets planted 5910 // (actually a movw $dst $src) and the downstream instructions consume 5911 // the result of the l2i as an iRegI input. That's a shame since the 5912 // movw is actually redundant but its not too costly. 5913 5914 opclass iRegIorL2I(iRegI, iRegL2I); 5915 5916 //----------PIPELINE----------------------------------------------------------- 5917 // Rules which define the behavior of the target architectures pipeline. 5918 5919 // For specific pipelines, eg A53, define the stages of that pipeline 5920 //pipe_desc(ISS, EX1, EX2, WR); 5921 #define ISS S0 5922 #define EX1 S1 5923 #define EX2 S2 5924 #define WR S3 5925 5926 // Integer ALU reg operation 5927 pipeline %{ 5928 5929 attributes %{ 5930 // ARM instructions are of fixed length 5931 fixed_size_instructions; // Fixed size instructions TODO does 5932 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5933 // ARM instructions come in 32-bit word units 5934 instruction_unit_size = 4; // An instruction is 4 bytes long 5935 instruction_fetch_unit_size = 64; // The processor fetches one line 5936 instruction_fetch_units = 1; // of 64 bytes 5937 5938 // List of nop instructions 5939 nops( MachNop ); 5940 %} 5941 5942 // We don't use an actual pipeline model so don't care about resources 5943 // or description. we do use pipeline classes to introduce fixed 5944 // latencies 5945 5946 //----------RESOURCES---------------------------------------------------------- 5947 // Resources are the functional units available to the machine 5948 5949 resources( INS0, INS1, INS01 = INS0 | INS1, 5950 ALU0, ALU1, ALU = ALU0 | ALU1, 5951 MAC, 5952 DIV, 5953 BRANCH, 5954 LDST, 5955 NEON_FP); 5956 5957 //----------PIPELINE DESCRIPTION----------------------------------------------- 5958 // Pipeline Description specifies the stages in the machine's pipeline 5959 5960 // Define the pipeline as a generic 6 stage pipeline 5961 pipe_desc(S0, S1, S2, S3, S4, S5); 5962 5963 //----------PIPELINE CLASSES--------------------------------------------------- 5964 // Pipeline Classes describe the stages in which input and output are 5965 // referenced by the hardware pipeline. 5966 5967 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5968 %{ 5969 single_instruction; 5970 src1 : S1(read); 5971 src2 : S2(read); 5972 dst : S5(write); 5973 INS01 : ISS; 5974 NEON_FP : S5; 5975 %} 5976 5977 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5978 %{ 5979 single_instruction; 5980 src1 : S1(read); 5981 src2 : S2(read); 5982 dst : S5(write); 5983 INS01 : ISS; 5984 NEON_FP : S5; 5985 %} 5986 5987 pipe_class fp_uop_s(vRegF dst, vRegF src) 5988 %{ 5989 single_instruction; 5990 src : S1(read); 5991 dst : S5(write); 5992 INS01 : ISS; 5993 NEON_FP : S5; 5994 %} 5995 5996 pipe_class fp_uop_d(vRegD dst, vRegD src) 5997 %{ 5998 single_instruction; 5999 src : S1(read); 6000 dst : S5(write); 6001 INS01 : ISS; 6002 NEON_FP : S5; 6003 %} 6004 6005 pipe_class fp_d2f(vRegF dst, vRegD src) 6006 %{ 6007 single_instruction; 6008 src : S1(read); 6009 dst : S5(write); 6010 INS01 : ISS; 6011 NEON_FP : S5; 6012 %} 6013 6014 pipe_class fp_f2d(vRegD dst, vRegF src) 6015 %{ 6016 single_instruction; 6017 src : S1(read); 6018 dst : S5(write); 6019 INS01 : ISS; 6020 NEON_FP : S5; 6021 %} 6022 6023 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 6024 %{ 6025 single_instruction; 6026 src : S1(read); 6027 dst : S5(write); 6028 INS01 : ISS; 6029 NEON_FP : S5; 6030 %} 6031 6032 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6033 %{ 6034 single_instruction; 6035 src : S1(read); 6036 dst : S5(write); 6037 INS01 : ISS; 6038 NEON_FP : S5; 6039 %} 6040 6041 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6042 %{ 6043 single_instruction; 6044 src : S1(read); 6045 dst : S5(write); 6046 INS01 : ISS; 6047 NEON_FP : S5; 6048 %} 6049 6050 pipe_class fp_l2f(vRegF dst, iRegL src) 6051 %{ 6052 single_instruction; 6053 src : S1(read); 6054 dst : S5(write); 6055 INS01 : ISS; 6056 NEON_FP : S5; 6057 %} 6058 6059 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6060 %{ 6061 single_instruction; 6062 src : S1(read); 6063 dst : S5(write); 6064 INS01 : ISS; 6065 NEON_FP : S5; 6066 %} 6067 6068 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6069 %{ 6070 single_instruction; 6071 src : S1(read); 6072 dst : S5(write); 6073 INS01 : ISS; 6074 NEON_FP : S5; 6075 %} 6076 6077 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6078 %{ 6079 single_instruction; 6080 src : S1(read); 6081 dst : S5(write); 6082 INS01 : ISS; 6083 NEON_FP : S5; 6084 %} 6085 6086 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6087 %{ 6088 single_instruction; 6089 src : S1(read); 6090 dst : S5(write); 6091 INS01 : ISS; 6092 NEON_FP : S5; 6093 %} 6094 6095 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6096 %{ 6097 single_instruction; 6098 src1 : S1(read); 6099 src2 : S2(read); 6100 dst : S5(write); 6101 INS0 : ISS; 6102 NEON_FP : S5; 6103 %} 6104 6105 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6106 %{ 6107 single_instruction; 6108 src1 : S1(read); 6109 src2 : S2(read); 6110 dst : S5(write); 6111 INS0 : ISS; 6112 NEON_FP : S5; 6113 %} 6114 6115 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6116 %{ 6117 single_instruction; 6118 cr : S1(read); 6119 src1 : S1(read); 6120 src2 : S1(read); 6121 dst : S3(write); 6122 INS01 : ISS; 6123 NEON_FP : S3; 6124 %} 6125 6126 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6127 %{ 6128 single_instruction; 6129 cr : S1(read); 6130 src1 : S1(read); 6131 src2 : S1(read); 6132 dst : S3(write); 6133 INS01 : ISS; 6134 NEON_FP : S3; 6135 %} 6136 6137 pipe_class fp_imm_s(vRegF dst) 6138 %{ 6139 single_instruction; 6140 dst : S3(write); 6141 INS01 : ISS; 6142 NEON_FP : S3; 6143 %} 6144 6145 pipe_class fp_imm_d(vRegD dst) 6146 %{ 6147 single_instruction; 6148 dst : S3(write); 6149 INS01 : ISS; 6150 NEON_FP : S3; 6151 %} 6152 6153 pipe_class fp_load_constant_s(vRegF dst) 6154 %{ 6155 single_instruction; 6156 dst : S4(write); 6157 INS01 : ISS; 6158 NEON_FP : S4; 6159 %} 6160 6161 pipe_class fp_load_constant_d(vRegD dst) 6162 %{ 6163 single_instruction; 6164 dst : S4(write); 6165 INS01 : ISS; 6166 NEON_FP : S4; 6167 %} 6168 6169 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6170 %{ 6171 single_instruction; 6172 dst : S5(write); 6173 src1 : S1(read); 6174 src2 : S1(read); 6175 INS01 : ISS; 6176 NEON_FP : S5; 6177 %} 6178 6179 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6180 %{ 6181 single_instruction; 6182 dst : S5(write); 6183 src1 : S1(read); 6184 src2 : S1(read); 6185 INS0 : ISS; 6186 NEON_FP : S5; 6187 %} 6188 6189 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6190 %{ 6191 single_instruction; 6192 dst : S5(write); 6193 src1 : S1(read); 6194 src2 : S1(read); 6195 dst : S1(read); 6196 INS01 : ISS; 6197 NEON_FP : S5; 6198 %} 6199 6200 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6201 %{ 6202 single_instruction; 6203 dst : S5(write); 6204 src1 : S1(read); 6205 src2 : S1(read); 6206 dst : S1(read); 6207 INS0 : ISS; 6208 NEON_FP : S5; 6209 %} 6210 6211 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6212 %{ 6213 single_instruction; 6214 dst : S4(write); 6215 src1 : S2(read); 6216 src2 : S2(read); 6217 INS01 : ISS; 6218 NEON_FP : S4; 6219 %} 6220 6221 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6222 %{ 6223 single_instruction; 6224 dst : S4(write); 6225 src1 : S2(read); 6226 src2 : S2(read); 6227 INS0 : ISS; 6228 NEON_FP : S4; 6229 %} 6230 6231 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6232 %{ 6233 single_instruction; 6234 dst : S3(write); 6235 src1 : S2(read); 6236 src2 : S2(read); 6237 INS01 : ISS; 6238 NEON_FP : S3; 6239 %} 6240 6241 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6242 %{ 6243 single_instruction; 6244 dst : S3(write); 6245 src1 : S2(read); 6246 src2 : S2(read); 6247 INS0 : ISS; 6248 NEON_FP : S3; 6249 %} 6250 6251 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6252 %{ 6253 single_instruction; 6254 dst : S3(write); 6255 src : S1(read); 6256 shift : S1(read); 6257 INS01 : ISS; 6258 NEON_FP : S3; 6259 %} 6260 6261 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6262 %{ 6263 single_instruction; 6264 dst : S3(write); 6265 src : S1(read); 6266 shift : S1(read); 6267 INS0 : ISS; 6268 NEON_FP : S3; 6269 %} 6270 6271 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6272 %{ 6273 single_instruction; 6274 dst : S3(write); 6275 src : S1(read); 6276 INS01 : ISS; 6277 NEON_FP : S3; 6278 %} 6279 6280 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6281 %{ 6282 single_instruction; 6283 dst : S3(write); 6284 src : S1(read); 6285 INS0 : ISS; 6286 NEON_FP : S3; 6287 %} 6288 6289 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6290 %{ 6291 single_instruction; 6292 dst : S5(write); 6293 src1 : S1(read); 6294 src2 : S1(read); 6295 INS01 : ISS; 6296 NEON_FP : S5; 6297 %} 6298 6299 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6300 %{ 6301 single_instruction; 6302 dst : S5(write); 6303 src1 : S1(read); 6304 src2 : S1(read); 6305 INS0 : ISS; 6306 NEON_FP : S5; 6307 %} 6308 6309 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6310 %{ 6311 single_instruction; 6312 dst : S5(write); 6313 src1 : S1(read); 6314 src2 : S1(read); 6315 INS0 : ISS; 6316 NEON_FP : S5; 6317 %} 6318 6319 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6320 %{ 6321 single_instruction; 6322 dst : S5(write); 6323 src1 : S1(read); 6324 src2 : S1(read); 6325 INS0 : ISS; 6326 NEON_FP : S5; 6327 %} 6328 6329 pipe_class vsqrt_fp128(vecX dst, vecX src) 6330 %{ 6331 single_instruction; 6332 dst : S5(write); 6333 src : S1(read); 6334 INS0 : ISS; 6335 NEON_FP : S5; 6336 %} 6337 6338 pipe_class vunop_fp64(vecD dst, vecD src) 6339 %{ 6340 single_instruction; 6341 dst : S5(write); 6342 src : S1(read); 6343 INS01 : ISS; 6344 NEON_FP : S5; 6345 %} 6346 6347 pipe_class vunop_fp128(vecX dst, vecX src) 6348 %{ 6349 single_instruction; 6350 dst : S5(write); 6351 src : S1(read); 6352 INS0 : ISS; 6353 NEON_FP : S5; 6354 %} 6355 6356 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6357 %{ 6358 single_instruction; 6359 dst : S3(write); 6360 src : S1(read); 6361 INS01 : ISS; 6362 NEON_FP : S3; 6363 %} 6364 6365 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6366 %{ 6367 single_instruction; 6368 dst : S3(write); 6369 src : S1(read); 6370 INS01 : ISS; 6371 NEON_FP : S3; 6372 %} 6373 6374 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6375 %{ 6376 single_instruction; 6377 dst : S3(write); 6378 src : S1(read); 6379 INS01 : ISS; 6380 NEON_FP : S3; 6381 %} 6382 6383 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6384 %{ 6385 single_instruction; 6386 dst : S3(write); 6387 src : S1(read); 6388 INS01 : ISS; 6389 NEON_FP : S3; 6390 %} 6391 6392 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6393 %{ 6394 single_instruction; 6395 dst : S3(write); 6396 src : S1(read); 6397 INS01 : ISS; 6398 NEON_FP : S3; 6399 %} 6400 6401 pipe_class vmovi_reg_imm64(vecD dst) 6402 %{ 6403 single_instruction; 6404 dst : S3(write); 6405 INS01 : ISS; 6406 NEON_FP : S3; 6407 %} 6408 6409 pipe_class vmovi_reg_imm128(vecX dst) 6410 %{ 6411 single_instruction; 6412 dst : S3(write); 6413 INS0 : ISS; 6414 NEON_FP : S3; 6415 %} 6416 6417 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6418 %{ 6419 single_instruction; 6420 dst : S5(write); 6421 mem : ISS(read); 6422 INS01 : ISS; 6423 NEON_FP : S3; 6424 %} 6425 6426 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6427 %{ 6428 single_instruction; 6429 dst : S5(write); 6430 mem : ISS(read); 6431 INS01 : ISS; 6432 NEON_FP : S3; 6433 %} 6434 6435 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6436 %{ 6437 single_instruction; 6438 mem : ISS(read); 6439 src : S2(read); 6440 INS01 : ISS; 6441 NEON_FP : S3; 6442 %} 6443 6444 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6445 %{ 6446 single_instruction; 6447 mem : ISS(read); 6448 src : S2(read); 6449 INS01 : ISS; 6450 NEON_FP : S3; 6451 %} 6452 6453 //------- Integer ALU operations -------------------------- 6454 6455 // Integer ALU reg-reg operation 6456 // Operands needed in EX1, result generated in EX2 6457 // Eg. ADD x0, x1, x2 6458 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6459 %{ 6460 single_instruction; 6461 dst : EX2(write); 6462 src1 : EX1(read); 6463 src2 : EX1(read); 6464 INS01 : ISS; // Dual issue as instruction 0 or 1 6465 ALU : EX2; 6466 %} 6467 6468 // Integer ALU reg-reg operation with constant shift 6469 // Shifted register must be available in LATE_ISS instead of EX1 6470 // Eg. ADD x0, x1, x2, LSL #2 6471 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6472 %{ 6473 single_instruction; 6474 dst : EX2(write); 6475 src1 : EX1(read); 6476 src2 : ISS(read); 6477 INS01 : ISS; 6478 ALU : EX2; 6479 %} 6480 6481 // Integer ALU reg operation with constant shift 6482 // Eg. LSL x0, x1, #shift 6483 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6484 %{ 6485 single_instruction; 6486 dst : EX2(write); 6487 src1 : ISS(read); 6488 INS01 : ISS; 6489 ALU : EX2; 6490 %} 6491 6492 // Integer ALU reg-reg operation with variable shift 6493 // Both operands must be available in LATE_ISS instead of EX1 6494 // Result is available in EX1 instead of EX2 6495 // Eg. LSLV x0, x1, x2 6496 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6497 %{ 6498 single_instruction; 6499 dst : EX1(write); 6500 src1 : ISS(read); 6501 src2 : ISS(read); 6502 INS01 : ISS; 6503 ALU : EX1; 6504 %} 6505 6506 // Integer ALU reg-reg operation with extract 6507 // As for _vshift above, but result generated in EX2 6508 // Eg. EXTR x0, x1, x2, #N 6509 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6510 %{ 6511 single_instruction; 6512 dst : EX2(write); 6513 src1 : ISS(read); 6514 src2 : ISS(read); 6515 INS1 : ISS; // Can only dual issue as Instruction 1 6516 ALU : EX1; 6517 %} 6518 6519 // Integer ALU reg operation 6520 // Eg. NEG x0, x1 6521 pipe_class ialu_reg(iRegI dst, iRegI src) 6522 %{ 6523 single_instruction; 6524 dst : EX2(write); 6525 src : EX1(read); 6526 INS01 : ISS; 6527 ALU : EX2; 6528 %} 6529 6530 // Integer ALU reg mmediate operation 6531 // Eg. ADD x0, x1, #N 6532 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6533 %{ 6534 single_instruction; 6535 dst : EX2(write); 6536 src1 : EX1(read); 6537 INS01 : ISS; 6538 ALU : EX2; 6539 %} 6540 6541 // Integer ALU immediate operation (no source operands) 6542 // Eg. MOV x0, #N 6543 pipe_class ialu_imm(iRegI dst) 6544 %{ 6545 single_instruction; 6546 dst : EX1(write); 6547 INS01 : ISS; 6548 ALU : EX1; 6549 %} 6550 6551 //------- Compare operation ------------------------------- 6552 6553 // Compare reg-reg 6554 // Eg. CMP x0, x1 6555 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6556 %{ 6557 single_instruction; 6558 // fixed_latency(16); 6559 cr : EX2(write); 6560 op1 : EX1(read); 6561 op2 : EX1(read); 6562 INS01 : ISS; 6563 ALU : EX2; 6564 %} 6565 6566 // Compare reg-reg 6567 // Eg. CMP x0, #N 6568 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6569 %{ 6570 single_instruction; 6571 // fixed_latency(16); 6572 cr : EX2(write); 6573 op1 : EX1(read); 6574 INS01 : ISS; 6575 ALU : EX2; 6576 %} 6577 6578 //------- Conditional instructions ------------------------ 6579 6580 // Conditional no operands 6581 // Eg. CSINC x0, zr, zr, <cond> 6582 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6583 %{ 6584 single_instruction; 6585 cr : EX1(read); 6586 dst : EX2(write); 6587 INS01 : ISS; 6588 ALU : EX2; 6589 %} 6590 6591 // Conditional 2 operand 6592 // EG. CSEL X0, X1, X2, <cond> 6593 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6594 %{ 6595 single_instruction; 6596 cr : EX1(read); 6597 src1 : EX1(read); 6598 src2 : EX1(read); 6599 dst : EX2(write); 6600 INS01 : ISS; 6601 ALU : EX2; 6602 %} 6603 6604 // Conditional 2 operand 6605 // EG. CSEL X0, X1, X2, <cond> 6606 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6607 %{ 6608 single_instruction; 6609 cr : EX1(read); 6610 src : EX1(read); 6611 dst : EX2(write); 6612 INS01 : ISS; 6613 ALU : EX2; 6614 %} 6615 6616 //------- Multiply pipeline operations -------------------- 6617 6618 // Multiply reg-reg 6619 // Eg. MUL w0, w1, w2 6620 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6621 %{ 6622 single_instruction; 6623 dst : WR(write); 6624 src1 : ISS(read); 6625 src2 : ISS(read); 6626 INS01 : ISS; 6627 MAC : WR; 6628 %} 6629 6630 // Multiply accumulate 6631 // Eg. MADD w0, w1, w2, w3 6632 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6633 %{ 6634 single_instruction; 6635 dst : WR(write); 6636 src1 : ISS(read); 6637 src2 : ISS(read); 6638 src3 : ISS(read); 6639 INS01 : ISS; 6640 MAC : WR; 6641 %} 6642 6643 // Eg. MUL w0, w1, w2 6644 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6645 %{ 6646 single_instruction; 6647 fixed_latency(3); // Maximum latency for 64 bit mul 6648 dst : WR(write); 6649 src1 : ISS(read); 6650 src2 : ISS(read); 6651 INS01 : ISS; 6652 MAC : WR; 6653 %} 6654 6655 // Multiply accumulate 6656 // Eg. MADD w0, w1, w2, w3 6657 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6658 %{ 6659 single_instruction; 6660 fixed_latency(3); // Maximum latency for 64 bit mul 6661 dst : WR(write); 6662 src1 : ISS(read); 6663 src2 : ISS(read); 6664 src3 : ISS(read); 6665 INS01 : ISS; 6666 MAC : WR; 6667 %} 6668 6669 //------- Divide pipeline operations -------------------- 6670 6671 // Eg. SDIV w0, w1, w2 6672 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6673 %{ 6674 single_instruction; 6675 fixed_latency(8); // Maximum latency for 32 bit divide 6676 dst : WR(write); 6677 src1 : ISS(read); 6678 src2 : ISS(read); 6679 INS0 : ISS; // Can only dual issue as instruction 0 6680 DIV : WR; 6681 %} 6682 6683 // Eg. SDIV x0, x1, x2 6684 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6685 %{ 6686 single_instruction; 6687 fixed_latency(16); // Maximum latency for 64 bit divide 6688 dst : WR(write); 6689 src1 : ISS(read); 6690 src2 : ISS(read); 6691 INS0 : ISS; // Can only dual issue as instruction 0 6692 DIV : WR; 6693 %} 6694 6695 //------- Load pipeline operations ------------------------ 6696 6697 // Load - prefetch 6698 // Eg. PFRM <mem> 6699 pipe_class iload_prefetch(memory mem) 6700 %{ 6701 single_instruction; 6702 mem : ISS(read); 6703 INS01 : ISS; 6704 LDST : WR; 6705 %} 6706 6707 // Load - reg, mem 6708 // Eg. LDR x0, <mem> 6709 pipe_class iload_reg_mem(iRegI dst, memory mem) 6710 %{ 6711 single_instruction; 6712 dst : WR(write); 6713 mem : ISS(read); 6714 INS01 : ISS; 6715 LDST : WR; 6716 %} 6717 6718 // Load - reg, reg 6719 // Eg. LDR x0, [sp, x1] 6720 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6721 %{ 6722 single_instruction; 6723 dst : WR(write); 6724 src : ISS(read); 6725 INS01 : ISS; 6726 LDST : WR; 6727 %} 6728 6729 //------- Store pipeline operations ----------------------- 6730 6731 // Store - zr, mem 6732 // Eg. STR zr, <mem> 6733 pipe_class istore_mem(memory mem) 6734 %{ 6735 single_instruction; 6736 mem : ISS(read); 6737 INS01 : ISS; 6738 LDST : WR; 6739 %} 6740 6741 // Store - reg, mem 6742 // Eg. STR x0, <mem> 6743 pipe_class istore_reg_mem(iRegI src, memory mem) 6744 %{ 6745 single_instruction; 6746 mem : ISS(read); 6747 src : EX2(read); 6748 INS01 : ISS; 6749 LDST : WR; 6750 %} 6751 6752 // Store - reg, reg 6753 // Eg. STR x0, [sp, x1] 6754 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6755 %{ 6756 single_instruction; 6757 dst : ISS(read); 6758 src : EX2(read); 6759 INS01 : ISS; 6760 LDST : WR; 6761 %} 6762 6763 //------- Store pipeline operations ----------------------- 6764 6765 // Branch 6766 pipe_class pipe_branch() 6767 %{ 6768 single_instruction; 6769 INS01 : ISS; 6770 BRANCH : EX1; 6771 %} 6772 6773 // Conditional branch 6774 pipe_class pipe_branch_cond(rFlagsReg cr) 6775 %{ 6776 single_instruction; 6777 cr : EX1(read); 6778 INS01 : ISS; 6779 BRANCH : EX1; 6780 %} 6781 6782 // Compare & Branch 6783 // EG. CBZ/CBNZ 6784 pipe_class pipe_cmp_branch(iRegI op1) 6785 %{ 6786 single_instruction; 6787 op1 : EX1(read); 6788 INS01 : ISS; 6789 BRANCH : EX1; 6790 %} 6791 6792 //------- Synchronisation operations ---------------------- 6793 6794 // Any operation requiring serialization. 6795 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6796 pipe_class pipe_serial() 6797 %{ 6798 single_instruction; 6799 force_serialization; 6800 fixed_latency(16); 6801 INS01 : ISS(2); // Cannot dual issue with any other instruction 6802 LDST : WR; 6803 %} 6804 6805 // Generic big/slow expanded idiom - also serialized 6806 pipe_class pipe_slow() 6807 %{ 6808 instruction_count(10); 6809 multiple_bundles; 6810 force_serialization; 6811 fixed_latency(16); 6812 INS01 : ISS(2); // Cannot dual issue with any other instruction 6813 LDST : WR; 6814 %} 6815 6816 // Empty pipeline class 6817 pipe_class pipe_class_empty() 6818 %{ 6819 single_instruction; 6820 fixed_latency(0); 6821 %} 6822 6823 // Default pipeline class. 6824 pipe_class pipe_class_default() 6825 %{ 6826 single_instruction; 6827 fixed_latency(2); 6828 %} 6829 6830 // Pipeline class for compares. 6831 pipe_class pipe_class_compare() 6832 %{ 6833 single_instruction; 6834 fixed_latency(16); 6835 %} 6836 6837 // Pipeline class for memory operations. 6838 pipe_class pipe_class_memory() 6839 %{ 6840 single_instruction; 6841 fixed_latency(16); 6842 %} 6843 6844 // Pipeline class for call. 6845 pipe_class pipe_class_call() 6846 %{ 6847 single_instruction; 6848 fixed_latency(100); 6849 %} 6850 6851 // Define the class for the Nop node. 6852 define %{ 6853 MachNop = pipe_class_empty; 6854 %} 6855 6856 %} 6857 //----------INSTRUCTIONS------------------------------------------------------- 6858 // 6859 // match -- States which machine-independent subtree may be replaced 6860 // by this instruction. 6861 // ins_cost -- The estimated cost of this instruction is used by instruction 6862 // selection to identify a minimum cost tree of machine 6863 // instructions that matches a tree of machine-independent 6864 // instructions. 6865 // format -- A string providing the disassembly for this instruction. 6866 // The value of an instruction's operand may be inserted 6867 // by referring to it with a '$' prefix. 6868 // opcode -- Three instruction opcodes may be provided. These are referred 6869 // to within an encode class as $primary, $secondary, and $tertiary 6870 // rrspectively. The primary opcode is commonly used to 6871 // indicate the type of machine instruction, while secondary 6872 // and tertiary are often used for prefix options or addressing 6873 // modes. 6874 // ins_encode -- A list of encode classes with parameters. The encode class 6875 // name must have been defined in an 'enc_class' specification 6876 // in the encode section of the architecture description. 6877 6878 // ============================================================================ 6879 // Memory (Load/Store) Instructions 6880 6881 // Load Instructions 6882 6883 // Load Byte (8 bit signed) 6884 instruct loadB(iRegINoSp dst, memory1 mem) 6885 %{ 6886 match(Set dst (LoadB mem)); 6887 predicate(!needs_acquiring_load(n)); 6888 6889 ins_cost(4 * INSN_COST); 6890 format %{ "ldrsbw $dst, $mem\t# byte" %} 6891 6892 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6893 6894 ins_pipe(iload_reg_mem); 6895 %} 6896 6897 // Load Byte (8 bit signed) into long 6898 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6899 %{ 6900 match(Set dst (ConvI2L (LoadB mem))); 6901 predicate(!needs_acquiring_load(n->in(1))); 6902 6903 ins_cost(4 * INSN_COST); 6904 format %{ "ldrsb $dst, $mem\t# byte" %} 6905 6906 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6907 6908 ins_pipe(iload_reg_mem); 6909 %} 6910 6911 // Load Byte (8 bit unsigned) 6912 instruct loadUB(iRegINoSp dst, memory1 mem) 6913 %{ 6914 match(Set dst (LoadUB mem)); 6915 predicate(!needs_acquiring_load(n)); 6916 6917 ins_cost(4 * INSN_COST); 6918 format %{ "ldrbw $dst, $mem\t# byte" %} 6919 6920 ins_encode(aarch64_enc_ldrb(dst, mem)); 6921 6922 ins_pipe(iload_reg_mem); 6923 %} 6924 6925 // Load Byte (8 bit unsigned) into long 6926 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6927 %{ 6928 match(Set dst (ConvI2L (LoadUB mem))); 6929 predicate(!needs_acquiring_load(n->in(1))); 6930 6931 ins_cost(4 * INSN_COST); 6932 format %{ "ldrb $dst, $mem\t# byte" %} 6933 6934 ins_encode(aarch64_enc_ldrb(dst, mem)); 6935 6936 ins_pipe(iload_reg_mem); 6937 %} 6938 6939 // Load Short (16 bit signed) 6940 instruct loadS(iRegINoSp dst, memory2 mem) 6941 %{ 6942 match(Set dst (LoadS mem)); 6943 predicate(!needs_acquiring_load(n)); 6944 6945 ins_cost(4 * INSN_COST); 6946 format %{ "ldrshw $dst, $mem\t# short" %} 6947 6948 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6949 6950 ins_pipe(iload_reg_mem); 6951 %} 6952 6953 // Load Short (16 bit signed) into long 6954 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6955 %{ 6956 match(Set dst (ConvI2L (LoadS mem))); 6957 predicate(!needs_acquiring_load(n->in(1))); 6958 6959 ins_cost(4 * INSN_COST); 6960 format %{ "ldrsh $dst, $mem\t# short" %} 6961 6962 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6963 6964 ins_pipe(iload_reg_mem); 6965 %} 6966 6967 // Load Char (16 bit unsigned) 6968 instruct loadUS(iRegINoSp dst, memory2 mem) 6969 %{ 6970 match(Set dst (LoadUS mem)); 6971 predicate(!needs_acquiring_load(n)); 6972 6973 ins_cost(4 * INSN_COST); 6974 format %{ "ldrh $dst, $mem\t# short" %} 6975 6976 ins_encode(aarch64_enc_ldrh(dst, mem)); 6977 6978 ins_pipe(iload_reg_mem); 6979 %} 6980 6981 // Load Short/Char (16 bit unsigned) into long 6982 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6983 %{ 6984 match(Set dst (ConvI2L (LoadUS mem))); 6985 predicate(!needs_acquiring_load(n->in(1))); 6986 6987 ins_cost(4 * INSN_COST); 6988 format %{ "ldrh $dst, $mem\t# short" %} 6989 6990 ins_encode(aarch64_enc_ldrh(dst, mem)); 6991 6992 ins_pipe(iload_reg_mem); 6993 %} 6994 6995 // Load Integer (32 bit signed) 6996 instruct loadI(iRegINoSp dst, memory4 mem) 6997 %{ 6998 match(Set dst (LoadI mem)); 6999 predicate(!needs_acquiring_load(n)); 7000 7001 ins_cost(4 * INSN_COST); 7002 format %{ "ldrw $dst, $mem\t# int" %} 7003 7004 ins_encode(aarch64_enc_ldrw(dst, mem)); 7005 7006 ins_pipe(iload_reg_mem); 7007 %} 7008 7009 // Load Integer (32 bit signed) into long 7010 instruct loadI2L(iRegLNoSp dst, memory4 mem) 7011 %{ 7012 match(Set dst (ConvI2L (LoadI mem))); 7013 predicate(!needs_acquiring_load(n->in(1))); 7014 7015 ins_cost(4 * INSN_COST); 7016 format %{ "ldrsw $dst, $mem\t# int" %} 7017 7018 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7019 7020 ins_pipe(iload_reg_mem); 7021 %} 7022 7023 // Load Integer (32 bit unsigned) into long 7024 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7025 %{ 7026 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7027 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7028 7029 ins_cost(4 * INSN_COST); 7030 format %{ "ldrw $dst, $mem\t# int" %} 7031 7032 ins_encode(aarch64_enc_ldrw(dst, mem)); 7033 7034 ins_pipe(iload_reg_mem); 7035 %} 7036 7037 // Load Long (64 bit signed) 7038 instruct loadL(iRegLNoSp dst, memory8 mem) 7039 %{ 7040 match(Set dst (LoadL mem)); 7041 predicate(!needs_acquiring_load(n)); 7042 7043 ins_cost(4 * INSN_COST); 7044 format %{ "ldr $dst, $mem\t# int" %} 7045 7046 ins_encode(aarch64_enc_ldr(dst, mem)); 7047 7048 ins_pipe(iload_reg_mem); 7049 %} 7050 7051 // Load Range 7052 instruct loadRange(iRegINoSp dst, memory4 mem) 7053 %{ 7054 match(Set dst (LoadRange mem)); 7055 7056 ins_cost(4 * INSN_COST); 7057 format %{ "ldrw $dst, $mem\t# range" %} 7058 7059 ins_encode(aarch64_enc_ldrw(dst, mem)); 7060 7061 ins_pipe(iload_reg_mem); 7062 %} 7063 7064 // Load Pointer 7065 instruct loadP(iRegPNoSp dst, memory8 mem) 7066 %{ 7067 match(Set dst (LoadP mem)); 7068 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7069 7070 ins_cost(4 * INSN_COST); 7071 format %{ "ldr $dst, $mem\t# ptr" %} 7072 7073 ins_encode(aarch64_enc_ldr(dst, mem)); 7074 7075 ins_pipe(iload_reg_mem); 7076 %} 7077 7078 // Load Compressed Pointer 7079 instruct loadN(iRegNNoSp dst, memory4 mem) 7080 %{ 7081 match(Set dst (LoadN mem)); 7082 predicate(!needs_acquiring_load(n)); 7083 7084 ins_cost(4 * INSN_COST); 7085 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7086 7087 ins_encode(aarch64_enc_ldrw(dst, mem)); 7088 7089 ins_pipe(iload_reg_mem); 7090 %} 7091 7092 // Load Klass Pointer 7093 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7094 %{ 7095 match(Set dst (LoadKlass mem)); 7096 predicate(!needs_acquiring_load(n)); 7097 7098 ins_cost(4 * INSN_COST); 7099 format %{ "ldr $dst, $mem\t# class" %} 7100 7101 ins_encode(aarch64_enc_ldr(dst, mem)); 7102 7103 ins_pipe(iload_reg_mem); 7104 %} 7105 7106 // Load Narrow Klass Pointer 7107 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7108 %{ 7109 match(Set dst (LoadNKlass mem)); 7110 predicate(!needs_acquiring_load(n)); 7111 7112 ins_cost(4 * INSN_COST); 7113 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7114 7115 ins_encode(aarch64_enc_ldrw(dst, mem)); 7116 7117 ins_pipe(iload_reg_mem); 7118 %} 7119 7120 // Load Float 7121 instruct loadF(vRegF dst, memory4 mem) 7122 %{ 7123 match(Set dst (LoadF mem)); 7124 predicate(!needs_acquiring_load(n)); 7125 7126 ins_cost(4 * INSN_COST); 7127 format %{ "ldrs $dst, $mem\t# float" %} 7128 7129 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7130 7131 ins_pipe(pipe_class_memory); 7132 %} 7133 7134 // Load Double 7135 instruct loadD(vRegD dst, memory8 mem) 7136 %{ 7137 match(Set dst (LoadD mem)); 7138 predicate(!needs_acquiring_load(n)); 7139 7140 ins_cost(4 * INSN_COST); 7141 format %{ "ldrd $dst, $mem\t# double" %} 7142 7143 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7144 7145 ins_pipe(pipe_class_memory); 7146 %} 7147 7148 7149 // Load Int Constant 7150 instruct loadConI(iRegINoSp dst, immI src) 7151 %{ 7152 match(Set dst src); 7153 7154 ins_cost(INSN_COST); 7155 format %{ "mov $dst, $src\t# int" %} 7156 7157 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7158 7159 ins_pipe(ialu_imm); 7160 %} 7161 7162 // Load Long Constant 7163 instruct loadConL(iRegLNoSp dst, immL src) 7164 %{ 7165 match(Set dst src); 7166 7167 ins_cost(INSN_COST); 7168 format %{ "mov $dst, $src\t# long" %} 7169 7170 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7171 7172 ins_pipe(ialu_imm); 7173 %} 7174 7175 // Load Pointer Constant 7176 7177 instruct loadConP(iRegPNoSp dst, immP con) 7178 %{ 7179 match(Set dst con); 7180 7181 ins_cost(INSN_COST * 4); 7182 format %{ 7183 "mov $dst, $con\t# ptr\n\t" 7184 %} 7185 7186 ins_encode(aarch64_enc_mov_p(dst, con)); 7187 7188 ins_pipe(ialu_imm); 7189 %} 7190 7191 // Load Null Pointer Constant 7192 7193 instruct loadConP0(iRegPNoSp dst, immP0 con) 7194 %{ 7195 match(Set dst con); 7196 7197 ins_cost(INSN_COST); 7198 format %{ "mov $dst, $con\t# NULL ptr" %} 7199 7200 ins_encode(aarch64_enc_mov_p0(dst, con)); 7201 7202 ins_pipe(ialu_imm); 7203 %} 7204 7205 // Load Pointer Constant One 7206 7207 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7208 %{ 7209 match(Set dst con); 7210 7211 ins_cost(INSN_COST); 7212 format %{ "mov $dst, $con\t# NULL ptr" %} 7213 7214 ins_encode(aarch64_enc_mov_p1(dst, con)); 7215 7216 ins_pipe(ialu_imm); 7217 %} 7218 7219 // Load Byte Map Base Constant 7220 7221 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7222 %{ 7223 match(Set dst con); 7224 7225 ins_cost(INSN_COST); 7226 format %{ "adr $dst, $con\t# Byte Map Base" %} 7227 7228 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7229 7230 ins_pipe(ialu_imm); 7231 %} 7232 7233 // Load Narrow Pointer Constant 7234 7235 instruct loadConN(iRegNNoSp dst, immN con) 7236 %{ 7237 match(Set dst con); 7238 7239 ins_cost(INSN_COST * 4); 7240 format %{ "mov $dst, $con\t# compressed ptr" %} 7241 7242 ins_encode(aarch64_enc_mov_n(dst, con)); 7243 7244 ins_pipe(ialu_imm); 7245 %} 7246 7247 // Load Narrow Null Pointer Constant 7248 7249 instruct loadConN0(iRegNNoSp dst, immN0 con) 7250 %{ 7251 match(Set dst con); 7252 7253 ins_cost(INSN_COST); 7254 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7255 7256 ins_encode(aarch64_enc_mov_n0(dst, con)); 7257 7258 ins_pipe(ialu_imm); 7259 %} 7260 7261 // Load Narrow Klass Constant 7262 7263 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7264 %{ 7265 match(Set dst con); 7266 7267 ins_cost(INSN_COST); 7268 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7269 7270 ins_encode(aarch64_enc_mov_nk(dst, con)); 7271 7272 ins_pipe(ialu_imm); 7273 %} 7274 7275 // Load Packed Float Constant 7276 7277 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7278 match(Set dst con); 7279 ins_cost(INSN_COST * 4); 7280 format %{ "fmovs $dst, $con"%} 7281 ins_encode %{ 7282 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7283 %} 7284 7285 ins_pipe(fp_imm_s); 7286 %} 7287 7288 // Load Float Constant 7289 7290 instruct loadConF(vRegF dst, immF con) %{ 7291 match(Set dst con); 7292 7293 ins_cost(INSN_COST * 4); 7294 7295 format %{ 7296 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7297 %} 7298 7299 ins_encode %{ 7300 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7301 %} 7302 7303 ins_pipe(fp_load_constant_s); 7304 %} 7305 7306 // Load Packed Double Constant 7307 7308 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7309 match(Set dst con); 7310 ins_cost(INSN_COST); 7311 format %{ "fmovd $dst, $con"%} 7312 ins_encode %{ 7313 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7314 %} 7315 7316 ins_pipe(fp_imm_d); 7317 %} 7318 7319 // Load Double Constant 7320 7321 instruct loadConD(vRegD dst, immD con) %{ 7322 match(Set dst con); 7323 7324 ins_cost(INSN_COST * 5); 7325 format %{ 7326 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7327 %} 7328 7329 ins_encode %{ 7330 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7331 %} 7332 7333 ins_pipe(fp_load_constant_d); 7334 %} 7335 7336 // Store Instructions 7337 7338 // Store CMS card-mark Immediate 7339 instruct storeimmCM0(immI0 zero, memory1 mem) 7340 %{ 7341 match(Set mem (StoreCM mem zero)); 7342 7343 ins_cost(INSN_COST); 7344 format %{ "storestore (elided)\n\t" 7345 "strb zr, $mem\t# byte" %} 7346 7347 ins_encode(aarch64_enc_strb0(mem)); 7348 7349 ins_pipe(istore_mem); 7350 %} 7351 7352 // Store CMS card-mark Immediate with intervening StoreStore 7353 // needed when using CMS with no conditional card marking 7354 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7355 %{ 7356 match(Set mem (StoreCM mem zero)); 7357 7358 ins_cost(INSN_COST * 2); 7359 format %{ "storestore\n\t" 7360 "dmb ishst" 7361 "\n\tstrb zr, $mem\t# byte" %} 7362 7363 ins_encode(aarch64_enc_strb0_ordered(mem)); 7364 7365 ins_pipe(istore_mem); 7366 %} 7367 7368 // Store Byte 7369 instruct storeB(iRegIorL2I src, memory1 mem) 7370 %{ 7371 match(Set mem (StoreB mem src)); 7372 predicate(!needs_releasing_store(n)); 7373 7374 ins_cost(INSN_COST); 7375 format %{ "strb $src, $mem\t# byte" %} 7376 7377 ins_encode(aarch64_enc_strb(src, mem)); 7378 7379 ins_pipe(istore_reg_mem); 7380 %} 7381 7382 7383 instruct storeimmB0(immI0 zero, memory1 mem) 7384 %{ 7385 match(Set mem (StoreB mem zero)); 7386 predicate(!needs_releasing_store(n)); 7387 7388 ins_cost(INSN_COST); 7389 format %{ "strb rscractch2, $mem\t# byte" %} 7390 7391 ins_encode(aarch64_enc_strb0(mem)); 7392 7393 ins_pipe(istore_mem); 7394 %} 7395 7396 // Store Char/Short 7397 instruct storeC(iRegIorL2I src, memory2 mem) 7398 %{ 7399 match(Set mem (StoreC mem src)); 7400 predicate(!needs_releasing_store(n)); 7401 7402 ins_cost(INSN_COST); 7403 format %{ "strh $src, $mem\t# short" %} 7404 7405 ins_encode(aarch64_enc_strh(src, mem)); 7406 7407 ins_pipe(istore_reg_mem); 7408 %} 7409 7410 instruct storeimmC0(immI0 zero, memory2 mem) 7411 %{ 7412 match(Set mem (StoreC mem zero)); 7413 predicate(!needs_releasing_store(n)); 7414 7415 ins_cost(INSN_COST); 7416 format %{ "strh zr, $mem\t# short" %} 7417 7418 ins_encode(aarch64_enc_strh0(mem)); 7419 7420 ins_pipe(istore_mem); 7421 %} 7422 7423 // Store Integer 7424 7425 instruct storeI(iRegIorL2I src, memory4 mem) 7426 %{ 7427 match(Set mem(StoreI mem src)); 7428 predicate(!needs_releasing_store(n)); 7429 7430 ins_cost(INSN_COST); 7431 format %{ "strw $src, $mem\t# int" %} 7432 7433 ins_encode(aarch64_enc_strw(src, mem)); 7434 7435 ins_pipe(istore_reg_mem); 7436 %} 7437 7438 instruct storeimmI0(immI0 zero, memory4 mem) 7439 %{ 7440 match(Set mem(StoreI mem zero)); 7441 predicate(!needs_releasing_store(n)); 7442 7443 ins_cost(INSN_COST); 7444 format %{ "strw zr, $mem\t# int" %} 7445 7446 ins_encode(aarch64_enc_strw0(mem)); 7447 7448 ins_pipe(istore_mem); 7449 %} 7450 7451 // Store Long (64 bit signed) 7452 instruct storeL(iRegL src, memory8 mem) 7453 %{ 7454 match(Set mem (StoreL mem src)); 7455 predicate(!needs_releasing_store(n)); 7456 7457 ins_cost(INSN_COST); 7458 format %{ "str $src, $mem\t# int" %} 7459 7460 ins_encode(aarch64_enc_str(src, mem)); 7461 7462 ins_pipe(istore_reg_mem); 7463 %} 7464 7465 // Store Long (64 bit signed) 7466 instruct storeimmL0(immL0 zero, memory8 mem) 7467 %{ 7468 match(Set mem (StoreL mem zero)); 7469 predicate(!needs_releasing_store(n)); 7470 7471 ins_cost(INSN_COST); 7472 format %{ "str zr, $mem\t# int" %} 7473 7474 ins_encode(aarch64_enc_str0(mem)); 7475 7476 ins_pipe(istore_mem); 7477 %} 7478 7479 // Store Pointer 7480 instruct storeP(iRegP src, memory8 mem) 7481 %{ 7482 match(Set mem (StoreP mem src)); 7483 predicate(!needs_releasing_store(n)); 7484 7485 ins_cost(INSN_COST); 7486 format %{ "str $src, $mem\t# ptr" %} 7487 7488 ins_encode(aarch64_enc_str(src, mem)); 7489 7490 ins_pipe(istore_reg_mem); 7491 %} 7492 7493 // Store Pointer 7494 instruct storeimmP0(immP0 zero, memory8 mem) 7495 %{ 7496 match(Set mem (StoreP mem zero)); 7497 predicate(!needs_releasing_store(n)); 7498 7499 ins_cost(INSN_COST); 7500 format %{ "str zr, $mem\t# ptr" %} 7501 7502 ins_encode(aarch64_enc_str0(mem)); 7503 7504 ins_pipe(istore_mem); 7505 %} 7506 7507 // Store Compressed Pointer 7508 instruct storeN(iRegN src, memory4 mem) 7509 %{ 7510 match(Set mem (StoreN mem src)); 7511 predicate(!needs_releasing_store(n)); 7512 7513 ins_cost(INSN_COST); 7514 format %{ "strw $src, $mem\t# compressed ptr" %} 7515 7516 ins_encode(aarch64_enc_strw(src, mem)); 7517 7518 ins_pipe(istore_reg_mem); 7519 %} 7520 7521 instruct storeImmN0(immN0 zero, memory4 mem) 7522 %{ 7523 match(Set mem (StoreN mem zero)); 7524 predicate(!needs_releasing_store(n)); 7525 7526 ins_cost(INSN_COST); 7527 format %{ "strw zr, $mem\t# compressed ptr" %} 7528 7529 ins_encode(aarch64_enc_strw0(mem)); 7530 7531 ins_pipe(istore_mem); 7532 %} 7533 7534 // Store Float 7535 instruct storeF(vRegF src, memory4 mem) 7536 %{ 7537 match(Set mem (StoreF mem src)); 7538 predicate(!needs_releasing_store(n)); 7539 7540 ins_cost(INSN_COST); 7541 format %{ "strs $src, $mem\t# float" %} 7542 7543 ins_encode( aarch64_enc_strs(src, mem) ); 7544 7545 ins_pipe(pipe_class_memory); 7546 %} 7547 7548 // TODO 7549 // implement storeImmF0 and storeFImmPacked 7550 7551 // Store Double 7552 instruct storeD(vRegD src, memory8 mem) 7553 %{ 7554 match(Set mem (StoreD mem src)); 7555 predicate(!needs_releasing_store(n)); 7556 7557 ins_cost(INSN_COST); 7558 format %{ "strd $src, $mem\t# double" %} 7559 7560 ins_encode( aarch64_enc_strd(src, mem) ); 7561 7562 ins_pipe(pipe_class_memory); 7563 %} 7564 7565 // Store Compressed Klass Pointer 7566 instruct storeNKlass(iRegN src, memory4 mem) 7567 %{ 7568 predicate(!needs_releasing_store(n)); 7569 match(Set mem (StoreNKlass mem src)); 7570 7571 ins_cost(INSN_COST); 7572 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7573 7574 ins_encode(aarch64_enc_strw(src, mem)); 7575 7576 ins_pipe(istore_reg_mem); 7577 %} 7578 7579 // TODO 7580 // implement storeImmD0 and storeDImmPacked 7581 7582 // prefetch instructions 7583 // Must be safe to execute with invalid address (cannot fault). 7584 7585 instruct prefetchalloc( memory8 mem ) %{ 7586 match(PrefetchAllocation mem); 7587 7588 ins_cost(INSN_COST); 7589 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7590 7591 ins_encode( aarch64_enc_prefetchw(mem) ); 7592 7593 ins_pipe(iload_prefetch); 7594 %} 7595 7596 // ---------------- volatile loads and stores ---------------- 7597 7598 // Load Byte (8 bit signed) 7599 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7600 %{ 7601 match(Set dst (LoadB mem)); 7602 7603 ins_cost(VOLATILE_REF_COST); 7604 format %{ "ldarsb $dst, $mem\t# byte" %} 7605 7606 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7607 7608 ins_pipe(pipe_serial); 7609 %} 7610 7611 // Load Byte (8 bit signed) into long 7612 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7613 %{ 7614 match(Set dst (ConvI2L (LoadB mem))); 7615 7616 ins_cost(VOLATILE_REF_COST); 7617 format %{ "ldarsb $dst, $mem\t# byte" %} 7618 7619 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7620 7621 ins_pipe(pipe_serial); 7622 %} 7623 7624 // Load Byte (8 bit unsigned) 7625 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7626 %{ 7627 match(Set dst (LoadUB mem)); 7628 7629 ins_cost(VOLATILE_REF_COST); 7630 format %{ "ldarb $dst, $mem\t# byte" %} 7631 7632 ins_encode(aarch64_enc_ldarb(dst, mem)); 7633 7634 ins_pipe(pipe_serial); 7635 %} 7636 7637 // Load Byte (8 bit unsigned) into long 7638 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7639 %{ 7640 match(Set dst (ConvI2L (LoadUB mem))); 7641 7642 ins_cost(VOLATILE_REF_COST); 7643 format %{ "ldarb $dst, $mem\t# byte" %} 7644 7645 ins_encode(aarch64_enc_ldarb(dst, mem)); 7646 7647 ins_pipe(pipe_serial); 7648 %} 7649 7650 // Load Short (16 bit signed) 7651 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7652 %{ 7653 match(Set dst (LoadS mem)); 7654 7655 ins_cost(VOLATILE_REF_COST); 7656 format %{ "ldarshw $dst, $mem\t# short" %} 7657 7658 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7659 7660 ins_pipe(pipe_serial); 7661 %} 7662 7663 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7664 %{ 7665 match(Set dst (LoadUS mem)); 7666 7667 ins_cost(VOLATILE_REF_COST); 7668 format %{ "ldarhw $dst, $mem\t# short" %} 7669 7670 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7671 7672 ins_pipe(pipe_serial); 7673 %} 7674 7675 // Load Short/Char (16 bit unsigned) into long 7676 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7677 %{ 7678 match(Set dst (ConvI2L (LoadUS mem))); 7679 7680 ins_cost(VOLATILE_REF_COST); 7681 format %{ "ldarh $dst, $mem\t# short" %} 7682 7683 ins_encode(aarch64_enc_ldarh(dst, mem)); 7684 7685 ins_pipe(pipe_serial); 7686 %} 7687 7688 // Load Short/Char (16 bit signed) into long 7689 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7690 %{ 7691 match(Set dst (ConvI2L (LoadS mem))); 7692 7693 ins_cost(VOLATILE_REF_COST); 7694 format %{ "ldarh $dst, $mem\t# short" %} 7695 7696 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7697 7698 ins_pipe(pipe_serial); 7699 %} 7700 7701 // Load Integer (32 bit signed) 7702 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7703 %{ 7704 match(Set dst (LoadI mem)); 7705 7706 ins_cost(VOLATILE_REF_COST); 7707 format %{ "ldarw $dst, $mem\t# int" %} 7708 7709 ins_encode(aarch64_enc_ldarw(dst, mem)); 7710 7711 ins_pipe(pipe_serial); 7712 %} 7713 7714 // Load Integer (32 bit unsigned) into long 7715 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7716 %{ 7717 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7718 7719 ins_cost(VOLATILE_REF_COST); 7720 format %{ "ldarw $dst, $mem\t# int" %} 7721 7722 ins_encode(aarch64_enc_ldarw(dst, mem)); 7723 7724 ins_pipe(pipe_serial); 7725 %} 7726 7727 // Load Long (64 bit signed) 7728 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7729 %{ 7730 match(Set dst (LoadL mem)); 7731 7732 ins_cost(VOLATILE_REF_COST); 7733 format %{ "ldar $dst, $mem\t# int" %} 7734 7735 ins_encode(aarch64_enc_ldar(dst, mem)); 7736 7737 ins_pipe(pipe_serial); 7738 %} 7739 7740 // Load Pointer 7741 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7742 %{ 7743 match(Set dst (LoadP mem)); 7744 predicate(n->as_Load()->barrier_data() == 0); 7745 7746 ins_cost(VOLATILE_REF_COST); 7747 format %{ "ldar $dst, $mem\t# ptr" %} 7748 7749 ins_encode(aarch64_enc_ldar(dst, mem)); 7750 7751 ins_pipe(pipe_serial); 7752 %} 7753 7754 // Load Compressed Pointer 7755 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7756 %{ 7757 match(Set dst (LoadN mem)); 7758 7759 ins_cost(VOLATILE_REF_COST); 7760 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7761 7762 ins_encode(aarch64_enc_ldarw(dst, mem)); 7763 7764 ins_pipe(pipe_serial); 7765 %} 7766 7767 // Load Float 7768 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7769 %{ 7770 match(Set dst (LoadF mem)); 7771 7772 ins_cost(VOLATILE_REF_COST); 7773 format %{ "ldars $dst, $mem\t# float" %} 7774 7775 ins_encode( aarch64_enc_fldars(dst, mem) ); 7776 7777 ins_pipe(pipe_serial); 7778 %} 7779 7780 // Load Double 7781 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7782 %{ 7783 match(Set dst (LoadD mem)); 7784 7785 ins_cost(VOLATILE_REF_COST); 7786 format %{ "ldard $dst, $mem\t# double" %} 7787 7788 ins_encode( aarch64_enc_fldard(dst, mem) ); 7789 7790 ins_pipe(pipe_serial); 7791 %} 7792 7793 // Store Byte 7794 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7795 %{ 7796 match(Set mem (StoreB mem src)); 7797 7798 ins_cost(VOLATILE_REF_COST); 7799 format %{ "stlrb $src, $mem\t# byte" %} 7800 7801 ins_encode(aarch64_enc_stlrb(src, mem)); 7802 7803 ins_pipe(pipe_class_memory); 7804 %} 7805 7806 // Store Char/Short 7807 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7808 %{ 7809 match(Set mem (StoreC mem src)); 7810 7811 ins_cost(VOLATILE_REF_COST); 7812 format %{ "stlrh $src, $mem\t# short" %} 7813 7814 ins_encode(aarch64_enc_stlrh(src, mem)); 7815 7816 ins_pipe(pipe_class_memory); 7817 %} 7818 7819 // Store Integer 7820 7821 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7822 %{ 7823 match(Set mem(StoreI mem src)); 7824 7825 ins_cost(VOLATILE_REF_COST); 7826 format %{ "stlrw $src, $mem\t# int" %} 7827 7828 ins_encode(aarch64_enc_stlrw(src, mem)); 7829 7830 ins_pipe(pipe_class_memory); 7831 %} 7832 7833 // Store Long (64 bit signed) 7834 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7835 %{ 7836 match(Set mem (StoreL mem src)); 7837 7838 ins_cost(VOLATILE_REF_COST); 7839 format %{ "stlr $src, $mem\t# int" %} 7840 7841 ins_encode(aarch64_enc_stlr(src, mem)); 7842 7843 ins_pipe(pipe_class_memory); 7844 %} 7845 7846 // Store Pointer 7847 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7848 %{ 7849 match(Set mem (StoreP mem src)); 7850 7851 ins_cost(VOLATILE_REF_COST); 7852 format %{ "stlr $src, $mem\t# ptr" %} 7853 7854 ins_encode(aarch64_enc_stlr(src, mem)); 7855 7856 ins_pipe(pipe_class_memory); 7857 %} 7858 7859 // Store Compressed Pointer 7860 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7861 %{ 7862 match(Set mem (StoreN mem src)); 7863 7864 ins_cost(VOLATILE_REF_COST); 7865 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7866 7867 ins_encode(aarch64_enc_stlrw(src, mem)); 7868 7869 ins_pipe(pipe_class_memory); 7870 %} 7871 7872 // Store Float 7873 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7874 %{ 7875 match(Set mem (StoreF mem src)); 7876 7877 ins_cost(VOLATILE_REF_COST); 7878 format %{ "stlrs $src, $mem\t# float" %} 7879 7880 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7881 7882 ins_pipe(pipe_class_memory); 7883 %} 7884 7885 // TODO 7886 // implement storeImmF0 and storeFImmPacked 7887 7888 // Store Double 7889 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7890 %{ 7891 match(Set mem (StoreD mem src)); 7892 7893 ins_cost(VOLATILE_REF_COST); 7894 format %{ "stlrd $src, $mem\t# double" %} 7895 7896 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7897 7898 ins_pipe(pipe_class_memory); 7899 %} 7900 7901 // ---------------- end of volatile loads and stores ---------------- 7902 7903 instruct cacheWB(indirect addr) 7904 %{ 7905 predicate(VM_Version::supports_data_cache_line_flush()); 7906 match(CacheWB addr); 7907 7908 ins_cost(100); 7909 format %{"cache wb $addr" %} 7910 ins_encode %{ 7911 assert($addr->index_position() < 0, "should be"); 7912 assert($addr$$disp == 0, "should be"); 7913 __ cache_wb(Address($addr$$base$$Register, 0)); 7914 %} 7915 ins_pipe(pipe_slow); // XXX 7916 %} 7917 7918 instruct cacheWBPreSync() 7919 %{ 7920 predicate(VM_Version::supports_data_cache_line_flush()); 7921 match(CacheWBPreSync); 7922 7923 ins_cost(100); 7924 format %{"cache wb presync" %} 7925 ins_encode %{ 7926 __ cache_wbsync(true); 7927 %} 7928 ins_pipe(pipe_slow); // XXX 7929 %} 7930 7931 instruct cacheWBPostSync() 7932 %{ 7933 predicate(VM_Version::supports_data_cache_line_flush()); 7934 match(CacheWBPostSync); 7935 7936 ins_cost(100); 7937 format %{"cache wb postsync" %} 7938 ins_encode %{ 7939 __ cache_wbsync(false); 7940 %} 7941 ins_pipe(pipe_slow); // XXX 7942 %} 7943 7944 // ============================================================================ 7945 // BSWAP Instructions 7946 7947 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7948 match(Set dst (ReverseBytesI src)); 7949 7950 ins_cost(INSN_COST); 7951 format %{ "revw $dst, $src" %} 7952 7953 ins_encode %{ 7954 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7955 %} 7956 7957 ins_pipe(ialu_reg); 7958 %} 7959 7960 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7961 match(Set dst (ReverseBytesL src)); 7962 7963 ins_cost(INSN_COST); 7964 format %{ "rev $dst, $src" %} 7965 7966 ins_encode %{ 7967 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7968 %} 7969 7970 ins_pipe(ialu_reg); 7971 %} 7972 7973 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7974 match(Set dst (ReverseBytesUS src)); 7975 7976 ins_cost(INSN_COST); 7977 format %{ "rev16w $dst, $src" %} 7978 7979 ins_encode %{ 7980 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7981 %} 7982 7983 ins_pipe(ialu_reg); 7984 %} 7985 7986 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7987 match(Set dst (ReverseBytesS src)); 7988 7989 ins_cost(INSN_COST); 7990 format %{ "rev16w $dst, $src\n\t" 7991 "sbfmw $dst, $dst, #0, #15" %} 7992 7993 ins_encode %{ 7994 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7995 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7996 %} 7997 7998 ins_pipe(ialu_reg); 7999 %} 8000 8001 // ============================================================================ 8002 // Zero Count Instructions 8003 8004 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8005 match(Set dst (CountLeadingZerosI src)); 8006 8007 ins_cost(INSN_COST); 8008 format %{ "clzw $dst, $src" %} 8009 ins_encode %{ 8010 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8011 %} 8012 8013 ins_pipe(ialu_reg); 8014 %} 8015 8016 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8017 match(Set dst (CountLeadingZerosL src)); 8018 8019 ins_cost(INSN_COST); 8020 format %{ "clz $dst, $src" %} 8021 ins_encode %{ 8022 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8023 %} 8024 8025 ins_pipe(ialu_reg); 8026 %} 8027 8028 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8029 match(Set dst (CountTrailingZerosI src)); 8030 8031 ins_cost(INSN_COST * 2); 8032 format %{ "rbitw $dst, $src\n\t" 8033 "clzw $dst, $dst" %} 8034 ins_encode %{ 8035 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8036 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8037 %} 8038 8039 ins_pipe(ialu_reg); 8040 %} 8041 8042 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8043 match(Set dst (CountTrailingZerosL src)); 8044 8045 ins_cost(INSN_COST * 2); 8046 format %{ "rbit $dst, $src\n\t" 8047 "clz $dst, $dst" %} 8048 ins_encode %{ 8049 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8050 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8051 %} 8052 8053 ins_pipe(ialu_reg); 8054 %} 8055 8056 //---------- Population Count Instructions ------------------------------------- 8057 // 8058 8059 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8060 predicate(UsePopCountInstruction); 8061 match(Set dst (PopCountI src)); 8062 effect(TEMP tmp); 8063 ins_cost(INSN_COST * 13); 8064 8065 format %{ "movw $src, $src\n\t" 8066 "mov $tmp, $src\t# vector (1D)\n\t" 8067 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8068 "addv $tmp, $tmp\t# vector (8B)\n\t" 8069 "mov $dst, $tmp\t# vector (1D)" %} 8070 ins_encode %{ 8071 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8072 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8073 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8074 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8075 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8076 %} 8077 8078 ins_pipe(pipe_class_default); 8079 %} 8080 8081 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8082 predicate(UsePopCountInstruction); 8083 match(Set dst (PopCountI (LoadI mem))); 8084 effect(TEMP tmp); 8085 ins_cost(INSN_COST * 13); 8086 8087 format %{ "ldrs $tmp, $mem\n\t" 8088 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8089 "addv $tmp, $tmp\t# vector (8B)\n\t" 8090 "mov $dst, $tmp\t# vector (1D)" %} 8091 ins_encode %{ 8092 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8093 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8094 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8095 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8096 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8097 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8098 %} 8099 8100 ins_pipe(pipe_class_default); 8101 %} 8102 8103 // Note: Long.bitCount(long) returns an int. 8104 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8105 predicate(UsePopCountInstruction); 8106 match(Set dst (PopCountL src)); 8107 effect(TEMP tmp); 8108 ins_cost(INSN_COST * 13); 8109 8110 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8111 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8112 "addv $tmp, $tmp\t# vector (8B)\n\t" 8113 "mov $dst, $tmp\t# vector (1D)" %} 8114 ins_encode %{ 8115 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8116 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8117 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8118 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8119 %} 8120 8121 ins_pipe(pipe_class_default); 8122 %} 8123 8124 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8125 predicate(UsePopCountInstruction); 8126 match(Set dst (PopCountL (LoadL mem))); 8127 effect(TEMP tmp); 8128 ins_cost(INSN_COST * 13); 8129 8130 format %{ "ldrd $tmp, $mem\n\t" 8131 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8132 "addv $tmp, $tmp\t# vector (8B)\n\t" 8133 "mov $dst, $tmp\t# vector (1D)" %} 8134 ins_encode %{ 8135 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8136 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8137 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8138 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8139 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8140 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8141 %} 8142 8143 ins_pipe(pipe_class_default); 8144 %} 8145 8146 // ============================================================================ 8147 // MemBar Instruction 8148 8149 instruct load_fence() %{ 8150 match(LoadFence); 8151 ins_cost(VOLATILE_REF_COST); 8152 8153 format %{ "load_fence" %} 8154 8155 ins_encode %{ 8156 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8157 %} 8158 ins_pipe(pipe_serial); 8159 %} 8160 8161 instruct unnecessary_membar_acquire() %{ 8162 predicate(unnecessary_acquire(n)); 8163 match(MemBarAcquire); 8164 ins_cost(0); 8165 8166 format %{ "membar_acquire (elided)" %} 8167 8168 ins_encode %{ 8169 __ block_comment("membar_acquire (elided)"); 8170 %} 8171 8172 ins_pipe(pipe_class_empty); 8173 %} 8174 8175 instruct membar_acquire() %{ 8176 match(MemBarAcquire); 8177 ins_cost(VOLATILE_REF_COST); 8178 8179 format %{ "membar_acquire\n\t" 8180 "dmb ish" %} 8181 8182 ins_encode %{ 8183 __ block_comment("membar_acquire"); 8184 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8185 %} 8186 8187 ins_pipe(pipe_serial); 8188 %} 8189 8190 8191 instruct membar_acquire_lock() %{ 8192 match(MemBarAcquireLock); 8193 ins_cost(VOLATILE_REF_COST); 8194 8195 format %{ "membar_acquire_lock (elided)" %} 8196 8197 ins_encode %{ 8198 __ block_comment("membar_acquire_lock (elided)"); 8199 %} 8200 8201 ins_pipe(pipe_serial); 8202 %} 8203 8204 instruct store_fence() %{ 8205 match(StoreFence); 8206 ins_cost(VOLATILE_REF_COST); 8207 8208 format %{ "store_fence" %} 8209 8210 ins_encode %{ 8211 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8212 %} 8213 ins_pipe(pipe_serial); 8214 %} 8215 8216 instruct unnecessary_membar_release() %{ 8217 predicate(unnecessary_release(n)); 8218 match(MemBarRelease); 8219 ins_cost(0); 8220 8221 format %{ "membar_release (elided)" %} 8222 8223 ins_encode %{ 8224 __ block_comment("membar_release (elided)"); 8225 %} 8226 ins_pipe(pipe_serial); 8227 %} 8228 8229 instruct membar_release() %{ 8230 match(MemBarRelease); 8231 ins_cost(VOLATILE_REF_COST); 8232 8233 format %{ "membar_release\n\t" 8234 "dmb ish" %} 8235 8236 ins_encode %{ 8237 __ block_comment("membar_release"); 8238 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8239 %} 8240 ins_pipe(pipe_serial); 8241 %} 8242 8243 instruct membar_storestore() %{ 8244 match(MemBarStoreStore); 8245 ins_cost(VOLATILE_REF_COST); 8246 8247 format %{ "MEMBAR-store-store" %} 8248 8249 ins_encode %{ 8250 __ membar(Assembler::StoreStore); 8251 %} 8252 ins_pipe(pipe_serial); 8253 %} 8254 8255 instruct membar_release_lock() %{ 8256 match(MemBarReleaseLock); 8257 ins_cost(VOLATILE_REF_COST); 8258 8259 format %{ "membar_release_lock (elided)" %} 8260 8261 ins_encode %{ 8262 __ block_comment("membar_release_lock (elided)"); 8263 %} 8264 8265 ins_pipe(pipe_serial); 8266 %} 8267 8268 instruct unnecessary_membar_volatile() %{ 8269 predicate(unnecessary_volatile(n)); 8270 match(MemBarVolatile); 8271 ins_cost(0); 8272 8273 format %{ "membar_volatile (elided)" %} 8274 8275 ins_encode %{ 8276 __ block_comment("membar_volatile (elided)"); 8277 %} 8278 8279 ins_pipe(pipe_serial); 8280 %} 8281 8282 instruct membar_volatile() %{ 8283 match(MemBarVolatile); 8284 ins_cost(VOLATILE_REF_COST*100); 8285 8286 format %{ "membar_volatile\n\t" 8287 "dmb ish"%} 8288 8289 ins_encode %{ 8290 __ block_comment("membar_volatile"); 8291 __ membar(Assembler::StoreLoad); 8292 %} 8293 8294 ins_pipe(pipe_serial); 8295 %} 8296 8297 // ============================================================================ 8298 // Cast/Convert Instructions 8299 8300 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8301 match(Set dst (CastX2P src)); 8302 8303 ins_cost(INSN_COST); 8304 format %{ "mov $dst, $src\t# long -> ptr" %} 8305 8306 ins_encode %{ 8307 if ($dst$$reg != $src$$reg) { 8308 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8309 } 8310 %} 8311 8312 ins_pipe(ialu_reg); 8313 %} 8314 8315 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8316 match(Set dst (CastP2X src)); 8317 8318 ins_cost(INSN_COST); 8319 format %{ "mov $dst, $src\t# ptr -> long" %} 8320 8321 ins_encode %{ 8322 if ($dst$$reg != $src$$reg) { 8323 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8324 } 8325 %} 8326 8327 ins_pipe(ialu_reg); 8328 %} 8329 8330 // Convert oop into int for vectors alignment masking 8331 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8332 match(Set dst (ConvL2I (CastP2X src))); 8333 8334 ins_cost(INSN_COST); 8335 format %{ "movw $dst, $src\t# ptr -> int" %} 8336 ins_encode %{ 8337 __ movw($dst$$Register, $src$$Register); 8338 %} 8339 8340 ins_pipe(ialu_reg); 8341 %} 8342 8343 // Convert compressed oop into int for vectors alignment masking 8344 // in case of 32bit oops (heap < 4Gb). 8345 instruct convN2I(iRegINoSp dst, iRegN src) 8346 %{ 8347 predicate(CompressedOops::shift() == 0); 8348 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8349 8350 ins_cost(INSN_COST); 8351 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8352 ins_encode %{ 8353 __ movw($dst$$Register, $src$$Register); 8354 %} 8355 8356 ins_pipe(ialu_reg); 8357 %} 8358 8359 8360 // Convert oop pointer into compressed form 8361 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8362 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8363 match(Set dst (EncodeP src)); 8364 effect(KILL cr); 8365 ins_cost(INSN_COST * 3); 8366 format %{ "encode_heap_oop $dst, $src" %} 8367 ins_encode %{ 8368 Register s = $src$$Register; 8369 Register d = $dst$$Register; 8370 __ encode_heap_oop(d, s); 8371 %} 8372 ins_pipe(ialu_reg); 8373 %} 8374 8375 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8376 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8377 match(Set dst (EncodeP src)); 8378 ins_cost(INSN_COST * 3); 8379 format %{ "encode_heap_oop_not_null $dst, $src" %} 8380 ins_encode %{ 8381 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8382 %} 8383 ins_pipe(ialu_reg); 8384 %} 8385 8386 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8387 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8388 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8389 match(Set dst (DecodeN src)); 8390 ins_cost(INSN_COST * 3); 8391 format %{ "decode_heap_oop $dst, $src" %} 8392 ins_encode %{ 8393 Register s = $src$$Register; 8394 Register d = $dst$$Register; 8395 __ decode_heap_oop(d, s); 8396 %} 8397 ins_pipe(ialu_reg); 8398 %} 8399 8400 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8401 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8402 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8403 match(Set dst (DecodeN src)); 8404 ins_cost(INSN_COST * 3); 8405 format %{ "decode_heap_oop_not_null $dst, $src" %} 8406 ins_encode %{ 8407 Register s = $src$$Register; 8408 Register d = $dst$$Register; 8409 __ decode_heap_oop_not_null(d, s); 8410 %} 8411 ins_pipe(ialu_reg); 8412 %} 8413 8414 // n.b. AArch64 implementations of encode_klass_not_null and 8415 // decode_klass_not_null do not modify the flags register so, unlike 8416 // Intel, we don't kill CR as a side effect here 8417 8418 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8419 match(Set dst (EncodePKlass src)); 8420 8421 ins_cost(INSN_COST * 3); 8422 format %{ "encode_klass_not_null $dst,$src" %} 8423 8424 ins_encode %{ 8425 Register src_reg = as_Register($src$$reg); 8426 Register dst_reg = as_Register($dst$$reg); 8427 __ encode_klass_not_null(dst_reg, src_reg); 8428 %} 8429 8430 ins_pipe(ialu_reg); 8431 %} 8432 8433 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8434 match(Set dst (DecodeNKlass src)); 8435 8436 ins_cost(INSN_COST * 3); 8437 format %{ "decode_klass_not_null $dst,$src" %} 8438 8439 ins_encode %{ 8440 Register src_reg = as_Register($src$$reg); 8441 Register dst_reg = as_Register($dst$$reg); 8442 if (dst_reg != src_reg) { 8443 __ decode_klass_not_null(dst_reg, src_reg); 8444 } else { 8445 __ decode_klass_not_null(dst_reg); 8446 } 8447 %} 8448 8449 ins_pipe(ialu_reg); 8450 %} 8451 8452 instruct checkCastPP(iRegPNoSp dst) 8453 %{ 8454 match(Set dst (CheckCastPP dst)); 8455 8456 size(0); 8457 format %{ "# checkcastPP of $dst" %} 8458 ins_encode(/* empty encoding */); 8459 ins_pipe(pipe_class_empty); 8460 %} 8461 8462 instruct castPP(iRegPNoSp dst) 8463 %{ 8464 match(Set dst (CastPP dst)); 8465 8466 size(0); 8467 format %{ "# castPP of $dst" %} 8468 ins_encode(/* empty encoding */); 8469 ins_pipe(pipe_class_empty); 8470 %} 8471 8472 instruct castII(iRegI dst) 8473 %{ 8474 match(Set dst (CastII dst)); 8475 8476 size(0); 8477 format %{ "# castII of $dst" %} 8478 ins_encode(/* empty encoding */); 8479 ins_cost(0); 8480 ins_pipe(pipe_class_empty); 8481 %} 8482 8483 // ============================================================================ 8484 // Atomic operation instructions 8485 // 8486 // Intel and SPARC both implement Ideal Node LoadPLocked and 8487 // Store{PIL}Conditional instructions using a normal load for the 8488 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8489 // 8490 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8491 // pair to lock object allocations from Eden space when not using 8492 // TLABs. 8493 // 8494 // There does not appear to be a Load{IL}Locked Ideal Node and the 8495 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8496 // and to use StoreIConditional only for 32-bit and StoreLConditional 8497 // only for 64-bit. 8498 // 8499 // We implement LoadPLocked and StorePLocked instructions using, 8500 // respectively the AArch64 hw load-exclusive and store-conditional 8501 // instructions. Whereas we must implement each of 8502 // Store{IL}Conditional using a CAS which employs a pair of 8503 // instructions comprising a load-exclusive followed by a 8504 // store-conditional. 8505 8506 8507 // Locked-load (linked load) of the current heap-top 8508 // used when updating the eden heap top 8509 // implemented using ldaxr on AArch64 8510 8511 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8512 %{ 8513 match(Set dst (LoadPLocked mem)); 8514 8515 ins_cost(VOLATILE_REF_COST); 8516 8517 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8518 8519 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8520 8521 ins_pipe(pipe_serial); 8522 %} 8523 8524 // Conditional-store of the updated heap-top. 8525 // Used during allocation of the shared heap. 8526 // Sets flag (EQ) on success. 8527 // implemented using stlxr on AArch64. 8528 8529 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8530 %{ 8531 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8532 8533 ins_cost(VOLATILE_REF_COST); 8534 8535 // TODO 8536 // do we need to do a store-conditional release or can we just use a 8537 // plain store-conditional? 8538 8539 format %{ 8540 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8541 "cmpw rscratch1, zr\t# EQ on successful write" 8542 %} 8543 8544 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8545 8546 ins_pipe(pipe_serial); 8547 %} 8548 8549 8550 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8551 // when attempting to rebias a lock towards the current thread. We 8552 // must use the acquire form of cmpxchg in order to guarantee acquire 8553 // semantics in this case. 8554 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8555 %{ 8556 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8557 8558 ins_cost(VOLATILE_REF_COST); 8559 8560 format %{ 8561 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8562 "cmpw rscratch1, zr\t# EQ on successful write" 8563 %} 8564 8565 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8566 8567 ins_pipe(pipe_slow); 8568 %} 8569 8570 // storeIConditional also has acquire semantics, for no better reason 8571 // than matching storeLConditional. At the time of writing this 8572 // comment storeIConditional was not used anywhere by AArch64. 8573 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8574 %{ 8575 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8576 8577 ins_cost(VOLATILE_REF_COST); 8578 8579 format %{ 8580 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8581 "cmpw rscratch1, zr\t# EQ on successful write" 8582 %} 8583 8584 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8585 8586 ins_pipe(pipe_slow); 8587 %} 8588 8589 // standard CompareAndSwapX when we are using barriers 8590 // these have higher priority than the rules selected by a predicate 8591 8592 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8593 // can't match them 8594 8595 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8596 8597 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8598 ins_cost(2 * VOLATILE_REF_COST); 8599 8600 effect(KILL cr); 8601 8602 format %{ 8603 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8604 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8605 %} 8606 8607 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8608 aarch64_enc_cset_eq(res)); 8609 8610 ins_pipe(pipe_slow); 8611 %} 8612 8613 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8614 8615 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8616 ins_cost(2 * VOLATILE_REF_COST); 8617 8618 effect(KILL cr); 8619 8620 format %{ 8621 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8622 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8623 %} 8624 8625 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8626 aarch64_enc_cset_eq(res)); 8627 8628 ins_pipe(pipe_slow); 8629 %} 8630 8631 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8632 8633 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8634 ins_cost(2 * VOLATILE_REF_COST); 8635 8636 effect(KILL cr); 8637 8638 format %{ 8639 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8640 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8641 %} 8642 8643 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8644 aarch64_enc_cset_eq(res)); 8645 8646 ins_pipe(pipe_slow); 8647 %} 8648 8649 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8650 8651 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8652 ins_cost(2 * VOLATILE_REF_COST); 8653 8654 effect(KILL cr); 8655 8656 format %{ 8657 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8658 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8659 %} 8660 8661 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8662 aarch64_enc_cset_eq(res)); 8663 8664 ins_pipe(pipe_slow); 8665 %} 8666 8667 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8668 8669 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8670 predicate(n->as_LoadStore()->barrier_data() == 0); 8671 ins_cost(2 * VOLATILE_REF_COST); 8672 8673 effect(KILL cr); 8674 8675 format %{ 8676 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8677 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8678 %} 8679 8680 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8681 aarch64_enc_cset_eq(res)); 8682 8683 ins_pipe(pipe_slow); 8684 %} 8685 8686 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8687 8688 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8689 ins_cost(2 * VOLATILE_REF_COST); 8690 8691 effect(KILL cr); 8692 8693 format %{ 8694 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8695 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8696 %} 8697 8698 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8699 aarch64_enc_cset_eq(res)); 8700 8701 ins_pipe(pipe_slow); 8702 %} 8703 8704 // alternative CompareAndSwapX when we are eliding barriers 8705 8706 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8707 8708 predicate(needs_acquiring_load_exclusive(n)); 8709 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8710 ins_cost(VOLATILE_REF_COST); 8711 8712 effect(KILL cr); 8713 8714 format %{ 8715 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8716 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8717 %} 8718 8719 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8720 aarch64_enc_cset_eq(res)); 8721 8722 ins_pipe(pipe_slow); 8723 %} 8724 8725 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8726 8727 predicate(needs_acquiring_load_exclusive(n)); 8728 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8729 ins_cost(VOLATILE_REF_COST); 8730 8731 effect(KILL cr); 8732 8733 format %{ 8734 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8735 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8736 %} 8737 8738 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8739 aarch64_enc_cset_eq(res)); 8740 8741 ins_pipe(pipe_slow); 8742 %} 8743 8744 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8745 8746 predicate(needs_acquiring_load_exclusive(n)); 8747 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8748 ins_cost(VOLATILE_REF_COST); 8749 8750 effect(KILL cr); 8751 8752 format %{ 8753 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8754 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8755 %} 8756 8757 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8758 aarch64_enc_cset_eq(res)); 8759 8760 ins_pipe(pipe_slow); 8761 %} 8762 8763 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8764 8765 predicate(needs_acquiring_load_exclusive(n)); 8766 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8767 ins_cost(VOLATILE_REF_COST); 8768 8769 effect(KILL cr); 8770 8771 format %{ 8772 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8773 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8774 %} 8775 8776 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8777 aarch64_enc_cset_eq(res)); 8778 8779 ins_pipe(pipe_slow); 8780 %} 8781 8782 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8783 8784 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8785 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8786 ins_cost(VOLATILE_REF_COST); 8787 8788 effect(KILL cr); 8789 8790 format %{ 8791 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8792 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8793 %} 8794 8795 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8796 aarch64_enc_cset_eq(res)); 8797 8798 ins_pipe(pipe_slow); 8799 %} 8800 8801 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8802 8803 predicate(needs_acquiring_load_exclusive(n)); 8804 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8805 ins_cost(VOLATILE_REF_COST); 8806 8807 effect(KILL cr); 8808 8809 format %{ 8810 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8811 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8812 %} 8813 8814 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8815 aarch64_enc_cset_eq(res)); 8816 8817 ins_pipe(pipe_slow); 8818 %} 8819 8820 8821 // --------------------------------------------------------------------- 8822 8823 8824 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8825 8826 // Sundry CAS operations. Note that release is always true, 8827 // regardless of the memory ordering of the CAS. This is because we 8828 // need the volatile case to be sequentially consistent but there is 8829 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8830 // can't check the type of memory ordering here, so we always emit a 8831 // STLXR. 8832 8833 // This section is generated from aarch64_ad_cas.m4 8834 8835 8836 8837 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8838 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8839 ins_cost(2 * VOLATILE_REF_COST); 8840 effect(TEMP_DEF res, KILL cr); 8841 format %{ 8842 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8843 %} 8844 ins_encode %{ 8845 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8846 Assembler::byte, /*acquire*/ false, /*release*/ true, 8847 /*weak*/ false, $res$$Register); 8848 __ sxtbw($res$$Register, $res$$Register); 8849 %} 8850 ins_pipe(pipe_slow); 8851 %} 8852 8853 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8854 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8855 ins_cost(2 * VOLATILE_REF_COST); 8856 effect(TEMP_DEF res, KILL cr); 8857 format %{ 8858 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8859 %} 8860 ins_encode %{ 8861 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8862 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8863 /*weak*/ false, $res$$Register); 8864 __ sxthw($res$$Register, $res$$Register); 8865 %} 8866 ins_pipe(pipe_slow); 8867 %} 8868 8869 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8870 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8871 ins_cost(2 * VOLATILE_REF_COST); 8872 effect(TEMP_DEF res, KILL cr); 8873 format %{ 8874 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8875 %} 8876 ins_encode %{ 8877 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8878 Assembler::word, /*acquire*/ false, /*release*/ true, 8879 /*weak*/ false, $res$$Register); 8880 %} 8881 ins_pipe(pipe_slow); 8882 %} 8883 8884 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8885 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8886 ins_cost(2 * VOLATILE_REF_COST); 8887 effect(TEMP_DEF res, KILL cr); 8888 format %{ 8889 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8890 %} 8891 ins_encode %{ 8892 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8893 Assembler::xword, /*acquire*/ false, /*release*/ true, 8894 /*weak*/ false, $res$$Register); 8895 %} 8896 ins_pipe(pipe_slow); 8897 %} 8898 8899 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8900 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8901 ins_cost(2 * VOLATILE_REF_COST); 8902 effect(TEMP_DEF res, KILL cr); 8903 format %{ 8904 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8905 %} 8906 ins_encode %{ 8907 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8908 Assembler::word, /*acquire*/ false, /*release*/ true, 8909 /*weak*/ false, $res$$Register); 8910 %} 8911 ins_pipe(pipe_slow); 8912 %} 8913 8914 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8915 predicate(n->as_LoadStore()->barrier_data() == 0); 8916 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8917 ins_cost(2 * VOLATILE_REF_COST); 8918 effect(TEMP_DEF res, KILL cr); 8919 format %{ 8920 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8921 %} 8922 ins_encode %{ 8923 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8924 Assembler::xword, /*acquire*/ false, /*release*/ true, 8925 /*weak*/ false, $res$$Register); 8926 %} 8927 ins_pipe(pipe_slow); 8928 %} 8929 8930 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8931 predicate(needs_acquiring_load_exclusive(n)); 8932 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8933 ins_cost(VOLATILE_REF_COST); 8934 effect(TEMP_DEF res, KILL cr); 8935 format %{ 8936 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8937 %} 8938 ins_encode %{ 8939 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8940 Assembler::byte, /*acquire*/ true, /*release*/ true, 8941 /*weak*/ false, $res$$Register); 8942 __ sxtbw($res$$Register, $res$$Register); 8943 %} 8944 ins_pipe(pipe_slow); 8945 %} 8946 8947 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8948 predicate(needs_acquiring_load_exclusive(n)); 8949 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8950 ins_cost(VOLATILE_REF_COST); 8951 effect(TEMP_DEF res, KILL cr); 8952 format %{ 8953 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8954 %} 8955 ins_encode %{ 8956 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8957 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8958 /*weak*/ false, $res$$Register); 8959 __ sxthw($res$$Register, $res$$Register); 8960 %} 8961 ins_pipe(pipe_slow); 8962 %} 8963 8964 8965 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8966 predicate(needs_acquiring_load_exclusive(n)); 8967 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8968 ins_cost(VOLATILE_REF_COST); 8969 effect(TEMP_DEF res, KILL cr); 8970 format %{ 8971 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8972 %} 8973 ins_encode %{ 8974 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8975 Assembler::word, /*acquire*/ true, /*release*/ true, 8976 /*weak*/ false, $res$$Register); 8977 %} 8978 ins_pipe(pipe_slow); 8979 %} 8980 8981 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8982 predicate(needs_acquiring_load_exclusive(n)); 8983 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8984 ins_cost(VOLATILE_REF_COST); 8985 effect(TEMP_DEF res, KILL cr); 8986 format %{ 8987 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8988 %} 8989 ins_encode %{ 8990 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8991 Assembler::xword, /*acquire*/ true, /*release*/ true, 8992 /*weak*/ false, $res$$Register); 8993 %} 8994 ins_pipe(pipe_slow); 8995 %} 8996 8997 8998 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8999 predicate(needs_acquiring_load_exclusive(n)); 9000 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9001 ins_cost(VOLATILE_REF_COST); 9002 effect(TEMP_DEF res, KILL cr); 9003 format %{ 9004 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9005 %} 9006 ins_encode %{ 9007 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9008 Assembler::word, /*acquire*/ true, /*release*/ true, 9009 /*weak*/ false, $res$$Register); 9010 %} 9011 ins_pipe(pipe_slow); 9012 %} 9013 9014 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9015 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9016 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9017 ins_cost(VOLATILE_REF_COST); 9018 effect(TEMP_DEF res, KILL cr); 9019 format %{ 9020 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9021 %} 9022 ins_encode %{ 9023 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9024 Assembler::xword, /*acquire*/ true, /*release*/ true, 9025 /*weak*/ false, $res$$Register); 9026 %} 9027 ins_pipe(pipe_slow); 9028 %} 9029 9030 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9031 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9032 ins_cost(2 * VOLATILE_REF_COST); 9033 effect(KILL cr); 9034 format %{ 9035 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9036 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9037 %} 9038 ins_encode %{ 9039 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9040 Assembler::byte, /*acquire*/ false, /*release*/ true, 9041 /*weak*/ true, noreg); 9042 __ csetw($res$$Register, Assembler::EQ); 9043 %} 9044 ins_pipe(pipe_slow); 9045 %} 9046 9047 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9048 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9049 ins_cost(2 * VOLATILE_REF_COST); 9050 effect(KILL cr); 9051 format %{ 9052 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9053 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9054 %} 9055 ins_encode %{ 9056 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9057 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9058 /*weak*/ true, noreg); 9059 __ csetw($res$$Register, Assembler::EQ); 9060 %} 9061 ins_pipe(pipe_slow); 9062 %} 9063 9064 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9065 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9066 ins_cost(2 * VOLATILE_REF_COST); 9067 effect(KILL cr); 9068 format %{ 9069 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9070 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9071 %} 9072 ins_encode %{ 9073 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9074 Assembler::word, /*acquire*/ false, /*release*/ true, 9075 /*weak*/ true, noreg); 9076 __ csetw($res$$Register, Assembler::EQ); 9077 %} 9078 ins_pipe(pipe_slow); 9079 %} 9080 9081 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9082 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9083 ins_cost(2 * VOLATILE_REF_COST); 9084 effect(KILL cr); 9085 format %{ 9086 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9087 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9088 %} 9089 ins_encode %{ 9090 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9091 Assembler::xword, /*acquire*/ false, /*release*/ true, 9092 /*weak*/ true, noreg); 9093 __ csetw($res$$Register, Assembler::EQ); 9094 %} 9095 ins_pipe(pipe_slow); 9096 %} 9097 9098 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9099 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9100 ins_cost(2 * VOLATILE_REF_COST); 9101 effect(KILL cr); 9102 format %{ 9103 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9104 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9105 %} 9106 ins_encode %{ 9107 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9108 Assembler::word, /*acquire*/ false, /*release*/ true, 9109 /*weak*/ true, noreg); 9110 __ csetw($res$$Register, Assembler::EQ); 9111 %} 9112 ins_pipe(pipe_slow); 9113 %} 9114 9115 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9116 predicate(n->as_LoadStore()->barrier_data() == 0); 9117 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9118 ins_cost(2 * VOLATILE_REF_COST); 9119 effect(KILL cr); 9120 format %{ 9121 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9122 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9123 %} 9124 ins_encode %{ 9125 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9126 Assembler::xword, /*acquire*/ false, /*release*/ true, 9127 /*weak*/ true, noreg); 9128 __ csetw($res$$Register, Assembler::EQ); 9129 %} 9130 ins_pipe(pipe_slow); 9131 %} 9132 9133 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9134 predicate(needs_acquiring_load_exclusive(n)); 9135 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9136 ins_cost(VOLATILE_REF_COST); 9137 effect(KILL cr); 9138 format %{ 9139 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9140 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9141 %} 9142 ins_encode %{ 9143 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9144 Assembler::byte, /*acquire*/ true, /*release*/ true, 9145 /*weak*/ true, noreg); 9146 __ csetw($res$$Register, Assembler::EQ); 9147 %} 9148 ins_pipe(pipe_slow); 9149 %} 9150 9151 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9152 predicate(needs_acquiring_load_exclusive(n)); 9153 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9154 ins_cost(VOLATILE_REF_COST); 9155 effect(KILL cr); 9156 format %{ 9157 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9158 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9159 %} 9160 ins_encode %{ 9161 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9162 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9163 /*weak*/ true, noreg); 9164 __ csetw($res$$Register, Assembler::EQ); 9165 %} 9166 ins_pipe(pipe_slow); 9167 %} 9168 9169 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9170 predicate(needs_acquiring_load_exclusive(n)); 9171 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9172 ins_cost(VOLATILE_REF_COST); 9173 effect(KILL cr); 9174 format %{ 9175 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9176 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9177 %} 9178 ins_encode %{ 9179 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9180 Assembler::word, /*acquire*/ true, /*release*/ true, 9181 /*weak*/ true, noreg); 9182 __ csetw($res$$Register, Assembler::EQ); 9183 %} 9184 ins_pipe(pipe_slow); 9185 %} 9186 9187 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9188 predicate(needs_acquiring_load_exclusive(n)); 9189 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9190 ins_cost(VOLATILE_REF_COST); 9191 effect(KILL cr); 9192 format %{ 9193 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9194 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9195 %} 9196 ins_encode %{ 9197 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9198 Assembler::xword, /*acquire*/ true, /*release*/ true, 9199 /*weak*/ true, noreg); 9200 __ csetw($res$$Register, Assembler::EQ); 9201 %} 9202 ins_pipe(pipe_slow); 9203 %} 9204 9205 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9206 predicate(needs_acquiring_load_exclusive(n)); 9207 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9208 ins_cost(VOLATILE_REF_COST); 9209 effect(KILL cr); 9210 format %{ 9211 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9212 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9213 %} 9214 ins_encode %{ 9215 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9216 Assembler::word, /*acquire*/ true, /*release*/ true, 9217 /*weak*/ true, noreg); 9218 __ csetw($res$$Register, Assembler::EQ); 9219 %} 9220 ins_pipe(pipe_slow); 9221 %} 9222 9223 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9224 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9225 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9226 ins_cost(VOLATILE_REF_COST); 9227 effect(KILL cr); 9228 format %{ 9229 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9230 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9231 %} 9232 ins_encode %{ 9233 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9234 Assembler::xword, /*acquire*/ true, /*release*/ true, 9235 /*weak*/ true, noreg); 9236 __ csetw($res$$Register, Assembler::EQ); 9237 %} 9238 ins_pipe(pipe_slow); 9239 %} 9240 9241 // END This section of the file is automatically generated. Do not edit -------------- 9242 // --------------------------------------------------------------------- 9243 9244 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9245 match(Set prev (GetAndSetI mem newv)); 9246 ins_cost(2 * VOLATILE_REF_COST); 9247 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9248 ins_encode %{ 9249 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9250 %} 9251 ins_pipe(pipe_serial); 9252 %} 9253 9254 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9255 match(Set prev (GetAndSetL mem newv)); 9256 ins_cost(2 * VOLATILE_REF_COST); 9257 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9258 ins_encode %{ 9259 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9260 %} 9261 ins_pipe(pipe_serial); 9262 %} 9263 9264 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9265 match(Set prev (GetAndSetN mem newv)); 9266 ins_cost(2 * VOLATILE_REF_COST); 9267 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9268 ins_encode %{ 9269 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9270 %} 9271 ins_pipe(pipe_serial); 9272 %} 9273 9274 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9275 predicate(n->as_LoadStore()->barrier_data() == 0); 9276 match(Set prev (GetAndSetP mem newv)); 9277 ins_cost(2 * VOLATILE_REF_COST); 9278 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9279 ins_encode %{ 9280 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9281 %} 9282 ins_pipe(pipe_serial); 9283 %} 9284 9285 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9286 predicate(needs_acquiring_load_exclusive(n)); 9287 match(Set prev (GetAndSetI mem newv)); 9288 ins_cost(VOLATILE_REF_COST); 9289 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9290 ins_encode %{ 9291 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9292 %} 9293 ins_pipe(pipe_serial); 9294 %} 9295 9296 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9297 predicate(needs_acquiring_load_exclusive(n)); 9298 match(Set prev (GetAndSetL mem newv)); 9299 ins_cost(VOLATILE_REF_COST); 9300 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9301 ins_encode %{ 9302 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9303 %} 9304 ins_pipe(pipe_serial); 9305 %} 9306 9307 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9308 predicate(needs_acquiring_load_exclusive(n)); 9309 match(Set prev (GetAndSetN mem newv)); 9310 ins_cost(VOLATILE_REF_COST); 9311 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9312 ins_encode %{ 9313 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9314 %} 9315 ins_pipe(pipe_serial); 9316 %} 9317 9318 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9319 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9320 match(Set prev (GetAndSetP mem newv)); 9321 ins_cost(VOLATILE_REF_COST); 9322 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9323 ins_encode %{ 9324 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9325 %} 9326 ins_pipe(pipe_serial); 9327 %} 9328 9329 9330 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9331 match(Set newval (GetAndAddL mem incr)); 9332 ins_cost(2 * VOLATILE_REF_COST + 1); 9333 format %{ "get_and_addL $newval, [$mem], $incr" %} 9334 ins_encode %{ 9335 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9336 %} 9337 ins_pipe(pipe_serial); 9338 %} 9339 9340 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9341 predicate(n->as_LoadStore()->result_not_used()); 9342 match(Set dummy (GetAndAddL mem incr)); 9343 ins_cost(2 * VOLATILE_REF_COST); 9344 format %{ "get_and_addL [$mem], $incr" %} 9345 ins_encode %{ 9346 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9347 %} 9348 ins_pipe(pipe_serial); 9349 %} 9350 9351 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9352 match(Set newval (GetAndAddL mem incr)); 9353 ins_cost(2 * VOLATILE_REF_COST + 1); 9354 format %{ "get_and_addL $newval, [$mem], $incr" %} 9355 ins_encode %{ 9356 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9357 %} 9358 ins_pipe(pipe_serial); 9359 %} 9360 9361 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9362 predicate(n->as_LoadStore()->result_not_used()); 9363 match(Set dummy (GetAndAddL mem incr)); 9364 ins_cost(2 * VOLATILE_REF_COST); 9365 format %{ "get_and_addL [$mem], $incr" %} 9366 ins_encode %{ 9367 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9368 %} 9369 ins_pipe(pipe_serial); 9370 %} 9371 9372 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9373 match(Set newval (GetAndAddI mem incr)); 9374 ins_cost(2 * VOLATILE_REF_COST + 1); 9375 format %{ "get_and_addI $newval, [$mem], $incr" %} 9376 ins_encode %{ 9377 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9378 %} 9379 ins_pipe(pipe_serial); 9380 %} 9381 9382 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9383 predicate(n->as_LoadStore()->result_not_used()); 9384 match(Set dummy (GetAndAddI mem incr)); 9385 ins_cost(2 * VOLATILE_REF_COST); 9386 format %{ "get_and_addI [$mem], $incr" %} 9387 ins_encode %{ 9388 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9389 %} 9390 ins_pipe(pipe_serial); 9391 %} 9392 9393 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9394 match(Set newval (GetAndAddI mem incr)); 9395 ins_cost(2 * VOLATILE_REF_COST + 1); 9396 format %{ "get_and_addI $newval, [$mem], $incr" %} 9397 ins_encode %{ 9398 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9399 %} 9400 ins_pipe(pipe_serial); 9401 %} 9402 9403 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9404 predicate(n->as_LoadStore()->result_not_used()); 9405 match(Set dummy (GetAndAddI mem incr)); 9406 ins_cost(2 * VOLATILE_REF_COST); 9407 format %{ "get_and_addI [$mem], $incr" %} 9408 ins_encode %{ 9409 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9410 %} 9411 ins_pipe(pipe_serial); 9412 %} 9413 9414 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9415 predicate(needs_acquiring_load_exclusive(n)); 9416 match(Set newval (GetAndAddL mem incr)); 9417 ins_cost(VOLATILE_REF_COST + 1); 9418 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9419 ins_encode %{ 9420 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9421 %} 9422 ins_pipe(pipe_serial); 9423 %} 9424 9425 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9426 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9427 match(Set dummy (GetAndAddL mem incr)); 9428 ins_cost(VOLATILE_REF_COST); 9429 format %{ "get_and_addL_acq [$mem], $incr" %} 9430 ins_encode %{ 9431 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9432 %} 9433 ins_pipe(pipe_serial); 9434 %} 9435 9436 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9437 predicate(needs_acquiring_load_exclusive(n)); 9438 match(Set newval (GetAndAddL mem incr)); 9439 ins_cost(VOLATILE_REF_COST + 1); 9440 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9441 ins_encode %{ 9442 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9443 %} 9444 ins_pipe(pipe_serial); 9445 %} 9446 9447 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9448 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9449 match(Set dummy (GetAndAddL mem incr)); 9450 ins_cost(VOLATILE_REF_COST); 9451 format %{ "get_and_addL_acq [$mem], $incr" %} 9452 ins_encode %{ 9453 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9454 %} 9455 ins_pipe(pipe_serial); 9456 %} 9457 9458 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9459 predicate(needs_acquiring_load_exclusive(n)); 9460 match(Set newval (GetAndAddI mem incr)); 9461 ins_cost(VOLATILE_REF_COST + 1); 9462 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9463 ins_encode %{ 9464 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9465 %} 9466 ins_pipe(pipe_serial); 9467 %} 9468 9469 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9470 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9471 match(Set dummy (GetAndAddI mem incr)); 9472 ins_cost(VOLATILE_REF_COST); 9473 format %{ "get_and_addI_acq [$mem], $incr" %} 9474 ins_encode %{ 9475 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9476 %} 9477 ins_pipe(pipe_serial); 9478 %} 9479 9480 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9481 predicate(needs_acquiring_load_exclusive(n)); 9482 match(Set newval (GetAndAddI mem incr)); 9483 ins_cost(VOLATILE_REF_COST + 1); 9484 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9485 ins_encode %{ 9486 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9487 %} 9488 ins_pipe(pipe_serial); 9489 %} 9490 9491 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9492 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9493 match(Set dummy (GetAndAddI mem incr)); 9494 ins_cost(VOLATILE_REF_COST); 9495 format %{ "get_and_addI_acq [$mem], $incr" %} 9496 ins_encode %{ 9497 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9498 %} 9499 ins_pipe(pipe_serial); 9500 %} 9501 9502 // Manifest a CmpL result in an integer register. 9503 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9504 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9505 %{ 9506 match(Set dst (CmpL3 src1 src2)); 9507 effect(KILL flags); 9508 9509 ins_cost(INSN_COST * 6); 9510 format %{ 9511 "cmp $src1, $src2" 9512 "csetw $dst, ne" 9513 "cnegw $dst, lt" 9514 %} 9515 // format %{ "CmpL3 $dst, $src1, $src2" %} 9516 ins_encode %{ 9517 __ cmp($src1$$Register, $src2$$Register); 9518 __ csetw($dst$$Register, Assembler::NE); 9519 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9520 %} 9521 9522 ins_pipe(pipe_class_default); 9523 %} 9524 9525 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9526 %{ 9527 match(Set dst (CmpL3 src1 src2)); 9528 effect(KILL flags); 9529 9530 ins_cost(INSN_COST * 6); 9531 format %{ 9532 "cmp $src1, $src2" 9533 "csetw $dst, ne" 9534 "cnegw $dst, lt" 9535 %} 9536 ins_encode %{ 9537 int32_t con = (int32_t)$src2$$constant; 9538 if (con < 0) { 9539 __ adds(zr, $src1$$Register, -con); 9540 } else { 9541 __ subs(zr, $src1$$Register, con); 9542 } 9543 __ csetw($dst$$Register, Assembler::NE); 9544 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9545 %} 9546 9547 ins_pipe(pipe_class_default); 9548 %} 9549 9550 // ============================================================================ 9551 // Conditional Move Instructions 9552 9553 // n.b. we have identical rules for both a signed compare op (cmpOp) 9554 // and an unsigned compare op (cmpOpU). it would be nice if we could 9555 // define an op class which merged both inputs and use it to type the 9556 // argument to a single rule. unfortunatelyt his fails because the 9557 // opclass does not live up to the COND_INTER interface of its 9558 // component operands. When the generic code tries to negate the 9559 // operand it ends up running the generci Machoper::negate method 9560 // which throws a ShouldNotHappen. So, we have to provide two flavours 9561 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9562 9563 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9564 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9565 9566 ins_cost(INSN_COST * 2); 9567 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9568 9569 ins_encode %{ 9570 __ cselw(as_Register($dst$$reg), 9571 as_Register($src2$$reg), 9572 as_Register($src1$$reg), 9573 (Assembler::Condition)$cmp$$cmpcode); 9574 %} 9575 9576 ins_pipe(icond_reg_reg); 9577 %} 9578 9579 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9580 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9581 9582 ins_cost(INSN_COST * 2); 9583 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9584 9585 ins_encode %{ 9586 __ cselw(as_Register($dst$$reg), 9587 as_Register($src2$$reg), 9588 as_Register($src1$$reg), 9589 (Assembler::Condition)$cmp$$cmpcode); 9590 %} 9591 9592 ins_pipe(icond_reg_reg); 9593 %} 9594 9595 // special cases where one arg is zero 9596 9597 // n.b. this is selected in preference to the rule above because it 9598 // avoids loading constant 0 into a source register 9599 9600 // TODO 9601 // we ought only to be able to cull one of these variants as the ideal 9602 // transforms ought always to order the zero consistently (to left/right?) 9603 9604 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9605 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9606 9607 ins_cost(INSN_COST * 2); 9608 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9609 9610 ins_encode %{ 9611 __ cselw(as_Register($dst$$reg), 9612 as_Register($src$$reg), 9613 zr, 9614 (Assembler::Condition)$cmp$$cmpcode); 9615 %} 9616 9617 ins_pipe(icond_reg); 9618 %} 9619 9620 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9621 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9622 9623 ins_cost(INSN_COST * 2); 9624 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9625 9626 ins_encode %{ 9627 __ cselw(as_Register($dst$$reg), 9628 as_Register($src$$reg), 9629 zr, 9630 (Assembler::Condition)$cmp$$cmpcode); 9631 %} 9632 9633 ins_pipe(icond_reg); 9634 %} 9635 9636 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9637 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9638 9639 ins_cost(INSN_COST * 2); 9640 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9641 9642 ins_encode %{ 9643 __ cselw(as_Register($dst$$reg), 9644 zr, 9645 as_Register($src$$reg), 9646 (Assembler::Condition)$cmp$$cmpcode); 9647 %} 9648 9649 ins_pipe(icond_reg); 9650 %} 9651 9652 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9653 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9654 9655 ins_cost(INSN_COST * 2); 9656 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9657 9658 ins_encode %{ 9659 __ cselw(as_Register($dst$$reg), 9660 zr, 9661 as_Register($src$$reg), 9662 (Assembler::Condition)$cmp$$cmpcode); 9663 %} 9664 9665 ins_pipe(icond_reg); 9666 %} 9667 9668 // special case for creating a boolean 0 or 1 9669 9670 // n.b. this is selected in preference to the rule above because it 9671 // avoids loading constants 0 and 1 into a source register 9672 9673 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9674 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9675 9676 ins_cost(INSN_COST * 2); 9677 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9678 9679 ins_encode %{ 9680 // equivalently 9681 // cset(as_Register($dst$$reg), 9682 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9683 __ csincw(as_Register($dst$$reg), 9684 zr, 9685 zr, 9686 (Assembler::Condition)$cmp$$cmpcode); 9687 %} 9688 9689 ins_pipe(icond_none); 9690 %} 9691 9692 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9693 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9694 9695 ins_cost(INSN_COST * 2); 9696 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9697 9698 ins_encode %{ 9699 // equivalently 9700 // cset(as_Register($dst$$reg), 9701 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9702 __ csincw(as_Register($dst$$reg), 9703 zr, 9704 zr, 9705 (Assembler::Condition)$cmp$$cmpcode); 9706 %} 9707 9708 ins_pipe(icond_none); 9709 %} 9710 9711 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9712 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9713 9714 ins_cost(INSN_COST * 2); 9715 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9716 9717 ins_encode %{ 9718 __ csel(as_Register($dst$$reg), 9719 as_Register($src2$$reg), 9720 as_Register($src1$$reg), 9721 (Assembler::Condition)$cmp$$cmpcode); 9722 %} 9723 9724 ins_pipe(icond_reg_reg); 9725 %} 9726 9727 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9728 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9729 9730 ins_cost(INSN_COST * 2); 9731 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9732 9733 ins_encode %{ 9734 __ csel(as_Register($dst$$reg), 9735 as_Register($src2$$reg), 9736 as_Register($src1$$reg), 9737 (Assembler::Condition)$cmp$$cmpcode); 9738 %} 9739 9740 ins_pipe(icond_reg_reg); 9741 %} 9742 9743 // special cases where one arg is zero 9744 9745 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9746 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9747 9748 ins_cost(INSN_COST * 2); 9749 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9750 9751 ins_encode %{ 9752 __ csel(as_Register($dst$$reg), 9753 zr, 9754 as_Register($src$$reg), 9755 (Assembler::Condition)$cmp$$cmpcode); 9756 %} 9757 9758 ins_pipe(icond_reg); 9759 %} 9760 9761 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9762 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9763 9764 ins_cost(INSN_COST * 2); 9765 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9766 9767 ins_encode %{ 9768 __ csel(as_Register($dst$$reg), 9769 zr, 9770 as_Register($src$$reg), 9771 (Assembler::Condition)$cmp$$cmpcode); 9772 %} 9773 9774 ins_pipe(icond_reg); 9775 %} 9776 9777 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9778 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9779 9780 ins_cost(INSN_COST * 2); 9781 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9782 9783 ins_encode %{ 9784 __ csel(as_Register($dst$$reg), 9785 as_Register($src$$reg), 9786 zr, 9787 (Assembler::Condition)$cmp$$cmpcode); 9788 %} 9789 9790 ins_pipe(icond_reg); 9791 %} 9792 9793 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9794 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9795 9796 ins_cost(INSN_COST * 2); 9797 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9798 9799 ins_encode %{ 9800 __ csel(as_Register($dst$$reg), 9801 as_Register($src$$reg), 9802 zr, 9803 (Assembler::Condition)$cmp$$cmpcode); 9804 %} 9805 9806 ins_pipe(icond_reg); 9807 %} 9808 9809 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9810 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9811 9812 ins_cost(INSN_COST * 2); 9813 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9814 9815 ins_encode %{ 9816 __ csel(as_Register($dst$$reg), 9817 as_Register($src2$$reg), 9818 as_Register($src1$$reg), 9819 (Assembler::Condition)$cmp$$cmpcode); 9820 %} 9821 9822 ins_pipe(icond_reg_reg); 9823 %} 9824 9825 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9826 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9827 9828 ins_cost(INSN_COST * 2); 9829 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9830 9831 ins_encode %{ 9832 __ csel(as_Register($dst$$reg), 9833 as_Register($src2$$reg), 9834 as_Register($src1$$reg), 9835 (Assembler::Condition)$cmp$$cmpcode); 9836 %} 9837 9838 ins_pipe(icond_reg_reg); 9839 %} 9840 9841 // special cases where one arg is zero 9842 9843 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9844 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9845 9846 ins_cost(INSN_COST * 2); 9847 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9848 9849 ins_encode %{ 9850 __ csel(as_Register($dst$$reg), 9851 zr, 9852 as_Register($src$$reg), 9853 (Assembler::Condition)$cmp$$cmpcode); 9854 %} 9855 9856 ins_pipe(icond_reg); 9857 %} 9858 9859 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9860 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9861 9862 ins_cost(INSN_COST * 2); 9863 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9864 9865 ins_encode %{ 9866 __ csel(as_Register($dst$$reg), 9867 zr, 9868 as_Register($src$$reg), 9869 (Assembler::Condition)$cmp$$cmpcode); 9870 %} 9871 9872 ins_pipe(icond_reg); 9873 %} 9874 9875 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9876 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9877 9878 ins_cost(INSN_COST * 2); 9879 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9880 9881 ins_encode %{ 9882 __ csel(as_Register($dst$$reg), 9883 as_Register($src$$reg), 9884 zr, 9885 (Assembler::Condition)$cmp$$cmpcode); 9886 %} 9887 9888 ins_pipe(icond_reg); 9889 %} 9890 9891 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9892 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9893 9894 ins_cost(INSN_COST * 2); 9895 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9896 9897 ins_encode %{ 9898 __ csel(as_Register($dst$$reg), 9899 as_Register($src$$reg), 9900 zr, 9901 (Assembler::Condition)$cmp$$cmpcode); 9902 %} 9903 9904 ins_pipe(icond_reg); 9905 %} 9906 9907 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9908 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9909 9910 ins_cost(INSN_COST * 2); 9911 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9912 9913 ins_encode %{ 9914 __ cselw(as_Register($dst$$reg), 9915 as_Register($src2$$reg), 9916 as_Register($src1$$reg), 9917 (Assembler::Condition)$cmp$$cmpcode); 9918 %} 9919 9920 ins_pipe(icond_reg_reg); 9921 %} 9922 9923 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9924 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9925 9926 ins_cost(INSN_COST * 2); 9927 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9928 9929 ins_encode %{ 9930 __ cselw(as_Register($dst$$reg), 9931 as_Register($src2$$reg), 9932 as_Register($src1$$reg), 9933 (Assembler::Condition)$cmp$$cmpcode); 9934 %} 9935 9936 ins_pipe(icond_reg_reg); 9937 %} 9938 9939 // special cases where one arg is zero 9940 9941 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9942 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9943 9944 ins_cost(INSN_COST * 2); 9945 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9946 9947 ins_encode %{ 9948 __ cselw(as_Register($dst$$reg), 9949 zr, 9950 as_Register($src$$reg), 9951 (Assembler::Condition)$cmp$$cmpcode); 9952 %} 9953 9954 ins_pipe(icond_reg); 9955 %} 9956 9957 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9958 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9959 9960 ins_cost(INSN_COST * 2); 9961 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9962 9963 ins_encode %{ 9964 __ cselw(as_Register($dst$$reg), 9965 zr, 9966 as_Register($src$$reg), 9967 (Assembler::Condition)$cmp$$cmpcode); 9968 %} 9969 9970 ins_pipe(icond_reg); 9971 %} 9972 9973 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9974 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9975 9976 ins_cost(INSN_COST * 2); 9977 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9978 9979 ins_encode %{ 9980 __ cselw(as_Register($dst$$reg), 9981 as_Register($src$$reg), 9982 zr, 9983 (Assembler::Condition)$cmp$$cmpcode); 9984 %} 9985 9986 ins_pipe(icond_reg); 9987 %} 9988 9989 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9990 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9991 9992 ins_cost(INSN_COST * 2); 9993 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9994 9995 ins_encode %{ 9996 __ cselw(as_Register($dst$$reg), 9997 as_Register($src$$reg), 9998 zr, 9999 (Assembler::Condition)$cmp$$cmpcode); 10000 %} 10001 10002 ins_pipe(icond_reg); 10003 %} 10004 10005 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10006 %{ 10007 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10008 10009 ins_cost(INSN_COST * 3); 10010 10011 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10012 ins_encode %{ 10013 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10014 __ fcsels(as_FloatRegister($dst$$reg), 10015 as_FloatRegister($src2$$reg), 10016 as_FloatRegister($src1$$reg), 10017 cond); 10018 %} 10019 10020 ins_pipe(fp_cond_reg_reg_s); 10021 %} 10022 10023 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10024 %{ 10025 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10026 10027 ins_cost(INSN_COST * 3); 10028 10029 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10030 ins_encode %{ 10031 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10032 __ fcsels(as_FloatRegister($dst$$reg), 10033 as_FloatRegister($src2$$reg), 10034 as_FloatRegister($src1$$reg), 10035 cond); 10036 %} 10037 10038 ins_pipe(fp_cond_reg_reg_s); 10039 %} 10040 10041 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10042 %{ 10043 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10044 10045 ins_cost(INSN_COST * 3); 10046 10047 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10048 ins_encode %{ 10049 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10050 __ fcseld(as_FloatRegister($dst$$reg), 10051 as_FloatRegister($src2$$reg), 10052 as_FloatRegister($src1$$reg), 10053 cond); 10054 %} 10055 10056 ins_pipe(fp_cond_reg_reg_d); 10057 %} 10058 10059 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10060 %{ 10061 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10062 10063 ins_cost(INSN_COST * 3); 10064 10065 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10066 ins_encode %{ 10067 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10068 __ fcseld(as_FloatRegister($dst$$reg), 10069 as_FloatRegister($src2$$reg), 10070 as_FloatRegister($src1$$reg), 10071 cond); 10072 %} 10073 10074 ins_pipe(fp_cond_reg_reg_d); 10075 %} 10076 10077 // ============================================================================ 10078 // Arithmetic Instructions 10079 // 10080 10081 // Integer Addition 10082 10083 // TODO 10084 // these currently employ operations which do not set CR and hence are 10085 // not flagged as killing CR but we would like to isolate the cases 10086 // where we want to set flags from those where we don't. need to work 10087 // out how to do that. 10088 10089 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10090 match(Set dst (AddI src1 src2)); 10091 10092 ins_cost(INSN_COST); 10093 format %{ "addw $dst, $src1, $src2" %} 10094 10095 ins_encode %{ 10096 __ addw(as_Register($dst$$reg), 10097 as_Register($src1$$reg), 10098 as_Register($src2$$reg)); 10099 %} 10100 10101 ins_pipe(ialu_reg_reg); 10102 %} 10103 10104 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10105 match(Set dst (AddI src1 src2)); 10106 10107 ins_cost(INSN_COST); 10108 format %{ "addw $dst, $src1, $src2" %} 10109 10110 // use opcode to indicate that this is an add not a sub 10111 opcode(0x0); 10112 10113 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10114 10115 ins_pipe(ialu_reg_imm); 10116 %} 10117 10118 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10119 match(Set dst (AddI (ConvL2I src1) src2)); 10120 10121 ins_cost(INSN_COST); 10122 format %{ "addw $dst, $src1, $src2" %} 10123 10124 // use opcode to indicate that this is an add not a sub 10125 opcode(0x0); 10126 10127 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10128 10129 ins_pipe(ialu_reg_imm); 10130 %} 10131 10132 // Pointer Addition 10133 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10134 match(Set dst (AddP src1 src2)); 10135 10136 ins_cost(INSN_COST); 10137 format %{ "add $dst, $src1, $src2\t# ptr" %} 10138 10139 ins_encode %{ 10140 __ add(as_Register($dst$$reg), 10141 as_Register($src1$$reg), 10142 as_Register($src2$$reg)); 10143 %} 10144 10145 ins_pipe(ialu_reg_reg); 10146 %} 10147 10148 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10149 match(Set dst (AddP src1 (ConvI2L src2))); 10150 10151 ins_cost(1.9 * INSN_COST); 10152 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10153 10154 ins_encode %{ 10155 __ add(as_Register($dst$$reg), 10156 as_Register($src1$$reg), 10157 as_Register($src2$$reg), ext::sxtw); 10158 %} 10159 10160 ins_pipe(ialu_reg_reg); 10161 %} 10162 10163 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10164 match(Set dst (AddP src1 (LShiftL src2 scale))); 10165 10166 ins_cost(1.9 * INSN_COST); 10167 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10168 10169 ins_encode %{ 10170 __ lea(as_Register($dst$$reg), 10171 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10172 Address::lsl($scale$$constant))); 10173 %} 10174 10175 ins_pipe(ialu_reg_reg_shift); 10176 %} 10177 10178 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10179 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10180 10181 ins_cost(1.9 * INSN_COST); 10182 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10183 10184 ins_encode %{ 10185 __ lea(as_Register($dst$$reg), 10186 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10187 Address::sxtw($scale$$constant))); 10188 %} 10189 10190 ins_pipe(ialu_reg_reg_shift); 10191 %} 10192 10193 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10194 match(Set dst (LShiftL (ConvI2L src) scale)); 10195 10196 ins_cost(INSN_COST); 10197 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10198 10199 ins_encode %{ 10200 __ sbfiz(as_Register($dst$$reg), 10201 as_Register($src$$reg), 10202 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 10203 %} 10204 10205 ins_pipe(ialu_reg_shift); 10206 %} 10207 10208 // Pointer Immediate Addition 10209 // n.b. this needs to be more expensive than using an indirect memory 10210 // operand 10211 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10212 match(Set dst (AddP src1 src2)); 10213 10214 ins_cost(INSN_COST); 10215 format %{ "add $dst, $src1, $src2\t# ptr" %} 10216 10217 // use opcode to indicate that this is an add not a sub 10218 opcode(0x0); 10219 10220 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10221 10222 ins_pipe(ialu_reg_imm); 10223 %} 10224 10225 // Long Addition 10226 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10227 10228 match(Set dst (AddL src1 src2)); 10229 10230 ins_cost(INSN_COST); 10231 format %{ "add $dst, $src1, $src2" %} 10232 10233 ins_encode %{ 10234 __ add(as_Register($dst$$reg), 10235 as_Register($src1$$reg), 10236 as_Register($src2$$reg)); 10237 %} 10238 10239 ins_pipe(ialu_reg_reg); 10240 %} 10241 10242 // No constant pool entries requiredLong Immediate Addition. 10243 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10244 match(Set dst (AddL src1 src2)); 10245 10246 ins_cost(INSN_COST); 10247 format %{ "add $dst, $src1, $src2" %} 10248 10249 // use opcode to indicate that this is an add not a sub 10250 opcode(0x0); 10251 10252 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10253 10254 ins_pipe(ialu_reg_imm); 10255 %} 10256 10257 // Integer Subtraction 10258 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10259 match(Set dst (SubI src1 src2)); 10260 10261 ins_cost(INSN_COST); 10262 format %{ "subw $dst, $src1, $src2" %} 10263 10264 ins_encode %{ 10265 __ subw(as_Register($dst$$reg), 10266 as_Register($src1$$reg), 10267 as_Register($src2$$reg)); 10268 %} 10269 10270 ins_pipe(ialu_reg_reg); 10271 %} 10272 10273 // Immediate Subtraction 10274 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10275 match(Set dst (SubI src1 src2)); 10276 10277 ins_cost(INSN_COST); 10278 format %{ "subw $dst, $src1, $src2" %} 10279 10280 // use opcode to indicate that this is a sub not an add 10281 opcode(0x1); 10282 10283 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10284 10285 ins_pipe(ialu_reg_imm); 10286 %} 10287 10288 // Long Subtraction 10289 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10290 10291 match(Set dst (SubL src1 src2)); 10292 10293 ins_cost(INSN_COST); 10294 format %{ "sub $dst, $src1, $src2" %} 10295 10296 ins_encode %{ 10297 __ sub(as_Register($dst$$reg), 10298 as_Register($src1$$reg), 10299 as_Register($src2$$reg)); 10300 %} 10301 10302 ins_pipe(ialu_reg_reg); 10303 %} 10304 10305 // No constant pool entries requiredLong Immediate Subtraction. 10306 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10307 match(Set dst (SubL src1 src2)); 10308 10309 ins_cost(INSN_COST); 10310 format %{ "sub$dst, $src1, $src2" %} 10311 10312 // use opcode to indicate that this is a sub not an add 10313 opcode(0x1); 10314 10315 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10316 10317 ins_pipe(ialu_reg_imm); 10318 %} 10319 10320 // Integer Negation (special case for sub) 10321 10322 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10323 match(Set dst (SubI zero src)); 10324 10325 ins_cost(INSN_COST); 10326 format %{ "negw $dst, $src\t# int" %} 10327 10328 ins_encode %{ 10329 __ negw(as_Register($dst$$reg), 10330 as_Register($src$$reg)); 10331 %} 10332 10333 ins_pipe(ialu_reg); 10334 %} 10335 10336 // Long Negation 10337 10338 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10339 match(Set dst (SubL zero src)); 10340 10341 ins_cost(INSN_COST); 10342 format %{ "neg $dst, $src\t# long" %} 10343 10344 ins_encode %{ 10345 __ neg(as_Register($dst$$reg), 10346 as_Register($src$$reg)); 10347 %} 10348 10349 ins_pipe(ialu_reg); 10350 %} 10351 10352 // Integer Multiply 10353 10354 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10355 match(Set dst (MulI src1 src2)); 10356 10357 ins_cost(INSN_COST * 3); 10358 format %{ "mulw $dst, $src1, $src2" %} 10359 10360 ins_encode %{ 10361 __ mulw(as_Register($dst$$reg), 10362 as_Register($src1$$reg), 10363 as_Register($src2$$reg)); 10364 %} 10365 10366 ins_pipe(imul_reg_reg); 10367 %} 10368 10369 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10370 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10371 10372 ins_cost(INSN_COST * 3); 10373 format %{ "smull $dst, $src1, $src2" %} 10374 10375 ins_encode %{ 10376 __ smull(as_Register($dst$$reg), 10377 as_Register($src1$$reg), 10378 as_Register($src2$$reg)); 10379 %} 10380 10381 ins_pipe(imul_reg_reg); 10382 %} 10383 10384 // Long Multiply 10385 10386 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10387 match(Set dst (MulL src1 src2)); 10388 10389 ins_cost(INSN_COST * 5); 10390 format %{ "mul $dst, $src1, $src2" %} 10391 10392 ins_encode %{ 10393 __ mul(as_Register($dst$$reg), 10394 as_Register($src1$$reg), 10395 as_Register($src2$$reg)); 10396 %} 10397 10398 ins_pipe(lmul_reg_reg); 10399 %} 10400 10401 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10402 %{ 10403 match(Set dst (MulHiL src1 src2)); 10404 10405 ins_cost(INSN_COST * 7); 10406 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10407 10408 ins_encode %{ 10409 __ smulh(as_Register($dst$$reg), 10410 as_Register($src1$$reg), 10411 as_Register($src2$$reg)); 10412 %} 10413 10414 ins_pipe(lmul_reg_reg); 10415 %} 10416 10417 // Combined Integer Multiply & Add/Sub 10418 10419 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10420 match(Set dst (AddI src3 (MulI src1 src2))); 10421 10422 ins_cost(INSN_COST * 3); 10423 format %{ "madd $dst, $src1, $src2, $src3" %} 10424 10425 ins_encode %{ 10426 __ maddw(as_Register($dst$$reg), 10427 as_Register($src1$$reg), 10428 as_Register($src2$$reg), 10429 as_Register($src3$$reg)); 10430 %} 10431 10432 ins_pipe(imac_reg_reg); 10433 %} 10434 10435 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10436 match(Set dst (SubI src3 (MulI src1 src2))); 10437 10438 ins_cost(INSN_COST * 3); 10439 format %{ "msub $dst, $src1, $src2, $src3" %} 10440 10441 ins_encode %{ 10442 __ msubw(as_Register($dst$$reg), 10443 as_Register($src1$$reg), 10444 as_Register($src2$$reg), 10445 as_Register($src3$$reg)); 10446 %} 10447 10448 ins_pipe(imac_reg_reg); 10449 %} 10450 10451 // Combined Integer Multiply & Neg 10452 10453 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10454 match(Set dst (MulI (SubI zero src1) src2)); 10455 match(Set dst (MulI src1 (SubI zero src2))); 10456 10457 ins_cost(INSN_COST * 3); 10458 format %{ "mneg $dst, $src1, $src2" %} 10459 10460 ins_encode %{ 10461 __ mnegw(as_Register($dst$$reg), 10462 as_Register($src1$$reg), 10463 as_Register($src2$$reg)); 10464 %} 10465 10466 ins_pipe(imac_reg_reg); 10467 %} 10468 10469 // Combined Long Multiply & Add/Sub 10470 10471 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10472 match(Set dst (AddL src3 (MulL src1 src2))); 10473 10474 ins_cost(INSN_COST * 5); 10475 format %{ "madd $dst, $src1, $src2, $src3" %} 10476 10477 ins_encode %{ 10478 __ madd(as_Register($dst$$reg), 10479 as_Register($src1$$reg), 10480 as_Register($src2$$reg), 10481 as_Register($src3$$reg)); 10482 %} 10483 10484 ins_pipe(lmac_reg_reg); 10485 %} 10486 10487 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10488 match(Set dst (SubL src3 (MulL src1 src2))); 10489 10490 ins_cost(INSN_COST * 5); 10491 format %{ "msub $dst, $src1, $src2, $src3" %} 10492 10493 ins_encode %{ 10494 __ msub(as_Register($dst$$reg), 10495 as_Register($src1$$reg), 10496 as_Register($src2$$reg), 10497 as_Register($src3$$reg)); 10498 %} 10499 10500 ins_pipe(lmac_reg_reg); 10501 %} 10502 10503 // Combined Long Multiply & Neg 10504 10505 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10506 match(Set dst (MulL (SubL zero src1) src2)); 10507 match(Set dst (MulL src1 (SubL zero src2))); 10508 10509 ins_cost(INSN_COST * 5); 10510 format %{ "mneg $dst, $src1, $src2" %} 10511 10512 ins_encode %{ 10513 __ mneg(as_Register($dst$$reg), 10514 as_Register($src1$$reg), 10515 as_Register($src2$$reg)); 10516 %} 10517 10518 ins_pipe(lmac_reg_reg); 10519 %} 10520 10521 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10522 10523 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10524 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10525 10526 ins_cost(INSN_COST * 3); 10527 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10528 10529 ins_encode %{ 10530 __ smaddl(as_Register($dst$$reg), 10531 as_Register($src1$$reg), 10532 as_Register($src2$$reg), 10533 as_Register($src3$$reg)); 10534 %} 10535 10536 ins_pipe(imac_reg_reg); 10537 %} 10538 10539 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10540 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10541 10542 ins_cost(INSN_COST * 3); 10543 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10544 10545 ins_encode %{ 10546 __ smsubl(as_Register($dst$$reg), 10547 as_Register($src1$$reg), 10548 as_Register($src2$$reg), 10549 as_Register($src3$$reg)); 10550 %} 10551 10552 ins_pipe(imac_reg_reg); 10553 %} 10554 10555 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10556 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10557 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10558 10559 ins_cost(INSN_COST * 3); 10560 format %{ "smnegl $dst, $src1, $src2" %} 10561 10562 ins_encode %{ 10563 __ smnegl(as_Register($dst$$reg), 10564 as_Register($src1$$reg), 10565 as_Register($src2$$reg)); 10566 %} 10567 10568 ins_pipe(imac_reg_reg); 10569 %} 10570 10571 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10572 10573 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10574 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10575 10576 ins_cost(INSN_COST * 5); 10577 format %{ "mulw rscratch1, $src1, $src2\n\t" 10578 "maddw $dst, $src3, $src4, rscratch1" %} 10579 10580 ins_encode %{ 10581 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10582 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10583 10584 ins_pipe(imac_reg_reg); 10585 %} 10586 10587 // Integer Divide 10588 10589 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10590 match(Set dst (DivI src1 src2)); 10591 10592 ins_cost(INSN_COST * 19); 10593 format %{ "sdivw $dst, $src1, $src2" %} 10594 10595 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10596 ins_pipe(idiv_reg_reg); 10597 %} 10598 10599 // Long Divide 10600 10601 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10602 match(Set dst (DivL src1 src2)); 10603 10604 ins_cost(INSN_COST * 35); 10605 format %{ "sdiv $dst, $src1, $src2" %} 10606 10607 ins_encode(aarch64_enc_div(dst, src1, src2)); 10608 ins_pipe(ldiv_reg_reg); 10609 %} 10610 10611 // Integer Remainder 10612 10613 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10614 match(Set dst (ModI src1 src2)); 10615 10616 ins_cost(INSN_COST * 22); 10617 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10618 "msubw($dst, rscratch1, $src2, $src1" %} 10619 10620 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10621 ins_pipe(idiv_reg_reg); 10622 %} 10623 10624 // Long Remainder 10625 10626 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10627 match(Set dst (ModL src1 src2)); 10628 10629 ins_cost(INSN_COST * 38); 10630 format %{ "sdiv rscratch1, $src1, $src2\n" 10631 "msub($dst, rscratch1, $src2, $src1" %} 10632 10633 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10634 ins_pipe(ldiv_reg_reg); 10635 %} 10636 10637 // Integer Shifts 10638 10639 // Shift Left Register 10640 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10641 match(Set dst (LShiftI src1 src2)); 10642 10643 ins_cost(INSN_COST * 2); 10644 format %{ "lslvw $dst, $src1, $src2" %} 10645 10646 ins_encode %{ 10647 __ lslvw(as_Register($dst$$reg), 10648 as_Register($src1$$reg), 10649 as_Register($src2$$reg)); 10650 %} 10651 10652 ins_pipe(ialu_reg_reg_vshift); 10653 %} 10654 10655 // Shift Left Immediate 10656 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10657 match(Set dst (LShiftI src1 src2)); 10658 10659 ins_cost(INSN_COST); 10660 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10661 10662 ins_encode %{ 10663 __ lslw(as_Register($dst$$reg), 10664 as_Register($src1$$reg), 10665 $src2$$constant & 0x1f); 10666 %} 10667 10668 ins_pipe(ialu_reg_shift); 10669 %} 10670 10671 // Shift Right Logical Register 10672 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10673 match(Set dst (URShiftI src1 src2)); 10674 10675 ins_cost(INSN_COST * 2); 10676 format %{ "lsrvw $dst, $src1, $src2" %} 10677 10678 ins_encode %{ 10679 __ lsrvw(as_Register($dst$$reg), 10680 as_Register($src1$$reg), 10681 as_Register($src2$$reg)); 10682 %} 10683 10684 ins_pipe(ialu_reg_reg_vshift); 10685 %} 10686 10687 // Shift Right Logical Immediate 10688 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10689 match(Set dst (URShiftI src1 src2)); 10690 10691 ins_cost(INSN_COST); 10692 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10693 10694 ins_encode %{ 10695 __ lsrw(as_Register($dst$$reg), 10696 as_Register($src1$$reg), 10697 $src2$$constant & 0x1f); 10698 %} 10699 10700 ins_pipe(ialu_reg_shift); 10701 %} 10702 10703 // Shift Right Arithmetic Register 10704 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10705 match(Set dst (RShiftI src1 src2)); 10706 10707 ins_cost(INSN_COST * 2); 10708 format %{ "asrvw $dst, $src1, $src2" %} 10709 10710 ins_encode %{ 10711 __ asrvw(as_Register($dst$$reg), 10712 as_Register($src1$$reg), 10713 as_Register($src2$$reg)); 10714 %} 10715 10716 ins_pipe(ialu_reg_reg_vshift); 10717 %} 10718 10719 // Shift Right Arithmetic Immediate 10720 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10721 match(Set dst (RShiftI src1 src2)); 10722 10723 ins_cost(INSN_COST); 10724 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10725 10726 ins_encode %{ 10727 __ asrw(as_Register($dst$$reg), 10728 as_Register($src1$$reg), 10729 $src2$$constant & 0x1f); 10730 %} 10731 10732 ins_pipe(ialu_reg_shift); 10733 %} 10734 10735 // Combined Int Mask and Right Shift (using UBFM) 10736 // TODO 10737 10738 // Long Shifts 10739 10740 // Shift Left Register 10741 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10742 match(Set dst (LShiftL src1 src2)); 10743 10744 ins_cost(INSN_COST * 2); 10745 format %{ "lslv $dst, $src1, $src2" %} 10746 10747 ins_encode %{ 10748 __ lslv(as_Register($dst$$reg), 10749 as_Register($src1$$reg), 10750 as_Register($src2$$reg)); 10751 %} 10752 10753 ins_pipe(ialu_reg_reg_vshift); 10754 %} 10755 10756 // Shift Left Immediate 10757 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10758 match(Set dst (LShiftL src1 src2)); 10759 10760 ins_cost(INSN_COST); 10761 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10762 10763 ins_encode %{ 10764 __ lsl(as_Register($dst$$reg), 10765 as_Register($src1$$reg), 10766 $src2$$constant & 0x3f); 10767 %} 10768 10769 ins_pipe(ialu_reg_shift); 10770 %} 10771 10772 // Shift Right Logical Register 10773 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10774 match(Set dst (URShiftL src1 src2)); 10775 10776 ins_cost(INSN_COST * 2); 10777 format %{ "lsrv $dst, $src1, $src2" %} 10778 10779 ins_encode %{ 10780 __ lsrv(as_Register($dst$$reg), 10781 as_Register($src1$$reg), 10782 as_Register($src2$$reg)); 10783 %} 10784 10785 ins_pipe(ialu_reg_reg_vshift); 10786 %} 10787 10788 // Shift Right Logical Immediate 10789 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10790 match(Set dst (URShiftL src1 src2)); 10791 10792 ins_cost(INSN_COST); 10793 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10794 10795 ins_encode %{ 10796 __ lsr(as_Register($dst$$reg), 10797 as_Register($src1$$reg), 10798 $src2$$constant & 0x3f); 10799 %} 10800 10801 ins_pipe(ialu_reg_shift); 10802 %} 10803 10804 // A special-case pattern for card table stores. 10805 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10806 match(Set dst (URShiftL (CastP2X src1) src2)); 10807 10808 ins_cost(INSN_COST); 10809 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10810 10811 ins_encode %{ 10812 __ lsr(as_Register($dst$$reg), 10813 as_Register($src1$$reg), 10814 $src2$$constant & 0x3f); 10815 %} 10816 10817 ins_pipe(ialu_reg_shift); 10818 %} 10819 10820 // Shift Right Arithmetic Register 10821 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10822 match(Set dst (RShiftL src1 src2)); 10823 10824 ins_cost(INSN_COST * 2); 10825 format %{ "asrv $dst, $src1, $src2" %} 10826 10827 ins_encode %{ 10828 __ asrv(as_Register($dst$$reg), 10829 as_Register($src1$$reg), 10830 as_Register($src2$$reg)); 10831 %} 10832 10833 ins_pipe(ialu_reg_reg_vshift); 10834 %} 10835 10836 // Shift Right Arithmetic Immediate 10837 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10838 match(Set dst (RShiftL src1 src2)); 10839 10840 ins_cost(INSN_COST); 10841 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10842 10843 ins_encode %{ 10844 __ asr(as_Register($dst$$reg), 10845 as_Register($src1$$reg), 10846 $src2$$constant & 0x3f); 10847 %} 10848 10849 ins_pipe(ialu_reg_shift); 10850 %} 10851 10852 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10853 // This section is generated from aarch64_ad.m4 10854 10855 instruct regL_not_reg(iRegLNoSp dst, 10856 iRegL src1, immL_M1 m1, 10857 rFlagsReg cr) %{ 10858 match(Set dst (XorL src1 m1)); 10859 ins_cost(INSN_COST); 10860 format %{ "eon $dst, $src1, zr" %} 10861 10862 ins_encode %{ 10863 __ eon(as_Register($dst$$reg), 10864 as_Register($src1$$reg), 10865 zr, 10866 Assembler::LSL, 0); 10867 %} 10868 10869 ins_pipe(ialu_reg); 10870 %} 10871 instruct regI_not_reg(iRegINoSp dst, 10872 iRegIorL2I src1, immI_M1 m1, 10873 rFlagsReg cr) %{ 10874 match(Set dst (XorI src1 m1)); 10875 ins_cost(INSN_COST); 10876 format %{ "eonw $dst, $src1, zr" %} 10877 10878 ins_encode %{ 10879 __ eonw(as_Register($dst$$reg), 10880 as_Register($src1$$reg), 10881 zr, 10882 Assembler::LSL, 0); 10883 %} 10884 10885 ins_pipe(ialu_reg); 10886 %} 10887 10888 instruct AndI_reg_not_reg(iRegINoSp dst, 10889 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10890 rFlagsReg cr) %{ 10891 match(Set dst (AndI src1 (XorI src2 m1))); 10892 ins_cost(INSN_COST); 10893 format %{ "bicw $dst, $src1, $src2" %} 10894 10895 ins_encode %{ 10896 __ bicw(as_Register($dst$$reg), 10897 as_Register($src1$$reg), 10898 as_Register($src2$$reg), 10899 Assembler::LSL, 0); 10900 %} 10901 10902 ins_pipe(ialu_reg_reg); 10903 %} 10904 10905 instruct AndL_reg_not_reg(iRegLNoSp dst, 10906 iRegL src1, iRegL src2, immL_M1 m1, 10907 rFlagsReg cr) %{ 10908 match(Set dst (AndL src1 (XorL src2 m1))); 10909 ins_cost(INSN_COST); 10910 format %{ "bic $dst, $src1, $src2" %} 10911 10912 ins_encode %{ 10913 __ bic(as_Register($dst$$reg), 10914 as_Register($src1$$reg), 10915 as_Register($src2$$reg), 10916 Assembler::LSL, 0); 10917 %} 10918 10919 ins_pipe(ialu_reg_reg); 10920 %} 10921 10922 instruct OrI_reg_not_reg(iRegINoSp dst, 10923 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10924 rFlagsReg cr) %{ 10925 match(Set dst (OrI src1 (XorI src2 m1))); 10926 ins_cost(INSN_COST); 10927 format %{ "ornw $dst, $src1, $src2" %} 10928 10929 ins_encode %{ 10930 __ ornw(as_Register($dst$$reg), 10931 as_Register($src1$$reg), 10932 as_Register($src2$$reg), 10933 Assembler::LSL, 0); 10934 %} 10935 10936 ins_pipe(ialu_reg_reg); 10937 %} 10938 10939 instruct OrL_reg_not_reg(iRegLNoSp dst, 10940 iRegL src1, iRegL src2, immL_M1 m1, 10941 rFlagsReg cr) %{ 10942 match(Set dst (OrL src1 (XorL src2 m1))); 10943 ins_cost(INSN_COST); 10944 format %{ "orn $dst, $src1, $src2" %} 10945 10946 ins_encode %{ 10947 __ orn(as_Register($dst$$reg), 10948 as_Register($src1$$reg), 10949 as_Register($src2$$reg), 10950 Assembler::LSL, 0); 10951 %} 10952 10953 ins_pipe(ialu_reg_reg); 10954 %} 10955 10956 instruct XorI_reg_not_reg(iRegINoSp dst, 10957 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10958 rFlagsReg cr) %{ 10959 match(Set dst (XorI m1 (XorI src2 src1))); 10960 ins_cost(INSN_COST); 10961 format %{ "eonw $dst, $src1, $src2" %} 10962 10963 ins_encode %{ 10964 __ eonw(as_Register($dst$$reg), 10965 as_Register($src1$$reg), 10966 as_Register($src2$$reg), 10967 Assembler::LSL, 0); 10968 %} 10969 10970 ins_pipe(ialu_reg_reg); 10971 %} 10972 10973 instruct XorL_reg_not_reg(iRegLNoSp dst, 10974 iRegL src1, iRegL src2, immL_M1 m1, 10975 rFlagsReg cr) %{ 10976 match(Set dst (XorL m1 (XorL src2 src1))); 10977 ins_cost(INSN_COST); 10978 format %{ "eon $dst, $src1, $src2" %} 10979 10980 ins_encode %{ 10981 __ eon(as_Register($dst$$reg), 10982 as_Register($src1$$reg), 10983 as_Register($src2$$reg), 10984 Assembler::LSL, 0); 10985 %} 10986 10987 ins_pipe(ialu_reg_reg); 10988 %} 10989 10990 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10991 iRegIorL2I src1, iRegIorL2I src2, 10992 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10993 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10994 ins_cost(1.9 * INSN_COST); 10995 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10996 10997 ins_encode %{ 10998 __ bicw(as_Register($dst$$reg), 10999 as_Register($src1$$reg), 11000 as_Register($src2$$reg), 11001 Assembler::LSR, 11002 $src3$$constant & 0x1f); 11003 %} 11004 11005 ins_pipe(ialu_reg_reg_shift); 11006 %} 11007 11008 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11009 iRegL src1, iRegL src2, 11010 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11011 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11012 ins_cost(1.9 * INSN_COST); 11013 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11014 11015 ins_encode %{ 11016 __ bic(as_Register($dst$$reg), 11017 as_Register($src1$$reg), 11018 as_Register($src2$$reg), 11019 Assembler::LSR, 11020 $src3$$constant & 0x3f); 11021 %} 11022 11023 ins_pipe(ialu_reg_reg_shift); 11024 %} 11025 11026 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11027 iRegIorL2I src1, iRegIorL2I src2, 11028 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11029 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11030 ins_cost(1.9 * INSN_COST); 11031 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11032 11033 ins_encode %{ 11034 __ bicw(as_Register($dst$$reg), 11035 as_Register($src1$$reg), 11036 as_Register($src2$$reg), 11037 Assembler::ASR, 11038 $src3$$constant & 0x1f); 11039 %} 11040 11041 ins_pipe(ialu_reg_reg_shift); 11042 %} 11043 11044 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11045 iRegL src1, iRegL src2, 11046 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11047 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11048 ins_cost(1.9 * INSN_COST); 11049 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11050 11051 ins_encode %{ 11052 __ bic(as_Register($dst$$reg), 11053 as_Register($src1$$reg), 11054 as_Register($src2$$reg), 11055 Assembler::ASR, 11056 $src3$$constant & 0x3f); 11057 %} 11058 11059 ins_pipe(ialu_reg_reg_shift); 11060 %} 11061 11062 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11063 iRegIorL2I src1, iRegIorL2I src2, 11064 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11065 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11066 ins_cost(1.9 * INSN_COST); 11067 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11068 11069 ins_encode %{ 11070 __ bicw(as_Register($dst$$reg), 11071 as_Register($src1$$reg), 11072 as_Register($src2$$reg), 11073 Assembler::LSL, 11074 $src3$$constant & 0x1f); 11075 %} 11076 11077 ins_pipe(ialu_reg_reg_shift); 11078 %} 11079 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 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11099 iRegIorL2I src1, iRegIorL2I src2, 11100 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11101 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11102 ins_cost(1.9 * INSN_COST); 11103 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11104 11105 ins_encode %{ 11106 __ eonw(as_Register($dst$$reg), 11107 as_Register($src1$$reg), 11108 as_Register($src2$$reg), 11109 Assembler::LSR, 11110 $src3$$constant & 0x1f); 11111 %} 11112 11113 ins_pipe(ialu_reg_reg_shift); 11114 %} 11115 11116 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11117 iRegL src1, iRegL src2, 11118 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11119 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11120 ins_cost(1.9 * INSN_COST); 11121 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11122 11123 ins_encode %{ 11124 __ eon(as_Register($dst$$reg), 11125 as_Register($src1$$reg), 11126 as_Register($src2$$reg), 11127 Assembler::LSR, 11128 $src3$$constant & 0x3f); 11129 %} 11130 11131 ins_pipe(ialu_reg_reg_shift); 11132 %} 11133 11134 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11135 iRegIorL2I src1, iRegIorL2I src2, 11136 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11137 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11138 ins_cost(1.9 * INSN_COST); 11139 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11140 11141 ins_encode %{ 11142 __ eonw(as_Register($dst$$reg), 11143 as_Register($src1$$reg), 11144 as_Register($src2$$reg), 11145 Assembler::ASR, 11146 $src3$$constant & 0x1f); 11147 %} 11148 11149 ins_pipe(ialu_reg_reg_shift); 11150 %} 11151 11152 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11153 iRegL src1, iRegL src2, 11154 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11155 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11156 ins_cost(1.9 * INSN_COST); 11157 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11158 11159 ins_encode %{ 11160 __ eon(as_Register($dst$$reg), 11161 as_Register($src1$$reg), 11162 as_Register($src2$$reg), 11163 Assembler::ASR, 11164 $src3$$constant & 0x3f); 11165 %} 11166 11167 ins_pipe(ialu_reg_reg_shift); 11168 %} 11169 11170 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11171 iRegIorL2I src1, iRegIorL2I src2, 11172 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11173 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11174 ins_cost(1.9 * INSN_COST); 11175 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11176 11177 ins_encode %{ 11178 __ eonw(as_Register($dst$$reg), 11179 as_Register($src1$$reg), 11180 as_Register($src2$$reg), 11181 Assembler::LSL, 11182 $src3$$constant & 0x1f); 11183 %} 11184 11185 ins_pipe(ialu_reg_reg_shift); 11186 %} 11187 11188 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11189 iRegL src1, iRegL src2, 11190 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11191 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11192 ins_cost(1.9 * INSN_COST); 11193 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11194 11195 ins_encode %{ 11196 __ eon(as_Register($dst$$reg), 11197 as_Register($src1$$reg), 11198 as_Register($src2$$reg), 11199 Assembler::LSL, 11200 $src3$$constant & 0x3f); 11201 %} 11202 11203 ins_pipe(ialu_reg_reg_shift); 11204 %} 11205 11206 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11207 iRegIorL2I src1, iRegIorL2I src2, 11208 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11209 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11210 ins_cost(1.9 * INSN_COST); 11211 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11212 11213 ins_encode %{ 11214 __ ornw(as_Register($dst$$reg), 11215 as_Register($src1$$reg), 11216 as_Register($src2$$reg), 11217 Assembler::LSR, 11218 $src3$$constant & 0x1f); 11219 %} 11220 11221 ins_pipe(ialu_reg_reg_shift); 11222 %} 11223 11224 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11225 iRegL src1, iRegL src2, 11226 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11227 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11228 ins_cost(1.9 * INSN_COST); 11229 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11230 11231 ins_encode %{ 11232 __ orn(as_Register($dst$$reg), 11233 as_Register($src1$$reg), 11234 as_Register($src2$$reg), 11235 Assembler::LSR, 11236 $src3$$constant & 0x3f); 11237 %} 11238 11239 ins_pipe(ialu_reg_reg_shift); 11240 %} 11241 11242 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11243 iRegIorL2I src1, iRegIorL2I src2, 11244 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11245 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11246 ins_cost(1.9 * INSN_COST); 11247 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11248 11249 ins_encode %{ 11250 __ ornw(as_Register($dst$$reg), 11251 as_Register($src1$$reg), 11252 as_Register($src2$$reg), 11253 Assembler::ASR, 11254 $src3$$constant & 0x1f); 11255 %} 11256 11257 ins_pipe(ialu_reg_reg_shift); 11258 %} 11259 11260 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11261 iRegL src1, iRegL src2, 11262 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11263 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11264 ins_cost(1.9 * INSN_COST); 11265 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11266 11267 ins_encode %{ 11268 __ orn(as_Register($dst$$reg), 11269 as_Register($src1$$reg), 11270 as_Register($src2$$reg), 11271 Assembler::ASR, 11272 $src3$$constant & 0x3f); 11273 %} 11274 11275 ins_pipe(ialu_reg_reg_shift); 11276 %} 11277 11278 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11279 iRegIorL2I src1, iRegIorL2I src2, 11280 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11281 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11282 ins_cost(1.9 * INSN_COST); 11283 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11284 11285 ins_encode %{ 11286 __ ornw(as_Register($dst$$reg), 11287 as_Register($src1$$reg), 11288 as_Register($src2$$reg), 11289 Assembler::LSL, 11290 $src3$$constant & 0x1f); 11291 %} 11292 11293 ins_pipe(ialu_reg_reg_shift); 11294 %} 11295 11296 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11297 iRegL src1, iRegL src2, 11298 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11299 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11300 ins_cost(1.9 * INSN_COST); 11301 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11302 11303 ins_encode %{ 11304 __ orn(as_Register($dst$$reg), 11305 as_Register($src1$$reg), 11306 as_Register($src2$$reg), 11307 Assembler::LSL, 11308 $src3$$constant & 0x3f); 11309 %} 11310 11311 ins_pipe(ialu_reg_reg_shift); 11312 %} 11313 11314 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11315 iRegIorL2I src1, iRegIorL2I src2, 11316 immI src3, rFlagsReg cr) %{ 11317 match(Set dst (AndI src1 (URShiftI src2 src3))); 11318 11319 ins_cost(1.9 * INSN_COST); 11320 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11321 11322 ins_encode %{ 11323 __ andw(as_Register($dst$$reg), 11324 as_Register($src1$$reg), 11325 as_Register($src2$$reg), 11326 Assembler::LSR, 11327 $src3$$constant & 0x1f); 11328 %} 11329 11330 ins_pipe(ialu_reg_reg_shift); 11331 %} 11332 11333 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11334 iRegL src1, iRegL src2, 11335 immI src3, rFlagsReg cr) %{ 11336 match(Set dst (AndL src1 (URShiftL src2 src3))); 11337 11338 ins_cost(1.9 * INSN_COST); 11339 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11340 11341 ins_encode %{ 11342 __ andr(as_Register($dst$$reg), 11343 as_Register($src1$$reg), 11344 as_Register($src2$$reg), 11345 Assembler::LSR, 11346 $src3$$constant & 0x3f); 11347 %} 11348 11349 ins_pipe(ialu_reg_reg_shift); 11350 %} 11351 11352 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11353 iRegIorL2I src1, iRegIorL2I src2, 11354 immI src3, rFlagsReg cr) %{ 11355 match(Set dst (AndI src1 (RShiftI src2 src3))); 11356 11357 ins_cost(1.9 * INSN_COST); 11358 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11359 11360 ins_encode %{ 11361 __ andw(as_Register($dst$$reg), 11362 as_Register($src1$$reg), 11363 as_Register($src2$$reg), 11364 Assembler::ASR, 11365 $src3$$constant & 0x1f); 11366 %} 11367 11368 ins_pipe(ialu_reg_reg_shift); 11369 %} 11370 11371 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11372 iRegL src1, iRegL src2, 11373 immI src3, rFlagsReg cr) %{ 11374 match(Set dst (AndL src1 (RShiftL src2 src3))); 11375 11376 ins_cost(1.9 * INSN_COST); 11377 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11378 11379 ins_encode %{ 11380 __ andr(as_Register($dst$$reg), 11381 as_Register($src1$$reg), 11382 as_Register($src2$$reg), 11383 Assembler::ASR, 11384 $src3$$constant & 0x3f); 11385 %} 11386 11387 ins_pipe(ialu_reg_reg_shift); 11388 %} 11389 11390 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11391 iRegIorL2I src1, iRegIorL2I src2, 11392 immI src3, rFlagsReg cr) %{ 11393 match(Set dst (AndI src1 (LShiftI src2 src3))); 11394 11395 ins_cost(1.9 * INSN_COST); 11396 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11397 11398 ins_encode %{ 11399 __ andw(as_Register($dst$$reg), 11400 as_Register($src1$$reg), 11401 as_Register($src2$$reg), 11402 Assembler::LSL, 11403 $src3$$constant & 0x1f); 11404 %} 11405 11406 ins_pipe(ialu_reg_reg_shift); 11407 %} 11408 11409 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11410 iRegL src1, iRegL src2, 11411 immI src3, rFlagsReg cr) %{ 11412 match(Set dst (AndL src1 (LShiftL src2 src3))); 11413 11414 ins_cost(1.9 * INSN_COST); 11415 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11416 11417 ins_encode %{ 11418 __ andr(as_Register($dst$$reg), 11419 as_Register($src1$$reg), 11420 as_Register($src2$$reg), 11421 Assembler::LSL, 11422 $src3$$constant & 0x3f); 11423 %} 11424 11425 ins_pipe(ialu_reg_reg_shift); 11426 %} 11427 11428 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11429 iRegIorL2I src1, iRegIorL2I src2, 11430 immI src3, rFlagsReg cr) %{ 11431 match(Set dst (XorI src1 (URShiftI src2 src3))); 11432 11433 ins_cost(1.9 * INSN_COST); 11434 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11435 11436 ins_encode %{ 11437 __ eorw(as_Register($dst$$reg), 11438 as_Register($src1$$reg), 11439 as_Register($src2$$reg), 11440 Assembler::LSR, 11441 $src3$$constant & 0x1f); 11442 %} 11443 11444 ins_pipe(ialu_reg_reg_shift); 11445 %} 11446 11447 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11448 iRegL src1, iRegL src2, 11449 immI src3, rFlagsReg cr) %{ 11450 match(Set dst (XorL src1 (URShiftL src2 src3))); 11451 11452 ins_cost(1.9 * INSN_COST); 11453 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11454 11455 ins_encode %{ 11456 __ eor(as_Register($dst$$reg), 11457 as_Register($src1$$reg), 11458 as_Register($src2$$reg), 11459 Assembler::LSR, 11460 $src3$$constant & 0x3f); 11461 %} 11462 11463 ins_pipe(ialu_reg_reg_shift); 11464 %} 11465 11466 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11467 iRegIorL2I src1, iRegIorL2I src2, 11468 immI src3, rFlagsReg cr) %{ 11469 match(Set dst (XorI src1 (RShiftI src2 src3))); 11470 11471 ins_cost(1.9 * INSN_COST); 11472 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11473 11474 ins_encode %{ 11475 __ eorw(as_Register($dst$$reg), 11476 as_Register($src1$$reg), 11477 as_Register($src2$$reg), 11478 Assembler::ASR, 11479 $src3$$constant & 0x1f); 11480 %} 11481 11482 ins_pipe(ialu_reg_reg_shift); 11483 %} 11484 11485 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11486 iRegL src1, iRegL src2, 11487 immI src3, rFlagsReg cr) %{ 11488 match(Set dst (XorL src1 (RShiftL src2 src3))); 11489 11490 ins_cost(1.9 * INSN_COST); 11491 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11492 11493 ins_encode %{ 11494 __ eor(as_Register($dst$$reg), 11495 as_Register($src1$$reg), 11496 as_Register($src2$$reg), 11497 Assembler::ASR, 11498 $src3$$constant & 0x3f); 11499 %} 11500 11501 ins_pipe(ialu_reg_reg_shift); 11502 %} 11503 11504 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11505 iRegIorL2I src1, iRegIorL2I src2, 11506 immI src3, rFlagsReg cr) %{ 11507 match(Set dst (XorI src1 (LShiftI src2 src3))); 11508 11509 ins_cost(1.9 * INSN_COST); 11510 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11511 11512 ins_encode %{ 11513 __ eorw(as_Register($dst$$reg), 11514 as_Register($src1$$reg), 11515 as_Register($src2$$reg), 11516 Assembler::LSL, 11517 $src3$$constant & 0x1f); 11518 %} 11519 11520 ins_pipe(ialu_reg_reg_shift); 11521 %} 11522 11523 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11524 iRegL src1, iRegL src2, 11525 immI src3, rFlagsReg cr) %{ 11526 match(Set dst (XorL src1 (LShiftL src2 src3))); 11527 11528 ins_cost(1.9 * INSN_COST); 11529 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11530 11531 ins_encode %{ 11532 __ eor(as_Register($dst$$reg), 11533 as_Register($src1$$reg), 11534 as_Register($src2$$reg), 11535 Assembler::LSL, 11536 $src3$$constant & 0x3f); 11537 %} 11538 11539 ins_pipe(ialu_reg_reg_shift); 11540 %} 11541 11542 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11543 iRegIorL2I src1, iRegIorL2I src2, 11544 immI src3, rFlagsReg cr) %{ 11545 match(Set dst (OrI src1 (URShiftI src2 src3))); 11546 11547 ins_cost(1.9 * INSN_COST); 11548 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11549 11550 ins_encode %{ 11551 __ orrw(as_Register($dst$$reg), 11552 as_Register($src1$$reg), 11553 as_Register($src2$$reg), 11554 Assembler::LSR, 11555 $src3$$constant & 0x1f); 11556 %} 11557 11558 ins_pipe(ialu_reg_reg_shift); 11559 %} 11560 11561 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11562 iRegL src1, iRegL src2, 11563 immI src3, rFlagsReg cr) %{ 11564 match(Set dst (OrL src1 (URShiftL src2 src3))); 11565 11566 ins_cost(1.9 * INSN_COST); 11567 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11568 11569 ins_encode %{ 11570 __ orr(as_Register($dst$$reg), 11571 as_Register($src1$$reg), 11572 as_Register($src2$$reg), 11573 Assembler::LSR, 11574 $src3$$constant & 0x3f); 11575 %} 11576 11577 ins_pipe(ialu_reg_reg_shift); 11578 %} 11579 11580 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11581 iRegIorL2I src1, iRegIorL2I src2, 11582 immI src3, rFlagsReg cr) %{ 11583 match(Set dst (OrI src1 (RShiftI src2 src3))); 11584 11585 ins_cost(1.9 * INSN_COST); 11586 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11587 11588 ins_encode %{ 11589 __ orrw(as_Register($dst$$reg), 11590 as_Register($src1$$reg), 11591 as_Register($src2$$reg), 11592 Assembler::ASR, 11593 $src3$$constant & 0x1f); 11594 %} 11595 11596 ins_pipe(ialu_reg_reg_shift); 11597 %} 11598 11599 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11600 iRegL src1, iRegL src2, 11601 immI src3, rFlagsReg cr) %{ 11602 match(Set dst (OrL src1 (RShiftL src2 src3))); 11603 11604 ins_cost(1.9 * INSN_COST); 11605 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11606 11607 ins_encode %{ 11608 __ orr(as_Register($dst$$reg), 11609 as_Register($src1$$reg), 11610 as_Register($src2$$reg), 11611 Assembler::ASR, 11612 $src3$$constant & 0x3f); 11613 %} 11614 11615 ins_pipe(ialu_reg_reg_shift); 11616 %} 11617 11618 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11619 iRegIorL2I src1, iRegIorL2I src2, 11620 immI src3, rFlagsReg cr) %{ 11621 match(Set dst (OrI src1 (LShiftI src2 src3))); 11622 11623 ins_cost(1.9 * INSN_COST); 11624 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11625 11626 ins_encode %{ 11627 __ orrw(as_Register($dst$$reg), 11628 as_Register($src1$$reg), 11629 as_Register($src2$$reg), 11630 Assembler::LSL, 11631 $src3$$constant & 0x1f); 11632 %} 11633 11634 ins_pipe(ialu_reg_reg_shift); 11635 %} 11636 11637 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11638 iRegL src1, iRegL src2, 11639 immI src3, rFlagsReg cr) %{ 11640 match(Set dst (OrL src1 (LShiftL src2 src3))); 11641 11642 ins_cost(1.9 * INSN_COST); 11643 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11644 11645 ins_encode %{ 11646 __ orr(as_Register($dst$$reg), 11647 as_Register($src1$$reg), 11648 as_Register($src2$$reg), 11649 Assembler::LSL, 11650 $src3$$constant & 0x3f); 11651 %} 11652 11653 ins_pipe(ialu_reg_reg_shift); 11654 %} 11655 11656 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11657 iRegIorL2I src1, iRegIorL2I src2, 11658 immI src3, rFlagsReg cr) %{ 11659 match(Set dst (AddI src1 (URShiftI src2 src3))); 11660 11661 ins_cost(1.9 * INSN_COST); 11662 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11663 11664 ins_encode %{ 11665 __ addw(as_Register($dst$$reg), 11666 as_Register($src1$$reg), 11667 as_Register($src2$$reg), 11668 Assembler::LSR, 11669 $src3$$constant & 0x1f); 11670 %} 11671 11672 ins_pipe(ialu_reg_reg_shift); 11673 %} 11674 11675 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11676 iRegL src1, iRegL src2, 11677 immI src3, rFlagsReg cr) %{ 11678 match(Set dst (AddL src1 (URShiftL src2 src3))); 11679 11680 ins_cost(1.9 * INSN_COST); 11681 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11682 11683 ins_encode %{ 11684 __ add(as_Register($dst$$reg), 11685 as_Register($src1$$reg), 11686 as_Register($src2$$reg), 11687 Assembler::LSR, 11688 $src3$$constant & 0x3f); 11689 %} 11690 11691 ins_pipe(ialu_reg_reg_shift); 11692 %} 11693 11694 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11695 iRegIorL2I src1, iRegIorL2I src2, 11696 immI src3, rFlagsReg cr) %{ 11697 match(Set dst (AddI src1 (RShiftI src2 src3))); 11698 11699 ins_cost(1.9 * INSN_COST); 11700 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11701 11702 ins_encode %{ 11703 __ addw(as_Register($dst$$reg), 11704 as_Register($src1$$reg), 11705 as_Register($src2$$reg), 11706 Assembler::ASR, 11707 $src3$$constant & 0x1f); 11708 %} 11709 11710 ins_pipe(ialu_reg_reg_shift); 11711 %} 11712 11713 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11714 iRegL src1, iRegL src2, 11715 immI src3, rFlagsReg cr) %{ 11716 match(Set dst (AddL src1 (RShiftL src2 src3))); 11717 11718 ins_cost(1.9 * INSN_COST); 11719 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11720 11721 ins_encode %{ 11722 __ add(as_Register($dst$$reg), 11723 as_Register($src1$$reg), 11724 as_Register($src2$$reg), 11725 Assembler::ASR, 11726 $src3$$constant & 0x3f); 11727 %} 11728 11729 ins_pipe(ialu_reg_reg_shift); 11730 %} 11731 11732 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11733 iRegIorL2I src1, iRegIorL2I src2, 11734 immI src3, rFlagsReg cr) %{ 11735 match(Set dst (AddI src1 (LShiftI src2 src3))); 11736 11737 ins_cost(1.9 * INSN_COST); 11738 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11739 11740 ins_encode %{ 11741 __ addw(as_Register($dst$$reg), 11742 as_Register($src1$$reg), 11743 as_Register($src2$$reg), 11744 Assembler::LSL, 11745 $src3$$constant & 0x1f); 11746 %} 11747 11748 ins_pipe(ialu_reg_reg_shift); 11749 %} 11750 11751 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11752 iRegL src1, iRegL src2, 11753 immI src3, rFlagsReg cr) %{ 11754 match(Set dst (AddL src1 (LShiftL src2 src3))); 11755 11756 ins_cost(1.9 * INSN_COST); 11757 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11758 11759 ins_encode %{ 11760 __ add(as_Register($dst$$reg), 11761 as_Register($src1$$reg), 11762 as_Register($src2$$reg), 11763 Assembler::LSL, 11764 $src3$$constant & 0x3f); 11765 %} 11766 11767 ins_pipe(ialu_reg_reg_shift); 11768 %} 11769 11770 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11771 iRegIorL2I src1, iRegIorL2I src2, 11772 immI src3, rFlagsReg cr) %{ 11773 match(Set dst (SubI src1 (URShiftI src2 src3))); 11774 11775 ins_cost(1.9 * INSN_COST); 11776 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11777 11778 ins_encode %{ 11779 __ subw(as_Register($dst$$reg), 11780 as_Register($src1$$reg), 11781 as_Register($src2$$reg), 11782 Assembler::LSR, 11783 $src3$$constant & 0x1f); 11784 %} 11785 11786 ins_pipe(ialu_reg_reg_shift); 11787 %} 11788 11789 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11790 iRegL src1, iRegL src2, 11791 immI src3, rFlagsReg cr) %{ 11792 match(Set dst (SubL src1 (URShiftL src2 src3))); 11793 11794 ins_cost(1.9 * INSN_COST); 11795 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11796 11797 ins_encode %{ 11798 __ sub(as_Register($dst$$reg), 11799 as_Register($src1$$reg), 11800 as_Register($src2$$reg), 11801 Assembler::LSR, 11802 $src3$$constant & 0x3f); 11803 %} 11804 11805 ins_pipe(ialu_reg_reg_shift); 11806 %} 11807 11808 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11809 iRegIorL2I src1, iRegIorL2I src2, 11810 immI src3, rFlagsReg cr) %{ 11811 match(Set dst (SubI src1 (RShiftI src2 src3))); 11812 11813 ins_cost(1.9 * INSN_COST); 11814 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11815 11816 ins_encode %{ 11817 __ subw(as_Register($dst$$reg), 11818 as_Register($src1$$reg), 11819 as_Register($src2$$reg), 11820 Assembler::ASR, 11821 $src3$$constant & 0x1f); 11822 %} 11823 11824 ins_pipe(ialu_reg_reg_shift); 11825 %} 11826 11827 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11828 iRegL src1, iRegL src2, 11829 immI src3, rFlagsReg cr) %{ 11830 match(Set dst (SubL src1 (RShiftL src2 src3))); 11831 11832 ins_cost(1.9 * INSN_COST); 11833 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11834 11835 ins_encode %{ 11836 __ sub(as_Register($dst$$reg), 11837 as_Register($src1$$reg), 11838 as_Register($src2$$reg), 11839 Assembler::ASR, 11840 $src3$$constant & 0x3f); 11841 %} 11842 11843 ins_pipe(ialu_reg_reg_shift); 11844 %} 11845 11846 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11847 iRegIorL2I src1, iRegIorL2I src2, 11848 immI src3, rFlagsReg cr) %{ 11849 match(Set dst (SubI src1 (LShiftI src2 src3))); 11850 11851 ins_cost(1.9 * INSN_COST); 11852 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11853 11854 ins_encode %{ 11855 __ subw(as_Register($dst$$reg), 11856 as_Register($src1$$reg), 11857 as_Register($src2$$reg), 11858 Assembler::LSL, 11859 $src3$$constant & 0x1f); 11860 %} 11861 11862 ins_pipe(ialu_reg_reg_shift); 11863 %} 11864 11865 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11866 iRegL src1, iRegL src2, 11867 immI src3, rFlagsReg cr) %{ 11868 match(Set dst (SubL src1 (LShiftL src2 src3))); 11869 11870 ins_cost(1.9 * INSN_COST); 11871 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11872 11873 ins_encode %{ 11874 __ sub(as_Register($dst$$reg), 11875 as_Register($src1$$reg), 11876 as_Register($src2$$reg), 11877 Assembler::LSL, 11878 $src3$$constant & 0x3f); 11879 %} 11880 11881 ins_pipe(ialu_reg_reg_shift); 11882 %} 11883 11884 11885 11886 // Shift Left followed by Shift Right. 11887 // This idiom is used by the compiler for the i2b bytecode etc. 11888 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11889 %{ 11890 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11891 ins_cost(INSN_COST * 2); 11892 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11893 ins_encode %{ 11894 int lshift = $lshift_count$$constant & 63; 11895 int rshift = $rshift_count$$constant & 63; 11896 int s = 63 - lshift; 11897 int r = (rshift - lshift) & 63; 11898 __ sbfm(as_Register($dst$$reg), 11899 as_Register($src$$reg), 11900 r, s); 11901 %} 11902 11903 ins_pipe(ialu_reg_shift); 11904 %} 11905 11906 // Shift Left followed by Shift Right. 11907 // This idiom is used by the compiler for the i2b bytecode etc. 11908 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11909 %{ 11910 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11911 ins_cost(INSN_COST * 2); 11912 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11913 ins_encode %{ 11914 int lshift = $lshift_count$$constant & 31; 11915 int rshift = $rshift_count$$constant & 31; 11916 int s = 31 - lshift; 11917 int r = (rshift - lshift) & 31; 11918 __ sbfmw(as_Register($dst$$reg), 11919 as_Register($src$$reg), 11920 r, s); 11921 %} 11922 11923 ins_pipe(ialu_reg_shift); 11924 %} 11925 11926 // Shift Left followed by Shift Right. 11927 // This idiom is used by the compiler for the i2b bytecode etc. 11928 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11929 %{ 11930 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11931 ins_cost(INSN_COST * 2); 11932 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11933 ins_encode %{ 11934 int lshift = $lshift_count$$constant & 63; 11935 int rshift = $rshift_count$$constant & 63; 11936 int s = 63 - lshift; 11937 int r = (rshift - lshift) & 63; 11938 __ ubfm(as_Register($dst$$reg), 11939 as_Register($src$$reg), 11940 r, s); 11941 %} 11942 11943 ins_pipe(ialu_reg_shift); 11944 %} 11945 11946 // Shift Left followed by Shift Right. 11947 // This idiom is used by the compiler for the i2b bytecode etc. 11948 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11949 %{ 11950 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11951 ins_cost(INSN_COST * 2); 11952 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11953 ins_encode %{ 11954 int lshift = $lshift_count$$constant & 31; 11955 int rshift = $rshift_count$$constant & 31; 11956 int s = 31 - lshift; 11957 int r = (rshift - lshift) & 31; 11958 __ ubfmw(as_Register($dst$$reg), 11959 as_Register($src$$reg), 11960 r, s); 11961 %} 11962 11963 ins_pipe(ialu_reg_shift); 11964 %} 11965 // Bitfield extract with shift & mask 11966 11967 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11968 %{ 11969 match(Set dst (AndI (URShiftI src rshift) mask)); 11970 // Make sure we are not going to exceed what ubfxw can do. 11971 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11972 11973 ins_cost(INSN_COST); 11974 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11975 ins_encode %{ 11976 int rshift = $rshift$$constant & 31; 11977 long mask = $mask$$constant; 11978 int width = exact_log2(mask+1); 11979 __ ubfxw(as_Register($dst$$reg), 11980 as_Register($src$$reg), rshift, width); 11981 %} 11982 ins_pipe(ialu_reg_shift); 11983 %} 11984 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11985 %{ 11986 match(Set dst (AndL (URShiftL src rshift) mask)); 11987 // Make sure we are not going to exceed what ubfx can do. 11988 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 11989 11990 ins_cost(INSN_COST); 11991 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11992 ins_encode %{ 11993 int rshift = $rshift$$constant & 63; 11994 long mask = $mask$$constant; 11995 int width = exact_log2_long(mask+1); 11996 __ ubfx(as_Register($dst$$reg), 11997 as_Register($src$$reg), rshift, width); 11998 %} 11999 ins_pipe(ialu_reg_shift); 12000 %} 12001 12002 // We can use ubfx when extending an And with a mask when we know mask 12003 // is positive. We know that because immI_bitmask guarantees it. 12004 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12005 %{ 12006 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12007 // Make sure we are not going to exceed what ubfxw can do. 12008 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12009 12010 ins_cost(INSN_COST * 2); 12011 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12012 ins_encode %{ 12013 int rshift = $rshift$$constant & 31; 12014 long mask = $mask$$constant; 12015 int width = exact_log2(mask+1); 12016 __ ubfx(as_Register($dst$$reg), 12017 as_Register($src$$reg), rshift, width); 12018 %} 12019 ins_pipe(ialu_reg_shift); 12020 %} 12021 12022 // We can use ubfiz when masking by a positive number and then left shifting the result. 12023 // We know that the mask is positive because immI_bitmask guarantees it. 12024 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12025 %{ 12026 match(Set dst (LShiftI (AndI src mask) lshift)); 12027 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12028 12029 ins_cost(INSN_COST); 12030 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12031 ins_encode %{ 12032 int lshift = $lshift$$constant & 31; 12033 long mask = $mask$$constant; 12034 int width = exact_log2(mask+1); 12035 __ ubfizw(as_Register($dst$$reg), 12036 as_Register($src$$reg), lshift, width); 12037 %} 12038 ins_pipe(ialu_reg_shift); 12039 %} 12040 // We can use ubfiz when masking by a positive number and then left shifting the result. 12041 // We know that the mask is positive because immL_bitmask guarantees it. 12042 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12043 %{ 12044 match(Set dst (LShiftL (AndL src mask) lshift)); 12045 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12046 12047 ins_cost(INSN_COST); 12048 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12049 ins_encode %{ 12050 int lshift = $lshift$$constant & 63; 12051 long mask = $mask$$constant; 12052 int width = exact_log2_long(mask+1); 12053 __ ubfiz(as_Register($dst$$reg), 12054 as_Register($src$$reg), lshift, width); 12055 %} 12056 ins_pipe(ialu_reg_shift); 12057 %} 12058 12059 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12060 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12061 %{ 12062 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12063 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12064 12065 ins_cost(INSN_COST); 12066 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12067 ins_encode %{ 12068 int lshift = $lshift$$constant & 63; 12069 long mask = $mask$$constant; 12070 int width = exact_log2(mask+1); 12071 __ ubfiz(as_Register($dst$$reg), 12072 as_Register($src$$reg), lshift, width); 12073 %} 12074 ins_pipe(ialu_reg_shift); 12075 %} 12076 12077 // Rotations 12078 12079 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12080 %{ 12081 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12082 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12083 12084 ins_cost(INSN_COST); 12085 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12086 12087 ins_encode %{ 12088 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12089 $rshift$$constant & 63); 12090 %} 12091 ins_pipe(ialu_reg_reg_extr); 12092 %} 12093 12094 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12095 %{ 12096 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12097 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12098 12099 ins_cost(INSN_COST); 12100 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12101 12102 ins_encode %{ 12103 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12104 $rshift$$constant & 31); 12105 %} 12106 ins_pipe(ialu_reg_reg_extr); 12107 %} 12108 12109 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12110 %{ 12111 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12112 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12113 12114 ins_cost(INSN_COST); 12115 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12116 12117 ins_encode %{ 12118 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12119 $rshift$$constant & 63); 12120 %} 12121 ins_pipe(ialu_reg_reg_extr); 12122 %} 12123 12124 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12125 %{ 12126 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12127 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12128 12129 ins_cost(INSN_COST); 12130 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12131 12132 ins_encode %{ 12133 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12134 $rshift$$constant & 31); 12135 %} 12136 ins_pipe(ialu_reg_reg_extr); 12137 %} 12138 12139 12140 // rol expander 12141 12142 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12143 %{ 12144 effect(DEF dst, USE src, USE shift); 12145 12146 format %{ "rol $dst, $src, $shift" %} 12147 ins_cost(INSN_COST * 3); 12148 ins_encode %{ 12149 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12150 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12151 rscratch1); 12152 %} 12153 ins_pipe(ialu_reg_reg_vshift); 12154 %} 12155 12156 // rol expander 12157 12158 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12159 %{ 12160 effect(DEF dst, USE src, USE shift); 12161 12162 format %{ "rol $dst, $src, $shift" %} 12163 ins_cost(INSN_COST * 3); 12164 ins_encode %{ 12165 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12166 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12167 rscratch1); 12168 %} 12169 ins_pipe(ialu_reg_reg_vshift); 12170 %} 12171 12172 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12173 %{ 12174 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12175 12176 expand %{ 12177 rolL_rReg(dst, src, shift, cr); 12178 %} 12179 %} 12180 12181 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12182 %{ 12183 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12184 12185 expand %{ 12186 rolL_rReg(dst, src, shift, cr); 12187 %} 12188 %} 12189 12190 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12191 %{ 12192 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12193 12194 expand %{ 12195 rolI_rReg(dst, src, shift, cr); 12196 %} 12197 %} 12198 12199 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12200 %{ 12201 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12202 12203 expand %{ 12204 rolI_rReg(dst, src, shift, cr); 12205 %} 12206 %} 12207 12208 // ror expander 12209 12210 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12211 %{ 12212 effect(DEF dst, USE src, USE shift); 12213 12214 format %{ "ror $dst, $src, $shift" %} 12215 ins_cost(INSN_COST); 12216 ins_encode %{ 12217 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12218 as_Register($shift$$reg)); 12219 %} 12220 ins_pipe(ialu_reg_reg_vshift); 12221 %} 12222 12223 // ror expander 12224 12225 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12226 %{ 12227 effect(DEF dst, USE src, USE shift); 12228 12229 format %{ "ror $dst, $src, $shift" %} 12230 ins_cost(INSN_COST); 12231 ins_encode %{ 12232 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12233 as_Register($shift$$reg)); 12234 %} 12235 ins_pipe(ialu_reg_reg_vshift); 12236 %} 12237 12238 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12239 %{ 12240 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12241 12242 expand %{ 12243 rorL_rReg(dst, src, shift, cr); 12244 %} 12245 %} 12246 12247 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12248 %{ 12249 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12250 12251 expand %{ 12252 rorL_rReg(dst, src, shift, cr); 12253 %} 12254 %} 12255 12256 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12257 %{ 12258 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12259 12260 expand %{ 12261 rorI_rReg(dst, src, shift, cr); 12262 %} 12263 %} 12264 12265 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12266 %{ 12267 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12268 12269 expand %{ 12270 rorI_rReg(dst, src, shift, cr); 12271 %} 12272 %} 12273 12274 // Add/subtract (extended) 12275 12276 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12277 %{ 12278 match(Set dst (AddL src1 (ConvI2L src2))); 12279 ins_cost(INSN_COST); 12280 format %{ "add $dst, $src1, $src2, sxtw" %} 12281 12282 ins_encode %{ 12283 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12284 as_Register($src2$$reg), ext::sxtw); 12285 %} 12286 ins_pipe(ialu_reg_reg); 12287 %}; 12288 12289 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12290 %{ 12291 match(Set dst (SubL src1 (ConvI2L src2))); 12292 ins_cost(INSN_COST); 12293 format %{ "sub $dst, $src1, $src2, sxtw" %} 12294 12295 ins_encode %{ 12296 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12297 as_Register($src2$$reg), ext::sxtw); 12298 %} 12299 ins_pipe(ialu_reg_reg); 12300 %}; 12301 12302 12303 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12304 %{ 12305 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12306 ins_cost(INSN_COST); 12307 format %{ "add $dst, $src1, $src2, sxth" %} 12308 12309 ins_encode %{ 12310 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12311 as_Register($src2$$reg), ext::sxth); 12312 %} 12313 ins_pipe(ialu_reg_reg); 12314 %} 12315 12316 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12317 %{ 12318 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12319 ins_cost(INSN_COST); 12320 format %{ "add $dst, $src1, $src2, sxtb" %} 12321 12322 ins_encode %{ 12323 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12324 as_Register($src2$$reg), ext::sxtb); 12325 %} 12326 ins_pipe(ialu_reg_reg); 12327 %} 12328 12329 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12330 %{ 12331 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12332 ins_cost(INSN_COST); 12333 format %{ "add $dst, $src1, $src2, uxtb" %} 12334 12335 ins_encode %{ 12336 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12337 as_Register($src2$$reg), ext::uxtb); 12338 %} 12339 ins_pipe(ialu_reg_reg); 12340 %} 12341 12342 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12343 %{ 12344 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12345 ins_cost(INSN_COST); 12346 format %{ "add $dst, $src1, $src2, sxth" %} 12347 12348 ins_encode %{ 12349 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12350 as_Register($src2$$reg), ext::sxth); 12351 %} 12352 ins_pipe(ialu_reg_reg); 12353 %} 12354 12355 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12356 %{ 12357 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12358 ins_cost(INSN_COST); 12359 format %{ "add $dst, $src1, $src2, sxtw" %} 12360 12361 ins_encode %{ 12362 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12363 as_Register($src2$$reg), ext::sxtw); 12364 %} 12365 ins_pipe(ialu_reg_reg); 12366 %} 12367 12368 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12369 %{ 12370 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12371 ins_cost(INSN_COST); 12372 format %{ "add $dst, $src1, $src2, sxtb" %} 12373 12374 ins_encode %{ 12375 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12376 as_Register($src2$$reg), ext::sxtb); 12377 %} 12378 ins_pipe(ialu_reg_reg); 12379 %} 12380 12381 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12382 %{ 12383 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12384 ins_cost(INSN_COST); 12385 format %{ "add $dst, $src1, $src2, uxtb" %} 12386 12387 ins_encode %{ 12388 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12389 as_Register($src2$$reg), ext::uxtb); 12390 %} 12391 ins_pipe(ialu_reg_reg); 12392 %} 12393 12394 12395 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12396 %{ 12397 match(Set dst (AddI src1 (AndI src2 mask))); 12398 ins_cost(INSN_COST); 12399 format %{ "addw $dst, $src1, $src2, uxtb" %} 12400 12401 ins_encode %{ 12402 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12403 as_Register($src2$$reg), ext::uxtb); 12404 %} 12405 ins_pipe(ialu_reg_reg); 12406 %} 12407 12408 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12409 %{ 12410 match(Set dst (AddI src1 (AndI src2 mask))); 12411 ins_cost(INSN_COST); 12412 format %{ "addw $dst, $src1, $src2, uxth" %} 12413 12414 ins_encode %{ 12415 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12416 as_Register($src2$$reg), ext::uxth); 12417 %} 12418 ins_pipe(ialu_reg_reg); 12419 %} 12420 12421 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12422 %{ 12423 match(Set dst (AddL src1 (AndL src2 mask))); 12424 ins_cost(INSN_COST); 12425 format %{ "add $dst, $src1, $src2, uxtb" %} 12426 12427 ins_encode %{ 12428 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12429 as_Register($src2$$reg), ext::uxtb); 12430 %} 12431 ins_pipe(ialu_reg_reg); 12432 %} 12433 12434 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12435 %{ 12436 match(Set dst (AddL src1 (AndL src2 mask))); 12437 ins_cost(INSN_COST); 12438 format %{ "add $dst, $src1, $src2, uxth" %} 12439 12440 ins_encode %{ 12441 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12442 as_Register($src2$$reg), ext::uxth); 12443 %} 12444 ins_pipe(ialu_reg_reg); 12445 %} 12446 12447 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12448 %{ 12449 match(Set dst (AddL src1 (AndL src2 mask))); 12450 ins_cost(INSN_COST); 12451 format %{ "add $dst, $src1, $src2, uxtw" %} 12452 12453 ins_encode %{ 12454 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12455 as_Register($src2$$reg), ext::uxtw); 12456 %} 12457 ins_pipe(ialu_reg_reg); 12458 %} 12459 12460 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12461 %{ 12462 match(Set dst (SubI src1 (AndI src2 mask))); 12463 ins_cost(INSN_COST); 12464 format %{ "subw $dst, $src1, $src2, uxtb" %} 12465 12466 ins_encode %{ 12467 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12468 as_Register($src2$$reg), ext::uxtb); 12469 %} 12470 ins_pipe(ialu_reg_reg); 12471 %} 12472 12473 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12474 %{ 12475 match(Set dst (SubI src1 (AndI src2 mask))); 12476 ins_cost(INSN_COST); 12477 format %{ "subw $dst, $src1, $src2, uxth" %} 12478 12479 ins_encode %{ 12480 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12481 as_Register($src2$$reg), ext::uxth); 12482 %} 12483 ins_pipe(ialu_reg_reg); 12484 %} 12485 12486 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12487 %{ 12488 match(Set dst (SubL src1 (AndL src2 mask))); 12489 ins_cost(INSN_COST); 12490 format %{ "sub $dst, $src1, $src2, uxtb" %} 12491 12492 ins_encode %{ 12493 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12494 as_Register($src2$$reg), ext::uxtb); 12495 %} 12496 ins_pipe(ialu_reg_reg); 12497 %} 12498 12499 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12500 %{ 12501 match(Set dst (SubL src1 (AndL src2 mask))); 12502 ins_cost(INSN_COST); 12503 format %{ "sub $dst, $src1, $src2, uxth" %} 12504 12505 ins_encode %{ 12506 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12507 as_Register($src2$$reg), ext::uxth); 12508 %} 12509 ins_pipe(ialu_reg_reg); 12510 %} 12511 12512 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12513 %{ 12514 match(Set dst (SubL src1 (AndL src2 mask))); 12515 ins_cost(INSN_COST); 12516 format %{ "sub $dst, $src1, $src2, uxtw" %} 12517 12518 ins_encode %{ 12519 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12520 as_Register($src2$$reg), ext::uxtw); 12521 %} 12522 ins_pipe(ialu_reg_reg); 12523 %} 12524 12525 12526 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12527 %{ 12528 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12529 ins_cost(1.9 * INSN_COST); 12530 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12531 12532 ins_encode %{ 12533 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12534 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12535 %} 12536 ins_pipe(ialu_reg_reg_shift); 12537 %} 12538 12539 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12540 %{ 12541 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12542 ins_cost(1.9 * INSN_COST); 12543 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12544 12545 ins_encode %{ 12546 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12547 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12548 %} 12549 ins_pipe(ialu_reg_reg_shift); 12550 %} 12551 12552 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12553 %{ 12554 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12555 ins_cost(1.9 * INSN_COST); 12556 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12557 12558 ins_encode %{ 12559 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12560 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12561 %} 12562 ins_pipe(ialu_reg_reg_shift); 12563 %} 12564 12565 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12566 %{ 12567 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12568 ins_cost(1.9 * INSN_COST); 12569 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12570 12571 ins_encode %{ 12572 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12573 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12574 %} 12575 ins_pipe(ialu_reg_reg_shift); 12576 %} 12577 12578 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12579 %{ 12580 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12581 ins_cost(1.9 * INSN_COST); 12582 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12583 12584 ins_encode %{ 12585 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12586 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12587 %} 12588 ins_pipe(ialu_reg_reg_shift); 12589 %} 12590 12591 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12592 %{ 12593 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12594 ins_cost(1.9 * INSN_COST); 12595 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12596 12597 ins_encode %{ 12598 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12599 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12600 %} 12601 ins_pipe(ialu_reg_reg_shift); 12602 %} 12603 12604 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12605 %{ 12606 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12607 ins_cost(1.9 * INSN_COST); 12608 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12609 12610 ins_encode %{ 12611 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12612 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12613 %} 12614 ins_pipe(ialu_reg_reg_shift); 12615 %} 12616 12617 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12618 %{ 12619 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12620 ins_cost(1.9 * INSN_COST); 12621 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12622 12623 ins_encode %{ 12624 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12625 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12626 %} 12627 ins_pipe(ialu_reg_reg_shift); 12628 %} 12629 12630 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12631 %{ 12632 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12633 ins_cost(1.9 * INSN_COST); 12634 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12635 12636 ins_encode %{ 12637 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12638 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12639 %} 12640 ins_pipe(ialu_reg_reg_shift); 12641 %} 12642 12643 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12644 %{ 12645 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12646 ins_cost(1.9 * INSN_COST); 12647 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12648 12649 ins_encode %{ 12650 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12651 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12652 %} 12653 ins_pipe(ialu_reg_reg_shift); 12654 %} 12655 12656 12657 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12658 %{ 12659 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12660 ins_cost(1.9 * INSN_COST); 12661 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12662 12663 ins_encode %{ 12664 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12665 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12666 %} 12667 ins_pipe(ialu_reg_reg_shift); 12668 %}; 12669 12670 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12671 %{ 12672 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12673 ins_cost(1.9 * INSN_COST); 12674 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12675 12676 ins_encode %{ 12677 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12678 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12679 %} 12680 ins_pipe(ialu_reg_reg_shift); 12681 %}; 12682 12683 12684 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12685 %{ 12686 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12687 ins_cost(1.9 * INSN_COST); 12688 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12689 12690 ins_encode %{ 12691 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12692 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12693 %} 12694 ins_pipe(ialu_reg_reg_shift); 12695 %} 12696 12697 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12698 %{ 12699 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12700 ins_cost(1.9 * INSN_COST); 12701 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12702 12703 ins_encode %{ 12704 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12705 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12706 %} 12707 ins_pipe(ialu_reg_reg_shift); 12708 %} 12709 12710 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12711 %{ 12712 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12713 ins_cost(1.9 * INSN_COST); 12714 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12715 12716 ins_encode %{ 12717 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12718 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12719 %} 12720 ins_pipe(ialu_reg_reg_shift); 12721 %} 12722 12723 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12724 %{ 12725 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12726 ins_cost(1.9 * INSN_COST); 12727 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12728 12729 ins_encode %{ 12730 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12731 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12732 %} 12733 ins_pipe(ialu_reg_reg_shift); 12734 %} 12735 12736 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12737 %{ 12738 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12739 ins_cost(1.9 * INSN_COST); 12740 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12741 12742 ins_encode %{ 12743 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12744 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12745 %} 12746 ins_pipe(ialu_reg_reg_shift); 12747 %} 12748 12749 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12750 %{ 12751 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12752 ins_cost(1.9 * INSN_COST); 12753 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12754 12755 ins_encode %{ 12756 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12757 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12758 %} 12759 ins_pipe(ialu_reg_reg_shift); 12760 %} 12761 12762 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12763 %{ 12764 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12765 ins_cost(1.9 * INSN_COST); 12766 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12767 12768 ins_encode %{ 12769 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12770 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12771 %} 12772 ins_pipe(ialu_reg_reg_shift); 12773 %} 12774 12775 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12776 %{ 12777 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12778 ins_cost(1.9 * INSN_COST); 12779 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12780 12781 ins_encode %{ 12782 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12783 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12784 %} 12785 ins_pipe(ialu_reg_reg_shift); 12786 %} 12787 12788 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12789 %{ 12790 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12791 ins_cost(1.9 * INSN_COST); 12792 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12793 12794 ins_encode %{ 12795 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12796 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12797 %} 12798 ins_pipe(ialu_reg_reg_shift); 12799 %} 12800 12801 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12802 %{ 12803 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12804 ins_cost(1.9 * INSN_COST); 12805 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12806 12807 ins_encode %{ 12808 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12809 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12810 %} 12811 ins_pipe(ialu_reg_reg_shift); 12812 %} 12813 // END This section of the file is automatically generated. Do not edit -------------- 12814 12815 // ============================================================================ 12816 // Floating Point Arithmetic Instructions 12817 12818 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12819 match(Set dst (AddF src1 src2)); 12820 12821 ins_cost(INSN_COST * 5); 12822 format %{ "fadds $dst, $src1, $src2" %} 12823 12824 ins_encode %{ 12825 __ fadds(as_FloatRegister($dst$$reg), 12826 as_FloatRegister($src1$$reg), 12827 as_FloatRegister($src2$$reg)); 12828 %} 12829 12830 ins_pipe(fp_dop_reg_reg_s); 12831 %} 12832 12833 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12834 match(Set dst (AddD src1 src2)); 12835 12836 ins_cost(INSN_COST * 5); 12837 format %{ "faddd $dst, $src1, $src2" %} 12838 12839 ins_encode %{ 12840 __ faddd(as_FloatRegister($dst$$reg), 12841 as_FloatRegister($src1$$reg), 12842 as_FloatRegister($src2$$reg)); 12843 %} 12844 12845 ins_pipe(fp_dop_reg_reg_d); 12846 %} 12847 12848 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12849 match(Set dst (SubF src1 src2)); 12850 12851 ins_cost(INSN_COST * 5); 12852 format %{ "fsubs $dst, $src1, $src2" %} 12853 12854 ins_encode %{ 12855 __ fsubs(as_FloatRegister($dst$$reg), 12856 as_FloatRegister($src1$$reg), 12857 as_FloatRegister($src2$$reg)); 12858 %} 12859 12860 ins_pipe(fp_dop_reg_reg_s); 12861 %} 12862 12863 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12864 match(Set dst (SubD src1 src2)); 12865 12866 ins_cost(INSN_COST * 5); 12867 format %{ "fsubd $dst, $src1, $src2" %} 12868 12869 ins_encode %{ 12870 __ fsubd(as_FloatRegister($dst$$reg), 12871 as_FloatRegister($src1$$reg), 12872 as_FloatRegister($src2$$reg)); 12873 %} 12874 12875 ins_pipe(fp_dop_reg_reg_d); 12876 %} 12877 12878 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12879 match(Set dst (MulF src1 src2)); 12880 12881 ins_cost(INSN_COST * 6); 12882 format %{ "fmuls $dst, $src1, $src2" %} 12883 12884 ins_encode %{ 12885 __ fmuls(as_FloatRegister($dst$$reg), 12886 as_FloatRegister($src1$$reg), 12887 as_FloatRegister($src2$$reg)); 12888 %} 12889 12890 ins_pipe(fp_dop_reg_reg_s); 12891 %} 12892 12893 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12894 match(Set dst (MulD src1 src2)); 12895 12896 ins_cost(INSN_COST * 6); 12897 format %{ "fmuld $dst, $src1, $src2" %} 12898 12899 ins_encode %{ 12900 __ fmuld(as_FloatRegister($dst$$reg), 12901 as_FloatRegister($src1$$reg), 12902 as_FloatRegister($src2$$reg)); 12903 %} 12904 12905 ins_pipe(fp_dop_reg_reg_d); 12906 %} 12907 12908 // src1 * src2 + src3 12909 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12910 predicate(UseFMA); 12911 match(Set dst (FmaF src3 (Binary src1 src2))); 12912 12913 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12914 12915 ins_encode %{ 12916 __ fmadds(as_FloatRegister($dst$$reg), 12917 as_FloatRegister($src1$$reg), 12918 as_FloatRegister($src2$$reg), 12919 as_FloatRegister($src3$$reg)); 12920 %} 12921 12922 ins_pipe(pipe_class_default); 12923 %} 12924 12925 // src1 * src2 + src3 12926 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12927 predicate(UseFMA); 12928 match(Set dst (FmaD src3 (Binary src1 src2))); 12929 12930 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12931 12932 ins_encode %{ 12933 __ fmaddd(as_FloatRegister($dst$$reg), 12934 as_FloatRegister($src1$$reg), 12935 as_FloatRegister($src2$$reg), 12936 as_FloatRegister($src3$$reg)); 12937 %} 12938 12939 ins_pipe(pipe_class_default); 12940 %} 12941 12942 // -src1 * src2 + src3 12943 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12944 predicate(UseFMA); 12945 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12946 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12947 12948 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12949 12950 ins_encode %{ 12951 __ fmsubs(as_FloatRegister($dst$$reg), 12952 as_FloatRegister($src1$$reg), 12953 as_FloatRegister($src2$$reg), 12954 as_FloatRegister($src3$$reg)); 12955 %} 12956 12957 ins_pipe(pipe_class_default); 12958 %} 12959 12960 // -src1 * src2 + src3 12961 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12962 predicate(UseFMA); 12963 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12964 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12965 12966 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12967 12968 ins_encode %{ 12969 __ fmsubd(as_FloatRegister($dst$$reg), 12970 as_FloatRegister($src1$$reg), 12971 as_FloatRegister($src2$$reg), 12972 as_FloatRegister($src3$$reg)); 12973 %} 12974 12975 ins_pipe(pipe_class_default); 12976 %} 12977 12978 // -src1 * src2 - src3 12979 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12980 predicate(UseFMA); 12981 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12982 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12983 12984 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12985 12986 ins_encode %{ 12987 __ fnmadds(as_FloatRegister($dst$$reg), 12988 as_FloatRegister($src1$$reg), 12989 as_FloatRegister($src2$$reg), 12990 as_FloatRegister($src3$$reg)); 12991 %} 12992 12993 ins_pipe(pipe_class_default); 12994 %} 12995 12996 // -src1 * src2 - src3 12997 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12998 predicate(UseFMA); 12999 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13000 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13001 13002 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13003 13004 ins_encode %{ 13005 __ fnmaddd(as_FloatRegister($dst$$reg), 13006 as_FloatRegister($src1$$reg), 13007 as_FloatRegister($src2$$reg), 13008 as_FloatRegister($src3$$reg)); 13009 %} 13010 13011 ins_pipe(pipe_class_default); 13012 %} 13013 13014 // src1 * src2 - src3 13015 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13016 predicate(UseFMA); 13017 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13018 13019 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13020 13021 ins_encode %{ 13022 __ fnmsubs(as_FloatRegister($dst$$reg), 13023 as_FloatRegister($src1$$reg), 13024 as_FloatRegister($src2$$reg), 13025 as_FloatRegister($src3$$reg)); 13026 %} 13027 13028 ins_pipe(pipe_class_default); 13029 %} 13030 13031 // src1 * src2 - src3 13032 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13033 predicate(UseFMA); 13034 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13035 13036 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13037 13038 ins_encode %{ 13039 // n.b. insn name should be fnmsubd 13040 __ fnmsub(as_FloatRegister($dst$$reg), 13041 as_FloatRegister($src1$$reg), 13042 as_FloatRegister($src2$$reg), 13043 as_FloatRegister($src3$$reg)); 13044 %} 13045 13046 ins_pipe(pipe_class_default); 13047 %} 13048 13049 13050 // Math.max(FF)F 13051 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13052 match(Set dst (MaxF src1 src2)); 13053 13054 format %{ "fmaxs $dst, $src1, $src2" %} 13055 ins_encode %{ 13056 __ fmaxs(as_FloatRegister($dst$$reg), 13057 as_FloatRegister($src1$$reg), 13058 as_FloatRegister($src2$$reg)); 13059 %} 13060 13061 ins_pipe(fp_dop_reg_reg_s); 13062 %} 13063 13064 // Math.min(FF)F 13065 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13066 match(Set dst (MinF src1 src2)); 13067 13068 format %{ "fmins $dst, $src1, $src2" %} 13069 ins_encode %{ 13070 __ fmins(as_FloatRegister($dst$$reg), 13071 as_FloatRegister($src1$$reg), 13072 as_FloatRegister($src2$$reg)); 13073 %} 13074 13075 ins_pipe(fp_dop_reg_reg_s); 13076 %} 13077 13078 // Math.max(DD)D 13079 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13080 match(Set dst (MaxD src1 src2)); 13081 13082 format %{ "fmaxd $dst, $src1, $src2" %} 13083 ins_encode %{ 13084 __ fmaxd(as_FloatRegister($dst$$reg), 13085 as_FloatRegister($src1$$reg), 13086 as_FloatRegister($src2$$reg)); 13087 %} 13088 13089 ins_pipe(fp_dop_reg_reg_d); 13090 %} 13091 13092 // Math.min(DD)D 13093 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13094 match(Set dst (MinD src1 src2)); 13095 13096 format %{ "fmind $dst, $src1, $src2" %} 13097 ins_encode %{ 13098 __ fmind(as_FloatRegister($dst$$reg), 13099 as_FloatRegister($src1$$reg), 13100 as_FloatRegister($src2$$reg)); 13101 %} 13102 13103 ins_pipe(fp_dop_reg_reg_d); 13104 %} 13105 13106 13107 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13108 match(Set dst (DivF src1 src2)); 13109 13110 ins_cost(INSN_COST * 18); 13111 format %{ "fdivs $dst, $src1, $src2" %} 13112 13113 ins_encode %{ 13114 __ fdivs(as_FloatRegister($dst$$reg), 13115 as_FloatRegister($src1$$reg), 13116 as_FloatRegister($src2$$reg)); 13117 %} 13118 13119 ins_pipe(fp_div_s); 13120 %} 13121 13122 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13123 match(Set dst (DivD src1 src2)); 13124 13125 ins_cost(INSN_COST * 32); 13126 format %{ "fdivd $dst, $src1, $src2" %} 13127 13128 ins_encode %{ 13129 __ fdivd(as_FloatRegister($dst$$reg), 13130 as_FloatRegister($src1$$reg), 13131 as_FloatRegister($src2$$reg)); 13132 %} 13133 13134 ins_pipe(fp_div_d); 13135 %} 13136 13137 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13138 match(Set dst (NegF src)); 13139 13140 ins_cost(INSN_COST * 3); 13141 format %{ "fneg $dst, $src" %} 13142 13143 ins_encode %{ 13144 __ fnegs(as_FloatRegister($dst$$reg), 13145 as_FloatRegister($src$$reg)); 13146 %} 13147 13148 ins_pipe(fp_uop_s); 13149 %} 13150 13151 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13152 match(Set dst (NegD src)); 13153 13154 ins_cost(INSN_COST * 3); 13155 format %{ "fnegd $dst, $src" %} 13156 13157 ins_encode %{ 13158 __ fnegd(as_FloatRegister($dst$$reg), 13159 as_FloatRegister($src$$reg)); 13160 %} 13161 13162 ins_pipe(fp_uop_d); 13163 %} 13164 13165 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13166 %{ 13167 match(Set dst (AbsI src)); 13168 13169 effect(KILL cr); 13170 ins_cost(INSN_COST * 2); 13171 format %{ "cmpw $src, zr\n\t" 13172 "cnegw $dst, $src, Assembler::LT\t# int abs" 13173 %} 13174 13175 ins_encode %{ 13176 __ cmpw(as_Register($src$$reg), zr); 13177 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13178 %} 13179 ins_pipe(pipe_class_default); 13180 %} 13181 13182 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 13183 %{ 13184 match(Set dst (AbsL src)); 13185 13186 effect(KILL cr); 13187 ins_cost(INSN_COST * 2); 13188 format %{ "cmp $src, zr\n\t" 13189 "cneg $dst, $src, Assembler::LT\t# long abs" 13190 %} 13191 13192 ins_encode %{ 13193 __ cmp(as_Register($src$$reg), zr); 13194 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13195 %} 13196 ins_pipe(pipe_class_default); 13197 %} 13198 13199 instruct absF_reg(vRegF dst, vRegF src) %{ 13200 match(Set dst (AbsF src)); 13201 13202 ins_cost(INSN_COST * 3); 13203 format %{ "fabss $dst, $src" %} 13204 ins_encode %{ 13205 __ fabss(as_FloatRegister($dst$$reg), 13206 as_FloatRegister($src$$reg)); 13207 %} 13208 13209 ins_pipe(fp_uop_s); 13210 %} 13211 13212 instruct absD_reg(vRegD dst, vRegD src) %{ 13213 match(Set dst (AbsD src)); 13214 13215 ins_cost(INSN_COST * 3); 13216 format %{ "fabsd $dst, $src" %} 13217 ins_encode %{ 13218 __ fabsd(as_FloatRegister($dst$$reg), 13219 as_FloatRegister($src$$reg)); 13220 %} 13221 13222 ins_pipe(fp_uop_d); 13223 %} 13224 13225 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13226 match(Set dst (SqrtD src)); 13227 13228 ins_cost(INSN_COST * 50); 13229 format %{ "fsqrtd $dst, $src" %} 13230 ins_encode %{ 13231 __ fsqrtd(as_FloatRegister($dst$$reg), 13232 as_FloatRegister($src$$reg)); 13233 %} 13234 13235 ins_pipe(fp_div_s); 13236 %} 13237 13238 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13239 match(Set dst (SqrtF src)); 13240 13241 ins_cost(INSN_COST * 50); 13242 format %{ "fsqrts $dst, $src" %} 13243 ins_encode %{ 13244 __ fsqrts(as_FloatRegister($dst$$reg), 13245 as_FloatRegister($src$$reg)); 13246 %} 13247 13248 ins_pipe(fp_div_d); 13249 %} 13250 13251 // Math.rint, floor, ceil 13252 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 13253 match(Set dst (RoundDoubleMode src rmode)); 13254 format %{ "frint $dst, $src, $rmode" %} 13255 ins_encode %{ 13256 switch ($rmode$$constant) { 13257 case RoundDoubleModeNode::rmode_rint: 13258 __ frintnd(as_FloatRegister($dst$$reg), 13259 as_FloatRegister($src$$reg)); 13260 break; 13261 case RoundDoubleModeNode::rmode_floor: 13262 __ frintmd(as_FloatRegister($dst$$reg), 13263 as_FloatRegister($src$$reg)); 13264 break; 13265 case RoundDoubleModeNode::rmode_ceil: 13266 __ frintpd(as_FloatRegister($dst$$reg), 13267 as_FloatRegister($src$$reg)); 13268 break; 13269 } 13270 %} 13271 ins_pipe(fp_uop_d); 13272 %} 13273 13274 // ============================================================================ 13275 // Logical Instructions 13276 13277 // Integer Logical Instructions 13278 13279 // And Instructions 13280 13281 13282 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13283 match(Set dst (AndI src1 src2)); 13284 13285 format %{ "andw $dst, $src1, $src2\t# int" %} 13286 13287 ins_cost(INSN_COST); 13288 ins_encode %{ 13289 __ andw(as_Register($dst$$reg), 13290 as_Register($src1$$reg), 13291 as_Register($src2$$reg)); 13292 %} 13293 13294 ins_pipe(ialu_reg_reg); 13295 %} 13296 13297 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13298 match(Set dst (AndI src1 src2)); 13299 13300 format %{ "andsw $dst, $src1, $src2\t# int" %} 13301 13302 ins_cost(INSN_COST); 13303 ins_encode %{ 13304 __ andw(as_Register($dst$$reg), 13305 as_Register($src1$$reg), 13306 (unsigned long)($src2$$constant)); 13307 %} 13308 13309 ins_pipe(ialu_reg_imm); 13310 %} 13311 13312 // Or Instructions 13313 13314 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13315 match(Set dst (OrI src1 src2)); 13316 13317 format %{ "orrw $dst, $src1, $src2\t# int" %} 13318 13319 ins_cost(INSN_COST); 13320 ins_encode %{ 13321 __ orrw(as_Register($dst$$reg), 13322 as_Register($src1$$reg), 13323 as_Register($src2$$reg)); 13324 %} 13325 13326 ins_pipe(ialu_reg_reg); 13327 %} 13328 13329 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13330 match(Set dst (OrI src1 src2)); 13331 13332 format %{ "orrw $dst, $src1, $src2\t# int" %} 13333 13334 ins_cost(INSN_COST); 13335 ins_encode %{ 13336 __ orrw(as_Register($dst$$reg), 13337 as_Register($src1$$reg), 13338 (unsigned long)($src2$$constant)); 13339 %} 13340 13341 ins_pipe(ialu_reg_imm); 13342 %} 13343 13344 // Xor Instructions 13345 13346 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13347 match(Set dst (XorI src1 src2)); 13348 13349 format %{ "eorw $dst, $src1, $src2\t# int" %} 13350 13351 ins_cost(INSN_COST); 13352 ins_encode %{ 13353 __ eorw(as_Register($dst$$reg), 13354 as_Register($src1$$reg), 13355 as_Register($src2$$reg)); 13356 %} 13357 13358 ins_pipe(ialu_reg_reg); 13359 %} 13360 13361 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13362 match(Set dst (XorI src1 src2)); 13363 13364 format %{ "eorw $dst, $src1, $src2\t# int" %} 13365 13366 ins_cost(INSN_COST); 13367 ins_encode %{ 13368 __ eorw(as_Register($dst$$reg), 13369 as_Register($src1$$reg), 13370 (unsigned long)($src2$$constant)); 13371 %} 13372 13373 ins_pipe(ialu_reg_imm); 13374 %} 13375 13376 // Long Logical Instructions 13377 // TODO 13378 13379 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13380 match(Set dst (AndL src1 src2)); 13381 13382 format %{ "and $dst, $src1, $src2\t# int" %} 13383 13384 ins_cost(INSN_COST); 13385 ins_encode %{ 13386 __ andr(as_Register($dst$$reg), 13387 as_Register($src1$$reg), 13388 as_Register($src2$$reg)); 13389 %} 13390 13391 ins_pipe(ialu_reg_reg); 13392 %} 13393 13394 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13395 match(Set dst (AndL src1 src2)); 13396 13397 format %{ "and $dst, $src1, $src2\t# int" %} 13398 13399 ins_cost(INSN_COST); 13400 ins_encode %{ 13401 __ andr(as_Register($dst$$reg), 13402 as_Register($src1$$reg), 13403 (unsigned long)($src2$$constant)); 13404 %} 13405 13406 ins_pipe(ialu_reg_imm); 13407 %} 13408 13409 // Or Instructions 13410 13411 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13412 match(Set dst (OrL src1 src2)); 13413 13414 format %{ "orr $dst, $src1, $src2\t# int" %} 13415 13416 ins_cost(INSN_COST); 13417 ins_encode %{ 13418 __ orr(as_Register($dst$$reg), 13419 as_Register($src1$$reg), 13420 as_Register($src2$$reg)); 13421 %} 13422 13423 ins_pipe(ialu_reg_reg); 13424 %} 13425 13426 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13427 match(Set dst (OrL src1 src2)); 13428 13429 format %{ "orr $dst, $src1, $src2\t# int" %} 13430 13431 ins_cost(INSN_COST); 13432 ins_encode %{ 13433 __ orr(as_Register($dst$$reg), 13434 as_Register($src1$$reg), 13435 (unsigned long)($src2$$constant)); 13436 %} 13437 13438 ins_pipe(ialu_reg_imm); 13439 %} 13440 13441 // Xor Instructions 13442 13443 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13444 match(Set dst (XorL src1 src2)); 13445 13446 format %{ "eor $dst, $src1, $src2\t# int" %} 13447 13448 ins_cost(INSN_COST); 13449 ins_encode %{ 13450 __ eor(as_Register($dst$$reg), 13451 as_Register($src1$$reg), 13452 as_Register($src2$$reg)); 13453 %} 13454 13455 ins_pipe(ialu_reg_reg); 13456 %} 13457 13458 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13459 match(Set dst (XorL src1 src2)); 13460 13461 ins_cost(INSN_COST); 13462 format %{ "eor $dst, $src1, $src2\t# int" %} 13463 13464 ins_encode %{ 13465 __ eor(as_Register($dst$$reg), 13466 as_Register($src1$$reg), 13467 (unsigned long)($src2$$constant)); 13468 %} 13469 13470 ins_pipe(ialu_reg_imm); 13471 %} 13472 13473 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13474 %{ 13475 match(Set dst (ConvI2L src)); 13476 13477 ins_cost(INSN_COST); 13478 format %{ "sxtw $dst, $src\t# i2l" %} 13479 ins_encode %{ 13480 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13481 %} 13482 ins_pipe(ialu_reg_shift); 13483 %} 13484 13485 // this pattern occurs in bigmath arithmetic 13486 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13487 %{ 13488 match(Set dst (AndL (ConvI2L src) mask)); 13489 13490 ins_cost(INSN_COST); 13491 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13492 ins_encode %{ 13493 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13494 %} 13495 13496 ins_pipe(ialu_reg_shift); 13497 %} 13498 13499 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13500 match(Set dst (ConvL2I src)); 13501 13502 ins_cost(INSN_COST); 13503 format %{ "movw $dst, $src \t// l2i" %} 13504 13505 ins_encode %{ 13506 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13507 %} 13508 13509 ins_pipe(ialu_reg); 13510 %} 13511 13512 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13513 %{ 13514 match(Set dst (Conv2B src)); 13515 effect(KILL cr); 13516 13517 format %{ 13518 "cmpw $src, zr\n\t" 13519 "cset $dst, ne" 13520 %} 13521 13522 ins_encode %{ 13523 __ cmpw(as_Register($src$$reg), zr); 13524 __ cset(as_Register($dst$$reg), Assembler::NE); 13525 %} 13526 13527 ins_pipe(ialu_reg); 13528 %} 13529 13530 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13531 %{ 13532 match(Set dst (Conv2B src)); 13533 effect(KILL cr); 13534 13535 format %{ 13536 "cmp $src, zr\n\t" 13537 "cset $dst, ne" 13538 %} 13539 13540 ins_encode %{ 13541 __ cmp(as_Register($src$$reg), zr); 13542 __ cset(as_Register($dst$$reg), Assembler::NE); 13543 %} 13544 13545 ins_pipe(ialu_reg); 13546 %} 13547 13548 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13549 match(Set dst (ConvD2F src)); 13550 13551 ins_cost(INSN_COST * 5); 13552 format %{ "fcvtd $dst, $src \t// d2f" %} 13553 13554 ins_encode %{ 13555 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13556 %} 13557 13558 ins_pipe(fp_d2f); 13559 %} 13560 13561 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13562 match(Set dst (ConvF2D src)); 13563 13564 ins_cost(INSN_COST * 5); 13565 format %{ "fcvts $dst, $src \t// f2d" %} 13566 13567 ins_encode %{ 13568 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13569 %} 13570 13571 ins_pipe(fp_f2d); 13572 %} 13573 13574 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13575 match(Set dst (ConvF2I src)); 13576 13577 ins_cost(INSN_COST * 5); 13578 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13579 13580 ins_encode %{ 13581 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13582 %} 13583 13584 ins_pipe(fp_f2i); 13585 %} 13586 13587 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13588 match(Set dst (ConvF2L src)); 13589 13590 ins_cost(INSN_COST * 5); 13591 format %{ "fcvtzs $dst, $src \t// f2l" %} 13592 13593 ins_encode %{ 13594 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13595 %} 13596 13597 ins_pipe(fp_f2l); 13598 %} 13599 13600 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13601 match(Set dst (ConvI2F src)); 13602 13603 ins_cost(INSN_COST * 5); 13604 format %{ "scvtfws $dst, $src \t// i2f" %} 13605 13606 ins_encode %{ 13607 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13608 %} 13609 13610 ins_pipe(fp_i2f); 13611 %} 13612 13613 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13614 match(Set dst (ConvL2F src)); 13615 13616 ins_cost(INSN_COST * 5); 13617 format %{ "scvtfs $dst, $src \t// l2f" %} 13618 13619 ins_encode %{ 13620 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13621 %} 13622 13623 ins_pipe(fp_l2f); 13624 %} 13625 13626 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13627 match(Set dst (ConvD2I src)); 13628 13629 ins_cost(INSN_COST * 5); 13630 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13631 13632 ins_encode %{ 13633 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13634 %} 13635 13636 ins_pipe(fp_d2i); 13637 %} 13638 13639 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13640 match(Set dst (ConvD2L src)); 13641 13642 ins_cost(INSN_COST * 5); 13643 format %{ "fcvtzd $dst, $src \t// d2l" %} 13644 13645 ins_encode %{ 13646 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13647 %} 13648 13649 ins_pipe(fp_d2l); 13650 %} 13651 13652 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13653 match(Set dst (ConvI2D src)); 13654 13655 ins_cost(INSN_COST * 5); 13656 format %{ "scvtfwd $dst, $src \t// i2d" %} 13657 13658 ins_encode %{ 13659 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13660 %} 13661 13662 ins_pipe(fp_i2d); 13663 %} 13664 13665 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13666 match(Set dst (ConvL2D src)); 13667 13668 ins_cost(INSN_COST * 5); 13669 format %{ "scvtfd $dst, $src \t// l2d" %} 13670 13671 ins_encode %{ 13672 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13673 %} 13674 13675 ins_pipe(fp_l2d); 13676 %} 13677 13678 // stack <-> reg and reg <-> reg shuffles with no conversion 13679 13680 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13681 13682 match(Set dst (MoveF2I src)); 13683 13684 effect(DEF dst, USE src); 13685 13686 ins_cost(4 * INSN_COST); 13687 13688 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13689 13690 ins_encode %{ 13691 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13692 %} 13693 13694 ins_pipe(iload_reg_reg); 13695 13696 %} 13697 13698 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13699 13700 match(Set dst (MoveI2F src)); 13701 13702 effect(DEF dst, USE src); 13703 13704 ins_cost(4 * INSN_COST); 13705 13706 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13707 13708 ins_encode %{ 13709 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13710 %} 13711 13712 ins_pipe(pipe_class_memory); 13713 13714 %} 13715 13716 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13717 13718 match(Set dst (MoveD2L src)); 13719 13720 effect(DEF dst, USE src); 13721 13722 ins_cost(4 * INSN_COST); 13723 13724 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13725 13726 ins_encode %{ 13727 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13728 %} 13729 13730 ins_pipe(iload_reg_reg); 13731 13732 %} 13733 13734 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13735 13736 match(Set dst (MoveL2D src)); 13737 13738 effect(DEF dst, USE src); 13739 13740 ins_cost(4 * INSN_COST); 13741 13742 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13743 13744 ins_encode %{ 13745 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13746 %} 13747 13748 ins_pipe(pipe_class_memory); 13749 13750 %} 13751 13752 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13753 13754 match(Set dst (MoveF2I src)); 13755 13756 effect(DEF dst, USE src); 13757 13758 ins_cost(INSN_COST); 13759 13760 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13761 13762 ins_encode %{ 13763 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13764 %} 13765 13766 ins_pipe(pipe_class_memory); 13767 13768 %} 13769 13770 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13771 13772 match(Set dst (MoveI2F src)); 13773 13774 effect(DEF dst, USE src); 13775 13776 ins_cost(INSN_COST); 13777 13778 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13779 13780 ins_encode %{ 13781 __ strw($src$$Register, Address(sp, $dst$$disp)); 13782 %} 13783 13784 ins_pipe(istore_reg_reg); 13785 13786 %} 13787 13788 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13789 13790 match(Set dst (MoveD2L src)); 13791 13792 effect(DEF dst, USE src); 13793 13794 ins_cost(INSN_COST); 13795 13796 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13797 13798 ins_encode %{ 13799 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13800 %} 13801 13802 ins_pipe(pipe_class_memory); 13803 13804 %} 13805 13806 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13807 13808 match(Set dst (MoveL2D src)); 13809 13810 effect(DEF dst, USE src); 13811 13812 ins_cost(INSN_COST); 13813 13814 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13815 13816 ins_encode %{ 13817 __ str($src$$Register, Address(sp, $dst$$disp)); 13818 %} 13819 13820 ins_pipe(istore_reg_reg); 13821 13822 %} 13823 13824 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13825 13826 match(Set dst (MoveF2I src)); 13827 13828 effect(DEF dst, USE src); 13829 13830 ins_cost(INSN_COST); 13831 13832 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13833 13834 ins_encode %{ 13835 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13836 %} 13837 13838 ins_pipe(fp_f2i); 13839 13840 %} 13841 13842 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13843 13844 match(Set dst (MoveI2F src)); 13845 13846 effect(DEF dst, USE src); 13847 13848 ins_cost(INSN_COST); 13849 13850 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13851 13852 ins_encode %{ 13853 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13854 %} 13855 13856 ins_pipe(fp_i2f); 13857 13858 %} 13859 13860 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13861 13862 match(Set dst (MoveD2L src)); 13863 13864 effect(DEF dst, USE src); 13865 13866 ins_cost(INSN_COST); 13867 13868 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13869 13870 ins_encode %{ 13871 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13872 %} 13873 13874 ins_pipe(fp_d2l); 13875 13876 %} 13877 13878 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13879 13880 match(Set dst (MoveL2D src)); 13881 13882 effect(DEF dst, USE src); 13883 13884 ins_cost(INSN_COST); 13885 13886 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13887 13888 ins_encode %{ 13889 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13890 %} 13891 13892 ins_pipe(fp_l2d); 13893 13894 %} 13895 13896 // ============================================================================ 13897 // clearing of an array 13898 13899 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13900 %{ 13901 match(Set dummy (ClearArray cnt base)); 13902 effect(USE_KILL cnt, USE_KILL base, KILL cr); 13903 13904 ins_cost(4 * INSN_COST); 13905 format %{ "ClearArray $cnt, $base" %} 13906 13907 ins_encode %{ 13908 __ zero_words($base$$Register, $cnt$$Register); 13909 %} 13910 13911 ins_pipe(pipe_class_memory); 13912 %} 13913 13914 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13915 %{ 13916 predicate((u_int64_t)n->in(2)->get_long() 13917 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13918 match(Set dummy (ClearArray cnt base)); 13919 effect(USE_KILL base); 13920 13921 ins_cost(4 * INSN_COST); 13922 format %{ "ClearArray $cnt, $base" %} 13923 13924 ins_encode %{ 13925 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13926 %} 13927 13928 ins_pipe(pipe_class_memory); 13929 %} 13930 13931 // ============================================================================ 13932 // Overflow Math Instructions 13933 13934 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13935 %{ 13936 match(Set cr (OverflowAddI op1 op2)); 13937 13938 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13939 ins_cost(INSN_COST); 13940 ins_encode %{ 13941 __ cmnw($op1$$Register, $op2$$Register); 13942 %} 13943 13944 ins_pipe(icmp_reg_reg); 13945 %} 13946 13947 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13948 %{ 13949 match(Set cr (OverflowAddI op1 op2)); 13950 13951 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13952 ins_cost(INSN_COST); 13953 ins_encode %{ 13954 __ cmnw($op1$$Register, $op2$$constant); 13955 %} 13956 13957 ins_pipe(icmp_reg_imm); 13958 %} 13959 13960 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13961 %{ 13962 match(Set cr (OverflowAddL op1 op2)); 13963 13964 format %{ "cmn $op1, $op2\t# overflow check long" %} 13965 ins_cost(INSN_COST); 13966 ins_encode %{ 13967 __ cmn($op1$$Register, $op2$$Register); 13968 %} 13969 13970 ins_pipe(icmp_reg_reg); 13971 %} 13972 13973 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13974 %{ 13975 match(Set cr (OverflowAddL op1 op2)); 13976 13977 format %{ "cmn $op1, $op2\t# overflow check long" %} 13978 ins_cost(INSN_COST); 13979 ins_encode %{ 13980 __ cmn($op1$$Register, $op2$$constant); 13981 %} 13982 13983 ins_pipe(icmp_reg_imm); 13984 %} 13985 13986 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13987 %{ 13988 match(Set cr (OverflowSubI op1 op2)); 13989 13990 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13991 ins_cost(INSN_COST); 13992 ins_encode %{ 13993 __ cmpw($op1$$Register, $op2$$Register); 13994 %} 13995 13996 ins_pipe(icmp_reg_reg); 13997 %} 13998 13999 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14000 %{ 14001 match(Set cr (OverflowSubI op1 op2)); 14002 14003 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14004 ins_cost(INSN_COST); 14005 ins_encode %{ 14006 __ cmpw($op1$$Register, $op2$$constant); 14007 %} 14008 14009 ins_pipe(icmp_reg_imm); 14010 %} 14011 14012 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14013 %{ 14014 match(Set cr (OverflowSubL op1 op2)); 14015 14016 format %{ "cmp $op1, $op2\t# overflow check long" %} 14017 ins_cost(INSN_COST); 14018 ins_encode %{ 14019 __ cmp($op1$$Register, $op2$$Register); 14020 %} 14021 14022 ins_pipe(icmp_reg_reg); 14023 %} 14024 14025 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14026 %{ 14027 match(Set cr (OverflowSubL op1 op2)); 14028 14029 format %{ "cmp $op1, $op2\t# overflow check long" %} 14030 ins_cost(INSN_COST); 14031 ins_encode %{ 14032 __ subs(zr, $op1$$Register, $op2$$constant); 14033 %} 14034 14035 ins_pipe(icmp_reg_imm); 14036 %} 14037 14038 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14039 %{ 14040 match(Set cr (OverflowSubI zero op1)); 14041 14042 format %{ "cmpw zr, $op1\t# overflow check int" %} 14043 ins_cost(INSN_COST); 14044 ins_encode %{ 14045 __ cmpw(zr, $op1$$Register); 14046 %} 14047 14048 ins_pipe(icmp_reg_imm); 14049 %} 14050 14051 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14052 %{ 14053 match(Set cr (OverflowSubL zero op1)); 14054 14055 format %{ "cmp zr, $op1\t# overflow check long" %} 14056 ins_cost(INSN_COST); 14057 ins_encode %{ 14058 __ cmp(zr, $op1$$Register); 14059 %} 14060 14061 ins_pipe(icmp_reg_imm); 14062 %} 14063 14064 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14065 %{ 14066 match(Set cr (OverflowMulI op1 op2)); 14067 14068 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14069 "cmp rscratch1, rscratch1, sxtw\n\t" 14070 "movw rscratch1, #0x80000000\n\t" 14071 "cselw rscratch1, rscratch1, zr, NE\n\t" 14072 "cmpw rscratch1, #1" %} 14073 ins_cost(5 * INSN_COST); 14074 ins_encode %{ 14075 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14076 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14077 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14078 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14079 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14080 %} 14081 14082 ins_pipe(pipe_slow); 14083 %} 14084 14085 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14086 %{ 14087 match(If cmp (OverflowMulI op1 op2)); 14088 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14089 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14090 effect(USE labl, KILL cr); 14091 14092 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14093 "cmp rscratch1, rscratch1, sxtw\n\t" 14094 "b$cmp $labl" %} 14095 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14096 ins_encode %{ 14097 Label* L = $labl$$label; 14098 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14099 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14100 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14101 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14102 %} 14103 14104 ins_pipe(pipe_serial); 14105 %} 14106 14107 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14108 %{ 14109 match(Set cr (OverflowMulL op1 op2)); 14110 14111 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14112 "smulh rscratch2, $op1, $op2\n\t" 14113 "cmp rscratch2, rscratch1, ASR #63\n\t" 14114 "movw rscratch1, #0x80000000\n\t" 14115 "cselw rscratch1, rscratch1, zr, NE\n\t" 14116 "cmpw rscratch1, #1" %} 14117 ins_cost(6 * INSN_COST); 14118 ins_encode %{ 14119 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14120 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14121 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14122 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14123 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14124 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14125 %} 14126 14127 ins_pipe(pipe_slow); 14128 %} 14129 14130 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14131 %{ 14132 match(If cmp (OverflowMulL op1 op2)); 14133 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14134 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14135 effect(USE labl, KILL cr); 14136 14137 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14138 "smulh rscratch2, $op1, $op2\n\t" 14139 "cmp rscratch2, rscratch1, ASR #63\n\t" 14140 "b$cmp $labl" %} 14141 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14142 ins_encode %{ 14143 Label* L = $labl$$label; 14144 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14145 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14146 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14147 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14148 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14149 %} 14150 14151 ins_pipe(pipe_serial); 14152 %} 14153 14154 // ============================================================================ 14155 // Compare Instructions 14156 14157 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14158 %{ 14159 match(Set cr (CmpI op1 op2)); 14160 14161 effect(DEF cr, USE op1, USE op2); 14162 14163 ins_cost(INSN_COST); 14164 format %{ "cmpw $op1, $op2" %} 14165 14166 ins_encode(aarch64_enc_cmpw(op1, op2)); 14167 14168 ins_pipe(icmp_reg_reg); 14169 %} 14170 14171 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14172 %{ 14173 match(Set cr (CmpI op1 zero)); 14174 14175 effect(DEF cr, USE op1); 14176 14177 ins_cost(INSN_COST); 14178 format %{ "cmpw $op1, 0" %} 14179 14180 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14181 14182 ins_pipe(icmp_reg_imm); 14183 %} 14184 14185 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14186 %{ 14187 match(Set cr (CmpI op1 op2)); 14188 14189 effect(DEF cr, USE op1); 14190 14191 ins_cost(INSN_COST); 14192 format %{ "cmpw $op1, $op2" %} 14193 14194 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14195 14196 ins_pipe(icmp_reg_imm); 14197 %} 14198 14199 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14200 %{ 14201 match(Set cr (CmpI op1 op2)); 14202 14203 effect(DEF cr, USE op1); 14204 14205 ins_cost(INSN_COST * 2); 14206 format %{ "cmpw $op1, $op2" %} 14207 14208 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14209 14210 ins_pipe(icmp_reg_imm); 14211 %} 14212 14213 // Unsigned compare Instructions; really, same as signed compare 14214 // except it should only be used to feed an If or a CMovI which takes a 14215 // cmpOpU. 14216 14217 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14218 %{ 14219 match(Set cr (CmpU op1 op2)); 14220 14221 effect(DEF cr, USE op1, USE op2); 14222 14223 ins_cost(INSN_COST); 14224 format %{ "cmpw $op1, $op2\t# unsigned" %} 14225 14226 ins_encode(aarch64_enc_cmpw(op1, op2)); 14227 14228 ins_pipe(icmp_reg_reg); 14229 %} 14230 14231 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14232 %{ 14233 match(Set cr (CmpU op1 zero)); 14234 14235 effect(DEF cr, USE op1); 14236 14237 ins_cost(INSN_COST); 14238 format %{ "cmpw $op1, #0\t# unsigned" %} 14239 14240 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14241 14242 ins_pipe(icmp_reg_imm); 14243 %} 14244 14245 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14246 %{ 14247 match(Set cr (CmpU op1 op2)); 14248 14249 effect(DEF cr, USE op1); 14250 14251 ins_cost(INSN_COST); 14252 format %{ "cmpw $op1, $op2\t# unsigned" %} 14253 14254 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14255 14256 ins_pipe(icmp_reg_imm); 14257 %} 14258 14259 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14260 %{ 14261 match(Set cr (CmpU op1 op2)); 14262 14263 effect(DEF cr, USE op1); 14264 14265 ins_cost(INSN_COST * 2); 14266 format %{ "cmpw $op1, $op2\t# unsigned" %} 14267 14268 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14269 14270 ins_pipe(icmp_reg_imm); 14271 %} 14272 14273 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14274 %{ 14275 match(Set cr (CmpL op1 op2)); 14276 14277 effect(DEF cr, USE op1, USE op2); 14278 14279 ins_cost(INSN_COST); 14280 format %{ "cmp $op1, $op2" %} 14281 14282 ins_encode(aarch64_enc_cmp(op1, op2)); 14283 14284 ins_pipe(icmp_reg_reg); 14285 %} 14286 14287 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14288 %{ 14289 match(Set cr (CmpL op1 zero)); 14290 14291 effect(DEF cr, USE op1); 14292 14293 ins_cost(INSN_COST); 14294 format %{ "tst $op1" %} 14295 14296 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14297 14298 ins_pipe(icmp_reg_imm); 14299 %} 14300 14301 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14302 %{ 14303 match(Set cr (CmpL op1 op2)); 14304 14305 effect(DEF cr, USE op1); 14306 14307 ins_cost(INSN_COST); 14308 format %{ "cmp $op1, $op2" %} 14309 14310 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14311 14312 ins_pipe(icmp_reg_imm); 14313 %} 14314 14315 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14316 %{ 14317 match(Set cr (CmpL op1 op2)); 14318 14319 effect(DEF cr, USE op1); 14320 14321 ins_cost(INSN_COST * 2); 14322 format %{ "cmp $op1, $op2" %} 14323 14324 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14325 14326 ins_pipe(icmp_reg_imm); 14327 %} 14328 14329 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14330 %{ 14331 match(Set cr (CmpUL op1 op2)); 14332 14333 effect(DEF cr, USE op1, USE op2); 14334 14335 ins_cost(INSN_COST); 14336 format %{ "cmp $op1, $op2" %} 14337 14338 ins_encode(aarch64_enc_cmp(op1, op2)); 14339 14340 ins_pipe(icmp_reg_reg); 14341 %} 14342 14343 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14344 %{ 14345 match(Set cr (CmpUL op1 zero)); 14346 14347 effect(DEF cr, USE op1); 14348 14349 ins_cost(INSN_COST); 14350 format %{ "tst $op1" %} 14351 14352 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14353 14354 ins_pipe(icmp_reg_imm); 14355 %} 14356 14357 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14358 %{ 14359 match(Set cr (CmpUL op1 op2)); 14360 14361 effect(DEF cr, USE op1); 14362 14363 ins_cost(INSN_COST); 14364 format %{ "cmp $op1, $op2" %} 14365 14366 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14367 14368 ins_pipe(icmp_reg_imm); 14369 %} 14370 14371 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14372 %{ 14373 match(Set cr (CmpUL op1 op2)); 14374 14375 effect(DEF cr, USE op1); 14376 14377 ins_cost(INSN_COST * 2); 14378 format %{ "cmp $op1, $op2" %} 14379 14380 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14381 14382 ins_pipe(icmp_reg_imm); 14383 %} 14384 14385 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14386 %{ 14387 match(Set cr (CmpP op1 op2)); 14388 14389 effect(DEF cr, USE op1, USE op2); 14390 14391 ins_cost(INSN_COST); 14392 format %{ "cmp $op1, $op2\t // ptr" %} 14393 14394 ins_encode(aarch64_enc_cmpp(op1, op2)); 14395 14396 ins_pipe(icmp_reg_reg); 14397 %} 14398 14399 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14400 %{ 14401 match(Set cr (CmpN op1 op2)); 14402 14403 effect(DEF cr, USE op1, USE op2); 14404 14405 ins_cost(INSN_COST); 14406 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14407 14408 ins_encode(aarch64_enc_cmpn(op1, op2)); 14409 14410 ins_pipe(icmp_reg_reg); 14411 %} 14412 14413 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14414 %{ 14415 match(Set cr (CmpP op1 zero)); 14416 14417 effect(DEF cr, USE op1, USE zero); 14418 14419 ins_cost(INSN_COST); 14420 format %{ "cmp $op1, 0\t // ptr" %} 14421 14422 ins_encode(aarch64_enc_testp(op1)); 14423 14424 ins_pipe(icmp_reg_imm); 14425 %} 14426 14427 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14428 %{ 14429 match(Set cr (CmpN op1 zero)); 14430 14431 effect(DEF cr, USE op1, USE zero); 14432 14433 ins_cost(INSN_COST); 14434 format %{ "cmp $op1, 0\t // compressed ptr" %} 14435 14436 ins_encode(aarch64_enc_testn(op1)); 14437 14438 ins_pipe(icmp_reg_imm); 14439 %} 14440 14441 // FP comparisons 14442 // 14443 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14444 // using normal cmpOp. See declaration of rFlagsReg for details. 14445 14446 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14447 %{ 14448 match(Set cr (CmpF src1 src2)); 14449 14450 ins_cost(3 * INSN_COST); 14451 format %{ "fcmps $src1, $src2" %} 14452 14453 ins_encode %{ 14454 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14455 %} 14456 14457 ins_pipe(pipe_class_compare); 14458 %} 14459 14460 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14461 %{ 14462 match(Set cr (CmpF src1 src2)); 14463 14464 ins_cost(3 * INSN_COST); 14465 format %{ "fcmps $src1, 0.0" %} 14466 14467 ins_encode %{ 14468 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14469 %} 14470 14471 ins_pipe(pipe_class_compare); 14472 %} 14473 // FROM HERE 14474 14475 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14476 %{ 14477 match(Set cr (CmpD src1 src2)); 14478 14479 ins_cost(3 * INSN_COST); 14480 format %{ "fcmpd $src1, $src2" %} 14481 14482 ins_encode %{ 14483 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14484 %} 14485 14486 ins_pipe(pipe_class_compare); 14487 %} 14488 14489 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14490 %{ 14491 match(Set cr (CmpD src1 src2)); 14492 14493 ins_cost(3 * INSN_COST); 14494 format %{ "fcmpd $src1, 0.0" %} 14495 14496 ins_encode %{ 14497 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14498 %} 14499 14500 ins_pipe(pipe_class_compare); 14501 %} 14502 14503 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14504 %{ 14505 match(Set dst (CmpF3 src1 src2)); 14506 effect(KILL cr); 14507 14508 ins_cost(5 * INSN_COST); 14509 format %{ "fcmps $src1, $src2\n\t" 14510 "csinvw($dst, zr, zr, eq\n\t" 14511 "csnegw($dst, $dst, $dst, lt)" 14512 %} 14513 14514 ins_encode %{ 14515 Label done; 14516 FloatRegister s1 = as_FloatRegister($src1$$reg); 14517 FloatRegister s2 = as_FloatRegister($src2$$reg); 14518 Register d = as_Register($dst$$reg); 14519 __ fcmps(s1, s2); 14520 // installs 0 if EQ else -1 14521 __ csinvw(d, zr, zr, Assembler::EQ); 14522 // keeps -1 if less or unordered else installs 1 14523 __ csnegw(d, d, d, Assembler::LT); 14524 __ bind(done); 14525 %} 14526 14527 ins_pipe(pipe_class_default); 14528 14529 %} 14530 14531 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14532 %{ 14533 match(Set dst (CmpD3 src1 src2)); 14534 effect(KILL cr); 14535 14536 ins_cost(5 * INSN_COST); 14537 format %{ "fcmpd $src1, $src2\n\t" 14538 "csinvw($dst, zr, zr, eq\n\t" 14539 "csnegw($dst, $dst, $dst, lt)" 14540 %} 14541 14542 ins_encode %{ 14543 Label done; 14544 FloatRegister s1 = as_FloatRegister($src1$$reg); 14545 FloatRegister s2 = as_FloatRegister($src2$$reg); 14546 Register d = as_Register($dst$$reg); 14547 __ fcmpd(s1, s2); 14548 // installs 0 if EQ else -1 14549 __ csinvw(d, zr, zr, Assembler::EQ); 14550 // keeps -1 if less or unordered else installs 1 14551 __ csnegw(d, d, d, Assembler::LT); 14552 __ bind(done); 14553 %} 14554 ins_pipe(pipe_class_default); 14555 14556 %} 14557 14558 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14559 %{ 14560 match(Set dst (CmpF3 src1 zero)); 14561 effect(KILL cr); 14562 14563 ins_cost(5 * INSN_COST); 14564 format %{ "fcmps $src1, 0.0\n\t" 14565 "csinvw($dst, zr, zr, eq\n\t" 14566 "csnegw($dst, $dst, $dst, lt)" 14567 %} 14568 14569 ins_encode %{ 14570 Label done; 14571 FloatRegister s1 = as_FloatRegister($src1$$reg); 14572 Register d = as_Register($dst$$reg); 14573 __ fcmps(s1, 0.0); 14574 // installs 0 if EQ else -1 14575 __ csinvw(d, zr, zr, Assembler::EQ); 14576 // keeps -1 if less or unordered else installs 1 14577 __ csnegw(d, d, d, Assembler::LT); 14578 __ bind(done); 14579 %} 14580 14581 ins_pipe(pipe_class_default); 14582 14583 %} 14584 14585 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14586 %{ 14587 match(Set dst (CmpD3 src1 zero)); 14588 effect(KILL cr); 14589 14590 ins_cost(5 * INSN_COST); 14591 format %{ "fcmpd $src1, 0.0\n\t" 14592 "csinvw($dst, zr, zr, eq\n\t" 14593 "csnegw($dst, $dst, $dst, lt)" 14594 %} 14595 14596 ins_encode %{ 14597 Label done; 14598 FloatRegister s1 = as_FloatRegister($src1$$reg); 14599 Register d = as_Register($dst$$reg); 14600 __ fcmpd(s1, 0.0); 14601 // installs 0 if EQ else -1 14602 __ csinvw(d, zr, zr, Assembler::EQ); 14603 // keeps -1 if less or unordered else installs 1 14604 __ csnegw(d, d, d, Assembler::LT); 14605 __ bind(done); 14606 %} 14607 ins_pipe(pipe_class_default); 14608 14609 %} 14610 14611 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14612 %{ 14613 match(Set dst (CmpLTMask p q)); 14614 effect(KILL cr); 14615 14616 ins_cost(3 * INSN_COST); 14617 14618 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14619 "csetw $dst, lt\n\t" 14620 "subw $dst, zr, $dst" 14621 %} 14622 14623 ins_encode %{ 14624 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14625 __ csetw(as_Register($dst$$reg), Assembler::LT); 14626 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14627 %} 14628 14629 ins_pipe(ialu_reg_reg); 14630 %} 14631 14632 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14633 %{ 14634 match(Set dst (CmpLTMask src zero)); 14635 effect(KILL cr); 14636 14637 ins_cost(INSN_COST); 14638 14639 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14640 14641 ins_encode %{ 14642 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14643 %} 14644 14645 ins_pipe(ialu_reg_shift); 14646 %} 14647 14648 // ============================================================================ 14649 // Max and Min 14650 14651 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14652 %{ 14653 effect( DEF dst, USE src1, USE src2, USE cr ); 14654 14655 ins_cost(INSN_COST * 2); 14656 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14657 14658 ins_encode %{ 14659 __ cselw(as_Register($dst$$reg), 14660 as_Register($src1$$reg), 14661 as_Register($src2$$reg), 14662 Assembler::LT); 14663 %} 14664 14665 ins_pipe(icond_reg_reg); 14666 %} 14667 14668 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14669 %{ 14670 match(Set dst (MinI src1 src2)); 14671 ins_cost(INSN_COST * 3); 14672 14673 expand %{ 14674 rFlagsReg cr; 14675 compI_reg_reg(cr, src1, src2); 14676 cmovI_reg_reg_lt(dst, src1, src2, cr); 14677 %} 14678 14679 %} 14680 // FROM HERE 14681 14682 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14683 %{ 14684 effect( DEF dst, USE src1, USE src2, USE cr ); 14685 14686 ins_cost(INSN_COST * 2); 14687 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14688 14689 ins_encode %{ 14690 __ cselw(as_Register($dst$$reg), 14691 as_Register($src1$$reg), 14692 as_Register($src2$$reg), 14693 Assembler::GT); 14694 %} 14695 14696 ins_pipe(icond_reg_reg); 14697 %} 14698 14699 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14700 %{ 14701 match(Set dst (MaxI src1 src2)); 14702 ins_cost(INSN_COST * 3); 14703 expand %{ 14704 rFlagsReg cr; 14705 compI_reg_reg(cr, src1, src2); 14706 cmovI_reg_reg_gt(dst, src1, src2, cr); 14707 %} 14708 %} 14709 14710 // ============================================================================ 14711 // Branch Instructions 14712 14713 // Direct Branch. 14714 instruct branch(label lbl) 14715 %{ 14716 match(Goto); 14717 14718 effect(USE lbl); 14719 14720 ins_cost(BRANCH_COST); 14721 format %{ "b $lbl" %} 14722 14723 ins_encode(aarch64_enc_b(lbl)); 14724 14725 ins_pipe(pipe_branch); 14726 %} 14727 14728 // Conditional Near Branch 14729 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14730 %{ 14731 // Same match rule as `branchConFar'. 14732 match(If cmp cr); 14733 14734 effect(USE lbl); 14735 14736 ins_cost(BRANCH_COST); 14737 // If set to 1 this indicates that the current instruction is a 14738 // short variant of a long branch. This avoids using this 14739 // instruction in first-pass matching. It will then only be used in 14740 // the `Shorten_branches' pass. 14741 // ins_short_branch(1); 14742 format %{ "b$cmp $lbl" %} 14743 14744 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14745 14746 ins_pipe(pipe_branch_cond); 14747 %} 14748 14749 // Conditional Near Branch Unsigned 14750 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14751 %{ 14752 // Same match rule as `branchConFar'. 14753 match(If cmp cr); 14754 14755 effect(USE lbl); 14756 14757 ins_cost(BRANCH_COST); 14758 // If set to 1 this indicates that the current instruction is a 14759 // short variant of a long branch. This avoids using this 14760 // instruction in first-pass matching. It will then only be used in 14761 // the `Shorten_branches' pass. 14762 // ins_short_branch(1); 14763 format %{ "b$cmp $lbl\t# unsigned" %} 14764 14765 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14766 14767 ins_pipe(pipe_branch_cond); 14768 %} 14769 14770 // Make use of CBZ and CBNZ. These instructions, as well as being 14771 // shorter than (cmp; branch), have the additional benefit of not 14772 // killing the flags. 14773 14774 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14775 match(If cmp (CmpI op1 op2)); 14776 effect(USE labl); 14777 14778 ins_cost(BRANCH_COST); 14779 format %{ "cbw$cmp $op1, $labl" %} 14780 ins_encode %{ 14781 Label* L = $labl$$label; 14782 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14783 if (cond == Assembler::EQ) 14784 __ cbzw($op1$$Register, *L); 14785 else 14786 __ cbnzw($op1$$Register, *L); 14787 %} 14788 ins_pipe(pipe_cmp_branch); 14789 %} 14790 14791 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14792 match(If cmp (CmpL op1 op2)); 14793 effect(USE labl); 14794 14795 ins_cost(BRANCH_COST); 14796 format %{ "cb$cmp $op1, $labl" %} 14797 ins_encode %{ 14798 Label* L = $labl$$label; 14799 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14800 if (cond == Assembler::EQ) 14801 __ cbz($op1$$Register, *L); 14802 else 14803 __ cbnz($op1$$Register, *L); 14804 %} 14805 ins_pipe(pipe_cmp_branch); 14806 %} 14807 14808 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14809 match(If cmp (CmpP op1 op2)); 14810 effect(USE labl); 14811 14812 ins_cost(BRANCH_COST); 14813 format %{ "cb$cmp $op1, $labl" %} 14814 ins_encode %{ 14815 Label* L = $labl$$label; 14816 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14817 if (cond == Assembler::EQ) 14818 __ cbz($op1$$Register, *L); 14819 else 14820 __ cbnz($op1$$Register, *L); 14821 %} 14822 ins_pipe(pipe_cmp_branch); 14823 %} 14824 14825 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14826 match(If cmp (CmpN op1 op2)); 14827 effect(USE labl); 14828 14829 ins_cost(BRANCH_COST); 14830 format %{ "cbw$cmp $op1, $labl" %} 14831 ins_encode %{ 14832 Label* L = $labl$$label; 14833 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14834 if (cond == Assembler::EQ) 14835 __ cbzw($op1$$Register, *L); 14836 else 14837 __ cbnzw($op1$$Register, *L); 14838 %} 14839 ins_pipe(pipe_cmp_branch); 14840 %} 14841 14842 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14843 match(If cmp (CmpP (DecodeN oop) zero)); 14844 effect(USE labl); 14845 14846 ins_cost(BRANCH_COST); 14847 format %{ "cb$cmp $oop, $labl" %} 14848 ins_encode %{ 14849 Label* L = $labl$$label; 14850 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14851 if (cond == Assembler::EQ) 14852 __ cbzw($oop$$Register, *L); 14853 else 14854 __ cbnzw($oop$$Register, *L); 14855 %} 14856 ins_pipe(pipe_cmp_branch); 14857 %} 14858 14859 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14860 match(If cmp (CmpU op1 op2)); 14861 effect(USE labl); 14862 14863 ins_cost(BRANCH_COST); 14864 format %{ "cbw$cmp $op1, $labl" %} 14865 ins_encode %{ 14866 Label* L = $labl$$label; 14867 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14868 if (cond == Assembler::EQ || cond == Assembler::LS) 14869 __ cbzw($op1$$Register, *L); 14870 else 14871 __ cbnzw($op1$$Register, *L); 14872 %} 14873 ins_pipe(pipe_cmp_branch); 14874 %} 14875 14876 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14877 match(If cmp (CmpUL op1 op2)); 14878 effect(USE labl); 14879 14880 ins_cost(BRANCH_COST); 14881 format %{ "cb$cmp $op1, $labl" %} 14882 ins_encode %{ 14883 Label* L = $labl$$label; 14884 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14885 if (cond == Assembler::EQ || cond == Assembler::LS) 14886 __ cbz($op1$$Register, *L); 14887 else 14888 __ cbnz($op1$$Register, *L); 14889 %} 14890 ins_pipe(pipe_cmp_branch); 14891 %} 14892 14893 // Test bit and Branch 14894 14895 // Patterns for short (< 32KiB) variants 14896 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14897 match(If cmp (CmpL op1 op2)); 14898 effect(USE labl); 14899 14900 ins_cost(BRANCH_COST); 14901 format %{ "cb$cmp $op1, $labl # long" %} 14902 ins_encode %{ 14903 Label* L = $labl$$label; 14904 Assembler::Condition cond = 14905 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14906 __ tbr(cond, $op1$$Register, 63, *L); 14907 %} 14908 ins_pipe(pipe_cmp_branch); 14909 ins_short_branch(1); 14910 %} 14911 14912 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14913 match(If cmp (CmpI op1 op2)); 14914 effect(USE labl); 14915 14916 ins_cost(BRANCH_COST); 14917 format %{ "cb$cmp $op1, $labl # int" %} 14918 ins_encode %{ 14919 Label* L = $labl$$label; 14920 Assembler::Condition cond = 14921 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14922 __ tbr(cond, $op1$$Register, 31, *L); 14923 %} 14924 ins_pipe(pipe_cmp_branch); 14925 ins_short_branch(1); 14926 %} 14927 14928 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14929 match(If cmp (CmpL (AndL op1 op2) op3)); 14930 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14931 effect(USE labl); 14932 14933 ins_cost(BRANCH_COST); 14934 format %{ "tb$cmp $op1, $op2, $labl" %} 14935 ins_encode %{ 14936 Label* L = $labl$$label; 14937 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14938 int bit = exact_log2_long($op2$$constant); 14939 __ tbr(cond, $op1$$Register, bit, *L); 14940 %} 14941 ins_pipe(pipe_cmp_branch); 14942 ins_short_branch(1); 14943 %} 14944 14945 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14946 match(If cmp (CmpI (AndI op1 op2) op3)); 14947 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 14948 effect(USE labl); 14949 14950 ins_cost(BRANCH_COST); 14951 format %{ "tb$cmp $op1, $op2, $labl" %} 14952 ins_encode %{ 14953 Label* L = $labl$$label; 14954 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14955 int bit = exact_log2((juint)$op2$$constant); 14956 __ tbr(cond, $op1$$Register, bit, *L); 14957 %} 14958 ins_pipe(pipe_cmp_branch); 14959 ins_short_branch(1); 14960 %} 14961 14962 // And far variants 14963 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14964 match(If cmp (CmpL op1 op2)); 14965 effect(USE labl); 14966 14967 ins_cost(BRANCH_COST); 14968 format %{ "cb$cmp $op1, $labl # long" %} 14969 ins_encode %{ 14970 Label* L = $labl$$label; 14971 Assembler::Condition cond = 14972 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14973 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14974 %} 14975 ins_pipe(pipe_cmp_branch); 14976 %} 14977 14978 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14979 match(If cmp (CmpI op1 op2)); 14980 effect(USE labl); 14981 14982 ins_cost(BRANCH_COST); 14983 format %{ "cb$cmp $op1, $labl # int" %} 14984 ins_encode %{ 14985 Label* L = $labl$$label; 14986 Assembler::Condition cond = 14987 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14988 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14989 %} 14990 ins_pipe(pipe_cmp_branch); 14991 %} 14992 14993 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14994 match(If cmp (CmpL (AndL op1 op2) op3)); 14995 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14996 effect(USE labl); 14997 14998 ins_cost(BRANCH_COST); 14999 format %{ "tb$cmp $op1, $op2, $labl" %} 15000 ins_encode %{ 15001 Label* L = $labl$$label; 15002 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15003 int bit = exact_log2_long($op2$$constant); 15004 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15005 %} 15006 ins_pipe(pipe_cmp_branch); 15007 %} 15008 15009 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15010 match(If cmp (CmpI (AndI op1 op2) op3)); 15011 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15012 effect(USE labl); 15013 15014 ins_cost(BRANCH_COST); 15015 format %{ "tb$cmp $op1, $op2, $labl" %} 15016 ins_encode %{ 15017 Label* L = $labl$$label; 15018 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15019 int bit = exact_log2((juint)$op2$$constant); 15020 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15021 %} 15022 ins_pipe(pipe_cmp_branch); 15023 %} 15024 15025 // Test bits 15026 15027 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15028 match(Set cr (CmpL (AndL op1 op2) op3)); 15029 predicate(Assembler::operand_valid_for_logical_immediate 15030 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15031 15032 ins_cost(INSN_COST); 15033 format %{ "tst $op1, $op2 # long" %} 15034 ins_encode %{ 15035 __ tst($op1$$Register, $op2$$constant); 15036 %} 15037 ins_pipe(ialu_reg_reg); 15038 %} 15039 15040 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15041 match(Set cr (CmpI (AndI op1 op2) op3)); 15042 predicate(Assembler::operand_valid_for_logical_immediate 15043 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15044 15045 ins_cost(INSN_COST); 15046 format %{ "tst $op1, $op2 # int" %} 15047 ins_encode %{ 15048 __ tstw($op1$$Register, $op2$$constant); 15049 %} 15050 ins_pipe(ialu_reg_reg); 15051 %} 15052 15053 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15054 match(Set cr (CmpL (AndL op1 op2) op3)); 15055 15056 ins_cost(INSN_COST); 15057 format %{ "tst $op1, $op2 # long" %} 15058 ins_encode %{ 15059 __ tst($op1$$Register, $op2$$Register); 15060 %} 15061 ins_pipe(ialu_reg_reg); 15062 %} 15063 15064 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15065 match(Set cr (CmpI (AndI op1 op2) op3)); 15066 15067 ins_cost(INSN_COST); 15068 format %{ "tstw $op1, $op2 # int" %} 15069 ins_encode %{ 15070 __ tstw($op1$$Register, $op2$$Register); 15071 %} 15072 ins_pipe(ialu_reg_reg); 15073 %} 15074 15075 15076 // Conditional Far Branch 15077 // Conditional Far Branch Unsigned 15078 // TODO: fixme 15079 15080 // counted loop end branch near 15081 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15082 %{ 15083 match(CountedLoopEnd cmp cr); 15084 15085 effect(USE lbl); 15086 15087 ins_cost(BRANCH_COST); 15088 // short variant. 15089 // ins_short_branch(1); 15090 format %{ "b$cmp $lbl \t// counted loop end" %} 15091 15092 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15093 15094 ins_pipe(pipe_branch); 15095 %} 15096 15097 // counted loop end branch near Unsigned 15098 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15099 %{ 15100 match(CountedLoopEnd cmp cr); 15101 15102 effect(USE lbl); 15103 15104 ins_cost(BRANCH_COST); 15105 // short variant. 15106 // ins_short_branch(1); 15107 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15108 15109 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15110 15111 ins_pipe(pipe_branch); 15112 %} 15113 15114 // counted loop end branch far 15115 // counted loop end branch far unsigned 15116 // TODO: fixme 15117 15118 // ============================================================================ 15119 // inlined locking and unlocking 15120 15121 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15122 %{ 15123 match(Set cr (FastLock object box)); 15124 effect(TEMP tmp, TEMP tmp2); 15125 15126 // TODO 15127 // identify correct cost 15128 ins_cost(5 * INSN_COST); 15129 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15130 15131 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15132 15133 ins_pipe(pipe_serial); 15134 %} 15135 15136 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15137 %{ 15138 match(Set cr (FastUnlock object box)); 15139 effect(TEMP tmp, TEMP tmp2); 15140 15141 ins_cost(5 * INSN_COST); 15142 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15143 15144 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15145 15146 ins_pipe(pipe_serial); 15147 %} 15148 15149 15150 // ============================================================================ 15151 // Safepoint Instructions 15152 15153 // TODO 15154 // provide a near and far version of this code 15155 15156 instruct safePoint(rFlagsReg cr, iRegP poll) 15157 %{ 15158 match(SafePoint poll); 15159 effect(KILL cr); 15160 15161 format %{ 15162 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15163 %} 15164 ins_encode %{ 15165 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15166 %} 15167 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15168 %} 15169 15170 15171 // ============================================================================ 15172 // Procedure Call/Return Instructions 15173 15174 // Call Java Static Instruction 15175 15176 instruct CallStaticJavaDirect(method meth) 15177 %{ 15178 match(CallStaticJava); 15179 15180 effect(USE meth); 15181 15182 ins_cost(CALL_COST); 15183 15184 format %{ "call,static $meth \t// ==> " %} 15185 15186 ins_encode( aarch64_enc_java_static_call(meth), 15187 aarch64_enc_call_epilog ); 15188 15189 ins_pipe(pipe_class_call); 15190 %} 15191 15192 // TO HERE 15193 15194 // Call Java Dynamic Instruction 15195 instruct CallDynamicJavaDirect(method meth) 15196 %{ 15197 match(CallDynamicJava); 15198 15199 effect(USE meth); 15200 15201 ins_cost(CALL_COST); 15202 15203 format %{ "CALL,dynamic $meth \t// ==> " %} 15204 15205 ins_encode( aarch64_enc_java_dynamic_call(meth), 15206 aarch64_enc_call_epilog ); 15207 15208 ins_pipe(pipe_class_call); 15209 %} 15210 15211 // Call Runtime Instruction 15212 15213 instruct CallRuntimeDirect(method meth) 15214 %{ 15215 match(CallRuntime); 15216 15217 effect(USE meth); 15218 15219 ins_cost(CALL_COST); 15220 15221 format %{ "CALL, runtime $meth" %} 15222 15223 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15224 15225 ins_pipe(pipe_class_call); 15226 %} 15227 15228 // Call Runtime Instruction 15229 15230 instruct CallLeafDirect(method meth) 15231 %{ 15232 match(CallLeaf); 15233 15234 effect(USE meth); 15235 15236 ins_cost(CALL_COST); 15237 15238 format %{ "CALL, runtime leaf $meth" %} 15239 15240 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15241 15242 ins_pipe(pipe_class_call); 15243 %} 15244 15245 // Call Runtime Instruction 15246 15247 instruct CallLeafNoFPDirect(method meth) 15248 %{ 15249 match(CallLeafNoFP); 15250 15251 effect(USE meth); 15252 15253 ins_cost(CALL_COST); 15254 15255 format %{ "CALL, runtime leaf nofp $meth" %} 15256 15257 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15258 15259 ins_pipe(pipe_class_call); 15260 %} 15261 15262 // Tail Call; Jump from runtime stub to Java code. 15263 // Also known as an 'interprocedural jump'. 15264 // Target of jump will eventually return to caller. 15265 // TailJump below removes the return address. 15266 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15267 %{ 15268 match(TailCall jump_target method_oop); 15269 15270 ins_cost(CALL_COST); 15271 15272 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15273 15274 ins_encode(aarch64_enc_tail_call(jump_target)); 15275 15276 ins_pipe(pipe_class_call); 15277 %} 15278 15279 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15280 %{ 15281 match(TailJump jump_target ex_oop); 15282 15283 ins_cost(CALL_COST); 15284 15285 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15286 15287 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15288 15289 ins_pipe(pipe_class_call); 15290 %} 15291 15292 // Create exception oop: created by stack-crawling runtime code. 15293 // Created exception is now available to this handler, and is setup 15294 // just prior to jumping to this handler. No code emitted. 15295 // TODO check 15296 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15297 instruct CreateException(iRegP_R0 ex_oop) 15298 %{ 15299 match(Set ex_oop (CreateEx)); 15300 15301 format %{ " -- \t// exception oop; no code emitted" %} 15302 15303 size(0); 15304 15305 ins_encode( /*empty*/ ); 15306 15307 ins_pipe(pipe_class_empty); 15308 %} 15309 15310 // Rethrow exception: The exception oop will come in the first 15311 // argument position. Then JUMP (not call) to the rethrow stub code. 15312 instruct RethrowException() %{ 15313 match(Rethrow); 15314 ins_cost(CALL_COST); 15315 15316 format %{ "b rethrow_stub" %} 15317 15318 ins_encode( aarch64_enc_rethrow() ); 15319 15320 ins_pipe(pipe_class_call); 15321 %} 15322 15323 15324 // Return Instruction 15325 // epilog node loads ret address into lr as part of frame pop 15326 instruct Ret() 15327 %{ 15328 match(Return); 15329 15330 format %{ "ret\t// return register" %} 15331 15332 ins_encode( aarch64_enc_ret() ); 15333 15334 ins_pipe(pipe_branch); 15335 %} 15336 15337 // Die now. 15338 instruct ShouldNotReachHere() %{ 15339 match(Halt); 15340 15341 ins_cost(CALL_COST); 15342 format %{ "ShouldNotReachHere" %} 15343 15344 ins_encode %{ 15345 if (is_reachable()) { 15346 __ stop(_halt_reason); 15347 } 15348 %} 15349 15350 ins_pipe(pipe_class_default); 15351 %} 15352 15353 // ============================================================================ 15354 // Partial Subtype Check 15355 // 15356 // superklass array for an instance of the superklass. Set a hidden 15357 // internal cache on a hit (cache is checked with exposed code in 15358 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15359 // encoding ALSO sets flags. 15360 15361 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15362 %{ 15363 match(Set result (PartialSubtypeCheck sub super)); 15364 effect(KILL cr, KILL temp); 15365 15366 ins_cost(1100); // slightly larger than the next version 15367 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15368 15369 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15370 15371 opcode(0x1); // Force zero of result reg on hit 15372 15373 ins_pipe(pipe_class_memory); 15374 %} 15375 15376 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15377 %{ 15378 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15379 effect(KILL temp, KILL result); 15380 15381 ins_cost(1100); // slightly larger than the next version 15382 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15383 15384 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15385 15386 opcode(0x0); // Don't zero result reg on hit 15387 15388 ins_pipe(pipe_class_memory); 15389 %} 15390 15391 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15392 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15393 %{ 15394 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15395 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15396 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15397 15398 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15399 ins_encode %{ 15400 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15401 __ string_compare($str1$$Register, $str2$$Register, 15402 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15403 $tmp1$$Register, $tmp2$$Register, 15404 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15405 %} 15406 ins_pipe(pipe_class_memory); 15407 %} 15408 15409 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15410 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15411 %{ 15412 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15413 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15414 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15415 15416 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15417 ins_encode %{ 15418 __ string_compare($str1$$Register, $str2$$Register, 15419 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15420 $tmp1$$Register, $tmp2$$Register, 15421 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15422 %} 15423 ins_pipe(pipe_class_memory); 15424 %} 15425 15426 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15427 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15428 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15429 %{ 15430 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15431 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15432 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15433 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15434 15435 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15436 ins_encode %{ 15437 __ string_compare($str1$$Register, $str2$$Register, 15438 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15439 $tmp1$$Register, $tmp2$$Register, 15440 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15441 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15442 %} 15443 ins_pipe(pipe_class_memory); 15444 %} 15445 15446 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15447 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15448 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15449 %{ 15450 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15451 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15452 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15453 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15454 15455 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15456 ins_encode %{ 15457 __ string_compare($str1$$Register, $str2$$Register, 15458 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15459 $tmp1$$Register, $tmp2$$Register, 15460 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15461 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15462 %} 15463 ins_pipe(pipe_class_memory); 15464 %} 15465 15466 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15467 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15468 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15469 %{ 15470 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15471 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15472 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15473 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15474 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15475 15476 ins_encode %{ 15477 __ string_indexof($str1$$Register, $str2$$Register, 15478 $cnt1$$Register, $cnt2$$Register, 15479 $tmp1$$Register, $tmp2$$Register, 15480 $tmp3$$Register, $tmp4$$Register, 15481 $tmp5$$Register, $tmp6$$Register, 15482 -1, $result$$Register, StrIntrinsicNode::UU); 15483 %} 15484 ins_pipe(pipe_class_memory); 15485 %} 15486 15487 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15488 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15489 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15490 %{ 15491 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15492 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15493 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15494 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15495 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15496 15497 ins_encode %{ 15498 __ string_indexof($str1$$Register, $str2$$Register, 15499 $cnt1$$Register, $cnt2$$Register, 15500 $tmp1$$Register, $tmp2$$Register, 15501 $tmp3$$Register, $tmp4$$Register, 15502 $tmp5$$Register, $tmp6$$Register, 15503 -1, $result$$Register, StrIntrinsicNode::LL); 15504 %} 15505 ins_pipe(pipe_class_memory); 15506 %} 15507 15508 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15509 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15510 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15511 %{ 15512 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15513 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15514 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15515 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15516 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15517 15518 ins_encode %{ 15519 __ string_indexof($str1$$Register, $str2$$Register, 15520 $cnt1$$Register, $cnt2$$Register, 15521 $tmp1$$Register, $tmp2$$Register, 15522 $tmp3$$Register, $tmp4$$Register, 15523 $tmp5$$Register, $tmp6$$Register, 15524 -1, $result$$Register, StrIntrinsicNode::UL); 15525 %} 15526 ins_pipe(pipe_class_memory); 15527 %} 15528 15529 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15530 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15531 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15532 %{ 15533 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15534 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15535 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15536 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15537 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15538 15539 ins_encode %{ 15540 int icnt2 = (int)$int_cnt2$$constant; 15541 __ string_indexof($str1$$Register, $str2$$Register, 15542 $cnt1$$Register, zr, 15543 $tmp1$$Register, $tmp2$$Register, 15544 $tmp3$$Register, $tmp4$$Register, zr, zr, 15545 icnt2, $result$$Register, StrIntrinsicNode::UU); 15546 %} 15547 ins_pipe(pipe_class_memory); 15548 %} 15549 15550 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15551 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15552 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15553 %{ 15554 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15555 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15556 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15557 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15558 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15559 15560 ins_encode %{ 15561 int icnt2 = (int)$int_cnt2$$constant; 15562 __ string_indexof($str1$$Register, $str2$$Register, 15563 $cnt1$$Register, zr, 15564 $tmp1$$Register, $tmp2$$Register, 15565 $tmp3$$Register, $tmp4$$Register, zr, zr, 15566 icnt2, $result$$Register, StrIntrinsicNode::LL); 15567 %} 15568 ins_pipe(pipe_class_memory); 15569 %} 15570 15571 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15572 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15573 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15574 %{ 15575 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15576 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15577 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15578 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15579 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15580 15581 ins_encode %{ 15582 int icnt2 = (int)$int_cnt2$$constant; 15583 __ string_indexof($str1$$Register, $str2$$Register, 15584 $cnt1$$Register, zr, 15585 $tmp1$$Register, $tmp2$$Register, 15586 $tmp3$$Register, $tmp4$$Register, zr, zr, 15587 icnt2, $result$$Register, StrIntrinsicNode::UL); 15588 %} 15589 ins_pipe(pipe_class_memory); 15590 %} 15591 15592 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15593 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15594 iRegINoSp tmp3, rFlagsReg cr) 15595 %{ 15596 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15597 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15598 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15599 15600 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15601 15602 ins_encode %{ 15603 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15604 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15605 $tmp3$$Register); 15606 %} 15607 ins_pipe(pipe_class_memory); 15608 %} 15609 15610 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15611 iRegI_R0 result, rFlagsReg cr) 15612 %{ 15613 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15614 match(Set result (StrEquals (Binary str1 str2) cnt)); 15615 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15616 15617 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15618 ins_encode %{ 15619 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15620 __ string_equals($str1$$Register, $str2$$Register, 15621 $result$$Register, $cnt$$Register, 1); 15622 %} 15623 ins_pipe(pipe_class_memory); 15624 %} 15625 15626 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15627 iRegI_R0 result, rFlagsReg cr) 15628 %{ 15629 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15630 match(Set result (StrEquals (Binary str1 str2) cnt)); 15631 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15632 15633 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15634 ins_encode %{ 15635 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15636 __ string_equals($str1$$Register, $str2$$Register, 15637 $result$$Register, $cnt$$Register, 2); 15638 %} 15639 ins_pipe(pipe_class_memory); 15640 %} 15641 15642 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15643 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15644 iRegP_R10 tmp, rFlagsReg cr) 15645 %{ 15646 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15647 match(Set result (AryEq ary1 ary2)); 15648 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15649 15650 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15651 ins_encode %{ 15652 __ arrays_equals($ary1$$Register, $ary2$$Register, 15653 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15654 $result$$Register, $tmp$$Register, 1); 15655 %} 15656 ins_pipe(pipe_class_memory); 15657 %} 15658 15659 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15660 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15661 iRegP_R10 tmp, rFlagsReg cr) 15662 %{ 15663 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15664 match(Set result (AryEq ary1 ary2)); 15665 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15666 15667 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15668 ins_encode %{ 15669 __ arrays_equals($ary1$$Register, $ary2$$Register, 15670 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15671 $result$$Register, $tmp$$Register, 2); 15672 %} 15673 ins_pipe(pipe_class_memory); 15674 %} 15675 15676 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15677 %{ 15678 match(Set result (HasNegatives ary1 len)); 15679 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15680 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15681 ins_encode %{ 15682 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15683 %} 15684 ins_pipe( pipe_slow ); 15685 %} 15686 15687 // fast char[] to byte[] compression 15688 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15689 vRegD_V0 tmp1, vRegD_V1 tmp2, 15690 vRegD_V2 tmp3, vRegD_V3 tmp4, 15691 iRegI_R0 result, rFlagsReg cr) 15692 %{ 15693 match(Set result (StrCompressedCopy src (Binary dst len))); 15694 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15695 15696 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15697 ins_encode %{ 15698 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15699 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15700 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15701 $result$$Register); 15702 %} 15703 ins_pipe( pipe_slow ); 15704 %} 15705 15706 // fast byte[] to char[] inflation 15707 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15708 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15709 %{ 15710 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15711 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15712 15713 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15714 ins_encode %{ 15715 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15716 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15717 %} 15718 ins_pipe(pipe_class_memory); 15719 %} 15720 15721 // encode char[] to byte[] in ISO_8859_1 15722 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15723 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15724 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15725 iRegI_R0 result, rFlagsReg cr) 15726 %{ 15727 match(Set result (EncodeISOArray src (Binary dst len))); 15728 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15729 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15730 15731 format %{ "Encode array $src,$dst,$len -> $result" %} 15732 ins_encode %{ 15733 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15734 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15735 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15736 %} 15737 ins_pipe( pipe_class_memory ); 15738 %} 15739 15740 // ============================================================================ 15741 // This name is KNOWN by the ADLC and cannot be changed. 15742 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15743 // for this guy. 15744 instruct tlsLoadP(thread_RegP dst) 15745 %{ 15746 match(Set dst (ThreadLocal)); 15747 15748 ins_cost(0); 15749 15750 format %{ " -- \t// $dst=Thread::current(), empty" %} 15751 15752 size(0); 15753 15754 ins_encode( /*empty*/ ); 15755 15756 ins_pipe(pipe_class_empty); 15757 %} 15758 15759 // ====================VECTOR INSTRUCTIONS===================================== 15760 15761 // Load vector (32 bits) 15762 instruct loadV4(vecD dst, vmem4 mem) 15763 %{ 15764 predicate(n->as_LoadVector()->memory_size() == 4); 15765 match(Set dst (LoadVector mem)); 15766 ins_cost(4 * INSN_COST); 15767 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15768 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15769 ins_pipe(vload_reg_mem64); 15770 %} 15771 15772 // Load vector (64 bits) 15773 instruct loadV8(vecD dst, vmem8 mem) 15774 %{ 15775 predicate(n->as_LoadVector()->memory_size() == 8); 15776 match(Set dst (LoadVector mem)); 15777 ins_cost(4 * INSN_COST); 15778 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15779 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15780 ins_pipe(vload_reg_mem64); 15781 %} 15782 15783 // Load Vector (128 bits) 15784 instruct loadV16(vecX dst, vmem16 mem) 15785 %{ 15786 predicate(n->as_LoadVector()->memory_size() == 16); 15787 match(Set dst (LoadVector mem)); 15788 ins_cost(4 * INSN_COST); 15789 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15790 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15791 ins_pipe(vload_reg_mem128); 15792 %} 15793 15794 // Store Vector (32 bits) 15795 instruct storeV4(vecD src, vmem4 mem) 15796 %{ 15797 predicate(n->as_StoreVector()->memory_size() == 4); 15798 match(Set mem (StoreVector mem src)); 15799 ins_cost(4 * INSN_COST); 15800 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15801 ins_encode( aarch64_enc_strvS(src, mem) ); 15802 ins_pipe(vstore_reg_mem64); 15803 %} 15804 15805 // Store Vector (64 bits) 15806 instruct storeV8(vecD src, vmem8 mem) 15807 %{ 15808 predicate(n->as_StoreVector()->memory_size() == 8); 15809 match(Set mem (StoreVector mem src)); 15810 ins_cost(4 * INSN_COST); 15811 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15812 ins_encode( aarch64_enc_strvD(src, mem) ); 15813 ins_pipe(vstore_reg_mem64); 15814 %} 15815 15816 // Store Vector (128 bits) 15817 instruct storeV16(vecX src, vmem16 mem) 15818 %{ 15819 predicate(n->as_StoreVector()->memory_size() == 16); 15820 match(Set mem (StoreVector mem src)); 15821 ins_cost(4 * INSN_COST); 15822 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15823 ins_encode( aarch64_enc_strvQ(src, mem) ); 15824 ins_pipe(vstore_reg_mem128); 15825 %} 15826 15827 instruct replicate8B(vecD dst, iRegIorL2I src) 15828 %{ 15829 predicate(n->as_Vector()->length() == 4 || 15830 n->as_Vector()->length() == 8); 15831 match(Set dst (ReplicateB src)); 15832 ins_cost(INSN_COST); 15833 format %{ "dup $dst, $src\t# vector (8B)" %} 15834 ins_encode %{ 15835 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15836 %} 15837 ins_pipe(vdup_reg_reg64); 15838 %} 15839 15840 instruct replicate16B(vecX dst, iRegIorL2I src) 15841 %{ 15842 predicate(n->as_Vector()->length() == 16); 15843 match(Set dst (ReplicateB src)); 15844 ins_cost(INSN_COST); 15845 format %{ "dup $dst, $src\t# vector (16B)" %} 15846 ins_encode %{ 15847 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15848 %} 15849 ins_pipe(vdup_reg_reg128); 15850 %} 15851 15852 instruct replicate8B_imm(vecD dst, immI con) 15853 %{ 15854 predicate(n->as_Vector()->length() == 4 || 15855 n->as_Vector()->length() == 8); 15856 match(Set dst (ReplicateB con)); 15857 ins_cost(INSN_COST); 15858 format %{ "movi $dst, $con\t# vector(8B)" %} 15859 ins_encode %{ 15860 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15861 %} 15862 ins_pipe(vmovi_reg_imm64); 15863 %} 15864 15865 instruct replicate16B_imm(vecX dst, immI con) 15866 %{ 15867 predicate(n->as_Vector()->length() == 16); 15868 match(Set dst (ReplicateB con)); 15869 ins_cost(INSN_COST); 15870 format %{ "movi $dst, $con\t# vector(16B)" %} 15871 ins_encode %{ 15872 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15873 %} 15874 ins_pipe(vmovi_reg_imm128); 15875 %} 15876 15877 instruct replicate4S(vecD dst, iRegIorL2I src) 15878 %{ 15879 predicate(n->as_Vector()->length() == 2 || 15880 n->as_Vector()->length() == 4); 15881 match(Set dst (ReplicateS src)); 15882 ins_cost(INSN_COST); 15883 format %{ "dup $dst, $src\t# vector (4S)" %} 15884 ins_encode %{ 15885 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15886 %} 15887 ins_pipe(vdup_reg_reg64); 15888 %} 15889 15890 instruct replicate8S(vecX dst, iRegIorL2I src) 15891 %{ 15892 predicate(n->as_Vector()->length() == 8); 15893 match(Set dst (ReplicateS src)); 15894 ins_cost(INSN_COST); 15895 format %{ "dup $dst, $src\t# vector (8S)" %} 15896 ins_encode %{ 15897 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15898 %} 15899 ins_pipe(vdup_reg_reg128); 15900 %} 15901 15902 instruct replicate4S_imm(vecD dst, immI con) 15903 %{ 15904 predicate(n->as_Vector()->length() == 2 || 15905 n->as_Vector()->length() == 4); 15906 match(Set dst (ReplicateS con)); 15907 ins_cost(INSN_COST); 15908 format %{ "movi $dst, $con\t# vector(4H)" %} 15909 ins_encode %{ 15910 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15911 %} 15912 ins_pipe(vmovi_reg_imm64); 15913 %} 15914 15915 instruct replicate8S_imm(vecX dst, immI con) 15916 %{ 15917 predicate(n->as_Vector()->length() == 8); 15918 match(Set dst (ReplicateS con)); 15919 ins_cost(INSN_COST); 15920 format %{ "movi $dst, $con\t# vector(8H)" %} 15921 ins_encode %{ 15922 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15923 %} 15924 ins_pipe(vmovi_reg_imm128); 15925 %} 15926 15927 instruct replicate2I(vecD dst, iRegIorL2I src) 15928 %{ 15929 predicate(n->as_Vector()->length() == 2); 15930 match(Set dst (ReplicateI src)); 15931 ins_cost(INSN_COST); 15932 format %{ "dup $dst, $src\t# vector (2I)" %} 15933 ins_encode %{ 15934 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15935 %} 15936 ins_pipe(vdup_reg_reg64); 15937 %} 15938 15939 instruct replicate4I(vecX dst, iRegIorL2I src) 15940 %{ 15941 predicate(n->as_Vector()->length() == 4); 15942 match(Set dst (ReplicateI src)); 15943 ins_cost(INSN_COST); 15944 format %{ "dup $dst, $src\t# vector (4I)" %} 15945 ins_encode %{ 15946 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15947 %} 15948 ins_pipe(vdup_reg_reg128); 15949 %} 15950 15951 instruct replicate2I_imm(vecD dst, immI con) 15952 %{ 15953 predicate(n->as_Vector()->length() == 2); 15954 match(Set dst (ReplicateI con)); 15955 ins_cost(INSN_COST); 15956 format %{ "movi $dst, $con\t# vector(2I)" %} 15957 ins_encode %{ 15958 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15959 %} 15960 ins_pipe(vmovi_reg_imm64); 15961 %} 15962 15963 instruct replicate4I_imm(vecX dst, immI con) 15964 %{ 15965 predicate(n->as_Vector()->length() == 4); 15966 match(Set dst (ReplicateI con)); 15967 ins_cost(INSN_COST); 15968 format %{ "movi $dst, $con\t# vector(4I)" %} 15969 ins_encode %{ 15970 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15971 %} 15972 ins_pipe(vmovi_reg_imm128); 15973 %} 15974 15975 instruct replicate2L(vecX dst, iRegL src) 15976 %{ 15977 predicate(n->as_Vector()->length() == 2); 15978 match(Set dst (ReplicateL src)); 15979 ins_cost(INSN_COST); 15980 format %{ "dup $dst, $src\t# vector (2L)" %} 15981 ins_encode %{ 15982 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15983 %} 15984 ins_pipe(vdup_reg_reg128); 15985 %} 15986 15987 instruct replicate2L_zero(vecX dst, immI0 zero) 15988 %{ 15989 predicate(n->as_Vector()->length() == 2); 15990 match(Set dst (ReplicateI zero)); 15991 ins_cost(INSN_COST); 15992 format %{ "movi $dst, $zero\t# vector(4I)" %} 15993 ins_encode %{ 15994 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15995 as_FloatRegister($dst$$reg), 15996 as_FloatRegister($dst$$reg)); 15997 %} 15998 ins_pipe(vmovi_reg_imm128); 15999 %} 16000 16001 instruct replicate2F(vecD dst, vRegF src) 16002 %{ 16003 predicate(n->as_Vector()->length() == 2); 16004 match(Set dst (ReplicateF src)); 16005 ins_cost(INSN_COST); 16006 format %{ "dup $dst, $src\t# vector (2F)" %} 16007 ins_encode %{ 16008 __ dup(as_FloatRegister($dst$$reg), __ T2S, 16009 as_FloatRegister($src$$reg)); 16010 %} 16011 ins_pipe(vdup_reg_freg64); 16012 %} 16013 16014 instruct replicate4F(vecX dst, vRegF src) 16015 %{ 16016 predicate(n->as_Vector()->length() == 4); 16017 match(Set dst (ReplicateF src)); 16018 ins_cost(INSN_COST); 16019 format %{ "dup $dst, $src\t# vector (4F)" %} 16020 ins_encode %{ 16021 __ dup(as_FloatRegister($dst$$reg), __ T4S, 16022 as_FloatRegister($src$$reg)); 16023 %} 16024 ins_pipe(vdup_reg_freg128); 16025 %} 16026 16027 instruct replicate2D(vecX dst, vRegD src) 16028 %{ 16029 predicate(n->as_Vector()->length() == 2); 16030 match(Set dst (ReplicateD src)); 16031 ins_cost(INSN_COST); 16032 format %{ "dup $dst, $src\t# vector (2D)" %} 16033 ins_encode %{ 16034 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16035 as_FloatRegister($src$$reg)); 16036 %} 16037 ins_pipe(vdup_reg_dreg128); 16038 %} 16039 16040 // ====================REDUCTION ARITHMETIC==================================== 16041 16042 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp, iRegINoSp tmp2) 16043 %{ 16044 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); 16045 match(Set dst (AddReductionVI isrc vsrc)); 16046 ins_cost(INSN_COST); 16047 effect(TEMP tmp, TEMP tmp2); 16048 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16049 "umov $tmp2, $vsrc, S, 1\n\t" 16050 "addw $tmp, $isrc, $tmp\n\t" 16051 "addw $dst, $tmp, $tmp2\t# add reduction2I" 16052 %} 16053 ins_encode %{ 16054 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16055 __ umov($tmp2$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16056 __ addw($tmp$$Register, $isrc$$Register, $tmp$$Register); 16057 __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); 16058 %} 16059 ins_pipe(pipe_class_default); 16060 %} 16061 16062 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16063 %{ 16064 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); 16065 match(Set dst (AddReductionVI isrc vsrc)); 16066 ins_cost(INSN_COST); 16067 effect(TEMP vtmp, TEMP itmp); 16068 format %{ "addv $vtmp, T4S, $vsrc\n\t" 16069 "umov $itmp, $vtmp, S, 0\n\t" 16070 "addw $dst, $itmp, $isrc\t# add reduction4I" 16071 %} 16072 ins_encode %{ 16073 __ addv(as_FloatRegister($vtmp$$reg), __ T4S, 16074 as_FloatRegister($vsrc$$reg)); 16075 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16076 __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); 16077 %} 16078 ins_pipe(pipe_class_default); 16079 %} 16080 16081 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) 16082 %{ 16083 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); 16084 match(Set dst (MulReductionVI isrc vsrc)); 16085 ins_cost(INSN_COST); 16086 effect(TEMP tmp, TEMP dst); 16087 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16088 "mul $dst, $tmp, $isrc\n\t" 16089 "umov $tmp, $vsrc, S, 1\n\t" 16090 "mul $dst, $tmp, $dst\t# mul reduction2I" 16091 %} 16092 ins_encode %{ 16093 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16094 __ mul($dst$$Register, $tmp$$Register, $isrc$$Register); 16095 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16096 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16097 %} 16098 ins_pipe(pipe_class_default); 16099 %} 16100 16101 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16102 %{ 16103 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); 16104 match(Set dst (MulReductionVI isrc vsrc)); 16105 ins_cost(INSN_COST); 16106 effect(TEMP vtmp, TEMP itmp, TEMP dst); 16107 format %{ "ins $vtmp, D, $vsrc, 0, 1\n\t" 16108 "mulv $vtmp, T2S, $vtmp, $vsrc\n\t" 16109 "umov $itmp, $vtmp, S, 0\n\t" 16110 "mul $dst, $itmp, $isrc\n\t" 16111 "umov $itmp, $vtmp, S, 1\n\t" 16112 "mul $dst, $itmp, $dst\t# mul reduction4I" 16113 %} 16114 ins_encode %{ 16115 __ ins(as_FloatRegister($vtmp$$reg), __ D, 16116 as_FloatRegister($vsrc$$reg), 0, 1); 16117 __ mulv(as_FloatRegister($vtmp$$reg), __ T2S, 16118 as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); 16119 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16120 __ mul($dst$$Register, $itmp$$Register, $isrc$$Register); 16121 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 1); 16122 __ mul($dst$$Register, $itmp$$Register, $dst$$Register); 16123 %} 16124 ins_pipe(pipe_class_default); 16125 %} 16126 16127 instruct reduce_add2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16128 %{ 16129 match(Set dst (AddReductionVF fsrc vsrc)); 16130 ins_cost(INSN_COST); 16131 effect(TEMP tmp, TEMP dst); 16132 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16133 "ins $tmp, S, $vsrc, 0, 1\n\t" 16134 "fadds $dst, $dst, $tmp\t# add reduction2F" 16135 %} 16136 ins_encode %{ 16137 __ fadds(as_FloatRegister($dst$$reg), 16138 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16139 __ ins(as_FloatRegister($tmp$$reg), __ S, 16140 as_FloatRegister($vsrc$$reg), 0, 1); 16141 __ fadds(as_FloatRegister($dst$$reg), 16142 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16143 %} 16144 ins_pipe(pipe_class_default); 16145 %} 16146 16147 instruct reduce_add4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16148 %{ 16149 match(Set dst (AddReductionVF fsrc vsrc)); 16150 ins_cost(INSN_COST); 16151 effect(TEMP tmp, TEMP dst); 16152 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16153 "ins $tmp, S, $vsrc, 0, 1\n\t" 16154 "fadds $dst, $dst, $tmp\n\t" 16155 "ins $tmp, S, $vsrc, 0, 2\n\t" 16156 "fadds $dst, $dst, $tmp\n\t" 16157 "ins $tmp, S, $vsrc, 0, 3\n\t" 16158 "fadds $dst, $dst, $tmp\t# add reduction4F" 16159 %} 16160 ins_encode %{ 16161 __ fadds(as_FloatRegister($dst$$reg), 16162 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16163 __ ins(as_FloatRegister($tmp$$reg), __ S, 16164 as_FloatRegister($vsrc$$reg), 0, 1); 16165 __ fadds(as_FloatRegister($dst$$reg), 16166 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16167 __ ins(as_FloatRegister($tmp$$reg), __ S, 16168 as_FloatRegister($vsrc$$reg), 0, 2); 16169 __ fadds(as_FloatRegister($dst$$reg), 16170 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16171 __ ins(as_FloatRegister($tmp$$reg), __ S, 16172 as_FloatRegister($vsrc$$reg), 0, 3); 16173 __ fadds(as_FloatRegister($dst$$reg), 16174 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16175 %} 16176 ins_pipe(pipe_class_default); 16177 %} 16178 16179 instruct reduce_mul2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16180 %{ 16181 match(Set dst (MulReductionVF fsrc vsrc)); 16182 ins_cost(INSN_COST); 16183 effect(TEMP tmp, TEMP dst); 16184 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16185 "ins $tmp, S, $vsrc, 0, 1\n\t" 16186 "fmuls $dst, $dst, $tmp\t# mul reduction2F" 16187 %} 16188 ins_encode %{ 16189 __ fmuls(as_FloatRegister($dst$$reg), 16190 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16191 __ ins(as_FloatRegister($tmp$$reg), __ S, 16192 as_FloatRegister($vsrc$$reg), 0, 1); 16193 __ fmuls(as_FloatRegister($dst$$reg), 16194 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16195 %} 16196 ins_pipe(pipe_class_default); 16197 %} 16198 16199 instruct reduce_mul4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16200 %{ 16201 match(Set dst (MulReductionVF fsrc vsrc)); 16202 ins_cost(INSN_COST); 16203 effect(TEMP tmp, TEMP dst); 16204 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16205 "ins $tmp, S, $vsrc, 0, 1\n\t" 16206 "fmuls $dst, $dst, $tmp\n\t" 16207 "ins $tmp, S, $vsrc, 0, 2\n\t" 16208 "fmuls $dst, $dst, $tmp\n\t" 16209 "ins $tmp, S, $vsrc, 0, 3\n\t" 16210 "fmuls $dst, $dst, $tmp\t# mul reduction4F" 16211 %} 16212 ins_encode %{ 16213 __ fmuls(as_FloatRegister($dst$$reg), 16214 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16215 __ ins(as_FloatRegister($tmp$$reg), __ S, 16216 as_FloatRegister($vsrc$$reg), 0, 1); 16217 __ fmuls(as_FloatRegister($dst$$reg), 16218 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16219 __ ins(as_FloatRegister($tmp$$reg), __ S, 16220 as_FloatRegister($vsrc$$reg), 0, 2); 16221 __ fmuls(as_FloatRegister($dst$$reg), 16222 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16223 __ ins(as_FloatRegister($tmp$$reg), __ S, 16224 as_FloatRegister($vsrc$$reg), 0, 3); 16225 __ fmuls(as_FloatRegister($dst$$reg), 16226 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16227 %} 16228 ins_pipe(pipe_class_default); 16229 %} 16230 16231 instruct reduce_add2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16232 %{ 16233 match(Set dst (AddReductionVD dsrc vsrc)); 16234 ins_cost(INSN_COST); 16235 effect(TEMP tmp, TEMP dst); 16236 format %{ "faddd $dst, $dsrc, $vsrc\n\t" 16237 "ins $tmp, D, $vsrc, 0, 1\n\t" 16238 "faddd $dst, $dst, $tmp\t# add reduction2D" 16239 %} 16240 ins_encode %{ 16241 __ faddd(as_FloatRegister($dst$$reg), 16242 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16243 __ ins(as_FloatRegister($tmp$$reg), __ D, 16244 as_FloatRegister($vsrc$$reg), 0, 1); 16245 __ faddd(as_FloatRegister($dst$$reg), 16246 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16247 %} 16248 ins_pipe(pipe_class_default); 16249 %} 16250 16251 instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16252 %{ 16253 match(Set dst (MulReductionVD dsrc vsrc)); 16254 ins_cost(INSN_COST); 16255 effect(TEMP tmp, TEMP dst); 16256 format %{ "fmuld $dst, $dsrc, $vsrc\n\t" 16257 "ins $tmp, D, $vsrc, 0, 1\n\t" 16258 "fmuld $dst, $dst, $tmp\t# mul reduction2D" 16259 %} 16260 ins_encode %{ 16261 __ fmuld(as_FloatRegister($dst$$reg), 16262 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16263 __ ins(as_FloatRegister($tmp$$reg), __ D, 16264 as_FloatRegister($vsrc$$reg), 0, 1); 16265 __ fmuld(as_FloatRegister($dst$$reg), 16266 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16267 %} 16268 ins_pipe(pipe_class_default); 16269 %} 16270 16271 instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16272 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16273 match(Set dst (MaxReductionV fsrc vsrc)); 16274 ins_cost(INSN_COST); 16275 effect(TEMP_DEF dst, TEMP tmp); 16276 format %{ "fmaxs $dst, $fsrc, $vsrc\n\t" 16277 "ins $tmp, S, $vsrc, 0, 1\n\t" 16278 "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} 16279 ins_encode %{ 16280 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16281 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16282 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16283 %} 16284 ins_pipe(pipe_class_default); 16285 %} 16286 16287 instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16288 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16289 match(Set dst (MaxReductionV fsrc vsrc)); 16290 ins_cost(INSN_COST); 16291 effect(TEMP_DEF dst); 16292 format %{ "fmaxv $dst, T4S, $vsrc\n\t" 16293 "fmaxs $dst, $dst, $fsrc\t# max reduction4F" %} 16294 ins_encode %{ 16295 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16296 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16297 %} 16298 ins_pipe(pipe_class_default); 16299 %} 16300 16301 instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16302 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16303 match(Set dst (MaxReductionV dsrc vsrc)); 16304 ins_cost(INSN_COST); 16305 effect(TEMP_DEF dst, TEMP tmp); 16306 format %{ "fmaxd $dst, $dsrc, $vsrc\n\t" 16307 "ins $tmp, D, $vsrc, 0, 1\n\t" 16308 "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} 16309 ins_encode %{ 16310 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16311 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16312 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16313 %} 16314 ins_pipe(pipe_class_default); 16315 %} 16316 16317 instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16318 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16319 match(Set dst (MinReductionV fsrc vsrc)); 16320 ins_cost(INSN_COST); 16321 effect(TEMP_DEF dst, TEMP tmp); 16322 format %{ "fmins $dst, $fsrc, $vsrc\n\t" 16323 "ins $tmp, S, $vsrc, 0, 1\n\t" 16324 "fmins $dst, $dst, $tmp\t# min reduction2F" %} 16325 ins_encode %{ 16326 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16327 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16328 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16329 %} 16330 ins_pipe(pipe_class_default); 16331 %} 16332 16333 instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16334 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16335 match(Set dst (MinReductionV fsrc vsrc)); 16336 ins_cost(INSN_COST); 16337 effect(TEMP_DEF dst); 16338 format %{ "fminv $dst, T4S, $vsrc\n\t" 16339 "fmins $dst, $dst, $fsrc\t# min reduction4F" %} 16340 ins_encode %{ 16341 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16342 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16343 %} 16344 ins_pipe(pipe_class_default); 16345 %} 16346 16347 instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16348 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16349 match(Set dst (MinReductionV dsrc vsrc)); 16350 ins_cost(INSN_COST); 16351 effect(TEMP_DEF dst, TEMP tmp); 16352 format %{ "fmind $dst, $dsrc, $vsrc\n\t" 16353 "ins $tmp, D, $vsrc, 0, 1\n\t" 16354 "fmind $dst, $dst, $tmp\t# min reduction2D" %} 16355 ins_encode %{ 16356 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16357 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16358 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16359 %} 16360 ins_pipe(pipe_class_default); 16361 %} 16362 16363 // ====================VECTOR ARITHMETIC======================================= 16364 16365 // --------------------------------- ADD -------------------------------------- 16366 16367 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16368 %{ 16369 predicate(n->as_Vector()->length() == 4 || 16370 n->as_Vector()->length() == 8); 16371 match(Set dst (AddVB src1 src2)); 16372 ins_cost(INSN_COST); 16373 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16374 ins_encode %{ 16375 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16376 as_FloatRegister($src1$$reg), 16377 as_FloatRegister($src2$$reg)); 16378 %} 16379 ins_pipe(vdop64); 16380 %} 16381 16382 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16383 %{ 16384 predicate(n->as_Vector()->length() == 16); 16385 match(Set dst (AddVB src1 src2)); 16386 ins_cost(INSN_COST); 16387 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16388 ins_encode %{ 16389 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16390 as_FloatRegister($src1$$reg), 16391 as_FloatRegister($src2$$reg)); 16392 %} 16393 ins_pipe(vdop128); 16394 %} 16395 16396 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16397 %{ 16398 predicate(n->as_Vector()->length() == 2 || 16399 n->as_Vector()->length() == 4); 16400 match(Set dst (AddVS src1 src2)); 16401 ins_cost(INSN_COST); 16402 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16403 ins_encode %{ 16404 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16405 as_FloatRegister($src1$$reg), 16406 as_FloatRegister($src2$$reg)); 16407 %} 16408 ins_pipe(vdop64); 16409 %} 16410 16411 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16412 %{ 16413 predicate(n->as_Vector()->length() == 8); 16414 match(Set dst (AddVS src1 src2)); 16415 ins_cost(INSN_COST); 16416 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16417 ins_encode %{ 16418 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16419 as_FloatRegister($src1$$reg), 16420 as_FloatRegister($src2$$reg)); 16421 %} 16422 ins_pipe(vdop128); 16423 %} 16424 16425 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16426 %{ 16427 predicate(n->as_Vector()->length() == 2); 16428 match(Set dst (AddVI src1 src2)); 16429 ins_cost(INSN_COST); 16430 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16431 ins_encode %{ 16432 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16433 as_FloatRegister($src1$$reg), 16434 as_FloatRegister($src2$$reg)); 16435 %} 16436 ins_pipe(vdop64); 16437 %} 16438 16439 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16440 %{ 16441 predicate(n->as_Vector()->length() == 4); 16442 match(Set dst (AddVI src1 src2)); 16443 ins_cost(INSN_COST); 16444 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16445 ins_encode %{ 16446 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16447 as_FloatRegister($src1$$reg), 16448 as_FloatRegister($src2$$reg)); 16449 %} 16450 ins_pipe(vdop128); 16451 %} 16452 16453 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16454 %{ 16455 predicate(n->as_Vector()->length() == 2); 16456 match(Set dst (AddVL src1 src2)); 16457 ins_cost(INSN_COST); 16458 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16459 ins_encode %{ 16460 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16461 as_FloatRegister($src1$$reg), 16462 as_FloatRegister($src2$$reg)); 16463 %} 16464 ins_pipe(vdop128); 16465 %} 16466 16467 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16468 %{ 16469 predicate(n->as_Vector()->length() == 2); 16470 match(Set dst (AddVF src1 src2)); 16471 ins_cost(INSN_COST); 16472 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16473 ins_encode %{ 16474 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16475 as_FloatRegister($src1$$reg), 16476 as_FloatRegister($src2$$reg)); 16477 %} 16478 ins_pipe(vdop_fp64); 16479 %} 16480 16481 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16482 %{ 16483 predicate(n->as_Vector()->length() == 4); 16484 match(Set dst (AddVF src1 src2)); 16485 ins_cost(INSN_COST); 16486 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16487 ins_encode %{ 16488 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16489 as_FloatRegister($src1$$reg), 16490 as_FloatRegister($src2$$reg)); 16491 %} 16492 ins_pipe(vdop_fp128); 16493 %} 16494 16495 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16496 %{ 16497 match(Set dst (AddVD src1 src2)); 16498 ins_cost(INSN_COST); 16499 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16500 ins_encode %{ 16501 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16502 as_FloatRegister($src1$$reg), 16503 as_FloatRegister($src2$$reg)); 16504 %} 16505 ins_pipe(vdop_fp128); 16506 %} 16507 16508 // --------------------------------- SUB -------------------------------------- 16509 16510 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16511 %{ 16512 predicate(n->as_Vector()->length() == 4 || 16513 n->as_Vector()->length() == 8); 16514 match(Set dst (SubVB src1 src2)); 16515 ins_cost(INSN_COST); 16516 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16517 ins_encode %{ 16518 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16519 as_FloatRegister($src1$$reg), 16520 as_FloatRegister($src2$$reg)); 16521 %} 16522 ins_pipe(vdop64); 16523 %} 16524 16525 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16526 %{ 16527 predicate(n->as_Vector()->length() == 16); 16528 match(Set dst (SubVB src1 src2)); 16529 ins_cost(INSN_COST); 16530 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16531 ins_encode %{ 16532 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16533 as_FloatRegister($src1$$reg), 16534 as_FloatRegister($src2$$reg)); 16535 %} 16536 ins_pipe(vdop128); 16537 %} 16538 16539 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16540 %{ 16541 predicate(n->as_Vector()->length() == 2 || 16542 n->as_Vector()->length() == 4); 16543 match(Set dst (SubVS src1 src2)); 16544 ins_cost(INSN_COST); 16545 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16546 ins_encode %{ 16547 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16548 as_FloatRegister($src1$$reg), 16549 as_FloatRegister($src2$$reg)); 16550 %} 16551 ins_pipe(vdop64); 16552 %} 16553 16554 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16555 %{ 16556 predicate(n->as_Vector()->length() == 8); 16557 match(Set dst (SubVS src1 src2)); 16558 ins_cost(INSN_COST); 16559 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16560 ins_encode %{ 16561 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16562 as_FloatRegister($src1$$reg), 16563 as_FloatRegister($src2$$reg)); 16564 %} 16565 ins_pipe(vdop128); 16566 %} 16567 16568 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16569 %{ 16570 predicate(n->as_Vector()->length() == 2); 16571 match(Set dst (SubVI src1 src2)); 16572 ins_cost(INSN_COST); 16573 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16574 ins_encode %{ 16575 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16576 as_FloatRegister($src1$$reg), 16577 as_FloatRegister($src2$$reg)); 16578 %} 16579 ins_pipe(vdop64); 16580 %} 16581 16582 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16583 %{ 16584 predicate(n->as_Vector()->length() == 4); 16585 match(Set dst (SubVI src1 src2)); 16586 ins_cost(INSN_COST); 16587 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16588 ins_encode %{ 16589 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16590 as_FloatRegister($src1$$reg), 16591 as_FloatRegister($src2$$reg)); 16592 %} 16593 ins_pipe(vdop128); 16594 %} 16595 16596 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16597 %{ 16598 predicate(n->as_Vector()->length() == 2); 16599 match(Set dst (SubVL src1 src2)); 16600 ins_cost(INSN_COST); 16601 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16602 ins_encode %{ 16603 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16604 as_FloatRegister($src1$$reg), 16605 as_FloatRegister($src2$$reg)); 16606 %} 16607 ins_pipe(vdop128); 16608 %} 16609 16610 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16611 %{ 16612 predicate(n->as_Vector()->length() == 2); 16613 match(Set dst (SubVF src1 src2)); 16614 ins_cost(INSN_COST); 16615 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16616 ins_encode %{ 16617 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16618 as_FloatRegister($src1$$reg), 16619 as_FloatRegister($src2$$reg)); 16620 %} 16621 ins_pipe(vdop_fp64); 16622 %} 16623 16624 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16625 %{ 16626 predicate(n->as_Vector()->length() == 4); 16627 match(Set dst (SubVF src1 src2)); 16628 ins_cost(INSN_COST); 16629 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16630 ins_encode %{ 16631 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16632 as_FloatRegister($src1$$reg), 16633 as_FloatRegister($src2$$reg)); 16634 %} 16635 ins_pipe(vdop_fp128); 16636 %} 16637 16638 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16639 %{ 16640 predicate(n->as_Vector()->length() == 2); 16641 match(Set dst (SubVD src1 src2)); 16642 ins_cost(INSN_COST); 16643 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16644 ins_encode %{ 16645 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16646 as_FloatRegister($src1$$reg), 16647 as_FloatRegister($src2$$reg)); 16648 %} 16649 ins_pipe(vdop_fp128); 16650 %} 16651 16652 // --------------------------------- MUL -------------------------------------- 16653 16654 instruct vmul8B(vecD dst, vecD src1, vecD src2) 16655 %{ 16656 predicate(n->as_Vector()->length() == 4 || 16657 n->as_Vector()->length() == 8); 16658 match(Set dst (MulVB src1 src2)); 16659 ins_cost(INSN_COST); 16660 format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %} 16661 ins_encode %{ 16662 __ mulv(as_FloatRegister($dst$$reg), __ T8B, 16663 as_FloatRegister($src1$$reg), 16664 as_FloatRegister($src2$$reg)); 16665 %} 16666 ins_pipe(vmul64); 16667 %} 16668 16669 instruct vmul16B(vecX dst, vecX src1, vecX src2) 16670 %{ 16671 predicate(n->as_Vector()->length() == 16); 16672 match(Set dst (MulVB src1 src2)); 16673 ins_cost(INSN_COST); 16674 format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %} 16675 ins_encode %{ 16676 __ mulv(as_FloatRegister($dst$$reg), __ T16B, 16677 as_FloatRegister($src1$$reg), 16678 as_FloatRegister($src2$$reg)); 16679 %} 16680 ins_pipe(vmul128); 16681 %} 16682 16683 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16684 %{ 16685 predicate(n->as_Vector()->length() == 2 || 16686 n->as_Vector()->length() == 4); 16687 match(Set dst (MulVS src1 src2)); 16688 ins_cost(INSN_COST); 16689 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16690 ins_encode %{ 16691 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16692 as_FloatRegister($src1$$reg), 16693 as_FloatRegister($src2$$reg)); 16694 %} 16695 ins_pipe(vmul64); 16696 %} 16697 16698 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16699 %{ 16700 predicate(n->as_Vector()->length() == 8); 16701 match(Set dst (MulVS src1 src2)); 16702 ins_cost(INSN_COST); 16703 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16704 ins_encode %{ 16705 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16706 as_FloatRegister($src1$$reg), 16707 as_FloatRegister($src2$$reg)); 16708 %} 16709 ins_pipe(vmul128); 16710 %} 16711 16712 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16713 %{ 16714 predicate(n->as_Vector()->length() == 2); 16715 match(Set dst (MulVI src1 src2)); 16716 ins_cost(INSN_COST); 16717 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16718 ins_encode %{ 16719 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16720 as_FloatRegister($src1$$reg), 16721 as_FloatRegister($src2$$reg)); 16722 %} 16723 ins_pipe(vmul64); 16724 %} 16725 16726 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16727 %{ 16728 predicate(n->as_Vector()->length() == 4); 16729 match(Set dst (MulVI src1 src2)); 16730 ins_cost(INSN_COST); 16731 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16732 ins_encode %{ 16733 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16734 as_FloatRegister($src1$$reg), 16735 as_FloatRegister($src2$$reg)); 16736 %} 16737 ins_pipe(vmul128); 16738 %} 16739 16740 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16741 %{ 16742 predicate(n->as_Vector()->length() == 2); 16743 match(Set dst (MulVF src1 src2)); 16744 ins_cost(INSN_COST); 16745 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16746 ins_encode %{ 16747 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16748 as_FloatRegister($src1$$reg), 16749 as_FloatRegister($src2$$reg)); 16750 %} 16751 ins_pipe(vmuldiv_fp64); 16752 %} 16753 16754 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16755 %{ 16756 predicate(n->as_Vector()->length() == 4); 16757 match(Set dst (MulVF src1 src2)); 16758 ins_cost(INSN_COST); 16759 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16760 ins_encode %{ 16761 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16762 as_FloatRegister($src1$$reg), 16763 as_FloatRegister($src2$$reg)); 16764 %} 16765 ins_pipe(vmuldiv_fp128); 16766 %} 16767 16768 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16769 %{ 16770 predicate(n->as_Vector()->length() == 2); 16771 match(Set dst (MulVD src1 src2)); 16772 ins_cost(INSN_COST); 16773 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16774 ins_encode %{ 16775 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16776 as_FloatRegister($src1$$reg), 16777 as_FloatRegister($src2$$reg)); 16778 %} 16779 ins_pipe(vmuldiv_fp128); 16780 %} 16781 16782 // --------------------------------- MLA -------------------------------------- 16783 16784 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16785 %{ 16786 predicate(n->as_Vector()->length() == 2 || 16787 n->as_Vector()->length() == 4); 16788 match(Set dst (AddVS dst (MulVS src1 src2))); 16789 ins_cost(INSN_COST); 16790 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16791 ins_encode %{ 16792 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16793 as_FloatRegister($src1$$reg), 16794 as_FloatRegister($src2$$reg)); 16795 %} 16796 ins_pipe(vmla64); 16797 %} 16798 16799 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16800 %{ 16801 predicate(n->as_Vector()->length() == 8); 16802 match(Set dst (AddVS dst (MulVS src1 src2))); 16803 ins_cost(INSN_COST); 16804 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16805 ins_encode %{ 16806 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16807 as_FloatRegister($src1$$reg), 16808 as_FloatRegister($src2$$reg)); 16809 %} 16810 ins_pipe(vmla128); 16811 %} 16812 16813 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16814 %{ 16815 predicate(n->as_Vector()->length() == 2); 16816 match(Set dst (AddVI dst (MulVI src1 src2))); 16817 ins_cost(INSN_COST); 16818 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16819 ins_encode %{ 16820 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16821 as_FloatRegister($src1$$reg), 16822 as_FloatRegister($src2$$reg)); 16823 %} 16824 ins_pipe(vmla64); 16825 %} 16826 16827 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16828 %{ 16829 predicate(n->as_Vector()->length() == 4); 16830 match(Set dst (AddVI dst (MulVI src1 src2))); 16831 ins_cost(INSN_COST); 16832 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16833 ins_encode %{ 16834 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16835 as_FloatRegister($src1$$reg), 16836 as_FloatRegister($src2$$reg)); 16837 %} 16838 ins_pipe(vmla128); 16839 %} 16840 16841 // dst + src1 * src2 16842 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16843 predicate(UseFMA && n->as_Vector()->length() == 2); 16844 match(Set dst (FmaVF dst (Binary src1 src2))); 16845 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16846 ins_cost(INSN_COST); 16847 ins_encode %{ 16848 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16849 as_FloatRegister($src1$$reg), 16850 as_FloatRegister($src2$$reg)); 16851 %} 16852 ins_pipe(vmuldiv_fp64); 16853 %} 16854 16855 // dst + src1 * src2 16856 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16857 predicate(UseFMA && n->as_Vector()->length() == 4); 16858 match(Set dst (FmaVF dst (Binary src1 src2))); 16859 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16860 ins_cost(INSN_COST); 16861 ins_encode %{ 16862 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16863 as_FloatRegister($src1$$reg), 16864 as_FloatRegister($src2$$reg)); 16865 %} 16866 ins_pipe(vmuldiv_fp128); 16867 %} 16868 16869 // dst + src1 * src2 16870 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16871 predicate(UseFMA && n->as_Vector()->length() == 2); 16872 match(Set dst (FmaVD dst (Binary src1 src2))); 16873 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16874 ins_cost(INSN_COST); 16875 ins_encode %{ 16876 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16877 as_FloatRegister($src1$$reg), 16878 as_FloatRegister($src2$$reg)); 16879 %} 16880 ins_pipe(vmuldiv_fp128); 16881 %} 16882 16883 // --------------------------------- MLS -------------------------------------- 16884 16885 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16886 %{ 16887 predicate(n->as_Vector()->length() == 2 || 16888 n->as_Vector()->length() == 4); 16889 match(Set dst (SubVS dst (MulVS src1 src2))); 16890 ins_cost(INSN_COST); 16891 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16892 ins_encode %{ 16893 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16894 as_FloatRegister($src1$$reg), 16895 as_FloatRegister($src2$$reg)); 16896 %} 16897 ins_pipe(vmla64); 16898 %} 16899 16900 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16901 %{ 16902 predicate(n->as_Vector()->length() == 8); 16903 match(Set dst (SubVS dst (MulVS src1 src2))); 16904 ins_cost(INSN_COST); 16905 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16906 ins_encode %{ 16907 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16908 as_FloatRegister($src1$$reg), 16909 as_FloatRegister($src2$$reg)); 16910 %} 16911 ins_pipe(vmla128); 16912 %} 16913 16914 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16915 %{ 16916 predicate(n->as_Vector()->length() == 2); 16917 match(Set dst (SubVI dst (MulVI src1 src2))); 16918 ins_cost(INSN_COST); 16919 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16920 ins_encode %{ 16921 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16922 as_FloatRegister($src1$$reg), 16923 as_FloatRegister($src2$$reg)); 16924 %} 16925 ins_pipe(vmla64); 16926 %} 16927 16928 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16929 %{ 16930 predicate(n->as_Vector()->length() == 4); 16931 match(Set dst (SubVI dst (MulVI src1 src2))); 16932 ins_cost(INSN_COST); 16933 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16934 ins_encode %{ 16935 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16936 as_FloatRegister($src1$$reg), 16937 as_FloatRegister($src2$$reg)); 16938 %} 16939 ins_pipe(vmla128); 16940 %} 16941 16942 // dst - src1 * src2 16943 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16944 predicate(UseFMA && n->as_Vector()->length() == 2); 16945 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16946 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16947 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16948 ins_cost(INSN_COST); 16949 ins_encode %{ 16950 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16951 as_FloatRegister($src1$$reg), 16952 as_FloatRegister($src2$$reg)); 16953 %} 16954 ins_pipe(vmuldiv_fp64); 16955 %} 16956 16957 // dst - src1 * src2 16958 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16959 predicate(UseFMA && n->as_Vector()->length() == 4); 16960 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16961 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16962 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16963 ins_cost(INSN_COST); 16964 ins_encode %{ 16965 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16966 as_FloatRegister($src1$$reg), 16967 as_FloatRegister($src2$$reg)); 16968 %} 16969 ins_pipe(vmuldiv_fp128); 16970 %} 16971 16972 // dst - src1 * src2 16973 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16974 predicate(UseFMA && n->as_Vector()->length() == 2); 16975 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16976 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16977 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16978 ins_cost(INSN_COST); 16979 ins_encode %{ 16980 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16981 as_FloatRegister($src1$$reg), 16982 as_FloatRegister($src2$$reg)); 16983 %} 16984 ins_pipe(vmuldiv_fp128); 16985 %} 16986 16987 // --------------- Vector Multiply-Add Shorts into Integer -------------------- 16988 16989 instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 16990 predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 16991 match(Set dst (MulAddVS2VI src1 src2)); 16992 ins_cost(INSN_COST); 16993 effect(TEMP_DEF dst, TEMP tmp); 16994 format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" 16995 "smullv $dst, $src1, $src2\t# vector (8H)\n\t" 16996 "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} 16997 ins_encode %{ 16998 __ smullv(as_FloatRegister($tmp$$reg), __ T4H, 16999 as_FloatRegister($src1$$reg), 17000 as_FloatRegister($src2$$reg)); 17001 __ smullv(as_FloatRegister($dst$$reg), __ T8H, 17002 as_FloatRegister($src1$$reg), 17003 as_FloatRegister($src2$$reg)); 17004 __ addpv(as_FloatRegister($dst$$reg), __ T4S, 17005 as_FloatRegister($tmp$$reg), 17006 as_FloatRegister($dst$$reg)); 17007 %} 17008 ins_pipe(vmuldiv_fp128); 17009 %} 17010 17011 // --------------------------------- DIV -------------------------------------- 17012 17013 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 17014 %{ 17015 predicate(n->as_Vector()->length() == 2); 17016 match(Set dst (DivVF src1 src2)); 17017 ins_cost(INSN_COST); 17018 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 17019 ins_encode %{ 17020 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 17021 as_FloatRegister($src1$$reg), 17022 as_FloatRegister($src2$$reg)); 17023 %} 17024 ins_pipe(vmuldiv_fp64); 17025 %} 17026 17027 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 17028 %{ 17029 predicate(n->as_Vector()->length() == 4); 17030 match(Set dst (DivVF src1 src2)); 17031 ins_cost(INSN_COST); 17032 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 17033 ins_encode %{ 17034 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 17035 as_FloatRegister($src1$$reg), 17036 as_FloatRegister($src2$$reg)); 17037 %} 17038 ins_pipe(vmuldiv_fp128); 17039 %} 17040 17041 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17042 %{ 17043 predicate(n->as_Vector()->length() == 2); 17044 match(Set dst (DivVD src1 src2)); 17045 ins_cost(INSN_COST); 17046 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17047 ins_encode %{ 17048 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17049 as_FloatRegister($src1$$reg), 17050 as_FloatRegister($src2$$reg)); 17051 %} 17052 ins_pipe(vmuldiv_fp128); 17053 %} 17054 17055 // --------------------------------- SQRT ------------------------------------- 17056 17057 instruct vsqrt2F(vecD dst, vecD src) 17058 %{ 17059 predicate(n->as_Vector()->length() == 2); 17060 match(Set dst (SqrtVF src)); 17061 format %{ "fsqrt $dst, $src\t# vector (2F)" %} 17062 ins_encode %{ 17063 __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17064 %} 17065 ins_pipe(vunop_fp64); 17066 %} 17067 17068 instruct vsqrt4F(vecX dst, vecX src) 17069 %{ 17070 predicate(n->as_Vector()->length() == 4); 17071 match(Set dst (SqrtVF src)); 17072 format %{ "fsqrt $dst, $src\t# vector (4F)" %} 17073 ins_encode %{ 17074 __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17075 %} 17076 ins_pipe(vsqrt_fp128); 17077 %} 17078 17079 instruct vsqrt2D(vecX dst, vecX src) 17080 %{ 17081 predicate(n->as_Vector()->length() == 2); 17082 match(Set dst (SqrtVD src)); 17083 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17084 ins_encode %{ 17085 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17086 as_FloatRegister($src$$reg)); 17087 %} 17088 ins_pipe(vsqrt_fp128); 17089 %} 17090 17091 // --------------------------------- ABS -------------------------------------- 17092 17093 instruct vabs8B(vecD dst, vecD src) 17094 %{ 17095 predicate(n->as_Vector()->length() == 4 || 17096 n->as_Vector()->length() == 8); 17097 match(Set dst (AbsVB src)); 17098 ins_cost(INSN_COST); 17099 format %{ "abs $dst, $src\t# vector (8B)" %} 17100 ins_encode %{ 17101 __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); 17102 %} 17103 ins_pipe(vlogical64); 17104 %} 17105 17106 instruct vabs16B(vecX dst, vecX src) 17107 %{ 17108 predicate(n->as_Vector()->length() == 16); 17109 match(Set dst (AbsVB src)); 17110 ins_cost(INSN_COST); 17111 format %{ "abs $dst, $src\t# vector (16B)" %} 17112 ins_encode %{ 17113 __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); 17114 %} 17115 ins_pipe(vlogical128); 17116 %} 17117 17118 instruct vabs4S(vecD dst, vecD src) 17119 %{ 17120 predicate(n->as_Vector()->length() == 4); 17121 match(Set dst (AbsVS src)); 17122 ins_cost(INSN_COST); 17123 format %{ "abs $dst, $src\t# vector (4H)" %} 17124 ins_encode %{ 17125 __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg)); 17126 %} 17127 ins_pipe(vlogical64); 17128 %} 17129 17130 instruct vabs8S(vecX dst, vecX src) 17131 %{ 17132 predicate(n->as_Vector()->length() == 8); 17133 match(Set dst (AbsVS src)); 17134 ins_cost(INSN_COST); 17135 format %{ "abs $dst, $src\t# vector (8H)" %} 17136 ins_encode %{ 17137 __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg)); 17138 %} 17139 ins_pipe(vlogical128); 17140 %} 17141 17142 instruct vabs2I(vecD dst, vecD src) 17143 %{ 17144 predicate(n->as_Vector()->length() == 2); 17145 match(Set dst (AbsVI src)); 17146 ins_cost(INSN_COST); 17147 format %{ "abs $dst, $src\t# vector (2S)" %} 17148 ins_encode %{ 17149 __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17150 %} 17151 ins_pipe(vlogical64); 17152 %} 17153 17154 instruct vabs4I(vecX dst, vecX src) 17155 %{ 17156 predicate(n->as_Vector()->length() == 4); 17157 match(Set dst (AbsVI src)); 17158 ins_cost(INSN_COST); 17159 format %{ "abs $dst, $src\t# vector (4S)" %} 17160 ins_encode %{ 17161 __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17162 %} 17163 ins_pipe(vlogical128); 17164 %} 17165 17166 instruct vabs2L(vecX dst, vecX src) 17167 %{ 17168 predicate(n->as_Vector()->length() == 2); 17169 match(Set dst (AbsVL src)); 17170 ins_cost(INSN_COST); 17171 format %{ "abs $dst, $src\t# vector (2D)" %} 17172 ins_encode %{ 17173 __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); 17174 %} 17175 ins_pipe(vlogical128); 17176 %} 17177 17178 instruct vabs2F(vecD dst, vecD src) 17179 %{ 17180 predicate(n->as_Vector()->length() == 2); 17181 match(Set dst (AbsVF src)); 17182 ins_cost(INSN_COST * 3); 17183 format %{ "fabs $dst,$src\t# vector (2S)" %} 17184 ins_encode %{ 17185 __ fabs(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17186 %} 17187 ins_pipe(vunop_fp64); 17188 %} 17189 17190 instruct vabs4F(vecX dst, vecX src) 17191 %{ 17192 predicate(n->as_Vector()->length() == 4); 17193 match(Set dst (AbsVF src)); 17194 ins_cost(INSN_COST * 3); 17195 format %{ "fabs $dst,$src\t# vector (4S)" %} 17196 ins_encode %{ 17197 __ fabs(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17198 %} 17199 ins_pipe(vunop_fp128); 17200 %} 17201 17202 instruct vabs2D(vecX dst, vecX src) 17203 %{ 17204 predicate(n->as_Vector()->length() == 2); 17205 match(Set dst (AbsVD src)); 17206 ins_cost(INSN_COST * 3); 17207 format %{ "fabs $dst,$src\t# vector (2D)" %} 17208 ins_encode %{ 17209 __ fabs(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); 17210 %} 17211 ins_pipe(vunop_fp128); 17212 %} 17213 17214 // --------------------------------- NEG -------------------------------------- 17215 17216 instruct vneg2F(vecD dst, vecD src) 17217 %{ 17218 predicate(n->as_Vector()->length() == 2); 17219 match(Set dst (NegVF src)); 17220 ins_cost(INSN_COST * 3); 17221 format %{ "fneg $dst,$src\t# vector (2S)" %} 17222 ins_encode %{ 17223 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17224 as_FloatRegister($src$$reg)); 17225 %} 17226 ins_pipe(vunop_fp64); 17227 %} 17228 17229 instruct vneg4F(vecX dst, vecX src) 17230 %{ 17231 predicate(n->as_Vector()->length() == 4); 17232 match(Set dst (NegVF src)); 17233 ins_cost(INSN_COST * 3); 17234 format %{ "fneg $dst,$src\t# vector (4S)" %} 17235 ins_encode %{ 17236 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17237 as_FloatRegister($src$$reg)); 17238 %} 17239 ins_pipe(vunop_fp128); 17240 %} 17241 17242 instruct vneg2D(vecX dst, vecX src) 17243 %{ 17244 predicate(n->as_Vector()->length() == 2); 17245 match(Set dst (NegVD src)); 17246 ins_cost(INSN_COST * 3); 17247 format %{ "fneg $dst,$src\t# vector (2D)" %} 17248 ins_encode %{ 17249 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17250 as_FloatRegister($src$$reg)); 17251 %} 17252 ins_pipe(vunop_fp128); 17253 %} 17254 17255 // --------------------------------- AND -------------------------------------- 17256 17257 instruct vand8B(vecD dst, vecD src1, vecD src2) 17258 %{ 17259 predicate(n->as_Vector()->length_in_bytes() == 4 || 17260 n->as_Vector()->length_in_bytes() == 8); 17261 match(Set dst (AndV src1 src2)); 17262 ins_cost(INSN_COST); 17263 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17264 ins_encode %{ 17265 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17266 as_FloatRegister($src1$$reg), 17267 as_FloatRegister($src2$$reg)); 17268 %} 17269 ins_pipe(vlogical64); 17270 %} 17271 17272 instruct vand16B(vecX dst, vecX src1, vecX src2) 17273 %{ 17274 predicate(n->as_Vector()->length_in_bytes() == 16); 17275 match(Set dst (AndV src1 src2)); 17276 ins_cost(INSN_COST); 17277 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17278 ins_encode %{ 17279 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17280 as_FloatRegister($src1$$reg), 17281 as_FloatRegister($src2$$reg)); 17282 %} 17283 ins_pipe(vlogical128); 17284 %} 17285 17286 // --------------------------------- OR --------------------------------------- 17287 17288 instruct vor8B(vecD dst, vecD src1, vecD src2) 17289 %{ 17290 predicate(n->as_Vector()->length_in_bytes() == 4 || 17291 n->as_Vector()->length_in_bytes() == 8); 17292 match(Set dst (OrV src1 src2)); 17293 ins_cost(INSN_COST); 17294 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17295 ins_encode %{ 17296 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17297 as_FloatRegister($src1$$reg), 17298 as_FloatRegister($src2$$reg)); 17299 %} 17300 ins_pipe(vlogical64); 17301 %} 17302 17303 instruct vor16B(vecX dst, vecX src1, vecX src2) 17304 %{ 17305 predicate(n->as_Vector()->length_in_bytes() == 16); 17306 match(Set dst (OrV src1 src2)); 17307 ins_cost(INSN_COST); 17308 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17309 ins_encode %{ 17310 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17311 as_FloatRegister($src1$$reg), 17312 as_FloatRegister($src2$$reg)); 17313 %} 17314 ins_pipe(vlogical128); 17315 %} 17316 17317 // --------------------------------- XOR -------------------------------------- 17318 17319 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17320 %{ 17321 predicate(n->as_Vector()->length_in_bytes() == 4 || 17322 n->as_Vector()->length_in_bytes() == 8); 17323 match(Set dst (XorV src1 src2)); 17324 ins_cost(INSN_COST); 17325 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17326 ins_encode %{ 17327 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17328 as_FloatRegister($src1$$reg), 17329 as_FloatRegister($src2$$reg)); 17330 %} 17331 ins_pipe(vlogical64); 17332 %} 17333 17334 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17335 %{ 17336 predicate(n->as_Vector()->length_in_bytes() == 16); 17337 match(Set dst (XorV src1 src2)); 17338 ins_cost(INSN_COST); 17339 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17340 ins_encode %{ 17341 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17342 as_FloatRegister($src1$$reg), 17343 as_FloatRegister($src2$$reg)); 17344 %} 17345 ins_pipe(vlogical128); 17346 %} 17347 17348 // ------------------------------ Shift --------------------------------------- 17349 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17350 predicate(n->as_Vector()->length_in_bytes() == 4 || 17351 n->as_Vector()->length_in_bytes() == 8); 17352 match(Set dst (LShiftCntV cnt)); 17353 match(Set dst (RShiftCntV cnt)); 17354 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17355 ins_encode %{ 17356 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17357 %} 17358 ins_pipe(vdup_reg_reg64); 17359 %} 17360 17361 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17362 predicate(n->as_Vector()->length_in_bytes() == 16); 17363 match(Set dst (LShiftCntV cnt)); 17364 match(Set dst (RShiftCntV cnt)); 17365 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17366 ins_encode %{ 17367 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17368 %} 17369 ins_pipe(vdup_reg_reg128); 17370 %} 17371 17372 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17373 predicate(n->as_Vector()->length() == 4 || 17374 n->as_Vector()->length() == 8); 17375 match(Set dst (LShiftVB src shift)); 17376 ins_cost(INSN_COST); 17377 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17378 ins_encode %{ 17379 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17380 as_FloatRegister($src$$reg), 17381 as_FloatRegister($shift$$reg)); 17382 %} 17383 ins_pipe(vshift64); 17384 %} 17385 17386 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17387 predicate(n->as_Vector()->length() == 16); 17388 match(Set dst (LShiftVB src shift)); 17389 ins_cost(INSN_COST); 17390 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17391 ins_encode %{ 17392 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17393 as_FloatRegister($src$$reg), 17394 as_FloatRegister($shift$$reg)); 17395 %} 17396 ins_pipe(vshift128); 17397 %} 17398 17399 // Right shifts with vector shift count on aarch64 SIMD are implemented 17400 // as left shift by negative shift count. 17401 // There are two cases for vector shift count. 17402 // 17403 // Case 1: The vector shift count is from replication. 17404 // | | 17405 // LoadVector RShiftCntV 17406 // | / 17407 // RShiftVI 17408 // Note: In inner loop, multiple neg instructions are used, which can be 17409 // moved to outer loop and merge into one neg instruction. 17410 // 17411 // Case 2: The vector shift count is from loading. 17412 // This case isn't supported by middle-end now. But it's supported by 17413 // panama/vectorIntrinsics(JEP 338: Vector API). 17414 // | | 17415 // LoadVector LoadVector 17416 // | / 17417 // RShiftVI 17418 // 17419 17420 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17421 predicate(n->as_Vector()->length() == 4 || 17422 n->as_Vector()->length() == 8); 17423 match(Set dst (RShiftVB src shift)); 17424 ins_cost(INSN_COST); 17425 effect(TEMP tmp); 17426 format %{ "negr $tmp,$shift\t" 17427 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17428 ins_encode %{ 17429 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17430 as_FloatRegister($shift$$reg)); 17431 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17432 as_FloatRegister($src$$reg), 17433 as_FloatRegister($tmp$$reg)); 17434 %} 17435 ins_pipe(vshift64); 17436 %} 17437 17438 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17439 predicate(n->as_Vector()->length() == 16); 17440 match(Set dst (RShiftVB src shift)); 17441 ins_cost(INSN_COST); 17442 effect(TEMP tmp); 17443 format %{ "negr $tmp,$shift\t" 17444 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17445 ins_encode %{ 17446 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17447 as_FloatRegister($shift$$reg)); 17448 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17449 as_FloatRegister($src$$reg), 17450 as_FloatRegister($tmp$$reg)); 17451 %} 17452 ins_pipe(vshift128); 17453 %} 17454 17455 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17456 predicate(n->as_Vector()->length() == 4 || 17457 n->as_Vector()->length() == 8); 17458 match(Set dst (URShiftVB src shift)); 17459 ins_cost(INSN_COST); 17460 effect(TEMP tmp); 17461 format %{ "negr $tmp,$shift\t" 17462 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17463 ins_encode %{ 17464 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17465 as_FloatRegister($shift$$reg)); 17466 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17467 as_FloatRegister($src$$reg), 17468 as_FloatRegister($tmp$$reg)); 17469 %} 17470 ins_pipe(vshift64); 17471 %} 17472 17473 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17474 predicate(n->as_Vector()->length() == 16); 17475 match(Set dst (URShiftVB src shift)); 17476 ins_cost(INSN_COST); 17477 effect(TEMP tmp); 17478 format %{ "negr $tmp,$shift\t" 17479 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17480 ins_encode %{ 17481 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17482 as_FloatRegister($shift$$reg)); 17483 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17484 as_FloatRegister($src$$reg), 17485 as_FloatRegister($tmp$$reg)); 17486 %} 17487 ins_pipe(vshift128); 17488 %} 17489 17490 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17491 predicate(n->as_Vector()->length() == 4 || 17492 n->as_Vector()->length() == 8); 17493 match(Set dst (LShiftVB src (LShiftCntV shift))); 17494 ins_cost(INSN_COST); 17495 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17496 ins_encode %{ 17497 int sh = (int)$shift$$constant; 17498 if (sh >= 8) { 17499 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17500 as_FloatRegister($src$$reg), 17501 as_FloatRegister($src$$reg)); 17502 } else { 17503 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17504 as_FloatRegister($src$$reg), sh); 17505 } 17506 %} 17507 ins_pipe(vshift64_imm); 17508 %} 17509 17510 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17511 predicate(n->as_Vector()->length() == 16); 17512 match(Set dst (LShiftVB src (LShiftCntV shift))); 17513 ins_cost(INSN_COST); 17514 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17515 ins_encode %{ 17516 int sh = (int)$shift$$constant; 17517 if (sh >= 8) { 17518 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17519 as_FloatRegister($src$$reg), 17520 as_FloatRegister($src$$reg)); 17521 } else { 17522 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17523 as_FloatRegister($src$$reg), sh); 17524 } 17525 %} 17526 ins_pipe(vshift128_imm); 17527 %} 17528 17529 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17530 predicate(n->as_Vector()->length() == 4 || 17531 n->as_Vector()->length() == 8); 17532 match(Set dst (RShiftVB src (RShiftCntV shift))); 17533 ins_cost(INSN_COST); 17534 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17535 ins_encode %{ 17536 int sh = (int)$shift$$constant; 17537 if (sh >= 8) sh = 7; 17538 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17539 as_FloatRegister($src$$reg), sh); 17540 %} 17541 ins_pipe(vshift64_imm); 17542 %} 17543 17544 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17545 predicate(n->as_Vector()->length() == 16); 17546 match(Set dst (RShiftVB src (RShiftCntV shift))); 17547 ins_cost(INSN_COST); 17548 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17549 ins_encode %{ 17550 int sh = (int)$shift$$constant; 17551 if (sh >= 8) sh = 7; 17552 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17553 as_FloatRegister($src$$reg), sh); 17554 %} 17555 ins_pipe(vshift128_imm); 17556 %} 17557 17558 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17559 predicate(n->as_Vector()->length() == 4 || 17560 n->as_Vector()->length() == 8); 17561 match(Set dst (URShiftVB src (RShiftCntV shift))); 17562 ins_cost(INSN_COST); 17563 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17564 ins_encode %{ 17565 int sh = (int)$shift$$constant; 17566 if (sh >= 8) { 17567 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17568 as_FloatRegister($src$$reg), 17569 as_FloatRegister($src$$reg)); 17570 } else { 17571 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17572 as_FloatRegister($src$$reg), sh); 17573 } 17574 %} 17575 ins_pipe(vshift64_imm); 17576 %} 17577 17578 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17579 predicate(n->as_Vector()->length() == 16); 17580 match(Set dst (URShiftVB src (RShiftCntV shift))); 17581 ins_cost(INSN_COST); 17582 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17583 ins_encode %{ 17584 int sh = (int)$shift$$constant; 17585 if (sh >= 8) { 17586 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17587 as_FloatRegister($src$$reg), 17588 as_FloatRegister($src$$reg)); 17589 } else { 17590 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17591 as_FloatRegister($src$$reg), sh); 17592 } 17593 %} 17594 ins_pipe(vshift128_imm); 17595 %} 17596 17597 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17598 predicate(n->as_Vector()->length() == 2 || 17599 n->as_Vector()->length() == 4); 17600 match(Set dst (LShiftVS src shift)); 17601 ins_cost(INSN_COST); 17602 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17603 ins_encode %{ 17604 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17605 as_FloatRegister($src$$reg), 17606 as_FloatRegister($shift$$reg)); 17607 %} 17608 ins_pipe(vshift64); 17609 %} 17610 17611 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17612 predicate(n->as_Vector()->length() == 8); 17613 match(Set dst (LShiftVS src shift)); 17614 ins_cost(INSN_COST); 17615 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17616 ins_encode %{ 17617 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17618 as_FloatRegister($src$$reg), 17619 as_FloatRegister($shift$$reg)); 17620 %} 17621 ins_pipe(vshift128); 17622 %} 17623 17624 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17625 predicate(n->as_Vector()->length() == 2 || 17626 n->as_Vector()->length() == 4); 17627 match(Set dst (RShiftVS src shift)); 17628 ins_cost(INSN_COST); 17629 effect(TEMP tmp); 17630 format %{ "negr $tmp,$shift\t" 17631 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17632 ins_encode %{ 17633 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17634 as_FloatRegister($shift$$reg)); 17635 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17636 as_FloatRegister($src$$reg), 17637 as_FloatRegister($tmp$$reg)); 17638 %} 17639 ins_pipe(vshift64); 17640 %} 17641 17642 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17643 predicate(n->as_Vector()->length() == 8); 17644 match(Set dst (RShiftVS src shift)); 17645 ins_cost(INSN_COST); 17646 effect(TEMP tmp); 17647 format %{ "negr $tmp,$shift\t" 17648 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17649 ins_encode %{ 17650 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17651 as_FloatRegister($shift$$reg)); 17652 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17653 as_FloatRegister($src$$reg), 17654 as_FloatRegister($tmp$$reg)); 17655 %} 17656 ins_pipe(vshift128); 17657 %} 17658 17659 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17660 predicate(n->as_Vector()->length() == 2 || 17661 n->as_Vector()->length() == 4); 17662 match(Set dst (URShiftVS src shift)); 17663 ins_cost(INSN_COST); 17664 effect(TEMP tmp); 17665 format %{ "negr $tmp,$shift\t" 17666 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17667 ins_encode %{ 17668 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17669 as_FloatRegister($shift$$reg)); 17670 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17671 as_FloatRegister($src$$reg), 17672 as_FloatRegister($tmp$$reg)); 17673 %} 17674 ins_pipe(vshift64); 17675 %} 17676 17677 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17678 predicate(n->as_Vector()->length() == 8); 17679 match(Set dst (URShiftVS src shift)); 17680 ins_cost(INSN_COST); 17681 effect(TEMP tmp); 17682 format %{ "negr $tmp,$shift\t" 17683 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17684 ins_encode %{ 17685 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17686 as_FloatRegister($shift$$reg)); 17687 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17688 as_FloatRegister($src$$reg), 17689 as_FloatRegister($tmp$$reg)); 17690 %} 17691 ins_pipe(vshift128); 17692 %} 17693 17694 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17695 predicate(n->as_Vector()->length() == 2 || 17696 n->as_Vector()->length() == 4); 17697 match(Set dst (LShiftVS src (LShiftCntV shift))); 17698 ins_cost(INSN_COST); 17699 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17700 ins_encode %{ 17701 int sh = (int)$shift$$constant; 17702 if (sh >= 16) { 17703 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17704 as_FloatRegister($src$$reg), 17705 as_FloatRegister($src$$reg)); 17706 } else { 17707 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17708 as_FloatRegister($src$$reg), sh); 17709 } 17710 %} 17711 ins_pipe(vshift64_imm); 17712 %} 17713 17714 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17715 predicate(n->as_Vector()->length() == 8); 17716 match(Set dst (LShiftVS src (LShiftCntV shift))); 17717 ins_cost(INSN_COST); 17718 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17719 ins_encode %{ 17720 int sh = (int)$shift$$constant; 17721 if (sh >= 16) { 17722 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17723 as_FloatRegister($src$$reg), 17724 as_FloatRegister($src$$reg)); 17725 } else { 17726 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17727 as_FloatRegister($src$$reg), sh); 17728 } 17729 %} 17730 ins_pipe(vshift128_imm); 17731 %} 17732 17733 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17734 predicate(n->as_Vector()->length() == 2 || 17735 n->as_Vector()->length() == 4); 17736 match(Set dst (RShiftVS src (RShiftCntV shift))); 17737 ins_cost(INSN_COST); 17738 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17739 ins_encode %{ 17740 int sh = (int)$shift$$constant; 17741 if (sh >= 16) sh = 15; 17742 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17743 as_FloatRegister($src$$reg), sh); 17744 %} 17745 ins_pipe(vshift64_imm); 17746 %} 17747 17748 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17749 predicate(n->as_Vector()->length() == 8); 17750 match(Set dst (RShiftVS src (RShiftCntV shift))); 17751 ins_cost(INSN_COST); 17752 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17753 ins_encode %{ 17754 int sh = (int)$shift$$constant; 17755 if (sh >= 16) sh = 15; 17756 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17757 as_FloatRegister($src$$reg), sh); 17758 %} 17759 ins_pipe(vshift128_imm); 17760 %} 17761 17762 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17763 predicate(n->as_Vector()->length() == 2 || 17764 n->as_Vector()->length() == 4); 17765 match(Set dst (URShiftVS src (RShiftCntV shift))); 17766 ins_cost(INSN_COST); 17767 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17768 ins_encode %{ 17769 int sh = (int)$shift$$constant; 17770 if (sh >= 16) { 17771 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17772 as_FloatRegister($src$$reg), 17773 as_FloatRegister($src$$reg)); 17774 } else { 17775 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17776 as_FloatRegister($src$$reg), sh); 17777 } 17778 %} 17779 ins_pipe(vshift64_imm); 17780 %} 17781 17782 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17783 predicate(n->as_Vector()->length() == 8); 17784 match(Set dst (URShiftVS src (RShiftCntV shift))); 17785 ins_cost(INSN_COST); 17786 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17787 ins_encode %{ 17788 int sh = (int)$shift$$constant; 17789 if (sh >= 16) { 17790 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17791 as_FloatRegister($src$$reg), 17792 as_FloatRegister($src$$reg)); 17793 } else { 17794 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17795 as_FloatRegister($src$$reg), sh); 17796 } 17797 %} 17798 ins_pipe(vshift128_imm); 17799 %} 17800 17801 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17802 predicate(n->as_Vector()->length() == 2); 17803 match(Set dst (LShiftVI src shift)); 17804 ins_cost(INSN_COST); 17805 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17806 ins_encode %{ 17807 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17808 as_FloatRegister($src$$reg), 17809 as_FloatRegister($shift$$reg)); 17810 %} 17811 ins_pipe(vshift64); 17812 %} 17813 17814 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17815 predicate(n->as_Vector()->length() == 4); 17816 match(Set dst (LShiftVI src shift)); 17817 ins_cost(INSN_COST); 17818 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17819 ins_encode %{ 17820 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17821 as_FloatRegister($src$$reg), 17822 as_FloatRegister($shift$$reg)); 17823 %} 17824 ins_pipe(vshift128); 17825 %} 17826 17827 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17828 predicate(n->as_Vector()->length() == 2); 17829 match(Set dst (RShiftVI src shift)); 17830 ins_cost(INSN_COST); 17831 effect(TEMP tmp); 17832 format %{ "negr $tmp,$shift\t" 17833 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17834 ins_encode %{ 17835 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17836 as_FloatRegister($shift$$reg)); 17837 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17838 as_FloatRegister($src$$reg), 17839 as_FloatRegister($tmp$$reg)); 17840 %} 17841 ins_pipe(vshift64); 17842 %} 17843 17844 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17845 predicate(n->as_Vector()->length() == 4); 17846 match(Set dst (RShiftVI src shift)); 17847 ins_cost(INSN_COST); 17848 effect(TEMP tmp); 17849 format %{ "negr $tmp,$shift\t" 17850 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17851 ins_encode %{ 17852 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17853 as_FloatRegister($shift$$reg)); 17854 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17855 as_FloatRegister($src$$reg), 17856 as_FloatRegister($tmp$$reg)); 17857 %} 17858 ins_pipe(vshift128); 17859 %} 17860 17861 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17862 predicate(n->as_Vector()->length() == 2); 17863 match(Set dst (URShiftVI src shift)); 17864 ins_cost(INSN_COST); 17865 effect(TEMP tmp); 17866 format %{ "negr $tmp,$shift\t" 17867 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17868 ins_encode %{ 17869 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17870 as_FloatRegister($shift$$reg)); 17871 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17872 as_FloatRegister($src$$reg), 17873 as_FloatRegister($tmp$$reg)); 17874 %} 17875 ins_pipe(vshift64); 17876 %} 17877 17878 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17879 predicate(n->as_Vector()->length() == 4); 17880 match(Set dst (URShiftVI src shift)); 17881 ins_cost(INSN_COST); 17882 effect(TEMP tmp); 17883 format %{ "negr $tmp,$shift\t" 17884 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17885 ins_encode %{ 17886 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17887 as_FloatRegister($shift$$reg)); 17888 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17889 as_FloatRegister($src$$reg), 17890 as_FloatRegister($tmp$$reg)); 17891 %} 17892 ins_pipe(vshift128); 17893 %} 17894 17895 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17896 predicate(n->as_Vector()->length() == 2); 17897 match(Set dst (LShiftVI src (LShiftCntV shift))); 17898 ins_cost(INSN_COST); 17899 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17900 ins_encode %{ 17901 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17902 as_FloatRegister($src$$reg), 17903 (int)$shift$$constant); 17904 %} 17905 ins_pipe(vshift64_imm); 17906 %} 17907 17908 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17909 predicate(n->as_Vector()->length() == 4); 17910 match(Set dst (LShiftVI src (LShiftCntV shift))); 17911 ins_cost(INSN_COST); 17912 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17913 ins_encode %{ 17914 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17915 as_FloatRegister($src$$reg), 17916 (int)$shift$$constant); 17917 %} 17918 ins_pipe(vshift128_imm); 17919 %} 17920 17921 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17922 predicate(n->as_Vector()->length() == 2); 17923 match(Set dst (RShiftVI src (RShiftCntV shift))); 17924 ins_cost(INSN_COST); 17925 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17926 ins_encode %{ 17927 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17928 as_FloatRegister($src$$reg), 17929 (int)$shift$$constant); 17930 %} 17931 ins_pipe(vshift64_imm); 17932 %} 17933 17934 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17935 predicate(n->as_Vector()->length() == 4); 17936 match(Set dst (RShiftVI src (RShiftCntV shift))); 17937 ins_cost(INSN_COST); 17938 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17939 ins_encode %{ 17940 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17941 as_FloatRegister($src$$reg), 17942 (int)$shift$$constant); 17943 %} 17944 ins_pipe(vshift128_imm); 17945 %} 17946 17947 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17948 predicate(n->as_Vector()->length() == 2); 17949 match(Set dst (URShiftVI src (RShiftCntV shift))); 17950 ins_cost(INSN_COST); 17951 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17952 ins_encode %{ 17953 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17954 as_FloatRegister($src$$reg), 17955 (int)$shift$$constant); 17956 %} 17957 ins_pipe(vshift64_imm); 17958 %} 17959 17960 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17961 predicate(n->as_Vector()->length() == 4); 17962 match(Set dst (URShiftVI src (RShiftCntV shift))); 17963 ins_cost(INSN_COST); 17964 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17965 ins_encode %{ 17966 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17967 as_FloatRegister($src$$reg), 17968 (int)$shift$$constant); 17969 %} 17970 ins_pipe(vshift128_imm); 17971 %} 17972 17973 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17974 predicate(n->as_Vector()->length() == 2); 17975 match(Set dst (LShiftVL src shift)); 17976 ins_cost(INSN_COST); 17977 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17978 ins_encode %{ 17979 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17980 as_FloatRegister($src$$reg), 17981 as_FloatRegister($shift$$reg)); 17982 %} 17983 ins_pipe(vshift128); 17984 %} 17985 17986 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17987 predicate(n->as_Vector()->length() == 2); 17988 match(Set dst (RShiftVL src shift)); 17989 ins_cost(INSN_COST); 17990 effect(TEMP tmp); 17991 format %{ "negr $tmp,$shift\t" 17992 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17993 ins_encode %{ 17994 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17995 as_FloatRegister($shift$$reg)); 17996 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17997 as_FloatRegister($src$$reg), 17998 as_FloatRegister($tmp$$reg)); 17999 %} 18000 ins_pipe(vshift128); 18001 %} 18002 18003 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 18004 predicate(n->as_Vector()->length() == 2); 18005 match(Set dst (URShiftVL src shift)); 18006 ins_cost(INSN_COST); 18007 effect(TEMP tmp); 18008 format %{ "negr $tmp,$shift\t" 18009 "ushl $dst,$src,$tmp\t# vector (2D)" %} 18010 ins_encode %{ 18011 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 18012 as_FloatRegister($shift$$reg)); 18013 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 18014 as_FloatRegister($src$$reg), 18015 as_FloatRegister($tmp$$reg)); 18016 %} 18017 ins_pipe(vshift128); 18018 %} 18019 18020 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 18021 predicate(n->as_Vector()->length() == 2); 18022 match(Set dst (LShiftVL src (LShiftCntV shift))); 18023 ins_cost(INSN_COST); 18024 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 18025 ins_encode %{ 18026 __ shl(as_FloatRegister($dst$$reg), __ T2D, 18027 as_FloatRegister($src$$reg), 18028 (int)$shift$$constant); 18029 %} 18030 ins_pipe(vshift128_imm); 18031 %} 18032 18033 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 18034 predicate(n->as_Vector()->length() == 2); 18035 match(Set dst (RShiftVL src (RShiftCntV shift))); 18036 ins_cost(INSN_COST); 18037 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 18038 ins_encode %{ 18039 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 18040 as_FloatRegister($src$$reg), 18041 (int)$shift$$constant); 18042 %} 18043 ins_pipe(vshift128_imm); 18044 %} 18045 18046 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 18047 predicate(n->as_Vector()->length() == 2); 18048 match(Set dst (URShiftVL src (RShiftCntV shift))); 18049 ins_cost(INSN_COST); 18050 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 18051 ins_encode %{ 18052 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 18053 as_FloatRegister($src$$reg), 18054 (int)$shift$$constant); 18055 %} 18056 ins_pipe(vshift128_imm); 18057 %} 18058 18059 instruct vmax2F(vecD dst, vecD src1, vecD src2) 18060 %{ 18061 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18062 match(Set dst (MaxV src1 src2)); 18063 ins_cost(INSN_COST); 18064 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 18065 ins_encode %{ 18066 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 18067 as_FloatRegister($src1$$reg), 18068 as_FloatRegister($src2$$reg)); 18069 %} 18070 ins_pipe(vdop_fp64); 18071 %} 18072 18073 instruct vmax4F(vecX dst, vecX src1, vecX src2) 18074 %{ 18075 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18076 match(Set dst (MaxV src1 src2)); 18077 ins_cost(INSN_COST); 18078 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 18079 ins_encode %{ 18080 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 18081 as_FloatRegister($src1$$reg), 18082 as_FloatRegister($src2$$reg)); 18083 %} 18084 ins_pipe(vdop_fp128); 18085 %} 18086 18087 instruct vmax2D(vecX dst, vecX src1, vecX src2) 18088 %{ 18089 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18090 match(Set dst (MaxV src1 src2)); 18091 ins_cost(INSN_COST); 18092 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 18093 ins_encode %{ 18094 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 18095 as_FloatRegister($src1$$reg), 18096 as_FloatRegister($src2$$reg)); 18097 %} 18098 ins_pipe(vdop_fp128); 18099 %} 18100 18101 instruct vmin2F(vecD dst, vecD src1, vecD src2) 18102 %{ 18103 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18104 match(Set dst (MinV src1 src2)); 18105 ins_cost(INSN_COST); 18106 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 18107 ins_encode %{ 18108 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 18109 as_FloatRegister($src1$$reg), 18110 as_FloatRegister($src2$$reg)); 18111 %} 18112 ins_pipe(vdop_fp64); 18113 %} 18114 18115 instruct vmin4F(vecX dst, vecX src1, vecX src2) 18116 %{ 18117 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18118 match(Set dst (MinV src1 src2)); 18119 ins_cost(INSN_COST); 18120 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 18121 ins_encode %{ 18122 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 18123 as_FloatRegister($src1$$reg), 18124 as_FloatRegister($src2$$reg)); 18125 %} 18126 ins_pipe(vdop_fp128); 18127 %} 18128 18129 instruct vmin2D(vecX dst, vecX src1, vecX src2) 18130 %{ 18131 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18132 match(Set dst (MinV src1 src2)); 18133 ins_cost(INSN_COST); 18134 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 18135 ins_encode %{ 18136 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 18137 as_FloatRegister($src1$$reg), 18138 as_FloatRegister($src2$$reg)); 18139 %} 18140 ins_pipe(vdop_fp128); 18141 %} 18142 18143 instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ 18144 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18145 match(Set dst (RoundDoubleModeV src rmode)); 18146 format %{ "frint $dst, $src, $rmode" %} 18147 ins_encode %{ 18148 switch ($rmode$$constant) { 18149 case RoundDoubleModeNode::rmode_rint: 18150 __ frintn(as_FloatRegister($dst$$reg), __ T2D, 18151 as_FloatRegister($src$$reg)); 18152 break; 18153 case RoundDoubleModeNode::rmode_floor: 18154 __ frintm(as_FloatRegister($dst$$reg), __ T2D, 18155 as_FloatRegister($src$$reg)); 18156 break; 18157 case RoundDoubleModeNode::rmode_ceil: 18158 __ frintp(as_FloatRegister($dst$$reg), __ T2D, 18159 as_FloatRegister($src$$reg)); 18160 break; 18161 } 18162 %} 18163 ins_pipe(vdop_fp128); 18164 %} 18165 18166 instruct vpopcount4I(vecX dst, vecX src) %{ 18167 predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); 18168 match(Set dst (PopCountVI src)); 18169 format %{ 18170 "cnt $dst, $src\t# vector (16B)\n\t" 18171 "uaddlp $dst, $dst\t# vector (16B)\n\t" 18172 "uaddlp $dst, $dst\t# vector (8H)" 18173 %} 18174 ins_encode %{ 18175 __ cnt(as_FloatRegister($dst$$reg), __ T16B, 18176 as_FloatRegister($src$$reg)); 18177 __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, 18178 as_FloatRegister($dst$$reg)); 18179 __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, 18180 as_FloatRegister($dst$$reg)); 18181 %} 18182 ins_pipe(pipe_class_default); 18183 %} 18184 18185 instruct vpopcount2I(vecD dst, vecD src) %{ 18186 predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); 18187 match(Set dst (PopCountVI src)); 18188 format %{ 18189 "cnt $dst, $src\t# vector (8B)\n\t" 18190 "uaddlp $dst, $dst\t# vector (8B)\n\t" 18191 "uaddlp $dst, $dst\t# vector (4H)" 18192 %} 18193 ins_encode %{ 18194 __ cnt(as_FloatRegister($dst$$reg), __ T8B, 18195 as_FloatRegister($src$$reg)); 18196 __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, 18197 as_FloatRegister($dst$$reg)); 18198 __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, 18199 as_FloatRegister($dst$$reg)); 18200 %} 18201 ins_pipe(pipe_class_default); 18202 %} 18203 18204 //----------PEEPHOLE RULES----------------------------------------------------- 18205 // These must follow all instruction definitions as they use the names 18206 // defined in the instructions definitions. 18207 // 18208 // peepmatch ( root_instr_name [preceding_instruction]* ); 18209 // 18210 // peepconstraint %{ 18211 // (instruction_number.operand_name relational_op instruction_number.operand_name 18212 // [, ...] ); 18213 // // instruction numbers are zero-based using left to right order in peepmatch 18214 // 18215 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18216 // // provide an instruction_number.operand_name for each operand that appears 18217 // // in the replacement instruction's match rule 18218 // 18219 // ---------VM FLAGS--------------------------------------------------------- 18220 // 18221 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18222 // 18223 // Each peephole rule is given an identifying number starting with zero and 18224 // increasing by one in the order seen by the parser. An individual peephole 18225 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18226 // on the command-line. 18227 // 18228 // ---------CURRENT LIMITATIONS---------------------------------------------- 18229 // 18230 // Only match adjacent instructions in same basic block 18231 // Only equality constraints 18232 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18233 // Only one replacement instruction 18234 // 18235 // ---------EXAMPLE---------------------------------------------------------- 18236 // 18237 // // pertinent parts of existing instructions in architecture description 18238 // instruct movI(iRegINoSp dst, iRegI src) 18239 // %{ 18240 // match(Set dst (CopyI src)); 18241 // %} 18242 // 18243 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18244 // %{ 18245 // match(Set dst (AddI dst src)); 18246 // effect(KILL cr); 18247 // %} 18248 // 18249 // // Change (inc mov) to lea 18250 // peephole %{ 18251 // // increment preceeded by register-register move 18252 // peepmatch ( incI_iReg movI ); 18253 // // require that the destination register of the increment 18254 // // match the destination register of the move 18255 // peepconstraint ( 0.dst == 1.dst ); 18256 // // construct a replacement instruction that sets 18257 // // the destination to ( move's source register + one ) 18258 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18259 // %} 18260 // 18261 18262 // Implementation no longer uses movX instructions since 18263 // machine-independent system no longer uses CopyX nodes. 18264 // 18265 // peephole 18266 // %{ 18267 // peepmatch (incI_iReg movI); 18268 // peepconstraint (0.dst == 1.dst); 18269 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18270 // %} 18271 18272 // peephole 18273 // %{ 18274 // peepmatch (decI_iReg movI); 18275 // peepconstraint (0.dst == 1.dst); 18276 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18277 // %} 18278 18279 // peephole 18280 // %{ 18281 // peepmatch (addI_iReg_imm movI); 18282 // peepconstraint (0.dst == 1.dst); 18283 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18284 // %} 18285 18286 // peephole 18287 // %{ 18288 // peepmatch (incL_iReg movL); 18289 // peepconstraint (0.dst == 1.dst); 18290 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18291 // %} 18292 18293 // peephole 18294 // %{ 18295 // peepmatch (decL_iReg movL); 18296 // peepconstraint (0.dst == 1.dst); 18297 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18298 // %} 18299 18300 // peephole 18301 // %{ 18302 // peepmatch (addL_iReg_imm movL); 18303 // peepconstraint (0.dst == 1.dst); 18304 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18305 // %} 18306 18307 // peephole 18308 // %{ 18309 // peepmatch (addP_iReg_imm movP); 18310 // peepconstraint (0.dst == 1.dst); 18311 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18312 // %} 18313 18314 // // Change load of spilled value to only a spill 18315 // instruct storeI(memory mem, iRegI src) 18316 // %{ 18317 // match(Set mem (StoreI mem src)); 18318 // %} 18319 // 18320 // instruct loadI(iRegINoSp dst, memory mem) 18321 // %{ 18322 // match(Set dst (LoadI mem)); 18323 // %} 18324 // 18325 18326 //----------SMARTSPILL RULES--------------------------------------------------- 18327 // These must follow all instruction definitions as they use the names 18328 // defined in the instructions definitions. 18329 18330 // Local Variables: 18331 // mode: c++ 18332 // End: