1 // 2 // Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2020, Red Hat, Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 167 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 168 169 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 170 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 171 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 172 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 173 174 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 175 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 176 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 177 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 178 179 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 180 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 181 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 182 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 183 184 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 185 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 186 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 187 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 188 189 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 190 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 191 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 192 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 193 194 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 195 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 196 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 197 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 198 199 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 200 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 201 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 202 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 203 204 reg_def V8 ( SOC, SOC, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next() ); 206 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 207 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 208 209 reg_def V9 ( SOC, SOC, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next() ); 211 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 212 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 213 214 reg_def V10 ( SOC, SOC, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() ); 216 reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2)); 217 reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3)); 218 219 reg_def V11 ( SOC, SOC, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() ); 221 reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2)); 222 reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3)); 223 224 reg_def V12 ( SOC, SOC, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() ); 226 reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2)); 227 reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3)); 228 229 reg_def V13 ( SOC, SOC, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() ); 231 reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2)); 232 reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3)); 233 234 reg_def V14 ( SOC, SOC, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() ); 236 reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2)); 237 reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3)); 238 239 reg_def V15 ( SOC, SOC, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() ); 241 reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2)); 242 reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3)); 243 244 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 245 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 246 reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2)); 247 reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3)); 248 249 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 250 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 251 reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2)); 252 reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3)); 253 254 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 255 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 256 reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2)); 257 reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3)); 258 259 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 260 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 261 reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2)); 262 reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3)); 263 264 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 265 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 266 reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2)); 267 reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3)); 268 269 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 270 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 271 reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2)); 272 reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3)); 273 274 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 275 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 276 reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2)); 277 reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3)); 278 279 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 280 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 281 reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2)); 282 reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3)); 283 284 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 285 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 286 reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2)); 287 reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3)); 288 289 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 290 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 291 reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2)); 292 reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3)); 293 294 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 295 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 296 reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2)); 297 reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3)); 298 299 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 300 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 301 reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2)); 302 reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3)); 303 304 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 305 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 306 reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2)); 307 reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3)); 308 309 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 310 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 311 reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2)); 312 reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3)); 313 314 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 315 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 316 reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2)); 317 reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3)); 318 319 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 320 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 321 reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2)); 322 reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3)); 323 324 // ---------------------------- 325 // Special Registers 326 // ---------------------------- 327 328 // the AArch64 CSPR status flag register is not directly acessible as 329 // instruction operand. the FPSR status flag register is a system 330 // register which can be written/read using MSR/MRS but again does not 331 // appear as an operand (a code identifying the FSPR occurs as an 332 // immediate value in the instruction). 333 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 335 336 337 // Specify priority of register selection within phases of register 338 // allocation. Highest priority is first. A useful heuristic is to 339 // give registers a low priority when they are required by machine 340 // instructions, like EAX and EDX on I486, and choose no-save registers 341 // before save-on-call, & save-on-call before save-on-entry. Registers 342 // which participate in fixed calling sequences should come last. 343 // Registers which are used as pairs must fall on an even boundary. 344 345 alloc_class chunk0( 346 // volatiles 347 R10, R10_H, 348 R11, R11_H, 349 R12, R12_H, 350 R13, R13_H, 351 R14, R14_H, 352 R15, R15_H, 353 R16, R16_H, 354 R17, R17_H, 355 R18, R18_H, 356 357 // arg registers 358 R0, R0_H, 359 R1, R1_H, 360 R2, R2_H, 361 R3, R3_H, 362 R4, R4_H, 363 R5, R5_H, 364 R6, R6_H, 365 R7, R7_H, 366 367 // non-volatiles 368 R19, R19_H, 369 R20, R20_H, 370 R21, R21_H, 371 R22, R22_H, 372 R23, R23_H, 373 R24, R24_H, 374 R25, R25_H, 375 R26, R26_H, 376 377 // non-allocatable registers 378 379 R27, R27_H, // heapbase 380 R28, R28_H, // thread 381 R29, R29_H, // fp 382 R30, R30_H, // lr 383 R31, R31_H, // sp 384 ); 385 386 alloc_class chunk1( 387 388 // no save 389 V16, V16_H, V16_J, V16_K, 390 V17, V17_H, V17_J, V17_K, 391 V18, V18_H, V18_J, V18_K, 392 V19, V19_H, V19_J, V19_K, 393 V20, V20_H, V20_J, V20_K, 394 V21, V21_H, V21_J, V21_K, 395 V22, V22_H, V22_J, V22_K, 396 V23, V23_H, V23_J, V23_K, 397 V24, V24_H, V24_J, V24_K, 398 V25, V25_H, V25_J, V25_K, 399 V26, V26_H, V26_J, V26_K, 400 V27, V27_H, V27_J, V27_K, 401 V28, V28_H, V28_J, V28_K, 402 V29, V29_H, V29_J, V29_K, 403 V30, V30_H, V30_J, V30_K, 404 V31, V31_H, V31_J, V31_K, 405 406 // arg registers 407 V0, V0_H, V0_J, V0_K, 408 V1, V1_H, V1_J, V1_K, 409 V2, V2_H, V2_J, V2_K, 410 V3, V3_H, V3_J, V3_K, 411 V4, V4_H, V4_J, V4_K, 412 V5, V5_H, V5_J, V5_K, 413 V6, V6_H, V6_J, V6_K, 414 V7, V7_H, V7_J, V7_K, 415 416 // non-volatiles 417 V8, V8_H, V8_J, V8_K, 418 V9, V9_H, V9_J, V9_K, 419 V10, V10_H, V10_J, V10_K, 420 V11, V11_H, V11_J, V11_K, 421 V12, V12_H, V12_J, V12_K, 422 V13, V13_H, V13_J, V13_K, 423 V14, V14_H, V14_J, V14_K, 424 V15, V15_H, V15_J, V15_K, 425 ); 426 427 alloc_class chunk2(RFLAGS); 428 429 //----------Architecture Description Register Classes-------------------------- 430 // Several register classes are automatically defined based upon information in 431 // this architecture description. 432 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 433 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 436 // 437 438 // Class for all 32 bit general purpose registers 439 reg_class all_reg32( 440 R0, 441 R1, 442 R2, 443 R3, 444 R4, 445 R5, 446 R6, 447 R7, 448 R10, 449 R11, 450 R12, 451 R13, 452 R14, 453 R15, 454 R16, 455 R17, 456 R18, 457 R19, 458 R20, 459 R21, 460 R22, 461 R23, 462 R24, 463 R25, 464 R26, 465 R27, 466 R28, 467 R29, 468 R30, 469 R31 470 ); 471 472 473 // Class for all 32 bit integer registers (excluding SP which 474 // will never be used as an integer register) 475 reg_class any_reg32 %{ 476 return _ANY_REG32_mask; 477 %} 478 479 // Singleton class for R0 int register 480 reg_class int_r0_reg(R0); 481 482 // Singleton class for R2 int register 483 reg_class int_r2_reg(R2); 484 485 // Singleton class for R3 int register 486 reg_class int_r3_reg(R3); 487 488 // Singleton class for R4 int register 489 reg_class int_r4_reg(R4); 490 491 // Singleton class for R31 int register 492 reg_class int_r31_reg(R31); 493 494 // Class for all 64 bit general purpose registers 495 reg_class all_reg( 496 R0, R0_H, 497 R1, R1_H, 498 R2, R2_H, 499 R3, R3_H, 500 R4, R4_H, 501 R5, R5_H, 502 R6, R6_H, 503 R7, R7_H, 504 R10, R10_H, 505 R11, R11_H, 506 R12, R12_H, 507 R13, R13_H, 508 R14, R14_H, 509 R15, R15_H, 510 R16, R16_H, 511 R17, R17_H, 512 R18, R18_H, 513 R19, R19_H, 514 R20, R20_H, 515 R21, R21_H, 516 R22, R22_H, 517 R23, R23_H, 518 R24, R24_H, 519 R25, R25_H, 520 R26, R26_H, 521 R27, R27_H, 522 R28, R28_H, 523 R29, R29_H, 524 R30, R30_H, 525 R31, R31_H 526 ); 527 528 // Class for all long integer registers (including SP) 529 reg_class any_reg %{ 530 return _ANY_REG_mask; 531 %} 532 533 // Class for non-allocatable 32 bit registers 534 reg_class non_allocatable_reg32( 535 R28, // thread 536 R30, // lr 537 R31 // sp 538 ); 539 540 // Class for non-allocatable 64 bit registers 541 reg_class non_allocatable_reg( 542 R28, R28_H, // thread 543 R30, R30_H, // lr 544 R31, R31_H // sp 545 ); 546 547 // Class for all non-special integer registers 548 reg_class no_special_reg32 %{ 549 return _NO_SPECIAL_REG32_mask; 550 %} 551 552 // Class for all non-special long integer registers 553 reg_class no_special_reg %{ 554 return _NO_SPECIAL_REG_mask; 555 %} 556 557 // Class for 64 bit register r0 558 reg_class r0_reg( 559 R0, R0_H 560 ); 561 562 // Class for 64 bit register r1 563 reg_class r1_reg( 564 R1, R1_H 565 ); 566 567 // Class for 64 bit register r2 568 reg_class r2_reg( 569 R2, R2_H 570 ); 571 572 // Class for 64 bit register r3 573 reg_class r3_reg( 574 R3, R3_H 575 ); 576 577 // Class for 64 bit register r4 578 reg_class r4_reg( 579 R4, R4_H 580 ); 581 582 // Class for 64 bit register r5 583 reg_class r5_reg( 584 R5, R5_H 585 ); 586 587 // Class for 64 bit register r10 588 reg_class r10_reg( 589 R10, R10_H 590 ); 591 592 // Class for 64 bit register r11 593 reg_class r11_reg( 594 R11, R11_H 595 ); 596 597 // Class for method register 598 reg_class method_reg( 599 R12, R12_H 600 ); 601 602 // Class for heapbase register 603 reg_class heapbase_reg( 604 R27, R27_H 605 ); 606 607 // Class for thread register 608 reg_class thread_reg( 609 R28, R28_H 610 ); 611 612 // Class for frame pointer register 613 reg_class fp_reg( 614 R29, R29_H 615 ); 616 617 // Class for link register 618 reg_class lr_reg( 619 R30, R30_H 620 ); 621 622 // Class for long sp register 623 reg_class sp_reg( 624 R31, R31_H 625 ); 626 627 // Class for all pointer registers 628 reg_class ptr_reg %{ 629 return _PTR_REG_mask; 630 %} 631 632 // Class for all non_special pointer registers 633 reg_class no_special_ptr_reg %{ 634 return _NO_SPECIAL_PTR_REG_mask; 635 %} 636 637 // Class for all float registers 638 reg_class float_reg( 639 V0, 640 V1, 641 V2, 642 V3, 643 V4, 644 V5, 645 V6, 646 V7, 647 V8, 648 V9, 649 V10, 650 V11, 651 V12, 652 V13, 653 V14, 654 V15, 655 V16, 656 V17, 657 V18, 658 V19, 659 V20, 660 V21, 661 V22, 662 V23, 663 V24, 664 V25, 665 V26, 666 V27, 667 V28, 668 V29, 669 V30, 670 V31 671 ); 672 673 // Double precision float registers have virtual `high halves' that 674 // are needed by the allocator. 675 // Class for all double registers 676 reg_class double_reg( 677 V0, V0_H, 678 V1, V1_H, 679 V2, V2_H, 680 V3, V3_H, 681 V4, V4_H, 682 V5, V5_H, 683 V6, V6_H, 684 V7, V7_H, 685 V8, V8_H, 686 V9, V9_H, 687 V10, V10_H, 688 V11, V11_H, 689 V12, V12_H, 690 V13, V13_H, 691 V14, V14_H, 692 V15, V15_H, 693 V16, V16_H, 694 V17, V17_H, 695 V18, V18_H, 696 V19, V19_H, 697 V20, V20_H, 698 V21, V21_H, 699 V22, V22_H, 700 V23, V23_H, 701 V24, V24_H, 702 V25, V25_H, 703 V26, V26_H, 704 V27, V27_H, 705 V28, V28_H, 706 V29, V29_H, 707 V30, V30_H, 708 V31, V31_H 709 ); 710 711 // Class for all 64bit vector registers 712 reg_class vectord_reg( 713 V0, V0_H, 714 V1, V1_H, 715 V2, V2_H, 716 V3, V3_H, 717 V4, V4_H, 718 V5, V5_H, 719 V6, V6_H, 720 V7, V7_H, 721 V8, V8_H, 722 V9, V9_H, 723 V10, V10_H, 724 V11, V11_H, 725 V12, V12_H, 726 V13, V13_H, 727 V14, V14_H, 728 V15, V15_H, 729 V16, V16_H, 730 V17, V17_H, 731 V18, V18_H, 732 V19, V19_H, 733 V20, V20_H, 734 V21, V21_H, 735 V22, V22_H, 736 V23, V23_H, 737 V24, V24_H, 738 V25, V25_H, 739 V26, V26_H, 740 V27, V27_H, 741 V28, V28_H, 742 V29, V29_H, 743 V30, V30_H, 744 V31, V31_H 745 ); 746 747 // Class for all 128bit vector registers 748 reg_class vectorx_reg( 749 V0, V0_H, V0_J, V0_K, 750 V1, V1_H, V1_J, V1_K, 751 V2, V2_H, V2_J, V2_K, 752 V3, V3_H, V3_J, V3_K, 753 V4, V4_H, V4_J, V4_K, 754 V5, V5_H, V5_J, V5_K, 755 V6, V6_H, V6_J, V6_K, 756 V7, V7_H, V7_J, V7_K, 757 V8, V8_H, V8_J, V8_K, 758 V9, V9_H, V9_J, V9_K, 759 V10, V10_H, V10_J, V10_K, 760 V11, V11_H, V11_J, V11_K, 761 V12, V12_H, V12_J, V12_K, 762 V13, V13_H, V13_J, V13_K, 763 V14, V14_H, V14_J, V14_K, 764 V15, V15_H, V15_J, V15_K, 765 V16, V16_H, V16_J, V16_K, 766 V17, V17_H, V17_J, V17_K, 767 V18, V18_H, V18_J, V18_K, 768 V19, V19_H, V19_J, V19_K, 769 V20, V20_H, V20_J, V20_K, 770 V21, V21_H, V21_J, V21_K, 771 V22, V22_H, V22_J, V22_K, 772 V23, V23_H, V23_J, V23_K, 773 V24, V24_H, V24_J, V24_K, 774 V25, V25_H, V25_J, V25_K, 775 V26, V26_H, V26_J, V26_K, 776 V27, V27_H, V27_J, V27_K, 777 V28, V28_H, V28_J, V28_K, 778 V29, V29_H, V29_J, V29_K, 779 V30, V30_H, V30_J, V30_K, 780 V31, V31_H, V31_J, V31_K 781 ); 782 783 // Class for 128 bit register v0 784 reg_class v0_reg( 785 V0, V0_H 786 ); 787 788 // Class for 128 bit register v1 789 reg_class v1_reg( 790 V1, V1_H 791 ); 792 793 // Class for 128 bit register v2 794 reg_class v2_reg( 795 V2, V2_H 796 ); 797 798 // Class for 128 bit register v3 799 reg_class v3_reg( 800 V3, V3_H 801 ); 802 803 // Class for 128 bit register v4 804 reg_class v4_reg( 805 V4, V4_H 806 ); 807 808 // Class for 128 bit register v5 809 reg_class v5_reg( 810 V5, V5_H 811 ); 812 813 // Class for 128 bit register v6 814 reg_class v6_reg( 815 V6, V6_H 816 ); 817 818 // Class for 128 bit register v7 819 reg_class v7_reg( 820 V7, V7_H 821 ); 822 823 // Class for 128 bit register v8 824 reg_class v8_reg( 825 V8, V8_H 826 ); 827 828 // Class for 128 bit register v9 829 reg_class v9_reg( 830 V9, V9_H 831 ); 832 833 // Class for 128 bit register v10 834 reg_class v10_reg( 835 V10, V10_H 836 ); 837 838 // Class for 128 bit register v11 839 reg_class v11_reg( 840 V11, V11_H 841 ); 842 843 // Class for 128 bit register v12 844 reg_class v12_reg( 845 V12, V12_H 846 ); 847 848 // Class for 128 bit register v13 849 reg_class v13_reg( 850 V13, V13_H 851 ); 852 853 // Class for 128 bit register v14 854 reg_class v14_reg( 855 V14, V14_H 856 ); 857 858 // Class for 128 bit register v15 859 reg_class v15_reg( 860 V15, V15_H 861 ); 862 863 // Class for 128 bit register v16 864 reg_class v16_reg( 865 V16, V16_H 866 ); 867 868 // Class for 128 bit register v17 869 reg_class v17_reg( 870 V17, V17_H 871 ); 872 873 // Class for 128 bit register v18 874 reg_class v18_reg( 875 V18, V18_H 876 ); 877 878 // Class for 128 bit register v19 879 reg_class v19_reg( 880 V19, V19_H 881 ); 882 883 // Class for 128 bit register v20 884 reg_class v20_reg( 885 V20, V20_H 886 ); 887 888 // Class for 128 bit register v21 889 reg_class v21_reg( 890 V21, V21_H 891 ); 892 893 // Class for 128 bit register v22 894 reg_class v22_reg( 895 V22, V22_H 896 ); 897 898 // Class for 128 bit register v23 899 reg_class v23_reg( 900 V23, V23_H 901 ); 902 903 // Class for 128 bit register v24 904 reg_class v24_reg( 905 V24, V24_H 906 ); 907 908 // Class for 128 bit register v25 909 reg_class v25_reg( 910 V25, V25_H 911 ); 912 913 // Class for 128 bit register v26 914 reg_class v26_reg( 915 V26, V26_H 916 ); 917 918 // Class for 128 bit register v27 919 reg_class v27_reg( 920 V27, V27_H 921 ); 922 923 // Class for 128 bit register v28 924 reg_class v28_reg( 925 V28, V28_H 926 ); 927 928 // Class for 128 bit register v29 929 reg_class v29_reg( 930 V29, V29_H 931 ); 932 933 // Class for 128 bit register v30 934 reg_class v30_reg( 935 V30, V30_H 936 ); 937 938 // Class for 128 bit register v31 939 reg_class v31_reg( 940 V31, V31_H 941 ); 942 943 // Singleton class for condition codes 944 reg_class int_flags(RFLAGS); 945 946 %} 947 948 //----------DEFINITION BLOCK--------------------------------------------------- 949 // Define name --> value mappings to inform the ADLC of an integer valued name 950 // Current support includes integer values in the range [0, 0x7FFFFFFF] 951 // Format: 952 // int_def <name> ( <int_value>, <expression>); 953 // Generated Code in ad_<arch>.hpp 954 // #define <name> (<expression>) 955 // // value == <int_value> 956 // Generated code in ad_<arch>.cpp adlc_verification() 957 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 958 // 959 960 // we follow the ppc-aix port in using a simple cost model which ranks 961 // register operations as cheap, memory ops as more expensive and 962 // branches as most expensive. the first two have a low as well as a 963 // normal cost. huge cost appears to be a way of saying don't do 964 // something 965 966 definitions %{ 967 // The default cost (of a register move instruction). 968 int_def INSN_COST ( 100, 100); 969 int_def BRANCH_COST ( 200, 2 * INSN_COST); 970 int_def CALL_COST ( 200, 2 * INSN_COST); 971 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 972 %} 973 974 975 //----------SOURCE BLOCK------------------------------------------------------- 976 // This is a block of C++ code which provides values, functions, and 977 // definitions necessary in the rest of the architecture description 978 979 source_hpp %{ 980 981 #include "asm/macroAssembler.hpp" 982 #include "gc/shared/cardTable.hpp" 983 #include "gc/shared/cardTableBarrierSet.hpp" 984 #include "gc/shared/collectedHeap.hpp" 985 #include "opto/addnode.hpp" 986 #include "opto/convertnode.hpp" 987 988 extern RegMask _ANY_REG32_mask; 989 extern RegMask _ANY_REG_mask; 990 extern RegMask _PTR_REG_mask; 991 extern RegMask _NO_SPECIAL_REG32_mask; 992 extern RegMask _NO_SPECIAL_REG_mask; 993 extern RegMask _NO_SPECIAL_PTR_REG_mask; 994 995 class CallStubImpl { 996 997 //-------------------------------------------------------------- 998 //---< Used for optimization in Compile::shorten_branches >--- 999 //-------------------------------------------------------------- 1000 1001 public: 1002 // Size of call trampoline stub. 1003 static uint size_call_trampoline() { 1004 return 0; // no call trampolines on this platform 1005 } 1006 1007 // number of relocations needed by a call trampoline stub 1008 static uint reloc_call_trampoline() { 1009 return 0; // no call trampolines on this platform 1010 } 1011 }; 1012 1013 class HandlerImpl { 1014 1015 public: 1016 1017 static int emit_exception_handler(CodeBuffer &cbuf); 1018 static int emit_deopt_handler(CodeBuffer& cbuf); 1019 1020 static uint size_exception_handler() { 1021 return MacroAssembler::far_branch_size(); 1022 } 1023 1024 static uint size_deopt_handler() { 1025 // count one adr and one far branch instruction 1026 return 4 * NativeInstruction::instruction_size; 1027 } 1028 }; 1029 1030 bool is_CAS(int opcode, bool maybe_volatile); 1031 1032 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1033 1034 bool unnecessary_acquire(const Node *barrier); 1035 bool needs_acquiring_load(const Node *load); 1036 1037 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1038 1039 bool unnecessary_release(const Node *barrier); 1040 bool unnecessary_volatile(const Node *barrier); 1041 bool needs_releasing_store(const Node *store); 1042 1043 // predicate controlling translation of CompareAndSwapX 1044 bool needs_acquiring_load_exclusive(const Node *load); 1045 1046 // predicate controlling addressing modes 1047 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1048 %} 1049 1050 source %{ 1051 1052 // Derived RegMask with conditionally allocatable registers 1053 1054 RegMask _ANY_REG32_mask; 1055 RegMask _ANY_REG_mask; 1056 RegMask _PTR_REG_mask; 1057 RegMask _NO_SPECIAL_REG32_mask; 1058 RegMask _NO_SPECIAL_REG_mask; 1059 RegMask _NO_SPECIAL_PTR_REG_mask; 1060 1061 void reg_mask_init() { 1062 // We derive below RegMask(s) from the ones which are auto-generated from 1063 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1064 // registers conditionally reserved. 1065 1066 _ANY_REG32_mask = _ALL_REG32_mask; 1067 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1068 1069 _ANY_REG_mask = _ALL_REG_mask; 1070 1071 _PTR_REG_mask = _ALL_REG_mask; 1072 1073 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1074 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1075 1076 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1077 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1078 1079 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1080 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1081 1082 // r27 is not allocatable when compressed oops is on, compressed klass 1083 // pointers doesn't use r27 after JDK-8234794 1084 if (UseCompressedOops) { 1085 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1086 _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1087 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1088 } 1089 1090 // r29 is not allocatable when PreserveFramePointer is on 1091 if (PreserveFramePointer) { 1092 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1093 _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); 1094 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); 1095 } 1096 } 1097 1098 // Optimizaton of volatile gets and puts 1099 // ------------------------------------- 1100 // 1101 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1102 // use to implement volatile reads and writes. For a volatile read 1103 // we simply need 1104 // 1105 // ldar<x> 1106 // 1107 // and for a volatile write we need 1108 // 1109 // stlr<x> 1110 // 1111 // Alternatively, we can implement them by pairing a normal 1112 // load/store with a memory barrier. For a volatile read we need 1113 // 1114 // ldr<x> 1115 // dmb ishld 1116 // 1117 // for a volatile write 1118 // 1119 // dmb ish 1120 // str<x> 1121 // dmb ish 1122 // 1123 // We can also use ldaxr and stlxr to implement compare and swap CAS 1124 // sequences. These are normally translated to an instruction 1125 // sequence like the following 1126 // 1127 // dmb ish 1128 // retry: 1129 // ldxr<x> rval raddr 1130 // cmp rval rold 1131 // b.ne done 1132 // stlxr<x> rval, rnew, rold 1133 // cbnz rval retry 1134 // done: 1135 // cset r0, eq 1136 // dmb ishld 1137 // 1138 // Note that the exclusive store is already using an stlxr 1139 // instruction. That is required to ensure visibility to other 1140 // threads of the exclusive write (assuming it succeeds) before that 1141 // of any subsequent writes. 1142 // 1143 // The following instruction sequence is an improvement on the above 1144 // 1145 // retry: 1146 // ldaxr<x> rval raddr 1147 // cmp rval rold 1148 // b.ne done 1149 // stlxr<x> rval, rnew, rold 1150 // cbnz rval retry 1151 // done: 1152 // cset r0, eq 1153 // 1154 // We don't need the leading dmb ish since the stlxr guarantees 1155 // visibility of prior writes in the case that the swap is 1156 // successful. Crucially we don't have to worry about the case where 1157 // the swap is not successful since no valid program should be 1158 // relying on visibility of prior changes by the attempting thread 1159 // in the case where the CAS fails. 1160 // 1161 // Similarly, we don't need the trailing dmb ishld if we substitute 1162 // an ldaxr instruction since that will provide all the guarantees we 1163 // require regarding observation of changes made by other threads 1164 // before any change to the CAS address observed by the load. 1165 // 1166 // In order to generate the desired instruction sequence we need to 1167 // be able to identify specific 'signature' ideal graph node 1168 // sequences which i) occur as a translation of a volatile reads or 1169 // writes or CAS operations and ii) do not occur through any other 1170 // translation or graph transformation. We can then provide 1171 // alternative aldc matching rules which translate these node 1172 // sequences to the desired machine code sequences. Selection of the 1173 // alternative rules can be implemented by predicates which identify 1174 // the relevant node sequences. 1175 // 1176 // The ideal graph generator translates a volatile read to the node 1177 // sequence 1178 // 1179 // LoadX[mo_acquire] 1180 // MemBarAcquire 1181 // 1182 // As a special case when using the compressed oops optimization we 1183 // may also see this variant 1184 // 1185 // LoadN[mo_acquire] 1186 // DecodeN 1187 // MemBarAcquire 1188 // 1189 // A volatile write is translated to the node sequence 1190 // 1191 // MemBarRelease 1192 // StoreX[mo_release] {CardMark}-optional 1193 // MemBarVolatile 1194 // 1195 // n.b. the above node patterns are generated with a strict 1196 // 'signature' configuration of input and output dependencies (see 1197 // the predicates below for exact details). The card mark may be as 1198 // simple as a few extra nodes or, in a few GC configurations, may 1199 // include more complex control flow between the leading and 1200 // trailing memory barriers. However, whatever the card mark 1201 // configuration these signatures are unique to translated volatile 1202 // reads/stores -- they will not appear as a result of any other 1203 // bytecode translation or inlining nor as a consequence of 1204 // optimizing transforms. 1205 // 1206 // We also want to catch inlined unsafe volatile gets and puts and 1207 // be able to implement them using either ldar<x>/stlr<x> or some 1208 // combination of ldr<x>/stlr<x> and dmb instructions. 1209 // 1210 // Inlined unsafe volatiles puts manifest as a minor variant of the 1211 // normal volatile put node sequence containing an extra cpuorder 1212 // membar 1213 // 1214 // MemBarRelease 1215 // MemBarCPUOrder 1216 // StoreX[mo_release] {CardMark}-optional 1217 // MemBarCPUOrder 1218 // MemBarVolatile 1219 // 1220 // n.b. as an aside, a cpuorder membar is not itself subject to 1221 // matching and translation by adlc rules. However, the rule 1222 // predicates need to detect its presence in order to correctly 1223 // select the desired adlc rules. 1224 // 1225 // Inlined unsafe volatile gets manifest as a slightly different 1226 // node sequence to a normal volatile get because of the 1227 // introduction of some CPUOrder memory barriers to bracket the 1228 // Load. However, but the same basic skeleton of a LoadX feeding a 1229 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1230 // present 1231 // 1232 // MemBarCPUOrder 1233 // || \\ 1234 // MemBarCPUOrder LoadX[mo_acquire] 1235 // || | 1236 // || {DecodeN} optional 1237 // || / 1238 // MemBarAcquire 1239 // 1240 // In this case the acquire membar does not directly depend on the 1241 // load. However, we can be sure that the load is generated from an 1242 // inlined unsafe volatile get if we see it dependent on this unique 1243 // sequence of membar nodes. Similarly, given an acquire membar we 1244 // can know that it was added because of an inlined unsafe volatile 1245 // get if it is fed and feeds a cpuorder membar and if its feed 1246 // membar also feeds an acquiring load. 1247 // 1248 // Finally an inlined (Unsafe) CAS operation is translated to the 1249 // following ideal graph 1250 // 1251 // MemBarRelease 1252 // MemBarCPUOrder 1253 // CompareAndSwapX {CardMark}-optional 1254 // MemBarCPUOrder 1255 // MemBarAcquire 1256 // 1257 // So, where we can identify these volatile read and write 1258 // signatures we can choose to plant either of the above two code 1259 // sequences. For a volatile read we can simply plant a normal 1260 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1261 // also choose to inhibit translation of the MemBarAcquire and 1262 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1263 // 1264 // When we recognise a volatile store signature we can choose to 1265 // plant at a dmb ish as a translation for the MemBarRelease, a 1266 // normal str<x> and then a dmb ish for the MemBarVolatile. 1267 // Alternatively, we can inhibit translation of the MemBarRelease 1268 // and MemBarVolatile and instead plant a simple stlr<x> 1269 // instruction. 1270 // 1271 // when we recognise a CAS signature we can choose to plant a dmb 1272 // ish as a translation for the MemBarRelease, the conventional 1273 // macro-instruction sequence for the CompareAndSwap node (which 1274 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1275 // Alternatively, we can elide generation of the dmb instructions 1276 // and plant the alternative CompareAndSwap macro-instruction 1277 // sequence (which uses ldaxr<x>). 1278 // 1279 // Of course, the above only applies when we see these signature 1280 // configurations. We still want to plant dmb instructions in any 1281 // other cases where we may see a MemBarAcquire, MemBarRelease or 1282 // MemBarVolatile. For example, at the end of a constructor which 1283 // writes final/volatile fields we will see a MemBarRelease 1284 // instruction and this needs a 'dmb ish' lest we risk the 1285 // constructed object being visible without making the 1286 // final/volatile field writes visible. 1287 // 1288 // n.b. the translation rules below which rely on detection of the 1289 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1290 // If we see anything other than the signature configurations we 1291 // always just translate the loads and stores to ldr<x> and str<x> 1292 // and translate acquire, release and volatile membars to the 1293 // relevant dmb instructions. 1294 // 1295 1296 // is_CAS(int opcode, bool maybe_volatile) 1297 // 1298 // return true if opcode is one of the possible CompareAndSwapX 1299 // values otherwise false. 1300 1301 bool is_CAS(int opcode, bool maybe_volatile) 1302 { 1303 switch(opcode) { 1304 // We handle these 1305 case Op_CompareAndSwapI: 1306 case Op_CompareAndSwapL: 1307 case Op_CompareAndSwapP: 1308 case Op_CompareAndSwapN: 1309 case Op_ShenandoahCompareAndSwapP: 1310 case Op_ShenandoahCompareAndSwapN: 1311 case Op_CompareAndSwapB: 1312 case Op_CompareAndSwapS: 1313 case Op_GetAndSetI: 1314 case Op_GetAndSetL: 1315 case Op_GetAndSetP: 1316 case Op_GetAndSetN: 1317 case Op_GetAndAddI: 1318 case Op_GetAndAddL: 1319 return true; 1320 case Op_CompareAndExchangeI: 1321 case Op_CompareAndExchangeN: 1322 case Op_CompareAndExchangeB: 1323 case Op_CompareAndExchangeS: 1324 case Op_CompareAndExchangeL: 1325 case Op_CompareAndExchangeP: 1326 case Op_WeakCompareAndSwapB: 1327 case Op_WeakCompareAndSwapS: 1328 case Op_WeakCompareAndSwapI: 1329 case Op_WeakCompareAndSwapL: 1330 case Op_WeakCompareAndSwapP: 1331 case Op_WeakCompareAndSwapN: 1332 case Op_ShenandoahWeakCompareAndSwapP: 1333 case Op_ShenandoahWeakCompareAndSwapN: 1334 case Op_ShenandoahCompareAndExchangeP: 1335 case Op_ShenandoahCompareAndExchangeN: 1336 return maybe_volatile; 1337 default: 1338 return false; 1339 } 1340 } 1341 1342 // helper to determine the maximum number of Phi nodes we may need to 1343 // traverse when searching from a card mark membar for the merge mem 1344 // feeding a trailing membar or vice versa 1345 1346 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1347 1348 bool unnecessary_acquire(const Node *barrier) 1349 { 1350 assert(barrier->is_MemBar(), "expecting a membar"); 1351 1352 if (UseBarriersForVolatile) { 1353 // we need to plant a dmb 1354 return false; 1355 } 1356 1357 MemBarNode* mb = barrier->as_MemBar(); 1358 1359 if (mb->trailing_load()) { 1360 return true; 1361 } 1362 1363 if (mb->trailing_load_store()) { 1364 Node* load_store = mb->in(MemBarNode::Precedent); 1365 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1366 return is_CAS(load_store->Opcode(), true); 1367 } 1368 1369 return false; 1370 } 1371 1372 bool needs_acquiring_load(const Node *n) 1373 { 1374 assert(n->is_Load(), "expecting a load"); 1375 if (UseBarriersForVolatile) { 1376 // we use a normal load and a dmb 1377 return false; 1378 } 1379 1380 LoadNode *ld = n->as_Load(); 1381 1382 return ld->is_acquire(); 1383 } 1384 1385 bool unnecessary_release(const Node *n) 1386 { 1387 assert((n->is_MemBar() && 1388 n->Opcode() == Op_MemBarRelease), 1389 "expecting a release membar"); 1390 1391 if (UseBarriersForVolatile) { 1392 // we need to plant a dmb 1393 return false; 1394 } 1395 1396 MemBarNode *barrier = n->as_MemBar(); 1397 if (!barrier->leading()) { 1398 return false; 1399 } else { 1400 Node* trailing = barrier->trailing_membar(); 1401 MemBarNode* trailing_mb = trailing->as_MemBar(); 1402 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1403 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1404 1405 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1406 if (mem->is_Store()) { 1407 assert(mem->as_Store()->is_release(), ""); 1408 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1409 return true; 1410 } else { 1411 assert(mem->is_LoadStore(), ""); 1412 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1413 return is_CAS(mem->Opcode(), true); 1414 } 1415 } 1416 return false; 1417 } 1418 1419 bool unnecessary_volatile(const Node *n) 1420 { 1421 // assert n->is_MemBar(); 1422 if (UseBarriersForVolatile) { 1423 // we need to plant a dmb 1424 return false; 1425 } 1426 1427 MemBarNode *mbvol = n->as_MemBar(); 1428 1429 bool release = mbvol->trailing_store(); 1430 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1431 #ifdef ASSERT 1432 if (release) { 1433 Node* leading = mbvol->leading_membar(); 1434 assert(leading->Opcode() == Op_MemBarRelease, ""); 1435 assert(leading->as_MemBar()->leading_store(), ""); 1436 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1437 } 1438 #endif 1439 1440 return release; 1441 } 1442 1443 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1444 1445 bool needs_releasing_store(const Node *n) 1446 { 1447 // assert n->is_Store(); 1448 if (UseBarriersForVolatile) { 1449 // we use a normal store and dmb combination 1450 return false; 1451 } 1452 1453 StoreNode *st = n->as_Store(); 1454 1455 return st->trailing_membar() != NULL; 1456 } 1457 1458 // predicate controlling translation of CAS 1459 // 1460 // returns true if CAS needs to use an acquiring load otherwise false 1461 1462 bool needs_acquiring_load_exclusive(const Node *n) 1463 { 1464 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1465 if (UseBarriersForVolatile) { 1466 return false; 1467 } 1468 1469 LoadStoreNode* ldst = n->as_LoadStore(); 1470 if (is_CAS(n->Opcode(), false)) { 1471 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1472 } else { 1473 return ldst->trailing_membar() != NULL; 1474 } 1475 1476 // so we can just return true here 1477 return true; 1478 } 1479 1480 #define __ _masm. 1481 1482 // advance declarations for helper functions to convert register 1483 // indices to register objects 1484 1485 // the ad file has to provide implementations of certain methods 1486 // expected by the generic code 1487 // 1488 // REQUIRED FUNCTIONALITY 1489 1490 //============================================================================= 1491 1492 // !!!!! Special hack to get all types of calls to specify the byte offset 1493 // from the start of the call to the point where the return address 1494 // will point. 1495 1496 int MachCallStaticJavaNode::ret_addr_offset() 1497 { 1498 // call should be a simple bl 1499 int off = 4; 1500 return off; 1501 } 1502 1503 int MachCallDynamicJavaNode::ret_addr_offset() 1504 { 1505 return 16; // movz, movk, movk, bl 1506 } 1507 1508 int MachCallRuntimeNode::ret_addr_offset() { 1509 // for generated stubs the call will be 1510 // far_call(addr) 1511 // for real runtime callouts it will be six instructions 1512 // see aarch64_enc_java_to_runtime 1513 // adr(rscratch2, retaddr) 1514 // lea(rscratch1, RuntimeAddress(addr) 1515 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1516 // blr(rscratch1) 1517 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1518 if (cb) { 1519 return MacroAssembler::far_branch_size(); 1520 } else { 1521 return 6 * NativeInstruction::instruction_size; 1522 } 1523 } 1524 1525 // Indicate if the safepoint node needs the polling page as an input 1526 1527 // the shared code plants the oop data at the start of the generated 1528 // code for the safepoint node and that needs ot be at the load 1529 // instruction itself. so we cannot plant a mov of the safepoint poll 1530 // address followed by a load. setting this to true means the mov is 1531 // scheduled as a prior instruction. that's better for scheduling 1532 // anyway. 1533 1534 bool SafePointNode::needs_polling_address_input() 1535 { 1536 return true; 1537 } 1538 1539 //============================================================================= 1540 1541 #ifndef PRODUCT 1542 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1543 st->print("BREAKPOINT"); 1544 } 1545 #endif 1546 1547 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1548 MacroAssembler _masm(&cbuf); 1549 __ brk(0); 1550 } 1551 1552 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1553 return MachNode::size(ra_); 1554 } 1555 1556 //============================================================================= 1557 1558 #ifndef PRODUCT 1559 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1560 st->print("nop \t# %d bytes pad for loops and calls", _count); 1561 } 1562 #endif 1563 1564 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1565 MacroAssembler _masm(&cbuf); 1566 for (int i = 0; i < _count; i++) { 1567 __ nop(); 1568 } 1569 } 1570 1571 uint MachNopNode::size(PhaseRegAlloc*) const { 1572 return _count * NativeInstruction::instruction_size; 1573 } 1574 1575 //============================================================================= 1576 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1577 1578 int Compile::ConstantTable::calculate_table_base_offset() const { 1579 return 0; // absolute addressing, no offset 1580 } 1581 1582 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1583 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1584 ShouldNotReachHere(); 1585 } 1586 1587 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1588 // Empty encoding 1589 } 1590 1591 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1592 return 0; 1593 } 1594 1595 #ifndef PRODUCT 1596 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1597 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1598 } 1599 #endif 1600 1601 #ifndef PRODUCT 1602 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1603 Compile* C = ra_->C; 1604 1605 int framesize = C->frame_slots() << LogBytesPerInt; 1606 1607 if (C->need_stack_bang(framesize)) 1608 st->print("# stack bang size=%d\n\t", framesize); 1609 1610 if (framesize < ((1 << 9) + 2 * wordSize)) { 1611 st->print("sub sp, sp, #%d\n\t", framesize); 1612 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1613 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1614 } else { 1615 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1616 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1617 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1618 st->print("sub sp, sp, rscratch1"); 1619 } 1620 } 1621 #endif 1622 1623 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1624 Compile* C = ra_->C; 1625 MacroAssembler _masm(&cbuf); 1626 1627 // n.b. frame size includes space for return pc and rfp 1628 const long framesize = C->frame_size_in_bytes(); 1629 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1630 1631 // insert a nop at the start of the prolog so we can patch in a 1632 // branch if we need to invalidate the method later 1633 __ nop(); 1634 1635 if (C->clinit_barrier_on_entry()) { 1636 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1637 1638 Label L_skip_barrier; 1639 1640 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1641 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1642 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1643 __ bind(L_skip_barrier); 1644 } 1645 1646 int bangsize = C->bang_size_in_bytes(); 1647 if (C->need_stack_bang(bangsize) && UseStackBanging) 1648 __ generate_stack_overflow_check(bangsize); 1649 1650 __ build_frame(framesize); 1651 1652 if (VerifyStackAtCalls) { 1653 Unimplemented(); 1654 } 1655 1656 C->set_frame_complete(cbuf.insts_size()); 1657 1658 if (C->has_mach_constant_base_node()) { 1659 // NOTE: We set the table base offset here because users might be 1660 // emitted before MachConstantBaseNode. 1661 Compile::ConstantTable& constant_table = C->constant_table(); 1662 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1663 } 1664 } 1665 1666 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1667 { 1668 return MachNode::size(ra_); // too many variables; just compute it 1669 // the hard way 1670 } 1671 1672 int MachPrologNode::reloc() const 1673 { 1674 return 0; 1675 } 1676 1677 //============================================================================= 1678 1679 #ifndef PRODUCT 1680 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1681 Compile* C = ra_->C; 1682 int framesize = C->frame_slots() << LogBytesPerInt; 1683 1684 st->print("# pop frame %d\n\t",framesize); 1685 1686 if (framesize == 0) { 1687 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1688 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1689 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1690 st->print("add sp, sp, #%d\n\t", framesize); 1691 } else { 1692 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1693 st->print("add sp, sp, rscratch1\n\t"); 1694 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1695 } 1696 1697 if (do_polling() && C->is_method_compilation()) { 1698 st->print("# touch polling page\n\t"); 1699 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1700 st->print("ldr zr, [rscratch1]"); 1701 } 1702 } 1703 #endif 1704 1705 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1706 Compile* C = ra_->C; 1707 MacroAssembler _masm(&cbuf); 1708 int framesize = C->frame_slots() << LogBytesPerInt; 1709 1710 __ remove_frame(framesize); 1711 1712 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1713 __ reserved_stack_check(); 1714 } 1715 1716 if (do_polling() && C->is_method_compilation()) { 1717 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1718 } 1719 } 1720 1721 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1722 // Variable size. Determine dynamically. 1723 return MachNode::size(ra_); 1724 } 1725 1726 int MachEpilogNode::reloc() const { 1727 // Return number of relocatable values contained in this instruction. 1728 return 1; // 1 for polling page. 1729 } 1730 1731 const Pipeline * MachEpilogNode::pipeline() const { 1732 return MachNode::pipeline_class(); 1733 } 1734 1735 // This method seems to be obsolete. It is declared in machnode.hpp 1736 // and defined in all *.ad files, but it is never called. Should we 1737 // get rid of it? 1738 int MachEpilogNode::safepoint_offset() const { 1739 assert(do_polling(), "no return for this epilog node"); 1740 return 4; 1741 } 1742 1743 //============================================================================= 1744 1745 // Figure out which register class each belongs in: rc_int, rc_float or 1746 // rc_stack. 1747 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1748 1749 static enum RC rc_class(OptoReg::Name reg) { 1750 1751 if (reg == OptoReg::Bad) { 1752 return rc_bad; 1753 } 1754 1755 // we have 30 int registers * 2 halves 1756 // (rscratch1 and rscratch2 are omitted) 1757 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1758 1759 if (reg < slots_of_int_registers) { 1760 return rc_int; 1761 } 1762 1763 // we have 32 float register * 4 halves 1764 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1765 return rc_float; 1766 } 1767 1768 // Between float regs & stack is the flags regs. 1769 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1770 1771 return rc_stack; 1772 } 1773 1774 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1775 Compile* C = ra_->C; 1776 1777 // Get registers to move. 1778 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1779 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1780 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1781 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1782 1783 enum RC src_hi_rc = rc_class(src_hi); 1784 enum RC src_lo_rc = rc_class(src_lo); 1785 enum RC dst_hi_rc = rc_class(dst_hi); 1786 enum RC dst_lo_rc = rc_class(dst_lo); 1787 1788 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1789 1790 if (src_hi != OptoReg::Bad) { 1791 assert((src_lo&1)==0 && src_lo+1==src_hi && 1792 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1793 "expected aligned-adjacent pairs"); 1794 } 1795 1796 if (src_lo == dst_lo && src_hi == dst_hi) { 1797 return 0; // Self copy, no move. 1798 } 1799 1800 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1801 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1802 int src_offset = ra_->reg2offset(src_lo); 1803 int dst_offset = ra_->reg2offset(dst_lo); 1804 1805 if (bottom_type()->isa_vect() != NULL) { 1806 uint ireg = ideal_reg(); 1807 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1808 if (cbuf) { 1809 MacroAssembler _masm(cbuf); 1810 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1811 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1812 // stack->stack 1813 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1814 if (ireg == Op_VecD) { 1815 __ unspill(rscratch1, true, src_offset); 1816 __ spill(rscratch1, true, dst_offset); 1817 } else { 1818 __ spill_copy128(src_offset, dst_offset); 1819 } 1820 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1821 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1822 ireg == Op_VecD ? __ T8B : __ T16B, 1823 as_FloatRegister(Matcher::_regEncode[src_lo])); 1824 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1825 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1826 ireg == Op_VecD ? __ D : __ Q, 1827 ra_->reg2offset(dst_lo)); 1828 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1829 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1830 ireg == Op_VecD ? __ D : __ Q, 1831 ra_->reg2offset(src_lo)); 1832 } else { 1833 ShouldNotReachHere(); 1834 } 1835 } 1836 } else if (cbuf) { 1837 MacroAssembler _masm(cbuf); 1838 switch (src_lo_rc) { 1839 case rc_int: 1840 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1841 if (is64) { 1842 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1843 as_Register(Matcher::_regEncode[src_lo])); 1844 } else { 1845 MacroAssembler _masm(cbuf); 1846 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1847 as_Register(Matcher::_regEncode[src_lo])); 1848 } 1849 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1850 if (is64) { 1851 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1852 as_Register(Matcher::_regEncode[src_lo])); 1853 } else { 1854 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1855 as_Register(Matcher::_regEncode[src_lo])); 1856 } 1857 } else { // gpr --> stack spill 1858 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1859 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1860 } 1861 break; 1862 case rc_float: 1863 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1864 if (is64) { 1865 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1866 as_FloatRegister(Matcher::_regEncode[src_lo])); 1867 } else { 1868 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1869 as_FloatRegister(Matcher::_regEncode[src_lo])); 1870 } 1871 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1872 if (cbuf) { 1873 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1874 as_FloatRegister(Matcher::_regEncode[src_lo])); 1875 } else { 1876 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1877 as_FloatRegister(Matcher::_regEncode[src_lo])); 1878 } 1879 } else { // fpr --> stack spill 1880 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1881 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1882 is64 ? __ D : __ S, dst_offset); 1883 } 1884 break; 1885 case rc_stack: 1886 if (dst_lo_rc == rc_int) { // stack --> gpr load 1887 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1888 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1889 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1890 is64 ? __ D : __ S, src_offset); 1891 } else { // stack --> stack copy 1892 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1893 __ unspill(rscratch1, is64, src_offset); 1894 __ spill(rscratch1, is64, dst_offset); 1895 } 1896 break; 1897 default: 1898 assert(false, "bad rc_class for spill"); 1899 ShouldNotReachHere(); 1900 } 1901 } 1902 1903 if (st) { 1904 st->print("spill "); 1905 if (src_lo_rc == rc_stack) { 1906 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1907 } else { 1908 st->print("%s -> ", Matcher::regName[src_lo]); 1909 } 1910 if (dst_lo_rc == rc_stack) { 1911 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1912 } else { 1913 st->print("%s", Matcher::regName[dst_lo]); 1914 } 1915 if (bottom_type()->isa_vect() != NULL) { 1916 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1917 } else { 1918 st->print("\t# spill size = %d", is64 ? 64:32); 1919 } 1920 } 1921 1922 return 0; 1923 1924 } 1925 1926 #ifndef PRODUCT 1927 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1928 if (!ra_) 1929 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1930 else 1931 implementation(NULL, ra_, false, st); 1932 } 1933 #endif 1934 1935 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1936 implementation(&cbuf, ra_, false, NULL); 1937 } 1938 1939 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1940 return MachNode::size(ra_); 1941 } 1942 1943 //============================================================================= 1944 1945 #ifndef PRODUCT 1946 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1947 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1948 int reg = ra_->get_reg_first(this); 1949 st->print("add %s, rsp, #%d]\t# box lock", 1950 Matcher::regName[reg], offset); 1951 } 1952 #endif 1953 1954 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1955 MacroAssembler _masm(&cbuf); 1956 1957 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1958 int reg = ra_->get_encode(this); 1959 1960 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1961 __ add(as_Register(reg), sp, offset); 1962 } else { 1963 ShouldNotReachHere(); 1964 } 1965 } 1966 1967 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1968 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1969 return 4; 1970 } 1971 1972 //============================================================================= 1973 1974 #ifndef PRODUCT 1975 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1976 { 1977 st->print_cr("# MachUEPNode"); 1978 if (UseCompressedClassPointers) { 1979 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1980 if (CompressedKlassPointers::shift() != 0) { 1981 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1982 } 1983 } else { 1984 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1985 } 1986 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1987 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1988 } 1989 #endif 1990 1991 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1992 { 1993 // This is the unverified entry point. 1994 MacroAssembler _masm(&cbuf); 1995 1996 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1997 Label skip; 1998 // TODO 1999 // can we avoid this skip and still use a reloc? 2000 __ br(Assembler::EQ, skip); 2001 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2002 __ bind(skip); 2003 } 2004 2005 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2006 { 2007 return MachNode::size(ra_); 2008 } 2009 2010 // REQUIRED EMIT CODE 2011 2012 //============================================================================= 2013 2014 // Emit exception handler code. 2015 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2016 { 2017 // mov rscratch1 #exception_blob_entry_point 2018 // br rscratch1 2019 // Note that the code buffer's insts_mark is always relative to insts. 2020 // That's why we must use the macroassembler to generate a handler. 2021 MacroAssembler _masm(&cbuf); 2022 address base = __ start_a_stub(size_exception_handler()); 2023 if (base == NULL) { 2024 ciEnv::current()->record_failure("CodeCache is full"); 2025 return 0; // CodeBuffer::expand failed 2026 } 2027 int offset = __ offset(); 2028 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2029 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2030 __ end_a_stub(); 2031 return offset; 2032 } 2033 2034 // Emit deopt handler code. 2035 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2036 { 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 MacroAssembler _masm(&cbuf); 2040 address base = __ start_a_stub(size_deopt_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 2047 __ adr(lr, __ pc()); 2048 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2049 2050 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2051 __ end_a_stub(); 2052 return offset; 2053 } 2054 2055 // REQUIRED MATCHER CODE 2056 2057 //============================================================================= 2058 2059 const bool Matcher::match_rule_supported(int opcode) { 2060 if (!has_match_rule(opcode)) 2061 return false; 2062 2063 bool ret_value = true; 2064 switch (opcode) { 2065 case Op_CacheWB: 2066 case Op_CacheWBPreSync: 2067 case Op_CacheWBPostSync: 2068 if (!VM_Version::supports_data_cache_line_flush()) { 2069 ret_value = false; 2070 } 2071 break; 2072 } 2073 2074 return ret_value; // Per default match rules are supported. 2075 } 2076 2077 // Identify extra cases that we might want to provide match rules for vector nodes and 2078 // other intrinsics guarded with vector length (vlen) and element type (bt). 2079 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2080 if (!match_rule_supported(opcode)) { 2081 return false; 2082 } 2083 2084 // Special cases which require vector length 2085 switch (opcode) { 2086 case Op_MulAddVS2VI: { 2087 if (vlen != 4) { 2088 return false; 2089 } 2090 break; 2091 } 2092 } 2093 2094 return true; // Per default match rules are supported. 2095 } 2096 2097 const bool Matcher::has_predicated_vectors(void) { 2098 return false; 2099 } 2100 2101 const int Matcher::float_pressure(int default_pressure_threshold) { 2102 return default_pressure_threshold; 2103 } 2104 2105 int Matcher::regnum_to_fpu_offset(int regnum) 2106 { 2107 Unimplemented(); 2108 return 0; 2109 } 2110 2111 // Is this branch offset short enough that a short branch can be used? 2112 // 2113 // NOTE: If the platform does not provide any short branch variants, then 2114 // this method should return false for offset 0. 2115 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2116 // The passed offset is relative to address of the branch. 2117 2118 return (-32768 <= offset && offset < 32768); 2119 } 2120 2121 const bool Matcher::isSimpleConstant64(jlong value) { 2122 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2123 // Probably always true, even if a temp register is required. 2124 return true; 2125 } 2126 2127 // true just means we have fast l2f conversion 2128 const bool Matcher::convL2FSupported(void) { 2129 return true; 2130 } 2131 2132 // Vector width in bytes. 2133 const int Matcher::vector_width_in_bytes(BasicType bt) { 2134 int size = MIN2(16,(int)MaxVectorSize); 2135 // Minimum 2 values in vector 2136 if (size < 2*type2aelembytes(bt)) size = 0; 2137 // But never < 4 2138 if (size < 4) size = 0; 2139 return size; 2140 } 2141 2142 // Limits on vector size (number of elements) loaded into vector. 2143 const int Matcher::max_vector_size(const BasicType bt) { 2144 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2145 } 2146 const int Matcher::min_vector_size(const BasicType bt) { 2147 // For the moment limit the vector size to 8 bytes 2148 int size = 8 / type2aelembytes(bt); 2149 if (size < 2) size = 2; 2150 return size; 2151 } 2152 2153 // Vector ideal reg. 2154 const uint Matcher::vector_ideal_reg(int len) { 2155 switch(len) { 2156 case 8: return Op_VecD; 2157 case 16: return Op_VecX; 2158 } 2159 ShouldNotReachHere(); 2160 return 0; 2161 } 2162 2163 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2164 switch(size) { 2165 case 8: return Op_VecD; 2166 case 16: return Op_VecX; 2167 } 2168 ShouldNotReachHere(); 2169 return 0; 2170 } 2171 2172 // AES support not yet implemented 2173 const bool Matcher::pass_original_key_for_aes() { 2174 return false; 2175 } 2176 2177 // aarch64 supports misaligned vectors store/load. 2178 const bool Matcher::misaligned_vectors_ok() { 2179 return true; 2180 } 2181 2182 // false => size gets scaled to BytesPerLong, ok. 2183 const bool Matcher::init_array_count_is_in_bytes = false; 2184 2185 // Use conditional move (CMOVL) 2186 const int Matcher::long_cmove_cost() { 2187 // long cmoves are no more expensive than int cmoves 2188 return 0; 2189 } 2190 2191 const int Matcher::float_cmove_cost() { 2192 // float cmoves are no more expensive than int cmoves 2193 return 0; 2194 } 2195 2196 // Does the CPU require late expand (see block.cpp for description of late expand)? 2197 const bool Matcher::require_postalloc_expand = false; 2198 2199 // Do we need to mask the count passed to shift instructions or does 2200 // the cpu only look at the lower 5/6 bits anyway? 2201 const bool Matcher::need_masked_shift_count = false; 2202 2203 // No support for generic vector operands. 2204 const bool Matcher::supports_generic_vector_operands = false; 2205 2206 MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2207 ShouldNotReachHere(); // generic vector operands not supported 2208 return NULL; 2209 } 2210 2211 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2212 ShouldNotReachHere(); // generic vector operands not supported 2213 return false; 2214 } 2215 2216 bool Matcher::is_generic_vector(MachOper* opnd) { 2217 ShouldNotReachHere(); // generic vector operands not supported 2218 return false; 2219 } 2220 2221 // This affects two different things: 2222 // - how Decode nodes are matched 2223 // - how ImplicitNullCheck opportunities are recognized 2224 // If true, the matcher will try to remove all Decodes and match them 2225 // (as operands) into nodes. NullChecks are not prepared to deal with 2226 // Decodes by final_graph_reshaping(). 2227 // If false, final_graph_reshaping() forces the decode behind the Cmp 2228 // for a NullCheck. The matcher matches the Decode node into a register. 2229 // Implicit_null_check optimization moves the Decode along with the 2230 // memory operation back up before the NullCheck. 2231 bool Matcher::narrow_oop_use_complex_address() { 2232 return CompressedOops::shift() == 0; 2233 } 2234 2235 bool Matcher::narrow_klass_use_complex_address() { 2236 // TODO 2237 // decide whether we need to set this to true 2238 return false; 2239 } 2240 2241 bool Matcher::const_oop_prefer_decode() { 2242 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2243 return CompressedOops::base() == NULL; 2244 } 2245 2246 bool Matcher::const_klass_prefer_decode() { 2247 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2248 return CompressedKlassPointers::base() == NULL; 2249 } 2250 2251 // Is it better to copy float constants, or load them directly from 2252 // memory? Intel can load a float constant from a direct address, 2253 // requiring no extra registers. Most RISCs will have to materialize 2254 // an address into a register first, so they would do better to copy 2255 // the constant from stack. 2256 const bool Matcher::rematerialize_float_constants = false; 2257 2258 // If CPU can load and store mis-aligned doubles directly then no 2259 // fixup is needed. Else we split the double into 2 integer pieces 2260 // and move it piece-by-piece. Only happens when passing doubles into 2261 // C code as the Java calling convention forces doubles to be aligned. 2262 const bool Matcher::misaligned_doubles_ok = true; 2263 2264 // No-op on amd64 2265 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2266 Unimplemented(); 2267 } 2268 2269 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2270 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2271 2272 // Are floats converted to double when stored to stack during 2273 // deoptimization? 2274 bool Matcher::float_in_double() { return false; } 2275 2276 // Do ints take an entire long register or just half? 2277 // The relevant question is how the int is callee-saved: 2278 // the whole long is written but de-opt'ing will have to extract 2279 // the relevant 32 bits. 2280 const bool Matcher::int_in_long = true; 2281 2282 // Return whether or not this register is ever used as an argument. 2283 // This function is used on startup to build the trampoline stubs in 2284 // generateOptoStub. Registers not mentioned will be killed by the VM 2285 // call in the trampoline, and arguments in those registers not be 2286 // available to the callee. 2287 bool Matcher::can_be_java_arg(int reg) 2288 { 2289 return 2290 reg == R0_num || reg == R0_H_num || 2291 reg == R1_num || reg == R1_H_num || 2292 reg == R2_num || reg == R2_H_num || 2293 reg == R3_num || reg == R3_H_num || 2294 reg == R4_num || reg == R4_H_num || 2295 reg == R5_num || reg == R5_H_num || 2296 reg == R6_num || reg == R6_H_num || 2297 reg == R7_num || reg == R7_H_num || 2298 reg == V0_num || reg == V0_H_num || 2299 reg == V1_num || reg == V1_H_num || 2300 reg == V2_num || reg == V2_H_num || 2301 reg == V3_num || reg == V3_H_num || 2302 reg == V4_num || reg == V4_H_num || 2303 reg == V5_num || reg == V5_H_num || 2304 reg == V6_num || reg == V6_H_num || 2305 reg == V7_num || reg == V7_H_num; 2306 } 2307 2308 bool Matcher::is_spillable_arg(int reg) 2309 { 2310 return can_be_java_arg(reg); 2311 } 2312 2313 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2314 return false; 2315 } 2316 2317 RegMask Matcher::divI_proj_mask() { 2318 ShouldNotReachHere(); 2319 return RegMask(); 2320 } 2321 2322 // Register for MODI projection of divmodI. 2323 RegMask Matcher::modI_proj_mask() { 2324 ShouldNotReachHere(); 2325 return RegMask(); 2326 } 2327 2328 // Register for DIVL projection of divmodL. 2329 RegMask Matcher::divL_proj_mask() { 2330 ShouldNotReachHere(); 2331 return RegMask(); 2332 } 2333 2334 // Register for MODL projection of divmodL. 2335 RegMask Matcher::modL_proj_mask() { 2336 ShouldNotReachHere(); 2337 return RegMask(); 2338 } 2339 2340 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2341 return FP_REG_mask(); 2342 } 2343 2344 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2345 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2346 Node* u = addp->fast_out(i); 2347 if (u->is_Mem()) { 2348 int opsize = u->as_Mem()->memory_size(); 2349 assert(opsize > 0, "unexpected memory operand size"); 2350 if (u->as_Mem()->memory_size() != (1<<shift)) { 2351 return false; 2352 } 2353 } 2354 } 2355 return true; 2356 } 2357 2358 const bool Matcher::convi2l_type_required = false; 2359 2360 // Should the Matcher clone shifts on addressing modes, expecting them 2361 // to be subsumed into complex addressing expressions or compute them 2362 // into registers? 2363 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2364 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2365 return true; 2366 } 2367 2368 Node *off = m->in(AddPNode::Offset); 2369 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2370 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2371 // Are there other uses besides address expressions? 2372 !is_visited(off)) { 2373 address_visited.set(off->_idx); // Flag as address_visited 2374 mstack.push(off->in(2), Visit); 2375 Node *conv = off->in(1); 2376 if (conv->Opcode() == Op_ConvI2L && 2377 // Are there other uses besides address expressions? 2378 !is_visited(conv)) { 2379 address_visited.set(conv->_idx); // Flag as address_visited 2380 mstack.push(conv->in(1), Pre_Visit); 2381 } else { 2382 mstack.push(conv, Pre_Visit); 2383 } 2384 address_visited.test_set(m->_idx); // Flag as address_visited 2385 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2386 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2387 return true; 2388 } else if (off->Opcode() == Op_ConvI2L && 2389 // Are there other uses besides address expressions? 2390 !is_visited(off)) { 2391 address_visited.test_set(m->_idx); // Flag as address_visited 2392 address_visited.set(off->_idx); // Flag as address_visited 2393 mstack.push(off->in(1), Pre_Visit); 2394 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2395 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2396 return true; 2397 } 2398 return false; 2399 } 2400 2401 void Compile::reshape_address(AddPNode* addp) { 2402 } 2403 2404 2405 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2406 MacroAssembler _masm(&cbuf); \ 2407 { \ 2408 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2409 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2410 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2411 __ INSN(REG, as_Register(BASE)); \ 2412 } 2413 2414 2415 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2416 { 2417 Address::extend scale; 2418 2419 // Hooboy, this is fugly. We need a way to communicate to the 2420 // encoder that the index needs to be sign extended, so we have to 2421 // enumerate all the cases. 2422 switch (opcode) { 2423 case INDINDEXSCALEDI2L: 2424 case INDINDEXSCALEDI2LN: 2425 case INDINDEXI2L: 2426 case INDINDEXI2LN: 2427 scale = Address::sxtw(size); 2428 break; 2429 default: 2430 scale = Address::lsl(size); 2431 } 2432 2433 if (index == -1) { 2434 return Address(base, disp); 2435 } else { 2436 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2437 return Address(base, as_Register(index), scale); 2438 } 2439 } 2440 2441 2442 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2443 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2444 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2445 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2446 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2447 2448 // Used for all non-volatile memory accesses. The use of 2449 // $mem->opcode() to discover whether this pattern uses sign-extended 2450 // offsets is something of a kludge. 2451 static void loadStore(MacroAssembler masm, mem_insn insn, 2452 Register reg, int opcode, 2453 Register base, int index, int scale, int disp, 2454 int size_in_memory) 2455 { 2456 Address addr = mem2address(opcode, base, index, scale, disp); 2457 if (addr.getMode() == Address::base_plus_offset) { 2458 /* If we get an out-of-range offset it is a bug in the compiler, 2459 so we assert here. */ 2460 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2461 "c2 compiler bug"); 2462 /* Fix up any out-of-range offsets. */ 2463 assert_different_registers(rscratch1, base); 2464 assert_different_registers(rscratch1, reg); 2465 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2466 } 2467 (masm.*insn)(reg, addr); 2468 } 2469 2470 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2471 FloatRegister reg, int opcode, 2472 Register base, int index, int size, int disp, 2473 int size_in_memory) 2474 { 2475 Address::extend scale; 2476 2477 switch (opcode) { 2478 case INDINDEXSCALEDI2L: 2479 case INDINDEXSCALEDI2LN: 2480 scale = Address::sxtw(size); 2481 break; 2482 default: 2483 scale = Address::lsl(size); 2484 } 2485 2486 if (index == -1) { 2487 /* If we get an out-of-range offset it is a bug in the compiler, 2488 so we assert here. */ 2489 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2490 /* Fix up any out-of-range offsets. */ 2491 assert_different_registers(rscratch1, base); 2492 Address addr = Address(base, disp); 2493 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2494 (masm.*insn)(reg, addr); 2495 } else { 2496 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2497 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2498 } 2499 } 2500 2501 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2502 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2503 int opcode, Register base, int index, int size, int disp) 2504 { 2505 if (index == -1) { 2506 (masm.*insn)(reg, T, Address(base, disp)); 2507 } else { 2508 assert(disp == 0, "unsupported address mode"); 2509 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2510 } 2511 } 2512 2513 %} 2514 2515 2516 2517 //----------ENCODING BLOCK----------------------------------------------------- 2518 // This block specifies the encoding classes used by the compiler to 2519 // output byte streams. Encoding classes are parameterized macros 2520 // used by Machine Instruction Nodes in order to generate the bit 2521 // encoding of the instruction. Operands specify their base encoding 2522 // interface with the interface keyword. There are currently 2523 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2524 // COND_INTER. REG_INTER causes an operand to generate a function 2525 // which returns its register number when queried. CONST_INTER causes 2526 // an operand to generate a function which returns the value of the 2527 // constant when queried. MEMORY_INTER causes an operand to generate 2528 // four functions which return the Base Register, the Index Register, 2529 // the Scale Value, and the Offset Value of the operand when queried. 2530 // COND_INTER causes an operand to generate six functions which return 2531 // the encoding code (ie - encoding bits for the instruction) 2532 // associated with each basic boolean condition for a conditional 2533 // instruction. 2534 // 2535 // Instructions specify two basic values for encoding. Again, a 2536 // function is available to check if the constant displacement is an 2537 // oop. They use the ins_encode keyword to specify their encoding 2538 // classes (which must be a sequence of enc_class names, and their 2539 // parameters, specified in the encoding block), and they use the 2540 // opcode keyword to specify, in order, their primary, secondary, and 2541 // tertiary opcode. Only the opcode sections which a particular 2542 // instruction needs for encoding need to be specified. 2543 encode %{ 2544 // Build emit functions for each basic byte or larger field in the 2545 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2546 // from C++ code in the enc_class source block. Emit functions will 2547 // live in the main source block for now. In future, we can 2548 // generalize this by adding a syntax that specifies the sizes of 2549 // fields in an order, so that the adlc can build the emit functions 2550 // automagically 2551 2552 // catch all for unimplemented encodings 2553 enc_class enc_unimplemented %{ 2554 MacroAssembler _masm(&cbuf); 2555 __ unimplemented("C2 catch all"); 2556 %} 2557 2558 // BEGIN Non-volatile memory access 2559 2560 // This encoding class is generated automatically from ad_encode.m4. 2561 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2562 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2563 Register dst_reg = as_Register($dst$$reg); 2564 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2565 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2566 %} 2567 2568 // This encoding class is generated automatically from ad_encode.m4. 2569 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2570 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2571 Register dst_reg = as_Register($dst$$reg); 2572 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2573 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2574 %} 2575 2576 // This encoding class is generated automatically from ad_encode.m4. 2577 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2578 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2579 Register dst_reg = as_Register($dst$$reg); 2580 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2581 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2582 %} 2583 2584 // This encoding class is generated automatically from ad_encode.m4. 2585 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2586 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2587 Register dst_reg = as_Register($dst$$reg); 2588 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2589 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2590 %} 2591 2592 // This encoding class is generated automatically from ad_encode.m4. 2593 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2594 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2595 Register dst_reg = as_Register($dst$$reg); 2596 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2597 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2598 %} 2599 2600 // This encoding class is generated automatically from ad_encode.m4. 2601 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2602 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2603 Register dst_reg = as_Register($dst$$reg); 2604 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2605 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2606 %} 2607 2608 // This encoding class is generated automatically from ad_encode.m4. 2609 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2610 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2611 Register dst_reg = as_Register($dst$$reg); 2612 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2613 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2614 %} 2615 2616 // This encoding class is generated automatically from ad_encode.m4. 2617 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2618 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2619 Register dst_reg = as_Register($dst$$reg); 2620 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2621 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2622 %} 2623 2624 // This encoding class is generated automatically from ad_encode.m4. 2625 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2626 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2627 Register dst_reg = as_Register($dst$$reg); 2628 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2629 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2630 %} 2631 2632 // This encoding class is generated automatically from ad_encode.m4. 2633 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2634 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2635 Register dst_reg = as_Register($dst$$reg); 2636 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2637 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2638 %} 2639 2640 // This encoding class is generated automatically from ad_encode.m4. 2641 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2642 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2643 Register dst_reg = as_Register($dst$$reg); 2644 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2645 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2646 %} 2647 2648 // This encoding class is generated automatically from ad_encode.m4. 2649 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2650 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2651 Register dst_reg = as_Register($dst$$reg); 2652 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2653 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2654 %} 2655 2656 // This encoding class is generated automatically from ad_encode.m4. 2657 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2658 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2659 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2660 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2661 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2662 %} 2663 2664 // This encoding class is generated automatically from ad_encode.m4. 2665 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2666 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2667 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2668 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2669 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2670 %} 2671 2672 // This encoding class is generated automatically from ad_encode.m4. 2673 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2674 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2675 Register src_reg = as_Register($src$$reg); 2676 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2677 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2678 %} 2679 2680 // This encoding class is generated automatically from ad_encode.m4. 2681 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2682 enc_class aarch64_enc_strb0(memory1 mem) %{ 2683 MacroAssembler _masm(&cbuf); 2684 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2685 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2686 %} 2687 2688 // This encoding class is generated automatically from ad_encode.m4. 2689 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2690 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2691 Register src_reg = as_Register($src$$reg); 2692 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2693 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2694 %} 2695 2696 // This encoding class is generated automatically from ad_encode.m4. 2697 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2698 enc_class aarch64_enc_strh0(memory2 mem) %{ 2699 MacroAssembler _masm(&cbuf); 2700 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2701 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2702 %} 2703 2704 // This encoding class is generated automatically from ad_encode.m4. 2705 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2706 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2707 Register src_reg = as_Register($src$$reg); 2708 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2709 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2710 %} 2711 2712 // This encoding class is generated automatically from ad_encode.m4. 2713 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2714 enc_class aarch64_enc_strw0(memory4 mem) %{ 2715 MacroAssembler _masm(&cbuf); 2716 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2717 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2718 %} 2719 2720 // This encoding class is generated automatically from ad_encode.m4. 2721 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2722 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2723 Register src_reg = as_Register($src$$reg); 2724 // we sometimes get asked to store the stack pointer into the 2725 // current thread -- we cannot do that directly on AArch64 2726 if (src_reg == r31_sp) { 2727 MacroAssembler _masm(&cbuf); 2728 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2729 __ mov(rscratch2, sp); 2730 src_reg = rscratch2; 2731 } 2732 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2733 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2734 %} 2735 2736 // This encoding class is generated automatically from ad_encode.m4. 2737 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2738 enc_class aarch64_enc_str0(memory8 mem) %{ 2739 MacroAssembler _masm(&cbuf); 2740 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2741 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2742 %} 2743 2744 // This encoding class is generated automatically from ad_encode.m4. 2745 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2746 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 2747 FloatRegister src_reg = as_FloatRegister($src$$reg); 2748 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2749 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2750 %} 2751 2752 // This encoding class is generated automatically from ad_encode.m4. 2753 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2754 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 2755 FloatRegister src_reg = as_FloatRegister($src$$reg); 2756 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2757 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2758 %} 2759 2760 // This encoding class is generated automatically from ad_encode.m4. 2761 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2762 enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{ 2763 MacroAssembler _masm(&cbuf); 2764 address con = (address)$src$$constant; 2765 // need to do this the hard way until we can manage relocs 2766 // for 32 bit constants 2767 __ movoop(rscratch2, (jobject)con); 2768 if (con) __ encode_heap_oop_not_null(rscratch2); 2769 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2770 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2771 %} 2772 2773 // This encoding class is generated automatically from ad_encode.m4. 2774 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2775 enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{ 2776 MacroAssembler _masm(&cbuf); 2777 address con = (address)$src$$constant; 2778 // need to do this the hard way until we can manage relocs 2779 // for 32 bit constants 2780 __ movoop(rscratch2, (jobject)con); 2781 __ encode_klass_not_null(rscratch2); 2782 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2783 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2784 %} 2785 2786 // This encoding class is generated automatically from ad_encode.m4. 2787 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2788 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 2789 MacroAssembler _masm(&cbuf); 2790 __ membar(Assembler::StoreStore); 2791 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2792 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2793 %} 2794 2795 // END Non-volatile memory access 2796 2797 // Vector loads and stores 2798 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2799 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2800 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2801 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2802 %} 2803 2804 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2805 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2806 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2807 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2808 %} 2809 2810 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2811 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2812 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2813 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2814 %} 2815 2816 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2817 FloatRegister src_reg = as_FloatRegister($src$$reg); 2818 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2819 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2820 %} 2821 2822 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2823 FloatRegister src_reg = as_FloatRegister($src$$reg); 2824 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2825 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2826 %} 2827 2828 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2829 FloatRegister src_reg = as_FloatRegister($src$$reg); 2830 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2831 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2832 %} 2833 2834 // volatile loads and stores 2835 2836 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2837 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2838 rscratch1, stlrb); 2839 %} 2840 2841 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2842 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2843 rscratch1, stlrh); 2844 %} 2845 2846 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2847 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2848 rscratch1, stlrw); 2849 %} 2850 2851 2852 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2853 Register dst_reg = as_Register($dst$$reg); 2854 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2855 rscratch1, ldarb); 2856 __ sxtbw(dst_reg, dst_reg); 2857 %} 2858 2859 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2860 Register dst_reg = as_Register($dst$$reg); 2861 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2862 rscratch1, ldarb); 2863 __ sxtb(dst_reg, dst_reg); 2864 %} 2865 2866 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2867 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2868 rscratch1, ldarb); 2869 %} 2870 2871 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2872 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2873 rscratch1, ldarb); 2874 %} 2875 2876 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2877 Register dst_reg = as_Register($dst$$reg); 2878 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2879 rscratch1, ldarh); 2880 __ sxthw(dst_reg, dst_reg); 2881 %} 2882 2883 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2884 Register dst_reg = as_Register($dst$$reg); 2885 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2886 rscratch1, ldarh); 2887 __ sxth(dst_reg, dst_reg); 2888 %} 2889 2890 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2891 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2892 rscratch1, ldarh); 2893 %} 2894 2895 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2896 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2897 rscratch1, ldarh); 2898 %} 2899 2900 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2901 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2902 rscratch1, ldarw); 2903 %} 2904 2905 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2906 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2907 rscratch1, ldarw); 2908 %} 2909 2910 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2911 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2912 rscratch1, ldar); 2913 %} 2914 2915 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2916 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2917 rscratch1, ldarw); 2918 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2919 %} 2920 2921 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2922 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2923 rscratch1, ldar); 2924 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2925 %} 2926 2927 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2928 Register src_reg = as_Register($src$$reg); 2929 // we sometimes get asked to store the stack pointer into the 2930 // current thread -- we cannot do that directly on AArch64 2931 if (src_reg == r31_sp) { 2932 MacroAssembler _masm(&cbuf); 2933 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2934 __ mov(rscratch2, sp); 2935 src_reg = rscratch2; 2936 } 2937 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2938 rscratch1, stlr); 2939 %} 2940 2941 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2942 { 2943 MacroAssembler _masm(&cbuf); 2944 FloatRegister src_reg = as_FloatRegister($src$$reg); 2945 __ fmovs(rscratch2, src_reg); 2946 } 2947 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2948 rscratch1, stlrw); 2949 %} 2950 2951 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2952 { 2953 MacroAssembler _masm(&cbuf); 2954 FloatRegister src_reg = as_FloatRegister($src$$reg); 2955 __ fmovd(rscratch2, src_reg); 2956 } 2957 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2958 rscratch1, stlr); 2959 %} 2960 2961 // synchronized read/update encodings 2962 2963 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 2964 MacroAssembler _masm(&cbuf); 2965 Register dst_reg = as_Register($dst$$reg); 2966 Register base = as_Register($mem$$base); 2967 int index = $mem$$index; 2968 int scale = $mem$$scale; 2969 int disp = $mem$$disp; 2970 if (index == -1) { 2971 if (disp != 0) { 2972 __ lea(rscratch1, Address(base, disp)); 2973 __ ldaxr(dst_reg, rscratch1); 2974 } else { 2975 // TODO 2976 // should we ever get anything other than this case? 2977 __ ldaxr(dst_reg, base); 2978 } 2979 } else { 2980 Register index_reg = as_Register(index); 2981 if (disp == 0) { 2982 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2983 __ ldaxr(dst_reg, rscratch1); 2984 } else { 2985 __ lea(rscratch1, Address(base, disp)); 2986 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2987 __ ldaxr(dst_reg, rscratch1); 2988 } 2989 } 2990 %} 2991 2992 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 2993 MacroAssembler _masm(&cbuf); 2994 Register src_reg = as_Register($src$$reg); 2995 Register base = as_Register($mem$$base); 2996 int index = $mem$$index; 2997 int scale = $mem$$scale; 2998 int disp = $mem$$disp; 2999 if (index == -1) { 3000 if (disp != 0) { 3001 __ lea(rscratch2, Address(base, disp)); 3002 __ stlxr(rscratch1, src_reg, rscratch2); 3003 } else { 3004 // TODO 3005 // should we ever get anything other than this case? 3006 __ stlxr(rscratch1, src_reg, base); 3007 } 3008 } else { 3009 Register index_reg = as_Register(index); 3010 if (disp == 0) { 3011 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3012 __ stlxr(rscratch1, src_reg, rscratch2); 3013 } else { 3014 __ lea(rscratch2, Address(base, disp)); 3015 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3016 __ stlxr(rscratch1, src_reg, rscratch2); 3017 } 3018 } 3019 __ cmpw(rscratch1, zr); 3020 %} 3021 3022 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3023 MacroAssembler _masm(&cbuf); 3024 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3025 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3026 Assembler::xword, /*acquire*/ false, /*release*/ true, 3027 /*weak*/ false, noreg); 3028 %} 3029 3030 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3031 MacroAssembler _masm(&cbuf); 3032 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3033 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3034 Assembler::word, /*acquire*/ false, /*release*/ true, 3035 /*weak*/ false, noreg); 3036 %} 3037 3038 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3039 MacroAssembler _masm(&cbuf); 3040 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3041 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3042 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3043 /*weak*/ false, noreg); 3044 %} 3045 3046 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3047 MacroAssembler _masm(&cbuf); 3048 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3049 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3050 Assembler::byte, /*acquire*/ false, /*release*/ true, 3051 /*weak*/ false, noreg); 3052 %} 3053 3054 3055 // The only difference between aarch64_enc_cmpxchg and 3056 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3057 // CompareAndSwap sequence to serve as a barrier on acquiring a 3058 // lock. 3059 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3060 MacroAssembler _masm(&cbuf); 3061 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3062 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3063 Assembler::xword, /*acquire*/ true, /*release*/ true, 3064 /*weak*/ false, noreg); 3065 %} 3066 3067 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3068 MacroAssembler _masm(&cbuf); 3069 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3070 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3071 Assembler::word, /*acquire*/ true, /*release*/ true, 3072 /*weak*/ false, noreg); 3073 %} 3074 3075 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3076 MacroAssembler _masm(&cbuf); 3077 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3078 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3079 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3080 /*weak*/ false, noreg); 3081 %} 3082 3083 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3084 MacroAssembler _masm(&cbuf); 3085 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3086 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3087 Assembler::byte, /*acquire*/ true, /*release*/ true, 3088 /*weak*/ false, noreg); 3089 %} 3090 3091 // auxiliary used for CompareAndSwapX to set result register 3092 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3093 MacroAssembler _masm(&cbuf); 3094 Register res_reg = as_Register($res$$reg); 3095 __ cset(res_reg, Assembler::EQ); 3096 %} 3097 3098 // prefetch encodings 3099 3100 enc_class aarch64_enc_prefetchw(memory mem) %{ 3101 MacroAssembler _masm(&cbuf); 3102 Register base = as_Register($mem$$base); 3103 int index = $mem$$index; 3104 int scale = $mem$$scale; 3105 int disp = $mem$$disp; 3106 if (index == -1) { 3107 __ prfm(Address(base, disp), PSTL1KEEP); 3108 } else { 3109 Register index_reg = as_Register(index); 3110 if (disp == 0) { 3111 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3112 } else { 3113 __ lea(rscratch1, Address(base, disp)); 3114 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3115 } 3116 } 3117 %} 3118 3119 /// mov envcodings 3120 3121 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3122 MacroAssembler _masm(&cbuf); 3123 u_int32_t con = (u_int32_t)$src$$constant; 3124 Register dst_reg = as_Register($dst$$reg); 3125 if (con == 0) { 3126 __ movw(dst_reg, zr); 3127 } else { 3128 __ movw(dst_reg, con); 3129 } 3130 %} 3131 3132 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3133 MacroAssembler _masm(&cbuf); 3134 Register dst_reg = as_Register($dst$$reg); 3135 u_int64_t con = (u_int64_t)$src$$constant; 3136 if (con == 0) { 3137 __ mov(dst_reg, zr); 3138 } else { 3139 __ mov(dst_reg, con); 3140 } 3141 %} 3142 3143 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3144 MacroAssembler _masm(&cbuf); 3145 Register dst_reg = as_Register($dst$$reg); 3146 address con = (address)$src$$constant; 3147 if (con == NULL || con == (address)1) { 3148 ShouldNotReachHere(); 3149 } else { 3150 relocInfo::relocType rtype = $src->constant_reloc(); 3151 if (rtype == relocInfo::oop_type) { 3152 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3153 } else if (rtype == relocInfo::metadata_type) { 3154 __ mov_metadata(dst_reg, (Metadata*)con); 3155 } else { 3156 assert(rtype == relocInfo::none, "unexpected reloc type"); 3157 if (con < (address)(uintptr_t)os::vm_page_size()) { 3158 __ mov(dst_reg, con); 3159 } else { 3160 unsigned long offset; 3161 __ adrp(dst_reg, con, offset); 3162 __ add(dst_reg, dst_reg, offset); 3163 } 3164 } 3165 } 3166 %} 3167 3168 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3169 MacroAssembler _masm(&cbuf); 3170 Register dst_reg = as_Register($dst$$reg); 3171 __ mov(dst_reg, zr); 3172 %} 3173 3174 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3175 MacroAssembler _masm(&cbuf); 3176 Register dst_reg = as_Register($dst$$reg); 3177 __ mov(dst_reg, (u_int64_t)1); 3178 %} 3179 3180 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3181 MacroAssembler _masm(&cbuf); 3182 address page = (address)$src$$constant; 3183 Register dst_reg = as_Register($dst$$reg); 3184 unsigned long off; 3185 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3186 assert(off == 0, "assumed offset == 0"); 3187 %} 3188 3189 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3190 MacroAssembler _masm(&cbuf); 3191 __ load_byte_map_base($dst$$Register); 3192 %} 3193 3194 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3195 MacroAssembler _masm(&cbuf); 3196 Register dst_reg = as_Register($dst$$reg); 3197 address con = (address)$src$$constant; 3198 if (con == NULL) { 3199 ShouldNotReachHere(); 3200 } else { 3201 relocInfo::relocType rtype = $src->constant_reloc(); 3202 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3203 __ set_narrow_oop(dst_reg, (jobject)con); 3204 } 3205 %} 3206 3207 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3208 MacroAssembler _masm(&cbuf); 3209 Register dst_reg = as_Register($dst$$reg); 3210 __ mov(dst_reg, zr); 3211 %} 3212 3213 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3214 MacroAssembler _masm(&cbuf); 3215 Register dst_reg = as_Register($dst$$reg); 3216 address con = (address)$src$$constant; 3217 if (con == NULL) { 3218 ShouldNotReachHere(); 3219 } else { 3220 relocInfo::relocType rtype = $src->constant_reloc(); 3221 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3222 __ set_narrow_klass(dst_reg, (Klass *)con); 3223 } 3224 %} 3225 3226 // arithmetic encodings 3227 3228 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3229 MacroAssembler _masm(&cbuf); 3230 Register dst_reg = as_Register($dst$$reg); 3231 Register src_reg = as_Register($src1$$reg); 3232 int32_t con = (int32_t)$src2$$constant; 3233 // add has primary == 0, subtract has primary == 1 3234 if ($primary) { con = -con; } 3235 if (con < 0) { 3236 __ subw(dst_reg, src_reg, -con); 3237 } else { 3238 __ addw(dst_reg, src_reg, con); 3239 } 3240 %} 3241 3242 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3243 MacroAssembler _masm(&cbuf); 3244 Register dst_reg = as_Register($dst$$reg); 3245 Register src_reg = as_Register($src1$$reg); 3246 int32_t con = (int32_t)$src2$$constant; 3247 // add has primary == 0, subtract has primary == 1 3248 if ($primary) { con = -con; } 3249 if (con < 0) { 3250 __ sub(dst_reg, src_reg, -con); 3251 } else { 3252 __ add(dst_reg, src_reg, con); 3253 } 3254 %} 3255 3256 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3257 MacroAssembler _masm(&cbuf); 3258 Register dst_reg = as_Register($dst$$reg); 3259 Register src1_reg = as_Register($src1$$reg); 3260 Register src2_reg = as_Register($src2$$reg); 3261 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3262 %} 3263 3264 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3265 MacroAssembler _masm(&cbuf); 3266 Register dst_reg = as_Register($dst$$reg); 3267 Register src1_reg = as_Register($src1$$reg); 3268 Register src2_reg = as_Register($src2$$reg); 3269 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3270 %} 3271 3272 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3273 MacroAssembler _masm(&cbuf); 3274 Register dst_reg = as_Register($dst$$reg); 3275 Register src1_reg = as_Register($src1$$reg); 3276 Register src2_reg = as_Register($src2$$reg); 3277 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3278 %} 3279 3280 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3281 MacroAssembler _masm(&cbuf); 3282 Register dst_reg = as_Register($dst$$reg); 3283 Register src1_reg = as_Register($src1$$reg); 3284 Register src2_reg = as_Register($src2$$reg); 3285 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3286 %} 3287 3288 // compare instruction encodings 3289 3290 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3291 MacroAssembler _masm(&cbuf); 3292 Register reg1 = as_Register($src1$$reg); 3293 Register reg2 = as_Register($src2$$reg); 3294 __ cmpw(reg1, reg2); 3295 %} 3296 3297 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3298 MacroAssembler _masm(&cbuf); 3299 Register reg = as_Register($src1$$reg); 3300 int32_t val = $src2$$constant; 3301 if (val >= 0) { 3302 __ subsw(zr, reg, val); 3303 } else { 3304 __ addsw(zr, reg, -val); 3305 } 3306 %} 3307 3308 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3309 MacroAssembler _masm(&cbuf); 3310 Register reg1 = as_Register($src1$$reg); 3311 u_int32_t val = (u_int32_t)$src2$$constant; 3312 __ movw(rscratch1, val); 3313 __ cmpw(reg1, rscratch1); 3314 %} 3315 3316 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3317 MacroAssembler _masm(&cbuf); 3318 Register reg1 = as_Register($src1$$reg); 3319 Register reg2 = as_Register($src2$$reg); 3320 __ cmp(reg1, reg2); 3321 %} 3322 3323 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3324 MacroAssembler _masm(&cbuf); 3325 Register reg = as_Register($src1$$reg); 3326 int64_t val = $src2$$constant; 3327 if (val >= 0) { 3328 __ subs(zr, reg, val); 3329 } else if (val != -val) { 3330 __ adds(zr, reg, -val); 3331 } else { 3332 // aargh, Long.MIN_VALUE is a special case 3333 __ orr(rscratch1, zr, (u_int64_t)val); 3334 __ subs(zr, reg, rscratch1); 3335 } 3336 %} 3337 3338 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3339 MacroAssembler _masm(&cbuf); 3340 Register reg1 = as_Register($src1$$reg); 3341 u_int64_t val = (u_int64_t)$src2$$constant; 3342 __ mov(rscratch1, val); 3343 __ cmp(reg1, rscratch1); 3344 %} 3345 3346 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3347 MacroAssembler _masm(&cbuf); 3348 Register reg1 = as_Register($src1$$reg); 3349 Register reg2 = as_Register($src2$$reg); 3350 __ cmp(reg1, reg2); 3351 %} 3352 3353 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3354 MacroAssembler _masm(&cbuf); 3355 Register reg1 = as_Register($src1$$reg); 3356 Register reg2 = as_Register($src2$$reg); 3357 __ cmpw(reg1, reg2); 3358 %} 3359 3360 enc_class aarch64_enc_testp(iRegP src) %{ 3361 MacroAssembler _masm(&cbuf); 3362 Register reg = as_Register($src$$reg); 3363 __ cmp(reg, zr); 3364 %} 3365 3366 enc_class aarch64_enc_testn(iRegN src) %{ 3367 MacroAssembler _masm(&cbuf); 3368 Register reg = as_Register($src$$reg); 3369 __ cmpw(reg, zr); 3370 %} 3371 3372 enc_class aarch64_enc_b(label lbl) %{ 3373 MacroAssembler _masm(&cbuf); 3374 Label *L = $lbl$$label; 3375 __ b(*L); 3376 %} 3377 3378 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3379 MacroAssembler _masm(&cbuf); 3380 Label *L = $lbl$$label; 3381 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3382 %} 3383 3384 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3385 MacroAssembler _masm(&cbuf); 3386 Label *L = $lbl$$label; 3387 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3388 %} 3389 3390 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3391 %{ 3392 Register sub_reg = as_Register($sub$$reg); 3393 Register super_reg = as_Register($super$$reg); 3394 Register temp_reg = as_Register($temp$$reg); 3395 Register result_reg = as_Register($result$$reg); 3396 3397 Label miss; 3398 MacroAssembler _masm(&cbuf); 3399 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3400 NULL, &miss, 3401 /*set_cond_codes:*/ true); 3402 if ($primary) { 3403 __ mov(result_reg, zr); 3404 } 3405 __ bind(miss); 3406 %} 3407 3408 enc_class aarch64_enc_java_static_call(method meth) %{ 3409 MacroAssembler _masm(&cbuf); 3410 3411 address addr = (address)$meth$$method; 3412 address call; 3413 if (!_method) { 3414 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3415 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3416 } else { 3417 int method_index = resolved_method_index(cbuf); 3418 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3419 : static_call_Relocation::spec(method_index); 3420 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3421 3422 // Emit stub for static call 3423 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3424 if (stub == NULL) { 3425 ciEnv::current()->record_failure("CodeCache is full"); 3426 return; 3427 } 3428 } 3429 if (call == NULL) { 3430 ciEnv::current()->record_failure("CodeCache is full"); 3431 return; 3432 } 3433 %} 3434 3435 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3436 MacroAssembler _masm(&cbuf); 3437 int method_index = resolved_method_index(cbuf); 3438 address call = __ ic_call((address)$meth$$method, method_index); 3439 if (call == NULL) { 3440 ciEnv::current()->record_failure("CodeCache is full"); 3441 return; 3442 } 3443 %} 3444 3445 enc_class aarch64_enc_call_epilog() %{ 3446 MacroAssembler _masm(&cbuf); 3447 if (VerifyStackAtCalls) { 3448 // Check that stack depth is unchanged: find majik cookie on stack 3449 __ call_Unimplemented(); 3450 } 3451 %} 3452 3453 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3454 MacroAssembler _masm(&cbuf); 3455 3456 // some calls to generated routines (arraycopy code) are scheduled 3457 // by C2 as runtime calls. if so we can call them using a br (they 3458 // will be in a reachable segment) otherwise we have to use a blr 3459 // which loads the absolute address into a register. 3460 address entry = (address)$meth$$method; 3461 CodeBlob *cb = CodeCache::find_blob(entry); 3462 if (cb) { 3463 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3464 if (call == NULL) { 3465 ciEnv::current()->record_failure("CodeCache is full"); 3466 return; 3467 } 3468 } else { 3469 Label retaddr; 3470 __ adr(rscratch2, retaddr); 3471 __ lea(rscratch1, RuntimeAddress(entry)); 3472 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3473 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3474 __ blr(rscratch1); 3475 __ bind(retaddr); 3476 __ add(sp, sp, 2 * wordSize); 3477 } 3478 %} 3479 3480 enc_class aarch64_enc_rethrow() %{ 3481 MacroAssembler _masm(&cbuf); 3482 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3483 %} 3484 3485 enc_class aarch64_enc_ret() %{ 3486 MacroAssembler _masm(&cbuf); 3487 __ ret(lr); 3488 %} 3489 3490 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3491 MacroAssembler _masm(&cbuf); 3492 Register target_reg = as_Register($jump_target$$reg); 3493 __ br(target_reg); 3494 %} 3495 3496 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3497 MacroAssembler _masm(&cbuf); 3498 Register target_reg = as_Register($jump_target$$reg); 3499 // exception oop should be in r0 3500 // ret addr has been popped into lr 3501 // callee expects it in r3 3502 __ mov(r3, lr); 3503 __ br(target_reg); 3504 %} 3505 3506 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3507 MacroAssembler _masm(&cbuf); 3508 Register oop = as_Register($object$$reg); 3509 Register box = as_Register($box$$reg); 3510 Register disp_hdr = as_Register($tmp$$reg); 3511 Register tmp = as_Register($tmp2$$reg); 3512 Label cont; 3513 Label object_has_monitor; 3514 Label cas_failed; 3515 3516 assert_different_registers(oop, box, tmp, disp_hdr); 3517 3518 // Load markWord from object into displaced_header. 3519 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3520 3521 if (UseBiasedLocking && !UseOptoBiasInlining) { 3522 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3523 } 3524 3525 // Check for existing monitor 3526 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3527 3528 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3529 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3530 3531 // Initialize the box. (Must happen before we update the object mark!) 3532 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3533 3534 // Compare object markWord with an unlocked value (tmp) and if 3535 // equal exchange the stack address of our box with object markWord. 3536 // On failure disp_hdr contains the possibly locked markWord. 3537 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3538 /*release*/ true, /*weak*/ false, disp_hdr); 3539 __ br(Assembler::EQ, cont); 3540 3541 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3542 3543 // If the compare-and-exchange succeeded, then we found an unlocked 3544 // object, will have now locked it will continue at label cont 3545 3546 __ bind(cas_failed); 3547 // We did not see an unlocked object so try the fast recursive case. 3548 3549 // Check if the owner is self by comparing the value in the 3550 // markWord of object (disp_hdr) with the stack pointer. 3551 __ mov(rscratch1, sp); 3552 __ sub(disp_hdr, disp_hdr, rscratch1); 3553 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3554 // If condition is true we are cont and hence we can store 0 as the 3555 // displaced header in the box, which indicates that it is a recursive lock. 3556 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3557 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3558 3559 __ b(cont); 3560 3561 // Handle existing monitor. 3562 __ bind(object_has_monitor); 3563 3564 // The object's monitor m is unlocked iff m->owner == NULL, 3565 // otherwise m->owner may contain a thread or a stack address. 3566 // 3567 // Try to CAS m->owner from NULL to current thread. 3568 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3569 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3570 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3571 3572 // Store a non-null value into the box to avoid looking like a re-entrant 3573 // lock. The fast-path monitor unlock code checks for 3574 // markWord::monitor_value so use markWord::unused_mark which has the 3575 // relevant bit set, and also matches ObjectSynchronizer::enter. 3576 __ mov(tmp, (address)markWord::unused_mark().value()); 3577 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3578 3579 __ bind(cont); 3580 // flag == EQ indicates success 3581 // flag == NE indicates failure 3582 %} 3583 3584 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3585 MacroAssembler _masm(&cbuf); 3586 Register oop = as_Register($object$$reg); 3587 Register box = as_Register($box$$reg); 3588 Register disp_hdr = as_Register($tmp$$reg); 3589 Register tmp = as_Register($tmp2$$reg); 3590 Label cont; 3591 Label object_has_monitor; 3592 3593 assert_different_registers(oop, box, tmp, disp_hdr); 3594 3595 if (UseBiasedLocking && !UseOptoBiasInlining) { 3596 __ biased_locking_exit(oop, tmp, cont); 3597 } 3598 3599 // Find the lock address and load the displaced header from the stack. 3600 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3601 3602 // If the displaced header is 0, we have a recursive unlock. 3603 __ cmp(disp_hdr, zr); 3604 __ br(Assembler::EQ, cont); 3605 3606 // Handle existing monitor. 3607 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3608 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3609 3610 // Check if it is still a light weight lock, this is is true if we 3611 // see the stack address of the basicLock in the markWord of the 3612 // object. 3613 3614 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3615 /*release*/ true, /*weak*/ false, tmp); 3616 __ b(cont); 3617 3618 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3619 3620 // Handle existing monitor. 3621 __ bind(object_has_monitor); 3622 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3623 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3624 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3625 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3626 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3627 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3628 __ cmp(rscratch1, zr); // Sets flags for result 3629 __ br(Assembler::NE, cont); 3630 3631 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3632 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3633 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3634 __ cmp(rscratch1, zr); // Sets flags for result 3635 __ cbnz(rscratch1, cont); 3636 // need a release store here 3637 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3638 __ stlr(zr, tmp); // set unowned 3639 3640 __ bind(cont); 3641 // flag == EQ indicates success 3642 // flag == NE indicates failure 3643 %} 3644 3645 %} 3646 3647 //----------FRAME-------------------------------------------------------------- 3648 // Definition of frame structure and management information. 3649 // 3650 // S T A C K L A Y O U T Allocators stack-slot number 3651 // | (to get allocators register number 3652 // G Owned by | | v add OptoReg::stack0()) 3653 // r CALLER | | 3654 // o | +--------+ pad to even-align allocators stack-slot 3655 // w V | pad0 | numbers; owned by CALLER 3656 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3657 // h ^ | in | 5 3658 // | | args | 4 Holes in incoming args owned by SELF 3659 // | | | | 3 3660 // | | +--------+ 3661 // V | | old out| Empty on Intel, window on Sparc 3662 // | old |preserve| Must be even aligned. 3663 // | SP-+--------+----> Matcher::_old_SP, even aligned 3664 // | | in | 3 area for Intel ret address 3665 // Owned by |preserve| Empty on Sparc. 3666 // SELF +--------+ 3667 // | | pad2 | 2 pad to align old SP 3668 // | +--------+ 1 3669 // | | locks | 0 3670 // | +--------+----> OptoReg::stack0(), even aligned 3671 // | | pad1 | 11 pad to align new SP 3672 // | +--------+ 3673 // | | | 10 3674 // | | spills | 9 spills 3675 // V | | 8 (pad0 slot for callee) 3676 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3677 // ^ | out | 7 3678 // | | args | 6 Holes in outgoing args owned by CALLEE 3679 // Owned by +--------+ 3680 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3681 // | new |preserve| Must be even-aligned. 3682 // | SP-+--------+----> Matcher::_new_SP, even aligned 3683 // | | | 3684 // 3685 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3686 // known from SELF's arguments and the Java calling convention. 3687 // Region 6-7 is determined per call site. 3688 // Note 2: If the calling convention leaves holes in the incoming argument 3689 // area, those holes are owned by SELF. Holes in the outgoing area 3690 // are owned by the CALLEE. Holes should not be nessecary in the 3691 // incoming area, as the Java calling convention is completely under 3692 // the control of the AD file. Doubles can be sorted and packed to 3693 // avoid holes. Holes in the outgoing arguments may be nessecary for 3694 // varargs C calling conventions. 3695 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3696 // even aligned with pad0 as needed. 3697 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3698 // (the latter is true on Intel but is it false on AArch64?) 3699 // region 6-11 is even aligned; it may be padded out more so that 3700 // the region from SP to FP meets the minimum stack alignment. 3701 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3702 // alignment. Region 11, pad1, may be dynamically extended so that 3703 // SP meets the minimum alignment. 3704 3705 frame %{ 3706 // What direction does stack grow in (assumed to be same for C & Java) 3707 stack_direction(TOWARDS_LOW); 3708 3709 // These three registers define part of the calling convention 3710 // between compiled code and the interpreter. 3711 3712 // Inline Cache Register or methodOop for I2C. 3713 inline_cache_reg(R12); 3714 3715 // Method Oop Register when calling interpreter. 3716 interpreter_method_oop_reg(R12); 3717 3718 // Number of stack slots consumed by locking an object 3719 sync_stack_slots(2); 3720 3721 // Compiled code's Frame Pointer 3722 frame_pointer(R31); 3723 3724 // Interpreter stores its frame pointer in a register which is 3725 // stored to the stack by I2CAdaptors. 3726 // I2CAdaptors convert from interpreted java to compiled java. 3727 interpreter_frame_pointer(R29); 3728 3729 // Stack alignment requirement 3730 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3731 3732 // Number of stack slots between incoming argument block and the start of 3733 // a new frame. The PROLOG must add this many slots to the stack. The 3734 // EPILOG must remove this many slots. aarch64 needs two slots for 3735 // return address and fp. 3736 // TODO think this is correct but check 3737 in_preserve_stack_slots(4); 3738 3739 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3740 // for calls to C. Supports the var-args backing area for register parms. 3741 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3742 3743 // The after-PROLOG location of the return address. Location of 3744 // return address specifies a type (REG or STACK) and a number 3745 // representing the register number (i.e. - use a register name) or 3746 // stack slot. 3747 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3748 // Otherwise, it is above the locks and verification slot and alignment word 3749 // TODO this may well be correct but need to check why that - 2 is there 3750 // ppc port uses 0 but we definitely need to allow for fixed_slots 3751 // which folds in the space used for monitors 3752 return_addr(STACK - 2 + 3753 align_up((Compile::current()->in_preserve_stack_slots() + 3754 Compile::current()->fixed_slots()), 3755 stack_alignment_in_slots())); 3756 3757 // Body of function which returns an integer array locating 3758 // arguments either in registers or in stack slots. Passed an array 3759 // of ideal registers called "sig" and a "length" count. Stack-slot 3760 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3761 // arguments for a CALLEE. Incoming stack arguments are 3762 // automatically biased by the preserve_stack_slots field above. 3763 3764 calling_convention 3765 %{ 3766 // No difference between ingoing/outgoing just pass false 3767 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3768 %} 3769 3770 c_calling_convention 3771 %{ 3772 // This is obviously always outgoing 3773 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3774 %} 3775 3776 // Location of compiled Java return values. Same as C for now. 3777 return_value 3778 %{ 3779 // TODO do we allow ideal_reg == Op_RegN??? 3780 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3781 "only return normal values"); 3782 3783 static const int lo[Op_RegL + 1] = { // enum name 3784 0, // Op_Node 3785 0, // Op_Set 3786 R0_num, // Op_RegN 3787 R0_num, // Op_RegI 3788 R0_num, // Op_RegP 3789 V0_num, // Op_RegF 3790 V0_num, // Op_RegD 3791 R0_num // Op_RegL 3792 }; 3793 3794 static const int hi[Op_RegL + 1] = { // enum name 3795 0, // Op_Node 3796 0, // Op_Set 3797 OptoReg::Bad, // Op_RegN 3798 OptoReg::Bad, // Op_RegI 3799 R0_H_num, // Op_RegP 3800 OptoReg::Bad, // Op_RegF 3801 V0_H_num, // Op_RegD 3802 R0_H_num // Op_RegL 3803 }; 3804 3805 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3806 %} 3807 %} 3808 3809 //----------ATTRIBUTES--------------------------------------------------------- 3810 //----------Operand Attributes------------------------------------------------- 3811 op_attrib op_cost(1); // Required cost attribute 3812 3813 //----------Instruction Attributes--------------------------------------------- 3814 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3815 ins_attrib ins_size(32); // Required size attribute (in bits) 3816 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3817 // a non-matching short branch variant 3818 // of some long branch? 3819 ins_attrib ins_alignment(4); // Required alignment attribute (must 3820 // be a power of 2) specifies the 3821 // alignment that some part of the 3822 // instruction (not necessarily the 3823 // start) requires. If > 1, a 3824 // compute_padding() function must be 3825 // provided for the instruction 3826 3827 //----------OPERANDS----------------------------------------------------------- 3828 // Operand definitions must precede instruction definitions for correct parsing 3829 // in the ADLC because operands constitute user defined types which are used in 3830 // instruction definitions. 3831 3832 //----------Simple Operands---------------------------------------------------- 3833 3834 // Integer operands 32 bit 3835 // 32 bit immediate 3836 operand immI() 3837 %{ 3838 match(ConI); 3839 3840 op_cost(0); 3841 format %{ %} 3842 interface(CONST_INTER); 3843 %} 3844 3845 // 32 bit zero 3846 operand immI0() 3847 %{ 3848 predicate(n->get_int() == 0); 3849 match(ConI); 3850 3851 op_cost(0); 3852 format %{ %} 3853 interface(CONST_INTER); 3854 %} 3855 3856 // 32 bit unit increment 3857 operand immI_1() 3858 %{ 3859 predicate(n->get_int() == 1); 3860 match(ConI); 3861 3862 op_cost(0); 3863 format %{ %} 3864 interface(CONST_INTER); 3865 %} 3866 3867 // 32 bit unit decrement 3868 operand immI_M1() 3869 %{ 3870 predicate(n->get_int() == -1); 3871 match(ConI); 3872 3873 op_cost(0); 3874 format %{ %} 3875 interface(CONST_INTER); 3876 %} 3877 3878 // Shift values for add/sub extension shift 3879 operand immIExt() 3880 %{ 3881 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3882 match(ConI); 3883 3884 op_cost(0); 3885 format %{ %} 3886 interface(CONST_INTER); 3887 %} 3888 3889 operand immI_le_4() 3890 %{ 3891 predicate(n->get_int() <= 4); 3892 match(ConI); 3893 3894 op_cost(0); 3895 format %{ %} 3896 interface(CONST_INTER); 3897 %} 3898 3899 operand immI_31() 3900 %{ 3901 predicate(n->get_int() == 31); 3902 match(ConI); 3903 3904 op_cost(0); 3905 format %{ %} 3906 interface(CONST_INTER); 3907 %} 3908 3909 operand immI_8() 3910 %{ 3911 predicate(n->get_int() == 8); 3912 match(ConI); 3913 3914 op_cost(0); 3915 format %{ %} 3916 interface(CONST_INTER); 3917 %} 3918 3919 operand immI_16() 3920 %{ 3921 predicate(n->get_int() == 16); 3922 match(ConI); 3923 3924 op_cost(0); 3925 format %{ %} 3926 interface(CONST_INTER); 3927 %} 3928 3929 operand immI_24() 3930 %{ 3931 predicate(n->get_int() == 24); 3932 match(ConI); 3933 3934 op_cost(0); 3935 format %{ %} 3936 interface(CONST_INTER); 3937 %} 3938 3939 operand immI_32() 3940 %{ 3941 predicate(n->get_int() == 32); 3942 match(ConI); 3943 3944 op_cost(0); 3945 format %{ %} 3946 interface(CONST_INTER); 3947 %} 3948 3949 operand immI_48() 3950 %{ 3951 predicate(n->get_int() == 48); 3952 match(ConI); 3953 3954 op_cost(0); 3955 format %{ %} 3956 interface(CONST_INTER); 3957 %} 3958 3959 operand immI_56() 3960 %{ 3961 predicate(n->get_int() == 56); 3962 match(ConI); 3963 3964 op_cost(0); 3965 format %{ %} 3966 interface(CONST_INTER); 3967 %} 3968 3969 operand immI_63() 3970 %{ 3971 predicate(n->get_int() == 63); 3972 match(ConI); 3973 3974 op_cost(0); 3975 format %{ %} 3976 interface(CONST_INTER); 3977 %} 3978 3979 operand immI_64() 3980 %{ 3981 predicate(n->get_int() == 64); 3982 match(ConI); 3983 3984 op_cost(0); 3985 format %{ %} 3986 interface(CONST_INTER); 3987 %} 3988 3989 operand immI_255() 3990 %{ 3991 predicate(n->get_int() == 255); 3992 match(ConI); 3993 3994 op_cost(0); 3995 format %{ %} 3996 interface(CONST_INTER); 3997 %} 3998 3999 operand immI_65535() 4000 %{ 4001 predicate(n->get_int() == 65535); 4002 match(ConI); 4003 4004 op_cost(0); 4005 format %{ %} 4006 interface(CONST_INTER); 4007 %} 4008 4009 operand immL_255() 4010 %{ 4011 predicate(n->get_long() == 255L); 4012 match(ConL); 4013 4014 op_cost(0); 4015 format %{ %} 4016 interface(CONST_INTER); 4017 %} 4018 4019 operand immL_65535() 4020 %{ 4021 predicate(n->get_long() == 65535L); 4022 match(ConL); 4023 4024 op_cost(0); 4025 format %{ %} 4026 interface(CONST_INTER); 4027 %} 4028 4029 operand immL_4294967295() 4030 %{ 4031 predicate(n->get_long() == 4294967295L); 4032 match(ConL); 4033 4034 op_cost(0); 4035 format %{ %} 4036 interface(CONST_INTER); 4037 %} 4038 4039 operand immL_bitmask() 4040 %{ 4041 predicate((n->get_long() != 0) 4042 && ((n->get_long() & 0xc000000000000000l) == 0) 4043 && is_power_of_2(n->get_long() + 1)); 4044 match(ConL); 4045 4046 op_cost(0); 4047 format %{ %} 4048 interface(CONST_INTER); 4049 %} 4050 4051 operand immI_bitmask() 4052 %{ 4053 predicate((n->get_int() != 0) 4054 && ((n->get_int() & 0xc0000000) == 0) 4055 && is_power_of_2(n->get_int() + 1)); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 // Scale values for scaled offset addressing modes (up to long but not quad) 4064 operand immIScale() 4065 %{ 4066 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 // 26 bit signed offset -- for pc-relative branches 4075 operand immI26() 4076 %{ 4077 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4078 match(ConI); 4079 4080 op_cost(0); 4081 format %{ %} 4082 interface(CONST_INTER); 4083 %} 4084 4085 // 19 bit signed offset -- for pc-relative loads 4086 operand immI19() 4087 %{ 4088 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4089 match(ConI); 4090 4091 op_cost(0); 4092 format %{ %} 4093 interface(CONST_INTER); 4094 %} 4095 4096 // 12 bit unsigned offset -- for base plus immediate loads 4097 operand immIU12() 4098 %{ 4099 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4100 match(ConI); 4101 4102 op_cost(0); 4103 format %{ %} 4104 interface(CONST_INTER); 4105 %} 4106 4107 operand immLU12() 4108 %{ 4109 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4110 match(ConL); 4111 4112 op_cost(0); 4113 format %{ %} 4114 interface(CONST_INTER); 4115 %} 4116 4117 // Offset for scaled or unscaled immediate loads and stores 4118 operand immIOffset() 4119 %{ 4120 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4121 match(ConI); 4122 4123 op_cost(0); 4124 format %{ %} 4125 interface(CONST_INTER); 4126 %} 4127 4128 operand immIOffset1() 4129 %{ 4130 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4131 match(ConI); 4132 4133 op_cost(0); 4134 format %{ %} 4135 interface(CONST_INTER); 4136 %} 4137 4138 operand immIOffset2() 4139 %{ 4140 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4141 match(ConI); 4142 4143 op_cost(0); 4144 format %{ %} 4145 interface(CONST_INTER); 4146 %} 4147 4148 operand immIOffset4() 4149 %{ 4150 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4151 match(ConI); 4152 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 operand immIOffset8() 4159 %{ 4160 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4161 match(ConI); 4162 4163 op_cost(0); 4164 format %{ %} 4165 interface(CONST_INTER); 4166 %} 4167 4168 operand immIOffset16() 4169 %{ 4170 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4171 match(ConI); 4172 4173 op_cost(0); 4174 format %{ %} 4175 interface(CONST_INTER); 4176 %} 4177 4178 operand immLoffset() 4179 %{ 4180 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4181 match(ConL); 4182 4183 op_cost(0); 4184 format %{ %} 4185 interface(CONST_INTER); 4186 %} 4187 4188 operand immLoffset1() 4189 %{ 4190 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4191 match(ConL); 4192 4193 op_cost(0); 4194 format %{ %} 4195 interface(CONST_INTER); 4196 %} 4197 4198 operand immLoffset2() 4199 %{ 4200 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4201 match(ConL); 4202 4203 op_cost(0); 4204 format %{ %} 4205 interface(CONST_INTER); 4206 %} 4207 4208 operand immLoffset4() 4209 %{ 4210 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4211 match(ConL); 4212 4213 op_cost(0); 4214 format %{ %} 4215 interface(CONST_INTER); 4216 %} 4217 4218 operand immLoffset8() 4219 %{ 4220 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4221 match(ConL); 4222 4223 op_cost(0); 4224 format %{ %} 4225 interface(CONST_INTER); 4226 %} 4227 4228 operand immLoffset16() 4229 %{ 4230 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4231 match(ConL); 4232 4233 op_cost(0); 4234 format %{ %} 4235 interface(CONST_INTER); 4236 %} 4237 4238 // 32 bit integer valid for add sub immediate 4239 operand immIAddSub() 4240 %{ 4241 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4242 match(ConI); 4243 op_cost(0); 4244 format %{ %} 4245 interface(CONST_INTER); 4246 %} 4247 4248 // 32 bit unsigned integer valid for logical immediate 4249 // TODO -- check this is right when e.g the mask is 0x80000000 4250 operand immILog() 4251 %{ 4252 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4253 match(ConI); 4254 4255 op_cost(0); 4256 format %{ %} 4257 interface(CONST_INTER); 4258 %} 4259 4260 // Integer operands 64 bit 4261 // 64 bit immediate 4262 operand immL() 4263 %{ 4264 match(ConL); 4265 4266 op_cost(0); 4267 format %{ %} 4268 interface(CONST_INTER); 4269 %} 4270 4271 // 64 bit zero 4272 operand immL0() 4273 %{ 4274 predicate(n->get_long() == 0); 4275 match(ConL); 4276 4277 op_cost(0); 4278 format %{ %} 4279 interface(CONST_INTER); 4280 %} 4281 4282 // 64 bit unit increment 4283 operand immL_1() 4284 %{ 4285 predicate(n->get_long() == 1); 4286 match(ConL); 4287 4288 op_cost(0); 4289 format %{ %} 4290 interface(CONST_INTER); 4291 %} 4292 4293 // 64 bit unit decrement 4294 operand immL_M1() 4295 %{ 4296 predicate(n->get_long() == -1); 4297 match(ConL); 4298 4299 op_cost(0); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 // 32 bit offset of pc in thread anchor 4305 4306 operand immL_pc_off() 4307 %{ 4308 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4309 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4310 match(ConL); 4311 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // 64 bit integer valid for add sub immediate 4318 operand immLAddSub() 4319 %{ 4320 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4321 match(ConL); 4322 op_cost(0); 4323 format %{ %} 4324 interface(CONST_INTER); 4325 %} 4326 4327 // 64 bit integer valid for logical immediate 4328 operand immLLog() 4329 %{ 4330 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4331 match(ConL); 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // Long Immediate: low 32-bit mask 4338 operand immL_32bits() 4339 %{ 4340 predicate(n->get_long() == 0xFFFFFFFFL); 4341 match(ConL); 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Pointer operands 4348 // Pointer Immediate 4349 operand immP() 4350 %{ 4351 match(ConP); 4352 4353 op_cost(0); 4354 format %{ %} 4355 interface(CONST_INTER); 4356 %} 4357 4358 // NULL Pointer Immediate 4359 operand immP0() 4360 %{ 4361 predicate(n->get_ptr() == 0); 4362 match(ConP); 4363 4364 op_cost(0); 4365 format %{ %} 4366 interface(CONST_INTER); 4367 %} 4368 4369 // Pointer Immediate One 4370 // this is used in object initialization (initial object header) 4371 operand immP_1() 4372 %{ 4373 predicate(n->get_ptr() == 1); 4374 match(ConP); 4375 4376 op_cost(0); 4377 format %{ %} 4378 interface(CONST_INTER); 4379 %} 4380 4381 // Polling Page Pointer Immediate 4382 operand immPollPage() 4383 %{ 4384 predicate((address)n->get_ptr() == os::get_polling_page()); 4385 match(ConP); 4386 4387 op_cost(0); 4388 format %{ %} 4389 interface(CONST_INTER); 4390 %} 4391 4392 // Card Table Byte Map Base 4393 operand immByteMapBase() 4394 %{ 4395 // Get base of card map 4396 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4397 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4398 match(ConP); 4399 4400 op_cost(0); 4401 format %{ %} 4402 interface(CONST_INTER); 4403 %} 4404 4405 // Pointer Immediate Minus One 4406 // this is used when we want to write the current PC to the thread anchor 4407 operand immP_M1() 4408 %{ 4409 predicate(n->get_ptr() == -1); 4410 match(ConP); 4411 4412 op_cost(0); 4413 format %{ %} 4414 interface(CONST_INTER); 4415 %} 4416 4417 // Pointer Immediate Minus Two 4418 // this is used when we want to write the current PC to the thread anchor 4419 operand immP_M2() 4420 %{ 4421 predicate(n->get_ptr() == -2); 4422 match(ConP); 4423 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // Float and Double operands 4430 // Double Immediate 4431 operand immD() 4432 %{ 4433 match(ConD); 4434 op_cost(0); 4435 format %{ %} 4436 interface(CONST_INTER); 4437 %} 4438 4439 // Double Immediate: +0.0d 4440 operand immD0() 4441 %{ 4442 predicate(jlong_cast(n->getd()) == 0); 4443 match(ConD); 4444 4445 op_cost(0); 4446 format %{ %} 4447 interface(CONST_INTER); 4448 %} 4449 4450 // constant 'double +0.0'. 4451 operand immDPacked() 4452 %{ 4453 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4454 match(ConD); 4455 op_cost(0); 4456 format %{ %} 4457 interface(CONST_INTER); 4458 %} 4459 4460 // Float Immediate 4461 operand immF() 4462 %{ 4463 match(ConF); 4464 op_cost(0); 4465 format %{ %} 4466 interface(CONST_INTER); 4467 %} 4468 4469 // Float Immediate: +0.0f. 4470 operand immF0() 4471 %{ 4472 predicate(jint_cast(n->getf()) == 0); 4473 match(ConF); 4474 4475 op_cost(0); 4476 format %{ %} 4477 interface(CONST_INTER); 4478 %} 4479 4480 // 4481 operand immFPacked() 4482 %{ 4483 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4484 match(ConF); 4485 op_cost(0); 4486 format %{ %} 4487 interface(CONST_INTER); 4488 %} 4489 4490 // Narrow pointer operands 4491 // Narrow Pointer Immediate 4492 operand immN() 4493 %{ 4494 match(ConN); 4495 4496 op_cost(0); 4497 format %{ %} 4498 interface(CONST_INTER); 4499 %} 4500 4501 // Narrow NULL Pointer Immediate 4502 operand immN0() 4503 %{ 4504 predicate(n->get_narrowcon() == 0); 4505 match(ConN); 4506 4507 op_cost(0); 4508 format %{ %} 4509 interface(CONST_INTER); 4510 %} 4511 4512 operand immNKlass() 4513 %{ 4514 match(ConNKlass); 4515 4516 op_cost(0); 4517 format %{ %} 4518 interface(CONST_INTER); 4519 %} 4520 4521 // Integer 32 bit Register Operands 4522 // Integer 32 bitRegister (excludes SP) 4523 operand iRegI() 4524 %{ 4525 constraint(ALLOC_IN_RC(any_reg32)); 4526 match(RegI); 4527 match(iRegINoSp); 4528 op_cost(0); 4529 format %{ %} 4530 interface(REG_INTER); 4531 %} 4532 4533 // Integer 32 bit Register not Special 4534 operand iRegINoSp() 4535 %{ 4536 constraint(ALLOC_IN_RC(no_special_reg32)); 4537 match(RegI); 4538 op_cost(0); 4539 format %{ %} 4540 interface(REG_INTER); 4541 %} 4542 4543 // Integer 64 bit Register Operands 4544 // Integer 64 bit Register (includes SP) 4545 operand iRegL() 4546 %{ 4547 constraint(ALLOC_IN_RC(any_reg)); 4548 match(RegL); 4549 match(iRegLNoSp); 4550 op_cost(0); 4551 format %{ %} 4552 interface(REG_INTER); 4553 %} 4554 4555 // Integer 64 bit Register not Special 4556 operand iRegLNoSp() 4557 %{ 4558 constraint(ALLOC_IN_RC(no_special_reg)); 4559 match(RegL); 4560 match(iRegL_R0); 4561 format %{ %} 4562 interface(REG_INTER); 4563 %} 4564 4565 // Pointer Register Operands 4566 // Pointer Register 4567 operand iRegP() 4568 %{ 4569 constraint(ALLOC_IN_RC(ptr_reg)); 4570 match(RegP); 4571 match(iRegPNoSp); 4572 match(iRegP_R0); 4573 //match(iRegP_R2); 4574 //match(iRegP_R4); 4575 //match(iRegP_R5); 4576 match(thread_RegP); 4577 op_cost(0); 4578 format %{ %} 4579 interface(REG_INTER); 4580 %} 4581 4582 // Pointer 64 bit Register not Special 4583 operand iRegPNoSp() 4584 %{ 4585 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4586 match(RegP); 4587 // match(iRegP); 4588 // match(iRegP_R0); 4589 // match(iRegP_R2); 4590 // match(iRegP_R4); 4591 // match(iRegP_R5); 4592 // match(thread_RegP); 4593 op_cost(0); 4594 format %{ %} 4595 interface(REG_INTER); 4596 %} 4597 4598 // Pointer 64 bit Register R0 only 4599 operand iRegP_R0() 4600 %{ 4601 constraint(ALLOC_IN_RC(r0_reg)); 4602 match(RegP); 4603 // match(iRegP); 4604 match(iRegPNoSp); 4605 op_cost(0); 4606 format %{ %} 4607 interface(REG_INTER); 4608 %} 4609 4610 // Pointer 64 bit Register R1 only 4611 operand iRegP_R1() 4612 %{ 4613 constraint(ALLOC_IN_RC(r1_reg)); 4614 match(RegP); 4615 // match(iRegP); 4616 match(iRegPNoSp); 4617 op_cost(0); 4618 format %{ %} 4619 interface(REG_INTER); 4620 %} 4621 4622 // Pointer 64 bit Register R2 only 4623 operand iRegP_R2() 4624 %{ 4625 constraint(ALLOC_IN_RC(r2_reg)); 4626 match(RegP); 4627 // match(iRegP); 4628 match(iRegPNoSp); 4629 op_cost(0); 4630 format %{ %} 4631 interface(REG_INTER); 4632 %} 4633 4634 // Pointer 64 bit Register R3 only 4635 operand iRegP_R3() 4636 %{ 4637 constraint(ALLOC_IN_RC(r3_reg)); 4638 match(RegP); 4639 // match(iRegP); 4640 match(iRegPNoSp); 4641 op_cost(0); 4642 format %{ %} 4643 interface(REG_INTER); 4644 %} 4645 4646 // Pointer 64 bit Register R4 only 4647 operand iRegP_R4() 4648 %{ 4649 constraint(ALLOC_IN_RC(r4_reg)); 4650 match(RegP); 4651 // match(iRegP); 4652 match(iRegPNoSp); 4653 op_cost(0); 4654 format %{ %} 4655 interface(REG_INTER); 4656 %} 4657 4658 // Pointer 64 bit Register R5 only 4659 operand iRegP_R5() 4660 %{ 4661 constraint(ALLOC_IN_RC(r5_reg)); 4662 match(RegP); 4663 // match(iRegP); 4664 match(iRegPNoSp); 4665 op_cost(0); 4666 format %{ %} 4667 interface(REG_INTER); 4668 %} 4669 4670 // Pointer 64 bit Register R10 only 4671 operand iRegP_R10() 4672 %{ 4673 constraint(ALLOC_IN_RC(r10_reg)); 4674 match(RegP); 4675 // match(iRegP); 4676 match(iRegPNoSp); 4677 op_cost(0); 4678 format %{ %} 4679 interface(REG_INTER); 4680 %} 4681 4682 // Long 64 bit Register R0 only 4683 operand iRegL_R0() 4684 %{ 4685 constraint(ALLOC_IN_RC(r0_reg)); 4686 match(RegL); 4687 match(iRegLNoSp); 4688 op_cost(0); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 // Long 64 bit Register R2 only 4694 operand iRegL_R2() 4695 %{ 4696 constraint(ALLOC_IN_RC(r2_reg)); 4697 match(RegL); 4698 match(iRegLNoSp); 4699 op_cost(0); 4700 format %{ %} 4701 interface(REG_INTER); 4702 %} 4703 4704 // Long 64 bit Register R3 only 4705 operand iRegL_R3() 4706 %{ 4707 constraint(ALLOC_IN_RC(r3_reg)); 4708 match(RegL); 4709 match(iRegLNoSp); 4710 op_cost(0); 4711 format %{ %} 4712 interface(REG_INTER); 4713 %} 4714 4715 // Long 64 bit Register R11 only 4716 operand iRegL_R11() 4717 %{ 4718 constraint(ALLOC_IN_RC(r11_reg)); 4719 match(RegL); 4720 match(iRegLNoSp); 4721 op_cost(0); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 // Pointer 64 bit Register FP only 4727 operand iRegP_FP() 4728 %{ 4729 constraint(ALLOC_IN_RC(fp_reg)); 4730 match(RegP); 4731 // match(iRegP); 4732 op_cost(0); 4733 format %{ %} 4734 interface(REG_INTER); 4735 %} 4736 4737 // Register R0 only 4738 operand iRegI_R0() 4739 %{ 4740 constraint(ALLOC_IN_RC(int_r0_reg)); 4741 match(RegI); 4742 match(iRegINoSp); 4743 op_cost(0); 4744 format %{ %} 4745 interface(REG_INTER); 4746 %} 4747 4748 // Register R2 only 4749 operand iRegI_R2() 4750 %{ 4751 constraint(ALLOC_IN_RC(int_r2_reg)); 4752 match(RegI); 4753 match(iRegINoSp); 4754 op_cost(0); 4755 format %{ %} 4756 interface(REG_INTER); 4757 %} 4758 4759 // Register R3 only 4760 operand iRegI_R3() 4761 %{ 4762 constraint(ALLOC_IN_RC(int_r3_reg)); 4763 match(RegI); 4764 match(iRegINoSp); 4765 op_cost(0); 4766 format %{ %} 4767 interface(REG_INTER); 4768 %} 4769 4770 4771 // Register R4 only 4772 operand iRegI_R4() 4773 %{ 4774 constraint(ALLOC_IN_RC(int_r4_reg)); 4775 match(RegI); 4776 match(iRegINoSp); 4777 op_cost(0); 4778 format %{ %} 4779 interface(REG_INTER); 4780 %} 4781 4782 4783 // Pointer Register Operands 4784 // Narrow Pointer Register 4785 operand iRegN() 4786 %{ 4787 constraint(ALLOC_IN_RC(any_reg32)); 4788 match(RegN); 4789 match(iRegNNoSp); 4790 op_cost(0); 4791 format %{ %} 4792 interface(REG_INTER); 4793 %} 4794 4795 operand iRegN_R0() 4796 %{ 4797 constraint(ALLOC_IN_RC(r0_reg)); 4798 match(iRegN); 4799 op_cost(0); 4800 format %{ %} 4801 interface(REG_INTER); 4802 %} 4803 4804 operand iRegN_R2() 4805 %{ 4806 constraint(ALLOC_IN_RC(r2_reg)); 4807 match(iRegN); 4808 op_cost(0); 4809 format %{ %} 4810 interface(REG_INTER); 4811 %} 4812 4813 operand iRegN_R3() 4814 %{ 4815 constraint(ALLOC_IN_RC(r3_reg)); 4816 match(iRegN); 4817 op_cost(0); 4818 format %{ %} 4819 interface(REG_INTER); 4820 %} 4821 4822 // Integer 64 bit Register not Special 4823 operand iRegNNoSp() 4824 %{ 4825 constraint(ALLOC_IN_RC(no_special_reg32)); 4826 match(RegN); 4827 op_cost(0); 4828 format %{ %} 4829 interface(REG_INTER); 4830 %} 4831 4832 // heap base register -- used for encoding immN0 4833 4834 operand iRegIHeapbase() 4835 %{ 4836 constraint(ALLOC_IN_RC(heapbase_reg)); 4837 match(RegI); 4838 op_cost(0); 4839 format %{ %} 4840 interface(REG_INTER); 4841 %} 4842 4843 // Float Register 4844 // Float register operands 4845 operand vRegF() 4846 %{ 4847 constraint(ALLOC_IN_RC(float_reg)); 4848 match(RegF); 4849 4850 op_cost(0); 4851 format %{ %} 4852 interface(REG_INTER); 4853 %} 4854 4855 // Double Register 4856 // Double register operands 4857 operand vRegD() 4858 %{ 4859 constraint(ALLOC_IN_RC(double_reg)); 4860 match(RegD); 4861 4862 op_cost(0); 4863 format %{ %} 4864 interface(REG_INTER); 4865 %} 4866 4867 operand vecD() 4868 %{ 4869 constraint(ALLOC_IN_RC(vectord_reg)); 4870 match(VecD); 4871 4872 op_cost(0); 4873 format %{ %} 4874 interface(REG_INTER); 4875 %} 4876 4877 operand vecX() 4878 %{ 4879 constraint(ALLOC_IN_RC(vectorx_reg)); 4880 match(VecX); 4881 4882 op_cost(0); 4883 format %{ %} 4884 interface(REG_INTER); 4885 %} 4886 4887 operand vRegD_V0() 4888 %{ 4889 constraint(ALLOC_IN_RC(v0_reg)); 4890 match(RegD); 4891 op_cost(0); 4892 format %{ %} 4893 interface(REG_INTER); 4894 %} 4895 4896 operand vRegD_V1() 4897 %{ 4898 constraint(ALLOC_IN_RC(v1_reg)); 4899 match(RegD); 4900 op_cost(0); 4901 format %{ %} 4902 interface(REG_INTER); 4903 %} 4904 4905 operand vRegD_V2() 4906 %{ 4907 constraint(ALLOC_IN_RC(v2_reg)); 4908 match(RegD); 4909 op_cost(0); 4910 format %{ %} 4911 interface(REG_INTER); 4912 %} 4913 4914 operand vRegD_V3() 4915 %{ 4916 constraint(ALLOC_IN_RC(v3_reg)); 4917 match(RegD); 4918 op_cost(0); 4919 format %{ %} 4920 interface(REG_INTER); 4921 %} 4922 4923 operand vRegD_V4() 4924 %{ 4925 constraint(ALLOC_IN_RC(v4_reg)); 4926 match(RegD); 4927 op_cost(0); 4928 format %{ %} 4929 interface(REG_INTER); 4930 %} 4931 4932 operand vRegD_V5() 4933 %{ 4934 constraint(ALLOC_IN_RC(v5_reg)); 4935 match(RegD); 4936 op_cost(0); 4937 format %{ %} 4938 interface(REG_INTER); 4939 %} 4940 4941 operand vRegD_V6() 4942 %{ 4943 constraint(ALLOC_IN_RC(v6_reg)); 4944 match(RegD); 4945 op_cost(0); 4946 format %{ %} 4947 interface(REG_INTER); 4948 %} 4949 4950 operand vRegD_V7() 4951 %{ 4952 constraint(ALLOC_IN_RC(v7_reg)); 4953 match(RegD); 4954 op_cost(0); 4955 format %{ %} 4956 interface(REG_INTER); 4957 %} 4958 4959 operand vRegD_V8() 4960 %{ 4961 constraint(ALLOC_IN_RC(v8_reg)); 4962 match(RegD); 4963 op_cost(0); 4964 format %{ %} 4965 interface(REG_INTER); 4966 %} 4967 4968 operand vRegD_V9() 4969 %{ 4970 constraint(ALLOC_IN_RC(v9_reg)); 4971 match(RegD); 4972 op_cost(0); 4973 format %{ %} 4974 interface(REG_INTER); 4975 %} 4976 4977 operand vRegD_V10() 4978 %{ 4979 constraint(ALLOC_IN_RC(v10_reg)); 4980 match(RegD); 4981 op_cost(0); 4982 format %{ %} 4983 interface(REG_INTER); 4984 %} 4985 4986 operand vRegD_V11() 4987 %{ 4988 constraint(ALLOC_IN_RC(v11_reg)); 4989 match(RegD); 4990 op_cost(0); 4991 format %{ %} 4992 interface(REG_INTER); 4993 %} 4994 4995 operand vRegD_V12() 4996 %{ 4997 constraint(ALLOC_IN_RC(v12_reg)); 4998 match(RegD); 4999 op_cost(0); 5000 format %{ %} 5001 interface(REG_INTER); 5002 %} 5003 5004 operand vRegD_V13() 5005 %{ 5006 constraint(ALLOC_IN_RC(v13_reg)); 5007 match(RegD); 5008 op_cost(0); 5009 format %{ %} 5010 interface(REG_INTER); 5011 %} 5012 5013 operand vRegD_V14() 5014 %{ 5015 constraint(ALLOC_IN_RC(v14_reg)); 5016 match(RegD); 5017 op_cost(0); 5018 format %{ %} 5019 interface(REG_INTER); 5020 %} 5021 5022 operand vRegD_V15() 5023 %{ 5024 constraint(ALLOC_IN_RC(v15_reg)); 5025 match(RegD); 5026 op_cost(0); 5027 format %{ %} 5028 interface(REG_INTER); 5029 %} 5030 5031 operand vRegD_V16() 5032 %{ 5033 constraint(ALLOC_IN_RC(v16_reg)); 5034 match(RegD); 5035 op_cost(0); 5036 format %{ %} 5037 interface(REG_INTER); 5038 %} 5039 5040 operand vRegD_V17() 5041 %{ 5042 constraint(ALLOC_IN_RC(v17_reg)); 5043 match(RegD); 5044 op_cost(0); 5045 format %{ %} 5046 interface(REG_INTER); 5047 %} 5048 5049 operand vRegD_V18() 5050 %{ 5051 constraint(ALLOC_IN_RC(v18_reg)); 5052 match(RegD); 5053 op_cost(0); 5054 format %{ %} 5055 interface(REG_INTER); 5056 %} 5057 5058 operand vRegD_V19() 5059 %{ 5060 constraint(ALLOC_IN_RC(v19_reg)); 5061 match(RegD); 5062 op_cost(0); 5063 format %{ %} 5064 interface(REG_INTER); 5065 %} 5066 5067 operand vRegD_V20() 5068 %{ 5069 constraint(ALLOC_IN_RC(v20_reg)); 5070 match(RegD); 5071 op_cost(0); 5072 format %{ %} 5073 interface(REG_INTER); 5074 %} 5075 5076 operand vRegD_V21() 5077 %{ 5078 constraint(ALLOC_IN_RC(v21_reg)); 5079 match(RegD); 5080 op_cost(0); 5081 format %{ %} 5082 interface(REG_INTER); 5083 %} 5084 5085 operand vRegD_V22() 5086 %{ 5087 constraint(ALLOC_IN_RC(v22_reg)); 5088 match(RegD); 5089 op_cost(0); 5090 format %{ %} 5091 interface(REG_INTER); 5092 %} 5093 5094 operand vRegD_V23() 5095 %{ 5096 constraint(ALLOC_IN_RC(v23_reg)); 5097 match(RegD); 5098 op_cost(0); 5099 format %{ %} 5100 interface(REG_INTER); 5101 %} 5102 5103 operand vRegD_V24() 5104 %{ 5105 constraint(ALLOC_IN_RC(v24_reg)); 5106 match(RegD); 5107 op_cost(0); 5108 format %{ %} 5109 interface(REG_INTER); 5110 %} 5111 5112 operand vRegD_V25() 5113 %{ 5114 constraint(ALLOC_IN_RC(v25_reg)); 5115 match(RegD); 5116 op_cost(0); 5117 format %{ %} 5118 interface(REG_INTER); 5119 %} 5120 5121 operand vRegD_V26() 5122 %{ 5123 constraint(ALLOC_IN_RC(v26_reg)); 5124 match(RegD); 5125 op_cost(0); 5126 format %{ %} 5127 interface(REG_INTER); 5128 %} 5129 5130 operand vRegD_V27() 5131 %{ 5132 constraint(ALLOC_IN_RC(v27_reg)); 5133 match(RegD); 5134 op_cost(0); 5135 format %{ %} 5136 interface(REG_INTER); 5137 %} 5138 5139 operand vRegD_V28() 5140 %{ 5141 constraint(ALLOC_IN_RC(v28_reg)); 5142 match(RegD); 5143 op_cost(0); 5144 format %{ %} 5145 interface(REG_INTER); 5146 %} 5147 5148 operand vRegD_V29() 5149 %{ 5150 constraint(ALLOC_IN_RC(v29_reg)); 5151 match(RegD); 5152 op_cost(0); 5153 format %{ %} 5154 interface(REG_INTER); 5155 %} 5156 5157 operand vRegD_V30() 5158 %{ 5159 constraint(ALLOC_IN_RC(v30_reg)); 5160 match(RegD); 5161 op_cost(0); 5162 format %{ %} 5163 interface(REG_INTER); 5164 %} 5165 5166 operand vRegD_V31() 5167 %{ 5168 constraint(ALLOC_IN_RC(v31_reg)); 5169 match(RegD); 5170 op_cost(0); 5171 format %{ %} 5172 interface(REG_INTER); 5173 %} 5174 5175 // Flags register, used as output of signed compare instructions 5176 5177 // note that on AArch64 we also use this register as the output for 5178 // for floating point compare instructions (CmpF CmpD). this ensures 5179 // that ordered inequality tests use GT, GE, LT or LE none of which 5180 // pass through cases where the result is unordered i.e. one or both 5181 // inputs to the compare is a NaN. this means that the ideal code can 5182 // replace e.g. a GT with an LE and not end up capturing the NaN case 5183 // (where the comparison should always fail). EQ and NE tests are 5184 // always generated in ideal code so that unordered folds into the NE 5185 // case, matching the behaviour of AArch64 NE. 5186 // 5187 // This differs from x86 where the outputs of FP compares use a 5188 // special FP flags registers and where compares based on this 5189 // register are distinguished into ordered inequalities (cmpOpUCF) and 5190 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5191 // to explicitly handle the unordered case in branches. x86 also has 5192 // to include extra CMoveX rules to accept a cmpOpUCF input. 5193 5194 operand rFlagsReg() 5195 %{ 5196 constraint(ALLOC_IN_RC(int_flags)); 5197 match(RegFlags); 5198 5199 op_cost(0); 5200 format %{ "RFLAGS" %} 5201 interface(REG_INTER); 5202 %} 5203 5204 // Flags register, used as output of unsigned compare instructions 5205 operand rFlagsRegU() 5206 %{ 5207 constraint(ALLOC_IN_RC(int_flags)); 5208 match(RegFlags); 5209 5210 op_cost(0); 5211 format %{ "RFLAGSU" %} 5212 interface(REG_INTER); 5213 %} 5214 5215 // Special Registers 5216 5217 // Method Register 5218 operand inline_cache_RegP(iRegP reg) 5219 %{ 5220 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5221 match(reg); 5222 match(iRegPNoSp); 5223 op_cost(0); 5224 format %{ %} 5225 interface(REG_INTER); 5226 %} 5227 5228 operand interpreter_method_oop_RegP(iRegP reg) 5229 %{ 5230 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5231 match(reg); 5232 match(iRegPNoSp); 5233 op_cost(0); 5234 format %{ %} 5235 interface(REG_INTER); 5236 %} 5237 5238 // Thread Register 5239 operand thread_RegP(iRegP reg) 5240 %{ 5241 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5242 match(reg); 5243 op_cost(0); 5244 format %{ %} 5245 interface(REG_INTER); 5246 %} 5247 5248 operand lr_RegP(iRegP reg) 5249 %{ 5250 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5251 match(reg); 5252 op_cost(0); 5253 format %{ %} 5254 interface(REG_INTER); 5255 %} 5256 5257 //----------Memory Operands---------------------------------------------------- 5258 5259 operand indirect(iRegP reg) 5260 %{ 5261 constraint(ALLOC_IN_RC(ptr_reg)); 5262 match(reg); 5263 op_cost(0); 5264 format %{ "[$reg]" %} 5265 interface(MEMORY_INTER) %{ 5266 base($reg); 5267 index(0xffffffff); 5268 scale(0x0); 5269 disp(0x0); 5270 %} 5271 %} 5272 5273 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5274 %{ 5275 constraint(ALLOC_IN_RC(ptr_reg)); 5276 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5277 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5278 op_cost(0); 5279 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5280 interface(MEMORY_INTER) %{ 5281 base($reg); 5282 index($ireg); 5283 scale($scale); 5284 disp(0x0); 5285 %} 5286 %} 5287 5288 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5289 %{ 5290 constraint(ALLOC_IN_RC(ptr_reg)); 5291 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5292 match(AddP reg (LShiftL lreg scale)); 5293 op_cost(0); 5294 format %{ "$reg, $lreg lsl($scale)" %} 5295 interface(MEMORY_INTER) %{ 5296 base($reg); 5297 index($lreg); 5298 scale($scale); 5299 disp(0x0); 5300 %} 5301 %} 5302 5303 operand indIndexI2L(iRegP reg, iRegI ireg) 5304 %{ 5305 constraint(ALLOC_IN_RC(ptr_reg)); 5306 match(AddP reg (ConvI2L ireg)); 5307 op_cost(0); 5308 format %{ "$reg, $ireg, 0, I2L" %} 5309 interface(MEMORY_INTER) %{ 5310 base($reg); 5311 index($ireg); 5312 scale(0x0); 5313 disp(0x0); 5314 %} 5315 %} 5316 5317 operand indIndex(iRegP reg, iRegL lreg) 5318 %{ 5319 constraint(ALLOC_IN_RC(ptr_reg)); 5320 match(AddP reg lreg); 5321 op_cost(0); 5322 format %{ "$reg, $lreg" %} 5323 interface(MEMORY_INTER) %{ 5324 base($reg); 5325 index($lreg); 5326 scale(0x0); 5327 disp(0x0); 5328 %} 5329 %} 5330 5331 operand indOffI(iRegP reg, immIOffset off) 5332 %{ 5333 constraint(ALLOC_IN_RC(ptr_reg)); 5334 match(AddP reg off); 5335 op_cost(0); 5336 format %{ "[$reg, $off]" %} 5337 interface(MEMORY_INTER) %{ 5338 base($reg); 5339 index(0xffffffff); 5340 scale(0x0); 5341 disp($off); 5342 %} 5343 %} 5344 5345 operand indOffI1(iRegP reg, immIOffset1 off) 5346 %{ 5347 constraint(ALLOC_IN_RC(ptr_reg)); 5348 match(AddP reg off); 5349 op_cost(0); 5350 format %{ "[$reg, $off]" %} 5351 interface(MEMORY_INTER) %{ 5352 base($reg); 5353 index(0xffffffff); 5354 scale(0x0); 5355 disp($off); 5356 %} 5357 %} 5358 5359 operand indOffI2(iRegP reg, immIOffset2 off) 5360 %{ 5361 constraint(ALLOC_IN_RC(ptr_reg)); 5362 match(AddP reg off); 5363 op_cost(0); 5364 format %{ "[$reg, $off]" %} 5365 interface(MEMORY_INTER) %{ 5366 base($reg); 5367 index(0xffffffff); 5368 scale(0x0); 5369 disp($off); 5370 %} 5371 %} 5372 5373 operand indOffI4(iRegP reg, immIOffset4 off) 5374 %{ 5375 constraint(ALLOC_IN_RC(ptr_reg)); 5376 match(AddP reg off); 5377 op_cost(0); 5378 format %{ "[$reg, $off]" %} 5379 interface(MEMORY_INTER) %{ 5380 base($reg); 5381 index(0xffffffff); 5382 scale(0x0); 5383 disp($off); 5384 %} 5385 %} 5386 5387 operand indOffI8(iRegP reg, immIOffset8 off) 5388 %{ 5389 constraint(ALLOC_IN_RC(ptr_reg)); 5390 match(AddP reg off); 5391 op_cost(0); 5392 format %{ "[$reg, $off]" %} 5393 interface(MEMORY_INTER) %{ 5394 base($reg); 5395 index(0xffffffff); 5396 scale(0x0); 5397 disp($off); 5398 %} 5399 %} 5400 5401 operand indOffI16(iRegP reg, immIOffset16 off) 5402 %{ 5403 constraint(ALLOC_IN_RC(ptr_reg)); 5404 match(AddP reg off); 5405 op_cost(0); 5406 format %{ "[$reg, $off]" %} 5407 interface(MEMORY_INTER) %{ 5408 base($reg); 5409 index(0xffffffff); 5410 scale(0x0); 5411 disp($off); 5412 %} 5413 %} 5414 5415 operand indOffL(iRegP reg, immLoffset off) 5416 %{ 5417 constraint(ALLOC_IN_RC(ptr_reg)); 5418 match(AddP reg off); 5419 op_cost(0); 5420 format %{ "[$reg, $off]" %} 5421 interface(MEMORY_INTER) %{ 5422 base($reg); 5423 index(0xffffffff); 5424 scale(0x0); 5425 disp($off); 5426 %} 5427 %} 5428 5429 operand indOffL1(iRegP reg, immLoffset1 off) 5430 %{ 5431 constraint(ALLOC_IN_RC(ptr_reg)); 5432 match(AddP reg off); 5433 op_cost(0); 5434 format %{ "[$reg, $off]" %} 5435 interface(MEMORY_INTER) %{ 5436 base($reg); 5437 index(0xffffffff); 5438 scale(0x0); 5439 disp($off); 5440 %} 5441 %} 5442 5443 operand indOffL2(iRegP reg, immLoffset2 off) 5444 %{ 5445 constraint(ALLOC_IN_RC(ptr_reg)); 5446 match(AddP reg off); 5447 op_cost(0); 5448 format %{ "[$reg, $off]" %} 5449 interface(MEMORY_INTER) %{ 5450 base($reg); 5451 index(0xffffffff); 5452 scale(0x0); 5453 disp($off); 5454 %} 5455 %} 5456 5457 operand indOffL4(iRegP reg, immLoffset4 off) 5458 %{ 5459 constraint(ALLOC_IN_RC(ptr_reg)); 5460 match(AddP reg off); 5461 op_cost(0); 5462 format %{ "[$reg, $off]" %} 5463 interface(MEMORY_INTER) %{ 5464 base($reg); 5465 index(0xffffffff); 5466 scale(0x0); 5467 disp($off); 5468 %} 5469 %} 5470 5471 operand indOffL8(iRegP reg, immLoffset8 off) 5472 %{ 5473 constraint(ALLOC_IN_RC(ptr_reg)); 5474 match(AddP reg off); 5475 op_cost(0); 5476 format %{ "[$reg, $off]" %} 5477 interface(MEMORY_INTER) %{ 5478 base($reg); 5479 index(0xffffffff); 5480 scale(0x0); 5481 disp($off); 5482 %} 5483 %} 5484 5485 operand indOffL16(iRegP reg, immLoffset16 off) 5486 %{ 5487 constraint(ALLOC_IN_RC(ptr_reg)); 5488 match(AddP reg off); 5489 op_cost(0); 5490 format %{ "[$reg, $off]" %} 5491 interface(MEMORY_INTER) %{ 5492 base($reg); 5493 index(0xffffffff); 5494 scale(0x0); 5495 disp($off); 5496 %} 5497 %} 5498 5499 operand indirectN(iRegN reg) 5500 %{ 5501 predicate(CompressedOops::shift() == 0); 5502 constraint(ALLOC_IN_RC(ptr_reg)); 5503 match(DecodeN reg); 5504 op_cost(0); 5505 format %{ "[$reg]\t# narrow" %} 5506 interface(MEMORY_INTER) %{ 5507 base($reg); 5508 index(0xffffffff); 5509 scale(0x0); 5510 disp(0x0); 5511 %} 5512 %} 5513 5514 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5515 %{ 5516 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5517 constraint(ALLOC_IN_RC(ptr_reg)); 5518 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5519 op_cost(0); 5520 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5521 interface(MEMORY_INTER) %{ 5522 base($reg); 5523 index($ireg); 5524 scale($scale); 5525 disp(0x0); 5526 %} 5527 %} 5528 5529 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5530 %{ 5531 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5532 constraint(ALLOC_IN_RC(ptr_reg)); 5533 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5534 op_cost(0); 5535 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5536 interface(MEMORY_INTER) %{ 5537 base($reg); 5538 index($lreg); 5539 scale($scale); 5540 disp(0x0); 5541 %} 5542 %} 5543 5544 operand indIndexI2LN(iRegN reg, iRegI ireg) 5545 %{ 5546 predicate(CompressedOops::shift() == 0); 5547 constraint(ALLOC_IN_RC(ptr_reg)); 5548 match(AddP (DecodeN reg) (ConvI2L ireg)); 5549 op_cost(0); 5550 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5551 interface(MEMORY_INTER) %{ 5552 base($reg); 5553 index($ireg); 5554 scale(0x0); 5555 disp(0x0); 5556 %} 5557 %} 5558 5559 operand indIndexN(iRegN reg, iRegL lreg) 5560 %{ 5561 predicate(CompressedOops::shift() == 0); 5562 constraint(ALLOC_IN_RC(ptr_reg)); 5563 match(AddP (DecodeN reg) lreg); 5564 op_cost(0); 5565 format %{ "$reg, $lreg\t# narrow" %} 5566 interface(MEMORY_INTER) %{ 5567 base($reg); 5568 index($lreg); 5569 scale(0x0); 5570 disp(0x0); 5571 %} 5572 %} 5573 5574 operand indOffIN(iRegN reg, immIOffset off) 5575 %{ 5576 predicate(CompressedOops::shift() == 0); 5577 constraint(ALLOC_IN_RC(ptr_reg)); 5578 match(AddP (DecodeN reg) off); 5579 op_cost(0); 5580 format %{ "[$reg, $off]\t# narrow" %} 5581 interface(MEMORY_INTER) %{ 5582 base($reg); 5583 index(0xffffffff); 5584 scale(0x0); 5585 disp($off); 5586 %} 5587 %} 5588 5589 operand indOffLN(iRegN reg, immLoffset off) 5590 %{ 5591 predicate(CompressedOops::shift() == 0); 5592 constraint(ALLOC_IN_RC(ptr_reg)); 5593 match(AddP (DecodeN reg) off); 5594 op_cost(0); 5595 format %{ "[$reg, $off]\t# narrow" %} 5596 interface(MEMORY_INTER) %{ 5597 base($reg); 5598 index(0xffffffff); 5599 scale(0x0); 5600 disp($off); 5601 %} 5602 %} 5603 5604 5605 5606 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5607 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5608 %{ 5609 constraint(ALLOC_IN_RC(ptr_reg)); 5610 match(AddP reg off); 5611 op_cost(0); 5612 format %{ "[$reg, $off]" %} 5613 interface(MEMORY_INTER) %{ 5614 base($reg); 5615 index(0xffffffff); 5616 scale(0x0); 5617 disp($off); 5618 %} 5619 %} 5620 5621 //----------Special Memory Operands-------------------------------------------- 5622 // Stack Slot Operand - This operand is used for loading and storing temporary 5623 // values on the stack where a match requires a value to 5624 // flow through memory. 5625 operand stackSlotP(sRegP reg) 5626 %{ 5627 constraint(ALLOC_IN_RC(stack_slots)); 5628 op_cost(100); 5629 // No match rule because this operand is only generated in matching 5630 // match(RegP); 5631 format %{ "[$reg]" %} 5632 interface(MEMORY_INTER) %{ 5633 base(0x1e); // RSP 5634 index(0x0); // No Index 5635 scale(0x0); // No Scale 5636 disp($reg); // Stack Offset 5637 %} 5638 %} 5639 5640 operand stackSlotI(sRegI reg) 5641 %{ 5642 constraint(ALLOC_IN_RC(stack_slots)); 5643 // No match rule because this operand is only generated in matching 5644 // match(RegI); 5645 format %{ "[$reg]" %} 5646 interface(MEMORY_INTER) %{ 5647 base(0x1e); // RSP 5648 index(0x0); // No Index 5649 scale(0x0); // No Scale 5650 disp($reg); // Stack Offset 5651 %} 5652 %} 5653 5654 operand stackSlotF(sRegF reg) 5655 %{ 5656 constraint(ALLOC_IN_RC(stack_slots)); 5657 // No match rule because this operand is only generated in matching 5658 // match(RegF); 5659 format %{ "[$reg]" %} 5660 interface(MEMORY_INTER) %{ 5661 base(0x1e); // RSP 5662 index(0x0); // No Index 5663 scale(0x0); // No Scale 5664 disp($reg); // Stack Offset 5665 %} 5666 %} 5667 5668 operand stackSlotD(sRegD reg) 5669 %{ 5670 constraint(ALLOC_IN_RC(stack_slots)); 5671 // No match rule because this operand is only generated in matching 5672 // match(RegD); 5673 format %{ "[$reg]" %} 5674 interface(MEMORY_INTER) %{ 5675 base(0x1e); // RSP 5676 index(0x0); // No Index 5677 scale(0x0); // No Scale 5678 disp($reg); // Stack Offset 5679 %} 5680 %} 5681 5682 operand stackSlotL(sRegL reg) 5683 %{ 5684 constraint(ALLOC_IN_RC(stack_slots)); 5685 // No match rule because this operand is only generated in matching 5686 // match(RegL); 5687 format %{ "[$reg]" %} 5688 interface(MEMORY_INTER) %{ 5689 base(0x1e); // RSP 5690 index(0x0); // No Index 5691 scale(0x0); // No Scale 5692 disp($reg); // Stack Offset 5693 %} 5694 %} 5695 5696 // Operands for expressing Control Flow 5697 // NOTE: Label is a predefined operand which should not be redefined in 5698 // the AD file. It is generically handled within the ADLC. 5699 5700 //----------Conditional Branch Operands---------------------------------------- 5701 // Comparison Op - This is the operation of the comparison, and is limited to 5702 // the following set of codes: 5703 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5704 // 5705 // Other attributes of the comparison, such as unsignedness, are specified 5706 // by the comparison instruction that sets a condition code flags register. 5707 // That result is represented by a flags operand whose subtype is appropriate 5708 // to the unsignedness (etc.) of the comparison. 5709 // 5710 // Later, the instruction which matches both the Comparison Op (a Bool) and 5711 // the flags (produced by the Cmp) specifies the coding of the comparison op 5712 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5713 5714 // used for signed integral comparisons and fp comparisons 5715 5716 operand cmpOp() 5717 %{ 5718 match(Bool); 5719 5720 format %{ "" %} 5721 interface(COND_INTER) %{ 5722 equal(0x0, "eq"); 5723 not_equal(0x1, "ne"); 5724 less(0xb, "lt"); 5725 greater_equal(0xa, "ge"); 5726 less_equal(0xd, "le"); 5727 greater(0xc, "gt"); 5728 overflow(0x6, "vs"); 5729 no_overflow(0x7, "vc"); 5730 %} 5731 %} 5732 5733 // used for unsigned integral comparisons 5734 5735 operand cmpOpU() 5736 %{ 5737 match(Bool); 5738 5739 format %{ "" %} 5740 interface(COND_INTER) %{ 5741 equal(0x0, "eq"); 5742 not_equal(0x1, "ne"); 5743 less(0x3, "lo"); 5744 greater_equal(0x2, "hs"); 5745 less_equal(0x9, "ls"); 5746 greater(0x8, "hi"); 5747 overflow(0x6, "vs"); 5748 no_overflow(0x7, "vc"); 5749 %} 5750 %} 5751 5752 // used for certain integral comparisons which can be 5753 // converted to cbxx or tbxx instructions 5754 5755 operand cmpOpEqNe() 5756 %{ 5757 match(Bool); 5758 op_cost(0); 5759 predicate(n->as_Bool()->_test._test == BoolTest::ne 5760 || n->as_Bool()->_test._test == BoolTest::eq); 5761 5762 format %{ "" %} 5763 interface(COND_INTER) %{ 5764 equal(0x0, "eq"); 5765 not_equal(0x1, "ne"); 5766 less(0xb, "lt"); 5767 greater_equal(0xa, "ge"); 5768 less_equal(0xd, "le"); 5769 greater(0xc, "gt"); 5770 overflow(0x6, "vs"); 5771 no_overflow(0x7, "vc"); 5772 %} 5773 %} 5774 5775 // used for certain integral comparisons which can be 5776 // converted to cbxx or tbxx instructions 5777 5778 operand cmpOpLtGe() 5779 %{ 5780 match(Bool); 5781 op_cost(0); 5782 5783 predicate(n->as_Bool()->_test._test == BoolTest::lt 5784 || n->as_Bool()->_test._test == BoolTest::ge); 5785 5786 format %{ "" %} 5787 interface(COND_INTER) %{ 5788 equal(0x0, "eq"); 5789 not_equal(0x1, "ne"); 5790 less(0xb, "lt"); 5791 greater_equal(0xa, "ge"); 5792 less_equal(0xd, "le"); 5793 greater(0xc, "gt"); 5794 overflow(0x6, "vs"); 5795 no_overflow(0x7, "vc"); 5796 %} 5797 %} 5798 5799 // used for certain unsigned integral comparisons which can be 5800 // converted to cbxx or tbxx instructions 5801 5802 operand cmpOpUEqNeLtGe() 5803 %{ 5804 match(Bool); 5805 op_cost(0); 5806 5807 predicate(n->as_Bool()->_test._test == BoolTest::eq 5808 || n->as_Bool()->_test._test == BoolTest::ne 5809 || n->as_Bool()->_test._test == BoolTest::lt 5810 || n->as_Bool()->_test._test == BoolTest::ge); 5811 5812 format %{ "" %} 5813 interface(COND_INTER) %{ 5814 equal(0x0, "eq"); 5815 not_equal(0x1, "ne"); 5816 less(0xb, "lt"); 5817 greater_equal(0xa, "ge"); 5818 less_equal(0xd, "le"); 5819 greater(0xc, "gt"); 5820 overflow(0x6, "vs"); 5821 no_overflow(0x7, "vc"); 5822 %} 5823 %} 5824 5825 // Special operand allowing long args to int ops to be truncated for free 5826 5827 operand iRegL2I(iRegL reg) %{ 5828 5829 op_cost(0); 5830 5831 match(ConvL2I reg); 5832 5833 format %{ "l2i($reg)" %} 5834 5835 interface(REG_INTER) 5836 %} 5837 5838 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5839 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5840 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5841 5842 //----------OPERAND CLASSES---------------------------------------------------- 5843 // Operand Classes are groups of operands that are used as to simplify 5844 // instruction definitions by not requiring the AD writer to specify 5845 // separate instructions for every form of operand when the 5846 // instruction accepts multiple operand types with the same basic 5847 // encoding and format. The classic case of this is memory operands. 5848 5849 // memory is used to define read/write location for load/store 5850 // instruction defs. we can turn a memory op into an Address 5851 5852 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5853 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5854 5855 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5856 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5857 5858 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5859 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5860 5861 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5862 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5863 5864 // All of the memory operands. For the pipeline description. 5865 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5866 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5867 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5868 5869 5870 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5871 // operations. it allows the src to be either an iRegI or a (ConvL2I 5872 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5873 // can be elided because the 32-bit instruction will just employ the 5874 // lower 32 bits anyway. 5875 // 5876 // n.b. this does not elide all L2I conversions. if the truncated 5877 // value is consumed by more than one operation then the ConvL2I 5878 // cannot be bundled into the consuming nodes so an l2i gets planted 5879 // (actually a movw $dst $src) and the downstream instructions consume 5880 // the result of the l2i as an iRegI input. That's a shame since the 5881 // movw is actually redundant but its not too costly. 5882 5883 opclass iRegIorL2I(iRegI, iRegL2I); 5884 5885 //----------PIPELINE----------------------------------------------------------- 5886 // Rules which define the behavior of the target architectures pipeline. 5887 5888 // For specific pipelines, eg A53, define the stages of that pipeline 5889 //pipe_desc(ISS, EX1, EX2, WR); 5890 #define ISS S0 5891 #define EX1 S1 5892 #define EX2 S2 5893 #define WR S3 5894 5895 // Integer ALU reg operation 5896 pipeline %{ 5897 5898 attributes %{ 5899 // ARM instructions are of fixed length 5900 fixed_size_instructions; // Fixed size instructions TODO does 5901 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5902 // ARM instructions come in 32-bit word units 5903 instruction_unit_size = 4; // An instruction is 4 bytes long 5904 instruction_fetch_unit_size = 64; // The processor fetches one line 5905 instruction_fetch_units = 1; // of 64 bytes 5906 5907 // List of nop instructions 5908 nops( MachNop ); 5909 %} 5910 5911 // We don't use an actual pipeline model so don't care about resources 5912 // or description. we do use pipeline classes to introduce fixed 5913 // latencies 5914 5915 //----------RESOURCES---------------------------------------------------------- 5916 // Resources are the functional units available to the machine 5917 5918 resources( INS0, INS1, INS01 = INS0 | INS1, 5919 ALU0, ALU1, ALU = ALU0 | ALU1, 5920 MAC, 5921 DIV, 5922 BRANCH, 5923 LDST, 5924 NEON_FP); 5925 5926 //----------PIPELINE DESCRIPTION----------------------------------------------- 5927 // Pipeline Description specifies the stages in the machine's pipeline 5928 5929 // Define the pipeline as a generic 6 stage pipeline 5930 pipe_desc(S0, S1, S2, S3, S4, S5); 5931 5932 //----------PIPELINE CLASSES--------------------------------------------------- 5933 // Pipeline Classes describe the stages in which input and output are 5934 // referenced by the hardware pipeline. 5935 5936 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5937 %{ 5938 single_instruction; 5939 src1 : S1(read); 5940 src2 : S2(read); 5941 dst : S5(write); 5942 INS01 : ISS; 5943 NEON_FP : S5; 5944 %} 5945 5946 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5947 %{ 5948 single_instruction; 5949 src1 : S1(read); 5950 src2 : S2(read); 5951 dst : S5(write); 5952 INS01 : ISS; 5953 NEON_FP : S5; 5954 %} 5955 5956 pipe_class fp_uop_s(vRegF dst, vRegF src) 5957 %{ 5958 single_instruction; 5959 src : S1(read); 5960 dst : S5(write); 5961 INS01 : ISS; 5962 NEON_FP : S5; 5963 %} 5964 5965 pipe_class fp_uop_d(vRegD dst, vRegD src) 5966 %{ 5967 single_instruction; 5968 src : S1(read); 5969 dst : S5(write); 5970 INS01 : ISS; 5971 NEON_FP : S5; 5972 %} 5973 5974 pipe_class fp_d2f(vRegF dst, vRegD src) 5975 %{ 5976 single_instruction; 5977 src : S1(read); 5978 dst : S5(write); 5979 INS01 : ISS; 5980 NEON_FP : S5; 5981 %} 5982 5983 pipe_class fp_f2d(vRegD dst, vRegF src) 5984 %{ 5985 single_instruction; 5986 src : S1(read); 5987 dst : S5(write); 5988 INS01 : ISS; 5989 NEON_FP : S5; 5990 %} 5991 5992 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5993 %{ 5994 single_instruction; 5995 src : S1(read); 5996 dst : S5(write); 5997 INS01 : ISS; 5998 NEON_FP : S5; 5999 %} 6000 6001 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6002 %{ 6003 single_instruction; 6004 src : S1(read); 6005 dst : S5(write); 6006 INS01 : ISS; 6007 NEON_FP : S5; 6008 %} 6009 6010 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6011 %{ 6012 single_instruction; 6013 src : S1(read); 6014 dst : S5(write); 6015 INS01 : ISS; 6016 NEON_FP : S5; 6017 %} 6018 6019 pipe_class fp_l2f(vRegF dst, iRegL src) 6020 %{ 6021 single_instruction; 6022 src : S1(read); 6023 dst : S5(write); 6024 INS01 : ISS; 6025 NEON_FP : S5; 6026 %} 6027 6028 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6029 %{ 6030 single_instruction; 6031 src : S1(read); 6032 dst : S5(write); 6033 INS01 : ISS; 6034 NEON_FP : S5; 6035 %} 6036 6037 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6038 %{ 6039 single_instruction; 6040 src : S1(read); 6041 dst : S5(write); 6042 INS01 : ISS; 6043 NEON_FP : S5; 6044 %} 6045 6046 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6047 %{ 6048 single_instruction; 6049 src : S1(read); 6050 dst : S5(write); 6051 INS01 : ISS; 6052 NEON_FP : S5; 6053 %} 6054 6055 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6056 %{ 6057 single_instruction; 6058 src : S1(read); 6059 dst : S5(write); 6060 INS01 : ISS; 6061 NEON_FP : S5; 6062 %} 6063 6064 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6065 %{ 6066 single_instruction; 6067 src1 : S1(read); 6068 src2 : S2(read); 6069 dst : S5(write); 6070 INS0 : ISS; 6071 NEON_FP : S5; 6072 %} 6073 6074 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6075 %{ 6076 single_instruction; 6077 src1 : S1(read); 6078 src2 : S2(read); 6079 dst : S5(write); 6080 INS0 : ISS; 6081 NEON_FP : S5; 6082 %} 6083 6084 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6085 %{ 6086 single_instruction; 6087 cr : S1(read); 6088 src1 : S1(read); 6089 src2 : S1(read); 6090 dst : S3(write); 6091 INS01 : ISS; 6092 NEON_FP : S3; 6093 %} 6094 6095 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6096 %{ 6097 single_instruction; 6098 cr : S1(read); 6099 src1 : S1(read); 6100 src2 : S1(read); 6101 dst : S3(write); 6102 INS01 : ISS; 6103 NEON_FP : S3; 6104 %} 6105 6106 pipe_class fp_imm_s(vRegF dst) 6107 %{ 6108 single_instruction; 6109 dst : S3(write); 6110 INS01 : ISS; 6111 NEON_FP : S3; 6112 %} 6113 6114 pipe_class fp_imm_d(vRegD dst) 6115 %{ 6116 single_instruction; 6117 dst : S3(write); 6118 INS01 : ISS; 6119 NEON_FP : S3; 6120 %} 6121 6122 pipe_class fp_load_constant_s(vRegF dst) 6123 %{ 6124 single_instruction; 6125 dst : S4(write); 6126 INS01 : ISS; 6127 NEON_FP : S4; 6128 %} 6129 6130 pipe_class fp_load_constant_d(vRegD dst) 6131 %{ 6132 single_instruction; 6133 dst : S4(write); 6134 INS01 : ISS; 6135 NEON_FP : S4; 6136 %} 6137 6138 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6139 %{ 6140 single_instruction; 6141 dst : S5(write); 6142 src1 : S1(read); 6143 src2 : S1(read); 6144 INS01 : ISS; 6145 NEON_FP : S5; 6146 %} 6147 6148 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6149 %{ 6150 single_instruction; 6151 dst : S5(write); 6152 src1 : S1(read); 6153 src2 : S1(read); 6154 INS0 : ISS; 6155 NEON_FP : S5; 6156 %} 6157 6158 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6159 %{ 6160 single_instruction; 6161 dst : S5(write); 6162 src1 : S1(read); 6163 src2 : S1(read); 6164 dst : S1(read); 6165 INS01 : ISS; 6166 NEON_FP : S5; 6167 %} 6168 6169 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6170 %{ 6171 single_instruction; 6172 dst : S5(write); 6173 src1 : S1(read); 6174 src2 : S1(read); 6175 dst : S1(read); 6176 INS0 : ISS; 6177 NEON_FP : S5; 6178 %} 6179 6180 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6181 %{ 6182 single_instruction; 6183 dst : S4(write); 6184 src1 : S2(read); 6185 src2 : S2(read); 6186 INS01 : ISS; 6187 NEON_FP : S4; 6188 %} 6189 6190 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6191 %{ 6192 single_instruction; 6193 dst : S4(write); 6194 src1 : S2(read); 6195 src2 : S2(read); 6196 INS0 : ISS; 6197 NEON_FP : S4; 6198 %} 6199 6200 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6201 %{ 6202 single_instruction; 6203 dst : S3(write); 6204 src1 : S2(read); 6205 src2 : S2(read); 6206 INS01 : ISS; 6207 NEON_FP : S3; 6208 %} 6209 6210 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6211 %{ 6212 single_instruction; 6213 dst : S3(write); 6214 src1 : S2(read); 6215 src2 : S2(read); 6216 INS0 : ISS; 6217 NEON_FP : S3; 6218 %} 6219 6220 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6221 %{ 6222 single_instruction; 6223 dst : S3(write); 6224 src : S1(read); 6225 shift : S1(read); 6226 INS01 : ISS; 6227 NEON_FP : S3; 6228 %} 6229 6230 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6231 %{ 6232 single_instruction; 6233 dst : S3(write); 6234 src : S1(read); 6235 shift : S1(read); 6236 INS0 : ISS; 6237 NEON_FP : S3; 6238 %} 6239 6240 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6241 %{ 6242 single_instruction; 6243 dst : S3(write); 6244 src : S1(read); 6245 INS01 : ISS; 6246 NEON_FP : S3; 6247 %} 6248 6249 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6250 %{ 6251 single_instruction; 6252 dst : S3(write); 6253 src : S1(read); 6254 INS0 : ISS; 6255 NEON_FP : S3; 6256 %} 6257 6258 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6259 %{ 6260 single_instruction; 6261 dst : S5(write); 6262 src1 : S1(read); 6263 src2 : S1(read); 6264 INS01 : ISS; 6265 NEON_FP : S5; 6266 %} 6267 6268 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6269 %{ 6270 single_instruction; 6271 dst : S5(write); 6272 src1 : S1(read); 6273 src2 : S1(read); 6274 INS0 : ISS; 6275 NEON_FP : S5; 6276 %} 6277 6278 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6279 %{ 6280 single_instruction; 6281 dst : S5(write); 6282 src1 : S1(read); 6283 src2 : S1(read); 6284 INS0 : ISS; 6285 NEON_FP : S5; 6286 %} 6287 6288 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6289 %{ 6290 single_instruction; 6291 dst : S5(write); 6292 src1 : S1(read); 6293 src2 : S1(read); 6294 INS0 : ISS; 6295 NEON_FP : S5; 6296 %} 6297 6298 pipe_class vsqrt_fp128(vecX dst, vecX src) 6299 %{ 6300 single_instruction; 6301 dst : S5(write); 6302 src : S1(read); 6303 INS0 : ISS; 6304 NEON_FP : S5; 6305 %} 6306 6307 pipe_class vunop_fp64(vecD dst, vecD src) 6308 %{ 6309 single_instruction; 6310 dst : S5(write); 6311 src : S1(read); 6312 INS01 : ISS; 6313 NEON_FP : S5; 6314 %} 6315 6316 pipe_class vunop_fp128(vecX dst, vecX src) 6317 %{ 6318 single_instruction; 6319 dst : S5(write); 6320 src : S1(read); 6321 INS0 : ISS; 6322 NEON_FP : S5; 6323 %} 6324 6325 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6326 %{ 6327 single_instruction; 6328 dst : S3(write); 6329 src : S1(read); 6330 INS01 : ISS; 6331 NEON_FP : S3; 6332 %} 6333 6334 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6335 %{ 6336 single_instruction; 6337 dst : S3(write); 6338 src : S1(read); 6339 INS01 : ISS; 6340 NEON_FP : S3; 6341 %} 6342 6343 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6344 %{ 6345 single_instruction; 6346 dst : S3(write); 6347 src : S1(read); 6348 INS01 : ISS; 6349 NEON_FP : S3; 6350 %} 6351 6352 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6353 %{ 6354 single_instruction; 6355 dst : S3(write); 6356 src : S1(read); 6357 INS01 : ISS; 6358 NEON_FP : S3; 6359 %} 6360 6361 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6362 %{ 6363 single_instruction; 6364 dst : S3(write); 6365 src : S1(read); 6366 INS01 : ISS; 6367 NEON_FP : S3; 6368 %} 6369 6370 pipe_class vmovi_reg_imm64(vecD dst) 6371 %{ 6372 single_instruction; 6373 dst : S3(write); 6374 INS01 : ISS; 6375 NEON_FP : S3; 6376 %} 6377 6378 pipe_class vmovi_reg_imm128(vecX dst) 6379 %{ 6380 single_instruction; 6381 dst : S3(write); 6382 INS0 : ISS; 6383 NEON_FP : S3; 6384 %} 6385 6386 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6387 %{ 6388 single_instruction; 6389 dst : S5(write); 6390 mem : ISS(read); 6391 INS01 : ISS; 6392 NEON_FP : S3; 6393 %} 6394 6395 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6396 %{ 6397 single_instruction; 6398 dst : S5(write); 6399 mem : ISS(read); 6400 INS01 : ISS; 6401 NEON_FP : S3; 6402 %} 6403 6404 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6405 %{ 6406 single_instruction; 6407 mem : ISS(read); 6408 src : S2(read); 6409 INS01 : ISS; 6410 NEON_FP : S3; 6411 %} 6412 6413 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6414 %{ 6415 single_instruction; 6416 mem : ISS(read); 6417 src : S2(read); 6418 INS01 : ISS; 6419 NEON_FP : S3; 6420 %} 6421 6422 //------- Integer ALU operations -------------------------- 6423 6424 // Integer ALU reg-reg operation 6425 // Operands needed in EX1, result generated in EX2 6426 // Eg. ADD x0, x1, x2 6427 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6428 %{ 6429 single_instruction; 6430 dst : EX2(write); 6431 src1 : EX1(read); 6432 src2 : EX1(read); 6433 INS01 : ISS; // Dual issue as instruction 0 or 1 6434 ALU : EX2; 6435 %} 6436 6437 // Integer ALU reg-reg operation with constant shift 6438 // Shifted register must be available in LATE_ISS instead of EX1 6439 // Eg. ADD x0, x1, x2, LSL #2 6440 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6441 %{ 6442 single_instruction; 6443 dst : EX2(write); 6444 src1 : EX1(read); 6445 src2 : ISS(read); 6446 INS01 : ISS; 6447 ALU : EX2; 6448 %} 6449 6450 // Integer ALU reg operation with constant shift 6451 // Eg. LSL x0, x1, #shift 6452 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6453 %{ 6454 single_instruction; 6455 dst : EX2(write); 6456 src1 : ISS(read); 6457 INS01 : ISS; 6458 ALU : EX2; 6459 %} 6460 6461 // Integer ALU reg-reg operation with variable shift 6462 // Both operands must be available in LATE_ISS instead of EX1 6463 // Result is available in EX1 instead of EX2 6464 // Eg. LSLV x0, x1, x2 6465 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6466 %{ 6467 single_instruction; 6468 dst : EX1(write); 6469 src1 : ISS(read); 6470 src2 : ISS(read); 6471 INS01 : ISS; 6472 ALU : EX1; 6473 %} 6474 6475 // Integer ALU reg-reg operation with extract 6476 // As for _vshift above, but result generated in EX2 6477 // Eg. EXTR x0, x1, x2, #N 6478 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6479 %{ 6480 single_instruction; 6481 dst : EX2(write); 6482 src1 : ISS(read); 6483 src2 : ISS(read); 6484 INS1 : ISS; // Can only dual issue as Instruction 1 6485 ALU : EX1; 6486 %} 6487 6488 // Integer ALU reg operation 6489 // Eg. NEG x0, x1 6490 pipe_class ialu_reg(iRegI dst, iRegI src) 6491 %{ 6492 single_instruction; 6493 dst : EX2(write); 6494 src : EX1(read); 6495 INS01 : ISS; 6496 ALU : EX2; 6497 %} 6498 6499 // Integer ALU reg mmediate operation 6500 // Eg. ADD x0, x1, #N 6501 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6502 %{ 6503 single_instruction; 6504 dst : EX2(write); 6505 src1 : EX1(read); 6506 INS01 : ISS; 6507 ALU : EX2; 6508 %} 6509 6510 // Integer ALU immediate operation (no source operands) 6511 // Eg. MOV x0, #N 6512 pipe_class ialu_imm(iRegI dst) 6513 %{ 6514 single_instruction; 6515 dst : EX1(write); 6516 INS01 : ISS; 6517 ALU : EX1; 6518 %} 6519 6520 //------- Compare operation ------------------------------- 6521 6522 // Compare reg-reg 6523 // Eg. CMP x0, x1 6524 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6525 %{ 6526 single_instruction; 6527 // fixed_latency(16); 6528 cr : EX2(write); 6529 op1 : EX1(read); 6530 op2 : EX1(read); 6531 INS01 : ISS; 6532 ALU : EX2; 6533 %} 6534 6535 // Compare reg-reg 6536 // Eg. CMP x0, #N 6537 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6538 %{ 6539 single_instruction; 6540 // fixed_latency(16); 6541 cr : EX2(write); 6542 op1 : EX1(read); 6543 INS01 : ISS; 6544 ALU : EX2; 6545 %} 6546 6547 //------- Conditional instructions ------------------------ 6548 6549 // Conditional no operands 6550 // Eg. CSINC x0, zr, zr, <cond> 6551 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6552 %{ 6553 single_instruction; 6554 cr : EX1(read); 6555 dst : EX2(write); 6556 INS01 : ISS; 6557 ALU : EX2; 6558 %} 6559 6560 // Conditional 2 operand 6561 // EG. CSEL X0, X1, X2, <cond> 6562 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6563 %{ 6564 single_instruction; 6565 cr : EX1(read); 6566 src1 : EX1(read); 6567 src2 : EX1(read); 6568 dst : EX2(write); 6569 INS01 : ISS; 6570 ALU : EX2; 6571 %} 6572 6573 // Conditional 2 operand 6574 // EG. CSEL X0, X1, X2, <cond> 6575 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6576 %{ 6577 single_instruction; 6578 cr : EX1(read); 6579 src : EX1(read); 6580 dst : EX2(write); 6581 INS01 : ISS; 6582 ALU : EX2; 6583 %} 6584 6585 //------- Multiply pipeline operations -------------------- 6586 6587 // Multiply reg-reg 6588 // Eg. MUL w0, w1, w2 6589 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6590 %{ 6591 single_instruction; 6592 dst : WR(write); 6593 src1 : ISS(read); 6594 src2 : ISS(read); 6595 INS01 : ISS; 6596 MAC : WR; 6597 %} 6598 6599 // Multiply accumulate 6600 // Eg. MADD w0, w1, w2, w3 6601 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6602 %{ 6603 single_instruction; 6604 dst : WR(write); 6605 src1 : ISS(read); 6606 src2 : ISS(read); 6607 src3 : ISS(read); 6608 INS01 : ISS; 6609 MAC : WR; 6610 %} 6611 6612 // Eg. MUL w0, w1, w2 6613 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6614 %{ 6615 single_instruction; 6616 fixed_latency(3); // Maximum latency for 64 bit mul 6617 dst : WR(write); 6618 src1 : ISS(read); 6619 src2 : ISS(read); 6620 INS01 : ISS; 6621 MAC : WR; 6622 %} 6623 6624 // Multiply accumulate 6625 // Eg. MADD w0, w1, w2, w3 6626 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6627 %{ 6628 single_instruction; 6629 fixed_latency(3); // Maximum latency for 64 bit mul 6630 dst : WR(write); 6631 src1 : ISS(read); 6632 src2 : ISS(read); 6633 src3 : ISS(read); 6634 INS01 : ISS; 6635 MAC : WR; 6636 %} 6637 6638 //------- Divide pipeline operations -------------------- 6639 6640 // Eg. SDIV w0, w1, w2 6641 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6642 %{ 6643 single_instruction; 6644 fixed_latency(8); // Maximum latency for 32 bit divide 6645 dst : WR(write); 6646 src1 : ISS(read); 6647 src2 : ISS(read); 6648 INS0 : ISS; // Can only dual issue as instruction 0 6649 DIV : WR; 6650 %} 6651 6652 // Eg. SDIV x0, x1, x2 6653 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6654 %{ 6655 single_instruction; 6656 fixed_latency(16); // Maximum latency for 64 bit divide 6657 dst : WR(write); 6658 src1 : ISS(read); 6659 src2 : ISS(read); 6660 INS0 : ISS; // Can only dual issue as instruction 0 6661 DIV : WR; 6662 %} 6663 6664 //------- Load pipeline operations ------------------------ 6665 6666 // Load - prefetch 6667 // Eg. PFRM <mem> 6668 pipe_class iload_prefetch(memory mem) 6669 %{ 6670 single_instruction; 6671 mem : ISS(read); 6672 INS01 : ISS; 6673 LDST : WR; 6674 %} 6675 6676 // Load - reg, mem 6677 // Eg. LDR x0, <mem> 6678 pipe_class iload_reg_mem(iRegI dst, memory mem) 6679 %{ 6680 single_instruction; 6681 dst : WR(write); 6682 mem : ISS(read); 6683 INS01 : ISS; 6684 LDST : WR; 6685 %} 6686 6687 // Load - reg, reg 6688 // Eg. LDR x0, [sp, x1] 6689 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6690 %{ 6691 single_instruction; 6692 dst : WR(write); 6693 src : ISS(read); 6694 INS01 : ISS; 6695 LDST : WR; 6696 %} 6697 6698 //------- Store pipeline operations ----------------------- 6699 6700 // Store - zr, mem 6701 // Eg. STR zr, <mem> 6702 pipe_class istore_mem(memory mem) 6703 %{ 6704 single_instruction; 6705 mem : ISS(read); 6706 INS01 : ISS; 6707 LDST : WR; 6708 %} 6709 6710 // Store - reg, mem 6711 // Eg. STR x0, <mem> 6712 pipe_class istore_reg_mem(iRegI src, memory mem) 6713 %{ 6714 single_instruction; 6715 mem : ISS(read); 6716 src : EX2(read); 6717 INS01 : ISS; 6718 LDST : WR; 6719 %} 6720 6721 // Store - reg, reg 6722 // Eg. STR x0, [sp, x1] 6723 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6724 %{ 6725 single_instruction; 6726 dst : ISS(read); 6727 src : EX2(read); 6728 INS01 : ISS; 6729 LDST : WR; 6730 %} 6731 6732 //------- Store pipeline operations ----------------------- 6733 6734 // Branch 6735 pipe_class pipe_branch() 6736 %{ 6737 single_instruction; 6738 INS01 : ISS; 6739 BRANCH : EX1; 6740 %} 6741 6742 // Conditional branch 6743 pipe_class pipe_branch_cond(rFlagsReg cr) 6744 %{ 6745 single_instruction; 6746 cr : EX1(read); 6747 INS01 : ISS; 6748 BRANCH : EX1; 6749 %} 6750 6751 // Compare & Branch 6752 // EG. CBZ/CBNZ 6753 pipe_class pipe_cmp_branch(iRegI op1) 6754 %{ 6755 single_instruction; 6756 op1 : EX1(read); 6757 INS01 : ISS; 6758 BRANCH : EX1; 6759 %} 6760 6761 //------- Synchronisation operations ---------------------- 6762 6763 // Any operation requiring serialization. 6764 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6765 pipe_class pipe_serial() 6766 %{ 6767 single_instruction; 6768 force_serialization; 6769 fixed_latency(16); 6770 INS01 : ISS(2); // Cannot dual issue with any other instruction 6771 LDST : WR; 6772 %} 6773 6774 // Generic big/slow expanded idiom - also serialized 6775 pipe_class pipe_slow() 6776 %{ 6777 instruction_count(10); 6778 multiple_bundles; 6779 force_serialization; 6780 fixed_latency(16); 6781 INS01 : ISS(2); // Cannot dual issue with any other instruction 6782 LDST : WR; 6783 %} 6784 6785 // Empty pipeline class 6786 pipe_class pipe_class_empty() 6787 %{ 6788 single_instruction; 6789 fixed_latency(0); 6790 %} 6791 6792 // Default pipeline class. 6793 pipe_class pipe_class_default() 6794 %{ 6795 single_instruction; 6796 fixed_latency(2); 6797 %} 6798 6799 // Pipeline class for compares. 6800 pipe_class pipe_class_compare() 6801 %{ 6802 single_instruction; 6803 fixed_latency(16); 6804 %} 6805 6806 // Pipeline class for memory operations. 6807 pipe_class pipe_class_memory() 6808 %{ 6809 single_instruction; 6810 fixed_latency(16); 6811 %} 6812 6813 // Pipeline class for call. 6814 pipe_class pipe_class_call() 6815 %{ 6816 single_instruction; 6817 fixed_latency(100); 6818 %} 6819 6820 // Define the class for the Nop node. 6821 define %{ 6822 MachNop = pipe_class_empty; 6823 %} 6824 6825 %} 6826 //----------INSTRUCTIONS------------------------------------------------------- 6827 // 6828 // match -- States which machine-independent subtree may be replaced 6829 // by this instruction. 6830 // ins_cost -- The estimated cost of this instruction is used by instruction 6831 // selection to identify a minimum cost tree of machine 6832 // instructions that matches a tree of machine-independent 6833 // instructions. 6834 // format -- A string providing the disassembly for this instruction. 6835 // The value of an instruction's operand may be inserted 6836 // by referring to it with a '$' prefix. 6837 // opcode -- Three instruction opcodes may be provided. These are referred 6838 // to within an encode class as $primary, $secondary, and $tertiary 6839 // rrspectively. The primary opcode is commonly used to 6840 // indicate the type of machine instruction, while secondary 6841 // and tertiary are often used for prefix options or addressing 6842 // modes. 6843 // ins_encode -- A list of encode classes with parameters. The encode class 6844 // name must have been defined in an 'enc_class' specification 6845 // in the encode section of the architecture description. 6846 6847 // ============================================================================ 6848 // Memory (Load/Store) Instructions 6849 6850 // Load Instructions 6851 6852 // Load Byte (8 bit signed) 6853 instruct loadB(iRegINoSp dst, memory1 mem) 6854 %{ 6855 match(Set dst (LoadB mem)); 6856 predicate(!needs_acquiring_load(n)); 6857 6858 ins_cost(4 * INSN_COST); 6859 format %{ "ldrsbw $dst, $mem\t# byte" %} 6860 6861 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6862 6863 ins_pipe(iload_reg_mem); 6864 %} 6865 6866 // Load Byte (8 bit signed) into long 6867 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6868 %{ 6869 match(Set dst (ConvI2L (LoadB mem))); 6870 predicate(!needs_acquiring_load(n->in(1))); 6871 6872 ins_cost(4 * INSN_COST); 6873 format %{ "ldrsb $dst, $mem\t# byte" %} 6874 6875 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6876 6877 ins_pipe(iload_reg_mem); 6878 %} 6879 6880 // Load Byte (8 bit unsigned) 6881 instruct loadUB(iRegINoSp dst, memory1 mem) 6882 %{ 6883 match(Set dst (LoadUB mem)); 6884 predicate(!needs_acquiring_load(n)); 6885 6886 ins_cost(4 * INSN_COST); 6887 format %{ "ldrbw $dst, $mem\t# byte" %} 6888 6889 ins_encode(aarch64_enc_ldrb(dst, mem)); 6890 6891 ins_pipe(iload_reg_mem); 6892 %} 6893 6894 // Load Byte (8 bit unsigned) into long 6895 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6896 %{ 6897 match(Set dst (ConvI2L (LoadUB mem))); 6898 predicate(!needs_acquiring_load(n->in(1))); 6899 6900 ins_cost(4 * INSN_COST); 6901 format %{ "ldrb $dst, $mem\t# byte" %} 6902 6903 ins_encode(aarch64_enc_ldrb(dst, mem)); 6904 6905 ins_pipe(iload_reg_mem); 6906 %} 6907 6908 // Load Short (16 bit signed) 6909 instruct loadS(iRegINoSp dst, memory2 mem) 6910 %{ 6911 match(Set dst (LoadS mem)); 6912 predicate(!needs_acquiring_load(n)); 6913 6914 ins_cost(4 * INSN_COST); 6915 format %{ "ldrshw $dst, $mem\t# short" %} 6916 6917 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6918 6919 ins_pipe(iload_reg_mem); 6920 %} 6921 6922 // Load Short (16 bit signed) into long 6923 instruct loadS2L(iRegLNoSp dst, memory2 mem) 6924 %{ 6925 match(Set dst (ConvI2L (LoadS mem))); 6926 predicate(!needs_acquiring_load(n->in(1))); 6927 6928 ins_cost(4 * INSN_COST); 6929 format %{ "ldrsh $dst, $mem\t# short" %} 6930 6931 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6932 6933 ins_pipe(iload_reg_mem); 6934 %} 6935 6936 // Load Char (16 bit unsigned) 6937 instruct loadUS(iRegINoSp dst, memory2 mem) 6938 %{ 6939 match(Set dst (LoadUS mem)); 6940 predicate(!needs_acquiring_load(n)); 6941 6942 ins_cost(4 * INSN_COST); 6943 format %{ "ldrh $dst, $mem\t# short" %} 6944 6945 ins_encode(aarch64_enc_ldrh(dst, mem)); 6946 6947 ins_pipe(iload_reg_mem); 6948 %} 6949 6950 // Load Short/Char (16 bit unsigned) into long 6951 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 6952 %{ 6953 match(Set dst (ConvI2L (LoadUS mem))); 6954 predicate(!needs_acquiring_load(n->in(1))); 6955 6956 ins_cost(4 * INSN_COST); 6957 format %{ "ldrh $dst, $mem\t# short" %} 6958 6959 ins_encode(aarch64_enc_ldrh(dst, mem)); 6960 6961 ins_pipe(iload_reg_mem); 6962 %} 6963 6964 // Load Integer (32 bit signed) 6965 instruct loadI(iRegINoSp dst, memory4 mem) 6966 %{ 6967 match(Set dst (LoadI mem)); 6968 predicate(!needs_acquiring_load(n)); 6969 6970 ins_cost(4 * INSN_COST); 6971 format %{ "ldrw $dst, $mem\t# int" %} 6972 6973 ins_encode(aarch64_enc_ldrw(dst, mem)); 6974 6975 ins_pipe(iload_reg_mem); 6976 %} 6977 6978 // Load Integer (32 bit signed) into long 6979 instruct loadI2L(iRegLNoSp dst, memory4 mem) 6980 %{ 6981 match(Set dst (ConvI2L (LoadI mem))); 6982 predicate(!needs_acquiring_load(n->in(1))); 6983 6984 ins_cost(4 * INSN_COST); 6985 format %{ "ldrsw $dst, $mem\t# int" %} 6986 6987 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6988 6989 ins_pipe(iload_reg_mem); 6990 %} 6991 6992 // Load Integer (32 bit unsigned) into long 6993 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 6994 %{ 6995 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6996 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6997 6998 ins_cost(4 * INSN_COST); 6999 format %{ "ldrw $dst, $mem\t# int" %} 7000 7001 ins_encode(aarch64_enc_ldrw(dst, mem)); 7002 7003 ins_pipe(iload_reg_mem); 7004 %} 7005 7006 // Load Long (64 bit signed) 7007 instruct loadL(iRegLNoSp dst, memory8 mem) 7008 %{ 7009 match(Set dst (LoadL mem)); 7010 predicate(!needs_acquiring_load(n)); 7011 7012 ins_cost(4 * INSN_COST); 7013 format %{ "ldr $dst, $mem\t# int" %} 7014 7015 ins_encode(aarch64_enc_ldr(dst, mem)); 7016 7017 ins_pipe(iload_reg_mem); 7018 %} 7019 7020 // Load Range 7021 instruct loadRange(iRegINoSp dst, memory4 mem) 7022 %{ 7023 match(Set dst (LoadRange mem)); 7024 7025 ins_cost(4 * INSN_COST); 7026 format %{ "ldrw $dst, $mem\t# range" %} 7027 7028 ins_encode(aarch64_enc_ldrw(dst, mem)); 7029 7030 ins_pipe(iload_reg_mem); 7031 %} 7032 7033 // Load Pointer 7034 instruct loadP(iRegPNoSp dst, memory8 mem) 7035 %{ 7036 match(Set dst (LoadP mem)); 7037 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7038 7039 ins_cost(4 * INSN_COST); 7040 format %{ "ldr $dst, $mem\t# ptr" %} 7041 7042 ins_encode(aarch64_enc_ldr(dst, mem)); 7043 7044 ins_pipe(iload_reg_mem); 7045 %} 7046 7047 // Load Compressed Pointer 7048 instruct loadN(iRegNNoSp dst, memory4 mem) 7049 %{ 7050 match(Set dst (LoadN mem)); 7051 predicate(!needs_acquiring_load(n)); 7052 7053 ins_cost(4 * INSN_COST); 7054 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7055 7056 ins_encode(aarch64_enc_ldrw(dst, mem)); 7057 7058 ins_pipe(iload_reg_mem); 7059 %} 7060 7061 // Load Klass Pointer 7062 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7063 %{ 7064 match(Set dst (LoadKlass mem)); 7065 predicate(!needs_acquiring_load(n)); 7066 7067 ins_cost(4 * INSN_COST); 7068 format %{ "ldr $dst, $mem\t# class" %} 7069 7070 ins_encode(aarch64_enc_ldr(dst, mem)); 7071 7072 ins_pipe(iload_reg_mem); 7073 %} 7074 7075 // Load Narrow Klass Pointer 7076 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7077 %{ 7078 match(Set dst (LoadNKlass mem)); 7079 predicate(!needs_acquiring_load(n)); 7080 7081 ins_cost(4 * INSN_COST); 7082 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7083 7084 ins_encode(aarch64_enc_ldrw(dst, mem)); 7085 7086 ins_pipe(iload_reg_mem); 7087 %} 7088 7089 // Load Float 7090 instruct loadF(vRegF dst, memory4 mem) 7091 %{ 7092 match(Set dst (LoadF mem)); 7093 predicate(!needs_acquiring_load(n)); 7094 7095 ins_cost(4 * INSN_COST); 7096 format %{ "ldrs $dst, $mem\t# float" %} 7097 7098 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7099 7100 ins_pipe(pipe_class_memory); 7101 %} 7102 7103 // Load Double 7104 instruct loadD(vRegD dst, memory8 mem) 7105 %{ 7106 match(Set dst (LoadD mem)); 7107 predicate(!needs_acquiring_load(n)); 7108 7109 ins_cost(4 * INSN_COST); 7110 format %{ "ldrd $dst, $mem\t# double" %} 7111 7112 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7113 7114 ins_pipe(pipe_class_memory); 7115 %} 7116 7117 7118 // Load Int Constant 7119 instruct loadConI(iRegINoSp dst, immI src) 7120 %{ 7121 match(Set dst src); 7122 7123 ins_cost(INSN_COST); 7124 format %{ "mov $dst, $src\t# int" %} 7125 7126 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7127 7128 ins_pipe(ialu_imm); 7129 %} 7130 7131 // Load Long Constant 7132 instruct loadConL(iRegLNoSp dst, immL src) 7133 %{ 7134 match(Set dst src); 7135 7136 ins_cost(INSN_COST); 7137 format %{ "mov $dst, $src\t# long" %} 7138 7139 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7140 7141 ins_pipe(ialu_imm); 7142 %} 7143 7144 // Load Pointer Constant 7145 7146 instruct loadConP(iRegPNoSp dst, immP con) 7147 %{ 7148 match(Set dst con); 7149 7150 ins_cost(INSN_COST * 4); 7151 format %{ 7152 "mov $dst, $con\t# ptr\n\t" 7153 %} 7154 7155 ins_encode(aarch64_enc_mov_p(dst, con)); 7156 7157 ins_pipe(ialu_imm); 7158 %} 7159 7160 // Load Null Pointer Constant 7161 7162 instruct loadConP0(iRegPNoSp dst, immP0 con) 7163 %{ 7164 match(Set dst con); 7165 7166 ins_cost(INSN_COST); 7167 format %{ "mov $dst, $con\t# NULL ptr" %} 7168 7169 ins_encode(aarch64_enc_mov_p0(dst, con)); 7170 7171 ins_pipe(ialu_imm); 7172 %} 7173 7174 // Load Pointer Constant One 7175 7176 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7177 %{ 7178 match(Set dst con); 7179 7180 ins_cost(INSN_COST); 7181 format %{ "mov $dst, $con\t# NULL ptr" %} 7182 7183 ins_encode(aarch64_enc_mov_p1(dst, con)); 7184 7185 ins_pipe(ialu_imm); 7186 %} 7187 7188 // Load Poll Page Constant 7189 7190 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 7191 %{ 7192 match(Set dst con); 7193 7194 ins_cost(INSN_COST); 7195 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 7196 7197 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 7198 7199 ins_pipe(ialu_imm); 7200 %} 7201 7202 // Load Byte Map Base Constant 7203 7204 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7205 %{ 7206 match(Set dst con); 7207 7208 ins_cost(INSN_COST); 7209 format %{ "adr $dst, $con\t# Byte Map Base" %} 7210 7211 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7212 7213 ins_pipe(ialu_imm); 7214 %} 7215 7216 // Load Narrow Pointer Constant 7217 7218 instruct loadConN(iRegNNoSp dst, immN con) 7219 %{ 7220 match(Set dst con); 7221 7222 ins_cost(INSN_COST * 4); 7223 format %{ "mov $dst, $con\t# compressed ptr" %} 7224 7225 ins_encode(aarch64_enc_mov_n(dst, con)); 7226 7227 ins_pipe(ialu_imm); 7228 %} 7229 7230 // Load Narrow Null Pointer Constant 7231 7232 instruct loadConN0(iRegNNoSp dst, immN0 con) 7233 %{ 7234 match(Set dst con); 7235 7236 ins_cost(INSN_COST); 7237 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7238 7239 ins_encode(aarch64_enc_mov_n0(dst, con)); 7240 7241 ins_pipe(ialu_imm); 7242 %} 7243 7244 // Load Narrow Klass Constant 7245 7246 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7247 %{ 7248 match(Set dst con); 7249 7250 ins_cost(INSN_COST); 7251 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7252 7253 ins_encode(aarch64_enc_mov_nk(dst, con)); 7254 7255 ins_pipe(ialu_imm); 7256 %} 7257 7258 // Load Packed Float Constant 7259 7260 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7261 match(Set dst con); 7262 ins_cost(INSN_COST * 4); 7263 format %{ "fmovs $dst, $con"%} 7264 ins_encode %{ 7265 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7266 %} 7267 7268 ins_pipe(fp_imm_s); 7269 %} 7270 7271 // Load Float Constant 7272 7273 instruct loadConF(vRegF dst, immF con) %{ 7274 match(Set dst con); 7275 7276 ins_cost(INSN_COST * 4); 7277 7278 format %{ 7279 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7280 %} 7281 7282 ins_encode %{ 7283 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7284 %} 7285 7286 ins_pipe(fp_load_constant_s); 7287 %} 7288 7289 // Load Packed Double Constant 7290 7291 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7292 match(Set dst con); 7293 ins_cost(INSN_COST); 7294 format %{ "fmovd $dst, $con"%} 7295 ins_encode %{ 7296 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7297 %} 7298 7299 ins_pipe(fp_imm_d); 7300 %} 7301 7302 // Load Double Constant 7303 7304 instruct loadConD(vRegD dst, immD con) %{ 7305 match(Set dst con); 7306 7307 ins_cost(INSN_COST * 5); 7308 format %{ 7309 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7310 %} 7311 7312 ins_encode %{ 7313 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7314 %} 7315 7316 ins_pipe(fp_load_constant_d); 7317 %} 7318 7319 // Store Instructions 7320 7321 // Store CMS card-mark Immediate 7322 instruct storeimmCM0(immI0 zero, memory1 mem) 7323 %{ 7324 match(Set mem (StoreCM mem zero)); 7325 7326 ins_cost(INSN_COST); 7327 format %{ "storestore (elided)\n\t" 7328 "strb zr, $mem\t# byte" %} 7329 7330 ins_encode(aarch64_enc_strb0(mem)); 7331 7332 ins_pipe(istore_mem); 7333 %} 7334 7335 // Store CMS card-mark Immediate with intervening StoreStore 7336 // needed when using CMS with no conditional card marking 7337 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7338 %{ 7339 match(Set mem (StoreCM mem zero)); 7340 7341 ins_cost(INSN_COST * 2); 7342 format %{ "storestore\n\t" 7343 "dmb ishst" 7344 "\n\tstrb zr, $mem\t# byte" %} 7345 7346 ins_encode(aarch64_enc_strb0_ordered(mem)); 7347 7348 ins_pipe(istore_mem); 7349 %} 7350 7351 // Store Byte 7352 instruct storeB(iRegIorL2I src, memory1 mem) 7353 %{ 7354 match(Set mem (StoreB mem src)); 7355 predicate(!needs_releasing_store(n)); 7356 7357 ins_cost(INSN_COST); 7358 format %{ "strb $src, $mem\t# byte" %} 7359 7360 ins_encode(aarch64_enc_strb(src, mem)); 7361 7362 ins_pipe(istore_reg_mem); 7363 %} 7364 7365 7366 instruct storeimmB0(immI0 zero, memory1 mem) 7367 %{ 7368 match(Set mem (StoreB mem zero)); 7369 predicate(!needs_releasing_store(n)); 7370 7371 ins_cost(INSN_COST); 7372 format %{ "strb rscractch2, $mem\t# byte" %} 7373 7374 ins_encode(aarch64_enc_strb0(mem)); 7375 7376 ins_pipe(istore_mem); 7377 %} 7378 7379 // Store Char/Short 7380 instruct storeC(iRegIorL2I src, memory2 mem) 7381 %{ 7382 match(Set mem (StoreC mem src)); 7383 predicate(!needs_releasing_store(n)); 7384 7385 ins_cost(INSN_COST); 7386 format %{ "strh $src, $mem\t# short" %} 7387 7388 ins_encode(aarch64_enc_strh(src, mem)); 7389 7390 ins_pipe(istore_reg_mem); 7391 %} 7392 7393 instruct storeimmC0(immI0 zero, memory2 mem) 7394 %{ 7395 match(Set mem (StoreC mem zero)); 7396 predicate(!needs_releasing_store(n)); 7397 7398 ins_cost(INSN_COST); 7399 format %{ "strh zr, $mem\t# short" %} 7400 7401 ins_encode(aarch64_enc_strh0(mem)); 7402 7403 ins_pipe(istore_mem); 7404 %} 7405 7406 // Store Integer 7407 7408 instruct storeI(iRegIorL2I src, memory4 mem) 7409 %{ 7410 match(Set mem(StoreI mem src)); 7411 predicate(!needs_releasing_store(n)); 7412 7413 ins_cost(INSN_COST); 7414 format %{ "strw $src, $mem\t# int" %} 7415 7416 ins_encode(aarch64_enc_strw(src, mem)); 7417 7418 ins_pipe(istore_reg_mem); 7419 %} 7420 7421 instruct storeimmI0(immI0 zero, memory4 mem) 7422 %{ 7423 match(Set mem(StoreI mem zero)); 7424 predicate(!needs_releasing_store(n)); 7425 7426 ins_cost(INSN_COST); 7427 format %{ "strw zr, $mem\t# int" %} 7428 7429 ins_encode(aarch64_enc_strw0(mem)); 7430 7431 ins_pipe(istore_mem); 7432 %} 7433 7434 // Store Long (64 bit signed) 7435 instruct storeL(iRegL src, memory8 mem) 7436 %{ 7437 match(Set mem (StoreL mem src)); 7438 predicate(!needs_releasing_store(n)); 7439 7440 ins_cost(INSN_COST); 7441 format %{ "str $src, $mem\t# int" %} 7442 7443 ins_encode(aarch64_enc_str(src, mem)); 7444 7445 ins_pipe(istore_reg_mem); 7446 %} 7447 7448 // Store Long (64 bit signed) 7449 instruct storeimmL0(immL0 zero, memory8 mem) 7450 %{ 7451 match(Set mem (StoreL mem zero)); 7452 predicate(!needs_releasing_store(n)); 7453 7454 ins_cost(INSN_COST); 7455 format %{ "str zr, $mem\t# int" %} 7456 7457 ins_encode(aarch64_enc_str0(mem)); 7458 7459 ins_pipe(istore_mem); 7460 %} 7461 7462 // Store Pointer 7463 instruct storeP(iRegP src, memory8 mem) 7464 %{ 7465 match(Set mem (StoreP mem src)); 7466 predicate(!needs_releasing_store(n)); 7467 7468 ins_cost(INSN_COST); 7469 format %{ "str $src, $mem\t# ptr" %} 7470 7471 ins_encode(aarch64_enc_str(src, mem)); 7472 7473 ins_pipe(istore_reg_mem); 7474 %} 7475 7476 // Store Pointer 7477 instruct storeimmP0(immP0 zero, memory8 mem) 7478 %{ 7479 match(Set mem (StoreP mem zero)); 7480 predicate(!needs_releasing_store(n)); 7481 7482 ins_cost(INSN_COST); 7483 format %{ "str zr, $mem\t# ptr" %} 7484 7485 ins_encode(aarch64_enc_str0(mem)); 7486 7487 ins_pipe(istore_mem); 7488 %} 7489 7490 // Store Compressed Pointer 7491 instruct storeN(iRegN src, memory4 mem) 7492 %{ 7493 match(Set mem (StoreN mem src)); 7494 predicate(!needs_releasing_store(n)); 7495 7496 ins_cost(INSN_COST); 7497 format %{ "strw $src, $mem\t# compressed ptr" %} 7498 7499 ins_encode(aarch64_enc_strw(src, mem)); 7500 7501 ins_pipe(istore_reg_mem); 7502 %} 7503 7504 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory4 mem) 7505 %{ 7506 match(Set mem (StoreN mem zero)); 7507 predicate(CompressedOops::base() == NULL && 7508 CompressedKlassPointers::base() == NULL && 7509 (!needs_releasing_store(n))); 7510 7511 ins_cost(INSN_COST); 7512 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7513 7514 ins_encode(aarch64_enc_strw(heapbase, mem)); 7515 7516 ins_pipe(istore_reg_mem); 7517 %} 7518 7519 // Store Float 7520 instruct storeF(vRegF src, memory4 mem) 7521 %{ 7522 match(Set mem (StoreF mem src)); 7523 predicate(!needs_releasing_store(n)); 7524 7525 ins_cost(INSN_COST); 7526 format %{ "strs $src, $mem\t# float" %} 7527 7528 ins_encode( aarch64_enc_strs(src, mem) ); 7529 7530 ins_pipe(pipe_class_memory); 7531 %} 7532 7533 // TODO 7534 // implement storeImmF0 and storeFImmPacked 7535 7536 // Store Double 7537 instruct storeD(vRegD src, memory8 mem) 7538 %{ 7539 match(Set mem (StoreD mem src)); 7540 predicate(!needs_releasing_store(n)); 7541 7542 ins_cost(INSN_COST); 7543 format %{ "strd $src, $mem\t# double" %} 7544 7545 ins_encode( aarch64_enc_strd(src, mem) ); 7546 7547 ins_pipe(pipe_class_memory); 7548 %} 7549 7550 // Store Compressed Klass Pointer 7551 instruct storeNKlass(iRegN src, memory4 mem) 7552 %{ 7553 predicate(!needs_releasing_store(n)); 7554 match(Set mem (StoreNKlass mem src)); 7555 7556 ins_cost(INSN_COST); 7557 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7558 7559 ins_encode(aarch64_enc_strw(src, mem)); 7560 7561 ins_pipe(istore_reg_mem); 7562 %} 7563 7564 // TODO 7565 // implement storeImmD0 and storeDImmPacked 7566 7567 // prefetch instructions 7568 // Must be safe to execute with invalid address (cannot fault). 7569 7570 instruct prefetchalloc( memory8 mem ) %{ 7571 match(PrefetchAllocation mem); 7572 7573 ins_cost(INSN_COST); 7574 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7575 7576 ins_encode( aarch64_enc_prefetchw(mem) ); 7577 7578 ins_pipe(iload_prefetch); 7579 %} 7580 7581 // ---------------- volatile loads and stores ---------------- 7582 7583 // Load Byte (8 bit signed) 7584 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7585 %{ 7586 match(Set dst (LoadB mem)); 7587 7588 ins_cost(VOLATILE_REF_COST); 7589 format %{ "ldarsb $dst, $mem\t# byte" %} 7590 7591 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7592 7593 ins_pipe(pipe_serial); 7594 %} 7595 7596 // Load Byte (8 bit signed) into long 7597 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7598 %{ 7599 match(Set dst (ConvI2L (LoadB mem))); 7600 7601 ins_cost(VOLATILE_REF_COST); 7602 format %{ "ldarsb $dst, $mem\t# byte" %} 7603 7604 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7605 7606 ins_pipe(pipe_serial); 7607 %} 7608 7609 // Load Byte (8 bit unsigned) 7610 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7611 %{ 7612 match(Set dst (LoadUB mem)); 7613 7614 ins_cost(VOLATILE_REF_COST); 7615 format %{ "ldarb $dst, $mem\t# byte" %} 7616 7617 ins_encode(aarch64_enc_ldarb(dst, mem)); 7618 7619 ins_pipe(pipe_serial); 7620 %} 7621 7622 // Load Byte (8 bit unsigned) into long 7623 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7624 %{ 7625 match(Set dst (ConvI2L (LoadUB mem))); 7626 7627 ins_cost(VOLATILE_REF_COST); 7628 format %{ "ldarb $dst, $mem\t# byte" %} 7629 7630 ins_encode(aarch64_enc_ldarb(dst, mem)); 7631 7632 ins_pipe(pipe_serial); 7633 %} 7634 7635 // Load Short (16 bit signed) 7636 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7637 %{ 7638 match(Set dst (LoadS mem)); 7639 7640 ins_cost(VOLATILE_REF_COST); 7641 format %{ "ldarshw $dst, $mem\t# short" %} 7642 7643 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7644 7645 ins_pipe(pipe_serial); 7646 %} 7647 7648 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7649 %{ 7650 match(Set dst (LoadUS mem)); 7651 7652 ins_cost(VOLATILE_REF_COST); 7653 format %{ "ldarhw $dst, $mem\t# short" %} 7654 7655 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7656 7657 ins_pipe(pipe_serial); 7658 %} 7659 7660 // Load Short/Char (16 bit unsigned) into long 7661 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7662 %{ 7663 match(Set dst (ConvI2L (LoadUS mem))); 7664 7665 ins_cost(VOLATILE_REF_COST); 7666 format %{ "ldarh $dst, $mem\t# short" %} 7667 7668 ins_encode(aarch64_enc_ldarh(dst, mem)); 7669 7670 ins_pipe(pipe_serial); 7671 %} 7672 7673 // Load Short/Char (16 bit signed) into long 7674 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7675 %{ 7676 match(Set dst (ConvI2L (LoadS mem))); 7677 7678 ins_cost(VOLATILE_REF_COST); 7679 format %{ "ldarh $dst, $mem\t# short" %} 7680 7681 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7682 7683 ins_pipe(pipe_serial); 7684 %} 7685 7686 // Load Integer (32 bit signed) 7687 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7688 %{ 7689 match(Set dst (LoadI mem)); 7690 7691 ins_cost(VOLATILE_REF_COST); 7692 format %{ "ldarw $dst, $mem\t# int" %} 7693 7694 ins_encode(aarch64_enc_ldarw(dst, mem)); 7695 7696 ins_pipe(pipe_serial); 7697 %} 7698 7699 // Load Integer (32 bit unsigned) into long 7700 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7701 %{ 7702 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7703 7704 ins_cost(VOLATILE_REF_COST); 7705 format %{ "ldarw $dst, $mem\t# int" %} 7706 7707 ins_encode(aarch64_enc_ldarw(dst, mem)); 7708 7709 ins_pipe(pipe_serial); 7710 %} 7711 7712 // Load Long (64 bit signed) 7713 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7714 %{ 7715 match(Set dst (LoadL mem)); 7716 7717 ins_cost(VOLATILE_REF_COST); 7718 format %{ "ldar $dst, $mem\t# int" %} 7719 7720 ins_encode(aarch64_enc_ldar(dst, mem)); 7721 7722 ins_pipe(pipe_serial); 7723 %} 7724 7725 // Load Pointer 7726 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7727 %{ 7728 match(Set dst (LoadP mem)); 7729 predicate(n->as_Load()->barrier_data() == 0); 7730 7731 ins_cost(VOLATILE_REF_COST); 7732 format %{ "ldar $dst, $mem\t# ptr" %} 7733 7734 ins_encode(aarch64_enc_ldar(dst, mem)); 7735 7736 ins_pipe(pipe_serial); 7737 %} 7738 7739 // Load Compressed Pointer 7740 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7741 %{ 7742 match(Set dst (LoadN mem)); 7743 7744 ins_cost(VOLATILE_REF_COST); 7745 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7746 7747 ins_encode(aarch64_enc_ldarw(dst, mem)); 7748 7749 ins_pipe(pipe_serial); 7750 %} 7751 7752 // Load Float 7753 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7754 %{ 7755 match(Set dst (LoadF mem)); 7756 7757 ins_cost(VOLATILE_REF_COST); 7758 format %{ "ldars $dst, $mem\t# float" %} 7759 7760 ins_encode( aarch64_enc_fldars(dst, mem) ); 7761 7762 ins_pipe(pipe_serial); 7763 %} 7764 7765 // Load Double 7766 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7767 %{ 7768 match(Set dst (LoadD mem)); 7769 7770 ins_cost(VOLATILE_REF_COST); 7771 format %{ "ldard $dst, $mem\t# double" %} 7772 7773 ins_encode( aarch64_enc_fldard(dst, mem) ); 7774 7775 ins_pipe(pipe_serial); 7776 %} 7777 7778 // Store Byte 7779 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7780 %{ 7781 match(Set mem (StoreB mem src)); 7782 7783 ins_cost(VOLATILE_REF_COST); 7784 format %{ "stlrb $src, $mem\t# byte" %} 7785 7786 ins_encode(aarch64_enc_stlrb(src, mem)); 7787 7788 ins_pipe(pipe_class_memory); 7789 %} 7790 7791 // Store Char/Short 7792 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7793 %{ 7794 match(Set mem (StoreC mem src)); 7795 7796 ins_cost(VOLATILE_REF_COST); 7797 format %{ "stlrh $src, $mem\t# short" %} 7798 7799 ins_encode(aarch64_enc_stlrh(src, mem)); 7800 7801 ins_pipe(pipe_class_memory); 7802 %} 7803 7804 // Store Integer 7805 7806 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7807 %{ 7808 match(Set mem(StoreI mem src)); 7809 7810 ins_cost(VOLATILE_REF_COST); 7811 format %{ "stlrw $src, $mem\t# int" %} 7812 7813 ins_encode(aarch64_enc_stlrw(src, mem)); 7814 7815 ins_pipe(pipe_class_memory); 7816 %} 7817 7818 // Store Long (64 bit signed) 7819 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7820 %{ 7821 match(Set mem (StoreL mem src)); 7822 7823 ins_cost(VOLATILE_REF_COST); 7824 format %{ "stlr $src, $mem\t# int" %} 7825 7826 ins_encode(aarch64_enc_stlr(src, mem)); 7827 7828 ins_pipe(pipe_class_memory); 7829 %} 7830 7831 // Store Pointer 7832 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7833 %{ 7834 match(Set mem (StoreP mem src)); 7835 7836 ins_cost(VOLATILE_REF_COST); 7837 format %{ "stlr $src, $mem\t# ptr" %} 7838 7839 ins_encode(aarch64_enc_stlr(src, mem)); 7840 7841 ins_pipe(pipe_class_memory); 7842 %} 7843 7844 // Store Compressed Pointer 7845 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7846 %{ 7847 match(Set mem (StoreN mem src)); 7848 7849 ins_cost(VOLATILE_REF_COST); 7850 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7851 7852 ins_encode(aarch64_enc_stlrw(src, mem)); 7853 7854 ins_pipe(pipe_class_memory); 7855 %} 7856 7857 // Store Float 7858 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7859 %{ 7860 match(Set mem (StoreF mem src)); 7861 7862 ins_cost(VOLATILE_REF_COST); 7863 format %{ "stlrs $src, $mem\t# float" %} 7864 7865 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7866 7867 ins_pipe(pipe_class_memory); 7868 %} 7869 7870 // TODO 7871 // implement storeImmF0 and storeFImmPacked 7872 7873 // Store Double 7874 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7875 %{ 7876 match(Set mem (StoreD mem src)); 7877 7878 ins_cost(VOLATILE_REF_COST); 7879 format %{ "stlrd $src, $mem\t# double" %} 7880 7881 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7882 7883 ins_pipe(pipe_class_memory); 7884 %} 7885 7886 // ---------------- end of volatile loads and stores ---------------- 7887 7888 instruct cacheWB(indirect addr) 7889 %{ 7890 predicate(VM_Version::supports_data_cache_line_flush()); 7891 match(CacheWB addr); 7892 7893 ins_cost(100); 7894 format %{"cache wb $addr" %} 7895 ins_encode %{ 7896 assert($addr->index_position() < 0, "should be"); 7897 assert($addr$$disp == 0, "should be"); 7898 __ cache_wb(Address($addr$$base$$Register, 0)); 7899 %} 7900 ins_pipe(pipe_slow); // XXX 7901 %} 7902 7903 instruct cacheWBPreSync() 7904 %{ 7905 predicate(VM_Version::supports_data_cache_line_flush()); 7906 match(CacheWBPreSync); 7907 7908 ins_cost(100); 7909 format %{"cache wb presync" %} 7910 ins_encode %{ 7911 __ cache_wbsync(true); 7912 %} 7913 ins_pipe(pipe_slow); // XXX 7914 %} 7915 7916 instruct cacheWBPostSync() 7917 %{ 7918 predicate(VM_Version::supports_data_cache_line_flush()); 7919 match(CacheWBPostSync); 7920 7921 ins_cost(100); 7922 format %{"cache wb postsync" %} 7923 ins_encode %{ 7924 __ cache_wbsync(false); 7925 %} 7926 ins_pipe(pipe_slow); // XXX 7927 %} 7928 7929 // ============================================================================ 7930 // BSWAP Instructions 7931 7932 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7933 match(Set dst (ReverseBytesI src)); 7934 7935 ins_cost(INSN_COST); 7936 format %{ "revw $dst, $src" %} 7937 7938 ins_encode %{ 7939 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7940 %} 7941 7942 ins_pipe(ialu_reg); 7943 %} 7944 7945 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7946 match(Set dst (ReverseBytesL src)); 7947 7948 ins_cost(INSN_COST); 7949 format %{ "rev $dst, $src" %} 7950 7951 ins_encode %{ 7952 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7953 %} 7954 7955 ins_pipe(ialu_reg); 7956 %} 7957 7958 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7959 match(Set dst (ReverseBytesUS src)); 7960 7961 ins_cost(INSN_COST); 7962 format %{ "rev16w $dst, $src" %} 7963 7964 ins_encode %{ 7965 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7966 %} 7967 7968 ins_pipe(ialu_reg); 7969 %} 7970 7971 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7972 match(Set dst (ReverseBytesS src)); 7973 7974 ins_cost(INSN_COST); 7975 format %{ "rev16w $dst, $src\n\t" 7976 "sbfmw $dst, $dst, #0, #15" %} 7977 7978 ins_encode %{ 7979 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7980 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7981 %} 7982 7983 ins_pipe(ialu_reg); 7984 %} 7985 7986 // ============================================================================ 7987 // Zero Count Instructions 7988 7989 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7990 match(Set dst (CountLeadingZerosI src)); 7991 7992 ins_cost(INSN_COST); 7993 format %{ "clzw $dst, $src" %} 7994 ins_encode %{ 7995 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7996 %} 7997 7998 ins_pipe(ialu_reg); 7999 %} 8000 8001 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8002 match(Set dst (CountLeadingZerosL src)); 8003 8004 ins_cost(INSN_COST); 8005 format %{ "clz $dst, $src" %} 8006 ins_encode %{ 8007 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8008 %} 8009 8010 ins_pipe(ialu_reg); 8011 %} 8012 8013 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8014 match(Set dst (CountTrailingZerosI src)); 8015 8016 ins_cost(INSN_COST * 2); 8017 format %{ "rbitw $dst, $src\n\t" 8018 "clzw $dst, $dst" %} 8019 ins_encode %{ 8020 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8021 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8022 %} 8023 8024 ins_pipe(ialu_reg); 8025 %} 8026 8027 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8028 match(Set dst (CountTrailingZerosL src)); 8029 8030 ins_cost(INSN_COST * 2); 8031 format %{ "rbit $dst, $src\n\t" 8032 "clz $dst, $dst" %} 8033 ins_encode %{ 8034 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8035 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8036 %} 8037 8038 ins_pipe(ialu_reg); 8039 %} 8040 8041 //---------- Population Count Instructions ------------------------------------- 8042 // 8043 8044 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8045 predicate(UsePopCountInstruction); 8046 match(Set dst (PopCountI src)); 8047 effect(TEMP tmp); 8048 ins_cost(INSN_COST * 13); 8049 8050 format %{ "movw $src, $src\n\t" 8051 "mov $tmp, $src\t# vector (1D)\n\t" 8052 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8053 "addv $tmp, $tmp\t# vector (8B)\n\t" 8054 "mov $dst, $tmp\t# vector (1D)" %} 8055 ins_encode %{ 8056 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8057 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8058 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8059 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8060 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8061 %} 8062 8063 ins_pipe(pipe_class_default); 8064 %} 8065 8066 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8067 predicate(UsePopCountInstruction); 8068 match(Set dst (PopCountI (LoadI mem))); 8069 effect(TEMP tmp); 8070 ins_cost(INSN_COST * 13); 8071 8072 format %{ "ldrs $tmp, $mem\n\t" 8073 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8074 "addv $tmp, $tmp\t# vector (8B)\n\t" 8075 "mov $dst, $tmp\t# vector (1D)" %} 8076 ins_encode %{ 8077 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8078 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8079 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8080 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8081 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8082 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8083 %} 8084 8085 ins_pipe(pipe_class_default); 8086 %} 8087 8088 // Note: Long.bitCount(long) returns an int. 8089 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8090 predicate(UsePopCountInstruction); 8091 match(Set dst (PopCountL src)); 8092 effect(TEMP tmp); 8093 ins_cost(INSN_COST * 13); 8094 8095 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8096 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8097 "addv $tmp, $tmp\t# vector (8B)\n\t" 8098 "mov $dst, $tmp\t# vector (1D)" %} 8099 ins_encode %{ 8100 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8101 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8102 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8103 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8104 %} 8105 8106 ins_pipe(pipe_class_default); 8107 %} 8108 8109 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8110 predicate(UsePopCountInstruction); 8111 match(Set dst (PopCountL (LoadL mem))); 8112 effect(TEMP tmp); 8113 ins_cost(INSN_COST * 13); 8114 8115 format %{ "ldrd $tmp, $mem\n\t" 8116 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8117 "addv $tmp, $tmp\t# vector (8B)\n\t" 8118 "mov $dst, $tmp\t# vector (1D)" %} 8119 ins_encode %{ 8120 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8121 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8122 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8123 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8124 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8125 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8126 %} 8127 8128 ins_pipe(pipe_class_default); 8129 %} 8130 8131 // ============================================================================ 8132 // MemBar Instruction 8133 8134 instruct load_fence() %{ 8135 match(LoadFence); 8136 ins_cost(VOLATILE_REF_COST); 8137 8138 format %{ "load_fence" %} 8139 8140 ins_encode %{ 8141 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8142 %} 8143 ins_pipe(pipe_serial); 8144 %} 8145 8146 instruct unnecessary_membar_acquire() %{ 8147 predicate(unnecessary_acquire(n)); 8148 match(MemBarAcquire); 8149 ins_cost(0); 8150 8151 format %{ "membar_acquire (elided)" %} 8152 8153 ins_encode %{ 8154 __ block_comment("membar_acquire (elided)"); 8155 %} 8156 8157 ins_pipe(pipe_class_empty); 8158 %} 8159 8160 instruct membar_acquire() %{ 8161 match(MemBarAcquire); 8162 ins_cost(VOLATILE_REF_COST); 8163 8164 format %{ "membar_acquire\n\t" 8165 "dmb ish" %} 8166 8167 ins_encode %{ 8168 __ block_comment("membar_acquire"); 8169 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8170 %} 8171 8172 ins_pipe(pipe_serial); 8173 %} 8174 8175 8176 instruct membar_acquire_lock() %{ 8177 match(MemBarAcquireLock); 8178 ins_cost(VOLATILE_REF_COST); 8179 8180 format %{ "membar_acquire_lock (elided)" %} 8181 8182 ins_encode %{ 8183 __ block_comment("membar_acquire_lock (elided)"); 8184 %} 8185 8186 ins_pipe(pipe_serial); 8187 %} 8188 8189 instruct store_fence() %{ 8190 match(StoreFence); 8191 ins_cost(VOLATILE_REF_COST); 8192 8193 format %{ "store_fence" %} 8194 8195 ins_encode %{ 8196 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8197 %} 8198 ins_pipe(pipe_serial); 8199 %} 8200 8201 instruct unnecessary_membar_release() %{ 8202 predicate(unnecessary_release(n)); 8203 match(MemBarRelease); 8204 ins_cost(0); 8205 8206 format %{ "membar_release (elided)" %} 8207 8208 ins_encode %{ 8209 __ block_comment("membar_release (elided)"); 8210 %} 8211 ins_pipe(pipe_serial); 8212 %} 8213 8214 instruct membar_release() %{ 8215 match(MemBarRelease); 8216 ins_cost(VOLATILE_REF_COST); 8217 8218 format %{ "membar_release\n\t" 8219 "dmb ish" %} 8220 8221 ins_encode %{ 8222 __ block_comment("membar_release"); 8223 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8224 %} 8225 ins_pipe(pipe_serial); 8226 %} 8227 8228 instruct membar_storestore() %{ 8229 match(MemBarStoreStore); 8230 ins_cost(VOLATILE_REF_COST); 8231 8232 format %{ "MEMBAR-store-store" %} 8233 8234 ins_encode %{ 8235 __ membar(Assembler::StoreStore); 8236 %} 8237 ins_pipe(pipe_serial); 8238 %} 8239 8240 instruct membar_release_lock() %{ 8241 match(MemBarReleaseLock); 8242 ins_cost(VOLATILE_REF_COST); 8243 8244 format %{ "membar_release_lock (elided)" %} 8245 8246 ins_encode %{ 8247 __ block_comment("membar_release_lock (elided)"); 8248 %} 8249 8250 ins_pipe(pipe_serial); 8251 %} 8252 8253 instruct unnecessary_membar_volatile() %{ 8254 predicate(unnecessary_volatile(n)); 8255 match(MemBarVolatile); 8256 ins_cost(0); 8257 8258 format %{ "membar_volatile (elided)" %} 8259 8260 ins_encode %{ 8261 __ block_comment("membar_volatile (elided)"); 8262 %} 8263 8264 ins_pipe(pipe_serial); 8265 %} 8266 8267 instruct membar_volatile() %{ 8268 match(MemBarVolatile); 8269 ins_cost(VOLATILE_REF_COST*100); 8270 8271 format %{ "membar_volatile\n\t" 8272 "dmb ish"%} 8273 8274 ins_encode %{ 8275 __ block_comment("membar_volatile"); 8276 __ membar(Assembler::StoreLoad); 8277 %} 8278 8279 ins_pipe(pipe_serial); 8280 %} 8281 8282 // ============================================================================ 8283 // Cast/Convert Instructions 8284 8285 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8286 match(Set dst (CastX2P src)); 8287 8288 ins_cost(INSN_COST); 8289 format %{ "mov $dst, $src\t# long -> ptr" %} 8290 8291 ins_encode %{ 8292 if ($dst$$reg != $src$$reg) { 8293 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8294 } 8295 %} 8296 8297 ins_pipe(ialu_reg); 8298 %} 8299 8300 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8301 match(Set dst (CastP2X src)); 8302 8303 ins_cost(INSN_COST); 8304 format %{ "mov $dst, $src\t# ptr -> long" %} 8305 8306 ins_encode %{ 8307 if ($dst$$reg != $src$$reg) { 8308 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8309 } 8310 %} 8311 8312 ins_pipe(ialu_reg); 8313 %} 8314 8315 // Convert oop into int for vectors alignment masking 8316 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8317 match(Set dst (ConvL2I (CastP2X src))); 8318 8319 ins_cost(INSN_COST); 8320 format %{ "movw $dst, $src\t# ptr -> int" %} 8321 ins_encode %{ 8322 __ movw($dst$$Register, $src$$Register); 8323 %} 8324 8325 ins_pipe(ialu_reg); 8326 %} 8327 8328 // Convert compressed oop into int for vectors alignment masking 8329 // in case of 32bit oops (heap < 4Gb). 8330 instruct convN2I(iRegINoSp dst, iRegN src) 8331 %{ 8332 predicate(CompressedOops::shift() == 0); 8333 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8334 8335 ins_cost(INSN_COST); 8336 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8337 ins_encode %{ 8338 __ movw($dst$$Register, $src$$Register); 8339 %} 8340 8341 ins_pipe(ialu_reg); 8342 %} 8343 8344 8345 // Convert oop pointer into compressed form 8346 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8347 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8348 match(Set dst (EncodeP src)); 8349 effect(KILL cr); 8350 ins_cost(INSN_COST * 3); 8351 format %{ "encode_heap_oop $dst, $src" %} 8352 ins_encode %{ 8353 Register s = $src$$Register; 8354 Register d = $dst$$Register; 8355 __ encode_heap_oop(d, s); 8356 %} 8357 ins_pipe(ialu_reg); 8358 %} 8359 8360 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8361 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8362 match(Set dst (EncodeP src)); 8363 ins_cost(INSN_COST * 3); 8364 format %{ "encode_heap_oop_not_null $dst, $src" %} 8365 ins_encode %{ 8366 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8367 %} 8368 ins_pipe(ialu_reg); 8369 %} 8370 8371 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8372 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8373 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8374 match(Set dst (DecodeN src)); 8375 ins_cost(INSN_COST * 3); 8376 format %{ "decode_heap_oop $dst, $src" %} 8377 ins_encode %{ 8378 Register s = $src$$Register; 8379 Register d = $dst$$Register; 8380 __ decode_heap_oop(d, s); 8381 %} 8382 ins_pipe(ialu_reg); 8383 %} 8384 8385 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8386 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8387 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8388 match(Set dst (DecodeN src)); 8389 ins_cost(INSN_COST * 3); 8390 format %{ "decode_heap_oop_not_null $dst, $src" %} 8391 ins_encode %{ 8392 Register s = $src$$Register; 8393 Register d = $dst$$Register; 8394 __ decode_heap_oop_not_null(d, s); 8395 %} 8396 ins_pipe(ialu_reg); 8397 %} 8398 8399 // n.b. AArch64 implementations of encode_klass_not_null and 8400 // decode_klass_not_null do not modify the flags register so, unlike 8401 // Intel, we don't kill CR as a side effect here 8402 8403 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8404 match(Set dst (EncodePKlass src)); 8405 8406 ins_cost(INSN_COST * 3); 8407 format %{ "encode_klass_not_null $dst,$src" %} 8408 8409 ins_encode %{ 8410 Register src_reg = as_Register($src$$reg); 8411 Register dst_reg = as_Register($dst$$reg); 8412 __ encode_klass_not_null(dst_reg, src_reg); 8413 %} 8414 8415 ins_pipe(ialu_reg); 8416 %} 8417 8418 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8419 match(Set dst (DecodeNKlass src)); 8420 8421 ins_cost(INSN_COST * 3); 8422 format %{ "decode_klass_not_null $dst,$src" %} 8423 8424 ins_encode %{ 8425 Register src_reg = as_Register($src$$reg); 8426 Register dst_reg = as_Register($dst$$reg); 8427 if (dst_reg != src_reg) { 8428 __ decode_klass_not_null(dst_reg, src_reg); 8429 } else { 8430 __ decode_klass_not_null(dst_reg); 8431 } 8432 %} 8433 8434 ins_pipe(ialu_reg); 8435 %} 8436 8437 instruct checkCastPP(iRegPNoSp dst) 8438 %{ 8439 match(Set dst (CheckCastPP dst)); 8440 8441 size(0); 8442 format %{ "# checkcastPP of $dst" %} 8443 ins_encode(/* empty encoding */); 8444 ins_pipe(pipe_class_empty); 8445 %} 8446 8447 instruct castPP(iRegPNoSp dst) 8448 %{ 8449 match(Set dst (CastPP dst)); 8450 8451 size(0); 8452 format %{ "# castPP of $dst" %} 8453 ins_encode(/* empty encoding */); 8454 ins_pipe(pipe_class_empty); 8455 %} 8456 8457 instruct castII(iRegI dst) 8458 %{ 8459 match(Set dst (CastII dst)); 8460 8461 size(0); 8462 format %{ "# castII of $dst" %} 8463 ins_encode(/* empty encoding */); 8464 ins_cost(0); 8465 ins_pipe(pipe_class_empty); 8466 %} 8467 8468 instruct castLL(iRegL dst) 8469 %{ 8470 match(Set dst (CastLL dst)); 8471 8472 size(0); 8473 format %{ "# castLL of $dst" %} 8474 ins_encode(/* empty encoding */); 8475 ins_cost(0); 8476 ins_pipe(pipe_class_empty); 8477 %} 8478 8479 // ============================================================================ 8480 // Atomic operation instructions 8481 // 8482 // Intel and SPARC both implement Ideal Node LoadPLocked and 8483 // Store{PIL}Conditional instructions using a normal load for the 8484 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8485 // 8486 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8487 // pair to lock object allocations from Eden space when not using 8488 // TLABs. 8489 // 8490 // There does not appear to be a Load{IL}Locked Ideal Node and the 8491 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8492 // and to use StoreIConditional only for 32-bit and StoreLConditional 8493 // only for 64-bit. 8494 // 8495 // We implement LoadPLocked and StorePLocked instructions using, 8496 // respectively the AArch64 hw load-exclusive and store-conditional 8497 // instructions. Whereas we must implement each of 8498 // Store{IL}Conditional using a CAS which employs a pair of 8499 // instructions comprising a load-exclusive followed by a 8500 // store-conditional. 8501 8502 8503 // Locked-load (linked load) of the current heap-top 8504 // used when updating the eden heap top 8505 // implemented using ldaxr on AArch64 8506 8507 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8508 %{ 8509 match(Set dst (LoadPLocked mem)); 8510 8511 ins_cost(VOLATILE_REF_COST); 8512 8513 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8514 8515 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8516 8517 ins_pipe(pipe_serial); 8518 %} 8519 8520 // Conditional-store of the updated heap-top. 8521 // Used during allocation of the shared heap. 8522 // Sets flag (EQ) on success. 8523 // implemented using stlxr on AArch64. 8524 8525 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8526 %{ 8527 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8528 8529 ins_cost(VOLATILE_REF_COST); 8530 8531 // TODO 8532 // do we need to do a store-conditional release or can we just use a 8533 // plain store-conditional? 8534 8535 format %{ 8536 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8537 "cmpw rscratch1, zr\t# EQ on successful write" 8538 %} 8539 8540 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8541 8542 ins_pipe(pipe_serial); 8543 %} 8544 8545 8546 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8547 // when attempting to rebias a lock towards the current thread. We 8548 // must use the acquire form of cmpxchg in order to guarantee acquire 8549 // semantics in this case. 8550 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8551 %{ 8552 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8553 8554 ins_cost(VOLATILE_REF_COST); 8555 8556 format %{ 8557 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8558 "cmpw rscratch1, zr\t# EQ on successful write" 8559 %} 8560 8561 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8562 8563 ins_pipe(pipe_slow); 8564 %} 8565 8566 // storeIConditional also has acquire semantics, for no better reason 8567 // than matching storeLConditional. At the time of writing this 8568 // comment storeIConditional was not used anywhere by AArch64. 8569 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8570 %{ 8571 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8572 8573 ins_cost(VOLATILE_REF_COST); 8574 8575 format %{ 8576 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8577 "cmpw rscratch1, zr\t# EQ on successful write" 8578 %} 8579 8580 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8581 8582 ins_pipe(pipe_slow); 8583 %} 8584 8585 // standard CompareAndSwapX when we are using barriers 8586 // these have higher priority than the rules selected by a predicate 8587 8588 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8589 // can't match them 8590 8591 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8592 8593 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8594 ins_cost(2 * VOLATILE_REF_COST); 8595 8596 effect(KILL cr); 8597 8598 format %{ 8599 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8600 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8601 %} 8602 8603 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8604 aarch64_enc_cset_eq(res)); 8605 8606 ins_pipe(pipe_slow); 8607 %} 8608 8609 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8610 8611 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8612 ins_cost(2 * VOLATILE_REF_COST); 8613 8614 effect(KILL cr); 8615 8616 format %{ 8617 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8618 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8619 %} 8620 8621 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8622 aarch64_enc_cset_eq(res)); 8623 8624 ins_pipe(pipe_slow); 8625 %} 8626 8627 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8628 8629 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8630 ins_cost(2 * VOLATILE_REF_COST); 8631 8632 effect(KILL cr); 8633 8634 format %{ 8635 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8636 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8637 %} 8638 8639 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8640 aarch64_enc_cset_eq(res)); 8641 8642 ins_pipe(pipe_slow); 8643 %} 8644 8645 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8646 8647 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8648 ins_cost(2 * VOLATILE_REF_COST); 8649 8650 effect(KILL cr); 8651 8652 format %{ 8653 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8654 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8655 %} 8656 8657 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8658 aarch64_enc_cset_eq(res)); 8659 8660 ins_pipe(pipe_slow); 8661 %} 8662 8663 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8664 8665 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8666 predicate(n->as_LoadStore()->barrier_data() == 0); 8667 ins_cost(2 * VOLATILE_REF_COST); 8668 8669 effect(KILL cr); 8670 8671 format %{ 8672 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8673 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8674 %} 8675 8676 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8677 aarch64_enc_cset_eq(res)); 8678 8679 ins_pipe(pipe_slow); 8680 %} 8681 8682 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8683 8684 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8685 ins_cost(2 * VOLATILE_REF_COST); 8686 8687 effect(KILL cr); 8688 8689 format %{ 8690 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8691 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8692 %} 8693 8694 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8695 aarch64_enc_cset_eq(res)); 8696 8697 ins_pipe(pipe_slow); 8698 %} 8699 8700 // alternative CompareAndSwapX when we are eliding barriers 8701 8702 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8703 8704 predicate(needs_acquiring_load_exclusive(n)); 8705 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8706 ins_cost(VOLATILE_REF_COST); 8707 8708 effect(KILL cr); 8709 8710 format %{ 8711 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8712 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8713 %} 8714 8715 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8716 aarch64_enc_cset_eq(res)); 8717 8718 ins_pipe(pipe_slow); 8719 %} 8720 8721 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8722 8723 predicate(needs_acquiring_load_exclusive(n)); 8724 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8725 ins_cost(VOLATILE_REF_COST); 8726 8727 effect(KILL cr); 8728 8729 format %{ 8730 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8731 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8732 %} 8733 8734 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8735 aarch64_enc_cset_eq(res)); 8736 8737 ins_pipe(pipe_slow); 8738 %} 8739 8740 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8741 8742 predicate(needs_acquiring_load_exclusive(n)); 8743 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8744 ins_cost(VOLATILE_REF_COST); 8745 8746 effect(KILL cr); 8747 8748 format %{ 8749 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8750 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8751 %} 8752 8753 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8754 aarch64_enc_cset_eq(res)); 8755 8756 ins_pipe(pipe_slow); 8757 %} 8758 8759 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8760 8761 predicate(needs_acquiring_load_exclusive(n)); 8762 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8763 ins_cost(VOLATILE_REF_COST); 8764 8765 effect(KILL cr); 8766 8767 format %{ 8768 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8769 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8770 %} 8771 8772 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8773 aarch64_enc_cset_eq(res)); 8774 8775 ins_pipe(pipe_slow); 8776 %} 8777 8778 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8779 8780 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8781 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8782 ins_cost(VOLATILE_REF_COST); 8783 8784 effect(KILL cr); 8785 8786 format %{ 8787 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8788 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8789 %} 8790 8791 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8792 aarch64_enc_cset_eq(res)); 8793 8794 ins_pipe(pipe_slow); 8795 %} 8796 8797 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8798 8799 predicate(needs_acquiring_load_exclusive(n)); 8800 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8801 ins_cost(VOLATILE_REF_COST); 8802 8803 effect(KILL cr); 8804 8805 format %{ 8806 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8807 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8808 %} 8809 8810 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8811 aarch64_enc_cset_eq(res)); 8812 8813 ins_pipe(pipe_slow); 8814 %} 8815 8816 8817 // --------------------------------------------------------------------- 8818 8819 8820 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8821 8822 // Sundry CAS operations. Note that release is always true, 8823 // regardless of the memory ordering of the CAS. This is because we 8824 // need the volatile case to be sequentially consistent but there is 8825 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8826 // can't check the type of memory ordering here, so we always emit a 8827 // STLXR. 8828 8829 // This section is generated from aarch64_ad_cas.m4 8830 8831 8832 8833 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8834 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8835 ins_cost(2 * VOLATILE_REF_COST); 8836 effect(TEMP_DEF res, KILL cr); 8837 format %{ 8838 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8839 %} 8840 ins_encode %{ 8841 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8842 Assembler::byte, /*acquire*/ false, /*release*/ true, 8843 /*weak*/ false, $res$$Register); 8844 __ sxtbw($res$$Register, $res$$Register); 8845 %} 8846 ins_pipe(pipe_slow); 8847 %} 8848 8849 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8850 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8851 ins_cost(2 * VOLATILE_REF_COST); 8852 effect(TEMP_DEF res, KILL cr); 8853 format %{ 8854 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8855 %} 8856 ins_encode %{ 8857 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8858 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8859 /*weak*/ false, $res$$Register); 8860 __ sxthw($res$$Register, $res$$Register); 8861 %} 8862 ins_pipe(pipe_slow); 8863 %} 8864 8865 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8866 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8867 ins_cost(2 * VOLATILE_REF_COST); 8868 effect(TEMP_DEF res, KILL cr); 8869 format %{ 8870 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8871 %} 8872 ins_encode %{ 8873 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8874 Assembler::word, /*acquire*/ false, /*release*/ true, 8875 /*weak*/ false, $res$$Register); 8876 %} 8877 ins_pipe(pipe_slow); 8878 %} 8879 8880 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8881 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8882 ins_cost(2 * VOLATILE_REF_COST); 8883 effect(TEMP_DEF res, KILL cr); 8884 format %{ 8885 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8886 %} 8887 ins_encode %{ 8888 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8889 Assembler::xword, /*acquire*/ false, /*release*/ true, 8890 /*weak*/ false, $res$$Register); 8891 %} 8892 ins_pipe(pipe_slow); 8893 %} 8894 8895 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8896 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8897 ins_cost(2 * VOLATILE_REF_COST); 8898 effect(TEMP_DEF res, KILL cr); 8899 format %{ 8900 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8901 %} 8902 ins_encode %{ 8903 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8904 Assembler::word, /*acquire*/ false, /*release*/ true, 8905 /*weak*/ false, $res$$Register); 8906 %} 8907 ins_pipe(pipe_slow); 8908 %} 8909 8910 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8911 predicate(n->as_LoadStore()->barrier_data() == 0); 8912 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8913 ins_cost(2 * VOLATILE_REF_COST); 8914 effect(TEMP_DEF res, KILL cr); 8915 format %{ 8916 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8917 %} 8918 ins_encode %{ 8919 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8920 Assembler::xword, /*acquire*/ false, /*release*/ true, 8921 /*weak*/ false, $res$$Register); 8922 %} 8923 ins_pipe(pipe_slow); 8924 %} 8925 8926 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8927 predicate(needs_acquiring_load_exclusive(n)); 8928 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8929 ins_cost(VOLATILE_REF_COST); 8930 effect(TEMP_DEF res, KILL cr); 8931 format %{ 8932 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8933 %} 8934 ins_encode %{ 8935 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8936 Assembler::byte, /*acquire*/ true, /*release*/ true, 8937 /*weak*/ false, $res$$Register); 8938 __ sxtbw($res$$Register, $res$$Register); 8939 %} 8940 ins_pipe(pipe_slow); 8941 %} 8942 8943 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8944 predicate(needs_acquiring_load_exclusive(n)); 8945 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8946 ins_cost(VOLATILE_REF_COST); 8947 effect(TEMP_DEF res, KILL cr); 8948 format %{ 8949 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8950 %} 8951 ins_encode %{ 8952 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8953 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8954 /*weak*/ false, $res$$Register); 8955 __ sxthw($res$$Register, $res$$Register); 8956 %} 8957 ins_pipe(pipe_slow); 8958 %} 8959 8960 8961 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8962 predicate(needs_acquiring_load_exclusive(n)); 8963 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8964 ins_cost(VOLATILE_REF_COST); 8965 effect(TEMP_DEF res, KILL cr); 8966 format %{ 8967 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8968 %} 8969 ins_encode %{ 8970 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8971 Assembler::word, /*acquire*/ true, /*release*/ true, 8972 /*weak*/ false, $res$$Register); 8973 %} 8974 ins_pipe(pipe_slow); 8975 %} 8976 8977 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8978 predicate(needs_acquiring_load_exclusive(n)); 8979 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8980 ins_cost(VOLATILE_REF_COST); 8981 effect(TEMP_DEF res, KILL cr); 8982 format %{ 8983 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8984 %} 8985 ins_encode %{ 8986 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8987 Assembler::xword, /*acquire*/ true, /*release*/ true, 8988 /*weak*/ false, $res$$Register); 8989 %} 8990 ins_pipe(pipe_slow); 8991 %} 8992 8993 8994 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8995 predicate(needs_acquiring_load_exclusive(n)); 8996 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8997 ins_cost(VOLATILE_REF_COST); 8998 effect(TEMP_DEF res, KILL cr); 8999 format %{ 9000 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9001 %} 9002 ins_encode %{ 9003 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9004 Assembler::word, /*acquire*/ true, /*release*/ true, 9005 /*weak*/ false, $res$$Register); 9006 %} 9007 ins_pipe(pipe_slow); 9008 %} 9009 9010 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9011 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9012 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9013 ins_cost(VOLATILE_REF_COST); 9014 effect(TEMP_DEF res, KILL cr); 9015 format %{ 9016 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9017 %} 9018 ins_encode %{ 9019 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9020 Assembler::xword, /*acquire*/ true, /*release*/ true, 9021 /*weak*/ false, $res$$Register); 9022 %} 9023 ins_pipe(pipe_slow); 9024 %} 9025 9026 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9027 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9028 ins_cost(2 * VOLATILE_REF_COST); 9029 effect(KILL cr); 9030 format %{ 9031 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9032 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9033 %} 9034 ins_encode %{ 9035 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9036 Assembler::byte, /*acquire*/ false, /*release*/ true, 9037 /*weak*/ true, noreg); 9038 __ csetw($res$$Register, Assembler::EQ); 9039 %} 9040 ins_pipe(pipe_slow); 9041 %} 9042 9043 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9044 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9045 ins_cost(2 * VOLATILE_REF_COST); 9046 effect(KILL cr); 9047 format %{ 9048 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9049 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9050 %} 9051 ins_encode %{ 9052 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9053 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9054 /*weak*/ true, noreg); 9055 __ csetw($res$$Register, Assembler::EQ); 9056 %} 9057 ins_pipe(pipe_slow); 9058 %} 9059 9060 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9061 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9062 ins_cost(2 * VOLATILE_REF_COST); 9063 effect(KILL cr); 9064 format %{ 9065 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9066 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9067 %} 9068 ins_encode %{ 9069 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9070 Assembler::word, /*acquire*/ false, /*release*/ true, 9071 /*weak*/ true, noreg); 9072 __ csetw($res$$Register, Assembler::EQ); 9073 %} 9074 ins_pipe(pipe_slow); 9075 %} 9076 9077 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9078 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9079 ins_cost(2 * VOLATILE_REF_COST); 9080 effect(KILL cr); 9081 format %{ 9082 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9083 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9084 %} 9085 ins_encode %{ 9086 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9087 Assembler::xword, /*acquire*/ false, /*release*/ true, 9088 /*weak*/ true, noreg); 9089 __ csetw($res$$Register, Assembler::EQ); 9090 %} 9091 ins_pipe(pipe_slow); 9092 %} 9093 9094 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9095 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9096 ins_cost(2 * VOLATILE_REF_COST); 9097 effect(KILL cr); 9098 format %{ 9099 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9100 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9101 %} 9102 ins_encode %{ 9103 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9104 Assembler::word, /*acquire*/ false, /*release*/ true, 9105 /*weak*/ true, noreg); 9106 __ csetw($res$$Register, Assembler::EQ); 9107 %} 9108 ins_pipe(pipe_slow); 9109 %} 9110 9111 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9112 predicate(n->as_LoadStore()->barrier_data() == 0); 9113 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9114 ins_cost(2 * VOLATILE_REF_COST); 9115 effect(KILL cr); 9116 format %{ 9117 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9118 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9119 %} 9120 ins_encode %{ 9121 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9122 Assembler::xword, /*acquire*/ false, /*release*/ true, 9123 /*weak*/ true, noreg); 9124 __ csetw($res$$Register, Assembler::EQ); 9125 %} 9126 ins_pipe(pipe_slow); 9127 %} 9128 9129 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9130 predicate(needs_acquiring_load_exclusive(n)); 9131 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9132 ins_cost(VOLATILE_REF_COST); 9133 effect(KILL cr); 9134 format %{ 9135 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9136 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9137 %} 9138 ins_encode %{ 9139 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9140 Assembler::byte, /*acquire*/ true, /*release*/ true, 9141 /*weak*/ true, noreg); 9142 __ csetw($res$$Register, Assembler::EQ); 9143 %} 9144 ins_pipe(pipe_slow); 9145 %} 9146 9147 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9148 predicate(needs_acquiring_load_exclusive(n)); 9149 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9150 ins_cost(VOLATILE_REF_COST); 9151 effect(KILL cr); 9152 format %{ 9153 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9154 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9155 %} 9156 ins_encode %{ 9157 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9158 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9159 /*weak*/ true, noreg); 9160 __ csetw($res$$Register, Assembler::EQ); 9161 %} 9162 ins_pipe(pipe_slow); 9163 %} 9164 9165 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9166 predicate(needs_acquiring_load_exclusive(n)); 9167 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9168 ins_cost(VOLATILE_REF_COST); 9169 effect(KILL cr); 9170 format %{ 9171 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9172 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9173 %} 9174 ins_encode %{ 9175 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9176 Assembler::word, /*acquire*/ true, /*release*/ true, 9177 /*weak*/ true, noreg); 9178 __ csetw($res$$Register, Assembler::EQ); 9179 %} 9180 ins_pipe(pipe_slow); 9181 %} 9182 9183 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9184 predicate(needs_acquiring_load_exclusive(n)); 9185 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9186 ins_cost(VOLATILE_REF_COST); 9187 effect(KILL cr); 9188 format %{ 9189 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9190 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9191 %} 9192 ins_encode %{ 9193 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9194 Assembler::xword, /*acquire*/ true, /*release*/ true, 9195 /*weak*/ true, noreg); 9196 __ csetw($res$$Register, Assembler::EQ); 9197 %} 9198 ins_pipe(pipe_slow); 9199 %} 9200 9201 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9202 predicate(needs_acquiring_load_exclusive(n)); 9203 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9204 ins_cost(VOLATILE_REF_COST); 9205 effect(KILL cr); 9206 format %{ 9207 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9208 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9209 %} 9210 ins_encode %{ 9211 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9212 Assembler::word, /*acquire*/ true, /*release*/ true, 9213 /*weak*/ true, noreg); 9214 __ csetw($res$$Register, Assembler::EQ); 9215 %} 9216 ins_pipe(pipe_slow); 9217 %} 9218 9219 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9220 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9221 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9222 ins_cost(VOLATILE_REF_COST); 9223 effect(KILL cr); 9224 format %{ 9225 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9226 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9227 %} 9228 ins_encode %{ 9229 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9230 Assembler::xword, /*acquire*/ true, /*release*/ true, 9231 /*weak*/ true, noreg); 9232 __ csetw($res$$Register, Assembler::EQ); 9233 %} 9234 ins_pipe(pipe_slow); 9235 %} 9236 9237 // END This section of the file is automatically generated. Do not edit -------------- 9238 // --------------------------------------------------------------------- 9239 9240 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9241 match(Set prev (GetAndSetI mem newv)); 9242 ins_cost(2 * VOLATILE_REF_COST); 9243 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9244 ins_encode %{ 9245 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9246 %} 9247 ins_pipe(pipe_serial); 9248 %} 9249 9250 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9251 match(Set prev (GetAndSetL mem newv)); 9252 ins_cost(2 * VOLATILE_REF_COST); 9253 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9254 ins_encode %{ 9255 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9256 %} 9257 ins_pipe(pipe_serial); 9258 %} 9259 9260 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9261 match(Set prev (GetAndSetN mem newv)); 9262 ins_cost(2 * VOLATILE_REF_COST); 9263 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9264 ins_encode %{ 9265 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9266 %} 9267 ins_pipe(pipe_serial); 9268 %} 9269 9270 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9271 predicate(n->as_LoadStore()->barrier_data() == 0); 9272 match(Set prev (GetAndSetP mem newv)); 9273 ins_cost(2 * VOLATILE_REF_COST); 9274 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9275 ins_encode %{ 9276 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9277 %} 9278 ins_pipe(pipe_serial); 9279 %} 9280 9281 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9282 predicate(needs_acquiring_load_exclusive(n)); 9283 match(Set prev (GetAndSetI mem newv)); 9284 ins_cost(VOLATILE_REF_COST); 9285 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9286 ins_encode %{ 9287 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9288 %} 9289 ins_pipe(pipe_serial); 9290 %} 9291 9292 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9293 predicate(needs_acquiring_load_exclusive(n)); 9294 match(Set prev (GetAndSetL mem newv)); 9295 ins_cost(VOLATILE_REF_COST); 9296 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9297 ins_encode %{ 9298 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9299 %} 9300 ins_pipe(pipe_serial); 9301 %} 9302 9303 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9304 predicate(needs_acquiring_load_exclusive(n)); 9305 match(Set prev (GetAndSetN mem newv)); 9306 ins_cost(VOLATILE_REF_COST); 9307 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9308 ins_encode %{ 9309 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9310 %} 9311 ins_pipe(pipe_serial); 9312 %} 9313 9314 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9315 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9316 match(Set prev (GetAndSetP mem newv)); 9317 ins_cost(VOLATILE_REF_COST); 9318 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9319 ins_encode %{ 9320 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9321 %} 9322 ins_pipe(pipe_serial); 9323 %} 9324 9325 9326 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9327 match(Set newval (GetAndAddL mem incr)); 9328 ins_cost(2 * VOLATILE_REF_COST + 1); 9329 format %{ "get_and_addL $newval, [$mem], $incr" %} 9330 ins_encode %{ 9331 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9332 %} 9333 ins_pipe(pipe_serial); 9334 %} 9335 9336 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9337 predicate(n->as_LoadStore()->result_not_used()); 9338 match(Set dummy (GetAndAddL mem incr)); 9339 ins_cost(2 * VOLATILE_REF_COST); 9340 format %{ "get_and_addL [$mem], $incr" %} 9341 ins_encode %{ 9342 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9343 %} 9344 ins_pipe(pipe_serial); 9345 %} 9346 9347 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9348 match(Set newval (GetAndAddL mem incr)); 9349 ins_cost(2 * VOLATILE_REF_COST + 1); 9350 format %{ "get_and_addL $newval, [$mem], $incr" %} 9351 ins_encode %{ 9352 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9353 %} 9354 ins_pipe(pipe_serial); 9355 %} 9356 9357 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9358 predicate(n->as_LoadStore()->result_not_used()); 9359 match(Set dummy (GetAndAddL mem incr)); 9360 ins_cost(2 * VOLATILE_REF_COST); 9361 format %{ "get_and_addL [$mem], $incr" %} 9362 ins_encode %{ 9363 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9364 %} 9365 ins_pipe(pipe_serial); 9366 %} 9367 9368 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9369 match(Set newval (GetAndAddI mem incr)); 9370 ins_cost(2 * VOLATILE_REF_COST + 1); 9371 format %{ "get_and_addI $newval, [$mem], $incr" %} 9372 ins_encode %{ 9373 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9374 %} 9375 ins_pipe(pipe_serial); 9376 %} 9377 9378 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9379 predicate(n->as_LoadStore()->result_not_used()); 9380 match(Set dummy (GetAndAddI mem incr)); 9381 ins_cost(2 * VOLATILE_REF_COST); 9382 format %{ "get_and_addI [$mem], $incr" %} 9383 ins_encode %{ 9384 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9385 %} 9386 ins_pipe(pipe_serial); 9387 %} 9388 9389 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9390 match(Set newval (GetAndAddI mem incr)); 9391 ins_cost(2 * VOLATILE_REF_COST + 1); 9392 format %{ "get_and_addI $newval, [$mem], $incr" %} 9393 ins_encode %{ 9394 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9395 %} 9396 ins_pipe(pipe_serial); 9397 %} 9398 9399 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9400 predicate(n->as_LoadStore()->result_not_used()); 9401 match(Set dummy (GetAndAddI mem incr)); 9402 ins_cost(2 * VOLATILE_REF_COST); 9403 format %{ "get_and_addI [$mem], $incr" %} 9404 ins_encode %{ 9405 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9406 %} 9407 ins_pipe(pipe_serial); 9408 %} 9409 9410 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9411 predicate(needs_acquiring_load_exclusive(n)); 9412 match(Set newval (GetAndAddL mem incr)); 9413 ins_cost(VOLATILE_REF_COST + 1); 9414 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9415 ins_encode %{ 9416 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9417 %} 9418 ins_pipe(pipe_serial); 9419 %} 9420 9421 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9422 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9423 match(Set dummy (GetAndAddL mem incr)); 9424 ins_cost(VOLATILE_REF_COST); 9425 format %{ "get_and_addL_acq [$mem], $incr" %} 9426 ins_encode %{ 9427 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9428 %} 9429 ins_pipe(pipe_serial); 9430 %} 9431 9432 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9433 predicate(needs_acquiring_load_exclusive(n)); 9434 match(Set newval (GetAndAddL mem incr)); 9435 ins_cost(VOLATILE_REF_COST + 1); 9436 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9437 ins_encode %{ 9438 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9439 %} 9440 ins_pipe(pipe_serial); 9441 %} 9442 9443 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9444 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9445 match(Set dummy (GetAndAddL mem incr)); 9446 ins_cost(VOLATILE_REF_COST); 9447 format %{ "get_and_addL_acq [$mem], $incr" %} 9448 ins_encode %{ 9449 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9450 %} 9451 ins_pipe(pipe_serial); 9452 %} 9453 9454 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9455 predicate(needs_acquiring_load_exclusive(n)); 9456 match(Set newval (GetAndAddI mem incr)); 9457 ins_cost(VOLATILE_REF_COST + 1); 9458 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9459 ins_encode %{ 9460 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9461 %} 9462 ins_pipe(pipe_serial); 9463 %} 9464 9465 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9466 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9467 match(Set dummy (GetAndAddI mem incr)); 9468 ins_cost(VOLATILE_REF_COST); 9469 format %{ "get_and_addI_acq [$mem], $incr" %} 9470 ins_encode %{ 9471 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9472 %} 9473 ins_pipe(pipe_serial); 9474 %} 9475 9476 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9477 predicate(needs_acquiring_load_exclusive(n)); 9478 match(Set newval (GetAndAddI mem incr)); 9479 ins_cost(VOLATILE_REF_COST + 1); 9480 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9481 ins_encode %{ 9482 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9483 %} 9484 ins_pipe(pipe_serial); 9485 %} 9486 9487 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9488 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9489 match(Set dummy (GetAndAddI mem incr)); 9490 ins_cost(VOLATILE_REF_COST); 9491 format %{ "get_and_addI_acq [$mem], $incr" %} 9492 ins_encode %{ 9493 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9494 %} 9495 ins_pipe(pipe_serial); 9496 %} 9497 9498 // Manifest a CmpL result in an integer register. 9499 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9500 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9501 %{ 9502 match(Set dst (CmpL3 src1 src2)); 9503 effect(KILL flags); 9504 9505 ins_cost(INSN_COST * 6); 9506 format %{ 9507 "cmp $src1, $src2" 9508 "csetw $dst, ne" 9509 "cnegw $dst, lt" 9510 %} 9511 // format %{ "CmpL3 $dst, $src1, $src2" %} 9512 ins_encode %{ 9513 __ cmp($src1$$Register, $src2$$Register); 9514 __ csetw($dst$$Register, Assembler::NE); 9515 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9516 %} 9517 9518 ins_pipe(pipe_class_default); 9519 %} 9520 9521 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9522 %{ 9523 match(Set dst (CmpL3 src1 src2)); 9524 effect(KILL flags); 9525 9526 ins_cost(INSN_COST * 6); 9527 format %{ 9528 "cmp $src1, $src2" 9529 "csetw $dst, ne" 9530 "cnegw $dst, lt" 9531 %} 9532 ins_encode %{ 9533 int32_t con = (int32_t)$src2$$constant; 9534 if (con < 0) { 9535 __ adds(zr, $src1$$Register, -con); 9536 } else { 9537 __ subs(zr, $src1$$Register, con); 9538 } 9539 __ csetw($dst$$Register, Assembler::NE); 9540 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9541 %} 9542 9543 ins_pipe(pipe_class_default); 9544 %} 9545 9546 // ============================================================================ 9547 // Conditional Move Instructions 9548 9549 // n.b. we have identical rules for both a signed compare op (cmpOp) 9550 // and an unsigned compare op (cmpOpU). it would be nice if we could 9551 // define an op class which merged both inputs and use it to type the 9552 // argument to a single rule. unfortunatelyt his fails because the 9553 // opclass does not live up to the COND_INTER interface of its 9554 // component operands. When the generic code tries to negate the 9555 // operand it ends up running the generci Machoper::negate method 9556 // which throws a ShouldNotHappen. So, we have to provide two flavours 9557 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9558 9559 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9560 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9561 9562 ins_cost(INSN_COST * 2); 9563 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9564 9565 ins_encode %{ 9566 __ cselw(as_Register($dst$$reg), 9567 as_Register($src2$$reg), 9568 as_Register($src1$$reg), 9569 (Assembler::Condition)$cmp$$cmpcode); 9570 %} 9571 9572 ins_pipe(icond_reg_reg); 9573 %} 9574 9575 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9576 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9577 9578 ins_cost(INSN_COST * 2); 9579 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9580 9581 ins_encode %{ 9582 __ cselw(as_Register($dst$$reg), 9583 as_Register($src2$$reg), 9584 as_Register($src1$$reg), 9585 (Assembler::Condition)$cmp$$cmpcode); 9586 %} 9587 9588 ins_pipe(icond_reg_reg); 9589 %} 9590 9591 // special cases where one arg is zero 9592 9593 // n.b. this is selected in preference to the rule above because it 9594 // avoids loading constant 0 into a source register 9595 9596 // TODO 9597 // we ought only to be able to cull one of these variants as the ideal 9598 // transforms ought always to order the zero consistently (to left/right?) 9599 9600 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9601 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9602 9603 ins_cost(INSN_COST * 2); 9604 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9605 9606 ins_encode %{ 9607 __ cselw(as_Register($dst$$reg), 9608 as_Register($src$$reg), 9609 zr, 9610 (Assembler::Condition)$cmp$$cmpcode); 9611 %} 9612 9613 ins_pipe(icond_reg); 9614 %} 9615 9616 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9617 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9618 9619 ins_cost(INSN_COST * 2); 9620 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9621 9622 ins_encode %{ 9623 __ cselw(as_Register($dst$$reg), 9624 as_Register($src$$reg), 9625 zr, 9626 (Assembler::Condition)$cmp$$cmpcode); 9627 %} 9628 9629 ins_pipe(icond_reg); 9630 %} 9631 9632 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9633 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9634 9635 ins_cost(INSN_COST * 2); 9636 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9637 9638 ins_encode %{ 9639 __ cselw(as_Register($dst$$reg), 9640 zr, 9641 as_Register($src$$reg), 9642 (Assembler::Condition)$cmp$$cmpcode); 9643 %} 9644 9645 ins_pipe(icond_reg); 9646 %} 9647 9648 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9649 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9650 9651 ins_cost(INSN_COST * 2); 9652 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9653 9654 ins_encode %{ 9655 __ cselw(as_Register($dst$$reg), 9656 zr, 9657 as_Register($src$$reg), 9658 (Assembler::Condition)$cmp$$cmpcode); 9659 %} 9660 9661 ins_pipe(icond_reg); 9662 %} 9663 9664 // special case for creating a boolean 0 or 1 9665 9666 // n.b. this is selected in preference to the rule above because it 9667 // avoids loading constants 0 and 1 into a source register 9668 9669 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9670 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9671 9672 ins_cost(INSN_COST * 2); 9673 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9674 9675 ins_encode %{ 9676 // equivalently 9677 // cset(as_Register($dst$$reg), 9678 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9679 __ csincw(as_Register($dst$$reg), 9680 zr, 9681 zr, 9682 (Assembler::Condition)$cmp$$cmpcode); 9683 %} 9684 9685 ins_pipe(icond_none); 9686 %} 9687 9688 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9689 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9690 9691 ins_cost(INSN_COST * 2); 9692 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9693 9694 ins_encode %{ 9695 // equivalently 9696 // cset(as_Register($dst$$reg), 9697 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9698 __ csincw(as_Register($dst$$reg), 9699 zr, 9700 zr, 9701 (Assembler::Condition)$cmp$$cmpcode); 9702 %} 9703 9704 ins_pipe(icond_none); 9705 %} 9706 9707 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9708 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9709 9710 ins_cost(INSN_COST * 2); 9711 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9712 9713 ins_encode %{ 9714 __ csel(as_Register($dst$$reg), 9715 as_Register($src2$$reg), 9716 as_Register($src1$$reg), 9717 (Assembler::Condition)$cmp$$cmpcode); 9718 %} 9719 9720 ins_pipe(icond_reg_reg); 9721 %} 9722 9723 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9724 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9725 9726 ins_cost(INSN_COST * 2); 9727 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9728 9729 ins_encode %{ 9730 __ csel(as_Register($dst$$reg), 9731 as_Register($src2$$reg), 9732 as_Register($src1$$reg), 9733 (Assembler::Condition)$cmp$$cmpcode); 9734 %} 9735 9736 ins_pipe(icond_reg_reg); 9737 %} 9738 9739 // special cases where one arg is zero 9740 9741 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9742 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9743 9744 ins_cost(INSN_COST * 2); 9745 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9746 9747 ins_encode %{ 9748 __ csel(as_Register($dst$$reg), 9749 zr, 9750 as_Register($src$$reg), 9751 (Assembler::Condition)$cmp$$cmpcode); 9752 %} 9753 9754 ins_pipe(icond_reg); 9755 %} 9756 9757 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9758 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9759 9760 ins_cost(INSN_COST * 2); 9761 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9762 9763 ins_encode %{ 9764 __ csel(as_Register($dst$$reg), 9765 zr, 9766 as_Register($src$$reg), 9767 (Assembler::Condition)$cmp$$cmpcode); 9768 %} 9769 9770 ins_pipe(icond_reg); 9771 %} 9772 9773 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9774 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9775 9776 ins_cost(INSN_COST * 2); 9777 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9778 9779 ins_encode %{ 9780 __ csel(as_Register($dst$$reg), 9781 as_Register($src$$reg), 9782 zr, 9783 (Assembler::Condition)$cmp$$cmpcode); 9784 %} 9785 9786 ins_pipe(icond_reg); 9787 %} 9788 9789 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9790 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9791 9792 ins_cost(INSN_COST * 2); 9793 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9794 9795 ins_encode %{ 9796 __ csel(as_Register($dst$$reg), 9797 as_Register($src$$reg), 9798 zr, 9799 (Assembler::Condition)$cmp$$cmpcode); 9800 %} 9801 9802 ins_pipe(icond_reg); 9803 %} 9804 9805 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9806 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9807 9808 ins_cost(INSN_COST * 2); 9809 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9810 9811 ins_encode %{ 9812 __ csel(as_Register($dst$$reg), 9813 as_Register($src2$$reg), 9814 as_Register($src1$$reg), 9815 (Assembler::Condition)$cmp$$cmpcode); 9816 %} 9817 9818 ins_pipe(icond_reg_reg); 9819 %} 9820 9821 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9822 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9823 9824 ins_cost(INSN_COST * 2); 9825 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9826 9827 ins_encode %{ 9828 __ csel(as_Register($dst$$reg), 9829 as_Register($src2$$reg), 9830 as_Register($src1$$reg), 9831 (Assembler::Condition)$cmp$$cmpcode); 9832 %} 9833 9834 ins_pipe(icond_reg_reg); 9835 %} 9836 9837 // special cases where one arg is zero 9838 9839 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9840 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9841 9842 ins_cost(INSN_COST * 2); 9843 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9844 9845 ins_encode %{ 9846 __ csel(as_Register($dst$$reg), 9847 zr, 9848 as_Register($src$$reg), 9849 (Assembler::Condition)$cmp$$cmpcode); 9850 %} 9851 9852 ins_pipe(icond_reg); 9853 %} 9854 9855 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9856 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9857 9858 ins_cost(INSN_COST * 2); 9859 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9860 9861 ins_encode %{ 9862 __ csel(as_Register($dst$$reg), 9863 zr, 9864 as_Register($src$$reg), 9865 (Assembler::Condition)$cmp$$cmpcode); 9866 %} 9867 9868 ins_pipe(icond_reg); 9869 %} 9870 9871 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9872 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9873 9874 ins_cost(INSN_COST * 2); 9875 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9876 9877 ins_encode %{ 9878 __ csel(as_Register($dst$$reg), 9879 as_Register($src$$reg), 9880 zr, 9881 (Assembler::Condition)$cmp$$cmpcode); 9882 %} 9883 9884 ins_pipe(icond_reg); 9885 %} 9886 9887 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9888 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9889 9890 ins_cost(INSN_COST * 2); 9891 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9892 9893 ins_encode %{ 9894 __ csel(as_Register($dst$$reg), 9895 as_Register($src$$reg), 9896 zr, 9897 (Assembler::Condition)$cmp$$cmpcode); 9898 %} 9899 9900 ins_pipe(icond_reg); 9901 %} 9902 9903 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9904 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9905 9906 ins_cost(INSN_COST * 2); 9907 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9908 9909 ins_encode %{ 9910 __ cselw(as_Register($dst$$reg), 9911 as_Register($src2$$reg), 9912 as_Register($src1$$reg), 9913 (Assembler::Condition)$cmp$$cmpcode); 9914 %} 9915 9916 ins_pipe(icond_reg_reg); 9917 %} 9918 9919 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9920 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9921 9922 ins_cost(INSN_COST * 2); 9923 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9924 9925 ins_encode %{ 9926 __ cselw(as_Register($dst$$reg), 9927 as_Register($src2$$reg), 9928 as_Register($src1$$reg), 9929 (Assembler::Condition)$cmp$$cmpcode); 9930 %} 9931 9932 ins_pipe(icond_reg_reg); 9933 %} 9934 9935 // special cases where one arg is zero 9936 9937 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9938 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9939 9940 ins_cost(INSN_COST * 2); 9941 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9942 9943 ins_encode %{ 9944 __ cselw(as_Register($dst$$reg), 9945 zr, 9946 as_Register($src$$reg), 9947 (Assembler::Condition)$cmp$$cmpcode); 9948 %} 9949 9950 ins_pipe(icond_reg); 9951 %} 9952 9953 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9954 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9955 9956 ins_cost(INSN_COST * 2); 9957 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9958 9959 ins_encode %{ 9960 __ cselw(as_Register($dst$$reg), 9961 zr, 9962 as_Register($src$$reg), 9963 (Assembler::Condition)$cmp$$cmpcode); 9964 %} 9965 9966 ins_pipe(icond_reg); 9967 %} 9968 9969 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9970 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9971 9972 ins_cost(INSN_COST * 2); 9973 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9974 9975 ins_encode %{ 9976 __ cselw(as_Register($dst$$reg), 9977 as_Register($src$$reg), 9978 zr, 9979 (Assembler::Condition)$cmp$$cmpcode); 9980 %} 9981 9982 ins_pipe(icond_reg); 9983 %} 9984 9985 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9986 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9987 9988 ins_cost(INSN_COST * 2); 9989 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9990 9991 ins_encode %{ 9992 __ cselw(as_Register($dst$$reg), 9993 as_Register($src$$reg), 9994 zr, 9995 (Assembler::Condition)$cmp$$cmpcode); 9996 %} 9997 9998 ins_pipe(icond_reg); 9999 %} 10000 10001 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10002 %{ 10003 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10004 10005 ins_cost(INSN_COST * 3); 10006 10007 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10008 ins_encode %{ 10009 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10010 __ fcsels(as_FloatRegister($dst$$reg), 10011 as_FloatRegister($src2$$reg), 10012 as_FloatRegister($src1$$reg), 10013 cond); 10014 %} 10015 10016 ins_pipe(fp_cond_reg_reg_s); 10017 %} 10018 10019 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10020 %{ 10021 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10022 10023 ins_cost(INSN_COST * 3); 10024 10025 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10026 ins_encode %{ 10027 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10028 __ fcsels(as_FloatRegister($dst$$reg), 10029 as_FloatRegister($src2$$reg), 10030 as_FloatRegister($src1$$reg), 10031 cond); 10032 %} 10033 10034 ins_pipe(fp_cond_reg_reg_s); 10035 %} 10036 10037 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10038 %{ 10039 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10040 10041 ins_cost(INSN_COST * 3); 10042 10043 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10044 ins_encode %{ 10045 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10046 __ fcseld(as_FloatRegister($dst$$reg), 10047 as_FloatRegister($src2$$reg), 10048 as_FloatRegister($src1$$reg), 10049 cond); 10050 %} 10051 10052 ins_pipe(fp_cond_reg_reg_d); 10053 %} 10054 10055 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10056 %{ 10057 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10058 10059 ins_cost(INSN_COST * 3); 10060 10061 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10062 ins_encode %{ 10063 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10064 __ fcseld(as_FloatRegister($dst$$reg), 10065 as_FloatRegister($src2$$reg), 10066 as_FloatRegister($src1$$reg), 10067 cond); 10068 %} 10069 10070 ins_pipe(fp_cond_reg_reg_d); 10071 %} 10072 10073 // ============================================================================ 10074 // Arithmetic Instructions 10075 // 10076 10077 // Integer Addition 10078 10079 // TODO 10080 // these currently employ operations which do not set CR and hence are 10081 // not flagged as killing CR but we would like to isolate the cases 10082 // where we want to set flags from those where we don't. need to work 10083 // out how to do that. 10084 10085 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10086 match(Set dst (AddI src1 src2)); 10087 10088 ins_cost(INSN_COST); 10089 format %{ "addw $dst, $src1, $src2" %} 10090 10091 ins_encode %{ 10092 __ addw(as_Register($dst$$reg), 10093 as_Register($src1$$reg), 10094 as_Register($src2$$reg)); 10095 %} 10096 10097 ins_pipe(ialu_reg_reg); 10098 %} 10099 10100 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10101 match(Set dst (AddI src1 src2)); 10102 10103 ins_cost(INSN_COST); 10104 format %{ "addw $dst, $src1, $src2" %} 10105 10106 // use opcode to indicate that this is an add not a sub 10107 opcode(0x0); 10108 10109 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10110 10111 ins_pipe(ialu_reg_imm); 10112 %} 10113 10114 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10115 match(Set dst (AddI (ConvL2I src1) src2)); 10116 10117 ins_cost(INSN_COST); 10118 format %{ "addw $dst, $src1, $src2" %} 10119 10120 // use opcode to indicate that this is an add not a sub 10121 opcode(0x0); 10122 10123 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10124 10125 ins_pipe(ialu_reg_imm); 10126 %} 10127 10128 // Pointer Addition 10129 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10130 match(Set dst (AddP src1 src2)); 10131 10132 ins_cost(INSN_COST); 10133 format %{ "add $dst, $src1, $src2\t# ptr" %} 10134 10135 ins_encode %{ 10136 __ add(as_Register($dst$$reg), 10137 as_Register($src1$$reg), 10138 as_Register($src2$$reg)); 10139 %} 10140 10141 ins_pipe(ialu_reg_reg); 10142 %} 10143 10144 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10145 match(Set dst (AddP src1 (ConvI2L src2))); 10146 10147 ins_cost(1.9 * INSN_COST); 10148 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10149 10150 ins_encode %{ 10151 __ add(as_Register($dst$$reg), 10152 as_Register($src1$$reg), 10153 as_Register($src2$$reg), ext::sxtw); 10154 %} 10155 10156 ins_pipe(ialu_reg_reg); 10157 %} 10158 10159 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10160 match(Set dst (AddP src1 (LShiftL src2 scale))); 10161 10162 ins_cost(1.9 * INSN_COST); 10163 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10164 10165 ins_encode %{ 10166 __ lea(as_Register($dst$$reg), 10167 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10168 Address::lsl($scale$$constant))); 10169 %} 10170 10171 ins_pipe(ialu_reg_reg_shift); 10172 %} 10173 10174 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10175 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10176 10177 ins_cost(1.9 * INSN_COST); 10178 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10179 10180 ins_encode %{ 10181 __ lea(as_Register($dst$$reg), 10182 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10183 Address::sxtw($scale$$constant))); 10184 %} 10185 10186 ins_pipe(ialu_reg_reg_shift); 10187 %} 10188 10189 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10190 match(Set dst (LShiftL (ConvI2L src) scale)); 10191 10192 ins_cost(INSN_COST); 10193 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10194 10195 ins_encode %{ 10196 __ sbfiz(as_Register($dst$$reg), 10197 as_Register($src$$reg), 10198 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 10199 %} 10200 10201 ins_pipe(ialu_reg_shift); 10202 %} 10203 10204 // Pointer Immediate Addition 10205 // n.b. this needs to be more expensive than using an indirect memory 10206 // operand 10207 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10208 match(Set dst (AddP src1 src2)); 10209 10210 ins_cost(INSN_COST); 10211 format %{ "add $dst, $src1, $src2\t# ptr" %} 10212 10213 // use opcode to indicate that this is an add not a sub 10214 opcode(0x0); 10215 10216 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10217 10218 ins_pipe(ialu_reg_imm); 10219 %} 10220 10221 // Long Addition 10222 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10223 10224 match(Set dst (AddL src1 src2)); 10225 10226 ins_cost(INSN_COST); 10227 format %{ "add $dst, $src1, $src2" %} 10228 10229 ins_encode %{ 10230 __ add(as_Register($dst$$reg), 10231 as_Register($src1$$reg), 10232 as_Register($src2$$reg)); 10233 %} 10234 10235 ins_pipe(ialu_reg_reg); 10236 %} 10237 10238 // No constant pool entries requiredLong Immediate Addition. 10239 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10240 match(Set dst (AddL src1 src2)); 10241 10242 ins_cost(INSN_COST); 10243 format %{ "add $dst, $src1, $src2" %} 10244 10245 // use opcode to indicate that this is an add not a sub 10246 opcode(0x0); 10247 10248 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10249 10250 ins_pipe(ialu_reg_imm); 10251 %} 10252 10253 // Integer Subtraction 10254 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10255 match(Set dst (SubI src1 src2)); 10256 10257 ins_cost(INSN_COST); 10258 format %{ "subw $dst, $src1, $src2" %} 10259 10260 ins_encode %{ 10261 __ subw(as_Register($dst$$reg), 10262 as_Register($src1$$reg), 10263 as_Register($src2$$reg)); 10264 %} 10265 10266 ins_pipe(ialu_reg_reg); 10267 %} 10268 10269 // Immediate Subtraction 10270 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10271 match(Set dst (SubI src1 src2)); 10272 10273 ins_cost(INSN_COST); 10274 format %{ "subw $dst, $src1, $src2" %} 10275 10276 // use opcode to indicate that this is a sub not an add 10277 opcode(0x1); 10278 10279 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10280 10281 ins_pipe(ialu_reg_imm); 10282 %} 10283 10284 // Long Subtraction 10285 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10286 10287 match(Set dst (SubL src1 src2)); 10288 10289 ins_cost(INSN_COST); 10290 format %{ "sub $dst, $src1, $src2" %} 10291 10292 ins_encode %{ 10293 __ sub(as_Register($dst$$reg), 10294 as_Register($src1$$reg), 10295 as_Register($src2$$reg)); 10296 %} 10297 10298 ins_pipe(ialu_reg_reg); 10299 %} 10300 10301 // No constant pool entries requiredLong Immediate Subtraction. 10302 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10303 match(Set dst (SubL src1 src2)); 10304 10305 ins_cost(INSN_COST); 10306 format %{ "sub$dst, $src1, $src2" %} 10307 10308 // use opcode to indicate that this is a sub not an add 10309 opcode(0x1); 10310 10311 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10312 10313 ins_pipe(ialu_reg_imm); 10314 %} 10315 10316 // Integer Negation (special case for sub) 10317 10318 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10319 match(Set dst (SubI zero src)); 10320 10321 ins_cost(INSN_COST); 10322 format %{ "negw $dst, $src\t# int" %} 10323 10324 ins_encode %{ 10325 __ negw(as_Register($dst$$reg), 10326 as_Register($src$$reg)); 10327 %} 10328 10329 ins_pipe(ialu_reg); 10330 %} 10331 10332 // Long Negation 10333 10334 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10335 match(Set dst (SubL zero src)); 10336 10337 ins_cost(INSN_COST); 10338 format %{ "neg $dst, $src\t# long" %} 10339 10340 ins_encode %{ 10341 __ neg(as_Register($dst$$reg), 10342 as_Register($src$$reg)); 10343 %} 10344 10345 ins_pipe(ialu_reg); 10346 %} 10347 10348 // Integer Multiply 10349 10350 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10351 match(Set dst (MulI src1 src2)); 10352 10353 ins_cost(INSN_COST * 3); 10354 format %{ "mulw $dst, $src1, $src2" %} 10355 10356 ins_encode %{ 10357 __ mulw(as_Register($dst$$reg), 10358 as_Register($src1$$reg), 10359 as_Register($src2$$reg)); 10360 %} 10361 10362 ins_pipe(imul_reg_reg); 10363 %} 10364 10365 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10366 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10367 10368 ins_cost(INSN_COST * 3); 10369 format %{ "smull $dst, $src1, $src2" %} 10370 10371 ins_encode %{ 10372 __ smull(as_Register($dst$$reg), 10373 as_Register($src1$$reg), 10374 as_Register($src2$$reg)); 10375 %} 10376 10377 ins_pipe(imul_reg_reg); 10378 %} 10379 10380 // Long Multiply 10381 10382 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10383 match(Set dst (MulL src1 src2)); 10384 10385 ins_cost(INSN_COST * 5); 10386 format %{ "mul $dst, $src1, $src2" %} 10387 10388 ins_encode %{ 10389 __ mul(as_Register($dst$$reg), 10390 as_Register($src1$$reg), 10391 as_Register($src2$$reg)); 10392 %} 10393 10394 ins_pipe(lmul_reg_reg); 10395 %} 10396 10397 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10398 %{ 10399 match(Set dst (MulHiL src1 src2)); 10400 10401 ins_cost(INSN_COST * 7); 10402 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10403 10404 ins_encode %{ 10405 __ smulh(as_Register($dst$$reg), 10406 as_Register($src1$$reg), 10407 as_Register($src2$$reg)); 10408 %} 10409 10410 ins_pipe(lmul_reg_reg); 10411 %} 10412 10413 // Combined Integer Multiply & Add/Sub 10414 10415 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10416 match(Set dst (AddI src3 (MulI src1 src2))); 10417 10418 ins_cost(INSN_COST * 3); 10419 format %{ "madd $dst, $src1, $src2, $src3" %} 10420 10421 ins_encode %{ 10422 __ maddw(as_Register($dst$$reg), 10423 as_Register($src1$$reg), 10424 as_Register($src2$$reg), 10425 as_Register($src3$$reg)); 10426 %} 10427 10428 ins_pipe(imac_reg_reg); 10429 %} 10430 10431 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10432 match(Set dst (SubI src3 (MulI src1 src2))); 10433 10434 ins_cost(INSN_COST * 3); 10435 format %{ "msub $dst, $src1, $src2, $src3" %} 10436 10437 ins_encode %{ 10438 __ msubw(as_Register($dst$$reg), 10439 as_Register($src1$$reg), 10440 as_Register($src2$$reg), 10441 as_Register($src3$$reg)); 10442 %} 10443 10444 ins_pipe(imac_reg_reg); 10445 %} 10446 10447 // Combined Integer Multiply & Neg 10448 10449 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10450 match(Set dst (MulI (SubI zero src1) src2)); 10451 match(Set dst (MulI src1 (SubI zero src2))); 10452 10453 ins_cost(INSN_COST * 3); 10454 format %{ "mneg $dst, $src1, $src2" %} 10455 10456 ins_encode %{ 10457 __ mnegw(as_Register($dst$$reg), 10458 as_Register($src1$$reg), 10459 as_Register($src2$$reg)); 10460 %} 10461 10462 ins_pipe(imac_reg_reg); 10463 %} 10464 10465 // Combined Long Multiply & Add/Sub 10466 10467 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10468 match(Set dst (AddL src3 (MulL src1 src2))); 10469 10470 ins_cost(INSN_COST * 5); 10471 format %{ "madd $dst, $src1, $src2, $src3" %} 10472 10473 ins_encode %{ 10474 __ madd(as_Register($dst$$reg), 10475 as_Register($src1$$reg), 10476 as_Register($src2$$reg), 10477 as_Register($src3$$reg)); 10478 %} 10479 10480 ins_pipe(lmac_reg_reg); 10481 %} 10482 10483 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10484 match(Set dst (SubL src3 (MulL src1 src2))); 10485 10486 ins_cost(INSN_COST * 5); 10487 format %{ "msub $dst, $src1, $src2, $src3" %} 10488 10489 ins_encode %{ 10490 __ msub(as_Register($dst$$reg), 10491 as_Register($src1$$reg), 10492 as_Register($src2$$reg), 10493 as_Register($src3$$reg)); 10494 %} 10495 10496 ins_pipe(lmac_reg_reg); 10497 %} 10498 10499 // Combined Long Multiply & Neg 10500 10501 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10502 match(Set dst (MulL (SubL zero src1) src2)); 10503 match(Set dst (MulL src1 (SubL zero src2))); 10504 10505 ins_cost(INSN_COST * 5); 10506 format %{ "mneg $dst, $src1, $src2" %} 10507 10508 ins_encode %{ 10509 __ mneg(as_Register($dst$$reg), 10510 as_Register($src1$$reg), 10511 as_Register($src2$$reg)); 10512 %} 10513 10514 ins_pipe(lmac_reg_reg); 10515 %} 10516 10517 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10518 10519 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10520 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10521 10522 ins_cost(INSN_COST * 3); 10523 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10524 10525 ins_encode %{ 10526 __ smaddl(as_Register($dst$$reg), 10527 as_Register($src1$$reg), 10528 as_Register($src2$$reg), 10529 as_Register($src3$$reg)); 10530 %} 10531 10532 ins_pipe(imac_reg_reg); 10533 %} 10534 10535 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10536 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10537 10538 ins_cost(INSN_COST * 3); 10539 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10540 10541 ins_encode %{ 10542 __ smsubl(as_Register($dst$$reg), 10543 as_Register($src1$$reg), 10544 as_Register($src2$$reg), 10545 as_Register($src3$$reg)); 10546 %} 10547 10548 ins_pipe(imac_reg_reg); 10549 %} 10550 10551 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10552 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10553 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10554 10555 ins_cost(INSN_COST * 3); 10556 format %{ "smnegl $dst, $src1, $src2" %} 10557 10558 ins_encode %{ 10559 __ smnegl(as_Register($dst$$reg), 10560 as_Register($src1$$reg), 10561 as_Register($src2$$reg)); 10562 %} 10563 10564 ins_pipe(imac_reg_reg); 10565 %} 10566 10567 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10568 10569 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10570 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10571 10572 ins_cost(INSN_COST * 5); 10573 format %{ "mulw rscratch1, $src1, $src2\n\t" 10574 "maddw $dst, $src3, $src4, rscratch1" %} 10575 10576 ins_encode %{ 10577 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10578 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10579 10580 ins_pipe(imac_reg_reg); 10581 %} 10582 10583 // Integer Divide 10584 10585 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10586 match(Set dst (DivI src1 src2)); 10587 10588 ins_cost(INSN_COST * 19); 10589 format %{ "sdivw $dst, $src1, $src2" %} 10590 10591 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10592 ins_pipe(idiv_reg_reg); 10593 %} 10594 10595 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 10596 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 10597 ins_cost(INSN_COST); 10598 format %{ "lsrw $dst, $src1, $div1" %} 10599 ins_encode %{ 10600 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 10601 %} 10602 ins_pipe(ialu_reg_shift); 10603 %} 10604 10605 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 10606 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 10607 ins_cost(INSN_COST); 10608 format %{ "addw $dst, $src, LSR $div1" %} 10609 10610 ins_encode %{ 10611 __ addw(as_Register($dst$$reg), 10612 as_Register($src$$reg), 10613 as_Register($src$$reg), 10614 Assembler::LSR, 31); 10615 %} 10616 ins_pipe(ialu_reg); 10617 %} 10618 10619 // Long Divide 10620 10621 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10622 match(Set dst (DivL src1 src2)); 10623 10624 ins_cost(INSN_COST * 35); 10625 format %{ "sdiv $dst, $src1, $src2" %} 10626 10627 ins_encode(aarch64_enc_div(dst, src1, src2)); 10628 ins_pipe(ldiv_reg_reg); 10629 %} 10630 10631 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 10632 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 10633 ins_cost(INSN_COST); 10634 format %{ "lsr $dst, $src1, $div1" %} 10635 ins_encode %{ 10636 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 10637 %} 10638 ins_pipe(ialu_reg_shift); 10639 %} 10640 10641 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 10642 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 10643 ins_cost(INSN_COST); 10644 format %{ "add $dst, $src, $div1" %} 10645 10646 ins_encode %{ 10647 __ add(as_Register($dst$$reg), 10648 as_Register($src$$reg), 10649 as_Register($src$$reg), 10650 Assembler::LSR, 63); 10651 %} 10652 ins_pipe(ialu_reg); 10653 %} 10654 10655 // Integer Remainder 10656 10657 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10658 match(Set dst (ModI src1 src2)); 10659 10660 ins_cost(INSN_COST * 22); 10661 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10662 "msubw($dst, rscratch1, $src2, $src1" %} 10663 10664 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10665 ins_pipe(idiv_reg_reg); 10666 %} 10667 10668 // Long Remainder 10669 10670 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10671 match(Set dst (ModL src1 src2)); 10672 10673 ins_cost(INSN_COST * 38); 10674 format %{ "sdiv rscratch1, $src1, $src2\n" 10675 "msub($dst, rscratch1, $src2, $src1" %} 10676 10677 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10678 ins_pipe(ldiv_reg_reg); 10679 %} 10680 10681 // Integer Shifts 10682 10683 // Shift Left Register 10684 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10685 match(Set dst (LShiftI src1 src2)); 10686 10687 ins_cost(INSN_COST * 2); 10688 format %{ "lslvw $dst, $src1, $src2" %} 10689 10690 ins_encode %{ 10691 __ lslvw(as_Register($dst$$reg), 10692 as_Register($src1$$reg), 10693 as_Register($src2$$reg)); 10694 %} 10695 10696 ins_pipe(ialu_reg_reg_vshift); 10697 %} 10698 10699 // Shift Left Immediate 10700 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10701 match(Set dst (LShiftI src1 src2)); 10702 10703 ins_cost(INSN_COST); 10704 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10705 10706 ins_encode %{ 10707 __ lslw(as_Register($dst$$reg), 10708 as_Register($src1$$reg), 10709 $src2$$constant & 0x1f); 10710 %} 10711 10712 ins_pipe(ialu_reg_shift); 10713 %} 10714 10715 // Shift Right Logical Register 10716 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10717 match(Set dst (URShiftI src1 src2)); 10718 10719 ins_cost(INSN_COST * 2); 10720 format %{ "lsrvw $dst, $src1, $src2" %} 10721 10722 ins_encode %{ 10723 __ lsrvw(as_Register($dst$$reg), 10724 as_Register($src1$$reg), 10725 as_Register($src2$$reg)); 10726 %} 10727 10728 ins_pipe(ialu_reg_reg_vshift); 10729 %} 10730 10731 // Shift Right Logical Immediate 10732 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10733 match(Set dst (URShiftI src1 src2)); 10734 10735 ins_cost(INSN_COST); 10736 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10737 10738 ins_encode %{ 10739 __ lsrw(as_Register($dst$$reg), 10740 as_Register($src1$$reg), 10741 $src2$$constant & 0x1f); 10742 %} 10743 10744 ins_pipe(ialu_reg_shift); 10745 %} 10746 10747 // Shift Right Arithmetic Register 10748 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10749 match(Set dst (RShiftI src1 src2)); 10750 10751 ins_cost(INSN_COST * 2); 10752 format %{ "asrvw $dst, $src1, $src2" %} 10753 10754 ins_encode %{ 10755 __ asrvw(as_Register($dst$$reg), 10756 as_Register($src1$$reg), 10757 as_Register($src2$$reg)); 10758 %} 10759 10760 ins_pipe(ialu_reg_reg_vshift); 10761 %} 10762 10763 // Shift Right Arithmetic Immediate 10764 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10765 match(Set dst (RShiftI src1 src2)); 10766 10767 ins_cost(INSN_COST); 10768 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10769 10770 ins_encode %{ 10771 __ asrw(as_Register($dst$$reg), 10772 as_Register($src1$$reg), 10773 $src2$$constant & 0x1f); 10774 %} 10775 10776 ins_pipe(ialu_reg_shift); 10777 %} 10778 10779 // Combined Int Mask and Right Shift (using UBFM) 10780 // TODO 10781 10782 // Long Shifts 10783 10784 // Shift Left Register 10785 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10786 match(Set dst (LShiftL src1 src2)); 10787 10788 ins_cost(INSN_COST * 2); 10789 format %{ "lslv $dst, $src1, $src2" %} 10790 10791 ins_encode %{ 10792 __ lslv(as_Register($dst$$reg), 10793 as_Register($src1$$reg), 10794 as_Register($src2$$reg)); 10795 %} 10796 10797 ins_pipe(ialu_reg_reg_vshift); 10798 %} 10799 10800 // Shift Left Immediate 10801 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10802 match(Set dst (LShiftL src1 src2)); 10803 10804 ins_cost(INSN_COST); 10805 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10806 10807 ins_encode %{ 10808 __ lsl(as_Register($dst$$reg), 10809 as_Register($src1$$reg), 10810 $src2$$constant & 0x3f); 10811 %} 10812 10813 ins_pipe(ialu_reg_shift); 10814 %} 10815 10816 // Shift Right Logical Register 10817 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10818 match(Set dst (URShiftL src1 src2)); 10819 10820 ins_cost(INSN_COST * 2); 10821 format %{ "lsrv $dst, $src1, $src2" %} 10822 10823 ins_encode %{ 10824 __ lsrv(as_Register($dst$$reg), 10825 as_Register($src1$$reg), 10826 as_Register($src2$$reg)); 10827 %} 10828 10829 ins_pipe(ialu_reg_reg_vshift); 10830 %} 10831 10832 // Shift Right Logical Immediate 10833 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10834 match(Set dst (URShiftL src1 src2)); 10835 10836 ins_cost(INSN_COST); 10837 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10838 10839 ins_encode %{ 10840 __ lsr(as_Register($dst$$reg), 10841 as_Register($src1$$reg), 10842 $src2$$constant & 0x3f); 10843 %} 10844 10845 ins_pipe(ialu_reg_shift); 10846 %} 10847 10848 // A special-case pattern for card table stores. 10849 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10850 match(Set dst (URShiftL (CastP2X src1) src2)); 10851 10852 ins_cost(INSN_COST); 10853 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10854 10855 ins_encode %{ 10856 __ lsr(as_Register($dst$$reg), 10857 as_Register($src1$$reg), 10858 $src2$$constant & 0x3f); 10859 %} 10860 10861 ins_pipe(ialu_reg_shift); 10862 %} 10863 10864 // Shift Right Arithmetic Register 10865 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10866 match(Set dst (RShiftL src1 src2)); 10867 10868 ins_cost(INSN_COST * 2); 10869 format %{ "asrv $dst, $src1, $src2" %} 10870 10871 ins_encode %{ 10872 __ asrv(as_Register($dst$$reg), 10873 as_Register($src1$$reg), 10874 as_Register($src2$$reg)); 10875 %} 10876 10877 ins_pipe(ialu_reg_reg_vshift); 10878 %} 10879 10880 // Shift Right Arithmetic Immediate 10881 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10882 match(Set dst (RShiftL src1 src2)); 10883 10884 ins_cost(INSN_COST); 10885 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10886 10887 ins_encode %{ 10888 __ asr(as_Register($dst$$reg), 10889 as_Register($src1$$reg), 10890 $src2$$constant & 0x3f); 10891 %} 10892 10893 ins_pipe(ialu_reg_shift); 10894 %} 10895 10896 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10897 10898 instruct regL_not_reg(iRegLNoSp dst, 10899 iRegL src1, immL_M1 m1, 10900 rFlagsReg cr) %{ 10901 match(Set dst (XorL src1 m1)); 10902 ins_cost(INSN_COST); 10903 format %{ "eon $dst, $src1, zr" %} 10904 10905 ins_encode %{ 10906 __ eon(as_Register($dst$$reg), 10907 as_Register($src1$$reg), 10908 zr, 10909 Assembler::LSL, 0); 10910 %} 10911 10912 ins_pipe(ialu_reg); 10913 %} 10914 instruct regI_not_reg(iRegINoSp dst, 10915 iRegIorL2I src1, immI_M1 m1, 10916 rFlagsReg cr) %{ 10917 match(Set dst (XorI src1 m1)); 10918 ins_cost(INSN_COST); 10919 format %{ "eonw $dst, $src1, zr" %} 10920 10921 ins_encode %{ 10922 __ eonw(as_Register($dst$$reg), 10923 as_Register($src1$$reg), 10924 zr, 10925 Assembler::LSL, 0); 10926 %} 10927 10928 ins_pipe(ialu_reg); 10929 %} 10930 10931 instruct AndI_reg_not_reg(iRegINoSp dst, 10932 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10933 rFlagsReg cr) %{ 10934 match(Set dst (AndI src1 (XorI src2 m1))); 10935 ins_cost(INSN_COST); 10936 format %{ "bicw $dst, $src1, $src2" %} 10937 10938 ins_encode %{ 10939 __ bicw(as_Register($dst$$reg), 10940 as_Register($src1$$reg), 10941 as_Register($src2$$reg), 10942 Assembler::LSL, 0); 10943 %} 10944 10945 ins_pipe(ialu_reg_reg); 10946 %} 10947 10948 instruct AndL_reg_not_reg(iRegLNoSp dst, 10949 iRegL src1, iRegL src2, immL_M1 m1, 10950 rFlagsReg cr) %{ 10951 match(Set dst (AndL src1 (XorL src2 m1))); 10952 ins_cost(INSN_COST); 10953 format %{ "bic $dst, $src1, $src2" %} 10954 10955 ins_encode %{ 10956 __ bic(as_Register($dst$$reg), 10957 as_Register($src1$$reg), 10958 as_Register($src2$$reg), 10959 Assembler::LSL, 0); 10960 %} 10961 10962 ins_pipe(ialu_reg_reg); 10963 %} 10964 10965 instruct OrI_reg_not_reg(iRegINoSp dst, 10966 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10967 rFlagsReg cr) %{ 10968 match(Set dst (OrI src1 (XorI src2 m1))); 10969 ins_cost(INSN_COST); 10970 format %{ "ornw $dst, $src1, $src2" %} 10971 10972 ins_encode %{ 10973 __ ornw(as_Register($dst$$reg), 10974 as_Register($src1$$reg), 10975 as_Register($src2$$reg), 10976 Assembler::LSL, 0); 10977 %} 10978 10979 ins_pipe(ialu_reg_reg); 10980 %} 10981 10982 instruct OrL_reg_not_reg(iRegLNoSp dst, 10983 iRegL src1, iRegL src2, immL_M1 m1, 10984 rFlagsReg cr) %{ 10985 match(Set dst (OrL src1 (XorL src2 m1))); 10986 ins_cost(INSN_COST); 10987 format %{ "orn $dst, $src1, $src2" %} 10988 10989 ins_encode %{ 10990 __ orn(as_Register($dst$$reg), 10991 as_Register($src1$$reg), 10992 as_Register($src2$$reg), 10993 Assembler::LSL, 0); 10994 %} 10995 10996 ins_pipe(ialu_reg_reg); 10997 %} 10998 10999 instruct XorI_reg_not_reg(iRegINoSp dst, 11000 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 11001 rFlagsReg cr) %{ 11002 match(Set dst (XorI m1 (XorI src2 src1))); 11003 ins_cost(INSN_COST); 11004 format %{ "eonw $dst, $src1, $src2" %} 11005 11006 ins_encode %{ 11007 __ eonw(as_Register($dst$$reg), 11008 as_Register($src1$$reg), 11009 as_Register($src2$$reg), 11010 Assembler::LSL, 0); 11011 %} 11012 11013 ins_pipe(ialu_reg_reg); 11014 %} 11015 11016 instruct XorL_reg_not_reg(iRegLNoSp dst, 11017 iRegL src1, iRegL src2, immL_M1 m1, 11018 rFlagsReg cr) %{ 11019 match(Set dst (XorL m1 (XorL src2 src1))); 11020 ins_cost(INSN_COST); 11021 format %{ "eon $dst, $src1, $src2" %} 11022 11023 ins_encode %{ 11024 __ eon(as_Register($dst$$reg), 11025 as_Register($src1$$reg), 11026 as_Register($src2$$reg), 11027 Assembler::LSL, 0); 11028 %} 11029 11030 ins_pipe(ialu_reg_reg); 11031 %} 11032 11033 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11034 iRegIorL2I src1, iRegIorL2I src2, 11035 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11036 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11037 ins_cost(1.9 * INSN_COST); 11038 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11039 11040 ins_encode %{ 11041 __ bicw(as_Register($dst$$reg), 11042 as_Register($src1$$reg), 11043 as_Register($src2$$reg), 11044 Assembler::LSR, 11045 $src3$$constant & 0x1f); 11046 %} 11047 11048 ins_pipe(ialu_reg_reg_shift); 11049 %} 11050 11051 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11052 iRegL src1, iRegL src2, 11053 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11054 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11055 ins_cost(1.9 * INSN_COST); 11056 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11057 11058 ins_encode %{ 11059 __ bic(as_Register($dst$$reg), 11060 as_Register($src1$$reg), 11061 as_Register($src2$$reg), 11062 Assembler::LSR, 11063 $src3$$constant & 0x3f); 11064 %} 11065 11066 ins_pipe(ialu_reg_reg_shift); 11067 %} 11068 11069 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11070 iRegIorL2I src1, iRegIorL2I src2, 11071 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11072 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11073 ins_cost(1.9 * INSN_COST); 11074 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11075 11076 ins_encode %{ 11077 __ bicw(as_Register($dst$$reg), 11078 as_Register($src1$$reg), 11079 as_Register($src2$$reg), 11080 Assembler::ASR, 11081 $src3$$constant & 0x1f); 11082 %} 11083 11084 ins_pipe(ialu_reg_reg_shift); 11085 %} 11086 11087 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11088 iRegL src1, iRegL src2, 11089 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11090 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11091 ins_cost(1.9 * INSN_COST); 11092 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11093 11094 ins_encode %{ 11095 __ bic(as_Register($dst$$reg), 11096 as_Register($src1$$reg), 11097 as_Register($src2$$reg), 11098 Assembler::ASR, 11099 $src3$$constant & 0x3f); 11100 %} 11101 11102 ins_pipe(ialu_reg_reg_shift); 11103 %} 11104 11105 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11106 iRegIorL2I src1, iRegIorL2I src2, 11107 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11108 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11109 ins_cost(1.9 * INSN_COST); 11110 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11111 11112 ins_encode %{ 11113 __ bicw(as_Register($dst$$reg), 11114 as_Register($src1$$reg), 11115 as_Register($src2$$reg), 11116 Assembler::LSL, 11117 $src3$$constant & 0x1f); 11118 %} 11119 11120 ins_pipe(ialu_reg_reg_shift); 11121 %} 11122 11123 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11124 iRegL src1, iRegL src2, 11125 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11126 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11127 ins_cost(1.9 * INSN_COST); 11128 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11129 11130 ins_encode %{ 11131 __ bic(as_Register($dst$$reg), 11132 as_Register($src1$$reg), 11133 as_Register($src2$$reg), 11134 Assembler::LSL, 11135 $src3$$constant & 0x3f); 11136 %} 11137 11138 ins_pipe(ialu_reg_reg_shift); 11139 %} 11140 11141 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11142 iRegIorL2I src1, iRegIorL2I src2, 11143 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11144 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11145 ins_cost(1.9 * INSN_COST); 11146 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11147 11148 ins_encode %{ 11149 __ eonw(as_Register($dst$$reg), 11150 as_Register($src1$$reg), 11151 as_Register($src2$$reg), 11152 Assembler::LSR, 11153 $src3$$constant & 0x1f); 11154 %} 11155 11156 ins_pipe(ialu_reg_reg_shift); 11157 %} 11158 11159 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11160 iRegL src1, iRegL src2, 11161 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11162 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11163 ins_cost(1.9 * INSN_COST); 11164 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11165 11166 ins_encode %{ 11167 __ eon(as_Register($dst$$reg), 11168 as_Register($src1$$reg), 11169 as_Register($src2$$reg), 11170 Assembler::LSR, 11171 $src3$$constant & 0x3f); 11172 %} 11173 11174 ins_pipe(ialu_reg_reg_shift); 11175 %} 11176 11177 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11178 iRegIorL2I src1, iRegIorL2I src2, 11179 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11180 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11181 ins_cost(1.9 * INSN_COST); 11182 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11183 11184 ins_encode %{ 11185 __ eonw(as_Register($dst$$reg), 11186 as_Register($src1$$reg), 11187 as_Register($src2$$reg), 11188 Assembler::ASR, 11189 $src3$$constant & 0x1f); 11190 %} 11191 11192 ins_pipe(ialu_reg_reg_shift); 11193 %} 11194 11195 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11196 iRegL src1, iRegL src2, 11197 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11198 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11199 ins_cost(1.9 * INSN_COST); 11200 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11201 11202 ins_encode %{ 11203 __ eon(as_Register($dst$$reg), 11204 as_Register($src1$$reg), 11205 as_Register($src2$$reg), 11206 Assembler::ASR, 11207 $src3$$constant & 0x3f); 11208 %} 11209 11210 ins_pipe(ialu_reg_reg_shift); 11211 %} 11212 11213 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11214 iRegIorL2I src1, iRegIorL2I src2, 11215 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11216 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11217 ins_cost(1.9 * INSN_COST); 11218 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11219 11220 ins_encode %{ 11221 __ eonw(as_Register($dst$$reg), 11222 as_Register($src1$$reg), 11223 as_Register($src2$$reg), 11224 Assembler::LSL, 11225 $src3$$constant & 0x1f); 11226 %} 11227 11228 ins_pipe(ialu_reg_reg_shift); 11229 %} 11230 11231 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11232 iRegL src1, iRegL src2, 11233 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11234 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11235 ins_cost(1.9 * INSN_COST); 11236 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11237 11238 ins_encode %{ 11239 __ eon(as_Register($dst$$reg), 11240 as_Register($src1$$reg), 11241 as_Register($src2$$reg), 11242 Assembler::LSL, 11243 $src3$$constant & 0x3f); 11244 %} 11245 11246 ins_pipe(ialu_reg_reg_shift); 11247 %} 11248 11249 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11250 iRegIorL2I src1, iRegIorL2I src2, 11251 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11252 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11253 ins_cost(1.9 * INSN_COST); 11254 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11255 11256 ins_encode %{ 11257 __ ornw(as_Register($dst$$reg), 11258 as_Register($src1$$reg), 11259 as_Register($src2$$reg), 11260 Assembler::LSR, 11261 $src3$$constant & 0x1f); 11262 %} 11263 11264 ins_pipe(ialu_reg_reg_shift); 11265 %} 11266 11267 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11268 iRegL src1, iRegL src2, 11269 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11270 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11271 ins_cost(1.9 * INSN_COST); 11272 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11273 11274 ins_encode %{ 11275 __ orn(as_Register($dst$$reg), 11276 as_Register($src1$$reg), 11277 as_Register($src2$$reg), 11278 Assembler::LSR, 11279 $src3$$constant & 0x3f); 11280 %} 11281 11282 ins_pipe(ialu_reg_reg_shift); 11283 %} 11284 11285 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11286 iRegIorL2I src1, iRegIorL2I src2, 11287 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11288 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11289 ins_cost(1.9 * INSN_COST); 11290 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11291 11292 ins_encode %{ 11293 __ ornw(as_Register($dst$$reg), 11294 as_Register($src1$$reg), 11295 as_Register($src2$$reg), 11296 Assembler::ASR, 11297 $src3$$constant & 0x1f); 11298 %} 11299 11300 ins_pipe(ialu_reg_reg_shift); 11301 %} 11302 11303 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11304 iRegL src1, iRegL src2, 11305 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11306 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11307 ins_cost(1.9 * INSN_COST); 11308 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11309 11310 ins_encode %{ 11311 __ orn(as_Register($dst$$reg), 11312 as_Register($src1$$reg), 11313 as_Register($src2$$reg), 11314 Assembler::ASR, 11315 $src3$$constant & 0x3f); 11316 %} 11317 11318 ins_pipe(ialu_reg_reg_shift); 11319 %} 11320 11321 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11322 iRegIorL2I src1, iRegIorL2I src2, 11323 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11324 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11325 ins_cost(1.9 * INSN_COST); 11326 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11327 11328 ins_encode %{ 11329 __ ornw(as_Register($dst$$reg), 11330 as_Register($src1$$reg), 11331 as_Register($src2$$reg), 11332 Assembler::LSL, 11333 $src3$$constant & 0x1f); 11334 %} 11335 11336 ins_pipe(ialu_reg_reg_shift); 11337 %} 11338 11339 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11340 iRegL src1, iRegL src2, 11341 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11342 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11343 ins_cost(1.9 * INSN_COST); 11344 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11345 11346 ins_encode %{ 11347 __ orn(as_Register($dst$$reg), 11348 as_Register($src1$$reg), 11349 as_Register($src2$$reg), 11350 Assembler::LSL, 11351 $src3$$constant & 0x3f); 11352 %} 11353 11354 ins_pipe(ialu_reg_reg_shift); 11355 %} 11356 11357 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11358 iRegIorL2I src1, iRegIorL2I src2, 11359 immI src3, rFlagsReg cr) %{ 11360 match(Set dst (AndI src1 (URShiftI src2 src3))); 11361 11362 ins_cost(1.9 * INSN_COST); 11363 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11364 11365 ins_encode %{ 11366 __ andw(as_Register($dst$$reg), 11367 as_Register($src1$$reg), 11368 as_Register($src2$$reg), 11369 Assembler::LSR, 11370 $src3$$constant & 0x1f); 11371 %} 11372 11373 ins_pipe(ialu_reg_reg_shift); 11374 %} 11375 11376 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11377 iRegL src1, iRegL src2, 11378 immI src3, rFlagsReg cr) %{ 11379 match(Set dst (AndL src1 (URShiftL src2 src3))); 11380 11381 ins_cost(1.9 * INSN_COST); 11382 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11383 11384 ins_encode %{ 11385 __ andr(as_Register($dst$$reg), 11386 as_Register($src1$$reg), 11387 as_Register($src2$$reg), 11388 Assembler::LSR, 11389 $src3$$constant & 0x3f); 11390 %} 11391 11392 ins_pipe(ialu_reg_reg_shift); 11393 %} 11394 11395 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11396 iRegIorL2I src1, iRegIorL2I src2, 11397 immI src3, rFlagsReg cr) %{ 11398 match(Set dst (AndI src1 (RShiftI src2 src3))); 11399 11400 ins_cost(1.9 * INSN_COST); 11401 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11402 11403 ins_encode %{ 11404 __ andw(as_Register($dst$$reg), 11405 as_Register($src1$$reg), 11406 as_Register($src2$$reg), 11407 Assembler::ASR, 11408 $src3$$constant & 0x1f); 11409 %} 11410 11411 ins_pipe(ialu_reg_reg_shift); 11412 %} 11413 11414 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11415 iRegL src1, iRegL src2, 11416 immI src3, rFlagsReg cr) %{ 11417 match(Set dst (AndL src1 (RShiftL src2 src3))); 11418 11419 ins_cost(1.9 * INSN_COST); 11420 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11421 11422 ins_encode %{ 11423 __ andr(as_Register($dst$$reg), 11424 as_Register($src1$$reg), 11425 as_Register($src2$$reg), 11426 Assembler::ASR, 11427 $src3$$constant & 0x3f); 11428 %} 11429 11430 ins_pipe(ialu_reg_reg_shift); 11431 %} 11432 11433 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11434 iRegIorL2I src1, iRegIorL2I src2, 11435 immI src3, rFlagsReg cr) %{ 11436 match(Set dst (AndI src1 (LShiftI src2 src3))); 11437 11438 ins_cost(1.9 * INSN_COST); 11439 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11440 11441 ins_encode %{ 11442 __ andw(as_Register($dst$$reg), 11443 as_Register($src1$$reg), 11444 as_Register($src2$$reg), 11445 Assembler::LSL, 11446 $src3$$constant & 0x1f); 11447 %} 11448 11449 ins_pipe(ialu_reg_reg_shift); 11450 %} 11451 11452 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11453 iRegL src1, iRegL src2, 11454 immI src3, rFlagsReg cr) %{ 11455 match(Set dst (AndL src1 (LShiftL src2 src3))); 11456 11457 ins_cost(1.9 * INSN_COST); 11458 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11459 11460 ins_encode %{ 11461 __ andr(as_Register($dst$$reg), 11462 as_Register($src1$$reg), 11463 as_Register($src2$$reg), 11464 Assembler::LSL, 11465 $src3$$constant & 0x3f); 11466 %} 11467 11468 ins_pipe(ialu_reg_reg_shift); 11469 %} 11470 11471 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11472 iRegIorL2I src1, iRegIorL2I src2, 11473 immI src3, rFlagsReg cr) %{ 11474 match(Set dst (XorI src1 (URShiftI src2 src3))); 11475 11476 ins_cost(1.9 * INSN_COST); 11477 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11478 11479 ins_encode %{ 11480 __ eorw(as_Register($dst$$reg), 11481 as_Register($src1$$reg), 11482 as_Register($src2$$reg), 11483 Assembler::LSR, 11484 $src3$$constant & 0x1f); 11485 %} 11486 11487 ins_pipe(ialu_reg_reg_shift); 11488 %} 11489 11490 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11491 iRegL src1, iRegL src2, 11492 immI src3, rFlagsReg cr) %{ 11493 match(Set dst (XorL src1 (URShiftL src2 src3))); 11494 11495 ins_cost(1.9 * INSN_COST); 11496 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11497 11498 ins_encode %{ 11499 __ eor(as_Register($dst$$reg), 11500 as_Register($src1$$reg), 11501 as_Register($src2$$reg), 11502 Assembler::LSR, 11503 $src3$$constant & 0x3f); 11504 %} 11505 11506 ins_pipe(ialu_reg_reg_shift); 11507 %} 11508 11509 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11510 iRegIorL2I src1, iRegIorL2I src2, 11511 immI src3, rFlagsReg cr) %{ 11512 match(Set dst (XorI src1 (RShiftI src2 src3))); 11513 11514 ins_cost(1.9 * INSN_COST); 11515 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11516 11517 ins_encode %{ 11518 __ eorw(as_Register($dst$$reg), 11519 as_Register($src1$$reg), 11520 as_Register($src2$$reg), 11521 Assembler::ASR, 11522 $src3$$constant & 0x1f); 11523 %} 11524 11525 ins_pipe(ialu_reg_reg_shift); 11526 %} 11527 11528 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11529 iRegL src1, iRegL src2, 11530 immI src3, rFlagsReg cr) %{ 11531 match(Set dst (XorL src1 (RShiftL src2 src3))); 11532 11533 ins_cost(1.9 * INSN_COST); 11534 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11535 11536 ins_encode %{ 11537 __ eor(as_Register($dst$$reg), 11538 as_Register($src1$$reg), 11539 as_Register($src2$$reg), 11540 Assembler::ASR, 11541 $src3$$constant & 0x3f); 11542 %} 11543 11544 ins_pipe(ialu_reg_reg_shift); 11545 %} 11546 11547 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11548 iRegIorL2I src1, iRegIorL2I src2, 11549 immI src3, rFlagsReg cr) %{ 11550 match(Set dst (XorI src1 (LShiftI src2 src3))); 11551 11552 ins_cost(1.9 * INSN_COST); 11553 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11554 11555 ins_encode %{ 11556 __ eorw(as_Register($dst$$reg), 11557 as_Register($src1$$reg), 11558 as_Register($src2$$reg), 11559 Assembler::LSL, 11560 $src3$$constant & 0x1f); 11561 %} 11562 11563 ins_pipe(ialu_reg_reg_shift); 11564 %} 11565 11566 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11567 iRegL src1, iRegL src2, 11568 immI src3, rFlagsReg cr) %{ 11569 match(Set dst (XorL src1 (LShiftL src2 src3))); 11570 11571 ins_cost(1.9 * INSN_COST); 11572 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11573 11574 ins_encode %{ 11575 __ eor(as_Register($dst$$reg), 11576 as_Register($src1$$reg), 11577 as_Register($src2$$reg), 11578 Assembler::LSL, 11579 $src3$$constant & 0x3f); 11580 %} 11581 11582 ins_pipe(ialu_reg_reg_shift); 11583 %} 11584 11585 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11586 iRegIorL2I src1, iRegIorL2I src2, 11587 immI src3, rFlagsReg cr) %{ 11588 match(Set dst (OrI src1 (URShiftI src2 src3))); 11589 11590 ins_cost(1.9 * INSN_COST); 11591 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11592 11593 ins_encode %{ 11594 __ orrw(as_Register($dst$$reg), 11595 as_Register($src1$$reg), 11596 as_Register($src2$$reg), 11597 Assembler::LSR, 11598 $src3$$constant & 0x1f); 11599 %} 11600 11601 ins_pipe(ialu_reg_reg_shift); 11602 %} 11603 11604 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11605 iRegL src1, iRegL src2, 11606 immI src3, rFlagsReg cr) %{ 11607 match(Set dst (OrL src1 (URShiftL src2 src3))); 11608 11609 ins_cost(1.9 * INSN_COST); 11610 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11611 11612 ins_encode %{ 11613 __ orr(as_Register($dst$$reg), 11614 as_Register($src1$$reg), 11615 as_Register($src2$$reg), 11616 Assembler::LSR, 11617 $src3$$constant & 0x3f); 11618 %} 11619 11620 ins_pipe(ialu_reg_reg_shift); 11621 %} 11622 11623 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11624 iRegIorL2I src1, iRegIorL2I src2, 11625 immI src3, rFlagsReg cr) %{ 11626 match(Set dst (OrI src1 (RShiftI src2 src3))); 11627 11628 ins_cost(1.9 * INSN_COST); 11629 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11630 11631 ins_encode %{ 11632 __ orrw(as_Register($dst$$reg), 11633 as_Register($src1$$reg), 11634 as_Register($src2$$reg), 11635 Assembler::ASR, 11636 $src3$$constant & 0x1f); 11637 %} 11638 11639 ins_pipe(ialu_reg_reg_shift); 11640 %} 11641 11642 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11643 iRegL src1, iRegL src2, 11644 immI src3, rFlagsReg cr) %{ 11645 match(Set dst (OrL src1 (RShiftL src2 src3))); 11646 11647 ins_cost(1.9 * INSN_COST); 11648 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11649 11650 ins_encode %{ 11651 __ orr(as_Register($dst$$reg), 11652 as_Register($src1$$reg), 11653 as_Register($src2$$reg), 11654 Assembler::ASR, 11655 $src3$$constant & 0x3f); 11656 %} 11657 11658 ins_pipe(ialu_reg_reg_shift); 11659 %} 11660 11661 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11662 iRegIorL2I src1, iRegIorL2I src2, 11663 immI src3, rFlagsReg cr) %{ 11664 match(Set dst (OrI src1 (LShiftI src2 src3))); 11665 11666 ins_cost(1.9 * INSN_COST); 11667 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11668 11669 ins_encode %{ 11670 __ orrw(as_Register($dst$$reg), 11671 as_Register($src1$$reg), 11672 as_Register($src2$$reg), 11673 Assembler::LSL, 11674 $src3$$constant & 0x1f); 11675 %} 11676 11677 ins_pipe(ialu_reg_reg_shift); 11678 %} 11679 11680 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11681 iRegL src1, iRegL src2, 11682 immI src3, rFlagsReg cr) %{ 11683 match(Set dst (OrL src1 (LShiftL src2 src3))); 11684 11685 ins_cost(1.9 * INSN_COST); 11686 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11687 11688 ins_encode %{ 11689 __ orr(as_Register($dst$$reg), 11690 as_Register($src1$$reg), 11691 as_Register($src2$$reg), 11692 Assembler::LSL, 11693 $src3$$constant & 0x3f); 11694 %} 11695 11696 ins_pipe(ialu_reg_reg_shift); 11697 %} 11698 11699 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11700 iRegIorL2I src1, iRegIorL2I src2, 11701 immI src3, rFlagsReg cr) %{ 11702 match(Set dst (AddI src1 (URShiftI src2 src3))); 11703 11704 ins_cost(1.9 * INSN_COST); 11705 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11706 11707 ins_encode %{ 11708 __ addw(as_Register($dst$$reg), 11709 as_Register($src1$$reg), 11710 as_Register($src2$$reg), 11711 Assembler::LSR, 11712 $src3$$constant & 0x1f); 11713 %} 11714 11715 ins_pipe(ialu_reg_reg_shift); 11716 %} 11717 11718 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11719 iRegL src1, iRegL src2, 11720 immI src3, rFlagsReg cr) %{ 11721 match(Set dst (AddL src1 (URShiftL src2 src3))); 11722 11723 ins_cost(1.9 * INSN_COST); 11724 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11725 11726 ins_encode %{ 11727 __ add(as_Register($dst$$reg), 11728 as_Register($src1$$reg), 11729 as_Register($src2$$reg), 11730 Assembler::LSR, 11731 $src3$$constant & 0x3f); 11732 %} 11733 11734 ins_pipe(ialu_reg_reg_shift); 11735 %} 11736 11737 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11738 iRegIorL2I src1, iRegIorL2I src2, 11739 immI src3, rFlagsReg cr) %{ 11740 match(Set dst (AddI src1 (RShiftI src2 src3))); 11741 11742 ins_cost(1.9 * INSN_COST); 11743 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11744 11745 ins_encode %{ 11746 __ addw(as_Register($dst$$reg), 11747 as_Register($src1$$reg), 11748 as_Register($src2$$reg), 11749 Assembler::ASR, 11750 $src3$$constant & 0x1f); 11751 %} 11752 11753 ins_pipe(ialu_reg_reg_shift); 11754 %} 11755 11756 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11757 iRegL src1, iRegL src2, 11758 immI src3, rFlagsReg cr) %{ 11759 match(Set dst (AddL src1 (RShiftL src2 src3))); 11760 11761 ins_cost(1.9 * INSN_COST); 11762 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11763 11764 ins_encode %{ 11765 __ add(as_Register($dst$$reg), 11766 as_Register($src1$$reg), 11767 as_Register($src2$$reg), 11768 Assembler::ASR, 11769 $src3$$constant & 0x3f); 11770 %} 11771 11772 ins_pipe(ialu_reg_reg_shift); 11773 %} 11774 11775 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11776 iRegIorL2I src1, iRegIorL2I src2, 11777 immI src3, rFlagsReg cr) %{ 11778 match(Set dst (AddI src1 (LShiftI src2 src3))); 11779 11780 ins_cost(1.9 * INSN_COST); 11781 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11782 11783 ins_encode %{ 11784 __ addw(as_Register($dst$$reg), 11785 as_Register($src1$$reg), 11786 as_Register($src2$$reg), 11787 Assembler::LSL, 11788 $src3$$constant & 0x1f); 11789 %} 11790 11791 ins_pipe(ialu_reg_reg_shift); 11792 %} 11793 11794 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11795 iRegL src1, iRegL src2, 11796 immI src3, rFlagsReg cr) %{ 11797 match(Set dst (AddL src1 (LShiftL src2 src3))); 11798 11799 ins_cost(1.9 * INSN_COST); 11800 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11801 11802 ins_encode %{ 11803 __ add(as_Register($dst$$reg), 11804 as_Register($src1$$reg), 11805 as_Register($src2$$reg), 11806 Assembler::LSL, 11807 $src3$$constant & 0x3f); 11808 %} 11809 11810 ins_pipe(ialu_reg_reg_shift); 11811 %} 11812 11813 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11814 iRegIorL2I src1, iRegIorL2I src2, 11815 immI src3, rFlagsReg cr) %{ 11816 match(Set dst (SubI src1 (URShiftI src2 src3))); 11817 11818 ins_cost(1.9 * INSN_COST); 11819 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11820 11821 ins_encode %{ 11822 __ subw(as_Register($dst$$reg), 11823 as_Register($src1$$reg), 11824 as_Register($src2$$reg), 11825 Assembler::LSR, 11826 $src3$$constant & 0x1f); 11827 %} 11828 11829 ins_pipe(ialu_reg_reg_shift); 11830 %} 11831 11832 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11833 iRegL src1, iRegL src2, 11834 immI src3, rFlagsReg cr) %{ 11835 match(Set dst (SubL src1 (URShiftL src2 src3))); 11836 11837 ins_cost(1.9 * INSN_COST); 11838 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11839 11840 ins_encode %{ 11841 __ sub(as_Register($dst$$reg), 11842 as_Register($src1$$reg), 11843 as_Register($src2$$reg), 11844 Assembler::LSR, 11845 $src3$$constant & 0x3f); 11846 %} 11847 11848 ins_pipe(ialu_reg_reg_shift); 11849 %} 11850 11851 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11852 iRegIorL2I src1, iRegIorL2I src2, 11853 immI src3, rFlagsReg cr) %{ 11854 match(Set dst (SubI src1 (RShiftI src2 src3))); 11855 11856 ins_cost(1.9 * INSN_COST); 11857 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11858 11859 ins_encode %{ 11860 __ subw(as_Register($dst$$reg), 11861 as_Register($src1$$reg), 11862 as_Register($src2$$reg), 11863 Assembler::ASR, 11864 $src3$$constant & 0x1f); 11865 %} 11866 11867 ins_pipe(ialu_reg_reg_shift); 11868 %} 11869 11870 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11871 iRegL src1, iRegL src2, 11872 immI src3, rFlagsReg cr) %{ 11873 match(Set dst (SubL src1 (RShiftL src2 src3))); 11874 11875 ins_cost(1.9 * INSN_COST); 11876 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11877 11878 ins_encode %{ 11879 __ sub(as_Register($dst$$reg), 11880 as_Register($src1$$reg), 11881 as_Register($src2$$reg), 11882 Assembler::ASR, 11883 $src3$$constant & 0x3f); 11884 %} 11885 11886 ins_pipe(ialu_reg_reg_shift); 11887 %} 11888 11889 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11890 iRegIorL2I src1, iRegIorL2I src2, 11891 immI src3, rFlagsReg cr) %{ 11892 match(Set dst (SubI src1 (LShiftI src2 src3))); 11893 11894 ins_cost(1.9 * INSN_COST); 11895 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11896 11897 ins_encode %{ 11898 __ subw(as_Register($dst$$reg), 11899 as_Register($src1$$reg), 11900 as_Register($src2$$reg), 11901 Assembler::LSL, 11902 $src3$$constant & 0x1f); 11903 %} 11904 11905 ins_pipe(ialu_reg_reg_shift); 11906 %} 11907 11908 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11909 iRegL src1, iRegL src2, 11910 immI src3, rFlagsReg cr) %{ 11911 match(Set dst (SubL src1 (LShiftL src2 src3))); 11912 11913 ins_cost(1.9 * INSN_COST); 11914 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11915 11916 ins_encode %{ 11917 __ sub(as_Register($dst$$reg), 11918 as_Register($src1$$reg), 11919 as_Register($src2$$reg), 11920 Assembler::LSL, 11921 $src3$$constant & 0x3f); 11922 %} 11923 11924 ins_pipe(ialu_reg_reg_shift); 11925 %} 11926 11927 11928 11929 // Shift Left followed by Shift Right. 11930 // This idiom is used by the compiler for the i2b bytecode etc. 11931 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11932 %{ 11933 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11934 ins_cost(INSN_COST * 2); 11935 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11936 ins_encode %{ 11937 int lshift = $lshift_count$$constant & 63; 11938 int rshift = $rshift_count$$constant & 63; 11939 int s = 63 - lshift; 11940 int r = (rshift - lshift) & 63; 11941 __ sbfm(as_Register($dst$$reg), 11942 as_Register($src$$reg), 11943 r, s); 11944 %} 11945 11946 ins_pipe(ialu_reg_shift); 11947 %} 11948 11949 // Shift Left followed by Shift Right. 11950 // This idiom is used by the compiler for the i2b bytecode etc. 11951 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11952 %{ 11953 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11954 ins_cost(INSN_COST * 2); 11955 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11956 ins_encode %{ 11957 int lshift = $lshift_count$$constant & 31; 11958 int rshift = $rshift_count$$constant & 31; 11959 int s = 31 - lshift; 11960 int r = (rshift - lshift) & 31; 11961 __ sbfmw(as_Register($dst$$reg), 11962 as_Register($src$$reg), 11963 r, s); 11964 %} 11965 11966 ins_pipe(ialu_reg_shift); 11967 %} 11968 11969 // Shift Left followed by Shift Right. 11970 // This idiom is used by the compiler for the i2b bytecode etc. 11971 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11972 %{ 11973 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11974 ins_cost(INSN_COST * 2); 11975 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11976 ins_encode %{ 11977 int lshift = $lshift_count$$constant & 63; 11978 int rshift = $rshift_count$$constant & 63; 11979 int s = 63 - lshift; 11980 int r = (rshift - lshift) & 63; 11981 __ ubfm(as_Register($dst$$reg), 11982 as_Register($src$$reg), 11983 r, s); 11984 %} 11985 11986 ins_pipe(ialu_reg_shift); 11987 %} 11988 11989 // Shift Left followed by Shift Right. 11990 // This idiom is used by the compiler for the i2b bytecode etc. 11991 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11992 %{ 11993 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11994 ins_cost(INSN_COST * 2); 11995 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11996 ins_encode %{ 11997 int lshift = $lshift_count$$constant & 31; 11998 int rshift = $rshift_count$$constant & 31; 11999 int s = 31 - lshift; 12000 int r = (rshift - lshift) & 31; 12001 __ ubfmw(as_Register($dst$$reg), 12002 as_Register($src$$reg), 12003 r, s); 12004 %} 12005 12006 ins_pipe(ialu_reg_shift); 12007 %} 12008 // Bitfield extract with shift & mask 12009 12010 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12011 %{ 12012 match(Set dst (AndI (URShiftI src rshift) mask)); 12013 // Make sure we are not going to exceed what ubfxw can do. 12014 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12015 12016 ins_cost(INSN_COST); 12017 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12018 ins_encode %{ 12019 int rshift = $rshift$$constant & 31; 12020 long mask = $mask$$constant; 12021 int width = exact_log2(mask+1); 12022 __ ubfxw(as_Register($dst$$reg), 12023 as_Register($src$$reg), rshift, width); 12024 %} 12025 ins_pipe(ialu_reg_shift); 12026 %} 12027 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12028 %{ 12029 match(Set dst (AndL (URShiftL src rshift) mask)); 12030 // Make sure we are not going to exceed what ubfx can do. 12031 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12032 12033 ins_cost(INSN_COST); 12034 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12035 ins_encode %{ 12036 int rshift = $rshift$$constant & 63; 12037 long mask = $mask$$constant; 12038 int width = exact_log2_long(mask+1); 12039 __ ubfx(as_Register($dst$$reg), 12040 as_Register($src$$reg), rshift, width); 12041 %} 12042 ins_pipe(ialu_reg_shift); 12043 %} 12044 12045 // We can use ubfx when extending an And with a mask when we know mask 12046 // is positive. We know that because immI_bitmask guarantees it. 12047 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12048 %{ 12049 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12050 // Make sure we are not going to exceed what ubfxw can do. 12051 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12052 12053 ins_cost(INSN_COST * 2); 12054 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12055 ins_encode %{ 12056 int rshift = $rshift$$constant & 31; 12057 long mask = $mask$$constant; 12058 int width = exact_log2(mask+1); 12059 __ ubfx(as_Register($dst$$reg), 12060 as_Register($src$$reg), rshift, width); 12061 %} 12062 ins_pipe(ialu_reg_shift); 12063 %} 12064 12065 // We can use ubfiz when masking by a positive number and then left shifting the result. 12066 // We know that the mask is positive because immI_bitmask guarantees it. 12067 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12068 %{ 12069 match(Set dst (LShiftI (AndI src mask) lshift)); 12070 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12071 12072 ins_cost(INSN_COST); 12073 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12074 ins_encode %{ 12075 int lshift = $lshift$$constant & 31; 12076 long mask = $mask$$constant; 12077 int width = exact_log2(mask+1); 12078 __ ubfizw(as_Register($dst$$reg), 12079 as_Register($src$$reg), lshift, width); 12080 %} 12081 ins_pipe(ialu_reg_shift); 12082 %} 12083 // We can use ubfiz when masking by a positive number and then left shifting the result. 12084 // We know that the mask is positive because immL_bitmask guarantees it. 12085 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12086 %{ 12087 match(Set dst (LShiftL (AndL src mask) lshift)); 12088 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12089 12090 ins_cost(INSN_COST); 12091 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12092 ins_encode %{ 12093 int lshift = $lshift$$constant & 63; 12094 long mask = $mask$$constant; 12095 int width = exact_log2_long(mask+1); 12096 __ ubfiz(as_Register($dst$$reg), 12097 as_Register($src$$reg), lshift, width); 12098 %} 12099 ins_pipe(ialu_reg_shift); 12100 %} 12101 12102 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12103 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12104 %{ 12105 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12106 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12107 12108 ins_cost(INSN_COST); 12109 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12110 ins_encode %{ 12111 int lshift = $lshift$$constant & 63; 12112 long mask = $mask$$constant; 12113 int width = exact_log2(mask+1); 12114 __ ubfiz(as_Register($dst$$reg), 12115 as_Register($src$$reg), lshift, width); 12116 %} 12117 ins_pipe(ialu_reg_shift); 12118 %} 12119 12120 // Rotations 12121 12122 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12123 %{ 12124 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12125 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12126 12127 ins_cost(INSN_COST); 12128 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12129 12130 ins_encode %{ 12131 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12132 $rshift$$constant & 63); 12133 %} 12134 ins_pipe(ialu_reg_reg_extr); 12135 %} 12136 12137 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12138 %{ 12139 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12140 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12141 12142 ins_cost(INSN_COST); 12143 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12144 12145 ins_encode %{ 12146 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12147 $rshift$$constant & 31); 12148 %} 12149 ins_pipe(ialu_reg_reg_extr); 12150 %} 12151 12152 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12153 %{ 12154 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12155 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12156 12157 ins_cost(INSN_COST); 12158 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12159 12160 ins_encode %{ 12161 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12162 $rshift$$constant & 63); 12163 %} 12164 ins_pipe(ialu_reg_reg_extr); 12165 %} 12166 12167 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12168 %{ 12169 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12170 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12171 12172 ins_cost(INSN_COST); 12173 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12174 12175 ins_encode %{ 12176 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12177 $rshift$$constant & 31); 12178 %} 12179 ins_pipe(ialu_reg_reg_extr); 12180 %} 12181 12182 12183 // rol expander 12184 12185 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12186 %{ 12187 effect(DEF dst, USE src, USE shift); 12188 12189 format %{ "rol $dst, $src, $shift" %} 12190 ins_cost(INSN_COST * 3); 12191 ins_encode %{ 12192 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12193 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12194 rscratch1); 12195 %} 12196 ins_pipe(ialu_reg_reg_vshift); 12197 %} 12198 12199 // rol expander 12200 12201 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12202 %{ 12203 effect(DEF dst, USE src, USE shift); 12204 12205 format %{ "rol $dst, $src, $shift" %} 12206 ins_cost(INSN_COST * 3); 12207 ins_encode %{ 12208 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12209 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12210 rscratch1); 12211 %} 12212 ins_pipe(ialu_reg_reg_vshift); 12213 %} 12214 12215 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12216 %{ 12217 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12218 12219 expand %{ 12220 rolL_rReg(dst, src, shift, cr); 12221 %} 12222 %} 12223 12224 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12225 %{ 12226 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12227 12228 expand %{ 12229 rolL_rReg(dst, src, shift, cr); 12230 %} 12231 %} 12232 12233 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12234 %{ 12235 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12236 12237 expand %{ 12238 rolI_rReg(dst, src, shift, cr); 12239 %} 12240 %} 12241 12242 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12243 %{ 12244 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12245 12246 expand %{ 12247 rolI_rReg(dst, src, shift, cr); 12248 %} 12249 %} 12250 12251 // ror expander 12252 12253 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12254 %{ 12255 effect(DEF dst, USE src, USE shift); 12256 12257 format %{ "ror $dst, $src, $shift" %} 12258 ins_cost(INSN_COST); 12259 ins_encode %{ 12260 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12261 as_Register($shift$$reg)); 12262 %} 12263 ins_pipe(ialu_reg_reg_vshift); 12264 %} 12265 12266 // ror expander 12267 12268 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12269 %{ 12270 effect(DEF dst, USE src, USE shift); 12271 12272 format %{ "ror $dst, $src, $shift" %} 12273 ins_cost(INSN_COST); 12274 ins_encode %{ 12275 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12276 as_Register($shift$$reg)); 12277 %} 12278 ins_pipe(ialu_reg_reg_vshift); 12279 %} 12280 12281 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12282 %{ 12283 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12284 12285 expand %{ 12286 rorL_rReg(dst, src, shift, cr); 12287 %} 12288 %} 12289 12290 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12291 %{ 12292 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12293 12294 expand %{ 12295 rorL_rReg(dst, src, shift, cr); 12296 %} 12297 %} 12298 12299 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12300 %{ 12301 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12302 12303 expand %{ 12304 rorI_rReg(dst, src, shift, cr); 12305 %} 12306 %} 12307 12308 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12309 %{ 12310 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12311 12312 expand %{ 12313 rorI_rReg(dst, src, shift, cr); 12314 %} 12315 %} 12316 12317 // Add/subtract (extended) 12318 12319 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12320 %{ 12321 match(Set dst (AddL src1 (ConvI2L src2))); 12322 ins_cost(INSN_COST); 12323 format %{ "add $dst, $src1, $src2, sxtw" %} 12324 12325 ins_encode %{ 12326 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12327 as_Register($src2$$reg), ext::sxtw); 12328 %} 12329 ins_pipe(ialu_reg_reg); 12330 %}; 12331 12332 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12333 %{ 12334 match(Set dst (SubL src1 (ConvI2L src2))); 12335 ins_cost(INSN_COST); 12336 format %{ "sub $dst, $src1, $src2, sxtw" %} 12337 12338 ins_encode %{ 12339 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12340 as_Register($src2$$reg), ext::sxtw); 12341 %} 12342 ins_pipe(ialu_reg_reg); 12343 %}; 12344 12345 12346 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12347 %{ 12348 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12349 ins_cost(INSN_COST); 12350 format %{ "add $dst, $src1, $src2, sxth" %} 12351 12352 ins_encode %{ 12353 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12354 as_Register($src2$$reg), ext::sxth); 12355 %} 12356 ins_pipe(ialu_reg_reg); 12357 %} 12358 12359 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12360 %{ 12361 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12362 ins_cost(INSN_COST); 12363 format %{ "add $dst, $src1, $src2, sxtb" %} 12364 12365 ins_encode %{ 12366 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12367 as_Register($src2$$reg), ext::sxtb); 12368 %} 12369 ins_pipe(ialu_reg_reg); 12370 %} 12371 12372 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12373 %{ 12374 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12375 ins_cost(INSN_COST); 12376 format %{ "add $dst, $src1, $src2, uxtb" %} 12377 12378 ins_encode %{ 12379 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12380 as_Register($src2$$reg), ext::uxtb); 12381 %} 12382 ins_pipe(ialu_reg_reg); 12383 %} 12384 12385 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12386 %{ 12387 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12388 ins_cost(INSN_COST); 12389 format %{ "add $dst, $src1, $src2, sxth" %} 12390 12391 ins_encode %{ 12392 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12393 as_Register($src2$$reg), ext::sxth); 12394 %} 12395 ins_pipe(ialu_reg_reg); 12396 %} 12397 12398 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12399 %{ 12400 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12401 ins_cost(INSN_COST); 12402 format %{ "add $dst, $src1, $src2, sxtw" %} 12403 12404 ins_encode %{ 12405 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12406 as_Register($src2$$reg), ext::sxtw); 12407 %} 12408 ins_pipe(ialu_reg_reg); 12409 %} 12410 12411 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12412 %{ 12413 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12414 ins_cost(INSN_COST); 12415 format %{ "add $dst, $src1, $src2, sxtb" %} 12416 12417 ins_encode %{ 12418 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12419 as_Register($src2$$reg), ext::sxtb); 12420 %} 12421 ins_pipe(ialu_reg_reg); 12422 %} 12423 12424 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12425 %{ 12426 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12427 ins_cost(INSN_COST); 12428 format %{ "add $dst, $src1, $src2, uxtb" %} 12429 12430 ins_encode %{ 12431 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12432 as_Register($src2$$reg), ext::uxtb); 12433 %} 12434 ins_pipe(ialu_reg_reg); 12435 %} 12436 12437 12438 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12439 %{ 12440 match(Set dst (AddI src1 (AndI src2 mask))); 12441 ins_cost(INSN_COST); 12442 format %{ "addw $dst, $src1, $src2, uxtb" %} 12443 12444 ins_encode %{ 12445 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12446 as_Register($src2$$reg), ext::uxtb); 12447 %} 12448 ins_pipe(ialu_reg_reg); 12449 %} 12450 12451 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12452 %{ 12453 match(Set dst (AddI src1 (AndI src2 mask))); 12454 ins_cost(INSN_COST); 12455 format %{ "addw $dst, $src1, $src2, uxth" %} 12456 12457 ins_encode %{ 12458 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12459 as_Register($src2$$reg), ext::uxth); 12460 %} 12461 ins_pipe(ialu_reg_reg); 12462 %} 12463 12464 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12465 %{ 12466 match(Set dst (AddL src1 (AndL src2 mask))); 12467 ins_cost(INSN_COST); 12468 format %{ "add $dst, $src1, $src2, uxtb" %} 12469 12470 ins_encode %{ 12471 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12472 as_Register($src2$$reg), ext::uxtb); 12473 %} 12474 ins_pipe(ialu_reg_reg); 12475 %} 12476 12477 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12478 %{ 12479 match(Set dst (AddL src1 (AndL src2 mask))); 12480 ins_cost(INSN_COST); 12481 format %{ "add $dst, $src1, $src2, uxth" %} 12482 12483 ins_encode %{ 12484 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12485 as_Register($src2$$reg), ext::uxth); 12486 %} 12487 ins_pipe(ialu_reg_reg); 12488 %} 12489 12490 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12491 %{ 12492 match(Set dst (AddL src1 (AndL src2 mask))); 12493 ins_cost(INSN_COST); 12494 format %{ "add $dst, $src1, $src2, uxtw" %} 12495 12496 ins_encode %{ 12497 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12498 as_Register($src2$$reg), ext::uxtw); 12499 %} 12500 ins_pipe(ialu_reg_reg); 12501 %} 12502 12503 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12504 %{ 12505 match(Set dst (SubI src1 (AndI src2 mask))); 12506 ins_cost(INSN_COST); 12507 format %{ "subw $dst, $src1, $src2, uxtb" %} 12508 12509 ins_encode %{ 12510 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12511 as_Register($src2$$reg), ext::uxtb); 12512 %} 12513 ins_pipe(ialu_reg_reg); 12514 %} 12515 12516 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12517 %{ 12518 match(Set dst (SubI src1 (AndI src2 mask))); 12519 ins_cost(INSN_COST); 12520 format %{ "subw $dst, $src1, $src2, uxth" %} 12521 12522 ins_encode %{ 12523 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12524 as_Register($src2$$reg), ext::uxth); 12525 %} 12526 ins_pipe(ialu_reg_reg); 12527 %} 12528 12529 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12530 %{ 12531 match(Set dst (SubL src1 (AndL src2 mask))); 12532 ins_cost(INSN_COST); 12533 format %{ "sub $dst, $src1, $src2, uxtb" %} 12534 12535 ins_encode %{ 12536 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12537 as_Register($src2$$reg), ext::uxtb); 12538 %} 12539 ins_pipe(ialu_reg_reg); 12540 %} 12541 12542 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12543 %{ 12544 match(Set dst (SubL src1 (AndL src2 mask))); 12545 ins_cost(INSN_COST); 12546 format %{ "sub $dst, $src1, $src2, uxth" %} 12547 12548 ins_encode %{ 12549 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12550 as_Register($src2$$reg), ext::uxth); 12551 %} 12552 ins_pipe(ialu_reg_reg); 12553 %} 12554 12555 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12556 %{ 12557 match(Set dst (SubL src1 (AndL src2 mask))); 12558 ins_cost(INSN_COST); 12559 format %{ "sub $dst, $src1, $src2, uxtw" %} 12560 12561 ins_encode %{ 12562 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12563 as_Register($src2$$reg), ext::uxtw); 12564 %} 12565 ins_pipe(ialu_reg_reg); 12566 %} 12567 12568 12569 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12570 %{ 12571 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12572 ins_cost(1.9 * INSN_COST); 12573 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12574 12575 ins_encode %{ 12576 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12577 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12578 %} 12579 ins_pipe(ialu_reg_reg_shift); 12580 %} 12581 12582 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12583 %{ 12584 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12585 ins_cost(1.9 * INSN_COST); 12586 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12587 12588 ins_encode %{ 12589 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12590 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12591 %} 12592 ins_pipe(ialu_reg_reg_shift); 12593 %} 12594 12595 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12596 %{ 12597 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12598 ins_cost(1.9 * INSN_COST); 12599 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12600 12601 ins_encode %{ 12602 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12603 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12604 %} 12605 ins_pipe(ialu_reg_reg_shift); 12606 %} 12607 12608 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12609 %{ 12610 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12611 ins_cost(1.9 * INSN_COST); 12612 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12613 12614 ins_encode %{ 12615 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12616 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12617 %} 12618 ins_pipe(ialu_reg_reg_shift); 12619 %} 12620 12621 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12622 %{ 12623 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12624 ins_cost(1.9 * INSN_COST); 12625 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12626 12627 ins_encode %{ 12628 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12629 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12630 %} 12631 ins_pipe(ialu_reg_reg_shift); 12632 %} 12633 12634 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12635 %{ 12636 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12637 ins_cost(1.9 * INSN_COST); 12638 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12639 12640 ins_encode %{ 12641 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12642 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12643 %} 12644 ins_pipe(ialu_reg_reg_shift); 12645 %} 12646 12647 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12648 %{ 12649 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12650 ins_cost(1.9 * INSN_COST); 12651 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12652 12653 ins_encode %{ 12654 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12655 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12656 %} 12657 ins_pipe(ialu_reg_reg_shift); 12658 %} 12659 12660 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12661 %{ 12662 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12663 ins_cost(1.9 * INSN_COST); 12664 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12665 12666 ins_encode %{ 12667 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12668 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12669 %} 12670 ins_pipe(ialu_reg_reg_shift); 12671 %} 12672 12673 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12674 %{ 12675 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12676 ins_cost(1.9 * INSN_COST); 12677 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12678 12679 ins_encode %{ 12680 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12681 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12682 %} 12683 ins_pipe(ialu_reg_reg_shift); 12684 %} 12685 12686 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12687 %{ 12688 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12689 ins_cost(1.9 * INSN_COST); 12690 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12691 12692 ins_encode %{ 12693 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12694 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12695 %} 12696 ins_pipe(ialu_reg_reg_shift); 12697 %} 12698 12699 12700 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12701 %{ 12702 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12703 ins_cost(1.9 * INSN_COST); 12704 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12705 12706 ins_encode %{ 12707 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12708 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12709 %} 12710 ins_pipe(ialu_reg_reg_shift); 12711 %}; 12712 12713 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12714 %{ 12715 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12716 ins_cost(1.9 * INSN_COST); 12717 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12718 12719 ins_encode %{ 12720 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12721 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12722 %} 12723 ins_pipe(ialu_reg_reg_shift); 12724 %}; 12725 12726 12727 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12728 %{ 12729 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12730 ins_cost(1.9 * INSN_COST); 12731 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12732 12733 ins_encode %{ 12734 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12735 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12736 %} 12737 ins_pipe(ialu_reg_reg_shift); 12738 %} 12739 12740 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12741 %{ 12742 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12743 ins_cost(1.9 * INSN_COST); 12744 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12745 12746 ins_encode %{ 12747 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12748 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12749 %} 12750 ins_pipe(ialu_reg_reg_shift); 12751 %} 12752 12753 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12754 %{ 12755 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12756 ins_cost(1.9 * INSN_COST); 12757 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12758 12759 ins_encode %{ 12760 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12761 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12762 %} 12763 ins_pipe(ialu_reg_reg_shift); 12764 %} 12765 12766 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12767 %{ 12768 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12769 ins_cost(1.9 * INSN_COST); 12770 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12771 12772 ins_encode %{ 12773 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12774 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12775 %} 12776 ins_pipe(ialu_reg_reg_shift); 12777 %} 12778 12779 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12780 %{ 12781 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12782 ins_cost(1.9 * INSN_COST); 12783 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12784 12785 ins_encode %{ 12786 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12787 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12788 %} 12789 ins_pipe(ialu_reg_reg_shift); 12790 %} 12791 12792 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12793 %{ 12794 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12795 ins_cost(1.9 * INSN_COST); 12796 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12797 12798 ins_encode %{ 12799 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12800 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12801 %} 12802 ins_pipe(ialu_reg_reg_shift); 12803 %} 12804 12805 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12806 %{ 12807 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12808 ins_cost(1.9 * INSN_COST); 12809 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12810 12811 ins_encode %{ 12812 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12813 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12814 %} 12815 ins_pipe(ialu_reg_reg_shift); 12816 %} 12817 12818 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12819 %{ 12820 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12821 ins_cost(1.9 * INSN_COST); 12822 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12823 12824 ins_encode %{ 12825 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12826 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12827 %} 12828 ins_pipe(ialu_reg_reg_shift); 12829 %} 12830 12831 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12832 %{ 12833 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12834 ins_cost(1.9 * INSN_COST); 12835 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12836 12837 ins_encode %{ 12838 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12839 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12840 %} 12841 ins_pipe(ialu_reg_reg_shift); 12842 %} 12843 12844 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12845 %{ 12846 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12847 ins_cost(1.9 * INSN_COST); 12848 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12849 12850 ins_encode %{ 12851 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12852 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12853 %} 12854 ins_pipe(ialu_reg_reg_shift); 12855 %} 12856 // END This section of the file is automatically generated. Do not edit -------------- 12857 12858 // ============================================================================ 12859 // Floating Point Arithmetic Instructions 12860 12861 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12862 match(Set dst (AddF src1 src2)); 12863 12864 ins_cost(INSN_COST * 5); 12865 format %{ "fadds $dst, $src1, $src2" %} 12866 12867 ins_encode %{ 12868 __ fadds(as_FloatRegister($dst$$reg), 12869 as_FloatRegister($src1$$reg), 12870 as_FloatRegister($src2$$reg)); 12871 %} 12872 12873 ins_pipe(fp_dop_reg_reg_s); 12874 %} 12875 12876 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12877 match(Set dst (AddD src1 src2)); 12878 12879 ins_cost(INSN_COST * 5); 12880 format %{ "faddd $dst, $src1, $src2" %} 12881 12882 ins_encode %{ 12883 __ faddd(as_FloatRegister($dst$$reg), 12884 as_FloatRegister($src1$$reg), 12885 as_FloatRegister($src2$$reg)); 12886 %} 12887 12888 ins_pipe(fp_dop_reg_reg_d); 12889 %} 12890 12891 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12892 match(Set dst (SubF src1 src2)); 12893 12894 ins_cost(INSN_COST * 5); 12895 format %{ "fsubs $dst, $src1, $src2" %} 12896 12897 ins_encode %{ 12898 __ fsubs(as_FloatRegister($dst$$reg), 12899 as_FloatRegister($src1$$reg), 12900 as_FloatRegister($src2$$reg)); 12901 %} 12902 12903 ins_pipe(fp_dop_reg_reg_s); 12904 %} 12905 12906 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12907 match(Set dst (SubD src1 src2)); 12908 12909 ins_cost(INSN_COST * 5); 12910 format %{ "fsubd $dst, $src1, $src2" %} 12911 12912 ins_encode %{ 12913 __ fsubd(as_FloatRegister($dst$$reg), 12914 as_FloatRegister($src1$$reg), 12915 as_FloatRegister($src2$$reg)); 12916 %} 12917 12918 ins_pipe(fp_dop_reg_reg_d); 12919 %} 12920 12921 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12922 match(Set dst (MulF src1 src2)); 12923 12924 ins_cost(INSN_COST * 6); 12925 format %{ "fmuls $dst, $src1, $src2" %} 12926 12927 ins_encode %{ 12928 __ fmuls(as_FloatRegister($dst$$reg), 12929 as_FloatRegister($src1$$reg), 12930 as_FloatRegister($src2$$reg)); 12931 %} 12932 12933 ins_pipe(fp_dop_reg_reg_s); 12934 %} 12935 12936 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12937 match(Set dst (MulD src1 src2)); 12938 12939 ins_cost(INSN_COST * 6); 12940 format %{ "fmuld $dst, $src1, $src2" %} 12941 12942 ins_encode %{ 12943 __ fmuld(as_FloatRegister($dst$$reg), 12944 as_FloatRegister($src1$$reg), 12945 as_FloatRegister($src2$$reg)); 12946 %} 12947 12948 ins_pipe(fp_dop_reg_reg_d); 12949 %} 12950 12951 // src1 * src2 + src3 12952 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12953 predicate(UseFMA); 12954 match(Set dst (FmaF src3 (Binary src1 src2))); 12955 12956 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12957 12958 ins_encode %{ 12959 __ fmadds(as_FloatRegister($dst$$reg), 12960 as_FloatRegister($src1$$reg), 12961 as_FloatRegister($src2$$reg), 12962 as_FloatRegister($src3$$reg)); 12963 %} 12964 12965 ins_pipe(pipe_class_default); 12966 %} 12967 12968 // src1 * src2 + src3 12969 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12970 predicate(UseFMA); 12971 match(Set dst (FmaD src3 (Binary src1 src2))); 12972 12973 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12974 12975 ins_encode %{ 12976 __ fmaddd(as_FloatRegister($dst$$reg), 12977 as_FloatRegister($src1$$reg), 12978 as_FloatRegister($src2$$reg), 12979 as_FloatRegister($src3$$reg)); 12980 %} 12981 12982 ins_pipe(pipe_class_default); 12983 %} 12984 12985 // -src1 * src2 + src3 12986 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12987 predicate(UseFMA); 12988 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12989 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12990 12991 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12992 12993 ins_encode %{ 12994 __ fmsubs(as_FloatRegister($dst$$reg), 12995 as_FloatRegister($src1$$reg), 12996 as_FloatRegister($src2$$reg), 12997 as_FloatRegister($src3$$reg)); 12998 %} 12999 13000 ins_pipe(pipe_class_default); 13001 %} 13002 13003 // -src1 * src2 + src3 13004 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13005 predicate(UseFMA); 13006 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 13007 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 13008 13009 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 13010 13011 ins_encode %{ 13012 __ fmsubd(as_FloatRegister($dst$$reg), 13013 as_FloatRegister($src1$$reg), 13014 as_FloatRegister($src2$$reg), 13015 as_FloatRegister($src3$$reg)); 13016 %} 13017 13018 ins_pipe(pipe_class_default); 13019 %} 13020 13021 // -src1 * src2 - src3 13022 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13023 predicate(UseFMA); 13024 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 13025 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13026 13027 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13028 13029 ins_encode %{ 13030 __ fnmadds(as_FloatRegister($dst$$reg), 13031 as_FloatRegister($src1$$reg), 13032 as_FloatRegister($src2$$reg), 13033 as_FloatRegister($src3$$reg)); 13034 %} 13035 13036 ins_pipe(pipe_class_default); 13037 %} 13038 13039 // -src1 * src2 - src3 13040 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13041 predicate(UseFMA); 13042 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13043 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13044 13045 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13046 13047 ins_encode %{ 13048 __ fnmaddd(as_FloatRegister($dst$$reg), 13049 as_FloatRegister($src1$$reg), 13050 as_FloatRegister($src2$$reg), 13051 as_FloatRegister($src3$$reg)); 13052 %} 13053 13054 ins_pipe(pipe_class_default); 13055 %} 13056 13057 // src1 * src2 - src3 13058 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13059 predicate(UseFMA); 13060 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13061 13062 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13063 13064 ins_encode %{ 13065 __ fnmsubs(as_FloatRegister($dst$$reg), 13066 as_FloatRegister($src1$$reg), 13067 as_FloatRegister($src2$$reg), 13068 as_FloatRegister($src3$$reg)); 13069 %} 13070 13071 ins_pipe(pipe_class_default); 13072 %} 13073 13074 // src1 * src2 - src3 13075 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13076 predicate(UseFMA); 13077 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13078 13079 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13080 13081 ins_encode %{ 13082 // n.b. insn name should be fnmsubd 13083 __ fnmsub(as_FloatRegister($dst$$reg), 13084 as_FloatRegister($src1$$reg), 13085 as_FloatRegister($src2$$reg), 13086 as_FloatRegister($src3$$reg)); 13087 %} 13088 13089 ins_pipe(pipe_class_default); 13090 %} 13091 13092 13093 // Math.max(FF)F 13094 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13095 match(Set dst (MaxF src1 src2)); 13096 13097 format %{ "fmaxs $dst, $src1, $src2" %} 13098 ins_encode %{ 13099 __ fmaxs(as_FloatRegister($dst$$reg), 13100 as_FloatRegister($src1$$reg), 13101 as_FloatRegister($src2$$reg)); 13102 %} 13103 13104 ins_pipe(fp_dop_reg_reg_s); 13105 %} 13106 13107 // Math.min(FF)F 13108 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13109 match(Set dst (MinF src1 src2)); 13110 13111 format %{ "fmins $dst, $src1, $src2" %} 13112 ins_encode %{ 13113 __ fmins(as_FloatRegister($dst$$reg), 13114 as_FloatRegister($src1$$reg), 13115 as_FloatRegister($src2$$reg)); 13116 %} 13117 13118 ins_pipe(fp_dop_reg_reg_s); 13119 %} 13120 13121 // Math.max(DD)D 13122 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13123 match(Set dst (MaxD src1 src2)); 13124 13125 format %{ "fmaxd $dst, $src1, $src2" %} 13126 ins_encode %{ 13127 __ fmaxd(as_FloatRegister($dst$$reg), 13128 as_FloatRegister($src1$$reg), 13129 as_FloatRegister($src2$$reg)); 13130 %} 13131 13132 ins_pipe(fp_dop_reg_reg_d); 13133 %} 13134 13135 // Math.min(DD)D 13136 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13137 match(Set dst (MinD src1 src2)); 13138 13139 format %{ "fmind $dst, $src1, $src2" %} 13140 ins_encode %{ 13141 __ fmind(as_FloatRegister($dst$$reg), 13142 as_FloatRegister($src1$$reg), 13143 as_FloatRegister($src2$$reg)); 13144 %} 13145 13146 ins_pipe(fp_dop_reg_reg_d); 13147 %} 13148 13149 13150 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13151 match(Set dst (DivF src1 src2)); 13152 13153 ins_cost(INSN_COST * 18); 13154 format %{ "fdivs $dst, $src1, $src2" %} 13155 13156 ins_encode %{ 13157 __ fdivs(as_FloatRegister($dst$$reg), 13158 as_FloatRegister($src1$$reg), 13159 as_FloatRegister($src2$$reg)); 13160 %} 13161 13162 ins_pipe(fp_div_s); 13163 %} 13164 13165 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13166 match(Set dst (DivD src1 src2)); 13167 13168 ins_cost(INSN_COST * 32); 13169 format %{ "fdivd $dst, $src1, $src2" %} 13170 13171 ins_encode %{ 13172 __ fdivd(as_FloatRegister($dst$$reg), 13173 as_FloatRegister($src1$$reg), 13174 as_FloatRegister($src2$$reg)); 13175 %} 13176 13177 ins_pipe(fp_div_d); 13178 %} 13179 13180 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13181 match(Set dst (NegF src)); 13182 13183 ins_cost(INSN_COST * 3); 13184 format %{ "fneg $dst, $src" %} 13185 13186 ins_encode %{ 13187 __ fnegs(as_FloatRegister($dst$$reg), 13188 as_FloatRegister($src$$reg)); 13189 %} 13190 13191 ins_pipe(fp_uop_s); 13192 %} 13193 13194 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13195 match(Set dst (NegD src)); 13196 13197 ins_cost(INSN_COST * 3); 13198 format %{ "fnegd $dst, $src" %} 13199 13200 ins_encode %{ 13201 __ fnegd(as_FloatRegister($dst$$reg), 13202 as_FloatRegister($src$$reg)); 13203 %} 13204 13205 ins_pipe(fp_uop_d); 13206 %} 13207 13208 instruct absF_reg(vRegF dst, vRegF src) %{ 13209 match(Set dst (AbsF src)); 13210 13211 ins_cost(INSN_COST * 3); 13212 format %{ "fabss $dst, $src" %} 13213 ins_encode %{ 13214 __ fabss(as_FloatRegister($dst$$reg), 13215 as_FloatRegister($src$$reg)); 13216 %} 13217 13218 ins_pipe(fp_uop_s); 13219 %} 13220 13221 instruct absD_reg(vRegD dst, vRegD src) %{ 13222 match(Set dst (AbsD src)); 13223 13224 ins_cost(INSN_COST * 3); 13225 format %{ "fabsd $dst, $src" %} 13226 ins_encode %{ 13227 __ fabsd(as_FloatRegister($dst$$reg), 13228 as_FloatRegister($src$$reg)); 13229 %} 13230 13231 ins_pipe(fp_uop_d); 13232 %} 13233 13234 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13235 match(Set dst (SqrtD src)); 13236 13237 ins_cost(INSN_COST * 50); 13238 format %{ "fsqrtd $dst, $src" %} 13239 ins_encode %{ 13240 __ fsqrtd(as_FloatRegister($dst$$reg), 13241 as_FloatRegister($src$$reg)); 13242 %} 13243 13244 ins_pipe(fp_div_s); 13245 %} 13246 13247 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13248 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 13249 13250 ins_cost(INSN_COST * 50); 13251 format %{ "fsqrts $dst, $src" %} 13252 ins_encode %{ 13253 __ fsqrts(as_FloatRegister($dst$$reg), 13254 as_FloatRegister($src$$reg)); 13255 %} 13256 13257 ins_pipe(fp_div_d); 13258 %} 13259 13260 // Math.rint, floor, ceil 13261 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 13262 match(Set dst (RoundDoubleMode src rmode)); 13263 format %{ "frint $dst, $src, $rmode" %} 13264 ins_encode %{ 13265 switch ($rmode$$constant) { 13266 case RoundDoubleModeNode::rmode_rint: 13267 __ frintnd(as_FloatRegister($dst$$reg), 13268 as_FloatRegister($src$$reg)); 13269 break; 13270 case RoundDoubleModeNode::rmode_floor: 13271 __ frintmd(as_FloatRegister($dst$$reg), 13272 as_FloatRegister($src$$reg)); 13273 break; 13274 case RoundDoubleModeNode::rmode_ceil: 13275 __ frintpd(as_FloatRegister($dst$$reg), 13276 as_FloatRegister($src$$reg)); 13277 break; 13278 } 13279 %} 13280 ins_pipe(fp_uop_d); 13281 %} 13282 13283 // ============================================================================ 13284 // Logical Instructions 13285 13286 // Integer Logical Instructions 13287 13288 // And Instructions 13289 13290 13291 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13292 match(Set dst (AndI src1 src2)); 13293 13294 format %{ "andw $dst, $src1, $src2\t# int" %} 13295 13296 ins_cost(INSN_COST); 13297 ins_encode %{ 13298 __ andw(as_Register($dst$$reg), 13299 as_Register($src1$$reg), 13300 as_Register($src2$$reg)); 13301 %} 13302 13303 ins_pipe(ialu_reg_reg); 13304 %} 13305 13306 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13307 match(Set dst (AndI src1 src2)); 13308 13309 format %{ "andsw $dst, $src1, $src2\t# int" %} 13310 13311 ins_cost(INSN_COST); 13312 ins_encode %{ 13313 __ andw(as_Register($dst$$reg), 13314 as_Register($src1$$reg), 13315 (unsigned long)($src2$$constant)); 13316 %} 13317 13318 ins_pipe(ialu_reg_imm); 13319 %} 13320 13321 // Or Instructions 13322 13323 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13324 match(Set dst (OrI src1 src2)); 13325 13326 format %{ "orrw $dst, $src1, $src2\t# int" %} 13327 13328 ins_cost(INSN_COST); 13329 ins_encode %{ 13330 __ orrw(as_Register($dst$$reg), 13331 as_Register($src1$$reg), 13332 as_Register($src2$$reg)); 13333 %} 13334 13335 ins_pipe(ialu_reg_reg); 13336 %} 13337 13338 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13339 match(Set dst (OrI src1 src2)); 13340 13341 format %{ "orrw $dst, $src1, $src2\t# int" %} 13342 13343 ins_cost(INSN_COST); 13344 ins_encode %{ 13345 __ orrw(as_Register($dst$$reg), 13346 as_Register($src1$$reg), 13347 (unsigned long)($src2$$constant)); 13348 %} 13349 13350 ins_pipe(ialu_reg_imm); 13351 %} 13352 13353 // Xor Instructions 13354 13355 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13356 match(Set dst (XorI src1 src2)); 13357 13358 format %{ "eorw $dst, $src1, $src2\t# int" %} 13359 13360 ins_cost(INSN_COST); 13361 ins_encode %{ 13362 __ eorw(as_Register($dst$$reg), 13363 as_Register($src1$$reg), 13364 as_Register($src2$$reg)); 13365 %} 13366 13367 ins_pipe(ialu_reg_reg); 13368 %} 13369 13370 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13371 match(Set dst (XorI src1 src2)); 13372 13373 format %{ "eorw $dst, $src1, $src2\t# int" %} 13374 13375 ins_cost(INSN_COST); 13376 ins_encode %{ 13377 __ eorw(as_Register($dst$$reg), 13378 as_Register($src1$$reg), 13379 (unsigned long)($src2$$constant)); 13380 %} 13381 13382 ins_pipe(ialu_reg_imm); 13383 %} 13384 13385 // Long Logical Instructions 13386 // TODO 13387 13388 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13389 match(Set dst (AndL src1 src2)); 13390 13391 format %{ "and $dst, $src1, $src2\t# int" %} 13392 13393 ins_cost(INSN_COST); 13394 ins_encode %{ 13395 __ andr(as_Register($dst$$reg), 13396 as_Register($src1$$reg), 13397 as_Register($src2$$reg)); 13398 %} 13399 13400 ins_pipe(ialu_reg_reg); 13401 %} 13402 13403 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13404 match(Set dst (AndL src1 src2)); 13405 13406 format %{ "and $dst, $src1, $src2\t# int" %} 13407 13408 ins_cost(INSN_COST); 13409 ins_encode %{ 13410 __ andr(as_Register($dst$$reg), 13411 as_Register($src1$$reg), 13412 (unsigned long)($src2$$constant)); 13413 %} 13414 13415 ins_pipe(ialu_reg_imm); 13416 %} 13417 13418 // Or Instructions 13419 13420 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13421 match(Set dst (OrL src1 src2)); 13422 13423 format %{ "orr $dst, $src1, $src2\t# int" %} 13424 13425 ins_cost(INSN_COST); 13426 ins_encode %{ 13427 __ orr(as_Register($dst$$reg), 13428 as_Register($src1$$reg), 13429 as_Register($src2$$reg)); 13430 %} 13431 13432 ins_pipe(ialu_reg_reg); 13433 %} 13434 13435 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13436 match(Set dst (OrL src1 src2)); 13437 13438 format %{ "orr $dst, $src1, $src2\t# int" %} 13439 13440 ins_cost(INSN_COST); 13441 ins_encode %{ 13442 __ orr(as_Register($dst$$reg), 13443 as_Register($src1$$reg), 13444 (unsigned long)($src2$$constant)); 13445 %} 13446 13447 ins_pipe(ialu_reg_imm); 13448 %} 13449 13450 // Xor Instructions 13451 13452 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13453 match(Set dst (XorL src1 src2)); 13454 13455 format %{ "eor $dst, $src1, $src2\t# int" %} 13456 13457 ins_cost(INSN_COST); 13458 ins_encode %{ 13459 __ eor(as_Register($dst$$reg), 13460 as_Register($src1$$reg), 13461 as_Register($src2$$reg)); 13462 %} 13463 13464 ins_pipe(ialu_reg_reg); 13465 %} 13466 13467 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13468 match(Set dst (XorL src1 src2)); 13469 13470 ins_cost(INSN_COST); 13471 format %{ "eor $dst, $src1, $src2\t# int" %} 13472 13473 ins_encode %{ 13474 __ eor(as_Register($dst$$reg), 13475 as_Register($src1$$reg), 13476 (unsigned long)($src2$$constant)); 13477 %} 13478 13479 ins_pipe(ialu_reg_imm); 13480 %} 13481 13482 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13483 %{ 13484 match(Set dst (ConvI2L src)); 13485 13486 ins_cost(INSN_COST); 13487 format %{ "sxtw $dst, $src\t# i2l" %} 13488 ins_encode %{ 13489 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13490 %} 13491 ins_pipe(ialu_reg_shift); 13492 %} 13493 13494 // this pattern occurs in bigmath arithmetic 13495 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13496 %{ 13497 match(Set dst (AndL (ConvI2L src) mask)); 13498 13499 ins_cost(INSN_COST); 13500 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13501 ins_encode %{ 13502 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13503 %} 13504 13505 ins_pipe(ialu_reg_shift); 13506 %} 13507 13508 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13509 match(Set dst (ConvL2I src)); 13510 13511 ins_cost(INSN_COST); 13512 format %{ "movw $dst, $src \t// l2i" %} 13513 13514 ins_encode %{ 13515 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13516 %} 13517 13518 ins_pipe(ialu_reg); 13519 %} 13520 13521 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13522 %{ 13523 match(Set dst (Conv2B src)); 13524 effect(KILL cr); 13525 13526 format %{ 13527 "cmpw $src, zr\n\t" 13528 "cset $dst, ne" 13529 %} 13530 13531 ins_encode %{ 13532 __ cmpw(as_Register($src$$reg), zr); 13533 __ cset(as_Register($dst$$reg), Assembler::NE); 13534 %} 13535 13536 ins_pipe(ialu_reg); 13537 %} 13538 13539 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13540 %{ 13541 match(Set dst (Conv2B src)); 13542 effect(KILL cr); 13543 13544 format %{ 13545 "cmp $src, zr\n\t" 13546 "cset $dst, ne" 13547 %} 13548 13549 ins_encode %{ 13550 __ cmp(as_Register($src$$reg), zr); 13551 __ cset(as_Register($dst$$reg), Assembler::NE); 13552 %} 13553 13554 ins_pipe(ialu_reg); 13555 %} 13556 13557 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13558 match(Set dst (ConvD2F src)); 13559 13560 ins_cost(INSN_COST * 5); 13561 format %{ "fcvtd $dst, $src \t// d2f" %} 13562 13563 ins_encode %{ 13564 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13565 %} 13566 13567 ins_pipe(fp_d2f); 13568 %} 13569 13570 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13571 match(Set dst (ConvF2D src)); 13572 13573 ins_cost(INSN_COST * 5); 13574 format %{ "fcvts $dst, $src \t// f2d" %} 13575 13576 ins_encode %{ 13577 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13578 %} 13579 13580 ins_pipe(fp_f2d); 13581 %} 13582 13583 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13584 match(Set dst (ConvF2I src)); 13585 13586 ins_cost(INSN_COST * 5); 13587 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13588 13589 ins_encode %{ 13590 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13591 %} 13592 13593 ins_pipe(fp_f2i); 13594 %} 13595 13596 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13597 match(Set dst (ConvF2L src)); 13598 13599 ins_cost(INSN_COST * 5); 13600 format %{ "fcvtzs $dst, $src \t// f2l" %} 13601 13602 ins_encode %{ 13603 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13604 %} 13605 13606 ins_pipe(fp_f2l); 13607 %} 13608 13609 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13610 match(Set dst (ConvI2F src)); 13611 13612 ins_cost(INSN_COST * 5); 13613 format %{ "scvtfws $dst, $src \t// i2f" %} 13614 13615 ins_encode %{ 13616 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13617 %} 13618 13619 ins_pipe(fp_i2f); 13620 %} 13621 13622 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13623 match(Set dst (ConvL2F src)); 13624 13625 ins_cost(INSN_COST * 5); 13626 format %{ "scvtfs $dst, $src \t// l2f" %} 13627 13628 ins_encode %{ 13629 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13630 %} 13631 13632 ins_pipe(fp_l2f); 13633 %} 13634 13635 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13636 match(Set dst (ConvD2I src)); 13637 13638 ins_cost(INSN_COST * 5); 13639 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13640 13641 ins_encode %{ 13642 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13643 %} 13644 13645 ins_pipe(fp_d2i); 13646 %} 13647 13648 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13649 match(Set dst (ConvD2L src)); 13650 13651 ins_cost(INSN_COST * 5); 13652 format %{ "fcvtzd $dst, $src \t// d2l" %} 13653 13654 ins_encode %{ 13655 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13656 %} 13657 13658 ins_pipe(fp_d2l); 13659 %} 13660 13661 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13662 match(Set dst (ConvI2D src)); 13663 13664 ins_cost(INSN_COST * 5); 13665 format %{ "scvtfwd $dst, $src \t// i2d" %} 13666 13667 ins_encode %{ 13668 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13669 %} 13670 13671 ins_pipe(fp_i2d); 13672 %} 13673 13674 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13675 match(Set dst (ConvL2D src)); 13676 13677 ins_cost(INSN_COST * 5); 13678 format %{ "scvtfd $dst, $src \t// l2d" %} 13679 13680 ins_encode %{ 13681 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13682 %} 13683 13684 ins_pipe(fp_l2d); 13685 %} 13686 13687 // stack <-> reg and reg <-> reg shuffles with no conversion 13688 13689 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13690 13691 match(Set dst (MoveF2I src)); 13692 13693 effect(DEF dst, USE src); 13694 13695 ins_cost(4 * INSN_COST); 13696 13697 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13698 13699 ins_encode %{ 13700 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13701 %} 13702 13703 ins_pipe(iload_reg_reg); 13704 13705 %} 13706 13707 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13708 13709 match(Set dst (MoveI2F src)); 13710 13711 effect(DEF dst, USE src); 13712 13713 ins_cost(4 * INSN_COST); 13714 13715 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13716 13717 ins_encode %{ 13718 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13719 %} 13720 13721 ins_pipe(pipe_class_memory); 13722 13723 %} 13724 13725 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13726 13727 match(Set dst (MoveD2L src)); 13728 13729 effect(DEF dst, USE src); 13730 13731 ins_cost(4 * INSN_COST); 13732 13733 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13734 13735 ins_encode %{ 13736 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13737 %} 13738 13739 ins_pipe(iload_reg_reg); 13740 13741 %} 13742 13743 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13744 13745 match(Set dst (MoveL2D src)); 13746 13747 effect(DEF dst, USE src); 13748 13749 ins_cost(4 * INSN_COST); 13750 13751 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13752 13753 ins_encode %{ 13754 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13755 %} 13756 13757 ins_pipe(pipe_class_memory); 13758 13759 %} 13760 13761 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13762 13763 match(Set dst (MoveF2I src)); 13764 13765 effect(DEF dst, USE src); 13766 13767 ins_cost(INSN_COST); 13768 13769 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13770 13771 ins_encode %{ 13772 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13773 %} 13774 13775 ins_pipe(pipe_class_memory); 13776 13777 %} 13778 13779 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13780 13781 match(Set dst (MoveI2F src)); 13782 13783 effect(DEF dst, USE src); 13784 13785 ins_cost(INSN_COST); 13786 13787 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13788 13789 ins_encode %{ 13790 __ strw($src$$Register, Address(sp, $dst$$disp)); 13791 %} 13792 13793 ins_pipe(istore_reg_reg); 13794 13795 %} 13796 13797 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13798 13799 match(Set dst (MoveD2L src)); 13800 13801 effect(DEF dst, USE src); 13802 13803 ins_cost(INSN_COST); 13804 13805 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13806 13807 ins_encode %{ 13808 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13809 %} 13810 13811 ins_pipe(pipe_class_memory); 13812 13813 %} 13814 13815 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13816 13817 match(Set dst (MoveL2D src)); 13818 13819 effect(DEF dst, USE src); 13820 13821 ins_cost(INSN_COST); 13822 13823 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13824 13825 ins_encode %{ 13826 __ str($src$$Register, Address(sp, $dst$$disp)); 13827 %} 13828 13829 ins_pipe(istore_reg_reg); 13830 13831 %} 13832 13833 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13834 13835 match(Set dst (MoveF2I src)); 13836 13837 effect(DEF dst, USE src); 13838 13839 ins_cost(INSN_COST); 13840 13841 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13842 13843 ins_encode %{ 13844 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13845 %} 13846 13847 ins_pipe(fp_f2i); 13848 13849 %} 13850 13851 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13852 13853 match(Set dst (MoveI2F src)); 13854 13855 effect(DEF dst, USE src); 13856 13857 ins_cost(INSN_COST); 13858 13859 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13860 13861 ins_encode %{ 13862 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13863 %} 13864 13865 ins_pipe(fp_i2f); 13866 13867 %} 13868 13869 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13870 13871 match(Set dst (MoveD2L src)); 13872 13873 effect(DEF dst, USE src); 13874 13875 ins_cost(INSN_COST); 13876 13877 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13878 13879 ins_encode %{ 13880 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13881 %} 13882 13883 ins_pipe(fp_d2l); 13884 13885 %} 13886 13887 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13888 13889 match(Set dst (MoveL2D src)); 13890 13891 effect(DEF dst, USE src); 13892 13893 ins_cost(INSN_COST); 13894 13895 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13896 13897 ins_encode %{ 13898 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13899 %} 13900 13901 ins_pipe(fp_l2d); 13902 13903 %} 13904 13905 // ============================================================================ 13906 // clearing of an array 13907 13908 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13909 %{ 13910 match(Set dummy (ClearArray cnt base)); 13911 effect(USE_KILL cnt, USE_KILL base); 13912 13913 ins_cost(4 * INSN_COST); 13914 format %{ "ClearArray $cnt, $base" %} 13915 13916 ins_encode %{ 13917 __ zero_words($base$$Register, $cnt$$Register); 13918 %} 13919 13920 ins_pipe(pipe_class_memory); 13921 %} 13922 13923 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13924 %{ 13925 predicate((u_int64_t)n->in(2)->get_long() 13926 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13927 match(Set dummy (ClearArray cnt base)); 13928 effect(USE_KILL base); 13929 13930 ins_cost(4 * INSN_COST); 13931 format %{ "ClearArray $cnt, $base" %} 13932 13933 ins_encode %{ 13934 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13935 %} 13936 13937 ins_pipe(pipe_class_memory); 13938 %} 13939 13940 // ============================================================================ 13941 // Overflow Math Instructions 13942 13943 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13944 %{ 13945 match(Set cr (OverflowAddI op1 op2)); 13946 13947 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13948 ins_cost(INSN_COST); 13949 ins_encode %{ 13950 __ cmnw($op1$$Register, $op2$$Register); 13951 %} 13952 13953 ins_pipe(icmp_reg_reg); 13954 %} 13955 13956 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13957 %{ 13958 match(Set cr (OverflowAddI op1 op2)); 13959 13960 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13961 ins_cost(INSN_COST); 13962 ins_encode %{ 13963 __ cmnw($op1$$Register, $op2$$constant); 13964 %} 13965 13966 ins_pipe(icmp_reg_imm); 13967 %} 13968 13969 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13970 %{ 13971 match(Set cr (OverflowAddL op1 op2)); 13972 13973 format %{ "cmn $op1, $op2\t# overflow check long" %} 13974 ins_cost(INSN_COST); 13975 ins_encode %{ 13976 __ cmn($op1$$Register, $op2$$Register); 13977 %} 13978 13979 ins_pipe(icmp_reg_reg); 13980 %} 13981 13982 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13983 %{ 13984 match(Set cr (OverflowAddL op1 op2)); 13985 13986 format %{ "cmn $op1, $op2\t# overflow check long" %} 13987 ins_cost(INSN_COST); 13988 ins_encode %{ 13989 __ cmn($op1$$Register, $op2$$constant); 13990 %} 13991 13992 ins_pipe(icmp_reg_imm); 13993 %} 13994 13995 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13996 %{ 13997 match(Set cr (OverflowSubI op1 op2)); 13998 13999 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14000 ins_cost(INSN_COST); 14001 ins_encode %{ 14002 __ cmpw($op1$$Register, $op2$$Register); 14003 %} 14004 14005 ins_pipe(icmp_reg_reg); 14006 %} 14007 14008 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14009 %{ 14010 match(Set cr (OverflowSubI op1 op2)); 14011 14012 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14013 ins_cost(INSN_COST); 14014 ins_encode %{ 14015 __ cmpw($op1$$Register, $op2$$constant); 14016 %} 14017 14018 ins_pipe(icmp_reg_imm); 14019 %} 14020 14021 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14022 %{ 14023 match(Set cr (OverflowSubL op1 op2)); 14024 14025 format %{ "cmp $op1, $op2\t# overflow check long" %} 14026 ins_cost(INSN_COST); 14027 ins_encode %{ 14028 __ cmp($op1$$Register, $op2$$Register); 14029 %} 14030 14031 ins_pipe(icmp_reg_reg); 14032 %} 14033 14034 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14035 %{ 14036 match(Set cr (OverflowSubL op1 op2)); 14037 14038 format %{ "cmp $op1, $op2\t# overflow check long" %} 14039 ins_cost(INSN_COST); 14040 ins_encode %{ 14041 __ subs(zr, $op1$$Register, $op2$$constant); 14042 %} 14043 14044 ins_pipe(icmp_reg_imm); 14045 %} 14046 14047 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14048 %{ 14049 match(Set cr (OverflowSubI zero op1)); 14050 14051 format %{ "cmpw zr, $op1\t# overflow check int" %} 14052 ins_cost(INSN_COST); 14053 ins_encode %{ 14054 __ cmpw(zr, $op1$$Register); 14055 %} 14056 14057 ins_pipe(icmp_reg_imm); 14058 %} 14059 14060 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14061 %{ 14062 match(Set cr (OverflowSubL zero op1)); 14063 14064 format %{ "cmp zr, $op1\t# overflow check long" %} 14065 ins_cost(INSN_COST); 14066 ins_encode %{ 14067 __ cmp(zr, $op1$$Register); 14068 %} 14069 14070 ins_pipe(icmp_reg_imm); 14071 %} 14072 14073 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14074 %{ 14075 match(Set cr (OverflowMulI op1 op2)); 14076 14077 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14078 "cmp rscratch1, rscratch1, sxtw\n\t" 14079 "movw rscratch1, #0x80000000\n\t" 14080 "cselw rscratch1, rscratch1, zr, NE\n\t" 14081 "cmpw rscratch1, #1" %} 14082 ins_cost(5 * INSN_COST); 14083 ins_encode %{ 14084 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14085 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14086 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14087 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14088 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14089 %} 14090 14091 ins_pipe(pipe_slow); 14092 %} 14093 14094 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14095 %{ 14096 match(If cmp (OverflowMulI op1 op2)); 14097 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14098 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14099 effect(USE labl, KILL cr); 14100 14101 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14102 "cmp rscratch1, rscratch1, sxtw\n\t" 14103 "b$cmp $labl" %} 14104 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14105 ins_encode %{ 14106 Label* L = $labl$$label; 14107 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14108 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14109 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14110 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14111 %} 14112 14113 ins_pipe(pipe_serial); 14114 %} 14115 14116 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14117 %{ 14118 match(Set cr (OverflowMulL op1 op2)); 14119 14120 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14121 "smulh rscratch2, $op1, $op2\n\t" 14122 "cmp rscratch2, rscratch1, ASR #63\n\t" 14123 "movw rscratch1, #0x80000000\n\t" 14124 "cselw rscratch1, rscratch1, zr, NE\n\t" 14125 "cmpw rscratch1, #1" %} 14126 ins_cost(6 * INSN_COST); 14127 ins_encode %{ 14128 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14129 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14130 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14131 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14132 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14133 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14134 %} 14135 14136 ins_pipe(pipe_slow); 14137 %} 14138 14139 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14140 %{ 14141 match(If cmp (OverflowMulL op1 op2)); 14142 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14143 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14144 effect(USE labl, KILL cr); 14145 14146 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14147 "smulh rscratch2, $op1, $op2\n\t" 14148 "cmp rscratch2, rscratch1, ASR #63\n\t" 14149 "b$cmp $labl" %} 14150 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14151 ins_encode %{ 14152 Label* L = $labl$$label; 14153 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14154 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14155 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14156 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14157 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14158 %} 14159 14160 ins_pipe(pipe_serial); 14161 %} 14162 14163 // ============================================================================ 14164 // Compare Instructions 14165 14166 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14167 %{ 14168 match(Set cr (CmpI op1 op2)); 14169 14170 effect(DEF cr, USE op1, USE op2); 14171 14172 ins_cost(INSN_COST); 14173 format %{ "cmpw $op1, $op2" %} 14174 14175 ins_encode(aarch64_enc_cmpw(op1, op2)); 14176 14177 ins_pipe(icmp_reg_reg); 14178 %} 14179 14180 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14181 %{ 14182 match(Set cr (CmpI op1 zero)); 14183 14184 effect(DEF cr, USE op1); 14185 14186 ins_cost(INSN_COST); 14187 format %{ "cmpw $op1, 0" %} 14188 14189 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14190 14191 ins_pipe(icmp_reg_imm); 14192 %} 14193 14194 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14195 %{ 14196 match(Set cr (CmpI op1 op2)); 14197 14198 effect(DEF cr, USE op1); 14199 14200 ins_cost(INSN_COST); 14201 format %{ "cmpw $op1, $op2" %} 14202 14203 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14204 14205 ins_pipe(icmp_reg_imm); 14206 %} 14207 14208 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14209 %{ 14210 match(Set cr (CmpI op1 op2)); 14211 14212 effect(DEF cr, USE op1); 14213 14214 ins_cost(INSN_COST * 2); 14215 format %{ "cmpw $op1, $op2" %} 14216 14217 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14218 14219 ins_pipe(icmp_reg_imm); 14220 %} 14221 14222 // Unsigned compare Instructions; really, same as signed compare 14223 // except it should only be used to feed an If or a CMovI which takes a 14224 // cmpOpU. 14225 14226 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14227 %{ 14228 match(Set cr (CmpU op1 op2)); 14229 14230 effect(DEF cr, USE op1, USE op2); 14231 14232 ins_cost(INSN_COST); 14233 format %{ "cmpw $op1, $op2\t# unsigned" %} 14234 14235 ins_encode(aarch64_enc_cmpw(op1, op2)); 14236 14237 ins_pipe(icmp_reg_reg); 14238 %} 14239 14240 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14241 %{ 14242 match(Set cr (CmpU op1 zero)); 14243 14244 effect(DEF cr, USE op1); 14245 14246 ins_cost(INSN_COST); 14247 format %{ "cmpw $op1, #0\t# unsigned" %} 14248 14249 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14250 14251 ins_pipe(icmp_reg_imm); 14252 %} 14253 14254 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14255 %{ 14256 match(Set cr (CmpU op1 op2)); 14257 14258 effect(DEF cr, USE op1); 14259 14260 ins_cost(INSN_COST); 14261 format %{ "cmpw $op1, $op2\t# unsigned" %} 14262 14263 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14264 14265 ins_pipe(icmp_reg_imm); 14266 %} 14267 14268 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14269 %{ 14270 match(Set cr (CmpU op1 op2)); 14271 14272 effect(DEF cr, USE op1); 14273 14274 ins_cost(INSN_COST * 2); 14275 format %{ "cmpw $op1, $op2\t# unsigned" %} 14276 14277 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14278 14279 ins_pipe(icmp_reg_imm); 14280 %} 14281 14282 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14283 %{ 14284 match(Set cr (CmpL op1 op2)); 14285 14286 effect(DEF cr, USE op1, USE op2); 14287 14288 ins_cost(INSN_COST); 14289 format %{ "cmp $op1, $op2" %} 14290 14291 ins_encode(aarch64_enc_cmp(op1, op2)); 14292 14293 ins_pipe(icmp_reg_reg); 14294 %} 14295 14296 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14297 %{ 14298 match(Set cr (CmpL op1 zero)); 14299 14300 effect(DEF cr, USE op1); 14301 14302 ins_cost(INSN_COST); 14303 format %{ "tst $op1" %} 14304 14305 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14306 14307 ins_pipe(icmp_reg_imm); 14308 %} 14309 14310 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14311 %{ 14312 match(Set cr (CmpL op1 op2)); 14313 14314 effect(DEF cr, USE op1); 14315 14316 ins_cost(INSN_COST); 14317 format %{ "cmp $op1, $op2" %} 14318 14319 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14320 14321 ins_pipe(icmp_reg_imm); 14322 %} 14323 14324 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14325 %{ 14326 match(Set cr (CmpL op1 op2)); 14327 14328 effect(DEF cr, USE op1); 14329 14330 ins_cost(INSN_COST * 2); 14331 format %{ "cmp $op1, $op2" %} 14332 14333 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14334 14335 ins_pipe(icmp_reg_imm); 14336 %} 14337 14338 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14339 %{ 14340 match(Set cr (CmpUL op1 op2)); 14341 14342 effect(DEF cr, USE op1, USE op2); 14343 14344 ins_cost(INSN_COST); 14345 format %{ "cmp $op1, $op2" %} 14346 14347 ins_encode(aarch64_enc_cmp(op1, op2)); 14348 14349 ins_pipe(icmp_reg_reg); 14350 %} 14351 14352 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14353 %{ 14354 match(Set cr (CmpUL op1 zero)); 14355 14356 effect(DEF cr, USE op1); 14357 14358 ins_cost(INSN_COST); 14359 format %{ "tst $op1" %} 14360 14361 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14362 14363 ins_pipe(icmp_reg_imm); 14364 %} 14365 14366 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14367 %{ 14368 match(Set cr (CmpUL op1 op2)); 14369 14370 effect(DEF cr, USE op1); 14371 14372 ins_cost(INSN_COST); 14373 format %{ "cmp $op1, $op2" %} 14374 14375 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14376 14377 ins_pipe(icmp_reg_imm); 14378 %} 14379 14380 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14381 %{ 14382 match(Set cr (CmpUL op1 op2)); 14383 14384 effect(DEF cr, USE op1); 14385 14386 ins_cost(INSN_COST * 2); 14387 format %{ "cmp $op1, $op2" %} 14388 14389 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14390 14391 ins_pipe(icmp_reg_imm); 14392 %} 14393 14394 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14395 %{ 14396 match(Set cr (CmpP op1 op2)); 14397 14398 effect(DEF cr, USE op1, USE op2); 14399 14400 ins_cost(INSN_COST); 14401 format %{ "cmp $op1, $op2\t // ptr" %} 14402 14403 ins_encode(aarch64_enc_cmpp(op1, op2)); 14404 14405 ins_pipe(icmp_reg_reg); 14406 %} 14407 14408 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14409 %{ 14410 match(Set cr (CmpN op1 op2)); 14411 14412 effect(DEF cr, USE op1, USE op2); 14413 14414 ins_cost(INSN_COST); 14415 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14416 14417 ins_encode(aarch64_enc_cmpn(op1, op2)); 14418 14419 ins_pipe(icmp_reg_reg); 14420 %} 14421 14422 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14423 %{ 14424 match(Set cr (CmpP op1 zero)); 14425 14426 effect(DEF cr, USE op1, USE zero); 14427 14428 ins_cost(INSN_COST); 14429 format %{ "cmp $op1, 0\t // ptr" %} 14430 14431 ins_encode(aarch64_enc_testp(op1)); 14432 14433 ins_pipe(icmp_reg_imm); 14434 %} 14435 14436 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14437 %{ 14438 match(Set cr (CmpN op1 zero)); 14439 14440 effect(DEF cr, USE op1, USE zero); 14441 14442 ins_cost(INSN_COST); 14443 format %{ "cmp $op1, 0\t // compressed ptr" %} 14444 14445 ins_encode(aarch64_enc_testn(op1)); 14446 14447 ins_pipe(icmp_reg_imm); 14448 %} 14449 14450 // FP comparisons 14451 // 14452 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14453 // using normal cmpOp. See declaration of rFlagsReg for details. 14454 14455 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14456 %{ 14457 match(Set cr (CmpF src1 src2)); 14458 14459 ins_cost(3 * INSN_COST); 14460 format %{ "fcmps $src1, $src2" %} 14461 14462 ins_encode %{ 14463 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14464 %} 14465 14466 ins_pipe(pipe_class_compare); 14467 %} 14468 14469 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14470 %{ 14471 match(Set cr (CmpF src1 src2)); 14472 14473 ins_cost(3 * INSN_COST); 14474 format %{ "fcmps $src1, 0.0" %} 14475 14476 ins_encode %{ 14477 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14478 %} 14479 14480 ins_pipe(pipe_class_compare); 14481 %} 14482 // FROM HERE 14483 14484 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14485 %{ 14486 match(Set cr (CmpD src1 src2)); 14487 14488 ins_cost(3 * INSN_COST); 14489 format %{ "fcmpd $src1, $src2" %} 14490 14491 ins_encode %{ 14492 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14493 %} 14494 14495 ins_pipe(pipe_class_compare); 14496 %} 14497 14498 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14499 %{ 14500 match(Set cr (CmpD src1 src2)); 14501 14502 ins_cost(3 * INSN_COST); 14503 format %{ "fcmpd $src1, 0.0" %} 14504 14505 ins_encode %{ 14506 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14507 %} 14508 14509 ins_pipe(pipe_class_compare); 14510 %} 14511 14512 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14513 %{ 14514 match(Set dst (CmpF3 src1 src2)); 14515 effect(KILL cr); 14516 14517 ins_cost(5 * INSN_COST); 14518 format %{ "fcmps $src1, $src2\n\t" 14519 "csinvw($dst, zr, zr, eq\n\t" 14520 "csnegw($dst, $dst, $dst, lt)" 14521 %} 14522 14523 ins_encode %{ 14524 Label done; 14525 FloatRegister s1 = as_FloatRegister($src1$$reg); 14526 FloatRegister s2 = as_FloatRegister($src2$$reg); 14527 Register d = as_Register($dst$$reg); 14528 __ fcmps(s1, s2); 14529 // installs 0 if EQ else -1 14530 __ csinvw(d, zr, zr, Assembler::EQ); 14531 // keeps -1 if less or unordered else installs 1 14532 __ csnegw(d, d, d, Assembler::LT); 14533 __ bind(done); 14534 %} 14535 14536 ins_pipe(pipe_class_default); 14537 14538 %} 14539 14540 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14541 %{ 14542 match(Set dst (CmpD3 src1 src2)); 14543 effect(KILL cr); 14544 14545 ins_cost(5 * INSN_COST); 14546 format %{ "fcmpd $src1, $src2\n\t" 14547 "csinvw($dst, zr, zr, eq\n\t" 14548 "csnegw($dst, $dst, $dst, lt)" 14549 %} 14550 14551 ins_encode %{ 14552 Label done; 14553 FloatRegister s1 = as_FloatRegister($src1$$reg); 14554 FloatRegister s2 = as_FloatRegister($src2$$reg); 14555 Register d = as_Register($dst$$reg); 14556 __ fcmpd(s1, s2); 14557 // installs 0 if EQ else -1 14558 __ csinvw(d, zr, zr, Assembler::EQ); 14559 // keeps -1 if less or unordered else installs 1 14560 __ csnegw(d, d, d, Assembler::LT); 14561 __ bind(done); 14562 %} 14563 ins_pipe(pipe_class_default); 14564 14565 %} 14566 14567 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14568 %{ 14569 match(Set dst (CmpF3 src1 zero)); 14570 effect(KILL cr); 14571 14572 ins_cost(5 * INSN_COST); 14573 format %{ "fcmps $src1, 0.0\n\t" 14574 "csinvw($dst, zr, zr, eq\n\t" 14575 "csnegw($dst, $dst, $dst, lt)" 14576 %} 14577 14578 ins_encode %{ 14579 Label done; 14580 FloatRegister s1 = as_FloatRegister($src1$$reg); 14581 Register d = as_Register($dst$$reg); 14582 __ fcmps(s1, 0.0); 14583 // installs 0 if EQ else -1 14584 __ csinvw(d, zr, zr, Assembler::EQ); 14585 // keeps -1 if less or unordered else installs 1 14586 __ csnegw(d, d, d, Assembler::LT); 14587 __ bind(done); 14588 %} 14589 14590 ins_pipe(pipe_class_default); 14591 14592 %} 14593 14594 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14595 %{ 14596 match(Set dst (CmpD3 src1 zero)); 14597 effect(KILL cr); 14598 14599 ins_cost(5 * INSN_COST); 14600 format %{ "fcmpd $src1, 0.0\n\t" 14601 "csinvw($dst, zr, zr, eq\n\t" 14602 "csnegw($dst, $dst, $dst, lt)" 14603 %} 14604 14605 ins_encode %{ 14606 Label done; 14607 FloatRegister s1 = as_FloatRegister($src1$$reg); 14608 Register d = as_Register($dst$$reg); 14609 __ fcmpd(s1, 0.0); 14610 // installs 0 if EQ else -1 14611 __ csinvw(d, zr, zr, Assembler::EQ); 14612 // keeps -1 if less or unordered else installs 1 14613 __ csnegw(d, d, d, Assembler::LT); 14614 __ bind(done); 14615 %} 14616 ins_pipe(pipe_class_default); 14617 14618 %} 14619 14620 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14621 %{ 14622 match(Set dst (CmpLTMask p q)); 14623 effect(KILL cr); 14624 14625 ins_cost(3 * INSN_COST); 14626 14627 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14628 "csetw $dst, lt\n\t" 14629 "subw $dst, zr, $dst" 14630 %} 14631 14632 ins_encode %{ 14633 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14634 __ csetw(as_Register($dst$$reg), Assembler::LT); 14635 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14636 %} 14637 14638 ins_pipe(ialu_reg_reg); 14639 %} 14640 14641 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14642 %{ 14643 match(Set dst (CmpLTMask src zero)); 14644 effect(KILL cr); 14645 14646 ins_cost(INSN_COST); 14647 14648 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14649 14650 ins_encode %{ 14651 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14652 %} 14653 14654 ins_pipe(ialu_reg_shift); 14655 %} 14656 14657 // ============================================================================ 14658 // Max and Min 14659 14660 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14661 %{ 14662 effect( DEF dst, USE src1, USE src2, USE cr ); 14663 14664 ins_cost(INSN_COST * 2); 14665 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14666 14667 ins_encode %{ 14668 __ cselw(as_Register($dst$$reg), 14669 as_Register($src1$$reg), 14670 as_Register($src2$$reg), 14671 Assembler::LT); 14672 %} 14673 14674 ins_pipe(icond_reg_reg); 14675 %} 14676 14677 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14678 %{ 14679 match(Set dst (MinI src1 src2)); 14680 ins_cost(INSN_COST * 3); 14681 14682 expand %{ 14683 rFlagsReg cr; 14684 compI_reg_reg(cr, src1, src2); 14685 cmovI_reg_reg_lt(dst, src1, src2, cr); 14686 %} 14687 14688 %} 14689 // FROM HERE 14690 14691 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14692 %{ 14693 effect( DEF dst, USE src1, USE src2, USE cr ); 14694 14695 ins_cost(INSN_COST * 2); 14696 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14697 14698 ins_encode %{ 14699 __ cselw(as_Register($dst$$reg), 14700 as_Register($src1$$reg), 14701 as_Register($src2$$reg), 14702 Assembler::GT); 14703 %} 14704 14705 ins_pipe(icond_reg_reg); 14706 %} 14707 14708 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14709 %{ 14710 match(Set dst (MaxI src1 src2)); 14711 ins_cost(INSN_COST * 3); 14712 expand %{ 14713 rFlagsReg cr; 14714 compI_reg_reg(cr, src1, src2); 14715 cmovI_reg_reg_gt(dst, src1, src2, cr); 14716 %} 14717 %} 14718 14719 // ============================================================================ 14720 // Branch Instructions 14721 14722 // Direct Branch. 14723 instruct branch(label lbl) 14724 %{ 14725 match(Goto); 14726 14727 effect(USE lbl); 14728 14729 ins_cost(BRANCH_COST); 14730 format %{ "b $lbl" %} 14731 14732 ins_encode(aarch64_enc_b(lbl)); 14733 14734 ins_pipe(pipe_branch); 14735 %} 14736 14737 // Conditional Near Branch 14738 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14739 %{ 14740 // Same match rule as `branchConFar'. 14741 match(If cmp cr); 14742 14743 effect(USE lbl); 14744 14745 ins_cost(BRANCH_COST); 14746 // If set to 1 this indicates that the current instruction is a 14747 // short variant of a long branch. This avoids using this 14748 // instruction in first-pass matching. It will then only be used in 14749 // the `Shorten_branches' pass. 14750 // ins_short_branch(1); 14751 format %{ "b$cmp $lbl" %} 14752 14753 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14754 14755 ins_pipe(pipe_branch_cond); 14756 %} 14757 14758 // Conditional Near Branch Unsigned 14759 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14760 %{ 14761 // Same match rule as `branchConFar'. 14762 match(If cmp cr); 14763 14764 effect(USE lbl); 14765 14766 ins_cost(BRANCH_COST); 14767 // If set to 1 this indicates that the current instruction is a 14768 // short variant of a long branch. This avoids using this 14769 // instruction in first-pass matching. It will then only be used in 14770 // the `Shorten_branches' pass. 14771 // ins_short_branch(1); 14772 format %{ "b$cmp $lbl\t# unsigned" %} 14773 14774 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14775 14776 ins_pipe(pipe_branch_cond); 14777 %} 14778 14779 // Make use of CBZ and CBNZ. These instructions, as well as being 14780 // shorter than (cmp; branch), have the additional benefit of not 14781 // killing the flags. 14782 14783 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14784 match(If cmp (CmpI op1 op2)); 14785 effect(USE labl); 14786 14787 ins_cost(BRANCH_COST); 14788 format %{ "cbw$cmp $op1, $labl" %} 14789 ins_encode %{ 14790 Label* L = $labl$$label; 14791 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14792 if (cond == Assembler::EQ) 14793 __ cbzw($op1$$Register, *L); 14794 else 14795 __ cbnzw($op1$$Register, *L); 14796 %} 14797 ins_pipe(pipe_cmp_branch); 14798 %} 14799 14800 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14801 match(If cmp (CmpL op1 op2)); 14802 effect(USE labl); 14803 14804 ins_cost(BRANCH_COST); 14805 format %{ "cb$cmp $op1, $labl" %} 14806 ins_encode %{ 14807 Label* L = $labl$$label; 14808 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14809 if (cond == Assembler::EQ) 14810 __ cbz($op1$$Register, *L); 14811 else 14812 __ cbnz($op1$$Register, *L); 14813 %} 14814 ins_pipe(pipe_cmp_branch); 14815 %} 14816 14817 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14818 match(If cmp (CmpP op1 op2)); 14819 effect(USE labl); 14820 14821 ins_cost(BRANCH_COST); 14822 format %{ "cb$cmp $op1, $labl" %} 14823 ins_encode %{ 14824 Label* L = $labl$$label; 14825 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14826 if (cond == Assembler::EQ) 14827 __ cbz($op1$$Register, *L); 14828 else 14829 __ cbnz($op1$$Register, *L); 14830 %} 14831 ins_pipe(pipe_cmp_branch); 14832 %} 14833 14834 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14835 match(If cmp (CmpN op1 op2)); 14836 effect(USE labl); 14837 14838 ins_cost(BRANCH_COST); 14839 format %{ "cbw$cmp $op1, $labl" %} 14840 ins_encode %{ 14841 Label* L = $labl$$label; 14842 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14843 if (cond == Assembler::EQ) 14844 __ cbzw($op1$$Register, *L); 14845 else 14846 __ cbnzw($op1$$Register, *L); 14847 %} 14848 ins_pipe(pipe_cmp_branch); 14849 %} 14850 14851 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14852 match(If cmp (CmpP (DecodeN oop) zero)); 14853 effect(USE labl); 14854 14855 ins_cost(BRANCH_COST); 14856 format %{ "cb$cmp $oop, $labl" %} 14857 ins_encode %{ 14858 Label* L = $labl$$label; 14859 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14860 if (cond == Assembler::EQ) 14861 __ cbzw($oop$$Register, *L); 14862 else 14863 __ cbnzw($oop$$Register, *L); 14864 %} 14865 ins_pipe(pipe_cmp_branch); 14866 %} 14867 14868 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14869 match(If cmp (CmpU op1 op2)); 14870 effect(USE labl); 14871 14872 ins_cost(BRANCH_COST); 14873 format %{ "cbw$cmp $op1, $labl" %} 14874 ins_encode %{ 14875 Label* L = $labl$$label; 14876 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14877 if (cond == Assembler::EQ || cond == Assembler::LS) 14878 __ cbzw($op1$$Register, *L); 14879 else 14880 __ cbnzw($op1$$Register, *L); 14881 %} 14882 ins_pipe(pipe_cmp_branch); 14883 %} 14884 14885 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14886 match(If cmp (CmpUL op1 op2)); 14887 effect(USE labl); 14888 14889 ins_cost(BRANCH_COST); 14890 format %{ "cb$cmp $op1, $labl" %} 14891 ins_encode %{ 14892 Label* L = $labl$$label; 14893 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14894 if (cond == Assembler::EQ || cond == Assembler::LS) 14895 __ cbz($op1$$Register, *L); 14896 else 14897 __ cbnz($op1$$Register, *L); 14898 %} 14899 ins_pipe(pipe_cmp_branch); 14900 %} 14901 14902 // Test bit and Branch 14903 14904 // Patterns for short (< 32KiB) variants 14905 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14906 match(If cmp (CmpL op1 op2)); 14907 effect(USE labl); 14908 14909 ins_cost(BRANCH_COST); 14910 format %{ "cb$cmp $op1, $labl # long" %} 14911 ins_encode %{ 14912 Label* L = $labl$$label; 14913 Assembler::Condition cond = 14914 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14915 __ tbr(cond, $op1$$Register, 63, *L); 14916 %} 14917 ins_pipe(pipe_cmp_branch); 14918 ins_short_branch(1); 14919 %} 14920 14921 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14922 match(If cmp (CmpI op1 op2)); 14923 effect(USE labl); 14924 14925 ins_cost(BRANCH_COST); 14926 format %{ "cb$cmp $op1, $labl # int" %} 14927 ins_encode %{ 14928 Label* L = $labl$$label; 14929 Assembler::Condition cond = 14930 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14931 __ tbr(cond, $op1$$Register, 31, *L); 14932 %} 14933 ins_pipe(pipe_cmp_branch); 14934 ins_short_branch(1); 14935 %} 14936 14937 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14938 match(If cmp (CmpL (AndL op1 op2) op3)); 14939 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 14940 effect(USE labl); 14941 14942 ins_cost(BRANCH_COST); 14943 format %{ "tb$cmp $op1, $op2, $labl" %} 14944 ins_encode %{ 14945 Label* L = $labl$$label; 14946 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14947 int bit = exact_log2_long($op2$$constant); 14948 __ tbr(cond, $op1$$Register, bit, *L); 14949 %} 14950 ins_pipe(pipe_cmp_branch); 14951 ins_short_branch(1); 14952 %} 14953 14954 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14955 match(If cmp (CmpI (AndI op1 op2) op3)); 14956 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 14957 effect(USE labl); 14958 14959 ins_cost(BRANCH_COST); 14960 format %{ "tb$cmp $op1, $op2, $labl" %} 14961 ins_encode %{ 14962 Label* L = $labl$$label; 14963 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14964 int bit = exact_log2((juint)$op2$$constant); 14965 __ tbr(cond, $op1$$Register, bit, *L); 14966 %} 14967 ins_pipe(pipe_cmp_branch); 14968 ins_short_branch(1); 14969 %} 14970 14971 // And far variants 14972 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14973 match(If cmp (CmpL op1 op2)); 14974 effect(USE labl); 14975 14976 ins_cost(BRANCH_COST); 14977 format %{ "cb$cmp $op1, $labl # long" %} 14978 ins_encode %{ 14979 Label* L = $labl$$label; 14980 Assembler::Condition cond = 14981 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14982 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14983 %} 14984 ins_pipe(pipe_cmp_branch); 14985 %} 14986 14987 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14988 match(If cmp (CmpI op1 op2)); 14989 effect(USE labl); 14990 14991 ins_cost(BRANCH_COST); 14992 format %{ "cb$cmp $op1, $labl # int" %} 14993 ins_encode %{ 14994 Label* L = $labl$$label; 14995 Assembler::Condition cond = 14996 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14997 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14998 %} 14999 ins_pipe(pipe_cmp_branch); 15000 %} 15001 15002 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15003 match(If cmp (CmpL (AndL op1 op2) op3)); 15004 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15005 effect(USE labl); 15006 15007 ins_cost(BRANCH_COST); 15008 format %{ "tb$cmp $op1, $op2, $labl" %} 15009 ins_encode %{ 15010 Label* L = $labl$$label; 15011 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15012 int bit = exact_log2_long($op2$$constant); 15013 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15014 %} 15015 ins_pipe(pipe_cmp_branch); 15016 %} 15017 15018 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15019 match(If cmp (CmpI (AndI op1 op2) op3)); 15020 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15021 effect(USE labl); 15022 15023 ins_cost(BRANCH_COST); 15024 format %{ "tb$cmp $op1, $op2, $labl" %} 15025 ins_encode %{ 15026 Label* L = $labl$$label; 15027 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15028 int bit = exact_log2((juint)$op2$$constant); 15029 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15030 %} 15031 ins_pipe(pipe_cmp_branch); 15032 %} 15033 15034 // Test bits 15035 15036 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15037 match(Set cr (CmpL (AndL op1 op2) op3)); 15038 predicate(Assembler::operand_valid_for_logical_immediate 15039 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15040 15041 ins_cost(INSN_COST); 15042 format %{ "tst $op1, $op2 # long" %} 15043 ins_encode %{ 15044 __ tst($op1$$Register, $op2$$constant); 15045 %} 15046 ins_pipe(ialu_reg_reg); 15047 %} 15048 15049 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15050 match(Set cr (CmpI (AndI op1 op2) op3)); 15051 predicate(Assembler::operand_valid_for_logical_immediate 15052 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15053 15054 ins_cost(INSN_COST); 15055 format %{ "tst $op1, $op2 # int" %} 15056 ins_encode %{ 15057 __ tstw($op1$$Register, $op2$$constant); 15058 %} 15059 ins_pipe(ialu_reg_reg); 15060 %} 15061 15062 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15063 match(Set cr (CmpL (AndL op1 op2) op3)); 15064 15065 ins_cost(INSN_COST); 15066 format %{ "tst $op1, $op2 # long" %} 15067 ins_encode %{ 15068 __ tst($op1$$Register, $op2$$Register); 15069 %} 15070 ins_pipe(ialu_reg_reg); 15071 %} 15072 15073 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15074 match(Set cr (CmpI (AndI op1 op2) op3)); 15075 15076 ins_cost(INSN_COST); 15077 format %{ "tstw $op1, $op2 # int" %} 15078 ins_encode %{ 15079 __ tstw($op1$$Register, $op2$$Register); 15080 %} 15081 ins_pipe(ialu_reg_reg); 15082 %} 15083 15084 15085 // Conditional Far Branch 15086 // Conditional Far Branch Unsigned 15087 // TODO: fixme 15088 15089 // counted loop end branch near 15090 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15091 %{ 15092 match(CountedLoopEnd cmp cr); 15093 15094 effect(USE lbl); 15095 15096 ins_cost(BRANCH_COST); 15097 // short variant. 15098 // ins_short_branch(1); 15099 format %{ "b$cmp $lbl \t// counted loop end" %} 15100 15101 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15102 15103 ins_pipe(pipe_branch); 15104 %} 15105 15106 // counted loop end branch near Unsigned 15107 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15108 %{ 15109 match(CountedLoopEnd cmp cr); 15110 15111 effect(USE lbl); 15112 15113 ins_cost(BRANCH_COST); 15114 // short variant. 15115 // ins_short_branch(1); 15116 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15117 15118 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15119 15120 ins_pipe(pipe_branch); 15121 %} 15122 15123 // counted loop end branch far 15124 // counted loop end branch far unsigned 15125 // TODO: fixme 15126 15127 // ============================================================================ 15128 // inlined locking and unlocking 15129 15130 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15131 %{ 15132 match(Set cr (FastLock object box)); 15133 effect(TEMP tmp, TEMP tmp2); 15134 15135 // TODO 15136 // identify correct cost 15137 ins_cost(5 * INSN_COST); 15138 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15139 15140 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15141 15142 ins_pipe(pipe_serial); 15143 %} 15144 15145 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15146 %{ 15147 match(Set cr (FastUnlock object box)); 15148 effect(TEMP tmp, TEMP tmp2); 15149 15150 ins_cost(5 * INSN_COST); 15151 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15152 15153 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15154 15155 ins_pipe(pipe_serial); 15156 %} 15157 15158 15159 // ============================================================================ 15160 // Safepoint Instructions 15161 15162 // TODO 15163 // provide a near and far version of this code 15164 15165 instruct safePoint(rFlagsReg cr, iRegP poll) 15166 %{ 15167 match(SafePoint poll); 15168 effect(KILL cr); 15169 15170 format %{ 15171 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15172 %} 15173 ins_encode %{ 15174 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15175 %} 15176 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15177 %} 15178 15179 15180 // ============================================================================ 15181 // Procedure Call/Return Instructions 15182 15183 // Call Java Static Instruction 15184 15185 instruct CallStaticJavaDirect(method meth) 15186 %{ 15187 match(CallStaticJava); 15188 15189 effect(USE meth); 15190 15191 ins_cost(CALL_COST); 15192 15193 format %{ "call,static $meth \t// ==> " %} 15194 15195 ins_encode( aarch64_enc_java_static_call(meth), 15196 aarch64_enc_call_epilog ); 15197 15198 ins_pipe(pipe_class_call); 15199 %} 15200 15201 // TO HERE 15202 15203 // Call Java Dynamic Instruction 15204 instruct CallDynamicJavaDirect(method meth) 15205 %{ 15206 match(CallDynamicJava); 15207 15208 effect(USE meth); 15209 15210 ins_cost(CALL_COST); 15211 15212 format %{ "CALL,dynamic $meth \t// ==> " %} 15213 15214 ins_encode( aarch64_enc_java_dynamic_call(meth), 15215 aarch64_enc_call_epilog ); 15216 15217 ins_pipe(pipe_class_call); 15218 %} 15219 15220 // Call Runtime Instruction 15221 15222 instruct CallRuntimeDirect(method meth) 15223 %{ 15224 match(CallRuntime); 15225 15226 effect(USE meth); 15227 15228 ins_cost(CALL_COST); 15229 15230 format %{ "CALL, runtime $meth" %} 15231 15232 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15233 15234 ins_pipe(pipe_class_call); 15235 %} 15236 15237 // Call Runtime Instruction 15238 15239 instruct CallLeafDirect(method meth) 15240 %{ 15241 match(CallLeaf); 15242 15243 effect(USE meth); 15244 15245 ins_cost(CALL_COST); 15246 15247 format %{ "CALL, runtime leaf $meth" %} 15248 15249 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15250 15251 ins_pipe(pipe_class_call); 15252 %} 15253 15254 // Call Runtime Instruction 15255 15256 instruct CallLeafNoFPDirect(method meth) 15257 %{ 15258 match(CallLeafNoFP); 15259 15260 effect(USE meth); 15261 15262 ins_cost(CALL_COST); 15263 15264 format %{ "CALL, runtime leaf nofp $meth" %} 15265 15266 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15267 15268 ins_pipe(pipe_class_call); 15269 %} 15270 15271 // Tail Call; Jump from runtime stub to Java code. 15272 // Also known as an 'interprocedural jump'. 15273 // Target of jump will eventually return to caller. 15274 // TailJump below removes the return address. 15275 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15276 %{ 15277 match(TailCall jump_target method_oop); 15278 15279 ins_cost(CALL_COST); 15280 15281 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15282 15283 ins_encode(aarch64_enc_tail_call(jump_target)); 15284 15285 ins_pipe(pipe_class_call); 15286 %} 15287 15288 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15289 %{ 15290 match(TailJump jump_target ex_oop); 15291 15292 ins_cost(CALL_COST); 15293 15294 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15295 15296 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15297 15298 ins_pipe(pipe_class_call); 15299 %} 15300 15301 // Create exception oop: created by stack-crawling runtime code. 15302 // Created exception is now available to this handler, and is setup 15303 // just prior to jumping to this handler. No code emitted. 15304 // TODO check 15305 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15306 instruct CreateException(iRegP_R0 ex_oop) 15307 %{ 15308 match(Set ex_oop (CreateEx)); 15309 15310 format %{ " -- \t// exception oop; no code emitted" %} 15311 15312 size(0); 15313 15314 ins_encode( /*empty*/ ); 15315 15316 ins_pipe(pipe_class_empty); 15317 %} 15318 15319 // Rethrow exception: The exception oop will come in the first 15320 // argument position. Then JUMP (not call) to the rethrow stub code. 15321 instruct RethrowException() %{ 15322 match(Rethrow); 15323 ins_cost(CALL_COST); 15324 15325 format %{ "b rethrow_stub" %} 15326 15327 ins_encode( aarch64_enc_rethrow() ); 15328 15329 ins_pipe(pipe_class_call); 15330 %} 15331 15332 15333 // Return Instruction 15334 // epilog node loads ret address into lr as part of frame pop 15335 instruct Ret() 15336 %{ 15337 match(Return); 15338 15339 format %{ "ret\t// return register" %} 15340 15341 ins_encode( aarch64_enc_ret() ); 15342 15343 ins_pipe(pipe_branch); 15344 %} 15345 15346 // Die now. 15347 instruct ShouldNotReachHere() %{ 15348 match(Halt); 15349 15350 ins_cost(CALL_COST); 15351 format %{ "ShouldNotReachHere" %} 15352 15353 ins_encode %{ 15354 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 15355 // return true 15356 __ dpcs1(0xdead + 1); 15357 %} 15358 15359 ins_pipe(pipe_class_default); 15360 %} 15361 15362 // ============================================================================ 15363 // Partial Subtype Check 15364 // 15365 // superklass array for an instance of the superklass. Set a hidden 15366 // internal cache on a hit (cache is checked with exposed code in 15367 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15368 // encoding ALSO sets flags. 15369 15370 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15371 %{ 15372 match(Set result (PartialSubtypeCheck sub super)); 15373 effect(KILL cr, KILL temp); 15374 15375 ins_cost(1100); // slightly larger than the next version 15376 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15377 15378 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15379 15380 opcode(0x1); // Force zero of result reg on hit 15381 15382 ins_pipe(pipe_class_memory); 15383 %} 15384 15385 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15386 %{ 15387 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15388 effect(KILL temp, KILL result); 15389 15390 ins_cost(1100); // slightly larger than the next version 15391 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15392 15393 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15394 15395 opcode(0x0); // Don't zero result reg on hit 15396 15397 ins_pipe(pipe_class_memory); 15398 %} 15399 15400 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15401 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15402 %{ 15403 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15404 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15405 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15406 15407 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15408 ins_encode %{ 15409 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15410 __ string_compare($str1$$Register, $str2$$Register, 15411 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15412 $tmp1$$Register, $tmp2$$Register, 15413 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15414 %} 15415 ins_pipe(pipe_class_memory); 15416 %} 15417 15418 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15419 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15420 %{ 15421 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15422 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15423 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15424 15425 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15426 ins_encode %{ 15427 __ string_compare($str1$$Register, $str2$$Register, 15428 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15429 $tmp1$$Register, $tmp2$$Register, 15430 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15431 %} 15432 ins_pipe(pipe_class_memory); 15433 %} 15434 15435 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15436 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15437 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15438 %{ 15439 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15440 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15441 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15442 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15443 15444 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15445 ins_encode %{ 15446 __ string_compare($str1$$Register, $str2$$Register, 15447 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15448 $tmp1$$Register, $tmp2$$Register, 15449 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15450 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15451 %} 15452 ins_pipe(pipe_class_memory); 15453 %} 15454 15455 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15456 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15457 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15458 %{ 15459 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15460 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15461 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15462 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15463 15464 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15465 ins_encode %{ 15466 __ string_compare($str1$$Register, $str2$$Register, 15467 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15468 $tmp1$$Register, $tmp2$$Register, 15469 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15470 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15471 %} 15472 ins_pipe(pipe_class_memory); 15473 %} 15474 15475 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15476 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15477 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15478 %{ 15479 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15480 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15481 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15482 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15483 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15484 15485 ins_encode %{ 15486 __ string_indexof($str1$$Register, $str2$$Register, 15487 $cnt1$$Register, $cnt2$$Register, 15488 $tmp1$$Register, $tmp2$$Register, 15489 $tmp3$$Register, $tmp4$$Register, 15490 $tmp5$$Register, $tmp6$$Register, 15491 -1, $result$$Register, StrIntrinsicNode::UU); 15492 %} 15493 ins_pipe(pipe_class_memory); 15494 %} 15495 15496 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15497 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15498 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15499 %{ 15500 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15501 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15502 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15503 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15504 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15505 15506 ins_encode %{ 15507 __ string_indexof($str1$$Register, $str2$$Register, 15508 $cnt1$$Register, $cnt2$$Register, 15509 $tmp1$$Register, $tmp2$$Register, 15510 $tmp3$$Register, $tmp4$$Register, 15511 $tmp5$$Register, $tmp6$$Register, 15512 -1, $result$$Register, StrIntrinsicNode::LL); 15513 %} 15514 ins_pipe(pipe_class_memory); 15515 %} 15516 15517 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15518 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15519 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15520 %{ 15521 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15522 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15523 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15524 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15525 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15526 15527 ins_encode %{ 15528 __ string_indexof($str1$$Register, $str2$$Register, 15529 $cnt1$$Register, $cnt2$$Register, 15530 $tmp1$$Register, $tmp2$$Register, 15531 $tmp3$$Register, $tmp4$$Register, 15532 $tmp5$$Register, $tmp6$$Register, 15533 -1, $result$$Register, StrIntrinsicNode::UL); 15534 %} 15535 ins_pipe(pipe_class_memory); 15536 %} 15537 15538 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15539 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15540 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15541 %{ 15542 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15543 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15544 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15545 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15546 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15547 15548 ins_encode %{ 15549 int icnt2 = (int)$int_cnt2$$constant; 15550 __ string_indexof($str1$$Register, $str2$$Register, 15551 $cnt1$$Register, zr, 15552 $tmp1$$Register, $tmp2$$Register, 15553 $tmp3$$Register, $tmp4$$Register, zr, zr, 15554 icnt2, $result$$Register, StrIntrinsicNode::UU); 15555 %} 15556 ins_pipe(pipe_class_memory); 15557 %} 15558 15559 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15560 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15561 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15562 %{ 15563 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15564 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15565 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15566 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15567 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15568 15569 ins_encode %{ 15570 int icnt2 = (int)$int_cnt2$$constant; 15571 __ string_indexof($str1$$Register, $str2$$Register, 15572 $cnt1$$Register, zr, 15573 $tmp1$$Register, $tmp2$$Register, 15574 $tmp3$$Register, $tmp4$$Register, zr, zr, 15575 icnt2, $result$$Register, StrIntrinsicNode::LL); 15576 %} 15577 ins_pipe(pipe_class_memory); 15578 %} 15579 15580 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15581 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15582 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15583 %{ 15584 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15585 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15586 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15587 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15588 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15589 15590 ins_encode %{ 15591 int icnt2 = (int)$int_cnt2$$constant; 15592 __ string_indexof($str1$$Register, $str2$$Register, 15593 $cnt1$$Register, zr, 15594 $tmp1$$Register, $tmp2$$Register, 15595 $tmp3$$Register, $tmp4$$Register, zr, zr, 15596 icnt2, $result$$Register, StrIntrinsicNode::UL); 15597 %} 15598 ins_pipe(pipe_class_memory); 15599 %} 15600 15601 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15602 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15603 iRegINoSp tmp3, rFlagsReg cr) 15604 %{ 15605 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15606 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15607 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15608 15609 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15610 15611 ins_encode %{ 15612 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15613 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15614 $tmp3$$Register); 15615 %} 15616 ins_pipe(pipe_class_memory); 15617 %} 15618 15619 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15620 iRegI_R0 result, rFlagsReg cr) 15621 %{ 15622 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15623 match(Set result (StrEquals (Binary str1 str2) cnt)); 15624 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15625 15626 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15627 ins_encode %{ 15628 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15629 __ string_equals($str1$$Register, $str2$$Register, 15630 $result$$Register, $cnt$$Register, 1); 15631 %} 15632 ins_pipe(pipe_class_memory); 15633 %} 15634 15635 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15636 iRegI_R0 result, rFlagsReg cr) 15637 %{ 15638 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15639 match(Set result (StrEquals (Binary str1 str2) cnt)); 15640 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15641 15642 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15643 ins_encode %{ 15644 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15645 __ string_equals($str1$$Register, $str2$$Register, 15646 $result$$Register, $cnt$$Register, 2); 15647 %} 15648 ins_pipe(pipe_class_memory); 15649 %} 15650 15651 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15652 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15653 iRegP_R10 tmp, rFlagsReg cr) 15654 %{ 15655 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15656 match(Set result (AryEq ary1 ary2)); 15657 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15658 15659 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15660 ins_encode %{ 15661 __ arrays_equals($ary1$$Register, $ary2$$Register, 15662 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15663 $result$$Register, $tmp$$Register, 1); 15664 %} 15665 ins_pipe(pipe_class_memory); 15666 %} 15667 15668 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15669 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15670 iRegP_R10 tmp, rFlagsReg cr) 15671 %{ 15672 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15673 match(Set result (AryEq ary1 ary2)); 15674 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15675 15676 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15677 ins_encode %{ 15678 __ arrays_equals($ary1$$Register, $ary2$$Register, 15679 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15680 $result$$Register, $tmp$$Register, 2); 15681 %} 15682 ins_pipe(pipe_class_memory); 15683 %} 15684 15685 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15686 %{ 15687 match(Set result (HasNegatives ary1 len)); 15688 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15689 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15690 ins_encode %{ 15691 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15692 %} 15693 ins_pipe( pipe_slow ); 15694 %} 15695 15696 // fast char[] to byte[] compression 15697 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15698 vRegD_V0 tmp1, vRegD_V1 tmp2, 15699 vRegD_V2 tmp3, vRegD_V3 tmp4, 15700 iRegI_R0 result, rFlagsReg cr) 15701 %{ 15702 match(Set result (StrCompressedCopy src (Binary dst len))); 15703 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15704 15705 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15706 ins_encode %{ 15707 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15708 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15709 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15710 $result$$Register); 15711 %} 15712 ins_pipe( pipe_slow ); 15713 %} 15714 15715 // fast byte[] to char[] inflation 15716 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15717 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15718 %{ 15719 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15720 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15721 15722 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15723 ins_encode %{ 15724 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15725 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15726 %} 15727 ins_pipe(pipe_class_memory); 15728 %} 15729 15730 // encode char[] to byte[] in ISO_8859_1 15731 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15732 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15733 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15734 iRegI_R0 result, rFlagsReg cr) 15735 %{ 15736 match(Set result (EncodeISOArray src (Binary dst len))); 15737 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15738 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15739 15740 format %{ "Encode array $src,$dst,$len -> $result" %} 15741 ins_encode %{ 15742 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15743 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15744 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15745 %} 15746 ins_pipe( pipe_class_memory ); 15747 %} 15748 15749 // ============================================================================ 15750 // This name is KNOWN by the ADLC and cannot be changed. 15751 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15752 // for this guy. 15753 instruct tlsLoadP(thread_RegP dst) 15754 %{ 15755 match(Set dst (ThreadLocal)); 15756 15757 ins_cost(0); 15758 15759 format %{ " -- \t// $dst=Thread::current(), empty" %} 15760 15761 size(0); 15762 15763 ins_encode( /*empty*/ ); 15764 15765 ins_pipe(pipe_class_empty); 15766 %} 15767 15768 // ====================VECTOR INSTRUCTIONS===================================== 15769 15770 // Load vector (32 bits) 15771 instruct loadV4(vecD dst, vmem4 mem) 15772 %{ 15773 predicate(n->as_LoadVector()->memory_size() == 4); 15774 match(Set dst (LoadVector mem)); 15775 ins_cost(4 * INSN_COST); 15776 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15777 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15778 ins_pipe(vload_reg_mem64); 15779 %} 15780 15781 // Load vector (64 bits) 15782 instruct loadV8(vecD dst, vmem8 mem) 15783 %{ 15784 predicate(n->as_LoadVector()->memory_size() == 8); 15785 match(Set dst (LoadVector mem)); 15786 ins_cost(4 * INSN_COST); 15787 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15788 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15789 ins_pipe(vload_reg_mem64); 15790 %} 15791 15792 // Load Vector (128 bits) 15793 instruct loadV16(vecX dst, vmem16 mem) 15794 %{ 15795 predicate(n->as_LoadVector()->memory_size() == 16); 15796 match(Set dst (LoadVector mem)); 15797 ins_cost(4 * INSN_COST); 15798 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15799 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15800 ins_pipe(vload_reg_mem128); 15801 %} 15802 15803 // Store Vector (32 bits) 15804 instruct storeV4(vecD src, vmem4 mem) 15805 %{ 15806 predicate(n->as_StoreVector()->memory_size() == 4); 15807 match(Set mem (StoreVector mem src)); 15808 ins_cost(4 * INSN_COST); 15809 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15810 ins_encode( aarch64_enc_strvS(src, mem) ); 15811 ins_pipe(vstore_reg_mem64); 15812 %} 15813 15814 // Store Vector (64 bits) 15815 instruct storeV8(vecD src, vmem8 mem) 15816 %{ 15817 predicate(n->as_StoreVector()->memory_size() == 8); 15818 match(Set mem (StoreVector mem src)); 15819 ins_cost(4 * INSN_COST); 15820 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15821 ins_encode( aarch64_enc_strvD(src, mem) ); 15822 ins_pipe(vstore_reg_mem64); 15823 %} 15824 15825 // Store Vector (128 bits) 15826 instruct storeV16(vecX src, vmem16 mem) 15827 %{ 15828 predicate(n->as_StoreVector()->memory_size() == 16); 15829 match(Set mem (StoreVector mem src)); 15830 ins_cost(4 * INSN_COST); 15831 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15832 ins_encode( aarch64_enc_strvQ(src, mem) ); 15833 ins_pipe(vstore_reg_mem128); 15834 %} 15835 15836 instruct replicate8B(vecD dst, iRegIorL2I src) 15837 %{ 15838 predicate(n->as_Vector()->length() == 4 || 15839 n->as_Vector()->length() == 8); 15840 match(Set dst (ReplicateB src)); 15841 ins_cost(INSN_COST); 15842 format %{ "dup $dst, $src\t# vector (8B)" %} 15843 ins_encode %{ 15844 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15845 %} 15846 ins_pipe(vdup_reg_reg64); 15847 %} 15848 15849 instruct replicate16B(vecX dst, iRegIorL2I src) 15850 %{ 15851 predicate(n->as_Vector()->length() == 16); 15852 match(Set dst (ReplicateB src)); 15853 ins_cost(INSN_COST); 15854 format %{ "dup $dst, $src\t# vector (16B)" %} 15855 ins_encode %{ 15856 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15857 %} 15858 ins_pipe(vdup_reg_reg128); 15859 %} 15860 15861 instruct replicate8B_imm(vecD dst, immI con) 15862 %{ 15863 predicate(n->as_Vector()->length() == 4 || 15864 n->as_Vector()->length() == 8); 15865 match(Set dst (ReplicateB con)); 15866 ins_cost(INSN_COST); 15867 format %{ "movi $dst, $con\t# vector(8B)" %} 15868 ins_encode %{ 15869 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15870 %} 15871 ins_pipe(vmovi_reg_imm64); 15872 %} 15873 15874 instruct replicate16B_imm(vecX dst, immI con) 15875 %{ 15876 predicate(n->as_Vector()->length() == 16); 15877 match(Set dst (ReplicateB con)); 15878 ins_cost(INSN_COST); 15879 format %{ "movi $dst, $con\t# vector(16B)" %} 15880 ins_encode %{ 15881 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15882 %} 15883 ins_pipe(vmovi_reg_imm128); 15884 %} 15885 15886 instruct replicate4S(vecD dst, iRegIorL2I src) 15887 %{ 15888 predicate(n->as_Vector()->length() == 2 || 15889 n->as_Vector()->length() == 4); 15890 match(Set dst (ReplicateS src)); 15891 ins_cost(INSN_COST); 15892 format %{ "dup $dst, $src\t# vector (4S)" %} 15893 ins_encode %{ 15894 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15895 %} 15896 ins_pipe(vdup_reg_reg64); 15897 %} 15898 15899 instruct replicate8S(vecX dst, iRegIorL2I src) 15900 %{ 15901 predicate(n->as_Vector()->length() == 8); 15902 match(Set dst (ReplicateS src)); 15903 ins_cost(INSN_COST); 15904 format %{ "dup $dst, $src\t# vector (8S)" %} 15905 ins_encode %{ 15906 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15907 %} 15908 ins_pipe(vdup_reg_reg128); 15909 %} 15910 15911 instruct replicate4S_imm(vecD dst, immI con) 15912 %{ 15913 predicate(n->as_Vector()->length() == 2 || 15914 n->as_Vector()->length() == 4); 15915 match(Set dst (ReplicateS con)); 15916 ins_cost(INSN_COST); 15917 format %{ "movi $dst, $con\t# vector(4H)" %} 15918 ins_encode %{ 15919 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15920 %} 15921 ins_pipe(vmovi_reg_imm64); 15922 %} 15923 15924 instruct replicate8S_imm(vecX dst, immI con) 15925 %{ 15926 predicate(n->as_Vector()->length() == 8); 15927 match(Set dst (ReplicateS con)); 15928 ins_cost(INSN_COST); 15929 format %{ "movi $dst, $con\t# vector(8H)" %} 15930 ins_encode %{ 15931 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15932 %} 15933 ins_pipe(vmovi_reg_imm128); 15934 %} 15935 15936 instruct replicate2I(vecD dst, iRegIorL2I src) 15937 %{ 15938 predicate(n->as_Vector()->length() == 2); 15939 match(Set dst (ReplicateI src)); 15940 ins_cost(INSN_COST); 15941 format %{ "dup $dst, $src\t# vector (2I)" %} 15942 ins_encode %{ 15943 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15944 %} 15945 ins_pipe(vdup_reg_reg64); 15946 %} 15947 15948 instruct replicate4I(vecX dst, iRegIorL2I src) 15949 %{ 15950 predicate(n->as_Vector()->length() == 4); 15951 match(Set dst (ReplicateI src)); 15952 ins_cost(INSN_COST); 15953 format %{ "dup $dst, $src\t# vector (4I)" %} 15954 ins_encode %{ 15955 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15956 %} 15957 ins_pipe(vdup_reg_reg128); 15958 %} 15959 15960 instruct replicate2I_imm(vecD dst, immI con) 15961 %{ 15962 predicate(n->as_Vector()->length() == 2); 15963 match(Set dst (ReplicateI con)); 15964 ins_cost(INSN_COST); 15965 format %{ "movi $dst, $con\t# vector(2I)" %} 15966 ins_encode %{ 15967 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15968 %} 15969 ins_pipe(vmovi_reg_imm64); 15970 %} 15971 15972 instruct replicate4I_imm(vecX dst, immI con) 15973 %{ 15974 predicate(n->as_Vector()->length() == 4); 15975 match(Set dst (ReplicateI con)); 15976 ins_cost(INSN_COST); 15977 format %{ "movi $dst, $con\t# vector(4I)" %} 15978 ins_encode %{ 15979 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15980 %} 15981 ins_pipe(vmovi_reg_imm128); 15982 %} 15983 15984 instruct replicate2L(vecX dst, iRegL src) 15985 %{ 15986 predicate(n->as_Vector()->length() == 2); 15987 match(Set dst (ReplicateL src)); 15988 ins_cost(INSN_COST); 15989 format %{ "dup $dst, $src\t# vector (2L)" %} 15990 ins_encode %{ 15991 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15992 %} 15993 ins_pipe(vdup_reg_reg128); 15994 %} 15995 15996 instruct replicate2L_zero(vecX dst, immI0 zero) 15997 %{ 15998 predicate(n->as_Vector()->length() == 2); 15999 match(Set dst (ReplicateI zero)); 16000 ins_cost(INSN_COST); 16001 format %{ "movi $dst, $zero\t# vector(4I)" %} 16002 ins_encode %{ 16003 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16004 as_FloatRegister($dst$$reg), 16005 as_FloatRegister($dst$$reg)); 16006 %} 16007 ins_pipe(vmovi_reg_imm128); 16008 %} 16009 16010 instruct replicate2F(vecD dst, vRegF src) 16011 %{ 16012 predicate(n->as_Vector()->length() == 2); 16013 match(Set dst (ReplicateF src)); 16014 ins_cost(INSN_COST); 16015 format %{ "dup $dst, $src\t# vector (2F)" %} 16016 ins_encode %{ 16017 __ dup(as_FloatRegister($dst$$reg), __ T2S, 16018 as_FloatRegister($src$$reg)); 16019 %} 16020 ins_pipe(vdup_reg_freg64); 16021 %} 16022 16023 instruct replicate4F(vecX dst, vRegF src) 16024 %{ 16025 predicate(n->as_Vector()->length() == 4); 16026 match(Set dst (ReplicateF src)); 16027 ins_cost(INSN_COST); 16028 format %{ "dup $dst, $src\t# vector (4F)" %} 16029 ins_encode %{ 16030 __ dup(as_FloatRegister($dst$$reg), __ T4S, 16031 as_FloatRegister($src$$reg)); 16032 %} 16033 ins_pipe(vdup_reg_freg128); 16034 %} 16035 16036 instruct replicate2D(vecX dst, vRegD src) 16037 %{ 16038 predicate(n->as_Vector()->length() == 2); 16039 match(Set dst (ReplicateD src)); 16040 ins_cost(INSN_COST); 16041 format %{ "dup $dst, $src\t# vector (2D)" %} 16042 ins_encode %{ 16043 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16044 as_FloatRegister($src$$reg)); 16045 %} 16046 ins_pipe(vdup_reg_dreg128); 16047 %} 16048 16049 // ====================REDUCTION ARITHMETIC==================================== 16050 16051 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 16052 %{ 16053 match(Set dst (AddReductionVI src1 src2)); 16054 ins_cost(INSN_COST); 16055 effect(TEMP tmp, TEMP tmp2); 16056 format %{ "umov $tmp, $src2, S, 0\n\t" 16057 "umov $tmp2, $src2, S, 1\n\t" 16058 "addw $dst, $src1, $tmp\n\t" 16059 "addw $dst, $dst, $tmp2\t add reduction2i" 16060 %} 16061 ins_encode %{ 16062 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16063 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16064 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 16065 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 16066 %} 16067 ins_pipe(pipe_class_default); 16068 %} 16069 16070 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16071 %{ 16072 match(Set dst (AddReductionVI src1 src2)); 16073 ins_cost(INSN_COST); 16074 effect(TEMP tmp, TEMP tmp2); 16075 format %{ "addv $tmp, T4S, $src2\n\t" 16076 "umov $tmp2, $tmp, S, 0\n\t" 16077 "addw $dst, $tmp2, $src1\t add reduction4i" 16078 %} 16079 ins_encode %{ 16080 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 16081 as_FloatRegister($src2$$reg)); 16082 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16083 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 16084 %} 16085 ins_pipe(pipe_class_default); 16086 %} 16087 16088 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 16089 %{ 16090 match(Set dst (MulReductionVI src1 src2)); 16091 ins_cost(INSN_COST); 16092 effect(TEMP tmp, TEMP dst); 16093 format %{ "umov $tmp, $src2, S, 0\n\t" 16094 "mul $dst, $tmp, $src1\n\t" 16095 "umov $tmp, $src2, S, 1\n\t" 16096 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 16097 %} 16098 ins_encode %{ 16099 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16100 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 16101 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16102 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16103 %} 16104 ins_pipe(pipe_class_default); 16105 %} 16106 16107 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16108 %{ 16109 match(Set dst (MulReductionVI src1 src2)); 16110 ins_cost(INSN_COST); 16111 effect(TEMP tmp, TEMP tmp2, TEMP dst); 16112 format %{ "ins $tmp, $src2, 0, 1\n\t" 16113 "mul $tmp, $tmp, $src2\n\t" 16114 "umov $tmp2, $tmp, S, 0\n\t" 16115 "mul $dst, $tmp2, $src1\n\t" 16116 "umov $tmp2, $tmp, S, 1\n\t" 16117 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 16118 %} 16119 ins_encode %{ 16120 __ ins(as_FloatRegister($tmp$$reg), __ D, 16121 as_FloatRegister($src2$$reg), 0, 1); 16122 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 16123 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 16124 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16125 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 16126 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 16127 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 16128 %} 16129 ins_pipe(pipe_class_default); 16130 %} 16131 16132 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16133 %{ 16134 match(Set dst (AddReductionVF src1 src2)); 16135 ins_cost(INSN_COST); 16136 effect(TEMP tmp, TEMP dst); 16137 format %{ "fadds $dst, $src1, $src2\n\t" 16138 "ins $tmp, S, $src2, 0, 1\n\t" 16139 "fadds $dst, $dst, $tmp\t add reduction2f" 16140 %} 16141 ins_encode %{ 16142 __ fadds(as_FloatRegister($dst$$reg), 16143 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16144 __ ins(as_FloatRegister($tmp$$reg), __ S, 16145 as_FloatRegister($src2$$reg), 0, 1); 16146 __ fadds(as_FloatRegister($dst$$reg), 16147 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16148 %} 16149 ins_pipe(pipe_class_default); 16150 %} 16151 16152 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16153 %{ 16154 match(Set dst (AddReductionVF src1 src2)); 16155 ins_cost(INSN_COST); 16156 effect(TEMP tmp, TEMP dst); 16157 format %{ "fadds $dst, $src1, $src2\n\t" 16158 "ins $tmp, S, $src2, 0, 1\n\t" 16159 "fadds $dst, $dst, $tmp\n\t" 16160 "ins $tmp, S, $src2, 0, 2\n\t" 16161 "fadds $dst, $dst, $tmp\n\t" 16162 "ins $tmp, S, $src2, 0, 3\n\t" 16163 "fadds $dst, $dst, $tmp\t add reduction4f" 16164 %} 16165 ins_encode %{ 16166 __ fadds(as_FloatRegister($dst$$reg), 16167 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16168 __ ins(as_FloatRegister($tmp$$reg), __ S, 16169 as_FloatRegister($src2$$reg), 0, 1); 16170 __ fadds(as_FloatRegister($dst$$reg), 16171 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16172 __ ins(as_FloatRegister($tmp$$reg), __ S, 16173 as_FloatRegister($src2$$reg), 0, 2); 16174 __ fadds(as_FloatRegister($dst$$reg), 16175 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16176 __ ins(as_FloatRegister($tmp$$reg), __ S, 16177 as_FloatRegister($src2$$reg), 0, 3); 16178 __ fadds(as_FloatRegister($dst$$reg), 16179 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16180 %} 16181 ins_pipe(pipe_class_default); 16182 %} 16183 16184 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16185 %{ 16186 match(Set dst (MulReductionVF src1 src2)); 16187 ins_cost(INSN_COST); 16188 effect(TEMP tmp, TEMP dst); 16189 format %{ "fmuls $dst, $src1, $src2\n\t" 16190 "ins $tmp, S, $src2, 0, 1\n\t" 16191 "fmuls $dst, $dst, $tmp\t add reduction4f" 16192 %} 16193 ins_encode %{ 16194 __ fmuls(as_FloatRegister($dst$$reg), 16195 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16196 __ ins(as_FloatRegister($tmp$$reg), __ S, 16197 as_FloatRegister($src2$$reg), 0, 1); 16198 __ fmuls(as_FloatRegister($dst$$reg), 16199 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16200 %} 16201 ins_pipe(pipe_class_default); 16202 %} 16203 16204 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16205 %{ 16206 match(Set dst (MulReductionVF src1 src2)); 16207 ins_cost(INSN_COST); 16208 effect(TEMP tmp, TEMP dst); 16209 format %{ "fmuls $dst, $src1, $src2\n\t" 16210 "ins $tmp, S, $src2, 0, 1\n\t" 16211 "fmuls $dst, $dst, $tmp\n\t" 16212 "ins $tmp, S, $src2, 0, 2\n\t" 16213 "fmuls $dst, $dst, $tmp\n\t" 16214 "ins $tmp, S, $src2, 0, 3\n\t" 16215 "fmuls $dst, $dst, $tmp\t add reduction4f" 16216 %} 16217 ins_encode %{ 16218 __ fmuls(as_FloatRegister($dst$$reg), 16219 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16220 __ ins(as_FloatRegister($tmp$$reg), __ S, 16221 as_FloatRegister($src2$$reg), 0, 1); 16222 __ fmuls(as_FloatRegister($dst$$reg), 16223 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16224 __ ins(as_FloatRegister($tmp$$reg), __ S, 16225 as_FloatRegister($src2$$reg), 0, 2); 16226 __ fmuls(as_FloatRegister($dst$$reg), 16227 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16228 __ ins(as_FloatRegister($tmp$$reg), __ S, 16229 as_FloatRegister($src2$$reg), 0, 3); 16230 __ fmuls(as_FloatRegister($dst$$reg), 16231 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16232 %} 16233 ins_pipe(pipe_class_default); 16234 %} 16235 16236 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16237 %{ 16238 match(Set dst (AddReductionVD src1 src2)); 16239 ins_cost(INSN_COST); 16240 effect(TEMP tmp, TEMP dst); 16241 format %{ "faddd $dst, $src1, $src2\n\t" 16242 "ins $tmp, D, $src2, 0, 1\n\t" 16243 "faddd $dst, $dst, $tmp\t add reduction2d" 16244 %} 16245 ins_encode %{ 16246 __ faddd(as_FloatRegister($dst$$reg), 16247 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16248 __ ins(as_FloatRegister($tmp$$reg), __ D, 16249 as_FloatRegister($src2$$reg), 0, 1); 16250 __ faddd(as_FloatRegister($dst$$reg), 16251 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16252 %} 16253 ins_pipe(pipe_class_default); 16254 %} 16255 16256 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16257 %{ 16258 match(Set dst (MulReductionVD src1 src2)); 16259 ins_cost(INSN_COST); 16260 effect(TEMP tmp, TEMP dst); 16261 format %{ "fmuld $dst, $src1, $src2\n\t" 16262 "ins $tmp, D, $src2, 0, 1\n\t" 16263 "fmuld $dst, $dst, $tmp\t add reduction2d" 16264 %} 16265 ins_encode %{ 16266 __ fmuld(as_FloatRegister($dst$$reg), 16267 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16268 __ ins(as_FloatRegister($tmp$$reg), __ D, 16269 as_FloatRegister($src2$$reg), 0, 1); 16270 __ fmuld(as_FloatRegister($dst$$reg), 16271 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16272 %} 16273 ins_pipe(pipe_class_default); 16274 %} 16275 16276 instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16277 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16278 match(Set dst (MaxReductionV src1 src2)); 16279 ins_cost(INSN_COST); 16280 effect(TEMP_DEF dst, TEMP tmp); 16281 format %{ "fmaxs $dst, $src1, $src2\n\t" 16282 "ins $tmp, S, $src2, 0, 1\n\t" 16283 "fmaxs $dst, $dst, $tmp\t max reduction2F" %} 16284 ins_encode %{ 16285 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16286 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16287 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16288 %} 16289 ins_pipe(pipe_class_default); 16290 %} 16291 16292 instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ 16293 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16294 match(Set dst (MaxReductionV src1 src2)); 16295 ins_cost(INSN_COST); 16296 effect(TEMP_DEF dst); 16297 format %{ "fmaxv $dst, T4S, $src2\n\t" 16298 "fmaxs $dst, $dst, $src1\t max reduction4F" %} 16299 ins_encode %{ 16300 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16301 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16302 %} 16303 ins_pipe(pipe_class_default); 16304 %} 16305 16306 instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16307 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16308 match(Set dst (MaxReductionV src1 src2)); 16309 ins_cost(INSN_COST); 16310 effect(TEMP_DEF dst, TEMP tmp); 16311 format %{ "fmaxd $dst, $src1, $src2\n\t" 16312 "ins $tmp, D, $src2, 0, 1\n\t" 16313 "fmaxd $dst, $dst, $tmp\t max reduction2D" %} 16314 ins_encode %{ 16315 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16316 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16317 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16318 %} 16319 ins_pipe(pipe_class_default); 16320 %} 16321 16322 instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16323 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16324 match(Set dst (MinReductionV src1 src2)); 16325 ins_cost(INSN_COST); 16326 effect(TEMP_DEF dst, TEMP tmp); 16327 format %{ "fmins $dst, $src1, $src2\n\t" 16328 "ins $tmp, S, $src2, 0, 1\n\t" 16329 "fmins $dst, $dst, $tmp\t min reduction2F" %} 16330 ins_encode %{ 16331 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16332 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16333 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16334 %} 16335 ins_pipe(pipe_class_default); 16336 %} 16337 16338 instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ 16339 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16340 match(Set dst (MinReductionV src1 src2)); 16341 ins_cost(INSN_COST); 16342 effect(TEMP_DEF dst); 16343 format %{ "fminv $dst, T4S, $src2\n\t" 16344 "fmins $dst, $dst, $src1\t min reduction4F" %} 16345 ins_encode %{ 16346 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16347 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16348 %} 16349 ins_pipe(pipe_class_default); 16350 %} 16351 16352 instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16353 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16354 match(Set dst (MinReductionV src1 src2)); 16355 ins_cost(INSN_COST); 16356 effect(TEMP_DEF dst, TEMP tmp); 16357 format %{ "fmind $dst, $src1, $src2\n\t" 16358 "ins $tmp, D, $src2, 0, 1\n\t" 16359 "fmind $dst, $dst, $tmp\t min reduction2D" %} 16360 ins_encode %{ 16361 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16362 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16363 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16364 %} 16365 ins_pipe(pipe_class_default); 16366 %} 16367 16368 // ====================VECTOR ARITHMETIC======================================= 16369 16370 // --------------------------------- ADD -------------------------------------- 16371 16372 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16373 %{ 16374 predicate(n->as_Vector()->length() == 4 || 16375 n->as_Vector()->length() == 8); 16376 match(Set dst (AddVB src1 src2)); 16377 ins_cost(INSN_COST); 16378 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16379 ins_encode %{ 16380 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16381 as_FloatRegister($src1$$reg), 16382 as_FloatRegister($src2$$reg)); 16383 %} 16384 ins_pipe(vdop64); 16385 %} 16386 16387 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16388 %{ 16389 predicate(n->as_Vector()->length() == 16); 16390 match(Set dst (AddVB src1 src2)); 16391 ins_cost(INSN_COST); 16392 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16393 ins_encode %{ 16394 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16395 as_FloatRegister($src1$$reg), 16396 as_FloatRegister($src2$$reg)); 16397 %} 16398 ins_pipe(vdop128); 16399 %} 16400 16401 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16402 %{ 16403 predicate(n->as_Vector()->length() == 2 || 16404 n->as_Vector()->length() == 4); 16405 match(Set dst (AddVS src1 src2)); 16406 ins_cost(INSN_COST); 16407 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16408 ins_encode %{ 16409 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16410 as_FloatRegister($src1$$reg), 16411 as_FloatRegister($src2$$reg)); 16412 %} 16413 ins_pipe(vdop64); 16414 %} 16415 16416 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16417 %{ 16418 predicate(n->as_Vector()->length() == 8); 16419 match(Set dst (AddVS src1 src2)); 16420 ins_cost(INSN_COST); 16421 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16422 ins_encode %{ 16423 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16424 as_FloatRegister($src1$$reg), 16425 as_FloatRegister($src2$$reg)); 16426 %} 16427 ins_pipe(vdop128); 16428 %} 16429 16430 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16431 %{ 16432 predicate(n->as_Vector()->length() == 2); 16433 match(Set dst (AddVI src1 src2)); 16434 ins_cost(INSN_COST); 16435 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16436 ins_encode %{ 16437 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16438 as_FloatRegister($src1$$reg), 16439 as_FloatRegister($src2$$reg)); 16440 %} 16441 ins_pipe(vdop64); 16442 %} 16443 16444 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16445 %{ 16446 predicate(n->as_Vector()->length() == 4); 16447 match(Set dst (AddVI src1 src2)); 16448 ins_cost(INSN_COST); 16449 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16450 ins_encode %{ 16451 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16452 as_FloatRegister($src1$$reg), 16453 as_FloatRegister($src2$$reg)); 16454 %} 16455 ins_pipe(vdop128); 16456 %} 16457 16458 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16459 %{ 16460 predicate(n->as_Vector()->length() == 2); 16461 match(Set dst (AddVL src1 src2)); 16462 ins_cost(INSN_COST); 16463 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16464 ins_encode %{ 16465 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16466 as_FloatRegister($src1$$reg), 16467 as_FloatRegister($src2$$reg)); 16468 %} 16469 ins_pipe(vdop128); 16470 %} 16471 16472 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16473 %{ 16474 predicate(n->as_Vector()->length() == 2); 16475 match(Set dst (AddVF src1 src2)); 16476 ins_cost(INSN_COST); 16477 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16478 ins_encode %{ 16479 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16480 as_FloatRegister($src1$$reg), 16481 as_FloatRegister($src2$$reg)); 16482 %} 16483 ins_pipe(vdop_fp64); 16484 %} 16485 16486 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16487 %{ 16488 predicate(n->as_Vector()->length() == 4); 16489 match(Set dst (AddVF src1 src2)); 16490 ins_cost(INSN_COST); 16491 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16492 ins_encode %{ 16493 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16494 as_FloatRegister($src1$$reg), 16495 as_FloatRegister($src2$$reg)); 16496 %} 16497 ins_pipe(vdop_fp128); 16498 %} 16499 16500 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16501 %{ 16502 match(Set dst (AddVD src1 src2)); 16503 ins_cost(INSN_COST); 16504 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16505 ins_encode %{ 16506 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16507 as_FloatRegister($src1$$reg), 16508 as_FloatRegister($src2$$reg)); 16509 %} 16510 ins_pipe(vdop_fp128); 16511 %} 16512 16513 // --------------------------------- SUB -------------------------------------- 16514 16515 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16516 %{ 16517 predicate(n->as_Vector()->length() == 4 || 16518 n->as_Vector()->length() == 8); 16519 match(Set dst (SubVB src1 src2)); 16520 ins_cost(INSN_COST); 16521 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16522 ins_encode %{ 16523 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16524 as_FloatRegister($src1$$reg), 16525 as_FloatRegister($src2$$reg)); 16526 %} 16527 ins_pipe(vdop64); 16528 %} 16529 16530 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16531 %{ 16532 predicate(n->as_Vector()->length() == 16); 16533 match(Set dst (SubVB src1 src2)); 16534 ins_cost(INSN_COST); 16535 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16536 ins_encode %{ 16537 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16538 as_FloatRegister($src1$$reg), 16539 as_FloatRegister($src2$$reg)); 16540 %} 16541 ins_pipe(vdop128); 16542 %} 16543 16544 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16545 %{ 16546 predicate(n->as_Vector()->length() == 2 || 16547 n->as_Vector()->length() == 4); 16548 match(Set dst (SubVS src1 src2)); 16549 ins_cost(INSN_COST); 16550 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16551 ins_encode %{ 16552 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16553 as_FloatRegister($src1$$reg), 16554 as_FloatRegister($src2$$reg)); 16555 %} 16556 ins_pipe(vdop64); 16557 %} 16558 16559 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16560 %{ 16561 predicate(n->as_Vector()->length() == 8); 16562 match(Set dst (SubVS src1 src2)); 16563 ins_cost(INSN_COST); 16564 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16565 ins_encode %{ 16566 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16567 as_FloatRegister($src1$$reg), 16568 as_FloatRegister($src2$$reg)); 16569 %} 16570 ins_pipe(vdop128); 16571 %} 16572 16573 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16574 %{ 16575 predicate(n->as_Vector()->length() == 2); 16576 match(Set dst (SubVI src1 src2)); 16577 ins_cost(INSN_COST); 16578 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16579 ins_encode %{ 16580 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16581 as_FloatRegister($src1$$reg), 16582 as_FloatRegister($src2$$reg)); 16583 %} 16584 ins_pipe(vdop64); 16585 %} 16586 16587 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16588 %{ 16589 predicate(n->as_Vector()->length() == 4); 16590 match(Set dst (SubVI src1 src2)); 16591 ins_cost(INSN_COST); 16592 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16593 ins_encode %{ 16594 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16595 as_FloatRegister($src1$$reg), 16596 as_FloatRegister($src2$$reg)); 16597 %} 16598 ins_pipe(vdop128); 16599 %} 16600 16601 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16602 %{ 16603 predicate(n->as_Vector()->length() == 2); 16604 match(Set dst (SubVL src1 src2)); 16605 ins_cost(INSN_COST); 16606 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16607 ins_encode %{ 16608 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16609 as_FloatRegister($src1$$reg), 16610 as_FloatRegister($src2$$reg)); 16611 %} 16612 ins_pipe(vdop128); 16613 %} 16614 16615 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16616 %{ 16617 predicate(n->as_Vector()->length() == 2); 16618 match(Set dst (SubVF src1 src2)); 16619 ins_cost(INSN_COST); 16620 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16621 ins_encode %{ 16622 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16623 as_FloatRegister($src1$$reg), 16624 as_FloatRegister($src2$$reg)); 16625 %} 16626 ins_pipe(vdop_fp64); 16627 %} 16628 16629 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16630 %{ 16631 predicate(n->as_Vector()->length() == 4); 16632 match(Set dst (SubVF src1 src2)); 16633 ins_cost(INSN_COST); 16634 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16635 ins_encode %{ 16636 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16637 as_FloatRegister($src1$$reg), 16638 as_FloatRegister($src2$$reg)); 16639 %} 16640 ins_pipe(vdop_fp128); 16641 %} 16642 16643 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16644 %{ 16645 predicate(n->as_Vector()->length() == 2); 16646 match(Set dst (SubVD src1 src2)); 16647 ins_cost(INSN_COST); 16648 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16649 ins_encode %{ 16650 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16651 as_FloatRegister($src1$$reg), 16652 as_FloatRegister($src2$$reg)); 16653 %} 16654 ins_pipe(vdop_fp128); 16655 %} 16656 16657 // --------------------------------- MUL -------------------------------------- 16658 16659 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16660 %{ 16661 predicate(n->as_Vector()->length() == 2 || 16662 n->as_Vector()->length() == 4); 16663 match(Set dst (MulVS src1 src2)); 16664 ins_cost(INSN_COST); 16665 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16666 ins_encode %{ 16667 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16668 as_FloatRegister($src1$$reg), 16669 as_FloatRegister($src2$$reg)); 16670 %} 16671 ins_pipe(vmul64); 16672 %} 16673 16674 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16675 %{ 16676 predicate(n->as_Vector()->length() == 8); 16677 match(Set dst (MulVS src1 src2)); 16678 ins_cost(INSN_COST); 16679 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16680 ins_encode %{ 16681 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16682 as_FloatRegister($src1$$reg), 16683 as_FloatRegister($src2$$reg)); 16684 %} 16685 ins_pipe(vmul128); 16686 %} 16687 16688 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16689 %{ 16690 predicate(n->as_Vector()->length() == 2); 16691 match(Set dst (MulVI src1 src2)); 16692 ins_cost(INSN_COST); 16693 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16694 ins_encode %{ 16695 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16696 as_FloatRegister($src1$$reg), 16697 as_FloatRegister($src2$$reg)); 16698 %} 16699 ins_pipe(vmul64); 16700 %} 16701 16702 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16703 %{ 16704 predicate(n->as_Vector()->length() == 4); 16705 match(Set dst (MulVI src1 src2)); 16706 ins_cost(INSN_COST); 16707 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16708 ins_encode %{ 16709 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16710 as_FloatRegister($src1$$reg), 16711 as_FloatRegister($src2$$reg)); 16712 %} 16713 ins_pipe(vmul128); 16714 %} 16715 16716 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16717 %{ 16718 predicate(n->as_Vector()->length() == 2); 16719 match(Set dst (MulVF src1 src2)); 16720 ins_cost(INSN_COST); 16721 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16722 ins_encode %{ 16723 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16724 as_FloatRegister($src1$$reg), 16725 as_FloatRegister($src2$$reg)); 16726 %} 16727 ins_pipe(vmuldiv_fp64); 16728 %} 16729 16730 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16731 %{ 16732 predicate(n->as_Vector()->length() == 4); 16733 match(Set dst (MulVF src1 src2)); 16734 ins_cost(INSN_COST); 16735 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16736 ins_encode %{ 16737 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16738 as_FloatRegister($src1$$reg), 16739 as_FloatRegister($src2$$reg)); 16740 %} 16741 ins_pipe(vmuldiv_fp128); 16742 %} 16743 16744 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16745 %{ 16746 predicate(n->as_Vector()->length() == 2); 16747 match(Set dst (MulVD src1 src2)); 16748 ins_cost(INSN_COST); 16749 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16750 ins_encode %{ 16751 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16752 as_FloatRegister($src1$$reg), 16753 as_FloatRegister($src2$$reg)); 16754 %} 16755 ins_pipe(vmuldiv_fp128); 16756 %} 16757 16758 // --------------------------------- MLA -------------------------------------- 16759 16760 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16761 %{ 16762 predicate(n->as_Vector()->length() == 2 || 16763 n->as_Vector()->length() == 4); 16764 match(Set dst (AddVS dst (MulVS src1 src2))); 16765 ins_cost(INSN_COST); 16766 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16767 ins_encode %{ 16768 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16769 as_FloatRegister($src1$$reg), 16770 as_FloatRegister($src2$$reg)); 16771 %} 16772 ins_pipe(vmla64); 16773 %} 16774 16775 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16776 %{ 16777 predicate(n->as_Vector()->length() == 8); 16778 match(Set dst (AddVS dst (MulVS src1 src2))); 16779 ins_cost(INSN_COST); 16780 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16781 ins_encode %{ 16782 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16783 as_FloatRegister($src1$$reg), 16784 as_FloatRegister($src2$$reg)); 16785 %} 16786 ins_pipe(vmla128); 16787 %} 16788 16789 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16790 %{ 16791 predicate(n->as_Vector()->length() == 2); 16792 match(Set dst (AddVI dst (MulVI src1 src2))); 16793 ins_cost(INSN_COST); 16794 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16795 ins_encode %{ 16796 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16797 as_FloatRegister($src1$$reg), 16798 as_FloatRegister($src2$$reg)); 16799 %} 16800 ins_pipe(vmla64); 16801 %} 16802 16803 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16804 %{ 16805 predicate(n->as_Vector()->length() == 4); 16806 match(Set dst (AddVI dst (MulVI src1 src2))); 16807 ins_cost(INSN_COST); 16808 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16809 ins_encode %{ 16810 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16811 as_FloatRegister($src1$$reg), 16812 as_FloatRegister($src2$$reg)); 16813 %} 16814 ins_pipe(vmla128); 16815 %} 16816 16817 // dst + src1 * src2 16818 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16819 predicate(UseFMA && n->as_Vector()->length() == 2); 16820 match(Set dst (FmaVF dst (Binary src1 src2))); 16821 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16822 ins_cost(INSN_COST); 16823 ins_encode %{ 16824 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16825 as_FloatRegister($src1$$reg), 16826 as_FloatRegister($src2$$reg)); 16827 %} 16828 ins_pipe(vmuldiv_fp64); 16829 %} 16830 16831 // dst + src1 * src2 16832 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16833 predicate(UseFMA && n->as_Vector()->length() == 4); 16834 match(Set dst (FmaVF dst (Binary src1 src2))); 16835 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16836 ins_cost(INSN_COST); 16837 ins_encode %{ 16838 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16839 as_FloatRegister($src1$$reg), 16840 as_FloatRegister($src2$$reg)); 16841 %} 16842 ins_pipe(vmuldiv_fp128); 16843 %} 16844 16845 // dst + src1 * src2 16846 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16847 predicate(UseFMA && n->as_Vector()->length() == 2); 16848 match(Set dst (FmaVD dst (Binary src1 src2))); 16849 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16850 ins_cost(INSN_COST); 16851 ins_encode %{ 16852 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16853 as_FloatRegister($src1$$reg), 16854 as_FloatRegister($src2$$reg)); 16855 %} 16856 ins_pipe(vmuldiv_fp128); 16857 %} 16858 16859 // --------------------------------- MLS -------------------------------------- 16860 16861 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16862 %{ 16863 predicate(n->as_Vector()->length() == 2 || 16864 n->as_Vector()->length() == 4); 16865 match(Set dst (SubVS dst (MulVS src1 src2))); 16866 ins_cost(INSN_COST); 16867 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16868 ins_encode %{ 16869 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16870 as_FloatRegister($src1$$reg), 16871 as_FloatRegister($src2$$reg)); 16872 %} 16873 ins_pipe(vmla64); 16874 %} 16875 16876 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16877 %{ 16878 predicate(n->as_Vector()->length() == 8); 16879 match(Set dst (SubVS dst (MulVS src1 src2))); 16880 ins_cost(INSN_COST); 16881 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16882 ins_encode %{ 16883 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16884 as_FloatRegister($src1$$reg), 16885 as_FloatRegister($src2$$reg)); 16886 %} 16887 ins_pipe(vmla128); 16888 %} 16889 16890 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16891 %{ 16892 predicate(n->as_Vector()->length() == 2); 16893 match(Set dst (SubVI dst (MulVI src1 src2))); 16894 ins_cost(INSN_COST); 16895 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16896 ins_encode %{ 16897 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16898 as_FloatRegister($src1$$reg), 16899 as_FloatRegister($src2$$reg)); 16900 %} 16901 ins_pipe(vmla64); 16902 %} 16903 16904 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16905 %{ 16906 predicate(n->as_Vector()->length() == 4); 16907 match(Set dst (SubVI dst (MulVI src1 src2))); 16908 ins_cost(INSN_COST); 16909 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16910 ins_encode %{ 16911 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16912 as_FloatRegister($src1$$reg), 16913 as_FloatRegister($src2$$reg)); 16914 %} 16915 ins_pipe(vmla128); 16916 %} 16917 16918 // dst - src1 * src2 16919 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16920 predicate(UseFMA && n->as_Vector()->length() == 2); 16921 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16922 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16923 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16924 ins_cost(INSN_COST); 16925 ins_encode %{ 16926 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16927 as_FloatRegister($src1$$reg), 16928 as_FloatRegister($src2$$reg)); 16929 %} 16930 ins_pipe(vmuldiv_fp64); 16931 %} 16932 16933 // dst - src1 * src2 16934 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16935 predicate(UseFMA && n->as_Vector()->length() == 4); 16936 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16937 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16938 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16939 ins_cost(INSN_COST); 16940 ins_encode %{ 16941 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16942 as_FloatRegister($src1$$reg), 16943 as_FloatRegister($src2$$reg)); 16944 %} 16945 ins_pipe(vmuldiv_fp128); 16946 %} 16947 16948 // dst - src1 * src2 16949 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16950 predicate(UseFMA && n->as_Vector()->length() == 2); 16951 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16952 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16953 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16954 ins_cost(INSN_COST); 16955 ins_encode %{ 16956 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16957 as_FloatRegister($src1$$reg), 16958 as_FloatRegister($src2$$reg)); 16959 %} 16960 ins_pipe(vmuldiv_fp128); 16961 %} 16962 16963 // --------------- Vector Multiply-Add Shorts into Integer -------------------- 16964 16965 instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 16966 predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); 16967 match(Set dst (MulAddVS2VI src1 src2)); 16968 ins_cost(INSN_COST); 16969 effect(TEMP tmp); 16970 format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" 16971 "smullv $dst, $src1, $src2\t# vector (8H)\n\t" 16972 "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} 16973 ins_encode %{ 16974 __ smullv(as_FloatRegister($tmp$$reg), __ T4H, 16975 as_FloatRegister($src1$$reg), 16976 as_FloatRegister($src2$$reg)); 16977 __ smullv(as_FloatRegister($dst$$reg), __ T8H, 16978 as_FloatRegister($src1$$reg), 16979 as_FloatRegister($src2$$reg)); 16980 __ addpv(as_FloatRegister($dst$$reg), __ T4S, 16981 as_FloatRegister($tmp$$reg), 16982 as_FloatRegister($dst$$reg)); 16983 %} 16984 ins_pipe(vmuldiv_fp128); 16985 %} 16986 16987 // --------------------------------- DIV -------------------------------------- 16988 16989 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16990 %{ 16991 predicate(n->as_Vector()->length() == 2); 16992 match(Set dst (DivVF src1 src2)); 16993 ins_cost(INSN_COST); 16994 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16995 ins_encode %{ 16996 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16997 as_FloatRegister($src1$$reg), 16998 as_FloatRegister($src2$$reg)); 16999 %} 17000 ins_pipe(vmuldiv_fp64); 17001 %} 17002 17003 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 17004 %{ 17005 predicate(n->as_Vector()->length() == 4); 17006 match(Set dst (DivVF src1 src2)); 17007 ins_cost(INSN_COST); 17008 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 17009 ins_encode %{ 17010 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 17011 as_FloatRegister($src1$$reg), 17012 as_FloatRegister($src2$$reg)); 17013 %} 17014 ins_pipe(vmuldiv_fp128); 17015 %} 17016 17017 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17018 %{ 17019 predicate(n->as_Vector()->length() == 2); 17020 match(Set dst (DivVD src1 src2)); 17021 ins_cost(INSN_COST); 17022 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17023 ins_encode %{ 17024 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17025 as_FloatRegister($src1$$reg), 17026 as_FloatRegister($src2$$reg)); 17027 %} 17028 ins_pipe(vmuldiv_fp128); 17029 %} 17030 17031 // --------------------------------- SQRT ------------------------------------- 17032 17033 instruct vsqrt2D(vecX dst, vecX src) 17034 %{ 17035 predicate(n->as_Vector()->length() == 2); 17036 match(Set dst (SqrtVD src)); 17037 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17038 ins_encode %{ 17039 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17040 as_FloatRegister($src$$reg)); 17041 %} 17042 ins_pipe(vsqrt_fp128); 17043 %} 17044 17045 // --------------------------------- ABS -------------------------------------- 17046 17047 instruct vabs2F(vecD dst, vecD src) 17048 %{ 17049 predicate(n->as_Vector()->length() == 2); 17050 match(Set dst (AbsVF src)); 17051 ins_cost(INSN_COST * 3); 17052 format %{ "fabs $dst,$src\t# vector (2S)" %} 17053 ins_encode %{ 17054 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 17055 as_FloatRegister($src$$reg)); 17056 %} 17057 ins_pipe(vunop_fp64); 17058 %} 17059 17060 instruct vabs4F(vecX dst, vecX src) 17061 %{ 17062 predicate(n->as_Vector()->length() == 4); 17063 match(Set dst (AbsVF src)); 17064 ins_cost(INSN_COST * 3); 17065 format %{ "fabs $dst,$src\t# vector (4S)" %} 17066 ins_encode %{ 17067 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 17068 as_FloatRegister($src$$reg)); 17069 %} 17070 ins_pipe(vunop_fp128); 17071 %} 17072 17073 instruct vabs2D(vecX dst, vecX src) 17074 %{ 17075 predicate(n->as_Vector()->length() == 2); 17076 match(Set dst (AbsVD src)); 17077 ins_cost(INSN_COST * 3); 17078 format %{ "fabs $dst,$src\t# vector (2D)" %} 17079 ins_encode %{ 17080 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17081 as_FloatRegister($src$$reg)); 17082 %} 17083 ins_pipe(vunop_fp128); 17084 %} 17085 17086 // --------------------------------- NEG -------------------------------------- 17087 17088 instruct vneg2F(vecD dst, vecD src) 17089 %{ 17090 predicate(n->as_Vector()->length() == 2); 17091 match(Set dst (NegVF src)); 17092 ins_cost(INSN_COST * 3); 17093 format %{ "fneg $dst,$src\t# vector (2S)" %} 17094 ins_encode %{ 17095 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17096 as_FloatRegister($src$$reg)); 17097 %} 17098 ins_pipe(vunop_fp64); 17099 %} 17100 17101 instruct vneg4F(vecX dst, vecX src) 17102 %{ 17103 predicate(n->as_Vector()->length() == 4); 17104 match(Set dst (NegVF src)); 17105 ins_cost(INSN_COST * 3); 17106 format %{ "fneg $dst,$src\t# vector (4S)" %} 17107 ins_encode %{ 17108 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17109 as_FloatRegister($src$$reg)); 17110 %} 17111 ins_pipe(vunop_fp128); 17112 %} 17113 17114 instruct vneg2D(vecX dst, vecX src) 17115 %{ 17116 predicate(n->as_Vector()->length() == 2); 17117 match(Set dst (NegVD src)); 17118 ins_cost(INSN_COST * 3); 17119 format %{ "fneg $dst,$src\t# vector (2D)" %} 17120 ins_encode %{ 17121 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17122 as_FloatRegister($src$$reg)); 17123 %} 17124 ins_pipe(vunop_fp128); 17125 %} 17126 17127 // --------------------------------- AND -------------------------------------- 17128 17129 instruct vand8B(vecD dst, vecD src1, vecD src2) 17130 %{ 17131 predicate(n->as_Vector()->length_in_bytes() == 4 || 17132 n->as_Vector()->length_in_bytes() == 8); 17133 match(Set dst (AndV src1 src2)); 17134 ins_cost(INSN_COST); 17135 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17136 ins_encode %{ 17137 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17138 as_FloatRegister($src1$$reg), 17139 as_FloatRegister($src2$$reg)); 17140 %} 17141 ins_pipe(vlogical64); 17142 %} 17143 17144 instruct vand16B(vecX dst, vecX src1, vecX src2) 17145 %{ 17146 predicate(n->as_Vector()->length_in_bytes() == 16); 17147 match(Set dst (AndV src1 src2)); 17148 ins_cost(INSN_COST); 17149 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17150 ins_encode %{ 17151 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17152 as_FloatRegister($src1$$reg), 17153 as_FloatRegister($src2$$reg)); 17154 %} 17155 ins_pipe(vlogical128); 17156 %} 17157 17158 // --------------------------------- OR --------------------------------------- 17159 17160 instruct vor8B(vecD dst, vecD src1, vecD src2) 17161 %{ 17162 predicate(n->as_Vector()->length_in_bytes() == 4 || 17163 n->as_Vector()->length_in_bytes() == 8); 17164 match(Set dst (OrV src1 src2)); 17165 ins_cost(INSN_COST); 17166 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17167 ins_encode %{ 17168 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17169 as_FloatRegister($src1$$reg), 17170 as_FloatRegister($src2$$reg)); 17171 %} 17172 ins_pipe(vlogical64); 17173 %} 17174 17175 instruct vor16B(vecX dst, vecX src1, vecX src2) 17176 %{ 17177 predicate(n->as_Vector()->length_in_bytes() == 16); 17178 match(Set dst (OrV src1 src2)); 17179 ins_cost(INSN_COST); 17180 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17181 ins_encode %{ 17182 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17183 as_FloatRegister($src1$$reg), 17184 as_FloatRegister($src2$$reg)); 17185 %} 17186 ins_pipe(vlogical128); 17187 %} 17188 17189 // --------------------------------- XOR -------------------------------------- 17190 17191 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17192 %{ 17193 predicate(n->as_Vector()->length_in_bytes() == 4 || 17194 n->as_Vector()->length_in_bytes() == 8); 17195 match(Set dst (XorV src1 src2)); 17196 ins_cost(INSN_COST); 17197 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17198 ins_encode %{ 17199 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17200 as_FloatRegister($src1$$reg), 17201 as_FloatRegister($src2$$reg)); 17202 %} 17203 ins_pipe(vlogical64); 17204 %} 17205 17206 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17207 %{ 17208 predicate(n->as_Vector()->length_in_bytes() == 16); 17209 match(Set dst (XorV src1 src2)); 17210 ins_cost(INSN_COST); 17211 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17212 ins_encode %{ 17213 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17214 as_FloatRegister($src1$$reg), 17215 as_FloatRegister($src2$$reg)); 17216 %} 17217 ins_pipe(vlogical128); 17218 %} 17219 17220 // ------------------------------ Shift --------------------------------------- 17221 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17222 predicate(n->as_Vector()->length_in_bytes() == 8); 17223 match(Set dst (LShiftCntV cnt)); 17224 match(Set dst (RShiftCntV cnt)); 17225 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17226 ins_encode %{ 17227 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17228 %} 17229 ins_pipe(vdup_reg_reg64); 17230 %} 17231 17232 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17233 predicate(n->as_Vector()->length_in_bytes() == 16); 17234 match(Set dst (LShiftCntV cnt)); 17235 match(Set dst (RShiftCntV cnt)); 17236 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17237 ins_encode %{ 17238 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17239 %} 17240 ins_pipe(vdup_reg_reg128); 17241 %} 17242 17243 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17244 predicate(n->as_Vector()->length() == 4 || 17245 n->as_Vector()->length() == 8); 17246 match(Set dst (LShiftVB src shift)); 17247 ins_cost(INSN_COST); 17248 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17249 ins_encode %{ 17250 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17251 as_FloatRegister($src$$reg), 17252 as_FloatRegister($shift$$reg)); 17253 %} 17254 ins_pipe(vshift64); 17255 %} 17256 17257 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17258 predicate(n->as_Vector()->length() == 16); 17259 match(Set dst (LShiftVB src shift)); 17260 ins_cost(INSN_COST); 17261 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17262 ins_encode %{ 17263 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17264 as_FloatRegister($src$$reg), 17265 as_FloatRegister($shift$$reg)); 17266 %} 17267 ins_pipe(vshift128); 17268 %} 17269 17270 // Right shifts with vector shift count on aarch64 SIMD are implemented 17271 // as left shift by negative shift count. 17272 // There are two cases for vector shift count. 17273 // 17274 // Case 1: The vector shift count is from replication. 17275 // | | 17276 // LoadVector RShiftCntV 17277 // | / 17278 // RShiftVI 17279 // Note: In inner loop, multiple neg instructions are used, which can be 17280 // moved to outer loop and merge into one neg instruction. 17281 // 17282 // Case 2: The vector shift count is from loading. 17283 // This case isn't supported by middle-end now. But it's supported by 17284 // panama/vectorIntrinsics(JEP 338: Vector API). 17285 // | | 17286 // LoadVector LoadVector 17287 // | / 17288 // RShiftVI 17289 // 17290 17291 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17292 predicate(n->as_Vector()->length() == 4 || 17293 n->as_Vector()->length() == 8); 17294 match(Set dst (RShiftVB src shift)); 17295 ins_cost(INSN_COST); 17296 effect(TEMP tmp); 17297 format %{ "negr $tmp,$shift\t" 17298 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17299 ins_encode %{ 17300 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17301 as_FloatRegister($shift$$reg)); 17302 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17303 as_FloatRegister($src$$reg), 17304 as_FloatRegister($tmp$$reg)); 17305 %} 17306 ins_pipe(vshift64); 17307 %} 17308 17309 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17310 predicate(n->as_Vector()->length() == 16); 17311 match(Set dst (RShiftVB src shift)); 17312 ins_cost(INSN_COST); 17313 effect(TEMP tmp); 17314 format %{ "negr $tmp,$shift\t" 17315 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17316 ins_encode %{ 17317 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17318 as_FloatRegister($shift$$reg)); 17319 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17320 as_FloatRegister($src$$reg), 17321 as_FloatRegister($tmp$$reg)); 17322 %} 17323 ins_pipe(vshift128); 17324 %} 17325 17326 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17327 predicate(n->as_Vector()->length() == 4 || 17328 n->as_Vector()->length() == 8); 17329 match(Set dst (URShiftVB src shift)); 17330 ins_cost(INSN_COST); 17331 effect(TEMP tmp); 17332 format %{ "negr $tmp,$shift\t" 17333 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17334 ins_encode %{ 17335 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17336 as_FloatRegister($shift$$reg)); 17337 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17338 as_FloatRegister($src$$reg), 17339 as_FloatRegister($tmp$$reg)); 17340 %} 17341 ins_pipe(vshift64); 17342 %} 17343 17344 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17345 predicate(n->as_Vector()->length() == 16); 17346 match(Set dst (URShiftVB src shift)); 17347 ins_cost(INSN_COST); 17348 effect(TEMP tmp); 17349 format %{ "negr $tmp,$shift\t" 17350 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17351 ins_encode %{ 17352 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17353 as_FloatRegister($shift$$reg)); 17354 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17355 as_FloatRegister($src$$reg), 17356 as_FloatRegister($tmp$$reg)); 17357 %} 17358 ins_pipe(vshift128); 17359 %} 17360 17361 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17362 predicate(n->as_Vector()->length() == 4 || 17363 n->as_Vector()->length() == 8); 17364 match(Set dst (LShiftVB src (LShiftCntV shift))); 17365 ins_cost(INSN_COST); 17366 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17367 ins_encode %{ 17368 int sh = (int)$shift$$constant; 17369 if (sh >= 8) { 17370 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17371 as_FloatRegister($src$$reg), 17372 as_FloatRegister($src$$reg)); 17373 } else { 17374 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17375 as_FloatRegister($src$$reg), sh); 17376 } 17377 %} 17378 ins_pipe(vshift64_imm); 17379 %} 17380 17381 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17382 predicate(n->as_Vector()->length() == 16); 17383 match(Set dst (LShiftVB src (LShiftCntV shift))); 17384 ins_cost(INSN_COST); 17385 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17386 ins_encode %{ 17387 int sh = (int)$shift$$constant; 17388 if (sh >= 8) { 17389 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17390 as_FloatRegister($src$$reg), 17391 as_FloatRegister($src$$reg)); 17392 } else { 17393 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17394 as_FloatRegister($src$$reg), sh); 17395 } 17396 %} 17397 ins_pipe(vshift128_imm); 17398 %} 17399 17400 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17401 predicate(n->as_Vector()->length() == 4 || 17402 n->as_Vector()->length() == 8); 17403 match(Set dst (RShiftVB src (RShiftCntV shift))); 17404 ins_cost(INSN_COST); 17405 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17406 ins_encode %{ 17407 int sh = (int)$shift$$constant; 17408 if (sh >= 8) sh = 7; 17409 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17410 as_FloatRegister($src$$reg), sh); 17411 %} 17412 ins_pipe(vshift64_imm); 17413 %} 17414 17415 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17416 predicate(n->as_Vector()->length() == 16); 17417 match(Set dst (RShiftVB src (RShiftCntV shift))); 17418 ins_cost(INSN_COST); 17419 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17420 ins_encode %{ 17421 int sh = (int)$shift$$constant; 17422 if (sh >= 8) sh = 7; 17423 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17424 as_FloatRegister($src$$reg), sh); 17425 %} 17426 ins_pipe(vshift128_imm); 17427 %} 17428 17429 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17430 predicate(n->as_Vector()->length() == 4 || 17431 n->as_Vector()->length() == 8); 17432 match(Set dst (URShiftVB src (RShiftCntV shift))); 17433 ins_cost(INSN_COST); 17434 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17435 ins_encode %{ 17436 int sh = (int)$shift$$constant; 17437 if (sh >= 8) { 17438 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17439 as_FloatRegister($src$$reg), 17440 as_FloatRegister($src$$reg)); 17441 } else { 17442 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17443 as_FloatRegister($src$$reg), sh); 17444 } 17445 %} 17446 ins_pipe(vshift64_imm); 17447 %} 17448 17449 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17450 predicate(n->as_Vector()->length() == 16); 17451 match(Set dst (URShiftVB src (RShiftCntV shift))); 17452 ins_cost(INSN_COST); 17453 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17454 ins_encode %{ 17455 int sh = (int)$shift$$constant; 17456 if (sh >= 8) { 17457 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17458 as_FloatRegister($src$$reg), 17459 as_FloatRegister($src$$reg)); 17460 } else { 17461 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17462 as_FloatRegister($src$$reg), sh); 17463 } 17464 %} 17465 ins_pipe(vshift128_imm); 17466 %} 17467 17468 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17469 predicate(n->as_Vector()->length() == 2 || 17470 n->as_Vector()->length() == 4); 17471 match(Set dst (LShiftVS src shift)); 17472 ins_cost(INSN_COST); 17473 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17474 ins_encode %{ 17475 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17476 as_FloatRegister($src$$reg), 17477 as_FloatRegister($shift$$reg)); 17478 %} 17479 ins_pipe(vshift64); 17480 %} 17481 17482 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17483 predicate(n->as_Vector()->length() == 8); 17484 match(Set dst (LShiftVS src shift)); 17485 ins_cost(INSN_COST); 17486 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17487 ins_encode %{ 17488 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17489 as_FloatRegister($src$$reg), 17490 as_FloatRegister($shift$$reg)); 17491 %} 17492 ins_pipe(vshift128); 17493 %} 17494 17495 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17496 predicate(n->as_Vector()->length() == 2 || 17497 n->as_Vector()->length() == 4); 17498 match(Set dst (RShiftVS src shift)); 17499 ins_cost(INSN_COST); 17500 effect(TEMP tmp); 17501 format %{ "negr $tmp,$shift\t" 17502 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17503 ins_encode %{ 17504 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17505 as_FloatRegister($shift$$reg)); 17506 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17507 as_FloatRegister($src$$reg), 17508 as_FloatRegister($tmp$$reg)); 17509 %} 17510 ins_pipe(vshift64); 17511 %} 17512 17513 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17514 predicate(n->as_Vector()->length() == 8); 17515 match(Set dst (RShiftVS src shift)); 17516 ins_cost(INSN_COST); 17517 effect(TEMP tmp); 17518 format %{ "negr $tmp,$shift\t" 17519 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17520 ins_encode %{ 17521 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17522 as_FloatRegister($shift$$reg)); 17523 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17524 as_FloatRegister($src$$reg), 17525 as_FloatRegister($tmp$$reg)); 17526 %} 17527 ins_pipe(vshift128); 17528 %} 17529 17530 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17531 predicate(n->as_Vector()->length() == 2 || 17532 n->as_Vector()->length() == 4); 17533 match(Set dst (URShiftVS src shift)); 17534 ins_cost(INSN_COST); 17535 effect(TEMP tmp); 17536 format %{ "negr $tmp,$shift\t" 17537 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17538 ins_encode %{ 17539 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17540 as_FloatRegister($shift$$reg)); 17541 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17542 as_FloatRegister($src$$reg), 17543 as_FloatRegister($tmp$$reg)); 17544 %} 17545 ins_pipe(vshift64); 17546 %} 17547 17548 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17549 predicate(n->as_Vector()->length() == 8); 17550 match(Set dst (URShiftVS src shift)); 17551 ins_cost(INSN_COST); 17552 effect(TEMP tmp); 17553 format %{ "negr $tmp,$shift\t" 17554 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17555 ins_encode %{ 17556 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17557 as_FloatRegister($shift$$reg)); 17558 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17559 as_FloatRegister($src$$reg), 17560 as_FloatRegister($tmp$$reg)); 17561 %} 17562 ins_pipe(vshift128); 17563 %} 17564 17565 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17566 predicate(n->as_Vector()->length() == 2 || 17567 n->as_Vector()->length() == 4); 17568 match(Set dst (LShiftVS src (LShiftCntV shift))); 17569 ins_cost(INSN_COST); 17570 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17571 ins_encode %{ 17572 int sh = (int)$shift$$constant; 17573 if (sh >= 16) { 17574 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17575 as_FloatRegister($src$$reg), 17576 as_FloatRegister($src$$reg)); 17577 } else { 17578 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17579 as_FloatRegister($src$$reg), sh); 17580 } 17581 %} 17582 ins_pipe(vshift64_imm); 17583 %} 17584 17585 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17586 predicate(n->as_Vector()->length() == 8); 17587 match(Set dst (LShiftVS src (LShiftCntV shift))); 17588 ins_cost(INSN_COST); 17589 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17590 ins_encode %{ 17591 int sh = (int)$shift$$constant; 17592 if (sh >= 16) { 17593 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17594 as_FloatRegister($src$$reg), 17595 as_FloatRegister($src$$reg)); 17596 } else { 17597 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17598 as_FloatRegister($src$$reg), sh); 17599 } 17600 %} 17601 ins_pipe(vshift128_imm); 17602 %} 17603 17604 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17605 predicate(n->as_Vector()->length() == 2 || 17606 n->as_Vector()->length() == 4); 17607 match(Set dst (RShiftVS src (LShiftCntV shift))); 17608 ins_cost(INSN_COST); 17609 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17610 ins_encode %{ 17611 int sh = (int)$shift$$constant; 17612 if (sh >= 16) sh = 15; 17613 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17614 as_FloatRegister($src$$reg), sh); 17615 %} 17616 ins_pipe(vshift64_imm); 17617 %} 17618 17619 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17620 predicate(n->as_Vector()->length() == 8); 17621 match(Set dst (RShiftVS src (LShiftCntV shift))); 17622 ins_cost(INSN_COST); 17623 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17624 ins_encode %{ 17625 int sh = (int)$shift$$constant; 17626 if (sh >= 16) sh = 15; 17627 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17628 as_FloatRegister($src$$reg), sh); 17629 %} 17630 ins_pipe(vshift128_imm); 17631 %} 17632 17633 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17634 predicate(n->as_Vector()->length() == 2 || 17635 n->as_Vector()->length() == 4); 17636 match(Set dst (URShiftVS src (RShiftCntV shift))); 17637 ins_cost(INSN_COST); 17638 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17639 ins_encode %{ 17640 int sh = (int)$shift$$constant; 17641 if (sh >= 16) { 17642 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17643 as_FloatRegister($src$$reg), 17644 as_FloatRegister($src$$reg)); 17645 } else { 17646 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17647 as_FloatRegister($src$$reg), sh); 17648 } 17649 %} 17650 ins_pipe(vshift64_imm); 17651 %} 17652 17653 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17654 predicate(n->as_Vector()->length() == 8); 17655 match(Set dst (URShiftVS src (RShiftCntV shift))); 17656 ins_cost(INSN_COST); 17657 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17658 ins_encode %{ 17659 int sh = (int)$shift$$constant; 17660 if (sh >= 16) { 17661 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17662 as_FloatRegister($src$$reg), 17663 as_FloatRegister($src$$reg)); 17664 } else { 17665 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17666 as_FloatRegister($src$$reg), sh); 17667 } 17668 %} 17669 ins_pipe(vshift128_imm); 17670 %} 17671 17672 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17673 predicate(n->as_Vector()->length() == 2); 17674 match(Set dst (LShiftVI src shift)); 17675 ins_cost(INSN_COST); 17676 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17677 ins_encode %{ 17678 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17679 as_FloatRegister($src$$reg), 17680 as_FloatRegister($shift$$reg)); 17681 %} 17682 ins_pipe(vshift64); 17683 %} 17684 17685 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17686 predicate(n->as_Vector()->length() == 4); 17687 match(Set dst (LShiftVI src shift)); 17688 ins_cost(INSN_COST); 17689 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17690 ins_encode %{ 17691 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17692 as_FloatRegister($src$$reg), 17693 as_FloatRegister($shift$$reg)); 17694 %} 17695 ins_pipe(vshift128); 17696 %} 17697 17698 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17699 predicate(n->as_Vector()->length() == 2); 17700 match(Set dst (RShiftVI src shift)); 17701 ins_cost(INSN_COST); 17702 effect(TEMP tmp); 17703 format %{ "negr $tmp,$shift\t" 17704 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17705 ins_encode %{ 17706 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17707 as_FloatRegister($shift$$reg)); 17708 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17709 as_FloatRegister($src$$reg), 17710 as_FloatRegister($tmp$$reg)); 17711 %} 17712 ins_pipe(vshift64); 17713 %} 17714 17715 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17716 predicate(n->as_Vector()->length() == 4); 17717 match(Set dst (RShiftVI src shift)); 17718 ins_cost(INSN_COST); 17719 effect(TEMP tmp); 17720 format %{ "negr $tmp,$shift\t" 17721 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17722 ins_encode %{ 17723 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17724 as_FloatRegister($shift$$reg)); 17725 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17726 as_FloatRegister($src$$reg), 17727 as_FloatRegister($tmp$$reg)); 17728 %} 17729 ins_pipe(vshift128); 17730 %} 17731 17732 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17733 predicate(n->as_Vector()->length() == 2); 17734 match(Set dst (URShiftVI src shift)); 17735 ins_cost(INSN_COST); 17736 effect(TEMP tmp); 17737 format %{ "negr $tmp,$shift\t" 17738 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17739 ins_encode %{ 17740 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17741 as_FloatRegister($shift$$reg)); 17742 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17743 as_FloatRegister($src$$reg), 17744 as_FloatRegister($tmp$$reg)); 17745 %} 17746 ins_pipe(vshift64); 17747 %} 17748 17749 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17750 predicate(n->as_Vector()->length() == 4); 17751 match(Set dst (URShiftVI src shift)); 17752 ins_cost(INSN_COST); 17753 effect(TEMP tmp); 17754 format %{ "negr $tmp,$shift\t" 17755 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17756 ins_encode %{ 17757 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17758 as_FloatRegister($shift$$reg)); 17759 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17760 as_FloatRegister($src$$reg), 17761 as_FloatRegister($tmp$$reg)); 17762 %} 17763 ins_pipe(vshift128); 17764 %} 17765 17766 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17767 predicate(n->as_Vector()->length() == 2); 17768 match(Set dst (LShiftVI src (LShiftCntV shift))); 17769 ins_cost(INSN_COST); 17770 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17771 ins_encode %{ 17772 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17773 as_FloatRegister($src$$reg), 17774 (int)$shift$$constant); 17775 %} 17776 ins_pipe(vshift64_imm); 17777 %} 17778 17779 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17780 predicate(n->as_Vector()->length() == 4); 17781 match(Set dst (LShiftVI src (LShiftCntV shift))); 17782 ins_cost(INSN_COST); 17783 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17784 ins_encode %{ 17785 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17786 as_FloatRegister($src$$reg), 17787 (int)$shift$$constant); 17788 %} 17789 ins_pipe(vshift128_imm); 17790 %} 17791 17792 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17793 predicate(n->as_Vector()->length() == 2); 17794 match(Set dst (RShiftVI src (RShiftCntV shift))); 17795 ins_cost(INSN_COST); 17796 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17797 ins_encode %{ 17798 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17799 as_FloatRegister($src$$reg), 17800 (int)$shift$$constant); 17801 %} 17802 ins_pipe(vshift64_imm); 17803 %} 17804 17805 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17806 predicate(n->as_Vector()->length() == 4); 17807 match(Set dst (RShiftVI src (RShiftCntV shift))); 17808 ins_cost(INSN_COST); 17809 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17810 ins_encode %{ 17811 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17812 as_FloatRegister($src$$reg), 17813 (int)$shift$$constant); 17814 %} 17815 ins_pipe(vshift128_imm); 17816 %} 17817 17818 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17819 predicate(n->as_Vector()->length() == 2); 17820 match(Set dst (URShiftVI src (RShiftCntV shift))); 17821 ins_cost(INSN_COST); 17822 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17823 ins_encode %{ 17824 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17825 as_FloatRegister($src$$reg), 17826 (int)$shift$$constant); 17827 %} 17828 ins_pipe(vshift64_imm); 17829 %} 17830 17831 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17832 predicate(n->as_Vector()->length() == 4); 17833 match(Set dst (URShiftVI src (RShiftCntV shift))); 17834 ins_cost(INSN_COST); 17835 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17836 ins_encode %{ 17837 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17838 as_FloatRegister($src$$reg), 17839 (int)$shift$$constant); 17840 %} 17841 ins_pipe(vshift128_imm); 17842 %} 17843 17844 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17845 predicate(n->as_Vector()->length() == 2); 17846 match(Set dst (LShiftVL src shift)); 17847 ins_cost(INSN_COST); 17848 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17849 ins_encode %{ 17850 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17851 as_FloatRegister($src$$reg), 17852 as_FloatRegister($shift$$reg)); 17853 %} 17854 ins_pipe(vshift128); 17855 %} 17856 17857 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17858 predicate(n->as_Vector()->length() == 2); 17859 match(Set dst (RShiftVL src shift)); 17860 ins_cost(INSN_COST); 17861 effect(TEMP tmp); 17862 format %{ "negr $tmp,$shift\t" 17863 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17864 ins_encode %{ 17865 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17866 as_FloatRegister($shift$$reg)); 17867 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17868 as_FloatRegister($src$$reg), 17869 as_FloatRegister($tmp$$reg)); 17870 %} 17871 ins_pipe(vshift128); 17872 %} 17873 17874 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17875 predicate(n->as_Vector()->length() == 2); 17876 match(Set dst (URShiftVL src shift)); 17877 ins_cost(INSN_COST); 17878 effect(TEMP tmp); 17879 format %{ "negr $tmp,$shift\t" 17880 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17881 ins_encode %{ 17882 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17883 as_FloatRegister($shift$$reg)); 17884 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17885 as_FloatRegister($src$$reg), 17886 as_FloatRegister($tmp$$reg)); 17887 %} 17888 ins_pipe(vshift128); 17889 %} 17890 17891 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17892 predicate(n->as_Vector()->length() == 2); 17893 match(Set dst (LShiftVL src (LShiftCntV shift))); 17894 ins_cost(INSN_COST); 17895 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17896 ins_encode %{ 17897 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17898 as_FloatRegister($src$$reg), 17899 (int)$shift$$constant); 17900 %} 17901 ins_pipe(vshift128_imm); 17902 %} 17903 17904 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17905 predicate(n->as_Vector()->length() == 2); 17906 match(Set dst (RShiftVL src (RShiftCntV shift))); 17907 ins_cost(INSN_COST); 17908 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17909 ins_encode %{ 17910 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17911 as_FloatRegister($src$$reg), 17912 (int)$shift$$constant); 17913 %} 17914 ins_pipe(vshift128_imm); 17915 %} 17916 17917 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17918 predicate(n->as_Vector()->length() == 2); 17919 match(Set dst (URShiftVL src (RShiftCntV shift))); 17920 ins_cost(INSN_COST); 17921 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17922 ins_encode %{ 17923 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17924 as_FloatRegister($src$$reg), 17925 (int)$shift$$constant); 17926 %} 17927 ins_pipe(vshift128_imm); 17928 %} 17929 17930 instruct vmax2F(vecD dst, vecD src1, vecD src2) 17931 %{ 17932 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17933 match(Set dst (MaxV src1 src2)); 17934 ins_cost(INSN_COST); 17935 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 17936 ins_encode %{ 17937 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 17938 as_FloatRegister($src1$$reg), 17939 as_FloatRegister($src2$$reg)); 17940 %} 17941 ins_pipe(vdop_fp64); 17942 %} 17943 17944 instruct vmax4F(vecX dst, vecX src1, vecX src2) 17945 %{ 17946 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17947 match(Set dst (MaxV src1 src2)); 17948 ins_cost(INSN_COST); 17949 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 17950 ins_encode %{ 17951 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 17952 as_FloatRegister($src1$$reg), 17953 as_FloatRegister($src2$$reg)); 17954 %} 17955 ins_pipe(vdop_fp128); 17956 %} 17957 17958 instruct vmax2D(vecX dst, vecX src1, vecX src2) 17959 %{ 17960 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17961 match(Set dst (MaxV src1 src2)); 17962 ins_cost(INSN_COST); 17963 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 17964 ins_encode %{ 17965 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 17966 as_FloatRegister($src1$$reg), 17967 as_FloatRegister($src2$$reg)); 17968 %} 17969 ins_pipe(vdop_fp128); 17970 %} 17971 17972 instruct vmin2F(vecD dst, vecD src1, vecD src2) 17973 %{ 17974 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17975 match(Set dst (MinV src1 src2)); 17976 ins_cost(INSN_COST); 17977 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 17978 ins_encode %{ 17979 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 17980 as_FloatRegister($src1$$reg), 17981 as_FloatRegister($src2$$reg)); 17982 %} 17983 ins_pipe(vdop_fp64); 17984 %} 17985 17986 instruct vmin4F(vecX dst, vecX src1, vecX src2) 17987 %{ 17988 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17989 match(Set dst (MinV src1 src2)); 17990 ins_cost(INSN_COST); 17991 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 17992 ins_encode %{ 17993 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 17994 as_FloatRegister($src1$$reg), 17995 as_FloatRegister($src2$$reg)); 17996 %} 17997 ins_pipe(vdop_fp128); 17998 %} 17999 18000 instruct vmin2D(vecX dst, vecX src1, vecX src2) 18001 %{ 18002 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18003 match(Set dst (MinV src1 src2)); 18004 ins_cost(INSN_COST); 18005 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 18006 ins_encode %{ 18007 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 18008 as_FloatRegister($src1$$reg), 18009 as_FloatRegister($src2$$reg)); 18010 %} 18011 ins_pipe(vdop_fp128); 18012 %} 18013 18014 instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ 18015 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18016 match(Set dst (RoundDoubleModeV src rmode)); 18017 format %{ "frint $dst, $src, $rmode" %} 18018 ins_encode %{ 18019 switch ($rmode$$constant) { 18020 case RoundDoubleModeNode::rmode_rint: 18021 __ frintn(as_FloatRegister($dst$$reg), __ T2D, 18022 as_FloatRegister($src$$reg)); 18023 break; 18024 case RoundDoubleModeNode::rmode_floor: 18025 __ frintm(as_FloatRegister($dst$$reg), __ T2D, 18026 as_FloatRegister($src$$reg)); 18027 break; 18028 case RoundDoubleModeNode::rmode_ceil: 18029 __ frintp(as_FloatRegister($dst$$reg), __ T2D, 18030 as_FloatRegister($src$$reg)); 18031 break; 18032 } 18033 %} 18034 ins_pipe(vdop_fp128); 18035 %} 18036 18037 //----------PEEPHOLE RULES----------------------------------------------------- 18038 // These must follow all instruction definitions as they use the names 18039 // defined in the instructions definitions. 18040 // 18041 // peepmatch ( root_instr_name [preceding_instruction]* ); 18042 // 18043 // peepconstraint %{ 18044 // (instruction_number.operand_name relational_op instruction_number.operand_name 18045 // [, ...] ); 18046 // // instruction numbers are zero-based using left to right order in peepmatch 18047 // 18048 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18049 // // provide an instruction_number.operand_name for each operand that appears 18050 // // in the replacement instruction's match rule 18051 // 18052 // ---------VM FLAGS--------------------------------------------------------- 18053 // 18054 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18055 // 18056 // Each peephole rule is given an identifying number starting with zero and 18057 // increasing by one in the order seen by the parser. An individual peephole 18058 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18059 // on the command-line. 18060 // 18061 // ---------CURRENT LIMITATIONS---------------------------------------------- 18062 // 18063 // Only match adjacent instructions in same basic block 18064 // Only equality constraints 18065 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18066 // Only one replacement instruction 18067 // 18068 // ---------EXAMPLE---------------------------------------------------------- 18069 // 18070 // // pertinent parts of existing instructions in architecture description 18071 // instruct movI(iRegINoSp dst, iRegI src) 18072 // %{ 18073 // match(Set dst (CopyI src)); 18074 // %} 18075 // 18076 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18077 // %{ 18078 // match(Set dst (AddI dst src)); 18079 // effect(KILL cr); 18080 // %} 18081 // 18082 // // Change (inc mov) to lea 18083 // peephole %{ 18084 // // increment preceeded by register-register move 18085 // peepmatch ( incI_iReg movI ); 18086 // // require that the destination register of the increment 18087 // // match the destination register of the move 18088 // peepconstraint ( 0.dst == 1.dst ); 18089 // // construct a replacement instruction that sets 18090 // // the destination to ( move's source register + one ) 18091 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18092 // %} 18093 // 18094 18095 // Implementation no longer uses movX instructions since 18096 // machine-independent system no longer uses CopyX nodes. 18097 // 18098 // peephole 18099 // %{ 18100 // peepmatch (incI_iReg movI); 18101 // peepconstraint (0.dst == 1.dst); 18102 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18103 // %} 18104 18105 // peephole 18106 // %{ 18107 // peepmatch (decI_iReg movI); 18108 // peepconstraint (0.dst == 1.dst); 18109 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18110 // %} 18111 18112 // peephole 18113 // %{ 18114 // peepmatch (addI_iReg_imm movI); 18115 // peepconstraint (0.dst == 1.dst); 18116 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18117 // %} 18118 18119 // peephole 18120 // %{ 18121 // peepmatch (incL_iReg movL); 18122 // peepconstraint (0.dst == 1.dst); 18123 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18124 // %} 18125 18126 // peephole 18127 // %{ 18128 // peepmatch (decL_iReg movL); 18129 // peepconstraint (0.dst == 1.dst); 18130 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18131 // %} 18132 18133 // peephole 18134 // %{ 18135 // peepmatch (addL_iReg_imm movL); 18136 // peepconstraint (0.dst == 1.dst); 18137 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18138 // %} 18139 18140 // peephole 18141 // %{ 18142 // peepmatch (addP_iReg_imm movP); 18143 // peepconstraint (0.dst == 1.dst); 18144 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18145 // %} 18146 18147 // // Change load of spilled value to only a spill 18148 // instruct storeI(memory mem, iRegI src) 18149 // %{ 18150 // match(Set mem (StoreI mem src)); 18151 // %} 18152 // 18153 // instruct loadI(iRegINoSp dst, memory mem) 18154 // %{ 18155 // match(Set dst (LoadI mem)); 18156 // %} 18157 // 18158 18159 //----------SMARTSPILL RULES--------------------------------------------------- 18160 // These must follow all instruction definitions as they use the names 18161 // defined in the instructions definitions. 18162 18163 // Local Variables: 18164 // mode: c++ 18165 // End: