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 #ifdef _WIN64 536 // On Windows-aarch64, R18 is used to store the pointer to the current 537 // thread's TEB which is itself used to store TLS variables. 538 // An alternative to simply never allocate it would be to save/restore it 539 // at key places. However, because the OS/Win32 exception handling (for 540 // segmentation faults for example) does use TLS to unwind the stack for 541 // Structured Exception Handling. If R18 were to be used for any other 542 // purpose at the time of the exception, the OS/Win32 would not be able to 543 // unwind the stack, and it would result in a crash. Because there are so 544 // many places where such an exception may happen, it's simpler and more 545 // efficient to never allocate R18. 546 // 547 // See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers 548 R18, // tls on Windows 549 #endif 550 R28, // thread 551 R30, // lr 552 R31 // sp 553 ); 554 555 // Class for non-allocatable 64 bit registers 556 reg_class non_allocatable_reg( 557 #ifdef _WIN64 558 R18, R18_H, // tls on Windows 559 #endif 560 R28, R28_H, // thread 561 R30, R30_H, // lr 562 R31, R31_H // sp 563 ); 564 565 // Class for all non-special integer registers 566 reg_class no_special_reg32 %{ 567 return _NO_SPECIAL_REG32_mask; 568 %} 569 570 // Class for all non-special long integer registers 571 reg_class no_special_reg %{ 572 return _NO_SPECIAL_REG_mask; 573 %} 574 575 // Class for 64 bit register r0 576 reg_class r0_reg( 577 R0, R0_H 578 ); 579 580 // Class for 64 bit register r1 581 reg_class r1_reg( 582 R1, R1_H 583 ); 584 585 // Class for 64 bit register r2 586 reg_class r2_reg( 587 R2, R2_H 588 ); 589 590 // Class for 64 bit register r3 591 reg_class r3_reg( 592 R3, R3_H 593 ); 594 595 // Class for 64 bit register r4 596 reg_class r4_reg( 597 R4, R4_H 598 ); 599 600 // Class for 64 bit register r5 601 reg_class r5_reg( 602 R5, R5_H 603 ); 604 605 // Class for 64 bit register r10 606 reg_class r10_reg( 607 R10, R10_H 608 ); 609 610 // Class for 64 bit register r11 611 reg_class r11_reg( 612 R11, R11_H 613 ); 614 615 // Class for method register 616 reg_class method_reg( 617 R12, R12_H 618 ); 619 620 // Class for heapbase register 621 reg_class heapbase_reg( 622 R27, R27_H 623 ); 624 625 // Class for thread register 626 reg_class thread_reg( 627 R28, R28_H 628 ); 629 630 // Class for frame pointer register 631 reg_class fp_reg( 632 R29, R29_H 633 ); 634 635 // Class for link register 636 reg_class lr_reg( 637 R30, R30_H 638 ); 639 640 // Class for long sp register 641 reg_class sp_reg( 642 R31, R31_H 643 ); 644 645 // Class for all pointer registers 646 reg_class ptr_reg %{ 647 return _PTR_REG_mask; 648 %} 649 650 // Class for all non_special pointer registers 651 reg_class no_special_ptr_reg %{ 652 return _NO_SPECIAL_PTR_REG_mask; 653 %} 654 655 // Class for all float registers 656 reg_class float_reg( 657 V0, 658 V1, 659 V2, 660 V3, 661 V4, 662 V5, 663 V6, 664 V7, 665 V8, 666 V9, 667 V10, 668 V11, 669 V12, 670 V13, 671 V14, 672 V15, 673 V16, 674 V17, 675 V18, 676 V19, 677 V20, 678 V21, 679 V22, 680 V23, 681 V24, 682 V25, 683 V26, 684 V27, 685 V28, 686 V29, 687 V30, 688 V31 689 ); 690 691 // Double precision float registers have virtual `high halves' that 692 // are needed by the allocator. 693 // Class for all double registers 694 reg_class double_reg( 695 V0, V0_H, 696 V1, V1_H, 697 V2, V2_H, 698 V3, V3_H, 699 V4, V4_H, 700 V5, V5_H, 701 V6, V6_H, 702 V7, V7_H, 703 V8, V8_H, 704 V9, V9_H, 705 V10, V10_H, 706 V11, V11_H, 707 V12, V12_H, 708 V13, V13_H, 709 V14, V14_H, 710 V15, V15_H, 711 V16, V16_H, 712 V17, V17_H, 713 V18, V18_H, 714 V19, V19_H, 715 V20, V20_H, 716 V21, V21_H, 717 V22, V22_H, 718 V23, V23_H, 719 V24, V24_H, 720 V25, V25_H, 721 V26, V26_H, 722 V27, V27_H, 723 V28, V28_H, 724 V29, V29_H, 725 V30, V30_H, 726 V31, V31_H 727 ); 728 729 // Class for all 64bit vector registers 730 reg_class vectord_reg( 731 V0, V0_H, 732 V1, V1_H, 733 V2, V2_H, 734 V3, V3_H, 735 V4, V4_H, 736 V5, V5_H, 737 V6, V6_H, 738 V7, V7_H, 739 V8, V8_H, 740 V9, V9_H, 741 V10, V10_H, 742 V11, V11_H, 743 V12, V12_H, 744 V13, V13_H, 745 V14, V14_H, 746 V15, V15_H, 747 V16, V16_H, 748 V17, V17_H, 749 V18, V18_H, 750 V19, V19_H, 751 V20, V20_H, 752 V21, V21_H, 753 V22, V22_H, 754 V23, V23_H, 755 V24, V24_H, 756 V25, V25_H, 757 V26, V26_H, 758 V27, V27_H, 759 V28, V28_H, 760 V29, V29_H, 761 V30, V30_H, 762 V31, V31_H 763 ); 764 765 // Class for all 128bit vector registers 766 reg_class vectorx_reg( 767 V0, V0_H, V0_J, V0_K, 768 V1, V1_H, V1_J, V1_K, 769 V2, V2_H, V2_J, V2_K, 770 V3, V3_H, V3_J, V3_K, 771 V4, V4_H, V4_J, V4_K, 772 V5, V5_H, V5_J, V5_K, 773 V6, V6_H, V6_J, V6_K, 774 V7, V7_H, V7_J, V7_K, 775 V8, V8_H, V8_J, V8_K, 776 V9, V9_H, V9_J, V9_K, 777 V10, V10_H, V10_J, V10_K, 778 V11, V11_H, V11_J, V11_K, 779 V12, V12_H, V12_J, V12_K, 780 V13, V13_H, V13_J, V13_K, 781 V14, V14_H, V14_J, V14_K, 782 V15, V15_H, V15_J, V15_K, 783 V16, V16_H, V16_J, V16_K, 784 V17, V17_H, V17_J, V17_K, 785 V18, V18_H, V18_J, V18_K, 786 V19, V19_H, V19_J, V19_K, 787 V20, V20_H, V20_J, V20_K, 788 V21, V21_H, V21_J, V21_K, 789 V22, V22_H, V22_J, V22_K, 790 V23, V23_H, V23_J, V23_K, 791 V24, V24_H, V24_J, V24_K, 792 V25, V25_H, V25_J, V25_K, 793 V26, V26_H, V26_J, V26_K, 794 V27, V27_H, V27_J, V27_K, 795 V28, V28_H, V28_J, V28_K, 796 V29, V29_H, V29_J, V29_K, 797 V30, V30_H, V30_J, V30_K, 798 V31, V31_H, V31_J, V31_K 799 ); 800 801 // Class for 128 bit register v0 802 reg_class v0_reg( 803 V0, V0_H 804 ); 805 806 // Class for 128 bit register v1 807 reg_class v1_reg( 808 V1, V1_H 809 ); 810 811 // Class for 128 bit register v2 812 reg_class v2_reg( 813 V2, V2_H 814 ); 815 816 // Class for 128 bit register v3 817 reg_class v3_reg( 818 V3, V3_H 819 ); 820 821 // Class for 128 bit register v4 822 reg_class v4_reg( 823 V4, V4_H 824 ); 825 826 // Class for 128 bit register v5 827 reg_class v5_reg( 828 V5, V5_H 829 ); 830 831 // Class for 128 bit register v6 832 reg_class v6_reg( 833 V6, V6_H 834 ); 835 836 // Class for 128 bit register v7 837 reg_class v7_reg( 838 V7, V7_H 839 ); 840 841 // Class for 128 bit register v8 842 reg_class v8_reg( 843 V8, V8_H 844 ); 845 846 // Class for 128 bit register v9 847 reg_class v9_reg( 848 V9, V9_H 849 ); 850 851 // Class for 128 bit register v10 852 reg_class v10_reg( 853 V10, V10_H 854 ); 855 856 // Class for 128 bit register v11 857 reg_class v11_reg( 858 V11, V11_H 859 ); 860 861 // Class for 128 bit register v12 862 reg_class v12_reg( 863 V12, V12_H 864 ); 865 866 // Class for 128 bit register v13 867 reg_class v13_reg( 868 V13, V13_H 869 ); 870 871 // Class for 128 bit register v14 872 reg_class v14_reg( 873 V14, V14_H 874 ); 875 876 // Class for 128 bit register v15 877 reg_class v15_reg( 878 V15, V15_H 879 ); 880 881 // Class for 128 bit register v16 882 reg_class v16_reg( 883 V16, V16_H 884 ); 885 886 // Class for 128 bit register v17 887 reg_class v17_reg( 888 V17, V17_H 889 ); 890 891 // Class for 128 bit register v18 892 reg_class v18_reg( 893 V18, V18_H 894 ); 895 896 // Class for 128 bit register v19 897 reg_class v19_reg( 898 V19, V19_H 899 ); 900 901 // Class for 128 bit register v20 902 reg_class v20_reg( 903 V20, V20_H 904 ); 905 906 // Class for 128 bit register v21 907 reg_class v21_reg( 908 V21, V21_H 909 ); 910 911 // Class for 128 bit register v22 912 reg_class v22_reg( 913 V22, V22_H 914 ); 915 916 // Class for 128 bit register v23 917 reg_class v23_reg( 918 V23, V23_H 919 ); 920 921 // Class for 128 bit register v24 922 reg_class v24_reg( 923 V24, V24_H 924 ); 925 926 // Class for 128 bit register v25 927 reg_class v25_reg( 928 V25, V25_H 929 ); 930 931 // Class for 128 bit register v26 932 reg_class v26_reg( 933 V26, V26_H 934 ); 935 936 // Class for 128 bit register v27 937 reg_class v27_reg( 938 V27, V27_H 939 ); 940 941 // Class for 128 bit register v28 942 reg_class v28_reg( 943 V28, V28_H 944 ); 945 946 // Class for 128 bit register v29 947 reg_class v29_reg( 948 V29, V29_H 949 ); 950 951 // Class for 128 bit register v30 952 reg_class v30_reg( 953 V30, V30_H 954 ); 955 956 // Class for 128 bit register v31 957 reg_class v31_reg( 958 V31, V31_H 959 ); 960 961 // Singleton class for condition codes 962 reg_class int_flags(RFLAGS); 963 964 %} 965 966 //----------DEFINITION BLOCK--------------------------------------------------- 967 // Define name --> value mappings to inform the ADLC of an integer valued name 968 // Current support includes integer values in the range [0, 0x7FFFFFFF] 969 // Format: 970 // int_def <name> ( <int_value>, <expression>); 971 // Generated Code in ad_<arch>.hpp 972 // #define <name> (<expression>) 973 // // value == <int_value> 974 // Generated code in ad_<arch>.cpp adlc_verification() 975 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 976 // 977 978 // we follow the ppc-aix port in using a simple cost model which ranks 979 // register operations as cheap, memory ops as more expensive and 980 // branches as most expensive. the first two have a low as well as a 981 // normal cost. huge cost appears to be a way of saying don't do 982 // something 983 984 definitions %{ 985 // The default cost (of a register move instruction). 986 int_def INSN_COST ( 100, 100); 987 int_def BRANCH_COST ( 200, 2 * INSN_COST); 988 int_def CALL_COST ( 200, 2 * INSN_COST); 989 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 990 %} 991 992 993 //----------SOURCE BLOCK------------------------------------------------------- 994 // This is a block of C++ code which provides values, functions, and 995 // definitions necessary in the rest of the architecture description 996 997 source_hpp %{ 998 999 #include "asm/macroAssembler.hpp" 1000 #include "gc/shared/cardTable.hpp" 1001 #include "gc/shared/cardTableBarrierSet.hpp" 1002 #include "gc/shared/collectedHeap.hpp" 1003 #include "gc/shared/barrierSet.hpp" 1004 #include "gc/shared/barrierSetAssembler.hpp" 1005 #include "opto/addnode.hpp" 1006 #include "opto/convertnode.hpp" 1007 1008 extern RegMask _ANY_REG32_mask; 1009 extern RegMask _ANY_REG_mask; 1010 extern RegMask _PTR_REG_mask; 1011 extern RegMask _NO_SPECIAL_REG32_mask; 1012 extern RegMask _NO_SPECIAL_REG_mask; 1013 extern RegMask _NO_SPECIAL_PTR_REG_mask; 1014 1015 class CallStubImpl { 1016 1017 //-------------------------------------------------------------- 1018 //---< Used for optimization in Compile::shorten_branches >--- 1019 //-------------------------------------------------------------- 1020 1021 public: 1022 // Size of call trampoline stub. 1023 static uint size_call_trampoline() { 1024 return 0; // no call trampolines on this platform 1025 } 1026 1027 // number of relocations needed by a call trampoline stub 1028 static uint reloc_call_trampoline() { 1029 return 0; // no call trampolines on this platform 1030 } 1031 }; 1032 1033 class HandlerImpl { 1034 1035 public: 1036 1037 static int emit_exception_handler(CodeBuffer &cbuf); 1038 static int emit_deopt_handler(CodeBuffer& cbuf); 1039 1040 static uint size_exception_handler() { 1041 return MacroAssembler::far_branch_size(); 1042 } 1043 1044 static uint size_deopt_handler() { 1045 // count one adr and one far branch instruction 1046 return 4 * NativeInstruction::instruction_size; 1047 } 1048 }; 1049 1050 class Node::PD { 1051 public: 1052 enum NodeFlags { 1053 _last_flag = Node::_last_flag 1054 }; 1055 }; 1056 1057 bool is_CAS(int opcode, bool maybe_volatile); 1058 1059 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1060 1061 bool unnecessary_acquire(const Node *barrier); 1062 bool needs_acquiring_load(const Node *load); 1063 1064 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1065 1066 bool unnecessary_release(const Node *barrier); 1067 bool unnecessary_volatile(const Node *barrier); 1068 bool needs_releasing_store(const Node *store); 1069 1070 // predicate controlling translation of CompareAndSwapX 1071 bool needs_acquiring_load_exclusive(const Node *load); 1072 1073 // predicate controlling addressing modes 1074 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1075 %} 1076 1077 source %{ 1078 1079 // Derived RegMask with conditionally allocatable registers 1080 1081 void PhaseOutput::pd_perform_mach_node_analysis() { 1082 } 1083 1084 int MachNode::pd_alignment_required() const { 1085 return 1; 1086 } 1087 1088 int MachNode::compute_padding(int current_offset) const { 1089 return 0; 1090 } 1091 1092 RegMask _ANY_REG32_mask; 1093 RegMask _ANY_REG_mask; 1094 RegMask _PTR_REG_mask; 1095 RegMask _NO_SPECIAL_REG32_mask; 1096 RegMask _NO_SPECIAL_REG_mask; 1097 RegMask _NO_SPECIAL_PTR_REG_mask; 1098 1099 void reg_mask_init() { 1100 // We derive below RegMask(s) from the ones which are auto-generated from 1101 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1102 // registers conditionally reserved. 1103 1104 _ANY_REG32_mask = _ALL_REG32_mask; 1105 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1106 1107 _ANY_REG_mask = _ALL_REG_mask; 1108 1109 _PTR_REG_mask = _ALL_REG_mask; 1110 1111 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1112 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1113 1114 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1115 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1116 1117 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1118 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1119 1120 // r27 is not allocatable when compressed oops is on and heapbase is not 1121 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1122 if (UseCompressedOops && CompressedOops::ptrs_base() != NULL) { 1123 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1124 _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1125 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1126 } 1127 1128 // r29 is not allocatable when PreserveFramePointer is on 1129 if (PreserveFramePointer) { 1130 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1131 _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); 1132 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); 1133 } 1134 } 1135 1136 // Optimizaton of volatile gets and puts 1137 // ------------------------------------- 1138 // 1139 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1140 // use to implement volatile reads and writes. For a volatile read 1141 // we simply need 1142 // 1143 // ldar<x> 1144 // 1145 // and for a volatile write we need 1146 // 1147 // stlr<x> 1148 // 1149 // Alternatively, we can implement them by pairing a normal 1150 // load/store with a memory barrier. For a volatile read we need 1151 // 1152 // ldr<x> 1153 // dmb ishld 1154 // 1155 // for a volatile write 1156 // 1157 // dmb ish 1158 // str<x> 1159 // dmb ish 1160 // 1161 // We can also use ldaxr and stlxr to implement compare and swap CAS 1162 // sequences. These are normally translated to an instruction 1163 // sequence like the following 1164 // 1165 // dmb ish 1166 // retry: 1167 // ldxr<x> rval raddr 1168 // cmp rval rold 1169 // b.ne done 1170 // stlxr<x> rval, rnew, rold 1171 // cbnz rval retry 1172 // done: 1173 // cset r0, eq 1174 // dmb ishld 1175 // 1176 // Note that the exclusive store is already using an stlxr 1177 // instruction. That is required to ensure visibility to other 1178 // threads of the exclusive write (assuming it succeeds) before that 1179 // of any subsequent writes. 1180 // 1181 // The following instruction sequence is an improvement on the above 1182 // 1183 // retry: 1184 // ldaxr<x> rval raddr 1185 // cmp rval rold 1186 // b.ne done 1187 // stlxr<x> rval, rnew, rold 1188 // cbnz rval retry 1189 // done: 1190 // cset r0, eq 1191 // 1192 // We don't need the leading dmb ish since the stlxr guarantees 1193 // visibility of prior writes in the case that the swap is 1194 // successful. Crucially we don't have to worry about the case where 1195 // the swap is not successful since no valid program should be 1196 // relying on visibility of prior changes by the attempting thread 1197 // in the case where the CAS fails. 1198 // 1199 // Similarly, we don't need the trailing dmb ishld if we substitute 1200 // an ldaxr instruction since that will provide all the guarantees we 1201 // require regarding observation of changes made by other threads 1202 // before any change to the CAS address observed by the load. 1203 // 1204 // In order to generate the desired instruction sequence we need to 1205 // be able to identify specific 'signature' ideal graph node 1206 // sequences which i) occur as a translation of a volatile reads or 1207 // writes or CAS operations and ii) do not occur through any other 1208 // translation or graph transformation. We can then provide 1209 // alternative aldc matching rules which translate these node 1210 // sequences to the desired machine code sequences. Selection of the 1211 // alternative rules can be implemented by predicates which identify 1212 // the relevant node sequences. 1213 // 1214 // The ideal graph generator translates a volatile read to the node 1215 // sequence 1216 // 1217 // LoadX[mo_acquire] 1218 // MemBarAcquire 1219 // 1220 // As a special case when using the compressed oops optimization we 1221 // may also see this variant 1222 // 1223 // LoadN[mo_acquire] 1224 // DecodeN 1225 // MemBarAcquire 1226 // 1227 // A volatile write is translated to the node sequence 1228 // 1229 // MemBarRelease 1230 // StoreX[mo_release] {CardMark}-optional 1231 // MemBarVolatile 1232 // 1233 // n.b. the above node patterns are generated with a strict 1234 // 'signature' configuration of input and output dependencies (see 1235 // the predicates below for exact details). The card mark may be as 1236 // simple as a few extra nodes or, in a few GC configurations, may 1237 // include more complex control flow between the leading and 1238 // trailing memory barriers. However, whatever the card mark 1239 // configuration these signatures are unique to translated volatile 1240 // reads/stores -- they will not appear as a result of any other 1241 // bytecode translation or inlining nor as a consequence of 1242 // optimizing transforms. 1243 // 1244 // We also want to catch inlined unsafe volatile gets and puts and 1245 // be able to implement them using either ldar<x>/stlr<x> or some 1246 // combination of ldr<x>/stlr<x> and dmb instructions. 1247 // 1248 // Inlined unsafe volatiles puts manifest as a minor variant of the 1249 // normal volatile put node sequence containing an extra cpuorder 1250 // membar 1251 // 1252 // MemBarRelease 1253 // MemBarCPUOrder 1254 // StoreX[mo_release] {CardMark}-optional 1255 // MemBarCPUOrder 1256 // MemBarVolatile 1257 // 1258 // n.b. as an aside, a cpuorder membar is not itself subject to 1259 // matching and translation by adlc rules. However, the rule 1260 // predicates need to detect its presence in order to correctly 1261 // select the desired adlc rules. 1262 // 1263 // Inlined unsafe volatile gets manifest as a slightly different 1264 // node sequence to a normal volatile get because of the 1265 // introduction of some CPUOrder memory barriers to bracket the 1266 // Load. However, but the same basic skeleton of a LoadX feeding a 1267 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1268 // present 1269 // 1270 // MemBarCPUOrder 1271 // || \\ 1272 // MemBarCPUOrder LoadX[mo_acquire] 1273 // || | 1274 // || {DecodeN} optional 1275 // || / 1276 // MemBarAcquire 1277 // 1278 // In this case the acquire membar does not directly depend on the 1279 // load. However, we can be sure that the load is generated from an 1280 // inlined unsafe volatile get if we see it dependent on this unique 1281 // sequence of membar nodes. Similarly, given an acquire membar we 1282 // can know that it was added because of an inlined unsafe volatile 1283 // get if it is fed and feeds a cpuorder membar and if its feed 1284 // membar also feeds an acquiring load. 1285 // 1286 // Finally an inlined (Unsafe) CAS operation is translated to the 1287 // following ideal graph 1288 // 1289 // MemBarRelease 1290 // MemBarCPUOrder 1291 // CompareAndSwapX {CardMark}-optional 1292 // MemBarCPUOrder 1293 // MemBarAcquire 1294 // 1295 // So, where we can identify these volatile read and write 1296 // signatures we can choose to plant either of the above two code 1297 // sequences. For a volatile read we can simply plant a normal 1298 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1299 // also choose to inhibit translation of the MemBarAcquire and 1300 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1301 // 1302 // When we recognise a volatile store signature we can choose to 1303 // plant at a dmb ish as a translation for the MemBarRelease, a 1304 // normal str<x> and then a dmb ish for the MemBarVolatile. 1305 // Alternatively, we can inhibit translation of the MemBarRelease 1306 // and MemBarVolatile and instead plant a simple stlr<x> 1307 // instruction. 1308 // 1309 // when we recognise a CAS signature we can choose to plant a dmb 1310 // ish as a translation for the MemBarRelease, the conventional 1311 // macro-instruction sequence for the CompareAndSwap node (which 1312 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1313 // Alternatively, we can elide generation of the dmb instructions 1314 // and plant the alternative CompareAndSwap macro-instruction 1315 // sequence (which uses ldaxr<x>). 1316 // 1317 // Of course, the above only applies when we see these signature 1318 // configurations. We still want to plant dmb instructions in any 1319 // other cases where we may see a MemBarAcquire, MemBarRelease or 1320 // MemBarVolatile. For example, at the end of a constructor which 1321 // writes final/volatile fields we will see a MemBarRelease 1322 // instruction and this needs a 'dmb ish' lest we risk the 1323 // constructed object being visible without making the 1324 // final/volatile field writes visible. 1325 // 1326 // n.b. the translation rules below which rely on detection of the 1327 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1328 // If we see anything other than the signature configurations we 1329 // always just translate the loads and stores to ldr<x> and str<x> 1330 // and translate acquire, release and volatile membars to the 1331 // relevant dmb instructions. 1332 // 1333 1334 // is_CAS(int opcode, bool maybe_volatile) 1335 // 1336 // return true if opcode is one of the possible CompareAndSwapX 1337 // values otherwise false. 1338 1339 bool is_CAS(int opcode, bool maybe_volatile) 1340 { 1341 switch(opcode) { 1342 // We handle these 1343 case Op_CompareAndSwapI: 1344 case Op_CompareAndSwapL: 1345 case Op_CompareAndSwapP: 1346 case Op_CompareAndSwapN: 1347 case Op_ShenandoahCompareAndSwapP: 1348 case Op_ShenandoahCompareAndSwapN: 1349 case Op_CompareAndSwapB: 1350 case Op_CompareAndSwapS: 1351 case Op_GetAndSetI: 1352 case Op_GetAndSetL: 1353 case Op_GetAndSetP: 1354 case Op_GetAndSetN: 1355 case Op_GetAndAddI: 1356 case Op_GetAndAddL: 1357 return true; 1358 case Op_CompareAndExchangeI: 1359 case Op_CompareAndExchangeN: 1360 case Op_CompareAndExchangeB: 1361 case Op_CompareAndExchangeS: 1362 case Op_CompareAndExchangeL: 1363 case Op_CompareAndExchangeP: 1364 case Op_WeakCompareAndSwapB: 1365 case Op_WeakCompareAndSwapS: 1366 case Op_WeakCompareAndSwapI: 1367 case Op_WeakCompareAndSwapL: 1368 case Op_WeakCompareAndSwapP: 1369 case Op_WeakCompareAndSwapN: 1370 case Op_ShenandoahWeakCompareAndSwapP: 1371 case Op_ShenandoahWeakCompareAndSwapN: 1372 case Op_ShenandoahCompareAndExchangeP: 1373 case Op_ShenandoahCompareAndExchangeN: 1374 return maybe_volatile; 1375 default: 1376 return false; 1377 } 1378 } 1379 1380 // helper to determine the maximum number of Phi nodes we may need to 1381 // traverse when searching from a card mark membar for the merge mem 1382 // feeding a trailing membar or vice versa 1383 1384 // predicates controlling emit of ldr<x>/ldar<x> 1385 1386 bool unnecessary_acquire(const Node *barrier) 1387 { 1388 assert(barrier->is_MemBar(), "expecting a membar"); 1389 1390 MemBarNode* mb = barrier->as_MemBar(); 1391 1392 if (mb->trailing_load()) { 1393 return true; 1394 } 1395 1396 if (mb->trailing_load_store()) { 1397 Node* load_store = mb->in(MemBarNode::Precedent); 1398 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1399 return is_CAS(load_store->Opcode(), true); 1400 } 1401 1402 return false; 1403 } 1404 1405 bool needs_acquiring_load(const Node *n) 1406 { 1407 assert(n->is_Load(), "expecting a load"); 1408 LoadNode *ld = n->as_Load(); 1409 return ld->is_acquire(); 1410 } 1411 1412 bool unnecessary_release(const Node *n) 1413 { 1414 assert((n->is_MemBar() && 1415 n->Opcode() == Op_MemBarRelease), 1416 "expecting a release membar"); 1417 1418 MemBarNode *barrier = n->as_MemBar(); 1419 if (!barrier->leading()) { 1420 return false; 1421 } else { 1422 Node* trailing = barrier->trailing_membar(); 1423 MemBarNode* trailing_mb = trailing->as_MemBar(); 1424 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1425 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1426 1427 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1428 if (mem->is_Store()) { 1429 assert(mem->as_Store()->is_release(), ""); 1430 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1431 return true; 1432 } else { 1433 assert(mem->is_LoadStore(), ""); 1434 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1435 return is_CAS(mem->Opcode(), true); 1436 } 1437 } 1438 return false; 1439 } 1440 1441 bool unnecessary_volatile(const Node *n) 1442 { 1443 // assert n->is_MemBar(); 1444 MemBarNode *mbvol = n->as_MemBar(); 1445 1446 bool release = mbvol->trailing_store(); 1447 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1448 #ifdef ASSERT 1449 if (release) { 1450 Node* leading = mbvol->leading_membar(); 1451 assert(leading->Opcode() == Op_MemBarRelease, ""); 1452 assert(leading->as_MemBar()->leading_store(), ""); 1453 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1454 } 1455 #endif 1456 1457 return release; 1458 } 1459 1460 // predicates controlling emit of str<x>/stlr<x> 1461 1462 bool needs_releasing_store(const Node *n) 1463 { 1464 // assert n->is_Store(); 1465 StoreNode *st = n->as_Store(); 1466 return st->trailing_membar() != NULL; 1467 } 1468 1469 // predicate controlling translation of CAS 1470 // 1471 // returns true if CAS needs to use an acquiring load otherwise false 1472 1473 bool needs_acquiring_load_exclusive(const Node *n) 1474 { 1475 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1476 LoadStoreNode* ldst = n->as_LoadStore(); 1477 if (is_CAS(n->Opcode(), false)) { 1478 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1479 } else { 1480 return ldst->trailing_membar() != NULL; 1481 } 1482 1483 // so we can just return true here 1484 return true; 1485 } 1486 1487 #define __ _masm. 1488 1489 // advance declarations for helper functions to convert register 1490 // indices to register objects 1491 1492 // the ad file has to provide implementations of certain methods 1493 // expected by the generic code 1494 // 1495 // REQUIRED FUNCTIONALITY 1496 1497 //============================================================================= 1498 1499 // !!!!! Special hack to get all types of calls to specify the byte offset 1500 // from the start of the call to the point where the return address 1501 // will point. 1502 1503 int MachCallStaticJavaNode::ret_addr_offset() 1504 { 1505 // call should be a simple bl 1506 int off = 4; 1507 return off; 1508 } 1509 1510 int MachCallDynamicJavaNode::ret_addr_offset() 1511 { 1512 return 16; // movz, movk, movk, bl 1513 } 1514 1515 int MachCallRuntimeNode::ret_addr_offset() { 1516 // for generated stubs the call will be 1517 // far_call(addr) 1518 // for real runtime callouts it will be six instructions 1519 // see aarch64_enc_java_to_runtime 1520 // adr(rscratch2, retaddr) 1521 // lea(rscratch1, RuntimeAddress(addr) 1522 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1523 // blr(rscratch1) 1524 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1525 if (cb) { 1526 return MacroAssembler::far_branch_size(); 1527 } else { 1528 return 6 * NativeInstruction::instruction_size; 1529 } 1530 } 1531 1532 // Indicate if the safepoint node needs the polling page as an input 1533 1534 // the shared code plants the oop data at the start of the generated 1535 // code for the safepoint node and that needs ot be at the load 1536 // instruction itself. so we cannot plant a mov of the safepoint poll 1537 // address followed by a load. setting this to true means the mov is 1538 // scheduled as a prior instruction. that's better for scheduling 1539 // anyway. 1540 1541 bool SafePointNode::needs_polling_address_input() 1542 { 1543 return true; 1544 } 1545 1546 //============================================================================= 1547 1548 #ifndef PRODUCT 1549 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1550 st->print("BREAKPOINT"); 1551 } 1552 #endif 1553 1554 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1555 C2_MacroAssembler _masm(&cbuf); 1556 __ brk(0); 1557 } 1558 1559 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1560 return MachNode::size(ra_); 1561 } 1562 1563 //============================================================================= 1564 1565 #ifndef PRODUCT 1566 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1567 st->print("nop \t# %d bytes pad for loops and calls", _count); 1568 } 1569 #endif 1570 1571 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1572 C2_MacroAssembler _masm(&cbuf); 1573 for (int i = 0; i < _count; i++) { 1574 __ nop(); 1575 } 1576 } 1577 1578 uint MachNopNode::size(PhaseRegAlloc*) const { 1579 return _count * NativeInstruction::instruction_size; 1580 } 1581 1582 //============================================================================= 1583 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1584 1585 int ConstantTable::calculate_table_base_offset() const { 1586 return 0; // absolute addressing, no offset 1587 } 1588 1589 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1590 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1591 ShouldNotReachHere(); 1592 } 1593 1594 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1595 // Empty encoding 1596 } 1597 1598 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1599 return 0; 1600 } 1601 1602 #ifndef PRODUCT 1603 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1604 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1605 } 1606 #endif 1607 1608 #ifndef PRODUCT 1609 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1610 Compile* C = ra_->C; 1611 1612 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1613 1614 if (C->output()->need_stack_bang(framesize)) 1615 st->print("# stack bang size=%d\n\t", framesize); 1616 1617 if (framesize < ((1 << 9) + 2 * wordSize)) { 1618 st->print("sub sp, sp, #%d\n\t", framesize); 1619 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1620 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1621 } else { 1622 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1623 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1624 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1625 st->print("sub sp, sp, rscratch1"); 1626 } 1627 if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1628 st->print("\n\t"); 1629 st->print("ldr rscratch1, [guard]\n\t"); 1630 st->print("dmb ishld\n\t"); 1631 st->print("ldr rscratch2, [rthread, #thread_disarmed_offset]\n\t"); 1632 st->print("cmp rscratch1, rscratch2\n\t"); 1633 st->print("b.eq skip"); 1634 st->print("\n\t"); 1635 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1636 st->print("b skip\n\t"); 1637 st->print("guard: int\n\t"); 1638 st->print("\n\t"); 1639 st->print("skip:\n\t"); 1640 } 1641 } 1642 #endif 1643 1644 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1645 Compile* C = ra_->C; 1646 C2_MacroAssembler _masm(&cbuf); 1647 1648 // n.b. frame size includes space for return pc and rfp 1649 const int64_t framesize = C->output()->frame_size_in_bytes(); 1650 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1651 1652 // insert a nop at the start of the prolog so we can patch in a 1653 // branch if we need to invalidate the method later 1654 __ nop(); 1655 1656 if (C->clinit_barrier_on_entry()) { 1657 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1658 1659 Label L_skip_barrier; 1660 1661 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1662 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1663 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1664 __ bind(L_skip_barrier); 1665 } 1666 1667 int bangsize = C->output()->bang_size_in_bytes(); 1668 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) 1669 __ generate_stack_overflow_check(bangsize); 1670 1671 __ build_frame(framesize); 1672 1673 if (C->stub_function() == NULL) { 1674 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1675 bs->nmethod_entry_barrier(&_masm); 1676 } 1677 1678 if (VerifyStackAtCalls) { 1679 Unimplemented(); 1680 } 1681 1682 C->output()->set_frame_complete(cbuf.insts_size()); 1683 1684 if (C->has_mach_constant_base_node()) { 1685 // NOTE: We set the table base offset here because users might be 1686 // emitted before MachConstantBaseNode. 1687 ConstantTable& constant_table = C->output()->constant_table(); 1688 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1689 } 1690 } 1691 1692 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1693 { 1694 return MachNode::size(ra_); // too many variables; just compute it 1695 // the hard way 1696 } 1697 1698 int MachPrologNode::reloc() const 1699 { 1700 return 0; 1701 } 1702 1703 //============================================================================= 1704 1705 #ifndef PRODUCT 1706 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1709 1710 st->print("# pop frame %d\n\t",framesize); 1711 1712 if (framesize == 0) { 1713 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1714 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1715 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1716 st->print("add sp, sp, #%d\n\t", framesize); 1717 } else { 1718 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1719 st->print("add sp, sp, rscratch1\n\t"); 1720 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1721 } 1722 1723 if (do_polling() && C->is_method_compilation()) { 1724 st->print("# touch polling page\n\t"); 1725 st->print("ldr rscratch1, [rthread],#polling_page_offset\n\t"); 1726 st->print("ldr zr, [rscratch1]"); 1727 } 1728 } 1729 #endif 1730 1731 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1732 Compile* C = ra_->C; 1733 C2_MacroAssembler _masm(&cbuf); 1734 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1735 1736 __ remove_frame(framesize); 1737 1738 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1739 __ reserved_stack_check(); 1740 } 1741 1742 if (do_polling() && C->is_method_compilation()) { 1743 __ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type); 1744 } 1745 } 1746 1747 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1748 // Variable size. Determine dynamically. 1749 return MachNode::size(ra_); 1750 } 1751 1752 int MachEpilogNode::reloc() const { 1753 // Return number of relocatable values contained in this instruction. 1754 return 1; // 1 for polling page. 1755 } 1756 1757 const Pipeline * MachEpilogNode::pipeline() const { 1758 return MachNode::pipeline_class(); 1759 } 1760 1761 //============================================================================= 1762 1763 // Figure out which register class each belongs in: rc_int, rc_float or 1764 // rc_stack. 1765 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1766 1767 static enum RC rc_class(OptoReg::Name reg) { 1768 1769 if (reg == OptoReg::Bad) { 1770 return rc_bad; 1771 } 1772 1773 // we have 30 int registers * 2 halves 1774 // (rscratch1 and rscratch2 are omitted) 1775 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1776 1777 if (reg < slots_of_int_registers) { 1778 return rc_int; 1779 } 1780 1781 // we have 32 float register * 4 halves 1782 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1783 return rc_float; 1784 } 1785 1786 // Between float regs & stack is the flags regs. 1787 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1788 1789 return rc_stack; 1790 } 1791 1792 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1793 Compile* C = ra_->C; 1794 1795 // Get registers to move. 1796 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1797 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1798 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1799 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1800 1801 enum RC src_hi_rc = rc_class(src_hi); 1802 enum RC src_lo_rc = rc_class(src_lo); 1803 enum RC dst_hi_rc = rc_class(dst_hi); 1804 enum RC dst_lo_rc = rc_class(dst_lo); 1805 1806 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1807 1808 if (src_hi != OptoReg::Bad) { 1809 assert((src_lo&1)==0 && src_lo+1==src_hi && 1810 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1811 "expected aligned-adjacent pairs"); 1812 } 1813 1814 if (src_lo == dst_lo && src_hi == dst_hi) { 1815 return 0; // Self copy, no move. 1816 } 1817 1818 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1819 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1820 int src_offset = ra_->reg2offset(src_lo); 1821 int dst_offset = ra_->reg2offset(dst_lo); 1822 1823 if (bottom_type()->isa_vect() != NULL) { 1824 uint ireg = ideal_reg(); 1825 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1826 if (cbuf) { 1827 C2_MacroAssembler _masm(cbuf); 1828 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1829 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1830 // stack->stack 1831 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1832 if (ireg == Op_VecD) { 1833 __ unspill(rscratch1, true, src_offset); 1834 __ spill(rscratch1, true, dst_offset); 1835 } else { 1836 __ spill_copy128(src_offset, dst_offset); 1837 } 1838 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1839 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1840 ireg == Op_VecD ? __ T8B : __ T16B, 1841 as_FloatRegister(Matcher::_regEncode[src_lo])); 1842 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1843 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1844 ireg == Op_VecD ? __ D : __ Q, 1845 ra_->reg2offset(dst_lo)); 1846 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1847 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1848 ireg == Op_VecD ? __ D : __ Q, 1849 ra_->reg2offset(src_lo)); 1850 } else { 1851 ShouldNotReachHere(); 1852 } 1853 } 1854 } else if (cbuf) { 1855 C2_MacroAssembler _masm(cbuf); 1856 switch (src_lo_rc) { 1857 case rc_int: 1858 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1859 if (is64) { 1860 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1861 as_Register(Matcher::_regEncode[src_lo])); 1862 } else { 1863 C2_MacroAssembler _masm(cbuf); 1864 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1865 as_Register(Matcher::_regEncode[src_lo])); 1866 } 1867 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1868 if (is64) { 1869 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1870 as_Register(Matcher::_regEncode[src_lo])); 1871 } else { 1872 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1873 as_Register(Matcher::_regEncode[src_lo])); 1874 } 1875 } else { // gpr --> stack spill 1876 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1877 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1878 } 1879 break; 1880 case rc_float: 1881 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1882 if (is64) { 1883 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1884 as_FloatRegister(Matcher::_regEncode[src_lo])); 1885 } else { 1886 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1887 as_FloatRegister(Matcher::_regEncode[src_lo])); 1888 } 1889 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1890 if (cbuf) { 1891 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1892 as_FloatRegister(Matcher::_regEncode[src_lo])); 1893 } else { 1894 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1895 as_FloatRegister(Matcher::_regEncode[src_lo])); 1896 } 1897 } else { // fpr --> stack spill 1898 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1899 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1900 is64 ? __ D : __ S, dst_offset); 1901 } 1902 break; 1903 case rc_stack: 1904 if (dst_lo_rc == rc_int) { // stack --> gpr load 1905 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1906 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1907 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1908 is64 ? __ D : __ S, src_offset); 1909 } else { // stack --> stack copy 1910 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1911 __ unspill(rscratch1, is64, src_offset); 1912 __ spill(rscratch1, is64, dst_offset); 1913 } 1914 break; 1915 default: 1916 assert(false, "bad rc_class for spill"); 1917 ShouldNotReachHere(); 1918 } 1919 } 1920 1921 if (st) { 1922 st->print("spill "); 1923 if (src_lo_rc == rc_stack) { 1924 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1925 } else { 1926 st->print("%s -> ", Matcher::regName[src_lo]); 1927 } 1928 if (dst_lo_rc == rc_stack) { 1929 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1930 } else { 1931 st->print("%s", Matcher::regName[dst_lo]); 1932 } 1933 if (bottom_type()->isa_vect() != NULL) { 1934 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1935 } else { 1936 st->print("\t# spill size = %d", is64 ? 64:32); 1937 } 1938 } 1939 1940 return 0; 1941 1942 } 1943 1944 #ifndef PRODUCT 1945 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1946 if (!ra_) 1947 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1948 else 1949 implementation(NULL, ra_, false, st); 1950 } 1951 #endif 1952 1953 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1954 implementation(&cbuf, ra_, false, NULL); 1955 } 1956 1957 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1958 return MachNode::size(ra_); 1959 } 1960 1961 //============================================================================= 1962 1963 #ifndef PRODUCT 1964 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1965 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1966 int reg = ra_->get_reg_first(this); 1967 st->print("add %s, rsp, #%d]\t# box lock", 1968 Matcher::regName[reg], offset); 1969 } 1970 #endif 1971 1972 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1973 C2_MacroAssembler _masm(&cbuf); 1974 1975 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1976 int reg = ra_->get_encode(this); 1977 1978 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1979 __ add(as_Register(reg), sp, offset); 1980 } else { 1981 ShouldNotReachHere(); 1982 } 1983 } 1984 1985 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1986 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1987 return 4; 1988 } 1989 1990 //============================================================================= 1991 1992 #ifndef PRODUCT 1993 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1994 { 1995 st->print_cr("# MachUEPNode"); 1996 if (UseCompressedClassPointers) { 1997 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1998 if (CompressedKlassPointers::shift() != 0) { 1999 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2000 } 2001 } else { 2002 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2003 } 2004 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2005 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2006 } 2007 #endif 2008 2009 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2010 { 2011 // This is the unverified entry point. 2012 C2_MacroAssembler _masm(&cbuf); 2013 2014 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2015 Label skip; 2016 // TODO 2017 // can we avoid this skip and still use a reloc? 2018 __ br(Assembler::EQ, skip); 2019 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2020 __ bind(skip); 2021 } 2022 2023 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2024 { 2025 return MachNode::size(ra_); 2026 } 2027 2028 // REQUIRED EMIT CODE 2029 2030 //============================================================================= 2031 2032 // Emit exception handler code. 2033 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2034 { 2035 // mov rscratch1 #exception_blob_entry_point 2036 // br rscratch1 2037 // Note that the code buffer's insts_mark is always relative to insts. 2038 // That's why we must use the macroassembler to generate a handler. 2039 C2_MacroAssembler _masm(&cbuf); 2040 address base = __ start_a_stub(size_exception_handler()); 2041 if (base == NULL) { 2042 ciEnv::current()->record_failure("CodeCache is full"); 2043 return 0; // CodeBuffer::expand failed 2044 } 2045 int offset = __ offset(); 2046 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2047 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2048 __ end_a_stub(); 2049 return offset; 2050 } 2051 2052 // Emit deopt handler code. 2053 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2054 { 2055 // Note that the code buffer's insts_mark is always relative to insts. 2056 // That's why we must use the macroassembler to generate a handler. 2057 C2_MacroAssembler _masm(&cbuf); 2058 address base = __ start_a_stub(size_deopt_handler()); 2059 if (base == NULL) { 2060 ciEnv::current()->record_failure("CodeCache is full"); 2061 return 0; // CodeBuffer::expand failed 2062 } 2063 int offset = __ offset(); 2064 2065 __ adr(lr, __ pc()); 2066 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2067 2068 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2069 __ end_a_stub(); 2070 return offset; 2071 } 2072 2073 // REQUIRED MATCHER CODE 2074 2075 //============================================================================= 2076 2077 const bool Matcher::match_rule_supported(int opcode) { 2078 if (!has_match_rule(opcode)) 2079 return false; 2080 2081 bool ret_value = true; 2082 switch (opcode) { 2083 case Op_CacheWB: 2084 case Op_CacheWBPreSync: 2085 case Op_CacheWBPostSync: 2086 if (!VM_Version::supports_data_cache_line_flush()) { 2087 ret_value = false; 2088 } 2089 break; 2090 } 2091 2092 return ret_value; // Per default match rules are supported. 2093 } 2094 2095 // Identify extra cases that we might want to provide match rules for vector nodes and 2096 // other intrinsics guarded with vector length (vlen) and element type (bt). 2097 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2098 if (!match_rule_supported(opcode)) { 2099 return false; 2100 } 2101 2102 // Special cases which require vector length 2103 switch (opcode) { 2104 case Op_MulAddVS2VI: { 2105 if (vlen != 4) { 2106 return false; 2107 } 2108 break; 2109 } 2110 } 2111 2112 return true; // Per default match rules are supported. 2113 } 2114 2115 const bool Matcher::has_predicated_vectors(void) { 2116 return false; 2117 } 2118 2119 const int Matcher::float_pressure(int default_pressure_threshold) { 2120 return default_pressure_threshold; 2121 } 2122 2123 int Matcher::regnum_to_fpu_offset(int regnum) 2124 { 2125 Unimplemented(); 2126 return 0; 2127 } 2128 2129 // Is this branch offset short enough that a short branch can be used? 2130 // 2131 // NOTE: If the platform does not provide any short branch variants, then 2132 // this method should return false for offset 0. 2133 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2134 // The passed offset is relative to address of the branch. 2135 2136 return (-32768 <= offset && offset < 32768); 2137 } 2138 2139 const bool Matcher::isSimpleConstant64(jlong value) { 2140 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2141 // Probably always true, even if a temp register is required. 2142 return true; 2143 } 2144 2145 // true just means we have fast l2f conversion 2146 const bool Matcher::convL2FSupported(void) { 2147 return true; 2148 } 2149 2150 // Vector width in bytes. 2151 const int Matcher::vector_width_in_bytes(BasicType bt) { 2152 int size = MIN2(16,(int)MaxVectorSize); 2153 // Minimum 2 values in vector 2154 if (size < 2*type2aelembytes(bt)) size = 0; 2155 // But never < 4 2156 if (size < 4) size = 0; 2157 return size; 2158 } 2159 2160 // Limits on vector size (number of elements) loaded into vector. 2161 const int Matcher::max_vector_size(const BasicType bt) { 2162 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2163 } 2164 const int Matcher::min_vector_size(const BasicType bt) { 2165 // For the moment limit the vector size to 8 bytes 2166 int size = 8 / type2aelembytes(bt); 2167 if (size < 2) size = 2; 2168 return size; 2169 } 2170 2171 // Vector ideal reg. 2172 const uint Matcher::vector_ideal_reg(int len) { 2173 switch(len) { 2174 case 8: return Op_VecD; 2175 case 16: return Op_VecX; 2176 } 2177 ShouldNotReachHere(); 2178 return 0; 2179 } 2180 2181 // AES support not yet implemented 2182 const bool Matcher::pass_original_key_for_aes() { 2183 return false; 2184 } 2185 2186 // aarch64 supports misaligned vectors store/load. 2187 const bool Matcher::misaligned_vectors_ok() { 2188 return true; 2189 } 2190 2191 // false => size gets scaled to BytesPerLong, ok. 2192 const bool Matcher::init_array_count_is_in_bytes = false; 2193 2194 // Use conditional move (CMOVL) 2195 const int Matcher::long_cmove_cost() { 2196 // long cmoves are no more expensive than int cmoves 2197 return 0; 2198 } 2199 2200 const int Matcher::float_cmove_cost() { 2201 // float cmoves are no more expensive than int cmoves 2202 return 0; 2203 } 2204 2205 // Does the CPU require late expand (see block.cpp for description of late expand)? 2206 const bool Matcher::require_postalloc_expand = false; 2207 2208 // Do we need to mask the count passed to shift instructions or does 2209 // the cpu only look at the lower 5/6 bits anyway? 2210 const bool Matcher::need_masked_shift_count = false; 2211 2212 // No support for generic vector operands. 2213 const bool Matcher::supports_generic_vector_operands = false; 2214 2215 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2216 ShouldNotReachHere(); // generic vector operands not supported 2217 return NULL; 2218 } 2219 2220 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2221 ShouldNotReachHere(); // generic vector operands not supported 2222 return false; 2223 } 2224 2225 bool Matcher::is_generic_vector(MachOper* opnd) { 2226 ShouldNotReachHere(); // generic vector operands not supported 2227 return false; 2228 } 2229 2230 // This affects two different things: 2231 // - how Decode nodes are matched 2232 // - how ImplicitNullCheck opportunities are recognized 2233 // If true, the matcher will try to remove all Decodes and match them 2234 // (as operands) into nodes. NullChecks are not prepared to deal with 2235 // Decodes by final_graph_reshaping(). 2236 // If false, final_graph_reshaping() forces the decode behind the Cmp 2237 // for a NullCheck. The matcher matches the Decode node into a register. 2238 // Implicit_null_check optimization moves the Decode along with the 2239 // memory operation back up before the NullCheck. 2240 bool Matcher::narrow_oop_use_complex_address() { 2241 return CompressedOops::shift() == 0; 2242 } 2243 2244 bool Matcher::narrow_klass_use_complex_address() { 2245 // TODO 2246 // decide whether we need to set this to true 2247 return false; 2248 } 2249 2250 bool Matcher::const_oop_prefer_decode() { 2251 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2252 return CompressedOops::base() == NULL; 2253 } 2254 2255 bool Matcher::const_klass_prefer_decode() { 2256 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2257 return CompressedKlassPointers::base() == NULL; 2258 } 2259 2260 // Is it better to copy float constants, or load them directly from 2261 // memory? Intel can load a float constant from a direct address, 2262 // requiring no extra registers. Most RISCs will have to materialize 2263 // an address into a register first, so they would do better to copy 2264 // the constant from stack. 2265 const bool Matcher::rematerialize_float_constants = false; 2266 2267 // If CPU can load and store mis-aligned doubles directly then no 2268 // fixup is needed. Else we split the double into 2 integer pieces 2269 // and move it piece-by-piece. Only happens when passing doubles into 2270 // C code as the Java calling convention forces doubles to be aligned. 2271 const bool Matcher::misaligned_doubles_ok = true; 2272 2273 // No-op on amd64 2274 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2275 Unimplemented(); 2276 } 2277 2278 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2279 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2280 2281 // Are floats converted to double when stored to stack during 2282 // deoptimization? 2283 bool Matcher::float_in_double() { return false; } 2284 2285 // Do ints take an entire long register or just half? 2286 // The relevant question is how the int is callee-saved: 2287 // the whole long is written but de-opt'ing will have to extract 2288 // the relevant 32 bits. 2289 const bool Matcher::int_in_long = true; 2290 2291 // Return whether or not this register is ever used as an argument. 2292 // This function is used on startup to build the trampoline stubs in 2293 // generateOptoStub. Registers not mentioned will be killed by the VM 2294 // call in the trampoline, and arguments in those registers not be 2295 // available to the callee. 2296 bool Matcher::can_be_java_arg(int reg) 2297 { 2298 return 2299 reg == R0_num || reg == R0_H_num || 2300 reg == R1_num || reg == R1_H_num || 2301 reg == R2_num || reg == R2_H_num || 2302 reg == R3_num || reg == R3_H_num || 2303 reg == R4_num || reg == R4_H_num || 2304 reg == R5_num || reg == R5_H_num || 2305 reg == R6_num || reg == R6_H_num || 2306 reg == R7_num || reg == R7_H_num || 2307 reg == V0_num || reg == V0_H_num || 2308 reg == V1_num || reg == V1_H_num || 2309 reg == V2_num || reg == V2_H_num || 2310 reg == V3_num || reg == V3_H_num || 2311 reg == V4_num || reg == V4_H_num || 2312 reg == V5_num || reg == V5_H_num || 2313 reg == V6_num || reg == V6_H_num || 2314 reg == V7_num || reg == V7_H_num; 2315 } 2316 2317 bool Matcher::is_spillable_arg(int reg) 2318 { 2319 return can_be_java_arg(reg); 2320 } 2321 2322 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2323 return false; 2324 } 2325 2326 RegMask Matcher::divI_proj_mask() { 2327 ShouldNotReachHere(); 2328 return RegMask(); 2329 } 2330 2331 // Register for MODI projection of divmodI. 2332 RegMask Matcher::modI_proj_mask() { 2333 ShouldNotReachHere(); 2334 return RegMask(); 2335 } 2336 2337 // Register for DIVL projection of divmodL. 2338 RegMask Matcher::divL_proj_mask() { 2339 ShouldNotReachHere(); 2340 return RegMask(); 2341 } 2342 2343 // Register for MODL projection of divmodL. 2344 RegMask Matcher::modL_proj_mask() { 2345 ShouldNotReachHere(); 2346 return RegMask(); 2347 } 2348 2349 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2350 return FP_REG_mask(); 2351 } 2352 2353 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2354 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2355 Node* u = addp->fast_out(i); 2356 if (u->is_Mem()) { 2357 int opsize = u->as_Mem()->memory_size(); 2358 assert(opsize > 0, "unexpected memory operand size"); 2359 if (u->as_Mem()->memory_size() != (1<<shift)) { 2360 return false; 2361 } 2362 } 2363 } 2364 return true; 2365 } 2366 2367 const bool Matcher::convi2l_type_required = false; 2368 2369 // Should the matcher clone input 'm' of node 'n'? 2370 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2371 if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) 2372 mstack.push(m, Visit); // m = ShiftCntV 2373 return true; 2374 } 2375 return false; 2376 } 2377 2378 // Should the Matcher clone shifts on addressing modes, expecting them 2379 // to be subsumed into complex addressing expressions or compute them 2380 // into registers? 2381 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2382 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2383 return true; 2384 } 2385 2386 Node *off = m->in(AddPNode::Offset); 2387 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2388 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2389 // Are there other uses besides address expressions? 2390 !is_visited(off)) { 2391 address_visited.set(off->_idx); // Flag as address_visited 2392 mstack.push(off->in(2), Visit); 2393 Node *conv = off->in(1); 2394 if (conv->Opcode() == Op_ConvI2L && 2395 // Are there other uses besides address expressions? 2396 !is_visited(conv)) { 2397 address_visited.set(conv->_idx); // Flag as address_visited 2398 mstack.push(conv->in(1), Pre_Visit); 2399 } else { 2400 mstack.push(conv, Pre_Visit); 2401 } 2402 address_visited.test_set(m->_idx); // Flag as address_visited 2403 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2404 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2405 return true; 2406 } else if (off->Opcode() == Op_ConvI2L && 2407 // Are there other uses besides address expressions? 2408 !is_visited(off)) { 2409 address_visited.test_set(m->_idx); // Flag as address_visited 2410 address_visited.set(off->_idx); // Flag as address_visited 2411 mstack.push(off->in(1), Pre_Visit); 2412 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2413 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2414 return true; 2415 } 2416 return false; 2417 } 2418 2419 void Compile::reshape_address(AddPNode* addp) { 2420 } 2421 2422 2423 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2424 C2_MacroAssembler _masm(&cbuf); \ 2425 { \ 2426 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2427 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2428 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2429 __ INSN(REG, as_Register(BASE)); \ 2430 } 2431 2432 2433 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2434 { 2435 Address::extend scale; 2436 2437 // Hooboy, this is fugly. We need a way to communicate to the 2438 // encoder that the index needs to be sign extended, so we have to 2439 // enumerate all the cases. 2440 switch (opcode) { 2441 case INDINDEXSCALEDI2L: 2442 case INDINDEXSCALEDI2LN: 2443 case INDINDEXI2L: 2444 case INDINDEXI2LN: 2445 scale = Address::sxtw(size); 2446 break; 2447 default: 2448 scale = Address::lsl(size); 2449 } 2450 2451 if (index == -1) { 2452 return Address(base, disp); 2453 } else { 2454 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2455 return Address(base, as_Register(index), scale); 2456 } 2457 } 2458 2459 2460 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2461 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2462 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2463 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2464 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2465 2466 // Used for all non-volatile memory accesses. The use of 2467 // $mem->opcode() to discover whether this pattern uses sign-extended 2468 // offsets is something of a kludge. 2469 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2470 Register reg, int opcode, 2471 Register base, int index, int scale, int disp, 2472 int size_in_memory) 2473 { 2474 Address addr = mem2address(opcode, base, index, scale, disp); 2475 if (addr.getMode() == Address::base_plus_offset) { 2476 /* If we get an out-of-range offset it is a bug in the compiler, 2477 so we assert here. */ 2478 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2479 "c2 compiler bug"); 2480 /* Fix up any out-of-range offsets. */ 2481 assert_different_registers(rscratch1, base); 2482 assert_different_registers(rscratch1, reg); 2483 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2484 } 2485 (masm.*insn)(reg, addr); 2486 } 2487 2488 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2489 FloatRegister reg, int opcode, 2490 Register base, int index, int size, int disp, 2491 int size_in_memory) 2492 { 2493 Address::extend scale; 2494 2495 switch (opcode) { 2496 case INDINDEXSCALEDI2L: 2497 case INDINDEXSCALEDI2LN: 2498 scale = Address::sxtw(size); 2499 break; 2500 default: 2501 scale = Address::lsl(size); 2502 } 2503 2504 if (index == -1) { 2505 /* If we get an out-of-range offset it is a bug in the compiler, 2506 so we assert here. */ 2507 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2508 /* Fix up any out-of-range offsets. */ 2509 assert_different_registers(rscratch1, base); 2510 Address addr = Address(base, disp); 2511 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2512 (masm.*insn)(reg, addr); 2513 } else { 2514 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2515 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2516 } 2517 } 2518 2519 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2520 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2521 int opcode, Register base, int index, int size, int disp) 2522 { 2523 if (index == -1) { 2524 (masm.*insn)(reg, T, Address(base, disp)); 2525 } else { 2526 assert(disp == 0, "unsupported address mode"); 2527 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2528 } 2529 } 2530 2531 %} 2532 2533 2534 2535 //----------ENCODING BLOCK----------------------------------------------------- 2536 // This block specifies the encoding classes used by the compiler to 2537 // output byte streams. Encoding classes are parameterized macros 2538 // used by Machine Instruction Nodes in order to generate the bit 2539 // encoding of the instruction. Operands specify their base encoding 2540 // interface with the interface keyword. There are currently 2541 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2542 // COND_INTER. REG_INTER causes an operand to generate a function 2543 // which returns its register number when queried. CONST_INTER causes 2544 // an operand to generate a function which returns the value of the 2545 // constant when queried. MEMORY_INTER causes an operand to generate 2546 // four functions which return the Base Register, the Index Register, 2547 // the Scale Value, and the Offset Value of the operand when queried. 2548 // COND_INTER causes an operand to generate six functions which return 2549 // the encoding code (ie - encoding bits for the instruction) 2550 // associated with each basic boolean condition for a conditional 2551 // instruction. 2552 // 2553 // Instructions specify two basic values for encoding. Again, a 2554 // function is available to check if the constant displacement is an 2555 // oop. They use the ins_encode keyword to specify their encoding 2556 // classes (which must be a sequence of enc_class names, and their 2557 // parameters, specified in the encoding block), and they use the 2558 // opcode keyword to specify, in order, their primary, secondary, and 2559 // tertiary opcode. Only the opcode sections which a particular 2560 // instruction needs for encoding need to be specified. 2561 encode %{ 2562 // Build emit functions for each basic byte or larger field in the 2563 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2564 // from C++ code in the enc_class source block. Emit functions will 2565 // live in the main source block for now. In future, we can 2566 // generalize this by adding a syntax that specifies the sizes of 2567 // fields in an order, so that the adlc can build the emit functions 2568 // automagically 2569 2570 // catch all for unimplemented encodings 2571 enc_class enc_unimplemented %{ 2572 C2_MacroAssembler _masm(&cbuf); 2573 __ unimplemented("C2 catch all"); 2574 %} 2575 2576 // BEGIN Non-volatile memory access 2577 2578 // This encoding class is generated automatically from ad_encode.m4. 2579 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2580 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2581 Register dst_reg = as_Register($dst$$reg); 2582 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2583 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2584 %} 2585 2586 // This encoding class is generated automatically from ad_encode.m4. 2587 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2588 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2589 Register dst_reg = as_Register($dst$$reg); 2590 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2591 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2592 %} 2593 2594 // This encoding class is generated automatically from ad_encode.m4. 2595 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2596 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2597 Register dst_reg = as_Register($dst$$reg); 2598 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2599 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2600 %} 2601 2602 // This encoding class is generated automatically from ad_encode.m4. 2603 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2604 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2605 Register dst_reg = as_Register($dst$$reg); 2606 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2607 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2608 %} 2609 2610 // This encoding class is generated automatically from ad_encode.m4. 2611 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2612 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2613 Register dst_reg = as_Register($dst$$reg); 2614 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2615 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2616 %} 2617 2618 // This encoding class is generated automatically from ad_encode.m4. 2619 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2620 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2621 Register dst_reg = as_Register($dst$$reg); 2622 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2623 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2624 %} 2625 2626 // This encoding class is generated automatically from ad_encode.m4. 2627 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2628 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2629 Register dst_reg = as_Register($dst$$reg); 2630 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2631 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2632 %} 2633 2634 // This encoding class is generated automatically from ad_encode.m4. 2635 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2636 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2637 Register dst_reg = as_Register($dst$$reg); 2638 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2639 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2640 %} 2641 2642 // This encoding class is generated automatically from ad_encode.m4. 2643 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2644 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2645 Register dst_reg = as_Register($dst$$reg); 2646 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2647 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2648 %} 2649 2650 // This encoding class is generated automatically from ad_encode.m4. 2651 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2652 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2653 Register dst_reg = as_Register($dst$$reg); 2654 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2655 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2656 %} 2657 2658 // This encoding class is generated automatically from ad_encode.m4. 2659 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2660 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2661 Register dst_reg = as_Register($dst$$reg); 2662 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2663 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2664 %} 2665 2666 // This encoding class is generated automatically from ad_encode.m4. 2667 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2668 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2669 Register dst_reg = as_Register($dst$$reg); 2670 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2671 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2672 %} 2673 2674 // This encoding class is generated automatically from ad_encode.m4. 2675 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2676 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2677 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2678 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2679 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2680 %} 2681 2682 // This encoding class is generated automatically from ad_encode.m4. 2683 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2684 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2685 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2686 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2687 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2688 %} 2689 2690 // This encoding class is generated automatically from ad_encode.m4. 2691 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2692 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2693 Register src_reg = as_Register($src$$reg); 2694 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2695 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2696 %} 2697 2698 // This encoding class is generated automatically from ad_encode.m4. 2699 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2700 enc_class aarch64_enc_strb0(memory1 mem) %{ 2701 C2_MacroAssembler _masm(&cbuf); 2702 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2703 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2704 %} 2705 2706 // This encoding class is generated automatically from ad_encode.m4. 2707 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2708 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2709 Register src_reg = as_Register($src$$reg); 2710 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2711 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2712 %} 2713 2714 // This encoding class is generated automatically from ad_encode.m4. 2715 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2716 enc_class aarch64_enc_strh0(memory2 mem) %{ 2717 C2_MacroAssembler _masm(&cbuf); 2718 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2719 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2720 %} 2721 2722 // This encoding class is generated automatically from ad_encode.m4. 2723 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2724 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2725 Register src_reg = as_Register($src$$reg); 2726 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2727 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2728 %} 2729 2730 // This encoding class is generated automatically from ad_encode.m4. 2731 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2732 enc_class aarch64_enc_strw0(memory4 mem) %{ 2733 C2_MacroAssembler _masm(&cbuf); 2734 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2735 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2736 %} 2737 2738 // This encoding class is generated automatically from ad_encode.m4. 2739 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2740 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2741 Register src_reg = as_Register($src$$reg); 2742 // we sometimes get asked to store the stack pointer into the 2743 // current thread -- we cannot do that directly on AArch64 2744 if (src_reg == r31_sp) { 2745 C2_MacroAssembler _masm(&cbuf); 2746 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2747 __ mov(rscratch2, sp); 2748 src_reg = rscratch2; 2749 } 2750 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2751 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2752 %} 2753 2754 // This encoding class is generated automatically from ad_encode.m4. 2755 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2756 enc_class aarch64_enc_str0(memory8 mem) %{ 2757 C2_MacroAssembler _masm(&cbuf); 2758 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2759 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2760 %} 2761 2762 // This encoding class is generated automatically from ad_encode.m4. 2763 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2764 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 2765 FloatRegister src_reg = as_FloatRegister($src$$reg); 2766 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2767 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2768 %} 2769 2770 // This encoding class is generated automatically from ad_encode.m4. 2771 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2772 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 2773 FloatRegister src_reg = as_FloatRegister($src$$reg); 2774 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2775 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2776 %} 2777 2778 // This encoding class is generated automatically from ad_encode.m4. 2779 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2780 enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{ 2781 C2_MacroAssembler _masm(&cbuf); 2782 address con = (address)$src$$constant; 2783 // need to do this the hard way until we can manage relocs 2784 // for 32 bit constants 2785 __ movoop(rscratch2, (jobject)con); 2786 if (con) __ encode_heap_oop_not_null(rscratch2); 2787 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2788 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2789 %} 2790 2791 // This encoding class is generated automatically from ad_encode.m4. 2792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2793 enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{ 2794 C2_MacroAssembler _masm(&cbuf); 2795 address con = (address)$src$$constant; 2796 // need to do this the hard way until we can manage relocs 2797 // for 32 bit constants 2798 __ movoop(rscratch2, (jobject)con); 2799 __ encode_klass_not_null(rscratch2); 2800 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2801 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2802 %} 2803 2804 // This encoding class is generated automatically from ad_encode.m4. 2805 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2806 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 2807 C2_MacroAssembler _masm(&cbuf); 2808 __ membar(Assembler::StoreStore); 2809 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2810 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2811 %} 2812 2813 // END Non-volatile memory access 2814 2815 // Vector loads and stores 2816 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2817 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2818 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2819 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2820 %} 2821 2822 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2823 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2824 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2825 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2826 %} 2827 2828 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2829 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2830 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2831 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2832 %} 2833 2834 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2835 FloatRegister src_reg = as_FloatRegister($src$$reg); 2836 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2837 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2838 %} 2839 2840 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2841 FloatRegister src_reg = as_FloatRegister($src$$reg); 2842 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2843 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2844 %} 2845 2846 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2847 FloatRegister src_reg = as_FloatRegister($src$$reg); 2848 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2849 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2850 %} 2851 2852 // volatile loads and stores 2853 2854 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2855 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2856 rscratch1, stlrb); 2857 %} 2858 2859 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2860 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2861 rscratch1, stlrh); 2862 %} 2863 2864 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2865 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2866 rscratch1, stlrw); 2867 %} 2868 2869 2870 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2871 Register dst_reg = as_Register($dst$$reg); 2872 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2873 rscratch1, ldarb); 2874 __ sxtbw(dst_reg, dst_reg); 2875 %} 2876 2877 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2878 Register dst_reg = as_Register($dst$$reg); 2879 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2880 rscratch1, ldarb); 2881 __ sxtb(dst_reg, dst_reg); 2882 %} 2883 2884 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2885 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2886 rscratch1, ldarb); 2887 %} 2888 2889 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2890 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2891 rscratch1, ldarb); 2892 %} 2893 2894 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2895 Register dst_reg = as_Register($dst$$reg); 2896 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2897 rscratch1, ldarh); 2898 __ sxthw(dst_reg, dst_reg); 2899 %} 2900 2901 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2902 Register dst_reg = as_Register($dst$$reg); 2903 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2904 rscratch1, ldarh); 2905 __ sxth(dst_reg, dst_reg); 2906 %} 2907 2908 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2909 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2910 rscratch1, ldarh); 2911 %} 2912 2913 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2914 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2915 rscratch1, ldarh); 2916 %} 2917 2918 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2919 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2920 rscratch1, ldarw); 2921 %} 2922 2923 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2924 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2925 rscratch1, ldarw); 2926 %} 2927 2928 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2929 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2930 rscratch1, ldar); 2931 %} 2932 2933 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2934 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2935 rscratch1, ldarw); 2936 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2937 %} 2938 2939 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2940 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2941 rscratch1, ldar); 2942 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2943 %} 2944 2945 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2946 Register src_reg = as_Register($src$$reg); 2947 // we sometimes get asked to store the stack pointer into the 2948 // current thread -- we cannot do that directly on AArch64 2949 if (src_reg == r31_sp) { 2950 C2_MacroAssembler _masm(&cbuf); 2951 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2952 __ mov(rscratch2, sp); 2953 src_reg = rscratch2; 2954 } 2955 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2956 rscratch1, stlr); 2957 %} 2958 2959 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2960 { 2961 C2_MacroAssembler _masm(&cbuf); 2962 FloatRegister src_reg = as_FloatRegister($src$$reg); 2963 __ fmovs(rscratch2, src_reg); 2964 } 2965 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2966 rscratch1, stlrw); 2967 %} 2968 2969 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2970 { 2971 C2_MacroAssembler _masm(&cbuf); 2972 FloatRegister src_reg = as_FloatRegister($src$$reg); 2973 __ fmovd(rscratch2, src_reg); 2974 } 2975 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2976 rscratch1, stlr); 2977 %} 2978 2979 // synchronized read/update encodings 2980 2981 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 2982 C2_MacroAssembler _masm(&cbuf); 2983 Register dst_reg = as_Register($dst$$reg); 2984 Register base = as_Register($mem$$base); 2985 int index = $mem$$index; 2986 int scale = $mem$$scale; 2987 int disp = $mem$$disp; 2988 if (index == -1) { 2989 if (disp != 0) { 2990 __ lea(rscratch1, Address(base, disp)); 2991 __ ldaxr(dst_reg, rscratch1); 2992 } else { 2993 // TODO 2994 // should we ever get anything other than this case? 2995 __ ldaxr(dst_reg, base); 2996 } 2997 } else { 2998 Register index_reg = as_Register(index); 2999 if (disp == 0) { 3000 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3001 __ ldaxr(dst_reg, rscratch1); 3002 } else { 3003 __ lea(rscratch1, Address(base, disp)); 3004 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3005 __ ldaxr(dst_reg, rscratch1); 3006 } 3007 } 3008 %} 3009 3010 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3011 C2_MacroAssembler _masm(&cbuf); 3012 Register src_reg = as_Register($src$$reg); 3013 Register base = as_Register($mem$$base); 3014 int index = $mem$$index; 3015 int scale = $mem$$scale; 3016 int disp = $mem$$disp; 3017 if (index == -1) { 3018 if (disp != 0) { 3019 __ lea(rscratch2, Address(base, disp)); 3020 __ stlxr(rscratch1, src_reg, rscratch2); 3021 } else { 3022 // TODO 3023 // should we ever get anything other than this case? 3024 __ stlxr(rscratch1, src_reg, base); 3025 } 3026 } else { 3027 Register index_reg = as_Register(index); 3028 if (disp == 0) { 3029 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3030 __ stlxr(rscratch1, src_reg, rscratch2); 3031 } else { 3032 __ lea(rscratch2, Address(base, disp)); 3033 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3034 __ stlxr(rscratch1, src_reg, rscratch2); 3035 } 3036 } 3037 __ cmpw(rscratch1, zr); 3038 %} 3039 3040 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3041 C2_MacroAssembler _masm(&cbuf); 3042 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3043 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3044 Assembler::xword, /*acquire*/ false, /*release*/ true, 3045 /*weak*/ false, noreg); 3046 %} 3047 3048 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3049 C2_MacroAssembler _masm(&cbuf); 3050 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3051 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3052 Assembler::word, /*acquire*/ false, /*release*/ true, 3053 /*weak*/ false, noreg); 3054 %} 3055 3056 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3057 C2_MacroAssembler _masm(&cbuf); 3058 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3059 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3060 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3061 /*weak*/ false, noreg); 3062 %} 3063 3064 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3065 C2_MacroAssembler _masm(&cbuf); 3066 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3067 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3068 Assembler::byte, /*acquire*/ false, /*release*/ true, 3069 /*weak*/ false, noreg); 3070 %} 3071 3072 3073 // The only difference between aarch64_enc_cmpxchg and 3074 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3075 // CompareAndSwap sequence to serve as a barrier on acquiring a 3076 // lock. 3077 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3078 C2_MacroAssembler _masm(&cbuf); 3079 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3080 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3081 Assembler::xword, /*acquire*/ true, /*release*/ true, 3082 /*weak*/ false, noreg); 3083 %} 3084 3085 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3086 C2_MacroAssembler _masm(&cbuf); 3087 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3088 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3089 Assembler::word, /*acquire*/ true, /*release*/ true, 3090 /*weak*/ false, noreg); 3091 %} 3092 3093 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3094 C2_MacroAssembler _masm(&cbuf); 3095 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3096 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3097 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3098 /*weak*/ false, noreg); 3099 %} 3100 3101 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3102 C2_MacroAssembler _masm(&cbuf); 3103 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3104 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3105 Assembler::byte, /*acquire*/ true, /*release*/ true, 3106 /*weak*/ false, noreg); 3107 %} 3108 3109 // auxiliary used for CompareAndSwapX to set result register 3110 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3111 C2_MacroAssembler _masm(&cbuf); 3112 Register res_reg = as_Register($res$$reg); 3113 __ cset(res_reg, Assembler::EQ); 3114 %} 3115 3116 // prefetch encodings 3117 3118 enc_class aarch64_enc_prefetchw(memory mem) %{ 3119 C2_MacroAssembler _masm(&cbuf); 3120 Register base = as_Register($mem$$base); 3121 int index = $mem$$index; 3122 int scale = $mem$$scale; 3123 int disp = $mem$$disp; 3124 if (index == -1) { 3125 __ prfm(Address(base, disp), PSTL1KEEP); 3126 } else { 3127 Register index_reg = as_Register(index); 3128 if (disp == 0) { 3129 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3130 } else { 3131 __ lea(rscratch1, Address(base, disp)); 3132 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3133 } 3134 } 3135 %} 3136 3137 /// mov envcodings 3138 3139 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3140 C2_MacroAssembler _masm(&cbuf); 3141 uint32_t con = (uint32_t)$src$$constant; 3142 Register dst_reg = as_Register($dst$$reg); 3143 if (con == 0) { 3144 __ movw(dst_reg, zr); 3145 } else { 3146 __ movw(dst_reg, con); 3147 } 3148 %} 3149 3150 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3151 C2_MacroAssembler _masm(&cbuf); 3152 Register dst_reg = as_Register($dst$$reg); 3153 uint64_t con = (uint64_t)$src$$constant; 3154 if (con == 0) { 3155 __ mov(dst_reg, zr); 3156 } else { 3157 __ mov(dst_reg, con); 3158 } 3159 %} 3160 3161 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3162 C2_MacroAssembler _masm(&cbuf); 3163 Register dst_reg = as_Register($dst$$reg); 3164 address con = (address)$src$$constant; 3165 if (con == NULL || con == (address)1) { 3166 ShouldNotReachHere(); 3167 } else { 3168 relocInfo::relocType rtype = $src->constant_reloc(); 3169 if (rtype == relocInfo::oop_type) { 3170 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3171 } else if (rtype == relocInfo::metadata_type) { 3172 __ mov_metadata(dst_reg, (Metadata*)con); 3173 } else { 3174 assert(rtype == relocInfo::none, "unexpected reloc type"); 3175 if (con < (address)(uintptr_t)os::vm_page_size()) { 3176 __ mov(dst_reg, con); 3177 } else { 3178 uint64_t offset; 3179 __ adrp(dst_reg, con, offset); 3180 __ add(dst_reg, dst_reg, offset); 3181 } 3182 } 3183 } 3184 %} 3185 3186 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3187 C2_MacroAssembler _masm(&cbuf); 3188 Register dst_reg = as_Register($dst$$reg); 3189 __ mov(dst_reg, zr); 3190 %} 3191 3192 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3193 C2_MacroAssembler _masm(&cbuf); 3194 Register dst_reg = as_Register($dst$$reg); 3195 __ mov(dst_reg, (uint64_t)1); 3196 %} 3197 3198 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3199 C2_MacroAssembler _masm(&cbuf); 3200 __ load_byte_map_base($dst$$Register); 3201 %} 3202 3203 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3204 C2_MacroAssembler _masm(&cbuf); 3205 Register dst_reg = as_Register($dst$$reg); 3206 address con = (address)$src$$constant; 3207 if (con == NULL) { 3208 ShouldNotReachHere(); 3209 } else { 3210 relocInfo::relocType rtype = $src->constant_reloc(); 3211 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3212 __ set_narrow_oop(dst_reg, (jobject)con); 3213 } 3214 %} 3215 3216 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3217 C2_MacroAssembler _masm(&cbuf); 3218 Register dst_reg = as_Register($dst$$reg); 3219 __ mov(dst_reg, zr); 3220 %} 3221 3222 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3223 C2_MacroAssembler _masm(&cbuf); 3224 Register dst_reg = as_Register($dst$$reg); 3225 address con = (address)$src$$constant; 3226 if (con == NULL) { 3227 ShouldNotReachHere(); 3228 } else { 3229 relocInfo::relocType rtype = $src->constant_reloc(); 3230 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3231 __ set_narrow_klass(dst_reg, (Klass *)con); 3232 } 3233 %} 3234 3235 // arithmetic encodings 3236 3237 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3238 C2_MacroAssembler _masm(&cbuf); 3239 Register dst_reg = as_Register($dst$$reg); 3240 Register src_reg = as_Register($src1$$reg); 3241 int32_t con = (int32_t)$src2$$constant; 3242 // add has primary == 0, subtract has primary == 1 3243 if ($primary) { con = -con; } 3244 if (con < 0) { 3245 __ subw(dst_reg, src_reg, -con); 3246 } else { 3247 __ addw(dst_reg, src_reg, con); 3248 } 3249 %} 3250 3251 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3252 C2_MacroAssembler _masm(&cbuf); 3253 Register dst_reg = as_Register($dst$$reg); 3254 Register src_reg = as_Register($src1$$reg); 3255 int32_t con = (int32_t)$src2$$constant; 3256 // add has primary == 0, subtract has primary == 1 3257 if ($primary) { con = -con; } 3258 if (con < 0) { 3259 __ sub(dst_reg, src_reg, -con); 3260 } else { 3261 __ add(dst_reg, src_reg, con); 3262 } 3263 %} 3264 3265 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3266 C2_MacroAssembler _masm(&cbuf); 3267 Register dst_reg = as_Register($dst$$reg); 3268 Register src1_reg = as_Register($src1$$reg); 3269 Register src2_reg = as_Register($src2$$reg); 3270 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3271 %} 3272 3273 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3274 C2_MacroAssembler _masm(&cbuf); 3275 Register dst_reg = as_Register($dst$$reg); 3276 Register src1_reg = as_Register($src1$$reg); 3277 Register src2_reg = as_Register($src2$$reg); 3278 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3279 %} 3280 3281 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3282 C2_MacroAssembler _masm(&cbuf); 3283 Register dst_reg = as_Register($dst$$reg); 3284 Register src1_reg = as_Register($src1$$reg); 3285 Register src2_reg = as_Register($src2$$reg); 3286 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3287 %} 3288 3289 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3290 C2_MacroAssembler _masm(&cbuf); 3291 Register dst_reg = as_Register($dst$$reg); 3292 Register src1_reg = as_Register($src1$$reg); 3293 Register src2_reg = as_Register($src2$$reg); 3294 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3295 %} 3296 3297 // compare instruction encodings 3298 3299 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3300 C2_MacroAssembler _masm(&cbuf); 3301 Register reg1 = as_Register($src1$$reg); 3302 Register reg2 = as_Register($src2$$reg); 3303 __ cmpw(reg1, reg2); 3304 %} 3305 3306 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3307 C2_MacroAssembler _masm(&cbuf); 3308 Register reg = as_Register($src1$$reg); 3309 int32_t val = $src2$$constant; 3310 if (val >= 0) { 3311 __ subsw(zr, reg, val); 3312 } else { 3313 __ addsw(zr, reg, -val); 3314 } 3315 %} 3316 3317 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3318 C2_MacroAssembler _masm(&cbuf); 3319 Register reg1 = as_Register($src1$$reg); 3320 uint32_t val = (uint32_t)$src2$$constant; 3321 __ movw(rscratch1, val); 3322 __ cmpw(reg1, rscratch1); 3323 %} 3324 3325 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3326 C2_MacroAssembler _masm(&cbuf); 3327 Register reg1 = as_Register($src1$$reg); 3328 Register reg2 = as_Register($src2$$reg); 3329 __ cmp(reg1, reg2); 3330 %} 3331 3332 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3333 C2_MacroAssembler _masm(&cbuf); 3334 Register reg = as_Register($src1$$reg); 3335 int64_t val = $src2$$constant; 3336 if (val >= 0) { 3337 __ subs(zr, reg, val); 3338 } else if (val != -val) { 3339 __ adds(zr, reg, -val); 3340 } else { 3341 // aargh, Long.MIN_VALUE is a special case 3342 __ orr(rscratch1, zr, (uint64_t)val); 3343 __ subs(zr, reg, rscratch1); 3344 } 3345 %} 3346 3347 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3348 C2_MacroAssembler _masm(&cbuf); 3349 Register reg1 = as_Register($src1$$reg); 3350 uint64_t val = (uint64_t)$src2$$constant; 3351 __ mov(rscratch1, val); 3352 __ cmp(reg1, rscratch1); 3353 %} 3354 3355 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3356 C2_MacroAssembler _masm(&cbuf); 3357 Register reg1 = as_Register($src1$$reg); 3358 Register reg2 = as_Register($src2$$reg); 3359 __ cmp(reg1, reg2); 3360 %} 3361 3362 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3363 C2_MacroAssembler _masm(&cbuf); 3364 Register reg1 = as_Register($src1$$reg); 3365 Register reg2 = as_Register($src2$$reg); 3366 __ cmpw(reg1, reg2); 3367 %} 3368 3369 enc_class aarch64_enc_testp(iRegP src) %{ 3370 C2_MacroAssembler _masm(&cbuf); 3371 Register reg = as_Register($src$$reg); 3372 __ cmp(reg, zr); 3373 %} 3374 3375 enc_class aarch64_enc_testn(iRegN src) %{ 3376 C2_MacroAssembler _masm(&cbuf); 3377 Register reg = as_Register($src$$reg); 3378 __ cmpw(reg, zr); 3379 %} 3380 3381 enc_class aarch64_enc_b(label lbl) %{ 3382 C2_MacroAssembler _masm(&cbuf); 3383 Label *L = $lbl$$label; 3384 __ b(*L); 3385 %} 3386 3387 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3388 C2_MacroAssembler _masm(&cbuf); 3389 Label *L = $lbl$$label; 3390 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3391 %} 3392 3393 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3394 C2_MacroAssembler _masm(&cbuf); 3395 Label *L = $lbl$$label; 3396 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3397 %} 3398 3399 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3400 %{ 3401 Register sub_reg = as_Register($sub$$reg); 3402 Register super_reg = as_Register($super$$reg); 3403 Register temp_reg = as_Register($temp$$reg); 3404 Register result_reg = as_Register($result$$reg); 3405 3406 Label miss; 3407 C2_MacroAssembler _masm(&cbuf); 3408 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3409 NULL, &miss, 3410 /*set_cond_codes:*/ true); 3411 if ($primary) { 3412 __ mov(result_reg, zr); 3413 } 3414 __ bind(miss); 3415 %} 3416 3417 enc_class aarch64_enc_java_static_call(method meth) %{ 3418 C2_MacroAssembler _masm(&cbuf); 3419 3420 address addr = (address)$meth$$method; 3421 address call; 3422 if (!_method) { 3423 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3424 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3425 } else { 3426 int method_index = resolved_method_index(cbuf); 3427 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3428 : static_call_Relocation::spec(method_index); 3429 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3430 3431 // Emit stub for static call 3432 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3433 if (stub == NULL) { 3434 ciEnv::current()->record_failure("CodeCache is full"); 3435 return; 3436 } 3437 } 3438 if (call == NULL) { 3439 ciEnv::current()->record_failure("CodeCache is full"); 3440 return; 3441 } 3442 %} 3443 3444 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3445 C2_MacroAssembler _masm(&cbuf); 3446 int method_index = resolved_method_index(cbuf); 3447 address call = __ ic_call((address)$meth$$method, method_index); 3448 if (call == NULL) { 3449 ciEnv::current()->record_failure("CodeCache is full"); 3450 return; 3451 } 3452 %} 3453 3454 enc_class aarch64_enc_call_epilog() %{ 3455 C2_MacroAssembler _masm(&cbuf); 3456 if (VerifyStackAtCalls) { 3457 // Check that stack depth is unchanged: find majik cookie on stack 3458 __ call_Unimplemented(); 3459 } 3460 %} 3461 3462 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3463 C2_MacroAssembler _masm(&cbuf); 3464 3465 // some calls to generated routines (arraycopy code) are scheduled 3466 // by C2 as runtime calls. if so we can call them using a br (they 3467 // will be in a reachable segment) otherwise we have to use a blr 3468 // which loads the absolute address into a register. 3469 address entry = (address)$meth$$method; 3470 CodeBlob *cb = CodeCache::find_blob(entry); 3471 if (cb) { 3472 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3473 if (call == NULL) { 3474 ciEnv::current()->record_failure("CodeCache is full"); 3475 return; 3476 } 3477 } else { 3478 Label retaddr; 3479 __ adr(rscratch2, retaddr); 3480 __ lea(rscratch1, RuntimeAddress(entry)); 3481 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3482 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3483 __ blr(rscratch1); 3484 __ bind(retaddr); 3485 __ add(sp, sp, 2 * wordSize); 3486 } 3487 %} 3488 3489 enc_class aarch64_enc_rethrow() %{ 3490 C2_MacroAssembler _masm(&cbuf); 3491 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3492 %} 3493 3494 enc_class aarch64_enc_ret() %{ 3495 C2_MacroAssembler _masm(&cbuf); 3496 __ ret(lr); 3497 %} 3498 3499 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3500 C2_MacroAssembler _masm(&cbuf); 3501 Register target_reg = as_Register($jump_target$$reg); 3502 __ br(target_reg); 3503 %} 3504 3505 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3506 C2_MacroAssembler _masm(&cbuf); 3507 Register target_reg = as_Register($jump_target$$reg); 3508 // exception oop should be in r0 3509 // ret addr has been popped into lr 3510 // callee expects it in r3 3511 __ mov(r3, lr); 3512 __ br(target_reg); 3513 %} 3514 3515 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3516 C2_MacroAssembler _masm(&cbuf); 3517 Register oop = as_Register($object$$reg); 3518 Register box = as_Register($box$$reg); 3519 Register disp_hdr = as_Register($tmp$$reg); 3520 Register tmp = as_Register($tmp2$$reg); 3521 Label cont; 3522 Label object_has_monitor; 3523 Label cas_failed; 3524 3525 assert_different_registers(oop, box, tmp, disp_hdr); 3526 3527 // Load markWord from object into displaced_header. 3528 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3529 3530 if (UseBiasedLocking && !UseOptoBiasInlining) { 3531 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3532 } 3533 3534 // Check for existing monitor 3535 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3536 3537 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3538 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3539 3540 // Initialize the box. (Must happen before we update the object mark!) 3541 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3542 3543 // Compare object markWord with an unlocked value (tmp) and if 3544 // equal exchange the stack address of our box with object markWord. 3545 // On failure disp_hdr contains the possibly locked markWord. 3546 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3547 /*release*/ true, /*weak*/ false, disp_hdr); 3548 __ br(Assembler::EQ, cont); 3549 3550 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3551 3552 // If the compare-and-exchange succeeded, then we found an unlocked 3553 // object, will have now locked it will continue at label cont 3554 3555 __ bind(cas_failed); 3556 // We did not see an unlocked object so try the fast recursive case. 3557 3558 // Check if the owner is self by comparing the value in the 3559 // markWord of object (disp_hdr) with the stack pointer. 3560 __ mov(rscratch1, sp); 3561 __ sub(disp_hdr, disp_hdr, rscratch1); 3562 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3563 // If condition is true we are cont and hence we can store 0 as the 3564 // displaced header in the box, which indicates that it is a recursive lock. 3565 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3566 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3567 3568 __ b(cont); 3569 3570 // Handle existing monitor. 3571 __ bind(object_has_monitor); 3572 3573 // The object's monitor m is unlocked iff m->owner == NULL, 3574 // otherwise m->owner may contain a thread or a stack address. 3575 // 3576 // Try to CAS m->owner from NULL to current thread. 3577 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3578 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3579 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3580 3581 // Store a non-null value into the box to avoid looking like a re-entrant 3582 // lock. The fast-path monitor unlock code checks for 3583 // markWord::monitor_value so use markWord::unused_mark which has the 3584 // relevant bit set, and also matches ObjectSynchronizer::enter. 3585 __ mov(tmp, (address)markWord::unused_mark().value()); 3586 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3587 3588 __ bind(cont); 3589 // flag == EQ indicates success 3590 // flag == NE indicates failure 3591 %} 3592 3593 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3594 C2_MacroAssembler _masm(&cbuf); 3595 Register oop = as_Register($object$$reg); 3596 Register box = as_Register($box$$reg); 3597 Register disp_hdr = as_Register($tmp$$reg); 3598 Register tmp = as_Register($tmp2$$reg); 3599 Label cont; 3600 Label object_has_monitor; 3601 3602 assert_different_registers(oop, box, tmp, disp_hdr); 3603 3604 if (UseBiasedLocking && !UseOptoBiasInlining) { 3605 __ biased_locking_exit(oop, tmp, cont); 3606 } 3607 3608 // Find the lock address and load the displaced header from the stack. 3609 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3610 3611 // If the displaced header is 0, we have a recursive unlock. 3612 __ cmp(disp_hdr, zr); 3613 __ br(Assembler::EQ, cont); 3614 3615 // Handle existing monitor. 3616 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3617 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3618 3619 // Check if it is still a light weight lock, this is is true if we 3620 // see the stack address of the basicLock in the markWord of the 3621 // object. 3622 3623 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3624 /*release*/ true, /*weak*/ false, tmp); 3625 __ b(cont); 3626 3627 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3628 3629 // Handle existing monitor. 3630 __ bind(object_has_monitor); 3631 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3632 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3633 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3634 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3635 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3636 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3637 __ cmp(rscratch1, zr); // Sets flags for result 3638 __ br(Assembler::NE, cont); 3639 3640 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3641 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3642 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3643 __ cmp(rscratch1, zr); // Sets flags for result 3644 __ cbnz(rscratch1, cont); 3645 // need a release store here 3646 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3647 __ stlr(zr, tmp); // set unowned 3648 3649 __ bind(cont); 3650 // flag == EQ indicates success 3651 // flag == NE indicates failure 3652 %} 3653 3654 %} 3655 3656 //----------FRAME-------------------------------------------------------------- 3657 // Definition of frame structure and management information. 3658 // 3659 // S T A C K L A Y O U T Allocators stack-slot number 3660 // | (to get allocators register number 3661 // G Owned by | | v add OptoReg::stack0()) 3662 // r CALLER | | 3663 // o | +--------+ pad to even-align allocators stack-slot 3664 // w V | pad0 | numbers; owned by CALLER 3665 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3666 // h ^ | in | 5 3667 // | | args | 4 Holes in incoming args owned by SELF 3668 // | | | | 3 3669 // | | +--------+ 3670 // V | | old out| Empty on Intel, window on Sparc 3671 // | old |preserve| Must be even aligned. 3672 // | SP-+--------+----> Matcher::_old_SP, even aligned 3673 // | | in | 3 area for Intel ret address 3674 // Owned by |preserve| Empty on Sparc. 3675 // SELF +--------+ 3676 // | | pad2 | 2 pad to align old SP 3677 // | +--------+ 1 3678 // | | locks | 0 3679 // | +--------+----> OptoReg::stack0(), even aligned 3680 // | | pad1 | 11 pad to align new SP 3681 // | +--------+ 3682 // | | | 10 3683 // | | spills | 9 spills 3684 // V | | 8 (pad0 slot for callee) 3685 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3686 // ^ | out | 7 3687 // | | args | 6 Holes in outgoing args owned by CALLEE 3688 // Owned by +--------+ 3689 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3690 // | new |preserve| Must be even-aligned. 3691 // | SP-+--------+----> Matcher::_new_SP, even aligned 3692 // | | | 3693 // 3694 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3695 // known from SELF's arguments and the Java calling convention. 3696 // Region 6-7 is determined per call site. 3697 // Note 2: If the calling convention leaves holes in the incoming argument 3698 // area, those holes are owned by SELF. Holes in the outgoing area 3699 // are owned by the CALLEE. Holes should not be nessecary in the 3700 // incoming area, as the Java calling convention is completely under 3701 // the control of the AD file. Doubles can be sorted and packed to 3702 // avoid holes. Holes in the outgoing arguments may be nessecary for 3703 // varargs C calling conventions. 3704 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3705 // even aligned with pad0 as needed. 3706 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3707 // (the latter is true on Intel but is it false on AArch64?) 3708 // region 6-11 is even aligned; it may be padded out more so that 3709 // the region from SP to FP meets the minimum stack alignment. 3710 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3711 // alignment. Region 11, pad1, may be dynamically extended so that 3712 // SP meets the minimum alignment. 3713 3714 frame %{ 3715 // What direction does stack grow in (assumed to be same for C & Java) 3716 stack_direction(TOWARDS_LOW); 3717 3718 // These three registers define part of the calling convention 3719 // between compiled code and the interpreter. 3720 3721 // Inline Cache Register or methodOop for I2C. 3722 inline_cache_reg(R12); 3723 3724 // Method Oop Register when calling interpreter. 3725 interpreter_method_oop_reg(R12); 3726 3727 // Number of stack slots consumed by locking an object 3728 sync_stack_slots(2); 3729 3730 // Compiled code's Frame Pointer 3731 frame_pointer(R31); 3732 3733 // Interpreter stores its frame pointer in a register which is 3734 // stored to the stack by I2CAdaptors. 3735 // I2CAdaptors convert from interpreted java to compiled java. 3736 interpreter_frame_pointer(R29); 3737 3738 // Stack alignment requirement 3739 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3740 3741 // Number of stack slots between incoming argument block and the start of 3742 // a new frame. The PROLOG must add this many slots to the stack. The 3743 // EPILOG must remove this many slots. aarch64 needs two slots for 3744 // return address and fp. 3745 // TODO think this is correct but check 3746 in_preserve_stack_slots(4); 3747 3748 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3749 // for calls to C. Supports the var-args backing area for register parms. 3750 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3751 3752 // The after-PROLOG location of the return address. Location of 3753 // return address specifies a type (REG or STACK) and a number 3754 // representing the register number (i.e. - use a register name) or 3755 // stack slot. 3756 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3757 // Otherwise, it is above the locks and verification slot and alignment word 3758 // TODO this may well be correct but need to check why that - 2 is there 3759 // ppc port uses 0 but we definitely need to allow for fixed_slots 3760 // which folds in the space used for monitors 3761 return_addr(STACK - 2 + 3762 align_up((Compile::current()->in_preserve_stack_slots() + 3763 Compile::current()->fixed_slots()), 3764 stack_alignment_in_slots())); 3765 3766 // Body of function which returns an integer array locating 3767 // arguments either in registers or in stack slots. Passed an array 3768 // of ideal registers called "sig" and a "length" count. Stack-slot 3769 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3770 // arguments for a CALLEE. Incoming stack arguments are 3771 // automatically biased by the preserve_stack_slots field above. 3772 3773 calling_convention 3774 %{ 3775 // No difference between ingoing/outgoing just pass false 3776 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3777 %} 3778 3779 c_calling_convention 3780 %{ 3781 // This is obviously always outgoing 3782 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3783 %} 3784 3785 // Location of compiled Java return values. Same as C for now. 3786 return_value 3787 %{ 3788 // TODO do we allow ideal_reg == Op_RegN??? 3789 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3790 "only return normal values"); 3791 3792 static const int lo[Op_RegL + 1] = { // enum name 3793 0, // Op_Node 3794 0, // Op_Set 3795 R0_num, // Op_RegN 3796 R0_num, // Op_RegI 3797 R0_num, // Op_RegP 3798 V0_num, // Op_RegF 3799 V0_num, // Op_RegD 3800 R0_num // Op_RegL 3801 }; 3802 3803 static const int hi[Op_RegL + 1] = { // enum name 3804 0, // Op_Node 3805 0, // Op_Set 3806 OptoReg::Bad, // Op_RegN 3807 OptoReg::Bad, // Op_RegI 3808 R0_H_num, // Op_RegP 3809 OptoReg::Bad, // Op_RegF 3810 V0_H_num, // Op_RegD 3811 R0_H_num // Op_RegL 3812 }; 3813 3814 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3815 %} 3816 %} 3817 3818 //----------ATTRIBUTES--------------------------------------------------------- 3819 //----------Operand Attributes------------------------------------------------- 3820 op_attrib op_cost(1); // Required cost attribute 3821 3822 //----------Instruction Attributes--------------------------------------------- 3823 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3824 ins_attrib ins_size(32); // Required size attribute (in bits) 3825 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3826 // a non-matching short branch variant 3827 // of some long branch? 3828 ins_attrib ins_alignment(4); // Required alignment attribute (must 3829 // be a power of 2) specifies the 3830 // alignment that some part of the 3831 // instruction (not necessarily the 3832 // start) requires. If > 1, a 3833 // compute_padding() function must be 3834 // provided for the instruction 3835 3836 //----------OPERANDS----------------------------------------------------------- 3837 // Operand definitions must precede instruction definitions for correct parsing 3838 // in the ADLC because operands constitute user defined types which are used in 3839 // instruction definitions. 3840 3841 //----------Simple Operands---------------------------------------------------- 3842 3843 // Integer operands 32 bit 3844 // 32 bit immediate 3845 operand immI() 3846 %{ 3847 match(ConI); 3848 3849 op_cost(0); 3850 format %{ %} 3851 interface(CONST_INTER); 3852 %} 3853 3854 // 32 bit zero 3855 operand immI0() 3856 %{ 3857 predicate(n->get_int() == 0); 3858 match(ConI); 3859 3860 op_cost(0); 3861 format %{ %} 3862 interface(CONST_INTER); 3863 %} 3864 3865 // 32 bit unit increment 3866 operand immI_1() 3867 %{ 3868 predicate(n->get_int() == 1); 3869 match(ConI); 3870 3871 op_cost(0); 3872 format %{ %} 3873 interface(CONST_INTER); 3874 %} 3875 3876 // 32 bit unit decrement 3877 operand immI_M1() 3878 %{ 3879 predicate(n->get_int() == -1); 3880 match(ConI); 3881 3882 op_cost(0); 3883 format %{ %} 3884 interface(CONST_INTER); 3885 %} 3886 3887 // Shift values for add/sub extension shift 3888 operand immIExt() 3889 %{ 3890 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3891 match(ConI); 3892 3893 op_cost(0); 3894 format %{ %} 3895 interface(CONST_INTER); 3896 %} 3897 3898 operand immI_le_4() 3899 %{ 3900 predicate(n->get_int() <= 4); 3901 match(ConI); 3902 3903 op_cost(0); 3904 format %{ %} 3905 interface(CONST_INTER); 3906 %} 3907 3908 operand immI_31() 3909 %{ 3910 predicate(n->get_int() == 31); 3911 match(ConI); 3912 3913 op_cost(0); 3914 format %{ %} 3915 interface(CONST_INTER); 3916 %} 3917 3918 operand immI_8() 3919 %{ 3920 predicate(n->get_int() == 8); 3921 match(ConI); 3922 3923 op_cost(0); 3924 format %{ %} 3925 interface(CONST_INTER); 3926 %} 3927 3928 operand immI_16() 3929 %{ 3930 predicate(n->get_int() == 16); 3931 match(ConI); 3932 3933 op_cost(0); 3934 format %{ %} 3935 interface(CONST_INTER); 3936 %} 3937 3938 operand immI_24() 3939 %{ 3940 predicate(n->get_int() == 24); 3941 match(ConI); 3942 3943 op_cost(0); 3944 format %{ %} 3945 interface(CONST_INTER); 3946 %} 3947 3948 operand immI_32() 3949 %{ 3950 predicate(n->get_int() == 32); 3951 match(ConI); 3952 3953 op_cost(0); 3954 format %{ %} 3955 interface(CONST_INTER); 3956 %} 3957 3958 operand immI_48() 3959 %{ 3960 predicate(n->get_int() == 48); 3961 match(ConI); 3962 3963 op_cost(0); 3964 format %{ %} 3965 interface(CONST_INTER); 3966 %} 3967 3968 operand immI_56() 3969 %{ 3970 predicate(n->get_int() == 56); 3971 match(ConI); 3972 3973 op_cost(0); 3974 format %{ %} 3975 interface(CONST_INTER); 3976 %} 3977 3978 operand immI_63() 3979 %{ 3980 predicate(n->get_int() == 63); 3981 match(ConI); 3982 3983 op_cost(0); 3984 format %{ %} 3985 interface(CONST_INTER); 3986 %} 3987 3988 operand immI_64() 3989 %{ 3990 predicate(n->get_int() == 64); 3991 match(ConI); 3992 3993 op_cost(0); 3994 format %{ %} 3995 interface(CONST_INTER); 3996 %} 3997 3998 operand immI_255() 3999 %{ 4000 predicate(n->get_int() == 255); 4001 match(ConI); 4002 4003 op_cost(0); 4004 format %{ %} 4005 interface(CONST_INTER); 4006 %} 4007 4008 operand immI_65535() 4009 %{ 4010 predicate(n->get_int() == 65535); 4011 match(ConI); 4012 4013 op_cost(0); 4014 format %{ %} 4015 interface(CONST_INTER); 4016 %} 4017 4018 operand immL_255() 4019 %{ 4020 predicate(n->get_long() == 255L); 4021 match(ConL); 4022 4023 op_cost(0); 4024 format %{ %} 4025 interface(CONST_INTER); 4026 %} 4027 4028 operand immL_65535() 4029 %{ 4030 predicate(n->get_long() == 65535L); 4031 match(ConL); 4032 4033 op_cost(0); 4034 format %{ %} 4035 interface(CONST_INTER); 4036 %} 4037 4038 operand immL_4294967295() 4039 %{ 4040 predicate(n->get_long() == 4294967295L); 4041 match(ConL); 4042 4043 op_cost(0); 4044 format %{ %} 4045 interface(CONST_INTER); 4046 %} 4047 4048 operand immL_bitmask() 4049 %{ 4050 predicate((n->get_long() != 0) 4051 && ((n->get_long() & 0xc000000000000000l) == 0) 4052 && is_power_of_2(n->get_long() + 1)); 4053 match(ConL); 4054 4055 op_cost(0); 4056 format %{ %} 4057 interface(CONST_INTER); 4058 %} 4059 4060 operand immI_bitmask() 4061 %{ 4062 predicate((n->get_int() != 0) 4063 && ((n->get_int() & 0xc0000000) == 0) 4064 && is_power_of_2(n->get_int() + 1)); 4065 match(ConI); 4066 4067 op_cost(0); 4068 format %{ %} 4069 interface(CONST_INTER); 4070 %} 4071 4072 // Scale values for scaled offset addressing modes (up to long but not quad) 4073 operand immIScale() 4074 %{ 4075 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4076 match(ConI); 4077 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 // 26 bit signed offset -- for pc-relative branches 4084 operand immI26() 4085 %{ 4086 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4087 match(ConI); 4088 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 // 19 bit signed offset -- for pc-relative loads 4095 operand immI19() 4096 %{ 4097 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4098 match(ConI); 4099 4100 op_cost(0); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 // 12 bit unsigned offset -- for base plus immediate loads 4106 operand immIU12() 4107 %{ 4108 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4109 match(ConI); 4110 4111 op_cost(0); 4112 format %{ %} 4113 interface(CONST_INTER); 4114 %} 4115 4116 operand immLU12() 4117 %{ 4118 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4119 match(ConL); 4120 4121 op_cost(0); 4122 format %{ %} 4123 interface(CONST_INTER); 4124 %} 4125 4126 // Offset for scaled or unscaled immediate loads and stores 4127 operand immIOffset() 4128 %{ 4129 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4130 match(ConI); 4131 4132 op_cost(0); 4133 format %{ %} 4134 interface(CONST_INTER); 4135 %} 4136 4137 operand immIOffset1() 4138 %{ 4139 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4140 match(ConI); 4141 4142 op_cost(0); 4143 format %{ %} 4144 interface(CONST_INTER); 4145 %} 4146 4147 operand immIOffset2() 4148 %{ 4149 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4150 match(ConI); 4151 4152 op_cost(0); 4153 format %{ %} 4154 interface(CONST_INTER); 4155 %} 4156 4157 operand immIOffset4() 4158 %{ 4159 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4160 match(ConI); 4161 4162 op_cost(0); 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 operand immIOffset8() 4168 %{ 4169 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4170 match(ConI); 4171 4172 op_cost(0); 4173 format %{ %} 4174 interface(CONST_INTER); 4175 %} 4176 4177 operand immIOffset16() 4178 %{ 4179 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4180 match(ConI); 4181 4182 op_cost(0); 4183 format %{ %} 4184 interface(CONST_INTER); 4185 %} 4186 4187 operand immLoffset() 4188 %{ 4189 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4190 match(ConL); 4191 4192 op_cost(0); 4193 format %{ %} 4194 interface(CONST_INTER); 4195 %} 4196 4197 operand immLoffset1() 4198 %{ 4199 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4200 match(ConL); 4201 4202 op_cost(0); 4203 format %{ %} 4204 interface(CONST_INTER); 4205 %} 4206 4207 operand immLoffset2() 4208 %{ 4209 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4210 match(ConL); 4211 4212 op_cost(0); 4213 format %{ %} 4214 interface(CONST_INTER); 4215 %} 4216 4217 operand immLoffset4() 4218 %{ 4219 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4220 match(ConL); 4221 4222 op_cost(0); 4223 format %{ %} 4224 interface(CONST_INTER); 4225 %} 4226 4227 operand immLoffset8() 4228 %{ 4229 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4230 match(ConL); 4231 4232 op_cost(0); 4233 format %{ %} 4234 interface(CONST_INTER); 4235 %} 4236 4237 operand immLoffset16() 4238 %{ 4239 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4240 match(ConL); 4241 4242 op_cost(0); 4243 format %{ %} 4244 interface(CONST_INTER); 4245 %} 4246 4247 // 32 bit integer valid for add sub immediate 4248 operand immIAddSub() 4249 %{ 4250 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4251 match(ConI); 4252 op_cost(0); 4253 format %{ %} 4254 interface(CONST_INTER); 4255 %} 4256 4257 // 32 bit unsigned integer valid for logical immediate 4258 // TODO -- check this is right when e.g the mask is 0x80000000 4259 operand immILog() 4260 %{ 4261 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4262 match(ConI); 4263 4264 op_cost(0); 4265 format %{ %} 4266 interface(CONST_INTER); 4267 %} 4268 4269 // Integer operands 64 bit 4270 // 64 bit immediate 4271 operand immL() 4272 %{ 4273 match(ConL); 4274 4275 op_cost(0); 4276 format %{ %} 4277 interface(CONST_INTER); 4278 %} 4279 4280 // 64 bit zero 4281 operand immL0() 4282 %{ 4283 predicate(n->get_long() == 0); 4284 match(ConL); 4285 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289 %} 4290 4291 // 64 bit unit increment 4292 operand immL_1() 4293 %{ 4294 predicate(n->get_long() == 1); 4295 match(ConL); 4296 4297 op_cost(0); 4298 format %{ %} 4299 interface(CONST_INTER); 4300 %} 4301 4302 // 64 bit unit decrement 4303 operand immL_M1() 4304 %{ 4305 predicate(n->get_long() == -1); 4306 match(ConL); 4307 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 // 32 bit offset of pc in thread anchor 4314 4315 operand immL_pc_off() 4316 %{ 4317 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4318 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4319 match(ConL); 4320 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // 64 bit integer valid for add sub immediate 4327 operand immLAddSub() 4328 %{ 4329 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4330 match(ConL); 4331 op_cost(0); 4332 format %{ %} 4333 interface(CONST_INTER); 4334 %} 4335 4336 // 64 bit integer valid for logical immediate 4337 operand immLLog() 4338 %{ 4339 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4340 match(ConL); 4341 op_cost(0); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // Long Immediate: low 32-bit mask 4347 operand immL_32bits() 4348 %{ 4349 predicate(n->get_long() == 0xFFFFFFFFL); 4350 match(ConL); 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Pointer operands 4357 // Pointer Immediate 4358 operand immP() 4359 %{ 4360 match(ConP); 4361 4362 op_cost(0); 4363 format %{ %} 4364 interface(CONST_INTER); 4365 %} 4366 4367 // NULL Pointer Immediate 4368 operand immP0() 4369 %{ 4370 predicate(n->get_ptr() == 0); 4371 match(ConP); 4372 4373 op_cost(0); 4374 format %{ %} 4375 interface(CONST_INTER); 4376 %} 4377 4378 // Pointer Immediate One 4379 // this is used in object initialization (initial object header) 4380 operand immP_1() 4381 %{ 4382 predicate(n->get_ptr() == 1); 4383 match(ConP); 4384 4385 op_cost(0); 4386 format %{ %} 4387 interface(CONST_INTER); 4388 %} 4389 4390 // Card Table Byte Map Base 4391 operand immByteMapBase() 4392 %{ 4393 // Get base of card map 4394 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4395 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4396 match(ConP); 4397 4398 op_cost(0); 4399 format %{ %} 4400 interface(CONST_INTER); 4401 %} 4402 4403 // Pointer Immediate Minus One 4404 // this is used when we want to write the current PC to the thread anchor 4405 operand immP_M1() 4406 %{ 4407 predicate(n->get_ptr() == -1); 4408 match(ConP); 4409 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413 %} 4414 4415 // Pointer Immediate Minus Two 4416 // this is used when we want to write the current PC to the thread anchor 4417 operand immP_M2() 4418 %{ 4419 predicate(n->get_ptr() == -2); 4420 match(ConP); 4421 4422 op_cost(0); 4423 format %{ %} 4424 interface(CONST_INTER); 4425 %} 4426 4427 // Float and Double operands 4428 // Double Immediate 4429 operand immD() 4430 %{ 4431 match(ConD); 4432 op_cost(0); 4433 format %{ %} 4434 interface(CONST_INTER); 4435 %} 4436 4437 // Double Immediate: +0.0d 4438 operand immD0() 4439 %{ 4440 predicate(jlong_cast(n->getd()) == 0); 4441 match(ConD); 4442 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 // constant 'double +0.0'. 4449 operand immDPacked() 4450 %{ 4451 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4452 match(ConD); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // Float Immediate 4459 operand immF() 4460 %{ 4461 match(ConF); 4462 op_cost(0); 4463 format %{ %} 4464 interface(CONST_INTER); 4465 %} 4466 4467 // Float Immediate: +0.0f. 4468 operand immF0() 4469 %{ 4470 predicate(jint_cast(n->getf()) == 0); 4471 match(ConF); 4472 4473 op_cost(0); 4474 format %{ %} 4475 interface(CONST_INTER); 4476 %} 4477 4478 // 4479 operand immFPacked() 4480 %{ 4481 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4482 match(ConF); 4483 op_cost(0); 4484 format %{ %} 4485 interface(CONST_INTER); 4486 %} 4487 4488 // Narrow pointer operands 4489 // Narrow Pointer Immediate 4490 operand immN() 4491 %{ 4492 match(ConN); 4493 4494 op_cost(0); 4495 format %{ %} 4496 interface(CONST_INTER); 4497 %} 4498 4499 // Narrow NULL Pointer Immediate 4500 operand immN0() 4501 %{ 4502 predicate(n->get_narrowcon() == 0); 4503 match(ConN); 4504 4505 op_cost(0); 4506 format %{ %} 4507 interface(CONST_INTER); 4508 %} 4509 4510 operand immNKlass() 4511 %{ 4512 match(ConNKlass); 4513 4514 op_cost(0); 4515 format %{ %} 4516 interface(CONST_INTER); 4517 %} 4518 4519 // Integer 32 bit Register Operands 4520 // Integer 32 bitRegister (excludes SP) 4521 operand iRegI() 4522 %{ 4523 constraint(ALLOC_IN_RC(any_reg32)); 4524 match(RegI); 4525 match(iRegINoSp); 4526 op_cost(0); 4527 format %{ %} 4528 interface(REG_INTER); 4529 %} 4530 4531 // Integer 32 bit Register not Special 4532 operand iRegINoSp() 4533 %{ 4534 constraint(ALLOC_IN_RC(no_special_reg32)); 4535 match(RegI); 4536 op_cost(0); 4537 format %{ %} 4538 interface(REG_INTER); 4539 %} 4540 4541 // Integer 64 bit Register Operands 4542 // Integer 64 bit Register (includes SP) 4543 operand iRegL() 4544 %{ 4545 constraint(ALLOC_IN_RC(any_reg)); 4546 match(RegL); 4547 match(iRegLNoSp); 4548 op_cost(0); 4549 format %{ %} 4550 interface(REG_INTER); 4551 %} 4552 4553 // Integer 64 bit Register not Special 4554 operand iRegLNoSp() 4555 %{ 4556 constraint(ALLOC_IN_RC(no_special_reg)); 4557 match(RegL); 4558 match(iRegL_R0); 4559 format %{ %} 4560 interface(REG_INTER); 4561 %} 4562 4563 // Pointer Register Operands 4564 // Pointer Register 4565 operand iRegP() 4566 %{ 4567 constraint(ALLOC_IN_RC(ptr_reg)); 4568 match(RegP); 4569 match(iRegPNoSp); 4570 match(iRegP_R0); 4571 //match(iRegP_R2); 4572 //match(iRegP_R4); 4573 //match(iRegP_R5); 4574 match(thread_RegP); 4575 op_cost(0); 4576 format %{ %} 4577 interface(REG_INTER); 4578 %} 4579 4580 // Pointer 64 bit Register not Special 4581 operand iRegPNoSp() 4582 %{ 4583 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4584 match(RegP); 4585 // match(iRegP); 4586 // match(iRegP_R0); 4587 // match(iRegP_R2); 4588 // match(iRegP_R4); 4589 // match(iRegP_R5); 4590 // match(thread_RegP); 4591 op_cost(0); 4592 format %{ %} 4593 interface(REG_INTER); 4594 %} 4595 4596 // Pointer 64 bit Register R0 only 4597 operand iRegP_R0() 4598 %{ 4599 constraint(ALLOC_IN_RC(r0_reg)); 4600 match(RegP); 4601 // match(iRegP); 4602 match(iRegPNoSp); 4603 op_cost(0); 4604 format %{ %} 4605 interface(REG_INTER); 4606 %} 4607 4608 // Pointer 64 bit Register R1 only 4609 operand iRegP_R1() 4610 %{ 4611 constraint(ALLOC_IN_RC(r1_reg)); 4612 match(RegP); 4613 // match(iRegP); 4614 match(iRegPNoSp); 4615 op_cost(0); 4616 format %{ %} 4617 interface(REG_INTER); 4618 %} 4619 4620 // Pointer 64 bit Register R2 only 4621 operand iRegP_R2() 4622 %{ 4623 constraint(ALLOC_IN_RC(r2_reg)); 4624 match(RegP); 4625 // match(iRegP); 4626 match(iRegPNoSp); 4627 op_cost(0); 4628 format %{ %} 4629 interface(REG_INTER); 4630 %} 4631 4632 // Pointer 64 bit Register R3 only 4633 operand iRegP_R3() 4634 %{ 4635 constraint(ALLOC_IN_RC(r3_reg)); 4636 match(RegP); 4637 // match(iRegP); 4638 match(iRegPNoSp); 4639 op_cost(0); 4640 format %{ %} 4641 interface(REG_INTER); 4642 %} 4643 4644 // Pointer 64 bit Register R4 only 4645 operand iRegP_R4() 4646 %{ 4647 constraint(ALLOC_IN_RC(r4_reg)); 4648 match(RegP); 4649 // match(iRegP); 4650 match(iRegPNoSp); 4651 op_cost(0); 4652 format %{ %} 4653 interface(REG_INTER); 4654 %} 4655 4656 // Pointer 64 bit Register R5 only 4657 operand iRegP_R5() 4658 %{ 4659 constraint(ALLOC_IN_RC(r5_reg)); 4660 match(RegP); 4661 // match(iRegP); 4662 match(iRegPNoSp); 4663 op_cost(0); 4664 format %{ %} 4665 interface(REG_INTER); 4666 %} 4667 4668 // Pointer 64 bit Register R10 only 4669 operand iRegP_R10() 4670 %{ 4671 constraint(ALLOC_IN_RC(r10_reg)); 4672 match(RegP); 4673 // match(iRegP); 4674 match(iRegPNoSp); 4675 op_cost(0); 4676 format %{ %} 4677 interface(REG_INTER); 4678 %} 4679 4680 // Long 64 bit Register R0 only 4681 operand iRegL_R0() 4682 %{ 4683 constraint(ALLOC_IN_RC(r0_reg)); 4684 match(RegL); 4685 match(iRegLNoSp); 4686 op_cost(0); 4687 format %{ %} 4688 interface(REG_INTER); 4689 %} 4690 4691 // Long 64 bit Register R2 only 4692 operand iRegL_R2() 4693 %{ 4694 constraint(ALLOC_IN_RC(r2_reg)); 4695 match(RegL); 4696 match(iRegLNoSp); 4697 op_cost(0); 4698 format %{ %} 4699 interface(REG_INTER); 4700 %} 4701 4702 // Long 64 bit Register R3 only 4703 operand iRegL_R3() 4704 %{ 4705 constraint(ALLOC_IN_RC(r3_reg)); 4706 match(RegL); 4707 match(iRegLNoSp); 4708 op_cost(0); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 // Long 64 bit Register R11 only 4714 operand iRegL_R11() 4715 %{ 4716 constraint(ALLOC_IN_RC(r11_reg)); 4717 match(RegL); 4718 match(iRegLNoSp); 4719 op_cost(0); 4720 format %{ %} 4721 interface(REG_INTER); 4722 %} 4723 4724 // Pointer 64 bit Register FP only 4725 operand iRegP_FP() 4726 %{ 4727 constraint(ALLOC_IN_RC(fp_reg)); 4728 match(RegP); 4729 // match(iRegP); 4730 op_cost(0); 4731 format %{ %} 4732 interface(REG_INTER); 4733 %} 4734 4735 // Register R0 only 4736 operand iRegI_R0() 4737 %{ 4738 constraint(ALLOC_IN_RC(int_r0_reg)); 4739 match(RegI); 4740 match(iRegINoSp); 4741 op_cost(0); 4742 format %{ %} 4743 interface(REG_INTER); 4744 %} 4745 4746 // Register R2 only 4747 operand iRegI_R2() 4748 %{ 4749 constraint(ALLOC_IN_RC(int_r2_reg)); 4750 match(RegI); 4751 match(iRegINoSp); 4752 op_cost(0); 4753 format %{ %} 4754 interface(REG_INTER); 4755 %} 4756 4757 // Register R3 only 4758 operand iRegI_R3() 4759 %{ 4760 constraint(ALLOC_IN_RC(int_r3_reg)); 4761 match(RegI); 4762 match(iRegINoSp); 4763 op_cost(0); 4764 format %{ %} 4765 interface(REG_INTER); 4766 %} 4767 4768 4769 // Register R4 only 4770 operand iRegI_R4() 4771 %{ 4772 constraint(ALLOC_IN_RC(int_r4_reg)); 4773 match(RegI); 4774 match(iRegINoSp); 4775 op_cost(0); 4776 format %{ %} 4777 interface(REG_INTER); 4778 %} 4779 4780 4781 // Pointer Register Operands 4782 // Narrow Pointer Register 4783 operand iRegN() 4784 %{ 4785 constraint(ALLOC_IN_RC(any_reg32)); 4786 match(RegN); 4787 match(iRegNNoSp); 4788 op_cost(0); 4789 format %{ %} 4790 interface(REG_INTER); 4791 %} 4792 4793 operand iRegN_R0() 4794 %{ 4795 constraint(ALLOC_IN_RC(r0_reg)); 4796 match(iRegN); 4797 op_cost(0); 4798 format %{ %} 4799 interface(REG_INTER); 4800 %} 4801 4802 operand iRegN_R2() 4803 %{ 4804 constraint(ALLOC_IN_RC(r2_reg)); 4805 match(iRegN); 4806 op_cost(0); 4807 format %{ %} 4808 interface(REG_INTER); 4809 %} 4810 4811 operand iRegN_R3() 4812 %{ 4813 constraint(ALLOC_IN_RC(r3_reg)); 4814 match(iRegN); 4815 op_cost(0); 4816 format %{ %} 4817 interface(REG_INTER); 4818 %} 4819 4820 // Integer 64 bit Register not Special 4821 operand iRegNNoSp() 4822 %{ 4823 constraint(ALLOC_IN_RC(no_special_reg32)); 4824 match(RegN); 4825 op_cost(0); 4826 format %{ %} 4827 interface(REG_INTER); 4828 %} 4829 4830 // heap base register -- used for encoding immN0 4831 4832 operand iRegIHeapbase() 4833 %{ 4834 constraint(ALLOC_IN_RC(heapbase_reg)); 4835 match(RegI); 4836 op_cost(0); 4837 format %{ %} 4838 interface(REG_INTER); 4839 %} 4840 4841 // Float Register 4842 // Float register operands 4843 operand vRegF() 4844 %{ 4845 constraint(ALLOC_IN_RC(float_reg)); 4846 match(RegF); 4847 4848 op_cost(0); 4849 format %{ %} 4850 interface(REG_INTER); 4851 %} 4852 4853 // Double Register 4854 // Double register operands 4855 operand vRegD() 4856 %{ 4857 constraint(ALLOC_IN_RC(double_reg)); 4858 match(RegD); 4859 4860 op_cost(0); 4861 format %{ %} 4862 interface(REG_INTER); 4863 %} 4864 4865 operand vecD() 4866 %{ 4867 constraint(ALLOC_IN_RC(vectord_reg)); 4868 match(VecD); 4869 4870 op_cost(0); 4871 format %{ %} 4872 interface(REG_INTER); 4873 %} 4874 4875 operand vecX() 4876 %{ 4877 constraint(ALLOC_IN_RC(vectorx_reg)); 4878 match(VecX); 4879 4880 op_cost(0); 4881 format %{ %} 4882 interface(REG_INTER); 4883 %} 4884 4885 operand vRegD_V0() 4886 %{ 4887 constraint(ALLOC_IN_RC(v0_reg)); 4888 match(RegD); 4889 op_cost(0); 4890 format %{ %} 4891 interface(REG_INTER); 4892 %} 4893 4894 operand vRegD_V1() 4895 %{ 4896 constraint(ALLOC_IN_RC(v1_reg)); 4897 match(RegD); 4898 op_cost(0); 4899 format %{ %} 4900 interface(REG_INTER); 4901 %} 4902 4903 operand vRegD_V2() 4904 %{ 4905 constraint(ALLOC_IN_RC(v2_reg)); 4906 match(RegD); 4907 op_cost(0); 4908 format %{ %} 4909 interface(REG_INTER); 4910 %} 4911 4912 operand vRegD_V3() 4913 %{ 4914 constraint(ALLOC_IN_RC(v3_reg)); 4915 match(RegD); 4916 op_cost(0); 4917 format %{ %} 4918 interface(REG_INTER); 4919 %} 4920 4921 operand vRegD_V4() 4922 %{ 4923 constraint(ALLOC_IN_RC(v4_reg)); 4924 match(RegD); 4925 op_cost(0); 4926 format %{ %} 4927 interface(REG_INTER); 4928 %} 4929 4930 operand vRegD_V5() 4931 %{ 4932 constraint(ALLOC_IN_RC(v5_reg)); 4933 match(RegD); 4934 op_cost(0); 4935 format %{ %} 4936 interface(REG_INTER); 4937 %} 4938 4939 operand vRegD_V6() 4940 %{ 4941 constraint(ALLOC_IN_RC(v6_reg)); 4942 match(RegD); 4943 op_cost(0); 4944 format %{ %} 4945 interface(REG_INTER); 4946 %} 4947 4948 operand vRegD_V7() 4949 %{ 4950 constraint(ALLOC_IN_RC(v7_reg)); 4951 match(RegD); 4952 op_cost(0); 4953 format %{ %} 4954 interface(REG_INTER); 4955 %} 4956 4957 operand vRegD_V8() 4958 %{ 4959 constraint(ALLOC_IN_RC(v8_reg)); 4960 match(RegD); 4961 op_cost(0); 4962 format %{ %} 4963 interface(REG_INTER); 4964 %} 4965 4966 operand vRegD_V9() 4967 %{ 4968 constraint(ALLOC_IN_RC(v9_reg)); 4969 match(RegD); 4970 op_cost(0); 4971 format %{ %} 4972 interface(REG_INTER); 4973 %} 4974 4975 operand vRegD_V10() 4976 %{ 4977 constraint(ALLOC_IN_RC(v10_reg)); 4978 match(RegD); 4979 op_cost(0); 4980 format %{ %} 4981 interface(REG_INTER); 4982 %} 4983 4984 operand vRegD_V11() 4985 %{ 4986 constraint(ALLOC_IN_RC(v11_reg)); 4987 match(RegD); 4988 op_cost(0); 4989 format %{ %} 4990 interface(REG_INTER); 4991 %} 4992 4993 operand vRegD_V12() 4994 %{ 4995 constraint(ALLOC_IN_RC(v12_reg)); 4996 match(RegD); 4997 op_cost(0); 4998 format %{ %} 4999 interface(REG_INTER); 5000 %} 5001 5002 operand vRegD_V13() 5003 %{ 5004 constraint(ALLOC_IN_RC(v13_reg)); 5005 match(RegD); 5006 op_cost(0); 5007 format %{ %} 5008 interface(REG_INTER); 5009 %} 5010 5011 operand vRegD_V14() 5012 %{ 5013 constraint(ALLOC_IN_RC(v14_reg)); 5014 match(RegD); 5015 op_cost(0); 5016 format %{ %} 5017 interface(REG_INTER); 5018 %} 5019 5020 operand vRegD_V15() 5021 %{ 5022 constraint(ALLOC_IN_RC(v15_reg)); 5023 match(RegD); 5024 op_cost(0); 5025 format %{ %} 5026 interface(REG_INTER); 5027 %} 5028 5029 operand vRegD_V16() 5030 %{ 5031 constraint(ALLOC_IN_RC(v16_reg)); 5032 match(RegD); 5033 op_cost(0); 5034 format %{ %} 5035 interface(REG_INTER); 5036 %} 5037 5038 operand vRegD_V17() 5039 %{ 5040 constraint(ALLOC_IN_RC(v17_reg)); 5041 match(RegD); 5042 op_cost(0); 5043 format %{ %} 5044 interface(REG_INTER); 5045 %} 5046 5047 operand vRegD_V18() 5048 %{ 5049 constraint(ALLOC_IN_RC(v18_reg)); 5050 match(RegD); 5051 op_cost(0); 5052 format %{ %} 5053 interface(REG_INTER); 5054 %} 5055 5056 operand vRegD_V19() 5057 %{ 5058 constraint(ALLOC_IN_RC(v19_reg)); 5059 match(RegD); 5060 op_cost(0); 5061 format %{ %} 5062 interface(REG_INTER); 5063 %} 5064 5065 operand vRegD_V20() 5066 %{ 5067 constraint(ALLOC_IN_RC(v20_reg)); 5068 match(RegD); 5069 op_cost(0); 5070 format %{ %} 5071 interface(REG_INTER); 5072 %} 5073 5074 operand vRegD_V21() 5075 %{ 5076 constraint(ALLOC_IN_RC(v21_reg)); 5077 match(RegD); 5078 op_cost(0); 5079 format %{ %} 5080 interface(REG_INTER); 5081 %} 5082 5083 operand vRegD_V22() 5084 %{ 5085 constraint(ALLOC_IN_RC(v22_reg)); 5086 match(RegD); 5087 op_cost(0); 5088 format %{ %} 5089 interface(REG_INTER); 5090 %} 5091 5092 operand vRegD_V23() 5093 %{ 5094 constraint(ALLOC_IN_RC(v23_reg)); 5095 match(RegD); 5096 op_cost(0); 5097 format %{ %} 5098 interface(REG_INTER); 5099 %} 5100 5101 operand vRegD_V24() 5102 %{ 5103 constraint(ALLOC_IN_RC(v24_reg)); 5104 match(RegD); 5105 op_cost(0); 5106 format %{ %} 5107 interface(REG_INTER); 5108 %} 5109 5110 operand vRegD_V25() 5111 %{ 5112 constraint(ALLOC_IN_RC(v25_reg)); 5113 match(RegD); 5114 op_cost(0); 5115 format %{ %} 5116 interface(REG_INTER); 5117 %} 5118 5119 operand vRegD_V26() 5120 %{ 5121 constraint(ALLOC_IN_RC(v26_reg)); 5122 match(RegD); 5123 op_cost(0); 5124 format %{ %} 5125 interface(REG_INTER); 5126 %} 5127 5128 operand vRegD_V27() 5129 %{ 5130 constraint(ALLOC_IN_RC(v27_reg)); 5131 match(RegD); 5132 op_cost(0); 5133 format %{ %} 5134 interface(REG_INTER); 5135 %} 5136 5137 operand vRegD_V28() 5138 %{ 5139 constraint(ALLOC_IN_RC(v28_reg)); 5140 match(RegD); 5141 op_cost(0); 5142 format %{ %} 5143 interface(REG_INTER); 5144 %} 5145 5146 operand vRegD_V29() 5147 %{ 5148 constraint(ALLOC_IN_RC(v29_reg)); 5149 match(RegD); 5150 op_cost(0); 5151 format %{ %} 5152 interface(REG_INTER); 5153 %} 5154 5155 operand vRegD_V30() 5156 %{ 5157 constraint(ALLOC_IN_RC(v30_reg)); 5158 match(RegD); 5159 op_cost(0); 5160 format %{ %} 5161 interface(REG_INTER); 5162 %} 5163 5164 operand vRegD_V31() 5165 %{ 5166 constraint(ALLOC_IN_RC(v31_reg)); 5167 match(RegD); 5168 op_cost(0); 5169 format %{ %} 5170 interface(REG_INTER); 5171 %} 5172 5173 // Flags register, used as output of signed compare instructions 5174 5175 // note that on AArch64 we also use this register as the output for 5176 // for floating point compare instructions (CmpF CmpD). this ensures 5177 // that ordered inequality tests use GT, GE, LT or LE none of which 5178 // pass through cases where the result is unordered i.e. one or both 5179 // inputs to the compare is a NaN. this means that the ideal code can 5180 // replace e.g. a GT with an LE and not end up capturing the NaN case 5181 // (where the comparison should always fail). EQ and NE tests are 5182 // always generated in ideal code so that unordered folds into the NE 5183 // case, matching the behaviour of AArch64 NE. 5184 // 5185 // This differs from x86 where the outputs of FP compares use a 5186 // special FP flags registers and where compares based on this 5187 // register are distinguished into ordered inequalities (cmpOpUCF) and 5188 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5189 // to explicitly handle the unordered case in branches. x86 also has 5190 // to include extra CMoveX rules to accept a cmpOpUCF input. 5191 5192 operand rFlagsReg() 5193 %{ 5194 constraint(ALLOC_IN_RC(int_flags)); 5195 match(RegFlags); 5196 5197 op_cost(0); 5198 format %{ "RFLAGS" %} 5199 interface(REG_INTER); 5200 %} 5201 5202 // Flags register, used as output of unsigned compare instructions 5203 operand rFlagsRegU() 5204 %{ 5205 constraint(ALLOC_IN_RC(int_flags)); 5206 match(RegFlags); 5207 5208 op_cost(0); 5209 format %{ "RFLAGSU" %} 5210 interface(REG_INTER); 5211 %} 5212 5213 // Special Registers 5214 5215 // Method Register 5216 operand inline_cache_RegP(iRegP reg) 5217 %{ 5218 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5219 match(reg); 5220 match(iRegPNoSp); 5221 op_cost(0); 5222 format %{ %} 5223 interface(REG_INTER); 5224 %} 5225 5226 operand interpreter_method_oop_RegP(iRegP reg) 5227 %{ 5228 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5229 match(reg); 5230 match(iRegPNoSp); 5231 op_cost(0); 5232 format %{ %} 5233 interface(REG_INTER); 5234 %} 5235 5236 // Thread Register 5237 operand thread_RegP(iRegP reg) 5238 %{ 5239 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5240 match(reg); 5241 op_cost(0); 5242 format %{ %} 5243 interface(REG_INTER); 5244 %} 5245 5246 operand lr_RegP(iRegP reg) 5247 %{ 5248 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5249 match(reg); 5250 op_cost(0); 5251 format %{ %} 5252 interface(REG_INTER); 5253 %} 5254 5255 //----------Memory Operands---------------------------------------------------- 5256 5257 operand indirect(iRegP reg) 5258 %{ 5259 constraint(ALLOC_IN_RC(ptr_reg)); 5260 match(reg); 5261 op_cost(0); 5262 format %{ "[$reg]" %} 5263 interface(MEMORY_INTER) %{ 5264 base($reg); 5265 index(0xffffffff); 5266 scale(0x0); 5267 disp(0x0); 5268 %} 5269 %} 5270 5271 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5272 %{ 5273 constraint(ALLOC_IN_RC(ptr_reg)); 5274 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5275 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5276 op_cost(0); 5277 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5278 interface(MEMORY_INTER) %{ 5279 base($reg); 5280 index($ireg); 5281 scale($scale); 5282 disp(0x0); 5283 %} 5284 %} 5285 5286 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5287 %{ 5288 constraint(ALLOC_IN_RC(ptr_reg)); 5289 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5290 match(AddP reg (LShiftL lreg scale)); 5291 op_cost(0); 5292 format %{ "$reg, $lreg lsl($scale)" %} 5293 interface(MEMORY_INTER) %{ 5294 base($reg); 5295 index($lreg); 5296 scale($scale); 5297 disp(0x0); 5298 %} 5299 %} 5300 5301 operand indIndexI2L(iRegP reg, iRegI ireg) 5302 %{ 5303 constraint(ALLOC_IN_RC(ptr_reg)); 5304 match(AddP reg (ConvI2L ireg)); 5305 op_cost(0); 5306 format %{ "$reg, $ireg, 0, I2L" %} 5307 interface(MEMORY_INTER) %{ 5308 base($reg); 5309 index($ireg); 5310 scale(0x0); 5311 disp(0x0); 5312 %} 5313 %} 5314 5315 operand indIndex(iRegP reg, iRegL lreg) 5316 %{ 5317 constraint(ALLOC_IN_RC(ptr_reg)); 5318 match(AddP reg lreg); 5319 op_cost(0); 5320 format %{ "$reg, $lreg" %} 5321 interface(MEMORY_INTER) %{ 5322 base($reg); 5323 index($lreg); 5324 scale(0x0); 5325 disp(0x0); 5326 %} 5327 %} 5328 5329 operand indOffI(iRegP reg, immIOffset off) 5330 %{ 5331 constraint(ALLOC_IN_RC(ptr_reg)); 5332 match(AddP reg off); 5333 op_cost(0); 5334 format %{ "[$reg, $off]" %} 5335 interface(MEMORY_INTER) %{ 5336 base($reg); 5337 index(0xffffffff); 5338 scale(0x0); 5339 disp($off); 5340 %} 5341 %} 5342 5343 operand indOffI1(iRegP reg, immIOffset1 off) 5344 %{ 5345 constraint(ALLOC_IN_RC(ptr_reg)); 5346 match(AddP reg off); 5347 op_cost(0); 5348 format %{ "[$reg, $off]" %} 5349 interface(MEMORY_INTER) %{ 5350 base($reg); 5351 index(0xffffffff); 5352 scale(0x0); 5353 disp($off); 5354 %} 5355 %} 5356 5357 operand indOffI2(iRegP reg, immIOffset2 off) 5358 %{ 5359 constraint(ALLOC_IN_RC(ptr_reg)); 5360 match(AddP reg off); 5361 op_cost(0); 5362 format %{ "[$reg, $off]" %} 5363 interface(MEMORY_INTER) %{ 5364 base($reg); 5365 index(0xffffffff); 5366 scale(0x0); 5367 disp($off); 5368 %} 5369 %} 5370 5371 operand indOffI4(iRegP reg, immIOffset4 off) 5372 %{ 5373 constraint(ALLOC_IN_RC(ptr_reg)); 5374 match(AddP reg off); 5375 op_cost(0); 5376 format %{ "[$reg, $off]" %} 5377 interface(MEMORY_INTER) %{ 5378 base($reg); 5379 index(0xffffffff); 5380 scale(0x0); 5381 disp($off); 5382 %} 5383 %} 5384 5385 operand indOffI8(iRegP reg, immIOffset8 off) 5386 %{ 5387 constraint(ALLOC_IN_RC(ptr_reg)); 5388 match(AddP reg off); 5389 op_cost(0); 5390 format %{ "[$reg, $off]" %} 5391 interface(MEMORY_INTER) %{ 5392 base($reg); 5393 index(0xffffffff); 5394 scale(0x0); 5395 disp($off); 5396 %} 5397 %} 5398 5399 operand indOffI16(iRegP reg, immIOffset16 off) 5400 %{ 5401 constraint(ALLOC_IN_RC(ptr_reg)); 5402 match(AddP reg off); 5403 op_cost(0); 5404 format %{ "[$reg, $off]" %} 5405 interface(MEMORY_INTER) %{ 5406 base($reg); 5407 index(0xffffffff); 5408 scale(0x0); 5409 disp($off); 5410 %} 5411 %} 5412 5413 operand indOffL(iRegP reg, immLoffset off) 5414 %{ 5415 constraint(ALLOC_IN_RC(ptr_reg)); 5416 match(AddP reg off); 5417 op_cost(0); 5418 format %{ "[$reg, $off]" %} 5419 interface(MEMORY_INTER) %{ 5420 base($reg); 5421 index(0xffffffff); 5422 scale(0x0); 5423 disp($off); 5424 %} 5425 %} 5426 5427 operand indOffL1(iRegP reg, immLoffset1 off) 5428 %{ 5429 constraint(ALLOC_IN_RC(ptr_reg)); 5430 match(AddP reg off); 5431 op_cost(0); 5432 format %{ "[$reg, $off]" %} 5433 interface(MEMORY_INTER) %{ 5434 base($reg); 5435 index(0xffffffff); 5436 scale(0x0); 5437 disp($off); 5438 %} 5439 %} 5440 5441 operand indOffL2(iRegP reg, immLoffset2 off) 5442 %{ 5443 constraint(ALLOC_IN_RC(ptr_reg)); 5444 match(AddP reg off); 5445 op_cost(0); 5446 format %{ "[$reg, $off]" %} 5447 interface(MEMORY_INTER) %{ 5448 base($reg); 5449 index(0xffffffff); 5450 scale(0x0); 5451 disp($off); 5452 %} 5453 %} 5454 5455 operand indOffL4(iRegP reg, immLoffset4 off) 5456 %{ 5457 constraint(ALLOC_IN_RC(ptr_reg)); 5458 match(AddP reg off); 5459 op_cost(0); 5460 format %{ "[$reg, $off]" %} 5461 interface(MEMORY_INTER) %{ 5462 base($reg); 5463 index(0xffffffff); 5464 scale(0x0); 5465 disp($off); 5466 %} 5467 %} 5468 5469 operand indOffL8(iRegP reg, immLoffset8 off) 5470 %{ 5471 constraint(ALLOC_IN_RC(ptr_reg)); 5472 match(AddP reg off); 5473 op_cost(0); 5474 format %{ "[$reg, $off]" %} 5475 interface(MEMORY_INTER) %{ 5476 base($reg); 5477 index(0xffffffff); 5478 scale(0x0); 5479 disp($off); 5480 %} 5481 %} 5482 5483 operand indOffL16(iRegP reg, immLoffset16 off) 5484 %{ 5485 constraint(ALLOC_IN_RC(ptr_reg)); 5486 match(AddP reg off); 5487 op_cost(0); 5488 format %{ "[$reg, $off]" %} 5489 interface(MEMORY_INTER) %{ 5490 base($reg); 5491 index(0xffffffff); 5492 scale(0x0); 5493 disp($off); 5494 %} 5495 %} 5496 5497 operand indirectN(iRegN reg) 5498 %{ 5499 predicate(CompressedOops::shift() == 0); 5500 constraint(ALLOC_IN_RC(ptr_reg)); 5501 match(DecodeN reg); 5502 op_cost(0); 5503 format %{ "[$reg]\t# narrow" %} 5504 interface(MEMORY_INTER) %{ 5505 base($reg); 5506 index(0xffffffff); 5507 scale(0x0); 5508 disp(0x0); 5509 %} 5510 %} 5511 5512 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5513 %{ 5514 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5515 constraint(ALLOC_IN_RC(ptr_reg)); 5516 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5517 op_cost(0); 5518 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5519 interface(MEMORY_INTER) %{ 5520 base($reg); 5521 index($ireg); 5522 scale($scale); 5523 disp(0x0); 5524 %} 5525 %} 5526 5527 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5528 %{ 5529 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5530 constraint(ALLOC_IN_RC(ptr_reg)); 5531 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5532 op_cost(0); 5533 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5534 interface(MEMORY_INTER) %{ 5535 base($reg); 5536 index($lreg); 5537 scale($scale); 5538 disp(0x0); 5539 %} 5540 %} 5541 5542 operand indIndexI2LN(iRegN reg, iRegI ireg) 5543 %{ 5544 predicate(CompressedOops::shift() == 0); 5545 constraint(ALLOC_IN_RC(ptr_reg)); 5546 match(AddP (DecodeN reg) (ConvI2L ireg)); 5547 op_cost(0); 5548 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5549 interface(MEMORY_INTER) %{ 5550 base($reg); 5551 index($ireg); 5552 scale(0x0); 5553 disp(0x0); 5554 %} 5555 %} 5556 5557 operand indIndexN(iRegN reg, iRegL lreg) 5558 %{ 5559 predicate(CompressedOops::shift() == 0); 5560 constraint(ALLOC_IN_RC(ptr_reg)); 5561 match(AddP (DecodeN reg) lreg); 5562 op_cost(0); 5563 format %{ "$reg, $lreg\t# narrow" %} 5564 interface(MEMORY_INTER) %{ 5565 base($reg); 5566 index($lreg); 5567 scale(0x0); 5568 disp(0x0); 5569 %} 5570 %} 5571 5572 operand indOffIN(iRegN reg, immIOffset off) 5573 %{ 5574 predicate(CompressedOops::shift() == 0); 5575 constraint(ALLOC_IN_RC(ptr_reg)); 5576 match(AddP (DecodeN reg) off); 5577 op_cost(0); 5578 format %{ "[$reg, $off]\t# narrow" %} 5579 interface(MEMORY_INTER) %{ 5580 base($reg); 5581 index(0xffffffff); 5582 scale(0x0); 5583 disp($off); 5584 %} 5585 %} 5586 5587 operand indOffLN(iRegN reg, immLoffset off) 5588 %{ 5589 predicate(CompressedOops::shift() == 0); 5590 constraint(ALLOC_IN_RC(ptr_reg)); 5591 match(AddP (DecodeN reg) off); 5592 op_cost(0); 5593 format %{ "[$reg, $off]\t# narrow" %} 5594 interface(MEMORY_INTER) %{ 5595 base($reg); 5596 index(0xffffffff); 5597 scale(0x0); 5598 disp($off); 5599 %} 5600 %} 5601 5602 5603 5604 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5605 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5606 %{ 5607 constraint(ALLOC_IN_RC(ptr_reg)); 5608 match(AddP reg off); 5609 op_cost(0); 5610 format %{ "[$reg, $off]" %} 5611 interface(MEMORY_INTER) %{ 5612 base($reg); 5613 index(0xffffffff); 5614 scale(0x0); 5615 disp($off); 5616 %} 5617 %} 5618 5619 //----------Special Memory Operands-------------------------------------------- 5620 // Stack Slot Operand - This operand is used for loading and storing temporary 5621 // values on the stack where a match requires a value to 5622 // flow through memory. 5623 operand stackSlotP(sRegP reg) 5624 %{ 5625 constraint(ALLOC_IN_RC(stack_slots)); 5626 op_cost(100); 5627 // No match rule because this operand is only generated in matching 5628 // match(RegP); 5629 format %{ "[$reg]" %} 5630 interface(MEMORY_INTER) %{ 5631 base(0x1e); // RSP 5632 index(0x0); // No Index 5633 scale(0x0); // No Scale 5634 disp($reg); // Stack Offset 5635 %} 5636 %} 5637 5638 operand stackSlotI(sRegI reg) 5639 %{ 5640 constraint(ALLOC_IN_RC(stack_slots)); 5641 // No match rule because this operand is only generated in matching 5642 // match(RegI); 5643 format %{ "[$reg]" %} 5644 interface(MEMORY_INTER) %{ 5645 base(0x1e); // RSP 5646 index(0x0); // No Index 5647 scale(0x0); // No Scale 5648 disp($reg); // Stack Offset 5649 %} 5650 %} 5651 5652 operand stackSlotF(sRegF reg) 5653 %{ 5654 constraint(ALLOC_IN_RC(stack_slots)); 5655 // No match rule because this operand is only generated in matching 5656 // match(RegF); 5657 format %{ "[$reg]" %} 5658 interface(MEMORY_INTER) %{ 5659 base(0x1e); // RSP 5660 index(0x0); // No Index 5661 scale(0x0); // No Scale 5662 disp($reg); // Stack Offset 5663 %} 5664 %} 5665 5666 operand stackSlotD(sRegD reg) 5667 %{ 5668 constraint(ALLOC_IN_RC(stack_slots)); 5669 // No match rule because this operand is only generated in matching 5670 // match(RegD); 5671 format %{ "[$reg]" %} 5672 interface(MEMORY_INTER) %{ 5673 base(0x1e); // RSP 5674 index(0x0); // No Index 5675 scale(0x0); // No Scale 5676 disp($reg); // Stack Offset 5677 %} 5678 %} 5679 5680 operand stackSlotL(sRegL reg) 5681 %{ 5682 constraint(ALLOC_IN_RC(stack_slots)); 5683 // No match rule because this operand is only generated in matching 5684 // match(RegL); 5685 format %{ "[$reg]" %} 5686 interface(MEMORY_INTER) %{ 5687 base(0x1e); // RSP 5688 index(0x0); // No Index 5689 scale(0x0); // No Scale 5690 disp($reg); // Stack Offset 5691 %} 5692 %} 5693 5694 // Operands for expressing Control Flow 5695 // NOTE: Label is a predefined operand which should not be redefined in 5696 // the AD file. It is generically handled within the ADLC. 5697 5698 //----------Conditional Branch Operands---------------------------------------- 5699 // Comparison Op - This is the operation of the comparison, and is limited to 5700 // the following set of codes: 5701 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5702 // 5703 // Other attributes of the comparison, such as unsignedness, are specified 5704 // by the comparison instruction that sets a condition code flags register. 5705 // That result is represented by a flags operand whose subtype is appropriate 5706 // to the unsignedness (etc.) of the comparison. 5707 // 5708 // Later, the instruction which matches both the Comparison Op (a Bool) and 5709 // the flags (produced by the Cmp) specifies the coding of the comparison op 5710 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5711 5712 // used for signed integral comparisons and fp comparisons 5713 5714 operand cmpOp() 5715 %{ 5716 match(Bool); 5717 5718 format %{ "" %} 5719 interface(COND_INTER) %{ 5720 equal(0x0, "eq"); 5721 not_equal(0x1, "ne"); 5722 less(0xb, "lt"); 5723 greater_equal(0xa, "ge"); 5724 less_equal(0xd, "le"); 5725 greater(0xc, "gt"); 5726 overflow(0x6, "vs"); 5727 no_overflow(0x7, "vc"); 5728 %} 5729 %} 5730 5731 // used for unsigned integral comparisons 5732 5733 operand cmpOpU() 5734 %{ 5735 match(Bool); 5736 5737 format %{ "" %} 5738 interface(COND_INTER) %{ 5739 equal(0x0, "eq"); 5740 not_equal(0x1, "ne"); 5741 less(0x3, "lo"); 5742 greater_equal(0x2, "hs"); 5743 less_equal(0x9, "ls"); 5744 greater(0x8, "hi"); 5745 overflow(0x6, "vs"); 5746 no_overflow(0x7, "vc"); 5747 %} 5748 %} 5749 5750 // used for certain integral comparisons which can be 5751 // converted to cbxx or tbxx instructions 5752 5753 operand cmpOpEqNe() 5754 %{ 5755 match(Bool); 5756 op_cost(0); 5757 predicate(n->as_Bool()->_test._test == BoolTest::ne 5758 || n->as_Bool()->_test._test == BoolTest::eq); 5759 5760 format %{ "" %} 5761 interface(COND_INTER) %{ 5762 equal(0x0, "eq"); 5763 not_equal(0x1, "ne"); 5764 less(0xb, "lt"); 5765 greater_equal(0xa, "ge"); 5766 less_equal(0xd, "le"); 5767 greater(0xc, "gt"); 5768 overflow(0x6, "vs"); 5769 no_overflow(0x7, "vc"); 5770 %} 5771 %} 5772 5773 // used for certain integral comparisons which can be 5774 // converted to cbxx or tbxx instructions 5775 5776 operand cmpOpLtGe() 5777 %{ 5778 match(Bool); 5779 op_cost(0); 5780 5781 predicate(n->as_Bool()->_test._test == BoolTest::lt 5782 || n->as_Bool()->_test._test == BoolTest::ge); 5783 5784 format %{ "" %} 5785 interface(COND_INTER) %{ 5786 equal(0x0, "eq"); 5787 not_equal(0x1, "ne"); 5788 less(0xb, "lt"); 5789 greater_equal(0xa, "ge"); 5790 less_equal(0xd, "le"); 5791 greater(0xc, "gt"); 5792 overflow(0x6, "vs"); 5793 no_overflow(0x7, "vc"); 5794 %} 5795 %} 5796 5797 // used for certain unsigned integral comparisons which can be 5798 // converted to cbxx or tbxx instructions 5799 5800 operand cmpOpUEqNeLtGe() 5801 %{ 5802 match(Bool); 5803 op_cost(0); 5804 5805 predicate(n->as_Bool()->_test._test == BoolTest::eq 5806 || n->as_Bool()->_test._test == BoolTest::ne 5807 || n->as_Bool()->_test._test == BoolTest::lt 5808 || n->as_Bool()->_test._test == BoolTest::ge); 5809 5810 format %{ "" %} 5811 interface(COND_INTER) %{ 5812 equal(0x0, "eq"); 5813 not_equal(0x1, "ne"); 5814 less(0xb, "lt"); 5815 greater_equal(0xa, "ge"); 5816 less_equal(0xd, "le"); 5817 greater(0xc, "gt"); 5818 overflow(0x6, "vs"); 5819 no_overflow(0x7, "vc"); 5820 %} 5821 %} 5822 5823 // Special operand allowing long args to int ops to be truncated for free 5824 5825 operand iRegL2I(iRegL reg) %{ 5826 5827 op_cost(0); 5828 5829 match(ConvL2I reg); 5830 5831 format %{ "l2i($reg)" %} 5832 5833 interface(REG_INTER) 5834 %} 5835 5836 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5837 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5838 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5839 5840 //----------OPERAND CLASSES---------------------------------------------------- 5841 // Operand Classes are groups of operands that are used as to simplify 5842 // instruction definitions by not requiring the AD writer to specify 5843 // separate instructions for every form of operand when the 5844 // instruction accepts multiple operand types with the same basic 5845 // encoding and format. The classic case of this is memory operands. 5846 5847 // memory is used to define read/write location for load/store 5848 // instruction defs. we can turn a memory op into an Address 5849 5850 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5851 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5852 5853 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5854 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5855 5856 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5857 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5858 5859 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5860 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5861 5862 // All of the memory operands. For the pipeline description. 5863 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5864 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5865 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5866 5867 5868 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5869 // operations. it allows the src to be either an iRegI or a (ConvL2I 5870 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5871 // can be elided because the 32-bit instruction will just employ the 5872 // lower 32 bits anyway. 5873 // 5874 // n.b. this does not elide all L2I conversions. if the truncated 5875 // value is consumed by more than one operation then the ConvL2I 5876 // cannot be bundled into the consuming nodes so an l2i gets planted 5877 // (actually a movw $dst $src) and the downstream instructions consume 5878 // the result of the l2i as an iRegI input. That's a shame since the 5879 // movw is actually redundant but its not too costly. 5880 5881 opclass iRegIorL2I(iRegI, iRegL2I); 5882 5883 //----------PIPELINE----------------------------------------------------------- 5884 // Rules which define the behavior of the target architectures pipeline. 5885 5886 // For specific pipelines, eg A53, define the stages of that pipeline 5887 //pipe_desc(ISS, EX1, EX2, WR); 5888 #define ISS S0 5889 #define EX1 S1 5890 #define EX2 S2 5891 #define WR S3 5892 5893 // Integer ALU reg operation 5894 pipeline %{ 5895 5896 attributes %{ 5897 // ARM instructions are of fixed length 5898 fixed_size_instructions; // Fixed size instructions TODO does 5899 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 5900 // ARM instructions come in 32-bit word units 5901 instruction_unit_size = 4; // An instruction is 4 bytes long 5902 instruction_fetch_unit_size = 64; // The processor fetches one line 5903 instruction_fetch_units = 1; // of 64 bytes 5904 5905 // List of nop instructions 5906 nops( MachNop ); 5907 %} 5908 5909 // We don't use an actual pipeline model so don't care about resources 5910 // or description. we do use pipeline classes to introduce fixed 5911 // latencies 5912 5913 //----------RESOURCES---------------------------------------------------------- 5914 // Resources are the functional units available to the machine 5915 5916 resources( INS0, INS1, INS01 = INS0 | INS1, 5917 ALU0, ALU1, ALU = ALU0 | ALU1, 5918 MAC, 5919 DIV, 5920 BRANCH, 5921 LDST, 5922 NEON_FP); 5923 5924 //----------PIPELINE DESCRIPTION----------------------------------------------- 5925 // Pipeline Description specifies the stages in the machine's pipeline 5926 5927 // Define the pipeline as a generic 6 stage pipeline 5928 pipe_desc(S0, S1, S2, S3, S4, S5); 5929 5930 //----------PIPELINE CLASSES--------------------------------------------------- 5931 // Pipeline Classes describe the stages in which input and output are 5932 // referenced by the hardware pipeline. 5933 5934 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5935 %{ 5936 single_instruction; 5937 src1 : S1(read); 5938 src2 : S2(read); 5939 dst : S5(write); 5940 INS01 : ISS; 5941 NEON_FP : S5; 5942 %} 5943 5944 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5945 %{ 5946 single_instruction; 5947 src1 : S1(read); 5948 src2 : S2(read); 5949 dst : S5(write); 5950 INS01 : ISS; 5951 NEON_FP : S5; 5952 %} 5953 5954 pipe_class fp_uop_s(vRegF dst, vRegF src) 5955 %{ 5956 single_instruction; 5957 src : S1(read); 5958 dst : S5(write); 5959 INS01 : ISS; 5960 NEON_FP : S5; 5961 %} 5962 5963 pipe_class fp_uop_d(vRegD dst, vRegD src) 5964 %{ 5965 single_instruction; 5966 src : S1(read); 5967 dst : S5(write); 5968 INS01 : ISS; 5969 NEON_FP : S5; 5970 %} 5971 5972 pipe_class fp_d2f(vRegF dst, vRegD src) 5973 %{ 5974 single_instruction; 5975 src : S1(read); 5976 dst : S5(write); 5977 INS01 : ISS; 5978 NEON_FP : S5; 5979 %} 5980 5981 pipe_class fp_f2d(vRegD dst, vRegF src) 5982 %{ 5983 single_instruction; 5984 src : S1(read); 5985 dst : S5(write); 5986 INS01 : ISS; 5987 NEON_FP : S5; 5988 %} 5989 5990 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5991 %{ 5992 single_instruction; 5993 src : S1(read); 5994 dst : S5(write); 5995 INS01 : ISS; 5996 NEON_FP : S5; 5997 %} 5998 5999 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6000 %{ 6001 single_instruction; 6002 src : S1(read); 6003 dst : S5(write); 6004 INS01 : ISS; 6005 NEON_FP : S5; 6006 %} 6007 6008 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6009 %{ 6010 single_instruction; 6011 src : S1(read); 6012 dst : S5(write); 6013 INS01 : ISS; 6014 NEON_FP : S5; 6015 %} 6016 6017 pipe_class fp_l2f(vRegF dst, iRegL src) 6018 %{ 6019 single_instruction; 6020 src : S1(read); 6021 dst : S5(write); 6022 INS01 : ISS; 6023 NEON_FP : S5; 6024 %} 6025 6026 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6027 %{ 6028 single_instruction; 6029 src : S1(read); 6030 dst : S5(write); 6031 INS01 : ISS; 6032 NEON_FP : S5; 6033 %} 6034 6035 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6036 %{ 6037 single_instruction; 6038 src : S1(read); 6039 dst : S5(write); 6040 INS01 : ISS; 6041 NEON_FP : S5; 6042 %} 6043 6044 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6045 %{ 6046 single_instruction; 6047 src : S1(read); 6048 dst : S5(write); 6049 INS01 : ISS; 6050 NEON_FP : S5; 6051 %} 6052 6053 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6054 %{ 6055 single_instruction; 6056 src : S1(read); 6057 dst : S5(write); 6058 INS01 : ISS; 6059 NEON_FP : S5; 6060 %} 6061 6062 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6063 %{ 6064 single_instruction; 6065 src1 : S1(read); 6066 src2 : S2(read); 6067 dst : S5(write); 6068 INS0 : ISS; 6069 NEON_FP : S5; 6070 %} 6071 6072 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6073 %{ 6074 single_instruction; 6075 src1 : S1(read); 6076 src2 : S2(read); 6077 dst : S5(write); 6078 INS0 : ISS; 6079 NEON_FP : S5; 6080 %} 6081 6082 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6083 %{ 6084 single_instruction; 6085 cr : S1(read); 6086 src1 : S1(read); 6087 src2 : S1(read); 6088 dst : S3(write); 6089 INS01 : ISS; 6090 NEON_FP : S3; 6091 %} 6092 6093 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6094 %{ 6095 single_instruction; 6096 cr : S1(read); 6097 src1 : S1(read); 6098 src2 : S1(read); 6099 dst : S3(write); 6100 INS01 : ISS; 6101 NEON_FP : S3; 6102 %} 6103 6104 pipe_class fp_imm_s(vRegF dst) 6105 %{ 6106 single_instruction; 6107 dst : S3(write); 6108 INS01 : ISS; 6109 NEON_FP : S3; 6110 %} 6111 6112 pipe_class fp_imm_d(vRegD dst) 6113 %{ 6114 single_instruction; 6115 dst : S3(write); 6116 INS01 : ISS; 6117 NEON_FP : S3; 6118 %} 6119 6120 pipe_class fp_load_constant_s(vRegF dst) 6121 %{ 6122 single_instruction; 6123 dst : S4(write); 6124 INS01 : ISS; 6125 NEON_FP : S4; 6126 %} 6127 6128 pipe_class fp_load_constant_d(vRegD dst) 6129 %{ 6130 single_instruction; 6131 dst : S4(write); 6132 INS01 : ISS; 6133 NEON_FP : S4; 6134 %} 6135 6136 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6137 %{ 6138 single_instruction; 6139 dst : S5(write); 6140 src1 : S1(read); 6141 src2 : S1(read); 6142 INS01 : ISS; 6143 NEON_FP : S5; 6144 %} 6145 6146 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6147 %{ 6148 single_instruction; 6149 dst : S5(write); 6150 src1 : S1(read); 6151 src2 : S1(read); 6152 INS0 : ISS; 6153 NEON_FP : S5; 6154 %} 6155 6156 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6157 %{ 6158 single_instruction; 6159 dst : S5(write); 6160 src1 : S1(read); 6161 src2 : S1(read); 6162 dst : S1(read); 6163 INS01 : ISS; 6164 NEON_FP : S5; 6165 %} 6166 6167 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6168 %{ 6169 single_instruction; 6170 dst : S5(write); 6171 src1 : S1(read); 6172 src2 : S1(read); 6173 dst : S1(read); 6174 INS0 : ISS; 6175 NEON_FP : S5; 6176 %} 6177 6178 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6179 %{ 6180 single_instruction; 6181 dst : S4(write); 6182 src1 : S2(read); 6183 src2 : S2(read); 6184 INS01 : ISS; 6185 NEON_FP : S4; 6186 %} 6187 6188 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6189 %{ 6190 single_instruction; 6191 dst : S4(write); 6192 src1 : S2(read); 6193 src2 : S2(read); 6194 INS0 : ISS; 6195 NEON_FP : S4; 6196 %} 6197 6198 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6199 %{ 6200 single_instruction; 6201 dst : S3(write); 6202 src1 : S2(read); 6203 src2 : S2(read); 6204 INS01 : ISS; 6205 NEON_FP : S3; 6206 %} 6207 6208 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6209 %{ 6210 single_instruction; 6211 dst : S3(write); 6212 src1 : S2(read); 6213 src2 : S2(read); 6214 INS0 : ISS; 6215 NEON_FP : S3; 6216 %} 6217 6218 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6219 %{ 6220 single_instruction; 6221 dst : S3(write); 6222 src : S1(read); 6223 shift : S1(read); 6224 INS01 : ISS; 6225 NEON_FP : S3; 6226 %} 6227 6228 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6229 %{ 6230 single_instruction; 6231 dst : S3(write); 6232 src : S1(read); 6233 shift : S1(read); 6234 INS0 : ISS; 6235 NEON_FP : S3; 6236 %} 6237 6238 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6239 %{ 6240 single_instruction; 6241 dst : S3(write); 6242 src : S1(read); 6243 INS01 : ISS; 6244 NEON_FP : S3; 6245 %} 6246 6247 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6248 %{ 6249 single_instruction; 6250 dst : S3(write); 6251 src : S1(read); 6252 INS0 : ISS; 6253 NEON_FP : S3; 6254 %} 6255 6256 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6257 %{ 6258 single_instruction; 6259 dst : S5(write); 6260 src1 : S1(read); 6261 src2 : S1(read); 6262 INS01 : ISS; 6263 NEON_FP : S5; 6264 %} 6265 6266 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6267 %{ 6268 single_instruction; 6269 dst : S5(write); 6270 src1 : S1(read); 6271 src2 : S1(read); 6272 INS0 : ISS; 6273 NEON_FP : S5; 6274 %} 6275 6276 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6277 %{ 6278 single_instruction; 6279 dst : S5(write); 6280 src1 : S1(read); 6281 src2 : S1(read); 6282 INS0 : ISS; 6283 NEON_FP : S5; 6284 %} 6285 6286 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6287 %{ 6288 single_instruction; 6289 dst : S5(write); 6290 src1 : S1(read); 6291 src2 : S1(read); 6292 INS0 : ISS; 6293 NEON_FP : S5; 6294 %} 6295 6296 pipe_class vsqrt_fp128(vecX dst, vecX src) 6297 %{ 6298 single_instruction; 6299 dst : S5(write); 6300 src : S1(read); 6301 INS0 : ISS; 6302 NEON_FP : S5; 6303 %} 6304 6305 pipe_class vunop_fp64(vecD dst, vecD src) 6306 %{ 6307 single_instruction; 6308 dst : S5(write); 6309 src : S1(read); 6310 INS01 : ISS; 6311 NEON_FP : S5; 6312 %} 6313 6314 pipe_class vunop_fp128(vecX dst, vecX src) 6315 %{ 6316 single_instruction; 6317 dst : S5(write); 6318 src : S1(read); 6319 INS0 : ISS; 6320 NEON_FP : S5; 6321 %} 6322 6323 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6324 %{ 6325 single_instruction; 6326 dst : S3(write); 6327 src : S1(read); 6328 INS01 : ISS; 6329 NEON_FP : S3; 6330 %} 6331 6332 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6333 %{ 6334 single_instruction; 6335 dst : S3(write); 6336 src : S1(read); 6337 INS01 : ISS; 6338 NEON_FP : S3; 6339 %} 6340 6341 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6342 %{ 6343 single_instruction; 6344 dst : S3(write); 6345 src : S1(read); 6346 INS01 : ISS; 6347 NEON_FP : S3; 6348 %} 6349 6350 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6351 %{ 6352 single_instruction; 6353 dst : S3(write); 6354 src : S1(read); 6355 INS01 : ISS; 6356 NEON_FP : S3; 6357 %} 6358 6359 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6360 %{ 6361 single_instruction; 6362 dst : S3(write); 6363 src : S1(read); 6364 INS01 : ISS; 6365 NEON_FP : S3; 6366 %} 6367 6368 pipe_class vmovi_reg_imm64(vecD dst) 6369 %{ 6370 single_instruction; 6371 dst : S3(write); 6372 INS01 : ISS; 6373 NEON_FP : S3; 6374 %} 6375 6376 pipe_class vmovi_reg_imm128(vecX dst) 6377 %{ 6378 single_instruction; 6379 dst : S3(write); 6380 INS0 : ISS; 6381 NEON_FP : S3; 6382 %} 6383 6384 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6385 %{ 6386 single_instruction; 6387 dst : S5(write); 6388 mem : ISS(read); 6389 INS01 : ISS; 6390 NEON_FP : S3; 6391 %} 6392 6393 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6394 %{ 6395 single_instruction; 6396 dst : S5(write); 6397 mem : ISS(read); 6398 INS01 : ISS; 6399 NEON_FP : S3; 6400 %} 6401 6402 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6403 %{ 6404 single_instruction; 6405 mem : ISS(read); 6406 src : S2(read); 6407 INS01 : ISS; 6408 NEON_FP : S3; 6409 %} 6410 6411 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6412 %{ 6413 single_instruction; 6414 mem : ISS(read); 6415 src : S2(read); 6416 INS01 : ISS; 6417 NEON_FP : S3; 6418 %} 6419 6420 //------- Integer ALU operations -------------------------- 6421 6422 // Integer ALU reg-reg operation 6423 // Operands needed in EX1, result generated in EX2 6424 // Eg. ADD x0, x1, x2 6425 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6426 %{ 6427 single_instruction; 6428 dst : EX2(write); 6429 src1 : EX1(read); 6430 src2 : EX1(read); 6431 INS01 : ISS; // Dual issue as instruction 0 or 1 6432 ALU : EX2; 6433 %} 6434 6435 // Integer ALU reg-reg operation with constant shift 6436 // Shifted register must be available in LATE_ISS instead of EX1 6437 // Eg. ADD x0, x1, x2, LSL #2 6438 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6439 %{ 6440 single_instruction; 6441 dst : EX2(write); 6442 src1 : EX1(read); 6443 src2 : ISS(read); 6444 INS01 : ISS; 6445 ALU : EX2; 6446 %} 6447 6448 // Integer ALU reg operation with constant shift 6449 // Eg. LSL x0, x1, #shift 6450 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6451 %{ 6452 single_instruction; 6453 dst : EX2(write); 6454 src1 : ISS(read); 6455 INS01 : ISS; 6456 ALU : EX2; 6457 %} 6458 6459 // Integer ALU reg-reg operation with variable shift 6460 // Both operands must be available in LATE_ISS instead of EX1 6461 // Result is available in EX1 instead of EX2 6462 // Eg. LSLV x0, x1, x2 6463 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6464 %{ 6465 single_instruction; 6466 dst : EX1(write); 6467 src1 : ISS(read); 6468 src2 : ISS(read); 6469 INS01 : ISS; 6470 ALU : EX1; 6471 %} 6472 6473 // Integer ALU reg-reg operation with extract 6474 // As for _vshift above, but result generated in EX2 6475 // Eg. EXTR x0, x1, x2, #N 6476 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6477 %{ 6478 single_instruction; 6479 dst : EX2(write); 6480 src1 : ISS(read); 6481 src2 : ISS(read); 6482 INS1 : ISS; // Can only dual issue as Instruction 1 6483 ALU : EX1; 6484 %} 6485 6486 // Integer ALU reg operation 6487 // Eg. NEG x0, x1 6488 pipe_class ialu_reg(iRegI dst, iRegI src) 6489 %{ 6490 single_instruction; 6491 dst : EX2(write); 6492 src : EX1(read); 6493 INS01 : ISS; 6494 ALU : EX2; 6495 %} 6496 6497 // Integer ALU reg mmediate operation 6498 // Eg. ADD x0, x1, #N 6499 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6500 %{ 6501 single_instruction; 6502 dst : EX2(write); 6503 src1 : EX1(read); 6504 INS01 : ISS; 6505 ALU : EX2; 6506 %} 6507 6508 // Integer ALU immediate operation (no source operands) 6509 // Eg. MOV x0, #N 6510 pipe_class ialu_imm(iRegI dst) 6511 %{ 6512 single_instruction; 6513 dst : EX1(write); 6514 INS01 : ISS; 6515 ALU : EX1; 6516 %} 6517 6518 //------- Compare operation ------------------------------- 6519 6520 // Compare reg-reg 6521 // Eg. CMP x0, x1 6522 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6523 %{ 6524 single_instruction; 6525 // fixed_latency(16); 6526 cr : EX2(write); 6527 op1 : EX1(read); 6528 op2 : EX1(read); 6529 INS01 : ISS; 6530 ALU : EX2; 6531 %} 6532 6533 // Compare reg-reg 6534 // Eg. CMP x0, #N 6535 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6536 %{ 6537 single_instruction; 6538 // fixed_latency(16); 6539 cr : EX2(write); 6540 op1 : EX1(read); 6541 INS01 : ISS; 6542 ALU : EX2; 6543 %} 6544 6545 //------- Conditional instructions ------------------------ 6546 6547 // Conditional no operands 6548 // Eg. CSINC x0, zr, zr, <cond> 6549 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6550 %{ 6551 single_instruction; 6552 cr : EX1(read); 6553 dst : EX2(write); 6554 INS01 : ISS; 6555 ALU : EX2; 6556 %} 6557 6558 // Conditional 2 operand 6559 // EG. CSEL X0, X1, X2, <cond> 6560 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6561 %{ 6562 single_instruction; 6563 cr : EX1(read); 6564 src1 : EX1(read); 6565 src2 : EX1(read); 6566 dst : EX2(write); 6567 INS01 : ISS; 6568 ALU : EX2; 6569 %} 6570 6571 // Conditional 2 operand 6572 // EG. CSEL X0, X1, X2, <cond> 6573 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6574 %{ 6575 single_instruction; 6576 cr : EX1(read); 6577 src : EX1(read); 6578 dst : EX2(write); 6579 INS01 : ISS; 6580 ALU : EX2; 6581 %} 6582 6583 //------- Multiply pipeline operations -------------------- 6584 6585 // Multiply reg-reg 6586 // Eg. MUL w0, w1, w2 6587 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6588 %{ 6589 single_instruction; 6590 dst : WR(write); 6591 src1 : ISS(read); 6592 src2 : ISS(read); 6593 INS01 : ISS; 6594 MAC : WR; 6595 %} 6596 6597 // Multiply accumulate 6598 // Eg. MADD w0, w1, w2, w3 6599 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6600 %{ 6601 single_instruction; 6602 dst : WR(write); 6603 src1 : ISS(read); 6604 src2 : ISS(read); 6605 src3 : ISS(read); 6606 INS01 : ISS; 6607 MAC : WR; 6608 %} 6609 6610 // Eg. MUL w0, w1, w2 6611 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6612 %{ 6613 single_instruction; 6614 fixed_latency(3); // Maximum latency for 64 bit mul 6615 dst : WR(write); 6616 src1 : ISS(read); 6617 src2 : ISS(read); 6618 INS01 : ISS; 6619 MAC : WR; 6620 %} 6621 6622 // Multiply accumulate 6623 // Eg. MADD w0, w1, w2, w3 6624 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6625 %{ 6626 single_instruction; 6627 fixed_latency(3); // Maximum latency for 64 bit mul 6628 dst : WR(write); 6629 src1 : ISS(read); 6630 src2 : ISS(read); 6631 src3 : ISS(read); 6632 INS01 : ISS; 6633 MAC : WR; 6634 %} 6635 6636 //------- Divide pipeline operations -------------------- 6637 6638 // Eg. SDIV w0, w1, w2 6639 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6640 %{ 6641 single_instruction; 6642 fixed_latency(8); // Maximum latency for 32 bit divide 6643 dst : WR(write); 6644 src1 : ISS(read); 6645 src2 : ISS(read); 6646 INS0 : ISS; // Can only dual issue as instruction 0 6647 DIV : WR; 6648 %} 6649 6650 // Eg. SDIV x0, x1, x2 6651 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6652 %{ 6653 single_instruction; 6654 fixed_latency(16); // Maximum latency for 64 bit divide 6655 dst : WR(write); 6656 src1 : ISS(read); 6657 src2 : ISS(read); 6658 INS0 : ISS; // Can only dual issue as instruction 0 6659 DIV : WR; 6660 %} 6661 6662 //------- Load pipeline operations ------------------------ 6663 6664 // Load - prefetch 6665 // Eg. PFRM <mem> 6666 pipe_class iload_prefetch(memory mem) 6667 %{ 6668 single_instruction; 6669 mem : ISS(read); 6670 INS01 : ISS; 6671 LDST : WR; 6672 %} 6673 6674 // Load - reg, mem 6675 // Eg. LDR x0, <mem> 6676 pipe_class iload_reg_mem(iRegI dst, memory mem) 6677 %{ 6678 single_instruction; 6679 dst : WR(write); 6680 mem : ISS(read); 6681 INS01 : ISS; 6682 LDST : WR; 6683 %} 6684 6685 // Load - reg, reg 6686 // Eg. LDR x0, [sp, x1] 6687 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6688 %{ 6689 single_instruction; 6690 dst : WR(write); 6691 src : ISS(read); 6692 INS01 : ISS; 6693 LDST : WR; 6694 %} 6695 6696 //------- Store pipeline operations ----------------------- 6697 6698 // Store - zr, mem 6699 // Eg. STR zr, <mem> 6700 pipe_class istore_mem(memory mem) 6701 %{ 6702 single_instruction; 6703 mem : ISS(read); 6704 INS01 : ISS; 6705 LDST : WR; 6706 %} 6707 6708 // Store - reg, mem 6709 // Eg. STR x0, <mem> 6710 pipe_class istore_reg_mem(iRegI src, memory mem) 6711 %{ 6712 single_instruction; 6713 mem : ISS(read); 6714 src : EX2(read); 6715 INS01 : ISS; 6716 LDST : WR; 6717 %} 6718 6719 // Store - reg, reg 6720 // Eg. STR x0, [sp, x1] 6721 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6722 %{ 6723 single_instruction; 6724 dst : ISS(read); 6725 src : EX2(read); 6726 INS01 : ISS; 6727 LDST : WR; 6728 %} 6729 6730 //------- Store pipeline operations ----------------------- 6731 6732 // Branch 6733 pipe_class pipe_branch() 6734 %{ 6735 single_instruction; 6736 INS01 : ISS; 6737 BRANCH : EX1; 6738 %} 6739 6740 // Conditional branch 6741 pipe_class pipe_branch_cond(rFlagsReg cr) 6742 %{ 6743 single_instruction; 6744 cr : EX1(read); 6745 INS01 : ISS; 6746 BRANCH : EX1; 6747 %} 6748 6749 // Compare & Branch 6750 // EG. CBZ/CBNZ 6751 pipe_class pipe_cmp_branch(iRegI op1) 6752 %{ 6753 single_instruction; 6754 op1 : EX1(read); 6755 INS01 : ISS; 6756 BRANCH : EX1; 6757 %} 6758 6759 //------- Synchronisation operations ---------------------- 6760 6761 // Any operation requiring serialization. 6762 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6763 pipe_class pipe_serial() 6764 %{ 6765 single_instruction; 6766 force_serialization; 6767 fixed_latency(16); 6768 INS01 : ISS(2); // Cannot dual issue with any other instruction 6769 LDST : WR; 6770 %} 6771 6772 // Generic big/slow expanded idiom - also serialized 6773 pipe_class pipe_slow() 6774 %{ 6775 instruction_count(10); 6776 multiple_bundles; 6777 force_serialization; 6778 fixed_latency(16); 6779 INS01 : ISS(2); // Cannot dual issue with any other instruction 6780 LDST : WR; 6781 %} 6782 6783 // Empty pipeline class 6784 pipe_class pipe_class_empty() 6785 %{ 6786 single_instruction; 6787 fixed_latency(0); 6788 %} 6789 6790 // Default pipeline class. 6791 pipe_class pipe_class_default() 6792 %{ 6793 single_instruction; 6794 fixed_latency(2); 6795 %} 6796 6797 // Pipeline class for compares. 6798 pipe_class pipe_class_compare() 6799 %{ 6800 single_instruction; 6801 fixed_latency(16); 6802 %} 6803 6804 // Pipeline class for memory operations. 6805 pipe_class pipe_class_memory() 6806 %{ 6807 single_instruction; 6808 fixed_latency(16); 6809 %} 6810 6811 // Pipeline class for call. 6812 pipe_class pipe_class_call() 6813 %{ 6814 single_instruction; 6815 fixed_latency(100); 6816 %} 6817 6818 // Define the class for the Nop node. 6819 define %{ 6820 MachNop = pipe_class_empty; 6821 %} 6822 6823 %} 6824 //----------INSTRUCTIONS------------------------------------------------------- 6825 // 6826 // match -- States which machine-independent subtree may be replaced 6827 // by this instruction. 6828 // ins_cost -- The estimated cost of this instruction is used by instruction 6829 // selection to identify a minimum cost tree of machine 6830 // instructions that matches a tree of machine-independent 6831 // instructions. 6832 // format -- A string providing the disassembly for this instruction. 6833 // The value of an instruction's operand may be inserted 6834 // by referring to it with a '$' prefix. 6835 // opcode -- Three instruction opcodes may be provided. These are referred 6836 // to within an encode class as $primary, $secondary, and $tertiary 6837 // rrspectively. The primary opcode is commonly used to 6838 // indicate the type of machine instruction, while secondary 6839 // and tertiary are often used for prefix options or addressing 6840 // modes. 6841 // ins_encode -- A list of encode classes with parameters. The encode class 6842 // name must have been defined in an 'enc_class' specification 6843 // in the encode section of the architecture description. 6844 6845 // ============================================================================ 6846 // Memory (Load/Store) Instructions 6847 6848 // Load Instructions 6849 6850 // Load Byte (8 bit signed) 6851 instruct loadB(iRegINoSp dst, memory1 mem) 6852 %{ 6853 match(Set dst (LoadB mem)); 6854 predicate(!needs_acquiring_load(n)); 6855 6856 ins_cost(4 * INSN_COST); 6857 format %{ "ldrsbw $dst, $mem\t# byte" %} 6858 6859 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6860 6861 ins_pipe(iload_reg_mem); 6862 %} 6863 6864 // Load Byte (8 bit signed) into long 6865 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6866 %{ 6867 match(Set dst (ConvI2L (LoadB mem))); 6868 predicate(!needs_acquiring_load(n->in(1))); 6869 6870 ins_cost(4 * INSN_COST); 6871 format %{ "ldrsb $dst, $mem\t# byte" %} 6872 6873 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6874 6875 ins_pipe(iload_reg_mem); 6876 %} 6877 6878 // Load Byte (8 bit unsigned) 6879 instruct loadUB(iRegINoSp dst, memory1 mem) 6880 %{ 6881 match(Set dst (LoadUB mem)); 6882 predicate(!needs_acquiring_load(n)); 6883 6884 ins_cost(4 * INSN_COST); 6885 format %{ "ldrbw $dst, $mem\t# byte" %} 6886 6887 ins_encode(aarch64_enc_ldrb(dst, mem)); 6888 6889 ins_pipe(iload_reg_mem); 6890 %} 6891 6892 // Load Byte (8 bit unsigned) into long 6893 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6894 %{ 6895 match(Set dst (ConvI2L (LoadUB mem))); 6896 predicate(!needs_acquiring_load(n->in(1))); 6897 6898 ins_cost(4 * INSN_COST); 6899 format %{ "ldrb $dst, $mem\t# byte" %} 6900 6901 ins_encode(aarch64_enc_ldrb(dst, mem)); 6902 6903 ins_pipe(iload_reg_mem); 6904 %} 6905 6906 // Load Short (16 bit signed) 6907 instruct loadS(iRegINoSp dst, memory2 mem) 6908 %{ 6909 match(Set dst (LoadS mem)); 6910 predicate(!needs_acquiring_load(n)); 6911 6912 ins_cost(4 * INSN_COST); 6913 format %{ "ldrshw $dst, $mem\t# short" %} 6914 6915 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6916 6917 ins_pipe(iload_reg_mem); 6918 %} 6919 6920 // Load Short (16 bit signed) into long 6921 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6922 %{ 6923 match(Set dst (ConvI2L (LoadS mem))); 6924 predicate(!needs_acquiring_load(n->in(1))); 6925 6926 ins_cost(4 * INSN_COST); 6927 format %{ "ldrsh $dst, $mem\t# short" %} 6928 6929 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6930 6931 ins_pipe(iload_reg_mem); 6932 %} 6933 6934 // Load Char (16 bit unsigned) 6935 instruct loadUS(iRegINoSp dst, memory2 mem) 6936 %{ 6937 match(Set dst (LoadUS mem)); 6938 predicate(!needs_acquiring_load(n)); 6939 6940 ins_cost(4 * INSN_COST); 6941 format %{ "ldrh $dst, $mem\t# short" %} 6942 6943 ins_encode(aarch64_enc_ldrh(dst, mem)); 6944 6945 ins_pipe(iload_reg_mem); 6946 %} 6947 6948 // Load Short/Char (16 bit unsigned) into long 6949 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6950 %{ 6951 match(Set dst (ConvI2L (LoadUS mem))); 6952 predicate(!needs_acquiring_load(n->in(1))); 6953 6954 ins_cost(4 * INSN_COST); 6955 format %{ "ldrh $dst, $mem\t# short" %} 6956 6957 ins_encode(aarch64_enc_ldrh(dst, mem)); 6958 6959 ins_pipe(iload_reg_mem); 6960 %} 6961 6962 // Load Integer (32 bit signed) 6963 instruct loadI(iRegINoSp dst, memory4 mem) 6964 %{ 6965 match(Set dst (LoadI mem)); 6966 predicate(!needs_acquiring_load(n)); 6967 6968 ins_cost(4 * INSN_COST); 6969 format %{ "ldrw $dst, $mem\t# int" %} 6970 6971 ins_encode(aarch64_enc_ldrw(dst, mem)); 6972 6973 ins_pipe(iload_reg_mem); 6974 %} 6975 6976 // Load Integer (32 bit signed) into long 6977 instruct loadI2L(iRegLNoSp dst, memory4 mem) 6978 %{ 6979 match(Set dst (ConvI2L (LoadI mem))); 6980 predicate(!needs_acquiring_load(n->in(1))); 6981 6982 ins_cost(4 * INSN_COST); 6983 format %{ "ldrsw $dst, $mem\t# int" %} 6984 6985 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6986 6987 ins_pipe(iload_reg_mem); 6988 %} 6989 6990 // Load Integer (32 bit unsigned) into long 6991 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 6992 %{ 6993 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6994 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6995 6996 ins_cost(4 * INSN_COST); 6997 format %{ "ldrw $dst, $mem\t# int" %} 6998 6999 ins_encode(aarch64_enc_ldrw(dst, mem)); 7000 7001 ins_pipe(iload_reg_mem); 7002 %} 7003 7004 // Load Long (64 bit signed) 7005 instruct loadL(iRegLNoSp dst, memory8 mem) 7006 %{ 7007 match(Set dst (LoadL mem)); 7008 predicate(!needs_acquiring_load(n)); 7009 7010 ins_cost(4 * INSN_COST); 7011 format %{ "ldr $dst, $mem\t# int" %} 7012 7013 ins_encode(aarch64_enc_ldr(dst, mem)); 7014 7015 ins_pipe(iload_reg_mem); 7016 %} 7017 7018 // Load Range 7019 instruct loadRange(iRegINoSp dst, memory4 mem) 7020 %{ 7021 match(Set dst (LoadRange mem)); 7022 7023 ins_cost(4 * INSN_COST); 7024 format %{ "ldrw $dst, $mem\t# range" %} 7025 7026 ins_encode(aarch64_enc_ldrw(dst, mem)); 7027 7028 ins_pipe(iload_reg_mem); 7029 %} 7030 7031 // Load Pointer 7032 instruct loadP(iRegPNoSp dst, memory8 mem) 7033 %{ 7034 match(Set dst (LoadP mem)); 7035 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7036 7037 ins_cost(4 * INSN_COST); 7038 format %{ "ldr $dst, $mem\t# ptr" %} 7039 7040 ins_encode(aarch64_enc_ldr(dst, mem)); 7041 7042 ins_pipe(iload_reg_mem); 7043 %} 7044 7045 // Load Compressed Pointer 7046 instruct loadN(iRegNNoSp dst, memory4 mem) 7047 %{ 7048 match(Set dst (LoadN mem)); 7049 predicate(!needs_acquiring_load(n)); 7050 7051 ins_cost(4 * INSN_COST); 7052 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7053 7054 ins_encode(aarch64_enc_ldrw(dst, mem)); 7055 7056 ins_pipe(iload_reg_mem); 7057 %} 7058 7059 // Load Klass Pointer 7060 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7061 %{ 7062 match(Set dst (LoadKlass mem)); 7063 predicate(!needs_acquiring_load(n)); 7064 7065 ins_cost(4 * INSN_COST); 7066 format %{ "ldr $dst, $mem\t# class" %} 7067 7068 ins_encode(aarch64_enc_ldr(dst, mem)); 7069 7070 ins_pipe(iload_reg_mem); 7071 %} 7072 7073 // Load Narrow Klass Pointer 7074 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7075 %{ 7076 match(Set dst (LoadNKlass mem)); 7077 predicate(!needs_acquiring_load(n)); 7078 7079 ins_cost(4 * INSN_COST); 7080 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7081 7082 ins_encode(aarch64_enc_ldrw(dst, mem)); 7083 7084 ins_pipe(iload_reg_mem); 7085 %} 7086 7087 // Load Float 7088 instruct loadF(vRegF dst, memory4 mem) 7089 %{ 7090 match(Set dst (LoadF mem)); 7091 predicate(!needs_acquiring_load(n)); 7092 7093 ins_cost(4 * INSN_COST); 7094 format %{ "ldrs $dst, $mem\t# float" %} 7095 7096 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7097 7098 ins_pipe(pipe_class_memory); 7099 %} 7100 7101 // Load Double 7102 instruct loadD(vRegD dst, memory8 mem) 7103 %{ 7104 match(Set dst (LoadD mem)); 7105 predicate(!needs_acquiring_load(n)); 7106 7107 ins_cost(4 * INSN_COST); 7108 format %{ "ldrd $dst, $mem\t# double" %} 7109 7110 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7111 7112 ins_pipe(pipe_class_memory); 7113 %} 7114 7115 7116 // Load Int Constant 7117 instruct loadConI(iRegINoSp dst, immI src) 7118 %{ 7119 match(Set dst src); 7120 7121 ins_cost(INSN_COST); 7122 format %{ "mov $dst, $src\t# int" %} 7123 7124 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7125 7126 ins_pipe(ialu_imm); 7127 %} 7128 7129 // Load Long Constant 7130 instruct loadConL(iRegLNoSp dst, immL src) 7131 %{ 7132 match(Set dst src); 7133 7134 ins_cost(INSN_COST); 7135 format %{ "mov $dst, $src\t# int64_t" %} 7136 7137 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7138 7139 ins_pipe(ialu_imm); 7140 %} 7141 7142 // Load Pointer Constant 7143 7144 instruct loadConP(iRegPNoSp dst, immP con) 7145 %{ 7146 match(Set dst con); 7147 7148 ins_cost(INSN_COST * 4); 7149 format %{ 7150 "mov $dst, $con\t# ptr\n\t" 7151 %} 7152 7153 ins_encode(aarch64_enc_mov_p(dst, con)); 7154 7155 ins_pipe(ialu_imm); 7156 %} 7157 7158 // Load Null Pointer Constant 7159 7160 instruct loadConP0(iRegPNoSp dst, immP0 con) 7161 %{ 7162 match(Set dst con); 7163 7164 ins_cost(INSN_COST); 7165 format %{ "mov $dst, $con\t# NULL ptr" %} 7166 7167 ins_encode(aarch64_enc_mov_p0(dst, con)); 7168 7169 ins_pipe(ialu_imm); 7170 %} 7171 7172 // Load Pointer Constant One 7173 7174 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7175 %{ 7176 match(Set dst con); 7177 7178 ins_cost(INSN_COST); 7179 format %{ "mov $dst, $con\t# NULL ptr" %} 7180 7181 ins_encode(aarch64_enc_mov_p1(dst, con)); 7182 7183 ins_pipe(ialu_imm); 7184 %} 7185 7186 // Load Byte Map Base Constant 7187 7188 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7189 %{ 7190 match(Set dst con); 7191 7192 ins_cost(INSN_COST); 7193 format %{ "adr $dst, $con\t# Byte Map Base" %} 7194 7195 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7196 7197 ins_pipe(ialu_imm); 7198 %} 7199 7200 // Load Narrow Pointer Constant 7201 7202 instruct loadConN(iRegNNoSp dst, immN con) 7203 %{ 7204 match(Set dst con); 7205 7206 ins_cost(INSN_COST * 4); 7207 format %{ "mov $dst, $con\t# compressed ptr" %} 7208 7209 ins_encode(aarch64_enc_mov_n(dst, con)); 7210 7211 ins_pipe(ialu_imm); 7212 %} 7213 7214 // Load Narrow Null Pointer Constant 7215 7216 instruct loadConN0(iRegNNoSp dst, immN0 con) 7217 %{ 7218 match(Set dst con); 7219 7220 ins_cost(INSN_COST); 7221 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7222 7223 ins_encode(aarch64_enc_mov_n0(dst, con)); 7224 7225 ins_pipe(ialu_imm); 7226 %} 7227 7228 // Load Narrow Klass Constant 7229 7230 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7231 %{ 7232 match(Set dst con); 7233 7234 ins_cost(INSN_COST); 7235 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7236 7237 ins_encode(aarch64_enc_mov_nk(dst, con)); 7238 7239 ins_pipe(ialu_imm); 7240 %} 7241 7242 // Load Packed Float Constant 7243 7244 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7245 match(Set dst con); 7246 ins_cost(INSN_COST * 4); 7247 format %{ "fmovs $dst, $con"%} 7248 ins_encode %{ 7249 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7250 %} 7251 7252 ins_pipe(fp_imm_s); 7253 %} 7254 7255 // Load Float Constant 7256 7257 instruct loadConF(vRegF dst, immF con) %{ 7258 match(Set dst con); 7259 7260 ins_cost(INSN_COST * 4); 7261 7262 format %{ 7263 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7264 %} 7265 7266 ins_encode %{ 7267 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7268 %} 7269 7270 ins_pipe(fp_load_constant_s); 7271 %} 7272 7273 // Load Packed Double Constant 7274 7275 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7276 match(Set dst con); 7277 ins_cost(INSN_COST); 7278 format %{ "fmovd $dst, $con"%} 7279 ins_encode %{ 7280 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7281 %} 7282 7283 ins_pipe(fp_imm_d); 7284 %} 7285 7286 // Load Double Constant 7287 7288 instruct loadConD(vRegD dst, immD con) %{ 7289 match(Set dst con); 7290 7291 ins_cost(INSN_COST * 5); 7292 format %{ 7293 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7294 %} 7295 7296 ins_encode %{ 7297 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7298 %} 7299 7300 ins_pipe(fp_load_constant_d); 7301 %} 7302 7303 // Store Instructions 7304 7305 // Store CMS card-mark Immediate 7306 instruct storeimmCM0(immI0 zero, memory1 mem) 7307 %{ 7308 match(Set mem (StoreCM mem zero)); 7309 7310 ins_cost(INSN_COST); 7311 format %{ "storestore (elided)\n\t" 7312 "strb zr, $mem\t# byte" %} 7313 7314 ins_encode(aarch64_enc_strb0(mem)); 7315 7316 ins_pipe(istore_mem); 7317 %} 7318 7319 // Store CMS card-mark Immediate with intervening StoreStore 7320 // needed when using CMS with no conditional card marking 7321 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7322 %{ 7323 match(Set mem (StoreCM mem zero)); 7324 7325 ins_cost(INSN_COST * 2); 7326 format %{ "storestore\n\t" 7327 "dmb ishst" 7328 "\n\tstrb zr, $mem\t# byte" %} 7329 7330 ins_encode(aarch64_enc_strb0_ordered(mem)); 7331 7332 ins_pipe(istore_mem); 7333 %} 7334 7335 // Store Byte 7336 instruct storeB(iRegIorL2I src, memory1 mem) 7337 %{ 7338 match(Set mem (StoreB mem src)); 7339 predicate(!needs_releasing_store(n)); 7340 7341 ins_cost(INSN_COST); 7342 format %{ "strb $src, $mem\t# byte" %} 7343 7344 ins_encode(aarch64_enc_strb(src, mem)); 7345 7346 ins_pipe(istore_reg_mem); 7347 %} 7348 7349 7350 instruct storeimmB0(immI0 zero, memory1 mem) 7351 %{ 7352 match(Set mem (StoreB mem zero)); 7353 predicate(!needs_releasing_store(n)); 7354 7355 ins_cost(INSN_COST); 7356 format %{ "strb rscractch2, $mem\t# byte" %} 7357 7358 ins_encode(aarch64_enc_strb0(mem)); 7359 7360 ins_pipe(istore_mem); 7361 %} 7362 7363 // Store Char/Short 7364 instruct storeC(iRegIorL2I src, memory2 mem) 7365 %{ 7366 match(Set mem (StoreC mem src)); 7367 predicate(!needs_releasing_store(n)); 7368 7369 ins_cost(INSN_COST); 7370 format %{ "strh $src, $mem\t# short" %} 7371 7372 ins_encode(aarch64_enc_strh(src, mem)); 7373 7374 ins_pipe(istore_reg_mem); 7375 %} 7376 7377 instruct storeimmC0(immI0 zero, memory2 mem) 7378 %{ 7379 match(Set mem (StoreC mem zero)); 7380 predicate(!needs_releasing_store(n)); 7381 7382 ins_cost(INSN_COST); 7383 format %{ "strh zr, $mem\t# short" %} 7384 7385 ins_encode(aarch64_enc_strh0(mem)); 7386 7387 ins_pipe(istore_mem); 7388 %} 7389 7390 // Store Integer 7391 7392 instruct storeI(iRegIorL2I src, memory4 mem) 7393 %{ 7394 match(Set mem(StoreI mem src)); 7395 predicate(!needs_releasing_store(n)); 7396 7397 ins_cost(INSN_COST); 7398 format %{ "strw $src, $mem\t# int" %} 7399 7400 ins_encode(aarch64_enc_strw(src, mem)); 7401 7402 ins_pipe(istore_reg_mem); 7403 %} 7404 7405 instruct storeimmI0(immI0 zero, memory4 mem) 7406 %{ 7407 match(Set mem(StoreI mem zero)); 7408 predicate(!needs_releasing_store(n)); 7409 7410 ins_cost(INSN_COST); 7411 format %{ "strw zr, $mem\t# int" %} 7412 7413 ins_encode(aarch64_enc_strw0(mem)); 7414 7415 ins_pipe(istore_mem); 7416 %} 7417 7418 // Store Long (64 bit signed) 7419 instruct storeL(iRegL src, memory8 mem) 7420 %{ 7421 match(Set mem (StoreL mem src)); 7422 predicate(!needs_releasing_store(n)); 7423 7424 ins_cost(INSN_COST); 7425 format %{ "str $src, $mem\t# int" %} 7426 7427 ins_encode(aarch64_enc_str(src, mem)); 7428 7429 ins_pipe(istore_reg_mem); 7430 %} 7431 7432 // Store Long (64 bit signed) 7433 instruct storeimmL0(immL0 zero, memory8 mem) 7434 %{ 7435 match(Set mem (StoreL mem zero)); 7436 predicate(!needs_releasing_store(n)); 7437 7438 ins_cost(INSN_COST); 7439 format %{ "str zr, $mem\t# int" %} 7440 7441 ins_encode(aarch64_enc_str0(mem)); 7442 7443 ins_pipe(istore_mem); 7444 %} 7445 7446 // Store Pointer 7447 instruct storeP(iRegP src, memory8 mem) 7448 %{ 7449 match(Set mem (StoreP mem src)); 7450 predicate(!needs_releasing_store(n)); 7451 7452 ins_cost(INSN_COST); 7453 format %{ "str $src, $mem\t# ptr" %} 7454 7455 ins_encode(aarch64_enc_str(src, mem)); 7456 7457 ins_pipe(istore_reg_mem); 7458 %} 7459 7460 // Store Pointer 7461 instruct storeimmP0(immP0 zero, memory8 mem) 7462 %{ 7463 match(Set mem (StoreP mem zero)); 7464 predicate(!needs_releasing_store(n)); 7465 7466 ins_cost(INSN_COST); 7467 format %{ "str zr, $mem\t# ptr" %} 7468 7469 ins_encode(aarch64_enc_str0(mem)); 7470 7471 ins_pipe(istore_mem); 7472 %} 7473 7474 // Store Compressed Pointer 7475 instruct storeN(iRegN src, memory4 mem) 7476 %{ 7477 match(Set mem (StoreN mem src)); 7478 predicate(!needs_releasing_store(n)); 7479 7480 ins_cost(INSN_COST); 7481 format %{ "strw $src, $mem\t# compressed ptr" %} 7482 7483 ins_encode(aarch64_enc_strw(src, mem)); 7484 7485 ins_pipe(istore_reg_mem); 7486 %} 7487 7488 instruct storeImmN0(immN0 zero, memory4 mem) 7489 %{ 7490 match(Set mem (StoreN mem zero)); 7491 predicate(!needs_releasing_store(n)); 7492 7493 ins_cost(INSN_COST); 7494 format %{ "strw zr, $mem\t# compressed ptr" %} 7495 7496 ins_encode(aarch64_enc_strw0(mem)); 7497 7498 ins_pipe(istore_mem); 7499 %} 7500 7501 // Store Float 7502 instruct storeF(vRegF src, memory4 mem) 7503 %{ 7504 match(Set mem (StoreF mem src)); 7505 predicate(!needs_releasing_store(n)); 7506 7507 ins_cost(INSN_COST); 7508 format %{ "strs $src, $mem\t# float" %} 7509 7510 ins_encode( aarch64_enc_strs(src, mem) ); 7511 7512 ins_pipe(pipe_class_memory); 7513 %} 7514 7515 // TODO 7516 // implement storeImmF0 and storeFImmPacked 7517 7518 // Store Double 7519 instruct storeD(vRegD src, memory8 mem) 7520 %{ 7521 match(Set mem (StoreD mem src)); 7522 predicate(!needs_releasing_store(n)); 7523 7524 ins_cost(INSN_COST); 7525 format %{ "strd $src, $mem\t# double" %} 7526 7527 ins_encode( aarch64_enc_strd(src, mem) ); 7528 7529 ins_pipe(pipe_class_memory); 7530 %} 7531 7532 // Store Compressed Klass Pointer 7533 instruct storeNKlass(iRegN src, memory4 mem) 7534 %{ 7535 predicate(!needs_releasing_store(n)); 7536 match(Set mem (StoreNKlass mem src)); 7537 7538 ins_cost(INSN_COST); 7539 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7540 7541 ins_encode(aarch64_enc_strw(src, mem)); 7542 7543 ins_pipe(istore_reg_mem); 7544 %} 7545 7546 // TODO 7547 // implement storeImmD0 and storeDImmPacked 7548 7549 // prefetch instructions 7550 // Must be safe to execute with invalid address (cannot fault). 7551 7552 instruct prefetchalloc( memory8 mem ) %{ 7553 match(PrefetchAllocation mem); 7554 7555 ins_cost(INSN_COST); 7556 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7557 7558 ins_encode( aarch64_enc_prefetchw(mem) ); 7559 7560 ins_pipe(iload_prefetch); 7561 %} 7562 7563 // ---------------- volatile loads and stores ---------------- 7564 7565 // Load Byte (8 bit signed) 7566 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7567 %{ 7568 match(Set dst (LoadB mem)); 7569 7570 ins_cost(VOLATILE_REF_COST); 7571 format %{ "ldarsb $dst, $mem\t# byte" %} 7572 7573 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7574 7575 ins_pipe(pipe_serial); 7576 %} 7577 7578 // Load Byte (8 bit signed) into long 7579 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7580 %{ 7581 match(Set dst (ConvI2L (LoadB mem))); 7582 7583 ins_cost(VOLATILE_REF_COST); 7584 format %{ "ldarsb $dst, $mem\t# byte" %} 7585 7586 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7587 7588 ins_pipe(pipe_serial); 7589 %} 7590 7591 // Load Byte (8 bit unsigned) 7592 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7593 %{ 7594 match(Set dst (LoadUB mem)); 7595 7596 ins_cost(VOLATILE_REF_COST); 7597 format %{ "ldarb $dst, $mem\t# byte" %} 7598 7599 ins_encode(aarch64_enc_ldarb(dst, mem)); 7600 7601 ins_pipe(pipe_serial); 7602 %} 7603 7604 // Load Byte (8 bit unsigned) into long 7605 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7606 %{ 7607 match(Set dst (ConvI2L (LoadUB mem))); 7608 7609 ins_cost(VOLATILE_REF_COST); 7610 format %{ "ldarb $dst, $mem\t# byte" %} 7611 7612 ins_encode(aarch64_enc_ldarb(dst, mem)); 7613 7614 ins_pipe(pipe_serial); 7615 %} 7616 7617 // Load Short (16 bit signed) 7618 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7619 %{ 7620 match(Set dst (LoadS mem)); 7621 7622 ins_cost(VOLATILE_REF_COST); 7623 format %{ "ldarshw $dst, $mem\t# short" %} 7624 7625 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7626 7627 ins_pipe(pipe_serial); 7628 %} 7629 7630 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7631 %{ 7632 match(Set dst (LoadUS mem)); 7633 7634 ins_cost(VOLATILE_REF_COST); 7635 format %{ "ldarhw $dst, $mem\t# short" %} 7636 7637 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7638 7639 ins_pipe(pipe_serial); 7640 %} 7641 7642 // Load Short/Char (16 bit unsigned) into long 7643 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7644 %{ 7645 match(Set dst (ConvI2L (LoadUS mem))); 7646 7647 ins_cost(VOLATILE_REF_COST); 7648 format %{ "ldarh $dst, $mem\t# short" %} 7649 7650 ins_encode(aarch64_enc_ldarh(dst, mem)); 7651 7652 ins_pipe(pipe_serial); 7653 %} 7654 7655 // Load Short/Char (16 bit signed) into long 7656 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7657 %{ 7658 match(Set dst (ConvI2L (LoadS mem))); 7659 7660 ins_cost(VOLATILE_REF_COST); 7661 format %{ "ldarh $dst, $mem\t# short" %} 7662 7663 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7664 7665 ins_pipe(pipe_serial); 7666 %} 7667 7668 // Load Integer (32 bit signed) 7669 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7670 %{ 7671 match(Set dst (LoadI mem)); 7672 7673 ins_cost(VOLATILE_REF_COST); 7674 format %{ "ldarw $dst, $mem\t# int" %} 7675 7676 ins_encode(aarch64_enc_ldarw(dst, mem)); 7677 7678 ins_pipe(pipe_serial); 7679 %} 7680 7681 // Load Integer (32 bit unsigned) into long 7682 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7683 %{ 7684 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7685 7686 ins_cost(VOLATILE_REF_COST); 7687 format %{ "ldarw $dst, $mem\t# int" %} 7688 7689 ins_encode(aarch64_enc_ldarw(dst, mem)); 7690 7691 ins_pipe(pipe_serial); 7692 %} 7693 7694 // Load Long (64 bit signed) 7695 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7696 %{ 7697 match(Set dst (LoadL mem)); 7698 7699 ins_cost(VOLATILE_REF_COST); 7700 format %{ "ldar $dst, $mem\t# int" %} 7701 7702 ins_encode(aarch64_enc_ldar(dst, mem)); 7703 7704 ins_pipe(pipe_serial); 7705 %} 7706 7707 // Load Pointer 7708 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7709 %{ 7710 match(Set dst (LoadP mem)); 7711 predicate(n->as_Load()->barrier_data() == 0); 7712 7713 ins_cost(VOLATILE_REF_COST); 7714 format %{ "ldar $dst, $mem\t# ptr" %} 7715 7716 ins_encode(aarch64_enc_ldar(dst, mem)); 7717 7718 ins_pipe(pipe_serial); 7719 %} 7720 7721 // Load Compressed Pointer 7722 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7723 %{ 7724 match(Set dst (LoadN mem)); 7725 7726 ins_cost(VOLATILE_REF_COST); 7727 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7728 7729 ins_encode(aarch64_enc_ldarw(dst, mem)); 7730 7731 ins_pipe(pipe_serial); 7732 %} 7733 7734 // Load Float 7735 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7736 %{ 7737 match(Set dst (LoadF mem)); 7738 7739 ins_cost(VOLATILE_REF_COST); 7740 format %{ "ldars $dst, $mem\t# float" %} 7741 7742 ins_encode( aarch64_enc_fldars(dst, mem) ); 7743 7744 ins_pipe(pipe_serial); 7745 %} 7746 7747 // Load Double 7748 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7749 %{ 7750 match(Set dst (LoadD mem)); 7751 7752 ins_cost(VOLATILE_REF_COST); 7753 format %{ "ldard $dst, $mem\t# double" %} 7754 7755 ins_encode( aarch64_enc_fldard(dst, mem) ); 7756 7757 ins_pipe(pipe_serial); 7758 %} 7759 7760 // Store Byte 7761 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7762 %{ 7763 match(Set mem (StoreB mem src)); 7764 7765 ins_cost(VOLATILE_REF_COST); 7766 format %{ "stlrb $src, $mem\t# byte" %} 7767 7768 ins_encode(aarch64_enc_stlrb(src, mem)); 7769 7770 ins_pipe(pipe_class_memory); 7771 %} 7772 7773 // Store Char/Short 7774 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7775 %{ 7776 match(Set mem (StoreC mem src)); 7777 7778 ins_cost(VOLATILE_REF_COST); 7779 format %{ "stlrh $src, $mem\t# short" %} 7780 7781 ins_encode(aarch64_enc_stlrh(src, mem)); 7782 7783 ins_pipe(pipe_class_memory); 7784 %} 7785 7786 // Store Integer 7787 7788 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7789 %{ 7790 match(Set mem(StoreI mem src)); 7791 7792 ins_cost(VOLATILE_REF_COST); 7793 format %{ "stlrw $src, $mem\t# int" %} 7794 7795 ins_encode(aarch64_enc_stlrw(src, mem)); 7796 7797 ins_pipe(pipe_class_memory); 7798 %} 7799 7800 // Store Long (64 bit signed) 7801 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7802 %{ 7803 match(Set mem (StoreL mem src)); 7804 7805 ins_cost(VOLATILE_REF_COST); 7806 format %{ "stlr $src, $mem\t# int" %} 7807 7808 ins_encode(aarch64_enc_stlr(src, mem)); 7809 7810 ins_pipe(pipe_class_memory); 7811 %} 7812 7813 // Store Pointer 7814 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7815 %{ 7816 match(Set mem (StoreP mem src)); 7817 7818 ins_cost(VOLATILE_REF_COST); 7819 format %{ "stlr $src, $mem\t# ptr" %} 7820 7821 ins_encode(aarch64_enc_stlr(src, mem)); 7822 7823 ins_pipe(pipe_class_memory); 7824 %} 7825 7826 // Store Compressed Pointer 7827 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7828 %{ 7829 match(Set mem (StoreN mem src)); 7830 7831 ins_cost(VOLATILE_REF_COST); 7832 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7833 7834 ins_encode(aarch64_enc_stlrw(src, mem)); 7835 7836 ins_pipe(pipe_class_memory); 7837 %} 7838 7839 // Store Float 7840 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7841 %{ 7842 match(Set mem (StoreF mem src)); 7843 7844 ins_cost(VOLATILE_REF_COST); 7845 format %{ "stlrs $src, $mem\t# float" %} 7846 7847 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7848 7849 ins_pipe(pipe_class_memory); 7850 %} 7851 7852 // TODO 7853 // implement storeImmF0 and storeFImmPacked 7854 7855 // Store Double 7856 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7857 %{ 7858 match(Set mem (StoreD mem src)); 7859 7860 ins_cost(VOLATILE_REF_COST); 7861 format %{ "stlrd $src, $mem\t# double" %} 7862 7863 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7864 7865 ins_pipe(pipe_class_memory); 7866 %} 7867 7868 // ---------------- end of volatile loads and stores ---------------- 7869 7870 instruct cacheWB(indirect addr) 7871 %{ 7872 predicate(VM_Version::supports_data_cache_line_flush()); 7873 match(CacheWB addr); 7874 7875 ins_cost(100); 7876 format %{"cache wb $addr" %} 7877 ins_encode %{ 7878 assert($addr->index_position() < 0, "should be"); 7879 assert($addr$$disp == 0, "should be"); 7880 __ cache_wb(Address($addr$$base$$Register, 0)); 7881 %} 7882 ins_pipe(pipe_slow); // XXX 7883 %} 7884 7885 instruct cacheWBPreSync() 7886 %{ 7887 predicate(VM_Version::supports_data_cache_line_flush()); 7888 match(CacheWBPreSync); 7889 7890 ins_cost(100); 7891 format %{"cache wb presync" %} 7892 ins_encode %{ 7893 __ cache_wbsync(true); 7894 %} 7895 ins_pipe(pipe_slow); // XXX 7896 %} 7897 7898 instruct cacheWBPostSync() 7899 %{ 7900 predicate(VM_Version::supports_data_cache_line_flush()); 7901 match(CacheWBPostSync); 7902 7903 ins_cost(100); 7904 format %{"cache wb postsync" %} 7905 ins_encode %{ 7906 __ cache_wbsync(false); 7907 %} 7908 ins_pipe(pipe_slow); // XXX 7909 %} 7910 7911 // ============================================================================ 7912 // BSWAP Instructions 7913 7914 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7915 match(Set dst (ReverseBytesI src)); 7916 7917 ins_cost(INSN_COST); 7918 format %{ "revw $dst, $src" %} 7919 7920 ins_encode %{ 7921 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7922 %} 7923 7924 ins_pipe(ialu_reg); 7925 %} 7926 7927 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7928 match(Set dst (ReverseBytesL src)); 7929 7930 ins_cost(INSN_COST); 7931 format %{ "rev $dst, $src" %} 7932 7933 ins_encode %{ 7934 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7935 %} 7936 7937 ins_pipe(ialu_reg); 7938 %} 7939 7940 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7941 match(Set dst (ReverseBytesUS src)); 7942 7943 ins_cost(INSN_COST); 7944 format %{ "rev16w $dst, $src" %} 7945 7946 ins_encode %{ 7947 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7948 %} 7949 7950 ins_pipe(ialu_reg); 7951 %} 7952 7953 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7954 match(Set dst (ReverseBytesS src)); 7955 7956 ins_cost(INSN_COST); 7957 format %{ "rev16w $dst, $src\n\t" 7958 "sbfmw $dst, $dst, #0, #15" %} 7959 7960 ins_encode %{ 7961 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7962 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7963 %} 7964 7965 ins_pipe(ialu_reg); 7966 %} 7967 7968 // ============================================================================ 7969 // Zero Count Instructions 7970 7971 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7972 match(Set dst (CountLeadingZerosI src)); 7973 7974 ins_cost(INSN_COST); 7975 format %{ "clzw $dst, $src" %} 7976 ins_encode %{ 7977 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7978 %} 7979 7980 ins_pipe(ialu_reg); 7981 %} 7982 7983 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7984 match(Set dst (CountLeadingZerosL src)); 7985 7986 ins_cost(INSN_COST); 7987 format %{ "clz $dst, $src" %} 7988 ins_encode %{ 7989 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7990 %} 7991 7992 ins_pipe(ialu_reg); 7993 %} 7994 7995 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7996 match(Set dst (CountTrailingZerosI src)); 7997 7998 ins_cost(INSN_COST * 2); 7999 format %{ "rbitw $dst, $src\n\t" 8000 "clzw $dst, $dst" %} 8001 ins_encode %{ 8002 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8003 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8004 %} 8005 8006 ins_pipe(ialu_reg); 8007 %} 8008 8009 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8010 match(Set dst (CountTrailingZerosL src)); 8011 8012 ins_cost(INSN_COST * 2); 8013 format %{ "rbit $dst, $src\n\t" 8014 "clz $dst, $dst" %} 8015 ins_encode %{ 8016 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8017 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8018 %} 8019 8020 ins_pipe(ialu_reg); 8021 %} 8022 8023 //---------- Population Count Instructions ------------------------------------- 8024 // 8025 8026 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8027 predicate(UsePopCountInstruction); 8028 match(Set dst (PopCountI src)); 8029 effect(TEMP tmp); 8030 ins_cost(INSN_COST * 13); 8031 8032 format %{ "movw $src, $src\n\t" 8033 "mov $tmp, $src\t# vector (1D)\n\t" 8034 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8035 "addv $tmp, $tmp\t# vector (8B)\n\t" 8036 "mov $dst, $tmp\t# vector (1D)" %} 8037 ins_encode %{ 8038 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8039 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8040 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8041 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8042 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8043 %} 8044 8045 ins_pipe(pipe_class_default); 8046 %} 8047 8048 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8049 predicate(UsePopCountInstruction); 8050 match(Set dst (PopCountI (LoadI mem))); 8051 effect(TEMP tmp); 8052 ins_cost(INSN_COST * 13); 8053 8054 format %{ "ldrs $tmp, $mem\n\t" 8055 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8056 "addv $tmp, $tmp\t# vector (8B)\n\t" 8057 "mov $dst, $tmp\t# vector (1D)" %} 8058 ins_encode %{ 8059 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8060 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8061 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8062 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8063 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8064 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8065 %} 8066 8067 ins_pipe(pipe_class_default); 8068 %} 8069 8070 // Note: Long.bitCount(long) returns an int. 8071 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8072 predicate(UsePopCountInstruction); 8073 match(Set dst (PopCountL src)); 8074 effect(TEMP tmp); 8075 ins_cost(INSN_COST * 13); 8076 8077 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8078 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8079 "addv $tmp, $tmp\t# vector (8B)\n\t" 8080 "mov $dst, $tmp\t# vector (1D)" %} 8081 ins_encode %{ 8082 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8083 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8084 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8085 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8086 %} 8087 8088 ins_pipe(pipe_class_default); 8089 %} 8090 8091 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8092 predicate(UsePopCountInstruction); 8093 match(Set dst (PopCountL (LoadL mem))); 8094 effect(TEMP tmp); 8095 ins_cost(INSN_COST * 13); 8096 8097 format %{ "ldrd $tmp, $mem\n\t" 8098 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8099 "addv $tmp, $tmp\t# vector (8B)\n\t" 8100 "mov $dst, $tmp\t# vector (1D)" %} 8101 ins_encode %{ 8102 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8103 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8104 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8105 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8106 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8107 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8108 %} 8109 8110 ins_pipe(pipe_class_default); 8111 %} 8112 8113 // ============================================================================ 8114 // MemBar Instruction 8115 8116 instruct load_fence() %{ 8117 match(LoadFence); 8118 ins_cost(VOLATILE_REF_COST); 8119 8120 format %{ "load_fence" %} 8121 8122 ins_encode %{ 8123 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8124 %} 8125 ins_pipe(pipe_serial); 8126 %} 8127 8128 instruct unnecessary_membar_acquire() %{ 8129 predicate(unnecessary_acquire(n)); 8130 match(MemBarAcquire); 8131 ins_cost(0); 8132 8133 format %{ "membar_acquire (elided)" %} 8134 8135 ins_encode %{ 8136 __ block_comment("membar_acquire (elided)"); 8137 %} 8138 8139 ins_pipe(pipe_class_empty); 8140 %} 8141 8142 instruct membar_acquire() %{ 8143 match(MemBarAcquire); 8144 ins_cost(VOLATILE_REF_COST); 8145 8146 format %{ "membar_acquire\n\t" 8147 "dmb ish" %} 8148 8149 ins_encode %{ 8150 __ block_comment("membar_acquire"); 8151 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8152 %} 8153 8154 ins_pipe(pipe_serial); 8155 %} 8156 8157 8158 instruct membar_acquire_lock() %{ 8159 match(MemBarAcquireLock); 8160 ins_cost(VOLATILE_REF_COST); 8161 8162 format %{ "membar_acquire_lock (elided)" %} 8163 8164 ins_encode %{ 8165 __ block_comment("membar_acquire_lock (elided)"); 8166 %} 8167 8168 ins_pipe(pipe_serial); 8169 %} 8170 8171 instruct store_fence() %{ 8172 match(StoreFence); 8173 ins_cost(VOLATILE_REF_COST); 8174 8175 format %{ "store_fence" %} 8176 8177 ins_encode %{ 8178 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8179 %} 8180 ins_pipe(pipe_serial); 8181 %} 8182 8183 instruct unnecessary_membar_release() %{ 8184 predicate(unnecessary_release(n)); 8185 match(MemBarRelease); 8186 ins_cost(0); 8187 8188 format %{ "membar_release (elided)" %} 8189 8190 ins_encode %{ 8191 __ block_comment("membar_release (elided)"); 8192 %} 8193 ins_pipe(pipe_serial); 8194 %} 8195 8196 instruct membar_release() %{ 8197 match(MemBarRelease); 8198 ins_cost(VOLATILE_REF_COST); 8199 8200 format %{ "membar_release\n\t" 8201 "dmb ish" %} 8202 8203 ins_encode %{ 8204 __ block_comment("membar_release"); 8205 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8206 %} 8207 ins_pipe(pipe_serial); 8208 %} 8209 8210 instruct membar_storestore() %{ 8211 match(MemBarStoreStore); 8212 ins_cost(VOLATILE_REF_COST); 8213 8214 format %{ "MEMBAR-store-store" %} 8215 8216 ins_encode %{ 8217 __ membar(Assembler::StoreStore); 8218 %} 8219 ins_pipe(pipe_serial); 8220 %} 8221 8222 instruct membar_release_lock() %{ 8223 match(MemBarReleaseLock); 8224 ins_cost(VOLATILE_REF_COST); 8225 8226 format %{ "membar_release_lock (elided)" %} 8227 8228 ins_encode %{ 8229 __ block_comment("membar_release_lock (elided)"); 8230 %} 8231 8232 ins_pipe(pipe_serial); 8233 %} 8234 8235 instruct unnecessary_membar_volatile() %{ 8236 predicate(unnecessary_volatile(n)); 8237 match(MemBarVolatile); 8238 ins_cost(0); 8239 8240 format %{ "membar_volatile (elided)" %} 8241 8242 ins_encode %{ 8243 __ block_comment("membar_volatile (elided)"); 8244 %} 8245 8246 ins_pipe(pipe_serial); 8247 %} 8248 8249 instruct membar_volatile() %{ 8250 match(MemBarVolatile); 8251 ins_cost(VOLATILE_REF_COST*100); 8252 8253 format %{ "membar_volatile\n\t" 8254 "dmb ish"%} 8255 8256 ins_encode %{ 8257 __ block_comment("membar_volatile"); 8258 __ membar(Assembler::StoreLoad); 8259 %} 8260 8261 ins_pipe(pipe_serial); 8262 %} 8263 8264 // ============================================================================ 8265 // Cast/Convert Instructions 8266 8267 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8268 match(Set dst (CastX2P src)); 8269 8270 ins_cost(INSN_COST); 8271 format %{ "mov $dst, $src\t# int64_t -> ptr" %} 8272 8273 ins_encode %{ 8274 if ($dst$$reg != $src$$reg) { 8275 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8276 } 8277 %} 8278 8279 ins_pipe(ialu_reg); 8280 %} 8281 8282 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8283 match(Set dst (CastP2X src)); 8284 8285 ins_cost(INSN_COST); 8286 format %{ "mov $dst, $src\t# ptr -> int64_t" %} 8287 8288 ins_encode %{ 8289 if ($dst$$reg != $src$$reg) { 8290 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8291 } 8292 %} 8293 8294 ins_pipe(ialu_reg); 8295 %} 8296 8297 // Convert oop into int for vectors alignment masking 8298 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8299 match(Set dst (ConvL2I (CastP2X src))); 8300 8301 ins_cost(INSN_COST); 8302 format %{ "movw $dst, $src\t# ptr -> int" %} 8303 ins_encode %{ 8304 __ movw($dst$$Register, $src$$Register); 8305 %} 8306 8307 ins_pipe(ialu_reg); 8308 %} 8309 8310 // Convert compressed oop into int for vectors alignment masking 8311 // in case of 32bit oops (heap < 4Gb). 8312 instruct convN2I(iRegINoSp dst, iRegN src) 8313 %{ 8314 predicate(CompressedOops::shift() == 0); 8315 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8316 8317 ins_cost(INSN_COST); 8318 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8319 ins_encode %{ 8320 __ movw($dst$$Register, $src$$Register); 8321 %} 8322 8323 ins_pipe(ialu_reg); 8324 %} 8325 8326 8327 // Convert oop pointer into compressed form 8328 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8329 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8330 match(Set dst (EncodeP src)); 8331 effect(KILL cr); 8332 ins_cost(INSN_COST * 3); 8333 format %{ "encode_heap_oop $dst, $src" %} 8334 ins_encode %{ 8335 Register s = $src$$Register; 8336 Register d = $dst$$Register; 8337 __ encode_heap_oop(d, s); 8338 %} 8339 ins_pipe(ialu_reg); 8340 %} 8341 8342 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8343 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8344 match(Set dst (EncodeP src)); 8345 ins_cost(INSN_COST * 3); 8346 format %{ "encode_heap_oop_not_null $dst, $src" %} 8347 ins_encode %{ 8348 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8349 %} 8350 ins_pipe(ialu_reg); 8351 %} 8352 8353 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8354 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8355 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8356 match(Set dst (DecodeN src)); 8357 ins_cost(INSN_COST * 3); 8358 format %{ "decode_heap_oop $dst, $src" %} 8359 ins_encode %{ 8360 Register s = $src$$Register; 8361 Register d = $dst$$Register; 8362 __ decode_heap_oop(d, s); 8363 %} 8364 ins_pipe(ialu_reg); 8365 %} 8366 8367 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8368 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8369 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8370 match(Set dst (DecodeN src)); 8371 ins_cost(INSN_COST * 3); 8372 format %{ "decode_heap_oop_not_null $dst, $src" %} 8373 ins_encode %{ 8374 Register s = $src$$Register; 8375 Register d = $dst$$Register; 8376 __ decode_heap_oop_not_null(d, s); 8377 %} 8378 ins_pipe(ialu_reg); 8379 %} 8380 8381 // n.b. AArch64 implementations of encode_klass_not_null and 8382 // decode_klass_not_null do not modify the flags register so, unlike 8383 // Intel, we don't kill CR as a side effect here 8384 8385 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8386 match(Set dst (EncodePKlass src)); 8387 8388 ins_cost(INSN_COST * 3); 8389 format %{ "encode_klass_not_null $dst,$src" %} 8390 8391 ins_encode %{ 8392 Register src_reg = as_Register($src$$reg); 8393 Register dst_reg = as_Register($dst$$reg); 8394 __ encode_klass_not_null(dst_reg, src_reg); 8395 %} 8396 8397 ins_pipe(ialu_reg); 8398 %} 8399 8400 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8401 match(Set dst (DecodeNKlass src)); 8402 8403 ins_cost(INSN_COST * 3); 8404 format %{ "decode_klass_not_null $dst,$src" %} 8405 8406 ins_encode %{ 8407 Register src_reg = as_Register($src$$reg); 8408 Register dst_reg = as_Register($dst$$reg); 8409 if (dst_reg != src_reg) { 8410 __ decode_klass_not_null(dst_reg, src_reg); 8411 } else { 8412 __ decode_klass_not_null(dst_reg); 8413 } 8414 %} 8415 8416 ins_pipe(ialu_reg); 8417 %} 8418 8419 instruct checkCastPP(iRegPNoSp dst) 8420 %{ 8421 match(Set dst (CheckCastPP dst)); 8422 8423 size(0); 8424 format %{ "# checkcastPP of $dst" %} 8425 ins_encode(/* empty encoding */); 8426 ins_pipe(pipe_class_empty); 8427 %} 8428 8429 instruct castPP(iRegPNoSp dst) 8430 %{ 8431 match(Set dst (CastPP dst)); 8432 8433 size(0); 8434 format %{ "# castPP of $dst" %} 8435 ins_encode(/* empty encoding */); 8436 ins_pipe(pipe_class_empty); 8437 %} 8438 8439 instruct castII(iRegI dst) 8440 %{ 8441 match(Set dst (CastII dst)); 8442 8443 size(0); 8444 format %{ "# castII of $dst" %} 8445 ins_encode(/* empty encoding */); 8446 ins_cost(0); 8447 ins_pipe(pipe_class_empty); 8448 %} 8449 8450 // ============================================================================ 8451 // Atomic operation instructions 8452 // 8453 // Intel and SPARC both implement Ideal Node LoadPLocked and 8454 // Store{PIL}Conditional instructions using a normal load for the 8455 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8456 // 8457 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8458 // pair to lock object allocations from Eden space when not using 8459 // TLABs. 8460 // 8461 // There does not appear to be a Load{IL}Locked Ideal Node and the 8462 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8463 // and to use StoreIConditional only for 32-bit and StoreLConditional 8464 // only for 64-bit. 8465 // 8466 // We implement LoadPLocked and StorePLocked instructions using, 8467 // respectively the AArch64 hw load-exclusive and store-conditional 8468 // instructions. Whereas we must implement each of 8469 // Store{IL}Conditional using a CAS which employs a pair of 8470 // instructions comprising a load-exclusive followed by a 8471 // store-conditional. 8472 8473 8474 // Locked-load (linked load) of the current heap-top 8475 // used when updating the eden heap top 8476 // implemented using ldaxr on AArch64 8477 8478 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8479 %{ 8480 match(Set dst (LoadPLocked mem)); 8481 8482 ins_cost(VOLATILE_REF_COST); 8483 8484 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8485 8486 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8487 8488 ins_pipe(pipe_serial); 8489 %} 8490 8491 // Conditional-store of the updated heap-top. 8492 // Used during allocation of the shared heap. 8493 // Sets flag (EQ) on success. 8494 // implemented using stlxr on AArch64. 8495 8496 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8497 %{ 8498 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8499 8500 ins_cost(VOLATILE_REF_COST); 8501 8502 // TODO 8503 // do we need to do a store-conditional release or can we just use a 8504 // plain store-conditional? 8505 8506 format %{ 8507 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8508 "cmpw rscratch1, zr\t# EQ on successful write" 8509 %} 8510 8511 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8512 8513 ins_pipe(pipe_serial); 8514 %} 8515 8516 8517 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8518 // when attempting to rebias a lock towards the current thread. We 8519 // must use the acquire form of cmpxchg in order to guarantee acquire 8520 // semantics in this case. 8521 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8522 %{ 8523 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8524 8525 ins_cost(VOLATILE_REF_COST); 8526 8527 format %{ 8528 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8529 "cmpw rscratch1, zr\t# EQ on successful write" 8530 %} 8531 8532 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8533 8534 ins_pipe(pipe_slow); 8535 %} 8536 8537 // storeIConditional also has acquire semantics, for no better reason 8538 // than matching storeLConditional. At the time of writing this 8539 // comment storeIConditional was not used anywhere by AArch64. 8540 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8541 %{ 8542 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8543 8544 ins_cost(VOLATILE_REF_COST); 8545 8546 format %{ 8547 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8548 "cmpw rscratch1, zr\t# EQ on successful write" 8549 %} 8550 8551 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8552 8553 ins_pipe(pipe_slow); 8554 %} 8555 8556 // standard CompareAndSwapX when we are using barriers 8557 // these have higher priority than the rules selected by a predicate 8558 8559 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8560 // can't match them 8561 8562 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8563 8564 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8565 ins_cost(2 * VOLATILE_REF_COST); 8566 8567 effect(KILL cr); 8568 8569 format %{ 8570 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8571 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8572 %} 8573 8574 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8575 aarch64_enc_cset_eq(res)); 8576 8577 ins_pipe(pipe_slow); 8578 %} 8579 8580 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8581 8582 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8583 ins_cost(2 * VOLATILE_REF_COST); 8584 8585 effect(KILL cr); 8586 8587 format %{ 8588 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8589 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8590 %} 8591 8592 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8593 aarch64_enc_cset_eq(res)); 8594 8595 ins_pipe(pipe_slow); 8596 %} 8597 8598 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8599 8600 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8601 ins_cost(2 * VOLATILE_REF_COST); 8602 8603 effect(KILL cr); 8604 8605 format %{ 8606 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8607 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8608 %} 8609 8610 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8611 aarch64_enc_cset_eq(res)); 8612 8613 ins_pipe(pipe_slow); 8614 %} 8615 8616 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8617 8618 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8619 ins_cost(2 * VOLATILE_REF_COST); 8620 8621 effect(KILL cr); 8622 8623 format %{ 8624 "cmpxchg $mem, $oldval, $newval\t# (int64_t) if $mem == $oldval then $mem <-- $newval" 8625 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8626 %} 8627 8628 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8629 aarch64_enc_cset_eq(res)); 8630 8631 ins_pipe(pipe_slow); 8632 %} 8633 8634 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8635 8636 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8637 predicate(n->as_LoadStore()->barrier_data() == 0); 8638 ins_cost(2 * VOLATILE_REF_COST); 8639 8640 effect(KILL cr); 8641 8642 format %{ 8643 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8644 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8645 %} 8646 8647 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8648 aarch64_enc_cset_eq(res)); 8649 8650 ins_pipe(pipe_slow); 8651 %} 8652 8653 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8654 8655 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8656 ins_cost(2 * VOLATILE_REF_COST); 8657 8658 effect(KILL cr); 8659 8660 format %{ 8661 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8662 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8663 %} 8664 8665 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8666 aarch64_enc_cset_eq(res)); 8667 8668 ins_pipe(pipe_slow); 8669 %} 8670 8671 // alternative CompareAndSwapX when we are eliding barriers 8672 8673 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8674 8675 predicate(needs_acquiring_load_exclusive(n)); 8676 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8677 ins_cost(VOLATILE_REF_COST); 8678 8679 effect(KILL cr); 8680 8681 format %{ 8682 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8683 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8684 %} 8685 8686 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8687 aarch64_enc_cset_eq(res)); 8688 8689 ins_pipe(pipe_slow); 8690 %} 8691 8692 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8693 8694 predicate(needs_acquiring_load_exclusive(n)); 8695 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8696 ins_cost(VOLATILE_REF_COST); 8697 8698 effect(KILL cr); 8699 8700 format %{ 8701 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8702 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8703 %} 8704 8705 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8706 aarch64_enc_cset_eq(res)); 8707 8708 ins_pipe(pipe_slow); 8709 %} 8710 8711 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8712 8713 predicate(needs_acquiring_load_exclusive(n)); 8714 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8715 ins_cost(VOLATILE_REF_COST); 8716 8717 effect(KILL cr); 8718 8719 format %{ 8720 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8721 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8722 %} 8723 8724 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8725 aarch64_enc_cset_eq(res)); 8726 8727 ins_pipe(pipe_slow); 8728 %} 8729 8730 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8731 8732 predicate(needs_acquiring_load_exclusive(n)); 8733 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8734 ins_cost(VOLATILE_REF_COST); 8735 8736 effect(KILL cr); 8737 8738 format %{ 8739 "cmpxchg_acq $mem, $oldval, $newval\t# (int64_t) if $mem == $oldval then $mem <-- $newval" 8740 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8741 %} 8742 8743 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8744 aarch64_enc_cset_eq(res)); 8745 8746 ins_pipe(pipe_slow); 8747 %} 8748 8749 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8750 8751 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8752 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8753 ins_cost(VOLATILE_REF_COST); 8754 8755 effect(KILL cr); 8756 8757 format %{ 8758 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8759 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8760 %} 8761 8762 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8763 aarch64_enc_cset_eq(res)); 8764 8765 ins_pipe(pipe_slow); 8766 %} 8767 8768 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8769 8770 predicate(needs_acquiring_load_exclusive(n)); 8771 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8772 ins_cost(VOLATILE_REF_COST); 8773 8774 effect(KILL cr); 8775 8776 format %{ 8777 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8778 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8779 %} 8780 8781 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8782 aarch64_enc_cset_eq(res)); 8783 8784 ins_pipe(pipe_slow); 8785 %} 8786 8787 8788 // --------------------------------------------------------------------- 8789 8790 8791 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8792 8793 // Sundry CAS operations. Note that release is always true, 8794 // regardless of the memory ordering of the CAS. This is because we 8795 // need the volatile case to be sequentially consistent but there is 8796 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8797 // can't check the type of memory ordering here, so we always emit a 8798 // STLXR. 8799 8800 // This section is generated from aarch64_ad_cas.m4 8801 8802 8803 8804 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8805 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8806 ins_cost(2 * VOLATILE_REF_COST); 8807 effect(TEMP_DEF res, KILL cr); 8808 format %{ 8809 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8810 %} 8811 ins_encode %{ 8812 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8813 Assembler::byte, /*acquire*/ false, /*release*/ true, 8814 /*weak*/ false, $res$$Register); 8815 __ sxtbw($res$$Register, $res$$Register); 8816 %} 8817 ins_pipe(pipe_slow); 8818 %} 8819 8820 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8821 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8822 ins_cost(2 * VOLATILE_REF_COST); 8823 effect(TEMP_DEF res, KILL cr); 8824 format %{ 8825 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8826 %} 8827 ins_encode %{ 8828 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8829 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8830 /*weak*/ false, $res$$Register); 8831 __ sxthw($res$$Register, $res$$Register); 8832 %} 8833 ins_pipe(pipe_slow); 8834 %} 8835 8836 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8837 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8838 ins_cost(2 * VOLATILE_REF_COST); 8839 effect(TEMP_DEF res, KILL cr); 8840 format %{ 8841 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8842 %} 8843 ins_encode %{ 8844 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8845 Assembler::word, /*acquire*/ false, /*release*/ true, 8846 /*weak*/ false, $res$$Register); 8847 %} 8848 ins_pipe(pipe_slow); 8849 %} 8850 8851 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8852 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8853 ins_cost(2 * VOLATILE_REF_COST); 8854 effect(TEMP_DEF res, KILL cr); 8855 format %{ 8856 "cmpxchg $res = $mem, $oldval, $newval\t# (int64_t, weak) if $mem == $oldval then $mem <-- $newval" 8857 %} 8858 ins_encode %{ 8859 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8860 Assembler::xword, /*acquire*/ false, /*release*/ true, 8861 /*weak*/ false, $res$$Register); 8862 %} 8863 ins_pipe(pipe_slow); 8864 %} 8865 8866 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8867 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8868 ins_cost(2 * VOLATILE_REF_COST); 8869 effect(TEMP_DEF res, KILL cr); 8870 format %{ 8871 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8872 %} 8873 ins_encode %{ 8874 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8875 Assembler::word, /*acquire*/ false, /*release*/ true, 8876 /*weak*/ false, $res$$Register); 8877 %} 8878 ins_pipe(pipe_slow); 8879 %} 8880 8881 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8882 predicate(n->as_LoadStore()->barrier_data() == 0); 8883 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8884 ins_cost(2 * VOLATILE_REF_COST); 8885 effect(TEMP_DEF res, KILL cr); 8886 format %{ 8887 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8888 %} 8889 ins_encode %{ 8890 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8891 Assembler::xword, /*acquire*/ false, /*release*/ true, 8892 /*weak*/ false, $res$$Register); 8893 %} 8894 ins_pipe(pipe_slow); 8895 %} 8896 8897 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8898 predicate(needs_acquiring_load_exclusive(n)); 8899 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8900 ins_cost(VOLATILE_REF_COST); 8901 effect(TEMP_DEF res, KILL cr); 8902 format %{ 8903 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8904 %} 8905 ins_encode %{ 8906 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8907 Assembler::byte, /*acquire*/ true, /*release*/ true, 8908 /*weak*/ false, $res$$Register); 8909 __ sxtbw($res$$Register, $res$$Register); 8910 %} 8911 ins_pipe(pipe_slow); 8912 %} 8913 8914 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8915 predicate(needs_acquiring_load_exclusive(n)); 8916 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8917 ins_cost(VOLATILE_REF_COST); 8918 effect(TEMP_DEF res, KILL cr); 8919 format %{ 8920 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8921 %} 8922 ins_encode %{ 8923 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8924 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8925 /*weak*/ false, $res$$Register); 8926 __ sxthw($res$$Register, $res$$Register); 8927 %} 8928 ins_pipe(pipe_slow); 8929 %} 8930 8931 8932 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8933 predicate(needs_acquiring_load_exclusive(n)); 8934 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8935 ins_cost(VOLATILE_REF_COST); 8936 effect(TEMP_DEF res, KILL cr); 8937 format %{ 8938 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8939 %} 8940 ins_encode %{ 8941 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8942 Assembler::word, /*acquire*/ true, /*release*/ true, 8943 /*weak*/ false, $res$$Register); 8944 %} 8945 ins_pipe(pipe_slow); 8946 %} 8947 8948 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8949 predicate(needs_acquiring_load_exclusive(n)); 8950 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8951 ins_cost(VOLATILE_REF_COST); 8952 effect(TEMP_DEF res, KILL cr); 8953 format %{ 8954 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int64_t, weak) if $mem == $oldval then $mem <-- $newval" 8955 %} 8956 ins_encode %{ 8957 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8958 Assembler::xword, /*acquire*/ true, /*release*/ true, 8959 /*weak*/ false, $res$$Register); 8960 %} 8961 ins_pipe(pipe_slow); 8962 %} 8963 8964 8965 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8966 predicate(needs_acquiring_load_exclusive(n)); 8967 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8968 ins_cost(VOLATILE_REF_COST); 8969 effect(TEMP_DEF res, KILL cr); 8970 format %{ 8971 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8972 %} 8973 ins_encode %{ 8974 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8975 Assembler::word, /*acquire*/ true, /*release*/ true, 8976 /*weak*/ false, $res$$Register); 8977 %} 8978 ins_pipe(pipe_slow); 8979 %} 8980 8981 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8982 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8983 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8984 ins_cost(VOLATILE_REF_COST); 8985 effect(TEMP_DEF res, KILL cr); 8986 format %{ 8987 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8988 %} 8989 ins_encode %{ 8990 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8991 Assembler::xword, /*acquire*/ true, /*release*/ true, 8992 /*weak*/ false, $res$$Register); 8993 %} 8994 ins_pipe(pipe_slow); 8995 %} 8996 8997 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8998 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8999 ins_cost(2 * VOLATILE_REF_COST); 9000 effect(KILL cr); 9001 format %{ 9002 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9003 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9004 %} 9005 ins_encode %{ 9006 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9007 Assembler::byte, /*acquire*/ false, /*release*/ true, 9008 /*weak*/ true, noreg); 9009 __ csetw($res$$Register, Assembler::EQ); 9010 %} 9011 ins_pipe(pipe_slow); 9012 %} 9013 9014 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9015 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9016 ins_cost(2 * VOLATILE_REF_COST); 9017 effect(KILL cr); 9018 format %{ 9019 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9020 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9021 %} 9022 ins_encode %{ 9023 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9024 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9025 /*weak*/ true, noreg); 9026 __ csetw($res$$Register, Assembler::EQ); 9027 %} 9028 ins_pipe(pipe_slow); 9029 %} 9030 9031 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9032 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9033 ins_cost(2 * VOLATILE_REF_COST); 9034 effect(KILL cr); 9035 format %{ 9036 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9037 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9038 %} 9039 ins_encode %{ 9040 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9041 Assembler::word, /*acquire*/ false, /*release*/ true, 9042 /*weak*/ true, noreg); 9043 __ csetw($res$$Register, Assembler::EQ); 9044 %} 9045 ins_pipe(pipe_slow); 9046 %} 9047 9048 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9049 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9050 ins_cost(2 * VOLATILE_REF_COST); 9051 effect(KILL cr); 9052 format %{ 9053 "cmpxchg $res = $mem, $oldval, $newval\t# (int64_t, weak) if $mem == $oldval then $mem <-- $newval" 9054 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9055 %} 9056 ins_encode %{ 9057 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9058 Assembler::xword, /*acquire*/ false, /*release*/ true, 9059 /*weak*/ true, noreg); 9060 __ csetw($res$$Register, Assembler::EQ); 9061 %} 9062 ins_pipe(pipe_slow); 9063 %} 9064 9065 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9066 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9067 ins_cost(2 * VOLATILE_REF_COST); 9068 effect(KILL cr); 9069 format %{ 9070 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9071 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9072 %} 9073 ins_encode %{ 9074 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9075 Assembler::word, /*acquire*/ false, /*release*/ true, 9076 /*weak*/ true, noreg); 9077 __ csetw($res$$Register, Assembler::EQ); 9078 %} 9079 ins_pipe(pipe_slow); 9080 %} 9081 9082 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9083 predicate(n->as_LoadStore()->barrier_data() == 0); 9084 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9085 ins_cost(2 * VOLATILE_REF_COST); 9086 effect(KILL cr); 9087 format %{ 9088 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9089 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9090 %} 9091 ins_encode %{ 9092 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9093 Assembler::xword, /*acquire*/ false, /*release*/ true, 9094 /*weak*/ true, noreg); 9095 __ csetw($res$$Register, Assembler::EQ); 9096 %} 9097 ins_pipe(pipe_slow); 9098 %} 9099 9100 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9101 predicate(needs_acquiring_load_exclusive(n)); 9102 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9103 ins_cost(VOLATILE_REF_COST); 9104 effect(KILL cr); 9105 format %{ 9106 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9107 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9108 %} 9109 ins_encode %{ 9110 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9111 Assembler::byte, /*acquire*/ true, /*release*/ true, 9112 /*weak*/ true, noreg); 9113 __ csetw($res$$Register, Assembler::EQ); 9114 %} 9115 ins_pipe(pipe_slow); 9116 %} 9117 9118 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9119 predicate(needs_acquiring_load_exclusive(n)); 9120 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9121 ins_cost(VOLATILE_REF_COST); 9122 effect(KILL cr); 9123 format %{ 9124 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9125 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9126 %} 9127 ins_encode %{ 9128 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9129 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9130 /*weak*/ true, noreg); 9131 __ csetw($res$$Register, Assembler::EQ); 9132 %} 9133 ins_pipe(pipe_slow); 9134 %} 9135 9136 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9137 predicate(needs_acquiring_load_exclusive(n)); 9138 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9139 ins_cost(VOLATILE_REF_COST); 9140 effect(KILL cr); 9141 format %{ 9142 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9143 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9144 %} 9145 ins_encode %{ 9146 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9147 Assembler::word, /*acquire*/ true, /*release*/ true, 9148 /*weak*/ true, noreg); 9149 __ csetw($res$$Register, Assembler::EQ); 9150 %} 9151 ins_pipe(pipe_slow); 9152 %} 9153 9154 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9155 predicate(needs_acquiring_load_exclusive(n)); 9156 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9157 ins_cost(VOLATILE_REF_COST); 9158 effect(KILL cr); 9159 format %{ 9160 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int64_t, weak) if $mem == $oldval then $mem <-- $newval" 9161 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9162 %} 9163 ins_encode %{ 9164 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9165 Assembler::xword, /*acquire*/ true, /*release*/ true, 9166 /*weak*/ true, noreg); 9167 __ csetw($res$$Register, Assembler::EQ); 9168 %} 9169 ins_pipe(pipe_slow); 9170 %} 9171 9172 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9173 predicate(needs_acquiring_load_exclusive(n)); 9174 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9175 ins_cost(VOLATILE_REF_COST); 9176 effect(KILL cr); 9177 format %{ 9178 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9179 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9180 %} 9181 ins_encode %{ 9182 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9183 Assembler::word, /*acquire*/ true, /*release*/ true, 9184 /*weak*/ true, noreg); 9185 __ csetw($res$$Register, Assembler::EQ); 9186 %} 9187 ins_pipe(pipe_slow); 9188 %} 9189 9190 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9191 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9192 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9193 ins_cost(VOLATILE_REF_COST); 9194 effect(KILL cr); 9195 format %{ 9196 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9197 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9198 %} 9199 ins_encode %{ 9200 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9201 Assembler::xword, /*acquire*/ true, /*release*/ true, 9202 /*weak*/ true, noreg); 9203 __ csetw($res$$Register, Assembler::EQ); 9204 %} 9205 ins_pipe(pipe_slow); 9206 %} 9207 9208 // END This section of the file is automatically generated. Do not edit -------------- 9209 // --------------------------------------------------------------------- 9210 9211 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9212 match(Set prev (GetAndSetI mem newv)); 9213 ins_cost(2 * VOLATILE_REF_COST); 9214 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9215 ins_encode %{ 9216 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9217 %} 9218 ins_pipe(pipe_serial); 9219 %} 9220 9221 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9222 match(Set prev (GetAndSetL mem newv)); 9223 ins_cost(2 * VOLATILE_REF_COST); 9224 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9225 ins_encode %{ 9226 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9227 %} 9228 ins_pipe(pipe_serial); 9229 %} 9230 9231 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9232 match(Set prev (GetAndSetN mem newv)); 9233 ins_cost(2 * VOLATILE_REF_COST); 9234 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9235 ins_encode %{ 9236 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9237 %} 9238 ins_pipe(pipe_serial); 9239 %} 9240 9241 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9242 predicate(n->as_LoadStore()->barrier_data() == 0); 9243 match(Set prev (GetAndSetP mem newv)); 9244 ins_cost(2 * VOLATILE_REF_COST); 9245 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9246 ins_encode %{ 9247 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9248 %} 9249 ins_pipe(pipe_serial); 9250 %} 9251 9252 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9253 predicate(needs_acquiring_load_exclusive(n)); 9254 match(Set prev (GetAndSetI mem newv)); 9255 ins_cost(VOLATILE_REF_COST); 9256 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9257 ins_encode %{ 9258 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9259 %} 9260 ins_pipe(pipe_serial); 9261 %} 9262 9263 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9264 predicate(needs_acquiring_load_exclusive(n)); 9265 match(Set prev (GetAndSetL mem newv)); 9266 ins_cost(VOLATILE_REF_COST); 9267 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9268 ins_encode %{ 9269 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9270 %} 9271 ins_pipe(pipe_serial); 9272 %} 9273 9274 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9275 predicate(needs_acquiring_load_exclusive(n)); 9276 match(Set prev (GetAndSetN mem newv)); 9277 ins_cost(VOLATILE_REF_COST); 9278 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9279 ins_encode %{ 9280 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9281 %} 9282 ins_pipe(pipe_serial); 9283 %} 9284 9285 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9286 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9287 match(Set prev (GetAndSetP mem newv)); 9288 ins_cost(VOLATILE_REF_COST); 9289 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9290 ins_encode %{ 9291 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9292 %} 9293 ins_pipe(pipe_serial); 9294 %} 9295 9296 9297 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9298 match(Set newval (GetAndAddL mem incr)); 9299 ins_cost(2 * VOLATILE_REF_COST + 1); 9300 format %{ "get_and_addL $newval, [$mem], $incr" %} 9301 ins_encode %{ 9302 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9303 %} 9304 ins_pipe(pipe_serial); 9305 %} 9306 9307 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9308 predicate(n->as_LoadStore()->result_not_used()); 9309 match(Set dummy (GetAndAddL mem incr)); 9310 ins_cost(2 * VOLATILE_REF_COST); 9311 format %{ "get_and_addL [$mem], $incr" %} 9312 ins_encode %{ 9313 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9314 %} 9315 ins_pipe(pipe_serial); 9316 %} 9317 9318 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9319 match(Set newval (GetAndAddL mem incr)); 9320 ins_cost(2 * VOLATILE_REF_COST + 1); 9321 format %{ "get_and_addL $newval, [$mem], $incr" %} 9322 ins_encode %{ 9323 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9324 %} 9325 ins_pipe(pipe_serial); 9326 %} 9327 9328 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9329 predicate(n->as_LoadStore()->result_not_used()); 9330 match(Set dummy (GetAndAddL mem incr)); 9331 ins_cost(2 * VOLATILE_REF_COST); 9332 format %{ "get_and_addL [$mem], $incr" %} 9333 ins_encode %{ 9334 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9335 %} 9336 ins_pipe(pipe_serial); 9337 %} 9338 9339 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9340 match(Set newval (GetAndAddI mem incr)); 9341 ins_cost(2 * VOLATILE_REF_COST + 1); 9342 format %{ "get_and_addI $newval, [$mem], $incr" %} 9343 ins_encode %{ 9344 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9345 %} 9346 ins_pipe(pipe_serial); 9347 %} 9348 9349 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9350 predicate(n->as_LoadStore()->result_not_used()); 9351 match(Set dummy (GetAndAddI mem incr)); 9352 ins_cost(2 * VOLATILE_REF_COST); 9353 format %{ "get_and_addI [$mem], $incr" %} 9354 ins_encode %{ 9355 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9356 %} 9357 ins_pipe(pipe_serial); 9358 %} 9359 9360 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9361 match(Set newval (GetAndAddI mem incr)); 9362 ins_cost(2 * VOLATILE_REF_COST + 1); 9363 format %{ "get_and_addI $newval, [$mem], $incr" %} 9364 ins_encode %{ 9365 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9366 %} 9367 ins_pipe(pipe_serial); 9368 %} 9369 9370 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9371 predicate(n->as_LoadStore()->result_not_used()); 9372 match(Set dummy (GetAndAddI mem incr)); 9373 ins_cost(2 * VOLATILE_REF_COST); 9374 format %{ "get_and_addI [$mem], $incr" %} 9375 ins_encode %{ 9376 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9377 %} 9378 ins_pipe(pipe_serial); 9379 %} 9380 9381 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9382 predicate(needs_acquiring_load_exclusive(n)); 9383 match(Set newval (GetAndAddL mem incr)); 9384 ins_cost(VOLATILE_REF_COST + 1); 9385 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9386 ins_encode %{ 9387 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9388 %} 9389 ins_pipe(pipe_serial); 9390 %} 9391 9392 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9393 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9394 match(Set dummy (GetAndAddL mem incr)); 9395 ins_cost(VOLATILE_REF_COST); 9396 format %{ "get_and_addL_acq [$mem], $incr" %} 9397 ins_encode %{ 9398 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9399 %} 9400 ins_pipe(pipe_serial); 9401 %} 9402 9403 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9404 predicate(needs_acquiring_load_exclusive(n)); 9405 match(Set newval (GetAndAddL mem incr)); 9406 ins_cost(VOLATILE_REF_COST + 1); 9407 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9408 ins_encode %{ 9409 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9410 %} 9411 ins_pipe(pipe_serial); 9412 %} 9413 9414 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9415 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9416 match(Set dummy (GetAndAddL mem incr)); 9417 ins_cost(VOLATILE_REF_COST); 9418 format %{ "get_and_addL_acq [$mem], $incr" %} 9419 ins_encode %{ 9420 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9421 %} 9422 ins_pipe(pipe_serial); 9423 %} 9424 9425 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9426 predicate(needs_acquiring_load_exclusive(n)); 9427 match(Set newval (GetAndAddI mem incr)); 9428 ins_cost(VOLATILE_REF_COST + 1); 9429 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9430 ins_encode %{ 9431 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9432 %} 9433 ins_pipe(pipe_serial); 9434 %} 9435 9436 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9437 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9438 match(Set dummy (GetAndAddI mem incr)); 9439 ins_cost(VOLATILE_REF_COST); 9440 format %{ "get_and_addI_acq [$mem], $incr" %} 9441 ins_encode %{ 9442 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9443 %} 9444 ins_pipe(pipe_serial); 9445 %} 9446 9447 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9448 predicate(needs_acquiring_load_exclusive(n)); 9449 match(Set newval (GetAndAddI mem incr)); 9450 ins_cost(VOLATILE_REF_COST + 1); 9451 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9452 ins_encode %{ 9453 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9454 %} 9455 ins_pipe(pipe_serial); 9456 %} 9457 9458 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9459 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9460 match(Set dummy (GetAndAddI mem incr)); 9461 ins_cost(VOLATILE_REF_COST); 9462 format %{ "get_and_addI_acq [$mem], $incr" %} 9463 ins_encode %{ 9464 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9465 %} 9466 ins_pipe(pipe_serial); 9467 %} 9468 9469 // Manifest a CmpL result in an integer register. 9470 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9471 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9472 %{ 9473 match(Set dst (CmpL3 src1 src2)); 9474 effect(KILL flags); 9475 9476 ins_cost(INSN_COST * 6); 9477 format %{ 9478 "cmp $src1, $src2" 9479 "csetw $dst, ne" 9480 "cnegw $dst, lt" 9481 %} 9482 // format %{ "CmpL3 $dst, $src1, $src2" %} 9483 ins_encode %{ 9484 __ cmp($src1$$Register, $src2$$Register); 9485 __ csetw($dst$$Register, Assembler::NE); 9486 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9487 %} 9488 9489 ins_pipe(pipe_class_default); 9490 %} 9491 9492 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9493 %{ 9494 match(Set dst (CmpL3 src1 src2)); 9495 effect(KILL flags); 9496 9497 ins_cost(INSN_COST * 6); 9498 format %{ 9499 "cmp $src1, $src2" 9500 "csetw $dst, ne" 9501 "cnegw $dst, lt" 9502 %} 9503 ins_encode %{ 9504 int32_t con = (int32_t)$src2$$constant; 9505 if (con < 0) { 9506 __ adds(zr, $src1$$Register, -con); 9507 } else { 9508 __ subs(zr, $src1$$Register, con); 9509 } 9510 __ csetw($dst$$Register, Assembler::NE); 9511 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9512 %} 9513 9514 ins_pipe(pipe_class_default); 9515 %} 9516 9517 // ============================================================================ 9518 // Conditional Move Instructions 9519 9520 // n.b. we have identical rules for both a signed compare op (cmpOp) 9521 // and an unsigned compare op (cmpOpU). it would be nice if we could 9522 // define an op class which merged both inputs and use it to type the 9523 // argument to a single rule. unfortunatelyt his fails because the 9524 // opclass does not live up to the COND_INTER interface of its 9525 // component operands. When the generic code tries to negate the 9526 // operand it ends up running the generci Machoper::negate method 9527 // which throws a ShouldNotHappen. So, we have to provide two flavours 9528 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9529 9530 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9531 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9532 9533 ins_cost(INSN_COST * 2); 9534 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9535 9536 ins_encode %{ 9537 __ cselw(as_Register($dst$$reg), 9538 as_Register($src2$$reg), 9539 as_Register($src1$$reg), 9540 (Assembler::Condition)$cmp$$cmpcode); 9541 %} 9542 9543 ins_pipe(icond_reg_reg); 9544 %} 9545 9546 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9547 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9548 9549 ins_cost(INSN_COST * 2); 9550 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9551 9552 ins_encode %{ 9553 __ cselw(as_Register($dst$$reg), 9554 as_Register($src2$$reg), 9555 as_Register($src1$$reg), 9556 (Assembler::Condition)$cmp$$cmpcode); 9557 %} 9558 9559 ins_pipe(icond_reg_reg); 9560 %} 9561 9562 // special cases where one arg is zero 9563 9564 // n.b. this is selected in preference to the rule above because it 9565 // avoids loading constant 0 into a source register 9566 9567 // TODO 9568 // we ought only to be able to cull one of these variants as the ideal 9569 // transforms ought always to order the zero consistently (to left/right?) 9570 9571 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9572 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9573 9574 ins_cost(INSN_COST * 2); 9575 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9576 9577 ins_encode %{ 9578 __ cselw(as_Register($dst$$reg), 9579 as_Register($src$$reg), 9580 zr, 9581 (Assembler::Condition)$cmp$$cmpcode); 9582 %} 9583 9584 ins_pipe(icond_reg); 9585 %} 9586 9587 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9588 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9589 9590 ins_cost(INSN_COST * 2); 9591 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9592 9593 ins_encode %{ 9594 __ cselw(as_Register($dst$$reg), 9595 as_Register($src$$reg), 9596 zr, 9597 (Assembler::Condition)$cmp$$cmpcode); 9598 %} 9599 9600 ins_pipe(icond_reg); 9601 %} 9602 9603 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9604 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9605 9606 ins_cost(INSN_COST * 2); 9607 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9608 9609 ins_encode %{ 9610 __ cselw(as_Register($dst$$reg), 9611 zr, 9612 as_Register($src$$reg), 9613 (Assembler::Condition)$cmp$$cmpcode); 9614 %} 9615 9616 ins_pipe(icond_reg); 9617 %} 9618 9619 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9620 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9621 9622 ins_cost(INSN_COST * 2); 9623 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9624 9625 ins_encode %{ 9626 __ cselw(as_Register($dst$$reg), 9627 zr, 9628 as_Register($src$$reg), 9629 (Assembler::Condition)$cmp$$cmpcode); 9630 %} 9631 9632 ins_pipe(icond_reg); 9633 %} 9634 9635 // special case for creating a boolean 0 or 1 9636 9637 // n.b. this is selected in preference to the rule above because it 9638 // avoids loading constants 0 and 1 into a source register 9639 9640 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9641 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9642 9643 ins_cost(INSN_COST * 2); 9644 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9645 9646 ins_encode %{ 9647 // equivalently 9648 // cset(as_Register($dst$$reg), 9649 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9650 __ csincw(as_Register($dst$$reg), 9651 zr, 9652 zr, 9653 (Assembler::Condition)$cmp$$cmpcode); 9654 %} 9655 9656 ins_pipe(icond_none); 9657 %} 9658 9659 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9660 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9661 9662 ins_cost(INSN_COST * 2); 9663 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9664 9665 ins_encode %{ 9666 // equivalently 9667 // cset(as_Register($dst$$reg), 9668 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9669 __ csincw(as_Register($dst$$reg), 9670 zr, 9671 zr, 9672 (Assembler::Condition)$cmp$$cmpcode); 9673 %} 9674 9675 ins_pipe(icond_none); 9676 %} 9677 9678 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9679 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9680 9681 ins_cost(INSN_COST * 2); 9682 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, int64_t" %} 9683 9684 ins_encode %{ 9685 __ csel(as_Register($dst$$reg), 9686 as_Register($src2$$reg), 9687 as_Register($src1$$reg), 9688 (Assembler::Condition)$cmp$$cmpcode); 9689 %} 9690 9691 ins_pipe(icond_reg_reg); 9692 %} 9693 9694 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9695 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9696 9697 ins_cost(INSN_COST * 2); 9698 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, int64_t" %} 9699 9700 ins_encode %{ 9701 __ csel(as_Register($dst$$reg), 9702 as_Register($src2$$reg), 9703 as_Register($src1$$reg), 9704 (Assembler::Condition)$cmp$$cmpcode); 9705 %} 9706 9707 ins_pipe(icond_reg_reg); 9708 %} 9709 9710 // special cases where one arg is zero 9711 9712 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9713 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9714 9715 ins_cost(INSN_COST * 2); 9716 format %{ "csel $dst, zr, $src $cmp\t# signed, int64_t" %} 9717 9718 ins_encode %{ 9719 __ csel(as_Register($dst$$reg), 9720 zr, 9721 as_Register($src$$reg), 9722 (Assembler::Condition)$cmp$$cmpcode); 9723 %} 9724 9725 ins_pipe(icond_reg); 9726 %} 9727 9728 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9729 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9730 9731 ins_cost(INSN_COST * 2); 9732 format %{ "csel $dst, zr, $src $cmp\t# unsigned, int64_t" %} 9733 9734 ins_encode %{ 9735 __ csel(as_Register($dst$$reg), 9736 zr, 9737 as_Register($src$$reg), 9738 (Assembler::Condition)$cmp$$cmpcode); 9739 %} 9740 9741 ins_pipe(icond_reg); 9742 %} 9743 9744 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9745 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9746 9747 ins_cost(INSN_COST * 2); 9748 format %{ "csel $dst, $src, zr $cmp\t# signed, int64_t" %} 9749 9750 ins_encode %{ 9751 __ csel(as_Register($dst$$reg), 9752 as_Register($src$$reg), 9753 zr, 9754 (Assembler::Condition)$cmp$$cmpcode); 9755 %} 9756 9757 ins_pipe(icond_reg); 9758 %} 9759 9760 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9761 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9762 9763 ins_cost(INSN_COST * 2); 9764 format %{ "csel $dst, $src, zr $cmp\t# unsigned, int64_t" %} 9765 9766 ins_encode %{ 9767 __ csel(as_Register($dst$$reg), 9768 as_Register($src$$reg), 9769 zr, 9770 (Assembler::Condition)$cmp$$cmpcode); 9771 %} 9772 9773 ins_pipe(icond_reg); 9774 %} 9775 9776 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9777 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9778 9779 ins_cost(INSN_COST * 2); 9780 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9781 9782 ins_encode %{ 9783 __ csel(as_Register($dst$$reg), 9784 as_Register($src2$$reg), 9785 as_Register($src1$$reg), 9786 (Assembler::Condition)$cmp$$cmpcode); 9787 %} 9788 9789 ins_pipe(icond_reg_reg); 9790 %} 9791 9792 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9793 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9794 9795 ins_cost(INSN_COST * 2); 9796 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9797 9798 ins_encode %{ 9799 __ csel(as_Register($dst$$reg), 9800 as_Register($src2$$reg), 9801 as_Register($src1$$reg), 9802 (Assembler::Condition)$cmp$$cmpcode); 9803 %} 9804 9805 ins_pipe(icond_reg_reg); 9806 %} 9807 9808 // special cases where one arg is zero 9809 9810 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9811 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9812 9813 ins_cost(INSN_COST * 2); 9814 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9815 9816 ins_encode %{ 9817 __ csel(as_Register($dst$$reg), 9818 zr, 9819 as_Register($src$$reg), 9820 (Assembler::Condition)$cmp$$cmpcode); 9821 %} 9822 9823 ins_pipe(icond_reg); 9824 %} 9825 9826 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9827 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9828 9829 ins_cost(INSN_COST * 2); 9830 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9831 9832 ins_encode %{ 9833 __ csel(as_Register($dst$$reg), 9834 zr, 9835 as_Register($src$$reg), 9836 (Assembler::Condition)$cmp$$cmpcode); 9837 %} 9838 9839 ins_pipe(icond_reg); 9840 %} 9841 9842 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9843 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9844 9845 ins_cost(INSN_COST * 2); 9846 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9847 9848 ins_encode %{ 9849 __ csel(as_Register($dst$$reg), 9850 as_Register($src$$reg), 9851 zr, 9852 (Assembler::Condition)$cmp$$cmpcode); 9853 %} 9854 9855 ins_pipe(icond_reg); 9856 %} 9857 9858 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9859 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9860 9861 ins_cost(INSN_COST * 2); 9862 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9863 9864 ins_encode %{ 9865 __ csel(as_Register($dst$$reg), 9866 as_Register($src$$reg), 9867 zr, 9868 (Assembler::Condition)$cmp$$cmpcode); 9869 %} 9870 9871 ins_pipe(icond_reg); 9872 %} 9873 9874 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9875 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9876 9877 ins_cost(INSN_COST * 2); 9878 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9879 9880 ins_encode %{ 9881 __ cselw(as_Register($dst$$reg), 9882 as_Register($src2$$reg), 9883 as_Register($src1$$reg), 9884 (Assembler::Condition)$cmp$$cmpcode); 9885 %} 9886 9887 ins_pipe(icond_reg_reg); 9888 %} 9889 9890 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9891 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9892 9893 ins_cost(INSN_COST * 2); 9894 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9895 9896 ins_encode %{ 9897 __ cselw(as_Register($dst$$reg), 9898 as_Register($src2$$reg), 9899 as_Register($src1$$reg), 9900 (Assembler::Condition)$cmp$$cmpcode); 9901 %} 9902 9903 ins_pipe(icond_reg_reg); 9904 %} 9905 9906 // special cases where one arg is zero 9907 9908 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9909 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9910 9911 ins_cost(INSN_COST * 2); 9912 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9913 9914 ins_encode %{ 9915 __ cselw(as_Register($dst$$reg), 9916 zr, 9917 as_Register($src$$reg), 9918 (Assembler::Condition)$cmp$$cmpcode); 9919 %} 9920 9921 ins_pipe(icond_reg); 9922 %} 9923 9924 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9925 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9926 9927 ins_cost(INSN_COST * 2); 9928 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9929 9930 ins_encode %{ 9931 __ cselw(as_Register($dst$$reg), 9932 zr, 9933 as_Register($src$$reg), 9934 (Assembler::Condition)$cmp$$cmpcode); 9935 %} 9936 9937 ins_pipe(icond_reg); 9938 %} 9939 9940 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9941 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9942 9943 ins_cost(INSN_COST * 2); 9944 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9945 9946 ins_encode %{ 9947 __ cselw(as_Register($dst$$reg), 9948 as_Register($src$$reg), 9949 zr, 9950 (Assembler::Condition)$cmp$$cmpcode); 9951 %} 9952 9953 ins_pipe(icond_reg); 9954 %} 9955 9956 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9957 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9958 9959 ins_cost(INSN_COST * 2); 9960 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9961 9962 ins_encode %{ 9963 __ cselw(as_Register($dst$$reg), 9964 as_Register($src$$reg), 9965 zr, 9966 (Assembler::Condition)$cmp$$cmpcode); 9967 %} 9968 9969 ins_pipe(icond_reg); 9970 %} 9971 9972 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9973 %{ 9974 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9975 9976 ins_cost(INSN_COST * 3); 9977 9978 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9979 ins_encode %{ 9980 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9981 __ fcsels(as_FloatRegister($dst$$reg), 9982 as_FloatRegister($src2$$reg), 9983 as_FloatRegister($src1$$reg), 9984 cond); 9985 %} 9986 9987 ins_pipe(fp_cond_reg_reg_s); 9988 %} 9989 9990 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9991 %{ 9992 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9993 9994 ins_cost(INSN_COST * 3); 9995 9996 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9997 ins_encode %{ 9998 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9999 __ fcsels(as_FloatRegister($dst$$reg), 10000 as_FloatRegister($src2$$reg), 10001 as_FloatRegister($src1$$reg), 10002 cond); 10003 %} 10004 10005 ins_pipe(fp_cond_reg_reg_s); 10006 %} 10007 10008 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10009 %{ 10010 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10011 10012 ins_cost(INSN_COST * 3); 10013 10014 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10015 ins_encode %{ 10016 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10017 __ fcseld(as_FloatRegister($dst$$reg), 10018 as_FloatRegister($src2$$reg), 10019 as_FloatRegister($src1$$reg), 10020 cond); 10021 %} 10022 10023 ins_pipe(fp_cond_reg_reg_d); 10024 %} 10025 10026 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10027 %{ 10028 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10029 10030 ins_cost(INSN_COST * 3); 10031 10032 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10033 ins_encode %{ 10034 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10035 __ fcseld(as_FloatRegister($dst$$reg), 10036 as_FloatRegister($src2$$reg), 10037 as_FloatRegister($src1$$reg), 10038 cond); 10039 %} 10040 10041 ins_pipe(fp_cond_reg_reg_d); 10042 %} 10043 10044 // ============================================================================ 10045 // Arithmetic Instructions 10046 // 10047 10048 // Integer Addition 10049 10050 // TODO 10051 // these currently employ operations which do not set CR and hence are 10052 // not flagged as killing CR but we would like to isolate the cases 10053 // where we want to set flags from those where we don't. need to work 10054 // out how to do that. 10055 10056 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10057 match(Set dst (AddI src1 src2)); 10058 10059 ins_cost(INSN_COST); 10060 format %{ "addw $dst, $src1, $src2" %} 10061 10062 ins_encode %{ 10063 __ addw(as_Register($dst$$reg), 10064 as_Register($src1$$reg), 10065 as_Register($src2$$reg)); 10066 %} 10067 10068 ins_pipe(ialu_reg_reg); 10069 %} 10070 10071 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10072 match(Set dst (AddI src1 src2)); 10073 10074 ins_cost(INSN_COST); 10075 format %{ "addw $dst, $src1, $src2" %} 10076 10077 // use opcode to indicate that this is an add not a sub 10078 opcode(0x0); 10079 10080 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10081 10082 ins_pipe(ialu_reg_imm); 10083 %} 10084 10085 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10086 match(Set dst (AddI (ConvL2I 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 // Pointer Addition 10100 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10101 match(Set dst (AddP src1 src2)); 10102 10103 ins_cost(INSN_COST); 10104 format %{ "add $dst, $src1, $src2\t# ptr" %} 10105 10106 ins_encode %{ 10107 __ add(as_Register($dst$$reg), 10108 as_Register($src1$$reg), 10109 as_Register($src2$$reg)); 10110 %} 10111 10112 ins_pipe(ialu_reg_reg); 10113 %} 10114 10115 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10116 match(Set dst (AddP src1 (ConvI2L src2))); 10117 10118 ins_cost(1.9 * INSN_COST); 10119 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10120 10121 ins_encode %{ 10122 __ add(as_Register($dst$$reg), 10123 as_Register($src1$$reg), 10124 as_Register($src2$$reg), ext::sxtw); 10125 %} 10126 10127 ins_pipe(ialu_reg_reg); 10128 %} 10129 10130 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10131 match(Set dst (AddP src1 (LShiftL src2 scale))); 10132 10133 ins_cost(1.9 * INSN_COST); 10134 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10135 10136 ins_encode %{ 10137 __ lea(as_Register($dst$$reg), 10138 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10139 Address::lsl($scale$$constant))); 10140 %} 10141 10142 ins_pipe(ialu_reg_reg_shift); 10143 %} 10144 10145 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10146 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10147 10148 ins_cost(1.9 * INSN_COST); 10149 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10150 10151 ins_encode %{ 10152 __ lea(as_Register($dst$$reg), 10153 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10154 Address::sxtw($scale$$constant))); 10155 %} 10156 10157 ins_pipe(ialu_reg_reg_shift); 10158 %} 10159 10160 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10161 match(Set dst (LShiftL (ConvI2L src) scale)); 10162 10163 ins_cost(INSN_COST); 10164 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10165 10166 ins_encode %{ 10167 __ sbfiz(as_Register($dst$$reg), 10168 as_Register($src$$reg), 10169 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10170 %} 10171 10172 ins_pipe(ialu_reg_shift); 10173 %} 10174 10175 // Pointer Immediate Addition 10176 // n.b. this needs to be more expensive than using an indirect memory 10177 // operand 10178 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10179 match(Set dst (AddP src1 src2)); 10180 10181 ins_cost(INSN_COST); 10182 format %{ "add $dst, $src1, $src2\t# ptr" %} 10183 10184 // use opcode to indicate that this is an add not a sub 10185 opcode(0x0); 10186 10187 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10188 10189 ins_pipe(ialu_reg_imm); 10190 %} 10191 10192 // Long Addition 10193 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10194 10195 match(Set dst (AddL src1 src2)); 10196 10197 ins_cost(INSN_COST); 10198 format %{ "add $dst, $src1, $src2" %} 10199 10200 ins_encode %{ 10201 __ add(as_Register($dst$$reg), 10202 as_Register($src1$$reg), 10203 as_Register($src2$$reg)); 10204 %} 10205 10206 ins_pipe(ialu_reg_reg); 10207 %} 10208 10209 // No constant pool entries requiredLong Immediate Addition. 10210 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10211 match(Set dst (AddL src1 src2)); 10212 10213 ins_cost(INSN_COST); 10214 format %{ "add $dst, $src1, $src2" %} 10215 10216 // use opcode to indicate that this is an add not a sub 10217 opcode(0x0); 10218 10219 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10220 10221 ins_pipe(ialu_reg_imm); 10222 %} 10223 10224 // Integer Subtraction 10225 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10226 match(Set dst (SubI src1 src2)); 10227 10228 ins_cost(INSN_COST); 10229 format %{ "subw $dst, $src1, $src2" %} 10230 10231 ins_encode %{ 10232 __ subw(as_Register($dst$$reg), 10233 as_Register($src1$$reg), 10234 as_Register($src2$$reg)); 10235 %} 10236 10237 ins_pipe(ialu_reg_reg); 10238 %} 10239 10240 // Immediate Subtraction 10241 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10242 match(Set dst (SubI src1 src2)); 10243 10244 ins_cost(INSN_COST); 10245 format %{ "subw $dst, $src1, $src2" %} 10246 10247 // use opcode to indicate that this is a sub not an add 10248 opcode(0x1); 10249 10250 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10251 10252 ins_pipe(ialu_reg_imm); 10253 %} 10254 10255 // Long Subtraction 10256 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10257 10258 match(Set dst (SubL src1 src2)); 10259 10260 ins_cost(INSN_COST); 10261 format %{ "sub $dst, $src1, $src2" %} 10262 10263 ins_encode %{ 10264 __ sub(as_Register($dst$$reg), 10265 as_Register($src1$$reg), 10266 as_Register($src2$$reg)); 10267 %} 10268 10269 ins_pipe(ialu_reg_reg); 10270 %} 10271 10272 // No constant pool entries requiredLong Immediate Subtraction. 10273 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10274 match(Set dst (SubL src1 src2)); 10275 10276 ins_cost(INSN_COST); 10277 format %{ "sub$dst, $src1, $src2" %} 10278 10279 // use opcode to indicate that this is a sub not an add 10280 opcode(0x1); 10281 10282 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10283 10284 ins_pipe(ialu_reg_imm); 10285 %} 10286 10287 // Integer Negation (special case for sub) 10288 10289 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10290 match(Set dst (SubI zero src)); 10291 10292 ins_cost(INSN_COST); 10293 format %{ "negw $dst, $src\t# int" %} 10294 10295 ins_encode %{ 10296 __ negw(as_Register($dst$$reg), 10297 as_Register($src$$reg)); 10298 %} 10299 10300 ins_pipe(ialu_reg); 10301 %} 10302 10303 // Long Negation 10304 10305 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10306 match(Set dst (SubL zero src)); 10307 10308 ins_cost(INSN_COST); 10309 format %{ "neg $dst, $src\t# int64_t" %} 10310 10311 ins_encode %{ 10312 __ neg(as_Register($dst$$reg), 10313 as_Register($src$$reg)); 10314 %} 10315 10316 ins_pipe(ialu_reg); 10317 %} 10318 10319 // Integer Multiply 10320 10321 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10322 match(Set dst (MulI src1 src2)); 10323 10324 ins_cost(INSN_COST * 3); 10325 format %{ "mulw $dst, $src1, $src2" %} 10326 10327 ins_encode %{ 10328 __ mulw(as_Register($dst$$reg), 10329 as_Register($src1$$reg), 10330 as_Register($src2$$reg)); 10331 %} 10332 10333 ins_pipe(imul_reg_reg); 10334 %} 10335 10336 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10337 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10338 10339 ins_cost(INSN_COST * 3); 10340 format %{ "smull $dst, $src1, $src2" %} 10341 10342 ins_encode %{ 10343 __ smull(as_Register($dst$$reg), 10344 as_Register($src1$$reg), 10345 as_Register($src2$$reg)); 10346 %} 10347 10348 ins_pipe(imul_reg_reg); 10349 %} 10350 10351 // Long Multiply 10352 10353 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10354 match(Set dst (MulL src1 src2)); 10355 10356 ins_cost(INSN_COST * 5); 10357 format %{ "mul $dst, $src1, $src2" %} 10358 10359 ins_encode %{ 10360 __ mul(as_Register($dst$$reg), 10361 as_Register($src1$$reg), 10362 as_Register($src2$$reg)); 10363 %} 10364 10365 ins_pipe(lmul_reg_reg); 10366 %} 10367 10368 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10369 %{ 10370 match(Set dst (MulHiL src1 src2)); 10371 10372 ins_cost(INSN_COST * 7); 10373 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10374 10375 ins_encode %{ 10376 __ smulh(as_Register($dst$$reg), 10377 as_Register($src1$$reg), 10378 as_Register($src2$$reg)); 10379 %} 10380 10381 ins_pipe(lmul_reg_reg); 10382 %} 10383 10384 // Combined Integer Multiply & Add/Sub 10385 10386 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10387 match(Set dst (AddI src3 (MulI src1 src2))); 10388 10389 ins_cost(INSN_COST * 3); 10390 format %{ "madd $dst, $src1, $src2, $src3" %} 10391 10392 ins_encode %{ 10393 __ maddw(as_Register($dst$$reg), 10394 as_Register($src1$$reg), 10395 as_Register($src2$$reg), 10396 as_Register($src3$$reg)); 10397 %} 10398 10399 ins_pipe(imac_reg_reg); 10400 %} 10401 10402 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10403 match(Set dst (SubI src3 (MulI src1 src2))); 10404 10405 ins_cost(INSN_COST * 3); 10406 format %{ "msub $dst, $src1, $src2, $src3" %} 10407 10408 ins_encode %{ 10409 __ msubw(as_Register($dst$$reg), 10410 as_Register($src1$$reg), 10411 as_Register($src2$$reg), 10412 as_Register($src3$$reg)); 10413 %} 10414 10415 ins_pipe(imac_reg_reg); 10416 %} 10417 10418 // Combined Integer Multiply & Neg 10419 10420 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10421 match(Set dst (MulI (SubI zero src1) src2)); 10422 match(Set dst (MulI src1 (SubI zero src2))); 10423 10424 ins_cost(INSN_COST * 3); 10425 format %{ "mneg $dst, $src1, $src2" %} 10426 10427 ins_encode %{ 10428 __ mnegw(as_Register($dst$$reg), 10429 as_Register($src1$$reg), 10430 as_Register($src2$$reg)); 10431 %} 10432 10433 ins_pipe(imac_reg_reg); 10434 %} 10435 10436 // Combined Long Multiply & Add/Sub 10437 10438 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10439 match(Set dst (AddL src3 (MulL src1 src2))); 10440 10441 ins_cost(INSN_COST * 5); 10442 format %{ "madd $dst, $src1, $src2, $src3" %} 10443 10444 ins_encode %{ 10445 __ madd(as_Register($dst$$reg), 10446 as_Register($src1$$reg), 10447 as_Register($src2$$reg), 10448 as_Register($src3$$reg)); 10449 %} 10450 10451 ins_pipe(lmac_reg_reg); 10452 %} 10453 10454 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10455 match(Set dst (SubL src3 (MulL src1 src2))); 10456 10457 ins_cost(INSN_COST * 5); 10458 format %{ "msub $dst, $src1, $src2, $src3" %} 10459 10460 ins_encode %{ 10461 __ msub(as_Register($dst$$reg), 10462 as_Register($src1$$reg), 10463 as_Register($src2$$reg), 10464 as_Register($src3$$reg)); 10465 %} 10466 10467 ins_pipe(lmac_reg_reg); 10468 %} 10469 10470 // Combined Long Multiply & Neg 10471 10472 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10473 match(Set dst (MulL (SubL zero src1) src2)); 10474 match(Set dst (MulL src1 (SubL zero src2))); 10475 10476 ins_cost(INSN_COST * 5); 10477 format %{ "mneg $dst, $src1, $src2" %} 10478 10479 ins_encode %{ 10480 __ mneg(as_Register($dst$$reg), 10481 as_Register($src1$$reg), 10482 as_Register($src2$$reg)); 10483 %} 10484 10485 ins_pipe(lmac_reg_reg); 10486 %} 10487 10488 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10489 10490 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10491 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10492 10493 ins_cost(INSN_COST * 3); 10494 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10495 10496 ins_encode %{ 10497 __ smaddl(as_Register($dst$$reg), 10498 as_Register($src1$$reg), 10499 as_Register($src2$$reg), 10500 as_Register($src3$$reg)); 10501 %} 10502 10503 ins_pipe(imac_reg_reg); 10504 %} 10505 10506 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10507 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10508 10509 ins_cost(INSN_COST * 3); 10510 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10511 10512 ins_encode %{ 10513 __ smsubl(as_Register($dst$$reg), 10514 as_Register($src1$$reg), 10515 as_Register($src2$$reg), 10516 as_Register($src3$$reg)); 10517 %} 10518 10519 ins_pipe(imac_reg_reg); 10520 %} 10521 10522 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10523 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10524 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10525 10526 ins_cost(INSN_COST * 3); 10527 format %{ "smnegl $dst, $src1, $src2" %} 10528 10529 ins_encode %{ 10530 __ smnegl(as_Register($dst$$reg), 10531 as_Register($src1$$reg), 10532 as_Register($src2$$reg)); 10533 %} 10534 10535 ins_pipe(imac_reg_reg); 10536 %} 10537 10538 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10539 10540 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10541 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10542 10543 ins_cost(INSN_COST * 5); 10544 format %{ "mulw rscratch1, $src1, $src2\n\t" 10545 "maddw $dst, $src3, $src4, rscratch1" %} 10546 10547 ins_encode %{ 10548 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10549 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10550 10551 ins_pipe(imac_reg_reg); 10552 %} 10553 10554 // Integer Divide 10555 10556 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10557 match(Set dst (DivI src1 src2)); 10558 10559 ins_cost(INSN_COST * 19); 10560 format %{ "sdivw $dst, $src1, $src2" %} 10561 10562 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10563 ins_pipe(idiv_reg_reg); 10564 %} 10565 10566 // Long Divide 10567 10568 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10569 match(Set dst (DivL src1 src2)); 10570 10571 ins_cost(INSN_COST * 35); 10572 format %{ "sdiv $dst, $src1, $src2" %} 10573 10574 ins_encode(aarch64_enc_div(dst, src1, src2)); 10575 ins_pipe(ldiv_reg_reg); 10576 %} 10577 10578 // Integer Remainder 10579 10580 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10581 match(Set dst (ModI src1 src2)); 10582 10583 ins_cost(INSN_COST * 22); 10584 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10585 "msubw($dst, rscratch1, $src2, $src1" %} 10586 10587 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10588 ins_pipe(idiv_reg_reg); 10589 %} 10590 10591 // Long Remainder 10592 10593 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10594 match(Set dst (ModL src1 src2)); 10595 10596 ins_cost(INSN_COST * 38); 10597 format %{ "sdiv rscratch1, $src1, $src2\n" 10598 "msub($dst, rscratch1, $src2, $src1" %} 10599 10600 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10601 ins_pipe(ldiv_reg_reg); 10602 %} 10603 10604 // Integer Shifts 10605 10606 // Shift Left Register 10607 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10608 match(Set dst (LShiftI src1 src2)); 10609 10610 ins_cost(INSN_COST * 2); 10611 format %{ "lslvw $dst, $src1, $src2" %} 10612 10613 ins_encode %{ 10614 __ lslvw(as_Register($dst$$reg), 10615 as_Register($src1$$reg), 10616 as_Register($src2$$reg)); 10617 %} 10618 10619 ins_pipe(ialu_reg_reg_vshift); 10620 %} 10621 10622 // Shift Left Immediate 10623 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10624 match(Set dst (LShiftI src1 src2)); 10625 10626 ins_cost(INSN_COST); 10627 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10628 10629 ins_encode %{ 10630 __ lslw(as_Register($dst$$reg), 10631 as_Register($src1$$reg), 10632 $src2$$constant & 0x1f); 10633 %} 10634 10635 ins_pipe(ialu_reg_shift); 10636 %} 10637 10638 // Shift Right Logical Register 10639 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10640 match(Set dst (URShiftI src1 src2)); 10641 10642 ins_cost(INSN_COST * 2); 10643 format %{ "lsrvw $dst, $src1, $src2" %} 10644 10645 ins_encode %{ 10646 __ lsrvw(as_Register($dst$$reg), 10647 as_Register($src1$$reg), 10648 as_Register($src2$$reg)); 10649 %} 10650 10651 ins_pipe(ialu_reg_reg_vshift); 10652 %} 10653 10654 // Shift Right Logical Immediate 10655 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10656 match(Set dst (URShiftI src1 src2)); 10657 10658 ins_cost(INSN_COST); 10659 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10660 10661 ins_encode %{ 10662 __ lsrw(as_Register($dst$$reg), 10663 as_Register($src1$$reg), 10664 $src2$$constant & 0x1f); 10665 %} 10666 10667 ins_pipe(ialu_reg_shift); 10668 %} 10669 10670 // Shift Right Arithmetic Register 10671 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10672 match(Set dst (RShiftI src1 src2)); 10673 10674 ins_cost(INSN_COST * 2); 10675 format %{ "asrvw $dst, $src1, $src2" %} 10676 10677 ins_encode %{ 10678 __ asrvw(as_Register($dst$$reg), 10679 as_Register($src1$$reg), 10680 as_Register($src2$$reg)); 10681 %} 10682 10683 ins_pipe(ialu_reg_reg_vshift); 10684 %} 10685 10686 // Shift Right Arithmetic Immediate 10687 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10688 match(Set dst (RShiftI src1 src2)); 10689 10690 ins_cost(INSN_COST); 10691 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10692 10693 ins_encode %{ 10694 __ asrw(as_Register($dst$$reg), 10695 as_Register($src1$$reg), 10696 $src2$$constant & 0x1f); 10697 %} 10698 10699 ins_pipe(ialu_reg_shift); 10700 %} 10701 10702 // Combined Int Mask and Right Shift (using UBFM) 10703 // TODO 10704 10705 // Long Shifts 10706 10707 // Shift Left Register 10708 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10709 match(Set dst (LShiftL src1 src2)); 10710 10711 ins_cost(INSN_COST * 2); 10712 format %{ "lslv $dst, $src1, $src2" %} 10713 10714 ins_encode %{ 10715 __ lslv(as_Register($dst$$reg), 10716 as_Register($src1$$reg), 10717 as_Register($src2$$reg)); 10718 %} 10719 10720 ins_pipe(ialu_reg_reg_vshift); 10721 %} 10722 10723 // Shift Left Immediate 10724 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10725 match(Set dst (LShiftL src1 src2)); 10726 10727 ins_cost(INSN_COST); 10728 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10729 10730 ins_encode %{ 10731 __ lsl(as_Register($dst$$reg), 10732 as_Register($src1$$reg), 10733 $src2$$constant & 0x3f); 10734 %} 10735 10736 ins_pipe(ialu_reg_shift); 10737 %} 10738 10739 // Shift Right Logical Register 10740 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10741 match(Set dst (URShiftL src1 src2)); 10742 10743 ins_cost(INSN_COST * 2); 10744 format %{ "lsrv $dst, $src1, $src2" %} 10745 10746 ins_encode %{ 10747 __ lsrv(as_Register($dst$$reg), 10748 as_Register($src1$$reg), 10749 as_Register($src2$$reg)); 10750 %} 10751 10752 ins_pipe(ialu_reg_reg_vshift); 10753 %} 10754 10755 // Shift Right Logical Immediate 10756 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10757 match(Set dst (URShiftL src1 src2)); 10758 10759 ins_cost(INSN_COST); 10760 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10761 10762 ins_encode %{ 10763 __ lsr(as_Register($dst$$reg), 10764 as_Register($src1$$reg), 10765 $src2$$constant & 0x3f); 10766 %} 10767 10768 ins_pipe(ialu_reg_shift); 10769 %} 10770 10771 // A special-case pattern for card table stores. 10772 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10773 match(Set dst (URShiftL (CastP2X src1) src2)); 10774 10775 ins_cost(INSN_COST); 10776 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10777 10778 ins_encode %{ 10779 __ lsr(as_Register($dst$$reg), 10780 as_Register($src1$$reg), 10781 $src2$$constant & 0x3f); 10782 %} 10783 10784 ins_pipe(ialu_reg_shift); 10785 %} 10786 10787 // Shift Right Arithmetic Register 10788 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10789 match(Set dst (RShiftL src1 src2)); 10790 10791 ins_cost(INSN_COST * 2); 10792 format %{ "asrv $dst, $src1, $src2" %} 10793 10794 ins_encode %{ 10795 __ asrv(as_Register($dst$$reg), 10796 as_Register($src1$$reg), 10797 as_Register($src2$$reg)); 10798 %} 10799 10800 ins_pipe(ialu_reg_reg_vshift); 10801 %} 10802 10803 // Shift Right Arithmetic Immediate 10804 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10805 match(Set dst (RShiftL src1 src2)); 10806 10807 ins_cost(INSN_COST); 10808 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10809 10810 ins_encode %{ 10811 __ asr(as_Register($dst$$reg), 10812 as_Register($src1$$reg), 10813 $src2$$constant & 0x3f); 10814 %} 10815 10816 ins_pipe(ialu_reg_shift); 10817 %} 10818 10819 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10820 10821 instruct regL_not_reg(iRegLNoSp dst, 10822 iRegL src1, immL_M1 m1, 10823 rFlagsReg cr) %{ 10824 match(Set dst (XorL src1 m1)); 10825 ins_cost(INSN_COST); 10826 format %{ "eon $dst, $src1, zr" %} 10827 10828 ins_encode %{ 10829 __ eon(as_Register($dst$$reg), 10830 as_Register($src1$$reg), 10831 zr, 10832 Assembler::LSL, 0); 10833 %} 10834 10835 ins_pipe(ialu_reg); 10836 %} 10837 instruct regI_not_reg(iRegINoSp dst, 10838 iRegIorL2I src1, immI_M1 m1, 10839 rFlagsReg cr) %{ 10840 match(Set dst (XorI src1 m1)); 10841 ins_cost(INSN_COST); 10842 format %{ "eonw $dst, $src1, zr" %} 10843 10844 ins_encode %{ 10845 __ eonw(as_Register($dst$$reg), 10846 as_Register($src1$$reg), 10847 zr, 10848 Assembler::LSL, 0); 10849 %} 10850 10851 ins_pipe(ialu_reg); 10852 %} 10853 10854 instruct AndI_reg_not_reg(iRegINoSp dst, 10855 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10856 rFlagsReg cr) %{ 10857 match(Set dst (AndI src1 (XorI src2 m1))); 10858 ins_cost(INSN_COST); 10859 format %{ "bicw $dst, $src1, $src2" %} 10860 10861 ins_encode %{ 10862 __ bicw(as_Register($dst$$reg), 10863 as_Register($src1$$reg), 10864 as_Register($src2$$reg), 10865 Assembler::LSL, 0); 10866 %} 10867 10868 ins_pipe(ialu_reg_reg); 10869 %} 10870 10871 instruct AndL_reg_not_reg(iRegLNoSp dst, 10872 iRegL src1, iRegL src2, immL_M1 m1, 10873 rFlagsReg cr) %{ 10874 match(Set dst (AndL src1 (XorL src2 m1))); 10875 ins_cost(INSN_COST); 10876 format %{ "bic $dst, $src1, $src2" %} 10877 10878 ins_encode %{ 10879 __ bic(as_Register($dst$$reg), 10880 as_Register($src1$$reg), 10881 as_Register($src2$$reg), 10882 Assembler::LSL, 0); 10883 %} 10884 10885 ins_pipe(ialu_reg_reg); 10886 %} 10887 10888 instruct OrI_reg_not_reg(iRegINoSp dst, 10889 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10890 rFlagsReg cr) %{ 10891 match(Set dst (OrI src1 (XorI src2 m1))); 10892 ins_cost(INSN_COST); 10893 format %{ "ornw $dst, $src1, $src2" %} 10894 10895 ins_encode %{ 10896 __ ornw(as_Register($dst$$reg), 10897 as_Register($src1$$reg), 10898 as_Register($src2$$reg), 10899 Assembler::LSL, 0); 10900 %} 10901 10902 ins_pipe(ialu_reg_reg); 10903 %} 10904 10905 instruct OrL_reg_not_reg(iRegLNoSp dst, 10906 iRegL src1, iRegL src2, immL_M1 m1, 10907 rFlagsReg cr) %{ 10908 match(Set dst (OrL src1 (XorL src2 m1))); 10909 ins_cost(INSN_COST); 10910 format %{ "orn $dst, $src1, $src2" %} 10911 10912 ins_encode %{ 10913 __ orn(as_Register($dst$$reg), 10914 as_Register($src1$$reg), 10915 as_Register($src2$$reg), 10916 Assembler::LSL, 0); 10917 %} 10918 10919 ins_pipe(ialu_reg_reg); 10920 %} 10921 10922 instruct XorI_reg_not_reg(iRegINoSp dst, 10923 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10924 rFlagsReg cr) %{ 10925 match(Set dst (XorI m1 (XorI src2 src1))); 10926 ins_cost(INSN_COST); 10927 format %{ "eonw $dst, $src1, $src2" %} 10928 10929 ins_encode %{ 10930 __ eonw(as_Register($dst$$reg), 10931 as_Register($src1$$reg), 10932 as_Register($src2$$reg), 10933 Assembler::LSL, 0); 10934 %} 10935 10936 ins_pipe(ialu_reg_reg); 10937 %} 10938 10939 instruct XorL_reg_not_reg(iRegLNoSp dst, 10940 iRegL src1, iRegL src2, immL_M1 m1, 10941 rFlagsReg cr) %{ 10942 match(Set dst (XorL m1 (XorL src2 src1))); 10943 ins_cost(INSN_COST); 10944 format %{ "eon $dst, $src1, $src2" %} 10945 10946 ins_encode %{ 10947 __ eon(as_Register($dst$$reg), 10948 as_Register($src1$$reg), 10949 as_Register($src2$$reg), 10950 Assembler::LSL, 0); 10951 %} 10952 10953 ins_pipe(ialu_reg_reg); 10954 %} 10955 10956 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10957 iRegIorL2I src1, iRegIorL2I src2, 10958 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10959 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10960 ins_cost(1.9 * INSN_COST); 10961 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10962 10963 ins_encode %{ 10964 __ bicw(as_Register($dst$$reg), 10965 as_Register($src1$$reg), 10966 as_Register($src2$$reg), 10967 Assembler::LSR, 10968 $src3$$constant & 0x1f); 10969 %} 10970 10971 ins_pipe(ialu_reg_reg_shift); 10972 %} 10973 10974 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10975 iRegL src1, iRegL src2, 10976 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10977 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10978 ins_cost(1.9 * INSN_COST); 10979 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10980 10981 ins_encode %{ 10982 __ bic(as_Register($dst$$reg), 10983 as_Register($src1$$reg), 10984 as_Register($src2$$reg), 10985 Assembler::LSR, 10986 $src3$$constant & 0x3f); 10987 %} 10988 10989 ins_pipe(ialu_reg_reg_shift); 10990 %} 10991 10992 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10993 iRegIorL2I src1, iRegIorL2I src2, 10994 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10995 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10996 ins_cost(1.9 * INSN_COST); 10997 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10998 10999 ins_encode %{ 11000 __ bicw(as_Register($dst$$reg), 11001 as_Register($src1$$reg), 11002 as_Register($src2$$reg), 11003 Assembler::ASR, 11004 $src3$$constant & 0x1f); 11005 %} 11006 11007 ins_pipe(ialu_reg_reg_shift); 11008 %} 11009 11010 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11011 iRegL src1, iRegL src2, 11012 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11013 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11014 ins_cost(1.9 * INSN_COST); 11015 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11016 11017 ins_encode %{ 11018 __ bic(as_Register($dst$$reg), 11019 as_Register($src1$$reg), 11020 as_Register($src2$$reg), 11021 Assembler::ASR, 11022 $src3$$constant & 0x3f); 11023 %} 11024 11025 ins_pipe(ialu_reg_reg_shift); 11026 %} 11027 11028 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11029 iRegIorL2I src1, iRegIorL2I src2, 11030 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11031 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11032 ins_cost(1.9 * INSN_COST); 11033 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11034 11035 ins_encode %{ 11036 __ bicw(as_Register($dst$$reg), 11037 as_Register($src1$$reg), 11038 as_Register($src2$$reg), 11039 Assembler::LSL, 11040 $src3$$constant & 0x1f); 11041 %} 11042 11043 ins_pipe(ialu_reg_reg_shift); 11044 %} 11045 11046 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11047 iRegL src1, iRegL src2, 11048 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11049 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11050 ins_cost(1.9 * INSN_COST); 11051 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11052 11053 ins_encode %{ 11054 __ bic(as_Register($dst$$reg), 11055 as_Register($src1$$reg), 11056 as_Register($src2$$reg), 11057 Assembler::LSL, 11058 $src3$$constant & 0x3f); 11059 %} 11060 11061 ins_pipe(ialu_reg_reg_shift); 11062 %} 11063 11064 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11065 iRegIorL2I src1, iRegIorL2I src2, 11066 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11067 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11068 ins_cost(1.9 * INSN_COST); 11069 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11070 11071 ins_encode %{ 11072 __ eonw(as_Register($dst$$reg), 11073 as_Register($src1$$reg), 11074 as_Register($src2$$reg), 11075 Assembler::LSR, 11076 $src3$$constant & 0x1f); 11077 %} 11078 11079 ins_pipe(ialu_reg_reg_shift); 11080 %} 11081 11082 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11083 iRegL src1, iRegL src2, 11084 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11085 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11086 ins_cost(1.9 * INSN_COST); 11087 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11088 11089 ins_encode %{ 11090 __ eon(as_Register($dst$$reg), 11091 as_Register($src1$$reg), 11092 as_Register($src2$$reg), 11093 Assembler::LSR, 11094 $src3$$constant & 0x3f); 11095 %} 11096 11097 ins_pipe(ialu_reg_reg_shift); 11098 %} 11099 11100 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11101 iRegIorL2I src1, iRegIorL2I src2, 11102 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11103 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11104 ins_cost(1.9 * INSN_COST); 11105 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11106 11107 ins_encode %{ 11108 __ eonw(as_Register($dst$$reg), 11109 as_Register($src1$$reg), 11110 as_Register($src2$$reg), 11111 Assembler::ASR, 11112 $src3$$constant & 0x1f); 11113 %} 11114 11115 ins_pipe(ialu_reg_reg_shift); 11116 %} 11117 11118 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11119 iRegL src1, iRegL src2, 11120 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11121 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11122 ins_cost(1.9 * INSN_COST); 11123 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11124 11125 ins_encode %{ 11126 __ eon(as_Register($dst$$reg), 11127 as_Register($src1$$reg), 11128 as_Register($src2$$reg), 11129 Assembler::ASR, 11130 $src3$$constant & 0x3f); 11131 %} 11132 11133 ins_pipe(ialu_reg_reg_shift); 11134 %} 11135 11136 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11137 iRegIorL2I src1, iRegIorL2I src2, 11138 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11139 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11140 ins_cost(1.9 * INSN_COST); 11141 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11142 11143 ins_encode %{ 11144 __ eonw(as_Register($dst$$reg), 11145 as_Register($src1$$reg), 11146 as_Register($src2$$reg), 11147 Assembler::LSL, 11148 $src3$$constant & 0x1f); 11149 %} 11150 11151 ins_pipe(ialu_reg_reg_shift); 11152 %} 11153 11154 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11155 iRegL src1, iRegL src2, 11156 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11157 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11158 ins_cost(1.9 * INSN_COST); 11159 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11160 11161 ins_encode %{ 11162 __ eon(as_Register($dst$$reg), 11163 as_Register($src1$$reg), 11164 as_Register($src2$$reg), 11165 Assembler::LSL, 11166 $src3$$constant & 0x3f); 11167 %} 11168 11169 ins_pipe(ialu_reg_reg_shift); 11170 %} 11171 11172 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11173 iRegIorL2I src1, iRegIorL2I src2, 11174 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11175 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11176 ins_cost(1.9 * INSN_COST); 11177 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11178 11179 ins_encode %{ 11180 __ ornw(as_Register($dst$$reg), 11181 as_Register($src1$$reg), 11182 as_Register($src2$$reg), 11183 Assembler::LSR, 11184 $src3$$constant & 0x1f); 11185 %} 11186 11187 ins_pipe(ialu_reg_reg_shift); 11188 %} 11189 11190 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11191 iRegL src1, iRegL src2, 11192 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11193 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11194 ins_cost(1.9 * INSN_COST); 11195 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11196 11197 ins_encode %{ 11198 __ orn(as_Register($dst$$reg), 11199 as_Register($src1$$reg), 11200 as_Register($src2$$reg), 11201 Assembler::LSR, 11202 $src3$$constant & 0x3f); 11203 %} 11204 11205 ins_pipe(ialu_reg_reg_shift); 11206 %} 11207 11208 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11209 iRegIorL2I src1, iRegIorL2I src2, 11210 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11211 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11212 ins_cost(1.9 * INSN_COST); 11213 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11214 11215 ins_encode %{ 11216 __ ornw(as_Register($dst$$reg), 11217 as_Register($src1$$reg), 11218 as_Register($src2$$reg), 11219 Assembler::ASR, 11220 $src3$$constant & 0x1f); 11221 %} 11222 11223 ins_pipe(ialu_reg_reg_shift); 11224 %} 11225 11226 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11227 iRegL src1, iRegL src2, 11228 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11229 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11230 ins_cost(1.9 * INSN_COST); 11231 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11232 11233 ins_encode %{ 11234 __ orn(as_Register($dst$$reg), 11235 as_Register($src1$$reg), 11236 as_Register($src2$$reg), 11237 Assembler::ASR, 11238 $src3$$constant & 0x3f); 11239 %} 11240 11241 ins_pipe(ialu_reg_reg_shift); 11242 %} 11243 11244 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11245 iRegIorL2I src1, iRegIorL2I src2, 11246 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11247 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11248 ins_cost(1.9 * INSN_COST); 11249 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11250 11251 ins_encode %{ 11252 __ ornw(as_Register($dst$$reg), 11253 as_Register($src1$$reg), 11254 as_Register($src2$$reg), 11255 Assembler::LSL, 11256 $src3$$constant & 0x1f); 11257 %} 11258 11259 ins_pipe(ialu_reg_reg_shift); 11260 %} 11261 11262 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11263 iRegL src1, iRegL src2, 11264 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11265 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11266 ins_cost(1.9 * INSN_COST); 11267 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11268 11269 ins_encode %{ 11270 __ orn(as_Register($dst$$reg), 11271 as_Register($src1$$reg), 11272 as_Register($src2$$reg), 11273 Assembler::LSL, 11274 $src3$$constant & 0x3f); 11275 %} 11276 11277 ins_pipe(ialu_reg_reg_shift); 11278 %} 11279 11280 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11281 iRegIorL2I src1, iRegIorL2I src2, 11282 immI src3, rFlagsReg cr) %{ 11283 match(Set dst (AndI src1 (URShiftI src2 src3))); 11284 11285 ins_cost(1.9 * INSN_COST); 11286 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11287 11288 ins_encode %{ 11289 __ andw(as_Register($dst$$reg), 11290 as_Register($src1$$reg), 11291 as_Register($src2$$reg), 11292 Assembler::LSR, 11293 $src3$$constant & 0x1f); 11294 %} 11295 11296 ins_pipe(ialu_reg_reg_shift); 11297 %} 11298 11299 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11300 iRegL src1, iRegL src2, 11301 immI src3, rFlagsReg cr) %{ 11302 match(Set dst (AndL src1 (URShiftL src2 src3))); 11303 11304 ins_cost(1.9 * INSN_COST); 11305 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11306 11307 ins_encode %{ 11308 __ andr(as_Register($dst$$reg), 11309 as_Register($src1$$reg), 11310 as_Register($src2$$reg), 11311 Assembler::LSR, 11312 $src3$$constant & 0x3f); 11313 %} 11314 11315 ins_pipe(ialu_reg_reg_shift); 11316 %} 11317 11318 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11319 iRegIorL2I src1, iRegIorL2I src2, 11320 immI src3, rFlagsReg cr) %{ 11321 match(Set dst (AndI src1 (RShiftI src2 src3))); 11322 11323 ins_cost(1.9 * INSN_COST); 11324 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11325 11326 ins_encode %{ 11327 __ andw(as_Register($dst$$reg), 11328 as_Register($src1$$reg), 11329 as_Register($src2$$reg), 11330 Assembler::ASR, 11331 $src3$$constant & 0x1f); 11332 %} 11333 11334 ins_pipe(ialu_reg_reg_shift); 11335 %} 11336 11337 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11338 iRegL src1, iRegL src2, 11339 immI src3, rFlagsReg cr) %{ 11340 match(Set dst (AndL src1 (RShiftL src2 src3))); 11341 11342 ins_cost(1.9 * INSN_COST); 11343 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11344 11345 ins_encode %{ 11346 __ andr(as_Register($dst$$reg), 11347 as_Register($src1$$reg), 11348 as_Register($src2$$reg), 11349 Assembler::ASR, 11350 $src3$$constant & 0x3f); 11351 %} 11352 11353 ins_pipe(ialu_reg_reg_shift); 11354 %} 11355 11356 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11357 iRegIorL2I src1, iRegIorL2I src2, 11358 immI src3, rFlagsReg cr) %{ 11359 match(Set dst (AndI src1 (LShiftI src2 src3))); 11360 11361 ins_cost(1.9 * INSN_COST); 11362 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11363 11364 ins_encode %{ 11365 __ andw(as_Register($dst$$reg), 11366 as_Register($src1$$reg), 11367 as_Register($src2$$reg), 11368 Assembler::LSL, 11369 $src3$$constant & 0x1f); 11370 %} 11371 11372 ins_pipe(ialu_reg_reg_shift); 11373 %} 11374 11375 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11376 iRegL src1, iRegL src2, 11377 immI src3, rFlagsReg cr) %{ 11378 match(Set dst (AndL src1 (LShiftL src2 src3))); 11379 11380 ins_cost(1.9 * INSN_COST); 11381 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11382 11383 ins_encode %{ 11384 __ andr(as_Register($dst$$reg), 11385 as_Register($src1$$reg), 11386 as_Register($src2$$reg), 11387 Assembler::LSL, 11388 $src3$$constant & 0x3f); 11389 %} 11390 11391 ins_pipe(ialu_reg_reg_shift); 11392 %} 11393 11394 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11395 iRegIorL2I src1, iRegIorL2I src2, 11396 immI src3, rFlagsReg cr) %{ 11397 match(Set dst (XorI src1 (URShiftI src2 src3))); 11398 11399 ins_cost(1.9 * INSN_COST); 11400 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11401 11402 ins_encode %{ 11403 __ eorw(as_Register($dst$$reg), 11404 as_Register($src1$$reg), 11405 as_Register($src2$$reg), 11406 Assembler::LSR, 11407 $src3$$constant & 0x1f); 11408 %} 11409 11410 ins_pipe(ialu_reg_reg_shift); 11411 %} 11412 11413 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11414 iRegL src1, iRegL src2, 11415 immI src3, rFlagsReg cr) %{ 11416 match(Set dst (XorL src1 (URShiftL src2 src3))); 11417 11418 ins_cost(1.9 * INSN_COST); 11419 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11420 11421 ins_encode %{ 11422 __ eor(as_Register($dst$$reg), 11423 as_Register($src1$$reg), 11424 as_Register($src2$$reg), 11425 Assembler::LSR, 11426 $src3$$constant & 0x3f); 11427 %} 11428 11429 ins_pipe(ialu_reg_reg_shift); 11430 %} 11431 11432 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11433 iRegIorL2I src1, iRegIorL2I src2, 11434 immI src3, rFlagsReg cr) %{ 11435 match(Set dst (XorI src1 (RShiftI src2 src3))); 11436 11437 ins_cost(1.9 * INSN_COST); 11438 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11439 11440 ins_encode %{ 11441 __ eorw(as_Register($dst$$reg), 11442 as_Register($src1$$reg), 11443 as_Register($src2$$reg), 11444 Assembler::ASR, 11445 $src3$$constant & 0x1f); 11446 %} 11447 11448 ins_pipe(ialu_reg_reg_shift); 11449 %} 11450 11451 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11452 iRegL src1, iRegL src2, 11453 immI src3, rFlagsReg cr) %{ 11454 match(Set dst (XorL src1 (RShiftL src2 src3))); 11455 11456 ins_cost(1.9 * INSN_COST); 11457 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11458 11459 ins_encode %{ 11460 __ eor(as_Register($dst$$reg), 11461 as_Register($src1$$reg), 11462 as_Register($src2$$reg), 11463 Assembler::ASR, 11464 $src3$$constant & 0x3f); 11465 %} 11466 11467 ins_pipe(ialu_reg_reg_shift); 11468 %} 11469 11470 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11471 iRegIorL2I src1, iRegIorL2I src2, 11472 immI src3, rFlagsReg cr) %{ 11473 match(Set dst (XorI src1 (LShiftI src2 src3))); 11474 11475 ins_cost(1.9 * INSN_COST); 11476 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11477 11478 ins_encode %{ 11479 __ eorw(as_Register($dst$$reg), 11480 as_Register($src1$$reg), 11481 as_Register($src2$$reg), 11482 Assembler::LSL, 11483 $src3$$constant & 0x1f); 11484 %} 11485 11486 ins_pipe(ialu_reg_reg_shift); 11487 %} 11488 11489 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11490 iRegL src1, iRegL src2, 11491 immI src3, rFlagsReg cr) %{ 11492 match(Set dst (XorL src1 (LShiftL src2 src3))); 11493 11494 ins_cost(1.9 * INSN_COST); 11495 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11496 11497 ins_encode %{ 11498 __ eor(as_Register($dst$$reg), 11499 as_Register($src1$$reg), 11500 as_Register($src2$$reg), 11501 Assembler::LSL, 11502 $src3$$constant & 0x3f); 11503 %} 11504 11505 ins_pipe(ialu_reg_reg_shift); 11506 %} 11507 11508 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11509 iRegIorL2I src1, iRegIorL2I src2, 11510 immI src3, rFlagsReg cr) %{ 11511 match(Set dst (OrI src1 (URShiftI src2 src3))); 11512 11513 ins_cost(1.9 * INSN_COST); 11514 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11515 11516 ins_encode %{ 11517 __ orrw(as_Register($dst$$reg), 11518 as_Register($src1$$reg), 11519 as_Register($src2$$reg), 11520 Assembler::LSR, 11521 $src3$$constant & 0x1f); 11522 %} 11523 11524 ins_pipe(ialu_reg_reg_shift); 11525 %} 11526 11527 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11528 iRegL src1, iRegL src2, 11529 immI src3, rFlagsReg cr) %{ 11530 match(Set dst (OrL src1 (URShiftL src2 src3))); 11531 11532 ins_cost(1.9 * INSN_COST); 11533 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11534 11535 ins_encode %{ 11536 __ orr(as_Register($dst$$reg), 11537 as_Register($src1$$reg), 11538 as_Register($src2$$reg), 11539 Assembler::LSR, 11540 $src3$$constant & 0x3f); 11541 %} 11542 11543 ins_pipe(ialu_reg_reg_shift); 11544 %} 11545 11546 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11547 iRegIorL2I src1, iRegIorL2I src2, 11548 immI src3, rFlagsReg cr) %{ 11549 match(Set dst (OrI src1 (RShiftI src2 src3))); 11550 11551 ins_cost(1.9 * INSN_COST); 11552 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11553 11554 ins_encode %{ 11555 __ orrw(as_Register($dst$$reg), 11556 as_Register($src1$$reg), 11557 as_Register($src2$$reg), 11558 Assembler::ASR, 11559 $src3$$constant & 0x1f); 11560 %} 11561 11562 ins_pipe(ialu_reg_reg_shift); 11563 %} 11564 11565 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11566 iRegL src1, iRegL src2, 11567 immI src3, rFlagsReg cr) %{ 11568 match(Set dst (OrL src1 (RShiftL src2 src3))); 11569 11570 ins_cost(1.9 * INSN_COST); 11571 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11572 11573 ins_encode %{ 11574 __ orr(as_Register($dst$$reg), 11575 as_Register($src1$$reg), 11576 as_Register($src2$$reg), 11577 Assembler::ASR, 11578 $src3$$constant & 0x3f); 11579 %} 11580 11581 ins_pipe(ialu_reg_reg_shift); 11582 %} 11583 11584 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11585 iRegIorL2I src1, iRegIorL2I src2, 11586 immI src3, rFlagsReg cr) %{ 11587 match(Set dst (OrI src1 (LShiftI src2 src3))); 11588 11589 ins_cost(1.9 * INSN_COST); 11590 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11591 11592 ins_encode %{ 11593 __ orrw(as_Register($dst$$reg), 11594 as_Register($src1$$reg), 11595 as_Register($src2$$reg), 11596 Assembler::LSL, 11597 $src3$$constant & 0x1f); 11598 %} 11599 11600 ins_pipe(ialu_reg_reg_shift); 11601 %} 11602 11603 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11604 iRegL src1, iRegL src2, 11605 immI src3, rFlagsReg cr) %{ 11606 match(Set dst (OrL src1 (LShiftL src2 src3))); 11607 11608 ins_cost(1.9 * INSN_COST); 11609 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11610 11611 ins_encode %{ 11612 __ orr(as_Register($dst$$reg), 11613 as_Register($src1$$reg), 11614 as_Register($src2$$reg), 11615 Assembler::LSL, 11616 $src3$$constant & 0x3f); 11617 %} 11618 11619 ins_pipe(ialu_reg_reg_shift); 11620 %} 11621 11622 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11623 iRegIorL2I src1, iRegIorL2I src2, 11624 immI src3, rFlagsReg cr) %{ 11625 match(Set dst (AddI src1 (URShiftI src2 src3))); 11626 11627 ins_cost(1.9 * INSN_COST); 11628 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11629 11630 ins_encode %{ 11631 __ addw(as_Register($dst$$reg), 11632 as_Register($src1$$reg), 11633 as_Register($src2$$reg), 11634 Assembler::LSR, 11635 $src3$$constant & 0x1f); 11636 %} 11637 11638 ins_pipe(ialu_reg_reg_shift); 11639 %} 11640 11641 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11642 iRegL src1, iRegL src2, 11643 immI src3, rFlagsReg cr) %{ 11644 match(Set dst (AddL src1 (URShiftL src2 src3))); 11645 11646 ins_cost(1.9 * INSN_COST); 11647 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11648 11649 ins_encode %{ 11650 __ add(as_Register($dst$$reg), 11651 as_Register($src1$$reg), 11652 as_Register($src2$$reg), 11653 Assembler::LSR, 11654 $src3$$constant & 0x3f); 11655 %} 11656 11657 ins_pipe(ialu_reg_reg_shift); 11658 %} 11659 11660 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11661 iRegIorL2I src1, iRegIorL2I src2, 11662 immI src3, rFlagsReg cr) %{ 11663 match(Set dst (AddI src1 (RShiftI src2 src3))); 11664 11665 ins_cost(1.9 * INSN_COST); 11666 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11667 11668 ins_encode %{ 11669 __ addw(as_Register($dst$$reg), 11670 as_Register($src1$$reg), 11671 as_Register($src2$$reg), 11672 Assembler::ASR, 11673 $src3$$constant & 0x1f); 11674 %} 11675 11676 ins_pipe(ialu_reg_reg_shift); 11677 %} 11678 11679 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11680 iRegL src1, iRegL src2, 11681 immI src3, rFlagsReg cr) %{ 11682 match(Set dst (AddL src1 (RShiftL src2 src3))); 11683 11684 ins_cost(1.9 * INSN_COST); 11685 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11686 11687 ins_encode %{ 11688 __ add(as_Register($dst$$reg), 11689 as_Register($src1$$reg), 11690 as_Register($src2$$reg), 11691 Assembler::ASR, 11692 $src3$$constant & 0x3f); 11693 %} 11694 11695 ins_pipe(ialu_reg_reg_shift); 11696 %} 11697 11698 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11699 iRegIorL2I src1, iRegIorL2I src2, 11700 immI src3, rFlagsReg cr) %{ 11701 match(Set dst (AddI src1 (LShiftI src2 src3))); 11702 11703 ins_cost(1.9 * INSN_COST); 11704 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11705 11706 ins_encode %{ 11707 __ addw(as_Register($dst$$reg), 11708 as_Register($src1$$reg), 11709 as_Register($src2$$reg), 11710 Assembler::LSL, 11711 $src3$$constant & 0x1f); 11712 %} 11713 11714 ins_pipe(ialu_reg_reg_shift); 11715 %} 11716 11717 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11718 iRegL src1, iRegL src2, 11719 immI src3, rFlagsReg cr) %{ 11720 match(Set dst (AddL src1 (LShiftL src2 src3))); 11721 11722 ins_cost(1.9 * INSN_COST); 11723 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11724 11725 ins_encode %{ 11726 __ add(as_Register($dst$$reg), 11727 as_Register($src1$$reg), 11728 as_Register($src2$$reg), 11729 Assembler::LSL, 11730 $src3$$constant & 0x3f); 11731 %} 11732 11733 ins_pipe(ialu_reg_reg_shift); 11734 %} 11735 11736 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11737 iRegIorL2I src1, iRegIorL2I src2, 11738 immI src3, rFlagsReg cr) %{ 11739 match(Set dst (SubI src1 (URShiftI src2 src3))); 11740 11741 ins_cost(1.9 * INSN_COST); 11742 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11743 11744 ins_encode %{ 11745 __ subw(as_Register($dst$$reg), 11746 as_Register($src1$$reg), 11747 as_Register($src2$$reg), 11748 Assembler::LSR, 11749 $src3$$constant & 0x1f); 11750 %} 11751 11752 ins_pipe(ialu_reg_reg_shift); 11753 %} 11754 11755 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11756 iRegL src1, iRegL src2, 11757 immI src3, rFlagsReg cr) %{ 11758 match(Set dst (SubL src1 (URShiftL src2 src3))); 11759 11760 ins_cost(1.9 * INSN_COST); 11761 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11762 11763 ins_encode %{ 11764 __ sub(as_Register($dst$$reg), 11765 as_Register($src1$$reg), 11766 as_Register($src2$$reg), 11767 Assembler::LSR, 11768 $src3$$constant & 0x3f); 11769 %} 11770 11771 ins_pipe(ialu_reg_reg_shift); 11772 %} 11773 11774 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11775 iRegIorL2I src1, iRegIorL2I src2, 11776 immI src3, rFlagsReg cr) %{ 11777 match(Set dst (SubI src1 (RShiftI src2 src3))); 11778 11779 ins_cost(1.9 * INSN_COST); 11780 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11781 11782 ins_encode %{ 11783 __ subw(as_Register($dst$$reg), 11784 as_Register($src1$$reg), 11785 as_Register($src2$$reg), 11786 Assembler::ASR, 11787 $src3$$constant & 0x1f); 11788 %} 11789 11790 ins_pipe(ialu_reg_reg_shift); 11791 %} 11792 11793 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11794 iRegL src1, iRegL src2, 11795 immI src3, rFlagsReg cr) %{ 11796 match(Set dst (SubL src1 (RShiftL src2 src3))); 11797 11798 ins_cost(1.9 * INSN_COST); 11799 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11800 11801 ins_encode %{ 11802 __ sub(as_Register($dst$$reg), 11803 as_Register($src1$$reg), 11804 as_Register($src2$$reg), 11805 Assembler::ASR, 11806 $src3$$constant & 0x3f); 11807 %} 11808 11809 ins_pipe(ialu_reg_reg_shift); 11810 %} 11811 11812 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11813 iRegIorL2I src1, iRegIorL2I src2, 11814 immI src3, rFlagsReg cr) %{ 11815 match(Set dst (SubI src1 (LShiftI src2 src3))); 11816 11817 ins_cost(1.9 * INSN_COST); 11818 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11819 11820 ins_encode %{ 11821 __ subw(as_Register($dst$$reg), 11822 as_Register($src1$$reg), 11823 as_Register($src2$$reg), 11824 Assembler::LSL, 11825 $src3$$constant & 0x1f); 11826 %} 11827 11828 ins_pipe(ialu_reg_reg_shift); 11829 %} 11830 11831 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11832 iRegL src1, iRegL src2, 11833 immI src3, rFlagsReg cr) %{ 11834 match(Set dst (SubL src1 (LShiftL src2 src3))); 11835 11836 ins_cost(1.9 * INSN_COST); 11837 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11838 11839 ins_encode %{ 11840 __ sub(as_Register($dst$$reg), 11841 as_Register($src1$$reg), 11842 as_Register($src2$$reg), 11843 Assembler::LSL, 11844 $src3$$constant & 0x3f); 11845 %} 11846 11847 ins_pipe(ialu_reg_reg_shift); 11848 %} 11849 11850 11851 11852 // Shift Left followed by Shift Right. 11853 // This idiom is used by the compiler for the i2b bytecode etc. 11854 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11855 %{ 11856 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11857 ins_cost(INSN_COST * 2); 11858 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11859 ins_encode %{ 11860 int lshift = $lshift_count$$constant & 63; 11861 int rshift = $rshift_count$$constant & 63; 11862 int s = 63 - lshift; 11863 int r = (rshift - lshift) & 63; 11864 __ sbfm(as_Register($dst$$reg), 11865 as_Register($src$$reg), 11866 r, s); 11867 %} 11868 11869 ins_pipe(ialu_reg_shift); 11870 %} 11871 11872 // Shift Left followed by Shift Right. 11873 // This idiom is used by the compiler for the i2b bytecode etc. 11874 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11875 %{ 11876 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11877 ins_cost(INSN_COST * 2); 11878 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11879 ins_encode %{ 11880 int lshift = $lshift_count$$constant & 31; 11881 int rshift = $rshift_count$$constant & 31; 11882 int s = 31 - lshift; 11883 int r = (rshift - lshift) & 31; 11884 __ sbfmw(as_Register($dst$$reg), 11885 as_Register($src$$reg), 11886 r, s); 11887 %} 11888 11889 ins_pipe(ialu_reg_shift); 11890 %} 11891 11892 // Shift Left followed by Shift Right. 11893 // This idiom is used by the compiler for the i2b bytecode etc. 11894 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11895 %{ 11896 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11897 ins_cost(INSN_COST * 2); 11898 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11899 ins_encode %{ 11900 int lshift = $lshift_count$$constant & 63; 11901 int rshift = $rshift_count$$constant & 63; 11902 int s = 63 - lshift; 11903 int r = (rshift - lshift) & 63; 11904 __ ubfm(as_Register($dst$$reg), 11905 as_Register($src$$reg), 11906 r, s); 11907 %} 11908 11909 ins_pipe(ialu_reg_shift); 11910 %} 11911 11912 // Shift Left followed by Shift Right. 11913 // This idiom is used by the compiler for the i2b bytecode etc. 11914 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11915 %{ 11916 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11917 ins_cost(INSN_COST * 2); 11918 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11919 ins_encode %{ 11920 int lshift = $lshift_count$$constant & 31; 11921 int rshift = $rshift_count$$constant & 31; 11922 int s = 31 - lshift; 11923 int r = (rshift - lshift) & 31; 11924 __ ubfmw(as_Register($dst$$reg), 11925 as_Register($src$$reg), 11926 r, s); 11927 %} 11928 11929 ins_pipe(ialu_reg_shift); 11930 %} 11931 // Bitfield extract with shift & mask 11932 11933 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11934 %{ 11935 match(Set dst (AndI (URShiftI src rshift) mask)); 11936 // Make sure we are not going to exceed what ubfxw can do. 11937 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11938 11939 ins_cost(INSN_COST); 11940 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11941 ins_encode %{ 11942 int rshift = $rshift$$constant & 31; 11943 int64_t mask = $mask$$constant; 11944 int width = exact_log2(mask+1); 11945 __ ubfxw(as_Register($dst$$reg), 11946 as_Register($src$$reg), rshift, width); 11947 %} 11948 ins_pipe(ialu_reg_shift); 11949 %} 11950 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11951 %{ 11952 match(Set dst (AndL (URShiftL src rshift) mask)); 11953 // Make sure we are not going to exceed what ubfx can do. 11954 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 11955 11956 ins_cost(INSN_COST); 11957 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11958 ins_encode %{ 11959 int rshift = $rshift$$constant & 63; 11960 int64_t mask = $mask$$constant; 11961 int width = exact_log2_long(mask+1); 11962 __ ubfx(as_Register($dst$$reg), 11963 as_Register($src$$reg), rshift, width); 11964 %} 11965 ins_pipe(ialu_reg_shift); 11966 %} 11967 11968 // We can use ubfx when extending an And with a mask when we know mask 11969 // is positive. We know that because immI_bitmask guarantees it. 11970 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11971 %{ 11972 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11973 // Make sure we are not going to exceed what ubfxw can do. 11974 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11975 11976 ins_cost(INSN_COST * 2); 11977 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11978 ins_encode %{ 11979 int rshift = $rshift$$constant & 31; 11980 int64_t mask = $mask$$constant; 11981 int width = exact_log2(mask+1); 11982 __ ubfx(as_Register($dst$$reg), 11983 as_Register($src$$reg), rshift, width); 11984 %} 11985 ins_pipe(ialu_reg_shift); 11986 %} 11987 11988 // We can use ubfiz when masking by a positive number and then left shifting the result. 11989 // We know that the mask is positive because immI_bitmask guarantees it. 11990 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11991 %{ 11992 match(Set dst (LShiftI (AndI src mask) lshift)); 11993 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 11994 11995 ins_cost(INSN_COST); 11996 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11997 ins_encode %{ 11998 int lshift = $lshift$$constant & 31; 11999 int64_t mask = $mask$$constant; 12000 int width = exact_log2(mask+1); 12001 __ ubfizw(as_Register($dst$$reg), 12002 as_Register($src$$reg), lshift, width); 12003 %} 12004 ins_pipe(ialu_reg_shift); 12005 %} 12006 // We can use ubfiz when masking by a positive number and then left shifting the result. 12007 // We know that the mask is positive because immL_bitmask guarantees it. 12008 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12009 %{ 12010 match(Set dst (LShiftL (AndL src mask) lshift)); 12011 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12012 12013 ins_cost(INSN_COST); 12014 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12015 ins_encode %{ 12016 int lshift = $lshift$$constant & 63; 12017 int64_t mask = $mask$$constant; 12018 int width = exact_log2_long(mask+1); 12019 __ ubfiz(as_Register($dst$$reg), 12020 as_Register($src$$reg), lshift, width); 12021 %} 12022 ins_pipe(ialu_reg_shift); 12023 %} 12024 12025 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12026 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12027 %{ 12028 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12029 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12030 12031 ins_cost(INSN_COST); 12032 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12033 ins_encode %{ 12034 int lshift = $lshift$$constant & 63; 12035 int64_t mask = $mask$$constant; 12036 int width = exact_log2(mask+1); 12037 __ ubfiz(as_Register($dst$$reg), 12038 as_Register($src$$reg), lshift, width); 12039 %} 12040 ins_pipe(ialu_reg_shift); 12041 %} 12042 12043 // Rotations 12044 12045 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12046 %{ 12047 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12048 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12049 12050 ins_cost(INSN_COST); 12051 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12052 12053 ins_encode %{ 12054 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12055 $rshift$$constant & 63); 12056 %} 12057 ins_pipe(ialu_reg_reg_extr); 12058 %} 12059 12060 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12061 %{ 12062 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12063 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12064 12065 ins_cost(INSN_COST); 12066 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12067 12068 ins_encode %{ 12069 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12070 $rshift$$constant & 31); 12071 %} 12072 ins_pipe(ialu_reg_reg_extr); 12073 %} 12074 12075 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12076 %{ 12077 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12078 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12079 12080 ins_cost(INSN_COST); 12081 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12082 12083 ins_encode %{ 12084 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12085 $rshift$$constant & 63); 12086 %} 12087 ins_pipe(ialu_reg_reg_extr); 12088 %} 12089 12090 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12091 %{ 12092 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12093 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12094 12095 ins_cost(INSN_COST); 12096 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12097 12098 ins_encode %{ 12099 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12100 $rshift$$constant & 31); 12101 %} 12102 ins_pipe(ialu_reg_reg_extr); 12103 %} 12104 12105 12106 // rol expander 12107 12108 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12109 %{ 12110 effect(DEF dst, USE src, USE shift); 12111 12112 format %{ "rol $dst, $src, $shift" %} 12113 ins_cost(INSN_COST * 3); 12114 ins_encode %{ 12115 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12116 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12117 rscratch1); 12118 %} 12119 ins_pipe(ialu_reg_reg_vshift); 12120 %} 12121 12122 // rol expander 12123 12124 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12125 %{ 12126 effect(DEF dst, USE src, USE shift); 12127 12128 format %{ "rol $dst, $src, $shift" %} 12129 ins_cost(INSN_COST * 3); 12130 ins_encode %{ 12131 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12132 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12133 rscratch1); 12134 %} 12135 ins_pipe(ialu_reg_reg_vshift); 12136 %} 12137 12138 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12139 %{ 12140 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12141 12142 expand %{ 12143 rolL_rReg(dst, src, shift, cr); 12144 %} 12145 %} 12146 12147 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12148 %{ 12149 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12150 12151 expand %{ 12152 rolL_rReg(dst, src, shift, cr); 12153 %} 12154 %} 12155 12156 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12157 %{ 12158 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12159 12160 expand %{ 12161 rolI_rReg(dst, src, shift, cr); 12162 %} 12163 %} 12164 12165 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12166 %{ 12167 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12168 12169 expand %{ 12170 rolI_rReg(dst, src, shift, cr); 12171 %} 12172 %} 12173 12174 // ror expander 12175 12176 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12177 %{ 12178 effect(DEF dst, USE src, USE shift); 12179 12180 format %{ "ror $dst, $src, $shift" %} 12181 ins_cost(INSN_COST); 12182 ins_encode %{ 12183 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12184 as_Register($shift$$reg)); 12185 %} 12186 ins_pipe(ialu_reg_reg_vshift); 12187 %} 12188 12189 // ror expander 12190 12191 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12192 %{ 12193 effect(DEF dst, USE src, USE shift); 12194 12195 format %{ "ror $dst, $src, $shift" %} 12196 ins_cost(INSN_COST); 12197 ins_encode %{ 12198 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12199 as_Register($shift$$reg)); 12200 %} 12201 ins_pipe(ialu_reg_reg_vshift); 12202 %} 12203 12204 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12205 %{ 12206 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12207 12208 expand %{ 12209 rorL_rReg(dst, src, shift, cr); 12210 %} 12211 %} 12212 12213 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12214 %{ 12215 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12216 12217 expand %{ 12218 rorL_rReg(dst, src, shift, cr); 12219 %} 12220 %} 12221 12222 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12223 %{ 12224 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12225 12226 expand %{ 12227 rorI_rReg(dst, src, shift, cr); 12228 %} 12229 %} 12230 12231 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12232 %{ 12233 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12234 12235 expand %{ 12236 rorI_rReg(dst, src, shift, cr); 12237 %} 12238 %} 12239 12240 // Add/subtract (extended) 12241 12242 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12243 %{ 12244 match(Set dst (AddL src1 (ConvI2L src2))); 12245 ins_cost(INSN_COST); 12246 format %{ "add $dst, $src1, $src2, sxtw" %} 12247 12248 ins_encode %{ 12249 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12250 as_Register($src2$$reg), ext::sxtw); 12251 %} 12252 ins_pipe(ialu_reg_reg); 12253 %}; 12254 12255 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12256 %{ 12257 match(Set dst (SubL src1 (ConvI2L src2))); 12258 ins_cost(INSN_COST); 12259 format %{ "sub $dst, $src1, $src2, sxtw" %} 12260 12261 ins_encode %{ 12262 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12263 as_Register($src2$$reg), ext::sxtw); 12264 %} 12265 ins_pipe(ialu_reg_reg); 12266 %}; 12267 12268 12269 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12270 %{ 12271 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12272 ins_cost(INSN_COST); 12273 format %{ "add $dst, $src1, $src2, sxth" %} 12274 12275 ins_encode %{ 12276 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12277 as_Register($src2$$reg), ext::sxth); 12278 %} 12279 ins_pipe(ialu_reg_reg); 12280 %} 12281 12282 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12283 %{ 12284 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12285 ins_cost(INSN_COST); 12286 format %{ "add $dst, $src1, $src2, sxtb" %} 12287 12288 ins_encode %{ 12289 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12290 as_Register($src2$$reg), ext::sxtb); 12291 %} 12292 ins_pipe(ialu_reg_reg); 12293 %} 12294 12295 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12296 %{ 12297 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12298 ins_cost(INSN_COST); 12299 format %{ "add $dst, $src1, $src2, uxtb" %} 12300 12301 ins_encode %{ 12302 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12303 as_Register($src2$$reg), ext::uxtb); 12304 %} 12305 ins_pipe(ialu_reg_reg); 12306 %} 12307 12308 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12309 %{ 12310 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12311 ins_cost(INSN_COST); 12312 format %{ "add $dst, $src1, $src2, sxth" %} 12313 12314 ins_encode %{ 12315 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12316 as_Register($src2$$reg), ext::sxth); 12317 %} 12318 ins_pipe(ialu_reg_reg); 12319 %} 12320 12321 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12322 %{ 12323 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12324 ins_cost(INSN_COST); 12325 format %{ "add $dst, $src1, $src2, sxtw" %} 12326 12327 ins_encode %{ 12328 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12329 as_Register($src2$$reg), ext::sxtw); 12330 %} 12331 ins_pipe(ialu_reg_reg); 12332 %} 12333 12334 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12335 %{ 12336 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12337 ins_cost(INSN_COST); 12338 format %{ "add $dst, $src1, $src2, sxtb" %} 12339 12340 ins_encode %{ 12341 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12342 as_Register($src2$$reg), ext::sxtb); 12343 %} 12344 ins_pipe(ialu_reg_reg); 12345 %} 12346 12347 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12348 %{ 12349 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12350 ins_cost(INSN_COST); 12351 format %{ "add $dst, $src1, $src2, uxtb" %} 12352 12353 ins_encode %{ 12354 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12355 as_Register($src2$$reg), ext::uxtb); 12356 %} 12357 ins_pipe(ialu_reg_reg); 12358 %} 12359 12360 12361 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12362 %{ 12363 match(Set dst (AddI src1 (AndI src2 mask))); 12364 ins_cost(INSN_COST); 12365 format %{ "addw $dst, $src1, $src2, uxtb" %} 12366 12367 ins_encode %{ 12368 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12369 as_Register($src2$$reg), ext::uxtb); 12370 %} 12371 ins_pipe(ialu_reg_reg); 12372 %} 12373 12374 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12375 %{ 12376 match(Set dst (AddI src1 (AndI src2 mask))); 12377 ins_cost(INSN_COST); 12378 format %{ "addw $dst, $src1, $src2, uxth" %} 12379 12380 ins_encode %{ 12381 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12382 as_Register($src2$$reg), ext::uxth); 12383 %} 12384 ins_pipe(ialu_reg_reg); 12385 %} 12386 12387 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12388 %{ 12389 match(Set dst (AddL src1 (AndL src2 mask))); 12390 ins_cost(INSN_COST); 12391 format %{ "add $dst, $src1, $src2, uxtb" %} 12392 12393 ins_encode %{ 12394 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12395 as_Register($src2$$reg), ext::uxtb); 12396 %} 12397 ins_pipe(ialu_reg_reg); 12398 %} 12399 12400 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12401 %{ 12402 match(Set dst (AddL src1 (AndL src2 mask))); 12403 ins_cost(INSN_COST); 12404 format %{ "add $dst, $src1, $src2, uxth" %} 12405 12406 ins_encode %{ 12407 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12408 as_Register($src2$$reg), ext::uxth); 12409 %} 12410 ins_pipe(ialu_reg_reg); 12411 %} 12412 12413 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12414 %{ 12415 match(Set dst (AddL src1 (AndL src2 mask))); 12416 ins_cost(INSN_COST); 12417 format %{ "add $dst, $src1, $src2, uxtw" %} 12418 12419 ins_encode %{ 12420 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12421 as_Register($src2$$reg), ext::uxtw); 12422 %} 12423 ins_pipe(ialu_reg_reg); 12424 %} 12425 12426 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12427 %{ 12428 match(Set dst (SubI src1 (AndI src2 mask))); 12429 ins_cost(INSN_COST); 12430 format %{ "subw $dst, $src1, $src2, uxtb" %} 12431 12432 ins_encode %{ 12433 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12434 as_Register($src2$$reg), ext::uxtb); 12435 %} 12436 ins_pipe(ialu_reg_reg); 12437 %} 12438 12439 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12440 %{ 12441 match(Set dst (SubI src1 (AndI src2 mask))); 12442 ins_cost(INSN_COST); 12443 format %{ "subw $dst, $src1, $src2, uxth" %} 12444 12445 ins_encode %{ 12446 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12447 as_Register($src2$$reg), ext::uxth); 12448 %} 12449 ins_pipe(ialu_reg_reg); 12450 %} 12451 12452 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12453 %{ 12454 match(Set dst (SubL src1 (AndL src2 mask))); 12455 ins_cost(INSN_COST); 12456 format %{ "sub $dst, $src1, $src2, uxtb" %} 12457 12458 ins_encode %{ 12459 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12460 as_Register($src2$$reg), ext::uxtb); 12461 %} 12462 ins_pipe(ialu_reg_reg); 12463 %} 12464 12465 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12466 %{ 12467 match(Set dst (SubL src1 (AndL src2 mask))); 12468 ins_cost(INSN_COST); 12469 format %{ "sub $dst, $src1, $src2, uxth" %} 12470 12471 ins_encode %{ 12472 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12473 as_Register($src2$$reg), ext::uxth); 12474 %} 12475 ins_pipe(ialu_reg_reg); 12476 %} 12477 12478 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12479 %{ 12480 match(Set dst (SubL src1 (AndL src2 mask))); 12481 ins_cost(INSN_COST); 12482 format %{ "sub $dst, $src1, $src2, uxtw" %} 12483 12484 ins_encode %{ 12485 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12486 as_Register($src2$$reg), ext::uxtw); 12487 %} 12488 ins_pipe(ialu_reg_reg); 12489 %} 12490 12491 12492 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12493 %{ 12494 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12495 ins_cost(1.9 * INSN_COST); 12496 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12497 12498 ins_encode %{ 12499 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12500 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12501 %} 12502 ins_pipe(ialu_reg_reg_shift); 12503 %} 12504 12505 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12506 %{ 12507 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12508 ins_cost(1.9 * INSN_COST); 12509 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12510 12511 ins_encode %{ 12512 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12513 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12514 %} 12515 ins_pipe(ialu_reg_reg_shift); 12516 %} 12517 12518 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12519 %{ 12520 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12521 ins_cost(1.9 * INSN_COST); 12522 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12523 12524 ins_encode %{ 12525 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12526 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12527 %} 12528 ins_pipe(ialu_reg_reg_shift); 12529 %} 12530 12531 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12532 %{ 12533 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12534 ins_cost(1.9 * INSN_COST); 12535 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12536 12537 ins_encode %{ 12538 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12539 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12540 %} 12541 ins_pipe(ialu_reg_reg_shift); 12542 %} 12543 12544 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12545 %{ 12546 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12547 ins_cost(1.9 * INSN_COST); 12548 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12549 12550 ins_encode %{ 12551 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12552 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12553 %} 12554 ins_pipe(ialu_reg_reg_shift); 12555 %} 12556 12557 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12558 %{ 12559 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12560 ins_cost(1.9 * INSN_COST); 12561 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12562 12563 ins_encode %{ 12564 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12565 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12566 %} 12567 ins_pipe(ialu_reg_reg_shift); 12568 %} 12569 12570 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12571 %{ 12572 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12573 ins_cost(1.9 * INSN_COST); 12574 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12575 12576 ins_encode %{ 12577 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12578 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12579 %} 12580 ins_pipe(ialu_reg_reg_shift); 12581 %} 12582 12583 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12584 %{ 12585 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12586 ins_cost(1.9 * INSN_COST); 12587 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12588 12589 ins_encode %{ 12590 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12591 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12592 %} 12593 ins_pipe(ialu_reg_reg_shift); 12594 %} 12595 12596 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12597 %{ 12598 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12599 ins_cost(1.9 * INSN_COST); 12600 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12601 12602 ins_encode %{ 12603 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12604 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12605 %} 12606 ins_pipe(ialu_reg_reg_shift); 12607 %} 12608 12609 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12610 %{ 12611 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12612 ins_cost(1.9 * INSN_COST); 12613 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12614 12615 ins_encode %{ 12616 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12617 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12618 %} 12619 ins_pipe(ialu_reg_reg_shift); 12620 %} 12621 12622 12623 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12624 %{ 12625 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12626 ins_cost(1.9 * INSN_COST); 12627 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12628 12629 ins_encode %{ 12630 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12631 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12632 %} 12633 ins_pipe(ialu_reg_reg_shift); 12634 %}; 12635 12636 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12637 %{ 12638 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12639 ins_cost(1.9 * INSN_COST); 12640 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12641 12642 ins_encode %{ 12643 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12644 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12645 %} 12646 ins_pipe(ialu_reg_reg_shift); 12647 %}; 12648 12649 12650 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12651 %{ 12652 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12653 ins_cost(1.9 * INSN_COST); 12654 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12655 12656 ins_encode %{ 12657 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12658 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12659 %} 12660 ins_pipe(ialu_reg_reg_shift); 12661 %} 12662 12663 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12664 %{ 12665 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12666 ins_cost(1.9 * INSN_COST); 12667 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12668 12669 ins_encode %{ 12670 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12671 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12672 %} 12673 ins_pipe(ialu_reg_reg_shift); 12674 %} 12675 12676 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12677 %{ 12678 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12679 ins_cost(1.9 * INSN_COST); 12680 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12681 12682 ins_encode %{ 12683 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12684 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12685 %} 12686 ins_pipe(ialu_reg_reg_shift); 12687 %} 12688 12689 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12690 %{ 12691 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12692 ins_cost(1.9 * INSN_COST); 12693 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12694 12695 ins_encode %{ 12696 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12697 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12698 %} 12699 ins_pipe(ialu_reg_reg_shift); 12700 %} 12701 12702 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12703 %{ 12704 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12705 ins_cost(1.9 * INSN_COST); 12706 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12707 12708 ins_encode %{ 12709 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12710 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12711 %} 12712 ins_pipe(ialu_reg_reg_shift); 12713 %} 12714 12715 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12716 %{ 12717 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12718 ins_cost(1.9 * INSN_COST); 12719 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12720 12721 ins_encode %{ 12722 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12723 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12724 %} 12725 ins_pipe(ialu_reg_reg_shift); 12726 %} 12727 12728 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12729 %{ 12730 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12731 ins_cost(1.9 * INSN_COST); 12732 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12733 12734 ins_encode %{ 12735 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12736 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12737 %} 12738 ins_pipe(ialu_reg_reg_shift); 12739 %} 12740 12741 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12742 %{ 12743 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12744 ins_cost(1.9 * INSN_COST); 12745 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12746 12747 ins_encode %{ 12748 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12749 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12750 %} 12751 ins_pipe(ialu_reg_reg_shift); 12752 %} 12753 12754 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12755 %{ 12756 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12757 ins_cost(1.9 * INSN_COST); 12758 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12759 12760 ins_encode %{ 12761 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12762 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12763 %} 12764 ins_pipe(ialu_reg_reg_shift); 12765 %} 12766 12767 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12768 %{ 12769 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12770 ins_cost(1.9 * INSN_COST); 12771 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12772 12773 ins_encode %{ 12774 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12775 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12776 %} 12777 ins_pipe(ialu_reg_reg_shift); 12778 %} 12779 // END This section of the file is automatically generated. Do not edit -------------- 12780 12781 // ============================================================================ 12782 // Floating Point Arithmetic Instructions 12783 12784 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12785 match(Set dst (AddF src1 src2)); 12786 12787 ins_cost(INSN_COST * 5); 12788 format %{ "fadds $dst, $src1, $src2" %} 12789 12790 ins_encode %{ 12791 __ fadds(as_FloatRegister($dst$$reg), 12792 as_FloatRegister($src1$$reg), 12793 as_FloatRegister($src2$$reg)); 12794 %} 12795 12796 ins_pipe(fp_dop_reg_reg_s); 12797 %} 12798 12799 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12800 match(Set dst (AddD src1 src2)); 12801 12802 ins_cost(INSN_COST * 5); 12803 format %{ "faddd $dst, $src1, $src2" %} 12804 12805 ins_encode %{ 12806 __ faddd(as_FloatRegister($dst$$reg), 12807 as_FloatRegister($src1$$reg), 12808 as_FloatRegister($src2$$reg)); 12809 %} 12810 12811 ins_pipe(fp_dop_reg_reg_d); 12812 %} 12813 12814 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12815 match(Set dst (SubF src1 src2)); 12816 12817 ins_cost(INSN_COST * 5); 12818 format %{ "fsubs $dst, $src1, $src2" %} 12819 12820 ins_encode %{ 12821 __ fsubs(as_FloatRegister($dst$$reg), 12822 as_FloatRegister($src1$$reg), 12823 as_FloatRegister($src2$$reg)); 12824 %} 12825 12826 ins_pipe(fp_dop_reg_reg_s); 12827 %} 12828 12829 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12830 match(Set dst (SubD src1 src2)); 12831 12832 ins_cost(INSN_COST * 5); 12833 format %{ "fsubd $dst, $src1, $src2" %} 12834 12835 ins_encode %{ 12836 __ fsubd(as_FloatRegister($dst$$reg), 12837 as_FloatRegister($src1$$reg), 12838 as_FloatRegister($src2$$reg)); 12839 %} 12840 12841 ins_pipe(fp_dop_reg_reg_d); 12842 %} 12843 12844 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12845 match(Set dst (MulF src1 src2)); 12846 12847 ins_cost(INSN_COST * 6); 12848 format %{ "fmuls $dst, $src1, $src2" %} 12849 12850 ins_encode %{ 12851 __ fmuls(as_FloatRegister($dst$$reg), 12852 as_FloatRegister($src1$$reg), 12853 as_FloatRegister($src2$$reg)); 12854 %} 12855 12856 ins_pipe(fp_dop_reg_reg_s); 12857 %} 12858 12859 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12860 match(Set dst (MulD src1 src2)); 12861 12862 ins_cost(INSN_COST * 6); 12863 format %{ "fmuld $dst, $src1, $src2" %} 12864 12865 ins_encode %{ 12866 __ fmuld(as_FloatRegister($dst$$reg), 12867 as_FloatRegister($src1$$reg), 12868 as_FloatRegister($src2$$reg)); 12869 %} 12870 12871 ins_pipe(fp_dop_reg_reg_d); 12872 %} 12873 12874 // src1 * src2 + src3 12875 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12876 predicate(UseFMA); 12877 match(Set dst (FmaF src3 (Binary src1 src2))); 12878 12879 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12880 12881 ins_encode %{ 12882 __ fmadds(as_FloatRegister($dst$$reg), 12883 as_FloatRegister($src1$$reg), 12884 as_FloatRegister($src2$$reg), 12885 as_FloatRegister($src3$$reg)); 12886 %} 12887 12888 ins_pipe(pipe_class_default); 12889 %} 12890 12891 // src1 * src2 + src3 12892 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12893 predicate(UseFMA); 12894 match(Set dst (FmaD src3 (Binary src1 src2))); 12895 12896 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12897 12898 ins_encode %{ 12899 __ fmaddd(as_FloatRegister($dst$$reg), 12900 as_FloatRegister($src1$$reg), 12901 as_FloatRegister($src2$$reg), 12902 as_FloatRegister($src3$$reg)); 12903 %} 12904 12905 ins_pipe(pipe_class_default); 12906 %} 12907 12908 // -src1 * src2 + src3 12909 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12910 predicate(UseFMA); 12911 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12912 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12913 12914 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12915 12916 ins_encode %{ 12917 __ fmsubs(as_FloatRegister($dst$$reg), 12918 as_FloatRegister($src1$$reg), 12919 as_FloatRegister($src2$$reg), 12920 as_FloatRegister($src3$$reg)); 12921 %} 12922 12923 ins_pipe(pipe_class_default); 12924 %} 12925 12926 // -src1 * src2 + src3 12927 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12928 predicate(UseFMA); 12929 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12930 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12931 12932 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12933 12934 ins_encode %{ 12935 __ fmsubd(as_FloatRegister($dst$$reg), 12936 as_FloatRegister($src1$$reg), 12937 as_FloatRegister($src2$$reg), 12938 as_FloatRegister($src3$$reg)); 12939 %} 12940 12941 ins_pipe(pipe_class_default); 12942 %} 12943 12944 // -src1 * src2 - src3 12945 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12946 predicate(UseFMA); 12947 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12948 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12949 12950 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12951 12952 ins_encode %{ 12953 __ fnmadds(as_FloatRegister($dst$$reg), 12954 as_FloatRegister($src1$$reg), 12955 as_FloatRegister($src2$$reg), 12956 as_FloatRegister($src3$$reg)); 12957 %} 12958 12959 ins_pipe(pipe_class_default); 12960 %} 12961 12962 // -src1 * src2 - src3 12963 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12964 predicate(UseFMA); 12965 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12966 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12967 12968 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12969 12970 ins_encode %{ 12971 __ fnmaddd(as_FloatRegister($dst$$reg), 12972 as_FloatRegister($src1$$reg), 12973 as_FloatRegister($src2$$reg), 12974 as_FloatRegister($src3$$reg)); 12975 %} 12976 12977 ins_pipe(pipe_class_default); 12978 %} 12979 12980 // src1 * src2 - src3 12981 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12982 predicate(UseFMA); 12983 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12984 12985 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12986 12987 ins_encode %{ 12988 __ fnmsubs(as_FloatRegister($dst$$reg), 12989 as_FloatRegister($src1$$reg), 12990 as_FloatRegister($src2$$reg), 12991 as_FloatRegister($src3$$reg)); 12992 %} 12993 12994 ins_pipe(pipe_class_default); 12995 %} 12996 12997 // src1 * src2 - src3 12998 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12999 predicate(UseFMA); 13000 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13001 13002 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13003 13004 ins_encode %{ 13005 // n.b. insn name should be fnmsubd 13006 __ fnmsub(as_FloatRegister($dst$$reg), 13007 as_FloatRegister($src1$$reg), 13008 as_FloatRegister($src2$$reg), 13009 as_FloatRegister($src3$$reg)); 13010 %} 13011 13012 ins_pipe(pipe_class_default); 13013 %} 13014 13015 13016 // Math.max(FF)F 13017 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13018 match(Set dst (MaxF src1 src2)); 13019 13020 format %{ "fmaxs $dst, $src1, $src2" %} 13021 ins_encode %{ 13022 __ fmaxs(as_FloatRegister($dst$$reg), 13023 as_FloatRegister($src1$$reg), 13024 as_FloatRegister($src2$$reg)); 13025 %} 13026 13027 ins_pipe(fp_dop_reg_reg_s); 13028 %} 13029 13030 // Math.min(FF)F 13031 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13032 match(Set dst (MinF src1 src2)); 13033 13034 format %{ "fmins $dst, $src1, $src2" %} 13035 ins_encode %{ 13036 __ fmins(as_FloatRegister($dst$$reg), 13037 as_FloatRegister($src1$$reg), 13038 as_FloatRegister($src2$$reg)); 13039 %} 13040 13041 ins_pipe(fp_dop_reg_reg_s); 13042 %} 13043 13044 // Math.max(DD)D 13045 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13046 match(Set dst (MaxD src1 src2)); 13047 13048 format %{ "fmaxd $dst, $src1, $src2" %} 13049 ins_encode %{ 13050 __ fmaxd(as_FloatRegister($dst$$reg), 13051 as_FloatRegister($src1$$reg), 13052 as_FloatRegister($src2$$reg)); 13053 %} 13054 13055 ins_pipe(fp_dop_reg_reg_d); 13056 %} 13057 13058 // Math.min(DD)D 13059 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13060 match(Set dst (MinD src1 src2)); 13061 13062 format %{ "fmind $dst, $src1, $src2" %} 13063 ins_encode %{ 13064 __ fmind(as_FloatRegister($dst$$reg), 13065 as_FloatRegister($src1$$reg), 13066 as_FloatRegister($src2$$reg)); 13067 %} 13068 13069 ins_pipe(fp_dop_reg_reg_d); 13070 %} 13071 13072 13073 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13074 match(Set dst (DivF src1 src2)); 13075 13076 ins_cost(INSN_COST * 18); 13077 format %{ "fdivs $dst, $src1, $src2" %} 13078 13079 ins_encode %{ 13080 __ fdivs(as_FloatRegister($dst$$reg), 13081 as_FloatRegister($src1$$reg), 13082 as_FloatRegister($src2$$reg)); 13083 %} 13084 13085 ins_pipe(fp_div_s); 13086 %} 13087 13088 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13089 match(Set dst (DivD src1 src2)); 13090 13091 ins_cost(INSN_COST * 32); 13092 format %{ "fdivd $dst, $src1, $src2" %} 13093 13094 ins_encode %{ 13095 __ fdivd(as_FloatRegister($dst$$reg), 13096 as_FloatRegister($src1$$reg), 13097 as_FloatRegister($src2$$reg)); 13098 %} 13099 13100 ins_pipe(fp_div_d); 13101 %} 13102 13103 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13104 match(Set dst (NegF src)); 13105 13106 ins_cost(INSN_COST * 3); 13107 format %{ "fneg $dst, $src" %} 13108 13109 ins_encode %{ 13110 __ fnegs(as_FloatRegister($dst$$reg), 13111 as_FloatRegister($src$$reg)); 13112 %} 13113 13114 ins_pipe(fp_uop_s); 13115 %} 13116 13117 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13118 match(Set dst (NegD src)); 13119 13120 ins_cost(INSN_COST * 3); 13121 format %{ "fnegd $dst, $src" %} 13122 13123 ins_encode %{ 13124 __ fnegd(as_FloatRegister($dst$$reg), 13125 as_FloatRegister($src$$reg)); 13126 %} 13127 13128 ins_pipe(fp_uop_d); 13129 %} 13130 13131 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13132 %{ 13133 match(Set dst (AbsI src)); 13134 13135 effect(KILL cr); 13136 ins_cost(INSN_COST * 2); 13137 format %{ "cmpw $src, zr\n\t" 13138 "cnegw $dst, $src, Assembler::LT\t# int abs" 13139 %} 13140 13141 ins_encode %{ 13142 __ cmpw(as_Register($src$$reg), zr); 13143 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13144 %} 13145 ins_pipe(pipe_class_default); 13146 %} 13147 13148 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 13149 %{ 13150 match(Set dst (AbsL src)); 13151 13152 effect(KILL cr); 13153 ins_cost(INSN_COST * 2); 13154 format %{ "cmp $src, zr\n\t" 13155 "cneg $dst, $src, Assembler::LT\t# long abs" 13156 %} 13157 13158 ins_encode %{ 13159 __ cmp(as_Register($src$$reg), zr); 13160 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 13161 %} 13162 ins_pipe(pipe_class_default); 13163 %} 13164 13165 instruct absF_reg(vRegF dst, vRegF src) %{ 13166 match(Set dst (AbsF src)); 13167 13168 ins_cost(INSN_COST * 3); 13169 format %{ "fabss $dst, $src" %} 13170 ins_encode %{ 13171 __ fabss(as_FloatRegister($dst$$reg), 13172 as_FloatRegister($src$$reg)); 13173 %} 13174 13175 ins_pipe(fp_uop_s); 13176 %} 13177 13178 instruct absD_reg(vRegD dst, vRegD src) %{ 13179 match(Set dst (AbsD src)); 13180 13181 ins_cost(INSN_COST * 3); 13182 format %{ "fabsd $dst, $src" %} 13183 ins_encode %{ 13184 __ fabsd(as_FloatRegister($dst$$reg), 13185 as_FloatRegister($src$$reg)); 13186 %} 13187 13188 ins_pipe(fp_uop_d); 13189 %} 13190 13191 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13192 match(Set dst (SqrtD src)); 13193 13194 ins_cost(INSN_COST * 50); 13195 format %{ "fsqrtd $dst, $src" %} 13196 ins_encode %{ 13197 __ fsqrtd(as_FloatRegister($dst$$reg), 13198 as_FloatRegister($src$$reg)); 13199 %} 13200 13201 ins_pipe(fp_div_s); 13202 %} 13203 13204 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13205 match(Set dst (SqrtF src)); 13206 13207 ins_cost(INSN_COST * 50); 13208 format %{ "fsqrts $dst, $src" %} 13209 ins_encode %{ 13210 __ fsqrts(as_FloatRegister($dst$$reg), 13211 as_FloatRegister($src$$reg)); 13212 %} 13213 13214 ins_pipe(fp_div_d); 13215 %} 13216 13217 // Math.rint, floor, ceil 13218 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 13219 match(Set dst (RoundDoubleMode src rmode)); 13220 format %{ "frint $dst, $src, $rmode" %} 13221 ins_encode %{ 13222 switch ($rmode$$constant) { 13223 case RoundDoubleModeNode::rmode_rint: 13224 __ frintnd(as_FloatRegister($dst$$reg), 13225 as_FloatRegister($src$$reg)); 13226 break; 13227 case RoundDoubleModeNode::rmode_floor: 13228 __ frintmd(as_FloatRegister($dst$$reg), 13229 as_FloatRegister($src$$reg)); 13230 break; 13231 case RoundDoubleModeNode::rmode_ceil: 13232 __ frintpd(as_FloatRegister($dst$$reg), 13233 as_FloatRegister($src$$reg)); 13234 break; 13235 } 13236 %} 13237 ins_pipe(fp_uop_d); 13238 %} 13239 13240 // ============================================================================ 13241 // Logical Instructions 13242 13243 // Integer Logical Instructions 13244 13245 // And Instructions 13246 13247 13248 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13249 match(Set dst (AndI src1 src2)); 13250 13251 format %{ "andw $dst, $src1, $src2\t# int" %} 13252 13253 ins_cost(INSN_COST); 13254 ins_encode %{ 13255 __ andw(as_Register($dst$$reg), 13256 as_Register($src1$$reg), 13257 as_Register($src2$$reg)); 13258 %} 13259 13260 ins_pipe(ialu_reg_reg); 13261 %} 13262 13263 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13264 match(Set dst (AndI src1 src2)); 13265 13266 format %{ "andsw $dst, $src1, $src2\t# int" %} 13267 13268 ins_cost(INSN_COST); 13269 ins_encode %{ 13270 __ andw(as_Register($dst$$reg), 13271 as_Register($src1$$reg), 13272 (uint64_t)($src2$$constant)); 13273 %} 13274 13275 ins_pipe(ialu_reg_imm); 13276 %} 13277 13278 // Or Instructions 13279 13280 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13281 match(Set dst (OrI src1 src2)); 13282 13283 format %{ "orrw $dst, $src1, $src2\t# int" %} 13284 13285 ins_cost(INSN_COST); 13286 ins_encode %{ 13287 __ orrw(as_Register($dst$$reg), 13288 as_Register($src1$$reg), 13289 as_Register($src2$$reg)); 13290 %} 13291 13292 ins_pipe(ialu_reg_reg); 13293 %} 13294 13295 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13296 match(Set dst (OrI src1 src2)); 13297 13298 format %{ "orrw $dst, $src1, $src2\t# int" %} 13299 13300 ins_cost(INSN_COST); 13301 ins_encode %{ 13302 __ orrw(as_Register($dst$$reg), 13303 as_Register($src1$$reg), 13304 (uint64_t)($src2$$constant)); 13305 %} 13306 13307 ins_pipe(ialu_reg_imm); 13308 %} 13309 13310 // Xor Instructions 13311 13312 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13313 match(Set dst (XorI src1 src2)); 13314 13315 format %{ "eorw $dst, $src1, $src2\t# int" %} 13316 13317 ins_cost(INSN_COST); 13318 ins_encode %{ 13319 __ eorw(as_Register($dst$$reg), 13320 as_Register($src1$$reg), 13321 as_Register($src2$$reg)); 13322 %} 13323 13324 ins_pipe(ialu_reg_reg); 13325 %} 13326 13327 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13328 match(Set dst (XorI src1 src2)); 13329 13330 format %{ "eorw $dst, $src1, $src2\t# int" %} 13331 13332 ins_cost(INSN_COST); 13333 ins_encode %{ 13334 __ eorw(as_Register($dst$$reg), 13335 as_Register($src1$$reg), 13336 (uint64_t)($src2$$constant)); 13337 %} 13338 13339 ins_pipe(ialu_reg_imm); 13340 %} 13341 13342 // Long Logical Instructions 13343 // TODO 13344 13345 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13346 match(Set dst (AndL src1 src2)); 13347 13348 format %{ "and $dst, $src1, $src2\t# int" %} 13349 13350 ins_cost(INSN_COST); 13351 ins_encode %{ 13352 __ andr(as_Register($dst$$reg), 13353 as_Register($src1$$reg), 13354 as_Register($src2$$reg)); 13355 %} 13356 13357 ins_pipe(ialu_reg_reg); 13358 %} 13359 13360 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13361 match(Set dst (AndL src1 src2)); 13362 13363 format %{ "and $dst, $src1, $src2\t# int" %} 13364 13365 ins_cost(INSN_COST); 13366 ins_encode %{ 13367 __ andr(as_Register($dst$$reg), 13368 as_Register($src1$$reg), 13369 (uint64_t)($src2$$constant)); 13370 %} 13371 13372 ins_pipe(ialu_reg_imm); 13373 %} 13374 13375 // Or Instructions 13376 13377 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13378 match(Set dst (OrL src1 src2)); 13379 13380 format %{ "orr $dst, $src1, $src2\t# int" %} 13381 13382 ins_cost(INSN_COST); 13383 ins_encode %{ 13384 __ orr(as_Register($dst$$reg), 13385 as_Register($src1$$reg), 13386 as_Register($src2$$reg)); 13387 %} 13388 13389 ins_pipe(ialu_reg_reg); 13390 %} 13391 13392 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13393 match(Set dst (OrL src1 src2)); 13394 13395 format %{ "orr $dst, $src1, $src2\t# int" %} 13396 13397 ins_cost(INSN_COST); 13398 ins_encode %{ 13399 __ orr(as_Register($dst$$reg), 13400 as_Register($src1$$reg), 13401 (uint64_t)($src2$$constant)); 13402 %} 13403 13404 ins_pipe(ialu_reg_imm); 13405 %} 13406 13407 // Xor Instructions 13408 13409 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13410 match(Set dst (XorL src1 src2)); 13411 13412 format %{ "eor $dst, $src1, $src2\t# int" %} 13413 13414 ins_cost(INSN_COST); 13415 ins_encode %{ 13416 __ eor(as_Register($dst$$reg), 13417 as_Register($src1$$reg), 13418 as_Register($src2$$reg)); 13419 %} 13420 13421 ins_pipe(ialu_reg_reg); 13422 %} 13423 13424 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13425 match(Set dst (XorL src1 src2)); 13426 13427 ins_cost(INSN_COST); 13428 format %{ "eor $dst, $src1, $src2\t# int" %} 13429 13430 ins_encode %{ 13431 __ eor(as_Register($dst$$reg), 13432 as_Register($src1$$reg), 13433 (uint64_t)($src2$$constant)); 13434 %} 13435 13436 ins_pipe(ialu_reg_imm); 13437 %} 13438 13439 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13440 %{ 13441 match(Set dst (ConvI2L src)); 13442 13443 ins_cost(INSN_COST); 13444 format %{ "sxtw $dst, $src\t# i2l" %} 13445 ins_encode %{ 13446 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13447 %} 13448 ins_pipe(ialu_reg_shift); 13449 %} 13450 13451 // this pattern occurs in bigmath arithmetic 13452 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13453 %{ 13454 match(Set dst (AndL (ConvI2L src) mask)); 13455 13456 ins_cost(INSN_COST); 13457 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13458 ins_encode %{ 13459 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13460 %} 13461 13462 ins_pipe(ialu_reg_shift); 13463 %} 13464 13465 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13466 match(Set dst (ConvL2I src)); 13467 13468 ins_cost(INSN_COST); 13469 format %{ "movw $dst, $src \t// l2i" %} 13470 13471 ins_encode %{ 13472 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13473 %} 13474 13475 ins_pipe(ialu_reg); 13476 %} 13477 13478 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13479 %{ 13480 match(Set dst (Conv2B src)); 13481 effect(KILL cr); 13482 13483 format %{ 13484 "cmpw $src, zr\n\t" 13485 "cset $dst, ne" 13486 %} 13487 13488 ins_encode %{ 13489 __ cmpw(as_Register($src$$reg), zr); 13490 __ cset(as_Register($dst$$reg), Assembler::NE); 13491 %} 13492 13493 ins_pipe(ialu_reg); 13494 %} 13495 13496 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13497 %{ 13498 match(Set dst (Conv2B src)); 13499 effect(KILL cr); 13500 13501 format %{ 13502 "cmp $src, zr\n\t" 13503 "cset $dst, ne" 13504 %} 13505 13506 ins_encode %{ 13507 __ cmp(as_Register($src$$reg), zr); 13508 __ cset(as_Register($dst$$reg), Assembler::NE); 13509 %} 13510 13511 ins_pipe(ialu_reg); 13512 %} 13513 13514 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13515 match(Set dst (ConvD2F src)); 13516 13517 ins_cost(INSN_COST * 5); 13518 format %{ "fcvtd $dst, $src \t// d2f" %} 13519 13520 ins_encode %{ 13521 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13522 %} 13523 13524 ins_pipe(fp_d2f); 13525 %} 13526 13527 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13528 match(Set dst (ConvF2D src)); 13529 13530 ins_cost(INSN_COST * 5); 13531 format %{ "fcvts $dst, $src \t// f2d" %} 13532 13533 ins_encode %{ 13534 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13535 %} 13536 13537 ins_pipe(fp_f2d); 13538 %} 13539 13540 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13541 match(Set dst (ConvF2I src)); 13542 13543 ins_cost(INSN_COST * 5); 13544 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13545 13546 ins_encode %{ 13547 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13548 %} 13549 13550 ins_pipe(fp_f2i); 13551 %} 13552 13553 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13554 match(Set dst (ConvF2L src)); 13555 13556 ins_cost(INSN_COST * 5); 13557 format %{ "fcvtzs $dst, $src \t// f2l" %} 13558 13559 ins_encode %{ 13560 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13561 %} 13562 13563 ins_pipe(fp_f2l); 13564 %} 13565 13566 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13567 match(Set dst (ConvI2F src)); 13568 13569 ins_cost(INSN_COST * 5); 13570 format %{ "scvtfws $dst, $src \t// i2f" %} 13571 13572 ins_encode %{ 13573 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13574 %} 13575 13576 ins_pipe(fp_i2f); 13577 %} 13578 13579 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13580 match(Set dst (ConvL2F src)); 13581 13582 ins_cost(INSN_COST * 5); 13583 format %{ "scvtfs $dst, $src \t// l2f" %} 13584 13585 ins_encode %{ 13586 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13587 %} 13588 13589 ins_pipe(fp_l2f); 13590 %} 13591 13592 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13593 match(Set dst (ConvD2I src)); 13594 13595 ins_cost(INSN_COST * 5); 13596 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13597 13598 ins_encode %{ 13599 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13600 %} 13601 13602 ins_pipe(fp_d2i); 13603 %} 13604 13605 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13606 match(Set dst (ConvD2L src)); 13607 13608 ins_cost(INSN_COST * 5); 13609 format %{ "fcvtzd $dst, $src \t// d2l" %} 13610 13611 ins_encode %{ 13612 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13613 %} 13614 13615 ins_pipe(fp_d2l); 13616 %} 13617 13618 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13619 match(Set dst (ConvI2D src)); 13620 13621 ins_cost(INSN_COST * 5); 13622 format %{ "scvtfwd $dst, $src \t// i2d" %} 13623 13624 ins_encode %{ 13625 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13626 %} 13627 13628 ins_pipe(fp_i2d); 13629 %} 13630 13631 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13632 match(Set dst (ConvL2D src)); 13633 13634 ins_cost(INSN_COST * 5); 13635 format %{ "scvtfd $dst, $src \t// l2d" %} 13636 13637 ins_encode %{ 13638 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13639 %} 13640 13641 ins_pipe(fp_l2d); 13642 %} 13643 13644 // stack <-> reg and reg <-> reg shuffles with no conversion 13645 13646 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13647 13648 match(Set dst (MoveF2I src)); 13649 13650 effect(DEF dst, USE src); 13651 13652 ins_cost(4 * INSN_COST); 13653 13654 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13655 13656 ins_encode %{ 13657 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13658 %} 13659 13660 ins_pipe(iload_reg_reg); 13661 13662 %} 13663 13664 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13665 13666 match(Set dst (MoveI2F src)); 13667 13668 effect(DEF dst, USE src); 13669 13670 ins_cost(4 * INSN_COST); 13671 13672 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13673 13674 ins_encode %{ 13675 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13676 %} 13677 13678 ins_pipe(pipe_class_memory); 13679 13680 %} 13681 13682 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13683 13684 match(Set dst (MoveD2L src)); 13685 13686 effect(DEF dst, USE src); 13687 13688 ins_cost(4 * INSN_COST); 13689 13690 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13691 13692 ins_encode %{ 13693 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13694 %} 13695 13696 ins_pipe(iload_reg_reg); 13697 13698 %} 13699 13700 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13701 13702 match(Set dst (MoveL2D src)); 13703 13704 effect(DEF dst, USE src); 13705 13706 ins_cost(4 * INSN_COST); 13707 13708 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13709 13710 ins_encode %{ 13711 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13712 %} 13713 13714 ins_pipe(pipe_class_memory); 13715 13716 %} 13717 13718 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13719 13720 match(Set dst (MoveF2I src)); 13721 13722 effect(DEF dst, USE src); 13723 13724 ins_cost(INSN_COST); 13725 13726 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13727 13728 ins_encode %{ 13729 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13730 %} 13731 13732 ins_pipe(pipe_class_memory); 13733 13734 %} 13735 13736 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13737 13738 match(Set dst (MoveI2F src)); 13739 13740 effect(DEF dst, USE src); 13741 13742 ins_cost(INSN_COST); 13743 13744 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13745 13746 ins_encode %{ 13747 __ strw($src$$Register, Address(sp, $dst$$disp)); 13748 %} 13749 13750 ins_pipe(istore_reg_reg); 13751 13752 %} 13753 13754 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13755 13756 match(Set dst (MoveD2L src)); 13757 13758 effect(DEF dst, USE src); 13759 13760 ins_cost(INSN_COST); 13761 13762 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13763 13764 ins_encode %{ 13765 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13766 %} 13767 13768 ins_pipe(pipe_class_memory); 13769 13770 %} 13771 13772 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13773 13774 match(Set dst (MoveL2D src)); 13775 13776 effect(DEF dst, USE src); 13777 13778 ins_cost(INSN_COST); 13779 13780 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13781 13782 ins_encode %{ 13783 __ str($src$$Register, Address(sp, $dst$$disp)); 13784 %} 13785 13786 ins_pipe(istore_reg_reg); 13787 13788 %} 13789 13790 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13791 13792 match(Set dst (MoveF2I src)); 13793 13794 effect(DEF dst, USE src); 13795 13796 ins_cost(INSN_COST); 13797 13798 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13799 13800 ins_encode %{ 13801 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13802 %} 13803 13804 ins_pipe(fp_f2i); 13805 13806 %} 13807 13808 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13809 13810 match(Set dst (MoveI2F src)); 13811 13812 effect(DEF dst, USE src); 13813 13814 ins_cost(INSN_COST); 13815 13816 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13817 13818 ins_encode %{ 13819 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13820 %} 13821 13822 ins_pipe(fp_i2f); 13823 13824 %} 13825 13826 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13827 13828 match(Set dst (MoveD2L src)); 13829 13830 effect(DEF dst, USE src); 13831 13832 ins_cost(INSN_COST); 13833 13834 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13835 13836 ins_encode %{ 13837 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13838 %} 13839 13840 ins_pipe(fp_d2l); 13841 13842 %} 13843 13844 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13845 13846 match(Set dst (MoveL2D src)); 13847 13848 effect(DEF dst, USE src); 13849 13850 ins_cost(INSN_COST); 13851 13852 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13853 13854 ins_encode %{ 13855 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13856 %} 13857 13858 ins_pipe(fp_l2d); 13859 13860 %} 13861 13862 // ============================================================================ 13863 // clearing of an array 13864 13865 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13866 %{ 13867 match(Set dummy (ClearArray cnt base)); 13868 effect(USE_KILL cnt, USE_KILL base); 13869 13870 ins_cost(4 * INSN_COST); 13871 format %{ "ClearArray $cnt, $base" %} 13872 13873 ins_encode %{ 13874 __ zero_words($base$$Register, $cnt$$Register); 13875 %} 13876 13877 ins_pipe(pipe_class_memory); 13878 %} 13879 13880 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13881 %{ 13882 predicate((uint64_t)n->in(2)->get_long() 13883 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13884 match(Set dummy (ClearArray cnt base)); 13885 effect(USE_KILL base); 13886 13887 ins_cost(4 * INSN_COST); 13888 format %{ "ClearArray $cnt, $base" %} 13889 13890 ins_encode %{ 13891 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 13892 %} 13893 13894 ins_pipe(pipe_class_memory); 13895 %} 13896 13897 // ============================================================================ 13898 // Overflow Math Instructions 13899 13900 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13901 %{ 13902 match(Set cr (OverflowAddI op1 op2)); 13903 13904 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13905 ins_cost(INSN_COST); 13906 ins_encode %{ 13907 __ cmnw($op1$$Register, $op2$$Register); 13908 %} 13909 13910 ins_pipe(icmp_reg_reg); 13911 %} 13912 13913 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13914 %{ 13915 match(Set cr (OverflowAddI op1 op2)); 13916 13917 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13918 ins_cost(INSN_COST); 13919 ins_encode %{ 13920 __ cmnw($op1$$Register, $op2$$constant); 13921 %} 13922 13923 ins_pipe(icmp_reg_imm); 13924 %} 13925 13926 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13927 %{ 13928 match(Set cr (OverflowAddL op1 op2)); 13929 13930 format %{ "cmn $op1, $op2\t# overflow check int64_t" %} 13931 ins_cost(INSN_COST); 13932 ins_encode %{ 13933 __ cmn($op1$$Register, $op2$$Register); 13934 %} 13935 13936 ins_pipe(icmp_reg_reg); 13937 %} 13938 13939 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13940 %{ 13941 match(Set cr (OverflowAddL op1 op2)); 13942 13943 format %{ "cmn $op1, $op2\t# overflow check int64_t" %} 13944 ins_cost(INSN_COST); 13945 ins_encode %{ 13946 __ cmn($op1$$Register, $op2$$constant); 13947 %} 13948 13949 ins_pipe(icmp_reg_imm); 13950 %} 13951 13952 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13953 %{ 13954 match(Set cr (OverflowSubI op1 op2)); 13955 13956 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13957 ins_cost(INSN_COST); 13958 ins_encode %{ 13959 __ cmpw($op1$$Register, $op2$$Register); 13960 %} 13961 13962 ins_pipe(icmp_reg_reg); 13963 %} 13964 13965 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13966 %{ 13967 match(Set cr (OverflowSubI op1 op2)); 13968 13969 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13970 ins_cost(INSN_COST); 13971 ins_encode %{ 13972 __ cmpw($op1$$Register, $op2$$constant); 13973 %} 13974 13975 ins_pipe(icmp_reg_imm); 13976 %} 13977 13978 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13979 %{ 13980 match(Set cr (OverflowSubL op1 op2)); 13981 13982 format %{ "cmp $op1, $op2\t# overflow check int64_t" %} 13983 ins_cost(INSN_COST); 13984 ins_encode %{ 13985 __ cmp($op1$$Register, $op2$$Register); 13986 %} 13987 13988 ins_pipe(icmp_reg_reg); 13989 %} 13990 13991 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13992 %{ 13993 match(Set cr (OverflowSubL op1 op2)); 13994 13995 format %{ "cmp $op1, $op2\t# overflow check int64_t" %} 13996 ins_cost(INSN_COST); 13997 ins_encode %{ 13998 __ subs(zr, $op1$$Register, $op2$$constant); 13999 %} 14000 14001 ins_pipe(icmp_reg_imm); 14002 %} 14003 14004 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14005 %{ 14006 match(Set cr (OverflowSubI zero op1)); 14007 14008 format %{ "cmpw zr, $op1\t# overflow check int" %} 14009 ins_cost(INSN_COST); 14010 ins_encode %{ 14011 __ cmpw(zr, $op1$$Register); 14012 %} 14013 14014 ins_pipe(icmp_reg_imm); 14015 %} 14016 14017 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14018 %{ 14019 match(Set cr (OverflowSubL zero op1)); 14020 14021 format %{ "cmp zr, $op1\t# overflow check int64_t" %} 14022 ins_cost(INSN_COST); 14023 ins_encode %{ 14024 __ cmp(zr, $op1$$Register); 14025 %} 14026 14027 ins_pipe(icmp_reg_imm); 14028 %} 14029 14030 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14031 %{ 14032 match(Set cr (OverflowMulI op1 op2)); 14033 14034 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14035 "cmp rscratch1, rscratch1, sxtw\n\t" 14036 "movw rscratch1, #0x80000000\n\t" 14037 "cselw rscratch1, rscratch1, zr, NE\n\t" 14038 "cmpw rscratch1, #1" %} 14039 ins_cost(5 * INSN_COST); 14040 ins_encode %{ 14041 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14042 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14043 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14044 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14045 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14046 %} 14047 14048 ins_pipe(pipe_slow); 14049 %} 14050 14051 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14052 %{ 14053 match(If cmp (OverflowMulI op1 op2)); 14054 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14055 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14056 effect(USE labl, KILL cr); 14057 14058 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14059 "cmp rscratch1, rscratch1, sxtw\n\t" 14060 "b$cmp $labl" %} 14061 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14062 ins_encode %{ 14063 Label* L = $labl$$label; 14064 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14065 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14066 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14067 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14068 %} 14069 14070 ins_pipe(pipe_serial); 14071 %} 14072 14073 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14074 %{ 14075 match(Set cr (OverflowMulL op1 op2)); 14076 14077 format %{ "mul rscratch1, $op1, $op2\t#overflow check int64_t\n\t" 14078 "smulh rscratch2, $op1, $op2\n\t" 14079 "cmp rscratch2, rscratch1, ASR #63\n\t" 14080 "movw rscratch1, #0x80000000\n\t" 14081 "cselw rscratch1, rscratch1, zr, NE\n\t" 14082 "cmpw rscratch1, #1" %} 14083 ins_cost(6 * INSN_COST); 14084 ins_encode %{ 14085 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14086 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14087 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14088 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14089 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14090 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14091 %} 14092 14093 ins_pipe(pipe_slow); 14094 %} 14095 14096 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14097 %{ 14098 match(If cmp (OverflowMulL op1 op2)); 14099 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14100 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14101 effect(USE labl, KILL cr); 14102 14103 format %{ "mul rscratch1, $op1, $op2\t#overflow check int64_t\n\t" 14104 "smulh rscratch2, $op1, $op2\n\t" 14105 "cmp rscratch2, rscratch1, ASR #63\n\t" 14106 "b$cmp $labl" %} 14107 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14108 ins_encode %{ 14109 Label* L = $labl$$label; 14110 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14111 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14112 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14113 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14114 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14115 %} 14116 14117 ins_pipe(pipe_serial); 14118 %} 14119 14120 // ============================================================================ 14121 // Compare Instructions 14122 14123 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14124 %{ 14125 match(Set cr (CmpI op1 op2)); 14126 14127 effect(DEF cr, USE op1, USE op2); 14128 14129 ins_cost(INSN_COST); 14130 format %{ "cmpw $op1, $op2" %} 14131 14132 ins_encode(aarch64_enc_cmpw(op1, op2)); 14133 14134 ins_pipe(icmp_reg_reg); 14135 %} 14136 14137 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14138 %{ 14139 match(Set cr (CmpI op1 zero)); 14140 14141 effect(DEF cr, USE op1); 14142 14143 ins_cost(INSN_COST); 14144 format %{ "cmpw $op1, 0" %} 14145 14146 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14147 14148 ins_pipe(icmp_reg_imm); 14149 %} 14150 14151 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14152 %{ 14153 match(Set cr (CmpI op1 op2)); 14154 14155 effect(DEF cr, USE op1); 14156 14157 ins_cost(INSN_COST); 14158 format %{ "cmpw $op1, $op2" %} 14159 14160 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14161 14162 ins_pipe(icmp_reg_imm); 14163 %} 14164 14165 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14166 %{ 14167 match(Set cr (CmpI op1 op2)); 14168 14169 effect(DEF cr, USE op1); 14170 14171 ins_cost(INSN_COST * 2); 14172 format %{ "cmpw $op1, $op2" %} 14173 14174 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14175 14176 ins_pipe(icmp_reg_imm); 14177 %} 14178 14179 // Unsigned compare Instructions; really, same as signed compare 14180 // except it should only be used to feed an If or a CMovI which takes a 14181 // cmpOpU. 14182 14183 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14184 %{ 14185 match(Set cr (CmpU op1 op2)); 14186 14187 effect(DEF cr, USE op1, USE op2); 14188 14189 ins_cost(INSN_COST); 14190 format %{ "cmpw $op1, $op2\t# unsigned" %} 14191 14192 ins_encode(aarch64_enc_cmpw(op1, op2)); 14193 14194 ins_pipe(icmp_reg_reg); 14195 %} 14196 14197 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14198 %{ 14199 match(Set cr (CmpU op1 zero)); 14200 14201 effect(DEF cr, USE op1); 14202 14203 ins_cost(INSN_COST); 14204 format %{ "cmpw $op1, #0\t# unsigned" %} 14205 14206 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14207 14208 ins_pipe(icmp_reg_imm); 14209 %} 14210 14211 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14212 %{ 14213 match(Set cr (CmpU op1 op2)); 14214 14215 effect(DEF cr, USE op1); 14216 14217 ins_cost(INSN_COST); 14218 format %{ "cmpw $op1, $op2\t# unsigned" %} 14219 14220 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14221 14222 ins_pipe(icmp_reg_imm); 14223 %} 14224 14225 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14226 %{ 14227 match(Set cr (CmpU op1 op2)); 14228 14229 effect(DEF cr, USE op1); 14230 14231 ins_cost(INSN_COST * 2); 14232 format %{ "cmpw $op1, $op2\t# unsigned" %} 14233 14234 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14235 14236 ins_pipe(icmp_reg_imm); 14237 %} 14238 14239 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14240 %{ 14241 match(Set cr (CmpL op1 op2)); 14242 14243 effect(DEF cr, USE op1, USE op2); 14244 14245 ins_cost(INSN_COST); 14246 format %{ "cmp $op1, $op2" %} 14247 14248 ins_encode(aarch64_enc_cmp(op1, op2)); 14249 14250 ins_pipe(icmp_reg_reg); 14251 %} 14252 14253 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14254 %{ 14255 match(Set cr (CmpL op1 zero)); 14256 14257 effect(DEF cr, USE op1); 14258 14259 ins_cost(INSN_COST); 14260 format %{ "tst $op1" %} 14261 14262 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14263 14264 ins_pipe(icmp_reg_imm); 14265 %} 14266 14267 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14268 %{ 14269 match(Set cr (CmpL op1 op2)); 14270 14271 effect(DEF cr, USE op1); 14272 14273 ins_cost(INSN_COST); 14274 format %{ "cmp $op1, $op2" %} 14275 14276 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14277 14278 ins_pipe(icmp_reg_imm); 14279 %} 14280 14281 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14282 %{ 14283 match(Set cr (CmpL op1 op2)); 14284 14285 effect(DEF cr, USE op1); 14286 14287 ins_cost(INSN_COST * 2); 14288 format %{ "cmp $op1, $op2" %} 14289 14290 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14291 14292 ins_pipe(icmp_reg_imm); 14293 %} 14294 14295 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14296 %{ 14297 match(Set cr (CmpUL op1 op2)); 14298 14299 effect(DEF cr, USE op1, USE op2); 14300 14301 ins_cost(INSN_COST); 14302 format %{ "cmp $op1, $op2" %} 14303 14304 ins_encode(aarch64_enc_cmp(op1, op2)); 14305 14306 ins_pipe(icmp_reg_reg); 14307 %} 14308 14309 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14310 %{ 14311 match(Set cr (CmpUL op1 zero)); 14312 14313 effect(DEF cr, USE op1); 14314 14315 ins_cost(INSN_COST); 14316 format %{ "tst $op1" %} 14317 14318 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14319 14320 ins_pipe(icmp_reg_imm); 14321 %} 14322 14323 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14324 %{ 14325 match(Set cr (CmpUL op1 op2)); 14326 14327 effect(DEF cr, USE op1); 14328 14329 ins_cost(INSN_COST); 14330 format %{ "cmp $op1, $op2" %} 14331 14332 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14333 14334 ins_pipe(icmp_reg_imm); 14335 %} 14336 14337 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14338 %{ 14339 match(Set cr (CmpUL op1 op2)); 14340 14341 effect(DEF cr, USE op1); 14342 14343 ins_cost(INSN_COST * 2); 14344 format %{ "cmp $op1, $op2" %} 14345 14346 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14347 14348 ins_pipe(icmp_reg_imm); 14349 %} 14350 14351 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14352 %{ 14353 match(Set cr (CmpP op1 op2)); 14354 14355 effect(DEF cr, USE op1, USE op2); 14356 14357 ins_cost(INSN_COST); 14358 format %{ "cmp $op1, $op2\t // ptr" %} 14359 14360 ins_encode(aarch64_enc_cmpp(op1, op2)); 14361 14362 ins_pipe(icmp_reg_reg); 14363 %} 14364 14365 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14366 %{ 14367 match(Set cr (CmpN op1 op2)); 14368 14369 effect(DEF cr, USE op1, USE op2); 14370 14371 ins_cost(INSN_COST); 14372 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14373 14374 ins_encode(aarch64_enc_cmpn(op1, op2)); 14375 14376 ins_pipe(icmp_reg_reg); 14377 %} 14378 14379 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14380 %{ 14381 match(Set cr (CmpP op1 zero)); 14382 14383 effect(DEF cr, USE op1, USE zero); 14384 14385 ins_cost(INSN_COST); 14386 format %{ "cmp $op1, 0\t // ptr" %} 14387 14388 ins_encode(aarch64_enc_testp(op1)); 14389 14390 ins_pipe(icmp_reg_imm); 14391 %} 14392 14393 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14394 %{ 14395 match(Set cr (CmpN op1 zero)); 14396 14397 effect(DEF cr, USE op1, USE zero); 14398 14399 ins_cost(INSN_COST); 14400 format %{ "cmp $op1, 0\t // compressed ptr" %} 14401 14402 ins_encode(aarch64_enc_testn(op1)); 14403 14404 ins_pipe(icmp_reg_imm); 14405 %} 14406 14407 // FP comparisons 14408 // 14409 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14410 // using normal cmpOp. See declaration of rFlagsReg for details. 14411 14412 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14413 %{ 14414 match(Set cr (CmpF src1 src2)); 14415 14416 ins_cost(3 * INSN_COST); 14417 format %{ "fcmps $src1, $src2" %} 14418 14419 ins_encode %{ 14420 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14421 %} 14422 14423 ins_pipe(pipe_class_compare); 14424 %} 14425 14426 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14427 %{ 14428 match(Set cr (CmpF src1 src2)); 14429 14430 ins_cost(3 * INSN_COST); 14431 format %{ "fcmps $src1, 0.0" %} 14432 14433 ins_encode %{ 14434 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14435 %} 14436 14437 ins_pipe(pipe_class_compare); 14438 %} 14439 // FROM HERE 14440 14441 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14442 %{ 14443 match(Set cr (CmpD src1 src2)); 14444 14445 ins_cost(3 * INSN_COST); 14446 format %{ "fcmpd $src1, $src2" %} 14447 14448 ins_encode %{ 14449 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14450 %} 14451 14452 ins_pipe(pipe_class_compare); 14453 %} 14454 14455 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14456 %{ 14457 match(Set cr (CmpD src1 src2)); 14458 14459 ins_cost(3 * INSN_COST); 14460 format %{ "fcmpd $src1, 0.0" %} 14461 14462 ins_encode %{ 14463 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14464 %} 14465 14466 ins_pipe(pipe_class_compare); 14467 %} 14468 14469 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14470 %{ 14471 match(Set dst (CmpF3 src1 src2)); 14472 effect(KILL cr); 14473 14474 ins_cost(5 * INSN_COST); 14475 format %{ "fcmps $src1, $src2\n\t" 14476 "csinvw($dst, zr, zr, eq\n\t" 14477 "csnegw($dst, $dst, $dst, lt)" 14478 %} 14479 14480 ins_encode %{ 14481 Label done; 14482 FloatRegister s1 = as_FloatRegister($src1$$reg); 14483 FloatRegister s2 = as_FloatRegister($src2$$reg); 14484 Register d = as_Register($dst$$reg); 14485 __ fcmps(s1, s2); 14486 // installs 0 if EQ else -1 14487 __ csinvw(d, zr, zr, Assembler::EQ); 14488 // keeps -1 if less or unordered else installs 1 14489 __ csnegw(d, d, d, Assembler::LT); 14490 __ bind(done); 14491 %} 14492 14493 ins_pipe(pipe_class_default); 14494 14495 %} 14496 14497 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14498 %{ 14499 match(Set dst (CmpD3 src1 src2)); 14500 effect(KILL cr); 14501 14502 ins_cost(5 * INSN_COST); 14503 format %{ "fcmpd $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 __ fcmpd(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 ins_pipe(pipe_class_default); 14521 14522 %} 14523 14524 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14525 %{ 14526 match(Set dst (CmpF3 src1 zero)); 14527 effect(KILL cr); 14528 14529 ins_cost(5 * INSN_COST); 14530 format %{ "fcmps $src1, 0.0\n\t" 14531 "csinvw($dst, zr, zr, eq\n\t" 14532 "csnegw($dst, $dst, $dst, lt)" 14533 %} 14534 14535 ins_encode %{ 14536 Label done; 14537 FloatRegister s1 = as_FloatRegister($src1$$reg); 14538 Register d = as_Register($dst$$reg); 14539 __ fcmps(s1, 0.0); 14540 // installs 0 if EQ else -1 14541 __ csinvw(d, zr, zr, Assembler::EQ); 14542 // keeps -1 if less or unordered else installs 1 14543 __ csnegw(d, d, d, Assembler::LT); 14544 __ bind(done); 14545 %} 14546 14547 ins_pipe(pipe_class_default); 14548 14549 %} 14550 14551 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14552 %{ 14553 match(Set dst (CmpD3 src1 zero)); 14554 effect(KILL cr); 14555 14556 ins_cost(5 * INSN_COST); 14557 format %{ "fcmpd $src1, 0.0\n\t" 14558 "csinvw($dst, zr, zr, eq\n\t" 14559 "csnegw($dst, $dst, $dst, lt)" 14560 %} 14561 14562 ins_encode %{ 14563 Label done; 14564 FloatRegister s1 = as_FloatRegister($src1$$reg); 14565 Register d = as_Register($dst$$reg); 14566 __ fcmpd(s1, 0.0); 14567 // installs 0 if EQ else -1 14568 __ csinvw(d, zr, zr, Assembler::EQ); 14569 // keeps -1 if less or unordered else installs 1 14570 __ csnegw(d, d, d, Assembler::LT); 14571 __ bind(done); 14572 %} 14573 ins_pipe(pipe_class_default); 14574 14575 %} 14576 14577 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14578 %{ 14579 match(Set dst (CmpLTMask p q)); 14580 effect(KILL cr); 14581 14582 ins_cost(3 * INSN_COST); 14583 14584 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14585 "csetw $dst, lt\n\t" 14586 "subw $dst, zr, $dst" 14587 %} 14588 14589 ins_encode %{ 14590 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14591 __ csetw(as_Register($dst$$reg), Assembler::LT); 14592 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14593 %} 14594 14595 ins_pipe(ialu_reg_reg); 14596 %} 14597 14598 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14599 %{ 14600 match(Set dst (CmpLTMask src zero)); 14601 effect(KILL cr); 14602 14603 ins_cost(INSN_COST); 14604 14605 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14606 14607 ins_encode %{ 14608 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14609 %} 14610 14611 ins_pipe(ialu_reg_shift); 14612 %} 14613 14614 // ============================================================================ 14615 // Max and Min 14616 14617 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14618 %{ 14619 effect( DEF dst, USE src1, USE src2, USE cr ); 14620 14621 ins_cost(INSN_COST * 2); 14622 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14623 14624 ins_encode %{ 14625 __ cselw(as_Register($dst$$reg), 14626 as_Register($src1$$reg), 14627 as_Register($src2$$reg), 14628 Assembler::LT); 14629 %} 14630 14631 ins_pipe(icond_reg_reg); 14632 %} 14633 14634 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14635 %{ 14636 match(Set dst (MinI src1 src2)); 14637 ins_cost(INSN_COST * 3); 14638 14639 expand %{ 14640 rFlagsReg cr; 14641 compI_reg_reg(cr, src1, src2); 14642 cmovI_reg_reg_lt(dst, src1, src2, cr); 14643 %} 14644 14645 %} 14646 // FROM HERE 14647 14648 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14649 %{ 14650 effect( DEF dst, USE src1, USE src2, USE cr ); 14651 14652 ins_cost(INSN_COST * 2); 14653 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14654 14655 ins_encode %{ 14656 __ cselw(as_Register($dst$$reg), 14657 as_Register($src1$$reg), 14658 as_Register($src2$$reg), 14659 Assembler::GT); 14660 %} 14661 14662 ins_pipe(icond_reg_reg); 14663 %} 14664 14665 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14666 %{ 14667 match(Set dst (MaxI src1 src2)); 14668 ins_cost(INSN_COST * 3); 14669 expand %{ 14670 rFlagsReg cr; 14671 compI_reg_reg(cr, src1, src2); 14672 cmovI_reg_reg_gt(dst, src1, src2, cr); 14673 %} 14674 %} 14675 14676 // ============================================================================ 14677 // Branch Instructions 14678 14679 // Direct Branch. 14680 instruct branch(label lbl) 14681 %{ 14682 match(Goto); 14683 14684 effect(USE lbl); 14685 14686 ins_cost(BRANCH_COST); 14687 format %{ "b $lbl" %} 14688 14689 ins_encode(aarch64_enc_b(lbl)); 14690 14691 ins_pipe(pipe_branch); 14692 %} 14693 14694 // Conditional Near Branch 14695 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14696 %{ 14697 // Same match rule as `branchConFar'. 14698 match(If cmp cr); 14699 14700 effect(USE lbl); 14701 14702 ins_cost(BRANCH_COST); 14703 // If set to 1 this indicates that the current instruction is a 14704 // short variant of a long branch. This avoids using this 14705 // instruction in first-pass matching. It will then only be used in 14706 // the `Shorten_branches' pass. 14707 // ins_short_branch(1); 14708 format %{ "b$cmp $lbl" %} 14709 14710 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14711 14712 ins_pipe(pipe_branch_cond); 14713 %} 14714 14715 // Conditional Near Branch Unsigned 14716 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14717 %{ 14718 // Same match rule as `branchConFar'. 14719 match(If cmp cr); 14720 14721 effect(USE lbl); 14722 14723 ins_cost(BRANCH_COST); 14724 // If set to 1 this indicates that the current instruction is a 14725 // short variant of a long branch. This avoids using this 14726 // instruction in first-pass matching. It will then only be used in 14727 // the `Shorten_branches' pass. 14728 // ins_short_branch(1); 14729 format %{ "b$cmp $lbl\t# unsigned" %} 14730 14731 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14732 14733 ins_pipe(pipe_branch_cond); 14734 %} 14735 14736 // Make use of CBZ and CBNZ. These instructions, as well as being 14737 // shorter than (cmp; branch), have the additional benefit of not 14738 // killing the flags. 14739 14740 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14741 match(If cmp (CmpI op1 op2)); 14742 effect(USE labl); 14743 14744 ins_cost(BRANCH_COST); 14745 format %{ "cbw$cmp $op1, $labl" %} 14746 ins_encode %{ 14747 Label* L = $labl$$label; 14748 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14749 if (cond == Assembler::EQ) 14750 __ cbzw($op1$$Register, *L); 14751 else 14752 __ cbnzw($op1$$Register, *L); 14753 %} 14754 ins_pipe(pipe_cmp_branch); 14755 %} 14756 14757 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14758 match(If cmp (CmpL op1 op2)); 14759 effect(USE labl); 14760 14761 ins_cost(BRANCH_COST); 14762 format %{ "cb$cmp $op1, $labl" %} 14763 ins_encode %{ 14764 Label* L = $labl$$label; 14765 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14766 if (cond == Assembler::EQ) 14767 __ cbz($op1$$Register, *L); 14768 else 14769 __ cbnz($op1$$Register, *L); 14770 %} 14771 ins_pipe(pipe_cmp_branch); 14772 %} 14773 14774 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14775 match(If cmp (CmpP op1 op2)); 14776 effect(USE labl); 14777 14778 ins_cost(BRANCH_COST); 14779 format %{ "cb$cmp $op1, $labl" %} 14780 ins_encode %{ 14781 Label* L = $labl$$label; 14782 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14783 if (cond == Assembler::EQ) 14784 __ cbz($op1$$Register, *L); 14785 else 14786 __ cbnz($op1$$Register, *L); 14787 %} 14788 ins_pipe(pipe_cmp_branch); 14789 %} 14790 14791 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14792 match(If cmp (CmpN op1 op2)); 14793 effect(USE labl); 14794 14795 ins_cost(BRANCH_COST); 14796 format %{ "cbw$cmp $op1, $labl" %} 14797 ins_encode %{ 14798 Label* L = $labl$$label; 14799 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14800 if (cond == Assembler::EQ) 14801 __ cbzw($op1$$Register, *L); 14802 else 14803 __ cbnzw($op1$$Register, *L); 14804 %} 14805 ins_pipe(pipe_cmp_branch); 14806 %} 14807 14808 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14809 match(If cmp (CmpP (DecodeN oop) zero)); 14810 effect(USE labl); 14811 14812 ins_cost(BRANCH_COST); 14813 format %{ "cb$cmp $oop, $labl" %} 14814 ins_encode %{ 14815 Label* L = $labl$$label; 14816 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14817 if (cond == Assembler::EQ) 14818 __ cbzw($oop$$Register, *L); 14819 else 14820 __ cbnzw($oop$$Register, *L); 14821 %} 14822 ins_pipe(pipe_cmp_branch); 14823 %} 14824 14825 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14826 match(If cmp (CmpU op1 op2)); 14827 effect(USE labl); 14828 14829 ins_cost(BRANCH_COST); 14830 format %{ "cbw$cmp $op1, $labl" %} 14831 ins_encode %{ 14832 Label* L = $labl$$label; 14833 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14834 if (cond == Assembler::EQ || cond == Assembler::LS) 14835 __ cbzw($op1$$Register, *L); 14836 else 14837 __ cbnzw($op1$$Register, *L); 14838 %} 14839 ins_pipe(pipe_cmp_branch); 14840 %} 14841 14842 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14843 match(If cmp (CmpUL op1 op2)); 14844 effect(USE labl); 14845 14846 ins_cost(BRANCH_COST); 14847 format %{ "cb$cmp $op1, $labl" %} 14848 ins_encode %{ 14849 Label* L = $labl$$label; 14850 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14851 if (cond == Assembler::EQ || cond == Assembler::LS) 14852 __ cbz($op1$$Register, *L); 14853 else 14854 __ cbnz($op1$$Register, *L); 14855 %} 14856 ins_pipe(pipe_cmp_branch); 14857 %} 14858 14859 // Test bit and Branch 14860 14861 // Patterns for short (< 32KiB) variants 14862 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14863 match(If cmp (CmpL op1 op2)); 14864 effect(USE labl); 14865 14866 ins_cost(BRANCH_COST); 14867 format %{ "cb$cmp $op1, $labl # int64_t" %} 14868 ins_encode %{ 14869 Label* L = $labl$$label; 14870 Assembler::Condition cond = 14871 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14872 __ tbr(cond, $op1$$Register, 63, *L); 14873 %} 14874 ins_pipe(pipe_cmp_branch); 14875 ins_short_branch(1); 14876 %} 14877 14878 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14879 match(If cmp (CmpI op1 op2)); 14880 effect(USE labl); 14881 14882 ins_cost(BRANCH_COST); 14883 format %{ "cb$cmp $op1, $labl # int" %} 14884 ins_encode %{ 14885 Label* L = $labl$$label; 14886 Assembler::Condition cond = 14887 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14888 __ tbr(cond, $op1$$Register, 31, *L); 14889 %} 14890 ins_pipe(pipe_cmp_branch); 14891 ins_short_branch(1); 14892 %} 14893 14894 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14895 match(If cmp (CmpL (AndL op1 op2) op3)); 14896 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14897 effect(USE labl); 14898 14899 ins_cost(BRANCH_COST); 14900 format %{ "tb$cmp $op1, $op2, $labl" %} 14901 ins_encode %{ 14902 Label* L = $labl$$label; 14903 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14904 int bit = exact_log2_long($op2$$constant); 14905 __ tbr(cond, $op1$$Register, bit, *L); 14906 %} 14907 ins_pipe(pipe_cmp_branch); 14908 ins_short_branch(1); 14909 %} 14910 14911 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14912 match(If cmp (CmpI (AndI op1 op2) op3)); 14913 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 14914 effect(USE labl); 14915 14916 ins_cost(BRANCH_COST); 14917 format %{ "tb$cmp $op1, $op2, $labl" %} 14918 ins_encode %{ 14919 Label* L = $labl$$label; 14920 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14921 int bit = exact_log2((juint)$op2$$constant); 14922 __ tbr(cond, $op1$$Register, bit, *L); 14923 %} 14924 ins_pipe(pipe_cmp_branch); 14925 ins_short_branch(1); 14926 %} 14927 14928 // And far variants 14929 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14930 match(If cmp (CmpL op1 op2)); 14931 effect(USE labl); 14932 14933 ins_cost(BRANCH_COST); 14934 format %{ "cb$cmp $op1, $labl # int64_t" %} 14935 ins_encode %{ 14936 Label* L = $labl$$label; 14937 Assembler::Condition cond = 14938 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14939 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14940 %} 14941 ins_pipe(pipe_cmp_branch); 14942 %} 14943 14944 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14945 match(If cmp (CmpI op1 op2)); 14946 effect(USE labl); 14947 14948 ins_cost(BRANCH_COST); 14949 format %{ "cb$cmp $op1, $labl # int" %} 14950 ins_encode %{ 14951 Label* L = $labl$$label; 14952 Assembler::Condition cond = 14953 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14954 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14955 %} 14956 ins_pipe(pipe_cmp_branch); 14957 %} 14958 14959 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14960 match(If cmp (CmpL (AndL op1 op2) op3)); 14961 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14962 effect(USE labl); 14963 14964 ins_cost(BRANCH_COST); 14965 format %{ "tb$cmp $op1, $op2, $labl" %} 14966 ins_encode %{ 14967 Label* L = $labl$$label; 14968 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14969 int bit = exact_log2_long($op2$$constant); 14970 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14971 %} 14972 ins_pipe(pipe_cmp_branch); 14973 %} 14974 14975 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14976 match(If cmp (CmpI (AndI op1 op2) op3)); 14977 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 14978 effect(USE labl); 14979 14980 ins_cost(BRANCH_COST); 14981 format %{ "tb$cmp $op1, $op2, $labl" %} 14982 ins_encode %{ 14983 Label* L = $labl$$label; 14984 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14985 int bit = exact_log2((juint)$op2$$constant); 14986 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14987 %} 14988 ins_pipe(pipe_cmp_branch); 14989 %} 14990 14991 // Test bits 14992 14993 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14994 match(Set cr (CmpL (AndL op1 op2) op3)); 14995 predicate(Assembler::operand_valid_for_logical_immediate 14996 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14997 14998 ins_cost(INSN_COST); 14999 format %{ "tst $op1, $op2 # int64_t" %} 15000 ins_encode %{ 15001 __ tst($op1$$Register, $op2$$constant); 15002 %} 15003 ins_pipe(ialu_reg_reg); 15004 %} 15005 15006 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15007 match(Set cr (CmpI (AndI op1 op2) op3)); 15008 predicate(Assembler::operand_valid_for_logical_immediate 15009 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15010 15011 ins_cost(INSN_COST); 15012 format %{ "tst $op1, $op2 # int" %} 15013 ins_encode %{ 15014 __ tstw($op1$$Register, $op2$$constant); 15015 %} 15016 ins_pipe(ialu_reg_reg); 15017 %} 15018 15019 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15020 match(Set cr (CmpL (AndL op1 op2) op3)); 15021 15022 ins_cost(INSN_COST); 15023 format %{ "tst $op1, $op2 # int64_t" %} 15024 ins_encode %{ 15025 __ tst($op1$$Register, $op2$$Register); 15026 %} 15027 ins_pipe(ialu_reg_reg); 15028 %} 15029 15030 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15031 match(Set cr (CmpI (AndI op1 op2) op3)); 15032 15033 ins_cost(INSN_COST); 15034 format %{ "tstw $op1, $op2 # int" %} 15035 ins_encode %{ 15036 __ tstw($op1$$Register, $op2$$Register); 15037 %} 15038 ins_pipe(ialu_reg_reg); 15039 %} 15040 15041 15042 // Conditional Far Branch 15043 // Conditional Far Branch Unsigned 15044 // TODO: fixme 15045 15046 // counted loop end branch near 15047 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15048 %{ 15049 match(CountedLoopEnd cmp cr); 15050 15051 effect(USE lbl); 15052 15053 ins_cost(BRANCH_COST); 15054 // short variant. 15055 // ins_short_branch(1); 15056 format %{ "b$cmp $lbl \t// counted loop end" %} 15057 15058 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15059 15060 ins_pipe(pipe_branch); 15061 %} 15062 15063 // counted loop end branch near Unsigned 15064 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15065 %{ 15066 match(CountedLoopEnd cmp cr); 15067 15068 effect(USE lbl); 15069 15070 ins_cost(BRANCH_COST); 15071 // short variant. 15072 // ins_short_branch(1); 15073 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15074 15075 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15076 15077 ins_pipe(pipe_branch); 15078 %} 15079 15080 // counted loop end branch far 15081 // counted loop end branch far unsigned 15082 // TODO: fixme 15083 15084 // ============================================================================ 15085 // inlined locking and unlocking 15086 15087 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15088 %{ 15089 match(Set cr (FastLock object box)); 15090 effect(TEMP tmp, TEMP tmp2); 15091 15092 // TODO 15093 // identify correct cost 15094 ins_cost(5 * INSN_COST); 15095 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15096 15097 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15098 15099 ins_pipe(pipe_serial); 15100 %} 15101 15102 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15103 %{ 15104 match(Set cr (FastUnlock object box)); 15105 effect(TEMP tmp, TEMP tmp2); 15106 15107 ins_cost(5 * INSN_COST); 15108 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15109 15110 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15111 15112 ins_pipe(pipe_serial); 15113 %} 15114 15115 15116 // ============================================================================ 15117 // Safepoint Instructions 15118 15119 // TODO 15120 // provide a near and far version of this code 15121 15122 instruct safePoint(rFlagsReg cr, iRegP poll) 15123 %{ 15124 match(SafePoint poll); 15125 effect(KILL cr); 15126 15127 format %{ 15128 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15129 %} 15130 ins_encode %{ 15131 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15132 %} 15133 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15134 %} 15135 15136 15137 // ============================================================================ 15138 // Procedure Call/Return Instructions 15139 15140 // Call Java Static Instruction 15141 15142 instruct CallStaticJavaDirect(method meth) 15143 %{ 15144 match(CallStaticJava); 15145 15146 effect(USE meth); 15147 15148 ins_cost(CALL_COST); 15149 15150 format %{ "call,static $meth \t// ==> " %} 15151 15152 ins_encode( aarch64_enc_java_static_call(meth), 15153 aarch64_enc_call_epilog ); 15154 15155 ins_pipe(pipe_class_call); 15156 %} 15157 15158 // TO HERE 15159 15160 // Call Java Dynamic Instruction 15161 instruct CallDynamicJavaDirect(method meth) 15162 %{ 15163 match(CallDynamicJava); 15164 15165 effect(USE meth); 15166 15167 ins_cost(CALL_COST); 15168 15169 format %{ "CALL,dynamic $meth \t// ==> " %} 15170 15171 ins_encode( aarch64_enc_java_dynamic_call(meth), 15172 aarch64_enc_call_epilog ); 15173 15174 ins_pipe(pipe_class_call); 15175 %} 15176 15177 // Call Runtime Instruction 15178 15179 instruct CallRuntimeDirect(method meth) 15180 %{ 15181 match(CallRuntime); 15182 15183 effect(USE meth); 15184 15185 ins_cost(CALL_COST); 15186 15187 format %{ "CALL, runtime $meth" %} 15188 15189 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15190 15191 ins_pipe(pipe_class_call); 15192 %} 15193 15194 // Call Runtime Instruction 15195 15196 instruct CallLeafDirect(method meth) 15197 %{ 15198 match(CallLeaf); 15199 15200 effect(USE meth); 15201 15202 ins_cost(CALL_COST); 15203 15204 format %{ "CALL, runtime leaf $meth" %} 15205 15206 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15207 15208 ins_pipe(pipe_class_call); 15209 %} 15210 15211 // Call Runtime Instruction 15212 15213 instruct CallLeafNoFPDirect(method meth) 15214 %{ 15215 match(CallLeafNoFP); 15216 15217 effect(USE meth); 15218 15219 ins_cost(CALL_COST); 15220 15221 format %{ "CALL, runtime leaf nofp $meth" %} 15222 15223 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15224 15225 ins_pipe(pipe_class_call); 15226 %} 15227 15228 // Tail Call; Jump from runtime stub to Java code. 15229 // Also known as an 'interprocedural jump'. 15230 // Target of jump will eventually return to caller. 15231 // TailJump below removes the return address. 15232 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15233 %{ 15234 match(TailCall jump_target method_oop); 15235 15236 ins_cost(CALL_COST); 15237 15238 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15239 15240 ins_encode(aarch64_enc_tail_call(jump_target)); 15241 15242 ins_pipe(pipe_class_call); 15243 %} 15244 15245 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15246 %{ 15247 match(TailJump jump_target ex_oop); 15248 15249 ins_cost(CALL_COST); 15250 15251 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15252 15253 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15254 15255 ins_pipe(pipe_class_call); 15256 %} 15257 15258 // Create exception oop: created by stack-crawling runtime code. 15259 // Created exception is now available to this handler, and is setup 15260 // just prior to jumping to this handler. No code emitted. 15261 // TODO check 15262 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15263 instruct CreateException(iRegP_R0 ex_oop) 15264 %{ 15265 match(Set ex_oop (CreateEx)); 15266 15267 format %{ " -- \t// exception oop; no code emitted" %} 15268 15269 size(0); 15270 15271 ins_encode( /*empty*/ ); 15272 15273 ins_pipe(pipe_class_empty); 15274 %} 15275 15276 // Rethrow exception: The exception oop will come in the first 15277 // argument position. Then JUMP (not call) to the rethrow stub code. 15278 instruct RethrowException() %{ 15279 match(Rethrow); 15280 ins_cost(CALL_COST); 15281 15282 format %{ "b rethrow_stub" %} 15283 15284 ins_encode( aarch64_enc_rethrow() ); 15285 15286 ins_pipe(pipe_class_call); 15287 %} 15288 15289 15290 // Return Instruction 15291 // epilog node loads ret address into lr as part of frame pop 15292 instruct Ret() 15293 %{ 15294 match(Return); 15295 15296 format %{ "ret\t// return register" %} 15297 15298 ins_encode( aarch64_enc_ret() ); 15299 15300 ins_pipe(pipe_branch); 15301 %} 15302 15303 // Die now. 15304 instruct ShouldNotReachHere() %{ 15305 match(Halt); 15306 15307 ins_cost(CALL_COST); 15308 format %{ "ShouldNotReachHere" %} 15309 15310 ins_encode %{ 15311 if (is_reachable()) { 15312 __ stop(_halt_reason); 15313 } 15314 %} 15315 15316 ins_pipe(pipe_class_default); 15317 %} 15318 15319 // ============================================================================ 15320 // Partial Subtype Check 15321 // 15322 // superklass array for an instance of the superklass. Set a hidden 15323 // internal cache on a hit (cache is checked with exposed code in 15324 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15325 // encoding ALSO sets flags. 15326 15327 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15328 %{ 15329 match(Set result (PartialSubtypeCheck sub super)); 15330 effect(KILL cr, KILL temp); 15331 15332 ins_cost(1100); // slightly larger than the next version 15333 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15334 15335 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15336 15337 opcode(0x1); // Force zero of result reg on hit 15338 15339 ins_pipe(pipe_class_memory); 15340 %} 15341 15342 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15343 %{ 15344 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15345 effect(KILL temp, KILL result); 15346 15347 ins_cost(1100); // slightly larger than the next version 15348 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15349 15350 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15351 15352 opcode(0x0); // Don't zero result reg on hit 15353 15354 ins_pipe(pipe_class_memory); 15355 %} 15356 15357 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15358 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15359 %{ 15360 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15361 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15362 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15363 15364 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15365 ins_encode %{ 15366 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15367 __ string_compare($str1$$Register, $str2$$Register, 15368 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15369 $tmp1$$Register, $tmp2$$Register, 15370 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15371 %} 15372 ins_pipe(pipe_class_memory); 15373 %} 15374 15375 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15376 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15377 %{ 15378 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15379 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15380 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15381 15382 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15383 ins_encode %{ 15384 __ string_compare($str1$$Register, $str2$$Register, 15385 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15386 $tmp1$$Register, $tmp2$$Register, 15387 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15388 %} 15389 ins_pipe(pipe_class_memory); 15390 %} 15391 15392 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15393 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15394 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15395 %{ 15396 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15397 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15398 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15399 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15400 15401 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15402 ins_encode %{ 15403 __ string_compare($str1$$Register, $str2$$Register, 15404 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15405 $tmp1$$Register, $tmp2$$Register, 15406 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15407 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15408 %} 15409 ins_pipe(pipe_class_memory); 15410 %} 15411 15412 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15413 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15414 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15415 %{ 15416 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15417 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15418 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15419 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15420 15421 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15422 ins_encode %{ 15423 __ string_compare($str1$$Register, $str2$$Register, 15424 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15425 $tmp1$$Register, $tmp2$$Register, 15426 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15427 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15428 %} 15429 ins_pipe(pipe_class_memory); 15430 %} 15431 15432 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15433 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15434 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15435 %{ 15436 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15437 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15438 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15439 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15440 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15441 15442 ins_encode %{ 15443 __ string_indexof($str1$$Register, $str2$$Register, 15444 $cnt1$$Register, $cnt2$$Register, 15445 $tmp1$$Register, $tmp2$$Register, 15446 $tmp3$$Register, $tmp4$$Register, 15447 $tmp5$$Register, $tmp6$$Register, 15448 -1, $result$$Register, StrIntrinsicNode::UU); 15449 %} 15450 ins_pipe(pipe_class_memory); 15451 %} 15452 15453 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15454 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15455 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15456 %{ 15457 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15458 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15459 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15460 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15461 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15462 15463 ins_encode %{ 15464 __ string_indexof($str1$$Register, $str2$$Register, 15465 $cnt1$$Register, $cnt2$$Register, 15466 $tmp1$$Register, $tmp2$$Register, 15467 $tmp3$$Register, $tmp4$$Register, 15468 $tmp5$$Register, $tmp6$$Register, 15469 -1, $result$$Register, StrIntrinsicNode::LL); 15470 %} 15471 ins_pipe(pipe_class_memory); 15472 %} 15473 15474 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15475 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15476 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15477 %{ 15478 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15479 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15480 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15481 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15482 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15483 15484 ins_encode %{ 15485 __ string_indexof($str1$$Register, $str2$$Register, 15486 $cnt1$$Register, $cnt2$$Register, 15487 $tmp1$$Register, $tmp2$$Register, 15488 $tmp3$$Register, $tmp4$$Register, 15489 $tmp5$$Register, $tmp6$$Register, 15490 -1, $result$$Register, StrIntrinsicNode::UL); 15491 %} 15492 ins_pipe(pipe_class_memory); 15493 %} 15494 15495 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15496 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15497 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15498 %{ 15499 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15500 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15501 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15502 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15503 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15504 15505 ins_encode %{ 15506 int icnt2 = (int)$int_cnt2$$constant; 15507 __ string_indexof($str1$$Register, $str2$$Register, 15508 $cnt1$$Register, zr, 15509 $tmp1$$Register, $tmp2$$Register, 15510 $tmp3$$Register, $tmp4$$Register, zr, zr, 15511 icnt2, $result$$Register, StrIntrinsicNode::UU); 15512 %} 15513 ins_pipe(pipe_class_memory); 15514 %} 15515 15516 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15517 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15518 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15519 %{ 15520 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15521 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15522 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15523 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15524 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15525 15526 ins_encode %{ 15527 int icnt2 = (int)$int_cnt2$$constant; 15528 __ string_indexof($str1$$Register, $str2$$Register, 15529 $cnt1$$Register, zr, 15530 $tmp1$$Register, $tmp2$$Register, 15531 $tmp3$$Register, $tmp4$$Register, zr, zr, 15532 icnt2, $result$$Register, StrIntrinsicNode::LL); 15533 %} 15534 ins_pipe(pipe_class_memory); 15535 %} 15536 15537 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15538 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15539 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15540 %{ 15541 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15542 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15543 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15544 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15545 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15546 15547 ins_encode %{ 15548 int icnt2 = (int)$int_cnt2$$constant; 15549 __ string_indexof($str1$$Register, $str2$$Register, 15550 $cnt1$$Register, zr, 15551 $tmp1$$Register, $tmp2$$Register, 15552 $tmp3$$Register, $tmp4$$Register, zr, zr, 15553 icnt2, $result$$Register, StrIntrinsicNode::UL); 15554 %} 15555 ins_pipe(pipe_class_memory); 15556 %} 15557 15558 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15559 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15560 iRegINoSp tmp3, rFlagsReg cr) 15561 %{ 15562 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15563 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15564 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15565 15566 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15567 15568 ins_encode %{ 15569 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15570 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15571 $tmp3$$Register); 15572 %} 15573 ins_pipe(pipe_class_memory); 15574 %} 15575 15576 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15577 iRegI_R0 result, rFlagsReg cr) 15578 %{ 15579 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15580 match(Set result (StrEquals (Binary str1 str2) cnt)); 15581 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15582 15583 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15584 ins_encode %{ 15585 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15586 __ string_equals($str1$$Register, $str2$$Register, 15587 $result$$Register, $cnt$$Register, 1); 15588 %} 15589 ins_pipe(pipe_class_memory); 15590 %} 15591 15592 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15593 iRegI_R0 result, rFlagsReg cr) 15594 %{ 15595 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15596 match(Set result (StrEquals (Binary str1 str2) cnt)); 15597 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15598 15599 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15600 ins_encode %{ 15601 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15602 __ string_equals($str1$$Register, $str2$$Register, 15603 $result$$Register, $cnt$$Register, 2); 15604 %} 15605 ins_pipe(pipe_class_memory); 15606 %} 15607 15608 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15609 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15610 iRegP_R10 tmp, rFlagsReg cr) 15611 %{ 15612 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15613 match(Set result (AryEq ary1 ary2)); 15614 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15615 15616 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15617 ins_encode %{ 15618 __ arrays_equals($ary1$$Register, $ary2$$Register, 15619 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15620 $result$$Register, $tmp$$Register, 1); 15621 %} 15622 ins_pipe(pipe_class_memory); 15623 %} 15624 15625 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15626 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15627 iRegP_R10 tmp, rFlagsReg cr) 15628 %{ 15629 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15630 match(Set result (AryEq ary1 ary2)); 15631 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15632 15633 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15634 ins_encode %{ 15635 __ arrays_equals($ary1$$Register, $ary2$$Register, 15636 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15637 $result$$Register, $tmp$$Register, 2); 15638 %} 15639 ins_pipe(pipe_class_memory); 15640 %} 15641 15642 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15643 %{ 15644 match(Set result (HasNegatives ary1 len)); 15645 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15646 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15647 ins_encode %{ 15648 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15649 %} 15650 ins_pipe( pipe_slow ); 15651 %} 15652 15653 // fast char[] to byte[] compression 15654 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15655 vRegD_V0 tmp1, vRegD_V1 tmp2, 15656 vRegD_V2 tmp3, vRegD_V3 tmp4, 15657 iRegI_R0 result, rFlagsReg cr) 15658 %{ 15659 match(Set result (StrCompressedCopy src (Binary dst len))); 15660 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15661 15662 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15663 ins_encode %{ 15664 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15665 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15666 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15667 $result$$Register); 15668 %} 15669 ins_pipe( pipe_slow ); 15670 %} 15671 15672 // fast byte[] to char[] inflation 15673 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15674 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15675 %{ 15676 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15677 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15678 15679 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15680 ins_encode %{ 15681 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15682 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15683 %} 15684 ins_pipe(pipe_class_memory); 15685 %} 15686 15687 // encode char[] to byte[] in ISO_8859_1 15688 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15689 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15690 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15691 iRegI_R0 result, rFlagsReg cr) 15692 %{ 15693 match(Set result (EncodeISOArray src (Binary dst len))); 15694 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15695 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15696 15697 format %{ "Encode array $src,$dst,$len -> $result" %} 15698 ins_encode %{ 15699 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15700 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15701 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15702 %} 15703 ins_pipe( pipe_class_memory ); 15704 %} 15705 15706 // ============================================================================ 15707 // This name is KNOWN by the ADLC and cannot be changed. 15708 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15709 // for this guy. 15710 instruct tlsLoadP(thread_RegP dst) 15711 %{ 15712 match(Set dst (ThreadLocal)); 15713 15714 ins_cost(0); 15715 15716 format %{ " -- \t// $dst=Thread::current(), empty" %} 15717 15718 size(0); 15719 15720 ins_encode( /*empty*/ ); 15721 15722 ins_pipe(pipe_class_empty); 15723 %} 15724 15725 // ====================VECTOR INSTRUCTIONS===================================== 15726 15727 // Load vector (32 bits) 15728 instruct loadV4(vecD dst, vmem4 mem) 15729 %{ 15730 predicate(n->as_LoadVector()->memory_size() == 4); 15731 match(Set dst (LoadVector mem)); 15732 ins_cost(4 * INSN_COST); 15733 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15734 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15735 ins_pipe(vload_reg_mem64); 15736 %} 15737 15738 // Load vector (64 bits) 15739 instruct loadV8(vecD dst, vmem8 mem) 15740 %{ 15741 predicate(n->as_LoadVector()->memory_size() == 8); 15742 match(Set dst (LoadVector mem)); 15743 ins_cost(4 * INSN_COST); 15744 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15745 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15746 ins_pipe(vload_reg_mem64); 15747 %} 15748 15749 // Load Vector (128 bits) 15750 instruct loadV16(vecX dst, vmem16 mem) 15751 %{ 15752 predicate(n->as_LoadVector()->memory_size() == 16); 15753 match(Set dst (LoadVector mem)); 15754 ins_cost(4 * INSN_COST); 15755 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15756 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15757 ins_pipe(vload_reg_mem128); 15758 %} 15759 15760 // Store Vector (32 bits) 15761 instruct storeV4(vecD src, vmem4 mem) 15762 %{ 15763 predicate(n->as_StoreVector()->memory_size() == 4); 15764 match(Set mem (StoreVector mem src)); 15765 ins_cost(4 * INSN_COST); 15766 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15767 ins_encode( aarch64_enc_strvS(src, mem) ); 15768 ins_pipe(vstore_reg_mem64); 15769 %} 15770 15771 // Store Vector (64 bits) 15772 instruct storeV8(vecD src, vmem8 mem) 15773 %{ 15774 predicate(n->as_StoreVector()->memory_size() == 8); 15775 match(Set mem (StoreVector mem src)); 15776 ins_cost(4 * INSN_COST); 15777 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15778 ins_encode( aarch64_enc_strvD(src, mem) ); 15779 ins_pipe(vstore_reg_mem64); 15780 %} 15781 15782 // Store Vector (128 bits) 15783 instruct storeV16(vecX src, vmem16 mem) 15784 %{ 15785 predicate(n->as_StoreVector()->memory_size() == 16); 15786 match(Set mem (StoreVector mem src)); 15787 ins_cost(4 * INSN_COST); 15788 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15789 ins_encode( aarch64_enc_strvQ(src, mem) ); 15790 ins_pipe(vstore_reg_mem128); 15791 %} 15792 15793 instruct replicate8B(vecD dst, iRegIorL2I src) 15794 %{ 15795 predicate(n->as_Vector()->length() == 4 || 15796 n->as_Vector()->length() == 8); 15797 match(Set dst (ReplicateB src)); 15798 ins_cost(INSN_COST); 15799 format %{ "dup $dst, $src\t# vector (8B)" %} 15800 ins_encode %{ 15801 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15802 %} 15803 ins_pipe(vdup_reg_reg64); 15804 %} 15805 15806 instruct replicate16B(vecX dst, iRegIorL2I src) 15807 %{ 15808 predicate(n->as_Vector()->length() == 16); 15809 match(Set dst (ReplicateB src)); 15810 ins_cost(INSN_COST); 15811 format %{ "dup $dst, $src\t# vector (16B)" %} 15812 ins_encode %{ 15813 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15814 %} 15815 ins_pipe(vdup_reg_reg128); 15816 %} 15817 15818 instruct replicate8B_imm(vecD dst, immI con) 15819 %{ 15820 predicate(n->as_Vector()->length() == 4 || 15821 n->as_Vector()->length() == 8); 15822 match(Set dst (ReplicateB con)); 15823 ins_cost(INSN_COST); 15824 format %{ "movi $dst, $con\t# vector(8B)" %} 15825 ins_encode %{ 15826 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15827 %} 15828 ins_pipe(vmovi_reg_imm64); 15829 %} 15830 15831 instruct replicate16B_imm(vecX dst, immI con) 15832 %{ 15833 predicate(n->as_Vector()->length() == 16); 15834 match(Set dst (ReplicateB con)); 15835 ins_cost(INSN_COST); 15836 format %{ "movi $dst, $con\t# vector(16B)" %} 15837 ins_encode %{ 15838 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15839 %} 15840 ins_pipe(vmovi_reg_imm128); 15841 %} 15842 15843 instruct replicate4S(vecD dst, iRegIorL2I src) 15844 %{ 15845 predicate(n->as_Vector()->length() == 2 || 15846 n->as_Vector()->length() == 4); 15847 match(Set dst (ReplicateS src)); 15848 ins_cost(INSN_COST); 15849 format %{ "dup $dst, $src\t# vector (4S)" %} 15850 ins_encode %{ 15851 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15852 %} 15853 ins_pipe(vdup_reg_reg64); 15854 %} 15855 15856 instruct replicate8S(vecX dst, iRegIorL2I src) 15857 %{ 15858 predicate(n->as_Vector()->length() == 8); 15859 match(Set dst (ReplicateS src)); 15860 ins_cost(INSN_COST); 15861 format %{ "dup $dst, $src\t# vector (8S)" %} 15862 ins_encode %{ 15863 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15864 %} 15865 ins_pipe(vdup_reg_reg128); 15866 %} 15867 15868 instruct replicate4S_imm(vecD dst, immI con) 15869 %{ 15870 predicate(n->as_Vector()->length() == 2 || 15871 n->as_Vector()->length() == 4); 15872 match(Set dst (ReplicateS con)); 15873 ins_cost(INSN_COST); 15874 format %{ "movi $dst, $con\t# vector(4H)" %} 15875 ins_encode %{ 15876 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15877 %} 15878 ins_pipe(vmovi_reg_imm64); 15879 %} 15880 15881 instruct replicate8S_imm(vecX dst, immI con) 15882 %{ 15883 predicate(n->as_Vector()->length() == 8); 15884 match(Set dst (ReplicateS con)); 15885 ins_cost(INSN_COST); 15886 format %{ "movi $dst, $con\t# vector(8H)" %} 15887 ins_encode %{ 15888 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15889 %} 15890 ins_pipe(vmovi_reg_imm128); 15891 %} 15892 15893 instruct replicate2I(vecD dst, iRegIorL2I src) 15894 %{ 15895 predicate(n->as_Vector()->length() == 2); 15896 match(Set dst (ReplicateI src)); 15897 ins_cost(INSN_COST); 15898 format %{ "dup $dst, $src\t# vector (2I)" %} 15899 ins_encode %{ 15900 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15901 %} 15902 ins_pipe(vdup_reg_reg64); 15903 %} 15904 15905 instruct replicate4I(vecX dst, iRegIorL2I src) 15906 %{ 15907 predicate(n->as_Vector()->length() == 4); 15908 match(Set dst (ReplicateI src)); 15909 ins_cost(INSN_COST); 15910 format %{ "dup $dst, $src\t# vector (4I)" %} 15911 ins_encode %{ 15912 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15913 %} 15914 ins_pipe(vdup_reg_reg128); 15915 %} 15916 15917 instruct replicate2I_imm(vecD dst, immI con) 15918 %{ 15919 predicate(n->as_Vector()->length() == 2); 15920 match(Set dst (ReplicateI con)); 15921 ins_cost(INSN_COST); 15922 format %{ "movi $dst, $con\t# vector(2I)" %} 15923 ins_encode %{ 15924 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15925 %} 15926 ins_pipe(vmovi_reg_imm64); 15927 %} 15928 15929 instruct replicate4I_imm(vecX dst, immI con) 15930 %{ 15931 predicate(n->as_Vector()->length() == 4); 15932 match(Set dst (ReplicateI con)); 15933 ins_cost(INSN_COST); 15934 format %{ "movi $dst, $con\t# vector(4I)" %} 15935 ins_encode %{ 15936 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15937 %} 15938 ins_pipe(vmovi_reg_imm128); 15939 %} 15940 15941 instruct replicate2L(vecX dst, iRegL src) 15942 %{ 15943 predicate(n->as_Vector()->length() == 2); 15944 match(Set dst (ReplicateL src)); 15945 ins_cost(INSN_COST); 15946 format %{ "dup $dst, $src\t# vector (2L)" %} 15947 ins_encode %{ 15948 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15949 %} 15950 ins_pipe(vdup_reg_reg128); 15951 %} 15952 15953 instruct replicate2L_zero(vecX dst, immI0 zero) 15954 %{ 15955 predicate(n->as_Vector()->length() == 2); 15956 match(Set dst (ReplicateI zero)); 15957 ins_cost(INSN_COST); 15958 format %{ "movi $dst, $zero\t# vector(4I)" %} 15959 ins_encode %{ 15960 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15961 as_FloatRegister($dst$$reg), 15962 as_FloatRegister($dst$$reg)); 15963 %} 15964 ins_pipe(vmovi_reg_imm128); 15965 %} 15966 15967 instruct replicate2F(vecD dst, vRegF src) 15968 %{ 15969 predicate(n->as_Vector()->length() == 2); 15970 match(Set dst (ReplicateF src)); 15971 ins_cost(INSN_COST); 15972 format %{ "dup $dst, $src\t# vector (2F)" %} 15973 ins_encode %{ 15974 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15975 as_FloatRegister($src$$reg)); 15976 %} 15977 ins_pipe(vdup_reg_freg64); 15978 %} 15979 15980 instruct replicate4F(vecX dst, vRegF src) 15981 %{ 15982 predicate(n->as_Vector()->length() == 4); 15983 match(Set dst (ReplicateF src)); 15984 ins_cost(INSN_COST); 15985 format %{ "dup $dst, $src\t# vector (4F)" %} 15986 ins_encode %{ 15987 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15988 as_FloatRegister($src$$reg)); 15989 %} 15990 ins_pipe(vdup_reg_freg128); 15991 %} 15992 15993 instruct replicate2D(vecX dst, vRegD src) 15994 %{ 15995 predicate(n->as_Vector()->length() == 2); 15996 match(Set dst (ReplicateD src)); 15997 ins_cost(INSN_COST); 15998 format %{ "dup $dst, $src\t# vector (2D)" %} 15999 ins_encode %{ 16000 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16001 as_FloatRegister($src$$reg)); 16002 %} 16003 ins_pipe(vdup_reg_dreg128); 16004 %} 16005 16006 // ====================REDUCTION ARITHMETIC==================================== 16007 16008 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp, iRegINoSp tmp2) 16009 %{ 16010 match(Set dst (AddReductionVI isrc vsrc)); 16011 ins_cost(INSN_COST); 16012 effect(TEMP tmp, TEMP tmp2); 16013 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16014 "umov $tmp2, $vsrc, S, 1\n\t" 16015 "addw $tmp, $isrc, $tmp\n\t" 16016 "addw $dst, $tmp, $tmp2\t# add reduction2I" 16017 %} 16018 ins_encode %{ 16019 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16020 __ umov($tmp2$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16021 __ addw($tmp$$Register, $isrc$$Register, $tmp$$Register); 16022 __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); 16023 %} 16024 ins_pipe(pipe_class_default); 16025 %} 16026 16027 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16028 %{ 16029 match(Set dst (AddReductionVI isrc vsrc)); 16030 ins_cost(INSN_COST); 16031 effect(TEMP vtmp, TEMP itmp); 16032 format %{ "addv $vtmp, T4S, $vsrc\n\t" 16033 "umov $itmp, $vtmp, S, 0\n\t" 16034 "addw $dst, $itmp, $isrc\t# add reduction4I" 16035 %} 16036 ins_encode %{ 16037 __ addv(as_FloatRegister($vtmp$$reg), __ T4S, 16038 as_FloatRegister($vsrc$$reg)); 16039 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16040 __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); 16041 %} 16042 ins_pipe(pipe_class_default); 16043 %} 16044 16045 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) 16046 %{ 16047 match(Set dst (MulReductionVI isrc vsrc)); 16048 ins_cost(INSN_COST); 16049 effect(TEMP tmp, TEMP dst); 16050 format %{ "umov $tmp, $vsrc, S, 0\n\t" 16051 "mul $dst, $tmp, $isrc\n\t" 16052 "umov $tmp, $vsrc, S, 1\n\t" 16053 "mul $dst, $tmp, $dst\t# mul reduction2I" 16054 %} 16055 ins_encode %{ 16056 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); 16057 __ mul($dst$$Register, $tmp$$Register, $isrc$$Register); 16058 __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); 16059 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16060 %} 16061 ins_pipe(pipe_class_default); 16062 %} 16063 16064 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) 16065 %{ 16066 match(Set dst (MulReductionVI isrc vsrc)); 16067 ins_cost(INSN_COST); 16068 effect(TEMP vtmp, TEMP itmp, TEMP dst); 16069 format %{ "ins $vtmp, D, $vsrc, 0, 1\n\t" 16070 "mulv $vtmp, T2S, $vtmp, $vsrc\n\t" 16071 "umov $itmp, $vtmp, S, 0\n\t" 16072 "mul $dst, $itmp, $isrc\n\t" 16073 "umov $itmp, $vtmp, S, 1\n\t" 16074 "mul $dst, $itmp, $dst\t# mul reduction4I" 16075 %} 16076 ins_encode %{ 16077 __ ins(as_FloatRegister($vtmp$$reg), __ D, 16078 as_FloatRegister($vsrc$$reg), 0, 1); 16079 __ mulv(as_FloatRegister($vtmp$$reg), __ T2S, 16080 as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); 16081 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); 16082 __ mul($dst$$Register, $itmp$$Register, $isrc$$Register); 16083 __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 1); 16084 __ mul($dst$$Register, $itmp$$Register, $dst$$Register); 16085 %} 16086 ins_pipe(pipe_class_default); 16087 %} 16088 16089 instruct reduce_add2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16090 %{ 16091 match(Set dst (AddReductionVF fsrc vsrc)); 16092 ins_cost(INSN_COST); 16093 effect(TEMP tmp, TEMP dst); 16094 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16095 "ins $tmp, S, $vsrc, 0, 1\n\t" 16096 "fadds $dst, $dst, $tmp\t# add reduction2F" 16097 %} 16098 ins_encode %{ 16099 __ fadds(as_FloatRegister($dst$$reg), 16100 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16101 __ ins(as_FloatRegister($tmp$$reg), __ S, 16102 as_FloatRegister($vsrc$$reg), 0, 1); 16103 __ fadds(as_FloatRegister($dst$$reg), 16104 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16105 %} 16106 ins_pipe(pipe_class_default); 16107 %} 16108 16109 instruct reduce_add4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16110 %{ 16111 match(Set dst (AddReductionVF fsrc vsrc)); 16112 ins_cost(INSN_COST); 16113 effect(TEMP tmp, TEMP dst); 16114 format %{ "fadds $dst, $fsrc, $vsrc\n\t" 16115 "ins $tmp, S, $vsrc, 0, 1\n\t" 16116 "fadds $dst, $dst, $tmp\n\t" 16117 "ins $tmp, S, $vsrc, 0, 2\n\t" 16118 "fadds $dst, $dst, $tmp\n\t" 16119 "ins $tmp, S, $vsrc, 0, 3\n\t" 16120 "fadds $dst, $dst, $tmp\t# add reduction4F" 16121 %} 16122 ins_encode %{ 16123 __ fadds(as_FloatRegister($dst$$reg), 16124 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16125 __ ins(as_FloatRegister($tmp$$reg), __ S, 16126 as_FloatRegister($vsrc$$reg), 0, 1); 16127 __ fadds(as_FloatRegister($dst$$reg), 16128 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16129 __ ins(as_FloatRegister($tmp$$reg), __ S, 16130 as_FloatRegister($vsrc$$reg), 0, 2); 16131 __ fadds(as_FloatRegister($dst$$reg), 16132 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16133 __ ins(as_FloatRegister($tmp$$reg), __ S, 16134 as_FloatRegister($vsrc$$reg), 0, 3); 16135 __ fadds(as_FloatRegister($dst$$reg), 16136 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16137 %} 16138 ins_pipe(pipe_class_default); 16139 %} 16140 16141 instruct reduce_mul2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) 16142 %{ 16143 match(Set dst (MulReductionVF fsrc vsrc)); 16144 ins_cost(INSN_COST); 16145 effect(TEMP tmp, TEMP dst); 16146 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16147 "ins $tmp, S, $vsrc, 0, 1\n\t" 16148 "fmuls $dst, $dst, $tmp\t# mul reduction2F" 16149 %} 16150 ins_encode %{ 16151 __ fmuls(as_FloatRegister($dst$$reg), 16152 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16153 __ ins(as_FloatRegister($tmp$$reg), __ S, 16154 as_FloatRegister($vsrc$$reg), 0, 1); 16155 __ fmuls(as_FloatRegister($dst$$reg), 16156 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16157 %} 16158 ins_pipe(pipe_class_default); 16159 %} 16160 16161 instruct reduce_mul4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) 16162 %{ 16163 match(Set dst (MulReductionVF fsrc vsrc)); 16164 ins_cost(INSN_COST); 16165 effect(TEMP tmp, TEMP dst); 16166 format %{ "fmuls $dst, $fsrc, $vsrc\n\t" 16167 "ins $tmp, S, $vsrc, 0, 1\n\t" 16168 "fmuls $dst, $dst, $tmp\n\t" 16169 "ins $tmp, S, $vsrc, 0, 2\n\t" 16170 "fmuls $dst, $dst, $tmp\n\t" 16171 "ins $tmp, S, $vsrc, 0, 3\n\t" 16172 "fmuls $dst, $dst, $tmp\t# mul reduction4F" 16173 %} 16174 ins_encode %{ 16175 __ fmuls(as_FloatRegister($dst$$reg), 16176 as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16177 __ ins(as_FloatRegister($tmp$$reg), __ S, 16178 as_FloatRegister($vsrc$$reg), 0, 1); 16179 __ fmuls(as_FloatRegister($dst$$reg), 16180 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16181 __ ins(as_FloatRegister($tmp$$reg), __ S, 16182 as_FloatRegister($vsrc$$reg), 0, 2); 16183 __ fmuls(as_FloatRegister($dst$$reg), 16184 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16185 __ ins(as_FloatRegister($tmp$$reg), __ S, 16186 as_FloatRegister($vsrc$$reg), 0, 3); 16187 __ fmuls(as_FloatRegister($dst$$reg), 16188 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16189 %} 16190 ins_pipe(pipe_class_default); 16191 %} 16192 16193 instruct reduce_add2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16194 %{ 16195 match(Set dst (AddReductionVD dsrc vsrc)); 16196 ins_cost(INSN_COST); 16197 effect(TEMP tmp, TEMP dst); 16198 format %{ "faddd $dst, $dsrc, $vsrc\n\t" 16199 "ins $tmp, D, $vsrc, 0, 1\n\t" 16200 "faddd $dst, $dst, $tmp\t# add reduction2D" 16201 %} 16202 ins_encode %{ 16203 __ faddd(as_FloatRegister($dst$$reg), 16204 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16205 __ ins(as_FloatRegister($tmp$$reg), __ D, 16206 as_FloatRegister($vsrc$$reg), 0, 1); 16207 __ faddd(as_FloatRegister($dst$$reg), 16208 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16209 %} 16210 ins_pipe(pipe_class_default); 16211 %} 16212 16213 instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) 16214 %{ 16215 match(Set dst (MulReductionVD dsrc vsrc)); 16216 ins_cost(INSN_COST); 16217 effect(TEMP tmp, TEMP dst); 16218 format %{ "fmuld $dst, $dsrc, $vsrc\n\t" 16219 "ins $tmp, D, $vsrc, 0, 1\n\t" 16220 "fmuld $dst, $dst, $tmp\t# mul reduction2D" 16221 %} 16222 ins_encode %{ 16223 __ fmuld(as_FloatRegister($dst$$reg), 16224 as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16225 __ ins(as_FloatRegister($tmp$$reg), __ D, 16226 as_FloatRegister($vsrc$$reg), 0, 1); 16227 __ fmuld(as_FloatRegister($dst$$reg), 16228 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16229 %} 16230 ins_pipe(pipe_class_default); 16231 %} 16232 16233 instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16234 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16235 match(Set dst (MaxReductionV fsrc vsrc)); 16236 ins_cost(INSN_COST); 16237 effect(TEMP_DEF dst, TEMP tmp); 16238 format %{ "fmaxs $dst, $fsrc, $vsrc\n\t" 16239 "ins $tmp, S, $vsrc, 0, 1\n\t" 16240 "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} 16241 ins_encode %{ 16242 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16243 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16244 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16245 %} 16246 ins_pipe(pipe_class_default); 16247 %} 16248 16249 instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16250 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16251 match(Set dst (MaxReductionV fsrc vsrc)); 16252 ins_cost(INSN_COST); 16253 effect(TEMP_DEF dst); 16254 format %{ "fmaxv $dst, T4S, $vsrc\n\t" 16255 "fmaxs $dst, $dst, $fsrc\t# max reduction4F" %} 16256 ins_encode %{ 16257 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16258 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16259 %} 16260 ins_pipe(pipe_class_default); 16261 %} 16262 16263 instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16264 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16265 match(Set dst (MaxReductionV dsrc vsrc)); 16266 ins_cost(INSN_COST); 16267 effect(TEMP_DEF dst, TEMP tmp); 16268 format %{ "fmaxd $dst, $dsrc, $vsrc\n\t" 16269 "ins $tmp, D, $vsrc, 0, 1\n\t" 16270 "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} 16271 ins_encode %{ 16272 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16273 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16274 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16275 %} 16276 ins_pipe(pipe_class_default); 16277 %} 16278 16279 instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ 16280 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16281 match(Set dst (MinReductionV fsrc vsrc)); 16282 ins_cost(INSN_COST); 16283 effect(TEMP_DEF dst, TEMP tmp); 16284 format %{ "fmins $dst, $fsrc, $vsrc\n\t" 16285 "ins $tmp, S, $vsrc, 0, 1\n\t" 16286 "fmins $dst, $dst, $tmp\t# min reduction2F" %} 16287 ins_encode %{ 16288 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); 16289 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); 16290 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16291 %} 16292 ins_pipe(pipe_class_default); 16293 %} 16294 16295 instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ 16296 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16297 match(Set dst (MinReductionV fsrc vsrc)); 16298 ins_cost(INSN_COST); 16299 effect(TEMP_DEF dst); 16300 format %{ "fminv $dst, T4S, $vsrc\n\t" 16301 "fmins $dst, $dst, $fsrc\t# min reduction4F" %} 16302 ins_encode %{ 16303 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); 16304 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); 16305 %} 16306 ins_pipe(pipe_class_default); 16307 %} 16308 16309 instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ 16310 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16311 match(Set dst (MinReductionV dsrc vsrc)); 16312 ins_cost(INSN_COST); 16313 effect(TEMP_DEF dst, TEMP tmp); 16314 format %{ "fmind $dst, $dsrc, $vsrc\n\t" 16315 "ins $tmp, D, $vsrc, 0, 1\n\t" 16316 "fmind $dst, $dst, $tmp\t# min reduction2D" %} 16317 ins_encode %{ 16318 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); 16319 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); 16320 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16321 %} 16322 ins_pipe(pipe_class_default); 16323 %} 16324 16325 // ====================VECTOR ARITHMETIC======================================= 16326 16327 // --------------------------------- ADD -------------------------------------- 16328 16329 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16330 %{ 16331 predicate(n->as_Vector()->length() == 4 || 16332 n->as_Vector()->length() == 8); 16333 match(Set dst (AddVB src1 src2)); 16334 ins_cost(INSN_COST); 16335 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16336 ins_encode %{ 16337 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16338 as_FloatRegister($src1$$reg), 16339 as_FloatRegister($src2$$reg)); 16340 %} 16341 ins_pipe(vdop64); 16342 %} 16343 16344 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16345 %{ 16346 predicate(n->as_Vector()->length() == 16); 16347 match(Set dst (AddVB src1 src2)); 16348 ins_cost(INSN_COST); 16349 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16350 ins_encode %{ 16351 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16352 as_FloatRegister($src1$$reg), 16353 as_FloatRegister($src2$$reg)); 16354 %} 16355 ins_pipe(vdop128); 16356 %} 16357 16358 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16359 %{ 16360 predicate(n->as_Vector()->length() == 2 || 16361 n->as_Vector()->length() == 4); 16362 match(Set dst (AddVS src1 src2)); 16363 ins_cost(INSN_COST); 16364 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16365 ins_encode %{ 16366 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16367 as_FloatRegister($src1$$reg), 16368 as_FloatRegister($src2$$reg)); 16369 %} 16370 ins_pipe(vdop64); 16371 %} 16372 16373 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16374 %{ 16375 predicate(n->as_Vector()->length() == 8); 16376 match(Set dst (AddVS src1 src2)); 16377 ins_cost(INSN_COST); 16378 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16379 ins_encode %{ 16380 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16381 as_FloatRegister($src1$$reg), 16382 as_FloatRegister($src2$$reg)); 16383 %} 16384 ins_pipe(vdop128); 16385 %} 16386 16387 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16388 %{ 16389 predicate(n->as_Vector()->length() == 2); 16390 match(Set dst (AddVI src1 src2)); 16391 ins_cost(INSN_COST); 16392 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16393 ins_encode %{ 16394 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16395 as_FloatRegister($src1$$reg), 16396 as_FloatRegister($src2$$reg)); 16397 %} 16398 ins_pipe(vdop64); 16399 %} 16400 16401 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16402 %{ 16403 predicate(n->as_Vector()->length() == 4); 16404 match(Set dst (AddVI src1 src2)); 16405 ins_cost(INSN_COST); 16406 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16407 ins_encode %{ 16408 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16409 as_FloatRegister($src1$$reg), 16410 as_FloatRegister($src2$$reg)); 16411 %} 16412 ins_pipe(vdop128); 16413 %} 16414 16415 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16416 %{ 16417 predicate(n->as_Vector()->length() == 2); 16418 match(Set dst (AddVL src1 src2)); 16419 ins_cost(INSN_COST); 16420 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16421 ins_encode %{ 16422 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16423 as_FloatRegister($src1$$reg), 16424 as_FloatRegister($src2$$reg)); 16425 %} 16426 ins_pipe(vdop128); 16427 %} 16428 16429 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16430 %{ 16431 predicate(n->as_Vector()->length() == 2); 16432 match(Set dst (AddVF src1 src2)); 16433 ins_cost(INSN_COST); 16434 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16435 ins_encode %{ 16436 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16437 as_FloatRegister($src1$$reg), 16438 as_FloatRegister($src2$$reg)); 16439 %} 16440 ins_pipe(vdop_fp64); 16441 %} 16442 16443 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16444 %{ 16445 predicate(n->as_Vector()->length() == 4); 16446 match(Set dst (AddVF src1 src2)); 16447 ins_cost(INSN_COST); 16448 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16449 ins_encode %{ 16450 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16451 as_FloatRegister($src1$$reg), 16452 as_FloatRegister($src2$$reg)); 16453 %} 16454 ins_pipe(vdop_fp128); 16455 %} 16456 16457 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16458 %{ 16459 match(Set dst (AddVD src1 src2)); 16460 ins_cost(INSN_COST); 16461 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16462 ins_encode %{ 16463 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16464 as_FloatRegister($src1$$reg), 16465 as_FloatRegister($src2$$reg)); 16466 %} 16467 ins_pipe(vdop_fp128); 16468 %} 16469 16470 // --------------------------------- SUB -------------------------------------- 16471 16472 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16473 %{ 16474 predicate(n->as_Vector()->length() == 4 || 16475 n->as_Vector()->length() == 8); 16476 match(Set dst (SubVB src1 src2)); 16477 ins_cost(INSN_COST); 16478 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16479 ins_encode %{ 16480 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16481 as_FloatRegister($src1$$reg), 16482 as_FloatRegister($src2$$reg)); 16483 %} 16484 ins_pipe(vdop64); 16485 %} 16486 16487 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16488 %{ 16489 predicate(n->as_Vector()->length() == 16); 16490 match(Set dst (SubVB src1 src2)); 16491 ins_cost(INSN_COST); 16492 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16493 ins_encode %{ 16494 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16495 as_FloatRegister($src1$$reg), 16496 as_FloatRegister($src2$$reg)); 16497 %} 16498 ins_pipe(vdop128); 16499 %} 16500 16501 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16502 %{ 16503 predicate(n->as_Vector()->length() == 2 || 16504 n->as_Vector()->length() == 4); 16505 match(Set dst (SubVS src1 src2)); 16506 ins_cost(INSN_COST); 16507 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16508 ins_encode %{ 16509 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16510 as_FloatRegister($src1$$reg), 16511 as_FloatRegister($src2$$reg)); 16512 %} 16513 ins_pipe(vdop64); 16514 %} 16515 16516 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16517 %{ 16518 predicate(n->as_Vector()->length() == 8); 16519 match(Set dst (SubVS src1 src2)); 16520 ins_cost(INSN_COST); 16521 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16522 ins_encode %{ 16523 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16524 as_FloatRegister($src1$$reg), 16525 as_FloatRegister($src2$$reg)); 16526 %} 16527 ins_pipe(vdop128); 16528 %} 16529 16530 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16531 %{ 16532 predicate(n->as_Vector()->length() == 2); 16533 match(Set dst (SubVI src1 src2)); 16534 ins_cost(INSN_COST); 16535 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16536 ins_encode %{ 16537 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16538 as_FloatRegister($src1$$reg), 16539 as_FloatRegister($src2$$reg)); 16540 %} 16541 ins_pipe(vdop64); 16542 %} 16543 16544 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16545 %{ 16546 predicate(n->as_Vector()->length() == 4); 16547 match(Set dst (SubVI src1 src2)); 16548 ins_cost(INSN_COST); 16549 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16550 ins_encode %{ 16551 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16552 as_FloatRegister($src1$$reg), 16553 as_FloatRegister($src2$$reg)); 16554 %} 16555 ins_pipe(vdop128); 16556 %} 16557 16558 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16559 %{ 16560 predicate(n->as_Vector()->length() == 2); 16561 match(Set dst (SubVL src1 src2)); 16562 ins_cost(INSN_COST); 16563 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16564 ins_encode %{ 16565 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16566 as_FloatRegister($src1$$reg), 16567 as_FloatRegister($src2$$reg)); 16568 %} 16569 ins_pipe(vdop128); 16570 %} 16571 16572 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16573 %{ 16574 predicate(n->as_Vector()->length() == 2); 16575 match(Set dst (SubVF src1 src2)); 16576 ins_cost(INSN_COST); 16577 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16578 ins_encode %{ 16579 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16580 as_FloatRegister($src1$$reg), 16581 as_FloatRegister($src2$$reg)); 16582 %} 16583 ins_pipe(vdop_fp64); 16584 %} 16585 16586 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16587 %{ 16588 predicate(n->as_Vector()->length() == 4); 16589 match(Set dst (SubVF src1 src2)); 16590 ins_cost(INSN_COST); 16591 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16592 ins_encode %{ 16593 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16594 as_FloatRegister($src1$$reg), 16595 as_FloatRegister($src2$$reg)); 16596 %} 16597 ins_pipe(vdop_fp128); 16598 %} 16599 16600 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16601 %{ 16602 predicate(n->as_Vector()->length() == 2); 16603 match(Set dst (SubVD src1 src2)); 16604 ins_cost(INSN_COST); 16605 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16606 ins_encode %{ 16607 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16608 as_FloatRegister($src1$$reg), 16609 as_FloatRegister($src2$$reg)); 16610 %} 16611 ins_pipe(vdop_fp128); 16612 %} 16613 16614 // --------------------------------- MUL -------------------------------------- 16615 16616 instruct vmul8B(vecD dst, vecD src1, vecD src2) 16617 %{ 16618 predicate(n->as_Vector()->length() == 4 || 16619 n->as_Vector()->length() == 8); 16620 match(Set dst (MulVB src1 src2)); 16621 ins_cost(INSN_COST); 16622 format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %} 16623 ins_encode %{ 16624 __ mulv(as_FloatRegister($dst$$reg), __ T8B, 16625 as_FloatRegister($src1$$reg), 16626 as_FloatRegister($src2$$reg)); 16627 %} 16628 ins_pipe(vmul64); 16629 %} 16630 16631 instruct vmul16B(vecX dst, vecX src1, vecX src2) 16632 %{ 16633 predicate(n->as_Vector()->length() == 16); 16634 match(Set dst (MulVB src1 src2)); 16635 ins_cost(INSN_COST); 16636 format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %} 16637 ins_encode %{ 16638 __ mulv(as_FloatRegister($dst$$reg), __ T16B, 16639 as_FloatRegister($src1$$reg), 16640 as_FloatRegister($src2$$reg)); 16641 %} 16642 ins_pipe(vmul128); 16643 %} 16644 16645 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16646 %{ 16647 predicate(n->as_Vector()->length() == 2 || 16648 n->as_Vector()->length() == 4); 16649 match(Set dst (MulVS src1 src2)); 16650 ins_cost(INSN_COST); 16651 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16652 ins_encode %{ 16653 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16654 as_FloatRegister($src1$$reg), 16655 as_FloatRegister($src2$$reg)); 16656 %} 16657 ins_pipe(vmul64); 16658 %} 16659 16660 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16661 %{ 16662 predicate(n->as_Vector()->length() == 8); 16663 match(Set dst (MulVS src1 src2)); 16664 ins_cost(INSN_COST); 16665 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16666 ins_encode %{ 16667 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16668 as_FloatRegister($src1$$reg), 16669 as_FloatRegister($src2$$reg)); 16670 %} 16671 ins_pipe(vmul128); 16672 %} 16673 16674 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16675 %{ 16676 predicate(n->as_Vector()->length() == 2); 16677 match(Set dst (MulVI src1 src2)); 16678 ins_cost(INSN_COST); 16679 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16680 ins_encode %{ 16681 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16682 as_FloatRegister($src1$$reg), 16683 as_FloatRegister($src2$$reg)); 16684 %} 16685 ins_pipe(vmul64); 16686 %} 16687 16688 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16689 %{ 16690 predicate(n->as_Vector()->length() == 4); 16691 match(Set dst (MulVI src1 src2)); 16692 ins_cost(INSN_COST); 16693 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16694 ins_encode %{ 16695 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16696 as_FloatRegister($src1$$reg), 16697 as_FloatRegister($src2$$reg)); 16698 %} 16699 ins_pipe(vmul128); 16700 %} 16701 16702 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16703 %{ 16704 predicate(n->as_Vector()->length() == 2); 16705 match(Set dst (MulVF src1 src2)); 16706 ins_cost(INSN_COST); 16707 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16708 ins_encode %{ 16709 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16710 as_FloatRegister($src1$$reg), 16711 as_FloatRegister($src2$$reg)); 16712 %} 16713 ins_pipe(vmuldiv_fp64); 16714 %} 16715 16716 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16717 %{ 16718 predicate(n->as_Vector()->length() == 4); 16719 match(Set dst (MulVF src1 src2)); 16720 ins_cost(INSN_COST); 16721 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16722 ins_encode %{ 16723 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16724 as_FloatRegister($src1$$reg), 16725 as_FloatRegister($src2$$reg)); 16726 %} 16727 ins_pipe(vmuldiv_fp128); 16728 %} 16729 16730 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16731 %{ 16732 predicate(n->as_Vector()->length() == 2); 16733 match(Set dst (MulVD src1 src2)); 16734 ins_cost(INSN_COST); 16735 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16736 ins_encode %{ 16737 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16738 as_FloatRegister($src1$$reg), 16739 as_FloatRegister($src2$$reg)); 16740 %} 16741 ins_pipe(vmuldiv_fp128); 16742 %} 16743 16744 // --------------------------------- MLA -------------------------------------- 16745 16746 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16747 %{ 16748 predicate(n->as_Vector()->length() == 2 || 16749 n->as_Vector()->length() == 4); 16750 match(Set dst (AddVS dst (MulVS src1 src2))); 16751 ins_cost(INSN_COST); 16752 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16753 ins_encode %{ 16754 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16755 as_FloatRegister($src1$$reg), 16756 as_FloatRegister($src2$$reg)); 16757 %} 16758 ins_pipe(vmla64); 16759 %} 16760 16761 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16762 %{ 16763 predicate(n->as_Vector()->length() == 8); 16764 match(Set dst (AddVS dst (MulVS src1 src2))); 16765 ins_cost(INSN_COST); 16766 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16767 ins_encode %{ 16768 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16769 as_FloatRegister($src1$$reg), 16770 as_FloatRegister($src2$$reg)); 16771 %} 16772 ins_pipe(vmla128); 16773 %} 16774 16775 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16776 %{ 16777 predicate(n->as_Vector()->length() == 2); 16778 match(Set dst (AddVI dst (MulVI src1 src2))); 16779 ins_cost(INSN_COST); 16780 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16781 ins_encode %{ 16782 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16783 as_FloatRegister($src1$$reg), 16784 as_FloatRegister($src2$$reg)); 16785 %} 16786 ins_pipe(vmla64); 16787 %} 16788 16789 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16790 %{ 16791 predicate(n->as_Vector()->length() == 4); 16792 match(Set dst (AddVI dst (MulVI src1 src2))); 16793 ins_cost(INSN_COST); 16794 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16795 ins_encode %{ 16796 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16797 as_FloatRegister($src1$$reg), 16798 as_FloatRegister($src2$$reg)); 16799 %} 16800 ins_pipe(vmla128); 16801 %} 16802 16803 // dst + src1 * src2 16804 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16805 predicate(UseFMA && n->as_Vector()->length() == 2); 16806 match(Set dst (FmaVF dst (Binary src1 src2))); 16807 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16808 ins_cost(INSN_COST); 16809 ins_encode %{ 16810 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16811 as_FloatRegister($src1$$reg), 16812 as_FloatRegister($src2$$reg)); 16813 %} 16814 ins_pipe(vmuldiv_fp64); 16815 %} 16816 16817 // dst + src1 * src2 16818 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16819 predicate(UseFMA && n->as_Vector()->length() == 4); 16820 match(Set dst (FmaVF dst (Binary src1 src2))); 16821 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16822 ins_cost(INSN_COST); 16823 ins_encode %{ 16824 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16825 as_FloatRegister($src1$$reg), 16826 as_FloatRegister($src2$$reg)); 16827 %} 16828 ins_pipe(vmuldiv_fp128); 16829 %} 16830 16831 // dst + src1 * src2 16832 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16833 predicate(UseFMA && n->as_Vector()->length() == 2); 16834 match(Set dst (FmaVD dst (Binary src1 src2))); 16835 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16836 ins_cost(INSN_COST); 16837 ins_encode %{ 16838 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16839 as_FloatRegister($src1$$reg), 16840 as_FloatRegister($src2$$reg)); 16841 %} 16842 ins_pipe(vmuldiv_fp128); 16843 %} 16844 16845 // --------------------------------- MLS -------------------------------------- 16846 16847 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16848 %{ 16849 predicate(n->as_Vector()->length() == 2 || 16850 n->as_Vector()->length() == 4); 16851 match(Set dst (SubVS dst (MulVS src1 src2))); 16852 ins_cost(INSN_COST); 16853 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16854 ins_encode %{ 16855 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16856 as_FloatRegister($src1$$reg), 16857 as_FloatRegister($src2$$reg)); 16858 %} 16859 ins_pipe(vmla64); 16860 %} 16861 16862 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16863 %{ 16864 predicate(n->as_Vector()->length() == 8); 16865 match(Set dst (SubVS dst (MulVS src1 src2))); 16866 ins_cost(INSN_COST); 16867 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16868 ins_encode %{ 16869 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16870 as_FloatRegister($src1$$reg), 16871 as_FloatRegister($src2$$reg)); 16872 %} 16873 ins_pipe(vmla128); 16874 %} 16875 16876 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16877 %{ 16878 predicate(n->as_Vector()->length() == 2); 16879 match(Set dst (SubVI dst (MulVI src1 src2))); 16880 ins_cost(INSN_COST); 16881 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16882 ins_encode %{ 16883 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16884 as_FloatRegister($src1$$reg), 16885 as_FloatRegister($src2$$reg)); 16886 %} 16887 ins_pipe(vmla64); 16888 %} 16889 16890 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16891 %{ 16892 predicate(n->as_Vector()->length() == 4); 16893 match(Set dst (SubVI dst (MulVI src1 src2))); 16894 ins_cost(INSN_COST); 16895 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16896 ins_encode %{ 16897 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16898 as_FloatRegister($src1$$reg), 16899 as_FloatRegister($src2$$reg)); 16900 %} 16901 ins_pipe(vmla128); 16902 %} 16903 16904 // dst - src1 * src2 16905 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16906 predicate(UseFMA && n->as_Vector()->length() == 2); 16907 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16908 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16909 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16910 ins_cost(INSN_COST); 16911 ins_encode %{ 16912 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16913 as_FloatRegister($src1$$reg), 16914 as_FloatRegister($src2$$reg)); 16915 %} 16916 ins_pipe(vmuldiv_fp64); 16917 %} 16918 16919 // dst - src1 * src2 16920 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16921 predicate(UseFMA && n->as_Vector()->length() == 4); 16922 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16923 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16924 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16925 ins_cost(INSN_COST); 16926 ins_encode %{ 16927 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16928 as_FloatRegister($src1$$reg), 16929 as_FloatRegister($src2$$reg)); 16930 %} 16931 ins_pipe(vmuldiv_fp128); 16932 %} 16933 16934 // dst - src1 * src2 16935 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16936 predicate(UseFMA && n->as_Vector()->length() == 2); 16937 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16938 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16939 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16940 ins_cost(INSN_COST); 16941 ins_encode %{ 16942 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16943 as_FloatRegister($src1$$reg), 16944 as_FloatRegister($src2$$reg)); 16945 %} 16946 ins_pipe(vmuldiv_fp128); 16947 %} 16948 16949 // --------------- Vector Multiply-Add Shorts into Integer -------------------- 16950 16951 instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 16952 predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 16953 match(Set dst (MulAddVS2VI src1 src2)); 16954 ins_cost(INSN_COST); 16955 effect(TEMP_DEF dst, TEMP tmp); 16956 format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" 16957 "smullv $dst, $src1, $src2\t# vector (8H)\n\t" 16958 "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} 16959 ins_encode %{ 16960 __ smullv(as_FloatRegister($tmp$$reg), __ T4H, 16961 as_FloatRegister($src1$$reg), 16962 as_FloatRegister($src2$$reg)); 16963 __ smullv(as_FloatRegister($dst$$reg), __ T8H, 16964 as_FloatRegister($src1$$reg), 16965 as_FloatRegister($src2$$reg)); 16966 __ addpv(as_FloatRegister($dst$$reg), __ T4S, 16967 as_FloatRegister($tmp$$reg), 16968 as_FloatRegister($dst$$reg)); 16969 %} 16970 ins_pipe(vmuldiv_fp128); 16971 %} 16972 16973 // --------------------------------- DIV -------------------------------------- 16974 16975 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16976 %{ 16977 predicate(n->as_Vector()->length() == 2); 16978 match(Set dst (DivVF src1 src2)); 16979 ins_cost(INSN_COST); 16980 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16981 ins_encode %{ 16982 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16983 as_FloatRegister($src1$$reg), 16984 as_FloatRegister($src2$$reg)); 16985 %} 16986 ins_pipe(vmuldiv_fp64); 16987 %} 16988 16989 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16990 %{ 16991 predicate(n->as_Vector()->length() == 4); 16992 match(Set dst (DivVF src1 src2)); 16993 ins_cost(INSN_COST); 16994 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16995 ins_encode %{ 16996 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16997 as_FloatRegister($src1$$reg), 16998 as_FloatRegister($src2$$reg)); 16999 %} 17000 ins_pipe(vmuldiv_fp128); 17001 %} 17002 17003 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17004 %{ 17005 predicate(n->as_Vector()->length() == 2); 17006 match(Set dst (DivVD src1 src2)); 17007 ins_cost(INSN_COST); 17008 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17009 ins_encode %{ 17010 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17011 as_FloatRegister($src1$$reg), 17012 as_FloatRegister($src2$$reg)); 17013 %} 17014 ins_pipe(vmuldiv_fp128); 17015 %} 17016 17017 // --------------------------------- SQRT ------------------------------------- 17018 17019 instruct vsqrt2F(vecD dst, vecD src) 17020 %{ 17021 predicate(n->as_Vector()->length() == 2); 17022 match(Set dst (SqrtVF src)); 17023 format %{ "fsqrt $dst, $src\t# vector (2F)" %} 17024 ins_encode %{ 17025 __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17026 %} 17027 ins_pipe(vunop_fp64); 17028 %} 17029 17030 instruct vsqrt4F(vecX dst, vecX src) 17031 %{ 17032 predicate(n->as_Vector()->length() == 4); 17033 match(Set dst (SqrtVF src)); 17034 format %{ "fsqrt $dst, $src\t# vector (4F)" %} 17035 ins_encode %{ 17036 __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17037 %} 17038 ins_pipe(vsqrt_fp128); 17039 %} 17040 17041 instruct vsqrt2D(vecX dst, vecX src) 17042 %{ 17043 predicate(n->as_Vector()->length() == 2); 17044 match(Set dst (SqrtVD src)); 17045 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17046 ins_encode %{ 17047 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17048 as_FloatRegister($src$$reg)); 17049 %} 17050 ins_pipe(vsqrt_fp128); 17051 %} 17052 17053 // --------------------------------- ABS -------------------------------------- 17054 17055 instruct vabs8B(vecD dst, vecD src) 17056 %{ 17057 predicate(n->as_Vector()->length() == 4 || 17058 n->as_Vector()->length() == 8); 17059 match(Set dst (AbsVB src)); 17060 ins_cost(INSN_COST); 17061 format %{ "abs $dst, $src\t# vector (8B)" %} 17062 ins_encode %{ 17063 __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); 17064 %} 17065 ins_pipe(vlogical64); 17066 %} 17067 17068 instruct vabs16B(vecX dst, vecX src) 17069 %{ 17070 predicate(n->as_Vector()->length() == 16); 17071 match(Set dst (AbsVB src)); 17072 ins_cost(INSN_COST); 17073 format %{ "abs $dst, $src\t# vector (16B)" %} 17074 ins_encode %{ 17075 __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); 17076 %} 17077 ins_pipe(vlogical128); 17078 %} 17079 17080 instruct vabs4S(vecD dst, vecD src) 17081 %{ 17082 predicate(n->as_Vector()->length() == 4); 17083 match(Set dst (AbsVS src)); 17084 ins_cost(INSN_COST); 17085 format %{ "abs $dst, $src\t# vector (4H)" %} 17086 ins_encode %{ 17087 __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg)); 17088 %} 17089 ins_pipe(vlogical64); 17090 %} 17091 17092 instruct vabs8S(vecX dst, vecX src) 17093 %{ 17094 predicate(n->as_Vector()->length() == 8); 17095 match(Set dst (AbsVS src)); 17096 ins_cost(INSN_COST); 17097 format %{ "abs $dst, $src\t# vector (8H)" %} 17098 ins_encode %{ 17099 __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg)); 17100 %} 17101 ins_pipe(vlogical128); 17102 %} 17103 17104 instruct vabs2I(vecD dst, vecD src) 17105 %{ 17106 predicate(n->as_Vector()->length() == 2); 17107 match(Set dst (AbsVI src)); 17108 ins_cost(INSN_COST); 17109 format %{ "abs $dst, $src\t# vector (2S)" %} 17110 ins_encode %{ 17111 __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 17112 %} 17113 ins_pipe(vlogical64); 17114 %} 17115 17116 instruct vabs4I(vecX dst, vecX src) 17117 %{ 17118 predicate(n->as_Vector()->length() == 4); 17119 match(Set dst (AbsVI src)); 17120 ins_cost(INSN_COST); 17121 format %{ "abs $dst, $src\t# vector (4S)" %} 17122 ins_encode %{ 17123 __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 17124 %} 17125 ins_pipe(vlogical128); 17126 %} 17127 17128 instruct vabs2L(vecX dst, vecX src) 17129 %{ 17130 predicate(n->as_Vector()->length() == 2); 17131 match(Set dst (AbsVL src)); 17132 ins_cost(INSN_COST); 17133 format %{ "abs $dst, $src\t# vector (2D)" %} 17134 ins_encode %{ 17135 __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); 17136 %} 17137 ins_pipe(vlogical128); 17138 %} 17139 17140 instruct vabs2F(vecD dst, vecD src) 17141 %{ 17142 predicate(n->as_Vector()->length() == 2); 17143 match(Set dst (AbsVF src)); 17144 ins_cost(INSN_COST * 3); 17145 format %{ "fabs $dst,$src\t# vector (2S)" %} 17146 ins_encode %{ 17147 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 17148 as_FloatRegister($src$$reg)); 17149 %} 17150 ins_pipe(vunop_fp64); 17151 %} 17152 17153 instruct vabs4F(vecX dst, vecX src) 17154 %{ 17155 predicate(n->as_Vector()->length() == 4); 17156 match(Set dst (AbsVF src)); 17157 ins_cost(INSN_COST * 3); 17158 format %{ "fabs $dst,$src\t# vector (4S)" %} 17159 ins_encode %{ 17160 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 17161 as_FloatRegister($src$$reg)); 17162 %} 17163 ins_pipe(vunop_fp128); 17164 %} 17165 17166 instruct vabs2D(vecX dst, vecX src) 17167 %{ 17168 predicate(n->as_Vector()->length() == 2); 17169 match(Set dst (AbsVD src)); 17170 ins_cost(INSN_COST * 3); 17171 format %{ "fabs $dst,$src\t# vector (2D)" %} 17172 ins_encode %{ 17173 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17174 as_FloatRegister($src$$reg)); 17175 %} 17176 ins_pipe(vunop_fp128); 17177 %} 17178 17179 // --------------------------------- NEG -------------------------------------- 17180 17181 instruct vneg2F(vecD dst, vecD src) 17182 %{ 17183 predicate(n->as_Vector()->length() == 2); 17184 match(Set dst (NegVF src)); 17185 ins_cost(INSN_COST * 3); 17186 format %{ "fneg $dst,$src\t# vector (2S)" %} 17187 ins_encode %{ 17188 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17189 as_FloatRegister($src$$reg)); 17190 %} 17191 ins_pipe(vunop_fp64); 17192 %} 17193 17194 instruct vneg4F(vecX dst, vecX src) 17195 %{ 17196 predicate(n->as_Vector()->length() == 4); 17197 match(Set dst (NegVF src)); 17198 ins_cost(INSN_COST * 3); 17199 format %{ "fneg $dst,$src\t# vector (4S)" %} 17200 ins_encode %{ 17201 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17202 as_FloatRegister($src$$reg)); 17203 %} 17204 ins_pipe(vunop_fp128); 17205 %} 17206 17207 instruct vneg2D(vecX dst, vecX src) 17208 %{ 17209 predicate(n->as_Vector()->length() == 2); 17210 match(Set dst (NegVD src)); 17211 ins_cost(INSN_COST * 3); 17212 format %{ "fneg $dst,$src\t# vector (2D)" %} 17213 ins_encode %{ 17214 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17215 as_FloatRegister($src$$reg)); 17216 %} 17217 ins_pipe(vunop_fp128); 17218 %} 17219 17220 // --------------------------------- AND -------------------------------------- 17221 17222 instruct vand8B(vecD dst, vecD src1, vecD src2) 17223 %{ 17224 predicate(n->as_Vector()->length_in_bytes() == 4 || 17225 n->as_Vector()->length_in_bytes() == 8); 17226 match(Set dst (AndV src1 src2)); 17227 ins_cost(INSN_COST); 17228 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17229 ins_encode %{ 17230 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17231 as_FloatRegister($src1$$reg), 17232 as_FloatRegister($src2$$reg)); 17233 %} 17234 ins_pipe(vlogical64); 17235 %} 17236 17237 instruct vand16B(vecX dst, vecX src1, vecX src2) 17238 %{ 17239 predicate(n->as_Vector()->length_in_bytes() == 16); 17240 match(Set dst (AndV src1 src2)); 17241 ins_cost(INSN_COST); 17242 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17243 ins_encode %{ 17244 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17245 as_FloatRegister($src1$$reg), 17246 as_FloatRegister($src2$$reg)); 17247 %} 17248 ins_pipe(vlogical128); 17249 %} 17250 17251 // --------------------------------- OR --------------------------------------- 17252 17253 instruct vor8B(vecD dst, vecD src1, vecD src2) 17254 %{ 17255 predicate(n->as_Vector()->length_in_bytes() == 4 || 17256 n->as_Vector()->length_in_bytes() == 8); 17257 match(Set dst (OrV src1 src2)); 17258 ins_cost(INSN_COST); 17259 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17260 ins_encode %{ 17261 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17262 as_FloatRegister($src1$$reg), 17263 as_FloatRegister($src2$$reg)); 17264 %} 17265 ins_pipe(vlogical64); 17266 %} 17267 17268 instruct vor16B(vecX dst, vecX src1, vecX src2) 17269 %{ 17270 predicate(n->as_Vector()->length_in_bytes() == 16); 17271 match(Set dst (OrV src1 src2)); 17272 ins_cost(INSN_COST); 17273 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17274 ins_encode %{ 17275 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17276 as_FloatRegister($src1$$reg), 17277 as_FloatRegister($src2$$reg)); 17278 %} 17279 ins_pipe(vlogical128); 17280 %} 17281 17282 // --------------------------------- XOR -------------------------------------- 17283 17284 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17285 %{ 17286 predicate(n->as_Vector()->length_in_bytes() == 4 || 17287 n->as_Vector()->length_in_bytes() == 8); 17288 match(Set dst (XorV src1 src2)); 17289 ins_cost(INSN_COST); 17290 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17291 ins_encode %{ 17292 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17293 as_FloatRegister($src1$$reg), 17294 as_FloatRegister($src2$$reg)); 17295 %} 17296 ins_pipe(vlogical64); 17297 %} 17298 17299 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17300 %{ 17301 predicate(n->as_Vector()->length_in_bytes() == 16); 17302 match(Set dst (XorV src1 src2)); 17303 ins_cost(INSN_COST); 17304 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17305 ins_encode %{ 17306 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17307 as_FloatRegister($src1$$reg), 17308 as_FloatRegister($src2$$reg)); 17309 %} 17310 ins_pipe(vlogical128); 17311 %} 17312 17313 // ------------------------------ Shift --------------------------------------- 17314 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17315 predicate(n->as_Vector()->length_in_bytes() == 8); 17316 match(Set dst (LShiftCntV cnt)); 17317 match(Set dst (RShiftCntV cnt)); 17318 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17319 ins_encode %{ 17320 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17321 %} 17322 ins_pipe(vdup_reg_reg64); 17323 %} 17324 17325 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17326 predicate(n->as_Vector()->length_in_bytes() == 16); 17327 match(Set dst (LShiftCntV cnt)); 17328 match(Set dst (RShiftCntV cnt)); 17329 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17330 ins_encode %{ 17331 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17332 %} 17333 ins_pipe(vdup_reg_reg128); 17334 %} 17335 17336 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17337 predicate(n->as_Vector()->length() == 4 || 17338 n->as_Vector()->length() == 8); 17339 match(Set dst (LShiftVB src shift)); 17340 ins_cost(INSN_COST); 17341 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17342 ins_encode %{ 17343 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17344 as_FloatRegister($src$$reg), 17345 as_FloatRegister($shift$$reg)); 17346 %} 17347 ins_pipe(vshift64); 17348 %} 17349 17350 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17351 predicate(n->as_Vector()->length() == 16); 17352 match(Set dst (LShiftVB src shift)); 17353 ins_cost(INSN_COST); 17354 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17355 ins_encode %{ 17356 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17357 as_FloatRegister($src$$reg), 17358 as_FloatRegister($shift$$reg)); 17359 %} 17360 ins_pipe(vshift128); 17361 %} 17362 17363 // Right shifts with vector shift count on aarch64 SIMD are implemented 17364 // as left shift by negative shift count. 17365 // There are two cases for vector shift count. 17366 // 17367 // Case 1: The vector shift count is from replication. 17368 // | | 17369 // LoadVector RShiftCntV 17370 // | / 17371 // RShiftVI 17372 // Note: In inner loop, multiple neg instructions are used, which can be 17373 // moved to outer loop and merge into one neg instruction. 17374 // 17375 // Case 2: The vector shift count is from loading. 17376 // This case isn't supported by middle-end now. But it's supported by 17377 // panama/vectorIntrinsics(JEP 338: Vector API). 17378 // | | 17379 // LoadVector LoadVector 17380 // | / 17381 // RShiftVI 17382 // 17383 17384 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17385 predicate(n->as_Vector()->length() == 4 || 17386 n->as_Vector()->length() == 8); 17387 match(Set dst (RShiftVB src shift)); 17388 ins_cost(INSN_COST); 17389 effect(TEMP tmp); 17390 format %{ "negr $tmp,$shift\t" 17391 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17392 ins_encode %{ 17393 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17394 as_FloatRegister($shift$$reg)); 17395 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17396 as_FloatRegister($src$$reg), 17397 as_FloatRegister($tmp$$reg)); 17398 %} 17399 ins_pipe(vshift64); 17400 %} 17401 17402 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17403 predicate(n->as_Vector()->length() == 16); 17404 match(Set dst (RShiftVB src shift)); 17405 ins_cost(INSN_COST); 17406 effect(TEMP tmp); 17407 format %{ "negr $tmp,$shift\t" 17408 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17409 ins_encode %{ 17410 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17411 as_FloatRegister($shift$$reg)); 17412 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17413 as_FloatRegister($src$$reg), 17414 as_FloatRegister($tmp$$reg)); 17415 %} 17416 ins_pipe(vshift128); 17417 %} 17418 17419 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17420 predicate(n->as_Vector()->length() == 4 || 17421 n->as_Vector()->length() == 8); 17422 match(Set dst (URShiftVB src shift)); 17423 ins_cost(INSN_COST); 17424 effect(TEMP tmp); 17425 format %{ "negr $tmp,$shift\t" 17426 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17427 ins_encode %{ 17428 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17429 as_FloatRegister($shift$$reg)); 17430 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17431 as_FloatRegister($src$$reg), 17432 as_FloatRegister($tmp$$reg)); 17433 %} 17434 ins_pipe(vshift64); 17435 %} 17436 17437 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17438 predicate(n->as_Vector()->length() == 16); 17439 match(Set dst (URShiftVB src shift)); 17440 ins_cost(INSN_COST); 17441 effect(TEMP tmp); 17442 format %{ "negr $tmp,$shift\t" 17443 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17444 ins_encode %{ 17445 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17446 as_FloatRegister($shift$$reg)); 17447 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17448 as_FloatRegister($src$$reg), 17449 as_FloatRegister($tmp$$reg)); 17450 %} 17451 ins_pipe(vshift128); 17452 %} 17453 17454 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17455 predicate(n->as_Vector()->length() == 4 || 17456 n->as_Vector()->length() == 8); 17457 match(Set dst (LShiftVB src (LShiftCntV shift))); 17458 ins_cost(INSN_COST); 17459 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17460 ins_encode %{ 17461 int sh = (int)$shift$$constant; 17462 if (sh >= 8) { 17463 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17464 as_FloatRegister($src$$reg), 17465 as_FloatRegister($src$$reg)); 17466 } else { 17467 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17468 as_FloatRegister($src$$reg), sh); 17469 } 17470 %} 17471 ins_pipe(vshift64_imm); 17472 %} 17473 17474 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17475 predicate(n->as_Vector()->length() == 16); 17476 match(Set dst (LShiftVB src (LShiftCntV shift))); 17477 ins_cost(INSN_COST); 17478 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17479 ins_encode %{ 17480 int sh = (int)$shift$$constant; 17481 if (sh >= 8) { 17482 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17483 as_FloatRegister($src$$reg), 17484 as_FloatRegister($src$$reg)); 17485 } else { 17486 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17487 as_FloatRegister($src$$reg), sh); 17488 } 17489 %} 17490 ins_pipe(vshift128_imm); 17491 %} 17492 17493 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17494 predicate(n->as_Vector()->length() == 4 || 17495 n->as_Vector()->length() == 8); 17496 match(Set dst (RShiftVB src (RShiftCntV shift))); 17497 ins_cost(INSN_COST); 17498 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17499 ins_encode %{ 17500 int sh = (int)$shift$$constant; 17501 if (sh >= 8) sh = 7; 17502 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17503 as_FloatRegister($src$$reg), sh); 17504 %} 17505 ins_pipe(vshift64_imm); 17506 %} 17507 17508 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17509 predicate(n->as_Vector()->length() == 16); 17510 match(Set dst (RShiftVB src (RShiftCntV shift))); 17511 ins_cost(INSN_COST); 17512 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17513 ins_encode %{ 17514 int sh = (int)$shift$$constant; 17515 if (sh >= 8) sh = 7; 17516 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17517 as_FloatRegister($src$$reg), sh); 17518 %} 17519 ins_pipe(vshift128_imm); 17520 %} 17521 17522 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17523 predicate(n->as_Vector()->length() == 4 || 17524 n->as_Vector()->length() == 8); 17525 match(Set dst (URShiftVB src (RShiftCntV shift))); 17526 ins_cost(INSN_COST); 17527 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17528 ins_encode %{ 17529 int sh = (int)$shift$$constant; 17530 if (sh >= 8) { 17531 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17532 as_FloatRegister($src$$reg), 17533 as_FloatRegister($src$$reg)); 17534 } else { 17535 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17536 as_FloatRegister($src$$reg), sh); 17537 } 17538 %} 17539 ins_pipe(vshift64_imm); 17540 %} 17541 17542 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17543 predicate(n->as_Vector()->length() == 16); 17544 match(Set dst (URShiftVB src (RShiftCntV shift))); 17545 ins_cost(INSN_COST); 17546 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17547 ins_encode %{ 17548 int sh = (int)$shift$$constant; 17549 if (sh >= 8) { 17550 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17551 as_FloatRegister($src$$reg), 17552 as_FloatRegister($src$$reg)); 17553 } else { 17554 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17555 as_FloatRegister($src$$reg), sh); 17556 } 17557 %} 17558 ins_pipe(vshift128_imm); 17559 %} 17560 17561 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17562 predicate(n->as_Vector()->length() == 2 || 17563 n->as_Vector()->length() == 4); 17564 match(Set dst (LShiftVS src shift)); 17565 ins_cost(INSN_COST); 17566 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17567 ins_encode %{ 17568 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17569 as_FloatRegister($src$$reg), 17570 as_FloatRegister($shift$$reg)); 17571 %} 17572 ins_pipe(vshift64); 17573 %} 17574 17575 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17576 predicate(n->as_Vector()->length() == 8); 17577 match(Set dst (LShiftVS src shift)); 17578 ins_cost(INSN_COST); 17579 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17580 ins_encode %{ 17581 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17582 as_FloatRegister($src$$reg), 17583 as_FloatRegister($shift$$reg)); 17584 %} 17585 ins_pipe(vshift128); 17586 %} 17587 17588 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17589 predicate(n->as_Vector()->length() == 2 || 17590 n->as_Vector()->length() == 4); 17591 match(Set dst (RShiftVS src shift)); 17592 ins_cost(INSN_COST); 17593 effect(TEMP tmp); 17594 format %{ "negr $tmp,$shift\t" 17595 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17596 ins_encode %{ 17597 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17598 as_FloatRegister($shift$$reg)); 17599 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17600 as_FloatRegister($src$$reg), 17601 as_FloatRegister($tmp$$reg)); 17602 %} 17603 ins_pipe(vshift64); 17604 %} 17605 17606 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17607 predicate(n->as_Vector()->length() == 8); 17608 match(Set dst (RShiftVS src shift)); 17609 ins_cost(INSN_COST); 17610 effect(TEMP tmp); 17611 format %{ "negr $tmp,$shift\t" 17612 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17613 ins_encode %{ 17614 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17615 as_FloatRegister($shift$$reg)); 17616 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17617 as_FloatRegister($src$$reg), 17618 as_FloatRegister($tmp$$reg)); 17619 %} 17620 ins_pipe(vshift128); 17621 %} 17622 17623 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17624 predicate(n->as_Vector()->length() == 2 || 17625 n->as_Vector()->length() == 4); 17626 match(Set dst (URShiftVS src shift)); 17627 ins_cost(INSN_COST); 17628 effect(TEMP tmp); 17629 format %{ "negr $tmp,$shift\t" 17630 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17631 ins_encode %{ 17632 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17633 as_FloatRegister($shift$$reg)); 17634 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17635 as_FloatRegister($src$$reg), 17636 as_FloatRegister($tmp$$reg)); 17637 %} 17638 ins_pipe(vshift64); 17639 %} 17640 17641 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17642 predicate(n->as_Vector()->length() == 8); 17643 match(Set dst (URShiftVS src shift)); 17644 ins_cost(INSN_COST); 17645 effect(TEMP tmp); 17646 format %{ "negr $tmp,$shift\t" 17647 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17648 ins_encode %{ 17649 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17650 as_FloatRegister($shift$$reg)); 17651 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17652 as_FloatRegister($src$$reg), 17653 as_FloatRegister($tmp$$reg)); 17654 %} 17655 ins_pipe(vshift128); 17656 %} 17657 17658 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17659 predicate(n->as_Vector()->length() == 2 || 17660 n->as_Vector()->length() == 4); 17661 match(Set dst (LShiftVS src (LShiftCntV shift))); 17662 ins_cost(INSN_COST); 17663 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17664 ins_encode %{ 17665 int sh = (int)$shift$$constant; 17666 if (sh >= 16) { 17667 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17668 as_FloatRegister($src$$reg), 17669 as_FloatRegister($src$$reg)); 17670 } else { 17671 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17672 as_FloatRegister($src$$reg), sh); 17673 } 17674 %} 17675 ins_pipe(vshift64_imm); 17676 %} 17677 17678 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17679 predicate(n->as_Vector()->length() == 8); 17680 match(Set dst (LShiftVS src (LShiftCntV shift))); 17681 ins_cost(INSN_COST); 17682 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17683 ins_encode %{ 17684 int sh = (int)$shift$$constant; 17685 if (sh >= 16) { 17686 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17687 as_FloatRegister($src$$reg), 17688 as_FloatRegister($src$$reg)); 17689 } else { 17690 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17691 as_FloatRegister($src$$reg), sh); 17692 } 17693 %} 17694 ins_pipe(vshift128_imm); 17695 %} 17696 17697 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17698 predicate(n->as_Vector()->length() == 2 || 17699 n->as_Vector()->length() == 4); 17700 match(Set dst (RShiftVS src (RShiftCntV shift))); 17701 ins_cost(INSN_COST); 17702 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17703 ins_encode %{ 17704 int sh = (int)$shift$$constant; 17705 if (sh >= 16) sh = 15; 17706 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17707 as_FloatRegister($src$$reg), sh); 17708 %} 17709 ins_pipe(vshift64_imm); 17710 %} 17711 17712 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17713 predicate(n->as_Vector()->length() == 8); 17714 match(Set dst (RShiftVS src (RShiftCntV shift))); 17715 ins_cost(INSN_COST); 17716 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17717 ins_encode %{ 17718 int sh = (int)$shift$$constant; 17719 if (sh >= 16) sh = 15; 17720 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17721 as_FloatRegister($src$$reg), sh); 17722 %} 17723 ins_pipe(vshift128_imm); 17724 %} 17725 17726 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17727 predicate(n->as_Vector()->length() == 2 || 17728 n->as_Vector()->length() == 4); 17729 match(Set dst (URShiftVS src (RShiftCntV shift))); 17730 ins_cost(INSN_COST); 17731 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17732 ins_encode %{ 17733 int sh = (int)$shift$$constant; 17734 if (sh >= 16) { 17735 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17736 as_FloatRegister($src$$reg), 17737 as_FloatRegister($src$$reg)); 17738 } else { 17739 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17740 as_FloatRegister($src$$reg), sh); 17741 } 17742 %} 17743 ins_pipe(vshift64_imm); 17744 %} 17745 17746 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17747 predicate(n->as_Vector()->length() == 8); 17748 match(Set dst (URShiftVS src (RShiftCntV shift))); 17749 ins_cost(INSN_COST); 17750 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17751 ins_encode %{ 17752 int sh = (int)$shift$$constant; 17753 if (sh >= 16) { 17754 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17755 as_FloatRegister($src$$reg), 17756 as_FloatRegister($src$$reg)); 17757 } else { 17758 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17759 as_FloatRegister($src$$reg), sh); 17760 } 17761 %} 17762 ins_pipe(vshift128_imm); 17763 %} 17764 17765 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17766 predicate(n->as_Vector()->length() == 2); 17767 match(Set dst (LShiftVI src shift)); 17768 ins_cost(INSN_COST); 17769 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17770 ins_encode %{ 17771 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17772 as_FloatRegister($src$$reg), 17773 as_FloatRegister($shift$$reg)); 17774 %} 17775 ins_pipe(vshift64); 17776 %} 17777 17778 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17779 predicate(n->as_Vector()->length() == 4); 17780 match(Set dst (LShiftVI src shift)); 17781 ins_cost(INSN_COST); 17782 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17783 ins_encode %{ 17784 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17785 as_FloatRegister($src$$reg), 17786 as_FloatRegister($shift$$reg)); 17787 %} 17788 ins_pipe(vshift128); 17789 %} 17790 17791 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17792 predicate(n->as_Vector()->length() == 2); 17793 match(Set dst (RShiftVI src shift)); 17794 ins_cost(INSN_COST); 17795 effect(TEMP tmp); 17796 format %{ "negr $tmp,$shift\t" 17797 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17798 ins_encode %{ 17799 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17800 as_FloatRegister($shift$$reg)); 17801 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17802 as_FloatRegister($src$$reg), 17803 as_FloatRegister($tmp$$reg)); 17804 %} 17805 ins_pipe(vshift64); 17806 %} 17807 17808 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17809 predicate(n->as_Vector()->length() == 4); 17810 match(Set dst (RShiftVI src shift)); 17811 ins_cost(INSN_COST); 17812 effect(TEMP tmp); 17813 format %{ "negr $tmp,$shift\t" 17814 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17815 ins_encode %{ 17816 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17817 as_FloatRegister($shift$$reg)); 17818 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17819 as_FloatRegister($src$$reg), 17820 as_FloatRegister($tmp$$reg)); 17821 %} 17822 ins_pipe(vshift128); 17823 %} 17824 17825 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17826 predicate(n->as_Vector()->length() == 2); 17827 match(Set dst (URShiftVI src shift)); 17828 ins_cost(INSN_COST); 17829 effect(TEMP tmp); 17830 format %{ "negr $tmp,$shift\t" 17831 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17832 ins_encode %{ 17833 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17834 as_FloatRegister($shift$$reg)); 17835 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17836 as_FloatRegister($src$$reg), 17837 as_FloatRegister($tmp$$reg)); 17838 %} 17839 ins_pipe(vshift64); 17840 %} 17841 17842 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17843 predicate(n->as_Vector()->length() == 4); 17844 match(Set dst (URShiftVI src shift)); 17845 ins_cost(INSN_COST); 17846 effect(TEMP tmp); 17847 format %{ "negr $tmp,$shift\t" 17848 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17849 ins_encode %{ 17850 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17851 as_FloatRegister($shift$$reg)); 17852 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17853 as_FloatRegister($src$$reg), 17854 as_FloatRegister($tmp$$reg)); 17855 %} 17856 ins_pipe(vshift128); 17857 %} 17858 17859 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17860 predicate(n->as_Vector()->length() == 2); 17861 match(Set dst (LShiftVI src (LShiftCntV shift))); 17862 ins_cost(INSN_COST); 17863 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17864 ins_encode %{ 17865 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17866 as_FloatRegister($src$$reg), 17867 (int)$shift$$constant); 17868 %} 17869 ins_pipe(vshift64_imm); 17870 %} 17871 17872 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17873 predicate(n->as_Vector()->length() == 4); 17874 match(Set dst (LShiftVI src (LShiftCntV shift))); 17875 ins_cost(INSN_COST); 17876 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17877 ins_encode %{ 17878 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17879 as_FloatRegister($src$$reg), 17880 (int)$shift$$constant); 17881 %} 17882 ins_pipe(vshift128_imm); 17883 %} 17884 17885 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17886 predicate(n->as_Vector()->length() == 2); 17887 match(Set dst (RShiftVI src (RShiftCntV shift))); 17888 ins_cost(INSN_COST); 17889 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17890 ins_encode %{ 17891 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17892 as_FloatRegister($src$$reg), 17893 (int)$shift$$constant); 17894 %} 17895 ins_pipe(vshift64_imm); 17896 %} 17897 17898 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17899 predicate(n->as_Vector()->length() == 4); 17900 match(Set dst (RShiftVI src (RShiftCntV shift))); 17901 ins_cost(INSN_COST); 17902 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17903 ins_encode %{ 17904 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17905 as_FloatRegister($src$$reg), 17906 (int)$shift$$constant); 17907 %} 17908 ins_pipe(vshift128_imm); 17909 %} 17910 17911 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17912 predicate(n->as_Vector()->length() == 2); 17913 match(Set dst (URShiftVI src (RShiftCntV shift))); 17914 ins_cost(INSN_COST); 17915 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17916 ins_encode %{ 17917 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17918 as_FloatRegister($src$$reg), 17919 (int)$shift$$constant); 17920 %} 17921 ins_pipe(vshift64_imm); 17922 %} 17923 17924 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17925 predicate(n->as_Vector()->length() == 4); 17926 match(Set dst (URShiftVI src (RShiftCntV shift))); 17927 ins_cost(INSN_COST); 17928 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17929 ins_encode %{ 17930 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17931 as_FloatRegister($src$$reg), 17932 (int)$shift$$constant); 17933 %} 17934 ins_pipe(vshift128_imm); 17935 %} 17936 17937 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17938 predicate(n->as_Vector()->length() == 2); 17939 match(Set dst (LShiftVL src shift)); 17940 ins_cost(INSN_COST); 17941 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17942 ins_encode %{ 17943 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17944 as_FloatRegister($src$$reg), 17945 as_FloatRegister($shift$$reg)); 17946 %} 17947 ins_pipe(vshift128); 17948 %} 17949 17950 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17951 predicate(n->as_Vector()->length() == 2); 17952 match(Set dst (RShiftVL src shift)); 17953 ins_cost(INSN_COST); 17954 effect(TEMP tmp); 17955 format %{ "negr $tmp,$shift\t" 17956 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17957 ins_encode %{ 17958 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17959 as_FloatRegister($shift$$reg)); 17960 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17961 as_FloatRegister($src$$reg), 17962 as_FloatRegister($tmp$$reg)); 17963 %} 17964 ins_pipe(vshift128); 17965 %} 17966 17967 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17968 predicate(n->as_Vector()->length() == 2); 17969 match(Set dst (URShiftVL src shift)); 17970 ins_cost(INSN_COST); 17971 effect(TEMP tmp); 17972 format %{ "negr $tmp,$shift\t" 17973 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17974 ins_encode %{ 17975 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17976 as_FloatRegister($shift$$reg)); 17977 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17978 as_FloatRegister($src$$reg), 17979 as_FloatRegister($tmp$$reg)); 17980 %} 17981 ins_pipe(vshift128); 17982 %} 17983 17984 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17985 predicate(n->as_Vector()->length() == 2); 17986 match(Set dst (LShiftVL src (LShiftCntV shift))); 17987 ins_cost(INSN_COST); 17988 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17989 ins_encode %{ 17990 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17991 as_FloatRegister($src$$reg), 17992 (int)$shift$$constant); 17993 %} 17994 ins_pipe(vshift128_imm); 17995 %} 17996 17997 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17998 predicate(n->as_Vector()->length() == 2); 17999 match(Set dst (RShiftVL src (RShiftCntV shift))); 18000 ins_cost(INSN_COST); 18001 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 18002 ins_encode %{ 18003 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 18004 as_FloatRegister($src$$reg), 18005 (int)$shift$$constant); 18006 %} 18007 ins_pipe(vshift128_imm); 18008 %} 18009 18010 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 18011 predicate(n->as_Vector()->length() == 2); 18012 match(Set dst (URShiftVL src (RShiftCntV shift))); 18013 ins_cost(INSN_COST); 18014 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 18015 ins_encode %{ 18016 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 18017 as_FloatRegister($src$$reg), 18018 (int)$shift$$constant); 18019 %} 18020 ins_pipe(vshift128_imm); 18021 %} 18022 18023 instruct vmax2F(vecD dst, vecD src1, vecD src2) 18024 %{ 18025 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18026 match(Set dst (MaxV src1 src2)); 18027 ins_cost(INSN_COST); 18028 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 18029 ins_encode %{ 18030 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 18031 as_FloatRegister($src1$$reg), 18032 as_FloatRegister($src2$$reg)); 18033 %} 18034 ins_pipe(vdop_fp64); 18035 %} 18036 18037 instruct vmax4F(vecX dst, vecX src1, vecX src2) 18038 %{ 18039 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18040 match(Set dst (MaxV src1 src2)); 18041 ins_cost(INSN_COST); 18042 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 18043 ins_encode %{ 18044 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 18045 as_FloatRegister($src1$$reg), 18046 as_FloatRegister($src2$$reg)); 18047 %} 18048 ins_pipe(vdop_fp128); 18049 %} 18050 18051 instruct vmax2D(vecX dst, vecX src1, vecX src2) 18052 %{ 18053 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18054 match(Set dst (MaxV src1 src2)); 18055 ins_cost(INSN_COST); 18056 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 18057 ins_encode %{ 18058 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 18059 as_FloatRegister($src1$$reg), 18060 as_FloatRegister($src2$$reg)); 18061 %} 18062 ins_pipe(vdop_fp128); 18063 %} 18064 18065 instruct vmin2F(vecD dst, vecD src1, vecD src2) 18066 %{ 18067 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18068 match(Set dst (MinV src1 src2)); 18069 ins_cost(INSN_COST); 18070 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 18071 ins_encode %{ 18072 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 18073 as_FloatRegister($src1$$reg), 18074 as_FloatRegister($src2$$reg)); 18075 %} 18076 ins_pipe(vdop_fp64); 18077 %} 18078 18079 instruct vmin4F(vecX dst, vecX src1, vecX src2) 18080 %{ 18081 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18082 match(Set dst (MinV src1 src2)); 18083 ins_cost(INSN_COST); 18084 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 18085 ins_encode %{ 18086 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 18087 as_FloatRegister($src1$$reg), 18088 as_FloatRegister($src2$$reg)); 18089 %} 18090 ins_pipe(vdop_fp128); 18091 %} 18092 18093 instruct vmin2D(vecX dst, vecX src1, vecX src2) 18094 %{ 18095 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18096 match(Set dst (MinV src1 src2)); 18097 ins_cost(INSN_COST); 18098 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 18099 ins_encode %{ 18100 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 18101 as_FloatRegister($src1$$reg), 18102 as_FloatRegister($src2$$reg)); 18103 %} 18104 ins_pipe(vdop_fp128); 18105 %} 18106 18107 instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ 18108 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18109 match(Set dst (RoundDoubleModeV src rmode)); 18110 format %{ "frint $dst, $src, $rmode" %} 18111 ins_encode %{ 18112 switch ($rmode$$constant) { 18113 case RoundDoubleModeNode::rmode_rint: 18114 __ frintn(as_FloatRegister($dst$$reg), __ T2D, 18115 as_FloatRegister($src$$reg)); 18116 break; 18117 case RoundDoubleModeNode::rmode_floor: 18118 __ frintm(as_FloatRegister($dst$$reg), __ T2D, 18119 as_FloatRegister($src$$reg)); 18120 break; 18121 case RoundDoubleModeNode::rmode_ceil: 18122 __ frintp(as_FloatRegister($dst$$reg), __ T2D, 18123 as_FloatRegister($src$$reg)); 18124 break; 18125 } 18126 %} 18127 ins_pipe(vdop_fp128); 18128 %} 18129 18130 instruct vpopcount4I(vecX dst, vecX src) %{ 18131 predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); 18132 match(Set dst (PopCountVI src)); 18133 format %{ 18134 "cnt $dst, $src\t# vector (16B)\n\t" 18135 "uaddlp $dst, $dst\t# vector (16B)\n\t" 18136 "uaddlp $dst, $dst\t# vector (8H)" 18137 %} 18138 ins_encode %{ 18139 __ cnt(as_FloatRegister($dst$$reg), __ T16B, 18140 as_FloatRegister($src$$reg)); 18141 __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, 18142 as_FloatRegister($dst$$reg)); 18143 __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, 18144 as_FloatRegister($dst$$reg)); 18145 %} 18146 ins_pipe(pipe_class_default); 18147 %} 18148 18149 instruct vpopcount2I(vecD dst, vecD src) %{ 18150 predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); 18151 match(Set dst (PopCountVI src)); 18152 format %{ 18153 "cnt $dst, $src\t# vector (8B)\n\t" 18154 "uaddlp $dst, $dst\t# vector (8B)\n\t" 18155 "uaddlp $dst, $dst\t# vector (4H)" 18156 %} 18157 ins_encode %{ 18158 __ cnt(as_FloatRegister($dst$$reg), __ T8B, 18159 as_FloatRegister($src$$reg)); 18160 __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, 18161 as_FloatRegister($dst$$reg)); 18162 __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, 18163 as_FloatRegister($dst$$reg)); 18164 %} 18165 ins_pipe(pipe_class_default); 18166 %} 18167 18168 //----------PEEPHOLE RULES----------------------------------------------------- 18169 // These must follow all instruction definitions as they use the names 18170 // defined in the instructions definitions. 18171 // 18172 // peepmatch ( root_instr_name [preceding_instruction]* ); 18173 // 18174 // peepconstraint %{ 18175 // (instruction_number.operand_name relational_op instruction_number.operand_name 18176 // [, ...] ); 18177 // // instruction numbers are zero-based using left to right order in peepmatch 18178 // 18179 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18180 // // provide an instruction_number.operand_name for each operand that appears 18181 // // in the replacement instruction's match rule 18182 // 18183 // ---------VM FLAGS--------------------------------------------------------- 18184 // 18185 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18186 // 18187 // Each peephole rule is given an identifying number starting with zero and 18188 // increasing by one in the order seen by the parser. An individual peephole 18189 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18190 // on the command-line. 18191 // 18192 // ---------CURRENT LIMITATIONS---------------------------------------------- 18193 // 18194 // Only match adjacent instructions in same basic block 18195 // Only equality constraints 18196 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18197 // Only one replacement instruction 18198 // 18199 // ---------EXAMPLE---------------------------------------------------------- 18200 // 18201 // // pertinent parts of existing instructions in architecture description 18202 // instruct movI(iRegINoSp dst, iRegI src) 18203 // %{ 18204 // match(Set dst (CopyI src)); 18205 // %} 18206 // 18207 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18208 // %{ 18209 // match(Set dst (AddI dst src)); 18210 // effect(KILL cr); 18211 // %} 18212 // 18213 // // Change (inc mov) to lea 18214 // peephole %{ 18215 // // increment preceeded by register-register move 18216 // peepmatch ( incI_iReg movI ); 18217 // // require that the destination register of the increment 18218 // // match the destination register of the move 18219 // peepconstraint ( 0.dst == 1.dst ); 18220 // // construct a replacement instruction that sets 18221 // // the destination to ( move's source register + one ) 18222 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18223 // %} 18224 // 18225 18226 // Implementation no longer uses movX instructions since 18227 // machine-independent system no longer uses CopyX nodes. 18228 // 18229 // peephole 18230 // %{ 18231 // peepmatch (incI_iReg movI); 18232 // peepconstraint (0.dst == 1.dst); 18233 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18234 // %} 18235 18236 // peephole 18237 // %{ 18238 // peepmatch (decI_iReg movI); 18239 // peepconstraint (0.dst == 1.dst); 18240 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18241 // %} 18242 18243 // peephole 18244 // %{ 18245 // peepmatch (addI_iReg_imm movI); 18246 // peepconstraint (0.dst == 1.dst); 18247 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18248 // %} 18249 18250 // peephole 18251 // %{ 18252 // peepmatch (incL_iReg movL); 18253 // peepconstraint (0.dst == 1.dst); 18254 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18255 // %} 18256 18257 // peephole 18258 // %{ 18259 // peepmatch (decL_iReg movL); 18260 // peepconstraint (0.dst == 1.dst); 18261 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18262 // %} 18263 18264 // peephole 18265 // %{ 18266 // peepmatch (addL_iReg_imm movL); 18267 // peepconstraint (0.dst == 1.dst); 18268 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18269 // %} 18270 18271 // peephole 18272 // %{ 18273 // peepmatch (addP_iReg_imm movP); 18274 // peepconstraint (0.dst == 1.dst); 18275 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18276 // %} 18277 18278 // // Change load of spilled value to only a spill 18279 // instruct storeI(memory mem, iRegI src) 18280 // %{ 18281 // match(Set mem (StoreI mem src)); 18282 // %} 18283 // 18284 // instruct loadI(iRegINoSp dst, memory mem) 18285 // %{ 18286 // match(Set dst (LoadI mem)); 18287 // %} 18288 // 18289 18290 //----------SMARTSPILL RULES--------------------------------------------------- 18291 // These must follow all instruction definitions as they use the names 18292 // defined in the instructions definitions. 18293 18294 // Local Variables: 18295 // mode: c++ 18296 // End: