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, compressed klass 1101 // pointers doesn't use r27 after JDK-8234794 1102 if (UseCompressedOops) { 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> and associated dmb 1365 1366 bool unnecessary_acquire(const Node *barrier) 1367 { 1368 assert(barrier->is_MemBar(), "expecting a membar"); 1369 1370 if (UseBarriersForVolatile) { 1371 // we need to plant a dmb 1372 return false; 1373 } 1374 1375 MemBarNode* mb = barrier->as_MemBar(); 1376 1377 if (mb->trailing_load()) { 1378 return true; 1379 } 1380 1381 if (mb->trailing_load_store()) { 1382 Node* load_store = mb->in(MemBarNode::Precedent); 1383 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1384 return is_CAS(load_store->Opcode(), true); 1385 } 1386 1387 return false; 1388 } 1389 1390 bool needs_acquiring_load(const Node *n) 1391 { 1392 assert(n->is_Load(), "expecting a load"); 1393 if (UseBarriersForVolatile) { 1394 // we use a normal load and a dmb 1395 return false; 1396 } 1397 1398 LoadNode *ld = n->as_Load(); 1399 1400 return ld->is_acquire(); 1401 } 1402 1403 bool unnecessary_release(const Node *n) 1404 { 1405 assert((n->is_MemBar() && 1406 n->Opcode() == Op_MemBarRelease), 1407 "expecting a release membar"); 1408 1409 if (UseBarriersForVolatile) { 1410 // we need to plant a dmb 1411 return false; 1412 } 1413 1414 MemBarNode *barrier = n->as_MemBar(); 1415 if (!barrier->leading()) { 1416 return false; 1417 } else { 1418 Node* trailing = barrier->trailing_membar(); 1419 MemBarNode* trailing_mb = trailing->as_MemBar(); 1420 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1421 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1422 1423 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1424 if (mem->is_Store()) { 1425 assert(mem->as_Store()->is_release(), ""); 1426 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1427 return true; 1428 } else { 1429 assert(mem->is_LoadStore(), ""); 1430 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1431 return is_CAS(mem->Opcode(), true); 1432 } 1433 } 1434 return false; 1435 } 1436 1437 bool unnecessary_volatile(const Node *n) 1438 { 1439 // assert n->is_MemBar(); 1440 if (UseBarriersForVolatile) { 1441 // we need to plant a dmb 1442 return false; 1443 } 1444 1445 MemBarNode *mbvol = n->as_MemBar(); 1446 1447 bool release = mbvol->trailing_store(); 1448 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1449 #ifdef ASSERT 1450 if (release) { 1451 Node* leading = mbvol->leading_membar(); 1452 assert(leading->Opcode() == Op_MemBarRelease, ""); 1453 assert(leading->as_MemBar()->leading_store(), ""); 1454 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1455 } 1456 #endif 1457 1458 return release; 1459 } 1460 1461 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1462 1463 bool needs_releasing_store(const Node *n) 1464 { 1465 // assert n->is_Store(); 1466 if (UseBarriersForVolatile) { 1467 // we use a normal store and dmb combination 1468 return false; 1469 } 1470 1471 StoreNode *st = n->as_Store(); 1472 1473 return st->trailing_membar() != NULL; 1474 } 1475 1476 // predicate controlling translation of CAS 1477 // 1478 // returns true if CAS needs to use an acquiring load otherwise false 1479 1480 bool needs_acquiring_load_exclusive(const Node *n) 1481 { 1482 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1483 if (UseBarriersForVolatile) { 1484 return false; 1485 } 1486 1487 LoadStoreNode* ldst = n->as_LoadStore(); 1488 if (is_CAS(n->Opcode(), false)) { 1489 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1490 } else { 1491 return ldst->trailing_membar() != NULL; 1492 } 1493 1494 // so we can just return true here 1495 return true; 1496 } 1497 1498 #define __ _masm. 1499 1500 // advance declarations for helper functions to convert register 1501 // indices to register objects 1502 1503 // the ad file has to provide implementations of certain methods 1504 // expected by the generic code 1505 // 1506 // REQUIRED FUNCTIONALITY 1507 1508 //============================================================================= 1509 1510 // !!!!! Special hack to get all types of calls to specify the byte offset 1511 // from the start of the call to the point where the return address 1512 // will point. 1513 1514 int MachCallStaticJavaNode::ret_addr_offset() 1515 { 1516 // call should be a simple bl 1517 int off = 4; 1518 return off; 1519 } 1520 1521 int MachCallDynamicJavaNode::ret_addr_offset() 1522 { 1523 return 16; // movz, movk, movk, bl 1524 } 1525 1526 int MachCallRuntimeNode::ret_addr_offset() { 1527 // for generated stubs the call will be 1528 // far_call(addr) 1529 // for real runtime callouts it will be six instructions 1530 // see aarch64_enc_java_to_runtime 1531 // adr(rscratch2, retaddr) 1532 // lea(rscratch1, RuntimeAddress(addr) 1533 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1534 // blr(rscratch1) 1535 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1536 if (cb) { 1537 return MacroAssembler::far_branch_size(); 1538 } else { 1539 return 6 * NativeInstruction::instruction_size; 1540 } 1541 } 1542 1543 // Indicate if the safepoint node needs the polling page as an input 1544 1545 // the shared code plants the oop data at the start of the generated 1546 // code for the safepoint node and that needs ot be at the load 1547 // instruction itself. so we cannot plant a mov of the safepoint poll 1548 // address followed by a load. setting this to true means the mov is 1549 // scheduled as a prior instruction. that's better for scheduling 1550 // anyway. 1551 1552 bool SafePointNode::needs_polling_address_input() 1553 { 1554 return true; 1555 } 1556 1557 //============================================================================= 1558 1559 #ifndef PRODUCT 1560 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1561 st->print("BREAKPOINT"); 1562 } 1563 #endif 1564 1565 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1566 C2_MacroAssembler _masm(&cbuf); 1567 __ brk(0); 1568 } 1569 1570 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1571 return MachNode::size(ra_); 1572 } 1573 1574 //============================================================================= 1575 1576 #ifndef PRODUCT 1577 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1578 st->print("nop \t# %d bytes pad for loops and calls", _count); 1579 } 1580 #endif 1581 1582 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1583 C2_MacroAssembler _masm(&cbuf); 1584 for (int i = 0; i < _count; i++) { 1585 __ nop(); 1586 } 1587 } 1588 1589 uint MachNopNode::size(PhaseRegAlloc*) const { 1590 return _count * NativeInstruction::instruction_size; 1591 } 1592 1593 //============================================================================= 1594 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1595 1596 int ConstantTable::calculate_table_base_offset() const { 1597 return 0; // absolute addressing, no offset 1598 } 1599 1600 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1601 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1602 ShouldNotReachHere(); 1603 } 1604 1605 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1606 // Empty encoding 1607 } 1608 1609 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1610 return 0; 1611 } 1612 1613 #ifndef PRODUCT 1614 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1615 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1616 } 1617 #endif 1618 1619 #ifndef PRODUCT 1620 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1621 Compile* C = ra_->C; 1622 1623 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1624 1625 if (C->output()->need_stack_bang(framesize)) 1626 st->print("# stack bang size=%d\n\t", framesize); 1627 1628 if (framesize < ((1 << 9) + 2 * wordSize)) { 1629 st->print("sub sp, sp, #%d\n\t", framesize); 1630 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1631 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1632 } else { 1633 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1634 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1635 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1636 st->print("sub sp, sp, rscratch1"); 1637 } 1638 } 1639 #endif 1640 1641 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1642 Compile* C = ra_->C; 1643 C2_MacroAssembler _masm(&cbuf); 1644 1645 // n.b. frame size includes space for return pc and rfp 1646 const long framesize = C->output()->frame_size_in_bytes(); 1647 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1648 1649 // insert a nop at the start of the prolog so we can patch in a 1650 // branch if we need to invalidate the method later 1651 __ nop(); 1652 1653 if (C->clinit_barrier_on_entry()) { 1654 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1655 1656 Label L_skip_barrier; 1657 1658 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1659 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1660 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1661 __ bind(L_skip_barrier); 1662 } 1663 1664 int bangsize = C->output()->bang_size_in_bytes(); 1665 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) 1666 __ generate_stack_overflow_check(bangsize); 1667 1668 __ build_frame(framesize); 1669 1670 if (VerifyStackAtCalls) { 1671 Unimplemented(); 1672 } 1673 1674 C->output()->set_frame_complete(cbuf.insts_size()); 1675 1676 if (C->has_mach_constant_base_node()) { 1677 // NOTE: We set the table base offset here because users might be 1678 // emitted before MachConstantBaseNode. 1679 ConstantTable& constant_table = C->output()->constant_table(); 1680 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1681 } 1682 } 1683 1684 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1685 { 1686 return MachNode::size(ra_); // too many variables; just compute it 1687 // the hard way 1688 } 1689 1690 int MachPrologNode::reloc() const 1691 { 1692 return 0; 1693 } 1694 1695 //============================================================================= 1696 1697 #ifndef PRODUCT 1698 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1699 Compile* C = ra_->C; 1700 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1701 1702 st->print("# pop frame %d\n\t",framesize); 1703 1704 if (framesize == 0) { 1705 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1706 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1707 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1708 st->print("add sp, sp, #%d\n\t", framesize); 1709 } else { 1710 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1711 st->print("add sp, sp, rscratch1\n\t"); 1712 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1713 } 1714 1715 if (do_polling() && C->is_method_compilation()) { 1716 st->print("# touch polling page\n\t"); 1717 st->print("ldr rscratch1, [rthread],#polling_page_offset\n\t"); 1718 st->print("ldr zr, [rscratch1]"); 1719 } 1720 } 1721 #endif 1722 1723 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1724 Compile* C = ra_->C; 1725 C2_MacroAssembler _masm(&cbuf); 1726 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1727 1728 __ remove_frame(framesize); 1729 1730 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1731 __ reserved_stack_check(); 1732 } 1733 1734 if (do_polling() && C->is_method_compilation()) { 1735 __ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type); 1736 } 1737 } 1738 1739 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1740 // Variable size. Determine dynamically. 1741 return MachNode::size(ra_); 1742 } 1743 1744 int MachEpilogNode::reloc() const { 1745 // Return number of relocatable values contained in this instruction. 1746 return 1; // 1 for polling page. 1747 } 1748 1749 const Pipeline * MachEpilogNode::pipeline() const { 1750 return MachNode::pipeline_class(); 1751 } 1752 1753 //============================================================================= 1754 1755 // Figure out which register class each belongs in: rc_int, rc_float or 1756 // rc_stack. 1757 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1758 1759 static enum RC rc_class(OptoReg::Name reg) { 1760 1761 if (reg == OptoReg::Bad) { 1762 return rc_bad; 1763 } 1764 1765 // we have 30 int registers * 2 halves 1766 // (rscratch1 and rscratch2 are omitted) 1767 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1768 1769 if (reg < slots_of_int_registers) { 1770 return rc_int; 1771 } 1772 1773 // we have 32 float register * 4 halves 1774 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1775 return rc_float; 1776 } 1777 1778 // Between float regs & stack is the flags regs. 1779 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1780 1781 return rc_stack; 1782 } 1783 1784 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1785 Compile* C = ra_->C; 1786 1787 // Get registers to move. 1788 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1789 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1790 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1791 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1792 1793 enum RC src_hi_rc = rc_class(src_hi); 1794 enum RC src_lo_rc = rc_class(src_lo); 1795 enum RC dst_hi_rc = rc_class(dst_hi); 1796 enum RC dst_lo_rc = rc_class(dst_lo); 1797 1798 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1799 1800 if (src_hi != OptoReg::Bad) { 1801 assert((src_lo&1)==0 && src_lo+1==src_hi && 1802 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1803 "expected aligned-adjacent pairs"); 1804 } 1805 1806 if (src_lo == dst_lo && src_hi == dst_hi) { 1807 return 0; // Self copy, no move. 1808 } 1809 1810 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1811 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1812 int src_offset = ra_->reg2offset(src_lo); 1813 int dst_offset = ra_->reg2offset(dst_lo); 1814 1815 if (bottom_type()->isa_vect() != NULL) { 1816 uint ireg = ideal_reg(); 1817 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1818 if (cbuf) { 1819 C2_MacroAssembler _masm(cbuf); 1820 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1821 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1822 // stack->stack 1823 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1824 if (ireg == Op_VecD) { 1825 __ unspill(rscratch1, true, src_offset); 1826 __ spill(rscratch1, true, dst_offset); 1827 } else { 1828 __ spill_copy128(src_offset, dst_offset); 1829 } 1830 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1831 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1832 ireg == Op_VecD ? __ T8B : __ T16B, 1833 as_FloatRegister(Matcher::_regEncode[src_lo])); 1834 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1835 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1836 ireg == Op_VecD ? __ D : __ Q, 1837 ra_->reg2offset(dst_lo)); 1838 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1839 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1840 ireg == Op_VecD ? __ D : __ Q, 1841 ra_->reg2offset(src_lo)); 1842 } else { 1843 ShouldNotReachHere(); 1844 } 1845 } 1846 } else if (cbuf) { 1847 C2_MacroAssembler _masm(cbuf); 1848 switch (src_lo_rc) { 1849 case rc_int: 1850 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1851 if (is64) { 1852 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1853 as_Register(Matcher::_regEncode[src_lo])); 1854 } else { 1855 C2_MacroAssembler _masm(cbuf); 1856 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1857 as_Register(Matcher::_regEncode[src_lo])); 1858 } 1859 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1860 if (is64) { 1861 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1862 as_Register(Matcher::_regEncode[src_lo])); 1863 } else { 1864 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1865 as_Register(Matcher::_regEncode[src_lo])); 1866 } 1867 } else { // gpr --> stack spill 1868 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1869 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1870 } 1871 break; 1872 case rc_float: 1873 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1874 if (is64) { 1875 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1876 as_FloatRegister(Matcher::_regEncode[src_lo])); 1877 } else { 1878 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1879 as_FloatRegister(Matcher::_regEncode[src_lo])); 1880 } 1881 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1882 if (cbuf) { 1883 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1884 as_FloatRegister(Matcher::_regEncode[src_lo])); 1885 } else { 1886 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1887 as_FloatRegister(Matcher::_regEncode[src_lo])); 1888 } 1889 } else { // fpr --> stack spill 1890 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1891 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1892 is64 ? __ D : __ S, dst_offset); 1893 } 1894 break; 1895 case rc_stack: 1896 if (dst_lo_rc == rc_int) { // stack --> gpr load 1897 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1898 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1899 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1900 is64 ? __ D : __ S, src_offset); 1901 } else { // stack --> stack copy 1902 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1903 __ unspill(rscratch1, is64, src_offset); 1904 __ spill(rscratch1, is64, dst_offset); 1905 } 1906 break; 1907 default: 1908 assert(false, "bad rc_class for spill"); 1909 ShouldNotReachHere(); 1910 } 1911 } 1912 1913 if (st) { 1914 st->print("spill "); 1915 if (src_lo_rc == rc_stack) { 1916 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1917 } else { 1918 st->print("%s -> ", Matcher::regName[src_lo]); 1919 } 1920 if (dst_lo_rc == rc_stack) { 1921 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1922 } else { 1923 st->print("%s", Matcher::regName[dst_lo]); 1924 } 1925 if (bottom_type()->isa_vect() != NULL) { 1926 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1927 } else { 1928 st->print("\t# spill size = %d", is64 ? 64:32); 1929 } 1930 } 1931 1932 return 0; 1933 1934 } 1935 1936 #ifndef PRODUCT 1937 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1938 if (!ra_) 1939 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1940 else 1941 implementation(NULL, ra_, false, st); 1942 } 1943 #endif 1944 1945 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1946 implementation(&cbuf, ra_, false, NULL); 1947 } 1948 1949 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1950 return MachNode::size(ra_); 1951 } 1952 1953 //============================================================================= 1954 1955 #ifndef PRODUCT 1956 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1957 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1958 int reg = ra_->get_reg_first(this); 1959 st->print("add %s, rsp, #%d]\t# box lock", 1960 Matcher::regName[reg], offset); 1961 } 1962 #endif 1963 1964 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1965 C2_MacroAssembler _masm(&cbuf); 1966 1967 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1968 int reg = ra_->get_encode(this); 1969 1970 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1971 __ add(as_Register(reg), sp, offset); 1972 } else { 1973 ShouldNotReachHere(); 1974 } 1975 } 1976 1977 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1978 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1979 return 4; 1980 } 1981 1982 //============================================================================= 1983 1984 #ifndef PRODUCT 1985 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1986 { 1987 st->print_cr("# MachUEPNode"); 1988 if (UseCompressedClassPointers) { 1989 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1990 if (CompressedKlassPointers::shift() != 0) { 1991 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1992 } 1993 } else { 1994 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1995 } 1996 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1997 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1998 } 1999 #endif 2000 2001 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2002 { 2003 // This is the unverified entry point. 2004 C2_MacroAssembler _masm(&cbuf); 2005 2006 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2007 Label skip; 2008 // TODO 2009 // can we avoid this skip and still use a reloc? 2010 __ br(Assembler::EQ, skip); 2011 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2012 __ bind(skip); 2013 } 2014 2015 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2016 { 2017 return MachNode::size(ra_); 2018 } 2019 2020 // REQUIRED EMIT CODE 2021 2022 //============================================================================= 2023 2024 // Emit exception handler code. 2025 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2026 { 2027 // mov rscratch1 #exception_blob_entry_point 2028 // br rscratch1 2029 // Note that the code buffer's insts_mark is always relative to insts. 2030 // That's why we must use the macroassembler to generate a handler. 2031 C2_MacroAssembler _masm(&cbuf); 2032 address base = __ start_a_stub(size_exception_handler()); 2033 if (base == NULL) { 2034 ciEnv::current()->record_failure("CodeCache is full"); 2035 return 0; // CodeBuffer::expand failed 2036 } 2037 int offset = __ offset(); 2038 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2039 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2040 __ end_a_stub(); 2041 return offset; 2042 } 2043 2044 // Emit deopt handler code. 2045 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2046 { 2047 // Note that the code buffer's insts_mark is always relative to insts. 2048 // That's why we must use the macroassembler to generate a handler. 2049 C2_MacroAssembler _masm(&cbuf); 2050 address base = __ start_a_stub(size_deopt_handler()); 2051 if (base == NULL) { 2052 ciEnv::current()->record_failure("CodeCache is full"); 2053 return 0; // CodeBuffer::expand failed 2054 } 2055 int offset = __ offset(); 2056 2057 __ adr(lr, __ pc()); 2058 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2059 2060 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2061 __ end_a_stub(); 2062 return offset; 2063 } 2064 2065 // REQUIRED MATCHER CODE 2066 2067 //============================================================================= 2068 2069 const bool Matcher::match_rule_supported(int opcode) { 2070 if (!has_match_rule(opcode)) 2071 return false; 2072 2073 bool ret_value = true; 2074 switch (opcode) { 2075 case Op_CacheWB: 2076 case Op_CacheWBPreSync: 2077 case Op_CacheWBPostSync: 2078 if (!VM_Version::supports_data_cache_line_flush()) { 2079 ret_value = false; 2080 } 2081 break; 2082 } 2083 2084 return ret_value; // Per default match rules are supported. 2085 } 2086 2087 // Identify extra cases that we might want to provide match rules for vector nodes and 2088 // other intrinsics guarded with vector length (vlen) and element type (bt). 2089 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2090 if (!match_rule_supported(opcode)) { 2091 return false; 2092 } 2093 2094 // Special cases which require vector length 2095 switch (opcode) { 2096 case Op_MulAddVS2VI: { 2097 if (vlen != 4) { 2098 return false; 2099 } 2100 break; 2101 } 2102 } 2103 2104 return true; // Per default match rules are supported. 2105 } 2106 2107 const bool Matcher::has_predicated_vectors(void) { 2108 return false; 2109 } 2110 2111 const int Matcher::float_pressure(int default_pressure_threshold) { 2112 return default_pressure_threshold; 2113 } 2114 2115 int Matcher::regnum_to_fpu_offset(int regnum) 2116 { 2117 Unimplemented(); 2118 return 0; 2119 } 2120 2121 // Is this branch offset short enough that a short branch can be used? 2122 // 2123 // NOTE: If the platform does not provide any short branch variants, then 2124 // this method should return false for offset 0. 2125 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2126 // The passed offset is relative to address of the branch. 2127 2128 return (-32768 <= offset && offset < 32768); 2129 } 2130 2131 const bool Matcher::isSimpleConstant64(jlong value) { 2132 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2133 // Probably always true, even if a temp register is required. 2134 return true; 2135 } 2136 2137 // true just means we have fast l2f conversion 2138 const bool Matcher::convL2FSupported(void) { 2139 return true; 2140 } 2141 2142 // Vector width in bytes. 2143 const int Matcher::vector_width_in_bytes(BasicType bt) { 2144 int size = MIN2(16,(int)MaxVectorSize); 2145 // Minimum 2 values in vector 2146 if (size < 2*type2aelembytes(bt)) size = 0; 2147 // But never < 4 2148 if (size < 4) size = 0; 2149 return size; 2150 } 2151 2152 // Limits on vector size (number of elements) loaded into vector. 2153 const int Matcher::max_vector_size(const BasicType bt) { 2154 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2155 } 2156 const int Matcher::min_vector_size(const BasicType bt) { 2157 // For the moment limit the vector size to 8 bytes 2158 int size = 8 / type2aelembytes(bt); 2159 if (size < 2) size = 2; 2160 return size; 2161 } 2162 2163 // Vector ideal reg. 2164 const uint Matcher::vector_ideal_reg(int len) { 2165 switch(len) { 2166 case 8: return Op_VecD; 2167 case 16: return Op_VecX; 2168 } 2169 ShouldNotReachHere(); 2170 return 0; 2171 } 2172 2173 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2174 switch(size) { 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::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_ldrvS(vecD dst, memory mem) %{ 2818 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2819 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2820 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2821 %} 2822 2823 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2824 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2825 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2826 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2827 %} 2828 2829 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2830 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2831 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2832 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2833 %} 2834 2835 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2836 FloatRegister src_reg = as_FloatRegister($src$$reg); 2837 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2838 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2839 %} 2840 2841 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2842 FloatRegister src_reg = as_FloatRegister($src$$reg); 2843 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2844 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2845 %} 2846 2847 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2848 FloatRegister src_reg = as_FloatRegister($src$$reg); 2849 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2850 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2851 %} 2852 2853 // volatile loads and stores 2854 2855 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2856 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2857 rscratch1, stlrb); 2858 %} 2859 2860 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2861 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2862 rscratch1, stlrh); 2863 %} 2864 2865 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2866 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2867 rscratch1, stlrw); 2868 %} 2869 2870 2871 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2872 Register dst_reg = as_Register($dst$$reg); 2873 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2874 rscratch1, ldarb); 2875 __ sxtbw(dst_reg, dst_reg); 2876 %} 2877 2878 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2879 Register dst_reg = as_Register($dst$$reg); 2880 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2881 rscratch1, ldarb); 2882 __ sxtb(dst_reg, dst_reg); 2883 %} 2884 2885 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2886 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2887 rscratch1, ldarb); 2888 %} 2889 2890 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2891 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2892 rscratch1, ldarb); 2893 %} 2894 2895 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2896 Register dst_reg = as_Register($dst$$reg); 2897 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2898 rscratch1, ldarh); 2899 __ sxthw(dst_reg, dst_reg); 2900 %} 2901 2902 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2903 Register dst_reg = as_Register($dst$$reg); 2904 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2905 rscratch1, ldarh); 2906 __ sxth(dst_reg, dst_reg); 2907 %} 2908 2909 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2910 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2911 rscratch1, ldarh); 2912 %} 2913 2914 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2915 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2916 rscratch1, ldarh); 2917 %} 2918 2919 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2920 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2921 rscratch1, ldarw); 2922 %} 2923 2924 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2925 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2926 rscratch1, ldarw); 2927 %} 2928 2929 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2930 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2931 rscratch1, ldar); 2932 %} 2933 2934 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2935 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2936 rscratch1, ldarw); 2937 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2938 %} 2939 2940 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2941 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2942 rscratch1, ldar); 2943 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2944 %} 2945 2946 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2947 Register src_reg = as_Register($src$$reg); 2948 // we sometimes get asked to store the stack pointer into the 2949 // current thread -- we cannot do that directly on AArch64 2950 if (src_reg == r31_sp) { 2951 C2_MacroAssembler _masm(&cbuf); 2952 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2953 __ mov(rscratch2, sp); 2954 src_reg = rscratch2; 2955 } 2956 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2957 rscratch1, stlr); 2958 %} 2959 2960 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2961 { 2962 C2_MacroAssembler _masm(&cbuf); 2963 FloatRegister src_reg = as_FloatRegister($src$$reg); 2964 __ fmovs(rscratch2, src_reg); 2965 } 2966 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2967 rscratch1, stlrw); 2968 %} 2969 2970 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2971 { 2972 C2_MacroAssembler _masm(&cbuf); 2973 FloatRegister src_reg = as_FloatRegister($src$$reg); 2974 __ fmovd(rscratch2, src_reg); 2975 } 2976 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2977 rscratch1, stlr); 2978 %} 2979 2980 // synchronized read/update encodings 2981 2982 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 2983 C2_MacroAssembler _masm(&cbuf); 2984 Register dst_reg = as_Register($dst$$reg); 2985 Register base = as_Register($mem$$base); 2986 int index = $mem$$index; 2987 int scale = $mem$$scale; 2988 int disp = $mem$$disp; 2989 if (index == -1) { 2990 if (disp != 0) { 2991 __ lea(rscratch1, Address(base, disp)); 2992 __ ldaxr(dst_reg, rscratch1); 2993 } else { 2994 // TODO 2995 // should we ever get anything other than this case? 2996 __ ldaxr(dst_reg, base); 2997 } 2998 } else { 2999 Register index_reg = as_Register(index); 3000 if (disp == 0) { 3001 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3002 __ ldaxr(dst_reg, rscratch1); 3003 } else { 3004 __ lea(rscratch1, Address(base, disp)); 3005 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3006 __ ldaxr(dst_reg, rscratch1); 3007 } 3008 } 3009 %} 3010 3011 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3012 C2_MacroAssembler _masm(&cbuf); 3013 Register src_reg = as_Register($src$$reg); 3014 Register base = as_Register($mem$$base); 3015 int index = $mem$$index; 3016 int scale = $mem$$scale; 3017 int disp = $mem$$disp; 3018 if (index == -1) { 3019 if (disp != 0) { 3020 __ lea(rscratch2, Address(base, disp)); 3021 __ stlxr(rscratch1, src_reg, rscratch2); 3022 } else { 3023 // TODO 3024 // should we ever get anything other than this case? 3025 __ stlxr(rscratch1, src_reg, base); 3026 } 3027 } else { 3028 Register index_reg = as_Register(index); 3029 if (disp == 0) { 3030 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3031 __ stlxr(rscratch1, src_reg, rscratch2); 3032 } else { 3033 __ lea(rscratch2, Address(base, disp)); 3034 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3035 __ stlxr(rscratch1, src_reg, rscratch2); 3036 } 3037 } 3038 __ cmpw(rscratch1, zr); 3039 %} 3040 3041 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3042 C2_MacroAssembler _masm(&cbuf); 3043 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3044 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3045 Assembler::xword, /*acquire*/ false, /*release*/ true, 3046 /*weak*/ false, noreg); 3047 %} 3048 3049 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3050 C2_MacroAssembler _masm(&cbuf); 3051 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3052 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3053 Assembler::word, /*acquire*/ false, /*release*/ true, 3054 /*weak*/ false, noreg); 3055 %} 3056 3057 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3058 C2_MacroAssembler _masm(&cbuf); 3059 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3060 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3061 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3062 /*weak*/ false, noreg); 3063 %} 3064 3065 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3066 C2_MacroAssembler _masm(&cbuf); 3067 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3068 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3069 Assembler::byte, /*acquire*/ false, /*release*/ true, 3070 /*weak*/ false, noreg); 3071 %} 3072 3073 3074 // The only difference between aarch64_enc_cmpxchg and 3075 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3076 // CompareAndSwap sequence to serve as a barrier on acquiring a 3077 // lock. 3078 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3079 C2_MacroAssembler _masm(&cbuf); 3080 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3081 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3082 Assembler::xword, /*acquire*/ true, /*release*/ true, 3083 /*weak*/ false, noreg); 3084 %} 3085 3086 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3087 C2_MacroAssembler _masm(&cbuf); 3088 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3089 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3090 Assembler::word, /*acquire*/ true, /*release*/ true, 3091 /*weak*/ false, noreg); 3092 %} 3093 3094 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3095 C2_MacroAssembler _masm(&cbuf); 3096 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3097 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3098 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3099 /*weak*/ false, noreg); 3100 %} 3101 3102 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3103 C2_MacroAssembler _masm(&cbuf); 3104 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3105 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3106 Assembler::byte, /*acquire*/ true, /*release*/ true, 3107 /*weak*/ false, noreg); 3108 %} 3109 3110 // auxiliary used for CompareAndSwapX to set result register 3111 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3112 C2_MacroAssembler _masm(&cbuf); 3113 Register res_reg = as_Register($res$$reg); 3114 __ cset(res_reg, Assembler::EQ); 3115 %} 3116 3117 // prefetch encodings 3118 3119 enc_class aarch64_enc_prefetchw(memory mem) %{ 3120 C2_MacroAssembler _masm(&cbuf); 3121 Register base = as_Register($mem$$base); 3122 int index = $mem$$index; 3123 int scale = $mem$$scale; 3124 int disp = $mem$$disp; 3125 if (index == -1) { 3126 __ prfm(Address(base, disp), PSTL1KEEP); 3127 } else { 3128 Register index_reg = as_Register(index); 3129 if (disp == 0) { 3130 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3131 } else { 3132 __ lea(rscratch1, Address(base, disp)); 3133 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3134 } 3135 } 3136 %} 3137 3138 /// mov envcodings 3139 3140 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3141 C2_MacroAssembler _masm(&cbuf); 3142 u_int32_t con = (u_int32_t)$src$$constant; 3143 Register dst_reg = as_Register($dst$$reg); 3144 if (con == 0) { 3145 __ movw(dst_reg, zr); 3146 } else { 3147 __ movw(dst_reg, con); 3148 } 3149 %} 3150 3151 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3152 C2_MacroAssembler _masm(&cbuf); 3153 Register dst_reg = as_Register($dst$$reg); 3154 u_int64_t con = (u_int64_t)$src$$constant; 3155 if (con == 0) { 3156 __ mov(dst_reg, zr); 3157 } else { 3158 __ mov(dst_reg, con); 3159 } 3160 %} 3161 3162 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3163 C2_MacroAssembler _masm(&cbuf); 3164 Register dst_reg = as_Register($dst$$reg); 3165 address con = (address)$src$$constant; 3166 if (con == NULL || con == (address)1) { 3167 ShouldNotReachHere(); 3168 } else { 3169 relocInfo::relocType rtype = $src->constant_reloc(); 3170 if (rtype == relocInfo::oop_type) { 3171 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3172 } else if (rtype == relocInfo::metadata_type) { 3173 __ mov_metadata(dst_reg, (Metadata*)con); 3174 } else { 3175 assert(rtype == relocInfo::none, "unexpected reloc type"); 3176 if (con < (address)(uintptr_t)os::vm_page_size()) { 3177 __ mov(dst_reg, con); 3178 } else { 3179 unsigned long offset; 3180 __ adrp(dst_reg, con, offset); 3181 __ add(dst_reg, dst_reg, offset); 3182 } 3183 } 3184 } 3185 %} 3186 3187 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3188 C2_MacroAssembler _masm(&cbuf); 3189 Register dst_reg = as_Register($dst$$reg); 3190 __ mov(dst_reg, zr); 3191 %} 3192 3193 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3194 C2_MacroAssembler _masm(&cbuf); 3195 Register dst_reg = as_Register($dst$$reg); 3196 __ mov(dst_reg, (u_int64_t)1); 3197 %} 3198 3199 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3200 C2_MacroAssembler _masm(&cbuf); 3201 __ load_byte_map_base($dst$$Register); 3202 %} 3203 3204 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3205 C2_MacroAssembler _masm(&cbuf); 3206 Register dst_reg = as_Register($dst$$reg); 3207 address con = (address)$src$$constant; 3208 if (con == NULL) { 3209 ShouldNotReachHere(); 3210 } else { 3211 relocInfo::relocType rtype = $src->constant_reloc(); 3212 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3213 __ set_narrow_oop(dst_reg, (jobject)con); 3214 } 3215 %} 3216 3217 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3218 C2_MacroAssembler _masm(&cbuf); 3219 Register dst_reg = as_Register($dst$$reg); 3220 __ mov(dst_reg, zr); 3221 %} 3222 3223 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3224 C2_MacroAssembler _masm(&cbuf); 3225 Register dst_reg = as_Register($dst$$reg); 3226 address con = (address)$src$$constant; 3227 if (con == NULL) { 3228 ShouldNotReachHere(); 3229 } else { 3230 relocInfo::relocType rtype = $src->constant_reloc(); 3231 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3232 __ set_narrow_klass(dst_reg, (Klass *)con); 3233 } 3234 %} 3235 3236 // arithmetic encodings 3237 3238 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3239 C2_MacroAssembler _masm(&cbuf); 3240 Register dst_reg = as_Register($dst$$reg); 3241 Register src_reg = as_Register($src1$$reg); 3242 int32_t con = (int32_t)$src2$$constant; 3243 // add has primary == 0, subtract has primary == 1 3244 if ($primary) { con = -con; } 3245 if (con < 0) { 3246 __ subw(dst_reg, src_reg, -con); 3247 } else { 3248 __ addw(dst_reg, src_reg, con); 3249 } 3250 %} 3251 3252 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3253 C2_MacroAssembler _masm(&cbuf); 3254 Register dst_reg = as_Register($dst$$reg); 3255 Register src_reg = as_Register($src1$$reg); 3256 int32_t con = (int32_t)$src2$$constant; 3257 // add has primary == 0, subtract has primary == 1 3258 if ($primary) { con = -con; } 3259 if (con < 0) { 3260 __ sub(dst_reg, src_reg, -con); 3261 } else { 3262 __ add(dst_reg, src_reg, con); 3263 } 3264 %} 3265 3266 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3267 C2_MacroAssembler _masm(&cbuf); 3268 Register dst_reg = as_Register($dst$$reg); 3269 Register src1_reg = as_Register($src1$$reg); 3270 Register src2_reg = as_Register($src2$$reg); 3271 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3272 %} 3273 3274 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3275 C2_MacroAssembler _masm(&cbuf); 3276 Register dst_reg = as_Register($dst$$reg); 3277 Register src1_reg = as_Register($src1$$reg); 3278 Register src2_reg = as_Register($src2$$reg); 3279 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3280 %} 3281 3282 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3283 C2_MacroAssembler _masm(&cbuf); 3284 Register dst_reg = as_Register($dst$$reg); 3285 Register src1_reg = as_Register($src1$$reg); 3286 Register src2_reg = as_Register($src2$$reg); 3287 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3288 %} 3289 3290 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3291 C2_MacroAssembler _masm(&cbuf); 3292 Register dst_reg = as_Register($dst$$reg); 3293 Register src1_reg = as_Register($src1$$reg); 3294 Register src2_reg = as_Register($src2$$reg); 3295 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3296 %} 3297 3298 // compare instruction encodings 3299 3300 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3301 C2_MacroAssembler _masm(&cbuf); 3302 Register reg1 = as_Register($src1$$reg); 3303 Register reg2 = as_Register($src2$$reg); 3304 __ cmpw(reg1, reg2); 3305 %} 3306 3307 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3308 C2_MacroAssembler _masm(&cbuf); 3309 Register reg = as_Register($src1$$reg); 3310 int32_t val = $src2$$constant; 3311 if (val >= 0) { 3312 __ subsw(zr, reg, val); 3313 } else { 3314 __ addsw(zr, reg, -val); 3315 } 3316 %} 3317 3318 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3319 C2_MacroAssembler _masm(&cbuf); 3320 Register reg1 = as_Register($src1$$reg); 3321 u_int32_t val = (u_int32_t)$src2$$constant; 3322 __ movw(rscratch1, val); 3323 __ cmpw(reg1, rscratch1); 3324 %} 3325 3326 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3327 C2_MacroAssembler _masm(&cbuf); 3328 Register reg1 = as_Register($src1$$reg); 3329 Register reg2 = as_Register($src2$$reg); 3330 __ cmp(reg1, reg2); 3331 %} 3332 3333 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3334 C2_MacroAssembler _masm(&cbuf); 3335 Register reg = as_Register($src1$$reg); 3336 int64_t val = $src2$$constant; 3337 if (val >= 0) { 3338 __ subs(zr, reg, val); 3339 } else if (val != -val) { 3340 __ adds(zr, reg, -val); 3341 } else { 3342 // aargh, Long.MIN_VALUE is a special case 3343 __ orr(rscratch1, zr, (u_int64_t)val); 3344 __ subs(zr, reg, rscratch1); 3345 } 3346 %} 3347 3348 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3349 C2_MacroAssembler _masm(&cbuf); 3350 Register reg1 = as_Register($src1$$reg); 3351 u_int64_t val = (u_int64_t)$src2$$constant; 3352 __ mov(rscratch1, val); 3353 __ cmp(reg1, rscratch1); 3354 %} 3355 3356 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3357 C2_MacroAssembler _masm(&cbuf); 3358 Register reg1 = as_Register($src1$$reg); 3359 Register reg2 = as_Register($src2$$reg); 3360 __ cmp(reg1, reg2); 3361 %} 3362 3363 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3364 C2_MacroAssembler _masm(&cbuf); 3365 Register reg1 = as_Register($src1$$reg); 3366 Register reg2 = as_Register($src2$$reg); 3367 __ cmpw(reg1, reg2); 3368 %} 3369 3370 enc_class aarch64_enc_testp(iRegP src) %{ 3371 C2_MacroAssembler _masm(&cbuf); 3372 Register reg = as_Register($src$$reg); 3373 __ cmp(reg, zr); 3374 %} 3375 3376 enc_class aarch64_enc_testn(iRegN src) %{ 3377 C2_MacroAssembler _masm(&cbuf); 3378 Register reg = as_Register($src$$reg); 3379 __ cmpw(reg, zr); 3380 %} 3381 3382 enc_class aarch64_enc_b(label lbl) %{ 3383 C2_MacroAssembler _masm(&cbuf); 3384 Label *L = $lbl$$label; 3385 __ b(*L); 3386 %} 3387 3388 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3389 C2_MacroAssembler _masm(&cbuf); 3390 Label *L = $lbl$$label; 3391 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3392 %} 3393 3394 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3395 C2_MacroAssembler _masm(&cbuf); 3396 Label *L = $lbl$$label; 3397 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3398 %} 3399 3400 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3401 %{ 3402 Register sub_reg = as_Register($sub$$reg); 3403 Register super_reg = as_Register($super$$reg); 3404 Register temp_reg = as_Register($temp$$reg); 3405 Register result_reg = as_Register($result$$reg); 3406 3407 Label miss; 3408 C2_MacroAssembler _masm(&cbuf); 3409 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3410 NULL, &miss, 3411 /*set_cond_codes:*/ true); 3412 if ($primary) { 3413 __ mov(result_reg, zr); 3414 } 3415 __ bind(miss); 3416 %} 3417 3418 enc_class aarch64_enc_java_static_call(method meth) %{ 3419 C2_MacroAssembler _masm(&cbuf); 3420 3421 address addr = (address)$meth$$method; 3422 address call; 3423 if (!_method) { 3424 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3425 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3426 } else { 3427 int method_index = resolved_method_index(cbuf); 3428 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3429 : static_call_Relocation::spec(method_index); 3430 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3431 3432 // Emit stub for static call 3433 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3434 if (stub == NULL) { 3435 ciEnv::current()->record_failure("CodeCache is full"); 3436 return; 3437 } 3438 } 3439 if (call == NULL) { 3440 ciEnv::current()->record_failure("CodeCache is full"); 3441 return; 3442 } 3443 %} 3444 3445 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3446 C2_MacroAssembler _masm(&cbuf); 3447 int method_index = resolved_method_index(cbuf); 3448 address call = __ ic_call((address)$meth$$method, method_index); 3449 if (call == NULL) { 3450 ciEnv::current()->record_failure("CodeCache is full"); 3451 return; 3452 } 3453 %} 3454 3455 enc_class aarch64_enc_call_epilog() %{ 3456 C2_MacroAssembler _masm(&cbuf); 3457 if (VerifyStackAtCalls) { 3458 // Check that stack depth is unchanged: find majik cookie on stack 3459 __ call_Unimplemented(); 3460 } 3461 %} 3462 3463 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3464 C2_MacroAssembler _masm(&cbuf); 3465 3466 // some calls to generated routines (arraycopy code) are scheduled 3467 // by C2 as runtime calls. if so we can call them using a br (they 3468 // will be in a reachable segment) otherwise we have to use a blr 3469 // which loads the absolute address into a register. 3470 address entry = (address)$meth$$method; 3471 CodeBlob *cb = CodeCache::find_blob(entry); 3472 if (cb) { 3473 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3474 if (call == NULL) { 3475 ciEnv::current()->record_failure("CodeCache is full"); 3476 return; 3477 } 3478 } else { 3479 Label retaddr; 3480 __ adr(rscratch2, retaddr); 3481 __ lea(rscratch1, RuntimeAddress(entry)); 3482 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3483 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3484 __ blr(rscratch1); 3485 __ bind(retaddr); 3486 __ add(sp, sp, 2 * wordSize); 3487 } 3488 %} 3489 3490 enc_class aarch64_enc_rethrow() %{ 3491 C2_MacroAssembler _masm(&cbuf); 3492 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3493 %} 3494 3495 enc_class aarch64_enc_ret() %{ 3496 C2_MacroAssembler _masm(&cbuf); 3497 __ ret(lr); 3498 %} 3499 3500 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3501 C2_MacroAssembler _masm(&cbuf); 3502 Register target_reg = as_Register($jump_target$$reg); 3503 __ br(target_reg); 3504 %} 3505 3506 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3507 C2_MacroAssembler _masm(&cbuf); 3508 Register target_reg = as_Register($jump_target$$reg); 3509 // exception oop should be in r0 3510 // ret addr has been popped into lr 3511 // callee expects it in r3 3512 __ mov(r3, lr); 3513 __ br(target_reg); 3514 %} 3515 3516 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3517 C2_MacroAssembler _masm(&cbuf); 3518 Register oop = as_Register($object$$reg); 3519 Register box = as_Register($box$$reg); 3520 Register disp_hdr = as_Register($tmp$$reg); 3521 Register tmp = as_Register($tmp2$$reg); 3522 Label cont; 3523 Label object_has_monitor; 3524 Label cas_failed; 3525 3526 assert_different_registers(oop, box, tmp, disp_hdr); 3527 3528 // Load markWord from object into displaced_header. 3529 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3530 3531 if (UseBiasedLocking && !UseOptoBiasInlining) { 3532 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3533 } 3534 3535 // Check for existing monitor 3536 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3537 3538 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3539 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3540 3541 // Initialize the box. (Must happen before we update the object mark!) 3542 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3543 3544 // Compare object markWord with an unlocked value (tmp) and if 3545 // equal exchange the stack address of our box with object markWord. 3546 // On failure disp_hdr contains the possibly locked markWord. 3547 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3548 /*release*/ true, /*weak*/ false, disp_hdr); 3549 __ br(Assembler::EQ, cont); 3550 3551 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3552 3553 // If the compare-and-exchange succeeded, then we found an unlocked 3554 // object, will have now locked it will continue at label cont 3555 3556 __ bind(cas_failed); 3557 // We did not see an unlocked object so try the fast recursive case. 3558 3559 // Check if the owner is self by comparing the value in the 3560 // markWord of object (disp_hdr) with the stack pointer. 3561 __ mov(rscratch1, sp); 3562 __ sub(disp_hdr, disp_hdr, rscratch1); 3563 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3564 // If condition is true we are cont and hence we can store 0 as the 3565 // displaced header in the box, which indicates that it is a recursive lock. 3566 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3567 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3568 3569 __ b(cont); 3570 3571 // Handle existing monitor. 3572 __ bind(object_has_monitor); 3573 3574 // The object's monitor m is unlocked iff m->owner == NULL, 3575 // otherwise m->owner may contain a thread or a stack address. 3576 // 3577 // Try to CAS m->owner from NULL to current thread. 3578 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3579 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3580 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3581 3582 // Store a non-null value into the box to avoid looking like a re-entrant 3583 // lock. The fast-path monitor unlock code checks for 3584 // markWord::monitor_value so use markWord::unused_mark which has the 3585 // relevant bit set, and also matches ObjectSynchronizer::enter. 3586 __ mov(tmp, (address)markWord::unused_mark().value()); 3587 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3588 3589 __ bind(cont); 3590 // flag == EQ indicates success 3591 // flag == NE indicates failure 3592 %} 3593 3594 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3595 C2_MacroAssembler _masm(&cbuf); 3596 Register oop = as_Register($object$$reg); 3597 Register box = as_Register($box$$reg); 3598 Register disp_hdr = as_Register($tmp$$reg); 3599 Register tmp = as_Register($tmp2$$reg); 3600 Label cont; 3601 Label object_has_monitor; 3602 3603 assert_different_registers(oop, box, tmp, disp_hdr); 3604 3605 if (UseBiasedLocking && !UseOptoBiasInlining) { 3606 __ biased_locking_exit(oop, tmp, cont); 3607 } 3608 3609 // Find the lock address and load the displaced header from the stack. 3610 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3611 3612 // If the displaced header is 0, we have a recursive unlock. 3613 __ cmp(disp_hdr, zr); 3614 __ br(Assembler::EQ, cont); 3615 3616 // Handle existing monitor. 3617 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3618 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3619 3620 // Check if it is still a light weight lock, this is is true if we 3621 // see the stack address of the basicLock in the markWord of the 3622 // object. 3623 3624 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3625 /*release*/ true, /*weak*/ false, tmp); 3626 __ b(cont); 3627 3628 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3629 3630 // Handle existing monitor. 3631 __ bind(object_has_monitor); 3632 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3633 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3634 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3635 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3636 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3637 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3638 __ cmp(rscratch1, zr); // Sets flags for result 3639 __ br(Assembler::NE, cont); 3640 3641 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3642 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3643 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3644 __ cmp(rscratch1, zr); // Sets flags for result 3645 __ cbnz(rscratch1, cont); 3646 // need a release store here 3647 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3648 __ stlr(zr, tmp); // set unowned 3649 3650 __ bind(cont); 3651 // flag == EQ indicates success 3652 // flag == NE indicates failure 3653 %} 3654 3655 %} 3656 3657 //----------FRAME-------------------------------------------------------------- 3658 // Definition of frame structure and management information. 3659 // 3660 // S T A C K L A Y O U T Allocators stack-slot number 3661 // | (to get allocators register number 3662 // G Owned by | | v add OptoReg::stack0()) 3663 // r CALLER | | 3664 // o | +--------+ pad to even-align allocators stack-slot 3665 // w V | pad0 | numbers; owned by CALLER 3666 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3667 // h ^ | in | 5 3668 // | | args | 4 Holes in incoming args owned by SELF 3669 // | | | | 3 3670 // | | +--------+ 3671 // V | | old out| Empty on Intel, window on Sparc 3672 // | old |preserve| Must be even aligned. 3673 // | SP-+--------+----> Matcher::_old_SP, even aligned 3674 // | | in | 3 area for Intel ret address 3675 // Owned by |preserve| Empty on Sparc. 3676 // SELF +--------+ 3677 // | | pad2 | 2 pad to align old SP 3678 // | +--------+ 1 3679 // | | locks | 0 3680 // | +--------+----> OptoReg::stack0(), even aligned 3681 // | | pad1 | 11 pad to align new SP 3682 // | +--------+ 3683 // | | | 10 3684 // | | spills | 9 spills 3685 // V | | 8 (pad0 slot for callee) 3686 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3687 // ^ | out | 7 3688 // | | args | 6 Holes in outgoing args owned by CALLEE 3689 // Owned by +--------+ 3690 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3691 // | new |preserve| Must be even-aligned. 3692 // | SP-+--------+----> Matcher::_new_SP, even aligned 3693 // | | | 3694 // 3695 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3696 // known from SELF's arguments and the Java calling convention. 3697 // Region 6-7 is determined per call site. 3698 // Note 2: If the calling convention leaves holes in the incoming argument 3699 // area, those holes are owned by SELF. Holes in the outgoing area 3700 // are owned by the CALLEE. Holes should not be nessecary in the 3701 // incoming area, as the Java calling convention is completely under 3702 // the control of the AD file. Doubles can be sorted and packed to 3703 // avoid holes. Holes in the outgoing arguments may be nessecary for 3704 // varargs C calling conventions. 3705 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3706 // even aligned with pad0 as needed. 3707 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3708 // (the latter is true on Intel but is it false on AArch64?) 3709 // region 6-11 is even aligned; it may be padded out more so that 3710 // the region from SP to FP meets the minimum stack alignment. 3711 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3712 // alignment. Region 11, pad1, may be dynamically extended so that 3713 // SP meets the minimum alignment. 3714 3715 frame %{ 3716 // What direction does stack grow in (assumed to be same for C & Java) 3717 stack_direction(TOWARDS_LOW); 3718 3719 // These three registers define part of the calling convention 3720 // between compiled code and the interpreter. 3721 3722 // Inline Cache Register or methodOop for I2C. 3723 inline_cache_reg(R12); 3724 3725 // Method Oop Register when calling interpreter. 3726 interpreter_method_oop_reg(R12); 3727 3728 // Number of stack slots consumed by locking an object 3729 sync_stack_slots(2); 3730 3731 // Compiled code's Frame Pointer 3732 frame_pointer(R31); 3733 3734 // Interpreter stores its frame pointer in a register which is 3735 // stored to the stack by I2CAdaptors. 3736 // I2CAdaptors convert from interpreted java to compiled java. 3737 interpreter_frame_pointer(R29); 3738 3739 // Stack alignment requirement 3740 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3741 3742 // Number of stack slots between incoming argument block and the start of 3743 // a new frame. The PROLOG must add this many slots to the stack. The 3744 // EPILOG must remove this many slots. aarch64 needs two slots for 3745 // return address and fp. 3746 // TODO think this is correct but check 3747 in_preserve_stack_slots(4); 3748 3749 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3750 // for calls to C. Supports the var-args backing area for register parms. 3751 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3752 3753 // The after-PROLOG location of the return address. Location of 3754 // return address specifies a type (REG or STACK) and a number 3755 // representing the register number (i.e. - use a register name) or 3756 // stack slot. 3757 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3758 // Otherwise, it is above the locks and verification slot and alignment word 3759 // TODO this may well be correct but need to check why that - 2 is there 3760 // ppc port uses 0 but we definitely need to allow for fixed_slots 3761 // which folds in the space used for monitors 3762 return_addr(STACK - 2 + 3763 align_up((Compile::current()->in_preserve_stack_slots() + 3764 Compile::current()->fixed_slots()), 3765 stack_alignment_in_slots())); 3766 3767 // Body of function which returns an integer array locating 3768 // arguments either in registers or in stack slots. Passed an array 3769 // of ideal registers called "sig" and a "length" count. Stack-slot 3770 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3771 // arguments for a CALLEE. Incoming stack arguments are 3772 // automatically biased by the preserve_stack_slots field above. 3773 3774 calling_convention 3775 %{ 3776 // No difference between ingoing/outgoing just pass false 3777 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3778 %} 3779 3780 c_calling_convention 3781 %{ 3782 // This is obviously always outgoing 3783 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3784 %} 3785 3786 // Location of compiled Java return values. Same as C for now. 3787 return_value 3788 %{ 3789 // TODO do we allow ideal_reg == Op_RegN??? 3790 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3791 "only return normal values"); 3792 3793 static const int lo[Op_RegL + 1] = { // enum name 3794 0, // Op_Node 3795 0, // Op_Set 3796 R0_num, // Op_RegN 3797 R0_num, // Op_RegI 3798 R0_num, // Op_RegP 3799 V0_num, // Op_RegF 3800 V0_num, // Op_RegD 3801 R0_num // Op_RegL 3802 }; 3803 3804 static const int hi[Op_RegL + 1] = { // enum name 3805 0, // Op_Node 3806 0, // Op_Set 3807 OptoReg::Bad, // Op_RegN 3808 OptoReg::Bad, // Op_RegI 3809 R0_H_num, // Op_RegP 3810 OptoReg::Bad, // Op_RegF 3811 V0_H_num, // Op_RegD 3812 R0_H_num // Op_RegL 3813 }; 3814 3815 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3816 %} 3817 %} 3818 3819 //----------ATTRIBUTES--------------------------------------------------------- 3820 //----------Operand Attributes------------------------------------------------- 3821 op_attrib op_cost(1); // Required cost attribute 3822 3823 //----------Instruction Attributes--------------------------------------------- 3824 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3825 ins_attrib ins_size(32); // Required size attribute (in bits) 3826 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3827 // a non-matching short branch variant 3828 // of some long branch? 3829 ins_attrib ins_alignment(4); // Required alignment attribute (must 3830 // be a power of 2) specifies the 3831 // alignment that some part of the 3832 // instruction (not necessarily the 3833 // start) requires. If > 1, a 3834 // compute_padding() function must be 3835 // provided for the instruction 3836 3837 //----------OPERANDS----------------------------------------------------------- 3838 // Operand definitions must precede instruction definitions for correct parsing 3839 // in the ADLC because operands constitute user defined types which are used in 3840 // instruction definitions. 3841 3842 //----------Simple Operands---------------------------------------------------- 3843 3844 // Integer operands 32 bit 3845 // 32 bit immediate 3846 operand immI() 3847 %{ 3848 match(ConI); 3849 3850 op_cost(0); 3851 format %{ %} 3852 interface(CONST_INTER); 3853 %} 3854 3855 // 32 bit zero 3856 operand immI0() 3857 %{ 3858 predicate(n->get_int() == 0); 3859 match(ConI); 3860 3861 op_cost(0); 3862 format %{ %} 3863 interface(CONST_INTER); 3864 %} 3865 3866 // 32 bit unit increment 3867 operand immI_1() 3868 %{ 3869 predicate(n->get_int() == 1); 3870 match(ConI); 3871 3872 op_cost(0); 3873 format %{ %} 3874 interface(CONST_INTER); 3875 %} 3876 3877 // 32 bit unit decrement 3878 operand immI_M1() 3879 %{ 3880 predicate(n->get_int() == -1); 3881 match(ConI); 3882 3883 op_cost(0); 3884 format %{ %} 3885 interface(CONST_INTER); 3886 %} 3887 3888 // Shift values for add/sub extension shift 3889 operand immIExt() 3890 %{ 3891 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3892 match(ConI); 3893 3894 op_cost(0); 3895 format %{ %} 3896 interface(CONST_INTER); 3897 %} 3898 3899 operand immI_le_4() 3900 %{ 3901 predicate(n->get_int() <= 4); 3902 match(ConI); 3903 3904 op_cost(0); 3905 format %{ %} 3906 interface(CONST_INTER); 3907 %} 3908 3909 operand immI_31() 3910 %{ 3911 predicate(n->get_int() == 31); 3912 match(ConI); 3913 3914 op_cost(0); 3915 format %{ %} 3916 interface(CONST_INTER); 3917 %} 3918 3919 operand immI_8() 3920 %{ 3921 predicate(n->get_int() == 8); 3922 match(ConI); 3923 3924 op_cost(0); 3925 format %{ %} 3926 interface(CONST_INTER); 3927 %} 3928 3929 operand immI_16() 3930 %{ 3931 predicate(n->get_int() == 16); 3932 match(ConI); 3933 3934 op_cost(0); 3935 format %{ %} 3936 interface(CONST_INTER); 3937 %} 3938 3939 operand immI_24() 3940 %{ 3941 predicate(n->get_int() == 24); 3942 match(ConI); 3943 3944 op_cost(0); 3945 format %{ %} 3946 interface(CONST_INTER); 3947 %} 3948 3949 operand immI_32() 3950 %{ 3951 predicate(n->get_int() == 32); 3952 match(ConI); 3953 3954 op_cost(0); 3955 format %{ %} 3956 interface(CONST_INTER); 3957 %} 3958 3959 operand immI_48() 3960 %{ 3961 predicate(n->get_int() == 48); 3962 match(ConI); 3963 3964 op_cost(0); 3965 format %{ %} 3966 interface(CONST_INTER); 3967 %} 3968 3969 operand immI_56() 3970 %{ 3971 predicate(n->get_int() == 56); 3972 match(ConI); 3973 3974 op_cost(0); 3975 format %{ %} 3976 interface(CONST_INTER); 3977 %} 3978 3979 operand immI_63() 3980 %{ 3981 predicate(n->get_int() == 63); 3982 match(ConI); 3983 3984 op_cost(0); 3985 format %{ %} 3986 interface(CONST_INTER); 3987 %} 3988 3989 operand immI_64() 3990 %{ 3991 predicate(n->get_int() == 64); 3992 match(ConI); 3993 3994 op_cost(0); 3995 format %{ %} 3996 interface(CONST_INTER); 3997 %} 3998 3999 operand immI_255() 4000 %{ 4001 predicate(n->get_int() == 255); 4002 match(ConI); 4003 4004 op_cost(0); 4005 format %{ %} 4006 interface(CONST_INTER); 4007 %} 4008 4009 operand immI_65535() 4010 %{ 4011 predicate(n->get_int() == 65535); 4012 match(ConI); 4013 4014 op_cost(0); 4015 format %{ %} 4016 interface(CONST_INTER); 4017 %} 4018 4019 operand immL_255() 4020 %{ 4021 predicate(n->get_long() == 255L); 4022 match(ConL); 4023 4024 op_cost(0); 4025 format %{ %} 4026 interface(CONST_INTER); 4027 %} 4028 4029 operand immL_65535() 4030 %{ 4031 predicate(n->get_long() == 65535L); 4032 match(ConL); 4033 4034 op_cost(0); 4035 format %{ %} 4036 interface(CONST_INTER); 4037 %} 4038 4039 operand immL_4294967295() 4040 %{ 4041 predicate(n->get_long() == 4294967295L); 4042 match(ConL); 4043 4044 op_cost(0); 4045 format %{ %} 4046 interface(CONST_INTER); 4047 %} 4048 4049 operand immL_bitmask() 4050 %{ 4051 predicate((n->get_long() != 0) 4052 && ((n->get_long() & 0xc000000000000000l) == 0) 4053 && is_power_of_2(n->get_long() + 1)); 4054 match(ConL); 4055 4056 op_cost(0); 4057 format %{ %} 4058 interface(CONST_INTER); 4059 %} 4060 4061 operand immI_bitmask() 4062 %{ 4063 predicate((n->get_int() != 0) 4064 && ((n->get_int() & 0xc0000000) == 0) 4065 && is_power_of_2(n->get_int() + 1)); 4066 match(ConI); 4067 4068 op_cost(0); 4069 format %{ %} 4070 interface(CONST_INTER); 4071 %} 4072 4073 // Scale values for scaled offset addressing modes (up to long but not quad) 4074 operand immIScale() 4075 %{ 4076 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4077 match(ConI); 4078 4079 op_cost(0); 4080 format %{ %} 4081 interface(CONST_INTER); 4082 %} 4083 4084 // 26 bit signed offset -- for pc-relative branches 4085 operand immI26() 4086 %{ 4087 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4088 match(ConI); 4089 4090 op_cost(0); 4091 format %{ %} 4092 interface(CONST_INTER); 4093 %} 4094 4095 // 19 bit signed offset -- for pc-relative loads 4096 operand immI19() 4097 %{ 4098 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4099 match(ConI); 4100 4101 op_cost(0); 4102 format %{ %} 4103 interface(CONST_INTER); 4104 %} 4105 4106 // 12 bit unsigned offset -- for base plus immediate loads 4107 operand immIU12() 4108 %{ 4109 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4110 match(ConI); 4111 4112 op_cost(0); 4113 format %{ %} 4114 interface(CONST_INTER); 4115 %} 4116 4117 operand immLU12() 4118 %{ 4119 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4120 match(ConL); 4121 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125 %} 4126 4127 // Offset for scaled or unscaled immediate loads and stores 4128 operand immIOffset() 4129 %{ 4130 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4131 match(ConI); 4132 4133 op_cost(0); 4134 format %{ %} 4135 interface(CONST_INTER); 4136 %} 4137 4138 operand immIOffset1() 4139 %{ 4140 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4141 match(ConI); 4142 4143 op_cost(0); 4144 format %{ %} 4145 interface(CONST_INTER); 4146 %} 4147 4148 operand immIOffset2() 4149 %{ 4150 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4151 match(ConI); 4152 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 operand immIOffset4() 4159 %{ 4160 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4161 match(ConI); 4162 4163 op_cost(0); 4164 format %{ %} 4165 interface(CONST_INTER); 4166 %} 4167 4168 operand immIOffset8() 4169 %{ 4170 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4171 match(ConI); 4172 4173 op_cost(0); 4174 format %{ %} 4175 interface(CONST_INTER); 4176 %} 4177 4178 operand immIOffset16() 4179 %{ 4180 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4181 match(ConI); 4182 4183 op_cost(0); 4184 format %{ %} 4185 interface(CONST_INTER); 4186 %} 4187 4188 operand immLoffset() 4189 %{ 4190 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4191 match(ConL); 4192 4193 op_cost(0); 4194 format %{ %} 4195 interface(CONST_INTER); 4196 %} 4197 4198 operand immLoffset1() 4199 %{ 4200 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4201 match(ConL); 4202 4203 op_cost(0); 4204 format %{ %} 4205 interface(CONST_INTER); 4206 %} 4207 4208 operand immLoffset2() 4209 %{ 4210 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4211 match(ConL); 4212 4213 op_cost(0); 4214 format %{ %} 4215 interface(CONST_INTER); 4216 %} 4217 4218 operand immLoffset4() 4219 %{ 4220 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4221 match(ConL); 4222 4223 op_cost(0); 4224 format %{ %} 4225 interface(CONST_INTER); 4226 %} 4227 4228 operand immLoffset8() 4229 %{ 4230 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4231 match(ConL); 4232 4233 op_cost(0); 4234 format %{ %} 4235 interface(CONST_INTER); 4236 %} 4237 4238 operand immLoffset16() 4239 %{ 4240 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4241 match(ConL); 4242 4243 op_cost(0); 4244 format %{ %} 4245 interface(CONST_INTER); 4246 %} 4247 4248 // 32 bit integer valid for add sub immediate 4249 operand immIAddSub() 4250 %{ 4251 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4252 match(ConI); 4253 op_cost(0); 4254 format %{ %} 4255 interface(CONST_INTER); 4256 %} 4257 4258 // 32 bit unsigned integer valid for logical immediate 4259 // TODO -- check this is right when e.g the mask is 0x80000000 4260 operand immILog() 4261 %{ 4262 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4263 match(ConI); 4264 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 // Integer operands 64 bit 4271 // 64 bit immediate 4272 operand immL() 4273 %{ 4274 match(ConL); 4275 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // 64 bit zero 4282 operand immL0() 4283 %{ 4284 predicate(n->get_long() == 0); 4285 match(ConL); 4286 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 // 64 bit unit increment 4293 operand immL_1() 4294 %{ 4295 predicate(n->get_long() == 1); 4296 match(ConL); 4297 4298 op_cost(0); 4299 format %{ %} 4300 interface(CONST_INTER); 4301 %} 4302 4303 // 64 bit unit decrement 4304 operand immL_M1() 4305 %{ 4306 predicate(n->get_long() == -1); 4307 match(ConL); 4308 4309 op_cost(0); 4310 format %{ %} 4311 interface(CONST_INTER); 4312 %} 4313 4314 // 32 bit offset of pc in thread anchor 4315 4316 operand immL_pc_off() 4317 %{ 4318 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4319 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4320 match(ConL); 4321 4322 op_cost(0); 4323 format %{ %} 4324 interface(CONST_INTER); 4325 %} 4326 4327 // 64 bit integer valid for add sub immediate 4328 operand immLAddSub() 4329 %{ 4330 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4331 match(ConL); 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // 64 bit integer valid for logical immediate 4338 operand immLLog() 4339 %{ 4340 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4341 match(ConL); 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Long Immediate: low 32-bit mask 4348 operand immL_32bits() 4349 %{ 4350 predicate(n->get_long() == 0xFFFFFFFFL); 4351 match(ConL); 4352 op_cost(0); 4353 format %{ %} 4354 interface(CONST_INTER); 4355 %} 4356 4357 // Pointer operands 4358 // Pointer Immediate 4359 operand immP() 4360 %{ 4361 match(ConP); 4362 4363 op_cost(0); 4364 format %{ %} 4365 interface(CONST_INTER); 4366 %} 4367 4368 // NULL Pointer Immediate 4369 operand immP0() 4370 %{ 4371 predicate(n->get_ptr() == 0); 4372 match(ConP); 4373 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 // Pointer Immediate One 4380 // this is used in object initialization (initial object header) 4381 operand immP_1() 4382 %{ 4383 predicate(n->get_ptr() == 1); 4384 match(ConP); 4385 4386 op_cost(0); 4387 format %{ %} 4388 interface(CONST_INTER); 4389 %} 4390 4391 // Card Table Byte Map Base 4392 operand immByteMapBase() 4393 %{ 4394 // Get base of card map 4395 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4396 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4397 match(ConP); 4398 4399 op_cost(0); 4400 format %{ %} 4401 interface(CONST_INTER); 4402 %} 4403 4404 // Pointer Immediate Minus One 4405 // this is used when we want to write the current PC to the thread anchor 4406 operand immP_M1() 4407 %{ 4408 predicate(n->get_ptr() == -1); 4409 match(ConP); 4410 4411 op_cost(0); 4412 format %{ %} 4413 interface(CONST_INTER); 4414 %} 4415 4416 // Pointer Immediate Minus Two 4417 // this is used when we want to write the current PC to the thread anchor 4418 operand immP_M2() 4419 %{ 4420 predicate(n->get_ptr() == -2); 4421 match(ConP); 4422 4423 op_cost(0); 4424 format %{ %} 4425 interface(CONST_INTER); 4426 %} 4427 4428 // Float and Double operands 4429 // Double Immediate 4430 operand immD() 4431 %{ 4432 match(ConD); 4433 op_cost(0); 4434 format %{ %} 4435 interface(CONST_INTER); 4436 %} 4437 4438 // Double Immediate: +0.0d 4439 operand immD0() 4440 %{ 4441 predicate(jlong_cast(n->getd()) == 0); 4442 match(ConD); 4443 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447 %} 4448 4449 // constant 'double +0.0'. 4450 operand immDPacked() 4451 %{ 4452 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4453 match(ConD); 4454 op_cost(0); 4455 format %{ %} 4456 interface(CONST_INTER); 4457 %} 4458 4459 // Float Immediate 4460 operand immF() 4461 %{ 4462 match(ConF); 4463 op_cost(0); 4464 format %{ %} 4465 interface(CONST_INTER); 4466 %} 4467 4468 // Float Immediate: +0.0f. 4469 operand immF0() 4470 %{ 4471 predicate(jint_cast(n->getf()) == 0); 4472 match(ConF); 4473 4474 op_cost(0); 4475 format %{ %} 4476 interface(CONST_INTER); 4477 %} 4478 4479 // 4480 operand immFPacked() 4481 %{ 4482 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4483 match(ConF); 4484 op_cost(0); 4485 format %{ %} 4486 interface(CONST_INTER); 4487 %} 4488 4489 // Narrow pointer operands 4490 // Narrow Pointer Immediate 4491 operand immN() 4492 %{ 4493 match(ConN); 4494 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // Narrow NULL Pointer Immediate 4501 operand immN0() 4502 %{ 4503 predicate(n->get_narrowcon() == 0); 4504 match(ConN); 4505 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 operand immNKlass() 4512 %{ 4513 match(ConNKlass); 4514 4515 op_cost(0); 4516 format %{ %} 4517 interface(CONST_INTER); 4518 %} 4519 4520 // Integer 32 bit Register Operands 4521 // Integer 32 bitRegister (excludes SP) 4522 operand iRegI() 4523 %{ 4524 constraint(ALLOC_IN_RC(any_reg32)); 4525 match(RegI); 4526 match(iRegINoSp); 4527 op_cost(0); 4528 format %{ %} 4529 interface(REG_INTER); 4530 %} 4531 4532 // Integer 32 bit Register not Special 4533 operand iRegINoSp() 4534 %{ 4535 constraint(ALLOC_IN_RC(no_special_reg32)); 4536 match(RegI); 4537 op_cost(0); 4538 format %{ %} 4539 interface(REG_INTER); 4540 %} 4541 4542 // Integer 64 bit Register Operands 4543 // Integer 64 bit Register (includes SP) 4544 operand iRegL() 4545 %{ 4546 constraint(ALLOC_IN_RC(any_reg)); 4547 match(RegL); 4548 match(iRegLNoSp); 4549 op_cost(0); 4550 format %{ %} 4551 interface(REG_INTER); 4552 %} 4553 4554 // Integer 64 bit Register not Special 4555 operand iRegLNoSp() 4556 %{ 4557 constraint(ALLOC_IN_RC(no_special_reg)); 4558 match(RegL); 4559 match(iRegL_R0); 4560 format %{ %} 4561 interface(REG_INTER); 4562 %} 4563 4564 // Pointer Register Operands 4565 // Pointer Register 4566 operand iRegP() 4567 %{ 4568 constraint(ALLOC_IN_RC(ptr_reg)); 4569 match(RegP); 4570 match(iRegPNoSp); 4571 match(iRegP_R0); 4572 //match(iRegP_R2); 4573 //match(iRegP_R4); 4574 //match(iRegP_R5); 4575 match(thread_RegP); 4576 op_cost(0); 4577 format %{ %} 4578 interface(REG_INTER); 4579 %} 4580 4581 // Pointer 64 bit Register not Special 4582 operand iRegPNoSp() 4583 %{ 4584 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4585 match(RegP); 4586 // match(iRegP); 4587 // match(iRegP_R0); 4588 // match(iRegP_R2); 4589 // match(iRegP_R4); 4590 // match(iRegP_R5); 4591 // match(thread_RegP); 4592 op_cost(0); 4593 format %{ %} 4594 interface(REG_INTER); 4595 %} 4596 4597 // Pointer 64 bit Register R0 only 4598 operand iRegP_R0() 4599 %{ 4600 constraint(ALLOC_IN_RC(r0_reg)); 4601 match(RegP); 4602 // match(iRegP); 4603 match(iRegPNoSp); 4604 op_cost(0); 4605 format %{ %} 4606 interface(REG_INTER); 4607 %} 4608 4609 // Pointer 64 bit Register R1 only 4610 operand iRegP_R1() 4611 %{ 4612 constraint(ALLOC_IN_RC(r1_reg)); 4613 match(RegP); 4614 // match(iRegP); 4615 match(iRegPNoSp); 4616 op_cost(0); 4617 format %{ %} 4618 interface(REG_INTER); 4619 %} 4620 4621 // Pointer 64 bit Register R2 only 4622 operand iRegP_R2() 4623 %{ 4624 constraint(ALLOC_IN_RC(r2_reg)); 4625 match(RegP); 4626 // match(iRegP); 4627 match(iRegPNoSp); 4628 op_cost(0); 4629 format %{ %} 4630 interface(REG_INTER); 4631 %} 4632 4633 // Pointer 64 bit Register R3 only 4634 operand iRegP_R3() 4635 %{ 4636 constraint(ALLOC_IN_RC(r3_reg)); 4637 match(RegP); 4638 // match(iRegP); 4639 match(iRegPNoSp); 4640 op_cost(0); 4641 format %{ %} 4642 interface(REG_INTER); 4643 %} 4644 4645 // Pointer 64 bit Register R4 only 4646 operand iRegP_R4() 4647 %{ 4648 constraint(ALLOC_IN_RC(r4_reg)); 4649 match(RegP); 4650 // match(iRegP); 4651 match(iRegPNoSp); 4652 op_cost(0); 4653 format %{ %} 4654 interface(REG_INTER); 4655 %} 4656 4657 // Pointer 64 bit Register R5 only 4658 operand iRegP_R5() 4659 %{ 4660 constraint(ALLOC_IN_RC(r5_reg)); 4661 match(RegP); 4662 // match(iRegP); 4663 match(iRegPNoSp); 4664 op_cost(0); 4665 format %{ %} 4666 interface(REG_INTER); 4667 %} 4668 4669 // Pointer 64 bit Register R10 only 4670 operand iRegP_R10() 4671 %{ 4672 constraint(ALLOC_IN_RC(r10_reg)); 4673 match(RegP); 4674 // match(iRegP); 4675 match(iRegPNoSp); 4676 op_cost(0); 4677 format %{ %} 4678 interface(REG_INTER); 4679 %} 4680 4681 // Long 64 bit Register R0 only 4682 operand iRegL_R0() 4683 %{ 4684 constraint(ALLOC_IN_RC(r0_reg)); 4685 match(RegL); 4686 match(iRegLNoSp); 4687 op_cost(0); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 // Long 64 bit Register R2 only 4693 operand iRegL_R2() 4694 %{ 4695 constraint(ALLOC_IN_RC(r2_reg)); 4696 match(RegL); 4697 match(iRegLNoSp); 4698 op_cost(0); 4699 format %{ %} 4700 interface(REG_INTER); 4701 %} 4702 4703 // Long 64 bit Register R3 only 4704 operand iRegL_R3() 4705 %{ 4706 constraint(ALLOC_IN_RC(r3_reg)); 4707 match(RegL); 4708 match(iRegLNoSp); 4709 op_cost(0); 4710 format %{ %} 4711 interface(REG_INTER); 4712 %} 4713 4714 // Long 64 bit Register R11 only 4715 operand iRegL_R11() 4716 %{ 4717 constraint(ALLOC_IN_RC(r11_reg)); 4718 match(RegL); 4719 match(iRegLNoSp); 4720 op_cost(0); 4721 format %{ %} 4722 interface(REG_INTER); 4723 %} 4724 4725 // Pointer 64 bit Register FP only 4726 operand iRegP_FP() 4727 %{ 4728 constraint(ALLOC_IN_RC(fp_reg)); 4729 match(RegP); 4730 // match(iRegP); 4731 op_cost(0); 4732 format %{ %} 4733 interface(REG_INTER); 4734 %} 4735 4736 // Register R0 only 4737 operand iRegI_R0() 4738 %{ 4739 constraint(ALLOC_IN_RC(int_r0_reg)); 4740 match(RegI); 4741 match(iRegINoSp); 4742 op_cost(0); 4743 format %{ %} 4744 interface(REG_INTER); 4745 %} 4746 4747 // Register R2 only 4748 operand iRegI_R2() 4749 %{ 4750 constraint(ALLOC_IN_RC(int_r2_reg)); 4751 match(RegI); 4752 match(iRegINoSp); 4753 op_cost(0); 4754 format %{ %} 4755 interface(REG_INTER); 4756 %} 4757 4758 // Register R3 only 4759 operand iRegI_R3() 4760 %{ 4761 constraint(ALLOC_IN_RC(int_r3_reg)); 4762 match(RegI); 4763 match(iRegINoSp); 4764 op_cost(0); 4765 format %{ %} 4766 interface(REG_INTER); 4767 %} 4768 4769 4770 // Register R4 only 4771 operand iRegI_R4() 4772 %{ 4773 constraint(ALLOC_IN_RC(int_r4_reg)); 4774 match(RegI); 4775 match(iRegINoSp); 4776 op_cost(0); 4777 format %{ %} 4778 interface(REG_INTER); 4779 %} 4780 4781 4782 // Pointer Register Operands 4783 // Narrow Pointer Register 4784 operand iRegN() 4785 %{ 4786 constraint(ALLOC_IN_RC(any_reg32)); 4787 match(RegN); 4788 match(iRegNNoSp); 4789 op_cost(0); 4790 format %{ %} 4791 interface(REG_INTER); 4792 %} 4793 4794 operand iRegN_R0() 4795 %{ 4796 constraint(ALLOC_IN_RC(r0_reg)); 4797 match(iRegN); 4798 op_cost(0); 4799 format %{ %} 4800 interface(REG_INTER); 4801 %} 4802 4803 operand iRegN_R2() 4804 %{ 4805 constraint(ALLOC_IN_RC(r2_reg)); 4806 match(iRegN); 4807 op_cost(0); 4808 format %{ %} 4809 interface(REG_INTER); 4810 %} 4811 4812 operand iRegN_R3() 4813 %{ 4814 constraint(ALLOC_IN_RC(r3_reg)); 4815 match(iRegN); 4816 op_cost(0); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 // Integer 64 bit Register not Special 4822 operand iRegNNoSp() 4823 %{ 4824 constraint(ALLOC_IN_RC(no_special_reg32)); 4825 match(RegN); 4826 op_cost(0); 4827 format %{ %} 4828 interface(REG_INTER); 4829 %} 4830 4831 // heap base register -- used for encoding immN0 4832 4833 operand iRegIHeapbase() 4834 %{ 4835 constraint(ALLOC_IN_RC(heapbase_reg)); 4836 match(RegI); 4837 op_cost(0); 4838 format %{ %} 4839 interface(REG_INTER); 4840 %} 4841 4842 // Float Register 4843 // Float register operands 4844 operand vRegF() 4845 %{ 4846 constraint(ALLOC_IN_RC(float_reg)); 4847 match(RegF); 4848 4849 op_cost(0); 4850 format %{ %} 4851 interface(REG_INTER); 4852 %} 4853 4854 // Double Register 4855 // Double register operands 4856 operand vRegD() 4857 %{ 4858 constraint(ALLOC_IN_RC(double_reg)); 4859 match(RegD); 4860 4861 op_cost(0); 4862 format %{ %} 4863 interface(REG_INTER); 4864 %} 4865 4866 operand vecD() 4867 %{ 4868 constraint(ALLOC_IN_RC(vectord_reg)); 4869 match(VecD); 4870 4871 op_cost(0); 4872 format %{ %} 4873 interface(REG_INTER); 4874 %} 4875 4876 operand vecX() 4877 %{ 4878 constraint(ALLOC_IN_RC(vectorx_reg)); 4879 match(VecX); 4880 4881 op_cost(0); 4882 format %{ %} 4883 interface(REG_INTER); 4884 %} 4885 4886 operand vRegD_V0() 4887 %{ 4888 constraint(ALLOC_IN_RC(v0_reg)); 4889 match(RegD); 4890 op_cost(0); 4891 format %{ %} 4892 interface(REG_INTER); 4893 %} 4894 4895 operand vRegD_V1() 4896 %{ 4897 constraint(ALLOC_IN_RC(v1_reg)); 4898 match(RegD); 4899 op_cost(0); 4900 format %{ %} 4901 interface(REG_INTER); 4902 %} 4903 4904 operand vRegD_V2() 4905 %{ 4906 constraint(ALLOC_IN_RC(v2_reg)); 4907 match(RegD); 4908 op_cost(0); 4909 format %{ %} 4910 interface(REG_INTER); 4911 %} 4912 4913 operand vRegD_V3() 4914 %{ 4915 constraint(ALLOC_IN_RC(v3_reg)); 4916 match(RegD); 4917 op_cost(0); 4918 format %{ %} 4919 interface(REG_INTER); 4920 %} 4921 4922 operand vRegD_V4() 4923 %{ 4924 constraint(ALLOC_IN_RC(v4_reg)); 4925 match(RegD); 4926 op_cost(0); 4927 format %{ %} 4928 interface(REG_INTER); 4929 %} 4930 4931 operand vRegD_V5() 4932 %{ 4933 constraint(ALLOC_IN_RC(v5_reg)); 4934 match(RegD); 4935 op_cost(0); 4936 format %{ %} 4937 interface(REG_INTER); 4938 %} 4939 4940 operand vRegD_V6() 4941 %{ 4942 constraint(ALLOC_IN_RC(v6_reg)); 4943 match(RegD); 4944 op_cost(0); 4945 format %{ %} 4946 interface(REG_INTER); 4947 %} 4948 4949 operand vRegD_V7() 4950 %{ 4951 constraint(ALLOC_IN_RC(v7_reg)); 4952 match(RegD); 4953 op_cost(0); 4954 format %{ %} 4955 interface(REG_INTER); 4956 %} 4957 4958 operand vRegD_V8() 4959 %{ 4960 constraint(ALLOC_IN_RC(v8_reg)); 4961 match(RegD); 4962 op_cost(0); 4963 format %{ %} 4964 interface(REG_INTER); 4965 %} 4966 4967 operand vRegD_V9() 4968 %{ 4969 constraint(ALLOC_IN_RC(v9_reg)); 4970 match(RegD); 4971 op_cost(0); 4972 format %{ %} 4973 interface(REG_INTER); 4974 %} 4975 4976 operand vRegD_V10() 4977 %{ 4978 constraint(ALLOC_IN_RC(v10_reg)); 4979 match(RegD); 4980 op_cost(0); 4981 format %{ %} 4982 interface(REG_INTER); 4983 %} 4984 4985 operand vRegD_V11() 4986 %{ 4987 constraint(ALLOC_IN_RC(v11_reg)); 4988 match(RegD); 4989 op_cost(0); 4990 format %{ %} 4991 interface(REG_INTER); 4992 %} 4993 4994 operand vRegD_V12() 4995 %{ 4996 constraint(ALLOC_IN_RC(v12_reg)); 4997 match(RegD); 4998 op_cost(0); 4999 format %{ %} 5000 interface(REG_INTER); 5001 %} 5002 5003 operand vRegD_V13() 5004 %{ 5005 constraint(ALLOC_IN_RC(v13_reg)); 5006 match(RegD); 5007 op_cost(0); 5008 format %{ %} 5009 interface(REG_INTER); 5010 %} 5011 5012 operand vRegD_V14() 5013 %{ 5014 constraint(ALLOC_IN_RC(v14_reg)); 5015 match(RegD); 5016 op_cost(0); 5017 format %{ %} 5018 interface(REG_INTER); 5019 %} 5020 5021 operand vRegD_V15() 5022 %{ 5023 constraint(ALLOC_IN_RC(v15_reg)); 5024 match(RegD); 5025 op_cost(0); 5026 format %{ %} 5027 interface(REG_INTER); 5028 %} 5029 5030 operand vRegD_V16() 5031 %{ 5032 constraint(ALLOC_IN_RC(v16_reg)); 5033 match(RegD); 5034 op_cost(0); 5035 format %{ %} 5036 interface(REG_INTER); 5037 %} 5038 5039 operand vRegD_V17() 5040 %{ 5041 constraint(ALLOC_IN_RC(v17_reg)); 5042 match(RegD); 5043 op_cost(0); 5044 format %{ %} 5045 interface(REG_INTER); 5046 %} 5047 5048 operand vRegD_V18() 5049 %{ 5050 constraint(ALLOC_IN_RC(v18_reg)); 5051 match(RegD); 5052 op_cost(0); 5053 format %{ %} 5054 interface(REG_INTER); 5055 %} 5056 5057 operand vRegD_V19() 5058 %{ 5059 constraint(ALLOC_IN_RC(v19_reg)); 5060 match(RegD); 5061 op_cost(0); 5062 format %{ %} 5063 interface(REG_INTER); 5064 %} 5065 5066 operand vRegD_V20() 5067 %{ 5068 constraint(ALLOC_IN_RC(v20_reg)); 5069 match(RegD); 5070 op_cost(0); 5071 format %{ %} 5072 interface(REG_INTER); 5073 %} 5074 5075 operand vRegD_V21() 5076 %{ 5077 constraint(ALLOC_IN_RC(v21_reg)); 5078 match(RegD); 5079 op_cost(0); 5080 format %{ %} 5081 interface(REG_INTER); 5082 %} 5083 5084 operand vRegD_V22() 5085 %{ 5086 constraint(ALLOC_IN_RC(v22_reg)); 5087 match(RegD); 5088 op_cost(0); 5089 format %{ %} 5090 interface(REG_INTER); 5091 %} 5092 5093 operand vRegD_V23() 5094 %{ 5095 constraint(ALLOC_IN_RC(v23_reg)); 5096 match(RegD); 5097 op_cost(0); 5098 format %{ %} 5099 interface(REG_INTER); 5100 %} 5101 5102 operand vRegD_V24() 5103 %{ 5104 constraint(ALLOC_IN_RC(v24_reg)); 5105 match(RegD); 5106 op_cost(0); 5107 format %{ %} 5108 interface(REG_INTER); 5109 %} 5110 5111 operand vRegD_V25() 5112 %{ 5113 constraint(ALLOC_IN_RC(v25_reg)); 5114 match(RegD); 5115 op_cost(0); 5116 format %{ %} 5117 interface(REG_INTER); 5118 %} 5119 5120 operand vRegD_V26() 5121 %{ 5122 constraint(ALLOC_IN_RC(v26_reg)); 5123 match(RegD); 5124 op_cost(0); 5125 format %{ %} 5126 interface(REG_INTER); 5127 %} 5128 5129 operand vRegD_V27() 5130 %{ 5131 constraint(ALLOC_IN_RC(v27_reg)); 5132 match(RegD); 5133 op_cost(0); 5134 format %{ %} 5135 interface(REG_INTER); 5136 %} 5137 5138 operand vRegD_V28() 5139 %{ 5140 constraint(ALLOC_IN_RC(v28_reg)); 5141 match(RegD); 5142 op_cost(0); 5143 format %{ %} 5144 interface(REG_INTER); 5145 %} 5146 5147 operand vRegD_V29() 5148 %{ 5149 constraint(ALLOC_IN_RC(v29_reg)); 5150 match(RegD); 5151 op_cost(0); 5152 format %{ %} 5153 interface(REG_INTER); 5154 %} 5155 5156 operand vRegD_V30() 5157 %{ 5158 constraint(ALLOC_IN_RC(v30_reg)); 5159 match(RegD); 5160 op_cost(0); 5161 format %{ %} 5162 interface(REG_INTER); 5163 %} 5164 5165 operand vRegD_V31() 5166 %{ 5167 constraint(ALLOC_IN_RC(v31_reg)); 5168 match(RegD); 5169 op_cost(0); 5170 format %{ %} 5171 interface(REG_INTER); 5172 %} 5173 5174 // Flags register, used as output of signed compare instructions 5175 5176 // note that on AArch64 we also use this register as the output for 5177 // for floating point compare instructions (CmpF CmpD). this ensures 5178 // that ordered inequality tests use GT, GE, LT or LE none of which 5179 // pass through cases where the result is unordered i.e. one or both 5180 // inputs to the compare is a NaN. this means that the ideal code can 5181 // replace e.g. a GT with an LE and not end up capturing the NaN case 5182 // (where the comparison should always fail). EQ and NE tests are 5183 // always generated in ideal code so that unordered folds into the NE 5184 // case, matching the behaviour of AArch64 NE. 5185 // 5186 // This differs from x86 where the outputs of FP compares use a 5187 // special FP flags registers and where compares based on this 5188 // register are distinguished into ordered inequalities (cmpOpUCF) and 5189 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5190 // to explicitly handle the unordered case in branches. x86 also has 5191 // to include extra CMoveX rules to accept a cmpOpUCF input. 5192 5193 operand rFlagsReg() 5194 %{ 5195 constraint(ALLOC_IN_RC(int_flags)); 5196 match(RegFlags); 5197 5198 op_cost(0); 5199 format %{ "RFLAGS" %} 5200 interface(REG_INTER); 5201 %} 5202 5203 // Flags register, used as output of unsigned compare instructions 5204 operand rFlagsRegU() 5205 %{ 5206 constraint(ALLOC_IN_RC(int_flags)); 5207 match(RegFlags); 5208 5209 op_cost(0); 5210 format %{ "RFLAGSU" %} 5211 interface(REG_INTER); 5212 %} 5213 5214 // Special Registers 5215 5216 // Method Register 5217 operand inline_cache_RegP(iRegP reg) 5218 %{ 5219 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5220 match(reg); 5221 match(iRegPNoSp); 5222 op_cost(0); 5223 format %{ %} 5224 interface(REG_INTER); 5225 %} 5226 5227 operand interpreter_method_oop_RegP(iRegP reg) 5228 %{ 5229 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5230 match(reg); 5231 match(iRegPNoSp); 5232 op_cost(0); 5233 format %{ %} 5234 interface(REG_INTER); 5235 %} 5236 5237 // Thread Register 5238 operand thread_RegP(iRegP reg) 5239 %{ 5240 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5241 match(reg); 5242 op_cost(0); 5243 format %{ %} 5244 interface(REG_INTER); 5245 %} 5246 5247 operand lr_RegP(iRegP reg) 5248 %{ 5249 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5250 match(reg); 5251 op_cost(0); 5252 format %{ %} 5253 interface(REG_INTER); 5254 %} 5255 5256 //----------Memory Operands---------------------------------------------------- 5257 5258 operand indirect(iRegP reg) 5259 %{ 5260 constraint(ALLOC_IN_RC(ptr_reg)); 5261 match(reg); 5262 op_cost(0); 5263 format %{ "[$reg]" %} 5264 interface(MEMORY_INTER) %{ 5265 base($reg); 5266 index(0xffffffff); 5267 scale(0x0); 5268 disp(0x0); 5269 %} 5270 %} 5271 5272 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5273 %{ 5274 constraint(ALLOC_IN_RC(ptr_reg)); 5275 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5276 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5277 op_cost(0); 5278 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5279 interface(MEMORY_INTER) %{ 5280 base($reg); 5281 index($ireg); 5282 scale($scale); 5283 disp(0x0); 5284 %} 5285 %} 5286 5287 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5288 %{ 5289 constraint(ALLOC_IN_RC(ptr_reg)); 5290 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5291 match(AddP reg (LShiftL lreg scale)); 5292 op_cost(0); 5293 format %{ "$reg, $lreg lsl($scale)" %} 5294 interface(MEMORY_INTER) %{ 5295 base($reg); 5296 index($lreg); 5297 scale($scale); 5298 disp(0x0); 5299 %} 5300 %} 5301 5302 operand indIndexI2L(iRegP reg, iRegI ireg) 5303 %{ 5304 constraint(ALLOC_IN_RC(ptr_reg)); 5305 match(AddP reg (ConvI2L ireg)); 5306 op_cost(0); 5307 format %{ "$reg, $ireg, 0, I2L" %} 5308 interface(MEMORY_INTER) %{ 5309 base($reg); 5310 index($ireg); 5311 scale(0x0); 5312 disp(0x0); 5313 %} 5314 %} 5315 5316 operand indIndex(iRegP reg, iRegL lreg) 5317 %{ 5318 constraint(ALLOC_IN_RC(ptr_reg)); 5319 match(AddP reg lreg); 5320 op_cost(0); 5321 format %{ "$reg, $lreg" %} 5322 interface(MEMORY_INTER) %{ 5323 base($reg); 5324 index($lreg); 5325 scale(0x0); 5326 disp(0x0); 5327 %} 5328 %} 5329 5330 operand indOffI(iRegP reg, immIOffset off) 5331 %{ 5332 constraint(ALLOC_IN_RC(ptr_reg)); 5333 match(AddP reg off); 5334 op_cost(0); 5335 format %{ "[$reg, $off]" %} 5336 interface(MEMORY_INTER) %{ 5337 base($reg); 5338 index(0xffffffff); 5339 scale(0x0); 5340 disp($off); 5341 %} 5342 %} 5343 5344 operand indOffI1(iRegP reg, immIOffset1 off) 5345 %{ 5346 constraint(ALLOC_IN_RC(ptr_reg)); 5347 match(AddP reg off); 5348 op_cost(0); 5349 format %{ "[$reg, $off]" %} 5350 interface(MEMORY_INTER) %{ 5351 base($reg); 5352 index(0xffffffff); 5353 scale(0x0); 5354 disp($off); 5355 %} 5356 %} 5357 5358 operand indOffI2(iRegP reg, immIOffset2 off) 5359 %{ 5360 constraint(ALLOC_IN_RC(ptr_reg)); 5361 match(AddP reg off); 5362 op_cost(0); 5363 format %{ "[$reg, $off]" %} 5364 interface(MEMORY_INTER) %{ 5365 base($reg); 5366 index(0xffffffff); 5367 scale(0x0); 5368 disp($off); 5369 %} 5370 %} 5371 5372 operand indOffI4(iRegP reg, immIOffset4 off) 5373 %{ 5374 constraint(ALLOC_IN_RC(ptr_reg)); 5375 match(AddP reg off); 5376 op_cost(0); 5377 format %{ "[$reg, $off]" %} 5378 interface(MEMORY_INTER) %{ 5379 base($reg); 5380 index(0xffffffff); 5381 scale(0x0); 5382 disp($off); 5383 %} 5384 %} 5385 5386 operand indOffI8(iRegP reg, immIOffset8 off) 5387 %{ 5388 constraint(ALLOC_IN_RC(ptr_reg)); 5389 match(AddP reg off); 5390 op_cost(0); 5391 format %{ "[$reg, $off]" %} 5392 interface(MEMORY_INTER) %{ 5393 base($reg); 5394 index(0xffffffff); 5395 scale(0x0); 5396 disp($off); 5397 %} 5398 %} 5399 5400 operand indOffI16(iRegP reg, immIOffset16 off) 5401 %{ 5402 constraint(ALLOC_IN_RC(ptr_reg)); 5403 match(AddP reg off); 5404 op_cost(0); 5405 format %{ "[$reg, $off]" %} 5406 interface(MEMORY_INTER) %{ 5407 base($reg); 5408 index(0xffffffff); 5409 scale(0x0); 5410 disp($off); 5411 %} 5412 %} 5413 5414 operand indOffL(iRegP reg, immLoffset off) 5415 %{ 5416 constraint(ALLOC_IN_RC(ptr_reg)); 5417 match(AddP reg off); 5418 op_cost(0); 5419 format %{ "[$reg, $off]" %} 5420 interface(MEMORY_INTER) %{ 5421 base($reg); 5422 index(0xffffffff); 5423 scale(0x0); 5424 disp($off); 5425 %} 5426 %} 5427 5428 operand indOffL1(iRegP reg, immLoffset1 off) 5429 %{ 5430 constraint(ALLOC_IN_RC(ptr_reg)); 5431 match(AddP reg off); 5432 op_cost(0); 5433 format %{ "[$reg, $off]" %} 5434 interface(MEMORY_INTER) %{ 5435 base($reg); 5436 index(0xffffffff); 5437 scale(0x0); 5438 disp($off); 5439 %} 5440 %} 5441 5442 operand indOffL2(iRegP reg, immLoffset2 off) 5443 %{ 5444 constraint(ALLOC_IN_RC(ptr_reg)); 5445 match(AddP reg off); 5446 op_cost(0); 5447 format %{ "[$reg, $off]" %} 5448 interface(MEMORY_INTER) %{ 5449 base($reg); 5450 index(0xffffffff); 5451 scale(0x0); 5452 disp($off); 5453 %} 5454 %} 5455 5456 operand indOffL4(iRegP reg, immLoffset4 off) 5457 %{ 5458 constraint(ALLOC_IN_RC(ptr_reg)); 5459 match(AddP reg off); 5460 op_cost(0); 5461 format %{ "[$reg, $off]" %} 5462 interface(MEMORY_INTER) %{ 5463 base($reg); 5464 index(0xffffffff); 5465 scale(0x0); 5466 disp($off); 5467 %} 5468 %} 5469 5470 operand indOffL8(iRegP reg, immLoffset8 off) 5471 %{ 5472 constraint(ALLOC_IN_RC(ptr_reg)); 5473 match(AddP reg off); 5474 op_cost(0); 5475 format %{ "[$reg, $off]" %} 5476 interface(MEMORY_INTER) %{ 5477 base($reg); 5478 index(0xffffffff); 5479 scale(0x0); 5480 disp($off); 5481 %} 5482 %} 5483 5484 operand indOffL16(iRegP reg, immLoffset16 off) 5485 %{ 5486 constraint(ALLOC_IN_RC(ptr_reg)); 5487 match(AddP reg off); 5488 op_cost(0); 5489 format %{ "[$reg, $off]" %} 5490 interface(MEMORY_INTER) %{ 5491 base($reg); 5492 index(0xffffffff); 5493 scale(0x0); 5494 disp($off); 5495 %} 5496 %} 5497 5498 operand indirectN(iRegN reg) 5499 %{ 5500 predicate(CompressedOops::shift() == 0); 5501 constraint(ALLOC_IN_RC(ptr_reg)); 5502 match(DecodeN reg); 5503 op_cost(0); 5504 format %{ "[$reg]\t# narrow" %} 5505 interface(MEMORY_INTER) %{ 5506 base($reg); 5507 index(0xffffffff); 5508 scale(0x0); 5509 disp(0x0); 5510 %} 5511 %} 5512 5513 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5514 %{ 5515 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5516 constraint(ALLOC_IN_RC(ptr_reg)); 5517 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5518 op_cost(0); 5519 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5520 interface(MEMORY_INTER) %{ 5521 base($reg); 5522 index($ireg); 5523 scale($scale); 5524 disp(0x0); 5525 %} 5526 %} 5527 5528 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5529 %{ 5530 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5531 constraint(ALLOC_IN_RC(ptr_reg)); 5532 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5533 op_cost(0); 5534 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5535 interface(MEMORY_INTER) %{ 5536 base($reg); 5537 index($lreg); 5538 scale($scale); 5539 disp(0x0); 5540 %} 5541 %} 5542 5543 operand indIndexI2LN(iRegN reg, iRegI ireg) 5544 %{ 5545 predicate(CompressedOops::shift() == 0); 5546 constraint(ALLOC_IN_RC(ptr_reg)); 5547 match(AddP (DecodeN reg) (ConvI2L ireg)); 5548 op_cost(0); 5549 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5550 interface(MEMORY_INTER) %{ 5551 base($reg); 5552 index($ireg); 5553 scale(0x0); 5554 disp(0x0); 5555 %} 5556 %} 5557 5558 operand indIndexN(iRegN reg, iRegL lreg) 5559 %{ 5560 predicate(CompressedOops::shift() == 0); 5561 constraint(ALLOC_IN_RC(ptr_reg)); 5562 match(AddP (DecodeN reg) lreg); 5563 op_cost(0); 5564 format %{ "$reg, $lreg\t# narrow" %} 5565 interface(MEMORY_INTER) %{ 5566 base($reg); 5567 index($lreg); 5568 scale(0x0); 5569 disp(0x0); 5570 %} 5571 %} 5572 5573 operand indOffIN(iRegN reg, immIOffset off) 5574 %{ 5575 predicate(CompressedOops::shift() == 0); 5576 constraint(ALLOC_IN_RC(ptr_reg)); 5577 match(AddP (DecodeN reg) off); 5578 op_cost(0); 5579 format %{ "[$reg, $off]\t# narrow" %} 5580 interface(MEMORY_INTER) %{ 5581 base($reg); 5582 index(0xffffffff); 5583 scale(0x0); 5584 disp($off); 5585 %} 5586 %} 5587 5588 operand indOffLN(iRegN reg, immLoffset off) 5589 %{ 5590 predicate(CompressedOops::shift() == 0); 5591 constraint(ALLOC_IN_RC(ptr_reg)); 5592 match(AddP (DecodeN reg) off); 5593 op_cost(0); 5594 format %{ "[$reg, $off]\t# narrow" %} 5595 interface(MEMORY_INTER) %{ 5596 base($reg); 5597 index(0xffffffff); 5598 scale(0x0); 5599 disp($off); 5600 %} 5601 %} 5602 5603 5604 5605 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5606 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5607 %{ 5608 constraint(ALLOC_IN_RC(ptr_reg)); 5609 match(AddP reg off); 5610 op_cost(0); 5611 format %{ "[$reg, $off]" %} 5612 interface(MEMORY_INTER) %{ 5613 base($reg); 5614 index(0xffffffff); 5615 scale(0x0); 5616 disp($off); 5617 %} 5618 %} 5619 5620 //----------Special Memory Operands-------------------------------------------- 5621 // Stack Slot Operand - This operand is used for loading and storing temporary 5622 // values on the stack where a match requires a value to 5623 // flow through memory. 5624 operand stackSlotP(sRegP reg) 5625 %{ 5626 constraint(ALLOC_IN_RC(stack_slots)); 5627 op_cost(100); 5628 // No match rule because this operand is only generated in matching 5629 // match(RegP); 5630 format %{ "[$reg]" %} 5631 interface(MEMORY_INTER) %{ 5632 base(0x1e); // RSP 5633 index(0x0); // No Index 5634 scale(0x0); // No Scale 5635 disp($reg); // Stack Offset 5636 %} 5637 %} 5638 5639 operand stackSlotI(sRegI reg) 5640 %{ 5641 constraint(ALLOC_IN_RC(stack_slots)); 5642 // No match rule because this operand is only generated in matching 5643 // match(RegI); 5644 format %{ "[$reg]" %} 5645 interface(MEMORY_INTER) %{ 5646 base(0x1e); // RSP 5647 index(0x0); // No Index 5648 scale(0x0); // No Scale 5649 disp($reg); // Stack Offset 5650 %} 5651 %} 5652 5653 operand stackSlotF(sRegF reg) 5654 %{ 5655 constraint(ALLOC_IN_RC(stack_slots)); 5656 // No match rule because this operand is only generated in matching 5657 // match(RegF); 5658 format %{ "[$reg]" %} 5659 interface(MEMORY_INTER) %{ 5660 base(0x1e); // RSP 5661 index(0x0); // No Index 5662 scale(0x0); // No Scale 5663 disp($reg); // Stack Offset 5664 %} 5665 %} 5666 5667 operand stackSlotD(sRegD reg) 5668 %{ 5669 constraint(ALLOC_IN_RC(stack_slots)); 5670 // No match rule because this operand is only generated in matching 5671 // match(RegD); 5672 format %{ "[$reg]" %} 5673 interface(MEMORY_INTER) %{ 5674 base(0x1e); // RSP 5675 index(0x0); // No Index 5676 scale(0x0); // No Scale 5677 disp($reg); // Stack Offset 5678 %} 5679 %} 5680 5681 operand stackSlotL(sRegL reg) 5682 %{ 5683 constraint(ALLOC_IN_RC(stack_slots)); 5684 // No match rule because this operand is only generated in matching 5685 // match(RegL); 5686 format %{ "[$reg]" %} 5687 interface(MEMORY_INTER) %{ 5688 base(0x1e); // RSP 5689 index(0x0); // No Index 5690 scale(0x0); // No Scale 5691 disp($reg); // Stack Offset 5692 %} 5693 %} 5694 5695 // Operands for expressing Control Flow 5696 // NOTE: Label is a predefined operand which should not be redefined in 5697 // the AD file. It is generically handled within the ADLC. 5698 5699 //----------Conditional Branch Operands---------------------------------------- 5700 // Comparison Op - This is the operation of the comparison, and is limited to 5701 // the following set of codes: 5702 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5703 // 5704 // Other attributes of the comparison, such as unsignedness, are specified 5705 // by the comparison instruction that sets a condition code flags register. 5706 // That result is represented by a flags operand whose subtype is appropriate 5707 // to the unsignedness (etc.) of the comparison. 5708 // 5709 // Later, the instruction which matches both the Comparison Op (a Bool) and 5710 // the flags (produced by the Cmp) specifies the coding of the comparison op 5711 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5712 5713 // used for signed integral comparisons and fp comparisons 5714 5715 operand cmpOp() 5716 %{ 5717 match(Bool); 5718 5719 format %{ "" %} 5720 interface(COND_INTER) %{ 5721 equal(0x0, "eq"); 5722 not_equal(0x1, "ne"); 5723 less(0xb, "lt"); 5724 greater_equal(0xa, "ge"); 5725 less_equal(0xd, "le"); 5726 greater(0xc, "gt"); 5727 overflow(0x6, "vs"); 5728 no_overflow(0x7, "vc"); 5729 %} 5730 %} 5731 5732 // used for unsigned integral comparisons 5733 5734 operand cmpOpU() 5735 %{ 5736 match(Bool); 5737 5738 format %{ "" %} 5739 interface(COND_INTER) %{ 5740 equal(0x0, "eq"); 5741 not_equal(0x1, "ne"); 5742 less(0x3, "lo"); 5743 greater_equal(0x2, "hs"); 5744 less_equal(0x9, "ls"); 5745 greater(0x8, "hi"); 5746 overflow(0x6, "vs"); 5747 no_overflow(0x7, "vc"); 5748 %} 5749 %} 5750 5751 // used for certain integral comparisons which can be 5752 // converted to cbxx or tbxx instructions 5753 5754 operand cmpOpEqNe() 5755 %{ 5756 match(Bool); 5757 op_cost(0); 5758 predicate(n->as_Bool()->_test._test == BoolTest::ne 5759 || n->as_Bool()->_test._test == BoolTest::eq); 5760 5761 format %{ "" %} 5762 interface(COND_INTER) %{ 5763 equal(0x0, "eq"); 5764 not_equal(0x1, "ne"); 5765 less(0xb, "lt"); 5766 greater_equal(0xa, "ge"); 5767 less_equal(0xd, "le"); 5768 greater(0xc, "gt"); 5769 overflow(0x6, "vs"); 5770 no_overflow(0x7, "vc"); 5771 %} 5772 %} 5773 5774 // used for certain integral comparisons which can be 5775 // converted to cbxx or tbxx instructions 5776 5777 operand cmpOpLtGe() 5778 %{ 5779 match(Bool); 5780 op_cost(0); 5781 5782 predicate(n->as_Bool()->_test._test == BoolTest::lt 5783 || n->as_Bool()->_test._test == BoolTest::ge); 5784 5785 format %{ "" %} 5786 interface(COND_INTER) %{ 5787 equal(0x0, "eq"); 5788 not_equal(0x1, "ne"); 5789 less(0xb, "lt"); 5790 greater_equal(0xa, "ge"); 5791 less_equal(0xd, "le"); 5792 greater(0xc, "gt"); 5793 overflow(0x6, "vs"); 5794 no_overflow(0x7, "vc"); 5795 %} 5796 %} 5797 5798 // used for certain unsigned integral comparisons which can be 5799 // converted to cbxx or tbxx instructions 5800 5801 operand cmpOpUEqNeLtGe() 5802 %{ 5803 match(Bool); 5804 op_cost(0); 5805 5806 predicate(n->as_Bool()->_test._test == BoolTest::eq 5807 || n->as_Bool()->_test._test == BoolTest::ne 5808 || n->as_Bool()->_test._test == BoolTest::lt 5809 || n->as_Bool()->_test._test == BoolTest::ge); 5810 5811 format %{ "" %} 5812 interface(COND_INTER) %{ 5813 equal(0x0, "eq"); 5814 not_equal(0x1, "ne"); 5815 less(0xb, "lt"); 5816 greater_equal(0xa, "ge"); 5817 less_equal(0xd, "le"); 5818 greater(0xc, "gt"); 5819 overflow(0x6, "vs"); 5820 no_overflow(0x7, "vc"); 5821 %} 5822 %} 5823 5824 // Special operand allowing long args to int ops to be truncated for free 5825 5826 operand iRegL2I(iRegL reg) %{ 5827 5828 op_cost(0); 5829 5830 match(ConvL2I reg); 5831 5832 format %{ "l2i($reg)" %} 5833 5834 interface(REG_INTER) 5835 %} 5836 5837 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5838 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5839 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5840 5841 //----------OPERAND CLASSES---------------------------------------------------- 5842 // Operand Classes are groups of operands that are used as to simplify 5843 // instruction definitions by not requiring the AD writer to specify 5844 // separate instructions for every form of operand when the 5845 // instruction accepts multiple operand types with the same basic 5846 // encoding and format. The classic case of this is memory operands. 5847 5848 // memory is used to define read/write location for load/store 5849 // instruction defs. we can turn a memory op into an Address 5850 5851 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5852 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5853 5854 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5855 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5856 5857 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5858 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5859 5860 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5861 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5862 5863 // All of the memory operands. For the pipeline description. 5864 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5865 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5866 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5867 5868 5869 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5870 // operations. it allows the src to be either an iRegI or a (ConvL2I 5871 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5872 // can be elided because the 32-bit instruction will just employ the 5873 // lower 32 bits anyway. 5874 // 5875 // n.b. this does not elide all L2I conversions. if the truncated 5876 // value is consumed by more than one operation then the ConvL2I 5877 // cannot be bundled into the consuming nodes so an l2i gets planted 5878 // (actually a movw $dst $src) and the downstream instructions consume 5879 // the result of the l2i as an iRegI input. That's a shame since the 5880 // movw is actually redundant but its not too costly. 5881 5882 opclass iRegIorL2I(iRegI, iRegL2I); 5883 5884 //----------PIPELINE----------------------------------------------------------- 5885 // Rules which define the behavior of the target architectures pipeline. 5886 5887 // For specific pipelines, eg A53, define the stages of that pipeline 5888 //pipe_desc(ISS, EX1, EX2, WR); 5889 #define ISS S0 5890 #define EX1 S1 5891 #define EX2 S2 5892 #define WR S3 5893 5894 // Integer ALU reg operation 5895 pipeline %{ 5896 5897 attributes %{ 5898 // ARM instructions are of fixed length 5899 fixed_size_instructions; // Fixed size instructions TODO does 5900 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5901 // ARM instructions come in 32-bit word units 5902 instruction_unit_size = 4; // An instruction is 4 bytes long 5903 instruction_fetch_unit_size = 64; // The processor fetches one line 5904 instruction_fetch_units = 1; // of 64 bytes 5905 5906 // List of nop instructions 5907 nops( MachNop ); 5908 %} 5909 5910 // We don't use an actual pipeline model so don't care about resources 5911 // or description. we do use pipeline classes to introduce fixed 5912 // latencies 5913 5914 //----------RESOURCES---------------------------------------------------------- 5915 // Resources are the functional units available to the machine 5916 5917 resources( INS0, INS1, INS01 = INS0 | INS1, 5918 ALU0, ALU1, ALU = ALU0 | ALU1, 5919 MAC, 5920 DIV, 5921 BRANCH, 5922 LDST, 5923 NEON_FP); 5924 5925 //----------PIPELINE DESCRIPTION----------------------------------------------- 5926 // Pipeline Description specifies the stages in the machine's pipeline 5927 5928 // Define the pipeline as a generic 6 stage pipeline 5929 pipe_desc(S0, S1, S2, S3, S4, S5); 5930 5931 //----------PIPELINE CLASSES--------------------------------------------------- 5932 // Pipeline Classes describe the stages in which input and output are 5933 // referenced by the hardware pipeline. 5934 5935 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5936 %{ 5937 single_instruction; 5938 src1 : S1(read); 5939 src2 : S2(read); 5940 dst : S5(write); 5941 INS01 : ISS; 5942 NEON_FP : S5; 5943 %} 5944 5945 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5946 %{ 5947 single_instruction; 5948 src1 : S1(read); 5949 src2 : S2(read); 5950 dst : S5(write); 5951 INS01 : ISS; 5952 NEON_FP : S5; 5953 %} 5954 5955 pipe_class fp_uop_s(vRegF dst, vRegF src) 5956 %{ 5957 single_instruction; 5958 src : S1(read); 5959 dst : S5(write); 5960 INS01 : ISS; 5961 NEON_FP : S5; 5962 %} 5963 5964 pipe_class fp_uop_d(vRegD dst, vRegD src) 5965 %{ 5966 single_instruction; 5967 src : S1(read); 5968 dst : S5(write); 5969 INS01 : ISS; 5970 NEON_FP : S5; 5971 %} 5972 5973 pipe_class fp_d2f(vRegF dst, vRegD src) 5974 %{ 5975 single_instruction; 5976 src : S1(read); 5977 dst : S5(write); 5978 INS01 : ISS; 5979 NEON_FP : S5; 5980 %} 5981 5982 pipe_class fp_f2d(vRegD dst, vRegF src) 5983 %{ 5984 single_instruction; 5985 src : S1(read); 5986 dst : S5(write); 5987 INS01 : ISS; 5988 NEON_FP : S5; 5989 %} 5990 5991 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5992 %{ 5993 single_instruction; 5994 src : S1(read); 5995 dst : S5(write); 5996 INS01 : ISS; 5997 NEON_FP : S5; 5998 %} 5999 6000 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6001 %{ 6002 single_instruction; 6003 src : S1(read); 6004 dst : S5(write); 6005 INS01 : ISS; 6006 NEON_FP : S5; 6007 %} 6008 6009 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6010 %{ 6011 single_instruction; 6012 src : S1(read); 6013 dst : S5(write); 6014 INS01 : ISS; 6015 NEON_FP : S5; 6016 %} 6017 6018 pipe_class fp_l2f(vRegF dst, iRegL src) 6019 %{ 6020 single_instruction; 6021 src : S1(read); 6022 dst : S5(write); 6023 INS01 : ISS; 6024 NEON_FP : S5; 6025 %} 6026 6027 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6028 %{ 6029 single_instruction; 6030 src : S1(read); 6031 dst : S5(write); 6032 INS01 : ISS; 6033 NEON_FP : S5; 6034 %} 6035 6036 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6037 %{ 6038 single_instruction; 6039 src : S1(read); 6040 dst : S5(write); 6041 INS01 : ISS; 6042 NEON_FP : S5; 6043 %} 6044 6045 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6046 %{ 6047 single_instruction; 6048 src : S1(read); 6049 dst : S5(write); 6050 INS01 : ISS; 6051 NEON_FP : S5; 6052 %} 6053 6054 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6055 %{ 6056 single_instruction; 6057 src : S1(read); 6058 dst : S5(write); 6059 INS01 : ISS; 6060 NEON_FP : S5; 6061 %} 6062 6063 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6064 %{ 6065 single_instruction; 6066 src1 : S1(read); 6067 src2 : S2(read); 6068 dst : S5(write); 6069 INS0 : ISS; 6070 NEON_FP : S5; 6071 %} 6072 6073 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6074 %{ 6075 single_instruction; 6076 src1 : S1(read); 6077 src2 : S2(read); 6078 dst : S5(write); 6079 INS0 : ISS; 6080 NEON_FP : S5; 6081 %} 6082 6083 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6084 %{ 6085 single_instruction; 6086 cr : S1(read); 6087 src1 : S1(read); 6088 src2 : S1(read); 6089 dst : S3(write); 6090 INS01 : ISS; 6091 NEON_FP : S3; 6092 %} 6093 6094 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6095 %{ 6096 single_instruction; 6097 cr : S1(read); 6098 src1 : S1(read); 6099 src2 : S1(read); 6100 dst : S3(write); 6101 INS01 : ISS; 6102 NEON_FP : S3; 6103 %} 6104 6105 pipe_class fp_imm_s(vRegF dst) 6106 %{ 6107 single_instruction; 6108 dst : S3(write); 6109 INS01 : ISS; 6110 NEON_FP : S3; 6111 %} 6112 6113 pipe_class fp_imm_d(vRegD dst) 6114 %{ 6115 single_instruction; 6116 dst : S3(write); 6117 INS01 : ISS; 6118 NEON_FP : S3; 6119 %} 6120 6121 pipe_class fp_load_constant_s(vRegF dst) 6122 %{ 6123 single_instruction; 6124 dst : S4(write); 6125 INS01 : ISS; 6126 NEON_FP : S4; 6127 %} 6128 6129 pipe_class fp_load_constant_d(vRegD dst) 6130 %{ 6131 single_instruction; 6132 dst : S4(write); 6133 INS01 : ISS; 6134 NEON_FP : S4; 6135 %} 6136 6137 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6138 %{ 6139 single_instruction; 6140 dst : S5(write); 6141 src1 : S1(read); 6142 src2 : S1(read); 6143 INS01 : ISS; 6144 NEON_FP : S5; 6145 %} 6146 6147 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6148 %{ 6149 single_instruction; 6150 dst : S5(write); 6151 src1 : S1(read); 6152 src2 : S1(read); 6153 INS0 : ISS; 6154 NEON_FP : S5; 6155 %} 6156 6157 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6158 %{ 6159 single_instruction; 6160 dst : S5(write); 6161 src1 : S1(read); 6162 src2 : S1(read); 6163 dst : S1(read); 6164 INS01 : ISS; 6165 NEON_FP : S5; 6166 %} 6167 6168 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6169 %{ 6170 single_instruction; 6171 dst : S5(write); 6172 src1 : S1(read); 6173 src2 : S1(read); 6174 dst : S1(read); 6175 INS0 : ISS; 6176 NEON_FP : S5; 6177 %} 6178 6179 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6180 %{ 6181 single_instruction; 6182 dst : S4(write); 6183 src1 : S2(read); 6184 src2 : S2(read); 6185 INS01 : ISS; 6186 NEON_FP : S4; 6187 %} 6188 6189 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6190 %{ 6191 single_instruction; 6192 dst : S4(write); 6193 src1 : S2(read); 6194 src2 : S2(read); 6195 INS0 : ISS; 6196 NEON_FP : S4; 6197 %} 6198 6199 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6200 %{ 6201 single_instruction; 6202 dst : S3(write); 6203 src1 : S2(read); 6204 src2 : S2(read); 6205 INS01 : ISS; 6206 NEON_FP : S3; 6207 %} 6208 6209 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6210 %{ 6211 single_instruction; 6212 dst : S3(write); 6213 src1 : S2(read); 6214 src2 : S2(read); 6215 INS0 : ISS; 6216 NEON_FP : S3; 6217 %} 6218 6219 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6220 %{ 6221 single_instruction; 6222 dst : S3(write); 6223 src : S1(read); 6224 shift : S1(read); 6225 INS01 : ISS; 6226 NEON_FP : S3; 6227 %} 6228 6229 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6230 %{ 6231 single_instruction; 6232 dst : S3(write); 6233 src : S1(read); 6234 shift : S1(read); 6235 INS0 : ISS; 6236 NEON_FP : S3; 6237 %} 6238 6239 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6240 %{ 6241 single_instruction; 6242 dst : S3(write); 6243 src : S1(read); 6244 INS01 : ISS; 6245 NEON_FP : S3; 6246 %} 6247 6248 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6249 %{ 6250 single_instruction; 6251 dst : S3(write); 6252 src : S1(read); 6253 INS0 : ISS; 6254 NEON_FP : S3; 6255 %} 6256 6257 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6258 %{ 6259 single_instruction; 6260 dst : S5(write); 6261 src1 : S1(read); 6262 src2 : S1(read); 6263 INS01 : ISS; 6264 NEON_FP : S5; 6265 %} 6266 6267 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6268 %{ 6269 single_instruction; 6270 dst : S5(write); 6271 src1 : S1(read); 6272 src2 : S1(read); 6273 INS0 : ISS; 6274 NEON_FP : S5; 6275 %} 6276 6277 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6278 %{ 6279 single_instruction; 6280 dst : S5(write); 6281 src1 : S1(read); 6282 src2 : S1(read); 6283 INS0 : ISS; 6284 NEON_FP : S5; 6285 %} 6286 6287 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6288 %{ 6289 single_instruction; 6290 dst : S5(write); 6291 src1 : S1(read); 6292 src2 : S1(read); 6293 INS0 : ISS; 6294 NEON_FP : S5; 6295 %} 6296 6297 pipe_class vsqrt_fp128(vecX dst, vecX src) 6298 %{ 6299 single_instruction; 6300 dst : S5(write); 6301 src : S1(read); 6302 INS0 : ISS; 6303 NEON_FP : S5; 6304 %} 6305 6306 pipe_class vunop_fp64(vecD dst, vecD src) 6307 %{ 6308 single_instruction; 6309 dst : S5(write); 6310 src : S1(read); 6311 INS01 : ISS; 6312 NEON_FP : S5; 6313 %} 6314 6315 pipe_class vunop_fp128(vecX dst, vecX src) 6316 %{ 6317 single_instruction; 6318 dst : S5(write); 6319 src : S1(read); 6320 INS0 : ISS; 6321 NEON_FP : S5; 6322 %} 6323 6324 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6325 %{ 6326 single_instruction; 6327 dst : S3(write); 6328 src : S1(read); 6329 INS01 : ISS; 6330 NEON_FP : S3; 6331 %} 6332 6333 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6334 %{ 6335 single_instruction; 6336 dst : S3(write); 6337 src : S1(read); 6338 INS01 : ISS; 6339 NEON_FP : S3; 6340 %} 6341 6342 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6343 %{ 6344 single_instruction; 6345 dst : S3(write); 6346 src : S1(read); 6347 INS01 : ISS; 6348 NEON_FP : S3; 6349 %} 6350 6351 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6352 %{ 6353 single_instruction; 6354 dst : S3(write); 6355 src : S1(read); 6356 INS01 : ISS; 6357 NEON_FP : S3; 6358 %} 6359 6360 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6361 %{ 6362 single_instruction; 6363 dst : S3(write); 6364 src : S1(read); 6365 INS01 : ISS; 6366 NEON_FP : S3; 6367 %} 6368 6369 pipe_class vmovi_reg_imm64(vecD dst) 6370 %{ 6371 single_instruction; 6372 dst : S3(write); 6373 INS01 : ISS; 6374 NEON_FP : S3; 6375 %} 6376 6377 pipe_class vmovi_reg_imm128(vecX dst) 6378 %{ 6379 single_instruction; 6380 dst : S3(write); 6381 INS0 : ISS; 6382 NEON_FP : S3; 6383 %} 6384 6385 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6386 %{ 6387 single_instruction; 6388 dst : S5(write); 6389 mem : ISS(read); 6390 INS01 : ISS; 6391 NEON_FP : S3; 6392 %} 6393 6394 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6395 %{ 6396 single_instruction; 6397 dst : S5(write); 6398 mem : ISS(read); 6399 INS01 : ISS; 6400 NEON_FP : S3; 6401 %} 6402 6403 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6404 %{ 6405 single_instruction; 6406 mem : ISS(read); 6407 src : S2(read); 6408 INS01 : ISS; 6409 NEON_FP : S3; 6410 %} 6411 6412 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6413 %{ 6414 single_instruction; 6415 mem : ISS(read); 6416 src : S2(read); 6417 INS01 : ISS; 6418 NEON_FP : S3; 6419 %} 6420 6421 //------- Integer ALU operations -------------------------- 6422 6423 // Integer ALU reg-reg operation 6424 // Operands needed in EX1, result generated in EX2 6425 // Eg. ADD x0, x1, x2 6426 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6427 %{ 6428 single_instruction; 6429 dst : EX2(write); 6430 src1 : EX1(read); 6431 src2 : EX1(read); 6432 INS01 : ISS; // Dual issue as instruction 0 or 1 6433 ALU : EX2; 6434 %} 6435 6436 // Integer ALU reg-reg operation with constant shift 6437 // Shifted register must be available in LATE_ISS instead of EX1 6438 // Eg. ADD x0, x1, x2, LSL #2 6439 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6440 %{ 6441 single_instruction; 6442 dst : EX2(write); 6443 src1 : EX1(read); 6444 src2 : ISS(read); 6445 INS01 : ISS; 6446 ALU : EX2; 6447 %} 6448 6449 // Integer ALU reg operation with constant shift 6450 // Eg. LSL x0, x1, #shift 6451 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6452 %{ 6453 single_instruction; 6454 dst : EX2(write); 6455 src1 : ISS(read); 6456 INS01 : ISS; 6457 ALU : EX2; 6458 %} 6459 6460 // Integer ALU reg-reg operation with variable shift 6461 // Both operands must be available in LATE_ISS instead of EX1 6462 // Result is available in EX1 instead of EX2 6463 // Eg. LSLV x0, x1, x2 6464 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6465 %{ 6466 single_instruction; 6467 dst : EX1(write); 6468 src1 : ISS(read); 6469 src2 : ISS(read); 6470 INS01 : ISS; 6471 ALU : EX1; 6472 %} 6473 6474 // Integer ALU reg-reg operation with extract 6475 // As for _vshift above, but result generated in EX2 6476 // Eg. EXTR x0, x1, x2, #N 6477 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6478 %{ 6479 single_instruction; 6480 dst : EX2(write); 6481 src1 : ISS(read); 6482 src2 : ISS(read); 6483 INS1 : ISS; // Can only dual issue as Instruction 1 6484 ALU : EX1; 6485 %} 6486 6487 // Integer ALU reg operation 6488 // Eg. NEG x0, x1 6489 pipe_class ialu_reg(iRegI dst, iRegI src) 6490 %{ 6491 single_instruction; 6492 dst : EX2(write); 6493 src : EX1(read); 6494 INS01 : ISS; 6495 ALU : EX2; 6496 %} 6497 6498 // Integer ALU reg mmediate operation 6499 // Eg. ADD x0, x1, #N 6500 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6501 %{ 6502 single_instruction; 6503 dst : EX2(write); 6504 src1 : EX1(read); 6505 INS01 : ISS; 6506 ALU : EX2; 6507 %} 6508 6509 // Integer ALU immediate operation (no source operands) 6510 // Eg. MOV x0, #N 6511 pipe_class ialu_imm(iRegI dst) 6512 %{ 6513 single_instruction; 6514 dst : EX1(write); 6515 INS01 : ISS; 6516 ALU : EX1; 6517 %} 6518 6519 //------- Compare operation ------------------------------- 6520 6521 // Compare reg-reg 6522 // Eg. CMP x0, x1 6523 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6524 %{ 6525 single_instruction; 6526 // fixed_latency(16); 6527 cr : EX2(write); 6528 op1 : EX1(read); 6529 op2 : EX1(read); 6530 INS01 : ISS; 6531 ALU : EX2; 6532 %} 6533 6534 // Compare reg-reg 6535 // Eg. CMP x0, #N 6536 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6537 %{ 6538 single_instruction; 6539 // fixed_latency(16); 6540 cr : EX2(write); 6541 op1 : EX1(read); 6542 INS01 : ISS; 6543 ALU : EX2; 6544 %} 6545 6546 //------- Conditional instructions ------------------------ 6547 6548 // Conditional no operands 6549 // Eg. CSINC x0, zr, zr, <cond> 6550 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6551 %{ 6552 single_instruction; 6553 cr : EX1(read); 6554 dst : EX2(write); 6555 INS01 : ISS; 6556 ALU : EX2; 6557 %} 6558 6559 // Conditional 2 operand 6560 // EG. CSEL X0, X1, X2, <cond> 6561 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6562 %{ 6563 single_instruction; 6564 cr : EX1(read); 6565 src1 : EX1(read); 6566 src2 : EX1(read); 6567 dst : EX2(write); 6568 INS01 : ISS; 6569 ALU : EX2; 6570 %} 6571 6572 // Conditional 2 operand 6573 // EG. CSEL X0, X1, X2, <cond> 6574 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6575 %{ 6576 single_instruction; 6577 cr : EX1(read); 6578 src : EX1(read); 6579 dst : EX2(write); 6580 INS01 : ISS; 6581 ALU : EX2; 6582 %} 6583 6584 //------- Multiply pipeline operations -------------------- 6585 6586 // Multiply reg-reg 6587 // Eg. MUL w0, w1, w2 6588 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6589 %{ 6590 single_instruction; 6591 dst : WR(write); 6592 src1 : ISS(read); 6593 src2 : ISS(read); 6594 INS01 : ISS; 6595 MAC : WR; 6596 %} 6597 6598 // Multiply accumulate 6599 // Eg. MADD w0, w1, w2, w3 6600 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6601 %{ 6602 single_instruction; 6603 dst : WR(write); 6604 src1 : ISS(read); 6605 src2 : ISS(read); 6606 src3 : ISS(read); 6607 INS01 : ISS; 6608 MAC : WR; 6609 %} 6610 6611 // Eg. MUL w0, w1, w2 6612 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6613 %{ 6614 single_instruction; 6615 fixed_latency(3); // Maximum latency for 64 bit mul 6616 dst : WR(write); 6617 src1 : ISS(read); 6618 src2 : ISS(read); 6619 INS01 : ISS; 6620 MAC : WR; 6621 %} 6622 6623 // Multiply accumulate 6624 // Eg. MADD w0, w1, w2, w3 6625 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6626 %{ 6627 single_instruction; 6628 fixed_latency(3); // Maximum latency for 64 bit mul 6629 dst : WR(write); 6630 src1 : ISS(read); 6631 src2 : ISS(read); 6632 src3 : ISS(read); 6633 INS01 : ISS; 6634 MAC : WR; 6635 %} 6636 6637 //------- Divide pipeline operations -------------------- 6638 6639 // Eg. SDIV w0, w1, w2 6640 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6641 %{ 6642 single_instruction; 6643 fixed_latency(8); // Maximum latency for 32 bit divide 6644 dst : WR(write); 6645 src1 : ISS(read); 6646 src2 : ISS(read); 6647 INS0 : ISS; // Can only dual issue as instruction 0 6648 DIV : WR; 6649 %} 6650 6651 // Eg. SDIV x0, x1, x2 6652 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6653 %{ 6654 single_instruction; 6655 fixed_latency(16); // Maximum latency for 64 bit divide 6656 dst : WR(write); 6657 src1 : ISS(read); 6658 src2 : ISS(read); 6659 INS0 : ISS; // Can only dual issue as instruction 0 6660 DIV : WR; 6661 %} 6662 6663 //------- Load pipeline operations ------------------------ 6664 6665 // Load - prefetch 6666 // Eg. PFRM <mem> 6667 pipe_class iload_prefetch(memory mem) 6668 %{ 6669 single_instruction; 6670 mem : ISS(read); 6671 INS01 : ISS; 6672 LDST : WR; 6673 %} 6674 6675 // Load - reg, mem 6676 // Eg. LDR x0, <mem> 6677 pipe_class iload_reg_mem(iRegI dst, memory mem) 6678 %{ 6679 single_instruction; 6680 dst : WR(write); 6681 mem : ISS(read); 6682 INS01 : ISS; 6683 LDST : WR; 6684 %} 6685 6686 // Load - reg, reg 6687 // Eg. LDR x0, [sp, x1] 6688 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6689 %{ 6690 single_instruction; 6691 dst : WR(write); 6692 src : ISS(read); 6693 INS01 : ISS; 6694 LDST : WR; 6695 %} 6696 6697 //------- Store pipeline operations ----------------------- 6698 6699 // Store - zr, mem 6700 // Eg. STR zr, <mem> 6701 pipe_class istore_mem(memory mem) 6702 %{ 6703 single_instruction; 6704 mem : ISS(read); 6705 INS01 : ISS; 6706 LDST : WR; 6707 %} 6708 6709 // Store - reg, mem 6710 // Eg. STR x0, <mem> 6711 pipe_class istore_reg_mem(iRegI src, memory mem) 6712 %{ 6713 single_instruction; 6714 mem : ISS(read); 6715 src : EX2(read); 6716 INS01 : ISS; 6717 LDST : WR; 6718 %} 6719 6720 // Store - reg, reg 6721 // Eg. STR x0, [sp, x1] 6722 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6723 %{ 6724 single_instruction; 6725 dst : ISS(read); 6726 src : EX2(read); 6727 INS01 : ISS; 6728 LDST : WR; 6729 %} 6730 6731 //------- Store pipeline operations ----------------------- 6732 6733 // Branch 6734 pipe_class pipe_branch() 6735 %{ 6736 single_instruction; 6737 INS01 : ISS; 6738 BRANCH : EX1; 6739 %} 6740 6741 // Conditional branch 6742 pipe_class pipe_branch_cond(rFlagsReg cr) 6743 %{ 6744 single_instruction; 6745 cr : EX1(read); 6746 INS01 : ISS; 6747 BRANCH : EX1; 6748 %} 6749 6750 // Compare & Branch 6751 // EG. CBZ/CBNZ 6752 pipe_class pipe_cmp_branch(iRegI op1) 6753 %{ 6754 single_instruction; 6755 op1 : EX1(read); 6756 INS01 : ISS; 6757 BRANCH : EX1; 6758 %} 6759 6760 //------- Synchronisation operations ---------------------- 6761 6762 // Any operation requiring serialization. 6763 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6764 pipe_class pipe_serial() 6765 %{ 6766 single_instruction; 6767 force_serialization; 6768 fixed_latency(16); 6769 INS01 : ISS(2); // Cannot dual issue with any other instruction 6770 LDST : WR; 6771 %} 6772 6773 // Generic big/slow expanded idiom - also serialized 6774 pipe_class pipe_slow() 6775 %{ 6776 instruction_count(10); 6777 multiple_bundles; 6778 force_serialization; 6779 fixed_latency(16); 6780 INS01 : ISS(2); // Cannot dual issue with any other instruction 6781 LDST : WR; 6782 %} 6783 6784 // Empty pipeline class 6785 pipe_class pipe_class_empty() 6786 %{ 6787 single_instruction; 6788 fixed_latency(0); 6789 %} 6790 6791 // Default pipeline class. 6792 pipe_class pipe_class_default() 6793 %{ 6794 single_instruction; 6795 fixed_latency(2); 6796 %} 6797 6798 // Pipeline class for compares. 6799 pipe_class pipe_class_compare() 6800 %{ 6801 single_instruction; 6802 fixed_latency(16); 6803 %} 6804 6805 // Pipeline class for memory operations. 6806 pipe_class pipe_class_memory() 6807 %{ 6808 single_instruction; 6809 fixed_latency(16); 6810 %} 6811 6812 // Pipeline class for call. 6813 pipe_class pipe_class_call() 6814 %{ 6815 single_instruction; 6816 fixed_latency(100); 6817 %} 6818 6819 // Define the class for the Nop node. 6820 define %{ 6821 MachNop = pipe_class_empty; 6822 %} 6823 6824 %} 6825 //----------INSTRUCTIONS------------------------------------------------------- 6826 // 6827 // match -- States which machine-independent subtree may be replaced 6828 // by this instruction. 6829 // ins_cost -- The estimated cost of this instruction is used by instruction 6830 // selection to identify a minimum cost tree of machine 6831 // instructions that matches a tree of machine-independent 6832 // instructions. 6833 // format -- A string providing the disassembly for this instruction. 6834 // The value of an instruction's operand may be inserted 6835 // by referring to it with a '$' prefix. 6836 // opcode -- Three instruction opcodes may be provided. These are referred 6837 // to within an encode class as $primary, $secondary, and $tertiary 6838 // rrspectively. The primary opcode is commonly used to 6839 // indicate the type of machine instruction, while secondary 6840 // and tertiary are often used for prefix options or addressing 6841 // modes. 6842 // ins_encode -- A list of encode classes with parameters. The encode class 6843 // name must have been defined in an 'enc_class' specification 6844 // in the encode section of the architecture description. 6845 6846 // ============================================================================ 6847 // Memory (Load/Store) Instructions 6848 6849 // Load Instructions 6850 6851 // Load Byte (8 bit signed) 6852 instruct loadB(iRegINoSp dst, memory1 mem) 6853 %{ 6854 match(Set dst (LoadB mem)); 6855 predicate(!needs_acquiring_load(n)); 6856 6857 ins_cost(4 * INSN_COST); 6858 format %{ "ldrsbw $dst, $mem\t# byte" %} 6859 6860 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6861 6862 ins_pipe(iload_reg_mem); 6863 %} 6864 6865 // Load Byte (8 bit signed) into long 6866 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6867 %{ 6868 match(Set dst (ConvI2L (LoadB mem))); 6869 predicate(!needs_acquiring_load(n->in(1))); 6870 6871 ins_cost(4 * INSN_COST); 6872 format %{ "ldrsb $dst, $mem\t# byte" %} 6873 6874 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6875 6876 ins_pipe(iload_reg_mem); 6877 %} 6878 6879 // Load Byte (8 bit unsigned) 6880 instruct loadUB(iRegINoSp dst, memory1 mem) 6881 %{ 6882 match(Set dst (LoadUB mem)); 6883 predicate(!needs_acquiring_load(n)); 6884 6885 ins_cost(4 * INSN_COST); 6886 format %{ "ldrbw $dst, $mem\t# byte" %} 6887 6888 ins_encode(aarch64_enc_ldrb(dst, mem)); 6889 6890 ins_pipe(iload_reg_mem); 6891 %} 6892 6893 // Load Byte (8 bit unsigned) into long 6894 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6895 %{ 6896 match(Set dst (ConvI2L (LoadUB mem))); 6897 predicate(!needs_acquiring_load(n->in(1))); 6898 6899 ins_cost(4 * INSN_COST); 6900 format %{ "ldrb $dst, $mem\t# byte" %} 6901 6902 ins_encode(aarch64_enc_ldrb(dst, mem)); 6903 6904 ins_pipe(iload_reg_mem); 6905 %} 6906 6907 // Load Short (16 bit signed) 6908 instruct loadS(iRegINoSp dst, memory2 mem) 6909 %{ 6910 match(Set dst (LoadS mem)); 6911 predicate(!needs_acquiring_load(n)); 6912 6913 ins_cost(4 * INSN_COST); 6914 format %{ "ldrshw $dst, $mem\t# short" %} 6915 6916 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6917 6918 ins_pipe(iload_reg_mem); 6919 %} 6920 6921 // Load Short (16 bit signed) into long 6922 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6923 %{ 6924 match(Set dst (ConvI2L (LoadS mem))); 6925 predicate(!needs_acquiring_load(n->in(1))); 6926 6927 ins_cost(4 * INSN_COST); 6928 format %{ "ldrsh $dst, $mem\t# short" %} 6929 6930 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6931 6932 ins_pipe(iload_reg_mem); 6933 %} 6934 6935 // Load Char (16 bit unsigned) 6936 instruct loadUS(iRegINoSp dst, memory2 mem) 6937 %{ 6938 match(Set dst (LoadUS mem)); 6939 predicate(!needs_acquiring_load(n)); 6940 6941 ins_cost(4 * INSN_COST); 6942 format %{ "ldrh $dst, $mem\t# short" %} 6943 6944 ins_encode(aarch64_enc_ldrh(dst, mem)); 6945 6946 ins_pipe(iload_reg_mem); 6947 %} 6948 6949 // Load Short/Char (16 bit unsigned) into long 6950 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6951 %{ 6952 match(Set dst (ConvI2L (LoadUS mem))); 6953 predicate(!needs_acquiring_load(n->in(1))); 6954 6955 ins_cost(4 * INSN_COST); 6956 format %{ "ldrh $dst, $mem\t# short" %} 6957 6958 ins_encode(aarch64_enc_ldrh(dst, mem)); 6959 6960 ins_pipe(iload_reg_mem); 6961 %} 6962 6963 // Load Integer (32 bit signed) 6964 instruct loadI(iRegINoSp dst, memory4 mem) 6965 %{ 6966 match(Set dst (LoadI mem)); 6967 predicate(!needs_acquiring_load(n)); 6968 6969 ins_cost(4 * INSN_COST); 6970 format %{ "ldrw $dst, $mem\t# int" %} 6971 6972 ins_encode(aarch64_enc_ldrw(dst, mem)); 6973 6974 ins_pipe(iload_reg_mem); 6975 %} 6976 6977 // Load Integer (32 bit signed) into long 6978 instruct loadI2L(iRegLNoSp dst, memory4 mem) 6979 %{ 6980 match(Set dst (ConvI2L (LoadI mem))); 6981 predicate(!needs_acquiring_load(n->in(1))); 6982 6983 ins_cost(4 * INSN_COST); 6984 format %{ "ldrsw $dst, $mem\t# int" %} 6985 6986 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6987 6988 ins_pipe(iload_reg_mem); 6989 %} 6990 6991 // Load Integer (32 bit unsigned) into long 6992 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 6993 %{ 6994 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6995 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6996 6997 ins_cost(4 * INSN_COST); 6998 format %{ "ldrw $dst, $mem\t# int" %} 6999 7000 ins_encode(aarch64_enc_ldrw(dst, mem)); 7001 7002 ins_pipe(iload_reg_mem); 7003 %} 7004 7005 // Load Long (64 bit signed) 7006 instruct loadL(iRegLNoSp dst, memory8 mem) 7007 %{ 7008 match(Set dst (LoadL mem)); 7009 predicate(!needs_acquiring_load(n)); 7010 7011 ins_cost(4 * INSN_COST); 7012 format %{ "ldr $dst, $mem\t# int" %} 7013 7014 ins_encode(aarch64_enc_ldr(dst, mem)); 7015 7016 ins_pipe(iload_reg_mem); 7017 %} 7018 7019 // Load Range 7020 instruct loadRange(iRegINoSp dst, memory4 mem) 7021 %{ 7022 match(Set dst (LoadRange mem)); 7023 7024 ins_cost(4 * INSN_COST); 7025 format %{ "ldrw $dst, $mem\t# range" %} 7026 7027 ins_encode(aarch64_enc_ldrw(dst, mem)); 7028 7029 ins_pipe(iload_reg_mem); 7030 %} 7031 7032 // Load Pointer 7033 instruct loadP(iRegPNoSp dst, memory8 mem) 7034 %{ 7035 match(Set dst (LoadP mem)); 7036 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7037 7038 ins_cost(4 * INSN_COST); 7039 format %{ "ldr $dst, $mem\t# ptr" %} 7040 7041 ins_encode(aarch64_enc_ldr(dst, mem)); 7042 7043 ins_pipe(iload_reg_mem); 7044 %} 7045 7046 // Load Compressed Pointer 7047 instruct loadN(iRegNNoSp dst, memory4 mem) 7048 %{ 7049 match(Set dst (LoadN mem)); 7050 predicate(!needs_acquiring_load(n)); 7051 7052 ins_cost(4 * INSN_COST); 7053 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7054 7055 ins_encode(aarch64_enc_ldrw(dst, mem)); 7056 7057 ins_pipe(iload_reg_mem); 7058 %} 7059 7060 // Load Klass Pointer 7061 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7062 %{ 7063 match(Set dst (LoadKlass mem)); 7064 predicate(!needs_acquiring_load(n)); 7065 7066 ins_cost(4 * INSN_COST); 7067 format %{ "ldr $dst, $mem\t# class" %} 7068 7069 ins_encode(aarch64_enc_ldr(dst, mem)); 7070 7071 ins_pipe(iload_reg_mem); 7072 %} 7073 7074 // Load Narrow Klass Pointer 7075 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7076 %{ 7077 match(Set dst (LoadNKlass mem)); 7078 predicate(!needs_acquiring_load(n)); 7079 7080 ins_cost(4 * INSN_COST); 7081 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7082 7083 ins_encode(aarch64_enc_ldrw(dst, mem)); 7084 7085 ins_pipe(iload_reg_mem); 7086 %} 7087 7088 // Load Float 7089 instruct loadF(vRegF dst, memory4 mem) 7090 %{ 7091 match(Set dst (LoadF mem)); 7092 predicate(!needs_acquiring_load(n)); 7093 7094 ins_cost(4 * INSN_COST); 7095 format %{ "ldrs $dst, $mem\t# float" %} 7096 7097 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7098 7099 ins_pipe(pipe_class_memory); 7100 %} 7101 7102 // Load Double 7103 instruct loadD(vRegD dst, memory8 mem) 7104 %{ 7105 match(Set dst (LoadD mem)); 7106 predicate(!needs_acquiring_load(n)); 7107 7108 ins_cost(4 * INSN_COST); 7109 format %{ "ldrd $dst, $mem\t# double" %} 7110 7111 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7112 7113 ins_pipe(pipe_class_memory); 7114 %} 7115 7116 7117 // Load Int Constant 7118 instruct loadConI(iRegINoSp dst, immI src) 7119 %{ 7120 match(Set dst src); 7121 7122 ins_cost(INSN_COST); 7123 format %{ "mov $dst, $src\t# int" %} 7124 7125 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7126 7127 ins_pipe(ialu_imm); 7128 %} 7129 7130 // Load Long Constant 7131 instruct loadConL(iRegLNoSp dst, immL src) 7132 %{ 7133 match(Set dst src); 7134 7135 ins_cost(INSN_COST); 7136 format %{ "mov $dst, $src\t# long" %} 7137 7138 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7139 7140 ins_pipe(ialu_imm); 7141 %} 7142 7143 // Load Pointer Constant 7144 7145 instruct loadConP(iRegPNoSp dst, immP con) 7146 %{ 7147 match(Set dst con); 7148 7149 ins_cost(INSN_COST * 4); 7150 format %{ 7151 "mov $dst, $con\t# ptr\n\t" 7152 %} 7153 7154 ins_encode(aarch64_enc_mov_p(dst, con)); 7155 7156 ins_pipe(ialu_imm); 7157 %} 7158 7159 // Load Null Pointer Constant 7160 7161 instruct loadConP0(iRegPNoSp dst, immP0 con) 7162 %{ 7163 match(Set dst con); 7164 7165 ins_cost(INSN_COST); 7166 format %{ "mov $dst, $con\t# NULL ptr" %} 7167 7168 ins_encode(aarch64_enc_mov_p0(dst, con)); 7169 7170 ins_pipe(ialu_imm); 7171 %} 7172 7173 // Load Pointer Constant One 7174 7175 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7176 %{ 7177 match(Set dst con); 7178 7179 ins_cost(INSN_COST); 7180 format %{ "mov $dst, $con\t# NULL ptr" %} 7181 7182 ins_encode(aarch64_enc_mov_p1(dst, con)); 7183 7184 ins_pipe(ialu_imm); 7185 %} 7186 7187 // Load Byte Map Base Constant 7188 7189 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7190 %{ 7191 match(Set dst con); 7192 7193 ins_cost(INSN_COST); 7194 format %{ "adr $dst, $con\t# Byte Map Base" %} 7195 7196 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7197 7198 ins_pipe(ialu_imm); 7199 %} 7200 7201 // Load Narrow Pointer Constant 7202 7203 instruct loadConN(iRegNNoSp dst, immN con) 7204 %{ 7205 match(Set dst con); 7206 7207 ins_cost(INSN_COST * 4); 7208 format %{ "mov $dst, $con\t# compressed ptr" %} 7209 7210 ins_encode(aarch64_enc_mov_n(dst, con)); 7211 7212 ins_pipe(ialu_imm); 7213 %} 7214 7215 // Load Narrow Null Pointer Constant 7216 7217 instruct loadConN0(iRegNNoSp dst, immN0 con) 7218 %{ 7219 match(Set dst con); 7220 7221 ins_cost(INSN_COST); 7222 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7223 7224 ins_encode(aarch64_enc_mov_n0(dst, con)); 7225 7226 ins_pipe(ialu_imm); 7227 %} 7228 7229 // Load Narrow Klass Constant 7230 7231 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7232 %{ 7233 match(Set dst con); 7234 7235 ins_cost(INSN_COST); 7236 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7237 7238 ins_encode(aarch64_enc_mov_nk(dst, con)); 7239 7240 ins_pipe(ialu_imm); 7241 %} 7242 7243 // Load Packed Float Constant 7244 7245 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7246 match(Set dst con); 7247 ins_cost(INSN_COST * 4); 7248 format %{ "fmovs $dst, $con"%} 7249 ins_encode %{ 7250 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7251 %} 7252 7253 ins_pipe(fp_imm_s); 7254 %} 7255 7256 // Load Float Constant 7257 7258 instruct loadConF(vRegF dst, immF con) %{ 7259 match(Set dst con); 7260 7261 ins_cost(INSN_COST * 4); 7262 7263 format %{ 7264 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7265 %} 7266 7267 ins_encode %{ 7268 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7269 %} 7270 7271 ins_pipe(fp_load_constant_s); 7272 %} 7273 7274 // Load Packed Double Constant 7275 7276 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7277 match(Set dst con); 7278 ins_cost(INSN_COST); 7279 format %{ "fmovd $dst, $con"%} 7280 ins_encode %{ 7281 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7282 %} 7283 7284 ins_pipe(fp_imm_d); 7285 %} 7286 7287 // Load Double Constant 7288 7289 instruct loadConD(vRegD dst, immD con) %{ 7290 match(Set dst con); 7291 7292 ins_cost(INSN_COST * 5); 7293 format %{ 7294 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7295 %} 7296 7297 ins_encode %{ 7298 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7299 %} 7300 7301 ins_pipe(fp_load_constant_d); 7302 %} 7303 7304 // Store Instructions 7305 7306 // Store CMS card-mark Immediate 7307 instruct storeimmCM0(immI0 zero, memory1 mem) 7308 %{ 7309 match(Set mem (StoreCM mem zero)); 7310 7311 ins_cost(INSN_COST); 7312 format %{ "storestore (elided)\n\t" 7313 "strb zr, $mem\t# byte" %} 7314 7315 ins_encode(aarch64_enc_strb0(mem)); 7316 7317 ins_pipe(istore_mem); 7318 %} 7319 7320 // Store CMS card-mark Immediate with intervening StoreStore 7321 // needed when using CMS with no conditional card marking 7322 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7323 %{ 7324 match(Set mem (StoreCM mem zero)); 7325 7326 ins_cost(INSN_COST * 2); 7327 format %{ "storestore\n\t" 7328 "dmb ishst" 7329 "\n\tstrb zr, $mem\t# byte" %} 7330 7331 ins_encode(aarch64_enc_strb0_ordered(mem)); 7332 7333 ins_pipe(istore_mem); 7334 %} 7335 7336 // Store Byte 7337 instruct storeB(iRegIorL2I src, memory1 mem) 7338 %{ 7339 match(Set mem (StoreB mem src)); 7340 predicate(!needs_releasing_store(n)); 7341 7342 ins_cost(INSN_COST); 7343 format %{ "strb $src, $mem\t# byte" %} 7344 7345 ins_encode(aarch64_enc_strb(src, mem)); 7346 7347 ins_pipe(istore_reg_mem); 7348 %} 7349 7350 7351 instruct storeimmB0(immI0 zero, memory1 mem) 7352 %{ 7353 match(Set mem (StoreB mem zero)); 7354 predicate(!needs_releasing_store(n)); 7355 7356 ins_cost(INSN_COST); 7357 format %{ "strb rscractch2, $mem\t# byte" %} 7358 7359 ins_encode(aarch64_enc_strb0(mem)); 7360 7361 ins_pipe(istore_mem); 7362 %} 7363 7364 // Store Char/Short 7365 instruct storeC(iRegIorL2I src, memory2 mem) 7366 %{ 7367 match(Set mem (StoreC mem src)); 7368 predicate(!needs_releasing_store(n)); 7369 7370 ins_cost(INSN_COST); 7371 format %{ "strh $src, $mem\t# short" %} 7372 7373 ins_encode(aarch64_enc_strh(src, mem)); 7374 7375 ins_pipe(istore_reg_mem); 7376 %} 7377 7378 instruct storeimmC0(immI0 zero, memory2 mem) 7379 %{ 7380 match(Set mem (StoreC mem zero)); 7381 predicate(!needs_releasing_store(n)); 7382 7383 ins_cost(INSN_COST); 7384 format %{ "strh zr, $mem\t# short" %} 7385 7386 ins_encode(aarch64_enc_strh0(mem)); 7387 7388 ins_pipe(istore_mem); 7389 %} 7390 7391 // Store Integer 7392 7393 instruct storeI(iRegIorL2I src, memory4 mem) 7394 %{ 7395 match(Set mem(StoreI mem src)); 7396 predicate(!needs_releasing_store(n)); 7397 7398 ins_cost(INSN_COST); 7399 format %{ "strw $src, $mem\t# int" %} 7400 7401 ins_encode(aarch64_enc_strw(src, mem)); 7402 7403 ins_pipe(istore_reg_mem); 7404 %} 7405 7406 instruct storeimmI0(immI0 zero, memory4 mem) 7407 %{ 7408 match(Set mem(StoreI mem zero)); 7409 predicate(!needs_releasing_store(n)); 7410 7411 ins_cost(INSN_COST); 7412 format %{ "strw zr, $mem\t# int" %} 7413 7414 ins_encode(aarch64_enc_strw0(mem)); 7415 7416 ins_pipe(istore_mem); 7417 %} 7418 7419 // Store Long (64 bit signed) 7420 instruct storeL(iRegL src, memory8 mem) 7421 %{ 7422 match(Set mem (StoreL mem src)); 7423 predicate(!needs_releasing_store(n)); 7424 7425 ins_cost(INSN_COST); 7426 format %{ "str $src, $mem\t# int" %} 7427 7428 ins_encode(aarch64_enc_str(src, mem)); 7429 7430 ins_pipe(istore_reg_mem); 7431 %} 7432 7433 // Store Long (64 bit signed) 7434 instruct storeimmL0(immL0 zero, memory8 mem) 7435 %{ 7436 match(Set mem (StoreL mem zero)); 7437 predicate(!needs_releasing_store(n)); 7438 7439 ins_cost(INSN_COST); 7440 format %{ "str zr, $mem\t# int" %} 7441 7442 ins_encode(aarch64_enc_str0(mem)); 7443 7444 ins_pipe(istore_mem); 7445 %} 7446 7447 // Store Pointer 7448 instruct storeP(iRegP src, memory8 mem) 7449 %{ 7450 match(Set mem (StoreP mem src)); 7451 predicate(!needs_releasing_store(n)); 7452 7453 ins_cost(INSN_COST); 7454 format %{ "str $src, $mem\t# ptr" %} 7455 7456 ins_encode(aarch64_enc_str(src, mem)); 7457 7458 ins_pipe(istore_reg_mem); 7459 %} 7460 7461 // Store Pointer 7462 instruct storeimmP0(immP0 zero, memory8 mem) 7463 %{ 7464 match(Set mem (StoreP mem zero)); 7465 predicate(!needs_releasing_store(n)); 7466 7467 ins_cost(INSN_COST); 7468 format %{ "str zr, $mem\t# ptr" %} 7469 7470 ins_encode(aarch64_enc_str0(mem)); 7471 7472 ins_pipe(istore_mem); 7473 %} 7474 7475 // Store Compressed Pointer 7476 instruct storeN(iRegN src, memory4 mem) 7477 %{ 7478 match(Set mem (StoreN mem src)); 7479 predicate(!needs_releasing_store(n)); 7480 7481 ins_cost(INSN_COST); 7482 format %{ "strw $src, $mem\t# compressed ptr" %} 7483 7484 ins_encode(aarch64_enc_strw(src, mem)); 7485 7486 ins_pipe(istore_reg_mem); 7487 %} 7488 7489 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory4 mem) 7490 %{ 7491 match(Set mem (StoreN mem zero)); 7492 predicate(CompressedOops::base() == NULL && 7493 CompressedKlassPointers::base() == NULL && 7494 (!needs_releasing_store(n))); 7495 7496 ins_cost(INSN_COST); 7497 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7498 7499 ins_encode(aarch64_enc_strw(heapbase, mem)); 7500 7501 ins_pipe(istore_reg_mem); 7502 %} 7503 7504 // Store Float 7505 instruct storeF(vRegF src, memory4 mem) 7506 %{ 7507 match(Set mem (StoreF mem src)); 7508 predicate(!needs_releasing_store(n)); 7509 7510 ins_cost(INSN_COST); 7511 format %{ "strs $src, $mem\t# float" %} 7512 7513 ins_encode( aarch64_enc_strs(src, mem) ); 7514 7515 ins_pipe(pipe_class_memory); 7516 %} 7517 7518 // TODO 7519 // implement storeImmF0 and storeFImmPacked 7520 7521 // Store Double 7522 instruct storeD(vRegD src, memory8 mem) 7523 %{ 7524 match(Set mem (StoreD mem src)); 7525 predicate(!needs_releasing_store(n)); 7526 7527 ins_cost(INSN_COST); 7528 format %{ "strd $src, $mem\t# double" %} 7529 7530 ins_encode( aarch64_enc_strd(src, mem) ); 7531 7532 ins_pipe(pipe_class_memory); 7533 %} 7534 7535 // Store Compressed Klass Pointer 7536 instruct storeNKlass(iRegN src, memory4 mem) 7537 %{ 7538 predicate(!needs_releasing_store(n)); 7539 match(Set mem (StoreNKlass mem src)); 7540 7541 ins_cost(INSN_COST); 7542 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7543 7544 ins_encode(aarch64_enc_strw(src, mem)); 7545 7546 ins_pipe(istore_reg_mem); 7547 %} 7548 7549 // TODO 7550 // implement storeImmD0 and storeDImmPacked 7551 7552 // prefetch instructions 7553 // Must be safe to execute with invalid address (cannot fault). 7554 7555 instruct prefetchalloc( memory8 mem ) %{ 7556 match(PrefetchAllocation mem); 7557 7558 ins_cost(INSN_COST); 7559 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7560 7561 ins_encode( aarch64_enc_prefetchw(mem) ); 7562 7563 ins_pipe(iload_prefetch); 7564 %} 7565 7566 // ---------------- volatile loads and stores ---------------- 7567 7568 // Load Byte (8 bit signed) 7569 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7570 %{ 7571 match(Set dst (LoadB mem)); 7572 7573 ins_cost(VOLATILE_REF_COST); 7574 format %{ "ldarsb $dst, $mem\t# byte" %} 7575 7576 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7577 7578 ins_pipe(pipe_serial); 7579 %} 7580 7581 // Load Byte (8 bit signed) into long 7582 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7583 %{ 7584 match(Set dst (ConvI2L (LoadB mem))); 7585 7586 ins_cost(VOLATILE_REF_COST); 7587 format %{ "ldarsb $dst, $mem\t# byte" %} 7588 7589 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7590 7591 ins_pipe(pipe_serial); 7592 %} 7593 7594 // Load Byte (8 bit unsigned) 7595 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7596 %{ 7597 match(Set dst (LoadUB mem)); 7598 7599 ins_cost(VOLATILE_REF_COST); 7600 format %{ "ldarb $dst, $mem\t# byte" %} 7601 7602 ins_encode(aarch64_enc_ldarb(dst, mem)); 7603 7604 ins_pipe(pipe_serial); 7605 %} 7606 7607 // Load Byte (8 bit unsigned) into long 7608 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7609 %{ 7610 match(Set dst (ConvI2L (LoadUB mem))); 7611 7612 ins_cost(VOLATILE_REF_COST); 7613 format %{ "ldarb $dst, $mem\t# byte" %} 7614 7615 ins_encode(aarch64_enc_ldarb(dst, mem)); 7616 7617 ins_pipe(pipe_serial); 7618 %} 7619 7620 // Load Short (16 bit signed) 7621 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7622 %{ 7623 match(Set dst (LoadS mem)); 7624 7625 ins_cost(VOLATILE_REF_COST); 7626 format %{ "ldarshw $dst, $mem\t# short" %} 7627 7628 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7629 7630 ins_pipe(pipe_serial); 7631 %} 7632 7633 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7634 %{ 7635 match(Set dst (LoadUS mem)); 7636 7637 ins_cost(VOLATILE_REF_COST); 7638 format %{ "ldarhw $dst, $mem\t# short" %} 7639 7640 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7641 7642 ins_pipe(pipe_serial); 7643 %} 7644 7645 // Load Short/Char (16 bit unsigned) into long 7646 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7647 %{ 7648 match(Set dst (ConvI2L (LoadUS mem))); 7649 7650 ins_cost(VOLATILE_REF_COST); 7651 format %{ "ldarh $dst, $mem\t# short" %} 7652 7653 ins_encode(aarch64_enc_ldarh(dst, mem)); 7654 7655 ins_pipe(pipe_serial); 7656 %} 7657 7658 // Load Short/Char (16 bit signed) into long 7659 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7660 %{ 7661 match(Set dst (ConvI2L (LoadS mem))); 7662 7663 ins_cost(VOLATILE_REF_COST); 7664 format %{ "ldarh $dst, $mem\t# short" %} 7665 7666 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7667 7668 ins_pipe(pipe_serial); 7669 %} 7670 7671 // Load Integer (32 bit signed) 7672 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7673 %{ 7674 match(Set dst (LoadI mem)); 7675 7676 ins_cost(VOLATILE_REF_COST); 7677 format %{ "ldarw $dst, $mem\t# int" %} 7678 7679 ins_encode(aarch64_enc_ldarw(dst, mem)); 7680 7681 ins_pipe(pipe_serial); 7682 %} 7683 7684 // Load Integer (32 bit unsigned) into long 7685 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7686 %{ 7687 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7688 7689 ins_cost(VOLATILE_REF_COST); 7690 format %{ "ldarw $dst, $mem\t# int" %} 7691 7692 ins_encode(aarch64_enc_ldarw(dst, mem)); 7693 7694 ins_pipe(pipe_serial); 7695 %} 7696 7697 // Load Long (64 bit signed) 7698 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7699 %{ 7700 match(Set dst (LoadL mem)); 7701 7702 ins_cost(VOLATILE_REF_COST); 7703 format %{ "ldar $dst, $mem\t# int" %} 7704 7705 ins_encode(aarch64_enc_ldar(dst, mem)); 7706 7707 ins_pipe(pipe_serial); 7708 %} 7709 7710 // Load Pointer 7711 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7712 %{ 7713 match(Set dst (LoadP mem)); 7714 predicate(n->as_Load()->barrier_data() == 0); 7715 7716 ins_cost(VOLATILE_REF_COST); 7717 format %{ "ldar $dst, $mem\t# ptr" %} 7718 7719 ins_encode(aarch64_enc_ldar(dst, mem)); 7720 7721 ins_pipe(pipe_serial); 7722 %} 7723 7724 // Load Compressed Pointer 7725 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7726 %{ 7727 match(Set dst (LoadN mem)); 7728 7729 ins_cost(VOLATILE_REF_COST); 7730 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7731 7732 ins_encode(aarch64_enc_ldarw(dst, mem)); 7733 7734 ins_pipe(pipe_serial); 7735 %} 7736 7737 // Load Float 7738 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7739 %{ 7740 match(Set dst (LoadF mem)); 7741 7742 ins_cost(VOLATILE_REF_COST); 7743 format %{ "ldars $dst, $mem\t# float" %} 7744 7745 ins_encode( aarch64_enc_fldars(dst, mem) ); 7746 7747 ins_pipe(pipe_serial); 7748 %} 7749 7750 // Load Double 7751 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7752 %{ 7753 match(Set dst (LoadD mem)); 7754 7755 ins_cost(VOLATILE_REF_COST); 7756 format %{ "ldard $dst, $mem\t# double" %} 7757 7758 ins_encode( aarch64_enc_fldard(dst, mem) ); 7759 7760 ins_pipe(pipe_serial); 7761 %} 7762 7763 // Store Byte 7764 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7765 %{ 7766 match(Set mem (StoreB mem src)); 7767 7768 ins_cost(VOLATILE_REF_COST); 7769 format %{ "stlrb $src, $mem\t# byte" %} 7770 7771 ins_encode(aarch64_enc_stlrb(src, mem)); 7772 7773 ins_pipe(pipe_class_memory); 7774 %} 7775 7776 // Store Char/Short 7777 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7778 %{ 7779 match(Set mem (StoreC mem src)); 7780 7781 ins_cost(VOLATILE_REF_COST); 7782 format %{ "stlrh $src, $mem\t# short" %} 7783 7784 ins_encode(aarch64_enc_stlrh(src, mem)); 7785 7786 ins_pipe(pipe_class_memory); 7787 %} 7788 7789 // Store Integer 7790 7791 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7792 %{ 7793 match(Set mem(StoreI mem src)); 7794 7795 ins_cost(VOLATILE_REF_COST); 7796 format %{ "stlrw $src, $mem\t# int" %} 7797 7798 ins_encode(aarch64_enc_stlrw(src, mem)); 7799 7800 ins_pipe(pipe_class_memory); 7801 %} 7802 7803 // Store Long (64 bit signed) 7804 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7805 %{ 7806 match(Set mem (StoreL mem src)); 7807 7808 ins_cost(VOLATILE_REF_COST); 7809 format %{ "stlr $src, $mem\t# int" %} 7810 7811 ins_encode(aarch64_enc_stlr(src, mem)); 7812 7813 ins_pipe(pipe_class_memory); 7814 %} 7815 7816 // Store Pointer 7817 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7818 %{ 7819 match(Set mem (StoreP mem src)); 7820 7821 ins_cost(VOLATILE_REF_COST); 7822 format %{ "stlr $src, $mem\t# ptr" %} 7823 7824 ins_encode(aarch64_enc_stlr(src, mem)); 7825 7826 ins_pipe(pipe_class_memory); 7827 %} 7828 7829 // Store Compressed Pointer 7830 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7831 %{ 7832 match(Set mem (StoreN mem src)); 7833 7834 ins_cost(VOLATILE_REF_COST); 7835 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7836 7837 ins_encode(aarch64_enc_stlrw(src, mem)); 7838 7839 ins_pipe(pipe_class_memory); 7840 %} 7841 7842 // Store Float 7843 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7844 %{ 7845 match(Set mem (StoreF mem src)); 7846 7847 ins_cost(VOLATILE_REF_COST); 7848 format %{ "stlrs $src, $mem\t# float" %} 7849 7850 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7851 7852 ins_pipe(pipe_class_memory); 7853 %} 7854 7855 // TODO 7856 // implement storeImmF0 and storeFImmPacked 7857 7858 // Store Double 7859 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7860 %{ 7861 match(Set mem (StoreD mem src)); 7862 7863 ins_cost(VOLATILE_REF_COST); 7864 format %{ "stlrd $src, $mem\t# double" %} 7865 7866 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7867 7868 ins_pipe(pipe_class_memory); 7869 %} 7870 7871 // ---------------- end of volatile loads and stores ---------------- 7872 7873 instruct cacheWB(indirect addr) 7874 %{ 7875 predicate(VM_Version::supports_data_cache_line_flush()); 7876 match(CacheWB addr); 7877 7878 ins_cost(100); 7879 format %{"cache wb $addr" %} 7880 ins_encode %{ 7881 assert($addr->index_position() < 0, "should be"); 7882 assert($addr$$disp == 0, "should be"); 7883 __ cache_wb(Address($addr$$base$$Register, 0)); 7884 %} 7885 ins_pipe(pipe_slow); // XXX 7886 %} 7887 7888 instruct cacheWBPreSync() 7889 %{ 7890 predicate(VM_Version::supports_data_cache_line_flush()); 7891 match(CacheWBPreSync); 7892 7893 ins_cost(100); 7894 format %{"cache wb presync" %} 7895 ins_encode %{ 7896 __ cache_wbsync(true); 7897 %} 7898 ins_pipe(pipe_slow); // XXX 7899 %} 7900 7901 instruct cacheWBPostSync() 7902 %{ 7903 predicate(VM_Version::supports_data_cache_line_flush()); 7904 match(CacheWBPostSync); 7905 7906 ins_cost(100); 7907 format %{"cache wb postsync" %} 7908 ins_encode %{ 7909 __ cache_wbsync(false); 7910 %} 7911 ins_pipe(pipe_slow); // XXX 7912 %} 7913 7914 // ============================================================================ 7915 // BSWAP Instructions 7916 7917 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7918 match(Set dst (ReverseBytesI src)); 7919 7920 ins_cost(INSN_COST); 7921 format %{ "revw $dst, $src" %} 7922 7923 ins_encode %{ 7924 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7925 %} 7926 7927 ins_pipe(ialu_reg); 7928 %} 7929 7930 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7931 match(Set dst (ReverseBytesL src)); 7932 7933 ins_cost(INSN_COST); 7934 format %{ "rev $dst, $src" %} 7935 7936 ins_encode %{ 7937 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7938 %} 7939 7940 ins_pipe(ialu_reg); 7941 %} 7942 7943 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7944 match(Set dst (ReverseBytesUS src)); 7945 7946 ins_cost(INSN_COST); 7947 format %{ "rev16w $dst, $src" %} 7948 7949 ins_encode %{ 7950 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7951 %} 7952 7953 ins_pipe(ialu_reg); 7954 %} 7955 7956 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7957 match(Set dst (ReverseBytesS src)); 7958 7959 ins_cost(INSN_COST); 7960 format %{ "rev16w $dst, $src\n\t" 7961 "sbfmw $dst, $dst, #0, #15" %} 7962 7963 ins_encode %{ 7964 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7965 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7966 %} 7967 7968 ins_pipe(ialu_reg); 7969 %} 7970 7971 // ============================================================================ 7972 // Zero Count Instructions 7973 7974 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7975 match(Set dst (CountLeadingZerosI src)); 7976 7977 ins_cost(INSN_COST); 7978 format %{ "clzw $dst, $src" %} 7979 ins_encode %{ 7980 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7981 %} 7982 7983 ins_pipe(ialu_reg); 7984 %} 7985 7986 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7987 match(Set dst (CountLeadingZerosL src)); 7988 7989 ins_cost(INSN_COST); 7990 format %{ "clz $dst, $src" %} 7991 ins_encode %{ 7992 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7993 %} 7994 7995 ins_pipe(ialu_reg); 7996 %} 7997 7998 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7999 match(Set dst (CountTrailingZerosI src)); 8000 8001 ins_cost(INSN_COST * 2); 8002 format %{ "rbitw $dst, $src\n\t" 8003 "clzw $dst, $dst" %} 8004 ins_encode %{ 8005 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8006 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8007 %} 8008 8009 ins_pipe(ialu_reg); 8010 %} 8011 8012 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8013 match(Set dst (CountTrailingZerosL src)); 8014 8015 ins_cost(INSN_COST * 2); 8016 format %{ "rbit $dst, $src\n\t" 8017 "clz $dst, $dst" %} 8018 ins_encode %{ 8019 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8020 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8021 %} 8022 8023 ins_pipe(ialu_reg); 8024 %} 8025 8026 //---------- Population Count Instructions ------------------------------------- 8027 // 8028 8029 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8030 predicate(UsePopCountInstruction); 8031 match(Set dst (PopCountI src)); 8032 effect(TEMP tmp); 8033 ins_cost(INSN_COST * 13); 8034 8035 format %{ "movw $src, $src\n\t" 8036 "mov $tmp, $src\t# vector (1D)\n\t" 8037 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8038 "addv $tmp, $tmp\t# vector (8B)\n\t" 8039 "mov $dst, $tmp\t# vector (1D)" %} 8040 ins_encode %{ 8041 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8042 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8043 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8044 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8045 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8046 %} 8047 8048 ins_pipe(pipe_class_default); 8049 %} 8050 8051 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8052 predicate(UsePopCountInstruction); 8053 match(Set dst (PopCountI (LoadI mem))); 8054 effect(TEMP tmp); 8055 ins_cost(INSN_COST * 13); 8056 8057 format %{ "ldrs $tmp, $mem\n\t" 8058 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8059 "addv $tmp, $tmp\t# vector (8B)\n\t" 8060 "mov $dst, $tmp\t# vector (1D)" %} 8061 ins_encode %{ 8062 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8063 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8064 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8065 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8066 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8067 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8068 %} 8069 8070 ins_pipe(pipe_class_default); 8071 %} 8072 8073 // Note: Long.bitCount(long) returns an int. 8074 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8075 predicate(UsePopCountInstruction); 8076 match(Set dst (PopCountL src)); 8077 effect(TEMP tmp); 8078 ins_cost(INSN_COST * 13); 8079 8080 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8081 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8082 "addv $tmp, $tmp\t# vector (8B)\n\t" 8083 "mov $dst, $tmp\t# vector (1D)" %} 8084 ins_encode %{ 8085 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8086 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8087 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8088 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8089 %} 8090 8091 ins_pipe(pipe_class_default); 8092 %} 8093 8094 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8095 predicate(UsePopCountInstruction); 8096 match(Set dst (PopCountL (LoadL mem))); 8097 effect(TEMP tmp); 8098 ins_cost(INSN_COST * 13); 8099 8100 format %{ "ldrd $tmp, $mem\n\t" 8101 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8102 "addv $tmp, $tmp\t# vector (8B)\n\t" 8103 "mov $dst, $tmp\t# vector (1D)" %} 8104 ins_encode %{ 8105 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8106 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8107 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8108 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8109 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8110 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8111 %} 8112 8113 ins_pipe(pipe_class_default); 8114 %} 8115 8116 // ============================================================================ 8117 // MemBar Instruction 8118 8119 instruct load_fence() %{ 8120 match(LoadFence); 8121 ins_cost(VOLATILE_REF_COST); 8122 8123 format %{ "load_fence" %} 8124 8125 ins_encode %{ 8126 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8127 %} 8128 ins_pipe(pipe_serial); 8129 %} 8130 8131 instruct unnecessary_membar_acquire() %{ 8132 predicate(unnecessary_acquire(n)); 8133 match(MemBarAcquire); 8134 ins_cost(0); 8135 8136 format %{ "membar_acquire (elided)" %} 8137 8138 ins_encode %{ 8139 __ block_comment("membar_acquire (elided)"); 8140 %} 8141 8142 ins_pipe(pipe_class_empty); 8143 %} 8144 8145 instruct membar_acquire() %{ 8146 match(MemBarAcquire); 8147 ins_cost(VOLATILE_REF_COST); 8148 8149 format %{ "membar_acquire\n\t" 8150 "dmb ish" %} 8151 8152 ins_encode %{ 8153 __ block_comment("membar_acquire"); 8154 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8155 %} 8156 8157 ins_pipe(pipe_serial); 8158 %} 8159 8160 8161 instruct membar_acquire_lock() %{ 8162 match(MemBarAcquireLock); 8163 ins_cost(VOLATILE_REF_COST); 8164 8165 format %{ "membar_acquire_lock (elided)" %} 8166 8167 ins_encode %{ 8168 __ block_comment("membar_acquire_lock (elided)"); 8169 %} 8170 8171 ins_pipe(pipe_serial); 8172 %} 8173 8174 instruct store_fence() %{ 8175 match(StoreFence); 8176 ins_cost(VOLATILE_REF_COST); 8177 8178 format %{ "store_fence" %} 8179 8180 ins_encode %{ 8181 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8182 %} 8183 ins_pipe(pipe_serial); 8184 %} 8185 8186 instruct unnecessary_membar_release() %{ 8187 predicate(unnecessary_release(n)); 8188 match(MemBarRelease); 8189 ins_cost(0); 8190 8191 format %{ "membar_release (elided)" %} 8192 8193 ins_encode %{ 8194 __ block_comment("membar_release (elided)"); 8195 %} 8196 ins_pipe(pipe_serial); 8197 %} 8198 8199 instruct membar_release() %{ 8200 match(MemBarRelease); 8201 ins_cost(VOLATILE_REF_COST); 8202 8203 format %{ "membar_release\n\t" 8204 "dmb ish" %} 8205 8206 ins_encode %{ 8207 __ block_comment("membar_release"); 8208 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8209 %} 8210 ins_pipe(pipe_serial); 8211 %} 8212 8213 instruct membar_storestore() %{ 8214 match(MemBarStoreStore); 8215 ins_cost(VOLATILE_REF_COST); 8216 8217 format %{ "MEMBAR-store-store" %} 8218 8219 ins_encode %{ 8220 __ membar(Assembler::StoreStore); 8221 %} 8222 ins_pipe(pipe_serial); 8223 %} 8224 8225 instruct membar_release_lock() %{ 8226 match(MemBarReleaseLock); 8227 ins_cost(VOLATILE_REF_COST); 8228 8229 format %{ "membar_release_lock (elided)" %} 8230 8231 ins_encode %{ 8232 __ block_comment("membar_release_lock (elided)"); 8233 %} 8234 8235 ins_pipe(pipe_serial); 8236 %} 8237 8238 instruct unnecessary_membar_volatile() %{ 8239 predicate(unnecessary_volatile(n)); 8240 match(MemBarVolatile); 8241 ins_cost(0); 8242 8243 format %{ "membar_volatile (elided)" %} 8244 8245 ins_encode %{ 8246 __ block_comment("membar_volatile (elided)"); 8247 %} 8248 8249 ins_pipe(pipe_serial); 8250 %} 8251 8252 instruct membar_volatile() %{ 8253 match(MemBarVolatile); 8254 ins_cost(VOLATILE_REF_COST*100); 8255 8256 format %{ "membar_volatile\n\t" 8257 "dmb ish"%} 8258 8259 ins_encode %{ 8260 __ block_comment("membar_volatile"); 8261 __ membar(Assembler::StoreLoad); 8262 %} 8263 8264 ins_pipe(pipe_serial); 8265 %} 8266 8267 // ============================================================================ 8268 // Cast/Convert Instructions 8269 8270 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8271 match(Set dst (CastX2P src)); 8272 8273 ins_cost(INSN_COST); 8274 format %{ "mov $dst, $src\t# long -> ptr" %} 8275 8276 ins_encode %{ 8277 if ($dst$$reg != $src$$reg) { 8278 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8279 } 8280 %} 8281 8282 ins_pipe(ialu_reg); 8283 %} 8284 8285 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8286 match(Set dst (CastP2X src)); 8287 8288 ins_cost(INSN_COST); 8289 format %{ "mov $dst, $src\t# ptr -> long" %} 8290 8291 ins_encode %{ 8292 if ($dst$$reg != $src$$reg) { 8293 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8294 } 8295 %} 8296 8297 ins_pipe(ialu_reg); 8298 %} 8299 8300 // Convert oop into int for vectors alignment masking 8301 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8302 match(Set dst (ConvL2I (CastP2X src))); 8303 8304 ins_cost(INSN_COST); 8305 format %{ "movw $dst, $src\t# ptr -> int" %} 8306 ins_encode %{ 8307 __ movw($dst$$Register, $src$$Register); 8308 %} 8309 8310 ins_pipe(ialu_reg); 8311 %} 8312 8313 // Convert compressed oop into int for vectors alignment masking 8314 // in case of 32bit oops (heap < 4Gb). 8315 instruct convN2I(iRegINoSp dst, iRegN src) 8316 %{ 8317 predicate(CompressedOops::shift() == 0); 8318 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8319 8320 ins_cost(INSN_COST); 8321 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8322 ins_encode %{ 8323 __ movw($dst$$Register, $src$$Register); 8324 %} 8325 8326 ins_pipe(ialu_reg); 8327 %} 8328 8329 8330 // Convert oop pointer into compressed form 8331 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8332 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8333 match(Set dst (EncodeP src)); 8334 effect(KILL cr); 8335 ins_cost(INSN_COST * 3); 8336 format %{ "encode_heap_oop $dst, $src" %} 8337 ins_encode %{ 8338 Register s = $src$$Register; 8339 Register d = $dst$$Register; 8340 __ encode_heap_oop(d, s); 8341 %} 8342 ins_pipe(ialu_reg); 8343 %} 8344 8345 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8346 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8347 match(Set dst (EncodeP src)); 8348 ins_cost(INSN_COST * 3); 8349 format %{ "encode_heap_oop_not_null $dst, $src" %} 8350 ins_encode %{ 8351 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8352 %} 8353 ins_pipe(ialu_reg); 8354 %} 8355 8356 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8357 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8358 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8359 match(Set dst (DecodeN src)); 8360 ins_cost(INSN_COST * 3); 8361 format %{ "decode_heap_oop $dst, $src" %} 8362 ins_encode %{ 8363 Register s = $src$$Register; 8364 Register d = $dst$$Register; 8365 __ decode_heap_oop(d, s); 8366 %} 8367 ins_pipe(ialu_reg); 8368 %} 8369 8370 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8371 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8372 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8373 match(Set dst (DecodeN src)); 8374 ins_cost(INSN_COST * 3); 8375 format %{ "decode_heap_oop_not_null $dst, $src" %} 8376 ins_encode %{ 8377 Register s = $src$$Register; 8378 Register d = $dst$$Register; 8379 __ decode_heap_oop_not_null(d, s); 8380 %} 8381 ins_pipe(ialu_reg); 8382 %} 8383 8384 // n.b. AArch64 implementations of encode_klass_not_null and 8385 // decode_klass_not_null do not modify the flags register so, unlike 8386 // Intel, we don't kill CR as a side effect here 8387 8388 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8389 match(Set dst (EncodePKlass src)); 8390 8391 ins_cost(INSN_COST * 3); 8392 format %{ "encode_klass_not_null $dst,$src" %} 8393 8394 ins_encode %{ 8395 Register src_reg = as_Register($src$$reg); 8396 Register dst_reg = as_Register($dst$$reg); 8397 __ encode_klass_not_null(dst_reg, src_reg); 8398 %} 8399 8400 ins_pipe(ialu_reg); 8401 %} 8402 8403 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8404 match(Set dst (DecodeNKlass src)); 8405 8406 ins_cost(INSN_COST * 3); 8407 format %{ "decode_klass_not_null $dst,$src" %} 8408 8409 ins_encode %{ 8410 Register src_reg = as_Register($src$$reg); 8411 Register dst_reg = as_Register($dst$$reg); 8412 if (dst_reg != src_reg) { 8413 __ decode_klass_not_null(dst_reg, src_reg); 8414 } else { 8415 __ decode_klass_not_null(dst_reg); 8416 } 8417 %} 8418 8419 ins_pipe(ialu_reg); 8420 %} 8421 8422 instruct checkCastPP(iRegPNoSp dst) 8423 %{ 8424 match(Set dst (CheckCastPP dst)); 8425 8426 size(0); 8427 format %{ "# checkcastPP of $dst" %} 8428 ins_encode(/* empty encoding */); 8429 ins_pipe(pipe_class_empty); 8430 %} 8431 8432 instruct castPP(iRegPNoSp dst) 8433 %{ 8434 match(Set dst (CastPP dst)); 8435 8436 size(0); 8437 format %{ "# castPP of $dst" %} 8438 ins_encode(/* empty encoding */); 8439 ins_pipe(pipe_class_empty); 8440 %} 8441 8442 instruct castII(iRegI dst) 8443 %{ 8444 match(Set dst (CastII dst)); 8445 8446 size(0); 8447 format %{ "# castII of $dst" %} 8448 ins_encode(/* empty encoding */); 8449 ins_cost(0); 8450 ins_pipe(pipe_class_empty); 8451 %} 8452 8453 instruct castLL(iRegL dst) 8454 %{ 8455 match(Set dst (CastLL dst)); 8456 8457 size(0); 8458 format %{ "# castLL of $dst" %} 8459 ins_encode(/* empty encoding */); 8460 ins_cost(0); 8461 ins_pipe(pipe_class_empty); 8462 %} 8463 8464 // ============================================================================ 8465 // Atomic operation instructions 8466 // 8467 // Intel and SPARC both implement Ideal Node LoadPLocked and 8468 // Store{PIL}Conditional instructions using a normal load for the 8469 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8470 // 8471 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8472 // pair to lock object allocations from Eden space when not using 8473 // TLABs. 8474 // 8475 // There does not appear to be a Load{IL}Locked Ideal Node and the 8476 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8477 // and to use StoreIConditional only for 32-bit and StoreLConditional 8478 // only for 64-bit. 8479 // 8480 // We implement LoadPLocked and StorePLocked instructions using, 8481 // respectively the AArch64 hw load-exclusive and store-conditional 8482 // instructions. Whereas we must implement each of 8483 // Store{IL}Conditional using a CAS which employs a pair of 8484 // instructions comprising a load-exclusive followed by a 8485 // store-conditional. 8486 8487 8488 // Locked-load (linked load) of the current heap-top 8489 // used when updating the eden heap top 8490 // implemented using ldaxr on AArch64 8491 8492 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8493 %{ 8494 match(Set dst (LoadPLocked mem)); 8495 8496 ins_cost(VOLATILE_REF_COST); 8497 8498 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8499 8500 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8501 8502 ins_pipe(pipe_serial); 8503 %} 8504 8505 // Conditional-store of the updated heap-top. 8506 // Used during allocation of the shared heap. 8507 // Sets flag (EQ) on success. 8508 // implemented using stlxr on AArch64. 8509 8510 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8511 %{ 8512 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8513 8514 ins_cost(VOLATILE_REF_COST); 8515 8516 // TODO 8517 // do we need to do a store-conditional release or can we just use a 8518 // plain store-conditional? 8519 8520 format %{ 8521 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8522 "cmpw rscratch1, zr\t# EQ on successful write" 8523 %} 8524 8525 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8526 8527 ins_pipe(pipe_serial); 8528 %} 8529 8530 8531 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8532 // when attempting to rebias a lock towards the current thread. We 8533 // must use the acquire form of cmpxchg in order to guarantee acquire 8534 // semantics in this case. 8535 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8536 %{ 8537 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8538 8539 ins_cost(VOLATILE_REF_COST); 8540 8541 format %{ 8542 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8543 "cmpw rscratch1, zr\t# EQ on successful write" 8544 %} 8545 8546 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8547 8548 ins_pipe(pipe_slow); 8549 %} 8550 8551 // storeIConditional also has acquire semantics, for no better reason 8552 // than matching storeLConditional. At the time of writing this 8553 // comment storeIConditional was not used anywhere by AArch64. 8554 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8555 %{ 8556 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8557 8558 ins_cost(VOLATILE_REF_COST); 8559 8560 format %{ 8561 "cmpxchgw 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_cmpxchgw_acq(mem, oldval, newval)); 8566 8567 ins_pipe(pipe_slow); 8568 %} 8569 8570 // standard CompareAndSwapX when we are using barriers 8571 // these have higher priority than the rules selected by a predicate 8572 8573 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8574 // can't match them 8575 8576 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8577 8578 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8579 ins_cost(2 * VOLATILE_REF_COST); 8580 8581 effect(KILL cr); 8582 8583 format %{ 8584 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8585 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8586 %} 8587 8588 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8589 aarch64_enc_cset_eq(res)); 8590 8591 ins_pipe(pipe_slow); 8592 %} 8593 8594 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8595 8596 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8597 ins_cost(2 * VOLATILE_REF_COST); 8598 8599 effect(KILL cr); 8600 8601 format %{ 8602 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8603 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8604 %} 8605 8606 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8607 aarch64_enc_cset_eq(res)); 8608 8609 ins_pipe(pipe_slow); 8610 %} 8611 8612 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8613 8614 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8615 ins_cost(2 * VOLATILE_REF_COST); 8616 8617 effect(KILL cr); 8618 8619 format %{ 8620 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8621 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8622 %} 8623 8624 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8625 aarch64_enc_cset_eq(res)); 8626 8627 ins_pipe(pipe_slow); 8628 %} 8629 8630 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8631 8632 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8633 ins_cost(2 * VOLATILE_REF_COST); 8634 8635 effect(KILL cr); 8636 8637 format %{ 8638 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8639 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8640 %} 8641 8642 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8643 aarch64_enc_cset_eq(res)); 8644 8645 ins_pipe(pipe_slow); 8646 %} 8647 8648 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8649 8650 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8651 predicate(n->as_LoadStore()->barrier_data() == 0); 8652 ins_cost(2 * VOLATILE_REF_COST); 8653 8654 effect(KILL cr); 8655 8656 format %{ 8657 "cmpxchg $mem, $oldval, $newval\t# (ptr) 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 compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8668 8669 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8670 ins_cost(2 * VOLATILE_REF_COST); 8671 8672 effect(KILL cr); 8673 8674 format %{ 8675 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8676 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8677 %} 8678 8679 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8680 aarch64_enc_cset_eq(res)); 8681 8682 ins_pipe(pipe_slow); 8683 %} 8684 8685 // alternative CompareAndSwapX when we are eliding barriers 8686 8687 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8688 8689 predicate(needs_acquiring_load_exclusive(n)); 8690 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8691 ins_cost(VOLATILE_REF_COST); 8692 8693 effect(KILL cr); 8694 8695 format %{ 8696 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8697 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8698 %} 8699 8700 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8701 aarch64_enc_cset_eq(res)); 8702 8703 ins_pipe(pipe_slow); 8704 %} 8705 8706 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8707 8708 predicate(needs_acquiring_load_exclusive(n)); 8709 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8710 ins_cost(VOLATILE_REF_COST); 8711 8712 effect(KILL cr); 8713 8714 format %{ 8715 "cmpxchgs_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_cmpxchgs_acq(mem, oldval, newval), 8720 aarch64_enc_cset_eq(res)); 8721 8722 ins_pipe(pipe_slow); 8723 %} 8724 8725 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8726 8727 predicate(needs_acquiring_load_exclusive(n)); 8728 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8729 ins_cost(VOLATILE_REF_COST); 8730 8731 effect(KILL cr); 8732 8733 format %{ 8734 "cmpxchgw_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_cmpxchgw_acq(mem, oldval, newval), 8739 aarch64_enc_cset_eq(res)); 8740 8741 ins_pipe(pipe_slow); 8742 %} 8743 8744 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8745 8746 predicate(needs_acquiring_load_exclusive(n)); 8747 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8748 ins_cost(VOLATILE_REF_COST); 8749 8750 effect(KILL cr); 8751 8752 format %{ 8753 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8754 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8755 %} 8756 8757 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8758 aarch64_enc_cset_eq(res)); 8759 8760 ins_pipe(pipe_slow); 8761 %} 8762 8763 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8764 8765 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8766 match(Set res (CompareAndSwapP 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# (ptr) 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 compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8783 8784 predicate(needs_acquiring_load_exclusive(n)); 8785 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8786 ins_cost(VOLATILE_REF_COST); 8787 8788 effect(KILL cr); 8789 8790 format %{ 8791 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8792 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8793 %} 8794 8795 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8796 aarch64_enc_cset_eq(res)); 8797 8798 ins_pipe(pipe_slow); 8799 %} 8800 8801 8802 // --------------------------------------------------------------------- 8803 8804 8805 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8806 8807 // Sundry CAS operations. Note that release is always true, 8808 // regardless of the memory ordering of the CAS. This is because we 8809 // need the volatile case to be sequentially consistent but there is 8810 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8811 // can't check the type of memory ordering here, so we always emit a 8812 // STLXR. 8813 8814 // This section is generated from aarch64_ad_cas.m4 8815 8816 8817 8818 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8819 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8820 ins_cost(2 * VOLATILE_REF_COST); 8821 effect(TEMP_DEF res, KILL cr); 8822 format %{ 8823 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8824 %} 8825 ins_encode %{ 8826 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8827 Assembler::byte, /*acquire*/ false, /*release*/ true, 8828 /*weak*/ false, $res$$Register); 8829 __ sxtbw($res$$Register, $res$$Register); 8830 %} 8831 ins_pipe(pipe_slow); 8832 %} 8833 8834 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8835 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8836 ins_cost(2 * VOLATILE_REF_COST); 8837 effect(TEMP_DEF res, KILL cr); 8838 format %{ 8839 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8840 %} 8841 ins_encode %{ 8842 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8843 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8844 /*weak*/ false, $res$$Register); 8845 __ sxthw($res$$Register, $res$$Register); 8846 %} 8847 ins_pipe(pipe_slow); 8848 %} 8849 8850 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8851 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8852 ins_cost(2 * VOLATILE_REF_COST); 8853 effect(TEMP_DEF res, KILL cr); 8854 format %{ 8855 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8856 %} 8857 ins_encode %{ 8858 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8859 Assembler::word, /*acquire*/ false, /*release*/ true, 8860 /*weak*/ false, $res$$Register); 8861 %} 8862 ins_pipe(pipe_slow); 8863 %} 8864 8865 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8866 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8867 ins_cost(2 * VOLATILE_REF_COST); 8868 effect(TEMP_DEF res, KILL cr); 8869 format %{ 8870 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8871 %} 8872 ins_encode %{ 8873 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8874 Assembler::xword, /*acquire*/ false, /*release*/ true, 8875 /*weak*/ false, $res$$Register); 8876 %} 8877 ins_pipe(pipe_slow); 8878 %} 8879 8880 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8881 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8882 ins_cost(2 * VOLATILE_REF_COST); 8883 effect(TEMP_DEF res, KILL cr); 8884 format %{ 8885 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8886 %} 8887 ins_encode %{ 8888 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8889 Assembler::word, /*acquire*/ false, /*release*/ true, 8890 /*weak*/ false, $res$$Register); 8891 %} 8892 ins_pipe(pipe_slow); 8893 %} 8894 8895 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8896 predicate(n->as_LoadStore()->barrier_data() == 0); 8897 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8898 ins_cost(2 * VOLATILE_REF_COST); 8899 effect(TEMP_DEF res, KILL cr); 8900 format %{ 8901 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8902 %} 8903 ins_encode %{ 8904 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8905 Assembler::xword, /*acquire*/ false, /*release*/ true, 8906 /*weak*/ false, $res$$Register); 8907 %} 8908 ins_pipe(pipe_slow); 8909 %} 8910 8911 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8912 predicate(needs_acquiring_load_exclusive(n)); 8913 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8914 ins_cost(VOLATILE_REF_COST); 8915 effect(TEMP_DEF res, KILL cr); 8916 format %{ 8917 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8918 %} 8919 ins_encode %{ 8920 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8921 Assembler::byte, /*acquire*/ true, /*release*/ true, 8922 /*weak*/ false, $res$$Register); 8923 __ sxtbw($res$$Register, $res$$Register); 8924 %} 8925 ins_pipe(pipe_slow); 8926 %} 8927 8928 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8929 predicate(needs_acquiring_load_exclusive(n)); 8930 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8931 ins_cost(VOLATILE_REF_COST); 8932 effect(TEMP_DEF res, KILL cr); 8933 format %{ 8934 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8935 %} 8936 ins_encode %{ 8937 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8938 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8939 /*weak*/ false, $res$$Register); 8940 __ sxthw($res$$Register, $res$$Register); 8941 %} 8942 ins_pipe(pipe_slow); 8943 %} 8944 8945 8946 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8947 predicate(needs_acquiring_load_exclusive(n)); 8948 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8949 ins_cost(VOLATILE_REF_COST); 8950 effect(TEMP_DEF res, KILL cr); 8951 format %{ 8952 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8953 %} 8954 ins_encode %{ 8955 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8956 Assembler::word, /*acquire*/ true, /*release*/ true, 8957 /*weak*/ false, $res$$Register); 8958 %} 8959 ins_pipe(pipe_slow); 8960 %} 8961 8962 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8963 predicate(needs_acquiring_load_exclusive(n)); 8964 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8965 ins_cost(VOLATILE_REF_COST); 8966 effect(TEMP_DEF res, KILL cr); 8967 format %{ 8968 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8969 %} 8970 ins_encode %{ 8971 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8972 Assembler::xword, /*acquire*/ true, /*release*/ true, 8973 /*weak*/ false, $res$$Register); 8974 %} 8975 ins_pipe(pipe_slow); 8976 %} 8977 8978 8979 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8980 predicate(needs_acquiring_load_exclusive(n)); 8981 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8982 ins_cost(VOLATILE_REF_COST); 8983 effect(TEMP_DEF res, KILL cr); 8984 format %{ 8985 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8986 %} 8987 ins_encode %{ 8988 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8989 Assembler::word, /*acquire*/ true, /*release*/ true, 8990 /*weak*/ false, $res$$Register); 8991 %} 8992 ins_pipe(pipe_slow); 8993 %} 8994 8995 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8996 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8997 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8998 ins_cost(VOLATILE_REF_COST); 8999 effect(TEMP_DEF res, KILL cr); 9000 format %{ 9001 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9002 %} 9003 ins_encode %{ 9004 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9005 Assembler::xword, /*acquire*/ true, /*release*/ true, 9006 /*weak*/ false, $res$$Register); 9007 %} 9008 ins_pipe(pipe_slow); 9009 %} 9010 9011 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9012 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9013 ins_cost(2 * VOLATILE_REF_COST); 9014 effect(KILL cr); 9015 format %{ 9016 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9017 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9018 %} 9019 ins_encode %{ 9020 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9021 Assembler::byte, /*acquire*/ false, /*release*/ true, 9022 /*weak*/ true, noreg); 9023 __ csetw($res$$Register, Assembler::EQ); 9024 %} 9025 ins_pipe(pipe_slow); 9026 %} 9027 9028 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9029 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9030 ins_cost(2 * VOLATILE_REF_COST); 9031 effect(KILL cr); 9032 format %{ 9033 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9034 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9035 %} 9036 ins_encode %{ 9037 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9038 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9039 /*weak*/ true, noreg); 9040 __ csetw($res$$Register, Assembler::EQ); 9041 %} 9042 ins_pipe(pipe_slow); 9043 %} 9044 9045 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9046 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9047 ins_cost(2 * VOLATILE_REF_COST); 9048 effect(KILL cr); 9049 format %{ 9050 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9051 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9052 %} 9053 ins_encode %{ 9054 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9055 Assembler::word, /*acquire*/ false, /*release*/ true, 9056 /*weak*/ true, noreg); 9057 __ csetw($res$$Register, Assembler::EQ); 9058 %} 9059 ins_pipe(pipe_slow); 9060 %} 9061 9062 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9063 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9064 ins_cost(2 * VOLATILE_REF_COST); 9065 effect(KILL cr); 9066 format %{ 9067 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9068 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9069 %} 9070 ins_encode %{ 9071 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9072 Assembler::xword, /*acquire*/ false, /*release*/ true, 9073 /*weak*/ true, noreg); 9074 __ csetw($res$$Register, Assembler::EQ); 9075 %} 9076 ins_pipe(pipe_slow); 9077 %} 9078 9079 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9080 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9081 ins_cost(2 * VOLATILE_REF_COST); 9082 effect(KILL cr); 9083 format %{ 9084 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9085 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9086 %} 9087 ins_encode %{ 9088 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9089 Assembler::word, /*acquire*/ false, /*release*/ true, 9090 /*weak*/ true, noreg); 9091 __ csetw($res$$Register, Assembler::EQ); 9092 %} 9093 ins_pipe(pipe_slow); 9094 %} 9095 9096 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9097 predicate(n->as_LoadStore()->barrier_data() == 0); 9098 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9099 ins_cost(2 * VOLATILE_REF_COST); 9100 effect(KILL cr); 9101 format %{ 9102 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9103 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9104 %} 9105 ins_encode %{ 9106 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9107 Assembler::xword, /*acquire*/ false, /*release*/ true, 9108 /*weak*/ true, noreg); 9109 __ csetw($res$$Register, Assembler::EQ); 9110 %} 9111 ins_pipe(pipe_slow); 9112 %} 9113 9114 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9115 predicate(needs_acquiring_load_exclusive(n)); 9116 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9117 ins_cost(VOLATILE_REF_COST); 9118 effect(KILL cr); 9119 format %{ 9120 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9121 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9122 %} 9123 ins_encode %{ 9124 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9125 Assembler::byte, /*acquire*/ true, /*release*/ true, 9126 /*weak*/ true, noreg); 9127 __ csetw($res$$Register, Assembler::EQ); 9128 %} 9129 ins_pipe(pipe_slow); 9130 %} 9131 9132 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9133 predicate(needs_acquiring_load_exclusive(n)); 9134 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9135 ins_cost(VOLATILE_REF_COST); 9136 effect(KILL cr); 9137 format %{ 9138 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9139 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9140 %} 9141 ins_encode %{ 9142 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9143 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9144 /*weak*/ true, noreg); 9145 __ csetw($res$$Register, Assembler::EQ); 9146 %} 9147 ins_pipe(pipe_slow); 9148 %} 9149 9150 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9151 predicate(needs_acquiring_load_exclusive(n)); 9152 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9153 ins_cost(VOLATILE_REF_COST); 9154 effect(KILL cr); 9155 format %{ 9156 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9157 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9158 %} 9159 ins_encode %{ 9160 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9161 Assembler::word, /*acquire*/ true, /*release*/ true, 9162 /*weak*/ true, noreg); 9163 __ csetw($res$$Register, Assembler::EQ); 9164 %} 9165 ins_pipe(pipe_slow); 9166 %} 9167 9168 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9169 predicate(needs_acquiring_load_exclusive(n)); 9170 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9171 ins_cost(VOLATILE_REF_COST); 9172 effect(KILL cr); 9173 format %{ 9174 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9175 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9176 %} 9177 ins_encode %{ 9178 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9179 Assembler::xword, /*acquire*/ true, /*release*/ true, 9180 /*weak*/ true, noreg); 9181 __ csetw($res$$Register, Assembler::EQ); 9182 %} 9183 ins_pipe(pipe_slow); 9184 %} 9185 9186 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9187 predicate(needs_acquiring_load_exclusive(n)); 9188 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9189 ins_cost(VOLATILE_REF_COST); 9190 effect(KILL cr); 9191 format %{ 9192 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9193 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9194 %} 9195 ins_encode %{ 9196 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9197 Assembler::word, /*acquire*/ true, /*release*/ true, 9198 /*weak*/ true, noreg); 9199 __ csetw($res$$Register, Assembler::EQ); 9200 %} 9201 ins_pipe(pipe_slow); 9202 %} 9203 9204 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9205 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9206 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9207 ins_cost(VOLATILE_REF_COST); 9208 effect(KILL cr); 9209 format %{ 9210 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9211 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9212 %} 9213 ins_encode %{ 9214 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9215 Assembler::xword, /*acquire*/ true, /*release*/ true, 9216 /*weak*/ true, noreg); 9217 __ csetw($res$$Register, Assembler::EQ); 9218 %} 9219 ins_pipe(pipe_slow); 9220 %} 9221 9222 // END This section of the file is automatically generated. Do not edit -------------- 9223 // --------------------------------------------------------------------- 9224 9225 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9226 match(Set prev (GetAndSetI mem newv)); 9227 ins_cost(2 * VOLATILE_REF_COST); 9228 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9229 ins_encode %{ 9230 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9231 %} 9232 ins_pipe(pipe_serial); 9233 %} 9234 9235 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9236 match(Set prev (GetAndSetL mem newv)); 9237 ins_cost(2 * VOLATILE_REF_COST); 9238 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9239 ins_encode %{ 9240 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9241 %} 9242 ins_pipe(pipe_serial); 9243 %} 9244 9245 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9246 match(Set prev (GetAndSetN mem newv)); 9247 ins_cost(2 * VOLATILE_REF_COST); 9248 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9249 ins_encode %{ 9250 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9251 %} 9252 ins_pipe(pipe_serial); 9253 %} 9254 9255 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9256 predicate(n->as_LoadStore()->barrier_data() == 0); 9257 match(Set prev (GetAndSetP mem newv)); 9258 ins_cost(2 * VOLATILE_REF_COST); 9259 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9260 ins_encode %{ 9261 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9262 %} 9263 ins_pipe(pipe_serial); 9264 %} 9265 9266 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9267 predicate(needs_acquiring_load_exclusive(n)); 9268 match(Set prev (GetAndSetI mem newv)); 9269 ins_cost(VOLATILE_REF_COST); 9270 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9271 ins_encode %{ 9272 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9273 %} 9274 ins_pipe(pipe_serial); 9275 %} 9276 9277 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9278 predicate(needs_acquiring_load_exclusive(n)); 9279 match(Set prev (GetAndSetL mem newv)); 9280 ins_cost(VOLATILE_REF_COST); 9281 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9282 ins_encode %{ 9283 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9284 %} 9285 ins_pipe(pipe_serial); 9286 %} 9287 9288 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9289 predicate(needs_acquiring_load_exclusive(n)); 9290 match(Set prev (GetAndSetN mem newv)); 9291 ins_cost(VOLATILE_REF_COST); 9292 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9293 ins_encode %{ 9294 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9295 %} 9296 ins_pipe(pipe_serial); 9297 %} 9298 9299 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9300 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9301 match(Set prev (GetAndSetP mem newv)); 9302 ins_cost(VOLATILE_REF_COST); 9303 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9304 ins_encode %{ 9305 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9306 %} 9307 ins_pipe(pipe_serial); 9308 %} 9309 9310 9311 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9312 match(Set newval (GetAndAddL mem incr)); 9313 ins_cost(2 * VOLATILE_REF_COST + 1); 9314 format %{ "get_and_addL $newval, [$mem], $incr" %} 9315 ins_encode %{ 9316 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9317 %} 9318 ins_pipe(pipe_serial); 9319 %} 9320 9321 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9322 predicate(n->as_LoadStore()->result_not_used()); 9323 match(Set dummy (GetAndAddL mem incr)); 9324 ins_cost(2 * VOLATILE_REF_COST); 9325 format %{ "get_and_addL [$mem], $incr" %} 9326 ins_encode %{ 9327 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9328 %} 9329 ins_pipe(pipe_serial); 9330 %} 9331 9332 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9333 match(Set newval (GetAndAddL mem incr)); 9334 ins_cost(2 * VOLATILE_REF_COST + 1); 9335 format %{ "get_and_addL $newval, [$mem], $incr" %} 9336 ins_encode %{ 9337 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9338 %} 9339 ins_pipe(pipe_serial); 9340 %} 9341 9342 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9343 predicate(n->as_LoadStore()->result_not_used()); 9344 match(Set dummy (GetAndAddL mem incr)); 9345 ins_cost(2 * VOLATILE_REF_COST); 9346 format %{ "get_and_addL [$mem], $incr" %} 9347 ins_encode %{ 9348 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9349 %} 9350 ins_pipe(pipe_serial); 9351 %} 9352 9353 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9354 match(Set newval (GetAndAddI mem incr)); 9355 ins_cost(2 * VOLATILE_REF_COST + 1); 9356 format %{ "get_and_addI $newval, [$mem], $incr" %} 9357 ins_encode %{ 9358 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9359 %} 9360 ins_pipe(pipe_serial); 9361 %} 9362 9363 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9364 predicate(n->as_LoadStore()->result_not_used()); 9365 match(Set dummy (GetAndAddI mem incr)); 9366 ins_cost(2 * VOLATILE_REF_COST); 9367 format %{ "get_and_addI [$mem], $incr" %} 9368 ins_encode %{ 9369 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9370 %} 9371 ins_pipe(pipe_serial); 9372 %} 9373 9374 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9375 match(Set newval (GetAndAddI mem incr)); 9376 ins_cost(2 * VOLATILE_REF_COST + 1); 9377 format %{ "get_and_addI $newval, [$mem], $incr" %} 9378 ins_encode %{ 9379 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9380 %} 9381 ins_pipe(pipe_serial); 9382 %} 9383 9384 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9385 predicate(n->as_LoadStore()->result_not_used()); 9386 match(Set dummy (GetAndAddI mem incr)); 9387 ins_cost(2 * VOLATILE_REF_COST); 9388 format %{ "get_and_addI [$mem], $incr" %} 9389 ins_encode %{ 9390 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9391 %} 9392 ins_pipe(pipe_serial); 9393 %} 9394 9395 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9396 predicate(needs_acquiring_load_exclusive(n)); 9397 match(Set newval (GetAndAddL mem incr)); 9398 ins_cost(VOLATILE_REF_COST + 1); 9399 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9400 ins_encode %{ 9401 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9402 %} 9403 ins_pipe(pipe_serial); 9404 %} 9405 9406 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9407 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9408 match(Set dummy (GetAndAddL mem incr)); 9409 ins_cost(VOLATILE_REF_COST); 9410 format %{ "get_and_addL_acq [$mem], $incr" %} 9411 ins_encode %{ 9412 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9413 %} 9414 ins_pipe(pipe_serial); 9415 %} 9416 9417 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9418 predicate(needs_acquiring_load_exclusive(n)); 9419 match(Set newval (GetAndAddL mem incr)); 9420 ins_cost(VOLATILE_REF_COST + 1); 9421 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9422 ins_encode %{ 9423 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9424 %} 9425 ins_pipe(pipe_serial); 9426 %} 9427 9428 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9429 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9430 match(Set dummy (GetAndAddL mem incr)); 9431 ins_cost(VOLATILE_REF_COST); 9432 format %{ "get_and_addL_acq [$mem], $incr" %} 9433 ins_encode %{ 9434 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9435 %} 9436 ins_pipe(pipe_serial); 9437 %} 9438 9439 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9440 predicate(needs_acquiring_load_exclusive(n)); 9441 match(Set newval (GetAndAddI mem incr)); 9442 ins_cost(VOLATILE_REF_COST + 1); 9443 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9444 ins_encode %{ 9445 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9446 %} 9447 ins_pipe(pipe_serial); 9448 %} 9449 9450 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9451 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9452 match(Set dummy (GetAndAddI mem incr)); 9453 ins_cost(VOLATILE_REF_COST); 9454 format %{ "get_and_addI_acq [$mem], $incr" %} 9455 ins_encode %{ 9456 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9457 %} 9458 ins_pipe(pipe_serial); 9459 %} 9460 9461 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9462 predicate(needs_acquiring_load_exclusive(n)); 9463 match(Set newval (GetAndAddI mem incr)); 9464 ins_cost(VOLATILE_REF_COST + 1); 9465 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9466 ins_encode %{ 9467 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9468 %} 9469 ins_pipe(pipe_serial); 9470 %} 9471 9472 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9473 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9474 match(Set dummy (GetAndAddI mem incr)); 9475 ins_cost(VOLATILE_REF_COST); 9476 format %{ "get_and_addI_acq [$mem], $incr" %} 9477 ins_encode %{ 9478 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9479 %} 9480 ins_pipe(pipe_serial); 9481 %} 9482 9483 // Manifest a CmpL result in an integer register. 9484 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9485 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9486 %{ 9487 match(Set dst (CmpL3 src1 src2)); 9488 effect(KILL flags); 9489 9490 ins_cost(INSN_COST * 6); 9491 format %{ 9492 "cmp $src1, $src2" 9493 "csetw $dst, ne" 9494 "cnegw $dst, lt" 9495 %} 9496 // format %{ "CmpL3 $dst, $src1, $src2" %} 9497 ins_encode %{ 9498 __ cmp($src1$$Register, $src2$$Register); 9499 __ csetw($dst$$Register, Assembler::NE); 9500 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9501 %} 9502 9503 ins_pipe(pipe_class_default); 9504 %} 9505 9506 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9507 %{ 9508 match(Set dst (CmpL3 src1 src2)); 9509 effect(KILL flags); 9510 9511 ins_cost(INSN_COST * 6); 9512 format %{ 9513 "cmp $src1, $src2" 9514 "csetw $dst, ne" 9515 "cnegw $dst, lt" 9516 %} 9517 ins_encode %{ 9518 int32_t con = (int32_t)$src2$$constant; 9519 if (con < 0) { 9520 __ adds(zr, $src1$$Register, -con); 9521 } else { 9522 __ subs(zr, $src1$$Register, con); 9523 } 9524 __ csetw($dst$$Register, Assembler::NE); 9525 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9526 %} 9527 9528 ins_pipe(pipe_class_default); 9529 %} 9530 9531 // ============================================================================ 9532 // Conditional Move Instructions 9533 9534 // n.b. we have identical rules for both a signed compare op (cmpOp) 9535 // and an unsigned compare op (cmpOpU). it would be nice if we could 9536 // define an op class which merged both inputs and use it to type the 9537 // argument to a single rule. unfortunatelyt his fails because the 9538 // opclass does not live up to the COND_INTER interface of its 9539 // component operands. When the generic code tries to negate the 9540 // operand it ends up running the generci Machoper::negate method 9541 // which throws a ShouldNotHappen. So, we have to provide two flavours 9542 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9543 9544 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9545 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9546 9547 ins_cost(INSN_COST * 2); 9548 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9549 9550 ins_encode %{ 9551 __ cselw(as_Register($dst$$reg), 9552 as_Register($src2$$reg), 9553 as_Register($src1$$reg), 9554 (Assembler::Condition)$cmp$$cmpcode); 9555 %} 9556 9557 ins_pipe(icond_reg_reg); 9558 %} 9559 9560 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9561 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9562 9563 ins_cost(INSN_COST * 2); 9564 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9565 9566 ins_encode %{ 9567 __ cselw(as_Register($dst$$reg), 9568 as_Register($src2$$reg), 9569 as_Register($src1$$reg), 9570 (Assembler::Condition)$cmp$$cmpcode); 9571 %} 9572 9573 ins_pipe(icond_reg_reg); 9574 %} 9575 9576 // special cases where one arg is zero 9577 9578 // n.b. this is selected in preference to the rule above because it 9579 // avoids loading constant 0 into a source register 9580 9581 // TODO 9582 // we ought only to be able to cull one of these variants as the ideal 9583 // transforms ought always to order the zero consistently (to left/right?) 9584 9585 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9586 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9587 9588 ins_cost(INSN_COST * 2); 9589 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9590 9591 ins_encode %{ 9592 __ cselw(as_Register($dst$$reg), 9593 as_Register($src$$reg), 9594 zr, 9595 (Assembler::Condition)$cmp$$cmpcode); 9596 %} 9597 9598 ins_pipe(icond_reg); 9599 %} 9600 9601 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9602 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9603 9604 ins_cost(INSN_COST * 2); 9605 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9606 9607 ins_encode %{ 9608 __ cselw(as_Register($dst$$reg), 9609 as_Register($src$$reg), 9610 zr, 9611 (Assembler::Condition)$cmp$$cmpcode); 9612 %} 9613 9614 ins_pipe(icond_reg); 9615 %} 9616 9617 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9618 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9619 9620 ins_cost(INSN_COST * 2); 9621 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9622 9623 ins_encode %{ 9624 __ cselw(as_Register($dst$$reg), 9625 zr, 9626 as_Register($src$$reg), 9627 (Assembler::Condition)$cmp$$cmpcode); 9628 %} 9629 9630 ins_pipe(icond_reg); 9631 %} 9632 9633 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9634 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9635 9636 ins_cost(INSN_COST * 2); 9637 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9638 9639 ins_encode %{ 9640 __ cselw(as_Register($dst$$reg), 9641 zr, 9642 as_Register($src$$reg), 9643 (Assembler::Condition)$cmp$$cmpcode); 9644 %} 9645 9646 ins_pipe(icond_reg); 9647 %} 9648 9649 // special case for creating a boolean 0 or 1 9650 9651 // n.b. this is selected in preference to the rule above because it 9652 // avoids loading constants 0 and 1 into a source register 9653 9654 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9655 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9656 9657 ins_cost(INSN_COST * 2); 9658 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9659 9660 ins_encode %{ 9661 // equivalently 9662 // cset(as_Register($dst$$reg), 9663 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9664 __ csincw(as_Register($dst$$reg), 9665 zr, 9666 zr, 9667 (Assembler::Condition)$cmp$$cmpcode); 9668 %} 9669 9670 ins_pipe(icond_none); 9671 %} 9672 9673 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU 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# unsigned, 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 cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9693 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9694 9695 ins_cost(INSN_COST * 2); 9696 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9697 9698 ins_encode %{ 9699 __ csel(as_Register($dst$$reg), 9700 as_Register($src2$$reg), 9701 as_Register($src1$$reg), 9702 (Assembler::Condition)$cmp$$cmpcode); 9703 %} 9704 9705 ins_pipe(icond_reg_reg); 9706 %} 9707 9708 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9709 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9710 9711 ins_cost(INSN_COST * 2); 9712 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9713 9714 ins_encode %{ 9715 __ csel(as_Register($dst$$reg), 9716 as_Register($src2$$reg), 9717 as_Register($src1$$reg), 9718 (Assembler::Condition)$cmp$$cmpcode); 9719 %} 9720 9721 ins_pipe(icond_reg_reg); 9722 %} 9723 9724 // special cases where one arg is zero 9725 9726 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9727 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9728 9729 ins_cost(INSN_COST * 2); 9730 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9731 9732 ins_encode %{ 9733 __ csel(as_Register($dst$$reg), 9734 zr, 9735 as_Register($src$$reg), 9736 (Assembler::Condition)$cmp$$cmpcode); 9737 %} 9738 9739 ins_pipe(icond_reg); 9740 %} 9741 9742 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9743 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9744 9745 ins_cost(INSN_COST * 2); 9746 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9747 9748 ins_encode %{ 9749 __ csel(as_Register($dst$$reg), 9750 zr, 9751 as_Register($src$$reg), 9752 (Assembler::Condition)$cmp$$cmpcode); 9753 %} 9754 9755 ins_pipe(icond_reg); 9756 %} 9757 9758 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9759 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9760 9761 ins_cost(INSN_COST * 2); 9762 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9763 9764 ins_encode %{ 9765 __ csel(as_Register($dst$$reg), 9766 as_Register($src$$reg), 9767 zr, 9768 (Assembler::Condition)$cmp$$cmpcode); 9769 %} 9770 9771 ins_pipe(icond_reg); 9772 %} 9773 9774 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9775 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9776 9777 ins_cost(INSN_COST * 2); 9778 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9779 9780 ins_encode %{ 9781 __ csel(as_Register($dst$$reg), 9782 as_Register($src$$reg), 9783 zr, 9784 (Assembler::Condition)$cmp$$cmpcode); 9785 %} 9786 9787 ins_pipe(icond_reg); 9788 %} 9789 9790 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9791 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9792 9793 ins_cost(INSN_COST * 2); 9794 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9795 9796 ins_encode %{ 9797 __ csel(as_Register($dst$$reg), 9798 as_Register($src2$$reg), 9799 as_Register($src1$$reg), 9800 (Assembler::Condition)$cmp$$cmpcode); 9801 %} 9802 9803 ins_pipe(icond_reg_reg); 9804 %} 9805 9806 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9807 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9808 9809 ins_cost(INSN_COST * 2); 9810 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9811 9812 ins_encode %{ 9813 __ csel(as_Register($dst$$reg), 9814 as_Register($src2$$reg), 9815 as_Register($src1$$reg), 9816 (Assembler::Condition)$cmp$$cmpcode); 9817 %} 9818 9819 ins_pipe(icond_reg_reg); 9820 %} 9821 9822 // special cases where one arg is zero 9823 9824 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9825 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9826 9827 ins_cost(INSN_COST * 2); 9828 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9829 9830 ins_encode %{ 9831 __ csel(as_Register($dst$$reg), 9832 zr, 9833 as_Register($src$$reg), 9834 (Assembler::Condition)$cmp$$cmpcode); 9835 %} 9836 9837 ins_pipe(icond_reg); 9838 %} 9839 9840 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9841 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9842 9843 ins_cost(INSN_COST * 2); 9844 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9845 9846 ins_encode %{ 9847 __ csel(as_Register($dst$$reg), 9848 zr, 9849 as_Register($src$$reg), 9850 (Assembler::Condition)$cmp$$cmpcode); 9851 %} 9852 9853 ins_pipe(icond_reg); 9854 %} 9855 9856 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9857 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9858 9859 ins_cost(INSN_COST * 2); 9860 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9861 9862 ins_encode %{ 9863 __ csel(as_Register($dst$$reg), 9864 as_Register($src$$reg), 9865 zr, 9866 (Assembler::Condition)$cmp$$cmpcode); 9867 %} 9868 9869 ins_pipe(icond_reg); 9870 %} 9871 9872 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9873 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9874 9875 ins_cost(INSN_COST * 2); 9876 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9877 9878 ins_encode %{ 9879 __ csel(as_Register($dst$$reg), 9880 as_Register($src$$reg), 9881 zr, 9882 (Assembler::Condition)$cmp$$cmpcode); 9883 %} 9884 9885 ins_pipe(icond_reg); 9886 %} 9887 9888 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9889 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9890 9891 ins_cost(INSN_COST * 2); 9892 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9893 9894 ins_encode %{ 9895 __ cselw(as_Register($dst$$reg), 9896 as_Register($src2$$reg), 9897 as_Register($src1$$reg), 9898 (Assembler::Condition)$cmp$$cmpcode); 9899 %} 9900 9901 ins_pipe(icond_reg_reg); 9902 %} 9903 9904 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9905 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9906 9907 ins_cost(INSN_COST * 2); 9908 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9909 9910 ins_encode %{ 9911 __ cselw(as_Register($dst$$reg), 9912 as_Register($src2$$reg), 9913 as_Register($src1$$reg), 9914 (Assembler::Condition)$cmp$$cmpcode); 9915 %} 9916 9917 ins_pipe(icond_reg_reg); 9918 %} 9919 9920 // special cases where one arg is zero 9921 9922 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9923 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9924 9925 ins_cost(INSN_COST * 2); 9926 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9927 9928 ins_encode %{ 9929 __ cselw(as_Register($dst$$reg), 9930 zr, 9931 as_Register($src$$reg), 9932 (Assembler::Condition)$cmp$$cmpcode); 9933 %} 9934 9935 ins_pipe(icond_reg); 9936 %} 9937 9938 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9939 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9940 9941 ins_cost(INSN_COST * 2); 9942 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9943 9944 ins_encode %{ 9945 __ cselw(as_Register($dst$$reg), 9946 zr, 9947 as_Register($src$$reg), 9948 (Assembler::Condition)$cmp$$cmpcode); 9949 %} 9950 9951 ins_pipe(icond_reg); 9952 %} 9953 9954 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9955 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9956 9957 ins_cost(INSN_COST * 2); 9958 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9959 9960 ins_encode %{ 9961 __ cselw(as_Register($dst$$reg), 9962 as_Register($src$$reg), 9963 zr, 9964 (Assembler::Condition)$cmp$$cmpcode); 9965 %} 9966 9967 ins_pipe(icond_reg); 9968 %} 9969 9970 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9971 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9972 9973 ins_cost(INSN_COST * 2); 9974 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9975 9976 ins_encode %{ 9977 __ cselw(as_Register($dst$$reg), 9978 as_Register($src$$reg), 9979 zr, 9980 (Assembler::Condition)$cmp$$cmpcode); 9981 %} 9982 9983 ins_pipe(icond_reg); 9984 %} 9985 9986 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9987 %{ 9988 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9989 9990 ins_cost(INSN_COST * 3); 9991 9992 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9993 ins_encode %{ 9994 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9995 __ fcsels(as_FloatRegister($dst$$reg), 9996 as_FloatRegister($src2$$reg), 9997 as_FloatRegister($src1$$reg), 9998 cond); 9999 %} 10000 10001 ins_pipe(fp_cond_reg_reg_s); 10002 %} 10003 10004 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10005 %{ 10006 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10007 10008 ins_cost(INSN_COST * 3); 10009 10010 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10011 ins_encode %{ 10012 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10013 __ fcsels(as_FloatRegister($dst$$reg), 10014 as_FloatRegister($src2$$reg), 10015 as_FloatRegister($src1$$reg), 10016 cond); 10017 %} 10018 10019 ins_pipe(fp_cond_reg_reg_s); 10020 %} 10021 10022 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10023 %{ 10024 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10025 10026 ins_cost(INSN_COST * 3); 10027 10028 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10029 ins_encode %{ 10030 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10031 __ fcseld(as_FloatRegister($dst$$reg), 10032 as_FloatRegister($src2$$reg), 10033 as_FloatRegister($src1$$reg), 10034 cond); 10035 %} 10036 10037 ins_pipe(fp_cond_reg_reg_d); 10038 %} 10039 10040 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10041 %{ 10042 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10043 10044 ins_cost(INSN_COST * 3); 10045 10046 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10047 ins_encode %{ 10048 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10049 __ fcseld(as_FloatRegister($dst$$reg), 10050 as_FloatRegister($src2$$reg), 10051 as_FloatRegister($src1$$reg), 10052 cond); 10053 %} 10054 10055 ins_pipe(fp_cond_reg_reg_d); 10056 %} 10057 10058 // ============================================================================ 10059 // Arithmetic Instructions 10060 // 10061 10062 // Integer Addition 10063 10064 // TODO 10065 // these currently employ operations which do not set CR and hence are 10066 // not flagged as killing CR but we would like to isolate the cases 10067 // where we want to set flags from those where we don't. need to work 10068 // out how to do that. 10069 10070 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10071 match(Set dst (AddI src1 src2)); 10072 10073 ins_cost(INSN_COST); 10074 format %{ "addw $dst, $src1, $src2" %} 10075 10076 ins_encode %{ 10077 __ addw(as_Register($dst$$reg), 10078 as_Register($src1$$reg), 10079 as_Register($src2$$reg)); 10080 %} 10081 10082 ins_pipe(ialu_reg_reg); 10083 %} 10084 10085 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10086 match(Set dst (AddI src1 src2)); 10087 10088 ins_cost(INSN_COST); 10089 format %{ "addw $dst, $src1, $src2" %} 10090 10091 // use opcode to indicate that this is an add not a sub 10092 opcode(0x0); 10093 10094 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10095 10096 ins_pipe(ialu_reg_imm); 10097 %} 10098 10099 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10100 match(Set dst (AddI (ConvL2I src1) src2)); 10101 10102 ins_cost(INSN_COST); 10103 format %{ "addw $dst, $src1, $src2" %} 10104 10105 // use opcode to indicate that this is an add not a sub 10106 opcode(0x0); 10107 10108 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10109 10110 ins_pipe(ialu_reg_imm); 10111 %} 10112 10113 // Pointer Addition 10114 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10115 match(Set dst (AddP src1 src2)); 10116 10117 ins_cost(INSN_COST); 10118 format %{ "add $dst, $src1, $src2\t# ptr" %} 10119 10120 ins_encode %{ 10121 __ add(as_Register($dst$$reg), 10122 as_Register($src1$$reg), 10123 as_Register($src2$$reg)); 10124 %} 10125 10126 ins_pipe(ialu_reg_reg); 10127 %} 10128 10129 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10130 match(Set dst (AddP src1 (ConvI2L src2))); 10131 10132 ins_cost(1.9 * INSN_COST); 10133 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10134 10135 ins_encode %{ 10136 __ add(as_Register($dst$$reg), 10137 as_Register($src1$$reg), 10138 as_Register($src2$$reg), ext::sxtw); 10139 %} 10140 10141 ins_pipe(ialu_reg_reg); 10142 %} 10143 10144 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10145 match(Set dst (AddP src1 (LShiftL src2 scale))); 10146 10147 ins_cost(1.9 * INSN_COST); 10148 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10149 10150 ins_encode %{ 10151 __ lea(as_Register($dst$$reg), 10152 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10153 Address::lsl($scale$$constant))); 10154 %} 10155 10156 ins_pipe(ialu_reg_reg_shift); 10157 %} 10158 10159 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10160 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10161 10162 ins_cost(1.9 * INSN_COST); 10163 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10164 10165 ins_encode %{ 10166 __ lea(as_Register($dst$$reg), 10167 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10168 Address::sxtw($scale$$constant))); 10169 %} 10170 10171 ins_pipe(ialu_reg_reg_shift); 10172 %} 10173 10174 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10175 match(Set dst (LShiftL (ConvI2L src) scale)); 10176 10177 ins_cost(INSN_COST); 10178 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10179 10180 ins_encode %{ 10181 __ sbfiz(as_Register($dst$$reg), 10182 as_Register($src$$reg), 10183 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 10184 %} 10185 10186 ins_pipe(ialu_reg_shift); 10187 %} 10188 10189 // Pointer Immediate Addition 10190 // n.b. this needs to be more expensive than using an indirect memory 10191 // operand 10192 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10193 match(Set dst (AddP src1 src2)); 10194 10195 ins_cost(INSN_COST); 10196 format %{ "add $dst, $src1, $src2\t# ptr" %} 10197 10198 // use opcode to indicate that this is an add not a sub 10199 opcode(0x0); 10200 10201 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10202 10203 ins_pipe(ialu_reg_imm); 10204 %} 10205 10206 // Long Addition 10207 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10208 10209 match(Set dst (AddL src1 src2)); 10210 10211 ins_cost(INSN_COST); 10212 format %{ "add $dst, $src1, $src2" %} 10213 10214 ins_encode %{ 10215 __ add(as_Register($dst$$reg), 10216 as_Register($src1$$reg), 10217 as_Register($src2$$reg)); 10218 %} 10219 10220 ins_pipe(ialu_reg_reg); 10221 %} 10222 10223 // No constant pool entries requiredLong Immediate Addition. 10224 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10225 match(Set dst (AddL src1 src2)); 10226 10227 ins_cost(INSN_COST); 10228 format %{ "add $dst, $src1, $src2" %} 10229 10230 // use opcode to indicate that this is an add not a sub 10231 opcode(0x0); 10232 10233 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10234 10235 ins_pipe(ialu_reg_imm); 10236 %} 10237 10238 // Integer Subtraction 10239 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10240 match(Set dst (SubI src1 src2)); 10241 10242 ins_cost(INSN_COST); 10243 format %{ "subw $dst, $src1, $src2" %} 10244 10245 ins_encode %{ 10246 __ subw(as_Register($dst$$reg), 10247 as_Register($src1$$reg), 10248 as_Register($src2$$reg)); 10249 %} 10250 10251 ins_pipe(ialu_reg_reg); 10252 %} 10253 10254 // Immediate Subtraction 10255 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10256 match(Set dst (SubI src1 src2)); 10257 10258 ins_cost(INSN_COST); 10259 format %{ "subw $dst, $src1, $src2" %} 10260 10261 // use opcode to indicate that this is a sub not an add 10262 opcode(0x1); 10263 10264 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10265 10266 ins_pipe(ialu_reg_imm); 10267 %} 10268 10269 // Long Subtraction 10270 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10271 10272 match(Set dst (SubL src1 src2)); 10273 10274 ins_cost(INSN_COST); 10275 format %{ "sub $dst, $src1, $src2" %} 10276 10277 ins_encode %{ 10278 __ sub(as_Register($dst$$reg), 10279 as_Register($src1$$reg), 10280 as_Register($src2$$reg)); 10281 %} 10282 10283 ins_pipe(ialu_reg_reg); 10284 %} 10285 10286 // No constant pool entries requiredLong Immediate Subtraction. 10287 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10288 match(Set dst (SubL src1 src2)); 10289 10290 ins_cost(INSN_COST); 10291 format %{ "sub$dst, $src1, $src2" %} 10292 10293 // use opcode to indicate that this is a sub not an add 10294 opcode(0x1); 10295 10296 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10297 10298 ins_pipe(ialu_reg_imm); 10299 %} 10300 10301 // Integer Negation (special case for sub) 10302 10303 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10304 match(Set dst (SubI zero src)); 10305 10306 ins_cost(INSN_COST); 10307 format %{ "negw $dst, $src\t# int" %} 10308 10309 ins_encode %{ 10310 __ negw(as_Register($dst$$reg), 10311 as_Register($src$$reg)); 10312 %} 10313 10314 ins_pipe(ialu_reg); 10315 %} 10316 10317 // Long Negation 10318 10319 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10320 match(Set dst (SubL zero src)); 10321 10322 ins_cost(INSN_COST); 10323 format %{ "neg $dst, $src\t# long" %} 10324 10325 ins_encode %{ 10326 __ neg(as_Register($dst$$reg), 10327 as_Register($src$$reg)); 10328 %} 10329 10330 ins_pipe(ialu_reg); 10331 %} 10332 10333 // Integer Multiply 10334 10335 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10336 match(Set dst (MulI src1 src2)); 10337 10338 ins_cost(INSN_COST * 3); 10339 format %{ "mulw $dst, $src1, $src2" %} 10340 10341 ins_encode %{ 10342 __ mulw(as_Register($dst$$reg), 10343 as_Register($src1$$reg), 10344 as_Register($src2$$reg)); 10345 %} 10346 10347 ins_pipe(imul_reg_reg); 10348 %} 10349 10350 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10351 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10352 10353 ins_cost(INSN_COST * 3); 10354 format %{ "smull $dst, $src1, $src2" %} 10355 10356 ins_encode %{ 10357 __ smull(as_Register($dst$$reg), 10358 as_Register($src1$$reg), 10359 as_Register($src2$$reg)); 10360 %} 10361 10362 ins_pipe(imul_reg_reg); 10363 %} 10364 10365 // Long Multiply 10366 10367 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10368 match(Set dst (MulL src1 src2)); 10369 10370 ins_cost(INSN_COST * 5); 10371 format %{ "mul $dst, $src1, $src2" %} 10372 10373 ins_encode %{ 10374 __ mul(as_Register($dst$$reg), 10375 as_Register($src1$$reg), 10376 as_Register($src2$$reg)); 10377 %} 10378 10379 ins_pipe(lmul_reg_reg); 10380 %} 10381 10382 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10383 %{ 10384 match(Set dst (MulHiL src1 src2)); 10385 10386 ins_cost(INSN_COST * 7); 10387 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10388 10389 ins_encode %{ 10390 __ smulh(as_Register($dst$$reg), 10391 as_Register($src1$$reg), 10392 as_Register($src2$$reg)); 10393 %} 10394 10395 ins_pipe(lmul_reg_reg); 10396 %} 10397 10398 // Combined Integer Multiply & Add/Sub 10399 10400 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10401 match(Set dst (AddI src3 (MulI src1 src2))); 10402 10403 ins_cost(INSN_COST * 3); 10404 format %{ "madd $dst, $src1, $src2, $src3" %} 10405 10406 ins_encode %{ 10407 __ maddw(as_Register($dst$$reg), 10408 as_Register($src1$$reg), 10409 as_Register($src2$$reg), 10410 as_Register($src3$$reg)); 10411 %} 10412 10413 ins_pipe(imac_reg_reg); 10414 %} 10415 10416 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10417 match(Set dst (SubI src3 (MulI src1 src2))); 10418 10419 ins_cost(INSN_COST * 3); 10420 format %{ "msub $dst, $src1, $src2, $src3" %} 10421 10422 ins_encode %{ 10423 __ msubw(as_Register($dst$$reg), 10424 as_Register($src1$$reg), 10425 as_Register($src2$$reg), 10426 as_Register($src3$$reg)); 10427 %} 10428 10429 ins_pipe(imac_reg_reg); 10430 %} 10431 10432 // Combined Integer Multiply & Neg 10433 10434 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10435 match(Set dst (MulI (SubI zero src1) src2)); 10436 match(Set dst (MulI src1 (SubI zero src2))); 10437 10438 ins_cost(INSN_COST * 3); 10439 format %{ "mneg $dst, $src1, $src2" %} 10440 10441 ins_encode %{ 10442 __ mnegw(as_Register($dst$$reg), 10443 as_Register($src1$$reg), 10444 as_Register($src2$$reg)); 10445 %} 10446 10447 ins_pipe(imac_reg_reg); 10448 %} 10449 10450 // Combined Long Multiply & Add/Sub 10451 10452 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10453 match(Set dst (AddL src3 (MulL src1 src2))); 10454 10455 ins_cost(INSN_COST * 5); 10456 format %{ "madd $dst, $src1, $src2, $src3" %} 10457 10458 ins_encode %{ 10459 __ madd(as_Register($dst$$reg), 10460 as_Register($src1$$reg), 10461 as_Register($src2$$reg), 10462 as_Register($src3$$reg)); 10463 %} 10464 10465 ins_pipe(lmac_reg_reg); 10466 %} 10467 10468 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10469 match(Set dst (SubL src3 (MulL src1 src2))); 10470 10471 ins_cost(INSN_COST * 5); 10472 format %{ "msub $dst, $src1, $src2, $src3" %} 10473 10474 ins_encode %{ 10475 __ msub(as_Register($dst$$reg), 10476 as_Register($src1$$reg), 10477 as_Register($src2$$reg), 10478 as_Register($src3$$reg)); 10479 %} 10480 10481 ins_pipe(lmac_reg_reg); 10482 %} 10483 10484 // Combined Long Multiply & Neg 10485 10486 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10487 match(Set dst (MulL (SubL zero src1) src2)); 10488 match(Set dst (MulL src1 (SubL zero src2))); 10489 10490 ins_cost(INSN_COST * 5); 10491 format %{ "mneg $dst, $src1, $src2" %} 10492 10493 ins_encode %{ 10494 __ mneg(as_Register($dst$$reg), 10495 as_Register($src1$$reg), 10496 as_Register($src2$$reg)); 10497 %} 10498 10499 ins_pipe(lmac_reg_reg); 10500 %} 10501 10502 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10503 10504 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10505 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10506 10507 ins_cost(INSN_COST * 3); 10508 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10509 10510 ins_encode %{ 10511 __ smaddl(as_Register($dst$$reg), 10512 as_Register($src1$$reg), 10513 as_Register($src2$$reg), 10514 as_Register($src3$$reg)); 10515 %} 10516 10517 ins_pipe(imac_reg_reg); 10518 %} 10519 10520 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10521 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10522 10523 ins_cost(INSN_COST * 3); 10524 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10525 10526 ins_encode %{ 10527 __ smsubl(as_Register($dst$$reg), 10528 as_Register($src1$$reg), 10529 as_Register($src2$$reg), 10530 as_Register($src3$$reg)); 10531 %} 10532 10533 ins_pipe(imac_reg_reg); 10534 %} 10535 10536 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10537 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10538 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10539 10540 ins_cost(INSN_COST * 3); 10541 format %{ "smnegl $dst, $src1, $src2" %} 10542 10543 ins_encode %{ 10544 __ smnegl(as_Register($dst$$reg), 10545 as_Register($src1$$reg), 10546 as_Register($src2$$reg)); 10547 %} 10548 10549 ins_pipe(imac_reg_reg); 10550 %} 10551 10552 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10553 10554 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10555 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10556 10557 ins_cost(INSN_COST * 5); 10558 format %{ "mulw rscratch1, $src1, $src2\n\t" 10559 "maddw $dst, $src3, $src4, rscratch1" %} 10560 10561 ins_encode %{ 10562 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10563 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10564 10565 ins_pipe(imac_reg_reg); 10566 %} 10567 10568 // Integer Divide 10569 10570 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10571 match(Set dst (DivI src1 src2)); 10572 10573 ins_cost(INSN_COST * 19); 10574 format %{ "sdivw $dst, $src1, $src2" %} 10575 10576 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10577 ins_pipe(idiv_reg_reg); 10578 %} 10579 10580 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 10581 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 10582 ins_cost(INSN_COST); 10583 format %{ "lsrw $dst, $src1, $div1" %} 10584 ins_encode %{ 10585 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 10586 %} 10587 ins_pipe(ialu_reg_shift); 10588 %} 10589 10590 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 10591 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 10592 ins_cost(INSN_COST); 10593 format %{ "addw $dst, $src, LSR $div1" %} 10594 10595 ins_encode %{ 10596 __ addw(as_Register($dst$$reg), 10597 as_Register($src$$reg), 10598 as_Register($src$$reg), 10599 Assembler::LSR, 31); 10600 %} 10601 ins_pipe(ialu_reg); 10602 %} 10603 10604 // Long Divide 10605 10606 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10607 match(Set dst (DivL src1 src2)); 10608 10609 ins_cost(INSN_COST * 35); 10610 format %{ "sdiv $dst, $src1, $src2" %} 10611 10612 ins_encode(aarch64_enc_div(dst, src1, src2)); 10613 ins_pipe(ldiv_reg_reg); 10614 %} 10615 10616 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 10617 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 10618 ins_cost(INSN_COST); 10619 format %{ "lsr $dst, $src1, $div1" %} 10620 ins_encode %{ 10621 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 10622 %} 10623 ins_pipe(ialu_reg_shift); 10624 %} 10625 10626 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 10627 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 10628 ins_cost(INSN_COST); 10629 format %{ "add $dst, $src, $div1" %} 10630 10631 ins_encode %{ 10632 __ add(as_Register($dst$$reg), 10633 as_Register($src$$reg), 10634 as_Register($src$$reg), 10635 Assembler::LSR, 63); 10636 %} 10637 ins_pipe(ialu_reg); 10638 %} 10639 10640 // Integer Remainder 10641 10642 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10643 match(Set dst (ModI src1 src2)); 10644 10645 ins_cost(INSN_COST * 22); 10646 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10647 "msubw($dst, rscratch1, $src2, $src1" %} 10648 10649 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10650 ins_pipe(idiv_reg_reg); 10651 %} 10652 10653 // Long Remainder 10654 10655 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10656 match(Set dst (ModL src1 src2)); 10657 10658 ins_cost(INSN_COST * 38); 10659 format %{ "sdiv rscratch1, $src1, $src2\n" 10660 "msub($dst, rscratch1, $src2, $src1" %} 10661 10662 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10663 ins_pipe(ldiv_reg_reg); 10664 %} 10665 10666 // Integer Shifts 10667 10668 // Shift Left Register 10669 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10670 match(Set dst (LShiftI src1 src2)); 10671 10672 ins_cost(INSN_COST * 2); 10673 format %{ "lslvw $dst, $src1, $src2" %} 10674 10675 ins_encode %{ 10676 __ lslvw(as_Register($dst$$reg), 10677 as_Register($src1$$reg), 10678 as_Register($src2$$reg)); 10679 %} 10680 10681 ins_pipe(ialu_reg_reg_vshift); 10682 %} 10683 10684 // Shift Left Immediate 10685 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10686 match(Set dst (LShiftI src1 src2)); 10687 10688 ins_cost(INSN_COST); 10689 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10690 10691 ins_encode %{ 10692 __ lslw(as_Register($dst$$reg), 10693 as_Register($src1$$reg), 10694 $src2$$constant & 0x1f); 10695 %} 10696 10697 ins_pipe(ialu_reg_shift); 10698 %} 10699 10700 // Shift Right Logical Register 10701 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10702 match(Set dst (URShiftI src1 src2)); 10703 10704 ins_cost(INSN_COST * 2); 10705 format %{ "lsrvw $dst, $src1, $src2" %} 10706 10707 ins_encode %{ 10708 __ lsrvw(as_Register($dst$$reg), 10709 as_Register($src1$$reg), 10710 as_Register($src2$$reg)); 10711 %} 10712 10713 ins_pipe(ialu_reg_reg_vshift); 10714 %} 10715 10716 // Shift Right Logical Immediate 10717 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10718 match(Set dst (URShiftI src1 src2)); 10719 10720 ins_cost(INSN_COST); 10721 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10722 10723 ins_encode %{ 10724 __ lsrw(as_Register($dst$$reg), 10725 as_Register($src1$$reg), 10726 $src2$$constant & 0x1f); 10727 %} 10728 10729 ins_pipe(ialu_reg_shift); 10730 %} 10731 10732 // Shift Right Arithmetic Register 10733 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10734 match(Set dst (RShiftI src1 src2)); 10735 10736 ins_cost(INSN_COST * 2); 10737 format %{ "asrvw $dst, $src1, $src2" %} 10738 10739 ins_encode %{ 10740 __ asrvw(as_Register($dst$$reg), 10741 as_Register($src1$$reg), 10742 as_Register($src2$$reg)); 10743 %} 10744 10745 ins_pipe(ialu_reg_reg_vshift); 10746 %} 10747 10748 // Shift Right Arithmetic Immediate 10749 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10750 match(Set dst (RShiftI src1 src2)); 10751 10752 ins_cost(INSN_COST); 10753 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10754 10755 ins_encode %{ 10756 __ asrw(as_Register($dst$$reg), 10757 as_Register($src1$$reg), 10758 $src2$$constant & 0x1f); 10759 %} 10760 10761 ins_pipe(ialu_reg_shift); 10762 %} 10763 10764 // Combined Int Mask and Right Shift (using UBFM) 10765 // TODO 10766 10767 // Long Shifts 10768 10769 // Shift Left Register 10770 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10771 match(Set dst (LShiftL src1 src2)); 10772 10773 ins_cost(INSN_COST * 2); 10774 format %{ "lslv $dst, $src1, $src2" %} 10775 10776 ins_encode %{ 10777 __ lslv(as_Register($dst$$reg), 10778 as_Register($src1$$reg), 10779 as_Register($src2$$reg)); 10780 %} 10781 10782 ins_pipe(ialu_reg_reg_vshift); 10783 %} 10784 10785 // Shift Left Immediate 10786 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10787 match(Set dst (LShiftL src1 src2)); 10788 10789 ins_cost(INSN_COST); 10790 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10791 10792 ins_encode %{ 10793 __ lsl(as_Register($dst$$reg), 10794 as_Register($src1$$reg), 10795 $src2$$constant & 0x3f); 10796 %} 10797 10798 ins_pipe(ialu_reg_shift); 10799 %} 10800 10801 // Shift Right Logical Register 10802 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10803 match(Set dst (URShiftL src1 src2)); 10804 10805 ins_cost(INSN_COST * 2); 10806 format %{ "lsrv $dst, $src1, $src2" %} 10807 10808 ins_encode %{ 10809 __ lsrv(as_Register($dst$$reg), 10810 as_Register($src1$$reg), 10811 as_Register($src2$$reg)); 10812 %} 10813 10814 ins_pipe(ialu_reg_reg_vshift); 10815 %} 10816 10817 // Shift Right Logical Immediate 10818 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10819 match(Set dst (URShiftL src1 src2)); 10820 10821 ins_cost(INSN_COST); 10822 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10823 10824 ins_encode %{ 10825 __ lsr(as_Register($dst$$reg), 10826 as_Register($src1$$reg), 10827 $src2$$constant & 0x3f); 10828 %} 10829 10830 ins_pipe(ialu_reg_shift); 10831 %} 10832 10833 // A special-case pattern for card table stores. 10834 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10835 match(Set dst (URShiftL (CastP2X src1) src2)); 10836 10837 ins_cost(INSN_COST); 10838 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10839 10840 ins_encode %{ 10841 __ lsr(as_Register($dst$$reg), 10842 as_Register($src1$$reg), 10843 $src2$$constant & 0x3f); 10844 %} 10845 10846 ins_pipe(ialu_reg_shift); 10847 %} 10848 10849 // Shift Right Arithmetic Register 10850 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10851 match(Set dst (RShiftL src1 src2)); 10852 10853 ins_cost(INSN_COST * 2); 10854 format %{ "asrv $dst, $src1, $src2" %} 10855 10856 ins_encode %{ 10857 __ asrv(as_Register($dst$$reg), 10858 as_Register($src1$$reg), 10859 as_Register($src2$$reg)); 10860 %} 10861 10862 ins_pipe(ialu_reg_reg_vshift); 10863 %} 10864 10865 // Shift Right Arithmetic Immediate 10866 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10867 match(Set dst (RShiftL src1 src2)); 10868 10869 ins_cost(INSN_COST); 10870 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10871 10872 ins_encode %{ 10873 __ asr(as_Register($dst$$reg), 10874 as_Register($src1$$reg), 10875 $src2$$constant & 0x3f); 10876 %} 10877 10878 ins_pipe(ialu_reg_shift); 10879 %} 10880 10881 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10882 10883 instruct regL_not_reg(iRegLNoSp dst, 10884 iRegL src1, immL_M1 m1, 10885 rFlagsReg cr) %{ 10886 match(Set dst (XorL src1 m1)); 10887 ins_cost(INSN_COST); 10888 format %{ "eon $dst, $src1, zr" %} 10889 10890 ins_encode %{ 10891 __ eon(as_Register($dst$$reg), 10892 as_Register($src1$$reg), 10893 zr, 10894 Assembler::LSL, 0); 10895 %} 10896 10897 ins_pipe(ialu_reg); 10898 %} 10899 instruct regI_not_reg(iRegINoSp dst, 10900 iRegIorL2I src1, immI_M1 m1, 10901 rFlagsReg cr) %{ 10902 match(Set dst (XorI src1 m1)); 10903 ins_cost(INSN_COST); 10904 format %{ "eonw $dst, $src1, zr" %} 10905 10906 ins_encode %{ 10907 __ eonw(as_Register($dst$$reg), 10908 as_Register($src1$$reg), 10909 zr, 10910 Assembler::LSL, 0); 10911 %} 10912 10913 ins_pipe(ialu_reg); 10914 %} 10915 10916 instruct AndI_reg_not_reg(iRegINoSp dst, 10917 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10918 rFlagsReg cr) %{ 10919 match(Set dst (AndI src1 (XorI src2 m1))); 10920 ins_cost(INSN_COST); 10921 format %{ "bicw $dst, $src1, $src2" %} 10922 10923 ins_encode %{ 10924 __ bicw(as_Register($dst$$reg), 10925 as_Register($src1$$reg), 10926 as_Register($src2$$reg), 10927 Assembler::LSL, 0); 10928 %} 10929 10930 ins_pipe(ialu_reg_reg); 10931 %} 10932 10933 instruct AndL_reg_not_reg(iRegLNoSp dst, 10934 iRegL src1, iRegL src2, immL_M1 m1, 10935 rFlagsReg cr) %{ 10936 match(Set dst (AndL src1 (XorL src2 m1))); 10937 ins_cost(INSN_COST); 10938 format %{ "bic $dst, $src1, $src2" %} 10939 10940 ins_encode %{ 10941 __ bic(as_Register($dst$$reg), 10942 as_Register($src1$$reg), 10943 as_Register($src2$$reg), 10944 Assembler::LSL, 0); 10945 %} 10946 10947 ins_pipe(ialu_reg_reg); 10948 %} 10949 10950 instruct OrI_reg_not_reg(iRegINoSp dst, 10951 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10952 rFlagsReg cr) %{ 10953 match(Set dst (OrI src1 (XorI src2 m1))); 10954 ins_cost(INSN_COST); 10955 format %{ "ornw $dst, $src1, $src2" %} 10956 10957 ins_encode %{ 10958 __ ornw(as_Register($dst$$reg), 10959 as_Register($src1$$reg), 10960 as_Register($src2$$reg), 10961 Assembler::LSL, 0); 10962 %} 10963 10964 ins_pipe(ialu_reg_reg); 10965 %} 10966 10967 instruct OrL_reg_not_reg(iRegLNoSp dst, 10968 iRegL src1, iRegL src2, immL_M1 m1, 10969 rFlagsReg cr) %{ 10970 match(Set dst (OrL src1 (XorL src2 m1))); 10971 ins_cost(INSN_COST); 10972 format %{ "orn $dst, $src1, $src2" %} 10973 10974 ins_encode %{ 10975 __ orn(as_Register($dst$$reg), 10976 as_Register($src1$$reg), 10977 as_Register($src2$$reg), 10978 Assembler::LSL, 0); 10979 %} 10980 10981 ins_pipe(ialu_reg_reg); 10982 %} 10983 10984 instruct XorI_reg_not_reg(iRegINoSp dst, 10985 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10986 rFlagsReg cr) %{ 10987 match(Set dst (XorI m1 (XorI src2 src1))); 10988 ins_cost(INSN_COST); 10989 format %{ "eonw $dst, $src1, $src2" %} 10990 10991 ins_encode %{ 10992 __ eonw(as_Register($dst$$reg), 10993 as_Register($src1$$reg), 10994 as_Register($src2$$reg), 10995 Assembler::LSL, 0); 10996 %} 10997 10998 ins_pipe(ialu_reg_reg); 10999 %} 11000 11001 instruct XorL_reg_not_reg(iRegLNoSp dst, 11002 iRegL src1, iRegL src2, immL_M1 m1, 11003 rFlagsReg cr) %{ 11004 match(Set dst (XorL m1 (XorL src2 src1))); 11005 ins_cost(INSN_COST); 11006 format %{ "eon $dst, $src1, $src2" %} 11007 11008 ins_encode %{ 11009 __ eon(as_Register($dst$$reg), 11010 as_Register($src1$$reg), 11011 as_Register($src2$$reg), 11012 Assembler::LSL, 0); 11013 %} 11014 11015 ins_pipe(ialu_reg_reg); 11016 %} 11017 11018 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11019 iRegIorL2I src1, iRegIorL2I src2, 11020 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11021 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11022 ins_cost(1.9 * INSN_COST); 11023 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11024 11025 ins_encode %{ 11026 __ bicw(as_Register($dst$$reg), 11027 as_Register($src1$$reg), 11028 as_Register($src2$$reg), 11029 Assembler::LSR, 11030 $src3$$constant & 0x1f); 11031 %} 11032 11033 ins_pipe(ialu_reg_reg_shift); 11034 %} 11035 11036 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11037 iRegL src1, iRegL src2, 11038 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11039 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11040 ins_cost(1.9 * INSN_COST); 11041 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11042 11043 ins_encode %{ 11044 __ bic(as_Register($dst$$reg), 11045 as_Register($src1$$reg), 11046 as_Register($src2$$reg), 11047 Assembler::LSR, 11048 $src3$$constant & 0x3f); 11049 %} 11050 11051 ins_pipe(ialu_reg_reg_shift); 11052 %} 11053 11054 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11055 iRegIorL2I src1, iRegIorL2I src2, 11056 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11057 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11058 ins_cost(1.9 * INSN_COST); 11059 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11060 11061 ins_encode %{ 11062 __ bicw(as_Register($dst$$reg), 11063 as_Register($src1$$reg), 11064 as_Register($src2$$reg), 11065 Assembler::ASR, 11066 $src3$$constant & 0x1f); 11067 %} 11068 11069 ins_pipe(ialu_reg_reg_shift); 11070 %} 11071 11072 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11073 iRegL src1, iRegL src2, 11074 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11075 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11076 ins_cost(1.9 * INSN_COST); 11077 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11078 11079 ins_encode %{ 11080 __ bic(as_Register($dst$$reg), 11081 as_Register($src1$$reg), 11082 as_Register($src2$$reg), 11083 Assembler::ASR, 11084 $src3$$constant & 0x3f); 11085 %} 11086 11087 ins_pipe(ialu_reg_reg_shift); 11088 %} 11089 11090 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11091 iRegIorL2I src1, iRegIorL2I src2, 11092 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11093 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11094 ins_cost(1.9 * INSN_COST); 11095 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11096 11097 ins_encode %{ 11098 __ bicw(as_Register($dst$$reg), 11099 as_Register($src1$$reg), 11100 as_Register($src2$$reg), 11101 Assembler::LSL, 11102 $src3$$constant & 0x1f); 11103 %} 11104 11105 ins_pipe(ialu_reg_reg_shift); 11106 %} 11107 11108 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11109 iRegL src1, iRegL src2, 11110 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11111 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11112 ins_cost(1.9 * INSN_COST); 11113 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11114 11115 ins_encode %{ 11116 __ bic(as_Register($dst$$reg), 11117 as_Register($src1$$reg), 11118 as_Register($src2$$reg), 11119 Assembler::LSL, 11120 $src3$$constant & 0x3f); 11121 %} 11122 11123 ins_pipe(ialu_reg_reg_shift); 11124 %} 11125 11126 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11127 iRegIorL2I src1, iRegIorL2I src2, 11128 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11129 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11130 ins_cost(1.9 * INSN_COST); 11131 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11132 11133 ins_encode %{ 11134 __ eonw(as_Register($dst$$reg), 11135 as_Register($src1$$reg), 11136 as_Register($src2$$reg), 11137 Assembler::LSR, 11138 $src3$$constant & 0x1f); 11139 %} 11140 11141 ins_pipe(ialu_reg_reg_shift); 11142 %} 11143 11144 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11145 iRegL src1, iRegL src2, 11146 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11147 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11148 ins_cost(1.9 * INSN_COST); 11149 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11150 11151 ins_encode %{ 11152 __ eon(as_Register($dst$$reg), 11153 as_Register($src1$$reg), 11154 as_Register($src2$$reg), 11155 Assembler::LSR, 11156 $src3$$constant & 0x3f); 11157 %} 11158 11159 ins_pipe(ialu_reg_reg_shift); 11160 %} 11161 11162 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11163 iRegIorL2I src1, iRegIorL2I src2, 11164 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11165 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11166 ins_cost(1.9 * INSN_COST); 11167 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11168 11169 ins_encode %{ 11170 __ eonw(as_Register($dst$$reg), 11171 as_Register($src1$$reg), 11172 as_Register($src2$$reg), 11173 Assembler::ASR, 11174 $src3$$constant & 0x1f); 11175 %} 11176 11177 ins_pipe(ialu_reg_reg_shift); 11178 %} 11179 11180 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11181 iRegL src1, iRegL src2, 11182 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11183 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11184 ins_cost(1.9 * INSN_COST); 11185 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11186 11187 ins_encode %{ 11188 __ eon(as_Register($dst$$reg), 11189 as_Register($src1$$reg), 11190 as_Register($src2$$reg), 11191 Assembler::ASR, 11192 $src3$$constant & 0x3f); 11193 %} 11194 11195 ins_pipe(ialu_reg_reg_shift); 11196 %} 11197 11198 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11199 iRegIorL2I src1, iRegIorL2I src2, 11200 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11201 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11202 ins_cost(1.9 * INSN_COST); 11203 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11204 11205 ins_encode %{ 11206 __ eonw(as_Register($dst$$reg), 11207 as_Register($src1$$reg), 11208 as_Register($src2$$reg), 11209 Assembler::LSL, 11210 $src3$$constant & 0x1f); 11211 %} 11212 11213 ins_pipe(ialu_reg_reg_shift); 11214 %} 11215 11216 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11217 iRegL src1, iRegL src2, 11218 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11219 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11220 ins_cost(1.9 * INSN_COST); 11221 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11222 11223 ins_encode %{ 11224 __ eon(as_Register($dst$$reg), 11225 as_Register($src1$$reg), 11226 as_Register($src2$$reg), 11227 Assembler::LSL, 11228 $src3$$constant & 0x3f); 11229 %} 11230 11231 ins_pipe(ialu_reg_reg_shift); 11232 %} 11233 11234 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11235 iRegIorL2I src1, iRegIorL2I src2, 11236 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11237 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11238 ins_cost(1.9 * INSN_COST); 11239 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11240 11241 ins_encode %{ 11242 __ ornw(as_Register($dst$$reg), 11243 as_Register($src1$$reg), 11244 as_Register($src2$$reg), 11245 Assembler::LSR, 11246 $src3$$constant & 0x1f); 11247 %} 11248 11249 ins_pipe(ialu_reg_reg_shift); 11250 %} 11251 11252 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11253 iRegL src1, iRegL src2, 11254 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11255 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11256 ins_cost(1.9 * INSN_COST); 11257 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11258 11259 ins_encode %{ 11260 __ orn(as_Register($dst$$reg), 11261 as_Register($src1$$reg), 11262 as_Register($src2$$reg), 11263 Assembler::LSR, 11264 $src3$$constant & 0x3f); 11265 %} 11266 11267 ins_pipe(ialu_reg_reg_shift); 11268 %} 11269 11270 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11271 iRegIorL2I src1, iRegIorL2I src2, 11272 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11273 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11274 ins_cost(1.9 * INSN_COST); 11275 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11276 11277 ins_encode %{ 11278 __ ornw(as_Register($dst$$reg), 11279 as_Register($src1$$reg), 11280 as_Register($src2$$reg), 11281 Assembler::ASR, 11282 $src3$$constant & 0x1f); 11283 %} 11284 11285 ins_pipe(ialu_reg_reg_shift); 11286 %} 11287 11288 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11289 iRegL src1, iRegL src2, 11290 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11291 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11292 ins_cost(1.9 * INSN_COST); 11293 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11294 11295 ins_encode %{ 11296 __ orn(as_Register($dst$$reg), 11297 as_Register($src1$$reg), 11298 as_Register($src2$$reg), 11299 Assembler::ASR, 11300 $src3$$constant & 0x3f); 11301 %} 11302 11303 ins_pipe(ialu_reg_reg_shift); 11304 %} 11305 11306 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11307 iRegIorL2I src1, iRegIorL2I src2, 11308 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11309 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11310 ins_cost(1.9 * INSN_COST); 11311 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11312 11313 ins_encode %{ 11314 __ ornw(as_Register($dst$$reg), 11315 as_Register($src1$$reg), 11316 as_Register($src2$$reg), 11317 Assembler::LSL, 11318 $src3$$constant & 0x1f); 11319 %} 11320 11321 ins_pipe(ialu_reg_reg_shift); 11322 %} 11323 11324 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11325 iRegL src1, iRegL src2, 11326 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11327 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11328 ins_cost(1.9 * INSN_COST); 11329 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11330 11331 ins_encode %{ 11332 __ orn(as_Register($dst$$reg), 11333 as_Register($src1$$reg), 11334 as_Register($src2$$reg), 11335 Assembler::LSL, 11336 $src3$$constant & 0x3f); 11337 %} 11338 11339 ins_pipe(ialu_reg_reg_shift); 11340 %} 11341 11342 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11343 iRegIorL2I src1, iRegIorL2I src2, 11344 immI src3, rFlagsReg cr) %{ 11345 match(Set dst (AndI src1 (URShiftI src2 src3))); 11346 11347 ins_cost(1.9 * INSN_COST); 11348 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11349 11350 ins_encode %{ 11351 __ andw(as_Register($dst$$reg), 11352 as_Register($src1$$reg), 11353 as_Register($src2$$reg), 11354 Assembler::LSR, 11355 $src3$$constant & 0x1f); 11356 %} 11357 11358 ins_pipe(ialu_reg_reg_shift); 11359 %} 11360 11361 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11362 iRegL src1, iRegL src2, 11363 immI src3, rFlagsReg cr) %{ 11364 match(Set dst (AndL src1 (URShiftL src2 src3))); 11365 11366 ins_cost(1.9 * INSN_COST); 11367 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11368 11369 ins_encode %{ 11370 __ andr(as_Register($dst$$reg), 11371 as_Register($src1$$reg), 11372 as_Register($src2$$reg), 11373 Assembler::LSR, 11374 $src3$$constant & 0x3f); 11375 %} 11376 11377 ins_pipe(ialu_reg_reg_shift); 11378 %} 11379 11380 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11381 iRegIorL2I src1, iRegIorL2I src2, 11382 immI src3, rFlagsReg cr) %{ 11383 match(Set dst (AndI src1 (RShiftI src2 src3))); 11384 11385 ins_cost(1.9 * INSN_COST); 11386 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11387 11388 ins_encode %{ 11389 __ andw(as_Register($dst$$reg), 11390 as_Register($src1$$reg), 11391 as_Register($src2$$reg), 11392 Assembler::ASR, 11393 $src3$$constant & 0x1f); 11394 %} 11395 11396 ins_pipe(ialu_reg_reg_shift); 11397 %} 11398 11399 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11400 iRegL src1, iRegL src2, 11401 immI src3, rFlagsReg cr) %{ 11402 match(Set dst (AndL src1 (RShiftL src2 src3))); 11403 11404 ins_cost(1.9 * INSN_COST); 11405 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11406 11407 ins_encode %{ 11408 __ andr(as_Register($dst$$reg), 11409 as_Register($src1$$reg), 11410 as_Register($src2$$reg), 11411 Assembler::ASR, 11412 $src3$$constant & 0x3f); 11413 %} 11414 11415 ins_pipe(ialu_reg_reg_shift); 11416 %} 11417 11418 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11419 iRegIorL2I src1, iRegIorL2I src2, 11420 immI src3, rFlagsReg cr) %{ 11421 match(Set dst (AndI src1 (LShiftI src2 src3))); 11422 11423 ins_cost(1.9 * INSN_COST); 11424 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11425 11426 ins_encode %{ 11427 __ andw(as_Register($dst$$reg), 11428 as_Register($src1$$reg), 11429 as_Register($src2$$reg), 11430 Assembler::LSL, 11431 $src3$$constant & 0x1f); 11432 %} 11433 11434 ins_pipe(ialu_reg_reg_shift); 11435 %} 11436 11437 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11438 iRegL src1, iRegL src2, 11439 immI src3, rFlagsReg cr) %{ 11440 match(Set dst (AndL src1 (LShiftL src2 src3))); 11441 11442 ins_cost(1.9 * INSN_COST); 11443 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11444 11445 ins_encode %{ 11446 __ andr(as_Register($dst$$reg), 11447 as_Register($src1$$reg), 11448 as_Register($src2$$reg), 11449 Assembler::LSL, 11450 $src3$$constant & 0x3f); 11451 %} 11452 11453 ins_pipe(ialu_reg_reg_shift); 11454 %} 11455 11456 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11457 iRegIorL2I src1, iRegIorL2I src2, 11458 immI src3, rFlagsReg cr) %{ 11459 match(Set dst (XorI src1 (URShiftI src2 src3))); 11460 11461 ins_cost(1.9 * INSN_COST); 11462 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11463 11464 ins_encode %{ 11465 __ eorw(as_Register($dst$$reg), 11466 as_Register($src1$$reg), 11467 as_Register($src2$$reg), 11468 Assembler::LSR, 11469 $src3$$constant & 0x1f); 11470 %} 11471 11472 ins_pipe(ialu_reg_reg_shift); 11473 %} 11474 11475 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11476 iRegL src1, iRegL src2, 11477 immI src3, rFlagsReg cr) %{ 11478 match(Set dst (XorL src1 (URShiftL src2 src3))); 11479 11480 ins_cost(1.9 * INSN_COST); 11481 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11482 11483 ins_encode %{ 11484 __ eor(as_Register($dst$$reg), 11485 as_Register($src1$$reg), 11486 as_Register($src2$$reg), 11487 Assembler::LSR, 11488 $src3$$constant & 0x3f); 11489 %} 11490 11491 ins_pipe(ialu_reg_reg_shift); 11492 %} 11493 11494 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11495 iRegIorL2I src1, iRegIorL2I src2, 11496 immI src3, rFlagsReg cr) %{ 11497 match(Set dst (XorI src1 (RShiftI src2 src3))); 11498 11499 ins_cost(1.9 * INSN_COST); 11500 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11501 11502 ins_encode %{ 11503 __ eorw(as_Register($dst$$reg), 11504 as_Register($src1$$reg), 11505 as_Register($src2$$reg), 11506 Assembler::ASR, 11507 $src3$$constant & 0x1f); 11508 %} 11509 11510 ins_pipe(ialu_reg_reg_shift); 11511 %} 11512 11513 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11514 iRegL src1, iRegL src2, 11515 immI src3, rFlagsReg cr) %{ 11516 match(Set dst (XorL src1 (RShiftL src2 src3))); 11517 11518 ins_cost(1.9 * INSN_COST); 11519 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11520 11521 ins_encode %{ 11522 __ eor(as_Register($dst$$reg), 11523 as_Register($src1$$reg), 11524 as_Register($src2$$reg), 11525 Assembler::ASR, 11526 $src3$$constant & 0x3f); 11527 %} 11528 11529 ins_pipe(ialu_reg_reg_shift); 11530 %} 11531 11532 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11533 iRegIorL2I src1, iRegIorL2I src2, 11534 immI src3, rFlagsReg cr) %{ 11535 match(Set dst (XorI src1 (LShiftI src2 src3))); 11536 11537 ins_cost(1.9 * INSN_COST); 11538 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11539 11540 ins_encode %{ 11541 __ eorw(as_Register($dst$$reg), 11542 as_Register($src1$$reg), 11543 as_Register($src2$$reg), 11544 Assembler::LSL, 11545 $src3$$constant & 0x1f); 11546 %} 11547 11548 ins_pipe(ialu_reg_reg_shift); 11549 %} 11550 11551 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11552 iRegL src1, iRegL src2, 11553 immI src3, rFlagsReg cr) %{ 11554 match(Set dst (XorL src1 (LShiftL src2 src3))); 11555 11556 ins_cost(1.9 * INSN_COST); 11557 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11558 11559 ins_encode %{ 11560 __ eor(as_Register($dst$$reg), 11561 as_Register($src1$$reg), 11562 as_Register($src2$$reg), 11563 Assembler::LSL, 11564 $src3$$constant & 0x3f); 11565 %} 11566 11567 ins_pipe(ialu_reg_reg_shift); 11568 %} 11569 11570 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11571 iRegIorL2I src1, iRegIorL2I src2, 11572 immI src3, rFlagsReg cr) %{ 11573 match(Set dst (OrI src1 (URShiftI src2 src3))); 11574 11575 ins_cost(1.9 * INSN_COST); 11576 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11577 11578 ins_encode %{ 11579 __ orrw(as_Register($dst$$reg), 11580 as_Register($src1$$reg), 11581 as_Register($src2$$reg), 11582 Assembler::LSR, 11583 $src3$$constant & 0x1f); 11584 %} 11585 11586 ins_pipe(ialu_reg_reg_shift); 11587 %} 11588 11589 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11590 iRegL src1, iRegL src2, 11591 immI src3, rFlagsReg cr) %{ 11592 match(Set dst (OrL src1 (URShiftL src2 src3))); 11593 11594 ins_cost(1.9 * INSN_COST); 11595 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11596 11597 ins_encode %{ 11598 __ orr(as_Register($dst$$reg), 11599 as_Register($src1$$reg), 11600 as_Register($src2$$reg), 11601 Assembler::LSR, 11602 $src3$$constant & 0x3f); 11603 %} 11604 11605 ins_pipe(ialu_reg_reg_shift); 11606 %} 11607 11608 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11609 iRegIorL2I src1, iRegIorL2I src2, 11610 immI src3, rFlagsReg cr) %{ 11611 match(Set dst (OrI src1 (RShiftI src2 src3))); 11612 11613 ins_cost(1.9 * INSN_COST); 11614 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11615 11616 ins_encode %{ 11617 __ orrw(as_Register($dst$$reg), 11618 as_Register($src1$$reg), 11619 as_Register($src2$$reg), 11620 Assembler::ASR, 11621 $src3$$constant & 0x1f); 11622 %} 11623 11624 ins_pipe(ialu_reg_reg_shift); 11625 %} 11626 11627 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11628 iRegL src1, iRegL src2, 11629 immI src3, rFlagsReg cr) %{ 11630 match(Set dst (OrL src1 (RShiftL src2 src3))); 11631 11632 ins_cost(1.9 * INSN_COST); 11633 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11634 11635 ins_encode %{ 11636 __ orr(as_Register($dst$$reg), 11637 as_Register($src1$$reg), 11638 as_Register($src2$$reg), 11639 Assembler::ASR, 11640 $src3$$constant & 0x3f); 11641 %} 11642 11643 ins_pipe(ialu_reg_reg_shift); 11644 %} 11645 11646 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11647 iRegIorL2I src1, iRegIorL2I src2, 11648 immI src3, rFlagsReg cr) %{ 11649 match(Set dst (OrI src1 (LShiftI src2 src3))); 11650 11651 ins_cost(1.9 * INSN_COST); 11652 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11653 11654 ins_encode %{ 11655 __ orrw(as_Register($dst$$reg), 11656 as_Register($src1$$reg), 11657 as_Register($src2$$reg), 11658 Assembler::LSL, 11659 $src3$$constant & 0x1f); 11660 %} 11661 11662 ins_pipe(ialu_reg_reg_shift); 11663 %} 11664 11665 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11666 iRegL src1, iRegL src2, 11667 immI src3, rFlagsReg cr) %{ 11668 match(Set dst (OrL src1 (LShiftL src2 src3))); 11669 11670 ins_cost(1.9 * INSN_COST); 11671 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11672 11673 ins_encode %{ 11674 __ orr(as_Register($dst$$reg), 11675 as_Register($src1$$reg), 11676 as_Register($src2$$reg), 11677 Assembler::LSL, 11678 $src3$$constant & 0x3f); 11679 %} 11680 11681 ins_pipe(ialu_reg_reg_shift); 11682 %} 11683 11684 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11685 iRegIorL2I src1, iRegIorL2I src2, 11686 immI src3, rFlagsReg cr) %{ 11687 match(Set dst (AddI src1 (URShiftI src2 src3))); 11688 11689 ins_cost(1.9 * INSN_COST); 11690 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11691 11692 ins_encode %{ 11693 __ addw(as_Register($dst$$reg), 11694 as_Register($src1$$reg), 11695 as_Register($src2$$reg), 11696 Assembler::LSR, 11697 $src3$$constant & 0x1f); 11698 %} 11699 11700 ins_pipe(ialu_reg_reg_shift); 11701 %} 11702 11703 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11704 iRegL src1, iRegL src2, 11705 immI src3, rFlagsReg cr) %{ 11706 match(Set dst (AddL src1 (URShiftL src2 src3))); 11707 11708 ins_cost(1.9 * INSN_COST); 11709 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11710 11711 ins_encode %{ 11712 __ add(as_Register($dst$$reg), 11713 as_Register($src1$$reg), 11714 as_Register($src2$$reg), 11715 Assembler::LSR, 11716 $src3$$constant & 0x3f); 11717 %} 11718 11719 ins_pipe(ialu_reg_reg_shift); 11720 %} 11721 11722 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11723 iRegIorL2I src1, iRegIorL2I src2, 11724 immI src3, rFlagsReg cr) %{ 11725 match(Set dst (AddI src1 (RShiftI src2 src3))); 11726 11727 ins_cost(1.9 * INSN_COST); 11728 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11729 11730 ins_encode %{ 11731 __ addw(as_Register($dst$$reg), 11732 as_Register($src1$$reg), 11733 as_Register($src2$$reg), 11734 Assembler::ASR, 11735 $src3$$constant & 0x1f); 11736 %} 11737 11738 ins_pipe(ialu_reg_reg_shift); 11739 %} 11740 11741 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11742 iRegL src1, iRegL src2, 11743 immI src3, rFlagsReg cr) %{ 11744 match(Set dst (AddL src1 (RShiftL src2 src3))); 11745 11746 ins_cost(1.9 * INSN_COST); 11747 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11748 11749 ins_encode %{ 11750 __ add(as_Register($dst$$reg), 11751 as_Register($src1$$reg), 11752 as_Register($src2$$reg), 11753 Assembler::ASR, 11754 $src3$$constant & 0x3f); 11755 %} 11756 11757 ins_pipe(ialu_reg_reg_shift); 11758 %} 11759 11760 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11761 iRegIorL2I src1, iRegIorL2I src2, 11762 immI src3, rFlagsReg cr) %{ 11763 match(Set dst (AddI src1 (LShiftI src2 src3))); 11764 11765 ins_cost(1.9 * INSN_COST); 11766 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11767 11768 ins_encode %{ 11769 __ addw(as_Register($dst$$reg), 11770 as_Register($src1$$reg), 11771 as_Register($src2$$reg), 11772 Assembler::LSL, 11773 $src3$$constant & 0x1f); 11774 %} 11775 11776 ins_pipe(ialu_reg_reg_shift); 11777 %} 11778 11779 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11780 iRegL src1, iRegL src2, 11781 immI src3, rFlagsReg cr) %{ 11782 match(Set dst (AddL src1 (LShiftL src2 src3))); 11783 11784 ins_cost(1.9 * INSN_COST); 11785 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11786 11787 ins_encode %{ 11788 __ add(as_Register($dst$$reg), 11789 as_Register($src1$$reg), 11790 as_Register($src2$$reg), 11791 Assembler::LSL, 11792 $src3$$constant & 0x3f); 11793 %} 11794 11795 ins_pipe(ialu_reg_reg_shift); 11796 %} 11797 11798 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11799 iRegIorL2I src1, iRegIorL2I src2, 11800 immI src3, rFlagsReg cr) %{ 11801 match(Set dst (SubI src1 (URShiftI src2 src3))); 11802 11803 ins_cost(1.9 * INSN_COST); 11804 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11805 11806 ins_encode %{ 11807 __ subw(as_Register($dst$$reg), 11808 as_Register($src1$$reg), 11809 as_Register($src2$$reg), 11810 Assembler::LSR, 11811 $src3$$constant & 0x1f); 11812 %} 11813 11814 ins_pipe(ialu_reg_reg_shift); 11815 %} 11816 11817 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11818 iRegL src1, iRegL src2, 11819 immI src3, rFlagsReg cr) %{ 11820 match(Set dst (SubL src1 (URShiftL src2 src3))); 11821 11822 ins_cost(1.9 * INSN_COST); 11823 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11824 11825 ins_encode %{ 11826 __ sub(as_Register($dst$$reg), 11827 as_Register($src1$$reg), 11828 as_Register($src2$$reg), 11829 Assembler::LSR, 11830 $src3$$constant & 0x3f); 11831 %} 11832 11833 ins_pipe(ialu_reg_reg_shift); 11834 %} 11835 11836 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11837 iRegIorL2I src1, iRegIorL2I src2, 11838 immI src3, rFlagsReg cr) %{ 11839 match(Set dst (SubI src1 (RShiftI src2 src3))); 11840 11841 ins_cost(1.9 * INSN_COST); 11842 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11843 11844 ins_encode %{ 11845 __ subw(as_Register($dst$$reg), 11846 as_Register($src1$$reg), 11847 as_Register($src2$$reg), 11848 Assembler::ASR, 11849 $src3$$constant & 0x1f); 11850 %} 11851 11852 ins_pipe(ialu_reg_reg_shift); 11853 %} 11854 11855 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11856 iRegL src1, iRegL src2, 11857 immI src3, rFlagsReg cr) %{ 11858 match(Set dst (SubL src1 (RShiftL src2 src3))); 11859 11860 ins_cost(1.9 * INSN_COST); 11861 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11862 11863 ins_encode %{ 11864 __ sub(as_Register($dst$$reg), 11865 as_Register($src1$$reg), 11866 as_Register($src2$$reg), 11867 Assembler::ASR, 11868 $src3$$constant & 0x3f); 11869 %} 11870 11871 ins_pipe(ialu_reg_reg_shift); 11872 %} 11873 11874 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11875 iRegIorL2I src1, iRegIorL2I src2, 11876 immI src3, rFlagsReg cr) %{ 11877 match(Set dst (SubI src1 (LShiftI src2 src3))); 11878 11879 ins_cost(1.9 * INSN_COST); 11880 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11881 11882 ins_encode %{ 11883 __ subw(as_Register($dst$$reg), 11884 as_Register($src1$$reg), 11885 as_Register($src2$$reg), 11886 Assembler::LSL, 11887 $src3$$constant & 0x1f); 11888 %} 11889 11890 ins_pipe(ialu_reg_reg_shift); 11891 %} 11892 11893 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11894 iRegL src1, iRegL src2, 11895 immI src3, rFlagsReg cr) %{ 11896 match(Set dst (SubL src1 (LShiftL src2 src3))); 11897 11898 ins_cost(1.9 * INSN_COST); 11899 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11900 11901 ins_encode %{ 11902 __ sub(as_Register($dst$$reg), 11903 as_Register($src1$$reg), 11904 as_Register($src2$$reg), 11905 Assembler::LSL, 11906 $src3$$constant & 0x3f); 11907 %} 11908 11909 ins_pipe(ialu_reg_reg_shift); 11910 %} 11911 11912 11913 11914 // Shift Left followed by Shift Right. 11915 // This idiom is used by the compiler for the i2b bytecode etc. 11916 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11917 %{ 11918 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11919 ins_cost(INSN_COST * 2); 11920 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11921 ins_encode %{ 11922 int lshift = $lshift_count$$constant & 63; 11923 int rshift = $rshift_count$$constant & 63; 11924 int s = 63 - lshift; 11925 int r = (rshift - lshift) & 63; 11926 __ sbfm(as_Register($dst$$reg), 11927 as_Register($src$$reg), 11928 r, s); 11929 %} 11930 11931 ins_pipe(ialu_reg_shift); 11932 %} 11933 11934 // Shift Left followed by Shift Right. 11935 // This idiom is used by the compiler for the i2b bytecode etc. 11936 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11937 %{ 11938 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11939 ins_cost(INSN_COST * 2); 11940 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11941 ins_encode %{ 11942 int lshift = $lshift_count$$constant & 31; 11943 int rshift = $rshift_count$$constant & 31; 11944 int s = 31 - lshift; 11945 int r = (rshift - lshift) & 31; 11946 __ sbfmw(as_Register($dst$$reg), 11947 as_Register($src$$reg), 11948 r, s); 11949 %} 11950 11951 ins_pipe(ialu_reg_shift); 11952 %} 11953 11954 // Shift Left followed by Shift Right. 11955 // This idiom is used by the compiler for the i2b bytecode etc. 11956 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11957 %{ 11958 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11959 ins_cost(INSN_COST * 2); 11960 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11961 ins_encode %{ 11962 int lshift = $lshift_count$$constant & 63; 11963 int rshift = $rshift_count$$constant & 63; 11964 int s = 63 - lshift; 11965 int r = (rshift - lshift) & 63; 11966 __ ubfm(as_Register($dst$$reg), 11967 as_Register($src$$reg), 11968 r, s); 11969 %} 11970 11971 ins_pipe(ialu_reg_shift); 11972 %} 11973 11974 // Shift Left followed by Shift Right. 11975 // This idiom is used by the compiler for the i2b bytecode etc. 11976 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11977 %{ 11978 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11979 ins_cost(INSN_COST * 2); 11980 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11981 ins_encode %{ 11982 int lshift = $lshift_count$$constant & 31; 11983 int rshift = $rshift_count$$constant & 31; 11984 int s = 31 - lshift; 11985 int r = (rshift - lshift) & 31; 11986 __ ubfmw(as_Register($dst$$reg), 11987 as_Register($src$$reg), 11988 r, s); 11989 %} 11990 11991 ins_pipe(ialu_reg_shift); 11992 %} 11993 // Bitfield extract with shift & mask 11994 11995 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11996 %{ 11997 match(Set dst (AndI (URShiftI src rshift) mask)); 11998 // Make sure we are not going to exceed what ubfxw can do. 11999 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12000 12001 ins_cost(INSN_COST); 12002 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12003 ins_encode %{ 12004 int rshift = $rshift$$constant & 31; 12005 long mask = $mask$$constant; 12006 int width = exact_log2(mask+1); 12007 __ ubfxw(as_Register($dst$$reg), 12008 as_Register($src$$reg), rshift, width); 12009 %} 12010 ins_pipe(ialu_reg_shift); 12011 %} 12012 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12013 %{ 12014 match(Set dst (AndL (URShiftL src rshift) mask)); 12015 // Make sure we are not going to exceed what ubfx can do. 12016 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12017 12018 ins_cost(INSN_COST); 12019 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12020 ins_encode %{ 12021 int rshift = $rshift$$constant & 63; 12022 long mask = $mask$$constant; 12023 int width = exact_log2_long(mask+1); 12024 __ ubfx(as_Register($dst$$reg), 12025 as_Register($src$$reg), rshift, width); 12026 %} 12027 ins_pipe(ialu_reg_shift); 12028 %} 12029 12030 // We can use ubfx when extending an And with a mask when we know mask 12031 // is positive. We know that because immI_bitmask guarantees it. 12032 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12033 %{ 12034 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12035 // Make sure we are not going to exceed what ubfxw can do. 12036 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12037 12038 ins_cost(INSN_COST * 2); 12039 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12040 ins_encode %{ 12041 int rshift = $rshift$$constant & 31; 12042 long mask = $mask$$constant; 12043 int width = exact_log2(mask+1); 12044 __ ubfx(as_Register($dst$$reg), 12045 as_Register($src$$reg), rshift, width); 12046 %} 12047 ins_pipe(ialu_reg_shift); 12048 %} 12049 12050 // We can use ubfiz when masking by a positive number and then left shifting the result. 12051 // We know that the mask is positive because immI_bitmask guarantees it. 12052 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12053 %{ 12054 match(Set dst (LShiftI (AndI src mask) lshift)); 12055 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12056 12057 ins_cost(INSN_COST); 12058 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12059 ins_encode %{ 12060 int lshift = $lshift$$constant & 31; 12061 long mask = $mask$$constant; 12062 int width = exact_log2(mask+1); 12063 __ ubfizw(as_Register($dst$$reg), 12064 as_Register($src$$reg), lshift, width); 12065 %} 12066 ins_pipe(ialu_reg_shift); 12067 %} 12068 // We can use ubfiz when masking by a positive number and then left shifting the result. 12069 // We know that the mask is positive because immL_bitmask guarantees it. 12070 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12071 %{ 12072 match(Set dst (LShiftL (AndL src mask) lshift)); 12073 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12074 12075 ins_cost(INSN_COST); 12076 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12077 ins_encode %{ 12078 int lshift = $lshift$$constant & 63; 12079 long mask = $mask$$constant; 12080 int width = exact_log2_long(mask+1); 12081 __ ubfiz(as_Register($dst$$reg), 12082 as_Register($src$$reg), lshift, width); 12083 %} 12084 ins_pipe(ialu_reg_shift); 12085 %} 12086 12087 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12088 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12089 %{ 12090 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12091 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12092 12093 ins_cost(INSN_COST); 12094 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12095 ins_encode %{ 12096 int lshift = $lshift$$constant & 63; 12097 long mask = $mask$$constant; 12098 int width = exact_log2(mask+1); 12099 __ ubfiz(as_Register($dst$$reg), 12100 as_Register($src$$reg), lshift, width); 12101 %} 12102 ins_pipe(ialu_reg_shift); 12103 %} 12104 12105 // Rotations 12106 12107 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12108 %{ 12109 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12110 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12111 12112 ins_cost(INSN_COST); 12113 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12114 12115 ins_encode %{ 12116 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12117 $rshift$$constant & 63); 12118 %} 12119 ins_pipe(ialu_reg_reg_extr); 12120 %} 12121 12122 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12123 %{ 12124 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12125 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12126 12127 ins_cost(INSN_COST); 12128 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12129 12130 ins_encode %{ 12131 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12132 $rshift$$constant & 31); 12133 %} 12134 ins_pipe(ialu_reg_reg_extr); 12135 %} 12136 12137 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12138 %{ 12139 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12140 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12141 12142 ins_cost(INSN_COST); 12143 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12144 12145 ins_encode %{ 12146 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12147 $rshift$$constant & 63); 12148 %} 12149 ins_pipe(ialu_reg_reg_extr); 12150 %} 12151 12152 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12153 %{ 12154 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12155 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12156 12157 ins_cost(INSN_COST); 12158 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12159 12160 ins_encode %{ 12161 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12162 $rshift$$constant & 31); 12163 %} 12164 ins_pipe(ialu_reg_reg_extr); 12165 %} 12166 12167 12168 // rol expander 12169 12170 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12171 %{ 12172 effect(DEF dst, USE src, USE shift); 12173 12174 format %{ "rol $dst, $src, $shift" %} 12175 ins_cost(INSN_COST * 3); 12176 ins_encode %{ 12177 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12178 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12179 rscratch1); 12180 %} 12181 ins_pipe(ialu_reg_reg_vshift); 12182 %} 12183 12184 // rol expander 12185 12186 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12187 %{ 12188 effect(DEF dst, USE src, USE shift); 12189 12190 format %{ "rol $dst, $src, $shift" %} 12191 ins_cost(INSN_COST * 3); 12192 ins_encode %{ 12193 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12194 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12195 rscratch1); 12196 %} 12197 ins_pipe(ialu_reg_reg_vshift); 12198 %} 12199 12200 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12201 %{ 12202 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12203 12204 expand %{ 12205 rolL_rReg(dst, src, shift, cr); 12206 %} 12207 %} 12208 12209 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12210 %{ 12211 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12212 12213 expand %{ 12214 rolL_rReg(dst, src, shift, cr); 12215 %} 12216 %} 12217 12218 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12219 %{ 12220 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12221 12222 expand %{ 12223 rolI_rReg(dst, src, shift, cr); 12224 %} 12225 %} 12226 12227 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12228 %{ 12229 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12230 12231 expand %{ 12232 rolI_rReg(dst, src, shift, cr); 12233 %} 12234 %} 12235 12236 // ror expander 12237 12238 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12239 %{ 12240 effect(DEF dst, USE src, USE shift); 12241 12242 format %{ "ror $dst, $src, $shift" %} 12243 ins_cost(INSN_COST); 12244 ins_encode %{ 12245 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12246 as_Register($shift$$reg)); 12247 %} 12248 ins_pipe(ialu_reg_reg_vshift); 12249 %} 12250 12251 // ror expander 12252 12253 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12254 %{ 12255 effect(DEF dst, USE src, USE shift); 12256 12257 format %{ "ror $dst, $src, $shift" %} 12258 ins_cost(INSN_COST); 12259 ins_encode %{ 12260 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12261 as_Register($shift$$reg)); 12262 %} 12263 ins_pipe(ialu_reg_reg_vshift); 12264 %} 12265 12266 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12267 %{ 12268 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12269 12270 expand %{ 12271 rorL_rReg(dst, src, shift, cr); 12272 %} 12273 %} 12274 12275 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12276 %{ 12277 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12278 12279 expand %{ 12280 rorL_rReg(dst, src, shift, cr); 12281 %} 12282 %} 12283 12284 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12285 %{ 12286 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12287 12288 expand %{ 12289 rorI_rReg(dst, src, shift, cr); 12290 %} 12291 %} 12292 12293 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12294 %{ 12295 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12296 12297 expand %{ 12298 rorI_rReg(dst, src, shift, cr); 12299 %} 12300 %} 12301 12302 // Add/subtract (extended) 12303 12304 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12305 %{ 12306 match(Set dst (AddL src1 (ConvI2L src2))); 12307 ins_cost(INSN_COST); 12308 format %{ "add $dst, $src1, $src2, sxtw" %} 12309 12310 ins_encode %{ 12311 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12312 as_Register($src2$$reg), ext::sxtw); 12313 %} 12314 ins_pipe(ialu_reg_reg); 12315 %}; 12316 12317 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12318 %{ 12319 match(Set dst (SubL src1 (ConvI2L src2))); 12320 ins_cost(INSN_COST); 12321 format %{ "sub $dst, $src1, $src2, sxtw" %} 12322 12323 ins_encode %{ 12324 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12325 as_Register($src2$$reg), ext::sxtw); 12326 %} 12327 ins_pipe(ialu_reg_reg); 12328 %}; 12329 12330 12331 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12332 %{ 12333 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12334 ins_cost(INSN_COST); 12335 format %{ "add $dst, $src1, $src2, sxth" %} 12336 12337 ins_encode %{ 12338 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12339 as_Register($src2$$reg), ext::sxth); 12340 %} 12341 ins_pipe(ialu_reg_reg); 12342 %} 12343 12344 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12345 %{ 12346 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12347 ins_cost(INSN_COST); 12348 format %{ "add $dst, $src1, $src2, sxtb" %} 12349 12350 ins_encode %{ 12351 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12352 as_Register($src2$$reg), ext::sxtb); 12353 %} 12354 ins_pipe(ialu_reg_reg); 12355 %} 12356 12357 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12358 %{ 12359 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12360 ins_cost(INSN_COST); 12361 format %{ "add $dst, $src1, $src2, uxtb" %} 12362 12363 ins_encode %{ 12364 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12365 as_Register($src2$$reg), ext::uxtb); 12366 %} 12367 ins_pipe(ialu_reg_reg); 12368 %} 12369 12370 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12371 %{ 12372 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12373 ins_cost(INSN_COST); 12374 format %{ "add $dst, $src1, $src2, sxth" %} 12375 12376 ins_encode %{ 12377 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12378 as_Register($src2$$reg), ext::sxth); 12379 %} 12380 ins_pipe(ialu_reg_reg); 12381 %} 12382 12383 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12384 %{ 12385 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12386 ins_cost(INSN_COST); 12387 format %{ "add $dst, $src1, $src2, sxtw" %} 12388 12389 ins_encode %{ 12390 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12391 as_Register($src2$$reg), ext::sxtw); 12392 %} 12393 ins_pipe(ialu_reg_reg); 12394 %} 12395 12396 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12397 %{ 12398 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12399 ins_cost(INSN_COST); 12400 format %{ "add $dst, $src1, $src2, sxtb" %} 12401 12402 ins_encode %{ 12403 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12404 as_Register($src2$$reg), ext::sxtb); 12405 %} 12406 ins_pipe(ialu_reg_reg); 12407 %} 12408 12409 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12410 %{ 12411 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12412 ins_cost(INSN_COST); 12413 format %{ "add $dst, $src1, $src2, uxtb" %} 12414 12415 ins_encode %{ 12416 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12417 as_Register($src2$$reg), ext::uxtb); 12418 %} 12419 ins_pipe(ialu_reg_reg); 12420 %} 12421 12422 12423 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12424 %{ 12425 match(Set dst (AddI src1 (AndI src2 mask))); 12426 ins_cost(INSN_COST); 12427 format %{ "addw $dst, $src1, $src2, uxtb" %} 12428 12429 ins_encode %{ 12430 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12431 as_Register($src2$$reg), ext::uxtb); 12432 %} 12433 ins_pipe(ialu_reg_reg); 12434 %} 12435 12436 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12437 %{ 12438 match(Set dst (AddI src1 (AndI src2 mask))); 12439 ins_cost(INSN_COST); 12440 format %{ "addw $dst, $src1, $src2, uxth" %} 12441 12442 ins_encode %{ 12443 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12444 as_Register($src2$$reg), ext::uxth); 12445 %} 12446 ins_pipe(ialu_reg_reg); 12447 %} 12448 12449 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12450 %{ 12451 match(Set dst (AddL src1 (AndL src2 mask))); 12452 ins_cost(INSN_COST); 12453 format %{ "add $dst, $src1, $src2, uxtb" %} 12454 12455 ins_encode %{ 12456 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12457 as_Register($src2$$reg), ext::uxtb); 12458 %} 12459 ins_pipe(ialu_reg_reg); 12460 %} 12461 12462 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12463 %{ 12464 match(Set dst (AddL src1 (AndL src2 mask))); 12465 ins_cost(INSN_COST); 12466 format %{ "add $dst, $src1, $src2, uxth" %} 12467 12468 ins_encode %{ 12469 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12470 as_Register($src2$$reg), ext::uxth); 12471 %} 12472 ins_pipe(ialu_reg_reg); 12473 %} 12474 12475 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12476 %{ 12477 match(Set dst (AddL src1 (AndL src2 mask))); 12478 ins_cost(INSN_COST); 12479 format %{ "add $dst, $src1, $src2, uxtw" %} 12480 12481 ins_encode %{ 12482 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12483 as_Register($src2$$reg), ext::uxtw); 12484 %} 12485 ins_pipe(ialu_reg_reg); 12486 %} 12487 12488 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12489 %{ 12490 match(Set dst (SubI src1 (AndI src2 mask))); 12491 ins_cost(INSN_COST); 12492 format %{ "subw $dst, $src1, $src2, uxtb" %} 12493 12494 ins_encode %{ 12495 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12496 as_Register($src2$$reg), ext::uxtb); 12497 %} 12498 ins_pipe(ialu_reg_reg); 12499 %} 12500 12501 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12502 %{ 12503 match(Set dst (SubI src1 (AndI src2 mask))); 12504 ins_cost(INSN_COST); 12505 format %{ "subw $dst, $src1, $src2, uxth" %} 12506 12507 ins_encode %{ 12508 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12509 as_Register($src2$$reg), ext::uxth); 12510 %} 12511 ins_pipe(ialu_reg_reg); 12512 %} 12513 12514 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12515 %{ 12516 match(Set dst (SubL src1 (AndL src2 mask))); 12517 ins_cost(INSN_COST); 12518 format %{ "sub $dst, $src1, $src2, uxtb" %} 12519 12520 ins_encode %{ 12521 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12522 as_Register($src2$$reg), ext::uxtb); 12523 %} 12524 ins_pipe(ialu_reg_reg); 12525 %} 12526 12527 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12528 %{ 12529 match(Set dst (SubL src1 (AndL src2 mask))); 12530 ins_cost(INSN_COST); 12531 format %{ "sub $dst, $src1, $src2, uxth" %} 12532 12533 ins_encode %{ 12534 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12535 as_Register($src2$$reg), ext::uxth); 12536 %} 12537 ins_pipe(ialu_reg_reg); 12538 %} 12539 12540 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12541 %{ 12542 match(Set dst (SubL src1 (AndL src2 mask))); 12543 ins_cost(INSN_COST); 12544 format %{ "sub $dst, $src1, $src2, uxtw" %} 12545 12546 ins_encode %{ 12547 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12548 as_Register($src2$$reg), ext::uxtw); 12549 %} 12550 ins_pipe(ialu_reg_reg); 12551 %} 12552 12553 12554 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12555 %{ 12556 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12557 ins_cost(1.9 * INSN_COST); 12558 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12559 12560 ins_encode %{ 12561 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12562 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12563 %} 12564 ins_pipe(ialu_reg_reg_shift); 12565 %} 12566 12567 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12568 %{ 12569 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12570 ins_cost(1.9 * INSN_COST); 12571 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12572 12573 ins_encode %{ 12574 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12575 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12576 %} 12577 ins_pipe(ialu_reg_reg_shift); 12578 %} 12579 12580 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12581 %{ 12582 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12583 ins_cost(1.9 * INSN_COST); 12584 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12585 12586 ins_encode %{ 12587 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12588 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12589 %} 12590 ins_pipe(ialu_reg_reg_shift); 12591 %} 12592 12593 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12594 %{ 12595 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12596 ins_cost(1.9 * INSN_COST); 12597 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12598 12599 ins_encode %{ 12600 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12601 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12602 %} 12603 ins_pipe(ialu_reg_reg_shift); 12604 %} 12605 12606 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12607 %{ 12608 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12609 ins_cost(1.9 * INSN_COST); 12610 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12611 12612 ins_encode %{ 12613 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12614 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12615 %} 12616 ins_pipe(ialu_reg_reg_shift); 12617 %} 12618 12619 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12620 %{ 12621 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12622 ins_cost(1.9 * INSN_COST); 12623 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12624 12625 ins_encode %{ 12626 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12627 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12628 %} 12629 ins_pipe(ialu_reg_reg_shift); 12630 %} 12631 12632 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12633 %{ 12634 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12635 ins_cost(1.9 * INSN_COST); 12636 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12637 12638 ins_encode %{ 12639 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12640 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12641 %} 12642 ins_pipe(ialu_reg_reg_shift); 12643 %} 12644 12645 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12646 %{ 12647 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12648 ins_cost(1.9 * INSN_COST); 12649 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12650 12651 ins_encode %{ 12652 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12653 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12654 %} 12655 ins_pipe(ialu_reg_reg_shift); 12656 %} 12657 12658 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12659 %{ 12660 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12661 ins_cost(1.9 * INSN_COST); 12662 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12663 12664 ins_encode %{ 12665 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12666 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12667 %} 12668 ins_pipe(ialu_reg_reg_shift); 12669 %} 12670 12671 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12672 %{ 12673 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12674 ins_cost(1.9 * INSN_COST); 12675 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12676 12677 ins_encode %{ 12678 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12679 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12680 %} 12681 ins_pipe(ialu_reg_reg_shift); 12682 %} 12683 12684 12685 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12686 %{ 12687 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12688 ins_cost(1.9 * INSN_COST); 12689 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12690 12691 ins_encode %{ 12692 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12693 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12694 %} 12695 ins_pipe(ialu_reg_reg_shift); 12696 %}; 12697 12698 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12699 %{ 12700 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12701 ins_cost(1.9 * INSN_COST); 12702 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12703 12704 ins_encode %{ 12705 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12706 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12707 %} 12708 ins_pipe(ialu_reg_reg_shift); 12709 %}; 12710 12711 12712 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12713 %{ 12714 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12715 ins_cost(1.9 * INSN_COST); 12716 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12717 12718 ins_encode %{ 12719 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12720 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12721 %} 12722 ins_pipe(ialu_reg_reg_shift); 12723 %} 12724 12725 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12726 %{ 12727 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12728 ins_cost(1.9 * INSN_COST); 12729 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12730 12731 ins_encode %{ 12732 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12733 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12734 %} 12735 ins_pipe(ialu_reg_reg_shift); 12736 %} 12737 12738 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12739 %{ 12740 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12741 ins_cost(1.9 * INSN_COST); 12742 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12743 12744 ins_encode %{ 12745 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12746 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12747 %} 12748 ins_pipe(ialu_reg_reg_shift); 12749 %} 12750 12751 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12752 %{ 12753 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12754 ins_cost(1.9 * INSN_COST); 12755 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12756 12757 ins_encode %{ 12758 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12759 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12760 %} 12761 ins_pipe(ialu_reg_reg_shift); 12762 %} 12763 12764 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12765 %{ 12766 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12767 ins_cost(1.9 * INSN_COST); 12768 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12769 12770 ins_encode %{ 12771 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12772 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12773 %} 12774 ins_pipe(ialu_reg_reg_shift); 12775 %} 12776 12777 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12778 %{ 12779 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12780 ins_cost(1.9 * INSN_COST); 12781 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12782 12783 ins_encode %{ 12784 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12785 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12786 %} 12787 ins_pipe(ialu_reg_reg_shift); 12788 %} 12789 12790 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12791 %{ 12792 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12793 ins_cost(1.9 * INSN_COST); 12794 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12795 12796 ins_encode %{ 12797 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12798 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12799 %} 12800 ins_pipe(ialu_reg_reg_shift); 12801 %} 12802 12803 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12804 %{ 12805 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12806 ins_cost(1.9 * INSN_COST); 12807 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12808 12809 ins_encode %{ 12810 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12811 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12812 %} 12813 ins_pipe(ialu_reg_reg_shift); 12814 %} 12815 12816 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12817 %{ 12818 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12819 ins_cost(1.9 * INSN_COST); 12820 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12821 12822 ins_encode %{ 12823 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12824 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12825 %} 12826 ins_pipe(ialu_reg_reg_shift); 12827 %} 12828 12829 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12830 %{ 12831 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12832 ins_cost(1.9 * INSN_COST); 12833 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12834 12835 ins_encode %{ 12836 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12837 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12838 %} 12839 ins_pipe(ialu_reg_reg_shift); 12840 %} 12841 // END This section of the file is automatically generated. Do not edit -------------- 12842 12843 // ============================================================================ 12844 // Floating Point Arithmetic Instructions 12845 12846 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12847 match(Set dst (AddF src1 src2)); 12848 12849 ins_cost(INSN_COST * 5); 12850 format %{ "fadds $dst, $src1, $src2" %} 12851 12852 ins_encode %{ 12853 __ fadds(as_FloatRegister($dst$$reg), 12854 as_FloatRegister($src1$$reg), 12855 as_FloatRegister($src2$$reg)); 12856 %} 12857 12858 ins_pipe(fp_dop_reg_reg_s); 12859 %} 12860 12861 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12862 match(Set dst (AddD src1 src2)); 12863 12864 ins_cost(INSN_COST * 5); 12865 format %{ "faddd $dst, $src1, $src2" %} 12866 12867 ins_encode %{ 12868 __ faddd(as_FloatRegister($dst$$reg), 12869 as_FloatRegister($src1$$reg), 12870 as_FloatRegister($src2$$reg)); 12871 %} 12872 12873 ins_pipe(fp_dop_reg_reg_d); 12874 %} 12875 12876 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12877 match(Set dst (SubF src1 src2)); 12878 12879 ins_cost(INSN_COST * 5); 12880 format %{ "fsubs $dst, $src1, $src2" %} 12881 12882 ins_encode %{ 12883 __ fsubs(as_FloatRegister($dst$$reg), 12884 as_FloatRegister($src1$$reg), 12885 as_FloatRegister($src2$$reg)); 12886 %} 12887 12888 ins_pipe(fp_dop_reg_reg_s); 12889 %} 12890 12891 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12892 match(Set dst (SubD src1 src2)); 12893 12894 ins_cost(INSN_COST * 5); 12895 format %{ "fsubd $dst, $src1, $src2" %} 12896 12897 ins_encode %{ 12898 __ fsubd(as_FloatRegister($dst$$reg), 12899 as_FloatRegister($src1$$reg), 12900 as_FloatRegister($src2$$reg)); 12901 %} 12902 12903 ins_pipe(fp_dop_reg_reg_d); 12904 %} 12905 12906 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12907 match(Set dst (MulF src1 src2)); 12908 12909 ins_cost(INSN_COST * 6); 12910 format %{ "fmuls $dst, $src1, $src2" %} 12911 12912 ins_encode %{ 12913 __ fmuls(as_FloatRegister($dst$$reg), 12914 as_FloatRegister($src1$$reg), 12915 as_FloatRegister($src2$$reg)); 12916 %} 12917 12918 ins_pipe(fp_dop_reg_reg_s); 12919 %} 12920 12921 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12922 match(Set dst (MulD src1 src2)); 12923 12924 ins_cost(INSN_COST * 6); 12925 format %{ "fmuld $dst, $src1, $src2" %} 12926 12927 ins_encode %{ 12928 __ fmuld(as_FloatRegister($dst$$reg), 12929 as_FloatRegister($src1$$reg), 12930 as_FloatRegister($src2$$reg)); 12931 %} 12932 12933 ins_pipe(fp_dop_reg_reg_d); 12934 %} 12935 12936 // src1 * src2 + src3 12937 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12938 predicate(UseFMA); 12939 match(Set dst (FmaF src3 (Binary src1 src2))); 12940 12941 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12942 12943 ins_encode %{ 12944 __ fmadds(as_FloatRegister($dst$$reg), 12945 as_FloatRegister($src1$$reg), 12946 as_FloatRegister($src2$$reg), 12947 as_FloatRegister($src3$$reg)); 12948 %} 12949 12950 ins_pipe(pipe_class_default); 12951 %} 12952 12953 // src1 * src2 + src3 12954 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12955 predicate(UseFMA); 12956 match(Set dst (FmaD src3 (Binary src1 src2))); 12957 12958 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12959 12960 ins_encode %{ 12961 __ fmaddd(as_FloatRegister($dst$$reg), 12962 as_FloatRegister($src1$$reg), 12963 as_FloatRegister($src2$$reg), 12964 as_FloatRegister($src3$$reg)); 12965 %} 12966 12967 ins_pipe(pipe_class_default); 12968 %} 12969 12970 // -src1 * src2 + src3 12971 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12972 predicate(UseFMA); 12973 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12974 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12975 12976 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12977 12978 ins_encode %{ 12979 __ fmsubs(as_FloatRegister($dst$$reg), 12980 as_FloatRegister($src1$$reg), 12981 as_FloatRegister($src2$$reg), 12982 as_FloatRegister($src3$$reg)); 12983 %} 12984 12985 ins_pipe(pipe_class_default); 12986 %} 12987 12988 // -src1 * src2 + src3 12989 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12990 predicate(UseFMA); 12991 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12992 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12993 12994 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12995 12996 ins_encode %{ 12997 __ fmsubd(as_FloatRegister($dst$$reg), 12998 as_FloatRegister($src1$$reg), 12999 as_FloatRegister($src2$$reg), 13000 as_FloatRegister($src3$$reg)); 13001 %} 13002 13003 ins_pipe(pipe_class_default); 13004 %} 13005 13006 // -src1 * src2 - src3 13007 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13008 predicate(UseFMA); 13009 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 13010 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13011 13012 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13013 13014 ins_encode %{ 13015 __ fnmadds(as_FloatRegister($dst$$reg), 13016 as_FloatRegister($src1$$reg), 13017 as_FloatRegister($src2$$reg), 13018 as_FloatRegister($src3$$reg)); 13019 %} 13020 13021 ins_pipe(pipe_class_default); 13022 %} 13023 13024 // -src1 * src2 - src3 13025 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13026 predicate(UseFMA); 13027 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13028 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13029 13030 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13031 13032 ins_encode %{ 13033 __ fnmaddd(as_FloatRegister($dst$$reg), 13034 as_FloatRegister($src1$$reg), 13035 as_FloatRegister($src2$$reg), 13036 as_FloatRegister($src3$$reg)); 13037 %} 13038 13039 ins_pipe(pipe_class_default); 13040 %} 13041 13042 // src1 * src2 - src3 13043 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13044 predicate(UseFMA); 13045 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13046 13047 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13048 13049 ins_encode %{ 13050 __ fnmsubs(as_FloatRegister($dst$$reg), 13051 as_FloatRegister($src1$$reg), 13052 as_FloatRegister($src2$$reg), 13053 as_FloatRegister($src3$$reg)); 13054 %} 13055 13056 ins_pipe(pipe_class_default); 13057 %} 13058 13059 // src1 * src2 - src3 13060 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13061 predicate(UseFMA); 13062 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13063 13064 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13065 13066 ins_encode %{ 13067 // n.b. insn name should be fnmsubd 13068 __ fnmsub(as_FloatRegister($dst$$reg), 13069 as_FloatRegister($src1$$reg), 13070 as_FloatRegister($src2$$reg), 13071 as_FloatRegister($src3$$reg)); 13072 %} 13073 13074 ins_pipe(pipe_class_default); 13075 %} 13076 13077 13078 // Math.max(FF)F 13079 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13080 match(Set dst (MaxF src1 src2)); 13081 13082 format %{ "fmaxs $dst, $src1, $src2" %} 13083 ins_encode %{ 13084 __ fmaxs(as_FloatRegister($dst$$reg), 13085 as_FloatRegister($src1$$reg), 13086 as_FloatRegister($src2$$reg)); 13087 %} 13088 13089 ins_pipe(fp_dop_reg_reg_s); 13090 %} 13091 13092 // Math.min(FF)F 13093 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13094 match(Set dst (MinF src1 src2)); 13095 13096 format %{ "fmins $dst, $src1, $src2" %} 13097 ins_encode %{ 13098 __ fmins(as_FloatRegister($dst$$reg), 13099 as_FloatRegister($src1$$reg), 13100 as_FloatRegister($src2$$reg)); 13101 %} 13102 13103 ins_pipe(fp_dop_reg_reg_s); 13104 %} 13105 13106 // Math.max(DD)D 13107 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13108 match(Set dst (MaxD src1 src2)); 13109 13110 format %{ "fmaxd $dst, $src1, $src2" %} 13111 ins_encode %{ 13112 __ fmaxd(as_FloatRegister($dst$$reg), 13113 as_FloatRegister($src1$$reg), 13114 as_FloatRegister($src2$$reg)); 13115 %} 13116 13117 ins_pipe(fp_dop_reg_reg_d); 13118 %} 13119 13120 // Math.min(DD)D 13121 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13122 match(Set dst (MinD src1 src2)); 13123 13124 format %{ "fmind $dst, $src1, $src2" %} 13125 ins_encode %{ 13126 __ fmind(as_FloatRegister($dst$$reg), 13127 as_FloatRegister($src1$$reg), 13128 as_FloatRegister($src2$$reg)); 13129 %} 13130 13131 ins_pipe(fp_dop_reg_reg_d); 13132 %} 13133 13134 13135 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13136 match(Set dst (DivF src1 src2)); 13137 13138 ins_cost(INSN_COST * 18); 13139 format %{ "fdivs $dst, $src1, $src2" %} 13140 13141 ins_encode %{ 13142 __ fdivs(as_FloatRegister($dst$$reg), 13143 as_FloatRegister($src1$$reg), 13144 as_FloatRegister($src2$$reg)); 13145 %} 13146 13147 ins_pipe(fp_div_s); 13148 %} 13149 13150 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13151 match(Set dst (DivD src1 src2)); 13152 13153 ins_cost(INSN_COST * 32); 13154 format %{ "fdivd $dst, $src1, $src2" %} 13155 13156 ins_encode %{ 13157 __ fdivd(as_FloatRegister($dst$$reg), 13158 as_FloatRegister($src1$$reg), 13159 as_FloatRegister($src2$$reg)); 13160 %} 13161 13162 ins_pipe(fp_div_d); 13163 %} 13164 13165 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13166 match(Set dst (NegF src)); 13167 13168 ins_cost(INSN_COST * 3); 13169 format %{ "fneg $dst, $src" %} 13170 13171 ins_encode %{ 13172 __ fnegs(as_FloatRegister($dst$$reg), 13173 as_FloatRegister($src$$reg)); 13174 %} 13175 13176 ins_pipe(fp_uop_s); 13177 %} 13178 13179 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13180 match(Set dst (NegD src)); 13181 13182 ins_cost(INSN_COST * 3); 13183 format %{ "fnegd $dst, $src" %} 13184 13185 ins_encode %{ 13186 __ fnegd(as_FloatRegister($dst$$reg), 13187 as_FloatRegister($src$$reg)); 13188 %} 13189 13190 ins_pipe(fp_uop_d); 13191 %} 13192 13193 instruct absF_reg(vRegF dst, vRegF src) %{ 13194 match(Set dst (AbsF src)); 13195 13196 ins_cost(INSN_COST * 3); 13197 format %{ "fabss $dst, $src" %} 13198 ins_encode %{ 13199 __ fabss(as_FloatRegister($dst$$reg), 13200 as_FloatRegister($src$$reg)); 13201 %} 13202 13203 ins_pipe(fp_uop_s); 13204 %} 13205 13206 instruct absD_reg(vRegD dst, vRegD src) %{ 13207 match(Set dst (AbsD src)); 13208 13209 ins_cost(INSN_COST * 3); 13210 format %{ "fabsd $dst, $src" %} 13211 ins_encode %{ 13212 __ fabsd(as_FloatRegister($dst$$reg), 13213 as_FloatRegister($src$$reg)); 13214 %} 13215 13216 ins_pipe(fp_uop_d); 13217 %} 13218 13219 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13220 match(Set dst (SqrtD src)); 13221 13222 ins_cost(INSN_COST * 50); 13223 format %{ "fsqrtd $dst, $src" %} 13224 ins_encode %{ 13225 __ fsqrtd(as_FloatRegister($dst$$reg), 13226 as_FloatRegister($src$$reg)); 13227 %} 13228 13229 ins_pipe(fp_div_s); 13230 %} 13231 13232 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13233 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 13234 13235 ins_cost(INSN_COST * 50); 13236 format %{ "fsqrts $dst, $src" %} 13237 ins_encode %{ 13238 __ fsqrts(as_FloatRegister($dst$$reg), 13239 as_FloatRegister($src$$reg)); 13240 %} 13241 13242 ins_pipe(fp_div_d); 13243 %} 13244 13245 // Math.rint, floor, ceil 13246 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 13247 match(Set dst (RoundDoubleMode src rmode)); 13248 format %{ "frint $dst, $src, $rmode" %} 13249 ins_encode %{ 13250 switch ($rmode$$constant) { 13251 case RoundDoubleModeNode::rmode_rint: 13252 __ frintnd(as_FloatRegister($dst$$reg), 13253 as_FloatRegister($src$$reg)); 13254 break; 13255 case RoundDoubleModeNode::rmode_floor: 13256 __ frintmd(as_FloatRegister($dst$$reg), 13257 as_FloatRegister($src$$reg)); 13258 break; 13259 case RoundDoubleModeNode::rmode_ceil: 13260 __ frintpd(as_FloatRegister($dst$$reg), 13261 as_FloatRegister($src$$reg)); 13262 break; 13263 } 13264 %} 13265 ins_pipe(fp_uop_d); 13266 %} 13267 13268 // ============================================================================ 13269 // Logical Instructions 13270 13271 // Integer Logical Instructions 13272 13273 // And Instructions 13274 13275 13276 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13277 match(Set dst (AndI src1 src2)); 13278 13279 format %{ "andw $dst, $src1, $src2\t# int" %} 13280 13281 ins_cost(INSN_COST); 13282 ins_encode %{ 13283 __ andw(as_Register($dst$$reg), 13284 as_Register($src1$$reg), 13285 as_Register($src2$$reg)); 13286 %} 13287 13288 ins_pipe(ialu_reg_reg); 13289 %} 13290 13291 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13292 match(Set dst (AndI src1 src2)); 13293 13294 format %{ "andsw $dst, $src1, $src2\t# int" %} 13295 13296 ins_cost(INSN_COST); 13297 ins_encode %{ 13298 __ andw(as_Register($dst$$reg), 13299 as_Register($src1$$reg), 13300 (unsigned long)($src2$$constant)); 13301 %} 13302 13303 ins_pipe(ialu_reg_imm); 13304 %} 13305 13306 // Or Instructions 13307 13308 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13309 match(Set dst (OrI src1 src2)); 13310 13311 format %{ "orrw $dst, $src1, $src2\t# int" %} 13312 13313 ins_cost(INSN_COST); 13314 ins_encode %{ 13315 __ orrw(as_Register($dst$$reg), 13316 as_Register($src1$$reg), 13317 as_Register($src2$$reg)); 13318 %} 13319 13320 ins_pipe(ialu_reg_reg); 13321 %} 13322 13323 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13324 match(Set dst (OrI src1 src2)); 13325 13326 format %{ "orrw $dst, $src1, $src2\t# int" %} 13327 13328 ins_cost(INSN_COST); 13329 ins_encode %{ 13330 __ orrw(as_Register($dst$$reg), 13331 as_Register($src1$$reg), 13332 (unsigned long)($src2$$constant)); 13333 %} 13334 13335 ins_pipe(ialu_reg_imm); 13336 %} 13337 13338 // Xor Instructions 13339 13340 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13341 match(Set dst (XorI src1 src2)); 13342 13343 format %{ "eorw $dst, $src1, $src2\t# int" %} 13344 13345 ins_cost(INSN_COST); 13346 ins_encode %{ 13347 __ eorw(as_Register($dst$$reg), 13348 as_Register($src1$$reg), 13349 as_Register($src2$$reg)); 13350 %} 13351 13352 ins_pipe(ialu_reg_reg); 13353 %} 13354 13355 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13356 match(Set dst (XorI src1 src2)); 13357 13358 format %{ "eorw $dst, $src1, $src2\t# int" %} 13359 13360 ins_cost(INSN_COST); 13361 ins_encode %{ 13362 __ eorw(as_Register($dst$$reg), 13363 as_Register($src1$$reg), 13364 (unsigned long)($src2$$constant)); 13365 %} 13366 13367 ins_pipe(ialu_reg_imm); 13368 %} 13369 13370 // Long Logical Instructions 13371 // TODO 13372 13373 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13374 match(Set dst (AndL src1 src2)); 13375 13376 format %{ "and $dst, $src1, $src2\t# int" %} 13377 13378 ins_cost(INSN_COST); 13379 ins_encode %{ 13380 __ andr(as_Register($dst$$reg), 13381 as_Register($src1$$reg), 13382 as_Register($src2$$reg)); 13383 %} 13384 13385 ins_pipe(ialu_reg_reg); 13386 %} 13387 13388 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13389 match(Set dst (AndL src1 src2)); 13390 13391 format %{ "and $dst, $src1, $src2\t# int" %} 13392 13393 ins_cost(INSN_COST); 13394 ins_encode %{ 13395 __ andr(as_Register($dst$$reg), 13396 as_Register($src1$$reg), 13397 (unsigned long)($src2$$constant)); 13398 %} 13399 13400 ins_pipe(ialu_reg_imm); 13401 %} 13402 13403 // Or Instructions 13404 13405 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13406 match(Set dst (OrL src1 src2)); 13407 13408 format %{ "orr $dst, $src1, $src2\t# int" %} 13409 13410 ins_cost(INSN_COST); 13411 ins_encode %{ 13412 __ orr(as_Register($dst$$reg), 13413 as_Register($src1$$reg), 13414 as_Register($src2$$reg)); 13415 %} 13416 13417 ins_pipe(ialu_reg_reg); 13418 %} 13419 13420 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13421 match(Set dst (OrL src1 src2)); 13422 13423 format %{ "orr $dst, $src1, $src2\t# int" %} 13424 13425 ins_cost(INSN_COST); 13426 ins_encode %{ 13427 __ orr(as_Register($dst$$reg), 13428 as_Register($src1$$reg), 13429 (unsigned long)($src2$$constant)); 13430 %} 13431 13432 ins_pipe(ialu_reg_imm); 13433 %} 13434 13435 // Xor Instructions 13436 13437 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13438 match(Set dst (XorL src1 src2)); 13439 13440 format %{ "eor $dst, $src1, $src2\t# int" %} 13441 13442 ins_cost(INSN_COST); 13443 ins_encode %{ 13444 __ eor(as_Register($dst$$reg), 13445 as_Register($src1$$reg), 13446 as_Register($src2$$reg)); 13447 %} 13448 13449 ins_pipe(ialu_reg_reg); 13450 %} 13451 13452 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13453 match(Set dst (XorL src1 src2)); 13454 13455 ins_cost(INSN_COST); 13456 format %{ "eor $dst, $src1, $src2\t# int" %} 13457 13458 ins_encode %{ 13459 __ eor(as_Register($dst$$reg), 13460 as_Register($src1$$reg), 13461 (unsigned long)($src2$$constant)); 13462 %} 13463 13464 ins_pipe(ialu_reg_imm); 13465 %} 13466 13467 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13468 %{ 13469 match(Set dst (ConvI2L src)); 13470 13471 ins_cost(INSN_COST); 13472 format %{ "sxtw $dst, $src\t# i2l" %} 13473 ins_encode %{ 13474 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13475 %} 13476 ins_pipe(ialu_reg_shift); 13477 %} 13478 13479 // this pattern occurs in bigmath arithmetic 13480 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13481 %{ 13482 match(Set dst (AndL (ConvI2L src) mask)); 13483 13484 ins_cost(INSN_COST); 13485 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13486 ins_encode %{ 13487 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13488 %} 13489 13490 ins_pipe(ialu_reg_shift); 13491 %} 13492 13493 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13494 match(Set dst (ConvL2I src)); 13495 13496 ins_cost(INSN_COST); 13497 format %{ "movw $dst, $src \t// l2i" %} 13498 13499 ins_encode %{ 13500 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13501 %} 13502 13503 ins_pipe(ialu_reg); 13504 %} 13505 13506 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13507 %{ 13508 match(Set dst (Conv2B src)); 13509 effect(KILL cr); 13510 13511 format %{ 13512 "cmpw $src, zr\n\t" 13513 "cset $dst, ne" 13514 %} 13515 13516 ins_encode %{ 13517 __ cmpw(as_Register($src$$reg), zr); 13518 __ cset(as_Register($dst$$reg), Assembler::NE); 13519 %} 13520 13521 ins_pipe(ialu_reg); 13522 %} 13523 13524 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13525 %{ 13526 match(Set dst (Conv2B src)); 13527 effect(KILL cr); 13528 13529 format %{ 13530 "cmp $src, zr\n\t" 13531 "cset $dst, ne" 13532 %} 13533 13534 ins_encode %{ 13535 __ cmp(as_Register($src$$reg), zr); 13536 __ cset(as_Register($dst$$reg), Assembler::NE); 13537 %} 13538 13539 ins_pipe(ialu_reg); 13540 %} 13541 13542 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13543 match(Set dst (ConvD2F src)); 13544 13545 ins_cost(INSN_COST * 5); 13546 format %{ "fcvtd $dst, $src \t// d2f" %} 13547 13548 ins_encode %{ 13549 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13550 %} 13551 13552 ins_pipe(fp_d2f); 13553 %} 13554 13555 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13556 match(Set dst (ConvF2D src)); 13557 13558 ins_cost(INSN_COST * 5); 13559 format %{ "fcvts $dst, $src \t// f2d" %} 13560 13561 ins_encode %{ 13562 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13563 %} 13564 13565 ins_pipe(fp_f2d); 13566 %} 13567 13568 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13569 match(Set dst (ConvF2I src)); 13570 13571 ins_cost(INSN_COST * 5); 13572 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13573 13574 ins_encode %{ 13575 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13576 %} 13577 13578 ins_pipe(fp_f2i); 13579 %} 13580 13581 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13582 match(Set dst (ConvF2L src)); 13583 13584 ins_cost(INSN_COST * 5); 13585 format %{ "fcvtzs $dst, $src \t// f2l" %} 13586 13587 ins_encode %{ 13588 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13589 %} 13590 13591 ins_pipe(fp_f2l); 13592 %} 13593 13594 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13595 match(Set dst (ConvI2F src)); 13596 13597 ins_cost(INSN_COST * 5); 13598 format %{ "scvtfws $dst, $src \t// i2f" %} 13599 13600 ins_encode %{ 13601 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13602 %} 13603 13604 ins_pipe(fp_i2f); 13605 %} 13606 13607 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13608 match(Set dst (ConvL2F src)); 13609 13610 ins_cost(INSN_COST * 5); 13611 format %{ "scvtfs $dst, $src \t// l2f" %} 13612 13613 ins_encode %{ 13614 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13615 %} 13616 13617 ins_pipe(fp_l2f); 13618 %} 13619 13620 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13621 match(Set dst (ConvD2I src)); 13622 13623 ins_cost(INSN_COST * 5); 13624 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13625 13626 ins_encode %{ 13627 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13628 %} 13629 13630 ins_pipe(fp_d2i); 13631 %} 13632 13633 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13634 match(Set dst (ConvD2L src)); 13635 13636 ins_cost(INSN_COST * 5); 13637 format %{ "fcvtzd $dst, $src \t// d2l" %} 13638 13639 ins_encode %{ 13640 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13641 %} 13642 13643 ins_pipe(fp_d2l); 13644 %} 13645 13646 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13647 match(Set dst (ConvI2D src)); 13648 13649 ins_cost(INSN_COST * 5); 13650 format %{ "scvtfwd $dst, $src \t// i2d" %} 13651 13652 ins_encode %{ 13653 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13654 %} 13655 13656 ins_pipe(fp_i2d); 13657 %} 13658 13659 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13660 match(Set dst (ConvL2D src)); 13661 13662 ins_cost(INSN_COST * 5); 13663 format %{ "scvtfd $dst, $src \t// l2d" %} 13664 13665 ins_encode %{ 13666 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13667 %} 13668 13669 ins_pipe(fp_l2d); 13670 %} 13671 13672 // stack <-> reg and reg <-> reg shuffles with no conversion 13673 13674 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13675 13676 match(Set dst (MoveF2I src)); 13677 13678 effect(DEF dst, USE src); 13679 13680 ins_cost(4 * INSN_COST); 13681 13682 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13683 13684 ins_encode %{ 13685 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13686 %} 13687 13688 ins_pipe(iload_reg_reg); 13689 13690 %} 13691 13692 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13693 13694 match(Set dst (MoveI2F src)); 13695 13696 effect(DEF dst, USE src); 13697 13698 ins_cost(4 * INSN_COST); 13699 13700 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13701 13702 ins_encode %{ 13703 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13704 %} 13705 13706 ins_pipe(pipe_class_memory); 13707 13708 %} 13709 13710 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13711 13712 match(Set dst (MoveD2L src)); 13713 13714 effect(DEF dst, USE src); 13715 13716 ins_cost(4 * INSN_COST); 13717 13718 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13719 13720 ins_encode %{ 13721 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13722 %} 13723 13724 ins_pipe(iload_reg_reg); 13725 13726 %} 13727 13728 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13729 13730 match(Set dst (MoveL2D src)); 13731 13732 effect(DEF dst, USE src); 13733 13734 ins_cost(4 * INSN_COST); 13735 13736 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13737 13738 ins_encode %{ 13739 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13740 %} 13741 13742 ins_pipe(pipe_class_memory); 13743 13744 %} 13745 13746 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13747 13748 match(Set dst (MoveF2I src)); 13749 13750 effect(DEF dst, USE src); 13751 13752 ins_cost(INSN_COST); 13753 13754 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13755 13756 ins_encode %{ 13757 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13758 %} 13759 13760 ins_pipe(pipe_class_memory); 13761 13762 %} 13763 13764 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13765 13766 match(Set dst (MoveI2F src)); 13767 13768 effect(DEF dst, USE src); 13769 13770 ins_cost(INSN_COST); 13771 13772 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13773 13774 ins_encode %{ 13775 __ strw($src$$Register, Address(sp, $dst$$disp)); 13776 %} 13777 13778 ins_pipe(istore_reg_reg); 13779 13780 %} 13781 13782 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13783 13784 match(Set dst (MoveD2L src)); 13785 13786 effect(DEF dst, USE src); 13787 13788 ins_cost(INSN_COST); 13789 13790 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13791 13792 ins_encode %{ 13793 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13794 %} 13795 13796 ins_pipe(pipe_class_memory); 13797 13798 %} 13799 13800 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13801 13802 match(Set dst (MoveL2D src)); 13803 13804 effect(DEF dst, USE src); 13805 13806 ins_cost(INSN_COST); 13807 13808 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13809 13810 ins_encode %{ 13811 __ str($src$$Register, Address(sp, $dst$$disp)); 13812 %} 13813 13814 ins_pipe(istore_reg_reg); 13815 13816 %} 13817 13818 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13819 13820 match(Set dst (MoveF2I src)); 13821 13822 effect(DEF dst, USE src); 13823 13824 ins_cost(INSN_COST); 13825 13826 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13827 13828 ins_encode %{ 13829 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13830 %} 13831 13832 ins_pipe(fp_f2i); 13833 13834 %} 13835 13836 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13837 13838 match(Set dst (MoveI2F src)); 13839 13840 effect(DEF dst, USE src); 13841 13842 ins_cost(INSN_COST); 13843 13844 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13845 13846 ins_encode %{ 13847 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13848 %} 13849 13850 ins_pipe(fp_i2f); 13851 13852 %} 13853 13854 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13855 13856 match(Set dst (MoveD2L src)); 13857 13858 effect(DEF dst, USE src); 13859 13860 ins_cost(INSN_COST); 13861 13862 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13863 13864 ins_encode %{ 13865 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13866 %} 13867 13868 ins_pipe(fp_d2l); 13869 13870 %} 13871 13872 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13873 13874 match(Set dst (MoveL2D src)); 13875 13876 effect(DEF dst, USE src); 13877 13878 ins_cost(INSN_COST); 13879 13880 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13881 13882 ins_encode %{ 13883 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13884 %} 13885 13886 ins_pipe(fp_l2d); 13887 13888 %} 13889 13890 // ============================================================================ 13891 // clearing of an array 13892 13893 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13894 %{ 13895 match(Set dummy (ClearArray cnt base)); 13896 effect(USE_KILL cnt, USE_KILL base); 13897 13898 ins_cost(4 * INSN_COST); 13899 format %{ "ClearArray $cnt, $base" %} 13900 13901 ins_encode %{ 13902 __ zero_words($base$$Register, $cnt$$Register); 13903 %} 13904 13905 ins_pipe(pipe_class_memory); 13906 %} 13907 13908 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13909 %{ 13910 predicate((u_int64_t)n->in(2)->get_long() 13911 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13912 match(Set dummy (ClearArray cnt base)); 13913 effect(USE_KILL base); 13914 13915 ins_cost(4 * INSN_COST); 13916 format %{ "ClearArray $cnt, $base" %} 13917 13918 ins_encode %{ 13919 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13920 %} 13921 13922 ins_pipe(pipe_class_memory); 13923 %} 13924 13925 // ============================================================================ 13926 // Overflow Math Instructions 13927 13928 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13929 %{ 13930 match(Set cr (OverflowAddI op1 op2)); 13931 13932 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13933 ins_cost(INSN_COST); 13934 ins_encode %{ 13935 __ cmnw($op1$$Register, $op2$$Register); 13936 %} 13937 13938 ins_pipe(icmp_reg_reg); 13939 %} 13940 13941 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13942 %{ 13943 match(Set cr (OverflowAddI op1 op2)); 13944 13945 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13946 ins_cost(INSN_COST); 13947 ins_encode %{ 13948 __ cmnw($op1$$Register, $op2$$constant); 13949 %} 13950 13951 ins_pipe(icmp_reg_imm); 13952 %} 13953 13954 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13955 %{ 13956 match(Set cr (OverflowAddL op1 op2)); 13957 13958 format %{ "cmn $op1, $op2\t# overflow check long" %} 13959 ins_cost(INSN_COST); 13960 ins_encode %{ 13961 __ cmn($op1$$Register, $op2$$Register); 13962 %} 13963 13964 ins_pipe(icmp_reg_reg); 13965 %} 13966 13967 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13968 %{ 13969 match(Set cr (OverflowAddL op1 op2)); 13970 13971 format %{ "cmn $op1, $op2\t# overflow check long" %} 13972 ins_cost(INSN_COST); 13973 ins_encode %{ 13974 __ cmn($op1$$Register, $op2$$constant); 13975 %} 13976 13977 ins_pipe(icmp_reg_imm); 13978 %} 13979 13980 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13981 %{ 13982 match(Set cr (OverflowSubI op1 op2)); 13983 13984 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13985 ins_cost(INSN_COST); 13986 ins_encode %{ 13987 __ cmpw($op1$$Register, $op2$$Register); 13988 %} 13989 13990 ins_pipe(icmp_reg_reg); 13991 %} 13992 13993 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13994 %{ 13995 match(Set cr (OverflowSubI op1 op2)); 13996 13997 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13998 ins_cost(INSN_COST); 13999 ins_encode %{ 14000 __ cmpw($op1$$Register, $op2$$constant); 14001 %} 14002 14003 ins_pipe(icmp_reg_imm); 14004 %} 14005 14006 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14007 %{ 14008 match(Set cr (OverflowSubL op1 op2)); 14009 14010 format %{ "cmp $op1, $op2\t# overflow check long" %} 14011 ins_cost(INSN_COST); 14012 ins_encode %{ 14013 __ cmp($op1$$Register, $op2$$Register); 14014 %} 14015 14016 ins_pipe(icmp_reg_reg); 14017 %} 14018 14019 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14020 %{ 14021 match(Set cr (OverflowSubL op1 op2)); 14022 14023 format %{ "cmp $op1, $op2\t# overflow check long" %} 14024 ins_cost(INSN_COST); 14025 ins_encode %{ 14026 __ subs(zr, $op1$$Register, $op2$$constant); 14027 %} 14028 14029 ins_pipe(icmp_reg_imm); 14030 %} 14031 14032 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14033 %{ 14034 match(Set cr (OverflowSubI zero op1)); 14035 14036 format %{ "cmpw zr, $op1\t# overflow check int" %} 14037 ins_cost(INSN_COST); 14038 ins_encode %{ 14039 __ cmpw(zr, $op1$$Register); 14040 %} 14041 14042 ins_pipe(icmp_reg_imm); 14043 %} 14044 14045 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14046 %{ 14047 match(Set cr (OverflowSubL zero op1)); 14048 14049 format %{ "cmp zr, $op1\t# overflow check long" %} 14050 ins_cost(INSN_COST); 14051 ins_encode %{ 14052 __ cmp(zr, $op1$$Register); 14053 %} 14054 14055 ins_pipe(icmp_reg_imm); 14056 %} 14057 14058 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14059 %{ 14060 match(Set cr (OverflowMulI op1 op2)); 14061 14062 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14063 "cmp rscratch1, rscratch1, sxtw\n\t" 14064 "movw rscratch1, #0x80000000\n\t" 14065 "cselw rscratch1, rscratch1, zr, NE\n\t" 14066 "cmpw rscratch1, #1" %} 14067 ins_cost(5 * INSN_COST); 14068 ins_encode %{ 14069 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14070 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14071 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14072 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14073 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14074 %} 14075 14076 ins_pipe(pipe_slow); 14077 %} 14078 14079 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14080 %{ 14081 match(If cmp (OverflowMulI op1 op2)); 14082 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14083 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14084 effect(USE labl, KILL cr); 14085 14086 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14087 "cmp rscratch1, rscratch1, sxtw\n\t" 14088 "b$cmp $labl" %} 14089 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14090 ins_encode %{ 14091 Label* L = $labl$$label; 14092 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14093 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14094 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14095 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14096 %} 14097 14098 ins_pipe(pipe_serial); 14099 %} 14100 14101 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14102 %{ 14103 match(Set cr (OverflowMulL op1 op2)); 14104 14105 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14106 "smulh rscratch2, $op1, $op2\n\t" 14107 "cmp rscratch2, rscratch1, ASR #63\n\t" 14108 "movw rscratch1, #0x80000000\n\t" 14109 "cselw rscratch1, rscratch1, zr, NE\n\t" 14110 "cmpw rscratch1, #1" %} 14111 ins_cost(6 * INSN_COST); 14112 ins_encode %{ 14113 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14114 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14115 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14116 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14117 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14118 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14119 %} 14120 14121 ins_pipe(pipe_slow); 14122 %} 14123 14124 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14125 %{ 14126 match(If cmp (OverflowMulL op1 op2)); 14127 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14128 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14129 effect(USE labl, KILL cr); 14130 14131 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14132 "smulh rscratch2, $op1, $op2\n\t" 14133 "cmp rscratch2, rscratch1, ASR #63\n\t" 14134 "b$cmp $labl" %} 14135 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14136 ins_encode %{ 14137 Label* L = $labl$$label; 14138 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14139 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14140 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14141 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14142 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14143 %} 14144 14145 ins_pipe(pipe_serial); 14146 %} 14147 14148 // ============================================================================ 14149 // Compare Instructions 14150 14151 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14152 %{ 14153 match(Set cr (CmpI op1 op2)); 14154 14155 effect(DEF cr, USE op1, USE op2); 14156 14157 ins_cost(INSN_COST); 14158 format %{ "cmpw $op1, $op2" %} 14159 14160 ins_encode(aarch64_enc_cmpw(op1, op2)); 14161 14162 ins_pipe(icmp_reg_reg); 14163 %} 14164 14165 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14166 %{ 14167 match(Set cr (CmpI op1 zero)); 14168 14169 effect(DEF cr, USE op1); 14170 14171 ins_cost(INSN_COST); 14172 format %{ "cmpw $op1, 0" %} 14173 14174 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14175 14176 ins_pipe(icmp_reg_imm); 14177 %} 14178 14179 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14180 %{ 14181 match(Set cr (CmpI op1 op2)); 14182 14183 effect(DEF cr, USE op1); 14184 14185 ins_cost(INSN_COST); 14186 format %{ "cmpw $op1, $op2" %} 14187 14188 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14189 14190 ins_pipe(icmp_reg_imm); 14191 %} 14192 14193 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14194 %{ 14195 match(Set cr (CmpI op1 op2)); 14196 14197 effect(DEF cr, USE op1); 14198 14199 ins_cost(INSN_COST * 2); 14200 format %{ "cmpw $op1, $op2" %} 14201 14202 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14203 14204 ins_pipe(icmp_reg_imm); 14205 %} 14206 14207 // Unsigned compare Instructions; really, same as signed compare 14208 // except it should only be used to feed an If or a CMovI which takes a 14209 // cmpOpU. 14210 14211 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14212 %{ 14213 match(Set cr (CmpU op1 op2)); 14214 14215 effect(DEF cr, USE op1, USE op2); 14216 14217 ins_cost(INSN_COST); 14218 format %{ "cmpw $op1, $op2\t# unsigned" %} 14219 14220 ins_encode(aarch64_enc_cmpw(op1, op2)); 14221 14222 ins_pipe(icmp_reg_reg); 14223 %} 14224 14225 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14226 %{ 14227 match(Set cr (CmpU op1 zero)); 14228 14229 effect(DEF cr, USE op1); 14230 14231 ins_cost(INSN_COST); 14232 format %{ "cmpw $op1, #0\t# unsigned" %} 14233 14234 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14235 14236 ins_pipe(icmp_reg_imm); 14237 %} 14238 14239 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14240 %{ 14241 match(Set cr (CmpU op1 op2)); 14242 14243 effect(DEF cr, USE op1); 14244 14245 ins_cost(INSN_COST); 14246 format %{ "cmpw $op1, $op2\t# unsigned" %} 14247 14248 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14249 14250 ins_pipe(icmp_reg_imm); 14251 %} 14252 14253 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14254 %{ 14255 match(Set cr (CmpU op1 op2)); 14256 14257 effect(DEF cr, USE op1); 14258 14259 ins_cost(INSN_COST * 2); 14260 format %{ "cmpw $op1, $op2\t# unsigned" %} 14261 14262 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14263 14264 ins_pipe(icmp_reg_imm); 14265 %} 14266 14267 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14268 %{ 14269 match(Set cr (CmpL op1 op2)); 14270 14271 effect(DEF cr, USE op1, USE op2); 14272 14273 ins_cost(INSN_COST); 14274 format %{ "cmp $op1, $op2" %} 14275 14276 ins_encode(aarch64_enc_cmp(op1, op2)); 14277 14278 ins_pipe(icmp_reg_reg); 14279 %} 14280 14281 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14282 %{ 14283 match(Set cr (CmpL op1 zero)); 14284 14285 effect(DEF cr, USE op1); 14286 14287 ins_cost(INSN_COST); 14288 format %{ "tst $op1" %} 14289 14290 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14291 14292 ins_pipe(icmp_reg_imm); 14293 %} 14294 14295 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14296 %{ 14297 match(Set cr (CmpL op1 op2)); 14298 14299 effect(DEF cr, USE op1); 14300 14301 ins_cost(INSN_COST); 14302 format %{ "cmp $op1, $op2" %} 14303 14304 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14305 14306 ins_pipe(icmp_reg_imm); 14307 %} 14308 14309 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14310 %{ 14311 match(Set cr (CmpL op1 op2)); 14312 14313 effect(DEF cr, USE op1); 14314 14315 ins_cost(INSN_COST * 2); 14316 format %{ "cmp $op1, $op2" %} 14317 14318 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14319 14320 ins_pipe(icmp_reg_imm); 14321 %} 14322 14323 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14324 %{ 14325 match(Set cr (CmpUL op1 op2)); 14326 14327 effect(DEF cr, USE op1, USE op2); 14328 14329 ins_cost(INSN_COST); 14330 format %{ "cmp $op1, $op2" %} 14331 14332 ins_encode(aarch64_enc_cmp(op1, op2)); 14333 14334 ins_pipe(icmp_reg_reg); 14335 %} 14336 14337 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14338 %{ 14339 match(Set cr (CmpUL op1 zero)); 14340 14341 effect(DEF cr, USE op1); 14342 14343 ins_cost(INSN_COST); 14344 format %{ "tst $op1" %} 14345 14346 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14347 14348 ins_pipe(icmp_reg_imm); 14349 %} 14350 14351 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14352 %{ 14353 match(Set cr (CmpUL op1 op2)); 14354 14355 effect(DEF cr, USE op1); 14356 14357 ins_cost(INSN_COST); 14358 format %{ "cmp $op1, $op2" %} 14359 14360 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14361 14362 ins_pipe(icmp_reg_imm); 14363 %} 14364 14365 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14366 %{ 14367 match(Set cr (CmpUL op1 op2)); 14368 14369 effect(DEF cr, USE op1); 14370 14371 ins_cost(INSN_COST * 2); 14372 format %{ "cmp $op1, $op2" %} 14373 14374 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14375 14376 ins_pipe(icmp_reg_imm); 14377 %} 14378 14379 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14380 %{ 14381 match(Set cr (CmpP op1 op2)); 14382 14383 effect(DEF cr, USE op1, USE op2); 14384 14385 ins_cost(INSN_COST); 14386 format %{ "cmp $op1, $op2\t // ptr" %} 14387 14388 ins_encode(aarch64_enc_cmpp(op1, op2)); 14389 14390 ins_pipe(icmp_reg_reg); 14391 %} 14392 14393 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14394 %{ 14395 match(Set cr (CmpN op1 op2)); 14396 14397 effect(DEF cr, USE op1, USE op2); 14398 14399 ins_cost(INSN_COST); 14400 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14401 14402 ins_encode(aarch64_enc_cmpn(op1, op2)); 14403 14404 ins_pipe(icmp_reg_reg); 14405 %} 14406 14407 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14408 %{ 14409 match(Set cr (CmpP op1 zero)); 14410 14411 effect(DEF cr, USE op1, USE zero); 14412 14413 ins_cost(INSN_COST); 14414 format %{ "cmp $op1, 0\t // ptr" %} 14415 14416 ins_encode(aarch64_enc_testp(op1)); 14417 14418 ins_pipe(icmp_reg_imm); 14419 %} 14420 14421 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14422 %{ 14423 match(Set cr (CmpN op1 zero)); 14424 14425 effect(DEF cr, USE op1, USE zero); 14426 14427 ins_cost(INSN_COST); 14428 format %{ "cmp $op1, 0\t // compressed ptr" %} 14429 14430 ins_encode(aarch64_enc_testn(op1)); 14431 14432 ins_pipe(icmp_reg_imm); 14433 %} 14434 14435 // FP comparisons 14436 // 14437 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14438 // using normal cmpOp. See declaration of rFlagsReg for details. 14439 14440 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14441 %{ 14442 match(Set cr (CmpF src1 src2)); 14443 14444 ins_cost(3 * INSN_COST); 14445 format %{ "fcmps $src1, $src2" %} 14446 14447 ins_encode %{ 14448 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14449 %} 14450 14451 ins_pipe(pipe_class_compare); 14452 %} 14453 14454 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14455 %{ 14456 match(Set cr (CmpF src1 src2)); 14457 14458 ins_cost(3 * INSN_COST); 14459 format %{ "fcmps $src1, 0.0" %} 14460 14461 ins_encode %{ 14462 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14463 %} 14464 14465 ins_pipe(pipe_class_compare); 14466 %} 14467 // FROM HERE 14468 14469 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14470 %{ 14471 match(Set cr (CmpD src1 src2)); 14472 14473 ins_cost(3 * INSN_COST); 14474 format %{ "fcmpd $src1, $src2" %} 14475 14476 ins_encode %{ 14477 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14478 %} 14479 14480 ins_pipe(pipe_class_compare); 14481 %} 14482 14483 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14484 %{ 14485 match(Set cr (CmpD src1 src2)); 14486 14487 ins_cost(3 * INSN_COST); 14488 format %{ "fcmpd $src1, 0.0" %} 14489 14490 ins_encode %{ 14491 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14492 %} 14493 14494 ins_pipe(pipe_class_compare); 14495 %} 14496 14497 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14498 %{ 14499 match(Set dst (CmpF3 src1 src2)); 14500 effect(KILL cr); 14501 14502 ins_cost(5 * INSN_COST); 14503 format %{ "fcmps $src1, $src2\n\t" 14504 "csinvw($dst, zr, zr, eq\n\t" 14505 "csnegw($dst, $dst, $dst, lt)" 14506 %} 14507 14508 ins_encode %{ 14509 Label done; 14510 FloatRegister s1 = as_FloatRegister($src1$$reg); 14511 FloatRegister s2 = as_FloatRegister($src2$$reg); 14512 Register d = as_Register($dst$$reg); 14513 __ fcmps(s1, s2); 14514 // installs 0 if EQ else -1 14515 __ csinvw(d, zr, zr, Assembler::EQ); 14516 // keeps -1 if less or unordered else installs 1 14517 __ csnegw(d, d, d, Assembler::LT); 14518 __ bind(done); 14519 %} 14520 14521 ins_pipe(pipe_class_default); 14522 14523 %} 14524 14525 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14526 %{ 14527 match(Set dst (CmpD3 src1 src2)); 14528 effect(KILL cr); 14529 14530 ins_cost(5 * INSN_COST); 14531 format %{ "fcmpd $src1, $src2\n\t" 14532 "csinvw($dst, zr, zr, eq\n\t" 14533 "csnegw($dst, $dst, $dst, lt)" 14534 %} 14535 14536 ins_encode %{ 14537 Label done; 14538 FloatRegister s1 = as_FloatRegister($src1$$reg); 14539 FloatRegister s2 = as_FloatRegister($src2$$reg); 14540 Register d = as_Register($dst$$reg); 14541 __ fcmpd(s1, s2); 14542 // installs 0 if EQ else -1 14543 __ csinvw(d, zr, zr, Assembler::EQ); 14544 // keeps -1 if less or unordered else installs 1 14545 __ csnegw(d, d, d, Assembler::LT); 14546 __ bind(done); 14547 %} 14548 ins_pipe(pipe_class_default); 14549 14550 %} 14551 14552 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14553 %{ 14554 match(Set dst (CmpF3 src1 zero)); 14555 effect(KILL cr); 14556 14557 ins_cost(5 * INSN_COST); 14558 format %{ "fcmps $src1, 0.0\n\t" 14559 "csinvw($dst, zr, zr, eq\n\t" 14560 "csnegw($dst, $dst, $dst, lt)" 14561 %} 14562 14563 ins_encode %{ 14564 Label done; 14565 FloatRegister s1 = as_FloatRegister($src1$$reg); 14566 Register d = as_Register($dst$$reg); 14567 __ fcmps(s1, 0.0); 14568 // installs 0 if EQ else -1 14569 __ csinvw(d, zr, zr, Assembler::EQ); 14570 // keeps -1 if less or unordered else installs 1 14571 __ csnegw(d, d, d, Assembler::LT); 14572 __ bind(done); 14573 %} 14574 14575 ins_pipe(pipe_class_default); 14576 14577 %} 14578 14579 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14580 %{ 14581 match(Set dst (CmpD3 src1 zero)); 14582 effect(KILL cr); 14583 14584 ins_cost(5 * INSN_COST); 14585 format %{ "fcmpd $src1, 0.0\n\t" 14586 "csinvw($dst, zr, zr, eq\n\t" 14587 "csnegw($dst, $dst, $dst, lt)" 14588 %} 14589 14590 ins_encode %{ 14591 Label done; 14592 FloatRegister s1 = as_FloatRegister($src1$$reg); 14593 Register d = as_Register($dst$$reg); 14594 __ fcmpd(s1, 0.0); 14595 // installs 0 if EQ else -1 14596 __ csinvw(d, zr, zr, Assembler::EQ); 14597 // keeps -1 if less or unordered else installs 1 14598 __ csnegw(d, d, d, Assembler::LT); 14599 __ bind(done); 14600 %} 14601 ins_pipe(pipe_class_default); 14602 14603 %} 14604 14605 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14606 %{ 14607 match(Set dst (CmpLTMask p q)); 14608 effect(KILL cr); 14609 14610 ins_cost(3 * INSN_COST); 14611 14612 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14613 "csetw $dst, lt\n\t" 14614 "subw $dst, zr, $dst" 14615 %} 14616 14617 ins_encode %{ 14618 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14619 __ csetw(as_Register($dst$$reg), Assembler::LT); 14620 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14621 %} 14622 14623 ins_pipe(ialu_reg_reg); 14624 %} 14625 14626 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14627 %{ 14628 match(Set dst (CmpLTMask src zero)); 14629 effect(KILL cr); 14630 14631 ins_cost(INSN_COST); 14632 14633 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14634 14635 ins_encode %{ 14636 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14637 %} 14638 14639 ins_pipe(ialu_reg_shift); 14640 %} 14641 14642 // ============================================================================ 14643 // Max and Min 14644 14645 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14646 %{ 14647 effect( DEF dst, USE src1, USE src2, USE cr ); 14648 14649 ins_cost(INSN_COST * 2); 14650 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14651 14652 ins_encode %{ 14653 __ cselw(as_Register($dst$$reg), 14654 as_Register($src1$$reg), 14655 as_Register($src2$$reg), 14656 Assembler::LT); 14657 %} 14658 14659 ins_pipe(icond_reg_reg); 14660 %} 14661 14662 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14663 %{ 14664 match(Set dst (MinI src1 src2)); 14665 ins_cost(INSN_COST * 3); 14666 14667 expand %{ 14668 rFlagsReg cr; 14669 compI_reg_reg(cr, src1, src2); 14670 cmovI_reg_reg_lt(dst, src1, src2, cr); 14671 %} 14672 14673 %} 14674 // FROM HERE 14675 14676 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14677 %{ 14678 effect( DEF dst, USE src1, USE src2, USE cr ); 14679 14680 ins_cost(INSN_COST * 2); 14681 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14682 14683 ins_encode %{ 14684 __ cselw(as_Register($dst$$reg), 14685 as_Register($src1$$reg), 14686 as_Register($src2$$reg), 14687 Assembler::GT); 14688 %} 14689 14690 ins_pipe(icond_reg_reg); 14691 %} 14692 14693 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14694 %{ 14695 match(Set dst (MaxI src1 src2)); 14696 ins_cost(INSN_COST * 3); 14697 expand %{ 14698 rFlagsReg cr; 14699 compI_reg_reg(cr, src1, src2); 14700 cmovI_reg_reg_gt(dst, src1, src2, cr); 14701 %} 14702 %} 14703 14704 // ============================================================================ 14705 // Branch Instructions 14706 14707 // Direct Branch. 14708 instruct branch(label lbl) 14709 %{ 14710 match(Goto); 14711 14712 effect(USE lbl); 14713 14714 ins_cost(BRANCH_COST); 14715 format %{ "b $lbl" %} 14716 14717 ins_encode(aarch64_enc_b(lbl)); 14718 14719 ins_pipe(pipe_branch); 14720 %} 14721 14722 // Conditional Near Branch 14723 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14724 %{ 14725 // Same match rule as `branchConFar'. 14726 match(If cmp cr); 14727 14728 effect(USE lbl); 14729 14730 ins_cost(BRANCH_COST); 14731 // If set to 1 this indicates that the current instruction is a 14732 // short variant of a long branch. This avoids using this 14733 // instruction in first-pass matching. It will then only be used in 14734 // the `Shorten_branches' pass. 14735 // ins_short_branch(1); 14736 format %{ "b$cmp $lbl" %} 14737 14738 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14739 14740 ins_pipe(pipe_branch_cond); 14741 %} 14742 14743 // Conditional Near Branch Unsigned 14744 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14745 %{ 14746 // Same match rule as `branchConFar'. 14747 match(If cmp cr); 14748 14749 effect(USE lbl); 14750 14751 ins_cost(BRANCH_COST); 14752 // If set to 1 this indicates that the current instruction is a 14753 // short variant of a long branch. This avoids using this 14754 // instruction in first-pass matching. It will then only be used in 14755 // the `Shorten_branches' pass. 14756 // ins_short_branch(1); 14757 format %{ "b$cmp $lbl\t# unsigned" %} 14758 14759 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14760 14761 ins_pipe(pipe_branch_cond); 14762 %} 14763 14764 // Make use of CBZ and CBNZ. These instructions, as well as being 14765 // shorter than (cmp; branch), have the additional benefit of not 14766 // killing the flags. 14767 14768 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14769 match(If cmp (CmpI op1 op2)); 14770 effect(USE labl); 14771 14772 ins_cost(BRANCH_COST); 14773 format %{ "cbw$cmp $op1, $labl" %} 14774 ins_encode %{ 14775 Label* L = $labl$$label; 14776 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14777 if (cond == Assembler::EQ) 14778 __ cbzw($op1$$Register, *L); 14779 else 14780 __ cbnzw($op1$$Register, *L); 14781 %} 14782 ins_pipe(pipe_cmp_branch); 14783 %} 14784 14785 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14786 match(If cmp (CmpL op1 op2)); 14787 effect(USE labl); 14788 14789 ins_cost(BRANCH_COST); 14790 format %{ "cb$cmp $op1, $labl" %} 14791 ins_encode %{ 14792 Label* L = $labl$$label; 14793 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14794 if (cond == Assembler::EQ) 14795 __ cbz($op1$$Register, *L); 14796 else 14797 __ cbnz($op1$$Register, *L); 14798 %} 14799 ins_pipe(pipe_cmp_branch); 14800 %} 14801 14802 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14803 match(If cmp (CmpP op1 op2)); 14804 effect(USE labl); 14805 14806 ins_cost(BRANCH_COST); 14807 format %{ "cb$cmp $op1, $labl" %} 14808 ins_encode %{ 14809 Label* L = $labl$$label; 14810 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14811 if (cond == Assembler::EQ) 14812 __ cbz($op1$$Register, *L); 14813 else 14814 __ cbnz($op1$$Register, *L); 14815 %} 14816 ins_pipe(pipe_cmp_branch); 14817 %} 14818 14819 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14820 match(If cmp (CmpN op1 op2)); 14821 effect(USE labl); 14822 14823 ins_cost(BRANCH_COST); 14824 format %{ "cbw$cmp $op1, $labl" %} 14825 ins_encode %{ 14826 Label* L = $labl$$label; 14827 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14828 if (cond == Assembler::EQ) 14829 __ cbzw($op1$$Register, *L); 14830 else 14831 __ cbnzw($op1$$Register, *L); 14832 %} 14833 ins_pipe(pipe_cmp_branch); 14834 %} 14835 14836 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14837 match(If cmp (CmpP (DecodeN oop) zero)); 14838 effect(USE labl); 14839 14840 ins_cost(BRANCH_COST); 14841 format %{ "cb$cmp $oop, $labl" %} 14842 ins_encode %{ 14843 Label* L = $labl$$label; 14844 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14845 if (cond == Assembler::EQ) 14846 __ cbzw($oop$$Register, *L); 14847 else 14848 __ cbnzw($oop$$Register, *L); 14849 %} 14850 ins_pipe(pipe_cmp_branch); 14851 %} 14852 14853 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14854 match(If cmp (CmpU op1 op2)); 14855 effect(USE labl); 14856 14857 ins_cost(BRANCH_COST); 14858 format %{ "cbw$cmp $op1, $labl" %} 14859 ins_encode %{ 14860 Label* L = $labl$$label; 14861 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14862 if (cond == Assembler::EQ || cond == Assembler::LS) 14863 __ cbzw($op1$$Register, *L); 14864 else 14865 __ cbnzw($op1$$Register, *L); 14866 %} 14867 ins_pipe(pipe_cmp_branch); 14868 %} 14869 14870 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14871 match(If cmp (CmpUL op1 op2)); 14872 effect(USE labl); 14873 14874 ins_cost(BRANCH_COST); 14875 format %{ "cb$cmp $op1, $labl" %} 14876 ins_encode %{ 14877 Label* L = $labl$$label; 14878 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14879 if (cond == Assembler::EQ || cond == Assembler::LS) 14880 __ cbz($op1$$Register, *L); 14881 else 14882 __ cbnz($op1$$Register, *L); 14883 %} 14884 ins_pipe(pipe_cmp_branch); 14885 %} 14886 14887 // Test bit and Branch 14888 14889 // Patterns for short (< 32KiB) variants 14890 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14891 match(If cmp (CmpL op1 op2)); 14892 effect(USE labl); 14893 14894 ins_cost(BRANCH_COST); 14895 format %{ "cb$cmp $op1, $labl # long" %} 14896 ins_encode %{ 14897 Label* L = $labl$$label; 14898 Assembler::Condition cond = 14899 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14900 __ tbr(cond, $op1$$Register, 63, *L); 14901 %} 14902 ins_pipe(pipe_cmp_branch); 14903 ins_short_branch(1); 14904 %} 14905 14906 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14907 match(If cmp (CmpI op1 op2)); 14908 effect(USE labl); 14909 14910 ins_cost(BRANCH_COST); 14911 format %{ "cb$cmp $op1, $labl # int" %} 14912 ins_encode %{ 14913 Label* L = $labl$$label; 14914 Assembler::Condition cond = 14915 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14916 __ tbr(cond, $op1$$Register, 31, *L); 14917 %} 14918 ins_pipe(pipe_cmp_branch); 14919 ins_short_branch(1); 14920 %} 14921 14922 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14923 match(If cmp (CmpL (AndL op1 op2) op3)); 14924 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14925 effect(USE labl); 14926 14927 ins_cost(BRANCH_COST); 14928 format %{ "tb$cmp $op1, $op2, $labl" %} 14929 ins_encode %{ 14930 Label* L = $labl$$label; 14931 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14932 int bit = exact_log2_long($op2$$constant); 14933 __ tbr(cond, $op1$$Register, bit, *L); 14934 %} 14935 ins_pipe(pipe_cmp_branch); 14936 ins_short_branch(1); 14937 %} 14938 14939 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14940 match(If cmp (CmpI (AndI op1 op2) op3)); 14941 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 14942 effect(USE labl); 14943 14944 ins_cost(BRANCH_COST); 14945 format %{ "tb$cmp $op1, $op2, $labl" %} 14946 ins_encode %{ 14947 Label* L = $labl$$label; 14948 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14949 int bit = exact_log2((juint)$op2$$constant); 14950 __ tbr(cond, $op1$$Register, bit, *L); 14951 %} 14952 ins_pipe(pipe_cmp_branch); 14953 ins_short_branch(1); 14954 %} 14955 14956 // And far variants 14957 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14958 match(If cmp (CmpL op1 op2)); 14959 effect(USE labl); 14960 14961 ins_cost(BRANCH_COST); 14962 format %{ "cb$cmp $op1, $labl # long" %} 14963 ins_encode %{ 14964 Label* L = $labl$$label; 14965 Assembler::Condition cond = 14966 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14967 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14968 %} 14969 ins_pipe(pipe_cmp_branch); 14970 %} 14971 14972 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14973 match(If cmp (CmpI op1 op2)); 14974 effect(USE labl); 14975 14976 ins_cost(BRANCH_COST); 14977 format %{ "cb$cmp $op1, $labl # int" %} 14978 ins_encode %{ 14979 Label* L = $labl$$label; 14980 Assembler::Condition cond = 14981 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14982 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14983 %} 14984 ins_pipe(pipe_cmp_branch); 14985 %} 14986 14987 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14988 match(If cmp (CmpL (AndL op1 op2) op3)); 14989 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14990 effect(USE labl); 14991 14992 ins_cost(BRANCH_COST); 14993 format %{ "tb$cmp $op1, $op2, $labl" %} 14994 ins_encode %{ 14995 Label* L = $labl$$label; 14996 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14997 int bit = exact_log2_long($op2$$constant); 14998 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14999 %} 15000 ins_pipe(pipe_cmp_branch); 15001 %} 15002 15003 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15004 match(If cmp (CmpI (AndI op1 op2) op3)); 15005 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15006 effect(USE labl); 15007 15008 ins_cost(BRANCH_COST); 15009 format %{ "tb$cmp $op1, $op2, $labl" %} 15010 ins_encode %{ 15011 Label* L = $labl$$label; 15012 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15013 int bit = exact_log2((juint)$op2$$constant); 15014 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15015 %} 15016 ins_pipe(pipe_cmp_branch); 15017 %} 15018 15019 // Test bits 15020 15021 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15022 match(Set cr (CmpL (AndL op1 op2) op3)); 15023 predicate(Assembler::operand_valid_for_logical_immediate 15024 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15025 15026 ins_cost(INSN_COST); 15027 format %{ "tst $op1, $op2 # long" %} 15028 ins_encode %{ 15029 __ tst($op1$$Register, $op2$$constant); 15030 %} 15031 ins_pipe(ialu_reg_reg); 15032 %} 15033 15034 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15035 match(Set cr (CmpI (AndI op1 op2) op3)); 15036 predicate(Assembler::operand_valid_for_logical_immediate 15037 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15038 15039 ins_cost(INSN_COST); 15040 format %{ "tst $op1, $op2 # int" %} 15041 ins_encode %{ 15042 __ tstw($op1$$Register, $op2$$constant); 15043 %} 15044 ins_pipe(ialu_reg_reg); 15045 %} 15046 15047 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15048 match(Set cr (CmpL (AndL op1 op2) op3)); 15049 15050 ins_cost(INSN_COST); 15051 format %{ "tst $op1, $op2 # long" %} 15052 ins_encode %{ 15053 __ tst($op1$$Register, $op2$$Register); 15054 %} 15055 ins_pipe(ialu_reg_reg); 15056 %} 15057 15058 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15059 match(Set cr (CmpI (AndI op1 op2) op3)); 15060 15061 ins_cost(INSN_COST); 15062 format %{ "tstw $op1, $op2 # int" %} 15063 ins_encode %{ 15064 __ tstw($op1$$Register, $op2$$Register); 15065 %} 15066 ins_pipe(ialu_reg_reg); 15067 %} 15068 15069 15070 // Conditional Far Branch 15071 // Conditional Far Branch Unsigned 15072 // TODO: fixme 15073 15074 // counted loop end branch near 15075 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15076 %{ 15077 match(CountedLoopEnd cmp cr); 15078 15079 effect(USE lbl); 15080 15081 ins_cost(BRANCH_COST); 15082 // short variant. 15083 // ins_short_branch(1); 15084 format %{ "b$cmp $lbl \t// counted loop end" %} 15085 15086 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15087 15088 ins_pipe(pipe_branch); 15089 %} 15090 15091 // counted loop end branch near Unsigned 15092 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15093 %{ 15094 match(CountedLoopEnd cmp cr); 15095 15096 effect(USE lbl); 15097 15098 ins_cost(BRANCH_COST); 15099 // short variant. 15100 // ins_short_branch(1); 15101 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15102 15103 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15104 15105 ins_pipe(pipe_branch); 15106 %} 15107 15108 // counted loop end branch far 15109 // counted loop end branch far unsigned 15110 // TODO: fixme 15111 15112 // ============================================================================ 15113 // inlined locking and unlocking 15114 15115 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15116 %{ 15117 match(Set cr (FastLock object box)); 15118 effect(TEMP tmp, TEMP tmp2); 15119 15120 // TODO 15121 // identify correct cost 15122 ins_cost(5 * INSN_COST); 15123 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15124 15125 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15126 15127 ins_pipe(pipe_serial); 15128 %} 15129 15130 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15131 %{ 15132 match(Set cr (FastUnlock object box)); 15133 effect(TEMP tmp, TEMP tmp2); 15134 15135 ins_cost(5 * INSN_COST); 15136 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15137 15138 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15139 15140 ins_pipe(pipe_serial); 15141 %} 15142 15143 15144 // ============================================================================ 15145 // Safepoint Instructions 15146 15147 // TODO 15148 // provide a near and far version of this code 15149 15150 instruct safePoint(rFlagsReg cr, iRegP poll) 15151 %{ 15152 match(SafePoint poll); 15153 effect(KILL cr); 15154 15155 format %{ 15156 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15157 %} 15158 ins_encode %{ 15159 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15160 %} 15161 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15162 %} 15163 15164 15165 // ============================================================================ 15166 // Procedure Call/Return Instructions 15167 15168 // Call Java Static Instruction 15169 15170 instruct CallStaticJavaDirect(method meth) 15171 %{ 15172 match(CallStaticJava); 15173 15174 effect(USE meth); 15175 15176 ins_cost(CALL_COST); 15177 15178 format %{ "call,static $meth \t// ==> " %} 15179 15180 ins_encode( aarch64_enc_java_static_call(meth), 15181 aarch64_enc_call_epilog ); 15182 15183 ins_pipe(pipe_class_call); 15184 %} 15185 15186 // TO HERE 15187 15188 // Call Java Dynamic Instruction 15189 instruct CallDynamicJavaDirect(method meth) 15190 %{ 15191 match(CallDynamicJava); 15192 15193 effect(USE meth); 15194 15195 ins_cost(CALL_COST); 15196 15197 format %{ "CALL,dynamic $meth \t// ==> " %} 15198 15199 ins_encode( aarch64_enc_java_dynamic_call(meth), 15200 aarch64_enc_call_epilog ); 15201 15202 ins_pipe(pipe_class_call); 15203 %} 15204 15205 // Call Runtime Instruction 15206 15207 instruct CallRuntimeDirect(method meth) 15208 %{ 15209 match(CallRuntime); 15210 15211 effect(USE meth); 15212 15213 ins_cost(CALL_COST); 15214 15215 format %{ "CALL, runtime $meth" %} 15216 15217 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15218 15219 ins_pipe(pipe_class_call); 15220 %} 15221 15222 // Call Runtime Instruction 15223 15224 instruct CallLeafDirect(method meth) 15225 %{ 15226 match(CallLeaf); 15227 15228 effect(USE meth); 15229 15230 ins_cost(CALL_COST); 15231 15232 format %{ "CALL, runtime leaf $meth" %} 15233 15234 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15235 15236 ins_pipe(pipe_class_call); 15237 %} 15238 15239 // Call Runtime Instruction 15240 15241 instruct CallLeafNoFPDirect(method meth) 15242 %{ 15243 match(CallLeafNoFP); 15244 15245 effect(USE meth); 15246 15247 ins_cost(CALL_COST); 15248 15249 format %{ "CALL, runtime leaf nofp $meth" %} 15250 15251 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15252 15253 ins_pipe(pipe_class_call); 15254 %} 15255 15256 // Tail Call; Jump from runtime stub to Java code. 15257 // Also known as an 'interprocedural jump'. 15258 // Target of jump will eventually return to caller. 15259 // TailJump below removes the return address. 15260 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15261 %{ 15262 match(TailCall jump_target method_oop); 15263 15264 ins_cost(CALL_COST); 15265 15266 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15267 15268 ins_encode(aarch64_enc_tail_call(jump_target)); 15269 15270 ins_pipe(pipe_class_call); 15271 %} 15272 15273 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15274 %{ 15275 match(TailJump jump_target ex_oop); 15276 15277 ins_cost(CALL_COST); 15278 15279 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15280 15281 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15282 15283 ins_pipe(pipe_class_call); 15284 %} 15285 15286 // Create exception oop: created by stack-crawling runtime code. 15287 // Created exception is now available to this handler, and is setup 15288 // just prior to jumping to this handler. No code emitted. 15289 // TODO check 15290 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15291 instruct CreateException(iRegP_R0 ex_oop) 15292 %{ 15293 match(Set ex_oop (CreateEx)); 15294 15295 format %{ " -- \t// exception oop; no code emitted" %} 15296 15297 size(0); 15298 15299 ins_encode( /*empty*/ ); 15300 15301 ins_pipe(pipe_class_empty); 15302 %} 15303 15304 // Rethrow exception: The exception oop will come in the first 15305 // argument position. Then JUMP (not call) to the rethrow stub code. 15306 instruct RethrowException() %{ 15307 match(Rethrow); 15308 ins_cost(CALL_COST); 15309 15310 format %{ "b rethrow_stub" %} 15311 15312 ins_encode( aarch64_enc_rethrow() ); 15313 15314 ins_pipe(pipe_class_call); 15315 %} 15316 15317 15318 // Return Instruction 15319 // epilog node loads ret address into lr as part of frame pop 15320 instruct Ret() 15321 %{ 15322 match(Return); 15323 15324 format %{ "ret\t// return register" %} 15325 15326 ins_encode( aarch64_enc_ret() ); 15327 15328 ins_pipe(pipe_branch); 15329 %} 15330 15331 // Die now. 15332 instruct ShouldNotReachHere() %{ 15333 match(Halt); 15334 15335 ins_cost(CALL_COST); 15336 format %{ "ShouldNotReachHere" %} 15337 15338 ins_encode %{ 15339 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 15340 // return true 15341 __ dpcs1(0xdead + 1); 15342 %} 15343 15344 ins_pipe(pipe_class_default); 15345 %} 15346 15347 // ============================================================================ 15348 // Partial Subtype Check 15349 // 15350 // superklass array for an instance of the superklass. Set a hidden 15351 // internal cache on a hit (cache is checked with exposed code in 15352 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15353 // encoding ALSO sets flags. 15354 15355 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15356 %{ 15357 match(Set result (PartialSubtypeCheck sub super)); 15358 effect(KILL cr, KILL temp); 15359 15360 ins_cost(1100); // slightly larger than the next version 15361 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15362 15363 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15364 15365 opcode(0x1); // Force zero of result reg on hit 15366 15367 ins_pipe(pipe_class_memory); 15368 %} 15369 15370 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15371 %{ 15372 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15373 effect(KILL temp, KILL result); 15374 15375 ins_cost(1100); // slightly larger than the next version 15376 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15377 15378 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15379 15380 opcode(0x0); // Don't zero result reg on hit 15381 15382 ins_pipe(pipe_class_memory); 15383 %} 15384 15385 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15386 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15387 %{ 15388 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15389 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15390 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15391 15392 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15393 ins_encode %{ 15394 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15395 __ string_compare($str1$$Register, $str2$$Register, 15396 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15397 $tmp1$$Register, $tmp2$$Register, 15398 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15399 %} 15400 ins_pipe(pipe_class_memory); 15401 %} 15402 15403 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15404 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15405 %{ 15406 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15407 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15408 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15409 15410 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15411 ins_encode %{ 15412 __ string_compare($str1$$Register, $str2$$Register, 15413 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15414 $tmp1$$Register, $tmp2$$Register, 15415 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15416 %} 15417 ins_pipe(pipe_class_memory); 15418 %} 15419 15420 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15421 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15422 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15423 %{ 15424 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15425 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15426 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15427 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15428 15429 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15430 ins_encode %{ 15431 __ string_compare($str1$$Register, $str2$$Register, 15432 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15433 $tmp1$$Register, $tmp2$$Register, 15434 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15435 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15436 %} 15437 ins_pipe(pipe_class_memory); 15438 %} 15439 15440 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15441 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15442 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15443 %{ 15444 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15445 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15446 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15447 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15448 15449 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15450 ins_encode %{ 15451 __ string_compare($str1$$Register, $str2$$Register, 15452 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15453 $tmp1$$Register, $tmp2$$Register, 15454 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15455 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15456 %} 15457 ins_pipe(pipe_class_memory); 15458 %} 15459 15460 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15461 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15462 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15463 %{ 15464 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15465 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15466 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15467 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15468 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15469 15470 ins_encode %{ 15471 __ string_indexof($str1$$Register, $str2$$Register, 15472 $cnt1$$Register, $cnt2$$Register, 15473 $tmp1$$Register, $tmp2$$Register, 15474 $tmp3$$Register, $tmp4$$Register, 15475 $tmp5$$Register, $tmp6$$Register, 15476 -1, $result$$Register, StrIntrinsicNode::UU); 15477 %} 15478 ins_pipe(pipe_class_memory); 15479 %} 15480 15481 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15482 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15483 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15484 %{ 15485 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15486 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15487 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15488 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15489 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15490 15491 ins_encode %{ 15492 __ string_indexof($str1$$Register, $str2$$Register, 15493 $cnt1$$Register, $cnt2$$Register, 15494 $tmp1$$Register, $tmp2$$Register, 15495 $tmp3$$Register, $tmp4$$Register, 15496 $tmp5$$Register, $tmp6$$Register, 15497 -1, $result$$Register, StrIntrinsicNode::LL); 15498 %} 15499 ins_pipe(pipe_class_memory); 15500 %} 15501 15502 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15503 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15504 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15505 %{ 15506 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15507 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15508 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15509 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15510 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15511 15512 ins_encode %{ 15513 __ string_indexof($str1$$Register, $str2$$Register, 15514 $cnt1$$Register, $cnt2$$Register, 15515 $tmp1$$Register, $tmp2$$Register, 15516 $tmp3$$Register, $tmp4$$Register, 15517 $tmp5$$Register, $tmp6$$Register, 15518 -1, $result$$Register, StrIntrinsicNode::UL); 15519 %} 15520 ins_pipe(pipe_class_memory); 15521 %} 15522 15523 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15524 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15525 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15526 %{ 15527 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15528 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15529 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15530 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15531 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15532 15533 ins_encode %{ 15534 int icnt2 = (int)$int_cnt2$$constant; 15535 __ string_indexof($str1$$Register, $str2$$Register, 15536 $cnt1$$Register, zr, 15537 $tmp1$$Register, $tmp2$$Register, 15538 $tmp3$$Register, $tmp4$$Register, zr, zr, 15539 icnt2, $result$$Register, StrIntrinsicNode::UU); 15540 %} 15541 ins_pipe(pipe_class_memory); 15542 %} 15543 15544 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15545 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15546 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15547 %{ 15548 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15549 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15550 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15551 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15552 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15553 15554 ins_encode %{ 15555 int icnt2 = (int)$int_cnt2$$constant; 15556 __ string_indexof($str1$$Register, $str2$$Register, 15557 $cnt1$$Register, zr, 15558 $tmp1$$Register, $tmp2$$Register, 15559 $tmp3$$Register, $tmp4$$Register, zr, zr, 15560 icnt2, $result$$Register, StrIntrinsicNode::LL); 15561 %} 15562 ins_pipe(pipe_class_memory); 15563 %} 15564 15565 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15566 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15567 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15568 %{ 15569 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15570 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15571 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15572 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15573 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15574 15575 ins_encode %{ 15576 int icnt2 = (int)$int_cnt2$$constant; 15577 __ string_indexof($str1$$Register, $str2$$Register, 15578 $cnt1$$Register, zr, 15579 $tmp1$$Register, $tmp2$$Register, 15580 $tmp3$$Register, $tmp4$$Register, zr, zr, 15581 icnt2, $result$$Register, StrIntrinsicNode::UL); 15582 %} 15583 ins_pipe(pipe_class_memory); 15584 %} 15585 15586 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15587 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15588 iRegINoSp tmp3, rFlagsReg cr) 15589 %{ 15590 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15591 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15592 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15593 15594 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15595 15596 ins_encode %{ 15597 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15598 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15599 $tmp3$$Register); 15600 %} 15601 ins_pipe(pipe_class_memory); 15602 %} 15603 15604 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15605 iRegI_R0 result, rFlagsReg cr) 15606 %{ 15607 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15608 match(Set result (StrEquals (Binary str1 str2) cnt)); 15609 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15610 15611 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15612 ins_encode %{ 15613 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15614 __ string_equals($str1$$Register, $str2$$Register, 15615 $result$$Register, $cnt$$Register, 1); 15616 %} 15617 ins_pipe(pipe_class_memory); 15618 %} 15619 15620 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15621 iRegI_R0 result, rFlagsReg cr) 15622 %{ 15623 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15624 match(Set result (StrEquals (Binary str1 str2) cnt)); 15625 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15626 15627 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15628 ins_encode %{ 15629 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15630 __ string_equals($str1$$Register, $str2$$Register, 15631 $result$$Register, $cnt$$Register, 2); 15632 %} 15633 ins_pipe(pipe_class_memory); 15634 %} 15635 15636 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15637 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15638 iRegP_R10 tmp, rFlagsReg cr) 15639 %{ 15640 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15641 match(Set result (AryEq ary1 ary2)); 15642 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15643 15644 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15645 ins_encode %{ 15646 __ arrays_equals($ary1$$Register, $ary2$$Register, 15647 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15648 $result$$Register, $tmp$$Register, 1); 15649 %} 15650 ins_pipe(pipe_class_memory); 15651 %} 15652 15653 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15654 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15655 iRegP_R10 tmp, rFlagsReg cr) 15656 %{ 15657 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15658 match(Set result (AryEq ary1 ary2)); 15659 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15660 15661 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15662 ins_encode %{ 15663 __ arrays_equals($ary1$$Register, $ary2$$Register, 15664 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15665 $result$$Register, $tmp$$Register, 2); 15666 %} 15667 ins_pipe(pipe_class_memory); 15668 %} 15669 15670 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15671 %{ 15672 match(Set result (HasNegatives ary1 len)); 15673 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15674 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15675 ins_encode %{ 15676 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15677 %} 15678 ins_pipe( pipe_slow ); 15679 %} 15680 15681 // fast char[] to byte[] compression 15682 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15683 vRegD_V0 tmp1, vRegD_V1 tmp2, 15684 vRegD_V2 tmp3, vRegD_V3 tmp4, 15685 iRegI_R0 result, rFlagsReg cr) 15686 %{ 15687 match(Set result (StrCompressedCopy src (Binary dst len))); 15688 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15689 15690 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15691 ins_encode %{ 15692 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15693 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15694 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15695 $result$$Register); 15696 %} 15697 ins_pipe( pipe_slow ); 15698 %} 15699 15700 // fast byte[] to char[] inflation 15701 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15702 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15703 %{ 15704 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15705 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15706 15707 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15708 ins_encode %{ 15709 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15710 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15711 %} 15712 ins_pipe(pipe_class_memory); 15713 %} 15714 15715 // encode char[] to byte[] in ISO_8859_1 15716 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15717 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15718 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15719 iRegI_R0 result, rFlagsReg cr) 15720 %{ 15721 match(Set result (EncodeISOArray src (Binary dst len))); 15722 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15723 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15724 15725 format %{ "Encode array $src,$dst,$len -> $result" %} 15726 ins_encode %{ 15727 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15728 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15729 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15730 %} 15731 ins_pipe( pipe_class_memory ); 15732 %} 15733 15734 // ============================================================================ 15735 // This name is KNOWN by the ADLC and cannot be changed. 15736 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15737 // for this guy. 15738 instruct tlsLoadP(thread_RegP dst) 15739 %{ 15740 match(Set dst (ThreadLocal)); 15741 15742 ins_cost(0); 15743 15744 format %{ " -- \t// $dst=Thread::current(), empty" %} 15745 15746 size(0); 15747 15748 ins_encode( /*empty*/ ); 15749 15750 ins_pipe(pipe_class_empty); 15751 %} 15752 15753 // ====================VECTOR INSTRUCTIONS===================================== 15754 15755 // Load vector (32 bits) 15756 instruct loadV4(vecD dst, vmem4 mem) 15757 %{ 15758 predicate(n->as_LoadVector()->memory_size() == 4); 15759 match(Set dst (LoadVector mem)); 15760 ins_cost(4 * INSN_COST); 15761 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15762 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15763 ins_pipe(vload_reg_mem64); 15764 %} 15765 15766 // Load vector (64 bits) 15767 instruct loadV8(vecD dst, vmem8 mem) 15768 %{ 15769 predicate(n->as_LoadVector()->memory_size() == 8); 15770 match(Set dst (LoadVector mem)); 15771 ins_cost(4 * INSN_COST); 15772 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15773 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15774 ins_pipe(vload_reg_mem64); 15775 %} 15776 15777 // Load Vector (128 bits) 15778 instruct loadV16(vecX dst, vmem16 mem) 15779 %{ 15780 predicate(n->as_LoadVector()->memory_size() == 16); 15781 match(Set dst (LoadVector mem)); 15782 ins_cost(4 * INSN_COST); 15783 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15784 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15785 ins_pipe(vload_reg_mem128); 15786 %} 15787 15788 // Store Vector (32 bits) 15789 instruct storeV4(vecD src, vmem4 mem) 15790 %{ 15791 predicate(n->as_StoreVector()->memory_size() == 4); 15792 match(Set mem (StoreVector mem src)); 15793 ins_cost(4 * INSN_COST); 15794 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15795 ins_encode( aarch64_enc_strvS(src, mem) ); 15796 ins_pipe(vstore_reg_mem64); 15797 %} 15798 15799 // Store Vector (64 bits) 15800 instruct storeV8(vecD src, vmem8 mem) 15801 %{ 15802 predicate(n->as_StoreVector()->memory_size() == 8); 15803 match(Set mem (StoreVector mem src)); 15804 ins_cost(4 * INSN_COST); 15805 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15806 ins_encode( aarch64_enc_strvD(src, mem) ); 15807 ins_pipe(vstore_reg_mem64); 15808 %} 15809 15810 // Store Vector (128 bits) 15811 instruct storeV16(vecX src, vmem16 mem) 15812 %{ 15813 predicate(n->as_StoreVector()->memory_size() == 16); 15814 match(Set mem (StoreVector mem src)); 15815 ins_cost(4 * INSN_COST); 15816 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15817 ins_encode( aarch64_enc_strvQ(src, mem) ); 15818 ins_pipe(vstore_reg_mem128); 15819 %} 15820 15821 instruct replicate8B(vecD dst, iRegIorL2I src) 15822 %{ 15823 predicate(n->as_Vector()->length() == 4 || 15824 n->as_Vector()->length() == 8); 15825 match(Set dst (ReplicateB src)); 15826 ins_cost(INSN_COST); 15827 format %{ "dup $dst, $src\t# vector (8B)" %} 15828 ins_encode %{ 15829 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15830 %} 15831 ins_pipe(vdup_reg_reg64); 15832 %} 15833 15834 instruct replicate16B(vecX dst, iRegIorL2I src) 15835 %{ 15836 predicate(n->as_Vector()->length() == 16); 15837 match(Set dst (ReplicateB src)); 15838 ins_cost(INSN_COST); 15839 format %{ "dup $dst, $src\t# vector (16B)" %} 15840 ins_encode %{ 15841 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15842 %} 15843 ins_pipe(vdup_reg_reg128); 15844 %} 15845 15846 instruct replicate8B_imm(vecD dst, immI con) 15847 %{ 15848 predicate(n->as_Vector()->length() == 4 || 15849 n->as_Vector()->length() == 8); 15850 match(Set dst (ReplicateB con)); 15851 ins_cost(INSN_COST); 15852 format %{ "movi $dst, $con\t# vector(8B)" %} 15853 ins_encode %{ 15854 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15855 %} 15856 ins_pipe(vmovi_reg_imm64); 15857 %} 15858 15859 instruct replicate16B_imm(vecX dst, immI con) 15860 %{ 15861 predicate(n->as_Vector()->length() == 16); 15862 match(Set dst (ReplicateB con)); 15863 ins_cost(INSN_COST); 15864 format %{ "movi $dst, $con\t# vector(16B)" %} 15865 ins_encode %{ 15866 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15867 %} 15868 ins_pipe(vmovi_reg_imm128); 15869 %} 15870 15871 instruct replicate4S(vecD dst, iRegIorL2I src) 15872 %{ 15873 predicate(n->as_Vector()->length() == 2 || 15874 n->as_Vector()->length() == 4); 15875 match(Set dst (ReplicateS src)); 15876 ins_cost(INSN_COST); 15877 format %{ "dup $dst, $src\t# vector (4S)" %} 15878 ins_encode %{ 15879 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15880 %} 15881 ins_pipe(vdup_reg_reg64); 15882 %} 15883 15884 instruct replicate8S(vecX dst, iRegIorL2I src) 15885 %{ 15886 predicate(n->as_Vector()->length() == 8); 15887 match(Set dst (ReplicateS src)); 15888 ins_cost(INSN_COST); 15889 format %{ "dup $dst, $src\t# vector (8S)" %} 15890 ins_encode %{ 15891 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15892 %} 15893 ins_pipe(vdup_reg_reg128); 15894 %} 15895 15896 instruct replicate4S_imm(vecD dst, immI con) 15897 %{ 15898 predicate(n->as_Vector()->length() == 2 || 15899 n->as_Vector()->length() == 4); 15900 match(Set dst (ReplicateS con)); 15901 ins_cost(INSN_COST); 15902 format %{ "movi $dst, $con\t# vector(4H)" %} 15903 ins_encode %{ 15904 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15905 %} 15906 ins_pipe(vmovi_reg_imm64); 15907 %} 15908 15909 instruct replicate8S_imm(vecX dst, immI con) 15910 %{ 15911 predicate(n->as_Vector()->length() == 8); 15912 match(Set dst (ReplicateS con)); 15913 ins_cost(INSN_COST); 15914 format %{ "movi $dst, $con\t# vector(8H)" %} 15915 ins_encode %{ 15916 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15917 %} 15918 ins_pipe(vmovi_reg_imm128); 15919 %} 15920 15921 instruct replicate2I(vecD dst, iRegIorL2I src) 15922 %{ 15923 predicate(n->as_Vector()->length() == 2); 15924 match(Set dst (ReplicateI src)); 15925 ins_cost(INSN_COST); 15926 format %{ "dup $dst, $src\t# vector (2I)" %} 15927 ins_encode %{ 15928 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15929 %} 15930 ins_pipe(vdup_reg_reg64); 15931 %} 15932 15933 instruct replicate4I(vecX dst, iRegIorL2I src) 15934 %{ 15935 predicate(n->as_Vector()->length() == 4); 15936 match(Set dst (ReplicateI src)); 15937 ins_cost(INSN_COST); 15938 format %{ "dup $dst, $src\t# vector (4I)" %} 15939 ins_encode %{ 15940 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15941 %} 15942 ins_pipe(vdup_reg_reg128); 15943 %} 15944 15945 instruct replicate2I_imm(vecD dst, immI con) 15946 %{ 15947 predicate(n->as_Vector()->length() == 2); 15948 match(Set dst (ReplicateI con)); 15949 ins_cost(INSN_COST); 15950 format %{ "movi $dst, $con\t# vector(2I)" %} 15951 ins_encode %{ 15952 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15953 %} 15954 ins_pipe(vmovi_reg_imm64); 15955 %} 15956 15957 instruct replicate4I_imm(vecX dst, immI con) 15958 %{ 15959 predicate(n->as_Vector()->length() == 4); 15960 match(Set dst (ReplicateI con)); 15961 ins_cost(INSN_COST); 15962 format %{ "movi $dst, $con\t# vector(4I)" %} 15963 ins_encode %{ 15964 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15965 %} 15966 ins_pipe(vmovi_reg_imm128); 15967 %} 15968 15969 instruct replicate2L(vecX dst, iRegL src) 15970 %{ 15971 predicate(n->as_Vector()->length() == 2); 15972 match(Set dst (ReplicateL src)); 15973 ins_cost(INSN_COST); 15974 format %{ "dup $dst, $src\t# vector (2L)" %} 15975 ins_encode %{ 15976 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15977 %} 15978 ins_pipe(vdup_reg_reg128); 15979 %} 15980 15981 instruct replicate2L_zero(vecX dst, immI0 zero) 15982 %{ 15983 predicate(n->as_Vector()->length() == 2); 15984 match(Set dst (ReplicateI zero)); 15985 ins_cost(INSN_COST); 15986 format %{ "movi $dst, $zero\t# vector(4I)" %} 15987 ins_encode %{ 15988 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15989 as_FloatRegister($dst$$reg), 15990 as_FloatRegister($dst$$reg)); 15991 %} 15992 ins_pipe(vmovi_reg_imm128); 15993 %} 15994 15995 instruct replicate2F(vecD dst, vRegF src) 15996 %{ 15997 predicate(n->as_Vector()->length() == 2); 15998 match(Set dst (ReplicateF src)); 15999 ins_cost(INSN_COST); 16000 format %{ "dup $dst, $src\t# vector (2F)" %} 16001 ins_encode %{ 16002 __ dup(as_FloatRegister($dst$$reg), __ T2S, 16003 as_FloatRegister($src$$reg)); 16004 %} 16005 ins_pipe(vdup_reg_freg64); 16006 %} 16007 16008 instruct replicate4F(vecX dst, vRegF src) 16009 %{ 16010 predicate(n->as_Vector()->length() == 4); 16011 match(Set dst (ReplicateF src)); 16012 ins_cost(INSN_COST); 16013 format %{ "dup $dst, $src\t# vector (4F)" %} 16014 ins_encode %{ 16015 __ dup(as_FloatRegister($dst$$reg), __ T4S, 16016 as_FloatRegister($src$$reg)); 16017 %} 16018 ins_pipe(vdup_reg_freg128); 16019 %} 16020 16021 instruct replicate2D(vecX dst, vRegD src) 16022 %{ 16023 predicate(n->as_Vector()->length() == 2); 16024 match(Set dst (ReplicateD src)); 16025 ins_cost(INSN_COST); 16026 format %{ "dup $dst, $src\t# vector (2D)" %} 16027 ins_encode %{ 16028 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16029 as_FloatRegister($src$$reg)); 16030 %} 16031 ins_pipe(vdup_reg_dreg128); 16032 %} 16033 16034 // ====================REDUCTION ARITHMETIC==================================== 16035 16036 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 16037 %{ 16038 match(Set dst (AddReductionVI src1 src2)); 16039 ins_cost(INSN_COST); 16040 effect(TEMP tmp, TEMP tmp2); 16041 format %{ "umov $tmp, $src2, S, 0\n\t" 16042 "umov $tmp2, $src2, S, 1\n\t" 16043 "addw $tmp, $src1, $tmp\n\t" 16044 "addw $dst, $tmp, $tmp2\t# add reduction2I" 16045 %} 16046 ins_encode %{ 16047 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16048 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16049 __ addw($tmp$$Register, $src1$$Register, $tmp$$Register); 16050 __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); 16051 %} 16052 ins_pipe(pipe_class_default); 16053 %} 16054 16055 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16056 %{ 16057 match(Set dst (AddReductionVI src1 src2)); 16058 ins_cost(INSN_COST); 16059 effect(TEMP tmp, TEMP tmp2); 16060 format %{ "addv $tmp, T4S, $src2\n\t" 16061 "umov $tmp2, $tmp, S, 0\n\t" 16062 "addw $dst, $tmp2, $src1\t# add reduction4I" 16063 %} 16064 ins_encode %{ 16065 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 16066 as_FloatRegister($src2$$reg)); 16067 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16068 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 16069 %} 16070 ins_pipe(pipe_class_default); 16071 %} 16072 16073 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 16074 %{ 16075 match(Set dst (MulReductionVI src1 src2)); 16076 ins_cost(INSN_COST); 16077 effect(TEMP tmp, TEMP dst); 16078 format %{ "umov $tmp, $src2, S, 0\n\t" 16079 "mul $dst, $tmp, $src1\n\t" 16080 "umov $tmp, $src2, S, 1\n\t" 16081 "mul $dst, $tmp, $dst\t# mul reduction2I" 16082 %} 16083 ins_encode %{ 16084 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16085 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 16086 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16087 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16088 %} 16089 ins_pipe(pipe_class_default); 16090 %} 16091 16092 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16093 %{ 16094 match(Set dst (MulReductionVI src1 src2)); 16095 ins_cost(INSN_COST); 16096 effect(TEMP tmp, TEMP tmp2, TEMP dst); 16097 format %{ "ins $tmp, $src2, 0, 1\n\t" 16098 "mul $tmp, $tmp, $src2\n\t" 16099 "umov $tmp2, $tmp, S, 0\n\t" 16100 "mul $dst, $tmp2, $src1\n\t" 16101 "umov $tmp2, $tmp, S, 1\n\t" 16102 "mul $dst, $tmp2, $dst\t# mul reduction4I" 16103 %} 16104 ins_encode %{ 16105 __ ins(as_FloatRegister($tmp$$reg), __ D, 16106 as_FloatRegister($src2$$reg), 0, 1); 16107 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 16108 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 16109 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16110 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 16111 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 16112 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 16113 %} 16114 ins_pipe(pipe_class_default); 16115 %} 16116 16117 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16118 %{ 16119 match(Set dst (AddReductionVF src1 src2)); 16120 ins_cost(INSN_COST); 16121 effect(TEMP tmp, TEMP dst); 16122 format %{ "fadds $dst, $src1, $src2\n\t" 16123 "ins $tmp, S, $src2, 0, 1\n\t" 16124 "fadds $dst, $dst, $tmp\t# add reduction2F" 16125 %} 16126 ins_encode %{ 16127 __ fadds(as_FloatRegister($dst$$reg), 16128 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16129 __ ins(as_FloatRegister($tmp$$reg), __ S, 16130 as_FloatRegister($src2$$reg), 0, 1); 16131 __ fadds(as_FloatRegister($dst$$reg), 16132 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16133 %} 16134 ins_pipe(pipe_class_default); 16135 %} 16136 16137 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16138 %{ 16139 match(Set dst (AddReductionVF src1 src2)); 16140 ins_cost(INSN_COST); 16141 effect(TEMP tmp, TEMP dst); 16142 format %{ "fadds $dst, $src1, $src2\n\t" 16143 "ins $tmp, S, $src2, 0, 1\n\t" 16144 "fadds $dst, $dst, $tmp\n\t" 16145 "ins $tmp, S, $src2, 0, 2\n\t" 16146 "fadds $dst, $dst, $tmp\n\t" 16147 "ins $tmp, S, $src2, 0, 3\n\t" 16148 "fadds $dst, $dst, $tmp\t# add reduction4F" 16149 %} 16150 ins_encode %{ 16151 __ fadds(as_FloatRegister($dst$$reg), 16152 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16153 __ ins(as_FloatRegister($tmp$$reg), __ S, 16154 as_FloatRegister($src2$$reg), 0, 1); 16155 __ fadds(as_FloatRegister($dst$$reg), 16156 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16157 __ ins(as_FloatRegister($tmp$$reg), __ S, 16158 as_FloatRegister($src2$$reg), 0, 2); 16159 __ fadds(as_FloatRegister($dst$$reg), 16160 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16161 __ ins(as_FloatRegister($tmp$$reg), __ S, 16162 as_FloatRegister($src2$$reg), 0, 3); 16163 __ fadds(as_FloatRegister($dst$$reg), 16164 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16165 %} 16166 ins_pipe(pipe_class_default); 16167 %} 16168 16169 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16170 %{ 16171 match(Set dst (MulReductionVF src1 src2)); 16172 ins_cost(INSN_COST); 16173 effect(TEMP tmp, TEMP dst); 16174 format %{ "fmuls $dst, $src1, $src2\n\t" 16175 "ins $tmp, S, $src2, 0, 1\n\t" 16176 "fmuls $dst, $dst, $tmp\t# mul reduction2F" 16177 %} 16178 ins_encode %{ 16179 __ fmuls(as_FloatRegister($dst$$reg), 16180 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16181 __ ins(as_FloatRegister($tmp$$reg), __ S, 16182 as_FloatRegister($src2$$reg), 0, 1); 16183 __ fmuls(as_FloatRegister($dst$$reg), 16184 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16185 %} 16186 ins_pipe(pipe_class_default); 16187 %} 16188 16189 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16190 %{ 16191 match(Set dst (MulReductionVF src1 src2)); 16192 ins_cost(INSN_COST); 16193 effect(TEMP tmp, TEMP dst); 16194 format %{ "fmuls $dst, $src1, $src2\n\t" 16195 "ins $tmp, S, $src2, 0, 1\n\t" 16196 "fmuls $dst, $dst, $tmp\n\t" 16197 "ins $tmp, S, $src2, 0, 2\n\t" 16198 "fmuls $dst, $dst, $tmp\n\t" 16199 "ins $tmp, S, $src2, 0, 3\n\t" 16200 "fmuls $dst, $dst, $tmp\t# mul reduction4F" 16201 %} 16202 ins_encode %{ 16203 __ fmuls(as_FloatRegister($dst$$reg), 16204 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16205 __ ins(as_FloatRegister($tmp$$reg), __ S, 16206 as_FloatRegister($src2$$reg), 0, 1); 16207 __ fmuls(as_FloatRegister($dst$$reg), 16208 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16209 __ ins(as_FloatRegister($tmp$$reg), __ S, 16210 as_FloatRegister($src2$$reg), 0, 2); 16211 __ fmuls(as_FloatRegister($dst$$reg), 16212 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16213 __ ins(as_FloatRegister($tmp$$reg), __ S, 16214 as_FloatRegister($src2$$reg), 0, 3); 16215 __ fmuls(as_FloatRegister($dst$$reg), 16216 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16217 %} 16218 ins_pipe(pipe_class_default); 16219 %} 16220 16221 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16222 %{ 16223 match(Set dst (AddReductionVD src1 src2)); 16224 ins_cost(INSN_COST); 16225 effect(TEMP tmp, TEMP dst); 16226 format %{ "faddd $dst, $src1, $src2\n\t" 16227 "ins $tmp, D, $src2, 0, 1\n\t" 16228 "faddd $dst, $dst, $tmp\t# add reduction2D" 16229 %} 16230 ins_encode %{ 16231 __ faddd(as_FloatRegister($dst$$reg), 16232 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16233 __ ins(as_FloatRegister($tmp$$reg), __ D, 16234 as_FloatRegister($src2$$reg), 0, 1); 16235 __ faddd(as_FloatRegister($dst$$reg), 16236 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16237 %} 16238 ins_pipe(pipe_class_default); 16239 %} 16240 16241 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16242 %{ 16243 match(Set dst (MulReductionVD src1 src2)); 16244 ins_cost(INSN_COST); 16245 effect(TEMP tmp, TEMP dst); 16246 format %{ "fmuld $dst, $src1, $src2\n\t" 16247 "ins $tmp, D, $src2, 0, 1\n\t" 16248 "fmuld $dst, $dst, $tmp\t# mul reduction2D" 16249 %} 16250 ins_encode %{ 16251 __ fmuld(as_FloatRegister($dst$$reg), 16252 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16253 __ ins(as_FloatRegister($tmp$$reg), __ D, 16254 as_FloatRegister($src2$$reg), 0, 1); 16255 __ fmuld(as_FloatRegister($dst$$reg), 16256 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16257 %} 16258 ins_pipe(pipe_class_default); 16259 %} 16260 16261 instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16262 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16263 match(Set dst (MaxReductionV src1 src2)); 16264 ins_cost(INSN_COST); 16265 effect(TEMP_DEF dst, TEMP tmp); 16266 format %{ "fmaxs $dst, $src1, $src2\n\t" 16267 "ins $tmp, S, $src2, 0, 1\n\t" 16268 "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} 16269 ins_encode %{ 16270 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16271 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16272 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16273 %} 16274 ins_pipe(pipe_class_default); 16275 %} 16276 16277 instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ 16278 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16279 match(Set dst (MaxReductionV src1 src2)); 16280 ins_cost(INSN_COST); 16281 effect(TEMP_DEF dst); 16282 format %{ "fmaxv $dst, T4S, $src2\n\t" 16283 "fmaxs $dst, $dst, $src1\t# max reduction4F" %} 16284 ins_encode %{ 16285 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16286 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16287 %} 16288 ins_pipe(pipe_class_default); 16289 %} 16290 16291 instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16292 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16293 match(Set dst (MaxReductionV src1 src2)); 16294 ins_cost(INSN_COST); 16295 effect(TEMP_DEF dst, TEMP tmp); 16296 format %{ "fmaxd $dst, $src1, $src2\n\t" 16297 "ins $tmp, D, $src2, 0, 1\n\t" 16298 "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} 16299 ins_encode %{ 16300 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16301 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16302 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16303 %} 16304 ins_pipe(pipe_class_default); 16305 %} 16306 16307 instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16308 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16309 match(Set dst (MinReductionV src1 src2)); 16310 ins_cost(INSN_COST); 16311 effect(TEMP_DEF dst, TEMP tmp); 16312 format %{ "fmins $dst, $src1, $src2\n\t" 16313 "ins $tmp, S, $src2, 0, 1\n\t" 16314 "fmins $dst, $dst, $tmp\t# min reduction2F" %} 16315 ins_encode %{ 16316 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16317 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16318 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16319 %} 16320 ins_pipe(pipe_class_default); 16321 %} 16322 16323 instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ 16324 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16325 match(Set dst (MinReductionV src1 src2)); 16326 ins_cost(INSN_COST); 16327 effect(TEMP_DEF dst); 16328 format %{ "fminv $dst, T4S, $src2\n\t" 16329 "fmins $dst, $dst, $src1\t# min reduction4F" %} 16330 ins_encode %{ 16331 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16332 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16333 %} 16334 ins_pipe(pipe_class_default); 16335 %} 16336 16337 instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16338 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16339 match(Set dst (MinReductionV src1 src2)); 16340 ins_cost(INSN_COST); 16341 effect(TEMP_DEF dst, TEMP tmp); 16342 format %{ "fmind $dst, $src1, $src2\n\t" 16343 "ins $tmp, D, $src2, 0, 1\n\t" 16344 "fmind $dst, $dst, $tmp\t# min reduction2D" %} 16345 ins_encode %{ 16346 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16347 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16348 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16349 %} 16350 ins_pipe(pipe_class_default); 16351 %} 16352 16353 // ====================VECTOR ARITHMETIC======================================= 16354 16355 // --------------------------------- ADD -------------------------------------- 16356 16357 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16358 %{ 16359 predicate(n->as_Vector()->length() == 4 || 16360 n->as_Vector()->length() == 8); 16361 match(Set dst (AddVB src1 src2)); 16362 ins_cost(INSN_COST); 16363 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16364 ins_encode %{ 16365 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16366 as_FloatRegister($src1$$reg), 16367 as_FloatRegister($src2$$reg)); 16368 %} 16369 ins_pipe(vdop64); 16370 %} 16371 16372 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16373 %{ 16374 predicate(n->as_Vector()->length() == 16); 16375 match(Set dst (AddVB src1 src2)); 16376 ins_cost(INSN_COST); 16377 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16378 ins_encode %{ 16379 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16380 as_FloatRegister($src1$$reg), 16381 as_FloatRegister($src2$$reg)); 16382 %} 16383 ins_pipe(vdop128); 16384 %} 16385 16386 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16387 %{ 16388 predicate(n->as_Vector()->length() == 2 || 16389 n->as_Vector()->length() == 4); 16390 match(Set dst (AddVS src1 src2)); 16391 ins_cost(INSN_COST); 16392 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16393 ins_encode %{ 16394 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16395 as_FloatRegister($src1$$reg), 16396 as_FloatRegister($src2$$reg)); 16397 %} 16398 ins_pipe(vdop64); 16399 %} 16400 16401 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16402 %{ 16403 predicate(n->as_Vector()->length() == 8); 16404 match(Set dst (AddVS src1 src2)); 16405 ins_cost(INSN_COST); 16406 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16407 ins_encode %{ 16408 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16409 as_FloatRegister($src1$$reg), 16410 as_FloatRegister($src2$$reg)); 16411 %} 16412 ins_pipe(vdop128); 16413 %} 16414 16415 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16416 %{ 16417 predicate(n->as_Vector()->length() == 2); 16418 match(Set dst (AddVI src1 src2)); 16419 ins_cost(INSN_COST); 16420 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16421 ins_encode %{ 16422 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16423 as_FloatRegister($src1$$reg), 16424 as_FloatRegister($src2$$reg)); 16425 %} 16426 ins_pipe(vdop64); 16427 %} 16428 16429 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16430 %{ 16431 predicate(n->as_Vector()->length() == 4); 16432 match(Set dst (AddVI src1 src2)); 16433 ins_cost(INSN_COST); 16434 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16435 ins_encode %{ 16436 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16437 as_FloatRegister($src1$$reg), 16438 as_FloatRegister($src2$$reg)); 16439 %} 16440 ins_pipe(vdop128); 16441 %} 16442 16443 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16444 %{ 16445 predicate(n->as_Vector()->length() == 2); 16446 match(Set dst (AddVL src1 src2)); 16447 ins_cost(INSN_COST); 16448 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16449 ins_encode %{ 16450 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16451 as_FloatRegister($src1$$reg), 16452 as_FloatRegister($src2$$reg)); 16453 %} 16454 ins_pipe(vdop128); 16455 %} 16456 16457 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16458 %{ 16459 predicate(n->as_Vector()->length() == 2); 16460 match(Set dst (AddVF src1 src2)); 16461 ins_cost(INSN_COST); 16462 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16463 ins_encode %{ 16464 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16465 as_FloatRegister($src1$$reg), 16466 as_FloatRegister($src2$$reg)); 16467 %} 16468 ins_pipe(vdop_fp64); 16469 %} 16470 16471 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16472 %{ 16473 predicate(n->as_Vector()->length() == 4); 16474 match(Set dst (AddVF src1 src2)); 16475 ins_cost(INSN_COST); 16476 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16477 ins_encode %{ 16478 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16479 as_FloatRegister($src1$$reg), 16480 as_FloatRegister($src2$$reg)); 16481 %} 16482 ins_pipe(vdop_fp128); 16483 %} 16484 16485 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16486 %{ 16487 match(Set dst (AddVD src1 src2)); 16488 ins_cost(INSN_COST); 16489 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16490 ins_encode %{ 16491 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16492 as_FloatRegister($src1$$reg), 16493 as_FloatRegister($src2$$reg)); 16494 %} 16495 ins_pipe(vdop_fp128); 16496 %} 16497 16498 // --------------------------------- SUB -------------------------------------- 16499 16500 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16501 %{ 16502 predicate(n->as_Vector()->length() == 4 || 16503 n->as_Vector()->length() == 8); 16504 match(Set dst (SubVB src1 src2)); 16505 ins_cost(INSN_COST); 16506 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16507 ins_encode %{ 16508 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16509 as_FloatRegister($src1$$reg), 16510 as_FloatRegister($src2$$reg)); 16511 %} 16512 ins_pipe(vdop64); 16513 %} 16514 16515 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16516 %{ 16517 predicate(n->as_Vector()->length() == 16); 16518 match(Set dst (SubVB src1 src2)); 16519 ins_cost(INSN_COST); 16520 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16521 ins_encode %{ 16522 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16523 as_FloatRegister($src1$$reg), 16524 as_FloatRegister($src2$$reg)); 16525 %} 16526 ins_pipe(vdop128); 16527 %} 16528 16529 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16530 %{ 16531 predicate(n->as_Vector()->length() == 2 || 16532 n->as_Vector()->length() == 4); 16533 match(Set dst (SubVS src1 src2)); 16534 ins_cost(INSN_COST); 16535 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16536 ins_encode %{ 16537 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16538 as_FloatRegister($src1$$reg), 16539 as_FloatRegister($src2$$reg)); 16540 %} 16541 ins_pipe(vdop64); 16542 %} 16543 16544 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16545 %{ 16546 predicate(n->as_Vector()->length() == 8); 16547 match(Set dst (SubVS src1 src2)); 16548 ins_cost(INSN_COST); 16549 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16550 ins_encode %{ 16551 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16552 as_FloatRegister($src1$$reg), 16553 as_FloatRegister($src2$$reg)); 16554 %} 16555 ins_pipe(vdop128); 16556 %} 16557 16558 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16559 %{ 16560 predicate(n->as_Vector()->length() == 2); 16561 match(Set dst (SubVI src1 src2)); 16562 ins_cost(INSN_COST); 16563 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16564 ins_encode %{ 16565 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16566 as_FloatRegister($src1$$reg), 16567 as_FloatRegister($src2$$reg)); 16568 %} 16569 ins_pipe(vdop64); 16570 %} 16571 16572 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16573 %{ 16574 predicate(n->as_Vector()->length() == 4); 16575 match(Set dst (SubVI src1 src2)); 16576 ins_cost(INSN_COST); 16577 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16578 ins_encode %{ 16579 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16580 as_FloatRegister($src1$$reg), 16581 as_FloatRegister($src2$$reg)); 16582 %} 16583 ins_pipe(vdop128); 16584 %} 16585 16586 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16587 %{ 16588 predicate(n->as_Vector()->length() == 2); 16589 match(Set dst (SubVL src1 src2)); 16590 ins_cost(INSN_COST); 16591 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16592 ins_encode %{ 16593 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16594 as_FloatRegister($src1$$reg), 16595 as_FloatRegister($src2$$reg)); 16596 %} 16597 ins_pipe(vdop128); 16598 %} 16599 16600 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16601 %{ 16602 predicate(n->as_Vector()->length() == 2); 16603 match(Set dst (SubVF src1 src2)); 16604 ins_cost(INSN_COST); 16605 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16606 ins_encode %{ 16607 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16608 as_FloatRegister($src1$$reg), 16609 as_FloatRegister($src2$$reg)); 16610 %} 16611 ins_pipe(vdop_fp64); 16612 %} 16613 16614 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16615 %{ 16616 predicate(n->as_Vector()->length() == 4); 16617 match(Set dst (SubVF src1 src2)); 16618 ins_cost(INSN_COST); 16619 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16620 ins_encode %{ 16621 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16622 as_FloatRegister($src1$$reg), 16623 as_FloatRegister($src2$$reg)); 16624 %} 16625 ins_pipe(vdop_fp128); 16626 %} 16627 16628 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16629 %{ 16630 predicate(n->as_Vector()->length() == 2); 16631 match(Set dst (SubVD src1 src2)); 16632 ins_cost(INSN_COST); 16633 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16634 ins_encode %{ 16635 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16636 as_FloatRegister($src1$$reg), 16637 as_FloatRegister($src2$$reg)); 16638 %} 16639 ins_pipe(vdop_fp128); 16640 %} 16641 16642 // --------------------------------- MUL -------------------------------------- 16643 16644 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16645 %{ 16646 predicate(n->as_Vector()->length() == 2 || 16647 n->as_Vector()->length() == 4); 16648 match(Set dst (MulVS src1 src2)); 16649 ins_cost(INSN_COST); 16650 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16651 ins_encode %{ 16652 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16653 as_FloatRegister($src1$$reg), 16654 as_FloatRegister($src2$$reg)); 16655 %} 16656 ins_pipe(vmul64); 16657 %} 16658 16659 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16660 %{ 16661 predicate(n->as_Vector()->length() == 8); 16662 match(Set dst (MulVS src1 src2)); 16663 ins_cost(INSN_COST); 16664 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16665 ins_encode %{ 16666 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16667 as_FloatRegister($src1$$reg), 16668 as_FloatRegister($src2$$reg)); 16669 %} 16670 ins_pipe(vmul128); 16671 %} 16672 16673 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16674 %{ 16675 predicate(n->as_Vector()->length() == 2); 16676 match(Set dst (MulVI src1 src2)); 16677 ins_cost(INSN_COST); 16678 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16679 ins_encode %{ 16680 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16681 as_FloatRegister($src1$$reg), 16682 as_FloatRegister($src2$$reg)); 16683 %} 16684 ins_pipe(vmul64); 16685 %} 16686 16687 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16688 %{ 16689 predicate(n->as_Vector()->length() == 4); 16690 match(Set dst (MulVI src1 src2)); 16691 ins_cost(INSN_COST); 16692 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16693 ins_encode %{ 16694 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16695 as_FloatRegister($src1$$reg), 16696 as_FloatRegister($src2$$reg)); 16697 %} 16698 ins_pipe(vmul128); 16699 %} 16700 16701 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16702 %{ 16703 predicate(n->as_Vector()->length() == 2); 16704 match(Set dst (MulVF src1 src2)); 16705 ins_cost(INSN_COST); 16706 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16707 ins_encode %{ 16708 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16709 as_FloatRegister($src1$$reg), 16710 as_FloatRegister($src2$$reg)); 16711 %} 16712 ins_pipe(vmuldiv_fp64); 16713 %} 16714 16715 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16716 %{ 16717 predicate(n->as_Vector()->length() == 4); 16718 match(Set dst (MulVF src1 src2)); 16719 ins_cost(INSN_COST); 16720 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16721 ins_encode %{ 16722 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16723 as_FloatRegister($src1$$reg), 16724 as_FloatRegister($src2$$reg)); 16725 %} 16726 ins_pipe(vmuldiv_fp128); 16727 %} 16728 16729 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16730 %{ 16731 predicate(n->as_Vector()->length() == 2); 16732 match(Set dst (MulVD src1 src2)); 16733 ins_cost(INSN_COST); 16734 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16735 ins_encode %{ 16736 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16737 as_FloatRegister($src1$$reg), 16738 as_FloatRegister($src2$$reg)); 16739 %} 16740 ins_pipe(vmuldiv_fp128); 16741 %} 16742 16743 // --------------------------------- MLA -------------------------------------- 16744 16745 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16746 %{ 16747 predicate(n->as_Vector()->length() == 2 || 16748 n->as_Vector()->length() == 4); 16749 match(Set dst (AddVS dst (MulVS src1 src2))); 16750 ins_cost(INSN_COST); 16751 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16752 ins_encode %{ 16753 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16754 as_FloatRegister($src1$$reg), 16755 as_FloatRegister($src2$$reg)); 16756 %} 16757 ins_pipe(vmla64); 16758 %} 16759 16760 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16761 %{ 16762 predicate(n->as_Vector()->length() == 8); 16763 match(Set dst (AddVS dst (MulVS src1 src2))); 16764 ins_cost(INSN_COST); 16765 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16766 ins_encode %{ 16767 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16768 as_FloatRegister($src1$$reg), 16769 as_FloatRegister($src2$$reg)); 16770 %} 16771 ins_pipe(vmla128); 16772 %} 16773 16774 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16775 %{ 16776 predicate(n->as_Vector()->length() == 2); 16777 match(Set dst (AddVI dst (MulVI src1 src2))); 16778 ins_cost(INSN_COST); 16779 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16780 ins_encode %{ 16781 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16782 as_FloatRegister($src1$$reg), 16783 as_FloatRegister($src2$$reg)); 16784 %} 16785 ins_pipe(vmla64); 16786 %} 16787 16788 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16789 %{ 16790 predicate(n->as_Vector()->length() == 4); 16791 match(Set dst (AddVI dst (MulVI src1 src2))); 16792 ins_cost(INSN_COST); 16793 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16794 ins_encode %{ 16795 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16796 as_FloatRegister($src1$$reg), 16797 as_FloatRegister($src2$$reg)); 16798 %} 16799 ins_pipe(vmla128); 16800 %} 16801 16802 // dst + src1 * src2 16803 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16804 predicate(UseFMA && n->as_Vector()->length() == 2); 16805 match(Set dst (FmaVF dst (Binary src1 src2))); 16806 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16807 ins_cost(INSN_COST); 16808 ins_encode %{ 16809 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16810 as_FloatRegister($src1$$reg), 16811 as_FloatRegister($src2$$reg)); 16812 %} 16813 ins_pipe(vmuldiv_fp64); 16814 %} 16815 16816 // dst + src1 * src2 16817 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16818 predicate(UseFMA && n->as_Vector()->length() == 4); 16819 match(Set dst (FmaVF dst (Binary src1 src2))); 16820 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16821 ins_cost(INSN_COST); 16822 ins_encode %{ 16823 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16824 as_FloatRegister($src1$$reg), 16825 as_FloatRegister($src2$$reg)); 16826 %} 16827 ins_pipe(vmuldiv_fp128); 16828 %} 16829 16830 // dst + src1 * src2 16831 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16832 predicate(UseFMA && n->as_Vector()->length() == 2); 16833 match(Set dst (FmaVD dst (Binary src1 src2))); 16834 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16835 ins_cost(INSN_COST); 16836 ins_encode %{ 16837 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16838 as_FloatRegister($src1$$reg), 16839 as_FloatRegister($src2$$reg)); 16840 %} 16841 ins_pipe(vmuldiv_fp128); 16842 %} 16843 16844 // --------------------------------- MLS -------------------------------------- 16845 16846 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16847 %{ 16848 predicate(n->as_Vector()->length() == 2 || 16849 n->as_Vector()->length() == 4); 16850 match(Set dst (SubVS dst (MulVS src1 src2))); 16851 ins_cost(INSN_COST); 16852 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16853 ins_encode %{ 16854 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16855 as_FloatRegister($src1$$reg), 16856 as_FloatRegister($src2$$reg)); 16857 %} 16858 ins_pipe(vmla64); 16859 %} 16860 16861 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16862 %{ 16863 predicate(n->as_Vector()->length() == 8); 16864 match(Set dst (SubVS dst (MulVS src1 src2))); 16865 ins_cost(INSN_COST); 16866 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16867 ins_encode %{ 16868 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16869 as_FloatRegister($src1$$reg), 16870 as_FloatRegister($src2$$reg)); 16871 %} 16872 ins_pipe(vmla128); 16873 %} 16874 16875 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16876 %{ 16877 predicate(n->as_Vector()->length() == 2); 16878 match(Set dst (SubVI dst (MulVI src1 src2))); 16879 ins_cost(INSN_COST); 16880 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16881 ins_encode %{ 16882 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16883 as_FloatRegister($src1$$reg), 16884 as_FloatRegister($src2$$reg)); 16885 %} 16886 ins_pipe(vmla64); 16887 %} 16888 16889 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16890 %{ 16891 predicate(n->as_Vector()->length() == 4); 16892 match(Set dst (SubVI dst (MulVI src1 src2))); 16893 ins_cost(INSN_COST); 16894 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16895 ins_encode %{ 16896 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16897 as_FloatRegister($src1$$reg), 16898 as_FloatRegister($src2$$reg)); 16899 %} 16900 ins_pipe(vmla128); 16901 %} 16902 16903 // dst - src1 * src2 16904 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16905 predicate(UseFMA && n->as_Vector()->length() == 2); 16906 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16907 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16908 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16909 ins_cost(INSN_COST); 16910 ins_encode %{ 16911 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16912 as_FloatRegister($src1$$reg), 16913 as_FloatRegister($src2$$reg)); 16914 %} 16915 ins_pipe(vmuldiv_fp64); 16916 %} 16917 16918 // dst - src1 * src2 16919 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16920 predicate(UseFMA && n->as_Vector()->length() == 4); 16921 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16922 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16923 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16924 ins_cost(INSN_COST); 16925 ins_encode %{ 16926 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16927 as_FloatRegister($src1$$reg), 16928 as_FloatRegister($src2$$reg)); 16929 %} 16930 ins_pipe(vmuldiv_fp128); 16931 %} 16932 16933 // dst - src1 * src2 16934 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16935 predicate(UseFMA && n->as_Vector()->length() == 2); 16936 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16937 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16938 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16939 ins_cost(INSN_COST); 16940 ins_encode %{ 16941 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16942 as_FloatRegister($src1$$reg), 16943 as_FloatRegister($src2$$reg)); 16944 %} 16945 ins_pipe(vmuldiv_fp128); 16946 %} 16947 16948 // --------------- Vector Multiply-Add Shorts into Integer -------------------- 16949 16950 instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 16951 predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 16952 match(Set dst (MulAddVS2VI src1 src2)); 16953 ins_cost(INSN_COST); 16954 effect(TEMP_DEF dst, TEMP tmp); 16955 format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" 16956 "smullv $dst, $src1, $src2\t# vector (8H)\n\t" 16957 "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} 16958 ins_encode %{ 16959 __ smullv(as_FloatRegister($tmp$$reg), __ T4H, 16960 as_FloatRegister($src1$$reg), 16961 as_FloatRegister($src2$$reg)); 16962 __ smullv(as_FloatRegister($dst$$reg), __ T8H, 16963 as_FloatRegister($src1$$reg), 16964 as_FloatRegister($src2$$reg)); 16965 __ addpv(as_FloatRegister($dst$$reg), __ T4S, 16966 as_FloatRegister($tmp$$reg), 16967 as_FloatRegister($dst$$reg)); 16968 %} 16969 ins_pipe(vmuldiv_fp128); 16970 %} 16971 16972 // --------------------------------- DIV -------------------------------------- 16973 16974 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16975 %{ 16976 predicate(n->as_Vector()->length() == 2); 16977 match(Set dst (DivVF src1 src2)); 16978 ins_cost(INSN_COST); 16979 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16980 ins_encode %{ 16981 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16982 as_FloatRegister($src1$$reg), 16983 as_FloatRegister($src2$$reg)); 16984 %} 16985 ins_pipe(vmuldiv_fp64); 16986 %} 16987 16988 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16989 %{ 16990 predicate(n->as_Vector()->length() == 4); 16991 match(Set dst (DivVF src1 src2)); 16992 ins_cost(INSN_COST); 16993 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16994 ins_encode %{ 16995 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16996 as_FloatRegister($src1$$reg), 16997 as_FloatRegister($src2$$reg)); 16998 %} 16999 ins_pipe(vmuldiv_fp128); 17000 %} 17001 17002 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17003 %{ 17004 predicate(n->as_Vector()->length() == 2); 17005 match(Set dst (DivVD src1 src2)); 17006 ins_cost(INSN_COST); 17007 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17008 ins_encode %{ 17009 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17010 as_FloatRegister($src1$$reg), 17011 as_FloatRegister($src2$$reg)); 17012 %} 17013 ins_pipe(vmuldiv_fp128); 17014 %} 17015 17016 // --------------------------------- SQRT ------------------------------------- 17017 17018 instruct vsqrt2D(vecX dst, vecX src) 17019 %{ 17020 predicate(n->as_Vector()->length() == 2); 17021 match(Set dst (SqrtVD src)); 17022 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17023 ins_encode %{ 17024 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17025 as_FloatRegister($src$$reg)); 17026 %} 17027 ins_pipe(vsqrt_fp128); 17028 %} 17029 17030 // --------------------------------- ABS -------------------------------------- 17031 17032 instruct vabs2F(vecD dst, vecD src) 17033 %{ 17034 predicate(n->as_Vector()->length() == 2); 17035 match(Set dst (AbsVF src)); 17036 ins_cost(INSN_COST * 3); 17037 format %{ "fabs $dst,$src\t# vector (2S)" %} 17038 ins_encode %{ 17039 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 17040 as_FloatRegister($src$$reg)); 17041 %} 17042 ins_pipe(vunop_fp64); 17043 %} 17044 17045 instruct vabs4F(vecX dst, vecX src) 17046 %{ 17047 predicate(n->as_Vector()->length() == 4); 17048 match(Set dst (AbsVF src)); 17049 ins_cost(INSN_COST * 3); 17050 format %{ "fabs $dst,$src\t# vector (4S)" %} 17051 ins_encode %{ 17052 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 17053 as_FloatRegister($src$$reg)); 17054 %} 17055 ins_pipe(vunop_fp128); 17056 %} 17057 17058 instruct vabs2D(vecX dst, vecX src) 17059 %{ 17060 predicate(n->as_Vector()->length() == 2); 17061 match(Set dst (AbsVD src)); 17062 ins_cost(INSN_COST * 3); 17063 format %{ "fabs $dst,$src\t# vector (2D)" %} 17064 ins_encode %{ 17065 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17066 as_FloatRegister($src$$reg)); 17067 %} 17068 ins_pipe(vunop_fp128); 17069 %} 17070 17071 // --------------------------------- NEG -------------------------------------- 17072 17073 instruct vneg2F(vecD dst, vecD src) 17074 %{ 17075 predicate(n->as_Vector()->length() == 2); 17076 match(Set dst (NegVF src)); 17077 ins_cost(INSN_COST * 3); 17078 format %{ "fneg $dst,$src\t# vector (2S)" %} 17079 ins_encode %{ 17080 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17081 as_FloatRegister($src$$reg)); 17082 %} 17083 ins_pipe(vunop_fp64); 17084 %} 17085 17086 instruct vneg4F(vecX dst, vecX src) 17087 %{ 17088 predicate(n->as_Vector()->length() == 4); 17089 match(Set dst (NegVF src)); 17090 ins_cost(INSN_COST * 3); 17091 format %{ "fneg $dst,$src\t# vector (4S)" %} 17092 ins_encode %{ 17093 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17094 as_FloatRegister($src$$reg)); 17095 %} 17096 ins_pipe(vunop_fp128); 17097 %} 17098 17099 instruct vneg2D(vecX dst, vecX src) 17100 %{ 17101 predicate(n->as_Vector()->length() == 2); 17102 match(Set dst (NegVD src)); 17103 ins_cost(INSN_COST * 3); 17104 format %{ "fneg $dst,$src\t# vector (2D)" %} 17105 ins_encode %{ 17106 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17107 as_FloatRegister($src$$reg)); 17108 %} 17109 ins_pipe(vunop_fp128); 17110 %} 17111 17112 // --------------------------------- AND -------------------------------------- 17113 17114 instruct vand8B(vecD dst, vecD src1, vecD src2) 17115 %{ 17116 predicate(n->as_Vector()->length_in_bytes() == 4 || 17117 n->as_Vector()->length_in_bytes() == 8); 17118 match(Set dst (AndV src1 src2)); 17119 ins_cost(INSN_COST); 17120 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17121 ins_encode %{ 17122 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17123 as_FloatRegister($src1$$reg), 17124 as_FloatRegister($src2$$reg)); 17125 %} 17126 ins_pipe(vlogical64); 17127 %} 17128 17129 instruct vand16B(vecX dst, vecX src1, vecX src2) 17130 %{ 17131 predicate(n->as_Vector()->length_in_bytes() == 16); 17132 match(Set dst (AndV src1 src2)); 17133 ins_cost(INSN_COST); 17134 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17135 ins_encode %{ 17136 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17137 as_FloatRegister($src1$$reg), 17138 as_FloatRegister($src2$$reg)); 17139 %} 17140 ins_pipe(vlogical128); 17141 %} 17142 17143 // --------------------------------- OR --------------------------------------- 17144 17145 instruct vor8B(vecD dst, vecD src1, vecD src2) 17146 %{ 17147 predicate(n->as_Vector()->length_in_bytes() == 4 || 17148 n->as_Vector()->length_in_bytes() == 8); 17149 match(Set dst (OrV src1 src2)); 17150 ins_cost(INSN_COST); 17151 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17152 ins_encode %{ 17153 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17154 as_FloatRegister($src1$$reg), 17155 as_FloatRegister($src2$$reg)); 17156 %} 17157 ins_pipe(vlogical64); 17158 %} 17159 17160 instruct vor16B(vecX dst, vecX src1, vecX src2) 17161 %{ 17162 predicate(n->as_Vector()->length_in_bytes() == 16); 17163 match(Set dst (OrV src1 src2)); 17164 ins_cost(INSN_COST); 17165 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17166 ins_encode %{ 17167 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17168 as_FloatRegister($src1$$reg), 17169 as_FloatRegister($src2$$reg)); 17170 %} 17171 ins_pipe(vlogical128); 17172 %} 17173 17174 // --------------------------------- XOR -------------------------------------- 17175 17176 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17177 %{ 17178 predicate(n->as_Vector()->length_in_bytes() == 4 || 17179 n->as_Vector()->length_in_bytes() == 8); 17180 match(Set dst (XorV src1 src2)); 17181 ins_cost(INSN_COST); 17182 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17183 ins_encode %{ 17184 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17185 as_FloatRegister($src1$$reg), 17186 as_FloatRegister($src2$$reg)); 17187 %} 17188 ins_pipe(vlogical64); 17189 %} 17190 17191 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17192 %{ 17193 predicate(n->as_Vector()->length_in_bytes() == 16); 17194 match(Set dst (XorV src1 src2)); 17195 ins_cost(INSN_COST); 17196 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17197 ins_encode %{ 17198 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17199 as_FloatRegister($src1$$reg), 17200 as_FloatRegister($src2$$reg)); 17201 %} 17202 ins_pipe(vlogical128); 17203 %} 17204 17205 // ------------------------------ Shift --------------------------------------- 17206 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17207 predicate(n->as_Vector()->length_in_bytes() == 8); 17208 match(Set dst (LShiftCntV cnt)); 17209 match(Set dst (RShiftCntV cnt)); 17210 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17211 ins_encode %{ 17212 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17213 %} 17214 ins_pipe(vdup_reg_reg64); 17215 %} 17216 17217 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17218 predicate(n->as_Vector()->length_in_bytes() == 16); 17219 match(Set dst (LShiftCntV cnt)); 17220 match(Set dst (RShiftCntV cnt)); 17221 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17222 ins_encode %{ 17223 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17224 %} 17225 ins_pipe(vdup_reg_reg128); 17226 %} 17227 17228 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17229 predicate(n->as_Vector()->length() == 4 || 17230 n->as_Vector()->length() == 8); 17231 match(Set dst (LShiftVB src shift)); 17232 ins_cost(INSN_COST); 17233 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17234 ins_encode %{ 17235 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17236 as_FloatRegister($src$$reg), 17237 as_FloatRegister($shift$$reg)); 17238 %} 17239 ins_pipe(vshift64); 17240 %} 17241 17242 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17243 predicate(n->as_Vector()->length() == 16); 17244 match(Set dst (LShiftVB src shift)); 17245 ins_cost(INSN_COST); 17246 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17247 ins_encode %{ 17248 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17249 as_FloatRegister($src$$reg), 17250 as_FloatRegister($shift$$reg)); 17251 %} 17252 ins_pipe(vshift128); 17253 %} 17254 17255 // Right shifts with vector shift count on aarch64 SIMD are implemented 17256 // as left shift by negative shift count. 17257 // There are two cases for vector shift count. 17258 // 17259 // Case 1: The vector shift count is from replication. 17260 // | | 17261 // LoadVector RShiftCntV 17262 // | / 17263 // RShiftVI 17264 // Note: In inner loop, multiple neg instructions are used, which can be 17265 // moved to outer loop and merge into one neg instruction. 17266 // 17267 // Case 2: The vector shift count is from loading. 17268 // This case isn't supported by middle-end now. But it's supported by 17269 // panama/vectorIntrinsics(JEP 338: Vector API). 17270 // | | 17271 // LoadVector LoadVector 17272 // | / 17273 // RShiftVI 17274 // 17275 17276 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17277 predicate(n->as_Vector()->length() == 4 || 17278 n->as_Vector()->length() == 8); 17279 match(Set dst (RShiftVB src shift)); 17280 ins_cost(INSN_COST); 17281 effect(TEMP tmp); 17282 format %{ "negr $tmp,$shift\t" 17283 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17284 ins_encode %{ 17285 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17286 as_FloatRegister($shift$$reg)); 17287 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17288 as_FloatRegister($src$$reg), 17289 as_FloatRegister($tmp$$reg)); 17290 %} 17291 ins_pipe(vshift64); 17292 %} 17293 17294 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17295 predicate(n->as_Vector()->length() == 16); 17296 match(Set dst (RShiftVB src shift)); 17297 ins_cost(INSN_COST); 17298 effect(TEMP tmp); 17299 format %{ "negr $tmp,$shift\t" 17300 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17301 ins_encode %{ 17302 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17303 as_FloatRegister($shift$$reg)); 17304 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17305 as_FloatRegister($src$$reg), 17306 as_FloatRegister($tmp$$reg)); 17307 %} 17308 ins_pipe(vshift128); 17309 %} 17310 17311 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17312 predicate(n->as_Vector()->length() == 4 || 17313 n->as_Vector()->length() == 8); 17314 match(Set dst (URShiftVB src shift)); 17315 ins_cost(INSN_COST); 17316 effect(TEMP tmp); 17317 format %{ "negr $tmp,$shift\t" 17318 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17319 ins_encode %{ 17320 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17321 as_FloatRegister($shift$$reg)); 17322 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17323 as_FloatRegister($src$$reg), 17324 as_FloatRegister($tmp$$reg)); 17325 %} 17326 ins_pipe(vshift64); 17327 %} 17328 17329 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17330 predicate(n->as_Vector()->length() == 16); 17331 match(Set dst (URShiftVB src shift)); 17332 ins_cost(INSN_COST); 17333 effect(TEMP tmp); 17334 format %{ "negr $tmp,$shift\t" 17335 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17336 ins_encode %{ 17337 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17338 as_FloatRegister($shift$$reg)); 17339 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17340 as_FloatRegister($src$$reg), 17341 as_FloatRegister($tmp$$reg)); 17342 %} 17343 ins_pipe(vshift128); 17344 %} 17345 17346 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17347 predicate(n->as_Vector()->length() == 4 || 17348 n->as_Vector()->length() == 8); 17349 match(Set dst (LShiftVB src (LShiftCntV shift))); 17350 ins_cost(INSN_COST); 17351 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17352 ins_encode %{ 17353 int sh = (int)$shift$$constant; 17354 if (sh >= 8) { 17355 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17356 as_FloatRegister($src$$reg), 17357 as_FloatRegister($src$$reg)); 17358 } else { 17359 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17360 as_FloatRegister($src$$reg), sh); 17361 } 17362 %} 17363 ins_pipe(vshift64_imm); 17364 %} 17365 17366 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17367 predicate(n->as_Vector()->length() == 16); 17368 match(Set dst (LShiftVB src (LShiftCntV shift))); 17369 ins_cost(INSN_COST); 17370 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17371 ins_encode %{ 17372 int sh = (int)$shift$$constant; 17373 if (sh >= 8) { 17374 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17375 as_FloatRegister($src$$reg), 17376 as_FloatRegister($src$$reg)); 17377 } else { 17378 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17379 as_FloatRegister($src$$reg), sh); 17380 } 17381 %} 17382 ins_pipe(vshift128_imm); 17383 %} 17384 17385 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17386 predicate(n->as_Vector()->length() == 4 || 17387 n->as_Vector()->length() == 8); 17388 match(Set dst (RShiftVB src (RShiftCntV shift))); 17389 ins_cost(INSN_COST); 17390 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17391 ins_encode %{ 17392 int sh = (int)$shift$$constant; 17393 if (sh >= 8) sh = 7; 17394 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17395 as_FloatRegister($src$$reg), sh); 17396 %} 17397 ins_pipe(vshift64_imm); 17398 %} 17399 17400 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17401 predicate(n->as_Vector()->length() == 16); 17402 match(Set dst (RShiftVB src (RShiftCntV shift))); 17403 ins_cost(INSN_COST); 17404 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17405 ins_encode %{ 17406 int sh = (int)$shift$$constant; 17407 if (sh >= 8) sh = 7; 17408 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17409 as_FloatRegister($src$$reg), sh); 17410 %} 17411 ins_pipe(vshift128_imm); 17412 %} 17413 17414 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17415 predicate(n->as_Vector()->length() == 4 || 17416 n->as_Vector()->length() == 8); 17417 match(Set dst (URShiftVB src (RShiftCntV shift))); 17418 ins_cost(INSN_COST); 17419 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17420 ins_encode %{ 17421 int sh = (int)$shift$$constant; 17422 if (sh >= 8) { 17423 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17424 as_FloatRegister($src$$reg), 17425 as_FloatRegister($src$$reg)); 17426 } else { 17427 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17428 as_FloatRegister($src$$reg), sh); 17429 } 17430 %} 17431 ins_pipe(vshift64_imm); 17432 %} 17433 17434 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17435 predicate(n->as_Vector()->length() == 16); 17436 match(Set dst (URShiftVB src (RShiftCntV shift))); 17437 ins_cost(INSN_COST); 17438 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17439 ins_encode %{ 17440 int sh = (int)$shift$$constant; 17441 if (sh >= 8) { 17442 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17443 as_FloatRegister($src$$reg), 17444 as_FloatRegister($src$$reg)); 17445 } else { 17446 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17447 as_FloatRegister($src$$reg), sh); 17448 } 17449 %} 17450 ins_pipe(vshift128_imm); 17451 %} 17452 17453 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17454 predicate(n->as_Vector()->length() == 2 || 17455 n->as_Vector()->length() == 4); 17456 match(Set dst (LShiftVS src shift)); 17457 ins_cost(INSN_COST); 17458 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17459 ins_encode %{ 17460 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17461 as_FloatRegister($src$$reg), 17462 as_FloatRegister($shift$$reg)); 17463 %} 17464 ins_pipe(vshift64); 17465 %} 17466 17467 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17468 predicate(n->as_Vector()->length() == 8); 17469 match(Set dst (LShiftVS src shift)); 17470 ins_cost(INSN_COST); 17471 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17472 ins_encode %{ 17473 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17474 as_FloatRegister($src$$reg), 17475 as_FloatRegister($shift$$reg)); 17476 %} 17477 ins_pipe(vshift128); 17478 %} 17479 17480 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17481 predicate(n->as_Vector()->length() == 2 || 17482 n->as_Vector()->length() == 4); 17483 match(Set dst (RShiftVS src shift)); 17484 ins_cost(INSN_COST); 17485 effect(TEMP tmp); 17486 format %{ "negr $tmp,$shift\t" 17487 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17488 ins_encode %{ 17489 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17490 as_FloatRegister($shift$$reg)); 17491 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17492 as_FloatRegister($src$$reg), 17493 as_FloatRegister($tmp$$reg)); 17494 %} 17495 ins_pipe(vshift64); 17496 %} 17497 17498 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17499 predicate(n->as_Vector()->length() == 8); 17500 match(Set dst (RShiftVS src shift)); 17501 ins_cost(INSN_COST); 17502 effect(TEMP tmp); 17503 format %{ "negr $tmp,$shift\t" 17504 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17505 ins_encode %{ 17506 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17507 as_FloatRegister($shift$$reg)); 17508 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17509 as_FloatRegister($src$$reg), 17510 as_FloatRegister($tmp$$reg)); 17511 %} 17512 ins_pipe(vshift128); 17513 %} 17514 17515 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17516 predicate(n->as_Vector()->length() == 2 || 17517 n->as_Vector()->length() == 4); 17518 match(Set dst (URShiftVS src shift)); 17519 ins_cost(INSN_COST); 17520 effect(TEMP tmp); 17521 format %{ "negr $tmp,$shift\t" 17522 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17523 ins_encode %{ 17524 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17525 as_FloatRegister($shift$$reg)); 17526 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17527 as_FloatRegister($src$$reg), 17528 as_FloatRegister($tmp$$reg)); 17529 %} 17530 ins_pipe(vshift64); 17531 %} 17532 17533 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17534 predicate(n->as_Vector()->length() == 8); 17535 match(Set dst (URShiftVS src shift)); 17536 ins_cost(INSN_COST); 17537 effect(TEMP tmp); 17538 format %{ "negr $tmp,$shift\t" 17539 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17540 ins_encode %{ 17541 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17542 as_FloatRegister($shift$$reg)); 17543 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17544 as_FloatRegister($src$$reg), 17545 as_FloatRegister($tmp$$reg)); 17546 %} 17547 ins_pipe(vshift128); 17548 %} 17549 17550 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17551 predicate(n->as_Vector()->length() == 2 || 17552 n->as_Vector()->length() == 4); 17553 match(Set dst (LShiftVS src (LShiftCntV shift))); 17554 ins_cost(INSN_COST); 17555 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17556 ins_encode %{ 17557 int sh = (int)$shift$$constant; 17558 if (sh >= 16) { 17559 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17560 as_FloatRegister($src$$reg), 17561 as_FloatRegister($src$$reg)); 17562 } else { 17563 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17564 as_FloatRegister($src$$reg), sh); 17565 } 17566 %} 17567 ins_pipe(vshift64_imm); 17568 %} 17569 17570 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17571 predicate(n->as_Vector()->length() == 8); 17572 match(Set dst (LShiftVS src (LShiftCntV shift))); 17573 ins_cost(INSN_COST); 17574 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17575 ins_encode %{ 17576 int sh = (int)$shift$$constant; 17577 if (sh >= 16) { 17578 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17579 as_FloatRegister($src$$reg), 17580 as_FloatRegister($src$$reg)); 17581 } else { 17582 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17583 as_FloatRegister($src$$reg), sh); 17584 } 17585 %} 17586 ins_pipe(vshift128_imm); 17587 %} 17588 17589 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17590 predicate(n->as_Vector()->length() == 2 || 17591 n->as_Vector()->length() == 4); 17592 match(Set dst (RShiftVS src (LShiftCntV shift))); 17593 ins_cost(INSN_COST); 17594 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17595 ins_encode %{ 17596 int sh = (int)$shift$$constant; 17597 if (sh >= 16) sh = 15; 17598 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17599 as_FloatRegister($src$$reg), sh); 17600 %} 17601 ins_pipe(vshift64_imm); 17602 %} 17603 17604 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17605 predicate(n->as_Vector()->length() == 8); 17606 match(Set dst (RShiftVS src (LShiftCntV shift))); 17607 ins_cost(INSN_COST); 17608 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17609 ins_encode %{ 17610 int sh = (int)$shift$$constant; 17611 if (sh >= 16) sh = 15; 17612 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17613 as_FloatRegister($src$$reg), sh); 17614 %} 17615 ins_pipe(vshift128_imm); 17616 %} 17617 17618 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17619 predicate(n->as_Vector()->length() == 2 || 17620 n->as_Vector()->length() == 4); 17621 match(Set dst (URShiftVS src (RShiftCntV shift))); 17622 ins_cost(INSN_COST); 17623 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17624 ins_encode %{ 17625 int sh = (int)$shift$$constant; 17626 if (sh >= 16) { 17627 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17628 as_FloatRegister($src$$reg), 17629 as_FloatRegister($src$$reg)); 17630 } else { 17631 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17632 as_FloatRegister($src$$reg), sh); 17633 } 17634 %} 17635 ins_pipe(vshift64_imm); 17636 %} 17637 17638 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17639 predicate(n->as_Vector()->length() == 8); 17640 match(Set dst (URShiftVS src (RShiftCntV shift))); 17641 ins_cost(INSN_COST); 17642 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17643 ins_encode %{ 17644 int sh = (int)$shift$$constant; 17645 if (sh >= 16) { 17646 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17647 as_FloatRegister($src$$reg), 17648 as_FloatRegister($src$$reg)); 17649 } else { 17650 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17651 as_FloatRegister($src$$reg), sh); 17652 } 17653 %} 17654 ins_pipe(vshift128_imm); 17655 %} 17656 17657 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17658 predicate(n->as_Vector()->length() == 2); 17659 match(Set dst (LShiftVI src shift)); 17660 ins_cost(INSN_COST); 17661 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17662 ins_encode %{ 17663 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17664 as_FloatRegister($src$$reg), 17665 as_FloatRegister($shift$$reg)); 17666 %} 17667 ins_pipe(vshift64); 17668 %} 17669 17670 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17671 predicate(n->as_Vector()->length() == 4); 17672 match(Set dst (LShiftVI src shift)); 17673 ins_cost(INSN_COST); 17674 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17675 ins_encode %{ 17676 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17677 as_FloatRegister($src$$reg), 17678 as_FloatRegister($shift$$reg)); 17679 %} 17680 ins_pipe(vshift128); 17681 %} 17682 17683 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17684 predicate(n->as_Vector()->length() == 2); 17685 match(Set dst (RShiftVI src shift)); 17686 ins_cost(INSN_COST); 17687 effect(TEMP tmp); 17688 format %{ "negr $tmp,$shift\t" 17689 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17690 ins_encode %{ 17691 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17692 as_FloatRegister($shift$$reg)); 17693 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17694 as_FloatRegister($src$$reg), 17695 as_FloatRegister($tmp$$reg)); 17696 %} 17697 ins_pipe(vshift64); 17698 %} 17699 17700 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17701 predicate(n->as_Vector()->length() == 4); 17702 match(Set dst (RShiftVI src shift)); 17703 ins_cost(INSN_COST); 17704 effect(TEMP tmp); 17705 format %{ "negr $tmp,$shift\t" 17706 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17707 ins_encode %{ 17708 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17709 as_FloatRegister($shift$$reg)); 17710 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17711 as_FloatRegister($src$$reg), 17712 as_FloatRegister($tmp$$reg)); 17713 %} 17714 ins_pipe(vshift128); 17715 %} 17716 17717 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17718 predicate(n->as_Vector()->length() == 2); 17719 match(Set dst (URShiftVI src shift)); 17720 ins_cost(INSN_COST); 17721 effect(TEMP tmp); 17722 format %{ "negr $tmp,$shift\t" 17723 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17724 ins_encode %{ 17725 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17726 as_FloatRegister($shift$$reg)); 17727 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17728 as_FloatRegister($src$$reg), 17729 as_FloatRegister($tmp$$reg)); 17730 %} 17731 ins_pipe(vshift64); 17732 %} 17733 17734 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17735 predicate(n->as_Vector()->length() == 4); 17736 match(Set dst (URShiftVI src shift)); 17737 ins_cost(INSN_COST); 17738 effect(TEMP tmp); 17739 format %{ "negr $tmp,$shift\t" 17740 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17741 ins_encode %{ 17742 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17743 as_FloatRegister($shift$$reg)); 17744 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17745 as_FloatRegister($src$$reg), 17746 as_FloatRegister($tmp$$reg)); 17747 %} 17748 ins_pipe(vshift128); 17749 %} 17750 17751 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17752 predicate(n->as_Vector()->length() == 2); 17753 match(Set dst (LShiftVI src (LShiftCntV shift))); 17754 ins_cost(INSN_COST); 17755 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17756 ins_encode %{ 17757 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17758 as_FloatRegister($src$$reg), 17759 (int)$shift$$constant); 17760 %} 17761 ins_pipe(vshift64_imm); 17762 %} 17763 17764 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17765 predicate(n->as_Vector()->length() == 4); 17766 match(Set dst (LShiftVI src (LShiftCntV shift))); 17767 ins_cost(INSN_COST); 17768 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17769 ins_encode %{ 17770 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17771 as_FloatRegister($src$$reg), 17772 (int)$shift$$constant); 17773 %} 17774 ins_pipe(vshift128_imm); 17775 %} 17776 17777 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17778 predicate(n->as_Vector()->length() == 2); 17779 match(Set dst (RShiftVI src (RShiftCntV shift))); 17780 ins_cost(INSN_COST); 17781 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17782 ins_encode %{ 17783 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17784 as_FloatRegister($src$$reg), 17785 (int)$shift$$constant); 17786 %} 17787 ins_pipe(vshift64_imm); 17788 %} 17789 17790 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17791 predicate(n->as_Vector()->length() == 4); 17792 match(Set dst (RShiftVI src (RShiftCntV shift))); 17793 ins_cost(INSN_COST); 17794 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17795 ins_encode %{ 17796 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17797 as_FloatRegister($src$$reg), 17798 (int)$shift$$constant); 17799 %} 17800 ins_pipe(vshift128_imm); 17801 %} 17802 17803 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17804 predicate(n->as_Vector()->length() == 2); 17805 match(Set dst (URShiftVI src (RShiftCntV shift))); 17806 ins_cost(INSN_COST); 17807 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17808 ins_encode %{ 17809 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17810 as_FloatRegister($src$$reg), 17811 (int)$shift$$constant); 17812 %} 17813 ins_pipe(vshift64_imm); 17814 %} 17815 17816 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17817 predicate(n->as_Vector()->length() == 4); 17818 match(Set dst (URShiftVI src (RShiftCntV shift))); 17819 ins_cost(INSN_COST); 17820 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17821 ins_encode %{ 17822 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17823 as_FloatRegister($src$$reg), 17824 (int)$shift$$constant); 17825 %} 17826 ins_pipe(vshift128_imm); 17827 %} 17828 17829 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17830 predicate(n->as_Vector()->length() == 2); 17831 match(Set dst (LShiftVL src shift)); 17832 ins_cost(INSN_COST); 17833 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17834 ins_encode %{ 17835 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17836 as_FloatRegister($src$$reg), 17837 as_FloatRegister($shift$$reg)); 17838 %} 17839 ins_pipe(vshift128); 17840 %} 17841 17842 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17843 predicate(n->as_Vector()->length() == 2); 17844 match(Set dst (RShiftVL src shift)); 17845 ins_cost(INSN_COST); 17846 effect(TEMP tmp); 17847 format %{ "negr $tmp,$shift\t" 17848 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17849 ins_encode %{ 17850 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17851 as_FloatRegister($shift$$reg)); 17852 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17853 as_FloatRegister($src$$reg), 17854 as_FloatRegister($tmp$$reg)); 17855 %} 17856 ins_pipe(vshift128); 17857 %} 17858 17859 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17860 predicate(n->as_Vector()->length() == 2); 17861 match(Set dst (URShiftVL src shift)); 17862 ins_cost(INSN_COST); 17863 effect(TEMP tmp); 17864 format %{ "negr $tmp,$shift\t" 17865 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17866 ins_encode %{ 17867 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17868 as_FloatRegister($shift$$reg)); 17869 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17870 as_FloatRegister($src$$reg), 17871 as_FloatRegister($tmp$$reg)); 17872 %} 17873 ins_pipe(vshift128); 17874 %} 17875 17876 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17877 predicate(n->as_Vector()->length() == 2); 17878 match(Set dst (LShiftVL src (LShiftCntV shift))); 17879 ins_cost(INSN_COST); 17880 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17881 ins_encode %{ 17882 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17883 as_FloatRegister($src$$reg), 17884 (int)$shift$$constant); 17885 %} 17886 ins_pipe(vshift128_imm); 17887 %} 17888 17889 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17890 predicate(n->as_Vector()->length() == 2); 17891 match(Set dst (RShiftVL src (RShiftCntV shift))); 17892 ins_cost(INSN_COST); 17893 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17894 ins_encode %{ 17895 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17896 as_FloatRegister($src$$reg), 17897 (int)$shift$$constant); 17898 %} 17899 ins_pipe(vshift128_imm); 17900 %} 17901 17902 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17903 predicate(n->as_Vector()->length() == 2); 17904 match(Set dst (URShiftVL src (RShiftCntV shift))); 17905 ins_cost(INSN_COST); 17906 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17907 ins_encode %{ 17908 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17909 as_FloatRegister($src$$reg), 17910 (int)$shift$$constant); 17911 %} 17912 ins_pipe(vshift128_imm); 17913 %} 17914 17915 instruct vmax2F(vecD dst, vecD src1, vecD src2) 17916 %{ 17917 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17918 match(Set dst (MaxV src1 src2)); 17919 ins_cost(INSN_COST); 17920 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 17921 ins_encode %{ 17922 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 17923 as_FloatRegister($src1$$reg), 17924 as_FloatRegister($src2$$reg)); 17925 %} 17926 ins_pipe(vdop_fp64); 17927 %} 17928 17929 instruct vmax4F(vecX dst, vecX src1, vecX src2) 17930 %{ 17931 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17932 match(Set dst (MaxV src1 src2)); 17933 ins_cost(INSN_COST); 17934 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 17935 ins_encode %{ 17936 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 17937 as_FloatRegister($src1$$reg), 17938 as_FloatRegister($src2$$reg)); 17939 %} 17940 ins_pipe(vdop_fp128); 17941 %} 17942 17943 instruct vmax2D(vecX dst, vecX src1, vecX src2) 17944 %{ 17945 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17946 match(Set dst (MaxV src1 src2)); 17947 ins_cost(INSN_COST); 17948 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 17949 ins_encode %{ 17950 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 17951 as_FloatRegister($src1$$reg), 17952 as_FloatRegister($src2$$reg)); 17953 %} 17954 ins_pipe(vdop_fp128); 17955 %} 17956 17957 instruct vmin2F(vecD dst, vecD src1, vecD src2) 17958 %{ 17959 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17960 match(Set dst (MinV src1 src2)); 17961 ins_cost(INSN_COST); 17962 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 17963 ins_encode %{ 17964 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 17965 as_FloatRegister($src1$$reg), 17966 as_FloatRegister($src2$$reg)); 17967 %} 17968 ins_pipe(vdop_fp64); 17969 %} 17970 17971 instruct vmin4F(vecX dst, vecX src1, vecX src2) 17972 %{ 17973 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17974 match(Set dst (MinV src1 src2)); 17975 ins_cost(INSN_COST); 17976 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 17977 ins_encode %{ 17978 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 17979 as_FloatRegister($src1$$reg), 17980 as_FloatRegister($src2$$reg)); 17981 %} 17982 ins_pipe(vdop_fp128); 17983 %} 17984 17985 instruct vmin2D(vecX dst, vecX src1, vecX src2) 17986 %{ 17987 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17988 match(Set dst (MinV src1 src2)); 17989 ins_cost(INSN_COST); 17990 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 17991 ins_encode %{ 17992 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 17993 as_FloatRegister($src1$$reg), 17994 as_FloatRegister($src2$$reg)); 17995 %} 17996 ins_pipe(vdop_fp128); 17997 %} 17998 17999 instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ 18000 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18001 match(Set dst (RoundDoubleModeV src rmode)); 18002 format %{ "frint $dst, $src, $rmode" %} 18003 ins_encode %{ 18004 switch ($rmode$$constant) { 18005 case RoundDoubleModeNode::rmode_rint: 18006 __ frintn(as_FloatRegister($dst$$reg), __ T2D, 18007 as_FloatRegister($src$$reg)); 18008 break; 18009 case RoundDoubleModeNode::rmode_floor: 18010 __ frintm(as_FloatRegister($dst$$reg), __ T2D, 18011 as_FloatRegister($src$$reg)); 18012 break; 18013 case RoundDoubleModeNode::rmode_ceil: 18014 __ frintp(as_FloatRegister($dst$$reg), __ T2D, 18015 as_FloatRegister($src$$reg)); 18016 break; 18017 } 18018 %} 18019 ins_pipe(vdop_fp128); 18020 %} 18021 18022 instruct vpopcount4I(vecX dst, vecX src) %{ 18023 predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); 18024 match(Set dst (PopCountVI src)); 18025 format %{ 18026 "cnt $dst, $src\t# vector (16B)\n\t" 18027 "uaddlp $dst, $dst\t# vector (16B)\n\t" 18028 "uaddlp $dst, $dst\t# vector (8H)" 18029 %} 18030 ins_encode %{ 18031 __ cnt(as_FloatRegister($dst$$reg), __ T16B, 18032 as_FloatRegister($src$$reg)); 18033 __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, 18034 as_FloatRegister($dst$$reg)); 18035 __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, 18036 as_FloatRegister($dst$$reg)); 18037 %} 18038 ins_pipe(pipe_class_default); 18039 %} 18040 18041 instruct vpopcount2I(vecD dst, vecD src) %{ 18042 predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); 18043 match(Set dst (PopCountVI src)); 18044 format %{ 18045 "cnt $dst, $src\t# vector (8B)\n\t" 18046 "uaddlp $dst, $dst\t# vector (8B)\n\t" 18047 "uaddlp $dst, $dst\t# vector (4H)" 18048 %} 18049 ins_encode %{ 18050 __ cnt(as_FloatRegister($dst$$reg), __ T8B, 18051 as_FloatRegister($src$$reg)); 18052 __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, 18053 as_FloatRegister($dst$$reg)); 18054 __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, 18055 as_FloatRegister($dst$$reg)); 18056 %} 18057 ins_pipe(pipe_class_default); 18058 %} 18059 18060 //----------PEEPHOLE RULES----------------------------------------------------- 18061 // These must follow all instruction definitions as they use the names 18062 // defined in the instructions definitions. 18063 // 18064 // peepmatch ( root_instr_name [preceding_instruction]* ); 18065 // 18066 // peepconstraint %{ 18067 // (instruction_number.operand_name relational_op instruction_number.operand_name 18068 // [, ...] ); 18069 // // instruction numbers are zero-based using left to right order in peepmatch 18070 // 18071 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18072 // // provide an instruction_number.operand_name for each operand that appears 18073 // // in the replacement instruction's match rule 18074 // 18075 // ---------VM FLAGS--------------------------------------------------------- 18076 // 18077 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18078 // 18079 // Each peephole rule is given an identifying number starting with zero and 18080 // increasing by one in the order seen by the parser. An individual peephole 18081 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18082 // on the command-line. 18083 // 18084 // ---------CURRENT LIMITATIONS---------------------------------------------- 18085 // 18086 // Only match adjacent instructions in same basic block 18087 // Only equality constraints 18088 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18089 // Only one replacement instruction 18090 // 18091 // ---------EXAMPLE---------------------------------------------------------- 18092 // 18093 // // pertinent parts of existing instructions in architecture description 18094 // instruct movI(iRegINoSp dst, iRegI src) 18095 // %{ 18096 // match(Set dst (CopyI src)); 18097 // %} 18098 // 18099 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18100 // %{ 18101 // match(Set dst (AddI dst src)); 18102 // effect(KILL cr); 18103 // %} 18104 // 18105 // // Change (inc mov) to lea 18106 // peephole %{ 18107 // // increment preceeded by register-register move 18108 // peepmatch ( incI_iReg movI ); 18109 // // require that the destination register of the increment 18110 // // match the destination register of the move 18111 // peepconstraint ( 0.dst == 1.dst ); 18112 // // construct a replacement instruction that sets 18113 // // the destination to ( move's source register + one ) 18114 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18115 // %} 18116 // 18117 18118 // Implementation no longer uses movX instructions since 18119 // machine-independent system no longer uses CopyX nodes. 18120 // 18121 // peephole 18122 // %{ 18123 // peepmatch (incI_iReg movI); 18124 // peepconstraint (0.dst == 1.dst); 18125 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18126 // %} 18127 18128 // peephole 18129 // %{ 18130 // peepmatch (decI_iReg movI); 18131 // peepconstraint (0.dst == 1.dst); 18132 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18133 // %} 18134 18135 // peephole 18136 // %{ 18137 // peepmatch (addI_iReg_imm movI); 18138 // peepconstraint (0.dst == 1.dst); 18139 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18140 // %} 18141 18142 // peephole 18143 // %{ 18144 // peepmatch (incL_iReg movL); 18145 // peepconstraint (0.dst == 1.dst); 18146 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18147 // %} 18148 18149 // peephole 18150 // %{ 18151 // peepmatch (decL_iReg movL); 18152 // peepconstraint (0.dst == 1.dst); 18153 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18154 // %} 18155 18156 // peephole 18157 // %{ 18158 // peepmatch (addL_iReg_imm movL); 18159 // peepconstraint (0.dst == 1.dst); 18160 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18161 // %} 18162 18163 // peephole 18164 // %{ 18165 // peepmatch (addP_iReg_imm movP); 18166 // peepconstraint (0.dst == 1.dst); 18167 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18168 // %} 18169 18170 // // Change load of spilled value to only a spill 18171 // instruct storeI(memory mem, iRegI src) 18172 // %{ 18173 // match(Set mem (StoreI mem src)); 18174 // %} 18175 // 18176 // instruct loadI(iRegINoSp dst, memory mem) 18177 // %{ 18178 // match(Set dst (LoadI mem)); 18179 // %} 18180 // 18181 18182 //----------SMARTSPILL RULES--------------------------------------------------- 18183 // These must follow all instruction definitions as they use the names 18184 // defined in the instructions definitions. 18185 18186 // Local Variables: 18187 // mode: c++ 18188 // End: