1 // 2 // Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2019, 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 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, 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 integer registers -- excludes SP which will 439 // never be used as an integer register 440 reg_class any_reg32( 441 R0, 442 R1, 443 R2, 444 R3, 445 R4, 446 R5, 447 R6, 448 R7, 449 R10, 450 R11, 451 R12, 452 R13, 453 R14, 454 R15, 455 R16, 456 R17, 457 R18, 458 R19, 459 R20, 460 R21, 461 R22, 462 R23, 463 R24, 464 R25, 465 R26, 466 R27, 467 R28, 468 R29, 469 R30 470 ); 471 472 // Singleton class for R0 int register 473 reg_class int_r0_reg(R0); 474 475 // Singleton class for R2 int register 476 reg_class int_r2_reg(R2); 477 478 // Singleton class for R3 int register 479 reg_class int_r3_reg(R3); 480 481 // Singleton class for R4 int register 482 reg_class int_r4_reg(R4); 483 484 // Class for all long integer registers (including RSP) 485 reg_class any_reg( 486 R0, R0_H, 487 R1, R1_H, 488 R2, R2_H, 489 R3, R3_H, 490 R4, R4_H, 491 R5, R5_H, 492 R6, R6_H, 493 R7, R7_H, 494 R10, R10_H, 495 R11, R11_H, 496 R12, R12_H, 497 R13, R13_H, 498 R14, R14_H, 499 R15, R15_H, 500 R16, R16_H, 501 R17, R17_H, 502 R18, R18_H, 503 R19, R19_H, 504 R20, R20_H, 505 R21, R21_H, 506 R22, R22_H, 507 R23, R23_H, 508 R24, R24_H, 509 R25, R25_H, 510 R26, R26_H, 511 R27, R27_H, 512 R28, R28_H, 513 R29, R29_H, 514 R30, R30_H, 515 R31, R31_H 516 ); 517 518 // Class for all non-special integer registers 519 reg_class no_special_reg32_no_fp( 520 R0, 521 R1, 522 R2, 523 R3, 524 R4, 525 R5, 526 R6, 527 R7, 528 R10, 529 R11, 530 R12, // rmethod 531 R13, 532 R14, 533 R15, 534 R16, 535 R17, 536 R18, 537 R19, 538 R20, 539 R21, 540 R22, 541 R23, 542 R24, 543 R25, 544 R26 545 /* R27, */ // heapbase 546 /* R28, */ // thread 547 /* R29, */ // fp 548 /* R30, */ // lr 549 /* R31 */ // sp 550 ); 551 552 reg_class no_special_reg32_with_fp( 553 R0, 554 R1, 555 R2, 556 R3, 557 R4, 558 R5, 559 R6, 560 R7, 561 R10, 562 R11, 563 R12, // rmethod 564 R13, 565 R14, 566 R15, 567 R16, 568 R17, 569 R18, 570 R19, 571 R20, 572 R21, 573 R22, 574 R23, 575 R24, 576 R25, 577 R26 578 /* R27, */ // heapbase 579 /* R28, */ // thread 580 R29, // fp 581 /* R30, */ // lr 582 /* R31 */ // sp 583 ); 584 585 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); 586 587 // Class for all non-special long integer registers 588 reg_class no_special_reg_no_fp( 589 R0, R0_H, 590 R1, R1_H, 591 R2, R2_H, 592 R3, R3_H, 593 R4, R4_H, 594 R5, R5_H, 595 R6, R6_H, 596 R7, R7_H, 597 R10, R10_H, 598 R11, R11_H, 599 R12, R12_H, // rmethod 600 R13, R13_H, 601 R14, R14_H, 602 R15, R15_H, 603 R16, R16_H, 604 R17, R17_H, 605 R18, R18_H, 606 R19, R19_H, 607 R20, R20_H, 608 R21, R21_H, 609 R22, R22_H, 610 R23, R23_H, 611 R24, R24_H, 612 R25, R25_H, 613 R26, R26_H, 614 /* R27, R27_H, */ // heapbase 615 /* R28, R28_H, */ // thread 616 /* R29, R29_H, */ // fp 617 /* R30, R30_H, */ // lr 618 /* R31, R31_H */ // sp 619 ); 620 621 reg_class no_special_reg_with_fp( 622 R0, R0_H, 623 R1, R1_H, 624 R2, R2_H, 625 R3, R3_H, 626 R4, R4_H, 627 R5, R5_H, 628 R6, R6_H, 629 R7, R7_H, 630 R10, R10_H, 631 R11, R11_H, 632 R12, R12_H, // rmethod 633 R13, R13_H, 634 R14, R14_H, 635 R15, R15_H, 636 R16, R16_H, 637 R17, R17_H, 638 R18, R18_H, 639 R19, R19_H, 640 R20, R20_H, 641 R21, R21_H, 642 R22, R22_H, 643 R23, R23_H, 644 R24, R24_H, 645 R25, R25_H, 646 R26, R26_H, 647 /* R27, R27_H, */ // heapbase 648 /* R28, R28_H, */ // thread 649 R29, R29_H, // fp 650 /* R30, R30_H, */ // lr 651 /* R31, R31_H */ // sp 652 ); 653 654 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 655 656 // Class for 64 bit register r0 657 reg_class r0_reg( 658 R0, R0_H 659 ); 660 661 // Class for 64 bit register r1 662 reg_class r1_reg( 663 R1, R1_H 664 ); 665 666 // Class for 64 bit register r2 667 reg_class r2_reg( 668 R2, R2_H 669 ); 670 671 // Class for 64 bit register r3 672 reg_class r3_reg( 673 R3, R3_H 674 ); 675 676 // Class for 64 bit register r4 677 reg_class r4_reg( 678 R4, R4_H 679 ); 680 681 // Class for 64 bit register r5 682 reg_class r5_reg( 683 R5, R5_H 684 ); 685 686 // Class for 64 bit register r10 687 reg_class r10_reg( 688 R10, R10_H 689 ); 690 691 // Class for 64 bit register r11 692 reg_class r11_reg( 693 R11, R11_H 694 ); 695 696 // Class for method register 697 reg_class method_reg( 698 R12, R12_H 699 ); 700 701 // Class for heapbase register 702 reg_class heapbase_reg( 703 R27, R27_H 704 ); 705 706 // Class for thread register 707 reg_class thread_reg( 708 R28, R28_H 709 ); 710 711 // Class for frame pointer register 712 reg_class fp_reg( 713 R29, R29_H 714 ); 715 716 // Class for link register 717 reg_class lr_reg( 718 R30, R30_H 719 ); 720 721 // Class for long sp register 722 reg_class sp_reg( 723 R31, R31_H 724 ); 725 726 // Class for all pointer registers 727 reg_class ptr_reg( 728 R0, R0_H, 729 R1, R1_H, 730 R2, R2_H, 731 R3, R3_H, 732 R4, R4_H, 733 R5, R5_H, 734 R6, R6_H, 735 R7, R7_H, 736 R10, R10_H, 737 R11, R11_H, 738 R12, R12_H, 739 R13, R13_H, 740 R14, R14_H, 741 R15, R15_H, 742 R16, R16_H, 743 R17, R17_H, 744 R18, R18_H, 745 R19, R19_H, 746 R20, R20_H, 747 R21, R21_H, 748 R22, R22_H, 749 R23, R23_H, 750 R24, R24_H, 751 R25, R25_H, 752 R26, R26_H, 753 R27, R27_H, 754 R28, R28_H, 755 R29, R29_H, 756 R30, R30_H, 757 R31, R31_H 758 ); 759 760 // Class for all non_special pointer registers 761 reg_class no_special_ptr_reg( 762 R0, R0_H, 763 R1, R1_H, 764 R2, R2_H, 765 R3, R3_H, 766 R4, R4_H, 767 R5, R5_H, 768 R6, R6_H, 769 R7, R7_H, 770 R10, R10_H, 771 R11, R11_H, 772 R12, R12_H, 773 R13, R13_H, 774 R14, R14_H, 775 R15, R15_H, 776 R16, R16_H, 777 R17, R17_H, 778 R18, R18_H, 779 R19, R19_H, 780 R20, R20_H, 781 R21, R21_H, 782 R22, R22_H, 783 R23, R23_H, 784 R24, R24_H, 785 R25, R25_H, 786 R26, R26_H, 787 /* R27, R27_H, */ // heapbase 788 /* R28, R28_H, */ // thread 789 /* R29, R29_H, */ // fp 790 /* R30, R30_H, */ // lr 791 /* R31, R31_H */ // sp 792 ); 793 794 // Class for all float registers 795 reg_class float_reg( 796 V0, 797 V1, 798 V2, 799 V3, 800 V4, 801 V5, 802 V6, 803 V7, 804 V8, 805 V9, 806 V10, 807 V11, 808 V12, 809 V13, 810 V14, 811 V15, 812 V16, 813 V17, 814 V18, 815 V19, 816 V20, 817 V21, 818 V22, 819 V23, 820 V24, 821 V25, 822 V26, 823 V27, 824 V28, 825 V29, 826 V30, 827 V31 828 ); 829 830 // Double precision float registers have virtual `high halves' that 831 // are needed by the allocator. 832 // Class for all double registers 833 reg_class double_reg( 834 V0, V0_H, 835 V1, V1_H, 836 V2, V2_H, 837 V3, V3_H, 838 V4, V4_H, 839 V5, V5_H, 840 V6, V6_H, 841 V7, V7_H, 842 V8, V8_H, 843 V9, V9_H, 844 V10, V10_H, 845 V11, V11_H, 846 V12, V12_H, 847 V13, V13_H, 848 V14, V14_H, 849 V15, V15_H, 850 V16, V16_H, 851 V17, V17_H, 852 V18, V18_H, 853 V19, V19_H, 854 V20, V20_H, 855 V21, V21_H, 856 V22, V22_H, 857 V23, V23_H, 858 V24, V24_H, 859 V25, V25_H, 860 V26, V26_H, 861 V27, V27_H, 862 V28, V28_H, 863 V29, V29_H, 864 V30, V30_H, 865 V31, V31_H 866 ); 867 868 // Class for all 64bit vector registers 869 reg_class vectord_reg( 870 V0, V0_H, 871 V1, V1_H, 872 V2, V2_H, 873 V3, V3_H, 874 V4, V4_H, 875 V5, V5_H, 876 V6, V6_H, 877 V7, V7_H, 878 V8, V8_H, 879 V9, V9_H, 880 V10, V10_H, 881 V11, V11_H, 882 V12, V12_H, 883 V13, V13_H, 884 V14, V14_H, 885 V15, V15_H, 886 V16, V16_H, 887 V17, V17_H, 888 V18, V18_H, 889 V19, V19_H, 890 V20, V20_H, 891 V21, V21_H, 892 V22, V22_H, 893 V23, V23_H, 894 V24, V24_H, 895 V25, V25_H, 896 V26, V26_H, 897 V27, V27_H, 898 V28, V28_H, 899 V29, V29_H, 900 V30, V30_H, 901 V31, V31_H 902 ); 903 904 // Class for all 128bit vector registers 905 reg_class vectorx_reg( 906 V0, V0_H, V0_J, V0_K, 907 V1, V1_H, V1_J, V1_K, 908 V2, V2_H, V2_J, V2_K, 909 V3, V3_H, V3_J, V3_K, 910 V4, V4_H, V4_J, V4_K, 911 V5, V5_H, V5_J, V5_K, 912 V6, V6_H, V6_J, V6_K, 913 V7, V7_H, V7_J, V7_K, 914 V8, V8_H, V8_J, V8_K, 915 V9, V9_H, V9_J, V9_K, 916 V10, V10_H, V10_J, V10_K, 917 V11, V11_H, V11_J, V11_K, 918 V12, V12_H, V12_J, V12_K, 919 V13, V13_H, V13_J, V13_K, 920 V14, V14_H, V14_J, V14_K, 921 V15, V15_H, V15_J, V15_K, 922 V16, V16_H, V16_J, V16_K, 923 V17, V17_H, V17_J, V17_K, 924 V18, V18_H, V18_J, V18_K, 925 V19, V19_H, V19_J, V19_K, 926 V20, V20_H, V20_J, V20_K, 927 V21, V21_H, V21_J, V21_K, 928 V22, V22_H, V22_J, V22_K, 929 V23, V23_H, V23_J, V23_K, 930 V24, V24_H, V24_J, V24_K, 931 V25, V25_H, V25_J, V25_K, 932 V26, V26_H, V26_J, V26_K, 933 V27, V27_H, V27_J, V27_K, 934 V28, V28_H, V28_J, V28_K, 935 V29, V29_H, V29_J, V29_K, 936 V30, V30_H, V30_J, V30_K, 937 V31, V31_H, V31_J, V31_K 938 ); 939 940 // Class for 128 bit register v0 941 reg_class v0_reg( 942 V0, V0_H 943 ); 944 945 // Class for 128 bit register v1 946 reg_class v1_reg( 947 V1, V1_H 948 ); 949 950 // Class for 128 bit register v2 951 reg_class v2_reg( 952 V2, V2_H 953 ); 954 955 // Class for 128 bit register v3 956 reg_class v3_reg( 957 V3, V3_H 958 ); 959 960 // Singleton class for condition codes 961 reg_class int_flags(RFLAGS); 962 963 %} 964 965 //----------DEFINITION BLOCK--------------------------------------------------- 966 // Define name --> value mappings to inform the ADLC of an integer valued name 967 // Current support includes integer values in the range [0, 0x7FFFFFFF] 968 // Format: 969 // int_def <name> ( <int_value>, <expression>); 970 // Generated Code in ad_<arch>.hpp 971 // #define <name> (<expression>) 972 // // value == <int_value> 973 // Generated code in ad_<arch>.cpp adlc_verification() 974 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 975 // 976 977 // we follow the ppc-aix port in using a simple cost model which ranks 978 // register operations as cheap, memory ops as more expensive and 979 // branches as most expensive. the first two have a low as well as a 980 // normal cost. huge cost appears to be a way of saying don't do 981 // something 982 983 definitions %{ 984 // The default cost (of a register move instruction). 985 int_def INSN_COST ( 100, 100); 986 int_def BRANCH_COST ( 200, 2 * INSN_COST); 987 int_def CALL_COST ( 200, 2 * INSN_COST); 988 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 989 %} 990 991 992 //----------SOURCE BLOCK------------------------------------------------------- 993 // This is a block of C++ code which provides values, functions, and 994 // definitions necessary in the rest of the architecture description 995 996 source_hpp %{ 997 998 #include "asm/macroAssembler.hpp" 999 #include "gc/shared/cardTable.hpp" 1000 #include "gc/shared/cardTableBarrierSet.hpp" 1001 #include "gc/shared/collectedHeap.hpp" 1002 #include "opto/addnode.hpp" 1003 1004 class CallStubImpl { 1005 1006 //-------------------------------------------------------------- 1007 //---< Used for optimization in Compile::shorten_branches >--- 1008 //-------------------------------------------------------------- 1009 1010 public: 1011 // Size of call trampoline stub. 1012 static uint size_call_trampoline() { 1013 return 0; // no call trampolines on this platform 1014 } 1015 1016 // number of relocations needed by a call trampoline stub 1017 static uint reloc_call_trampoline() { 1018 return 0; // no call trampolines on this platform 1019 } 1020 }; 1021 1022 class HandlerImpl { 1023 1024 public: 1025 1026 static int emit_exception_handler(CodeBuffer &cbuf); 1027 static int emit_deopt_handler(CodeBuffer& cbuf); 1028 1029 static uint size_exception_handler() { 1030 return MacroAssembler::far_branch_size(); 1031 } 1032 1033 static uint size_deopt_handler() { 1034 // count one adr and one far branch instruction 1035 return 4 * NativeInstruction::instruction_size; 1036 } 1037 }; 1038 1039 bool is_CAS(int opcode, bool maybe_volatile); 1040 1041 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1042 1043 bool unnecessary_acquire(const Node *barrier); 1044 bool needs_acquiring_load(const Node *load); 1045 1046 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1047 1048 bool unnecessary_release(const Node *barrier); 1049 bool unnecessary_volatile(const Node *barrier); 1050 bool needs_releasing_store(const Node *store); 1051 1052 // predicate controlling translation of CompareAndSwapX 1053 bool needs_acquiring_load_exclusive(const Node *load); 1054 1055 // predicate controlling translation of StoreCM 1056 bool unnecessary_storestore(const Node *storecm); 1057 1058 // predicate controlling addressing modes 1059 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1060 %} 1061 1062 source %{ 1063 1064 // Optimizaton of volatile gets and puts 1065 // ------------------------------------- 1066 // 1067 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1068 // use to implement volatile reads and writes. For a volatile read 1069 // we simply need 1070 // 1071 // ldar<x> 1072 // 1073 // and for a volatile write we need 1074 // 1075 // stlr<x> 1076 // 1077 // Alternatively, we can implement them by pairing a normal 1078 // load/store with a memory barrier. For a volatile read we need 1079 // 1080 // ldr<x> 1081 // dmb ishld 1082 // 1083 // for a volatile write 1084 // 1085 // dmb ish 1086 // str<x> 1087 // dmb ish 1088 // 1089 // We can also use ldaxr and stlxr to implement compare and swap CAS 1090 // sequences. These are normally translated to an instruction 1091 // sequence like the following 1092 // 1093 // dmb ish 1094 // retry: 1095 // ldxr<x> rval raddr 1096 // cmp rval rold 1097 // b.ne done 1098 // stlxr<x> rval, rnew, rold 1099 // cbnz rval retry 1100 // done: 1101 // cset r0, eq 1102 // dmb ishld 1103 // 1104 // Note that the exclusive store is already using an stlxr 1105 // instruction. That is required to ensure visibility to other 1106 // threads of the exclusive write (assuming it succeeds) before that 1107 // of any subsequent writes. 1108 // 1109 // The following instruction sequence is an improvement on the above 1110 // 1111 // retry: 1112 // ldaxr<x> rval raddr 1113 // cmp rval rold 1114 // b.ne done 1115 // stlxr<x> rval, rnew, rold 1116 // cbnz rval retry 1117 // done: 1118 // cset r0, eq 1119 // 1120 // We don't need the leading dmb ish since the stlxr guarantees 1121 // visibility of prior writes in the case that the swap is 1122 // successful. Crucially we don't have to worry about the case where 1123 // the swap is not successful since no valid program should be 1124 // relying on visibility of prior changes by the attempting thread 1125 // in the case where the CAS fails. 1126 // 1127 // Similarly, we don't need the trailing dmb ishld if we substitute 1128 // an ldaxr instruction since that will provide all the guarantees we 1129 // require regarding observation of changes made by other threads 1130 // before any change to the CAS address observed by the load. 1131 // 1132 // In order to generate the desired instruction sequence we need to 1133 // be able to identify specific 'signature' ideal graph node 1134 // sequences which i) occur as a translation of a volatile reads or 1135 // writes or CAS operations and ii) do not occur through any other 1136 // translation or graph transformation. We can then provide 1137 // alternative aldc matching rules which translate these node 1138 // sequences to the desired machine code sequences. Selection of the 1139 // alternative rules can be implemented by predicates which identify 1140 // the relevant node sequences. 1141 // 1142 // The ideal graph generator translates a volatile read to the node 1143 // sequence 1144 // 1145 // LoadX[mo_acquire] 1146 // MemBarAcquire 1147 // 1148 // As a special case when using the compressed oops optimization we 1149 // may also see this variant 1150 // 1151 // LoadN[mo_acquire] 1152 // DecodeN 1153 // MemBarAcquire 1154 // 1155 // A volatile write is translated to the node sequence 1156 // 1157 // MemBarRelease 1158 // StoreX[mo_release] {CardMark}-optional 1159 // MemBarVolatile 1160 // 1161 // n.b. the above node patterns are generated with a strict 1162 // 'signature' configuration of input and output dependencies (see 1163 // the predicates below for exact details). The card mark may be as 1164 // simple as a few extra nodes or, in a few GC configurations, may 1165 // include more complex control flow between the leading and 1166 // trailing memory barriers. However, whatever the card mark 1167 // configuration these signatures are unique to translated volatile 1168 // reads/stores -- they will not appear as a result of any other 1169 // bytecode translation or inlining nor as a consequence of 1170 // optimizing transforms. 1171 // 1172 // We also want to catch inlined unsafe volatile gets and puts and 1173 // be able to implement them using either ldar<x>/stlr<x> or some 1174 // combination of ldr<x>/stlr<x> and dmb instructions. 1175 // 1176 // Inlined unsafe volatiles puts manifest as a minor variant of the 1177 // normal volatile put node sequence containing an extra cpuorder 1178 // membar 1179 // 1180 // MemBarRelease 1181 // MemBarCPUOrder 1182 // StoreX[mo_release] {CardMark}-optional 1183 // MemBarCPUOrder 1184 // MemBarVolatile 1185 // 1186 // n.b. as an aside, a cpuorder membar is not itself subject to 1187 // matching and translation by adlc rules. However, the rule 1188 // predicates need to detect its presence in order to correctly 1189 // select the desired adlc rules. 1190 // 1191 // Inlined unsafe volatile gets manifest as a slightly different 1192 // node sequence to a normal volatile get because of the 1193 // introduction of some CPUOrder memory barriers to bracket the 1194 // Load. However, but the same basic skeleton of a LoadX feeding a 1195 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1196 // present 1197 // 1198 // MemBarCPUOrder 1199 // || \\ 1200 // MemBarCPUOrder LoadX[mo_acquire] 1201 // || | 1202 // || {DecodeN} optional 1203 // || / 1204 // MemBarAcquire 1205 // 1206 // In this case the acquire membar does not directly depend on the 1207 // load. However, we can be sure that the load is generated from an 1208 // inlined unsafe volatile get if we see it dependent on this unique 1209 // sequence of membar nodes. Similarly, given an acquire membar we 1210 // can know that it was added because of an inlined unsafe volatile 1211 // get if it is fed and feeds a cpuorder membar and if its feed 1212 // membar also feeds an acquiring load. 1213 // 1214 // Finally an inlined (Unsafe) CAS operation is translated to the 1215 // following ideal graph 1216 // 1217 // MemBarRelease 1218 // MemBarCPUOrder 1219 // CompareAndSwapX {CardMark}-optional 1220 // MemBarCPUOrder 1221 // MemBarAcquire 1222 // 1223 // So, where we can identify these volatile read and write 1224 // signatures we can choose to plant either of the above two code 1225 // sequences. For a volatile read we can simply plant a normal 1226 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1227 // also choose to inhibit translation of the MemBarAcquire and 1228 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1229 // 1230 // When we recognise a volatile store signature we can choose to 1231 // plant at a dmb ish as a translation for the MemBarRelease, a 1232 // normal str<x> and then a dmb ish for the MemBarVolatile. 1233 // Alternatively, we can inhibit translation of the MemBarRelease 1234 // and MemBarVolatile and instead plant a simple stlr<x> 1235 // instruction. 1236 // 1237 // when we recognise a CAS signature we can choose to plant a dmb 1238 // ish as a translation for the MemBarRelease, the conventional 1239 // macro-instruction sequence for the CompareAndSwap node (which 1240 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1241 // Alternatively, we can elide generation of the dmb instructions 1242 // and plant the alternative CompareAndSwap macro-instruction 1243 // sequence (which uses ldaxr<x>). 1244 // 1245 // Of course, the above only applies when we see these signature 1246 // configurations. We still want to plant dmb instructions in any 1247 // other cases where we may see a MemBarAcquire, MemBarRelease or 1248 // MemBarVolatile. For example, at the end of a constructor which 1249 // writes final/volatile fields we will see a MemBarRelease 1250 // instruction and this needs a 'dmb ish' lest we risk the 1251 // constructed object being visible without making the 1252 // final/volatile field writes visible. 1253 // 1254 // n.b. the translation rules below which rely on detection of the 1255 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1256 // If we see anything other than the signature configurations we 1257 // always just translate the loads and stores to ldr<x> and str<x> 1258 // and translate acquire, release and volatile membars to the 1259 // relevant dmb instructions. 1260 // 1261 1262 // is_CAS(int opcode, bool maybe_volatile) 1263 // 1264 // return true if opcode is one of the possible CompareAndSwapX 1265 // values otherwise false. 1266 1267 bool is_CAS(int opcode, bool maybe_volatile) 1268 { 1269 switch(opcode) { 1270 // We handle these 1271 case Op_CompareAndSwapI: 1272 case Op_CompareAndSwapL: 1273 case Op_CompareAndSwapP: 1274 case Op_CompareAndSwapN: 1275 case Op_CompareAndSwapB: 1276 case Op_CompareAndSwapS: 1277 case Op_GetAndSetI: 1278 case Op_GetAndSetL: 1279 case Op_GetAndSetP: 1280 case Op_GetAndSetN: 1281 case Op_GetAndAddI: 1282 case Op_GetAndAddL: 1283 return true; 1284 case Op_CompareAndExchangeI: 1285 case Op_CompareAndExchangeN: 1286 case Op_CompareAndExchangeB: 1287 case Op_CompareAndExchangeS: 1288 case Op_CompareAndExchangeL: 1289 case Op_CompareAndExchangeP: 1290 case Op_WeakCompareAndSwapB: 1291 case Op_WeakCompareAndSwapS: 1292 case Op_WeakCompareAndSwapI: 1293 case Op_WeakCompareAndSwapL: 1294 case Op_WeakCompareAndSwapP: 1295 case Op_WeakCompareAndSwapN: 1296 return maybe_volatile; 1297 default: 1298 return false; 1299 } 1300 } 1301 1302 // helper to determine the maximum number of Phi nodes we may need to 1303 // traverse when searching from a card mark membar for the merge mem 1304 // feeding a trailing membar or vice versa 1305 1306 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1307 1308 bool unnecessary_acquire(const Node *barrier) 1309 { 1310 assert(barrier->is_MemBar(), "expecting a membar"); 1311 1312 if (UseBarriersForVolatile) { 1313 // we need to plant a dmb 1314 return false; 1315 } 1316 1317 MemBarNode* mb = barrier->as_MemBar(); 1318 1319 if (mb->trailing_load()) { 1320 return true; 1321 } 1322 1323 if (mb->trailing_load_store()) { 1324 Node* load_store = mb->in(MemBarNode::Precedent); 1325 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1326 return is_CAS(load_store->Opcode(), true); 1327 } 1328 1329 return false; 1330 } 1331 1332 bool needs_acquiring_load(const Node *n) 1333 { 1334 assert(n->is_Load(), "expecting a load"); 1335 if (UseBarriersForVolatile) { 1336 // we use a normal load and a dmb 1337 return false; 1338 } 1339 1340 LoadNode *ld = n->as_Load(); 1341 1342 return ld->is_acquire(); 1343 } 1344 1345 bool unnecessary_release(const Node *n) 1346 { 1347 assert((n->is_MemBar() && 1348 n->Opcode() == Op_MemBarRelease), 1349 "expecting a release membar"); 1350 1351 if (UseBarriersForVolatile) { 1352 // we need to plant a dmb 1353 return false; 1354 } 1355 1356 MemBarNode *barrier = n->as_MemBar(); 1357 if (!barrier->leading()) { 1358 return false; 1359 } else { 1360 Node* trailing = barrier->trailing_membar(); 1361 MemBarNode* trailing_mb = trailing->as_MemBar(); 1362 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1363 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1364 1365 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1366 if (mem->is_Store()) { 1367 assert(mem->as_Store()->is_release(), ""); 1368 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1369 return true; 1370 } else { 1371 assert(mem->is_LoadStore(), ""); 1372 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1373 return is_CAS(mem->Opcode(), true); 1374 } 1375 } 1376 return false; 1377 } 1378 1379 bool unnecessary_volatile(const Node *n) 1380 { 1381 // assert n->is_MemBar(); 1382 if (UseBarriersForVolatile) { 1383 // we need to plant a dmb 1384 return false; 1385 } 1386 1387 MemBarNode *mbvol = n->as_MemBar(); 1388 1389 bool release = mbvol->trailing_store(); 1390 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1391 #ifdef ASSERT 1392 if (release) { 1393 Node* leading = mbvol->leading_membar(); 1394 assert(leading->Opcode() == Op_MemBarRelease, ""); 1395 assert(leading->as_MemBar()->leading_store(), ""); 1396 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1397 } 1398 #endif 1399 1400 return release; 1401 } 1402 1403 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1404 1405 bool needs_releasing_store(const Node *n) 1406 { 1407 // assert n->is_Store(); 1408 if (UseBarriersForVolatile) { 1409 // we use a normal store and dmb combination 1410 return false; 1411 } 1412 1413 StoreNode *st = n->as_Store(); 1414 1415 return st->trailing_membar() != NULL; 1416 } 1417 1418 // predicate controlling translation of CAS 1419 // 1420 // returns true if CAS needs to use an acquiring load otherwise false 1421 1422 bool needs_acquiring_load_exclusive(const Node *n) 1423 { 1424 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1425 if (UseBarriersForVolatile) { 1426 return false; 1427 } 1428 1429 LoadStoreNode* ldst = n->as_LoadStore(); 1430 if (is_CAS(n->Opcode(), false)) { 1431 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1432 } else { 1433 return ldst->trailing_membar() != NULL; 1434 } 1435 1436 // so we can just return true here 1437 return true; 1438 } 1439 1440 // predicate controlling translation of StoreCM 1441 // 1442 // returns true if a StoreStore must precede the card write otherwise 1443 // false 1444 1445 bool unnecessary_storestore(const Node *storecm) 1446 { 1447 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1448 1449 // we need to generate a dmb ishst between an object put and the 1450 // associated card mark when we are using CMS without conditional 1451 // card marking 1452 1453 if (UseConcMarkSweepGC && !UseCondCardMark) { 1454 return false; 1455 } 1456 1457 // a storestore is unnecesary in all other cases 1458 1459 return true; 1460 } 1461 1462 1463 #define __ _masm. 1464 1465 // advance declarations for helper functions to convert register 1466 // indices to register objects 1467 1468 // the ad file has to provide implementations of certain methods 1469 // expected by the generic code 1470 // 1471 // REQUIRED FUNCTIONALITY 1472 1473 //============================================================================= 1474 1475 // !!!!! Special hack to get all types of calls to specify the byte offset 1476 // from the start of the call to the point where the return address 1477 // will point. 1478 1479 int MachCallStaticJavaNode::ret_addr_offset() 1480 { 1481 // call should be a simple bl 1482 int off = 4; 1483 return off; 1484 } 1485 1486 int MachCallDynamicJavaNode::ret_addr_offset() 1487 { 1488 return 16; // movz, movk, movk, bl 1489 } 1490 1491 int MachCallRuntimeNode::ret_addr_offset() { 1492 // for generated stubs the call will be 1493 // far_call(addr) 1494 // for real runtime callouts it will be six instructions 1495 // see aarch64_enc_java_to_runtime 1496 // adr(rscratch2, retaddr) 1497 // lea(rscratch1, RuntimeAddress(addr) 1498 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1499 // blr(rscratch1) 1500 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1501 if (cb) { 1502 return MacroAssembler::far_branch_size(); 1503 } else { 1504 return 6 * NativeInstruction::instruction_size; 1505 } 1506 } 1507 1508 // Indicate if the safepoint node needs the polling page as an input 1509 1510 // the shared code plants the oop data at the start of the generated 1511 // code for the safepoint node and that needs ot be at the load 1512 // instruction itself. so we cannot plant a mov of the safepoint poll 1513 // address followed by a load. setting this to true means the mov is 1514 // scheduled as a prior instruction. that's better for scheduling 1515 // anyway. 1516 1517 bool SafePointNode::needs_polling_address_input() 1518 { 1519 return true; 1520 } 1521 1522 //============================================================================= 1523 1524 #ifndef PRODUCT 1525 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1526 st->print("BREAKPOINT"); 1527 } 1528 #endif 1529 1530 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1531 MacroAssembler _masm(&cbuf); 1532 __ brk(0); 1533 } 1534 1535 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1536 return MachNode::size(ra_); 1537 } 1538 1539 //============================================================================= 1540 1541 #ifndef PRODUCT 1542 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1543 st->print("nop \t# %d bytes pad for loops and calls", _count); 1544 } 1545 #endif 1546 1547 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1548 MacroAssembler _masm(&cbuf); 1549 for (int i = 0; i < _count; i++) { 1550 __ nop(); 1551 } 1552 } 1553 1554 uint MachNopNode::size(PhaseRegAlloc*) const { 1555 return _count * NativeInstruction::instruction_size; 1556 } 1557 1558 //============================================================================= 1559 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1560 1561 int Compile::ConstantTable::calculate_table_base_offset() const { 1562 return 0; // absolute addressing, no offset 1563 } 1564 1565 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1566 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1567 ShouldNotReachHere(); 1568 } 1569 1570 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1571 // Empty encoding 1572 } 1573 1574 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1575 return 0; 1576 } 1577 1578 #ifndef PRODUCT 1579 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1580 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1581 } 1582 #endif 1583 1584 #ifndef PRODUCT 1585 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1586 Compile* C = ra_->C; 1587 1588 int framesize = C->frame_slots() << LogBytesPerInt; 1589 1590 if (C->need_stack_bang(framesize)) 1591 st->print("# stack bang size=%d\n\t", framesize); 1592 1593 if (framesize < ((1 << 9) + 2 * wordSize)) { 1594 st->print("sub sp, sp, #%d\n\t", framesize); 1595 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1596 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1597 } else { 1598 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1599 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1600 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1601 st->print("sub sp, sp, rscratch1"); 1602 } 1603 } 1604 #endif 1605 1606 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1607 Compile* C = ra_->C; 1608 MacroAssembler _masm(&cbuf); 1609 1610 // n.b. frame size includes space for return pc and rfp 1611 const long framesize = C->frame_size_in_bytes(); 1612 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1613 1614 // insert a nop at the start of the prolog so we can patch in a 1615 // branch if we need to invalidate the method later 1616 __ nop(); 1617 1618 int bangsize = C->bang_size_in_bytes(); 1619 if (C->need_stack_bang(bangsize) && UseStackBanging) 1620 __ generate_stack_overflow_check(bangsize); 1621 1622 __ build_frame(framesize); 1623 1624 if (VerifyStackAtCalls) { 1625 Unimplemented(); 1626 } 1627 1628 C->set_frame_complete(cbuf.insts_size()); 1629 1630 if (C->has_mach_constant_base_node()) { 1631 // NOTE: We set the table base offset here because users might be 1632 // emitted before MachConstantBaseNode. 1633 Compile::ConstantTable& constant_table = C->constant_table(); 1634 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1635 } 1636 } 1637 1638 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1639 { 1640 return MachNode::size(ra_); // too many variables; just compute it 1641 // the hard way 1642 } 1643 1644 int MachPrologNode::reloc() const 1645 { 1646 return 0; 1647 } 1648 1649 //============================================================================= 1650 1651 #ifndef PRODUCT 1652 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1653 Compile* C = ra_->C; 1654 int framesize = C->frame_slots() << LogBytesPerInt; 1655 1656 st->print("# pop frame %d\n\t",framesize); 1657 1658 if (framesize == 0) { 1659 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1660 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1661 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1662 st->print("add sp, sp, #%d\n\t", framesize); 1663 } else { 1664 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1665 st->print("add sp, sp, rscratch1\n\t"); 1666 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1667 } 1668 1669 if (do_polling() && C->is_method_compilation()) { 1670 st->print("# touch polling page\n\t"); 1671 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1672 st->print("ldr zr, [rscratch1]"); 1673 } 1674 } 1675 #endif 1676 1677 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1678 Compile* C = ra_->C; 1679 MacroAssembler _masm(&cbuf); 1680 int framesize = C->frame_slots() << LogBytesPerInt; 1681 1682 __ remove_frame(framesize); 1683 1684 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1685 __ reserved_stack_check(); 1686 } 1687 1688 if (do_polling() && C->is_method_compilation()) { 1689 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1690 } 1691 } 1692 1693 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1694 // Variable size. Determine dynamically. 1695 return MachNode::size(ra_); 1696 } 1697 1698 int MachEpilogNode::reloc() const { 1699 // Return number of relocatable values contained in this instruction. 1700 return 1; // 1 for polling page. 1701 } 1702 1703 const Pipeline * MachEpilogNode::pipeline() const { 1704 return MachNode::pipeline_class(); 1705 } 1706 1707 // This method seems to be obsolete. It is declared in machnode.hpp 1708 // and defined in all *.ad files, but it is never called. Should we 1709 // get rid of it? 1710 int MachEpilogNode::safepoint_offset() const { 1711 assert(do_polling(), "no return for this epilog node"); 1712 return 4; 1713 } 1714 1715 //============================================================================= 1716 1717 // Figure out which register class each belongs in: rc_int, rc_float or 1718 // rc_stack. 1719 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1720 1721 static enum RC rc_class(OptoReg::Name reg) { 1722 1723 if (reg == OptoReg::Bad) { 1724 return rc_bad; 1725 } 1726 1727 // we have 30 int registers * 2 halves 1728 // (rscratch1 and rscratch2 are omitted) 1729 1730 if (reg < 60) { 1731 return rc_int; 1732 } 1733 1734 // we have 32 float register * 2 halves 1735 if (reg < 60 + 128) { 1736 return rc_float; 1737 } 1738 1739 // Between float regs & stack is the flags regs. 1740 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1741 1742 return rc_stack; 1743 } 1744 1745 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1746 Compile* C = ra_->C; 1747 1748 // Get registers to move. 1749 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1750 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1751 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1752 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1753 1754 enum RC src_hi_rc = rc_class(src_hi); 1755 enum RC src_lo_rc = rc_class(src_lo); 1756 enum RC dst_hi_rc = rc_class(dst_hi); 1757 enum RC dst_lo_rc = rc_class(dst_lo); 1758 1759 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1760 1761 if (src_hi != OptoReg::Bad) { 1762 assert((src_lo&1)==0 && src_lo+1==src_hi && 1763 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1764 "expected aligned-adjacent pairs"); 1765 } 1766 1767 if (src_lo == dst_lo && src_hi == dst_hi) { 1768 return 0; // Self copy, no move. 1769 } 1770 1771 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1772 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1773 int src_offset = ra_->reg2offset(src_lo); 1774 int dst_offset = ra_->reg2offset(dst_lo); 1775 1776 if (bottom_type()->isa_vect() != NULL) { 1777 uint ireg = ideal_reg(); 1778 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1779 if (cbuf) { 1780 MacroAssembler _masm(cbuf); 1781 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1782 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1783 // stack->stack 1784 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1785 if (ireg == Op_VecD) { 1786 __ unspill(rscratch1, true, src_offset); 1787 __ spill(rscratch1, true, dst_offset); 1788 } else { 1789 __ spill_copy128(src_offset, dst_offset); 1790 } 1791 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1792 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1793 ireg == Op_VecD ? __ T8B : __ T16B, 1794 as_FloatRegister(Matcher::_regEncode[src_lo])); 1795 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1796 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1797 ireg == Op_VecD ? __ D : __ Q, 1798 ra_->reg2offset(dst_lo)); 1799 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1800 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1801 ireg == Op_VecD ? __ D : __ Q, 1802 ra_->reg2offset(src_lo)); 1803 } else { 1804 ShouldNotReachHere(); 1805 } 1806 } 1807 } else if (cbuf) { 1808 MacroAssembler _masm(cbuf); 1809 switch (src_lo_rc) { 1810 case rc_int: 1811 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1812 if (is64) { 1813 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1814 as_Register(Matcher::_regEncode[src_lo])); 1815 } else { 1816 MacroAssembler _masm(cbuf); 1817 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1818 as_Register(Matcher::_regEncode[src_lo])); 1819 } 1820 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1821 if (is64) { 1822 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1823 as_Register(Matcher::_regEncode[src_lo])); 1824 } else { 1825 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1826 as_Register(Matcher::_regEncode[src_lo])); 1827 } 1828 } else { // gpr --> stack spill 1829 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1830 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1831 } 1832 break; 1833 case rc_float: 1834 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1835 if (is64) { 1836 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1837 as_FloatRegister(Matcher::_regEncode[src_lo])); 1838 } else { 1839 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1840 as_FloatRegister(Matcher::_regEncode[src_lo])); 1841 } 1842 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1843 if (cbuf) { 1844 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1845 as_FloatRegister(Matcher::_regEncode[src_lo])); 1846 } else { 1847 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1848 as_FloatRegister(Matcher::_regEncode[src_lo])); 1849 } 1850 } else { // fpr --> stack spill 1851 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1852 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1853 is64 ? __ D : __ S, dst_offset); 1854 } 1855 break; 1856 case rc_stack: 1857 if (dst_lo_rc == rc_int) { // stack --> gpr load 1858 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1859 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1860 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1861 is64 ? __ D : __ S, src_offset); 1862 } else { // stack --> stack copy 1863 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1864 __ unspill(rscratch1, is64, src_offset); 1865 __ spill(rscratch1, is64, dst_offset); 1866 } 1867 break; 1868 default: 1869 assert(false, "bad rc_class for spill"); 1870 ShouldNotReachHere(); 1871 } 1872 } 1873 1874 if (st) { 1875 st->print("spill "); 1876 if (src_lo_rc == rc_stack) { 1877 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1878 } else { 1879 st->print("%s -> ", Matcher::regName[src_lo]); 1880 } 1881 if (dst_lo_rc == rc_stack) { 1882 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1883 } else { 1884 st->print("%s", Matcher::regName[dst_lo]); 1885 } 1886 if (bottom_type()->isa_vect() != NULL) { 1887 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1888 } else { 1889 st->print("\t# spill size = %d", is64 ? 64:32); 1890 } 1891 } 1892 1893 return 0; 1894 1895 } 1896 1897 #ifndef PRODUCT 1898 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1899 if (!ra_) 1900 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1901 else 1902 implementation(NULL, ra_, false, st); 1903 } 1904 #endif 1905 1906 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1907 implementation(&cbuf, ra_, false, NULL); 1908 } 1909 1910 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1911 return MachNode::size(ra_); 1912 } 1913 1914 //============================================================================= 1915 1916 #ifndef PRODUCT 1917 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1918 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1919 int reg = ra_->get_reg_first(this); 1920 st->print("add %s, rsp, #%d]\t# box lock", 1921 Matcher::regName[reg], offset); 1922 } 1923 #endif 1924 1925 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1926 MacroAssembler _masm(&cbuf); 1927 1928 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1929 int reg = ra_->get_encode(this); 1930 1931 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1932 __ add(as_Register(reg), sp, offset); 1933 } else { 1934 ShouldNotReachHere(); 1935 } 1936 } 1937 1938 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1939 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1940 return 4; 1941 } 1942 1943 //============================================================================= 1944 1945 #ifndef PRODUCT 1946 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1947 { 1948 st->print_cr("# MachUEPNode"); 1949 if (UseCompressedClassPointers) { 1950 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1951 if (Universe::narrow_klass_shift() != 0) { 1952 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1953 } 1954 } else { 1955 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1956 } 1957 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1958 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1959 } 1960 #endif 1961 1962 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1963 { 1964 // This is the unverified entry point. 1965 MacroAssembler _masm(&cbuf); 1966 1967 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1968 Label skip; 1969 // TODO 1970 // can we avoid this skip and still use a reloc? 1971 __ br(Assembler::EQ, skip); 1972 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1973 __ bind(skip); 1974 } 1975 1976 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1977 { 1978 return MachNode::size(ra_); 1979 } 1980 1981 // REQUIRED EMIT CODE 1982 1983 //============================================================================= 1984 1985 // Emit exception handler code. 1986 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1987 { 1988 // mov rscratch1 #exception_blob_entry_point 1989 // br rscratch1 1990 // Note that the code buffer's insts_mark is always relative to insts. 1991 // That's why we must use the macroassembler to generate a handler. 1992 MacroAssembler _masm(&cbuf); 1993 address base = __ start_a_stub(size_exception_handler()); 1994 if (base == NULL) { 1995 ciEnv::current()->record_failure("CodeCache is full"); 1996 return 0; // CodeBuffer::expand failed 1997 } 1998 int offset = __ offset(); 1999 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2000 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2001 __ end_a_stub(); 2002 return offset; 2003 } 2004 2005 // Emit deopt handler code. 2006 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2007 { 2008 // Note that the code buffer's insts_mark is always relative to insts. 2009 // That's why we must use the macroassembler to generate a handler. 2010 MacroAssembler _masm(&cbuf); 2011 address base = __ start_a_stub(size_deopt_handler()); 2012 if (base == NULL) { 2013 ciEnv::current()->record_failure("CodeCache is full"); 2014 return 0; // CodeBuffer::expand failed 2015 } 2016 int offset = __ offset(); 2017 2018 __ adr(lr, __ pc()); 2019 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2020 2021 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2022 __ end_a_stub(); 2023 return offset; 2024 } 2025 2026 // REQUIRED MATCHER CODE 2027 2028 //============================================================================= 2029 2030 const bool Matcher::match_rule_supported(int opcode) { 2031 2032 switch (opcode) { 2033 default: 2034 break; 2035 } 2036 2037 if (!has_match_rule(opcode)) { 2038 return false; 2039 } 2040 2041 return true; // Per default match rules are supported. 2042 } 2043 2044 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2045 2046 // TODO 2047 // identify extra cases that we might want to provide match rules for 2048 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2049 bool ret_value = match_rule_supported(opcode); 2050 // Add rules here. 2051 2052 return ret_value; // Per default match rules are supported. 2053 } 2054 2055 const bool Matcher::has_predicated_vectors(void) { 2056 return false; 2057 } 2058 2059 const int Matcher::float_pressure(int default_pressure_threshold) { 2060 return default_pressure_threshold; 2061 } 2062 2063 int Matcher::regnum_to_fpu_offset(int regnum) 2064 { 2065 Unimplemented(); 2066 return 0; 2067 } 2068 2069 // Is this branch offset short enough that a short branch can be used? 2070 // 2071 // NOTE: If the platform does not provide any short branch variants, then 2072 // this method should return false for offset 0. 2073 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2074 // The passed offset is relative to address of the branch. 2075 2076 return (-32768 <= offset && offset < 32768); 2077 } 2078 2079 const bool Matcher::isSimpleConstant64(jlong value) { 2080 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2081 // Probably always true, even if a temp register is required. 2082 return true; 2083 } 2084 2085 // true just means we have fast l2f conversion 2086 const bool Matcher::convL2FSupported(void) { 2087 return true; 2088 } 2089 2090 // Vector width in bytes. 2091 const int Matcher::vector_width_in_bytes(BasicType bt) { 2092 int size = MIN2(16,(int)MaxVectorSize); 2093 // Minimum 2 values in vector 2094 if (size < 2*type2aelembytes(bt)) size = 0; 2095 // But never < 4 2096 if (size < 4) size = 0; 2097 return size; 2098 } 2099 2100 // Limits on vector size (number of elements) loaded into vector. 2101 const int Matcher::max_vector_size(const BasicType bt) { 2102 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2103 } 2104 const int Matcher::min_vector_size(const BasicType bt) { 2105 // For the moment limit the vector size to 8 bytes 2106 int size = 8 / type2aelembytes(bt); 2107 if (size < 2) size = 2; 2108 return size; 2109 } 2110 2111 // Vector ideal reg. 2112 const uint Matcher::vector_ideal_reg(int len) { 2113 switch(len) { 2114 case 8: return Op_VecD; 2115 case 16: return Op_VecX; 2116 } 2117 ShouldNotReachHere(); 2118 return 0; 2119 } 2120 2121 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2122 switch(size) { 2123 case 8: return Op_VecD; 2124 case 16: return Op_VecX; 2125 } 2126 ShouldNotReachHere(); 2127 return 0; 2128 } 2129 2130 // AES support not yet implemented 2131 const bool Matcher::pass_original_key_for_aes() { 2132 return false; 2133 } 2134 2135 // aarch64 supports misaligned vectors store/load. 2136 const bool Matcher::misaligned_vectors_ok() { 2137 return true; 2138 } 2139 2140 // false => size gets scaled to BytesPerLong, ok. 2141 const bool Matcher::init_array_count_is_in_bytes = false; 2142 2143 // Use conditional move (CMOVL) 2144 const int Matcher::long_cmove_cost() { 2145 // long cmoves are no more expensive than int cmoves 2146 return 0; 2147 } 2148 2149 const int Matcher::float_cmove_cost() { 2150 // float cmoves are no more expensive than int cmoves 2151 return 0; 2152 } 2153 2154 // Does the CPU require late expand (see block.cpp for description of late expand)? 2155 const bool Matcher::require_postalloc_expand = false; 2156 2157 // Do we need to mask the count passed to shift instructions or does 2158 // the cpu only look at the lower 5/6 bits anyway? 2159 const bool Matcher::need_masked_shift_count = false; 2160 2161 // This affects two different things: 2162 // - how Decode nodes are matched 2163 // - how ImplicitNullCheck opportunities are recognized 2164 // If true, the matcher will try to remove all Decodes and match them 2165 // (as operands) into nodes. NullChecks are not prepared to deal with 2166 // Decodes by final_graph_reshaping(). 2167 // If false, final_graph_reshaping() forces the decode behind the Cmp 2168 // for a NullCheck. The matcher matches the Decode node into a register. 2169 // Implicit_null_check optimization moves the Decode along with the 2170 // memory operation back up before the NullCheck. 2171 bool Matcher::narrow_oop_use_complex_address() { 2172 return Universe::narrow_oop_shift() == 0; 2173 } 2174 2175 bool Matcher::narrow_klass_use_complex_address() { 2176 // TODO 2177 // decide whether we need to set this to true 2178 return false; 2179 } 2180 2181 bool Matcher::const_oop_prefer_decode() { 2182 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2183 return Universe::narrow_oop_base() == NULL; 2184 } 2185 2186 bool Matcher::const_klass_prefer_decode() { 2187 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2188 return Universe::narrow_klass_base() == NULL; 2189 } 2190 2191 // Is it better to copy float constants, or load them directly from 2192 // memory? Intel can load a float constant from a direct address, 2193 // requiring no extra registers. Most RISCs will have to materialize 2194 // an address into a register first, so they would do better to copy 2195 // the constant from stack. 2196 const bool Matcher::rematerialize_float_constants = false; 2197 2198 // If CPU can load and store mis-aligned doubles directly then no 2199 // fixup is needed. Else we split the double into 2 integer pieces 2200 // and move it piece-by-piece. Only happens when passing doubles into 2201 // C code as the Java calling convention forces doubles to be aligned. 2202 const bool Matcher::misaligned_doubles_ok = true; 2203 2204 // No-op on amd64 2205 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2206 Unimplemented(); 2207 } 2208 2209 // Advertise here if the CPU requires explicit rounding operations to 2210 // implement the UseStrictFP mode. 2211 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2212 2213 // Are floats converted to double when stored to stack during 2214 // deoptimization? 2215 bool Matcher::float_in_double() { return false; } 2216 2217 // Do ints take an entire long register or just half? 2218 // The relevant question is how the int is callee-saved: 2219 // the whole long is written but de-opt'ing will have to extract 2220 // the relevant 32 bits. 2221 const bool Matcher::int_in_long = true; 2222 2223 // Return whether or not this register is ever used as an argument. 2224 // This function is used on startup to build the trampoline stubs in 2225 // generateOptoStub. Registers not mentioned will be killed by the VM 2226 // call in the trampoline, and arguments in those registers not be 2227 // available to the callee. 2228 bool Matcher::can_be_java_arg(int reg) 2229 { 2230 return 2231 reg == R0_num || reg == R0_H_num || 2232 reg == R1_num || reg == R1_H_num || 2233 reg == R2_num || reg == R2_H_num || 2234 reg == R3_num || reg == R3_H_num || 2235 reg == R4_num || reg == R4_H_num || 2236 reg == R5_num || reg == R5_H_num || 2237 reg == R6_num || reg == R6_H_num || 2238 reg == R7_num || reg == R7_H_num || 2239 reg == V0_num || reg == V0_H_num || 2240 reg == V1_num || reg == V1_H_num || 2241 reg == V2_num || reg == V2_H_num || 2242 reg == V3_num || reg == V3_H_num || 2243 reg == V4_num || reg == V4_H_num || 2244 reg == V5_num || reg == V5_H_num || 2245 reg == V6_num || reg == V6_H_num || 2246 reg == V7_num || reg == V7_H_num; 2247 } 2248 2249 bool Matcher::is_spillable_arg(int reg) 2250 { 2251 return can_be_java_arg(reg); 2252 } 2253 2254 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2255 return false; 2256 } 2257 2258 RegMask Matcher::divI_proj_mask() { 2259 ShouldNotReachHere(); 2260 return RegMask(); 2261 } 2262 2263 // Register for MODI projection of divmodI. 2264 RegMask Matcher::modI_proj_mask() { 2265 ShouldNotReachHere(); 2266 return RegMask(); 2267 } 2268 2269 // Register for DIVL projection of divmodL. 2270 RegMask Matcher::divL_proj_mask() { 2271 ShouldNotReachHere(); 2272 return RegMask(); 2273 } 2274 2275 // Register for MODL projection of divmodL. 2276 RegMask Matcher::modL_proj_mask() { 2277 ShouldNotReachHere(); 2278 return RegMask(); 2279 } 2280 2281 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2282 return FP_REG_mask(); 2283 } 2284 2285 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2286 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2287 Node* u = addp->fast_out(i); 2288 if (u->is_Mem()) { 2289 int opsize = u->as_Mem()->memory_size(); 2290 assert(opsize > 0, "unexpected memory operand size"); 2291 if (u->as_Mem()->memory_size() != (1<<shift)) { 2292 return false; 2293 } 2294 } 2295 } 2296 return true; 2297 } 2298 2299 const bool Matcher::convi2l_type_required = false; 2300 2301 // Should the Matcher clone shifts on addressing modes, expecting them 2302 // to be subsumed into complex addressing expressions or compute them 2303 // into registers? 2304 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2305 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2306 return true; 2307 } 2308 2309 Node *off = m->in(AddPNode::Offset); 2310 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2311 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2312 // Are there other uses besides address expressions? 2313 !is_visited(off)) { 2314 address_visited.set(off->_idx); // Flag as address_visited 2315 mstack.push(off->in(2), Visit); 2316 Node *conv = off->in(1); 2317 if (conv->Opcode() == Op_ConvI2L && 2318 // Are there other uses besides address expressions? 2319 !is_visited(conv)) { 2320 address_visited.set(conv->_idx); // Flag as address_visited 2321 mstack.push(conv->in(1), Pre_Visit); 2322 } else { 2323 mstack.push(conv, Pre_Visit); 2324 } 2325 address_visited.test_set(m->_idx); // Flag as address_visited 2326 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2327 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2328 return true; 2329 } else if (off->Opcode() == Op_ConvI2L && 2330 // Are there other uses besides address expressions? 2331 !is_visited(off)) { 2332 address_visited.test_set(m->_idx); // Flag as address_visited 2333 address_visited.set(off->_idx); // Flag as address_visited 2334 mstack.push(off->in(1), Pre_Visit); 2335 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2336 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2337 return true; 2338 } 2339 return false; 2340 } 2341 2342 void Compile::reshape_address(AddPNode* addp) { 2343 } 2344 2345 2346 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2347 MacroAssembler _masm(&cbuf); \ 2348 { \ 2349 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2350 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2351 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2352 __ INSN(REG, as_Register(BASE)); \ 2353 } 2354 2355 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2356 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2357 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2358 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2359 2360 // Used for all non-volatile memory accesses. The use of 2361 // $mem->opcode() to discover whether this pattern uses sign-extended 2362 // offsets is something of a kludge. 2363 static void loadStore(MacroAssembler masm, mem_insn insn, 2364 Register reg, int opcode, 2365 Register base, int index, int size, int disp) 2366 { 2367 Address::extend scale; 2368 2369 // Hooboy, this is fugly. We need a way to communicate to the 2370 // encoder that the index needs to be sign extended, so we have to 2371 // enumerate all the cases. 2372 switch (opcode) { 2373 case INDINDEXSCALEDI2L: 2374 case INDINDEXSCALEDI2LN: 2375 case INDINDEXI2L: 2376 case INDINDEXI2LN: 2377 scale = Address::sxtw(size); 2378 break; 2379 default: 2380 scale = Address::lsl(size); 2381 } 2382 2383 if (index == -1) { 2384 (masm.*insn)(reg, Address(base, disp)); 2385 } else { 2386 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2387 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2388 } 2389 } 2390 2391 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2392 FloatRegister reg, int opcode, 2393 Register base, int index, int size, int disp) 2394 { 2395 Address::extend scale; 2396 2397 switch (opcode) { 2398 case INDINDEXSCALEDI2L: 2399 case INDINDEXSCALEDI2LN: 2400 scale = Address::sxtw(size); 2401 break; 2402 default: 2403 scale = Address::lsl(size); 2404 } 2405 2406 if (index == -1) { 2407 (masm.*insn)(reg, Address(base, disp)); 2408 } else { 2409 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2410 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2411 } 2412 } 2413 2414 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2415 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2416 int opcode, Register base, int index, int size, int disp) 2417 { 2418 if (index == -1) { 2419 (masm.*insn)(reg, T, Address(base, disp)); 2420 } else { 2421 assert(disp == 0, "unsupported address mode"); 2422 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2423 } 2424 } 2425 2426 %} 2427 2428 2429 2430 //----------ENCODING BLOCK----------------------------------------------------- 2431 // This block specifies the encoding classes used by the compiler to 2432 // output byte streams. Encoding classes are parameterized macros 2433 // used by Machine Instruction Nodes in order to generate the bit 2434 // encoding of the instruction. Operands specify their base encoding 2435 // interface with the interface keyword. There are currently 2436 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2437 // COND_INTER. REG_INTER causes an operand to generate a function 2438 // which returns its register number when queried. CONST_INTER causes 2439 // an operand to generate a function which returns the value of the 2440 // constant when queried. MEMORY_INTER causes an operand to generate 2441 // four functions which return the Base Register, the Index Register, 2442 // the Scale Value, and the Offset Value of the operand when queried. 2443 // COND_INTER causes an operand to generate six functions which return 2444 // the encoding code (ie - encoding bits for the instruction) 2445 // associated with each basic boolean condition for a conditional 2446 // instruction. 2447 // 2448 // Instructions specify two basic values for encoding. Again, a 2449 // function is available to check if the constant displacement is an 2450 // oop. They use the ins_encode keyword to specify their encoding 2451 // classes (which must be a sequence of enc_class names, and their 2452 // parameters, specified in the encoding block), and they use the 2453 // opcode keyword to specify, in order, their primary, secondary, and 2454 // tertiary opcode. Only the opcode sections which a particular 2455 // instruction needs for encoding need to be specified. 2456 encode %{ 2457 // Build emit functions for each basic byte or larger field in the 2458 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2459 // from C++ code in the enc_class source block. Emit functions will 2460 // live in the main source block for now. In future, we can 2461 // generalize this by adding a syntax that specifies the sizes of 2462 // fields in an order, so that the adlc can build the emit functions 2463 // automagically 2464 2465 // catch all for unimplemented encodings 2466 enc_class enc_unimplemented %{ 2467 MacroAssembler _masm(&cbuf); 2468 __ unimplemented("C2 catch all"); 2469 %} 2470 2471 // BEGIN Non-volatile memory access 2472 2473 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2474 Register dst_reg = as_Register($dst$$reg); 2475 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2476 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2477 %} 2478 2479 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2480 Register dst_reg = as_Register($dst$$reg); 2481 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2482 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2483 %} 2484 2485 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2486 Register dst_reg = as_Register($dst$$reg); 2487 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2488 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2489 %} 2490 2491 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2492 Register dst_reg = as_Register($dst$$reg); 2493 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2494 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2495 %} 2496 2497 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2498 Register dst_reg = as_Register($dst$$reg); 2499 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2500 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2501 %} 2502 2503 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2504 Register dst_reg = as_Register($dst$$reg); 2505 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2506 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2507 %} 2508 2509 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2510 Register dst_reg = as_Register($dst$$reg); 2511 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2512 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2513 %} 2514 2515 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2516 Register dst_reg = as_Register($dst$$reg); 2517 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2518 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2519 %} 2520 2521 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2522 Register dst_reg = as_Register($dst$$reg); 2523 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2524 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2525 %} 2526 2527 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2528 Register dst_reg = as_Register($dst$$reg); 2529 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2530 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2531 %} 2532 2533 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2534 Register dst_reg = as_Register($dst$$reg); 2535 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2536 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2537 %} 2538 2539 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2540 Register dst_reg = as_Register($dst$$reg); 2541 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2542 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2543 %} 2544 2545 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2546 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2547 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2548 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2549 %} 2550 2551 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2552 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2553 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2554 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2555 %} 2556 2557 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2558 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2559 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2560 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2561 %} 2562 2563 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2564 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2565 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2566 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2567 %} 2568 2569 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2570 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2571 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2572 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2573 %} 2574 2575 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2576 Register src_reg = as_Register($src$$reg); 2577 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2578 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2579 %} 2580 2581 enc_class aarch64_enc_strb0(memory mem) %{ 2582 MacroAssembler _masm(&cbuf); 2583 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2584 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2585 %} 2586 2587 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2588 MacroAssembler _masm(&cbuf); 2589 __ membar(Assembler::StoreStore); 2590 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2591 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2592 %} 2593 2594 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2595 Register src_reg = as_Register($src$$reg); 2596 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2597 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2598 %} 2599 2600 enc_class aarch64_enc_strh0(memory mem) %{ 2601 MacroAssembler _masm(&cbuf); 2602 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2603 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2604 %} 2605 2606 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2607 Register src_reg = as_Register($src$$reg); 2608 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2609 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2610 %} 2611 2612 enc_class aarch64_enc_strw0(memory mem) %{ 2613 MacroAssembler _masm(&cbuf); 2614 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2615 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2616 %} 2617 2618 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2619 Register src_reg = as_Register($src$$reg); 2620 // we sometimes get asked to store the stack pointer into the 2621 // current thread -- we cannot do that directly on AArch64 2622 if (src_reg == r31_sp) { 2623 MacroAssembler _masm(&cbuf); 2624 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2625 __ mov(rscratch2, sp); 2626 src_reg = rscratch2; 2627 } 2628 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2629 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2630 %} 2631 2632 enc_class aarch64_enc_str0(memory mem) %{ 2633 MacroAssembler _masm(&cbuf); 2634 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2635 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2636 %} 2637 2638 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2639 FloatRegister src_reg = as_FloatRegister($src$$reg); 2640 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2641 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2642 %} 2643 2644 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2645 FloatRegister src_reg = as_FloatRegister($src$$reg); 2646 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2647 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2648 %} 2649 2650 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2651 FloatRegister src_reg = as_FloatRegister($src$$reg); 2652 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2653 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2654 %} 2655 2656 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2657 FloatRegister src_reg = as_FloatRegister($src$$reg); 2658 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2659 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2660 %} 2661 2662 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2663 FloatRegister src_reg = as_FloatRegister($src$$reg); 2664 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2665 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2666 %} 2667 2668 // END Non-volatile memory access 2669 2670 // volatile loads and stores 2671 2672 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2673 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2674 rscratch1, stlrb); 2675 %} 2676 2677 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2678 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2679 rscratch1, stlrh); 2680 %} 2681 2682 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2683 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2684 rscratch1, stlrw); 2685 %} 2686 2687 2688 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2689 Register dst_reg = as_Register($dst$$reg); 2690 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2691 rscratch1, ldarb); 2692 __ sxtbw(dst_reg, dst_reg); 2693 %} 2694 2695 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2696 Register dst_reg = as_Register($dst$$reg); 2697 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2698 rscratch1, ldarb); 2699 __ sxtb(dst_reg, dst_reg); 2700 %} 2701 2702 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2703 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2704 rscratch1, ldarb); 2705 %} 2706 2707 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2708 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2709 rscratch1, ldarb); 2710 %} 2711 2712 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2713 Register dst_reg = as_Register($dst$$reg); 2714 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2715 rscratch1, ldarh); 2716 __ sxthw(dst_reg, dst_reg); 2717 %} 2718 2719 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2720 Register dst_reg = as_Register($dst$$reg); 2721 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2722 rscratch1, ldarh); 2723 __ sxth(dst_reg, dst_reg); 2724 %} 2725 2726 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2727 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2728 rscratch1, ldarh); 2729 %} 2730 2731 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2732 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2733 rscratch1, ldarh); 2734 %} 2735 2736 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2737 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2738 rscratch1, ldarw); 2739 %} 2740 2741 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2742 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2743 rscratch1, ldarw); 2744 %} 2745 2746 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2747 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2748 rscratch1, ldar); 2749 %} 2750 2751 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2752 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2753 rscratch1, ldarw); 2754 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2755 %} 2756 2757 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2758 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2759 rscratch1, ldar); 2760 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2761 %} 2762 2763 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2764 Register src_reg = as_Register($src$$reg); 2765 // we sometimes get asked to store the stack pointer into the 2766 // current thread -- we cannot do that directly on AArch64 2767 if (src_reg == r31_sp) { 2768 MacroAssembler _masm(&cbuf); 2769 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2770 __ mov(rscratch2, sp); 2771 src_reg = rscratch2; 2772 } 2773 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2774 rscratch1, stlr); 2775 %} 2776 2777 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2778 { 2779 MacroAssembler _masm(&cbuf); 2780 FloatRegister src_reg = as_FloatRegister($src$$reg); 2781 __ fmovs(rscratch2, src_reg); 2782 } 2783 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2784 rscratch1, stlrw); 2785 %} 2786 2787 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2788 { 2789 MacroAssembler _masm(&cbuf); 2790 FloatRegister src_reg = as_FloatRegister($src$$reg); 2791 __ fmovd(rscratch2, src_reg); 2792 } 2793 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2794 rscratch1, stlr); 2795 %} 2796 2797 // synchronized read/update encodings 2798 2799 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2800 MacroAssembler _masm(&cbuf); 2801 Register dst_reg = as_Register($dst$$reg); 2802 Register base = as_Register($mem$$base); 2803 int index = $mem$$index; 2804 int scale = $mem$$scale; 2805 int disp = $mem$$disp; 2806 if (index == -1) { 2807 if (disp != 0) { 2808 __ lea(rscratch1, Address(base, disp)); 2809 __ ldaxr(dst_reg, rscratch1); 2810 } else { 2811 // TODO 2812 // should we ever get anything other than this case? 2813 __ ldaxr(dst_reg, base); 2814 } 2815 } else { 2816 Register index_reg = as_Register(index); 2817 if (disp == 0) { 2818 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2819 __ ldaxr(dst_reg, rscratch1); 2820 } else { 2821 __ lea(rscratch1, Address(base, disp)); 2822 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2823 __ ldaxr(dst_reg, rscratch1); 2824 } 2825 } 2826 %} 2827 2828 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2829 MacroAssembler _masm(&cbuf); 2830 Register src_reg = as_Register($src$$reg); 2831 Register base = as_Register($mem$$base); 2832 int index = $mem$$index; 2833 int scale = $mem$$scale; 2834 int disp = $mem$$disp; 2835 if (index == -1) { 2836 if (disp != 0) { 2837 __ lea(rscratch2, Address(base, disp)); 2838 __ stlxr(rscratch1, src_reg, rscratch2); 2839 } else { 2840 // TODO 2841 // should we ever get anything other than this case? 2842 __ stlxr(rscratch1, src_reg, base); 2843 } 2844 } else { 2845 Register index_reg = as_Register(index); 2846 if (disp == 0) { 2847 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2848 __ stlxr(rscratch1, src_reg, rscratch2); 2849 } else { 2850 __ lea(rscratch2, Address(base, disp)); 2851 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2852 __ stlxr(rscratch1, src_reg, rscratch2); 2853 } 2854 } 2855 __ cmpw(rscratch1, zr); 2856 %} 2857 2858 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2859 MacroAssembler _masm(&cbuf); 2860 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2861 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2862 Assembler::xword, /*acquire*/ false, /*release*/ true, 2863 /*weak*/ false, noreg); 2864 %} 2865 2866 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2867 MacroAssembler _masm(&cbuf); 2868 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2869 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2870 Assembler::word, /*acquire*/ false, /*release*/ true, 2871 /*weak*/ false, noreg); 2872 %} 2873 2874 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2875 MacroAssembler _masm(&cbuf); 2876 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2877 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2878 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2879 /*weak*/ false, noreg); 2880 %} 2881 2882 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2883 MacroAssembler _masm(&cbuf); 2884 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2885 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2886 Assembler::byte, /*acquire*/ false, /*release*/ true, 2887 /*weak*/ false, noreg); 2888 %} 2889 2890 2891 // The only difference between aarch64_enc_cmpxchg and 2892 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2893 // CompareAndSwap sequence to serve as a barrier on acquiring a 2894 // lock. 2895 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2896 MacroAssembler _masm(&cbuf); 2897 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2898 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2899 Assembler::xword, /*acquire*/ true, /*release*/ true, 2900 /*weak*/ false, noreg); 2901 %} 2902 2903 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2904 MacroAssembler _masm(&cbuf); 2905 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2906 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2907 Assembler::word, /*acquire*/ true, /*release*/ true, 2908 /*weak*/ false, noreg); 2909 %} 2910 2911 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2912 MacroAssembler _masm(&cbuf); 2913 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2914 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2915 Assembler::halfword, /*acquire*/ true, /*release*/ true, 2916 /*weak*/ false, noreg); 2917 %} 2918 2919 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2920 MacroAssembler _masm(&cbuf); 2921 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2922 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2923 Assembler::byte, /*acquire*/ true, /*release*/ true, 2924 /*weak*/ false, noreg); 2925 %} 2926 2927 // auxiliary used for CompareAndSwapX to set result register 2928 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2929 MacroAssembler _masm(&cbuf); 2930 Register res_reg = as_Register($res$$reg); 2931 __ cset(res_reg, Assembler::EQ); 2932 %} 2933 2934 // prefetch encodings 2935 2936 enc_class aarch64_enc_prefetchw(memory mem) %{ 2937 MacroAssembler _masm(&cbuf); 2938 Register base = as_Register($mem$$base); 2939 int index = $mem$$index; 2940 int scale = $mem$$scale; 2941 int disp = $mem$$disp; 2942 if (index == -1) { 2943 __ prfm(Address(base, disp), PSTL1KEEP); 2944 } else { 2945 Register index_reg = as_Register(index); 2946 if (disp == 0) { 2947 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2948 } else { 2949 __ lea(rscratch1, Address(base, disp)); 2950 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2951 } 2952 } 2953 %} 2954 2955 /// mov envcodings 2956 2957 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2958 MacroAssembler _masm(&cbuf); 2959 u_int32_t con = (u_int32_t)$src$$constant; 2960 Register dst_reg = as_Register($dst$$reg); 2961 if (con == 0) { 2962 __ movw(dst_reg, zr); 2963 } else { 2964 __ movw(dst_reg, con); 2965 } 2966 %} 2967 2968 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2969 MacroAssembler _masm(&cbuf); 2970 Register dst_reg = as_Register($dst$$reg); 2971 u_int64_t con = (u_int64_t)$src$$constant; 2972 if (con == 0) { 2973 __ mov(dst_reg, zr); 2974 } else { 2975 __ mov(dst_reg, con); 2976 } 2977 %} 2978 2979 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 2980 MacroAssembler _masm(&cbuf); 2981 Register dst_reg = as_Register($dst$$reg); 2982 address con = (address)$src$$constant; 2983 if (con == NULL || con == (address)1) { 2984 ShouldNotReachHere(); 2985 } else { 2986 relocInfo::relocType rtype = $src->constant_reloc(); 2987 if (rtype == relocInfo::oop_type) { 2988 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 2989 } else if (rtype == relocInfo::metadata_type) { 2990 __ mov_metadata(dst_reg, (Metadata*)con); 2991 } else { 2992 assert(rtype == relocInfo::none, "unexpected reloc type"); 2993 if (con < (address)(uintptr_t)os::vm_page_size()) { 2994 __ mov(dst_reg, con); 2995 } else { 2996 unsigned long offset; 2997 __ adrp(dst_reg, con, offset); 2998 __ add(dst_reg, dst_reg, offset); 2999 } 3000 } 3001 } 3002 %} 3003 3004 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3005 MacroAssembler _masm(&cbuf); 3006 Register dst_reg = as_Register($dst$$reg); 3007 __ mov(dst_reg, zr); 3008 %} 3009 3010 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3011 MacroAssembler _masm(&cbuf); 3012 Register dst_reg = as_Register($dst$$reg); 3013 __ mov(dst_reg, (u_int64_t)1); 3014 %} 3015 3016 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3017 MacroAssembler _masm(&cbuf); 3018 address page = (address)$src$$constant; 3019 Register dst_reg = as_Register($dst$$reg); 3020 unsigned long off; 3021 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3022 assert(off == 0, "assumed offset == 0"); 3023 %} 3024 3025 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3026 MacroAssembler _masm(&cbuf); 3027 __ load_byte_map_base($dst$$Register); 3028 %} 3029 3030 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3031 MacroAssembler _masm(&cbuf); 3032 Register dst_reg = as_Register($dst$$reg); 3033 address con = (address)$src$$constant; 3034 if (con == NULL) { 3035 ShouldNotReachHere(); 3036 } else { 3037 relocInfo::relocType rtype = $src->constant_reloc(); 3038 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3039 __ set_narrow_oop(dst_reg, (jobject)con); 3040 } 3041 %} 3042 3043 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3044 MacroAssembler _masm(&cbuf); 3045 Register dst_reg = as_Register($dst$$reg); 3046 __ mov(dst_reg, zr); 3047 %} 3048 3049 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3050 MacroAssembler _masm(&cbuf); 3051 Register dst_reg = as_Register($dst$$reg); 3052 address con = (address)$src$$constant; 3053 if (con == NULL) { 3054 ShouldNotReachHere(); 3055 } else { 3056 relocInfo::relocType rtype = $src->constant_reloc(); 3057 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3058 __ set_narrow_klass(dst_reg, (Klass *)con); 3059 } 3060 %} 3061 3062 // arithmetic encodings 3063 3064 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3065 MacroAssembler _masm(&cbuf); 3066 Register dst_reg = as_Register($dst$$reg); 3067 Register src_reg = as_Register($src1$$reg); 3068 int32_t con = (int32_t)$src2$$constant; 3069 // add has primary == 0, subtract has primary == 1 3070 if ($primary) { con = -con; } 3071 if (con < 0) { 3072 __ subw(dst_reg, src_reg, -con); 3073 } else { 3074 __ addw(dst_reg, src_reg, con); 3075 } 3076 %} 3077 3078 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3079 MacroAssembler _masm(&cbuf); 3080 Register dst_reg = as_Register($dst$$reg); 3081 Register src_reg = as_Register($src1$$reg); 3082 int32_t con = (int32_t)$src2$$constant; 3083 // add has primary == 0, subtract has primary == 1 3084 if ($primary) { con = -con; } 3085 if (con < 0) { 3086 __ sub(dst_reg, src_reg, -con); 3087 } else { 3088 __ add(dst_reg, src_reg, con); 3089 } 3090 %} 3091 3092 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3093 MacroAssembler _masm(&cbuf); 3094 Register dst_reg = as_Register($dst$$reg); 3095 Register src1_reg = as_Register($src1$$reg); 3096 Register src2_reg = as_Register($src2$$reg); 3097 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3098 %} 3099 3100 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3101 MacroAssembler _masm(&cbuf); 3102 Register dst_reg = as_Register($dst$$reg); 3103 Register src1_reg = as_Register($src1$$reg); 3104 Register src2_reg = as_Register($src2$$reg); 3105 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3106 %} 3107 3108 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3109 MacroAssembler _masm(&cbuf); 3110 Register dst_reg = as_Register($dst$$reg); 3111 Register src1_reg = as_Register($src1$$reg); 3112 Register src2_reg = as_Register($src2$$reg); 3113 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3114 %} 3115 3116 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3117 MacroAssembler _masm(&cbuf); 3118 Register dst_reg = as_Register($dst$$reg); 3119 Register src1_reg = as_Register($src1$$reg); 3120 Register src2_reg = as_Register($src2$$reg); 3121 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3122 %} 3123 3124 // compare instruction encodings 3125 3126 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3127 MacroAssembler _masm(&cbuf); 3128 Register reg1 = as_Register($src1$$reg); 3129 Register reg2 = as_Register($src2$$reg); 3130 __ cmpw(reg1, reg2); 3131 %} 3132 3133 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3134 MacroAssembler _masm(&cbuf); 3135 Register reg = as_Register($src1$$reg); 3136 int32_t val = $src2$$constant; 3137 if (val >= 0) { 3138 __ subsw(zr, reg, val); 3139 } else { 3140 __ addsw(zr, reg, -val); 3141 } 3142 %} 3143 3144 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3145 MacroAssembler _masm(&cbuf); 3146 Register reg1 = as_Register($src1$$reg); 3147 u_int32_t val = (u_int32_t)$src2$$constant; 3148 __ movw(rscratch1, val); 3149 __ cmpw(reg1, rscratch1); 3150 %} 3151 3152 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3153 MacroAssembler _masm(&cbuf); 3154 Register reg1 = as_Register($src1$$reg); 3155 Register reg2 = as_Register($src2$$reg); 3156 __ cmp(reg1, reg2); 3157 %} 3158 3159 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3160 MacroAssembler _masm(&cbuf); 3161 Register reg = as_Register($src1$$reg); 3162 int64_t val = $src2$$constant; 3163 if (val >= 0) { 3164 __ subs(zr, reg, val); 3165 } else if (val != -val) { 3166 __ adds(zr, reg, -val); 3167 } else { 3168 // aargh, Long.MIN_VALUE is a special case 3169 __ orr(rscratch1, zr, (u_int64_t)val); 3170 __ subs(zr, reg, rscratch1); 3171 } 3172 %} 3173 3174 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3175 MacroAssembler _masm(&cbuf); 3176 Register reg1 = as_Register($src1$$reg); 3177 u_int64_t val = (u_int64_t)$src2$$constant; 3178 __ mov(rscratch1, val); 3179 __ cmp(reg1, rscratch1); 3180 %} 3181 3182 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3183 MacroAssembler _masm(&cbuf); 3184 Register reg1 = as_Register($src1$$reg); 3185 Register reg2 = as_Register($src2$$reg); 3186 __ cmp(reg1, reg2); 3187 %} 3188 3189 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3190 MacroAssembler _masm(&cbuf); 3191 Register reg1 = as_Register($src1$$reg); 3192 Register reg2 = as_Register($src2$$reg); 3193 __ cmpw(reg1, reg2); 3194 %} 3195 3196 enc_class aarch64_enc_testp(iRegP src) %{ 3197 MacroAssembler _masm(&cbuf); 3198 Register reg = as_Register($src$$reg); 3199 __ cmp(reg, zr); 3200 %} 3201 3202 enc_class aarch64_enc_testn(iRegN src) %{ 3203 MacroAssembler _masm(&cbuf); 3204 Register reg = as_Register($src$$reg); 3205 __ cmpw(reg, zr); 3206 %} 3207 3208 enc_class aarch64_enc_b(label lbl) %{ 3209 MacroAssembler _masm(&cbuf); 3210 Label *L = $lbl$$label; 3211 __ b(*L); 3212 %} 3213 3214 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3215 MacroAssembler _masm(&cbuf); 3216 Label *L = $lbl$$label; 3217 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3218 %} 3219 3220 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3221 MacroAssembler _masm(&cbuf); 3222 Label *L = $lbl$$label; 3223 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3224 %} 3225 3226 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3227 %{ 3228 Register sub_reg = as_Register($sub$$reg); 3229 Register super_reg = as_Register($super$$reg); 3230 Register temp_reg = as_Register($temp$$reg); 3231 Register result_reg = as_Register($result$$reg); 3232 3233 Label miss; 3234 MacroAssembler _masm(&cbuf); 3235 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3236 NULL, &miss, 3237 /*set_cond_codes:*/ true); 3238 if ($primary) { 3239 __ mov(result_reg, zr); 3240 } 3241 __ bind(miss); 3242 %} 3243 3244 enc_class aarch64_enc_java_static_call(method meth) %{ 3245 MacroAssembler _masm(&cbuf); 3246 3247 address addr = (address)$meth$$method; 3248 address call; 3249 if (!_method) { 3250 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3251 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3252 } else { 3253 int method_index = resolved_method_index(cbuf); 3254 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3255 : static_call_Relocation::spec(method_index); 3256 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3257 3258 // Emit stub for static call 3259 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3260 if (stub == NULL) { 3261 ciEnv::current()->record_failure("CodeCache is full"); 3262 return; 3263 } 3264 } 3265 if (call == NULL) { 3266 ciEnv::current()->record_failure("CodeCache is full"); 3267 return; 3268 } 3269 %} 3270 3271 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3272 MacroAssembler _masm(&cbuf); 3273 int method_index = resolved_method_index(cbuf); 3274 address call = __ ic_call((address)$meth$$method, method_index); 3275 if (call == NULL) { 3276 ciEnv::current()->record_failure("CodeCache is full"); 3277 return; 3278 } 3279 %} 3280 3281 enc_class aarch64_enc_call_epilog() %{ 3282 MacroAssembler _masm(&cbuf); 3283 if (VerifyStackAtCalls) { 3284 // Check that stack depth is unchanged: find majik cookie on stack 3285 __ call_Unimplemented(); 3286 } 3287 %} 3288 3289 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3290 MacroAssembler _masm(&cbuf); 3291 3292 // some calls to generated routines (arraycopy code) are scheduled 3293 // by C2 as runtime calls. if so we can call them using a br (they 3294 // will be in a reachable segment) otherwise we have to use a blr 3295 // which loads the absolute address into a register. 3296 address entry = (address)$meth$$method; 3297 CodeBlob *cb = CodeCache::find_blob(entry); 3298 if (cb) { 3299 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3300 if (call == NULL) { 3301 ciEnv::current()->record_failure("CodeCache is full"); 3302 return; 3303 } 3304 } else { 3305 Label retaddr; 3306 __ adr(rscratch2, retaddr); 3307 __ lea(rscratch1, RuntimeAddress(entry)); 3308 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3309 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3310 __ blr(rscratch1); 3311 __ bind(retaddr); 3312 __ add(sp, sp, 2 * wordSize); 3313 } 3314 %} 3315 3316 enc_class aarch64_enc_rethrow() %{ 3317 MacroAssembler _masm(&cbuf); 3318 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3319 %} 3320 3321 enc_class aarch64_enc_ret() %{ 3322 MacroAssembler _masm(&cbuf); 3323 __ ret(lr); 3324 %} 3325 3326 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3327 MacroAssembler _masm(&cbuf); 3328 Register target_reg = as_Register($jump_target$$reg); 3329 __ br(target_reg); 3330 %} 3331 3332 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3333 MacroAssembler _masm(&cbuf); 3334 Register target_reg = as_Register($jump_target$$reg); 3335 // exception oop should be in r0 3336 // ret addr has been popped into lr 3337 // callee expects it in r3 3338 __ mov(r3, lr); 3339 __ br(target_reg); 3340 %} 3341 3342 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3343 MacroAssembler _masm(&cbuf); 3344 Register oop = as_Register($object$$reg); 3345 Register box = as_Register($box$$reg); 3346 Register disp_hdr = as_Register($tmp$$reg); 3347 Register tmp = as_Register($tmp2$$reg); 3348 Label cont; 3349 Label object_has_monitor; 3350 Label cas_failed; 3351 3352 assert_different_registers(oop, box, tmp, disp_hdr); 3353 3354 // Load markOop from object into displaced_header. 3355 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3356 3357 // Always do locking in runtime. 3358 if (EmitSync & 0x01) { 3359 __ cmp(oop, zr); 3360 return; 3361 } 3362 3363 if (UseBiasedLocking && !UseOptoBiasInlining) { 3364 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3365 } 3366 3367 // Check for existing monitor 3368 if ((EmitSync & 0x02) == 0) { 3369 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3370 } 3371 3372 // Set tmp to be (markOop of object | UNLOCK_VALUE). 3373 __ orr(tmp, disp_hdr, markOopDesc::unlocked_value); 3374 3375 // Initialize the box. (Must happen before we update the object mark!) 3376 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3377 3378 // Compare object markOop with an unlocked value (tmp) and if 3379 // equal exchange the stack address of our box with object markOop. 3380 // On failure disp_hdr contains the possibly locked markOop. 3381 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3382 /*release*/ true, /*weak*/ false, disp_hdr); 3383 __ br(Assembler::EQ, cont); 3384 3385 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3386 3387 // If the compare-and-exchange succeeded, then we found an unlocked 3388 // object, will have now locked it will continue at label cont 3389 3390 __ bind(cas_failed); 3391 // We did not see an unlocked object so try the fast recursive case. 3392 3393 // Check if the owner is self by comparing the value in the 3394 // markOop of object (disp_hdr) with the stack pointer. 3395 __ mov(rscratch1, sp); 3396 __ sub(disp_hdr, disp_hdr, rscratch1); 3397 __ mov(tmp, (address) (~(os::vm_page_size()-1) | (uintptr_t)markOopDesc::lock_mask_in_place)); 3398 // If condition is true we are cont and hence we can store 0 as the 3399 // displaced header in the box, which indicates that it is a recursive lock. 3400 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3401 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3402 3403 if ((EmitSync & 0x02) == 0) { 3404 __ b(cont); 3405 3406 // Handle existing monitor. 3407 __ bind(object_has_monitor); 3408 // The object's monitor m is unlocked iff m->owner == NULL, 3409 // otherwise m->owner may contain a thread or a stack address. 3410 // 3411 // Try to CAS m->owner from NULL to current thread. 3412 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3413 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3414 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3415 3416 // Store a non-null value into the box to avoid looking like a re-entrant 3417 // lock. The fast-path monitor unlock code checks for 3418 // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the 3419 // relevant bit set, and also matches ObjectSynchronizer::slow_enter. 3420 __ mov(tmp, (address)markOopDesc::unused_mark()); 3421 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3422 } 3423 3424 __ bind(cont); 3425 // flag == EQ indicates success 3426 // flag == NE indicates failure 3427 %} 3428 3429 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3430 MacroAssembler _masm(&cbuf); 3431 Register oop = as_Register($object$$reg); 3432 Register box = as_Register($box$$reg); 3433 Register disp_hdr = as_Register($tmp$$reg); 3434 Register tmp = as_Register($tmp2$$reg); 3435 Label cont; 3436 Label object_has_monitor; 3437 3438 assert_different_registers(oop, box, tmp, disp_hdr); 3439 3440 // Always do locking in runtime. 3441 if (EmitSync & 0x01) { 3442 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3443 return; 3444 } 3445 3446 if (UseBiasedLocking && !UseOptoBiasInlining) { 3447 __ biased_locking_exit(oop, tmp, cont); 3448 } 3449 3450 // Find the lock address and load the displaced header from the stack. 3451 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3452 3453 // If the displaced header is 0, we have a recursive unlock. 3454 __ cmp(disp_hdr, zr); 3455 __ br(Assembler::EQ, cont); 3456 3457 // Handle existing monitor. 3458 if ((EmitSync & 0x02) == 0) { 3459 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3460 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3461 } 3462 3463 // Check if it is still a light weight lock, this is is true if we 3464 // see the stack address of the basicLock in the markOop of the 3465 // object. 3466 3467 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3468 /*release*/ true, /*weak*/ false, tmp); 3469 __ b(cont); 3470 3471 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3472 3473 // Handle existing monitor. 3474 if ((EmitSync & 0x02) == 0) { 3475 __ bind(object_has_monitor); 3476 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3477 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3478 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3479 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3480 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3481 __ cmp(rscratch1, zr); // Sets flags for result 3482 __ br(Assembler::NE, cont); 3483 3484 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3485 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3486 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3487 __ cmp(rscratch1, zr); // Sets flags for result 3488 __ cbnz(rscratch1, cont); 3489 // need a release store here 3490 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3491 __ stlr(zr, tmp); // set unowned 3492 } 3493 3494 __ bind(cont); 3495 // flag == EQ indicates success 3496 // flag == NE indicates failure 3497 %} 3498 3499 %} 3500 3501 //----------FRAME-------------------------------------------------------------- 3502 // Definition of frame structure and management information. 3503 // 3504 // S T A C K L A Y O U T Allocators stack-slot number 3505 // | (to get allocators register number 3506 // G Owned by | | v add OptoReg::stack0()) 3507 // r CALLER | | 3508 // o | +--------+ pad to even-align allocators stack-slot 3509 // w V | pad0 | numbers; owned by CALLER 3510 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3511 // h ^ | in | 5 3512 // | | args | 4 Holes in incoming args owned by SELF 3513 // | | | | 3 3514 // | | +--------+ 3515 // V | | old out| Empty on Intel, window on Sparc 3516 // | old |preserve| Must be even aligned. 3517 // | SP-+--------+----> Matcher::_old_SP, even aligned 3518 // | | in | 3 area for Intel ret address 3519 // Owned by |preserve| Empty on Sparc. 3520 // SELF +--------+ 3521 // | | pad2 | 2 pad to align old SP 3522 // | +--------+ 1 3523 // | | locks | 0 3524 // | +--------+----> OptoReg::stack0(), even aligned 3525 // | | pad1 | 11 pad to align new SP 3526 // | +--------+ 3527 // | | | 10 3528 // | | spills | 9 spills 3529 // V | | 8 (pad0 slot for callee) 3530 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3531 // ^ | out | 7 3532 // | | args | 6 Holes in outgoing args owned by CALLEE 3533 // Owned by +--------+ 3534 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3535 // | new |preserve| Must be even-aligned. 3536 // | SP-+--------+----> Matcher::_new_SP, even aligned 3537 // | | | 3538 // 3539 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3540 // known from SELF's arguments and the Java calling convention. 3541 // Region 6-7 is determined per call site. 3542 // Note 2: If the calling convention leaves holes in the incoming argument 3543 // area, those holes are owned by SELF. Holes in the outgoing area 3544 // are owned by the CALLEE. Holes should not be nessecary in the 3545 // incoming area, as the Java calling convention is completely under 3546 // the control of the AD file. Doubles can be sorted and packed to 3547 // avoid holes. Holes in the outgoing arguments may be nessecary for 3548 // varargs C calling conventions. 3549 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3550 // even aligned with pad0 as needed. 3551 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3552 // (the latter is true on Intel but is it false on AArch64?) 3553 // region 6-11 is even aligned; it may be padded out more so that 3554 // the region from SP to FP meets the minimum stack alignment. 3555 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3556 // alignment. Region 11, pad1, may be dynamically extended so that 3557 // SP meets the minimum alignment. 3558 3559 frame %{ 3560 // What direction does stack grow in (assumed to be same for C & Java) 3561 stack_direction(TOWARDS_LOW); 3562 3563 // These three registers define part of the calling convention 3564 // between compiled code and the interpreter. 3565 3566 // Inline Cache Register or methodOop for I2C. 3567 inline_cache_reg(R12); 3568 3569 // Method Oop Register when calling interpreter. 3570 interpreter_method_oop_reg(R12); 3571 3572 // Number of stack slots consumed by locking an object 3573 sync_stack_slots(2); 3574 3575 // Compiled code's Frame Pointer 3576 frame_pointer(R31); 3577 3578 // Interpreter stores its frame pointer in a register which is 3579 // stored to the stack by I2CAdaptors. 3580 // I2CAdaptors convert from interpreted java to compiled java. 3581 interpreter_frame_pointer(R29); 3582 3583 // Stack alignment requirement 3584 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3585 3586 // Number of stack slots between incoming argument block and the start of 3587 // a new frame. The PROLOG must add this many slots to the stack. The 3588 // EPILOG must remove this many slots. aarch64 needs two slots for 3589 // return address and fp. 3590 // TODO think this is correct but check 3591 in_preserve_stack_slots(4); 3592 3593 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3594 // for calls to C. Supports the var-args backing area for register parms. 3595 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3596 3597 // The after-PROLOG location of the return address. Location of 3598 // return address specifies a type (REG or STACK) and a number 3599 // representing the register number (i.e. - use a register name) or 3600 // stack slot. 3601 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3602 // Otherwise, it is above the locks and verification slot and alignment word 3603 // TODO this may well be correct but need to check why that - 2 is there 3604 // ppc port uses 0 but we definitely need to allow for fixed_slots 3605 // which folds in the space used for monitors 3606 return_addr(STACK - 2 + 3607 align_up((Compile::current()->in_preserve_stack_slots() + 3608 Compile::current()->fixed_slots()), 3609 stack_alignment_in_slots())); 3610 3611 // Body of function which returns an integer array locating 3612 // arguments either in registers or in stack slots. Passed an array 3613 // of ideal registers called "sig" and a "length" count. Stack-slot 3614 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3615 // arguments for a CALLEE. Incoming stack arguments are 3616 // automatically biased by the preserve_stack_slots field above. 3617 3618 calling_convention 3619 %{ 3620 // No difference between ingoing/outgoing just pass false 3621 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3622 %} 3623 3624 c_calling_convention 3625 %{ 3626 // This is obviously always outgoing 3627 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3628 %} 3629 3630 // Location of compiled Java return values. Same as C for now. 3631 return_value 3632 %{ 3633 // TODO do we allow ideal_reg == Op_RegN??? 3634 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3635 "only return normal values"); 3636 3637 static const int lo[Op_RegL + 1] = { // enum name 3638 0, // Op_Node 3639 0, // Op_Set 3640 R0_num, // Op_RegN 3641 R0_num, // Op_RegI 3642 R0_num, // Op_RegP 3643 V0_num, // Op_RegF 3644 V0_num, // Op_RegD 3645 R0_num // Op_RegL 3646 }; 3647 3648 static const int hi[Op_RegL + 1] = { // enum name 3649 0, // Op_Node 3650 0, // Op_Set 3651 OptoReg::Bad, // Op_RegN 3652 OptoReg::Bad, // Op_RegI 3653 R0_H_num, // Op_RegP 3654 OptoReg::Bad, // Op_RegF 3655 V0_H_num, // Op_RegD 3656 R0_H_num // Op_RegL 3657 }; 3658 3659 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3660 %} 3661 %} 3662 3663 //----------ATTRIBUTES--------------------------------------------------------- 3664 //----------Operand Attributes------------------------------------------------- 3665 op_attrib op_cost(1); // Required cost attribute 3666 3667 //----------Instruction Attributes--------------------------------------------- 3668 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3669 ins_attrib ins_size(32); // Required size attribute (in bits) 3670 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3671 // a non-matching short branch variant 3672 // of some long branch? 3673 ins_attrib ins_alignment(4); // Required alignment attribute (must 3674 // be a power of 2) specifies the 3675 // alignment that some part of the 3676 // instruction (not necessarily the 3677 // start) requires. If > 1, a 3678 // compute_padding() function must be 3679 // provided for the instruction 3680 3681 //----------OPERANDS----------------------------------------------------------- 3682 // Operand definitions must precede instruction definitions for correct parsing 3683 // in the ADLC because operands constitute user defined types which are used in 3684 // instruction definitions. 3685 3686 //----------Simple Operands---------------------------------------------------- 3687 3688 // Integer operands 32 bit 3689 // 32 bit immediate 3690 operand immI() 3691 %{ 3692 match(ConI); 3693 3694 op_cost(0); 3695 format %{ %} 3696 interface(CONST_INTER); 3697 %} 3698 3699 // 32 bit zero 3700 operand immI0() 3701 %{ 3702 predicate(n->get_int() == 0); 3703 match(ConI); 3704 3705 op_cost(0); 3706 format %{ %} 3707 interface(CONST_INTER); 3708 %} 3709 3710 // 32 bit unit increment 3711 operand immI_1() 3712 %{ 3713 predicate(n->get_int() == 1); 3714 match(ConI); 3715 3716 op_cost(0); 3717 format %{ %} 3718 interface(CONST_INTER); 3719 %} 3720 3721 // 32 bit unit decrement 3722 operand immI_M1() 3723 %{ 3724 predicate(n->get_int() == -1); 3725 match(ConI); 3726 3727 op_cost(0); 3728 format %{ %} 3729 interface(CONST_INTER); 3730 %} 3731 3732 // Shift values for add/sub extension shift 3733 operand immIExt() 3734 %{ 3735 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3736 match(ConI); 3737 3738 op_cost(0); 3739 format %{ %} 3740 interface(CONST_INTER); 3741 %} 3742 3743 operand immI_le_4() 3744 %{ 3745 predicate(n->get_int() <= 4); 3746 match(ConI); 3747 3748 op_cost(0); 3749 format %{ %} 3750 interface(CONST_INTER); 3751 %} 3752 3753 operand immI_31() 3754 %{ 3755 predicate(n->get_int() == 31); 3756 match(ConI); 3757 3758 op_cost(0); 3759 format %{ %} 3760 interface(CONST_INTER); 3761 %} 3762 3763 operand immI_8() 3764 %{ 3765 predicate(n->get_int() == 8); 3766 match(ConI); 3767 3768 op_cost(0); 3769 format %{ %} 3770 interface(CONST_INTER); 3771 %} 3772 3773 operand immI_16() 3774 %{ 3775 predicate(n->get_int() == 16); 3776 match(ConI); 3777 3778 op_cost(0); 3779 format %{ %} 3780 interface(CONST_INTER); 3781 %} 3782 3783 operand immI_24() 3784 %{ 3785 predicate(n->get_int() == 24); 3786 match(ConI); 3787 3788 op_cost(0); 3789 format %{ %} 3790 interface(CONST_INTER); 3791 %} 3792 3793 operand immI_32() 3794 %{ 3795 predicate(n->get_int() == 32); 3796 match(ConI); 3797 3798 op_cost(0); 3799 format %{ %} 3800 interface(CONST_INTER); 3801 %} 3802 3803 operand immI_48() 3804 %{ 3805 predicate(n->get_int() == 48); 3806 match(ConI); 3807 3808 op_cost(0); 3809 format %{ %} 3810 interface(CONST_INTER); 3811 %} 3812 3813 operand immI_56() 3814 %{ 3815 predicate(n->get_int() == 56); 3816 match(ConI); 3817 3818 op_cost(0); 3819 format %{ %} 3820 interface(CONST_INTER); 3821 %} 3822 3823 operand immI_63() 3824 %{ 3825 predicate(n->get_int() == 63); 3826 match(ConI); 3827 3828 op_cost(0); 3829 format %{ %} 3830 interface(CONST_INTER); 3831 %} 3832 3833 operand immI_64() 3834 %{ 3835 predicate(n->get_int() == 64); 3836 match(ConI); 3837 3838 op_cost(0); 3839 format %{ %} 3840 interface(CONST_INTER); 3841 %} 3842 3843 operand immI_255() 3844 %{ 3845 predicate(n->get_int() == 255); 3846 match(ConI); 3847 3848 op_cost(0); 3849 format %{ %} 3850 interface(CONST_INTER); 3851 %} 3852 3853 operand immI_65535() 3854 %{ 3855 predicate(n->get_int() == 65535); 3856 match(ConI); 3857 3858 op_cost(0); 3859 format %{ %} 3860 interface(CONST_INTER); 3861 %} 3862 3863 operand immL_255() 3864 %{ 3865 predicate(n->get_long() == 255L); 3866 match(ConL); 3867 3868 op_cost(0); 3869 format %{ %} 3870 interface(CONST_INTER); 3871 %} 3872 3873 operand immL_65535() 3874 %{ 3875 predicate(n->get_long() == 65535L); 3876 match(ConL); 3877 3878 op_cost(0); 3879 format %{ %} 3880 interface(CONST_INTER); 3881 %} 3882 3883 operand immL_4294967295() 3884 %{ 3885 predicate(n->get_long() == 4294967295L); 3886 match(ConL); 3887 3888 op_cost(0); 3889 format %{ %} 3890 interface(CONST_INTER); 3891 %} 3892 3893 operand immL_bitmask() 3894 %{ 3895 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3896 && is_power_of_2(n->get_long() + 1)); 3897 match(ConL); 3898 3899 op_cost(0); 3900 format %{ %} 3901 interface(CONST_INTER); 3902 %} 3903 3904 operand immI_bitmask() 3905 %{ 3906 predicate(((n->get_int() & 0xc0000000) == 0) 3907 && is_power_of_2(n->get_int() + 1)); 3908 match(ConI); 3909 3910 op_cost(0); 3911 format %{ %} 3912 interface(CONST_INTER); 3913 %} 3914 3915 // Scale values for scaled offset addressing modes (up to long but not quad) 3916 operand immIScale() 3917 %{ 3918 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3919 match(ConI); 3920 3921 op_cost(0); 3922 format %{ %} 3923 interface(CONST_INTER); 3924 %} 3925 3926 // 26 bit signed offset -- for pc-relative branches 3927 operand immI26() 3928 %{ 3929 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 3930 match(ConI); 3931 3932 op_cost(0); 3933 format %{ %} 3934 interface(CONST_INTER); 3935 %} 3936 3937 // 19 bit signed offset -- for pc-relative loads 3938 operand immI19() 3939 %{ 3940 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 3941 match(ConI); 3942 3943 op_cost(0); 3944 format %{ %} 3945 interface(CONST_INTER); 3946 %} 3947 3948 // 12 bit unsigned offset -- for base plus immediate loads 3949 operand immIU12() 3950 %{ 3951 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 3952 match(ConI); 3953 3954 op_cost(0); 3955 format %{ %} 3956 interface(CONST_INTER); 3957 %} 3958 3959 operand immLU12() 3960 %{ 3961 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 3962 match(ConL); 3963 3964 op_cost(0); 3965 format %{ %} 3966 interface(CONST_INTER); 3967 %} 3968 3969 // Offset for scaled or unscaled immediate loads and stores 3970 operand immIOffset() 3971 %{ 3972 predicate(Address::offset_ok_for_immed(n->get_int())); 3973 match(ConI); 3974 3975 op_cost(0); 3976 format %{ %} 3977 interface(CONST_INTER); 3978 %} 3979 3980 operand immIOffset4() 3981 %{ 3982 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 3983 match(ConI); 3984 3985 op_cost(0); 3986 format %{ %} 3987 interface(CONST_INTER); 3988 %} 3989 3990 operand immIOffset8() 3991 %{ 3992 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 3993 match(ConI); 3994 3995 op_cost(0); 3996 format %{ %} 3997 interface(CONST_INTER); 3998 %} 3999 4000 operand immIOffset16() 4001 %{ 4002 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4003 match(ConI); 4004 4005 op_cost(0); 4006 format %{ %} 4007 interface(CONST_INTER); 4008 %} 4009 4010 operand immLoffset() 4011 %{ 4012 predicate(Address::offset_ok_for_immed(n->get_long())); 4013 match(ConL); 4014 4015 op_cost(0); 4016 format %{ %} 4017 interface(CONST_INTER); 4018 %} 4019 4020 operand immLoffset4() 4021 %{ 4022 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4023 match(ConL); 4024 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 operand immLoffset8() 4031 %{ 4032 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4033 match(ConL); 4034 4035 op_cost(0); 4036 format %{ %} 4037 interface(CONST_INTER); 4038 %} 4039 4040 operand immLoffset16() 4041 %{ 4042 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4043 match(ConL); 4044 4045 op_cost(0); 4046 format %{ %} 4047 interface(CONST_INTER); 4048 %} 4049 4050 // 32 bit integer valid for add sub immediate 4051 operand immIAddSub() 4052 %{ 4053 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4054 match(ConI); 4055 op_cost(0); 4056 format %{ %} 4057 interface(CONST_INTER); 4058 %} 4059 4060 // 32 bit unsigned integer valid for logical immediate 4061 // TODO -- check this is right when e.g the mask is 0x80000000 4062 operand immILog() 4063 %{ 4064 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4065 match(ConI); 4066 4067 op_cost(0); 4068 format %{ %} 4069 interface(CONST_INTER); 4070 %} 4071 4072 // Integer operands 64 bit 4073 // 64 bit immediate 4074 operand immL() 4075 %{ 4076 match(ConL); 4077 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 // 64 bit zero 4084 operand immL0() 4085 %{ 4086 predicate(n->get_long() == 0); 4087 match(ConL); 4088 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 // 64 bit unit increment 4095 operand immL_1() 4096 %{ 4097 predicate(n->get_long() == 1); 4098 match(ConL); 4099 4100 op_cost(0); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 // 64 bit unit decrement 4106 operand immL_M1() 4107 %{ 4108 predicate(n->get_long() == -1); 4109 match(ConL); 4110 4111 op_cost(0); 4112 format %{ %} 4113 interface(CONST_INTER); 4114 %} 4115 4116 // 32 bit offset of pc in thread anchor 4117 4118 operand immL_pc_off() 4119 %{ 4120 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4121 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4122 match(ConL); 4123 4124 op_cost(0); 4125 format %{ %} 4126 interface(CONST_INTER); 4127 %} 4128 4129 // 64 bit integer valid for add sub immediate 4130 operand immLAddSub() 4131 %{ 4132 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4133 match(ConL); 4134 op_cost(0); 4135 format %{ %} 4136 interface(CONST_INTER); 4137 %} 4138 4139 // 64 bit integer valid for logical immediate 4140 operand immLLog() 4141 %{ 4142 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4143 match(ConL); 4144 op_cost(0); 4145 format %{ %} 4146 interface(CONST_INTER); 4147 %} 4148 4149 // Long Immediate: low 32-bit mask 4150 operand immL_32bits() 4151 %{ 4152 predicate(n->get_long() == 0xFFFFFFFFL); 4153 match(ConL); 4154 op_cost(0); 4155 format %{ %} 4156 interface(CONST_INTER); 4157 %} 4158 4159 // Pointer operands 4160 // Pointer Immediate 4161 operand immP() 4162 %{ 4163 match(ConP); 4164 4165 op_cost(0); 4166 format %{ %} 4167 interface(CONST_INTER); 4168 %} 4169 4170 // NULL Pointer Immediate 4171 operand immP0() 4172 %{ 4173 predicate(n->get_ptr() == 0); 4174 match(ConP); 4175 4176 op_cost(0); 4177 format %{ %} 4178 interface(CONST_INTER); 4179 %} 4180 4181 // Pointer Immediate One 4182 // this is used in object initialization (initial object header) 4183 operand immP_1() 4184 %{ 4185 predicate(n->get_ptr() == 1); 4186 match(ConP); 4187 4188 op_cost(0); 4189 format %{ %} 4190 interface(CONST_INTER); 4191 %} 4192 4193 // Polling Page Pointer Immediate 4194 operand immPollPage() 4195 %{ 4196 predicate((address)n->get_ptr() == os::get_polling_page()); 4197 match(ConP); 4198 4199 op_cost(0); 4200 format %{ %} 4201 interface(CONST_INTER); 4202 %} 4203 4204 // Card Table Byte Map Base 4205 operand immByteMapBase() 4206 %{ 4207 // Get base of card map 4208 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4209 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4210 match(ConP); 4211 4212 op_cost(0); 4213 format %{ %} 4214 interface(CONST_INTER); 4215 %} 4216 4217 // Pointer Immediate Minus One 4218 // this is used when we want to write the current PC to the thread anchor 4219 operand immP_M1() 4220 %{ 4221 predicate(n->get_ptr() == -1); 4222 match(ConP); 4223 4224 op_cost(0); 4225 format %{ %} 4226 interface(CONST_INTER); 4227 %} 4228 4229 // Pointer Immediate Minus Two 4230 // this is used when we want to write the current PC to the thread anchor 4231 operand immP_M2() 4232 %{ 4233 predicate(n->get_ptr() == -2); 4234 match(ConP); 4235 4236 op_cost(0); 4237 format %{ %} 4238 interface(CONST_INTER); 4239 %} 4240 4241 // Float and Double operands 4242 // Double Immediate 4243 operand immD() 4244 %{ 4245 match(ConD); 4246 op_cost(0); 4247 format %{ %} 4248 interface(CONST_INTER); 4249 %} 4250 4251 // Double Immediate: +0.0d 4252 operand immD0() 4253 %{ 4254 predicate(jlong_cast(n->getd()) == 0); 4255 match(ConD); 4256 4257 op_cost(0); 4258 format %{ %} 4259 interface(CONST_INTER); 4260 %} 4261 4262 // constant 'double +0.0'. 4263 operand immDPacked() 4264 %{ 4265 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4266 match(ConD); 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // Float Immediate 4273 operand immF() 4274 %{ 4275 match(ConF); 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // Float Immediate: +0.0f. 4282 operand immF0() 4283 %{ 4284 predicate(jint_cast(n->getf()) == 0); 4285 match(ConF); 4286 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 // 4293 operand immFPacked() 4294 %{ 4295 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4296 match(ConF); 4297 op_cost(0); 4298 format %{ %} 4299 interface(CONST_INTER); 4300 %} 4301 4302 // Narrow pointer operands 4303 // Narrow Pointer Immediate 4304 operand immN() 4305 %{ 4306 match(ConN); 4307 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 // Narrow NULL Pointer Immediate 4314 operand immN0() 4315 %{ 4316 predicate(n->get_narrowcon() == 0); 4317 match(ConN); 4318 4319 op_cost(0); 4320 format %{ %} 4321 interface(CONST_INTER); 4322 %} 4323 4324 operand immNKlass() 4325 %{ 4326 match(ConNKlass); 4327 4328 op_cost(0); 4329 format %{ %} 4330 interface(CONST_INTER); 4331 %} 4332 4333 // Integer 32 bit Register Operands 4334 // Integer 32 bitRegister (excludes SP) 4335 operand iRegI() 4336 %{ 4337 constraint(ALLOC_IN_RC(any_reg32)); 4338 match(RegI); 4339 match(iRegINoSp); 4340 op_cost(0); 4341 format %{ %} 4342 interface(REG_INTER); 4343 %} 4344 4345 // Integer 32 bit Register not Special 4346 operand iRegINoSp() 4347 %{ 4348 constraint(ALLOC_IN_RC(no_special_reg32)); 4349 match(RegI); 4350 op_cost(0); 4351 format %{ %} 4352 interface(REG_INTER); 4353 %} 4354 4355 // Integer 64 bit Register Operands 4356 // Integer 64 bit Register (includes SP) 4357 operand iRegL() 4358 %{ 4359 constraint(ALLOC_IN_RC(any_reg)); 4360 match(RegL); 4361 match(iRegLNoSp); 4362 op_cost(0); 4363 format %{ %} 4364 interface(REG_INTER); 4365 %} 4366 4367 // Integer 64 bit Register not Special 4368 operand iRegLNoSp() 4369 %{ 4370 constraint(ALLOC_IN_RC(no_special_reg)); 4371 match(RegL); 4372 match(iRegL_R0); 4373 format %{ %} 4374 interface(REG_INTER); 4375 %} 4376 4377 // Pointer Register Operands 4378 // Pointer Register 4379 operand iRegP() 4380 %{ 4381 constraint(ALLOC_IN_RC(ptr_reg)); 4382 match(RegP); 4383 match(iRegPNoSp); 4384 match(iRegP_R0); 4385 //match(iRegP_R2); 4386 //match(iRegP_R4); 4387 //match(iRegP_R5); 4388 match(thread_RegP); 4389 op_cost(0); 4390 format %{ %} 4391 interface(REG_INTER); 4392 %} 4393 4394 // Pointer 64 bit Register not Special 4395 operand iRegPNoSp() 4396 %{ 4397 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4398 match(RegP); 4399 // match(iRegP); 4400 // match(iRegP_R0); 4401 // match(iRegP_R2); 4402 // match(iRegP_R4); 4403 // match(iRegP_R5); 4404 // match(thread_RegP); 4405 op_cost(0); 4406 format %{ %} 4407 interface(REG_INTER); 4408 %} 4409 4410 // Pointer 64 bit Register R0 only 4411 operand iRegP_R0() 4412 %{ 4413 constraint(ALLOC_IN_RC(r0_reg)); 4414 match(RegP); 4415 // match(iRegP); 4416 match(iRegPNoSp); 4417 op_cost(0); 4418 format %{ %} 4419 interface(REG_INTER); 4420 %} 4421 4422 // Pointer 64 bit Register R1 only 4423 operand iRegP_R1() 4424 %{ 4425 constraint(ALLOC_IN_RC(r1_reg)); 4426 match(RegP); 4427 // match(iRegP); 4428 match(iRegPNoSp); 4429 op_cost(0); 4430 format %{ %} 4431 interface(REG_INTER); 4432 %} 4433 4434 // Pointer 64 bit Register R2 only 4435 operand iRegP_R2() 4436 %{ 4437 constraint(ALLOC_IN_RC(r2_reg)); 4438 match(RegP); 4439 // match(iRegP); 4440 match(iRegPNoSp); 4441 op_cost(0); 4442 format %{ %} 4443 interface(REG_INTER); 4444 %} 4445 4446 // Pointer 64 bit Register R3 only 4447 operand iRegP_R3() 4448 %{ 4449 constraint(ALLOC_IN_RC(r3_reg)); 4450 match(RegP); 4451 // match(iRegP); 4452 match(iRegPNoSp); 4453 op_cost(0); 4454 format %{ %} 4455 interface(REG_INTER); 4456 %} 4457 4458 // Pointer 64 bit Register R4 only 4459 operand iRegP_R4() 4460 %{ 4461 constraint(ALLOC_IN_RC(r4_reg)); 4462 match(RegP); 4463 // match(iRegP); 4464 match(iRegPNoSp); 4465 op_cost(0); 4466 format %{ %} 4467 interface(REG_INTER); 4468 %} 4469 4470 // Pointer 64 bit Register R5 only 4471 operand iRegP_R5() 4472 %{ 4473 constraint(ALLOC_IN_RC(r5_reg)); 4474 match(RegP); 4475 // match(iRegP); 4476 match(iRegPNoSp); 4477 op_cost(0); 4478 format %{ %} 4479 interface(REG_INTER); 4480 %} 4481 4482 // Pointer 64 bit Register R10 only 4483 operand iRegP_R10() 4484 %{ 4485 constraint(ALLOC_IN_RC(r10_reg)); 4486 match(RegP); 4487 // match(iRegP); 4488 match(iRegPNoSp); 4489 op_cost(0); 4490 format %{ %} 4491 interface(REG_INTER); 4492 %} 4493 4494 // Long 64 bit Register R0 only 4495 operand iRegL_R0() 4496 %{ 4497 constraint(ALLOC_IN_RC(r0_reg)); 4498 match(RegL); 4499 match(iRegLNoSp); 4500 op_cost(0); 4501 format %{ %} 4502 interface(REG_INTER); 4503 %} 4504 4505 // Long 64 bit Register R2 only 4506 operand iRegL_R2() 4507 %{ 4508 constraint(ALLOC_IN_RC(r2_reg)); 4509 match(RegL); 4510 match(iRegLNoSp); 4511 op_cost(0); 4512 format %{ %} 4513 interface(REG_INTER); 4514 %} 4515 4516 // Long 64 bit Register R3 only 4517 operand iRegL_R3() 4518 %{ 4519 constraint(ALLOC_IN_RC(r3_reg)); 4520 match(RegL); 4521 match(iRegLNoSp); 4522 op_cost(0); 4523 format %{ %} 4524 interface(REG_INTER); 4525 %} 4526 4527 // Long 64 bit Register R11 only 4528 operand iRegL_R11() 4529 %{ 4530 constraint(ALLOC_IN_RC(r11_reg)); 4531 match(RegL); 4532 match(iRegLNoSp); 4533 op_cost(0); 4534 format %{ %} 4535 interface(REG_INTER); 4536 %} 4537 4538 // Pointer 64 bit Register FP only 4539 operand iRegP_FP() 4540 %{ 4541 constraint(ALLOC_IN_RC(fp_reg)); 4542 match(RegP); 4543 // match(iRegP); 4544 op_cost(0); 4545 format %{ %} 4546 interface(REG_INTER); 4547 %} 4548 4549 // Register R0 only 4550 operand iRegI_R0() 4551 %{ 4552 constraint(ALLOC_IN_RC(int_r0_reg)); 4553 match(RegI); 4554 match(iRegINoSp); 4555 op_cost(0); 4556 format %{ %} 4557 interface(REG_INTER); 4558 %} 4559 4560 // Register R2 only 4561 operand iRegI_R2() 4562 %{ 4563 constraint(ALLOC_IN_RC(int_r2_reg)); 4564 match(RegI); 4565 match(iRegINoSp); 4566 op_cost(0); 4567 format %{ %} 4568 interface(REG_INTER); 4569 %} 4570 4571 // Register R3 only 4572 operand iRegI_R3() 4573 %{ 4574 constraint(ALLOC_IN_RC(int_r3_reg)); 4575 match(RegI); 4576 match(iRegINoSp); 4577 op_cost(0); 4578 format %{ %} 4579 interface(REG_INTER); 4580 %} 4581 4582 4583 // Register R4 only 4584 operand iRegI_R4() 4585 %{ 4586 constraint(ALLOC_IN_RC(int_r4_reg)); 4587 match(RegI); 4588 match(iRegINoSp); 4589 op_cost(0); 4590 format %{ %} 4591 interface(REG_INTER); 4592 %} 4593 4594 4595 // Pointer Register Operands 4596 // Narrow Pointer Register 4597 operand iRegN() 4598 %{ 4599 constraint(ALLOC_IN_RC(any_reg32)); 4600 match(RegN); 4601 match(iRegNNoSp); 4602 op_cost(0); 4603 format %{ %} 4604 interface(REG_INTER); 4605 %} 4606 4607 operand iRegN_R0() 4608 %{ 4609 constraint(ALLOC_IN_RC(r0_reg)); 4610 match(iRegN); 4611 op_cost(0); 4612 format %{ %} 4613 interface(REG_INTER); 4614 %} 4615 4616 operand iRegN_R2() 4617 %{ 4618 constraint(ALLOC_IN_RC(r2_reg)); 4619 match(iRegN); 4620 op_cost(0); 4621 format %{ %} 4622 interface(REG_INTER); 4623 %} 4624 4625 operand iRegN_R3() 4626 %{ 4627 constraint(ALLOC_IN_RC(r3_reg)); 4628 match(iRegN); 4629 op_cost(0); 4630 format %{ %} 4631 interface(REG_INTER); 4632 %} 4633 4634 // Integer 64 bit Register not Special 4635 operand iRegNNoSp() 4636 %{ 4637 constraint(ALLOC_IN_RC(no_special_reg32)); 4638 match(RegN); 4639 op_cost(0); 4640 format %{ %} 4641 interface(REG_INTER); 4642 %} 4643 4644 // heap base register -- used for encoding immN0 4645 4646 operand iRegIHeapbase() 4647 %{ 4648 constraint(ALLOC_IN_RC(heapbase_reg)); 4649 match(RegI); 4650 op_cost(0); 4651 format %{ %} 4652 interface(REG_INTER); 4653 %} 4654 4655 // Float Register 4656 // Float register operands 4657 operand vRegF() 4658 %{ 4659 constraint(ALLOC_IN_RC(float_reg)); 4660 match(RegF); 4661 4662 op_cost(0); 4663 format %{ %} 4664 interface(REG_INTER); 4665 %} 4666 4667 // Double Register 4668 // Double register operands 4669 operand vRegD() 4670 %{ 4671 constraint(ALLOC_IN_RC(double_reg)); 4672 match(RegD); 4673 4674 op_cost(0); 4675 format %{ %} 4676 interface(REG_INTER); 4677 %} 4678 4679 operand vecD() 4680 %{ 4681 constraint(ALLOC_IN_RC(vectord_reg)); 4682 match(VecD); 4683 4684 op_cost(0); 4685 format %{ %} 4686 interface(REG_INTER); 4687 %} 4688 4689 operand vecX() 4690 %{ 4691 constraint(ALLOC_IN_RC(vectorx_reg)); 4692 match(VecX); 4693 4694 op_cost(0); 4695 format %{ %} 4696 interface(REG_INTER); 4697 %} 4698 4699 operand vRegD_V0() 4700 %{ 4701 constraint(ALLOC_IN_RC(v0_reg)); 4702 match(RegD); 4703 op_cost(0); 4704 format %{ %} 4705 interface(REG_INTER); 4706 %} 4707 4708 operand vRegD_V1() 4709 %{ 4710 constraint(ALLOC_IN_RC(v1_reg)); 4711 match(RegD); 4712 op_cost(0); 4713 format %{ %} 4714 interface(REG_INTER); 4715 %} 4716 4717 operand vRegD_V2() 4718 %{ 4719 constraint(ALLOC_IN_RC(v2_reg)); 4720 match(RegD); 4721 op_cost(0); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 operand vRegD_V3() 4727 %{ 4728 constraint(ALLOC_IN_RC(v3_reg)); 4729 match(RegD); 4730 op_cost(0); 4731 format %{ %} 4732 interface(REG_INTER); 4733 %} 4734 4735 // Flags register, used as output of signed compare instructions 4736 4737 // note that on AArch64 we also use this register as the output for 4738 // for floating point compare instructions (CmpF CmpD). this ensures 4739 // that ordered inequality tests use GT, GE, LT or LE none of which 4740 // pass through cases where the result is unordered i.e. one or both 4741 // inputs to the compare is a NaN. this means that the ideal code can 4742 // replace e.g. a GT with an LE and not end up capturing the NaN case 4743 // (where the comparison should always fail). EQ and NE tests are 4744 // always generated in ideal code so that unordered folds into the NE 4745 // case, matching the behaviour of AArch64 NE. 4746 // 4747 // This differs from x86 where the outputs of FP compares use a 4748 // special FP flags registers and where compares based on this 4749 // register are distinguished into ordered inequalities (cmpOpUCF) and 4750 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4751 // to explicitly handle the unordered case in branches. x86 also has 4752 // to include extra CMoveX rules to accept a cmpOpUCF input. 4753 4754 operand rFlagsReg() 4755 %{ 4756 constraint(ALLOC_IN_RC(int_flags)); 4757 match(RegFlags); 4758 4759 op_cost(0); 4760 format %{ "RFLAGS" %} 4761 interface(REG_INTER); 4762 %} 4763 4764 // Flags register, used as output of unsigned compare instructions 4765 operand rFlagsRegU() 4766 %{ 4767 constraint(ALLOC_IN_RC(int_flags)); 4768 match(RegFlags); 4769 4770 op_cost(0); 4771 format %{ "RFLAGSU" %} 4772 interface(REG_INTER); 4773 %} 4774 4775 // Special Registers 4776 4777 // Method Register 4778 operand inline_cache_RegP(iRegP reg) 4779 %{ 4780 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4781 match(reg); 4782 match(iRegPNoSp); 4783 op_cost(0); 4784 format %{ %} 4785 interface(REG_INTER); 4786 %} 4787 4788 operand interpreter_method_oop_RegP(iRegP reg) 4789 %{ 4790 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4791 match(reg); 4792 match(iRegPNoSp); 4793 op_cost(0); 4794 format %{ %} 4795 interface(REG_INTER); 4796 %} 4797 4798 // Thread Register 4799 operand thread_RegP(iRegP reg) 4800 %{ 4801 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4802 match(reg); 4803 op_cost(0); 4804 format %{ %} 4805 interface(REG_INTER); 4806 %} 4807 4808 operand lr_RegP(iRegP reg) 4809 %{ 4810 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4811 match(reg); 4812 op_cost(0); 4813 format %{ %} 4814 interface(REG_INTER); 4815 %} 4816 4817 //----------Memory Operands---------------------------------------------------- 4818 4819 operand indirect(iRegP reg) 4820 %{ 4821 constraint(ALLOC_IN_RC(ptr_reg)); 4822 match(reg); 4823 op_cost(0); 4824 format %{ "[$reg]" %} 4825 interface(MEMORY_INTER) %{ 4826 base($reg); 4827 index(0xffffffff); 4828 scale(0x0); 4829 disp(0x0); 4830 %} 4831 %} 4832 4833 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4834 %{ 4835 constraint(ALLOC_IN_RC(ptr_reg)); 4836 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4837 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4838 op_cost(0); 4839 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4840 interface(MEMORY_INTER) %{ 4841 base($reg); 4842 index($ireg); 4843 scale($scale); 4844 disp(0x0); 4845 %} 4846 %} 4847 4848 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4849 %{ 4850 constraint(ALLOC_IN_RC(ptr_reg)); 4851 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4852 match(AddP reg (LShiftL lreg scale)); 4853 op_cost(0); 4854 format %{ "$reg, $lreg lsl($scale)" %} 4855 interface(MEMORY_INTER) %{ 4856 base($reg); 4857 index($lreg); 4858 scale($scale); 4859 disp(0x0); 4860 %} 4861 %} 4862 4863 operand indIndexI2L(iRegP reg, iRegI ireg) 4864 %{ 4865 constraint(ALLOC_IN_RC(ptr_reg)); 4866 match(AddP reg (ConvI2L ireg)); 4867 op_cost(0); 4868 format %{ "$reg, $ireg, 0, I2L" %} 4869 interface(MEMORY_INTER) %{ 4870 base($reg); 4871 index($ireg); 4872 scale(0x0); 4873 disp(0x0); 4874 %} 4875 %} 4876 4877 operand indIndex(iRegP reg, iRegL lreg) 4878 %{ 4879 constraint(ALLOC_IN_RC(ptr_reg)); 4880 match(AddP reg lreg); 4881 op_cost(0); 4882 format %{ "$reg, $lreg" %} 4883 interface(MEMORY_INTER) %{ 4884 base($reg); 4885 index($lreg); 4886 scale(0x0); 4887 disp(0x0); 4888 %} 4889 %} 4890 4891 operand indOffI(iRegP reg, immIOffset off) 4892 %{ 4893 constraint(ALLOC_IN_RC(ptr_reg)); 4894 match(AddP reg off); 4895 op_cost(0); 4896 format %{ "[$reg, $off]" %} 4897 interface(MEMORY_INTER) %{ 4898 base($reg); 4899 index(0xffffffff); 4900 scale(0x0); 4901 disp($off); 4902 %} 4903 %} 4904 4905 operand indOffI4(iRegP reg, immIOffset4 off) 4906 %{ 4907 constraint(ALLOC_IN_RC(ptr_reg)); 4908 match(AddP reg off); 4909 op_cost(0); 4910 format %{ "[$reg, $off]" %} 4911 interface(MEMORY_INTER) %{ 4912 base($reg); 4913 index(0xffffffff); 4914 scale(0x0); 4915 disp($off); 4916 %} 4917 %} 4918 4919 operand indOffI8(iRegP reg, immIOffset8 off) 4920 %{ 4921 constraint(ALLOC_IN_RC(ptr_reg)); 4922 match(AddP reg off); 4923 op_cost(0); 4924 format %{ "[$reg, $off]" %} 4925 interface(MEMORY_INTER) %{ 4926 base($reg); 4927 index(0xffffffff); 4928 scale(0x0); 4929 disp($off); 4930 %} 4931 %} 4932 4933 operand indOffI16(iRegP reg, immIOffset16 off) 4934 %{ 4935 constraint(ALLOC_IN_RC(ptr_reg)); 4936 match(AddP reg off); 4937 op_cost(0); 4938 format %{ "[$reg, $off]" %} 4939 interface(MEMORY_INTER) %{ 4940 base($reg); 4941 index(0xffffffff); 4942 scale(0x0); 4943 disp($off); 4944 %} 4945 %} 4946 4947 operand indOffL(iRegP reg, immLoffset off) 4948 %{ 4949 constraint(ALLOC_IN_RC(ptr_reg)); 4950 match(AddP reg off); 4951 op_cost(0); 4952 format %{ "[$reg, $off]" %} 4953 interface(MEMORY_INTER) %{ 4954 base($reg); 4955 index(0xffffffff); 4956 scale(0x0); 4957 disp($off); 4958 %} 4959 %} 4960 4961 operand indOffL4(iRegP reg, immLoffset4 off) 4962 %{ 4963 constraint(ALLOC_IN_RC(ptr_reg)); 4964 match(AddP reg off); 4965 op_cost(0); 4966 format %{ "[$reg, $off]" %} 4967 interface(MEMORY_INTER) %{ 4968 base($reg); 4969 index(0xffffffff); 4970 scale(0x0); 4971 disp($off); 4972 %} 4973 %} 4974 4975 operand indOffL8(iRegP reg, immLoffset8 off) 4976 %{ 4977 constraint(ALLOC_IN_RC(ptr_reg)); 4978 match(AddP reg off); 4979 op_cost(0); 4980 format %{ "[$reg, $off]" %} 4981 interface(MEMORY_INTER) %{ 4982 base($reg); 4983 index(0xffffffff); 4984 scale(0x0); 4985 disp($off); 4986 %} 4987 %} 4988 4989 operand indOffL16(iRegP reg, immLoffset16 off) 4990 %{ 4991 constraint(ALLOC_IN_RC(ptr_reg)); 4992 match(AddP reg off); 4993 op_cost(0); 4994 format %{ "[$reg, $off]" %} 4995 interface(MEMORY_INTER) %{ 4996 base($reg); 4997 index(0xffffffff); 4998 scale(0x0); 4999 disp($off); 5000 %} 5001 %} 5002 5003 operand indirectN(iRegN reg) 5004 %{ 5005 predicate(Universe::narrow_oop_shift() == 0); 5006 constraint(ALLOC_IN_RC(ptr_reg)); 5007 match(DecodeN reg); 5008 op_cost(0); 5009 format %{ "[$reg]\t# narrow" %} 5010 interface(MEMORY_INTER) %{ 5011 base($reg); 5012 index(0xffffffff); 5013 scale(0x0); 5014 disp(0x0); 5015 %} 5016 %} 5017 5018 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5019 %{ 5020 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5021 constraint(ALLOC_IN_RC(ptr_reg)); 5022 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5023 op_cost(0); 5024 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5025 interface(MEMORY_INTER) %{ 5026 base($reg); 5027 index($ireg); 5028 scale($scale); 5029 disp(0x0); 5030 %} 5031 %} 5032 5033 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5034 %{ 5035 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5036 constraint(ALLOC_IN_RC(ptr_reg)); 5037 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5038 op_cost(0); 5039 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5040 interface(MEMORY_INTER) %{ 5041 base($reg); 5042 index($lreg); 5043 scale($scale); 5044 disp(0x0); 5045 %} 5046 %} 5047 5048 operand indIndexI2LN(iRegN reg, iRegI ireg) 5049 %{ 5050 predicate(Universe::narrow_oop_shift() == 0); 5051 constraint(ALLOC_IN_RC(ptr_reg)); 5052 match(AddP (DecodeN reg) (ConvI2L ireg)); 5053 op_cost(0); 5054 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5055 interface(MEMORY_INTER) %{ 5056 base($reg); 5057 index($ireg); 5058 scale(0x0); 5059 disp(0x0); 5060 %} 5061 %} 5062 5063 operand indIndexN(iRegN reg, iRegL lreg) 5064 %{ 5065 predicate(Universe::narrow_oop_shift() == 0); 5066 constraint(ALLOC_IN_RC(ptr_reg)); 5067 match(AddP (DecodeN reg) lreg); 5068 op_cost(0); 5069 format %{ "$reg, $lreg\t# narrow" %} 5070 interface(MEMORY_INTER) %{ 5071 base($reg); 5072 index($lreg); 5073 scale(0x0); 5074 disp(0x0); 5075 %} 5076 %} 5077 5078 operand indOffIN(iRegN reg, immIOffset off) 5079 %{ 5080 predicate(Universe::narrow_oop_shift() == 0); 5081 constraint(ALLOC_IN_RC(ptr_reg)); 5082 match(AddP (DecodeN reg) off); 5083 op_cost(0); 5084 format %{ "[$reg, $off]\t# narrow" %} 5085 interface(MEMORY_INTER) %{ 5086 base($reg); 5087 index(0xffffffff); 5088 scale(0x0); 5089 disp($off); 5090 %} 5091 %} 5092 5093 operand indOffLN(iRegN reg, immLoffset off) 5094 %{ 5095 predicate(Universe::narrow_oop_shift() == 0); 5096 constraint(ALLOC_IN_RC(ptr_reg)); 5097 match(AddP (DecodeN reg) off); 5098 op_cost(0); 5099 format %{ "[$reg, $off]\t# narrow" %} 5100 interface(MEMORY_INTER) %{ 5101 base($reg); 5102 index(0xffffffff); 5103 scale(0x0); 5104 disp($off); 5105 %} 5106 %} 5107 5108 5109 5110 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5111 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5112 %{ 5113 constraint(ALLOC_IN_RC(ptr_reg)); 5114 match(AddP reg off); 5115 op_cost(0); 5116 format %{ "[$reg, $off]" %} 5117 interface(MEMORY_INTER) %{ 5118 base($reg); 5119 index(0xffffffff); 5120 scale(0x0); 5121 disp($off); 5122 %} 5123 %} 5124 5125 //----------Special Memory Operands-------------------------------------------- 5126 // Stack Slot Operand - This operand is used for loading and storing temporary 5127 // values on the stack where a match requires a value to 5128 // flow through memory. 5129 operand stackSlotP(sRegP reg) 5130 %{ 5131 constraint(ALLOC_IN_RC(stack_slots)); 5132 op_cost(100); 5133 // No match rule because this operand is only generated in matching 5134 // match(RegP); 5135 format %{ "[$reg]" %} 5136 interface(MEMORY_INTER) %{ 5137 base(0x1e); // RSP 5138 index(0x0); // No Index 5139 scale(0x0); // No Scale 5140 disp($reg); // Stack Offset 5141 %} 5142 %} 5143 5144 operand stackSlotI(sRegI reg) 5145 %{ 5146 constraint(ALLOC_IN_RC(stack_slots)); 5147 // No match rule because this operand is only generated in matching 5148 // match(RegI); 5149 format %{ "[$reg]" %} 5150 interface(MEMORY_INTER) %{ 5151 base(0x1e); // RSP 5152 index(0x0); // No Index 5153 scale(0x0); // No Scale 5154 disp($reg); // Stack Offset 5155 %} 5156 %} 5157 5158 operand stackSlotF(sRegF reg) 5159 %{ 5160 constraint(ALLOC_IN_RC(stack_slots)); 5161 // No match rule because this operand is only generated in matching 5162 // match(RegF); 5163 format %{ "[$reg]" %} 5164 interface(MEMORY_INTER) %{ 5165 base(0x1e); // RSP 5166 index(0x0); // No Index 5167 scale(0x0); // No Scale 5168 disp($reg); // Stack Offset 5169 %} 5170 %} 5171 5172 operand stackSlotD(sRegD reg) 5173 %{ 5174 constraint(ALLOC_IN_RC(stack_slots)); 5175 // No match rule because this operand is only generated in matching 5176 // match(RegD); 5177 format %{ "[$reg]" %} 5178 interface(MEMORY_INTER) %{ 5179 base(0x1e); // RSP 5180 index(0x0); // No Index 5181 scale(0x0); // No Scale 5182 disp($reg); // Stack Offset 5183 %} 5184 %} 5185 5186 operand stackSlotL(sRegL reg) 5187 %{ 5188 constraint(ALLOC_IN_RC(stack_slots)); 5189 // No match rule because this operand is only generated in matching 5190 // match(RegL); 5191 format %{ "[$reg]" %} 5192 interface(MEMORY_INTER) %{ 5193 base(0x1e); // RSP 5194 index(0x0); // No Index 5195 scale(0x0); // No Scale 5196 disp($reg); // Stack Offset 5197 %} 5198 %} 5199 5200 // Operands for expressing Control Flow 5201 // NOTE: Label is a predefined operand which should not be redefined in 5202 // the AD file. It is generically handled within the ADLC. 5203 5204 //----------Conditional Branch Operands---------------------------------------- 5205 // Comparison Op - This is the operation of the comparison, and is limited to 5206 // the following set of codes: 5207 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5208 // 5209 // Other attributes of the comparison, such as unsignedness, are specified 5210 // by the comparison instruction that sets a condition code flags register. 5211 // That result is represented by a flags operand whose subtype is appropriate 5212 // to the unsignedness (etc.) of the comparison. 5213 // 5214 // Later, the instruction which matches both the Comparison Op (a Bool) and 5215 // the flags (produced by the Cmp) specifies the coding of the comparison op 5216 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5217 5218 // used for signed integral comparisons and fp comparisons 5219 5220 operand cmpOp() 5221 %{ 5222 match(Bool); 5223 5224 format %{ "" %} 5225 interface(COND_INTER) %{ 5226 equal(0x0, "eq"); 5227 not_equal(0x1, "ne"); 5228 less(0xb, "lt"); 5229 greater_equal(0xa, "ge"); 5230 less_equal(0xd, "le"); 5231 greater(0xc, "gt"); 5232 overflow(0x6, "vs"); 5233 no_overflow(0x7, "vc"); 5234 %} 5235 %} 5236 5237 // used for unsigned integral comparisons 5238 5239 operand cmpOpU() 5240 %{ 5241 match(Bool); 5242 5243 format %{ "" %} 5244 interface(COND_INTER) %{ 5245 equal(0x0, "eq"); 5246 not_equal(0x1, "ne"); 5247 less(0x3, "lo"); 5248 greater_equal(0x2, "hs"); 5249 less_equal(0x9, "ls"); 5250 greater(0x8, "hi"); 5251 overflow(0x6, "vs"); 5252 no_overflow(0x7, "vc"); 5253 %} 5254 %} 5255 5256 // used for certain integral comparisons which can be 5257 // converted to cbxx or tbxx instructions 5258 5259 operand cmpOpEqNe() 5260 %{ 5261 match(Bool); 5262 match(CmpOp); 5263 op_cost(0); 5264 predicate(n->as_Bool()->_test._test == BoolTest::ne 5265 || n->as_Bool()->_test._test == BoolTest::eq); 5266 5267 format %{ "" %} 5268 interface(COND_INTER) %{ 5269 equal(0x0, "eq"); 5270 not_equal(0x1, "ne"); 5271 less(0xb, "lt"); 5272 greater_equal(0xa, "ge"); 5273 less_equal(0xd, "le"); 5274 greater(0xc, "gt"); 5275 overflow(0x6, "vs"); 5276 no_overflow(0x7, "vc"); 5277 %} 5278 %} 5279 5280 // used for certain integral comparisons which can be 5281 // converted to cbxx or tbxx instructions 5282 5283 operand cmpOpLtGe() 5284 %{ 5285 match(Bool); 5286 match(CmpOp); 5287 op_cost(0); 5288 5289 predicate(n->as_Bool()->_test._test == BoolTest::lt 5290 || n->as_Bool()->_test._test == BoolTest::ge); 5291 5292 format %{ "" %} 5293 interface(COND_INTER) %{ 5294 equal(0x0, "eq"); 5295 not_equal(0x1, "ne"); 5296 less(0xb, "lt"); 5297 greater_equal(0xa, "ge"); 5298 less_equal(0xd, "le"); 5299 greater(0xc, "gt"); 5300 overflow(0x6, "vs"); 5301 no_overflow(0x7, "vc"); 5302 %} 5303 %} 5304 5305 // used for certain unsigned integral comparisons which can be 5306 // converted to cbxx or tbxx instructions 5307 5308 operand cmpOpUEqNeLtGe() 5309 %{ 5310 match(Bool); 5311 match(CmpOp); 5312 op_cost(0); 5313 5314 predicate(n->as_Bool()->_test._test == BoolTest::eq 5315 || n->as_Bool()->_test._test == BoolTest::ne 5316 || n->as_Bool()->_test._test == BoolTest::lt 5317 || n->as_Bool()->_test._test == BoolTest::ge); 5318 5319 format %{ "" %} 5320 interface(COND_INTER) %{ 5321 equal(0x0, "eq"); 5322 not_equal(0x1, "ne"); 5323 less(0xb, "lt"); 5324 greater_equal(0xa, "ge"); 5325 less_equal(0xd, "le"); 5326 greater(0xc, "gt"); 5327 overflow(0x6, "vs"); 5328 no_overflow(0x7, "vc"); 5329 %} 5330 %} 5331 5332 // Special operand allowing long args to int ops to be truncated for free 5333 5334 operand iRegL2I(iRegL reg) %{ 5335 5336 op_cost(0); 5337 5338 match(ConvL2I reg); 5339 5340 format %{ "l2i($reg)" %} 5341 5342 interface(REG_INTER) 5343 %} 5344 5345 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5346 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5347 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5348 5349 //----------OPERAND CLASSES---------------------------------------------------- 5350 // Operand Classes are groups of operands that are used as to simplify 5351 // instruction definitions by not requiring the AD writer to specify 5352 // separate instructions for every form of operand when the 5353 // instruction accepts multiple operand types with the same basic 5354 // encoding and format. The classic case of this is memory operands. 5355 5356 // memory is used to define read/write location for load/store 5357 // instruction defs. we can turn a memory op into an Address 5358 5359 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5360 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5361 5362 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5363 // operations. it allows the src to be either an iRegI or a (ConvL2I 5364 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5365 // can be elided because the 32-bit instruction will just employ the 5366 // lower 32 bits anyway. 5367 // 5368 // n.b. this does not elide all L2I conversions. if the truncated 5369 // value is consumed by more than one operation then the ConvL2I 5370 // cannot be bundled into the consuming nodes so an l2i gets planted 5371 // (actually a movw $dst $src) and the downstream instructions consume 5372 // the result of the l2i as an iRegI input. That's a shame since the 5373 // movw is actually redundant but its not too costly. 5374 5375 opclass iRegIorL2I(iRegI, iRegL2I); 5376 5377 //----------PIPELINE----------------------------------------------------------- 5378 // Rules which define the behavior of the target architectures pipeline. 5379 5380 // For specific pipelines, eg A53, define the stages of that pipeline 5381 //pipe_desc(ISS, EX1, EX2, WR); 5382 #define ISS S0 5383 #define EX1 S1 5384 #define EX2 S2 5385 #define WR S3 5386 5387 // Integer ALU reg operation 5388 pipeline %{ 5389 5390 attributes %{ 5391 // ARM instructions are of fixed length 5392 fixed_size_instructions; // Fixed size instructions TODO does 5393 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5394 // ARM instructions come in 32-bit word units 5395 instruction_unit_size = 4; // An instruction is 4 bytes long 5396 instruction_fetch_unit_size = 64; // The processor fetches one line 5397 instruction_fetch_units = 1; // of 64 bytes 5398 5399 // List of nop instructions 5400 nops( MachNop ); 5401 %} 5402 5403 // We don't use an actual pipeline model so don't care about resources 5404 // or description. we do use pipeline classes to introduce fixed 5405 // latencies 5406 5407 //----------RESOURCES---------------------------------------------------------- 5408 // Resources are the functional units available to the machine 5409 5410 resources( INS0, INS1, INS01 = INS0 | INS1, 5411 ALU0, ALU1, ALU = ALU0 | ALU1, 5412 MAC, 5413 DIV, 5414 BRANCH, 5415 LDST, 5416 NEON_FP); 5417 5418 //----------PIPELINE DESCRIPTION----------------------------------------------- 5419 // Pipeline Description specifies the stages in the machine's pipeline 5420 5421 // Define the pipeline as a generic 6 stage pipeline 5422 pipe_desc(S0, S1, S2, S3, S4, S5); 5423 5424 //----------PIPELINE CLASSES--------------------------------------------------- 5425 // Pipeline Classes describe the stages in which input and output are 5426 // referenced by the hardware pipeline. 5427 5428 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5429 %{ 5430 single_instruction; 5431 src1 : S1(read); 5432 src2 : S2(read); 5433 dst : S5(write); 5434 INS01 : ISS; 5435 NEON_FP : S5; 5436 %} 5437 5438 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5439 %{ 5440 single_instruction; 5441 src1 : S1(read); 5442 src2 : S2(read); 5443 dst : S5(write); 5444 INS01 : ISS; 5445 NEON_FP : S5; 5446 %} 5447 5448 pipe_class fp_uop_s(vRegF dst, vRegF src) 5449 %{ 5450 single_instruction; 5451 src : S1(read); 5452 dst : S5(write); 5453 INS01 : ISS; 5454 NEON_FP : S5; 5455 %} 5456 5457 pipe_class fp_uop_d(vRegD dst, vRegD src) 5458 %{ 5459 single_instruction; 5460 src : S1(read); 5461 dst : S5(write); 5462 INS01 : ISS; 5463 NEON_FP : S5; 5464 %} 5465 5466 pipe_class fp_d2f(vRegF dst, vRegD src) 5467 %{ 5468 single_instruction; 5469 src : S1(read); 5470 dst : S5(write); 5471 INS01 : ISS; 5472 NEON_FP : S5; 5473 %} 5474 5475 pipe_class fp_f2d(vRegD dst, vRegF src) 5476 %{ 5477 single_instruction; 5478 src : S1(read); 5479 dst : S5(write); 5480 INS01 : ISS; 5481 NEON_FP : S5; 5482 %} 5483 5484 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5485 %{ 5486 single_instruction; 5487 src : S1(read); 5488 dst : S5(write); 5489 INS01 : ISS; 5490 NEON_FP : S5; 5491 %} 5492 5493 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5494 %{ 5495 single_instruction; 5496 src : S1(read); 5497 dst : S5(write); 5498 INS01 : ISS; 5499 NEON_FP : S5; 5500 %} 5501 5502 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5503 %{ 5504 single_instruction; 5505 src : S1(read); 5506 dst : S5(write); 5507 INS01 : ISS; 5508 NEON_FP : S5; 5509 %} 5510 5511 pipe_class fp_l2f(vRegF dst, iRegL src) 5512 %{ 5513 single_instruction; 5514 src : S1(read); 5515 dst : S5(write); 5516 INS01 : ISS; 5517 NEON_FP : S5; 5518 %} 5519 5520 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5521 %{ 5522 single_instruction; 5523 src : S1(read); 5524 dst : S5(write); 5525 INS01 : ISS; 5526 NEON_FP : S5; 5527 %} 5528 5529 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5530 %{ 5531 single_instruction; 5532 src : S1(read); 5533 dst : S5(write); 5534 INS01 : ISS; 5535 NEON_FP : S5; 5536 %} 5537 5538 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5539 %{ 5540 single_instruction; 5541 src : S1(read); 5542 dst : S5(write); 5543 INS01 : ISS; 5544 NEON_FP : S5; 5545 %} 5546 5547 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5548 %{ 5549 single_instruction; 5550 src : S1(read); 5551 dst : S5(write); 5552 INS01 : ISS; 5553 NEON_FP : S5; 5554 %} 5555 5556 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5557 %{ 5558 single_instruction; 5559 src1 : S1(read); 5560 src2 : S2(read); 5561 dst : S5(write); 5562 INS0 : ISS; 5563 NEON_FP : S5; 5564 %} 5565 5566 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5567 %{ 5568 single_instruction; 5569 src1 : S1(read); 5570 src2 : S2(read); 5571 dst : S5(write); 5572 INS0 : ISS; 5573 NEON_FP : S5; 5574 %} 5575 5576 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5577 %{ 5578 single_instruction; 5579 cr : S1(read); 5580 src1 : S1(read); 5581 src2 : S1(read); 5582 dst : S3(write); 5583 INS01 : ISS; 5584 NEON_FP : S3; 5585 %} 5586 5587 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5588 %{ 5589 single_instruction; 5590 cr : S1(read); 5591 src1 : S1(read); 5592 src2 : S1(read); 5593 dst : S3(write); 5594 INS01 : ISS; 5595 NEON_FP : S3; 5596 %} 5597 5598 pipe_class fp_imm_s(vRegF dst) 5599 %{ 5600 single_instruction; 5601 dst : S3(write); 5602 INS01 : ISS; 5603 NEON_FP : S3; 5604 %} 5605 5606 pipe_class fp_imm_d(vRegD dst) 5607 %{ 5608 single_instruction; 5609 dst : S3(write); 5610 INS01 : ISS; 5611 NEON_FP : S3; 5612 %} 5613 5614 pipe_class fp_load_constant_s(vRegF dst) 5615 %{ 5616 single_instruction; 5617 dst : S4(write); 5618 INS01 : ISS; 5619 NEON_FP : S4; 5620 %} 5621 5622 pipe_class fp_load_constant_d(vRegD dst) 5623 %{ 5624 single_instruction; 5625 dst : S4(write); 5626 INS01 : ISS; 5627 NEON_FP : S4; 5628 %} 5629 5630 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5631 %{ 5632 single_instruction; 5633 dst : S5(write); 5634 src1 : S1(read); 5635 src2 : S1(read); 5636 INS01 : ISS; 5637 NEON_FP : S5; 5638 %} 5639 5640 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5641 %{ 5642 single_instruction; 5643 dst : S5(write); 5644 src1 : S1(read); 5645 src2 : S1(read); 5646 INS0 : ISS; 5647 NEON_FP : S5; 5648 %} 5649 5650 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5651 %{ 5652 single_instruction; 5653 dst : S5(write); 5654 src1 : S1(read); 5655 src2 : S1(read); 5656 dst : S1(read); 5657 INS01 : ISS; 5658 NEON_FP : S5; 5659 %} 5660 5661 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5662 %{ 5663 single_instruction; 5664 dst : S5(write); 5665 src1 : S1(read); 5666 src2 : S1(read); 5667 dst : S1(read); 5668 INS0 : ISS; 5669 NEON_FP : S5; 5670 %} 5671 5672 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5673 %{ 5674 single_instruction; 5675 dst : S4(write); 5676 src1 : S2(read); 5677 src2 : S2(read); 5678 INS01 : ISS; 5679 NEON_FP : S4; 5680 %} 5681 5682 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5683 %{ 5684 single_instruction; 5685 dst : S4(write); 5686 src1 : S2(read); 5687 src2 : S2(read); 5688 INS0 : ISS; 5689 NEON_FP : S4; 5690 %} 5691 5692 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5693 %{ 5694 single_instruction; 5695 dst : S3(write); 5696 src1 : S2(read); 5697 src2 : S2(read); 5698 INS01 : ISS; 5699 NEON_FP : S3; 5700 %} 5701 5702 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5703 %{ 5704 single_instruction; 5705 dst : S3(write); 5706 src1 : S2(read); 5707 src2 : S2(read); 5708 INS0 : ISS; 5709 NEON_FP : S3; 5710 %} 5711 5712 pipe_class vshift64(vecD dst, vecD src, vecX shift) 5713 %{ 5714 single_instruction; 5715 dst : S3(write); 5716 src : S1(read); 5717 shift : S1(read); 5718 INS01 : ISS; 5719 NEON_FP : S3; 5720 %} 5721 5722 pipe_class vshift128(vecX dst, vecX src, vecX shift) 5723 %{ 5724 single_instruction; 5725 dst : S3(write); 5726 src : S1(read); 5727 shift : S1(read); 5728 INS0 : ISS; 5729 NEON_FP : S3; 5730 %} 5731 5732 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5733 %{ 5734 single_instruction; 5735 dst : S3(write); 5736 src : S1(read); 5737 INS01 : ISS; 5738 NEON_FP : S3; 5739 %} 5740 5741 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5742 %{ 5743 single_instruction; 5744 dst : S3(write); 5745 src : S1(read); 5746 INS0 : ISS; 5747 NEON_FP : S3; 5748 %} 5749 5750 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5751 %{ 5752 single_instruction; 5753 dst : S5(write); 5754 src1 : S1(read); 5755 src2 : S1(read); 5756 INS01 : ISS; 5757 NEON_FP : S5; 5758 %} 5759 5760 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5761 %{ 5762 single_instruction; 5763 dst : S5(write); 5764 src1 : S1(read); 5765 src2 : S1(read); 5766 INS0 : ISS; 5767 NEON_FP : S5; 5768 %} 5769 5770 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5771 %{ 5772 single_instruction; 5773 dst : S5(write); 5774 src1 : S1(read); 5775 src2 : S1(read); 5776 INS0 : ISS; 5777 NEON_FP : S5; 5778 %} 5779 5780 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5781 %{ 5782 single_instruction; 5783 dst : S5(write); 5784 src1 : S1(read); 5785 src2 : S1(read); 5786 INS0 : ISS; 5787 NEON_FP : S5; 5788 %} 5789 5790 pipe_class vsqrt_fp128(vecX dst, vecX src) 5791 %{ 5792 single_instruction; 5793 dst : S5(write); 5794 src : S1(read); 5795 INS0 : ISS; 5796 NEON_FP : S5; 5797 %} 5798 5799 pipe_class vunop_fp64(vecD dst, vecD src) 5800 %{ 5801 single_instruction; 5802 dst : S5(write); 5803 src : S1(read); 5804 INS01 : ISS; 5805 NEON_FP : S5; 5806 %} 5807 5808 pipe_class vunop_fp128(vecX dst, vecX src) 5809 %{ 5810 single_instruction; 5811 dst : S5(write); 5812 src : S1(read); 5813 INS0 : ISS; 5814 NEON_FP : S5; 5815 %} 5816 5817 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5818 %{ 5819 single_instruction; 5820 dst : S3(write); 5821 src : S1(read); 5822 INS01 : ISS; 5823 NEON_FP : S3; 5824 %} 5825 5826 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5827 %{ 5828 single_instruction; 5829 dst : S3(write); 5830 src : S1(read); 5831 INS01 : ISS; 5832 NEON_FP : S3; 5833 %} 5834 5835 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5836 %{ 5837 single_instruction; 5838 dst : S3(write); 5839 src : S1(read); 5840 INS01 : ISS; 5841 NEON_FP : S3; 5842 %} 5843 5844 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5845 %{ 5846 single_instruction; 5847 dst : S3(write); 5848 src : S1(read); 5849 INS01 : ISS; 5850 NEON_FP : S3; 5851 %} 5852 5853 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5854 %{ 5855 single_instruction; 5856 dst : S3(write); 5857 src : S1(read); 5858 INS01 : ISS; 5859 NEON_FP : S3; 5860 %} 5861 5862 pipe_class vmovi_reg_imm64(vecD dst) 5863 %{ 5864 single_instruction; 5865 dst : S3(write); 5866 INS01 : ISS; 5867 NEON_FP : S3; 5868 %} 5869 5870 pipe_class vmovi_reg_imm128(vecX dst) 5871 %{ 5872 single_instruction; 5873 dst : S3(write); 5874 INS0 : ISS; 5875 NEON_FP : S3; 5876 %} 5877 5878 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 5879 %{ 5880 single_instruction; 5881 dst : S5(write); 5882 mem : ISS(read); 5883 INS01 : ISS; 5884 NEON_FP : S3; 5885 %} 5886 5887 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 5888 %{ 5889 single_instruction; 5890 dst : S5(write); 5891 mem : ISS(read); 5892 INS01 : ISS; 5893 NEON_FP : S3; 5894 %} 5895 5896 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 5897 %{ 5898 single_instruction; 5899 mem : ISS(read); 5900 src : S2(read); 5901 INS01 : ISS; 5902 NEON_FP : S3; 5903 %} 5904 5905 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 5906 %{ 5907 single_instruction; 5908 mem : ISS(read); 5909 src : S2(read); 5910 INS01 : ISS; 5911 NEON_FP : S3; 5912 %} 5913 5914 //------- Integer ALU operations -------------------------- 5915 5916 // Integer ALU reg-reg operation 5917 // Operands needed in EX1, result generated in EX2 5918 // Eg. ADD x0, x1, x2 5919 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5920 %{ 5921 single_instruction; 5922 dst : EX2(write); 5923 src1 : EX1(read); 5924 src2 : EX1(read); 5925 INS01 : ISS; // Dual issue as instruction 0 or 1 5926 ALU : EX2; 5927 %} 5928 5929 // Integer ALU reg-reg operation with constant shift 5930 // Shifted register must be available in LATE_ISS instead of EX1 5931 // Eg. ADD x0, x1, x2, LSL #2 5932 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5933 %{ 5934 single_instruction; 5935 dst : EX2(write); 5936 src1 : EX1(read); 5937 src2 : ISS(read); 5938 INS01 : ISS; 5939 ALU : EX2; 5940 %} 5941 5942 // Integer ALU reg operation with constant shift 5943 // Eg. LSL x0, x1, #shift 5944 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5945 %{ 5946 single_instruction; 5947 dst : EX2(write); 5948 src1 : ISS(read); 5949 INS01 : ISS; 5950 ALU : EX2; 5951 %} 5952 5953 // Integer ALU reg-reg operation with variable shift 5954 // Both operands must be available in LATE_ISS instead of EX1 5955 // Result is available in EX1 instead of EX2 5956 // Eg. LSLV x0, x1, x2 5957 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5958 %{ 5959 single_instruction; 5960 dst : EX1(write); 5961 src1 : ISS(read); 5962 src2 : ISS(read); 5963 INS01 : ISS; 5964 ALU : EX1; 5965 %} 5966 5967 // Integer ALU reg-reg operation with extract 5968 // As for _vshift above, but result generated in EX2 5969 // Eg. EXTR x0, x1, x2, #N 5970 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 5971 %{ 5972 single_instruction; 5973 dst : EX2(write); 5974 src1 : ISS(read); 5975 src2 : ISS(read); 5976 INS1 : ISS; // Can only dual issue as Instruction 1 5977 ALU : EX1; 5978 %} 5979 5980 // Integer ALU reg operation 5981 // Eg. NEG x0, x1 5982 pipe_class ialu_reg(iRegI dst, iRegI src) 5983 %{ 5984 single_instruction; 5985 dst : EX2(write); 5986 src : EX1(read); 5987 INS01 : ISS; 5988 ALU : EX2; 5989 %} 5990 5991 // Integer ALU reg mmediate operation 5992 // Eg. ADD x0, x1, #N 5993 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 5994 %{ 5995 single_instruction; 5996 dst : EX2(write); 5997 src1 : EX1(read); 5998 INS01 : ISS; 5999 ALU : EX2; 6000 %} 6001 6002 // Integer ALU immediate operation (no source operands) 6003 // Eg. MOV x0, #N 6004 pipe_class ialu_imm(iRegI dst) 6005 %{ 6006 single_instruction; 6007 dst : EX1(write); 6008 INS01 : ISS; 6009 ALU : EX1; 6010 %} 6011 6012 //------- Compare operation ------------------------------- 6013 6014 // Compare reg-reg 6015 // Eg. CMP x0, x1 6016 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6017 %{ 6018 single_instruction; 6019 // fixed_latency(16); 6020 cr : EX2(write); 6021 op1 : EX1(read); 6022 op2 : EX1(read); 6023 INS01 : ISS; 6024 ALU : EX2; 6025 %} 6026 6027 // Compare reg-reg 6028 // Eg. CMP x0, #N 6029 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6030 %{ 6031 single_instruction; 6032 // fixed_latency(16); 6033 cr : EX2(write); 6034 op1 : EX1(read); 6035 INS01 : ISS; 6036 ALU : EX2; 6037 %} 6038 6039 //------- Conditional instructions ------------------------ 6040 6041 // Conditional no operands 6042 // Eg. CSINC x0, zr, zr, <cond> 6043 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6044 %{ 6045 single_instruction; 6046 cr : EX1(read); 6047 dst : EX2(write); 6048 INS01 : ISS; 6049 ALU : EX2; 6050 %} 6051 6052 // Conditional 2 operand 6053 // EG. CSEL X0, X1, X2, <cond> 6054 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6055 %{ 6056 single_instruction; 6057 cr : EX1(read); 6058 src1 : EX1(read); 6059 src2 : EX1(read); 6060 dst : EX2(write); 6061 INS01 : ISS; 6062 ALU : EX2; 6063 %} 6064 6065 // Conditional 2 operand 6066 // EG. CSEL X0, X1, X2, <cond> 6067 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6068 %{ 6069 single_instruction; 6070 cr : EX1(read); 6071 src : EX1(read); 6072 dst : EX2(write); 6073 INS01 : ISS; 6074 ALU : EX2; 6075 %} 6076 6077 //------- Multiply pipeline operations -------------------- 6078 6079 // Multiply reg-reg 6080 // Eg. MUL w0, w1, w2 6081 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6082 %{ 6083 single_instruction; 6084 dst : WR(write); 6085 src1 : ISS(read); 6086 src2 : ISS(read); 6087 INS01 : ISS; 6088 MAC : WR; 6089 %} 6090 6091 // Multiply accumulate 6092 // Eg. MADD w0, w1, w2, w3 6093 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6094 %{ 6095 single_instruction; 6096 dst : WR(write); 6097 src1 : ISS(read); 6098 src2 : ISS(read); 6099 src3 : ISS(read); 6100 INS01 : ISS; 6101 MAC : WR; 6102 %} 6103 6104 // Eg. MUL w0, w1, w2 6105 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6106 %{ 6107 single_instruction; 6108 fixed_latency(3); // Maximum latency for 64 bit mul 6109 dst : WR(write); 6110 src1 : ISS(read); 6111 src2 : ISS(read); 6112 INS01 : ISS; 6113 MAC : WR; 6114 %} 6115 6116 // Multiply accumulate 6117 // Eg. MADD w0, w1, w2, w3 6118 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6119 %{ 6120 single_instruction; 6121 fixed_latency(3); // Maximum latency for 64 bit mul 6122 dst : WR(write); 6123 src1 : ISS(read); 6124 src2 : ISS(read); 6125 src3 : ISS(read); 6126 INS01 : ISS; 6127 MAC : WR; 6128 %} 6129 6130 //------- Divide pipeline operations -------------------- 6131 6132 // Eg. SDIV w0, w1, w2 6133 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6134 %{ 6135 single_instruction; 6136 fixed_latency(8); // Maximum latency for 32 bit divide 6137 dst : WR(write); 6138 src1 : ISS(read); 6139 src2 : ISS(read); 6140 INS0 : ISS; // Can only dual issue as instruction 0 6141 DIV : WR; 6142 %} 6143 6144 // Eg. SDIV x0, x1, x2 6145 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6146 %{ 6147 single_instruction; 6148 fixed_latency(16); // Maximum latency for 64 bit divide 6149 dst : WR(write); 6150 src1 : ISS(read); 6151 src2 : ISS(read); 6152 INS0 : ISS; // Can only dual issue as instruction 0 6153 DIV : WR; 6154 %} 6155 6156 //------- Load pipeline operations ------------------------ 6157 6158 // Load - prefetch 6159 // Eg. PFRM <mem> 6160 pipe_class iload_prefetch(memory mem) 6161 %{ 6162 single_instruction; 6163 mem : ISS(read); 6164 INS01 : ISS; 6165 LDST : WR; 6166 %} 6167 6168 // Load - reg, mem 6169 // Eg. LDR x0, <mem> 6170 pipe_class iload_reg_mem(iRegI dst, memory mem) 6171 %{ 6172 single_instruction; 6173 dst : WR(write); 6174 mem : ISS(read); 6175 INS01 : ISS; 6176 LDST : WR; 6177 %} 6178 6179 // Load - reg, reg 6180 // Eg. LDR x0, [sp, x1] 6181 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6182 %{ 6183 single_instruction; 6184 dst : WR(write); 6185 src : ISS(read); 6186 INS01 : ISS; 6187 LDST : WR; 6188 %} 6189 6190 //------- Store pipeline operations ----------------------- 6191 6192 // Store - zr, mem 6193 // Eg. STR zr, <mem> 6194 pipe_class istore_mem(memory mem) 6195 %{ 6196 single_instruction; 6197 mem : ISS(read); 6198 INS01 : ISS; 6199 LDST : WR; 6200 %} 6201 6202 // Store - reg, mem 6203 // Eg. STR x0, <mem> 6204 pipe_class istore_reg_mem(iRegI src, memory mem) 6205 %{ 6206 single_instruction; 6207 mem : ISS(read); 6208 src : EX2(read); 6209 INS01 : ISS; 6210 LDST : WR; 6211 %} 6212 6213 // Store - reg, reg 6214 // Eg. STR x0, [sp, x1] 6215 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6216 %{ 6217 single_instruction; 6218 dst : ISS(read); 6219 src : EX2(read); 6220 INS01 : ISS; 6221 LDST : WR; 6222 %} 6223 6224 //------- Store pipeline operations ----------------------- 6225 6226 // Branch 6227 pipe_class pipe_branch() 6228 %{ 6229 single_instruction; 6230 INS01 : ISS; 6231 BRANCH : EX1; 6232 %} 6233 6234 // Conditional branch 6235 pipe_class pipe_branch_cond(rFlagsReg cr) 6236 %{ 6237 single_instruction; 6238 cr : EX1(read); 6239 INS01 : ISS; 6240 BRANCH : EX1; 6241 %} 6242 6243 // Compare & Branch 6244 // EG. CBZ/CBNZ 6245 pipe_class pipe_cmp_branch(iRegI op1) 6246 %{ 6247 single_instruction; 6248 op1 : EX1(read); 6249 INS01 : ISS; 6250 BRANCH : EX1; 6251 %} 6252 6253 //------- Synchronisation operations ---------------------- 6254 6255 // Any operation requiring serialization. 6256 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6257 pipe_class pipe_serial() 6258 %{ 6259 single_instruction; 6260 force_serialization; 6261 fixed_latency(16); 6262 INS01 : ISS(2); // Cannot dual issue with any other instruction 6263 LDST : WR; 6264 %} 6265 6266 // Generic big/slow expanded idiom - also serialized 6267 pipe_class pipe_slow() 6268 %{ 6269 instruction_count(10); 6270 multiple_bundles; 6271 force_serialization; 6272 fixed_latency(16); 6273 INS01 : ISS(2); // Cannot dual issue with any other instruction 6274 LDST : WR; 6275 %} 6276 6277 // Empty pipeline class 6278 pipe_class pipe_class_empty() 6279 %{ 6280 single_instruction; 6281 fixed_latency(0); 6282 %} 6283 6284 // Default pipeline class. 6285 pipe_class pipe_class_default() 6286 %{ 6287 single_instruction; 6288 fixed_latency(2); 6289 %} 6290 6291 // Pipeline class for compares. 6292 pipe_class pipe_class_compare() 6293 %{ 6294 single_instruction; 6295 fixed_latency(16); 6296 %} 6297 6298 // Pipeline class for memory operations. 6299 pipe_class pipe_class_memory() 6300 %{ 6301 single_instruction; 6302 fixed_latency(16); 6303 %} 6304 6305 // Pipeline class for call. 6306 pipe_class pipe_class_call() 6307 %{ 6308 single_instruction; 6309 fixed_latency(100); 6310 %} 6311 6312 // Define the class for the Nop node. 6313 define %{ 6314 MachNop = pipe_class_empty; 6315 %} 6316 6317 %} 6318 //----------INSTRUCTIONS------------------------------------------------------- 6319 // 6320 // match -- States which machine-independent subtree may be replaced 6321 // by this instruction. 6322 // ins_cost -- The estimated cost of this instruction is used by instruction 6323 // selection to identify a minimum cost tree of machine 6324 // instructions that matches a tree of machine-independent 6325 // instructions. 6326 // format -- A string providing the disassembly for this instruction. 6327 // The value of an instruction's operand may be inserted 6328 // by referring to it with a '$' prefix. 6329 // opcode -- Three instruction opcodes may be provided. These are referred 6330 // to within an encode class as $primary, $secondary, and $tertiary 6331 // rrspectively. The primary opcode is commonly used to 6332 // indicate the type of machine instruction, while secondary 6333 // and tertiary are often used for prefix options or addressing 6334 // modes. 6335 // ins_encode -- A list of encode classes with parameters. The encode class 6336 // name must have been defined in an 'enc_class' specification 6337 // in the encode section of the architecture description. 6338 6339 // ============================================================================ 6340 // Memory (Load/Store) Instructions 6341 6342 // Load Instructions 6343 6344 // Load Byte (8 bit signed) 6345 instruct loadB(iRegINoSp dst, memory mem) 6346 %{ 6347 match(Set dst (LoadB mem)); 6348 predicate(!needs_acquiring_load(n)); 6349 6350 ins_cost(4 * INSN_COST); 6351 format %{ "ldrsbw $dst, $mem\t# byte" %} 6352 6353 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6354 6355 ins_pipe(iload_reg_mem); 6356 %} 6357 6358 // Load Byte (8 bit signed) into long 6359 instruct loadB2L(iRegLNoSp dst, memory mem) 6360 %{ 6361 match(Set dst (ConvI2L (LoadB mem))); 6362 predicate(!needs_acquiring_load(n->in(1))); 6363 6364 ins_cost(4 * INSN_COST); 6365 format %{ "ldrsb $dst, $mem\t# byte" %} 6366 6367 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6368 6369 ins_pipe(iload_reg_mem); 6370 %} 6371 6372 // Load Byte (8 bit unsigned) 6373 instruct loadUB(iRegINoSp dst, memory mem) 6374 %{ 6375 match(Set dst (LoadUB mem)); 6376 predicate(!needs_acquiring_load(n)); 6377 6378 ins_cost(4 * INSN_COST); 6379 format %{ "ldrbw $dst, $mem\t# byte" %} 6380 6381 ins_encode(aarch64_enc_ldrb(dst, mem)); 6382 6383 ins_pipe(iload_reg_mem); 6384 %} 6385 6386 // Load Byte (8 bit unsigned) into long 6387 instruct loadUB2L(iRegLNoSp dst, memory mem) 6388 %{ 6389 match(Set dst (ConvI2L (LoadUB mem))); 6390 predicate(!needs_acquiring_load(n->in(1))); 6391 6392 ins_cost(4 * INSN_COST); 6393 format %{ "ldrb $dst, $mem\t# byte" %} 6394 6395 ins_encode(aarch64_enc_ldrb(dst, mem)); 6396 6397 ins_pipe(iload_reg_mem); 6398 %} 6399 6400 // Load Short (16 bit signed) 6401 instruct loadS(iRegINoSp dst, memory mem) 6402 %{ 6403 match(Set dst (LoadS mem)); 6404 predicate(!needs_acquiring_load(n)); 6405 6406 ins_cost(4 * INSN_COST); 6407 format %{ "ldrshw $dst, $mem\t# short" %} 6408 6409 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6410 6411 ins_pipe(iload_reg_mem); 6412 %} 6413 6414 // Load Short (16 bit signed) into long 6415 instruct loadS2L(iRegLNoSp dst, memory mem) 6416 %{ 6417 match(Set dst (ConvI2L (LoadS mem))); 6418 predicate(!needs_acquiring_load(n->in(1))); 6419 6420 ins_cost(4 * INSN_COST); 6421 format %{ "ldrsh $dst, $mem\t# short" %} 6422 6423 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6424 6425 ins_pipe(iload_reg_mem); 6426 %} 6427 6428 // Load Char (16 bit unsigned) 6429 instruct loadUS(iRegINoSp dst, memory mem) 6430 %{ 6431 match(Set dst (LoadUS mem)); 6432 predicate(!needs_acquiring_load(n)); 6433 6434 ins_cost(4 * INSN_COST); 6435 format %{ "ldrh $dst, $mem\t# short" %} 6436 6437 ins_encode(aarch64_enc_ldrh(dst, mem)); 6438 6439 ins_pipe(iload_reg_mem); 6440 %} 6441 6442 // Load Short/Char (16 bit unsigned) into long 6443 instruct loadUS2L(iRegLNoSp dst, memory mem) 6444 %{ 6445 match(Set dst (ConvI2L (LoadUS mem))); 6446 predicate(!needs_acquiring_load(n->in(1))); 6447 6448 ins_cost(4 * INSN_COST); 6449 format %{ "ldrh $dst, $mem\t# short" %} 6450 6451 ins_encode(aarch64_enc_ldrh(dst, mem)); 6452 6453 ins_pipe(iload_reg_mem); 6454 %} 6455 6456 // Load Integer (32 bit signed) 6457 instruct loadI(iRegINoSp dst, memory mem) 6458 %{ 6459 match(Set dst (LoadI mem)); 6460 predicate(!needs_acquiring_load(n)); 6461 6462 ins_cost(4 * INSN_COST); 6463 format %{ "ldrw $dst, $mem\t# int" %} 6464 6465 ins_encode(aarch64_enc_ldrw(dst, mem)); 6466 6467 ins_pipe(iload_reg_mem); 6468 %} 6469 6470 // Load Integer (32 bit signed) into long 6471 instruct loadI2L(iRegLNoSp dst, memory mem) 6472 %{ 6473 match(Set dst (ConvI2L (LoadI mem))); 6474 predicate(!needs_acquiring_load(n->in(1))); 6475 6476 ins_cost(4 * INSN_COST); 6477 format %{ "ldrsw $dst, $mem\t# int" %} 6478 6479 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6480 6481 ins_pipe(iload_reg_mem); 6482 %} 6483 6484 // Load Integer (32 bit unsigned) into long 6485 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6486 %{ 6487 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6488 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6489 6490 ins_cost(4 * INSN_COST); 6491 format %{ "ldrw $dst, $mem\t# int" %} 6492 6493 ins_encode(aarch64_enc_ldrw(dst, mem)); 6494 6495 ins_pipe(iload_reg_mem); 6496 %} 6497 6498 // Load Long (64 bit signed) 6499 instruct loadL(iRegLNoSp dst, memory mem) 6500 %{ 6501 match(Set dst (LoadL mem)); 6502 predicate(!needs_acquiring_load(n)); 6503 6504 ins_cost(4 * INSN_COST); 6505 format %{ "ldr $dst, $mem\t# int" %} 6506 6507 ins_encode(aarch64_enc_ldr(dst, mem)); 6508 6509 ins_pipe(iload_reg_mem); 6510 %} 6511 6512 // Load Range 6513 instruct loadRange(iRegINoSp dst, memory mem) 6514 %{ 6515 match(Set dst (LoadRange mem)); 6516 6517 ins_cost(4 * INSN_COST); 6518 format %{ "ldrw $dst, $mem\t# range" %} 6519 6520 ins_encode(aarch64_enc_ldrw(dst, mem)); 6521 6522 ins_pipe(iload_reg_mem); 6523 %} 6524 6525 // Load Pointer 6526 instruct loadP(iRegPNoSp dst, memory mem) 6527 %{ 6528 match(Set dst (LoadP mem)); 6529 predicate(!needs_acquiring_load(n)); 6530 6531 ins_cost(4 * INSN_COST); 6532 format %{ "ldr $dst, $mem\t# ptr" %} 6533 6534 ins_encode(aarch64_enc_ldr(dst, mem)); 6535 6536 ins_pipe(iload_reg_mem); 6537 %} 6538 6539 // Load Compressed Pointer 6540 instruct loadN(iRegNNoSp dst, memory mem) 6541 %{ 6542 match(Set dst (LoadN mem)); 6543 predicate(!needs_acquiring_load(n)); 6544 6545 ins_cost(4 * INSN_COST); 6546 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6547 6548 ins_encode(aarch64_enc_ldrw(dst, mem)); 6549 6550 ins_pipe(iload_reg_mem); 6551 %} 6552 6553 // Load Klass Pointer 6554 instruct loadKlass(iRegPNoSp dst, memory mem) 6555 %{ 6556 match(Set dst (LoadKlass mem)); 6557 predicate(!needs_acquiring_load(n)); 6558 6559 ins_cost(4 * INSN_COST); 6560 format %{ "ldr $dst, $mem\t# class" %} 6561 6562 ins_encode(aarch64_enc_ldr(dst, mem)); 6563 6564 ins_pipe(iload_reg_mem); 6565 %} 6566 6567 // Load Narrow Klass Pointer 6568 instruct loadNKlass(iRegNNoSp dst, memory mem) 6569 %{ 6570 match(Set dst (LoadNKlass mem)); 6571 predicate(!needs_acquiring_load(n)); 6572 6573 ins_cost(4 * INSN_COST); 6574 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6575 6576 ins_encode(aarch64_enc_ldrw(dst, mem)); 6577 6578 ins_pipe(iload_reg_mem); 6579 %} 6580 6581 // Load Float 6582 instruct loadF(vRegF dst, memory mem) 6583 %{ 6584 match(Set dst (LoadF mem)); 6585 predicate(!needs_acquiring_load(n)); 6586 6587 ins_cost(4 * INSN_COST); 6588 format %{ "ldrs $dst, $mem\t# float" %} 6589 6590 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6591 6592 ins_pipe(pipe_class_memory); 6593 %} 6594 6595 // Load Double 6596 instruct loadD(vRegD dst, memory mem) 6597 %{ 6598 match(Set dst (LoadD mem)); 6599 predicate(!needs_acquiring_load(n)); 6600 6601 ins_cost(4 * INSN_COST); 6602 format %{ "ldrd $dst, $mem\t# double" %} 6603 6604 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6605 6606 ins_pipe(pipe_class_memory); 6607 %} 6608 6609 6610 // Load Int Constant 6611 instruct loadConI(iRegINoSp dst, immI src) 6612 %{ 6613 match(Set dst src); 6614 6615 ins_cost(INSN_COST); 6616 format %{ "mov $dst, $src\t# int" %} 6617 6618 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6619 6620 ins_pipe(ialu_imm); 6621 %} 6622 6623 // Load Long Constant 6624 instruct loadConL(iRegLNoSp dst, immL src) 6625 %{ 6626 match(Set dst src); 6627 6628 ins_cost(INSN_COST); 6629 format %{ "mov $dst, $src\t# long" %} 6630 6631 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6632 6633 ins_pipe(ialu_imm); 6634 %} 6635 6636 // Load Pointer Constant 6637 6638 instruct loadConP(iRegPNoSp dst, immP con) 6639 %{ 6640 match(Set dst con); 6641 6642 ins_cost(INSN_COST * 4); 6643 format %{ 6644 "mov $dst, $con\t# ptr\n\t" 6645 %} 6646 6647 ins_encode(aarch64_enc_mov_p(dst, con)); 6648 6649 ins_pipe(ialu_imm); 6650 %} 6651 6652 // Load Null Pointer Constant 6653 6654 instruct loadConP0(iRegPNoSp dst, immP0 con) 6655 %{ 6656 match(Set dst con); 6657 6658 ins_cost(INSN_COST); 6659 format %{ "mov $dst, $con\t# NULL ptr" %} 6660 6661 ins_encode(aarch64_enc_mov_p0(dst, con)); 6662 6663 ins_pipe(ialu_imm); 6664 %} 6665 6666 // Load Pointer Constant One 6667 6668 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6669 %{ 6670 match(Set dst con); 6671 6672 ins_cost(INSN_COST); 6673 format %{ "mov $dst, $con\t# NULL ptr" %} 6674 6675 ins_encode(aarch64_enc_mov_p1(dst, con)); 6676 6677 ins_pipe(ialu_imm); 6678 %} 6679 6680 // Load Poll Page Constant 6681 6682 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6683 %{ 6684 match(Set dst con); 6685 6686 ins_cost(INSN_COST); 6687 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6688 6689 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6690 6691 ins_pipe(ialu_imm); 6692 %} 6693 6694 // Load Byte Map Base Constant 6695 6696 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6697 %{ 6698 match(Set dst con); 6699 6700 ins_cost(INSN_COST); 6701 format %{ "adr $dst, $con\t# Byte Map Base" %} 6702 6703 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6704 6705 ins_pipe(ialu_imm); 6706 %} 6707 6708 // Load Narrow Pointer Constant 6709 6710 instruct loadConN(iRegNNoSp dst, immN con) 6711 %{ 6712 match(Set dst con); 6713 6714 ins_cost(INSN_COST * 4); 6715 format %{ "mov $dst, $con\t# compressed ptr" %} 6716 6717 ins_encode(aarch64_enc_mov_n(dst, con)); 6718 6719 ins_pipe(ialu_imm); 6720 %} 6721 6722 // Load Narrow Null Pointer Constant 6723 6724 instruct loadConN0(iRegNNoSp dst, immN0 con) 6725 %{ 6726 match(Set dst con); 6727 6728 ins_cost(INSN_COST); 6729 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6730 6731 ins_encode(aarch64_enc_mov_n0(dst, con)); 6732 6733 ins_pipe(ialu_imm); 6734 %} 6735 6736 // Load Narrow Klass Constant 6737 6738 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6739 %{ 6740 match(Set dst con); 6741 6742 ins_cost(INSN_COST); 6743 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6744 6745 ins_encode(aarch64_enc_mov_nk(dst, con)); 6746 6747 ins_pipe(ialu_imm); 6748 %} 6749 6750 // Load Packed Float Constant 6751 6752 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6753 match(Set dst con); 6754 ins_cost(INSN_COST * 4); 6755 format %{ "fmovs $dst, $con"%} 6756 ins_encode %{ 6757 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6758 %} 6759 6760 ins_pipe(fp_imm_s); 6761 %} 6762 6763 // Load Float Constant 6764 6765 instruct loadConF(vRegF dst, immF con) %{ 6766 match(Set dst con); 6767 6768 ins_cost(INSN_COST * 4); 6769 6770 format %{ 6771 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6772 %} 6773 6774 ins_encode %{ 6775 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6776 %} 6777 6778 ins_pipe(fp_load_constant_s); 6779 %} 6780 6781 // Load Packed Double Constant 6782 6783 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6784 match(Set dst con); 6785 ins_cost(INSN_COST); 6786 format %{ "fmovd $dst, $con"%} 6787 ins_encode %{ 6788 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6789 %} 6790 6791 ins_pipe(fp_imm_d); 6792 %} 6793 6794 // Load Double Constant 6795 6796 instruct loadConD(vRegD dst, immD con) %{ 6797 match(Set dst con); 6798 6799 ins_cost(INSN_COST * 5); 6800 format %{ 6801 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6802 %} 6803 6804 ins_encode %{ 6805 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6806 %} 6807 6808 ins_pipe(fp_load_constant_d); 6809 %} 6810 6811 // Store Instructions 6812 6813 // Store CMS card-mark Immediate 6814 instruct storeimmCM0(immI0 zero, memory mem) 6815 %{ 6816 match(Set mem (StoreCM mem zero)); 6817 predicate(unnecessary_storestore(n)); 6818 6819 ins_cost(INSN_COST); 6820 format %{ "storestore (elided)\n\t" 6821 "strb zr, $mem\t# byte" %} 6822 6823 ins_encode(aarch64_enc_strb0(mem)); 6824 6825 ins_pipe(istore_mem); 6826 %} 6827 6828 // Store CMS card-mark Immediate with intervening StoreStore 6829 // needed when using CMS with no conditional card marking 6830 instruct storeimmCM0_ordered(immI0 zero, memory mem) 6831 %{ 6832 match(Set mem (StoreCM mem zero)); 6833 6834 ins_cost(INSN_COST * 2); 6835 format %{ "storestore\n\t" 6836 "dmb ishst" 6837 "\n\tstrb zr, $mem\t# byte" %} 6838 6839 ins_encode(aarch64_enc_strb0_ordered(mem)); 6840 6841 ins_pipe(istore_mem); 6842 %} 6843 6844 // Store Byte 6845 instruct storeB(iRegIorL2I src, memory mem) 6846 %{ 6847 match(Set mem (StoreB mem src)); 6848 predicate(!needs_releasing_store(n)); 6849 6850 ins_cost(INSN_COST); 6851 format %{ "strb $src, $mem\t# byte" %} 6852 6853 ins_encode(aarch64_enc_strb(src, mem)); 6854 6855 ins_pipe(istore_reg_mem); 6856 %} 6857 6858 6859 instruct storeimmB0(immI0 zero, memory mem) 6860 %{ 6861 match(Set mem (StoreB mem zero)); 6862 predicate(!needs_releasing_store(n)); 6863 6864 ins_cost(INSN_COST); 6865 format %{ "strb rscractch2, $mem\t# byte" %} 6866 6867 ins_encode(aarch64_enc_strb0(mem)); 6868 6869 ins_pipe(istore_mem); 6870 %} 6871 6872 // Store Char/Short 6873 instruct storeC(iRegIorL2I src, memory mem) 6874 %{ 6875 match(Set mem (StoreC mem src)); 6876 predicate(!needs_releasing_store(n)); 6877 6878 ins_cost(INSN_COST); 6879 format %{ "strh $src, $mem\t# short" %} 6880 6881 ins_encode(aarch64_enc_strh(src, mem)); 6882 6883 ins_pipe(istore_reg_mem); 6884 %} 6885 6886 instruct storeimmC0(immI0 zero, memory mem) 6887 %{ 6888 match(Set mem (StoreC mem zero)); 6889 predicate(!needs_releasing_store(n)); 6890 6891 ins_cost(INSN_COST); 6892 format %{ "strh zr, $mem\t# short" %} 6893 6894 ins_encode(aarch64_enc_strh0(mem)); 6895 6896 ins_pipe(istore_mem); 6897 %} 6898 6899 // Store Integer 6900 6901 instruct storeI(iRegIorL2I src, memory mem) 6902 %{ 6903 match(Set mem(StoreI mem src)); 6904 predicate(!needs_releasing_store(n)); 6905 6906 ins_cost(INSN_COST); 6907 format %{ "strw $src, $mem\t# int" %} 6908 6909 ins_encode(aarch64_enc_strw(src, mem)); 6910 6911 ins_pipe(istore_reg_mem); 6912 %} 6913 6914 instruct storeimmI0(immI0 zero, memory mem) 6915 %{ 6916 match(Set mem(StoreI mem zero)); 6917 predicate(!needs_releasing_store(n)); 6918 6919 ins_cost(INSN_COST); 6920 format %{ "strw zr, $mem\t# int" %} 6921 6922 ins_encode(aarch64_enc_strw0(mem)); 6923 6924 ins_pipe(istore_mem); 6925 %} 6926 6927 // Store Long (64 bit signed) 6928 instruct storeL(iRegL src, memory mem) 6929 %{ 6930 match(Set mem (StoreL mem src)); 6931 predicate(!needs_releasing_store(n)); 6932 6933 ins_cost(INSN_COST); 6934 format %{ "str $src, $mem\t# int" %} 6935 6936 ins_encode(aarch64_enc_str(src, mem)); 6937 6938 ins_pipe(istore_reg_mem); 6939 %} 6940 6941 // Store Long (64 bit signed) 6942 instruct storeimmL0(immL0 zero, memory mem) 6943 %{ 6944 match(Set mem (StoreL mem zero)); 6945 predicate(!needs_releasing_store(n)); 6946 6947 ins_cost(INSN_COST); 6948 format %{ "str zr, $mem\t# int" %} 6949 6950 ins_encode(aarch64_enc_str0(mem)); 6951 6952 ins_pipe(istore_mem); 6953 %} 6954 6955 // Store Pointer 6956 instruct storeP(iRegP src, memory mem) 6957 %{ 6958 match(Set mem (StoreP mem src)); 6959 predicate(!needs_releasing_store(n)); 6960 6961 ins_cost(INSN_COST); 6962 format %{ "str $src, $mem\t# ptr" %} 6963 6964 ins_encode(aarch64_enc_str(src, mem)); 6965 6966 ins_pipe(istore_reg_mem); 6967 %} 6968 6969 // Store Pointer 6970 instruct storeimmP0(immP0 zero, memory mem) 6971 %{ 6972 match(Set mem (StoreP mem zero)); 6973 predicate(!needs_releasing_store(n)); 6974 6975 ins_cost(INSN_COST); 6976 format %{ "str zr, $mem\t# ptr" %} 6977 6978 ins_encode(aarch64_enc_str0(mem)); 6979 6980 ins_pipe(istore_mem); 6981 %} 6982 6983 // Store Compressed Pointer 6984 instruct storeN(iRegN src, memory mem) 6985 %{ 6986 match(Set mem (StoreN mem src)); 6987 predicate(!needs_releasing_store(n)); 6988 6989 ins_cost(INSN_COST); 6990 format %{ "strw $src, $mem\t# compressed ptr" %} 6991 6992 ins_encode(aarch64_enc_strw(src, mem)); 6993 6994 ins_pipe(istore_reg_mem); 6995 %} 6996 6997 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 6998 %{ 6999 match(Set mem (StoreN mem zero)); 7000 predicate(Universe::narrow_oop_base() == NULL && 7001 Universe::narrow_klass_base() == NULL && 7002 (!needs_releasing_store(n))); 7003 7004 ins_cost(INSN_COST); 7005 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7006 7007 ins_encode(aarch64_enc_strw(heapbase, mem)); 7008 7009 ins_pipe(istore_reg_mem); 7010 %} 7011 7012 // Store Float 7013 instruct storeF(vRegF src, memory mem) 7014 %{ 7015 match(Set mem (StoreF mem src)); 7016 predicate(!needs_releasing_store(n)); 7017 7018 ins_cost(INSN_COST); 7019 format %{ "strs $src, $mem\t# float" %} 7020 7021 ins_encode( aarch64_enc_strs(src, mem) ); 7022 7023 ins_pipe(pipe_class_memory); 7024 %} 7025 7026 // TODO 7027 // implement storeImmF0 and storeFImmPacked 7028 7029 // Store Double 7030 instruct storeD(vRegD src, memory mem) 7031 %{ 7032 match(Set mem (StoreD mem src)); 7033 predicate(!needs_releasing_store(n)); 7034 7035 ins_cost(INSN_COST); 7036 format %{ "strd $src, $mem\t# double" %} 7037 7038 ins_encode( aarch64_enc_strd(src, mem) ); 7039 7040 ins_pipe(pipe_class_memory); 7041 %} 7042 7043 // Store Compressed Klass Pointer 7044 instruct storeNKlass(iRegN src, memory mem) 7045 %{ 7046 predicate(!needs_releasing_store(n)); 7047 match(Set mem (StoreNKlass mem src)); 7048 7049 ins_cost(INSN_COST); 7050 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7051 7052 ins_encode(aarch64_enc_strw(src, mem)); 7053 7054 ins_pipe(istore_reg_mem); 7055 %} 7056 7057 // TODO 7058 // implement storeImmD0 and storeDImmPacked 7059 7060 // prefetch instructions 7061 // Must be safe to execute with invalid address (cannot fault). 7062 7063 instruct prefetchalloc( memory mem ) %{ 7064 match(PrefetchAllocation mem); 7065 7066 ins_cost(INSN_COST); 7067 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7068 7069 ins_encode( aarch64_enc_prefetchw(mem) ); 7070 7071 ins_pipe(iload_prefetch); 7072 %} 7073 7074 // ---------------- volatile loads and stores ---------------- 7075 7076 // Load Byte (8 bit signed) 7077 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7078 %{ 7079 match(Set dst (LoadB mem)); 7080 7081 ins_cost(VOLATILE_REF_COST); 7082 format %{ "ldarsb $dst, $mem\t# byte" %} 7083 7084 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7085 7086 ins_pipe(pipe_serial); 7087 %} 7088 7089 // Load Byte (8 bit signed) into long 7090 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7091 %{ 7092 match(Set dst (ConvI2L (LoadB mem))); 7093 7094 ins_cost(VOLATILE_REF_COST); 7095 format %{ "ldarsb $dst, $mem\t# byte" %} 7096 7097 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7098 7099 ins_pipe(pipe_serial); 7100 %} 7101 7102 // Load Byte (8 bit unsigned) 7103 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7104 %{ 7105 match(Set dst (LoadUB mem)); 7106 7107 ins_cost(VOLATILE_REF_COST); 7108 format %{ "ldarb $dst, $mem\t# byte" %} 7109 7110 ins_encode(aarch64_enc_ldarb(dst, mem)); 7111 7112 ins_pipe(pipe_serial); 7113 %} 7114 7115 // Load Byte (8 bit unsigned) into long 7116 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7117 %{ 7118 match(Set dst (ConvI2L (LoadUB mem))); 7119 7120 ins_cost(VOLATILE_REF_COST); 7121 format %{ "ldarb $dst, $mem\t# byte" %} 7122 7123 ins_encode(aarch64_enc_ldarb(dst, mem)); 7124 7125 ins_pipe(pipe_serial); 7126 %} 7127 7128 // Load Short (16 bit signed) 7129 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7130 %{ 7131 match(Set dst (LoadS mem)); 7132 7133 ins_cost(VOLATILE_REF_COST); 7134 format %{ "ldarshw $dst, $mem\t# short" %} 7135 7136 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7137 7138 ins_pipe(pipe_serial); 7139 %} 7140 7141 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7142 %{ 7143 match(Set dst (LoadUS mem)); 7144 7145 ins_cost(VOLATILE_REF_COST); 7146 format %{ "ldarhw $dst, $mem\t# short" %} 7147 7148 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7149 7150 ins_pipe(pipe_serial); 7151 %} 7152 7153 // Load Short/Char (16 bit unsigned) into long 7154 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7155 %{ 7156 match(Set dst (ConvI2L (LoadUS mem))); 7157 7158 ins_cost(VOLATILE_REF_COST); 7159 format %{ "ldarh $dst, $mem\t# short" %} 7160 7161 ins_encode(aarch64_enc_ldarh(dst, mem)); 7162 7163 ins_pipe(pipe_serial); 7164 %} 7165 7166 // Load Short/Char (16 bit signed) into long 7167 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7168 %{ 7169 match(Set dst (ConvI2L (LoadS mem))); 7170 7171 ins_cost(VOLATILE_REF_COST); 7172 format %{ "ldarh $dst, $mem\t# short" %} 7173 7174 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7175 7176 ins_pipe(pipe_serial); 7177 %} 7178 7179 // Load Integer (32 bit signed) 7180 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7181 %{ 7182 match(Set dst (LoadI mem)); 7183 7184 ins_cost(VOLATILE_REF_COST); 7185 format %{ "ldarw $dst, $mem\t# int" %} 7186 7187 ins_encode(aarch64_enc_ldarw(dst, mem)); 7188 7189 ins_pipe(pipe_serial); 7190 %} 7191 7192 // Load Integer (32 bit unsigned) into long 7193 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7194 %{ 7195 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7196 7197 ins_cost(VOLATILE_REF_COST); 7198 format %{ "ldarw $dst, $mem\t# int" %} 7199 7200 ins_encode(aarch64_enc_ldarw(dst, mem)); 7201 7202 ins_pipe(pipe_serial); 7203 %} 7204 7205 // Load Long (64 bit signed) 7206 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7207 %{ 7208 match(Set dst (LoadL mem)); 7209 7210 ins_cost(VOLATILE_REF_COST); 7211 format %{ "ldar $dst, $mem\t# int" %} 7212 7213 ins_encode(aarch64_enc_ldar(dst, mem)); 7214 7215 ins_pipe(pipe_serial); 7216 %} 7217 7218 // Load Pointer 7219 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7220 %{ 7221 match(Set dst (LoadP mem)); 7222 7223 ins_cost(VOLATILE_REF_COST); 7224 format %{ "ldar $dst, $mem\t# ptr" %} 7225 7226 ins_encode(aarch64_enc_ldar(dst, mem)); 7227 7228 ins_pipe(pipe_serial); 7229 %} 7230 7231 // Load Compressed Pointer 7232 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7233 %{ 7234 match(Set dst (LoadN mem)); 7235 7236 ins_cost(VOLATILE_REF_COST); 7237 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7238 7239 ins_encode(aarch64_enc_ldarw(dst, mem)); 7240 7241 ins_pipe(pipe_serial); 7242 %} 7243 7244 // Load Float 7245 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7246 %{ 7247 match(Set dst (LoadF mem)); 7248 7249 ins_cost(VOLATILE_REF_COST); 7250 format %{ "ldars $dst, $mem\t# float" %} 7251 7252 ins_encode( aarch64_enc_fldars(dst, mem) ); 7253 7254 ins_pipe(pipe_serial); 7255 %} 7256 7257 // Load Double 7258 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7259 %{ 7260 match(Set dst (LoadD mem)); 7261 7262 ins_cost(VOLATILE_REF_COST); 7263 format %{ "ldard $dst, $mem\t# double" %} 7264 7265 ins_encode( aarch64_enc_fldard(dst, mem) ); 7266 7267 ins_pipe(pipe_serial); 7268 %} 7269 7270 // Store Byte 7271 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7272 %{ 7273 match(Set mem (StoreB mem src)); 7274 7275 ins_cost(VOLATILE_REF_COST); 7276 format %{ "stlrb $src, $mem\t# byte" %} 7277 7278 ins_encode(aarch64_enc_stlrb(src, mem)); 7279 7280 ins_pipe(pipe_class_memory); 7281 %} 7282 7283 // Store Char/Short 7284 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7285 %{ 7286 match(Set mem (StoreC mem src)); 7287 7288 ins_cost(VOLATILE_REF_COST); 7289 format %{ "stlrh $src, $mem\t# short" %} 7290 7291 ins_encode(aarch64_enc_stlrh(src, mem)); 7292 7293 ins_pipe(pipe_class_memory); 7294 %} 7295 7296 // Store Integer 7297 7298 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7299 %{ 7300 match(Set mem(StoreI mem src)); 7301 7302 ins_cost(VOLATILE_REF_COST); 7303 format %{ "stlrw $src, $mem\t# int" %} 7304 7305 ins_encode(aarch64_enc_stlrw(src, mem)); 7306 7307 ins_pipe(pipe_class_memory); 7308 %} 7309 7310 // Store Long (64 bit signed) 7311 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7312 %{ 7313 match(Set mem (StoreL mem src)); 7314 7315 ins_cost(VOLATILE_REF_COST); 7316 format %{ "stlr $src, $mem\t# int" %} 7317 7318 ins_encode(aarch64_enc_stlr(src, mem)); 7319 7320 ins_pipe(pipe_class_memory); 7321 %} 7322 7323 // Store Pointer 7324 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7325 %{ 7326 match(Set mem (StoreP mem src)); 7327 7328 ins_cost(VOLATILE_REF_COST); 7329 format %{ "stlr $src, $mem\t# ptr" %} 7330 7331 ins_encode(aarch64_enc_stlr(src, mem)); 7332 7333 ins_pipe(pipe_class_memory); 7334 %} 7335 7336 // Store Compressed Pointer 7337 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7338 %{ 7339 match(Set mem (StoreN mem src)); 7340 7341 ins_cost(VOLATILE_REF_COST); 7342 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7343 7344 ins_encode(aarch64_enc_stlrw(src, mem)); 7345 7346 ins_pipe(pipe_class_memory); 7347 %} 7348 7349 // Store Float 7350 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7351 %{ 7352 match(Set mem (StoreF mem src)); 7353 7354 ins_cost(VOLATILE_REF_COST); 7355 format %{ "stlrs $src, $mem\t# float" %} 7356 7357 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7358 7359 ins_pipe(pipe_class_memory); 7360 %} 7361 7362 // TODO 7363 // implement storeImmF0 and storeFImmPacked 7364 7365 // Store Double 7366 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7367 %{ 7368 match(Set mem (StoreD mem src)); 7369 7370 ins_cost(VOLATILE_REF_COST); 7371 format %{ "stlrd $src, $mem\t# double" %} 7372 7373 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7374 7375 ins_pipe(pipe_class_memory); 7376 %} 7377 7378 // ---------------- end of volatile loads and stores ---------------- 7379 7380 // ============================================================================ 7381 // BSWAP Instructions 7382 7383 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7384 match(Set dst (ReverseBytesI src)); 7385 7386 ins_cost(INSN_COST); 7387 format %{ "revw $dst, $src" %} 7388 7389 ins_encode %{ 7390 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7391 %} 7392 7393 ins_pipe(ialu_reg); 7394 %} 7395 7396 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7397 match(Set dst (ReverseBytesL src)); 7398 7399 ins_cost(INSN_COST); 7400 format %{ "rev $dst, $src" %} 7401 7402 ins_encode %{ 7403 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7404 %} 7405 7406 ins_pipe(ialu_reg); 7407 %} 7408 7409 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7410 match(Set dst (ReverseBytesUS src)); 7411 7412 ins_cost(INSN_COST); 7413 format %{ "rev16w $dst, $src" %} 7414 7415 ins_encode %{ 7416 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7417 %} 7418 7419 ins_pipe(ialu_reg); 7420 %} 7421 7422 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7423 match(Set dst (ReverseBytesS src)); 7424 7425 ins_cost(INSN_COST); 7426 format %{ "rev16w $dst, $src\n\t" 7427 "sbfmw $dst, $dst, #0, #15" %} 7428 7429 ins_encode %{ 7430 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7431 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7432 %} 7433 7434 ins_pipe(ialu_reg); 7435 %} 7436 7437 // ============================================================================ 7438 // Zero Count Instructions 7439 7440 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7441 match(Set dst (CountLeadingZerosI src)); 7442 7443 ins_cost(INSN_COST); 7444 format %{ "clzw $dst, $src" %} 7445 ins_encode %{ 7446 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7447 %} 7448 7449 ins_pipe(ialu_reg); 7450 %} 7451 7452 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7453 match(Set dst (CountLeadingZerosL src)); 7454 7455 ins_cost(INSN_COST); 7456 format %{ "clz $dst, $src" %} 7457 ins_encode %{ 7458 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7459 %} 7460 7461 ins_pipe(ialu_reg); 7462 %} 7463 7464 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7465 match(Set dst (CountTrailingZerosI src)); 7466 7467 ins_cost(INSN_COST * 2); 7468 format %{ "rbitw $dst, $src\n\t" 7469 "clzw $dst, $dst" %} 7470 ins_encode %{ 7471 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7472 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7473 %} 7474 7475 ins_pipe(ialu_reg); 7476 %} 7477 7478 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7479 match(Set dst (CountTrailingZerosL src)); 7480 7481 ins_cost(INSN_COST * 2); 7482 format %{ "rbit $dst, $src\n\t" 7483 "clz $dst, $dst" %} 7484 ins_encode %{ 7485 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7486 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7487 %} 7488 7489 ins_pipe(ialu_reg); 7490 %} 7491 7492 //---------- Population Count Instructions ------------------------------------- 7493 // 7494 7495 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7496 predicate(UsePopCountInstruction); 7497 match(Set dst (PopCountI src)); 7498 effect(TEMP tmp); 7499 ins_cost(INSN_COST * 13); 7500 7501 format %{ "movw $src, $src\n\t" 7502 "mov $tmp, $src\t# vector (1D)\n\t" 7503 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7504 "addv $tmp, $tmp\t# vector (8B)\n\t" 7505 "mov $dst, $tmp\t# vector (1D)" %} 7506 ins_encode %{ 7507 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7508 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7509 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7510 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7511 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7512 %} 7513 7514 ins_pipe(pipe_class_default); 7515 %} 7516 7517 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7518 predicate(UsePopCountInstruction); 7519 match(Set dst (PopCountI (LoadI mem))); 7520 effect(TEMP tmp); 7521 ins_cost(INSN_COST * 13); 7522 7523 format %{ "ldrs $tmp, $mem\n\t" 7524 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7525 "addv $tmp, $tmp\t# vector (8B)\n\t" 7526 "mov $dst, $tmp\t# vector (1D)" %} 7527 ins_encode %{ 7528 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7529 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7530 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7531 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7532 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7533 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7534 %} 7535 7536 ins_pipe(pipe_class_default); 7537 %} 7538 7539 // Note: Long.bitCount(long) returns an int. 7540 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7541 predicate(UsePopCountInstruction); 7542 match(Set dst (PopCountL src)); 7543 effect(TEMP tmp); 7544 ins_cost(INSN_COST * 13); 7545 7546 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7547 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7548 "addv $tmp, $tmp\t# vector (8B)\n\t" 7549 "mov $dst, $tmp\t# vector (1D)" %} 7550 ins_encode %{ 7551 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7552 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7553 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7554 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7555 %} 7556 7557 ins_pipe(pipe_class_default); 7558 %} 7559 7560 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7561 predicate(UsePopCountInstruction); 7562 match(Set dst (PopCountL (LoadL mem))); 7563 effect(TEMP tmp); 7564 ins_cost(INSN_COST * 13); 7565 7566 format %{ "ldrd $tmp, $mem\n\t" 7567 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7568 "addv $tmp, $tmp\t# vector (8B)\n\t" 7569 "mov $dst, $tmp\t# vector (1D)" %} 7570 ins_encode %{ 7571 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7572 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7573 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7574 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7575 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7576 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7577 %} 7578 7579 ins_pipe(pipe_class_default); 7580 %} 7581 7582 // ============================================================================ 7583 // MemBar Instruction 7584 7585 instruct load_fence() %{ 7586 match(LoadFence); 7587 ins_cost(VOLATILE_REF_COST); 7588 7589 format %{ "load_fence" %} 7590 7591 ins_encode %{ 7592 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7593 %} 7594 ins_pipe(pipe_serial); 7595 %} 7596 7597 instruct unnecessary_membar_acquire() %{ 7598 predicate(unnecessary_acquire(n)); 7599 match(MemBarAcquire); 7600 ins_cost(0); 7601 7602 format %{ "membar_acquire (elided)" %} 7603 7604 ins_encode %{ 7605 __ block_comment("membar_acquire (elided)"); 7606 %} 7607 7608 ins_pipe(pipe_class_empty); 7609 %} 7610 7611 instruct membar_acquire() %{ 7612 match(MemBarAcquire); 7613 ins_cost(VOLATILE_REF_COST); 7614 7615 format %{ "membar_acquire\n\t" 7616 "dmb ish" %} 7617 7618 ins_encode %{ 7619 __ block_comment("membar_acquire"); 7620 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7621 %} 7622 7623 ins_pipe(pipe_serial); 7624 %} 7625 7626 7627 instruct membar_acquire_lock() %{ 7628 match(MemBarAcquireLock); 7629 ins_cost(VOLATILE_REF_COST); 7630 7631 format %{ "membar_acquire_lock (elided)" %} 7632 7633 ins_encode %{ 7634 __ block_comment("membar_acquire_lock (elided)"); 7635 %} 7636 7637 ins_pipe(pipe_serial); 7638 %} 7639 7640 instruct store_fence() %{ 7641 match(StoreFence); 7642 ins_cost(VOLATILE_REF_COST); 7643 7644 format %{ "store_fence" %} 7645 7646 ins_encode %{ 7647 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7648 %} 7649 ins_pipe(pipe_serial); 7650 %} 7651 7652 instruct unnecessary_membar_release() %{ 7653 predicate(unnecessary_release(n)); 7654 match(MemBarRelease); 7655 ins_cost(0); 7656 7657 format %{ "membar_release (elided)" %} 7658 7659 ins_encode %{ 7660 __ block_comment("membar_release (elided)"); 7661 %} 7662 ins_pipe(pipe_serial); 7663 %} 7664 7665 instruct membar_release() %{ 7666 match(MemBarRelease); 7667 ins_cost(VOLATILE_REF_COST); 7668 7669 format %{ "membar_release\n\t" 7670 "dmb ish" %} 7671 7672 ins_encode %{ 7673 __ block_comment("membar_release"); 7674 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7675 %} 7676 ins_pipe(pipe_serial); 7677 %} 7678 7679 instruct membar_storestore() %{ 7680 match(MemBarStoreStore); 7681 ins_cost(VOLATILE_REF_COST); 7682 7683 format %{ "MEMBAR-store-store" %} 7684 7685 ins_encode %{ 7686 __ membar(Assembler::StoreStore); 7687 %} 7688 ins_pipe(pipe_serial); 7689 %} 7690 7691 instruct membar_release_lock() %{ 7692 match(MemBarReleaseLock); 7693 ins_cost(VOLATILE_REF_COST); 7694 7695 format %{ "membar_release_lock (elided)" %} 7696 7697 ins_encode %{ 7698 __ block_comment("membar_release_lock (elided)"); 7699 %} 7700 7701 ins_pipe(pipe_serial); 7702 %} 7703 7704 instruct unnecessary_membar_volatile() %{ 7705 predicate(unnecessary_volatile(n)); 7706 match(MemBarVolatile); 7707 ins_cost(0); 7708 7709 format %{ "membar_volatile (elided)" %} 7710 7711 ins_encode %{ 7712 __ block_comment("membar_volatile (elided)"); 7713 %} 7714 7715 ins_pipe(pipe_serial); 7716 %} 7717 7718 instruct membar_volatile() %{ 7719 match(MemBarVolatile); 7720 ins_cost(VOLATILE_REF_COST*100); 7721 7722 format %{ "membar_volatile\n\t" 7723 "dmb ish"%} 7724 7725 ins_encode %{ 7726 __ block_comment("membar_volatile"); 7727 __ membar(Assembler::StoreLoad); 7728 %} 7729 7730 ins_pipe(pipe_serial); 7731 %} 7732 7733 // ============================================================================ 7734 // Cast/Convert Instructions 7735 7736 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7737 match(Set dst (CastX2P src)); 7738 7739 ins_cost(INSN_COST); 7740 format %{ "mov $dst, $src\t# long -> ptr" %} 7741 7742 ins_encode %{ 7743 if ($dst$$reg != $src$$reg) { 7744 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7745 } 7746 %} 7747 7748 ins_pipe(ialu_reg); 7749 %} 7750 7751 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7752 match(Set dst (CastP2X src)); 7753 7754 ins_cost(INSN_COST); 7755 format %{ "mov $dst, $src\t# ptr -> long" %} 7756 7757 ins_encode %{ 7758 if ($dst$$reg != $src$$reg) { 7759 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7760 } 7761 %} 7762 7763 ins_pipe(ialu_reg); 7764 %} 7765 7766 // Convert oop into int for vectors alignment masking 7767 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7768 match(Set dst (ConvL2I (CastP2X src))); 7769 7770 ins_cost(INSN_COST); 7771 format %{ "movw $dst, $src\t# ptr -> int" %} 7772 ins_encode %{ 7773 __ movw($dst$$Register, $src$$Register); 7774 %} 7775 7776 ins_pipe(ialu_reg); 7777 %} 7778 7779 // Convert compressed oop into int for vectors alignment masking 7780 // in case of 32bit oops (heap < 4Gb). 7781 instruct convN2I(iRegINoSp dst, iRegN src) 7782 %{ 7783 predicate(Universe::narrow_oop_shift() == 0); 7784 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7785 7786 ins_cost(INSN_COST); 7787 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7788 ins_encode %{ 7789 __ movw($dst$$Register, $src$$Register); 7790 %} 7791 7792 ins_pipe(ialu_reg); 7793 %} 7794 7795 7796 // Convert oop pointer into compressed form 7797 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7798 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7799 match(Set dst (EncodeP src)); 7800 effect(KILL cr); 7801 ins_cost(INSN_COST * 3); 7802 format %{ "encode_heap_oop $dst, $src" %} 7803 ins_encode %{ 7804 Register s = $src$$Register; 7805 Register d = $dst$$Register; 7806 __ encode_heap_oop(d, s); 7807 %} 7808 ins_pipe(ialu_reg); 7809 %} 7810 7811 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7812 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7813 match(Set dst (EncodeP src)); 7814 ins_cost(INSN_COST * 3); 7815 format %{ "encode_heap_oop_not_null $dst, $src" %} 7816 ins_encode %{ 7817 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7818 %} 7819 ins_pipe(ialu_reg); 7820 %} 7821 7822 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7823 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7824 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7825 match(Set dst (DecodeN src)); 7826 ins_cost(INSN_COST * 3); 7827 format %{ "decode_heap_oop $dst, $src" %} 7828 ins_encode %{ 7829 Register s = $src$$Register; 7830 Register d = $dst$$Register; 7831 __ decode_heap_oop(d, s); 7832 %} 7833 ins_pipe(ialu_reg); 7834 %} 7835 7836 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7837 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7838 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7839 match(Set dst (DecodeN src)); 7840 ins_cost(INSN_COST * 3); 7841 format %{ "decode_heap_oop_not_null $dst, $src" %} 7842 ins_encode %{ 7843 Register s = $src$$Register; 7844 Register d = $dst$$Register; 7845 __ decode_heap_oop_not_null(d, s); 7846 %} 7847 ins_pipe(ialu_reg); 7848 %} 7849 7850 // n.b. AArch64 implementations of encode_klass_not_null and 7851 // decode_klass_not_null do not modify the flags register so, unlike 7852 // Intel, we don't kill CR as a side effect here 7853 7854 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7855 match(Set dst (EncodePKlass src)); 7856 7857 ins_cost(INSN_COST * 3); 7858 format %{ "encode_klass_not_null $dst,$src" %} 7859 7860 ins_encode %{ 7861 Register src_reg = as_Register($src$$reg); 7862 Register dst_reg = as_Register($dst$$reg); 7863 __ encode_klass_not_null(dst_reg, src_reg); 7864 %} 7865 7866 ins_pipe(ialu_reg); 7867 %} 7868 7869 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7870 match(Set dst (DecodeNKlass src)); 7871 7872 ins_cost(INSN_COST * 3); 7873 format %{ "decode_klass_not_null $dst,$src" %} 7874 7875 ins_encode %{ 7876 Register src_reg = as_Register($src$$reg); 7877 Register dst_reg = as_Register($dst$$reg); 7878 if (dst_reg != src_reg) { 7879 __ decode_klass_not_null(dst_reg, src_reg); 7880 } else { 7881 __ decode_klass_not_null(dst_reg); 7882 } 7883 %} 7884 7885 ins_pipe(ialu_reg); 7886 %} 7887 7888 instruct checkCastPP(iRegPNoSp dst) 7889 %{ 7890 match(Set dst (CheckCastPP dst)); 7891 7892 size(0); 7893 format %{ "# checkcastPP of $dst" %} 7894 ins_encode(/* empty encoding */); 7895 ins_pipe(pipe_class_empty); 7896 %} 7897 7898 instruct castPP(iRegPNoSp dst) 7899 %{ 7900 match(Set dst (CastPP dst)); 7901 7902 size(0); 7903 format %{ "# castPP of $dst" %} 7904 ins_encode(/* empty encoding */); 7905 ins_pipe(pipe_class_empty); 7906 %} 7907 7908 instruct castII(iRegI dst) 7909 %{ 7910 match(Set dst (CastII dst)); 7911 7912 size(0); 7913 format %{ "# castII of $dst" %} 7914 ins_encode(/* empty encoding */); 7915 ins_cost(0); 7916 ins_pipe(pipe_class_empty); 7917 %} 7918 7919 instruct castLL(iRegL dst) 7920 %{ 7921 match(Set dst (CastLL dst)); 7922 7923 size(0); 7924 format %{ "# castLL of $dst" %} 7925 ins_encode(/* empty encoding */); 7926 ins_cost(0); 7927 ins_pipe(pipe_class_empty); 7928 %} 7929 7930 // ============================================================================ 7931 // Atomic operation instructions 7932 // 7933 // Intel and SPARC both implement Ideal Node LoadPLocked and 7934 // Store{PIL}Conditional instructions using a normal load for the 7935 // LoadPLocked and a CAS for the Store{PIL}Conditional. 7936 // 7937 // The ideal code appears only to use LoadPLocked/StorePLocked as a 7938 // pair to lock object allocations from Eden space when not using 7939 // TLABs. 7940 // 7941 // There does not appear to be a Load{IL}Locked Ideal Node and the 7942 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 7943 // and to use StoreIConditional only for 32-bit and StoreLConditional 7944 // only for 64-bit. 7945 // 7946 // We implement LoadPLocked and StorePLocked instructions using, 7947 // respectively the AArch64 hw load-exclusive and store-conditional 7948 // instructions. Whereas we must implement each of 7949 // Store{IL}Conditional using a CAS which employs a pair of 7950 // instructions comprising a load-exclusive followed by a 7951 // store-conditional. 7952 7953 7954 // Locked-load (linked load) of the current heap-top 7955 // used when updating the eden heap top 7956 // implemented using ldaxr on AArch64 7957 7958 instruct loadPLocked(iRegPNoSp dst, indirect mem) 7959 %{ 7960 match(Set dst (LoadPLocked mem)); 7961 7962 ins_cost(VOLATILE_REF_COST); 7963 7964 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7965 7966 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7967 7968 ins_pipe(pipe_serial); 7969 %} 7970 7971 // Conditional-store of the updated heap-top. 7972 // Used during allocation of the shared heap. 7973 // Sets flag (EQ) on success. 7974 // implemented using stlxr on AArch64. 7975 7976 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7977 %{ 7978 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7979 7980 ins_cost(VOLATILE_REF_COST); 7981 7982 // TODO 7983 // do we need to do a store-conditional release or can we just use a 7984 // plain store-conditional? 7985 7986 format %{ 7987 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 7988 "cmpw rscratch1, zr\t# EQ on successful write" 7989 %} 7990 7991 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 7992 7993 ins_pipe(pipe_serial); 7994 %} 7995 7996 7997 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 7998 // when attempting to rebias a lock towards the current thread. We 7999 // must use the acquire form of cmpxchg in order to guarantee acquire 8000 // semantics in this case. 8001 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8002 %{ 8003 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8004 8005 ins_cost(VOLATILE_REF_COST); 8006 8007 format %{ 8008 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8009 "cmpw rscratch1, zr\t# EQ on successful write" 8010 %} 8011 8012 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8013 8014 ins_pipe(pipe_slow); 8015 %} 8016 8017 // storeIConditional also has acquire semantics, for no better reason 8018 // than matching storeLConditional. At the time of writing this 8019 // comment storeIConditional was not used anywhere by AArch64. 8020 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8021 %{ 8022 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8023 8024 ins_cost(VOLATILE_REF_COST); 8025 8026 format %{ 8027 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8028 "cmpw rscratch1, zr\t# EQ on successful write" 8029 %} 8030 8031 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8032 8033 ins_pipe(pipe_slow); 8034 %} 8035 8036 // standard CompareAndSwapX when we are using barriers 8037 // these have higher priority than the rules selected by a predicate 8038 8039 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8040 // can't match them 8041 8042 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8043 8044 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8045 ins_cost(2 * VOLATILE_REF_COST); 8046 8047 effect(KILL cr); 8048 8049 format %{ 8050 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8051 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8052 %} 8053 8054 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8055 aarch64_enc_cset_eq(res)); 8056 8057 ins_pipe(pipe_slow); 8058 %} 8059 8060 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8061 8062 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8063 ins_cost(2 * VOLATILE_REF_COST); 8064 8065 effect(KILL cr); 8066 8067 format %{ 8068 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8069 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8070 %} 8071 8072 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8073 aarch64_enc_cset_eq(res)); 8074 8075 ins_pipe(pipe_slow); 8076 %} 8077 8078 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8079 8080 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8081 ins_cost(2 * VOLATILE_REF_COST); 8082 8083 effect(KILL cr); 8084 8085 format %{ 8086 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8087 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8088 %} 8089 8090 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8091 aarch64_enc_cset_eq(res)); 8092 8093 ins_pipe(pipe_slow); 8094 %} 8095 8096 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8097 8098 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8099 ins_cost(2 * VOLATILE_REF_COST); 8100 8101 effect(KILL cr); 8102 8103 format %{ 8104 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8105 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8106 %} 8107 8108 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8109 aarch64_enc_cset_eq(res)); 8110 8111 ins_pipe(pipe_slow); 8112 %} 8113 8114 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8115 8116 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8117 ins_cost(2 * VOLATILE_REF_COST); 8118 8119 effect(KILL cr); 8120 8121 format %{ 8122 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8123 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8124 %} 8125 8126 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8127 aarch64_enc_cset_eq(res)); 8128 8129 ins_pipe(pipe_slow); 8130 %} 8131 8132 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8133 8134 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8135 ins_cost(2 * VOLATILE_REF_COST); 8136 8137 effect(KILL cr); 8138 8139 format %{ 8140 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8141 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8142 %} 8143 8144 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8145 aarch64_enc_cset_eq(res)); 8146 8147 ins_pipe(pipe_slow); 8148 %} 8149 8150 // alternative CompareAndSwapX when we are eliding barriers 8151 8152 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8153 8154 predicate(needs_acquiring_load_exclusive(n)); 8155 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8156 ins_cost(VOLATILE_REF_COST); 8157 8158 effect(KILL cr); 8159 8160 format %{ 8161 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8162 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8163 %} 8164 8165 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8166 aarch64_enc_cset_eq(res)); 8167 8168 ins_pipe(pipe_slow); 8169 %} 8170 8171 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8172 8173 predicate(needs_acquiring_load_exclusive(n)); 8174 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8175 ins_cost(VOLATILE_REF_COST); 8176 8177 effect(KILL cr); 8178 8179 format %{ 8180 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8181 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8182 %} 8183 8184 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8185 aarch64_enc_cset_eq(res)); 8186 8187 ins_pipe(pipe_slow); 8188 %} 8189 8190 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8191 8192 predicate(needs_acquiring_load_exclusive(n)); 8193 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8194 ins_cost(VOLATILE_REF_COST); 8195 8196 effect(KILL cr); 8197 8198 format %{ 8199 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8200 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8201 %} 8202 8203 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8204 aarch64_enc_cset_eq(res)); 8205 8206 ins_pipe(pipe_slow); 8207 %} 8208 8209 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8210 8211 predicate(needs_acquiring_load_exclusive(n)); 8212 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8213 ins_cost(VOLATILE_REF_COST); 8214 8215 effect(KILL cr); 8216 8217 format %{ 8218 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8219 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8220 %} 8221 8222 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8223 aarch64_enc_cset_eq(res)); 8224 8225 ins_pipe(pipe_slow); 8226 %} 8227 8228 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8229 8230 predicate(needs_acquiring_load_exclusive(n)); 8231 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8232 ins_cost(VOLATILE_REF_COST); 8233 8234 effect(KILL cr); 8235 8236 format %{ 8237 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8238 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8239 %} 8240 8241 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8242 aarch64_enc_cset_eq(res)); 8243 8244 ins_pipe(pipe_slow); 8245 %} 8246 8247 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8248 8249 predicate(needs_acquiring_load_exclusive(n)); 8250 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8251 ins_cost(VOLATILE_REF_COST); 8252 8253 effect(KILL cr); 8254 8255 format %{ 8256 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8257 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8258 %} 8259 8260 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8261 aarch64_enc_cset_eq(res)); 8262 8263 ins_pipe(pipe_slow); 8264 %} 8265 8266 8267 // --------------------------------------------------------------------- 8268 8269 8270 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8271 8272 // Sundry CAS operations. Note that release is always true, 8273 // regardless of the memory ordering of the CAS. This is because we 8274 // need the volatile case to be sequentially consistent but there is 8275 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8276 // can't check the type of memory ordering here, so we always emit a 8277 // STLXR. 8278 8279 // This section is generated from aarch64_ad_cas.m4 8280 8281 8282 8283 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8284 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8285 ins_cost(2 * VOLATILE_REF_COST); 8286 effect(TEMP_DEF res, KILL cr); 8287 format %{ 8288 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8289 %} 8290 ins_encode %{ 8291 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8292 Assembler::byte, /*acquire*/ false, /*release*/ true, 8293 /*weak*/ false, $res$$Register); 8294 __ sxtbw($res$$Register, $res$$Register); 8295 %} 8296 ins_pipe(pipe_slow); 8297 %} 8298 8299 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8300 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8301 ins_cost(2 * VOLATILE_REF_COST); 8302 effect(TEMP_DEF res, KILL cr); 8303 format %{ 8304 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8305 %} 8306 ins_encode %{ 8307 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8308 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8309 /*weak*/ false, $res$$Register); 8310 __ sxthw($res$$Register, $res$$Register); 8311 %} 8312 ins_pipe(pipe_slow); 8313 %} 8314 8315 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8316 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8317 ins_cost(2 * VOLATILE_REF_COST); 8318 effect(TEMP_DEF res, KILL cr); 8319 format %{ 8320 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8321 %} 8322 ins_encode %{ 8323 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8324 Assembler::word, /*acquire*/ false, /*release*/ true, 8325 /*weak*/ false, $res$$Register); 8326 %} 8327 ins_pipe(pipe_slow); 8328 %} 8329 8330 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8331 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8332 ins_cost(2 * VOLATILE_REF_COST); 8333 effect(TEMP_DEF res, KILL cr); 8334 format %{ 8335 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8336 %} 8337 ins_encode %{ 8338 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8339 Assembler::xword, /*acquire*/ false, /*release*/ true, 8340 /*weak*/ false, $res$$Register); 8341 %} 8342 ins_pipe(pipe_slow); 8343 %} 8344 8345 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8346 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8347 ins_cost(2 * VOLATILE_REF_COST); 8348 effect(TEMP_DEF res, KILL cr); 8349 format %{ 8350 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8351 %} 8352 ins_encode %{ 8353 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8354 Assembler::word, /*acquire*/ false, /*release*/ true, 8355 /*weak*/ false, $res$$Register); 8356 %} 8357 ins_pipe(pipe_slow); 8358 %} 8359 8360 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8361 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8362 ins_cost(2 * VOLATILE_REF_COST); 8363 effect(TEMP_DEF res, KILL cr); 8364 format %{ 8365 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8366 %} 8367 ins_encode %{ 8368 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8369 Assembler::xword, /*acquire*/ false, /*release*/ true, 8370 /*weak*/ false, $res$$Register); 8371 %} 8372 ins_pipe(pipe_slow); 8373 %} 8374 8375 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8376 predicate(needs_acquiring_load_exclusive(n)); 8377 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8378 ins_cost(VOLATILE_REF_COST); 8379 effect(TEMP_DEF res, KILL cr); 8380 format %{ 8381 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8382 %} 8383 ins_encode %{ 8384 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8385 Assembler::byte, /*acquire*/ true, /*release*/ true, 8386 /*weak*/ false, $res$$Register); 8387 __ sxtbw($res$$Register, $res$$Register); 8388 %} 8389 ins_pipe(pipe_slow); 8390 %} 8391 8392 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8393 predicate(needs_acquiring_load_exclusive(n)); 8394 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8395 ins_cost(VOLATILE_REF_COST); 8396 effect(TEMP_DEF res, KILL cr); 8397 format %{ 8398 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8399 %} 8400 ins_encode %{ 8401 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8402 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8403 /*weak*/ false, $res$$Register); 8404 __ sxthw($res$$Register, $res$$Register); 8405 %} 8406 ins_pipe(pipe_slow); 8407 %} 8408 8409 8410 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8411 predicate(needs_acquiring_load_exclusive(n)); 8412 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8413 ins_cost(VOLATILE_REF_COST); 8414 effect(TEMP_DEF res, KILL cr); 8415 format %{ 8416 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8417 %} 8418 ins_encode %{ 8419 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8420 Assembler::word, /*acquire*/ true, /*release*/ true, 8421 /*weak*/ false, $res$$Register); 8422 %} 8423 ins_pipe(pipe_slow); 8424 %} 8425 8426 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8427 predicate(needs_acquiring_load_exclusive(n)); 8428 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8429 ins_cost(VOLATILE_REF_COST); 8430 effect(TEMP_DEF res, KILL cr); 8431 format %{ 8432 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8433 %} 8434 ins_encode %{ 8435 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8436 Assembler::xword, /*acquire*/ true, /*release*/ true, 8437 /*weak*/ false, $res$$Register); 8438 %} 8439 ins_pipe(pipe_slow); 8440 %} 8441 8442 8443 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8444 predicate(needs_acquiring_load_exclusive(n)); 8445 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8446 ins_cost(VOLATILE_REF_COST); 8447 effect(TEMP_DEF res, KILL cr); 8448 format %{ 8449 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8450 %} 8451 ins_encode %{ 8452 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8453 Assembler::word, /*acquire*/ true, /*release*/ true, 8454 /*weak*/ false, $res$$Register); 8455 %} 8456 ins_pipe(pipe_slow); 8457 %} 8458 8459 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8460 predicate(needs_acquiring_load_exclusive(n)); 8461 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8462 ins_cost(VOLATILE_REF_COST); 8463 effect(TEMP_DEF res, KILL cr); 8464 format %{ 8465 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8466 %} 8467 ins_encode %{ 8468 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8469 Assembler::xword, /*acquire*/ true, /*release*/ true, 8470 /*weak*/ false, $res$$Register); 8471 %} 8472 ins_pipe(pipe_slow); 8473 %} 8474 8475 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8476 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8477 ins_cost(2 * VOLATILE_REF_COST); 8478 effect(KILL cr); 8479 format %{ 8480 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8481 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8482 %} 8483 ins_encode %{ 8484 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8485 Assembler::byte, /*acquire*/ false, /*release*/ true, 8486 /*weak*/ true, noreg); 8487 __ csetw($res$$Register, Assembler::EQ); 8488 %} 8489 ins_pipe(pipe_slow); 8490 %} 8491 8492 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8493 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8494 ins_cost(2 * VOLATILE_REF_COST); 8495 effect(KILL cr); 8496 format %{ 8497 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8498 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8499 %} 8500 ins_encode %{ 8501 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8502 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8503 /*weak*/ true, noreg); 8504 __ csetw($res$$Register, Assembler::EQ); 8505 %} 8506 ins_pipe(pipe_slow); 8507 %} 8508 8509 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8510 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8511 ins_cost(2 * VOLATILE_REF_COST); 8512 effect(KILL cr); 8513 format %{ 8514 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8515 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8516 %} 8517 ins_encode %{ 8518 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8519 Assembler::word, /*acquire*/ false, /*release*/ true, 8520 /*weak*/ true, noreg); 8521 __ csetw($res$$Register, Assembler::EQ); 8522 %} 8523 ins_pipe(pipe_slow); 8524 %} 8525 8526 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8527 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8528 ins_cost(2 * VOLATILE_REF_COST); 8529 effect(KILL cr); 8530 format %{ 8531 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8532 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8533 %} 8534 ins_encode %{ 8535 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8536 Assembler::xword, /*acquire*/ false, /*release*/ true, 8537 /*weak*/ true, noreg); 8538 __ csetw($res$$Register, Assembler::EQ); 8539 %} 8540 ins_pipe(pipe_slow); 8541 %} 8542 8543 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8544 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8545 ins_cost(2 * VOLATILE_REF_COST); 8546 effect(KILL cr); 8547 format %{ 8548 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8549 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8550 %} 8551 ins_encode %{ 8552 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8553 Assembler::word, /*acquire*/ false, /*release*/ true, 8554 /*weak*/ true, noreg); 8555 __ csetw($res$$Register, Assembler::EQ); 8556 %} 8557 ins_pipe(pipe_slow); 8558 %} 8559 8560 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8561 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8562 ins_cost(2 * VOLATILE_REF_COST); 8563 effect(KILL cr); 8564 format %{ 8565 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8566 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8567 %} 8568 ins_encode %{ 8569 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8570 Assembler::xword, /*acquire*/ false, /*release*/ true, 8571 /*weak*/ true, noreg); 8572 __ csetw($res$$Register, Assembler::EQ); 8573 %} 8574 ins_pipe(pipe_slow); 8575 %} 8576 8577 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8578 predicate(needs_acquiring_load_exclusive(n)); 8579 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8580 ins_cost(VOLATILE_REF_COST); 8581 effect(KILL cr); 8582 format %{ 8583 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8584 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8585 %} 8586 ins_encode %{ 8587 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8588 Assembler::byte, /*acquire*/ true, /*release*/ true, 8589 /*weak*/ true, noreg); 8590 __ csetw($res$$Register, Assembler::EQ); 8591 %} 8592 ins_pipe(pipe_slow); 8593 %} 8594 8595 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8596 predicate(needs_acquiring_load_exclusive(n)); 8597 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8598 ins_cost(VOLATILE_REF_COST); 8599 effect(KILL cr); 8600 format %{ 8601 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8602 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8603 %} 8604 ins_encode %{ 8605 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8606 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8607 /*weak*/ true, noreg); 8608 __ csetw($res$$Register, Assembler::EQ); 8609 %} 8610 ins_pipe(pipe_slow); 8611 %} 8612 8613 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8614 predicate(needs_acquiring_load_exclusive(n)); 8615 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8616 ins_cost(VOLATILE_REF_COST); 8617 effect(KILL cr); 8618 format %{ 8619 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8620 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8621 %} 8622 ins_encode %{ 8623 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8624 Assembler::word, /*acquire*/ true, /*release*/ true, 8625 /*weak*/ true, noreg); 8626 __ csetw($res$$Register, Assembler::EQ); 8627 %} 8628 ins_pipe(pipe_slow); 8629 %} 8630 8631 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8632 predicate(needs_acquiring_load_exclusive(n)); 8633 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8634 ins_cost(VOLATILE_REF_COST); 8635 effect(KILL cr); 8636 format %{ 8637 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8638 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8639 %} 8640 ins_encode %{ 8641 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8642 Assembler::xword, /*acquire*/ true, /*release*/ true, 8643 /*weak*/ true, noreg); 8644 __ csetw($res$$Register, Assembler::EQ); 8645 %} 8646 ins_pipe(pipe_slow); 8647 %} 8648 8649 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8650 predicate(needs_acquiring_load_exclusive(n)); 8651 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8652 ins_cost(VOLATILE_REF_COST); 8653 effect(KILL cr); 8654 format %{ 8655 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8656 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8657 %} 8658 ins_encode %{ 8659 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8660 Assembler::word, /*acquire*/ true, /*release*/ true, 8661 /*weak*/ true, noreg); 8662 __ csetw($res$$Register, Assembler::EQ); 8663 %} 8664 ins_pipe(pipe_slow); 8665 %} 8666 8667 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8668 predicate(needs_acquiring_load_exclusive(n)); 8669 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8670 ins_cost(VOLATILE_REF_COST); 8671 effect(KILL cr); 8672 format %{ 8673 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8674 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8675 %} 8676 ins_encode %{ 8677 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8678 Assembler::xword, /*acquire*/ true, /*release*/ true, 8679 /*weak*/ true, noreg); 8680 __ csetw($res$$Register, Assembler::EQ); 8681 %} 8682 ins_pipe(pipe_slow); 8683 %} 8684 8685 // END This section of the file is automatically generated. Do not edit -------------- 8686 // --------------------------------------------------------------------- 8687 8688 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8689 match(Set prev (GetAndSetI mem newv)); 8690 ins_cost(2 * VOLATILE_REF_COST); 8691 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8692 ins_encode %{ 8693 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8694 %} 8695 ins_pipe(pipe_serial); 8696 %} 8697 8698 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8699 match(Set prev (GetAndSetL mem newv)); 8700 ins_cost(2 * VOLATILE_REF_COST); 8701 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8702 ins_encode %{ 8703 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8704 %} 8705 ins_pipe(pipe_serial); 8706 %} 8707 8708 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8709 match(Set prev (GetAndSetN mem newv)); 8710 ins_cost(2 * VOLATILE_REF_COST); 8711 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8712 ins_encode %{ 8713 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8714 %} 8715 ins_pipe(pipe_serial); 8716 %} 8717 8718 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8719 match(Set prev (GetAndSetP mem newv)); 8720 ins_cost(2 * VOLATILE_REF_COST); 8721 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8722 ins_encode %{ 8723 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8724 %} 8725 ins_pipe(pipe_serial); 8726 %} 8727 8728 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 8729 predicate(needs_acquiring_load_exclusive(n)); 8730 match(Set prev (GetAndSetI mem newv)); 8731 ins_cost(VOLATILE_REF_COST); 8732 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8733 ins_encode %{ 8734 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8735 %} 8736 ins_pipe(pipe_serial); 8737 %} 8738 8739 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8740 predicate(needs_acquiring_load_exclusive(n)); 8741 match(Set prev (GetAndSetL mem newv)); 8742 ins_cost(VOLATILE_REF_COST); 8743 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8744 ins_encode %{ 8745 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8746 %} 8747 ins_pipe(pipe_serial); 8748 %} 8749 8750 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 8751 predicate(needs_acquiring_load_exclusive(n)); 8752 match(Set prev (GetAndSetN mem newv)); 8753 ins_cost(VOLATILE_REF_COST); 8754 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8755 ins_encode %{ 8756 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8757 %} 8758 ins_pipe(pipe_serial); 8759 %} 8760 8761 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8762 predicate(needs_acquiring_load_exclusive(n)); 8763 match(Set prev (GetAndSetP mem newv)); 8764 ins_cost(VOLATILE_REF_COST); 8765 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8766 ins_encode %{ 8767 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8768 %} 8769 ins_pipe(pipe_serial); 8770 %} 8771 8772 8773 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8774 match(Set newval (GetAndAddL mem incr)); 8775 ins_cost(2 * VOLATILE_REF_COST + 1); 8776 format %{ "get_and_addL $newval, [$mem], $incr" %} 8777 ins_encode %{ 8778 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8779 %} 8780 ins_pipe(pipe_serial); 8781 %} 8782 8783 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8784 predicate(n->as_LoadStore()->result_not_used()); 8785 match(Set dummy (GetAndAddL mem incr)); 8786 ins_cost(2 * VOLATILE_REF_COST); 8787 format %{ "get_and_addL [$mem], $incr" %} 8788 ins_encode %{ 8789 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8790 %} 8791 ins_pipe(pipe_serial); 8792 %} 8793 8794 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8795 match(Set newval (GetAndAddL mem incr)); 8796 ins_cost(2 * VOLATILE_REF_COST + 1); 8797 format %{ "get_and_addL $newval, [$mem], $incr" %} 8798 ins_encode %{ 8799 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8800 %} 8801 ins_pipe(pipe_serial); 8802 %} 8803 8804 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8805 predicate(n->as_LoadStore()->result_not_used()); 8806 match(Set dummy (GetAndAddL mem incr)); 8807 ins_cost(2 * VOLATILE_REF_COST); 8808 format %{ "get_and_addL [$mem], $incr" %} 8809 ins_encode %{ 8810 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8811 %} 8812 ins_pipe(pipe_serial); 8813 %} 8814 8815 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8816 match(Set newval (GetAndAddI mem incr)); 8817 ins_cost(2 * VOLATILE_REF_COST + 1); 8818 format %{ "get_and_addI $newval, [$mem], $incr" %} 8819 ins_encode %{ 8820 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8821 %} 8822 ins_pipe(pipe_serial); 8823 %} 8824 8825 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8826 predicate(n->as_LoadStore()->result_not_used()); 8827 match(Set dummy (GetAndAddI mem incr)); 8828 ins_cost(2 * VOLATILE_REF_COST); 8829 format %{ "get_and_addI [$mem], $incr" %} 8830 ins_encode %{ 8831 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8832 %} 8833 ins_pipe(pipe_serial); 8834 %} 8835 8836 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8837 match(Set newval (GetAndAddI mem incr)); 8838 ins_cost(2 * VOLATILE_REF_COST + 1); 8839 format %{ "get_and_addI $newval, [$mem], $incr" %} 8840 ins_encode %{ 8841 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8842 %} 8843 ins_pipe(pipe_serial); 8844 %} 8845 8846 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8847 predicate(n->as_LoadStore()->result_not_used()); 8848 match(Set dummy (GetAndAddI mem incr)); 8849 ins_cost(2 * VOLATILE_REF_COST); 8850 format %{ "get_and_addI [$mem], $incr" %} 8851 ins_encode %{ 8852 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8853 %} 8854 ins_pipe(pipe_serial); 8855 %} 8856 8857 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8858 predicate(needs_acquiring_load_exclusive(n)); 8859 match(Set newval (GetAndAddL mem incr)); 8860 ins_cost(VOLATILE_REF_COST + 1); 8861 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8862 ins_encode %{ 8863 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8864 %} 8865 ins_pipe(pipe_serial); 8866 %} 8867 8868 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 8869 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8870 match(Set dummy (GetAndAddL mem incr)); 8871 ins_cost(VOLATILE_REF_COST); 8872 format %{ "get_and_addL_acq [$mem], $incr" %} 8873 ins_encode %{ 8874 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 8875 %} 8876 ins_pipe(pipe_serial); 8877 %} 8878 8879 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8880 predicate(needs_acquiring_load_exclusive(n)); 8881 match(Set newval (GetAndAddL mem incr)); 8882 ins_cost(VOLATILE_REF_COST + 1); 8883 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8884 ins_encode %{ 8885 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8886 %} 8887 ins_pipe(pipe_serial); 8888 %} 8889 8890 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 8891 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8892 match(Set dummy (GetAndAddL mem incr)); 8893 ins_cost(VOLATILE_REF_COST); 8894 format %{ "get_and_addL_acq [$mem], $incr" %} 8895 ins_encode %{ 8896 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 8897 %} 8898 ins_pipe(pipe_serial); 8899 %} 8900 8901 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8902 predicate(needs_acquiring_load_exclusive(n)); 8903 match(Set newval (GetAndAddI mem incr)); 8904 ins_cost(VOLATILE_REF_COST + 1); 8905 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8906 ins_encode %{ 8907 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8908 %} 8909 ins_pipe(pipe_serial); 8910 %} 8911 8912 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8913 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8914 match(Set dummy (GetAndAddI mem incr)); 8915 ins_cost(VOLATILE_REF_COST); 8916 format %{ "get_and_addI_acq [$mem], $incr" %} 8917 ins_encode %{ 8918 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 8919 %} 8920 ins_pipe(pipe_serial); 8921 %} 8922 8923 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8924 predicate(needs_acquiring_load_exclusive(n)); 8925 match(Set newval (GetAndAddI mem incr)); 8926 ins_cost(VOLATILE_REF_COST + 1); 8927 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8928 ins_encode %{ 8929 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8930 %} 8931 ins_pipe(pipe_serial); 8932 %} 8933 8934 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 8935 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8936 match(Set dummy (GetAndAddI mem incr)); 8937 ins_cost(VOLATILE_REF_COST); 8938 format %{ "get_and_addI_acq [$mem], $incr" %} 8939 ins_encode %{ 8940 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 8941 %} 8942 ins_pipe(pipe_serial); 8943 %} 8944 8945 // Manifest a CmpL result in an integer register. 8946 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8947 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8948 %{ 8949 match(Set dst (CmpL3 src1 src2)); 8950 effect(KILL flags); 8951 8952 ins_cost(INSN_COST * 6); 8953 format %{ 8954 "cmp $src1, $src2" 8955 "csetw $dst, ne" 8956 "cnegw $dst, lt" 8957 %} 8958 // format %{ "CmpL3 $dst, $src1, $src2" %} 8959 ins_encode %{ 8960 __ cmp($src1$$Register, $src2$$Register); 8961 __ csetw($dst$$Register, Assembler::NE); 8962 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8963 %} 8964 8965 ins_pipe(pipe_class_default); 8966 %} 8967 8968 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8969 %{ 8970 match(Set dst (CmpL3 src1 src2)); 8971 effect(KILL flags); 8972 8973 ins_cost(INSN_COST * 6); 8974 format %{ 8975 "cmp $src1, $src2" 8976 "csetw $dst, ne" 8977 "cnegw $dst, lt" 8978 %} 8979 ins_encode %{ 8980 int32_t con = (int32_t)$src2$$constant; 8981 if (con < 0) { 8982 __ adds(zr, $src1$$Register, -con); 8983 } else { 8984 __ subs(zr, $src1$$Register, con); 8985 } 8986 __ csetw($dst$$Register, Assembler::NE); 8987 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8988 %} 8989 8990 ins_pipe(pipe_class_default); 8991 %} 8992 8993 // ============================================================================ 8994 // Conditional Move Instructions 8995 8996 // n.b. we have identical rules for both a signed compare op (cmpOp) 8997 // and an unsigned compare op (cmpOpU). it would be nice if we could 8998 // define an op class which merged both inputs and use it to type the 8999 // argument to a single rule. unfortunatelyt his fails because the 9000 // opclass does not live up to the COND_INTER interface of its 9001 // component operands. When the generic code tries to negate the 9002 // operand it ends up running the generci Machoper::negate method 9003 // which throws a ShouldNotHappen. So, we have to provide two flavours 9004 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9005 9006 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9007 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9008 9009 ins_cost(INSN_COST * 2); 9010 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9011 9012 ins_encode %{ 9013 __ cselw(as_Register($dst$$reg), 9014 as_Register($src2$$reg), 9015 as_Register($src1$$reg), 9016 (Assembler::Condition)$cmp$$cmpcode); 9017 %} 9018 9019 ins_pipe(icond_reg_reg); 9020 %} 9021 9022 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9023 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9024 9025 ins_cost(INSN_COST * 2); 9026 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9027 9028 ins_encode %{ 9029 __ cselw(as_Register($dst$$reg), 9030 as_Register($src2$$reg), 9031 as_Register($src1$$reg), 9032 (Assembler::Condition)$cmp$$cmpcode); 9033 %} 9034 9035 ins_pipe(icond_reg_reg); 9036 %} 9037 9038 // special cases where one arg is zero 9039 9040 // n.b. this is selected in preference to the rule above because it 9041 // avoids loading constant 0 into a source register 9042 9043 // TODO 9044 // we ought only to be able to cull one of these variants as the ideal 9045 // transforms ought always to order the zero consistently (to left/right?) 9046 9047 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9048 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9049 9050 ins_cost(INSN_COST * 2); 9051 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9052 9053 ins_encode %{ 9054 __ cselw(as_Register($dst$$reg), 9055 as_Register($src$$reg), 9056 zr, 9057 (Assembler::Condition)$cmp$$cmpcode); 9058 %} 9059 9060 ins_pipe(icond_reg); 9061 %} 9062 9063 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9064 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9065 9066 ins_cost(INSN_COST * 2); 9067 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9068 9069 ins_encode %{ 9070 __ cselw(as_Register($dst$$reg), 9071 as_Register($src$$reg), 9072 zr, 9073 (Assembler::Condition)$cmp$$cmpcode); 9074 %} 9075 9076 ins_pipe(icond_reg); 9077 %} 9078 9079 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9080 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9081 9082 ins_cost(INSN_COST * 2); 9083 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9084 9085 ins_encode %{ 9086 __ cselw(as_Register($dst$$reg), 9087 zr, 9088 as_Register($src$$reg), 9089 (Assembler::Condition)$cmp$$cmpcode); 9090 %} 9091 9092 ins_pipe(icond_reg); 9093 %} 9094 9095 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9096 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9097 9098 ins_cost(INSN_COST * 2); 9099 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9100 9101 ins_encode %{ 9102 __ cselw(as_Register($dst$$reg), 9103 zr, 9104 as_Register($src$$reg), 9105 (Assembler::Condition)$cmp$$cmpcode); 9106 %} 9107 9108 ins_pipe(icond_reg); 9109 %} 9110 9111 // special case for creating a boolean 0 or 1 9112 9113 // n.b. this is selected in preference to the rule above because it 9114 // avoids loading constants 0 and 1 into a source register 9115 9116 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9117 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9118 9119 ins_cost(INSN_COST * 2); 9120 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9121 9122 ins_encode %{ 9123 // equivalently 9124 // cset(as_Register($dst$$reg), 9125 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9126 __ csincw(as_Register($dst$$reg), 9127 zr, 9128 zr, 9129 (Assembler::Condition)$cmp$$cmpcode); 9130 %} 9131 9132 ins_pipe(icond_none); 9133 %} 9134 9135 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9136 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9137 9138 ins_cost(INSN_COST * 2); 9139 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9140 9141 ins_encode %{ 9142 // equivalently 9143 // cset(as_Register($dst$$reg), 9144 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9145 __ csincw(as_Register($dst$$reg), 9146 zr, 9147 zr, 9148 (Assembler::Condition)$cmp$$cmpcode); 9149 %} 9150 9151 ins_pipe(icond_none); 9152 %} 9153 9154 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9155 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9156 9157 ins_cost(INSN_COST * 2); 9158 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9159 9160 ins_encode %{ 9161 __ csel(as_Register($dst$$reg), 9162 as_Register($src2$$reg), 9163 as_Register($src1$$reg), 9164 (Assembler::Condition)$cmp$$cmpcode); 9165 %} 9166 9167 ins_pipe(icond_reg_reg); 9168 %} 9169 9170 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9171 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9172 9173 ins_cost(INSN_COST * 2); 9174 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9175 9176 ins_encode %{ 9177 __ csel(as_Register($dst$$reg), 9178 as_Register($src2$$reg), 9179 as_Register($src1$$reg), 9180 (Assembler::Condition)$cmp$$cmpcode); 9181 %} 9182 9183 ins_pipe(icond_reg_reg); 9184 %} 9185 9186 // special cases where one arg is zero 9187 9188 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9189 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9190 9191 ins_cost(INSN_COST * 2); 9192 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9193 9194 ins_encode %{ 9195 __ csel(as_Register($dst$$reg), 9196 zr, 9197 as_Register($src$$reg), 9198 (Assembler::Condition)$cmp$$cmpcode); 9199 %} 9200 9201 ins_pipe(icond_reg); 9202 %} 9203 9204 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9205 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9206 9207 ins_cost(INSN_COST * 2); 9208 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9209 9210 ins_encode %{ 9211 __ csel(as_Register($dst$$reg), 9212 zr, 9213 as_Register($src$$reg), 9214 (Assembler::Condition)$cmp$$cmpcode); 9215 %} 9216 9217 ins_pipe(icond_reg); 9218 %} 9219 9220 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9221 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9222 9223 ins_cost(INSN_COST * 2); 9224 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9225 9226 ins_encode %{ 9227 __ csel(as_Register($dst$$reg), 9228 as_Register($src$$reg), 9229 zr, 9230 (Assembler::Condition)$cmp$$cmpcode); 9231 %} 9232 9233 ins_pipe(icond_reg); 9234 %} 9235 9236 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9237 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9238 9239 ins_cost(INSN_COST * 2); 9240 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9241 9242 ins_encode %{ 9243 __ csel(as_Register($dst$$reg), 9244 as_Register($src$$reg), 9245 zr, 9246 (Assembler::Condition)$cmp$$cmpcode); 9247 %} 9248 9249 ins_pipe(icond_reg); 9250 %} 9251 9252 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9253 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9254 9255 ins_cost(INSN_COST * 2); 9256 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9257 9258 ins_encode %{ 9259 __ csel(as_Register($dst$$reg), 9260 as_Register($src2$$reg), 9261 as_Register($src1$$reg), 9262 (Assembler::Condition)$cmp$$cmpcode); 9263 %} 9264 9265 ins_pipe(icond_reg_reg); 9266 %} 9267 9268 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9269 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9270 9271 ins_cost(INSN_COST * 2); 9272 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9273 9274 ins_encode %{ 9275 __ csel(as_Register($dst$$reg), 9276 as_Register($src2$$reg), 9277 as_Register($src1$$reg), 9278 (Assembler::Condition)$cmp$$cmpcode); 9279 %} 9280 9281 ins_pipe(icond_reg_reg); 9282 %} 9283 9284 // special cases where one arg is zero 9285 9286 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9287 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9288 9289 ins_cost(INSN_COST * 2); 9290 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9291 9292 ins_encode %{ 9293 __ csel(as_Register($dst$$reg), 9294 zr, 9295 as_Register($src$$reg), 9296 (Assembler::Condition)$cmp$$cmpcode); 9297 %} 9298 9299 ins_pipe(icond_reg); 9300 %} 9301 9302 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9303 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9304 9305 ins_cost(INSN_COST * 2); 9306 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9307 9308 ins_encode %{ 9309 __ csel(as_Register($dst$$reg), 9310 zr, 9311 as_Register($src$$reg), 9312 (Assembler::Condition)$cmp$$cmpcode); 9313 %} 9314 9315 ins_pipe(icond_reg); 9316 %} 9317 9318 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9319 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9320 9321 ins_cost(INSN_COST * 2); 9322 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9323 9324 ins_encode %{ 9325 __ csel(as_Register($dst$$reg), 9326 as_Register($src$$reg), 9327 zr, 9328 (Assembler::Condition)$cmp$$cmpcode); 9329 %} 9330 9331 ins_pipe(icond_reg); 9332 %} 9333 9334 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9335 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9336 9337 ins_cost(INSN_COST * 2); 9338 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9339 9340 ins_encode %{ 9341 __ csel(as_Register($dst$$reg), 9342 as_Register($src$$reg), 9343 zr, 9344 (Assembler::Condition)$cmp$$cmpcode); 9345 %} 9346 9347 ins_pipe(icond_reg); 9348 %} 9349 9350 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9351 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9352 9353 ins_cost(INSN_COST * 2); 9354 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9355 9356 ins_encode %{ 9357 __ cselw(as_Register($dst$$reg), 9358 as_Register($src2$$reg), 9359 as_Register($src1$$reg), 9360 (Assembler::Condition)$cmp$$cmpcode); 9361 %} 9362 9363 ins_pipe(icond_reg_reg); 9364 %} 9365 9366 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9367 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9368 9369 ins_cost(INSN_COST * 2); 9370 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9371 9372 ins_encode %{ 9373 __ cselw(as_Register($dst$$reg), 9374 as_Register($src2$$reg), 9375 as_Register($src1$$reg), 9376 (Assembler::Condition)$cmp$$cmpcode); 9377 %} 9378 9379 ins_pipe(icond_reg_reg); 9380 %} 9381 9382 // special cases where one arg is zero 9383 9384 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9385 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9386 9387 ins_cost(INSN_COST * 2); 9388 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9389 9390 ins_encode %{ 9391 __ cselw(as_Register($dst$$reg), 9392 zr, 9393 as_Register($src$$reg), 9394 (Assembler::Condition)$cmp$$cmpcode); 9395 %} 9396 9397 ins_pipe(icond_reg); 9398 %} 9399 9400 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9401 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9402 9403 ins_cost(INSN_COST * 2); 9404 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9405 9406 ins_encode %{ 9407 __ cselw(as_Register($dst$$reg), 9408 zr, 9409 as_Register($src$$reg), 9410 (Assembler::Condition)$cmp$$cmpcode); 9411 %} 9412 9413 ins_pipe(icond_reg); 9414 %} 9415 9416 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9417 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9418 9419 ins_cost(INSN_COST * 2); 9420 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9421 9422 ins_encode %{ 9423 __ cselw(as_Register($dst$$reg), 9424 as_Register($src$$reg), 9425 zr, 9426 (Assembler::Condition)$cmp$$cmpcode); 9427 %} 9428 9429 ins_pipe(icond_reg); 9430 %} 9431 9432 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9433 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9434 9435 ins_cost(INSN_COST * 2); 9436 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9437 9438 ins_encode %{ 9439 __ cselw(as_Register($dst$$reg), 9440 as_Register($src$$reg), 9441 zr, 9442 (Assembler::Condition)$cmp$$cmpcode); 9443 %} 9444 9445 ins_pipe(icond_reg); 9446 %} 9447 9448 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9449 %{ 9450 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9451 9452 ins_cost(INSN_COST * 3); 9453 9454 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9455 ins_encode %{ 9456 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9457 __ fcsels(as_FloatRegister($dst$$reg), 9458 as_FloatRegister($src2$$reg), 9459 as_FloatRegister($src1$$reg), 9460 cond); 9461 %} 9462 9463 ins_pipe(fp_cond_reg_reg_s); 9464 %} 9465 9466 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9467 %{ 9468 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9469 9470 ins_cost(INSN_COST * 3); 9471 9472 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9473 ins_encode %{ 9474 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9475 __ fcsels(as_FloatRegister($dst$$reg), 9476 as_FloatRegister($src2$$reg), 9477 as_FloatRegister($src1$$reg), 9478 cond); 9479 %} 9480 9481 ins_pipe(fp_cond_reg_reg_s); 9482 %} 9483 9484 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9485 %{ 9486 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9487 9488 ins_cost(INSN_COST * 3); 9489 9490 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9491 ins_encode %{ 9492 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9493 __ fcseld(as_FloatRegister($dst$$reg), 9494 as_FloatRegister($src2$$reg), 9495 as_FloatRegister($src1$$reg), 9496 cond); 9497 %} 9498 9499 ins_pipe(fp_cond_reg_reg_d); 9500 %} 9501 9502 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9503 %{ 9504 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9505 9506 ins_cost(INSN_COST * 3); 9507 9508 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9509 ins_encode %{ 9510 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9511 __ fcseld(as_FloatRegister($dst$$reg), 9512 as_FloatRegister($src2$$reg), 9513 as_FloatRegister($src1$$reg), 9514 cond); 9515 %} 9516 9517 ins_pipe(fp_cond_reg_reg_d); 9518 %} 9519 9520 // ============================================================================ 9521 // Arithmetic Instructions 9522 // 9523 9524 // Integer Addition 9525 9526 // TODO 9527 // these currently employ operations which do not set CR and hence are 9528 // not flagged as killing CR but we would like to isolate the cases 9529 // where we want to set flags from those where we don't. need to work 9530 // out how to do that. 9531 9532 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9533 match(Set dst (AddI src1 src2)); 9534 9535 ins_cost(INSN_COST); 9536 format %{ "addw $dst, $src1, $src2" %} 9537 9538 ins_encode %{ 9539 __ addw(as_Register($dst$$reg), 9540 as_Register($src1$$reg), 9541 as_Register($src2$$reg)); 9542 %} 9543 9544 ins_pipe(ialu_reg_reg); 9545 %} 9546 9547 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9548 match(Set dst (AddI src1 src2)); 9549 9550 ins_cost(INSN_COST); 9551 format %{ "addw $dst, $src1, $src2" %} 9552 9553 // use opcode to indicate that this is an add not a sub 9554 opcode(0x0); 9555 9556 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9557 9558 ins_pipe(ialu_reg_imm); 9559 %} 9560 9561 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9562 match(Set dst (AddI (ConvL2I src1) src2)); 9563 9564 ins_cost(INSN_COST); 9565 format %{ "addw $dst, $src1, $src2" %} 9566 9567 // use opcode to indicate that this is an add not a sub 9568 opcode(0x0); 9569 9570 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9571 9572 ins_pipe(ialu_reg_imm); 9573 %} 9574 9575 // Pointer Addition 9576 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9577 match(Set dst (AddP src1 src2)); 9578 9579 ins_cost(INSN_COST); 9580 format %{ "add $dst, $src1, $src2\t# ptr" %} 9581 9582 ins_encode %{ 9583 __ add(as_Register($dst$$reg), 9584 as_Register($src1$$reg), 9585 as_Register($src2$$reg)); 9586 %} 9587 9588 ins_pipe(ialu_reg_reg); 9589 %} 9590 9591 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9592 match(Set dst (AddP src1 (ConvI2L src2))); 9593 9594 ins_cost(1.9 * INSN_COST); 9595 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9596 9597 ins_encode %{ 9598 __ add(as_Register($dst$$reg), 9599 as_Register($src1$$reg), 9600 as_Register($src2$$reg), ext::sxtw); 9601 %} 9602 9603 ins_pipe(ialu_reg_reg); 9604 %} 9605 9606 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9607 match(Set dst (AddP src1 (LShiftL src2 scale))); 9608 9609 ins_cost(1.9 * INSN_COST); 9610 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9611 9612 ins_encode %{ 9613 __ lea(as_Register($dst$$reg), 9614 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9615 Address::lsl($scale$$constant))); 9616 %} 9617 9618 ins_pipe(ialu_reg_reg_shift); 9619 %} 9620 9621 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9622 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9623 9624 ins_cost(1.9 * INSN_COST); 9625 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9626 9627 ins_encode %{ 9628 __ lea(as_Register($dst$$reg), 9629 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9630 Address::sxtw($scale$$constant))); 9631 %} 9632 9633 ins_pipe(ialu_reg_reg_shift); 9634 %} 9635 9636 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9637 match(Set dst (LShiftL (ConvI2L src) scale)); 9638 9639 ins_cost(INSN_COST); 9640 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9641 9642 ins_encode %{ 9643 __ sbfiz(as_Register($dst$$reg), 9644 as_Register($src$$reg), 9645 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 9646 %} 9647 9648 ins_pipe(ialu_reg_shift); 9649 %} 9650 9651 // Pointer Immediate Addition 9652 // n.b. this needs to be more expensive than using an indirect memory 9653 // operand 9654 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9655 match(Set dst (AddP src1 src2)); 9656 9657 ins_cost(INSN_COST); 9658 format %{ "add $dst, $src1, $src2\t# ptr" %} 9659 9660 // use opcode to indicate that this is an add not a sub 9661 opcode(0x0); 9662 9663 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9664 9665 ins_pipe(ialu_reg_imm); 9666 %} 9667 9668 // Long Addition 9669 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9670 9671 match(Set dst (AddL src1 src2)); 9672 9673 ins_cost(INSN_COST); 9674 format %{ "add $dst, $src1, $src2" %} 9675 9676 ins_encode %{ 9677 __ add(as_Register($dst$$reg), 9678 as_Register($src1$$reg), 9679 as_Register($src2$$reg)); 9680 %} 9681 9682 ins_pipe(ialu_reg_reg); 9683 %} 9684 9685 // No constant pool entries requiredLong Immediate Addition. 9686 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9687 match(Set dst (AddL src1 src2)); 9688 9689 ins_cost(INSN_COST); 9690 format %{ "add $dst, $src1, $src2" %} 9691 9692 // use opcode to indicate that this is an add not a sub 9693 opcode(0x0); 9694 9695 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9696 9697 ins_pipe(ialu_reg_imm); 9698 %} 9699 9700 // Integer Subtraction 9701 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9702 match(Set dst (SubI src1 src2)); 9703 9704 ins_cost(INSN_COST); 9705 format %{ "subw $dst, $src1, $src2" %} 9706 9707 ins_encode %{ 9708 __ subw(as_Register($dst$$reg), 9709 as_Register($src1$$reg), 9710 as_Register($src2$$reg)); 9711 %} 9712 9713 ins_pipe(ialu_reg_reg); 9714 %} 9715 9716 // Immediate Subtraction 9717 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9718 match(Set dst (SubI src1 src2)); 9719 9720 ins_cost(INSN_COST); 9721 format %{ "subw $dst, $src1, $src2" %} 9722 9723 // use opcode to indicate that this is a sub not an add 9724 opcode(0x1); 9725 9726 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9727 9728 ins_pipe(ialu_reg_imm); 9729 %} 9730 9731 // Long Subtraction 9732 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9733 9734 match(Set dst (SubL src1 src2)); 9735 9736 ins_cost(INSN_COST); 9737 format %{ "sub $dst, $src1, $src2" %} 9738 9739 ins_encode %{ 9740 __ sub(as_Register($dst$$reg), 9741 as_Register($src1$$reg), 9742 as_Register($src2$$reg)); 9743 %} 9744 9745 ins_pipe(ialu_reg_reg); 9746 %} 9747 9748 // No constant pool entries requiredLong Immediate Subtraction. 9749 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9750 match(Set dst (SubL src1 src2)); 9751 9752 ins_cost(INSN_COST); 9753 format %{ "sub$dst, $src1, $src2" %} 9754 9755 // use opcode to indicate that this is a sub not an add 9756 opcode(0x1); 9757 9758 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9759 9760 ins_pipe(ialu_reg_imm); 9761 %} 9762 9763 // Integer Negation (special case for sub) 9764 9765 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9766 match(Set dst (SubI zero src)); 9767 9768 ins_cost(INSN_COST); 9769 format %{ "negw $dst, $src\t# int" %} 9770 9771 ins_encode %{ 9772 __ negw(as_Register($dst$$reg), 9773 as_Register($src$$reg)); 9774 %} 9775 9776 ins_pipe(ialu_reg); 9777 %} 9778 9779 // Long Negation 9780 9781 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9782 match(Set dst (SubL zero src)); 9783 9784 ins_cost(INSN_COST); 9785 format %{ "neg $dst, $src\t# long" %} 9786 9787 ins_encode %{ 9788 __ neg(as_Register($dst$$reg), 9789 as_Register($src$$reg)); 9790 %} 9791 9792 ins_pipe(ialu_reg); 9793 %} 9794 9795 // Integer Multiply 9796 9797 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9798 match(Set dst (MulI src1 src2)); 9799 9800 ins_cost(INSN_COST * 3); 9801 format %{ "mulw $dst, $src1, $src2" %} 9802 9803 ins_encode %{ 9804 __ mulw(as_Register($dst$$reg), 9805 as_Register($src1$$reg), 9806 as_Register($src2$$reg)); 9807 %} 9808 9809 ins_pipe(imul_reg_reg); 9810 %} 9811 9812 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9813 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9814 9815 ins_cost(INSN_COST * 3); 9816 format %{ "smull $dst, $src1, $src2" %} 9817 9818 ins_encode %{ 9819 __ smull(as_Register($dst$$reg), 9820 as_Register($src1$$reg), 9821 as_Register($src2$$reg)); 9822 %} 9823 9824 ins_pipe(imul_reg_reg); 9825 %} 9826 9827 // Long Multiply 9828 9829 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9830 match(Set dst (MulL src1 src2)); 9831 9832 ins_cost(INSN_COST * 5); 9833 format %{ "mul $dst, $src1, $src2" %} 9834 9835 ins_encode %{ 9836 __ mul(as_Register($dst$$reg), 9837 as_Register($src1$$reg), 9838 as_Register($src2$$reg)); 9839 %} 9840 9841 ins_pipe(lmul_reg_reg); 9842 %} 9843 9844 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9845 %{ 9846 match(Set dst (MulHiL src1 src2)); 9847 9848 ins_cost(INSN_COST * 7); 9849 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9850 9851 ins_encode %{ 9852 __ smulh(as_Register($dst$$reg), 9853 as_Register($src1$$reg), 9854 as_Register($src2$$reg)); 9855 %} 9856 9857 ins_pipe(lmul_reg_reg); 9858 %} 9859 9860 // Combined Integer Multiply & Add/Sub 9861 9862 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9863 match(Set dst (AddI src3 (MulI src1 src2))); 9864 9865 ins_cost(INSN_COST * 3); 9866 format %{ "madd $dst, $src1, $src2, $src3" %} 9867 9868 ins_encode %{ 9869 __ maddw(as_Register($dst$$reg), 9870 as_Register($src1$$reg), 9871 as_Register($src2$$reg), 9872 as_Register($src3$$reg)); 9873 %} 9874 9875 ins_pipe(imac_reg_reg); 9876 %} 9877 9878 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9879 match(Set dst (SubI src3 (MulI src1 src2))); 9880 9881 ins_cost(INSN_COST * 3); 9882 format %{ "msub $dst, $src1, $src2, $src3" %} 9883 9884 ins_encode %{ 9885 __ msubw(as_Register($dst$$reg), 9886 as_Register($src1$$reg), 9887 as_Register($src2$$reg), 9888 as_Register($src3$$reg)); 9889 %} 9890 9891 ins_pipe(imac_reg_reg); 9892 %} 9893 9894 // Combined Long Multiply & Add/Sub 9895 9896 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9897 match(Set dst (AddL src3 (MulL src1 src2))); 9898 9899 ins_cost(INSN_COST * 5); 9900 format %{ "madd $dst, $src1, $src2, $src3" %} 9901 9902 ins_encode %{ 9903 __ madd(as_Register($dst$$reg), 9904 as_Register($src1$$reg), 9905 as_Register($src2$$reg), 9906 as_Register($src3$$reg)); 9907 %} 9908 9909 ins_pipe(lmac_reg_reg); 9910 %} 9911 9912 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9913 match(Set dst (SubL src3 (MulL src1 src2))); 9914 9915 ins_cost(INSN_COST * 5); 9916 format %{ "msub $dst, $src1, $src2, $src3" %} 9917 9918 ins_encode %{ 9919 __ msub(as_Register($dst$$reg), 9920 as_Register($src1$$reg), 9921 as_Register($src2$$reg), 9922 as_Register($src3$$reg)); 9923 %} 9924 9925 ins_pipe(lmac_reg_reg); 9926 %} 9927 9928 // Integer Divide 9929 9930 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9931 match(Set dst (DivI src1 src2)); 9932 9933 ins_cost(INSN_COST * 19); 9934 format %{ "sdivw $dst, $src1, $src2" %} 9935 9936 ins_encode(aarch64_enc_divw(dst, src1, src2)); 9937 ins_pipe(idiv_reg_reg); 9938 %} 9939 9940 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 9941 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 9942 ins_cost(INSN_COST); 9943 format %{ "lsrw $dst, $src1, $div1" %} 9944 ins_encode %{ 9945 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 9946 %} 9947 ins_pipe(ialu_reg_shift); 9948 %} 9949 9950 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 9951 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 9952 ins_cost(INSN_COST); 9953 format %{ "addw $dst, $src, LSR $div1" %} 9954 9955 ins_encode %{ 9956 __ addw(as_Register($dst$$reg), 9957 as_Register($src$$reg), 9958 as_Register($src$$reg), 9959 Assembler::LSR, 31); 9960 %} 9961 ins_pipe(ialu_reg); 9962 %} 9963 9964 // Long Divide 9965 9966 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9967 match(Set dst (DivL src1 src2)); 9968 9969 ins_cost(INSN_COST * 35); 9970 format %{ "sdiv $dst, $src1, $src2" %} 9971 9972 ins_encode(aarch64_enc_div(dst, src1, src2)); 9973 ins_pipe(ldiv_reg_reg); 9974 %} 9975 9976 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 9977 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 9978 ins_cost(INSN_COST); 9979 format %{ "lsr $dst, $src1, $div1" %} 9980 ins_encode %{ 9981 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 9982 %} 9983 ins_pipe(ialu_reg_shift); 9984 %} 9985 9986 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 9987 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 9988 ins_cost(INSN_COST); 9989 format %{ "add $dst, $src, $div1" %} 9990 9991 ins_encode %{ 9992 __ add(as_Register($dst$$reg), 9993 as_Register($src$$reg), 9994 as_Register($src$$reg), 9995 Assembler::LSR, 63); 9996 %} 9997 ins_pipe(ialu_reg); 9998 %} 9999 10000 // Integer Remainder 10001 10002 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10003 match(Set dst (ModI src1 src2)); 10004 10005 ins_cost(INSN_COST * 22); 10006 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10007 "msubw($dst, rscratch1, $src2, $src1" %} 10008 10009 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10010 ins_pipe(idiv_reg_reg); 10011 %} 10012 10013 // Long Remainder 10014 10015 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10016 match(Set dst (ModL src1 src2)); 10017 10018 ins_cost(INSN_COST * 38); 10019 format %{ "sdiv rscratch1, $src1, $src2\n" 10020 "msub($dst, rscratch1, $src2, $src1" %} 10021 10022 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10023 ins_pipe(ldiv_reg_reg); 10024 %} 10025 10026 // Integer Shifts 10027 10028 // Shift Left Register 10029 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10030 match(Set dst (LShiftI src1 src2)); 10031 10032 ins_cost(INSN_COST * 2); 10033 format %{ "lslvw $dst, $src1, $src2" %} 10034 10035 ins_encode %{ 10036 __ lslvw(as_Register($dst$$reg), 10037 as_Register($src1$$reg), 10038 as_Register($src2$$reg)); 10039 %} 10040 10041 ins_pipe(ialu_reg_reg_vshift); 10042 %} 10043 10044 // Shift Left Immediate 10045 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10046 match(Set dst (LShiftI src1 src2)); 10047 10048 ins_cost(INSN_COST); 10049 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10050 10051 ins_encode %{ 10052 __ lslw(as_Register($dst$$reg), 10053 as_Register($src1$$reg), 10054 $src2$$constant & 0x1f); 10055 %} 10056 10057 ins_pipe(ialu_reg_shift); 10058 %} 10059 10060 // Shift Right Logical Register 10061 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10062 match(Set dst (URShiftI src1 src2)); 10063 10064 ins_cost(INSN_COST * 2); 10065 format %{ "lsrvw $dst, $src1, $src2" %} 10066 10067 ins_encode %{ 10068 __ lsrvw(as_Register($dst$$reg), 10069 as_Register($src1$$reg), 10070 as_Register($src2$$reg)); 10071 %} 10072 10073 ins_pipe(ialu_reg_reg_vshift); 10074 %} 10075 10076 // Shift Right Logical Immediate 10077 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10078 match(Set dst (URShiftI src1 src2)); 10079 10080 ins_cost(INSN_COST); 10081 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10082 10083 ins_encode %{ 10084 __ lsrw(as_Register($dst$$reg), 10085 as_Register($src1$$reg), 10086 $src2$$constant & 0x1f); 10087 %} 10088 10089 ins_pipe(ialu_reg_shift); 10090 %} 10091 10092 // Shift Right Arithmetic Register 10093 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10094 match(Set dst (RShiftI src1 src2)); 10095 10096 ins_cost(INSN_COST * 2); 10097 format %{ "asrvw $dst, $src1, $src2" %} 10098 10099 ins_encode %{ 10100 __ asrvw(as_Register($dst$$reg), 10101 as_Register($src1$$reg), 10102 as_Register($src2$$reg)); 10103 %} 10104 10105 ins_pipe(ialu_reg_reg_vshift); 10106 %} 10107 10108 // Shift Right Arithmetic Immediate 10109 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10110 match(Set dst (RShiftI src1 src2)); 10111 10112 ins_cost(INSN_COST); 10113 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10114 10115 ins_encode %{ 10116 __ asrw(as_Register($dst$$reg), 10117 as_Register($src1$$reg), 10118 $src2$$constant & 0x1f); 10119 %} 10120 10121 ins_pipe(ialu_reg_shift); 10122 %} 10123 10124 // Combined Int Mask and Right Shift (using UBFM) 10125 // TODO 10126 10127 // Long Shifts 10128 10129 // Shift Left Register 10130 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10131 match(Set dst (LShiftL src1 src2)); 10132 10133 ins_cost(INSN_COST * 2); 10134 format %{ "lslv $dst, $src1, $src2" %} 10135 10136 ins_encode %{ 10137 __ lslv(as_Register($dst$$reg), 10138 as_Register($src1$$reg), 10139 as_Register($src2$$reg)); 10140 %} 10141 10142 ins_pipe(ialu_reg_reg_vshift); 10143 %} 10144 10145 // Shift Left Immediate 10146 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10147 match(Set dst (LShiftL src1 src2)); 10148 10149 ins_cost(INSN_COST); 10150 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10151 10152 ins_encode %{ 10153 __ lsl(as_Register($dst$$reg), 10154 as_Register($src1$$reg), 10155 $src2$$constant & 0x3f); 10156 %} 10157 10158 ins_pipe(ialu_reg_shift); 10159 %} 10160 10161 // Shift Right Logical Register 10162 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10163 match(Set dst (URShiftL src1 src2)); 10164 10165 ins_cost(INSN_COST * 2); 10166 format %{ "lsrv $dst, $src1, $src2" %} 10167 10168 ins_encode %{ 10169 __ lsrv(as_Register($dst$$reg), 10170 as_Register($src1$$reg), 10171 as_Register($src2$$reg)); 10172 %} 10173 10174 ins_pipe(ialu_reg_reg_vshift); 10175 %} 10176 10177 // Shift Right Logical Immediate 10178 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10179 match(Set dst (URShiftL src1 src2)); 10180 10181 ins_cost(INSN_COST); 10182 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10183 10184 ins_encode %{ 10185 __ lsr(as_Register($dst$$reg), 10186 as_Register($src1$$reg), 10187 $src2$$constant & 0x3f); 10188 %} 10189 10190 ins_pipe(ialu_reg_shift); 10191 %} 10192 10193 // A special-case pattern for card table stores. 10194 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10195 match(Set dst (URShiftL (CastP2X src1) src2)); 10196 10197 ins_cost(INSN_COST); 10198 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10199 10200 ins_encode %{ 10201 __ lsr(as_Register($dst$$reg), 10202 as_Register($src1$$reg), 10203 $src2$$constant & 0x3f); 10204 %} 10205 10206 ins_pipe(ialu_reg_shift); 10207 %} 10208 10209 // Shift Right Arithmetic Register 10210 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10211 match(Set dst (RShiftL src1 src2)); 10212 10213 ins_cost(INSN_COST * 2); 10214 format %{ "asrv $dst, $src1, $src2" %} 10215 10216 ins_encode %{ 10217 __ asrv(as_Register($dst$$reg), 10218 as_Register($src1$$reg), 10219 as_Register($src2$$reg)); 10220 %} 10221 10222 ins_pipe(ialu_reg_reg_vshift); 10223 %} 10224 10225 // Shift Right Arithmetic Immediate 10226 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10227 match(Set dst (RShiftL src1 src2)); 10228 10229 ins_cost(INSN_COST); 10230 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10231 10232 ins_encode %{ 10233 __ asr(as_Register($dst$$reg), 10234 as_Register($src1$$reg), 10235 $src2$$constant & 0x3f); 10236 %} 10237 10238 ins_pipe(ialu_reg_shift); 10239 %} 10240 10241 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10242 10243 instruct regL_not_reg(iRegLNoSp dst, 10244 iRegL src1, immL_M1 m1, 10245 rFlagsReg cr) %{ 10246 match(Set dst (XorL src1 m1)); 10247 ins_cost(INSN_COST); 10248 format %{ "eon $dst, $src1, zr" %} 10249 10250 ins_encode %{ 10251 __ eon(as_Register($dst$$reg), 10252 as_Register($src1$$reg), 10253 zr, 10254 Assembler::LSL, 0); 10255 %} 10256 10257 ins_pipe(ialu_reg); 10258 %} 10259 instruct regI_not_reg(iRegINoSp dst, 10260 iRegIorL2I src1, immI_M1 m1, 10261 rFlagsReg cr) %{ 10262 match(Set dst (XorI src1 m1)); 10263 ins_cost(INSN_COST); 10264 format %{ "eonw $dst, $src1, zr" %} 10265 10266 ins_encode %{ 10267 __ eonw(as_Register($dst$$reg), 10268 as_Register($src1$$reg), 10269 zr, 10270 Assembler::LSL, 0); 10271 %} 10272 10273 ins_pipe(ialu_reg); 10274 %} 10275 10276 instruct AndI_reg_not_reg(iRegINoSp dst, 10277 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10278 rFlagsReg cr) %{ 10279 match(Set dst (AndI src1 (XorI src2 m1))); 10280 ins_cost(INSN_COST); 10281 format %{ "bicw $dst, $src1, $src2" %} 10282 10283 ins_encode %{ 10284 __ bicw(as_Register($dst$$reg), 10285 as_Register($src1$$reg), 10286 as_Register($src2$$reg), 10287 Assembler::LSL, 0); 10288 %} 10289 10290 ins_pipe(ialu_reg_reg); 10291 %} 10292 10293 instruct AndL_reg_not_reg(iRegLNoSp dst, 10294 iRegL src1, iRegL src2, immL_M1 m1, 10295 rFlagsReg cr) %{ 10296 match(Set dst (AndL src1 (XorL src2 m1))); 10297 ins_cost(INSN_COST); 10298 format %{ "bic $dst, $src1, $src2" %} 10299 10300 ins_encode %{ 10301 __ bic(as_Register($dst$$reg), 10302 as_Register($src1$$reg), 10303 as_Register($src2$$reg), 10304 Assembler::LSL, 0); 10305 %} 10306 10307 ins_pipe(ialu_reg_reg); 10308 %} 10309 10310 instruct OrI_reg_not_reg(iRegINoSp dst, 10311 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10312 rFlagsReg cr) %{ 10313 match(Set dst (OrI src1 (XorI src2 m1))); 10314 ins_cost(INSN_COST); 10315 format %{ "ornw $dst, $src1, $src2" %} 10316 10317 ins_encode %{ 10318 __ ornw(as_Register($dst$$reg), 10319 as_Register($src1$$reg), 10320 as_Register($src2$$reg), 10321 Assembler::LSL, 0); 10322 %} 10323 10324 ins_pipe(ialu_reg_reg); 10325 %} 10326 10327 instruct OrL_reg_not_reg(iRegLNoSp dst, 10328 iRegL src1, iRegL src2, immL_M1 m1, 10329 rFlagsReg cr) %{ 10330 match(Set dst (OrL src1 (XorL src2 m1))); 10331 ins_cost(INSN_COST); 10332 format %{ "orn $dst, $src1, $src2" %} 10333 10334 ins_encode %{ 10335 __ orn(as_Register($dst$$reg), 10336 as_Register($src1$$reg), 10337 as_Register($src2$$reg), 10338 Assembler::LSL, 0); 10339 %} 10340 10341 ins_pipe(ialu_reg_reg); 10342 %} 10343 10344 instruct XorI_reg_not_reg(iRegINoSp dst, 10345 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10346 rFlagsReg cr) %{ 10347 match(Set dst (XorI m1 (XorI src2 src1))); 10348 ins_cost(INSN_COST); 10349 format %{ "eonw $dst, $src1, $src2" %} 10350 10351 ins_encode %{ 10352 __ eonw(as_Register($dst$$reg), 10353 as_Register($src1$$reg), 10354 as_Register($src2$$reg), 10355 Assembler::LSL, 0); 10356 %} 10357 10358 ins_pipe(ialu_reg_reg); 10359 %} 10360 10361 instruct XorL_reg_not_reg(iRegLNoSp dst, 10362 iRegL src1, iRegL src2, immL_M1 m1, 10363 rFlagsReg cr) %{ 10364 match(Set dst (XorL m1 (XorL src2 src1))); 10365 ins_cost(INSN_COST); 10366 format %{ "eon $dst, $src1, $src2" %} 10367 10368 ins_encode %{ 10369 __ eon(as_Register($dst$$reg), 10370 as_Register($src1$$reg), 10371 as_Register($src2$$reg), 10372 Assembler::LSL, 0); 10373 %} 10374 10375 ins_pipe(ialu_reg_reg); 10376 %} 10377 10378 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10379 iRegIorL2I src1, iRegIorL2I src2, 10380 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10381 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10382 ins_cost(1.9 * INSN_COST); 10383 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10384 10385 ins_encode %{ 10386 __ bicw(as_Register($dst$$reg), 10387 as_Register($src1$$reg), 10388 as_Register($src2$$reg), 10389 Assembler::LSR, 10390 $src3$$constant & 0x1f); 10391 %} 10392 10393 ins_pipe(ialu_reg_reg_shift); 10394 %} 10395 10396 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10397 iRegL src1, iRegL src2, 10398 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10399 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10400 ins_cost(1.9 * INSN_COST); 10401 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10402 10403 ins_encode %{ 10404 __ bic(as_Register($dst$$reg), 10405 as_Register($src1$$reg), 10406 as_Register($src2$$reg), 10407 Assembler::LSR, 10408 $src3$$constant & 0x3f); 10409 %} 10410 10411 ins_pipe(ialu_reg_reg_shift); 10412 %} 10413 10414 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10415 iRegIorL2I src1, iRegIorL2I src2, 10416 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10417 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10418 ins_cost(1.9 * INSN_COST); 10419 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10420 10421 ins_encode %{ 10422 __ bicw(as_Register($dst$$reg), 10423 as_Register($src1$$reg), 10424 as_Register($src2$$reg), 10425 Assembler::ASR, 10426 $src3$$constant & 0x1f); 10427 %} 10428 10429 ins_pipe(ialu_reg_reg_shift); 10430 %} 10431 10432 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10433 iRegL src1, iRegL src2, 10434 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10435 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10436 ins_cost(1.9 * INSN_COST); 10437 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10438 10439 ins_encode %{ 10440 __ bic(as_Register($dst$$reg), 10441 as_Register($src1$$reg), 10442 as_Register($src2$$reg), 10443 Assembler::ASR, 10444 $src3$$constant & 0x3f); 10445 %} 10446 10447 ins_pipe(ialu_reg_reg_shift); 10448 %} 10449 10450 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10451 iRegIorL2I src1, iRegIorL2I src2, 10452 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10453 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10454 ins_cost(1.9 * INSN_COST); 10455 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10456 10457 ins_encode %{ 10458 __ bicw(as_Register($dst$$reg), 10459 as_Register($src1$$reg), 10460 as_Register($src2$$reg), 10461 Assembler::LSL, 10462 $src3$$constant & 0x1f); 10463 %} 10464 10465 ins_pipe(ialu_reg_reg_shift); 10466 %} 10467 10468 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10469 iRegL src1, iRegL src2, 10470 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10471 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10472 ins_cost(1.9 * INSN_COST); 10473 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10474 10475 ins_encode %{ 10476 __ bic(as_Register($dst$$reg), 10477 as_Register($src1$$reg), 10478 as_Register($src2$$reg), 10479 Assembler::LSL, 10480 $src3$$constant & 0x3f); 10481 %} 10482 10483 ins_pipe(ialu_reg_reg_shift); 10484 %} 10485 10486 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10487 iRegIorL2I src1, iRegIorL2I src2, 10488 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10489 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10490 ins_cost(1.9 * INSN_COST); 10491 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10492 10493 ins_encode %{ 10494 __ eonw(as_Register($dst$$reg), 10495 as_Register($src1$$reg), 10496 as_Register($src2$$reg), 10497 Assembler::LSR, 10498 $src3$$constant & 0x1f); 10499 %} 10500 10501 ins_pipe(ialu_reg_reg_shift); 10502 %} 10503 10504 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10505 iRegL src1, iRegL src2, 10506 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10507 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10508 ins_cost(1.9 * INSN_COST); 10509 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10510 10511 ins_encode %{ 10512 __ eon(as_Register($dst$$reg), 10513 as_Register($src1$$reg), 10514 as_Register($src2$$reg), 10515 Assembler::LSR, 10516 $src3$$constant & 0x3f); 10517 %} 10518 10519 ins_pipe(ialu_reg_reg_shift); 10520 %} 10521 10522 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10523 iRegIorL2I src1, iRegIorL2I src2, 10524 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10525 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10526 ins_cost(1.9 * INSN_COST); 10527 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10528 10529 ins_encode %{ 10530 __ eonw(as_Register($dst$$reg), 10531 as_Register($src1$$reg), 10532 as_Register($src2$$reg), 10533 Assembler::ASR, 10534 $src3$$constant & 0x1f); 10535 %} 10536 10537 ins_pipe(ialu_reg_reg_shift); 10538 %} 10539 10540 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10541 iRegL src1, iRegL src2, 10542 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10543 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10544 ins_cost(1.9 * INSN_COST); 10545 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10546 10547 ins_encode %{ 10548 __ eon(as_Register($dst$$reg), 10549 as_Register($src1$$reg), 10550 as_Register($src2$$reg), 10551 Assembler::ASR, 10552 $src3$$constant & 0x3f); 10553 %} 10554 10555 ins_pipe(ialu_reg_reg_shift); 10556 %} 10557 10558 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10559 iRegIorL2I src1, iRegIorL2I src2, 10560 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10561 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10562 ins_cost(1.9 * INSN_COST); 10563 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10564 10565 ins_encode %{ 10566 __ eonw(as_Register($dst$$reg), 10567 as_Register($src1$$reg), 10568 as_Register($src2$$reg), 10569 Assembler::LSL, 10570 $src3$$constant & 0x1f); 10571 %} 10572 10573 ins_pipe(ialu_reg_reg_shift); 10574 %} 10575 10576 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10577 iRegL src1, iRegL src2, 10578 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10579 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10580 ins_cost(1.9 * INSN_COST); 10581 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10582 10583 ins_encode %{ 10584 __ eon(as_Register($dst$$reg), 10585 as_Register($src1$$reg), 10586 as_Register($src2$$reg), 10587 Assembler::LSL, 10588 $src3$$constant & 0x3f); 10589 %} 10590 10591 ins_pipe(ialu_reg_reg_shift); 10592 %} 10593 10594 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10595 iRegIorL2I src1, iRegIorL2I src2, 10596 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10597 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10598 ins_cost(1.9 * INSN_COST); 10599 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10600 10601 ins_encode %{ 10602 __ ornw(as_Register($dst$$reg), 10603 as_Register($src1$$reg), 10604 as_Register($src2$$reg), 10605 Assembler::LSR, 10606 $src3$$constant & 0x1f); 10607 %} 10608 10609 ins_pipe(ialu_reg_reg_shift); 10610 %} 10611 10612 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10613 iRegL src1, iRegL src2, 10614 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10615 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10616 ins_cost(1.9 * INSN_COST); 10617 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10618 10619 ins_encode %{ 10620 __ orn(as_Register($dst$$reg), 10621 as_Register($src1$$reg), 10622 as_Register($src2$$reg), 10623 Assembler::LSR, 10624 $src3$$constant & 0x3f); 10625 %} 10626 10627 ins_pipe(ialu_reg_reg_shift); 10628 %} 10629 10630 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10631 iRegIorL2I src1, iRegIorL2I src2, 10632 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10633 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10634 ins_cost(1.9 * INSN_COST); 10635 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10636 10637 ins_encode %{ 10638 __ ornw(as_Register($dst$$reg), 10639 as_Register($src1$$reg), 10640 as_Register($src2$$reg), 10641 Assembler::ASR, 10642 $src3$$constant & 0x1f); 10643 %} 10644 10645 ins_pipe(ialu_reg_reg_shift); 10646 %} 10647 10648 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10649 iRegL src1, iRegL src2, 10650 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10651 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10652 ins_cost(1.9 * INSN_COST); 10653 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10654 10655 ins_encode %{ 10656 __ orn(as_Register($dst$$reg), 10657 as_Register($src1$$reg), 10658 as_Register($src2$$reg), 10659 Assembler::ASR, 10660 $src3$$constant & 0x3f); 10661 %} 10662 10663 ins_pipe(ialu_reg_reg_shift); 10664 %} 10665 10666 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10667 iRegIorL2I src1, iRegIorL2I src2, 10668 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10669 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10670 ins_cost(1.9 * INSN_COST); 10671 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10672 10673 ins_encode %{ 10674 __ ornw(as_Register($dst$$reg), 10675 as_Register($src1$$reg), 10676 as_Register($src2$$reg), 10677 Assembler::LSL, 10678 $src3$$constant & 0x1f); 10679 %} 10680 10681 ins_pipe(ialu_reg_reg_shift); 10682 %} 10683 10684 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10685 iRegL src1, iRegL src2, 10686 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10687 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10688 ins_cost(1.9 * INSN_COST); 10689 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10690 10691 ins_encode %{ 10692 __ orn(as_Register($dst$$reg), 10693 as_Register($src1$$reg), 10694 as_Register($src2$$reg), 10695 Assembler::LSL, 10696 $src3$$constant & 0x3f); 10697 %} 10698 10699 ins_pipe(ialu_reg_reg_shift); 10700 %} 10701 10702 instruct AndI_reg_URShift_reg(iRegINoSp dst, 10703 iRegIorL2I src1, iRegIorL2I src2, 10704 immI src3, rFlagsReg cr) %{ 10705 match(Set dst (AndI src1 (URShiftI src2 src3))); 10706 10707 ins_cost(1.9 * INSN_COST); 10708 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10709 10710 ins_encode %{ 10711 __ andw(as_Register($dst$$reg), 10712 as_Register($src1$$reg), 10713 as_Register($src2$$reg), 10714 Assembler::LSR, 10715 $src3$$constant & 0x1f); 10716 %} 10717 10718 ins_pipe(ialu_reg_reg_shift); 10719 %} 10720 10721 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 10722 iRegL src1, iRegL src2, 10723 immI src3, rFlagsReg cr) %{ 10724 match(Set dst (AndL src1 (URShiftL src2 src3))); 10725 10726 ins_cost(1.9 * INSN_COST); 10727 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10728 10729 ins_encode %{ 10730 __ andr(as_Register($dst$$reg), 10731 as_Register($src1$$reg), 10732 as_Register($src2$$reg), 10733 Assembler::LSR, 10734 $src3$$constant & 0x3f); 10735 %} 10736 10737 ins_pipe(ialu_reg_reg_shift); 10738 %} 10739 10740 instruct AndI_reg_RShift_reg(iRegINoSp dst, 10741 iRegIorL2I src1, iRegIorL2I src2, 10742 immI src3, rFlagsReg cr) %{ 10743 match(Set dst (AndI src1 (RShiftI src2 src3))); 10744 10745 ins_cost(1.9 * INSN_COST); 10746 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10747 10748 ins_encode %{ 10749 __ andw(as_Register($dst$$reg), 10750 as_Register($src1$$reg), 10751 as_Register($src2$$reg), 10752 Assembler::ASR, 10753 $src3$$constant & 0x1f); 10754 %} 10755 10756 ins_pipe(ialu_reg_reg_shift); 10757 %} 10758 10759 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10760 iRegL src1, iRegL src2, 10761 immI src3, rFlagsReg cr) %{ 10762 match(Set dst (AndL src1 (RShiftL src2 src3))); 10763 10764 ins_cost(1.9 * INSN_COST); 10765 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10766 10767 ins_encode %{ 10768 __ andr(as_Register($dst$$reg), 10769 as_Register($src1$$reg), 10770 as_Register($src2$$reg), 10771 Assembler::ASR, 10772 $src3$$constant & 0x3f); 10773 %} 10774 10775 ins_pipe(ialu_reg_reg_shift); 10776 %} 10777 10778 instruct AndI_reg_LShift_reg(iRegINoSp dst, 10779 iRegIorL2I src1, iRegIorL2I src2, 10780 immI src3, rFlagsReg cr) %{ 10781 match(Set dst (AndI src1 (LShiftI src2 src3))); 10782 10783 ins_cost(1.9 * INSN_COST); 10784 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10785 10786 ins_encode %{ 10787 __ andw(as_Register($dst$$reg), 10788 as_Register($src1$$reg), 10789 as_Register($src2$$reg), 10790 Assembler::LSL, 10791 $src3$$constant & 0x1f); 10792 %} 10793 10794 ins_pipe(ialu_reg_reg_shift); 10795 %} 10796 10797 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10798 iRegL src1, iRegL src2, 10799 immI src3, rFlagsReg cr) %{ 10800 match(Set dst (AndL src1 (LShiftL src2 src3))); 10801 10802 ins_cost(1.9 * INSN_COST); 10803 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10804 10805 ins_encode %{ 10806 __ andr(as_Register($dst$$reg), 10807 as_Register($src1$$reg), 10808 as_Register($src2$$reg), 10809 Assembler::LSL, 10810 $src3$$constant & 0x3f); 10811 %} 10812 10813 ins_pipe(ialu_reg_reg_shift); 10814 %} 10815 10816 instruct XorI_reg_URShift_reg(iRegINoSp dst, 10817 iRegIorL2I src1, iRegIorL2I src2, 10818 immI src3, rFlagsReg cr) %{ 10819 match(Set dst (XorI src1 (URShiftI src2 src3))); 10820 10821 ins_cost(1.9 * INSN_COST); 10822 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10823 10824 ins_encode %{ 10825 __ eorw(as_Register($dst$$reg), 10826 as_Register($src1$$reg), 10827 as_Register($src2$$reg), 10828 Assembler::LSR, 10829 $src3$$constant & 0x1f); 10830 %} 10831 10832 ins_pipe(ialu_reg_reg_shift); 10833 %} 10834 10835 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10836 iRegL src1, iRegL src2, 10837 immI src3, rFlagsReg cr) %{ 10838 match(Set dst (XorL src1 (URShiftL src2 src3))); 10839 10840 ins_cost(1.9 * INSN_COST); 10841 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10842 10843 ins_encode %{ 10844 __ eor(as_Register($dst$$reg), 10845 as_Register($src1$$reg), 10846 as_Register($src2$$reg), 10847 Assembler::LSR, 10848 $src3$$constant & 0x3f); 10849 %} 10850 10851 ins_pipe(ialu_reg_reg_shift); 10852 %} 10853 10854 instruct XorI_reg_RShift_reg(iRegINoSp dst, 10855 iRegIorL2I src1, iRegIorL2I src2, 10856 immI src3, rFlagsReg cr) %{ 10857 match(Set dst (XorI src1 (RShiftI src2 src3))); 10858 10859 ins_cost(1.9 * INSN_COST); 10860 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10861 10862 ins_encode %{ 10863 __ eorw(as_Register($dst$$reg), 10864 as_Register($src1$$reg), 10865 as_Register($src2$$reg), 10866 Assembler::ASR, 10867 $src3$$constant & 0x1f); 10868 %} 10869 10870 ins_pipe(ialu_reg_reg_shift); 10871 %} 10872 10873 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10874 iRegL src1, iRegL src2, 10875 immI src3, rFlagsReg cr) %{ 10876 match(Set dst (XorL src1 (RShiftL src2 src3))); 10877 10878 ins_cost(1.9 * INSN_COST); 10879 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10880 10881 ins_encode %{ 10882 __ eor(as_Register($dst$$reg), 10883 as_Register($src1$$reg), 10884 as_Register($src2$$reg), 10885 Assembler::ASR, 10886 $src3$$constant & 0x3f); 10887 %} 10888 10889 ins_pipe(ialu_reg_reg_shift); 10890 %} 10891 10892 instruct XorI_reg_LShift_reg(iRegINoSp dst, 10893 iRegIorL2I src1, iRegIorL2I src2, 10894 immI src3, rFlagsReg cr) %{ 10895 match(Set dst (XorI src1 (LShiftI src2 src3))); 10896 10897 ins_cost(1.9 * INSN_COST); 10898 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10899 10900 ins_encode %{ 10901 __ eorw(as_Register($dst$$reg), 10902 as_Register($src1$$reg), 10903 as_Register($src2$$reg), 10904 Assembler::LSL, 10905 $src3$$constant & 0x1f); 10906 %} 10907 10908 ins_pipe(ialu_reg_reg_shift); 10909 %} 10910 10911 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 10912 iRegL src1, iRegL src2, 10913 immI src3, rFlagsReg cr) %{ 10914 match(Set dst (XorL src1 (LShiftL src2 src3))); 10915 10916 ins_cost(1.9 * INSN_COST); 10917 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 10918 10919 ins_encode %{ 10920 __ eor(as_Register($dst$$reg), 10921 as_Register($src1$$reg), 10922 as_Register($src2$$reg), 10923 Assembler::LSL, 10924 $src3$$constant & 0x3f); 10925 %} 10926 10927 ins_pipe(ialu_reg_reg_shift); 10928 %} 10929 10930 instruct OrI_reg_URShift_reg(iRegINoSp dst, 10931 iRegIorL2I src1, iRegIorL2I src2, 10932 immI src3, rFlagsReg cr) %{ 10933 match(Set dst (OrI src1 (URShiftI src2 src3))); 10934 10935 ins_cost(1.9 * INSN_COST); 10936 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 10937 10938 ins_encode %{ 10939 __ orrw(as_Register($dst$$reg), 10940 as_Register($src1$$reg), 10941 as_Register($src2$$reg), 10942 Assembler::LSR, 10943 $src3$$constant & 0x1f); 10944 %} 10945 10946 ins_pipe(ialu_reg_reg_shift); 10947 %} 10948 10949 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 10950 iRegL src1, iRegL src2, 10951 immI src3, rFlagsReg cr) %{ 10952 match(Set dst (OrL src1 (URShiftL src2 src3))); 10953 10954 ins_cost(1.9 * INSN_COST); 10955 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 10956 10957 ins_encode %{ 10958 __ orr(as_Register($dst$$reg), 10959 as_Register($src1$$reg), 10960 as_Register($src2$$reg), 10961 Assembler::LSR, 10962 $src3$$constant & 0x3f); 10963 %} 10964 10965 ins_pipe(ialu_reg_reg_shift); 10966 %} 10967 10968 instruct OrI_reg_RShift_reg(iRegINoSp dst, 10969 iRegIorL2I src1, iRegIorL2I src2, 10970 immI src3, rFlagsReg cr) %{ 10971 match(Set dst (OrI src1 (RShiftI src2 src3))); 10972 10973 ins_cost(1.9 * INSN_COST); 10974 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 10975 10976 ins_encode %{ 10977 __ orrw(as_Register($dst$$reg), 10978 as_Register($src1$$reg), 10979 as_Register($src2$$reg), 10980 Assembler::ASR, 10981 $src3$$constant & 0x1f); 10982 %} 10983 10984 ins_pipe(ialu_reg_reg_shift); 10985 %} 10986 10987 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 10988 iRegL src1, iRegL src2, 10989 immI src3, rFlagsReg cr) %{ 10990 match(Set dst (OrL src1 (RShiftL src2 src3))); 10991 10992 ins_cost(1.9 * INSN_COST); 10993 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 10994 10995 ins_encode %{ 10996 __ orr(as_Register($dst$$reg), 10997 as_Register($src1$$reg), 10998 as_Register($src2$$reg), 10999 Assembler::ASR, 11000 $src3$$constant & 0x3f); 11001 %} 11002 11003 ins_pipe(ialu_reg_reg_shift); 11004 %} 11005 11006 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11007 iRegIorL2I src1, iRegIorL2I src2, 11008 immI src3, rFlagsReg cr) %{ 11009 match(Set dst (OrI src1 (LShiftI src2 src3))); 11010 11011 ins_cost(1.9 * INSN_COST); 11012 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11013 11014 ins_encode %{ 11015 __ orrw(as_Register($dst$$reg), 11016 as_Register($src1$$reg), 11017 as_Register($src2$$reg), 11018 Assembler::LSL, 11019 $src3$$constant & 0x1f); 11020 %} 11021 11022 ins_pipe(ialu_reg_reg_shift); 11023 %} 11024 11025 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11026 iRegL src1, iRegL src2, 11027 immI src3, rFlagsReg cr) %{ 11028 match(Set dst (OrL src1 (LShiftL src2 src3))); 11029 11030 ins_cost(1.9 * INSN_COST); 11031 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11032 11033 ins_encode %{ 11034 __ orr(as_Register($dst$$reg), 11035 as_Register($src1$$reg), 11036 as_Register($src2$$reg), 11037 Assembler::LSL, 11038 $src3$$constant & 0x3f); 11039 %} 11040 11041 ins_pipe(ialu_reg_reg_shift); 11042 %} 11043 11044 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11045 iRegIorL2I src1, iRegIorL2I src2, 11046 immI src3, rFlagsReg cr) %{ 11047 match(Set dst (AddI src1 (URShiftI src2 src3))); 11048 11049 ins_cost(1.9 * INSN_COST); 11050 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11051 11052 ins_encode %{ 11053 __ addw(as_Register($dst$$reg), 11054 as_Register($src1$$reg), 11055 as_Register($src2$$reg), 11056 Assembler::LSR, 11057 $src3$$constant & 0x1f); 11058 %} 11059 11060 ins_pipe(ialu_reg_reg_shift); 11061 %} 11062 11063 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11064 iRegL src1, iRegL src2, 11065 immI src3, rFlagsReg cr) %{ 11066 match(Set dst (AddL src1 (URShiftL src2 src3))); 11067 11068 ins_cost(1.9 * INSN_COST); 11069 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11070 11071 ins_encode %{ 11072 __ add(as_Register($dst$$reg), 11073 as_Register($src1$$reg), 11074 as_Register($src2$$reg), 11075 Assembler::LSR, 11076 $src3$$constant & 0x3f); 11077 %} 11078 11079 ins_pipe(ialu_reg_reg_shift); 11080 %} 11081 11082 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11083 iRegIorL2I src1, iRegIorL2I src2, 11084 immI src3, rFlagsReg cr) %{ 11085 match(Set dst (AddI src1 (RShiftI src2 src3))); 11086 11087 ins_cost(1.9 * INSN_COST); 11088 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11089 11090 ins_encode %{ 11091 __ addw(as_Register($dst$$reg), 11092 as_Register($src1$$reg), 11093 as_Register($src2$$reg), 11094 Assembler::ASR, 11095 $src3$$constant & 0x1f); 11096 %} 11097 11098 ins_pipe(ialu_reg_reg_shift); 11099 %} 11100 11101 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11102 iRegL src1, iRegL src2, 11103 immI src3, rFlagsReg cr) %{ 11104 match(Set dst (AddL src1 (RShiftL src2 src3))); 11105 11106 ins_cost(1.9 * INSN_COST); 11107 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11108 11109 ins_encode %{ 11110 __ add(as_Register($dst$$reg), 11111 as_Register($src1$$reg), 11112 as_Register($src2$$reg), 11113 Assembler::ASR, 11114 $src3$$constant & 0x3f); 11115 %} 11116 11117 ins_pipe(ialu_reg_reg_shift); 11118 %} 11119 11120 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11121 iRegIorL2I src1, iRegIorL2I src2, 11122 immI src3, rFlagsReg cr) %{ 11123 match(Set dst (AddI src1 (LShiftI src2 src3))); 11124 11125 ins_cost(1.9 * INSN_COST); 11126 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11127 11128 ins_encode %{ 11129 __ addw(as_Register($dst$$reg), 11130 as_Register($src1$$reg), 11131 as_Register($src2$$reg), 11132 Assembler::LSL, 11133 $src3$$constant & 0x1f); 11134 %} 11135 11136 ins_pipe(ialu_reg_reg_shift); 11137 %} 11138 11139 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11140 iRegL src1, iRegL src2, 11141 immI src3, rFlagsReg cr) %{ 11142 match(Set dst (AddL src1 (LShiftL src2 src3))); 11143 11144 ins_cost(1.9 * INSN_COST); 11145 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11146 11147 ins_encode %{ 11148 __ add(as_Register($dst$$reg), 11149 as_Register($src1$$reg), 11150 as_Register($src2$$reg), 11151 Assembler::LSL, 11152 $src3$$constant & 0x3f); 11153 %} 11154 11155 ins_pipe(ialu_reg_reg_shift); 11156 %} 11157 11158 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11159 iRegIorL2I src1, iRegIorL2I src2, 11160 immI src3, rFlagsReg cr) %{ 11161 match(Set dst (SubI src1 (URShiftI src2 src3))); 11162 11163 ins_cost(1.9 * INSN_COST); 11164 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11165 11166 ins_encode %{ 11167 __ subw(as_Register($dst$$reg), 11168 as_Register($src1$$reg), 11169 as_Register($src2$$reg), 11170 Assembler::LSR, 11171 $src3$$constant & 0x1f); 11172 %} 11173 11174 ins_pipe(ialu_reg_reg_shift); 11175 %} 11176 11177 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11178 iRegL src1, iRegL src2, 11179 immI src3, rFlagsReg cr) %{ 11180 match(Set dst (SubL src1 (URShiftL src2 src3))); 11181 11182 ins_cost(1.9 * INSN_COST); 11183 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11184 11185 ins_encode %{ 11186 __ sub(as_Register($dst$$reg), 11187 as_Register($src1$$reg), 11188 as_Register($src2$$reg), 11189 Assembler::LSR, 11190 $src3$$constant & 0x3f); 11191 %} 11192 11193 ins_pipe(ialu_reg_reg_shift); 11194 %} 11195 11196 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11197 iRegIorL2I src1, iRegIorL2I src2, 11198 immI src3, rFlagsReg cr) %{ 11199 match(Set dst (SubI src1 (RShiftI src2 src3))); 11200 11201 ins_cost(1.9 * INSN_COST); 11202 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11203 11204 ins_encode %{ 11205 __ subw(as_Register($dst$$reg), 11206 as_Register($src1$$reg), 11207 as_Register($src2$$reg), 11208 Assembler::ASR, 11209 $src3$$constant & 0x1f); 11210 %} 11211 11212 ins_pipe(ialu_reg_reg_shift); 11213 %} 11214 11215 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11216 iRegL src1, iRegL src2, 11217 immI src3, rFlagsReg cr) %{ 11218 match(Set dst (SubL src1 (RShiftL src2 src3))); 11219 11220 ins_cost(1.9 * INSN_COST); 11221 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11222 11223 ins_encode %{ 11224 __ sub(as_Register($dst$$reg), 11225 as_Register($src1$$reg), 11226 as_Register($src2$$reg), 11227 Assembler::ASR, 11228 $src3$$constant & 0x3f); 11229 %} 11230 11231 ins_pipe(ialu_reg_reg_shift); 11232 %} 11233 11234 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11235 iRegIorL2I src1, iRegIorL2I src2, 11236 immI src3, rFlagsReg cr) %{ 11237 match(Set dst (SubI src1 (LShiftI src2 src3))); 11238 11239 ins_cost(1.9 * INSN_COST); 11240 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11241 11242 ins_encode %{ 11243 __ subw(as_Register($dst$$reg), 11244 as_Register($src1$$reg), 11245 as_Register($src2$$reg), 11246 Assembler::LSL, 11247 $src3$$constant & 0x1f); 11248 %} 11249 11250 ins_pipe(ialu_reg_reg_shift); 11251 %} 11252 11253 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11254 iRegL src1, iRegL src2, 11255 immI src3, rFlagsReg cr) %{ 11256 match(Set dst (SubL src1 (LShiftL src2 src3))); 11257 11258 ins_cost(1.9 * INSN_COST); 11259 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11260 11261 ins_encode %{ 11262 __ sub(as_Register($dst$$reg), 11263 as_Register($src1$$reg), 11264 as_Register($src2$$reg), 11265 Assembler::LSL, 11266 $src3$$constant & 0x3f); 11267 %} 11268 11269 ins_pipe(ialu_reg_reg_shift); 11270 %} 11271 11272 11273 11274 // Shift Left followed by Shift Right. 11275 // This idiom is used by the compiler for the i2b bytecode etc. 11276 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11277 %{ 11278 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11279 // Make sure we are not going to exceed what sbfm can do. 11280 predicate((unsigned int)n->in(2)->get_int() <= 63 11281 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11282 11283 ins_cost(INSN_COST * 2); 11284 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11285 ins_encode %{ 11286 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11287 int s = 63 - lshift; 11288 int r = (rshift - lshift) & 63; 11289 __ sbfm(as_Register($dst$$reg), 11290 as_Register($src$$reg), 11291 r, s); 11292 %} 11293 11294 ins_pipe(ialu_reg_shift); 11295 %} 11296 11297 // Shift Left followed by Shift Right. 11298 // This idiom is used by the compiler for the i2b bytecode etc. 11299 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11300 %{ 11301 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11302 // Make sure we are not going to exceed what sbfmw can do. 11303 predicate((unsigned int)n->in(2)->get_int() <= 31 11304 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11305 11306 ins_cost(INSN_COST * 2); 11307 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11308 ins_encode %{ 11309 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11310 int s = 31 - lshift; 11311 int r = (rshift - lshift) & 31; 11312 __ sbfmw(as_Register($dst$$reg), 11313 as_Register($src$$reg), 11314 r, s); 11315 %} 11316 11317 ins_pipe(ialu_reg_shift); 11318 %} 11319 11320 // Shift Left followed by Shift Right. 11321 // This idiom is used by the compiler for the i2b bytecode etc. 11322 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11323 %{ 11324 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11325 // Make sure we are not going to exceed what ubfm can do. 11326 predicate((unsigned int)n->in(2)->get_int() <= 63 11327 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11328 11329 ins_cost(INSN_COST * 2); 11330 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11331 ins_encode %{ 11332 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11333 int s = 63 - lshift; 11334 int r = (rshift - lshift) & 63; 11335 __ ubfm(as_Register($dst$$reg), 11336 as_Register($src$$reg), 11337 r, s); 11338 %} 11339 11340 ins_pipe(ialu_reg_shift); 11341 %} 11342 11343 // Shift Left followed by Shift Right. 11344 // This idiom is used by the compiler for the i2b bytecode etc. 11345 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11346 %{ 11347 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11348 // Make sure we are not going to exceed what ubfmw can do. 11349 predicate((unsigned int)n->in(2)->get_int() <= 31 11350 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11351 11352 ins_cost(INSN_COST * 2); 11353 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11354 ins_encode %{ 11355 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11356 int s = 31 - lshift; 11357 int r = (rshift - lshift) & 31; 11358 __ ubfmw(as_Register($dst$$reg), 11359 as_Register($src$$reg), 11360 r, s); 11361 %} 11362 11363 ins_pipe(ialu_reg_shift); 11364 %} 11365 // Bitfield extract with shift & mask 11366 11367 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11368 %{ 11369 match(Set dst (AndI (URShiftI src rshift) mask)); 11370 11371 ins_cost(INSN_COST); 11372 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11373 ins_encode %{ 11374 int rshift = $rshift$$constant; 11375 long mask = $mask$$constant; 11376 int width = exact_log2(mask+1); 11377 __ ubfxw(as_Register($dst$$reg), 11378 as_Register($src$$reg), rshift, width); 11379 %} 11380 ins_pipe(ialu_reg_shift); 11381 %} 11382 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11383 %{ 11384 match(Set dst (AndL (URShiftL src rshift) mask)); 11385 11386 ins_cost(INSN_COST); 11387 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11388 ins_encode %{ 11389 int rshift = $rshift$$constant; 11390 long mask = $mask$$constant; 11391 int width = exact_log2(mask+1); 11392 __ ubfx(as_Register($dst$$reg), 11393 as_Register($src$$reg), rshift, width); 11394 %} 11395 ins_pipe(ialu_reg_shift); 11396 %} 11397 11398 // We can use ubfx when extending an And with a mask when we know mask 11399 // is positive. We know that because immI_bitmask guarantees it. 11400 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11401 %{ 11402 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11403 11404 ins_cost(INSN_COST * 2); 11405 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11406 ins_encode %{ 11407 int rshift = $rshift$$constant; 11408 long mask = $mask$$constant; 11409 int width = exact_log2(mask+1); 11410 __ ubfx(as_Register($dst$$reg), 11411 as_Register($src$$reg), rshift, width); 11412 %} 11413 ins_pipe(ialu_reg_shift); 11414 %} 11415 11416 // We can use ubfiz when masking by a positive number and then left shifting the result. 11417 // We know that the mask is positive because immI_bitmask guarantees it. 11418 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11419 %{ 11420 match(Set dst (LShiftI (AndI src mask) lshift)); 11421 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11422 (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1)); 11423 11424 ins_cost(INSN_COST); 11425 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11426 ins_encode %{ 11427 int lshift = $lshift$$constant; 11428 long mask = $mask$$constant; 11429 int width = exact_log2(mask+1); 11430 __ ubfizw(as_Register($dst$$reg), 11431 as_Register($src$$reg), lshift, width); 11432 %} 11433 ins_pipe(ialu_reg_shift); 11434 %} 11435 // We can use ubfiz when masking by a positive number and then left shifting the result. 11436 // We know that the mask is positive because immL_bitmask guarantees it. 11437 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11438 %{ 11439 match(Set dst (LShiftL (AndL src mask) lshift)); 11440 predicate((unsigned int)n->in(2)->get_int() <= 63 && 11441 (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1)); 11442 11443 ins_cost(INSN_COST); 11444 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11445 ins_encode %{ 11446 int lshift = $lshift$$constant; 11447 long mask = $mask$$constant; 11448 int width = exact_log2(mask+1); 11449 __ ubfiz(as_Register($dst$$reg), 11450 as_Register($src$$reg), lshift, width); 11451 %} 11452 ins_pipe(ialu_reg_shift); 11453 %} 11454 11455 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11456 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11457 %{ 11458 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); 11459 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11460 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); 11461 11462 ins_cost(INSN_COST); 11463 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11464 ins_encode %{ 11465 int lshift = $lshift$$constant; 11466 long mask = $mask$$constant; 11467 int width = exact_log2(mask+1); 11468 __ ubfiz(as_Register($dst$$reg), 11469 as_Register($src$$reg), lshift, width); 11470 %} 11471 ins_pipe(ialu_reg_shift); 11472 %} 11473 11474 // Rotations 11475 11476 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11477 %{ 11478 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11479 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11480 11481 ins_cost(INSN_COST); 11482 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11483 11484 ins_encode %{ 11485 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11486 $rshift$$constant & 63); 11487 %} 11488 ins_pipe(ialu_reg_reg_extr); 11489 %} 11490 11491 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11492 %{ 11493 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11494 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11495 11496 ins_cost(INSN_COST); 11497 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11498 11499 ins_encode %{ 11500 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11501 $rshift$$constant & 31); 11502 %} 11503 ins_pipe(ialu_reg_reg_extr); 11504 %} 11505 11506 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11507 %{ 11508 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11509 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11510 11511 ins_cost(INSN_COST); 11512 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11513 11514 ins_encode %{ 11515 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11516 $rshift$$constant & 63); 11517 %} 11518 ins_pipe(ialu_reg_reg_extr); 11519 %} 11520 11521 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11522 %{ 11523 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11524 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11525 11526 ins_cost(INSN_COST); 11527 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11528 11529 ins_encode %{ 11530 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11531 $rshift$$constant & 31); 11532 %} 11533 ins_pipe(ialu_reg_reg_extr); 11534 %} 11535 11536 11537 // rol expander 11538 11539 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11540 %{ 11541 effect(DEF dst, USE src, USE shift); 11542 11543 format %{ "rol $dst, $src, $shift" %} 11544 ins_cost(INSN_COST * 3); 11545 ins_encode %{ 11546 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11547 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11548 rscratch1); 11549 %} 11550 ins_pipe(ialu_reg_reg_vshift); 11551 %} 11552 11553 // rol expander 11554 11555 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11556 %{ 11557 effect(DEF dst, USE src, USE shift); 11558 11559 format %{ "rol $dst, $src, $shift" %} 11560 ins_cost(INSN_COST * 3); 11561 ins_encode %{ 11562 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11563 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11564 rscratch1); 11565 %} 11566 ins_pipe(ialu_reg_reg_vshift); 11567 %} 11568 11569 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11570 %{ 11571 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11572 11573 expand %{ 11574 rolL_rReg(dst, src, shift, cr); 11575 %} 11576 %} 11577 11578 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11579 %{ 11580 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11581 11582 expand %{ 11583 rolL_rReg(dst, src, shift, cr); 11584 %} 11585 %} 11586 11587 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11588 %{ 11589 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11590 11591 expand %{ 11592 rolI_rReg(dst, src, shift, cr); 11593 %} 11594 %} 11595 11596 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11597 %{ 11598 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11599 11600 expand %{ 11601 rolI_rReg(dst, src, shift, cr); 11602 %} 11603 %} 11604 11605 // ror expander 11606 11607 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11608 %{ 11609 effect(DEF dst, USE src, USE shift); 11610 11611 format %{ "ror $dst, $src, $shift" %} 11612 ins_cost(INSN_COST); 11613 ins_encode %{ 11614 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11615 as_Register($shift$$reg)); 11616 %} 11617 ins_pipe(ialu_reg_reg_vshift); 11618 %} 11619 11620 // ror expander 11621 11622 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11623 %{ 11624 effect(DEF dst, USE src, USE shift); 11625 11626 format %{ "ror $dst, $src, $shift" %} 11627 ins_cost(INSN_COST); 11628 ins_encode %{ 11629 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11630 as_Register($shift$$reg)); 11631 %} 11632 ins_pipe(ialu_reg_reg_vshift); 11633 %} 11634 11635 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11636 %{ 11637 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11638 11639 expand %{ 11640 rorL_rReg(dst, src, shift, cr); 11641 %} 11642 %} 11643 11644 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11645 %{ 11646 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11647 11648 expand %{ 11649 rorL_rReg(dst, src, shift, cr); 11650 %} 11651 %} 11652 11653 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11654 %{ 11655 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11656 11657 expand %{ 11658 rorI_rReg(dst, src, shift, cr); 11659 %} 11660 %} 11661 11662 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11663 %{ 11664 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11665 11666 expand %{ 11667 rorI_rReg(dst, src, shift, cr); 11668 %} 11669 %} 11670 11671 // Add/subtract (extended) 11672 11673 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11674 %{ 11675 match(Set dst (AddL src1 (ConvI2L src2))); 11676 ins_cost(INSN_COST); 11677 format %{ "add $dst, $src1, $src2, sxtw" %} 11678 11679 ins_encode %{ 11680 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11681 as_Register($src2$$reg), ext::sxtw); 11682 %} 11683 ins_pipe(ialu_reg_reg); 11684 %}; 11685 11686 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11687 %{ 11688 match(Set dst (SubL src1 (ConvI2L src2))); 11689 ins_cost(INSN_COST); 11690 format %{ "sub $dst, $src1, $src2, sxtw" %} 11691 11692 ins_encode %{ 11693 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11694 as_Register($src2$$reg), ext::sxtw); 11695 %} 11696 ins_pipe(ialu_reg_reg); 11697 %}; 11698 11699 11700 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11701 %{ 11702 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11703 ins_cost(INSN_COST); 11704 format %{ "add $dst, $src1, $src2, sxth" %} 11705 11706 ins_encode %{ 11707 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11708 as_Register($src2$$reg), ext::sxth); 11709 %} 11710 ins_pipe(ialu_reg_reg); 11711 %} 11712 11713 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11714 %{ 11715 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11716 ins_cost(INSN_COST); 11717 format %{ "add $dst, $src1, $src2, sxtb" %} 11718 11719 ins_encode %{ 11720 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11721 as_Register($src2$$reg), ext::sxtb); 11722 %} 11723 ins_pipe(ialu_reg_reg); 11724 %} 11725 11726 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11727 %{ 11728 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 11729 ins_cost(INSN_COST); 11730 format %{ "add $dst, $src1, $src2, uxtb" %} 11731 11732 ins_encode %{ 11733 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11734 as_Register($src2$$reg), ext::uxtb); 11735 %} 11736 ins_pipe(ialu_reg_reg); 11737 %} 11738 11739 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 11740 %{ 11741 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11742 ins_cost(INSN_COST); 11743 format %{ "add $dst, $src1, $src2, sxth" %} 11744 11745 ins_encode %{ 11746 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11747 as_Register($src2$$reg), ext::sxth); 11748 %} 11749 ins_pipe(ialu_reg_reg); 11750 %} 11751 11752 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 11753 %{ 11754 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11755 ins_cost(INSN_COST); 11756 format %{ "add $dst, $src1, $src2, sxtw" %} 11757 11758 ins_encode %{ 11759 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11760 as_Register($src2$$reg), ext::sxtw); 11761 %} 11762 ins_pipe(ialu_reg_reg); 11763 %} 11764 11765 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11766 %{ 11767 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11768 ins_cost(INSN_COST); 11769 format %{ "add $dst, $src1, $src2, sxtb" %} 11770 11771 ins_encode %{ 11772 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11773 as_Register($src2$$reg), ext::sxtb); 11774 %} 11775 ins_pipe(ialu_reg_reg); 11776 %} 11777 11778 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11779 %{ 11780 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 11781 ins_cost(INSN_COST); 11782 format %{ "add $dst, $src1, $src2, uxtb" %} 11783 11784 ins_encode %{ 11785 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11786 as_Register($src2$$reg), ext::uxtb); 11787 %} 11788 ins_pipe(ialu_reg_reg); 11789 %} 11790 11791 11792 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11793 %{ 11794 match(Set dst (AddI src1 (AndI src2 mask))); 11795 ins_cost(INSN_COST); 11796 format %{ "addw $dst, $src1, $src2, uxtb" %} 11797 11798 ins_encode %{ 11799 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11800 as_Register($src2$$reg), ext::uxtb); 11801 %} 11802 ins_pipe(ialu_reg_reg); 11803 %} 11804 11805 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11806 %{ 11807 match(Set dst (AddI src1 (AndI src2 mask))); 11808 ins_cost(INSN_COST); 11809 format %{ "addw $dst, $src1, $src2, uxth" %} 11810 11811 ins_encode %{ 11812 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11813 as_Register($src2$$reg), ext::uxth); 11814 %} 11815 ins_pipe(ialu_reg_reg); 11816 %} 11817 11818 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11819 %{ 11820 match(Set dst (AddL src1 (AndL src2 mask))); 11821 ins_cost(INSN_COST); 11822 format %{ "add $dst, $src1, $src2, uxtb" %} 11823 11824 ins_encode %{ 11825 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11826 as_Register($src2$$reg), ext::uxtb); 11827 %} 11828 ins_pipe(ialu_reg_reg); 11829 %} 11830 11831 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11832 %{ 11833 match(Set dst (AddL src1 (AndL src2 mask))); 11834 ins_cost(INSN_COST); 11835 format %{ "add $dst, $src1, $src2, uxth" %} 11836 11837 ins_encode %{ 11838 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11839 as_Register($src2$$reg), ext::uxth); 11840 %} 11841 ins_pipe(ialu_reg_reg); 11842 %} 11843 11844 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11845 %{ 11846 match(Set dst (AddL src1 (AndL src2 mask))); 11847 ins_cost(INSN_COST); 11848 format %{ "add $dst, $src1, $src2, uxtw" %} 11849 11850 ins_encode %{ 11851 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11852 as_Register($src2$$reg), ext::uxtw); 11853 %} 11854 ins_pipe(ialu_reg_reg); 11855 %} 11856 11857 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11858 %{ 11859 match(Set dst (SubI src1 (AndI src2 mask))); 11860 ins_cost(INSN_COST); 11861 format %{ "subw $dst, $src1, $src2, uxtb" %} 11862 11863 ins_encode %{ 11864 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11865 as_Register($src2$$reg), ext::uxtb); 11866 %} 11867 ins_pipe(ialu_reg_reg); 11868 %} 11869 11870 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11871 %{ 11872 match(Set dst (SubI src1 (AndI src2 mask))); 11873 ins_cost(INSN_COST); 11874 format %{ "subw $dst, $src1, $src2, uxth" %} 11875 11876 ins_encode %{ 11877 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11878 as_Register($src2$$reg), ext::uxth); 11879 %} 11880 ins_pipe(ialu_reg_reg); 11881 %} 11882 11883 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11884 %{ 11885 match(Set dst (SubL src1 (AndL src2 mask))); 11886 ins_cost(INSN_COST); 11887 format %{ "sub $dst, $src1, $src2, uxtb" %} 11888 11889 ins_encode %{ 11890 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11891 as_Register($src2$$reg), ext::uxtb); 11892 %} 11893 ins_pipe(ialu_reg_reg); 11894 %} 11895 11896 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11897 %{ 11898 match(Set dst (SubL src1 (AndL src2 mask))); 11899 ins_cost(INSN_COST); 11900 format %{ "sub $dst, $src1, $src2, uxth" %} 11901 11902 ins_encode %{ 11903 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11904 as_Register($src2$$reg), ext::uxth); 11905 %} 11906 ins_pipe(ialu_reg_reg); 11907 %} 11908 11909 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11910 %{ 11911 match(Set dst (SubL src1 (AndL src2 mask))); 11912 ins_cost(INSN_COST); 11913 format %{ "sub $dst, $src1, $src2, uxtw" %} 11914 11915 ins_encode %{ 11916 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11917 as_Register($src2$$reg), ext::uxtw); 11918 %} 11919 ins_pipe(ialu_reg_reg); 11920 %} 11921 11922 11923 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11924 %{ 11925 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11926 ins_cost(1.9 * INSN_COST); 11927 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 11928 11929 ins_encode %{ 11930 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11931 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11932 %} 11933 ins_pipe(ialu_reg_reg_shift); 11934 %} 11935 11936 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11937 %{ 11938 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11939 ins_cost(1.9 * INSN_COST); 11940 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 11941 11942 ins_encode %{ 11943 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11944 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11945 %} 11946 ins_pipe(ialu_reg_reg_shift); 11947 %} 11948 11949 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11950 %{ 11951 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11952 ins_cost(1.9 * INSN_COST); 11953 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 11954 11955 ins_encode %{ 11956 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11957 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11958 %} 11959 ins_pipe(ialu_reg_reg_shift); 11960 %} 11961 11962 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11963 %{ 11964 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11965 ins_cost(1.9 * INSN_COST); 11966 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 11967 11968 ins_encode %{ 11969 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11970 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11971 %} 11972 ins_pipe(ialu_reg_reg_shift); 11973 %} 11974 11975 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11976 %{ 11977 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11978 ins_cost(1.9 * INSN_COST); 11979 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 11980 11981 ins_encode %{ 11982 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11983 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11984 %} 11985 ins_pipe(ialu_reg_reg_shift); 11986 %} 11987 11988 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11989 %{ 11990 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11991 ins_cost(1.9 * INSN_COST); 11992 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 11993 11994 ins_encode %{ 11995 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11996 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11997 %} 11998 ins_pipe(ialu_reg_reg_shift); 11999 %} 12000 12001 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12002 %{ 12003 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12004 ins_cost(1.9 * INSN_COST); 12005 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12006 12007 ins_encode %{ 12008 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12009 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12010 %} 12011 ins_pipe(ialu_reg_reg_shift); 12012 %} 12013 12014 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12015 %{ 12016 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12017 ins_cost(1.9 * INSN_COST); 12018 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12019 12020 ins_encode %{ 12021 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12022 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12023 %} 12024 ins_pipe(ialu_reg_reg_shift); 12025 %} 12026 12027 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12028 %{ 12029 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12030 ins_cost(1.9 * INSN_COST); 12031 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12032 12033 ins_encode %{ 12034 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12035 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12036 %} 12037 ins_pipe(ialu_reg_reg_shift); 12038 %} 12039 12040 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12041 %{ 12042 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12043 ins_cost(1.9 * INSN_COST); 12044 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12045 12046 ins_encode %{ 12047 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12048 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12049 %} 12050 ins_pipe(ialu_reg_reg_shift); 12051 %} 12052 12053 12054 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12055 %{ 12056 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12057 ins_cost(1.9 * INSN_COST); 12058 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12059 12060 ins_encode %{ 12061 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12062 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12063 %} 12064 ins_pipe(ialu_reg_reg_shift); 12065 %}; 12066 12067 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12068 %{ 12069 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12070 ins_cost(1.9 * INSN_COST); 12071 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12072 12073 ins_encode %{ 12074 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12075 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12076 %} 12077 ins_pipe(ialu_reg_reg_shift); 12078 %}; 12079 12080 12081 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12082 %{ 12083 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12084 ins_cost(1.9 * INSN_COST); 12085 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12086 12087 ins_encode %{ 12088 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12089 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12090 %} 12091 ins_pipe(ialu_reg_reg_shift); 12092 %} 12093 12094 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12095 %{ 12096 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12097 ins_cost(1.9 * INSN_COST); 12098 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12099 12100 ins_encode %{ 12101 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12102 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12103 %} 12104 ins_pipe(ialu_reg_reg_shift); 12105 %} 12106 12107 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12108 %{ 12109 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12110 ins_cost(1.9 * INSN_COST); 12111 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12112 12113 ins_encode %{ 12114 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12115 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12116 %} 12117 ins_pipe(ialu_reg_reg_shift); 12118 %} 12119 12120 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12121 %{ 12122 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12123 ins_cost(1.9 * INSN_COST); 12124 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12125 12126 ins_encode %{ 12127 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12128 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12129 %} 12130 ins_pipe(ialu_reg_reg_shift); 12131 %} 12132 12133 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12134 %{ 12135 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12136 ins_cost(1.9 * INSN_COST); 12137 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12138 12139 ins_encode %{ 12140 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12141 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12142 %} 12143 ins_pipe(ialu_reg_reg_shift); 12144 %} 12145 12146 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12147 %{ 12148 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12149 ins_cost(1.9 * INSN_COST); 12150 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12151 12152 ins_encode %{ 12153 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12154 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12155 %} 12156 ins_pipe(ialu_reg_reg_shift); 12157 %} 12158 12159 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12160 %{ 12161 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12162 ins_cost(1.9 * INSN_COST); 12163 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12164 12165 ins_encode %{ 12166 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12167 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12168 %} 12169 ins_pipe(ialu_reg_reg_shift); 12170 %} 12171 12172 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12173 %{ 12174 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12175 ins_cost(1.9 * INSN_COST); 12176 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12177 12178 ins_encode %{ 12179 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12180 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12181 %} 12182 ins_pipe(ialu_reg_reg_shift); 12183 %} 12184 12185 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12186 %{ 12187 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12188 ins_cost(1.9 * INSN_COST); 12189 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12190 12191 ins_encode %{ 12192 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12193 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12194 %} 12195 ins_pipe(ialu_reg_reg_shift); 12196 %} 12197 12198 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12199 %{ 12200 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12201 ins_cost(1.9 * INSN_COST); 12202 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12203 12204 ins_encode %{ 12205 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12206 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12207 %} 12208 ins_pipe(ialu_reg_reg_shift); 12209 %} 12210 // END This section of the file is automatically generated. Do not edit -------------- 12211 12212 // ============================================================================ 12213 // Floating Point Arithmetic Instructions 12214 12215 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12216 match(Set dst (AddF src1 src2)); 12217 12218 ins_cost(INSN_COST * 5); 12219 format %{ "fadds $dst, $src1, $src2" %} 12220 12221 ins_encode %{ 12222 __ fadds(as_FloatRegister($dst$$reg), 12223 as_FloatRegister($src1$$reg), 12224 as_FloatRegister($src2$$reg)); 12225 %} 12226 12227 ins_pipe(fp_dop_reg_reg_s); 12228 %} 12229 12230 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12231 match(Set dst (AddD src1 src2)); 12232 12233 ins_cost(INSN_COST * 5); 12234 format %{ "faddd $dst, $src1, $src2" %} 12235 12236 ins_encode %{ 12237 __ faddd(as_FloatRegister($dst$$reg), 12238 as_FloatRegister($src1$$reg), 12239 as_FloatRegister($src2$$reg)); 12240 %} 12241 12242 ins_pipe(fp_dop_reg_reg_d); 12243 %} 12244 12245 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12246 match(Set dst (SubF src1 src2)); 12247 12248 ins_cost(INSN_COST * 5); 12249 format %{ "fsubs $dst, $src1, $src2" %} 12250 12251 ins_encode %{ 12252 __ fsubs(as_FloatRegister($dst$$reg), 12253 as_FloatRegister($src1$$reg), 12254 as_FloatRegister($src2$$reg)); 12255 %} 12256 12257 ins_pipe(fp_dop_reg_reg_s); 12258 %} 12259 12260 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12261 match(Set dst (SubD src1 src2)); 12262 12263 ins_cost(INSN_COST * 5); 12264 format %{ "fsubd $dst, $src1, $src2" %} 12265 12266 ins_encode %{ 12267 __ fsubd(as_FloatRegister($dst$$reg), 12268 as_FloatRegister($src1$$reg), 12269 as_FloatRegister($src2$$reg)); 12270 %} 12271 12272 ins_pipe(fp_dop_reg_reg_d); 12273 %} 12274 12275 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12276 match(Set dst (MulF src1 src2)); 12277 12278 ins_cost(INSN_COST * 6); 12279 format %{ "fmuls $dst, $src1, $src2" %} 12280 12281 ins_encode %{ 12282 __ fmuls(as_FloatRegister($dst$$reg), 12283 as_FloatRegister($src1$$reg), 12284 as_FloatRegister($src2$$reg)); 12285 %} 12286 12287 ins_pipe(fp_dop_reg_reg_s); 12288 %} 12289 12290 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12291 match(Set dst (MulD src1 src2)); 12292 12293 ins_cost(INSN_COST * 6); 12294 format %{ "fmuld $dst, $src1, $src2" %} 12295 12296 ins_encode %{ 12297 __ fmuld(as_FloatRegister($dst$$reg), 12298 as_FloatRegister($src1$$reg), 12299 as_FloatRegister($src2$$reg)); 12300 %} 12301 12302 ins_pipe(fp_dop_reg_reg_d); 12303 %} 12304 12305 // src1 * src2 + src3 12306 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12307 predicate(UseFMA); 12308 match(Set dst (FmaF src3 (Binary src1 src2))); 12309 12310 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12311 12312 ins_encode %{ 12313 __ fmadds(as_FloatRegister($dst$$reg), 12314 as_FloatRegister($src1$$reg), 12315 as_FloatRegister($src2$$reg), 12316 as_FloatRegister($src3$$reg)); 12317 %} 12318 12319 ins_pipe(pipe_class_default); 12320 %} 12321 12322 // src1 * src2 + src3 12323 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12324 predicate(UseFMA); 12325 match(Set dst (FmaD src3 (Binary src1 src2))); 12326 12327 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12328 12329 ins_encode %{ 12330 __ fmaddd(as_FloatRegister($dst$$reg), 12331 as_FloatRegister($src1$$reg), 12332 as_FloatRegister($src2$$reg), 12333 as_FloatRegister($src3$$reg)); 12334 %} 12335 12336 ins_pipe(pipe_class_default); 12337 %} 12338 12339 // -src1 * src2 + src3 12340 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12341 predicate(UseFMA); 12342 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12343 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12344 12345 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12346 12347 ins_encode %{ 12348 __ fmsubs(as_FloatRegister($dst$$reg), 12349 as_FloatRegister($src1$$reg), 12350 as_FloatRegister($src2$$reg), 12351 as_FloatRegister($src3$$reg)); 12352 %} 12353 12354 ins_pipe(pipe_class_default); 12355 %} 12356 12357 // -src1 * src2 + src3 12358 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12359 predicate(UseFMA); 12360 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12361 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12362 12363 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12364 12365 ins_encode %{ 12366 __ fmsubd(as_FloatRegister($dst$$reg), 12367 as_FloatRegister($src1$$reg), 12368 as_FloatRegister($src2$$reg), 12369 as_FloatRegister($src3$$reg)); 12370 %} 12371 12372 ins_pipe(pipe_class_default); 12373 %} 12374 12375 // -src1 * src2 - src3 12376 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12377 predicate(UseFMA); 12378 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12379 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12380 12381 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12382 12383 ins_encode %{ 12384 __ fnmadds(as_FloatRegister($dst$$reg), 12385 as_FloatRegister($src1$$reg), 12386 as_FloatRegister($src2$$reg), 12387 as_FloatRegister($src3$$reg)); 12388 %} 12389 12390 ins_pipe(pipe_class_default); 12391 %} 12392 12393 // -src1 * src2 - src3 12394 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12395 predicate(UseFMA); 12396 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12397 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12398 12399 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12400 12401 ins_encode %{ 12402 __ fnmaddd(as_FloatRegister($dst$$reg), 12403 as_FloatRegister($src1$$reg), 12404 as_FloatRegister($src2$$reg), 12405 as_FloatRegister($src3$$reg)); 12406 %} 12407 12408 ins_pipe(pipe_class_default); 12409 %} 12410 12411 // src1 * src2 - src3 12412 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12413 predicate(UseFMA); 12414 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12415 12416 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12417 12418 ins_encode %{ 12419 __ fnmsubs(as_FloatRegister($dst$$reg), 12420 as_FloatRegister($src1$$reg), 12421 as_FloatRegister($src2$$reg), 12422 as_FloatRegister($src3$$reg)); 12423 %} 12424 12425 ins_pipe(pipe_class_default); 12426 %} 12427 12428 // src1 * src2 - src3 12429 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12430 predicate(UseFMA); 12431 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12432 12433 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12434 12435 ins_encode %{ 12436 // n.b. insn name should be fnmsubd 12437 __ fnmsub(as_FloatRegister($dst$$reg), 12438 as_FloatRegister($src1$$reg), 12439 as_FloatRegister($src2$$reg), 12440 as_FloatRegister($src3$$reg)); 12441 %} 12442 12443 ins_pipe(pipe_class_default); 12444 %} 12445 12446 12447 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12448 match(Set dst (DivF src1 src2)); 12449 12450 ins_cost(INSN_COST * 18); 12451 format %{ "fdivs $dst, $src1, $src2" %} 12452 12453 ins_encode %{ 12454 __ fdivs(as_FloatRegister($dst$$reg), 12455 as_FloatRegister($src1$$reg), 12456 as_FloatRegister($src2$$reg)); 12457 %} 12458 12459 ins_pipe(fp_div_s); 12460 %} 12461 12462 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12463 match(Set dst (DivD src1 src2)); 12464 12465 ins_cost(INSN_COST * 32); 12466 format %{ "fdivd $dst, $src1, $src2" %} 12467 12468 ins_encode %{ 12469 __ fdivd(as_FloatRegister($dst$$reg), 12470 as_FloatRegister($src1$$reg), 12471 as_FloatRegister($src2$$reg)); 12472 %} 12473 12474 ins_pipe(fp_div_d); 12475 %} 12476 12477 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12478 match(Set dst (NegF src)); 12479 12480 ins_cost(INSN_COST * 3); 12481 format %{ "fneg $dst, $src" %} 12482 12483 ins_encode %{ 12484 __ fnegs(as_FloatRegister($dst$$reg), 12485 as_FloatRegister($src$$reg)); 12486 %} 12487 12488 ins_pipe(fp_uop_s); 12489 %} 12490 12491 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12492 match(Set dst (NegD src)); 12493 12494 ins_cost(INSN_COST * 3); 12495 format %{ "fnegd $dst, $src" %} 12496 12497 ins_encode %{ 12498 __ fnegd(as_FloatRegister($dst$$reg), 12499 as_FloatRegister($src$$reg)); 12500 %} 12501 12502 ins_pipe(fp_uop_d); 12503 %} 12504 12505 instruct absF_reg(vRegF dst, vRegF src) %{ 12506 match(Set dst (AbsF src)); 12507 12508 ins_cost(INSN_COST * 3); 12509 format %{ "fabss $dst, $src" %} 12510 ins_encode %{ 12511 __ fabss(as_FloatRegister($dst$$reg), 12512 as_FloatRegister($src$$reg)); 12513 %} 12514 12515 ins_pipe(fp_uop_s); 12516 %} 12517 12518 instruct absD_reg(vRegD dst, vRegD src) %{ 12519 match(Set dst (AbsD src)); 12520 12521 ins_cost(INSN_COST * 3); 12522 format %{ "fabsd $dst, $src" %} 12523 ins_encode %{ 12524 __ fabsd(as_FloatRegister($dst$$reg), 12525 as_FloatRegister($src$$reg)); 12526 %} 12527 12528 ins_pipe(fp_uop_d); 12529 %} 12530 12531 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12532 match(Set dst (SqrtD src)); 12533 12534 ins_cost(INSN_COST * 50); 12535 format %{ "fsqrtd $dst, $src" %} 12536 ins_encode %{ 12537 __ fsqrtd(as_FloatRegister($dst$$reg), 12538 as_FloatRegister($src$$reg)); 12539 %} 12540 12541 ins_pipe(fp_div_s); 12542 %} 12543 12544 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12545 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 12546 12547 ins_cost(INSN_COST * 50); 12548 format %{ "fsqrts $dst, $src" %} 12549 ins_encode %{ 12550 __ fsqrts(as_FloatRegister($dst$$reg), 12551 as_FloatRegister($src$$reg)); 12552 %} 12553 12554 ins_pipe(fp_div_d); 12555 %} 12556 12557 // ============================================================================ 12558 // Logical Instructions 12559 12560 // Integer Logical Instructions 12561 12562 // And Instructions 12563 12564 12565 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 12566 match(Set dst (AndI src1 src2)); 12567 12568 format %{ "andw $dst, $src1, $src2\t# int" %} 12569 12570 ins_cost(INSN_COST); 12571 ins_encode %{ 12572 __ andw(as_Register($dst$$reg), 12573 as_Register($src1$$reg), 12574 as_Register($src2$$reg)); 12575 %} 12576 12577 ins_pipe(ialu_reg_reg); 12578 %} 12579 12580 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 12581 match(Set dst (AndI src1 src2)); 12582 12583 format %{ "andsw $dst, $src1, $src2\t# int" %} 12584 12585 ins_cost(INSN_COST); 12586 ins_encode %{ 12587 __ andw(as_Register($dst$$reg), 12588 as_Register($src1$$reg), 12589 (unsigned long)($src2$$constant)); 12590 %} 12591 12592 ins_pipe(ialu_reg_imm); 12593 %} 12594 12595 // Or Instructions 12596 12597 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12598 match(Set dst (OrI src1 src2)); 12599 12600 format %{ "orrw $dst, $src1, $src2\t# int" %} 12601 12602 ins_cost(INSN_COST); 12603 ins_encode %{ 12604 __ orrw(as_Register($dst$$reg), 12605 as_Register($src1$$reg), 12606 as_Register($src2$$reg)); 12607 %} 12608 12609 ins_pipe(ialu_reg_reg); 12610 %} 12611 12612 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12613 match(Set dst (OrI src1 src2)); 12614 12615 format %{ "orrw $dst, $src1, $src2\t# int" %} 12616 12617 ins_cost(INSN_COST); 12618 ins_encode %{ 12619 __ orrw(as_Register($dst$$reg), 12620 as_Register($src1$$reg), 12621 (unsigned long)($src2$$constant)); 12622 %} 12623 12624 ins_pipe(ialu_reg_imm); 12625 %} 12626 12627 // Xor Instructions 12628 12629 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12630 match(Set dst (XorI src1 src2)); 12631 12632 format %{ "eorw $dst, $src1, $src2\t# int" %} 12633 12634 ins_cost(INSN_COST); 12635 ins_encode %{ 12636 __ eorw(as_Register($dst$$reg), 12637 as_Register($src1$$reg), 12638 as_Register($src2$$reg)); 12639 %} 12640 12641 ins_pipe(ialu_reg_reg); 12642 %} 12643 12644 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12645 match(Set dst (XorI src1 src2)); 12646 12647 format %{ "eorw $dst, $src1, $src2\t# int" %} 12648 12649 ins_cost(INSN_COST); 12650 ins_encode %{ 12651 __ eorw(as_Register($dst$$reg), 12652 as_Register($src1$$reg), 12653 (unsigned long)($src2$$constant)); 12654 %} 12655 12656 ins_pipe(ialu_reg_imm); 12657 %} 12658 12659 // Long Logical Instructions 12660 // TODO 12661 12662 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 12663 match(Set dst (AndL src1 src2)); 12664 12665 format %{ "and $dst, $src1, $src2\t# int" %} 12666 12667 ins_cost(INSN_COST); 12668 ins_encode %{ 12669 __ andr(as_Register($dst$$reg), 12670 as_Register($src1$$reg), 12671 as_Register($src2$$reg)); 12672 %} 12673 12674 ins_pipe(ialu_reg_reg); 12675 %} 12676 12677 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 12678 match(Set dst (AndL src1 src2)); 12679 12680 format %{ "and $dst, $src1, $src2\t# int" %} 12681 12682 ins_cost(INSN_COST); 12683 ins_encode %{ 12684 __ andr(as_Register($dst$$reg), 12685 as_Register($src1$$reg), 12686 (unsigned long)($src2$$constant)); 12687 %} 12688 12689 ins_pipe(ialu_reg_imm); 12690 %} 12691 12692 // Or Instructions 12693 12694 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12695 match(Set dst (OrL src1 src2)); 12696 12697 format %{ "orr $dst, $src1, $src2\t# int" %} 12698 12699 ins_cost(INSN_COST); 12700 ins_encode %{ 12701 __ orr(as_Register($dst$$reg), 12702 as_Register($src1$$reg), 12703 as_Register($src2$$reg)); 12704 %} 12705 12706 ins_pipe(ialu_reg_reg); 12707 %} 12708 12709 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12710 match(Set dst (OrL src1 src2)); 12711 12712 format %{ "orr $dst, $src1, $src2\t# int" %} 12713 12714 ins_cost(INSN_COST); 12715 ins_encode %{ 12716 __ orr(as_Register($dst$$reg), 12717 as_Register($src1$$reg), 12718 (unsigned long)($src2$$constant)); 12719 %} 12720 12721 ins_pipe(ialu_reg_imm); 12722 %} 12723 12724 // Xor Instructions 12725 12726 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12727 match(Set dst (XorL src1 src2)); 12728 12729 format %{ "eor $dst, $src1, $src2\t# int" %} 12730 12731 ins_cost(INSN_COST); 12732 ins_encode %{ 12733 __ eor(as_Register($dst$$reg), 12734 as_Register($src1$$reg), 12735 as_Register($src2$$reg)); 12736 %} 12737 12738 ins_pipe(ialu_reg_reg); 12739 %} 12740 12741 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12742 match(Set dst (XorL src1 src2)); 12743 12744 ins_cost(INSN_COST); 12745 format %{ "eor $dst, $src1, $src2\t# int" %} 12746 12747 ins_encode %{ 12748 __ eor(as_Register($dst$$reg), 12749 as_Register($src1$$reg), 12750 (unsigned long)($src2$$constant)); 12751 %} 12752 12753 ins_pipe(ialu_reg_imm); 12754 %} 12755 12756 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 12757 %{ 12758 match(Set dst (ConvI2L src)); 12759 12760 ins_cost(INSN_COST); 12761 format %{ "sxtw $dst, $src\t# i2l" %} 12762 ins_encode %{ 12763 __ sbfm($dst$$Register, $src$$Register, 0, 31); 12764 %} 12765 ins_pipe(ialu_reg_shift); 12766 %} 12767 12768 // this pattern occurs in bigmath arithmetic 12769 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 12770 %{ 12771 match(Set dst (AndL (ConvI2L src) mask)); 12772 12773 ins_cost(INSN_COST); 12774 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 12775 ins_encode %{ 12776 __ ubfm($dst$$Register, $src$$Register, 0, 31); 12777 %} 12778 12779 ins_pipe(ialu_reg_shift); 12780 %} 12781 12782 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 12783 match(Set dst (ConvL2I src)); 12784 12785 ins_cost(INSN_COST); 12786 format %{ "movw $dst, $src \t// l2i" %} 12787 12788 ins_encode %{ 12789 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 12790 %} 12791 12792 ins_pipe(ialu_reg); 12793 %} 12794 12795 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12796 %{ 12797 match(Set dst (Conv2B src)); 12798 effect(KILL cr); 12799 12800 format %{ 12801 "cmpw $src, zr\n\t" 12802 "cset $dst, ne" 12803 %} 12804 12805 ins_encode %{ 12806 __ cmpw(as_Register($src$$reg), zr); 12807 __ cset(as_Register($dst$$reg), Assembler::NE); 12808 %} 12809 12810 ins_pipe(ialu_reg); 12811 %} 12812 12813 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 12814 %{ 12815 match(Set dst (Conv2B src)); 12816 effect(KILL cr); 12817 12818 format %{ 12819 "cmp $src, zr\n\t" 12820 "cset $dst, ne" 12821 %} 12822 12823 ins_encode %{ 12824 __ cmp(as_Register($src$$reg), zr); 12825 __ cset(as_Register($dst$$reg), Assembler::NE); 12826 %} 12827 12828 ins_pipe(ialu_reg); 12829 %} 12830 12831 instruct convD2F_reg(vRegF dst, vRegD src) %{ 12832 match(Set dst (ConvD2F src)); 12833 12834 ins_cost(INSN_COST * 5); 12835 format %{ "fcvtd $dst, $src \t// d2f" %} 12836 12837 ins_encode %{ 12838 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12839 %} 12840 12841 ins_pipe(fp_d2f); 12842 %} 12843 12844 instruct convF2D_reg(vRegD dst, vRegF src) %{ 12845 match(Set dst (ConvF2D src)); 12846 12847 ins_cost(INSN_COST * 5); 12848 format %{ "fcvts $dst, $src \t// f2d" %} 12849 12850 ins_encode %{ 12851 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12852 %} 12853 12854 ins_pipe(fp_f2d); 12855 %} 12856 12857 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12858 match(Set dst (ConvF2I src)); 12859 12860 ins_cost(INSN_COST * 5); 12861 format %{ "fcvtzsw $dst, $src \t// f2i" %} 12862 12863 ins_encode %{ 12864 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12865 %} 12866 12867 ins_pipe(fp_f2i); 12868 %} 12869 12870 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 12871 match(Set dst (ConvF2L src)); 12872 12873 ins_cost(INSN_COST * 5); 12874 format %{ "fcvtzs $dst, $src \t// f2l" %} 12875 12876 ins_encode %{ 12877 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12878 %} 12879 12880 ins_pipe(fp_f2l); 12881 %} 12882 12883 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 12884 match(Set dst (ConvI2F src)); 12885 12886 ins_cost(INSN_COST * 5); 12887 format %{ "scvtfws $dst, $src \t// i2f" %} 12888 12889 ins_encode %{ 12890 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12891 %} 12892 12893 ins_pipe(fp_i2f); 12894 %} 12895 12896 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 12897 match(Set dst (ConvL2F src)); 12898 12899 ins_cost(INSN_COST * 5); 12900 format %{ "scvtfs $dst, $src \t// l2f" %} 12901 12902 ins_encode %{ 12903 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12904 %} 12905 12906 ins_pipe(fp_l2f); 12907 %} 12908 12909 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 12910 match(Set dst (ConvD2I src)); 12911 12912 ins_cost(INSN_COST * 5); 12913 format %{ "fcvtzdw $dst, $src \t// d2i" %} 12914 12915 ins_encode %{ 12916 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12917 %} 12918 12919 ins_pipe(fp_d2i); 12920 %} 12921 12922 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12923 match(Set dst (ConvD2L src)); 12924 12925 ins_cost(INSN_COST * 5); 12926 format %{ "fcvtzd $dst, $src \t// d2l" %} 12927 12928 ins_encode %{ 12929 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12930 %} 12931 12932 ins_pipe(fp_d2l); 12933 %} 12934 12935 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 12936 match(Set dst (ConvI2D src)); 12937 12938 ins_cost(INSN_COST * 5); 12939 format %{ "scvtfwd $dst, $src \t// i2d" %} 12940 12941 ins_encode %{ 12942 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12943 %} 12944 12945 ins_pipe(fp_i2d); 12946 %} 12947 12948 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 12949 match(Set dst (ConvL2D src)); 12950 12951 ins_cost(INSN_COST * 5); 12952 format %{ "scvtfd $dst, $src \t// l2d" %} 12953 12954 ins_encode %{ 12955 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12956 %} 12957 12958 ins_pipe(fp_l2d); 12959 %} 12960 12961 // stack <-> reg and reg <-> reg shuffles with no conversion 12962 12963 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 12964 12965 match(Set dst (MoveF2I src)); 12966 12967 effect(DEF dst, USE src); 12968 12969 ins_cost(4 * INSN_COST); 12970 12971 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 12972 12973 ins_encode %{ 12974 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 12975 %} 12976 12977 ins_pipe(iload_reg_reg); 12978 12979 %} 12980 12981 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 12982 12983 match(Set dst (MoveI2F src)); 12984 12985 effect(DEF dst, USE src); 12986 12987 ins_cost(4 * INSN_COST); 12988 12989 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 12990 12991 ins_encode %{ 12992 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12993 %} 12994 12995 ins_pipe(pipe_class_memory); 12996 12997 %} 12998 12999 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13000 13001 match(Set dst (MoveD2L src)); 13002 13003 effect(DEF dst, USE src); 13004 13005 ins_cost(4 * INSN_COST); 13006 13007 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13008 13009 ins_encode %{ 13010 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13011 %} 13012 13013 ins_pipe(iload_reg_reg); 13014 13015 %} 13016 13017 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13018 13019 match(Set dst (MoveL2D src)); 13020 13021 effect(DEF dst, USE src); 13022 13023 ins_cost(4 * INSN_COST); 13024 13025 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13026 13027 ins_encode %{ 13028 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13029 %} 13030 13031 ins_pipe(pipe_class_memory); 13032 13033 %} 13034 13035 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13036 13037 match(Set dst (MoveF2I src)); 13038 13039 effect(DEF dst, USE src); 13040 13041 ins_cost(INSN_COST); 13042 13043 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13044 13045 ins_encode %{ 13046 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13047 %} 13048 13049 ins_pipe(pipe_class_memory); 13050 13051 %} 13052 13053 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13054 13055 match(Set dst (MoveI2F src)); 13056 13057 effect(DEF dst, USE src); 13058 13059 ins_cost(INSN_COST); 13060 13061 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13062 13063 ins_encode %{ 13064 __ strw($src$$Register, Address(sp, $dst$$disp)); 13065 %} 13066 13067 ins_pipe(istore_reg_reg); 13068 13069 %} 13070 13071 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13072 13073 match(Set dst (MoveD2L src)); 13074 13075 effect(DEF dst, USE src); 13076 13077 ins_cost(INSN_COST); 13078 13079 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13080 13081 ins_encode %{ 13082 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13083 %} 13084 13085 ins_pipe(pipe_class_memory); 13086 13087 %} 13088 13089 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13090 13091 match(Set dst (MoveL2D src)); 13092 13093 effect(DEF dst, USE src); 13094 13095 ins_cost(INSN_COST); 13096 13097 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13098 13099 ins_encode %{ 13100 __ str($src$$Register, Address(sp, $dst$$disp)); 13101 %} 13102 13103 ins_pipe(istore_reg_reg); 13104 13105 %} 13106 13107 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13108 13109 match(Set dst (MoveF2I src)); 13110 13111 effect(DEF dst, USE src); 13112 13113 ins_cost(INSN_COST); 13114 13115 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13116 13117 ins_encode %{ 13118 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13119 %} 13120 13121 ins_pipe(fp_f2i); 13122 13123 %} 13124 13125 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13126 13127 match(Set dst (MoveI2F src)); 13128 13129 effect(DEF dst, USE src); 13130 13131 ins_cost(INSN_COST); 13132 13133 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13134 13135 ins_encode %{ 13136 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13137 %} 13138 13139 ins_pipe(fp_i2f); 13140 13141 %} 13142 13143 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13144 13145 match(Set dst (MoveD2L src)); 13146 13147 effect(DEF dst, USE src); 13148 13149 ins_cost(INSN_COST); 13150 13151 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13152 13153 ins_encode %{ 13154 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13155 %} 13156 13157 ins_pipe(fp_d2l); 13158 13159 %} 13160 13161 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13162 13163 match(Set dst (MoveL2D src)); 13164 13165 effect(DEF dst, USE src); 13166 13167 ins_cost(INSN_COST); 13168 13169 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13170 13171 ins_encode %{ 13172 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13173 %} 13174 13175 ins_pipe(fp_l2d); 13176 13177 %} 13178 13179 // ============================================================================ 13180 // clearing of an array 13181 13182 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13183 %{ 13184 match(Set dummy (ClearArray cnt base)); 13185 effect(USE_KILL cnt, USE_KILL base); 13186 13187 ins_cost(4 * INSN_COST); 13188 format %{ "ClearArray $cnt, $base" %} 13189 13190 ins_encode %{ 13191 __ zero_words($base$$Register, $cnt$$Register); 13192 %} 13193 13194 ins_pipe(pipe_class_memory); 13195 %} 13196 13197 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13198 %{ 13199 predicate((u_int64_t)n->in(2)->get_long() 13200 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13201 match(Set dummy (ClearArray cnt base)); 13202 effect(USE_KILL base); 13203 13204 ins_cost(4 * INSN_COST); 13205 format %{ "ClearArray $cnt, $base" %} 13206 13207 ins_encode %{ 13208 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13209 %} 13210 13211 ins_pipe(pipe_class_memory); 13212 %} 13213 13214 // ============================================================================ 13215 // Overflow Math Instructions 13216 13217 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13218 %{ 13219 match(Set cr (OverflowAddI op1 op2)); 13220 13221 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13222 ins_cost(INSN_COST); 13223 ins_encode %{ 13224 __ cmnw($op1$$Register, $op2$$Register); 13225 %} 13226 13227 ins_pipe(icmp_reg_reg); 13228 %} 13229 13230 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13231 %{ 13232 match(Set cr (OverflowAddI op1 op2)); 13233 13234 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13235 ins_cost(INSN_COST); 13236 ins_encode %{ 13237 __ cmnw($op1$$Register, $op2$$constant); 13238 %} 13239 13240 ins_pipe(icmp_reg_imm); 13241 %} 13242 13243 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13244 %{ 13245 match(Set cr (OverflowAddL op1 op2)); 13246 13247 format %{ "cmn $op1, $op2\t# overflow check long" %} 13248 ins_cost(INSN_COST); 13249 ins_encode %{ 13250 __ cmn($op1$$Register, $op2$$Register); 13251 %} 13252 13253 ins_pipe(icmp_reg_reg); 13254 %} 13255 13256 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13257 %{ 13258 match(Set cr (OverflowAddL op1 op2)); 13259 13260 format %{ "cmn $op1, $op2\t# overflow check long" %} 13261 ins_cost(INSN_COST); 13262 ins_encode %{ 13263 __ cmn($op1$$Register, $op2$$constant); 13264 %} 13265 13266 ins_pipe(icmp_reg_imm); 13267 %} 13268 13269 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13270 %{ 13271 match(Set cr (OverflowSubI op1 op2)); 13272 13273 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13274 ins_cost(INSN_COST); 13275 ins_encode %{ 13276 __ cmpw($op1$$Register, $op2$$Register); 13277 %} 13278 13279 ins_pipe(icmp_reg_reg); 13280 %} 13281 13282 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13283 %{ 13284 match(Set cr (OverflowSubI op1 op2)); 13285 13286 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13287 ins_cost(INSN_COST); 13288 ins_encode %{ 13289 __ cmpw($op1$$Register, $op2$$constant); 13290 %} 13291 13292 ins_pipe(icmp_reg_imm); 13293 %} 13294 13295 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13296 %{ 13297 match(Set cr (OverflowSubL op1 op2)); 13298 13299 format %{ "cmp $op1, $op2\t# overflow check long" %} 13300 ins_cost(INSN_COST); 13301 ins_encode %{ 13302 __ cmp($op1$$Register, $op2$$Register); 13303 %} 13304 13305 ins_pipe(icmp_reg_reg); 13306 %} 13307 13308 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13309 %{ 13310 match(Set cr (OverflowSubL op1 op2)); 13311 13312 format %{ "cmp $op1, $op2\t# overflow check long" %} 13313 ins_cost(INSN_COST); 13314 ins_encode %{ 13315 __ cmp($op1$$Register, $op2$$constant); 13316 %} 13317 13318 ins_pipe(icmp_reg_imm); 13319 %} 13320 13321 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13322 %{ 13323 match(Set cr (OverflowSubI zero op1)); 13324 13325 format %{ "cmpw zr, $op1\t# overflow check int" %} 13326 ins_cost(INSN_COST); 13327 ins_encode %{ 13328 __ cmpw(zr, $op1$$Register); 13329 %} 13330 13331 ins_pipe(icmp_reg_imm); 13332 %} 13333 13334 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13335 %{ 13336 match(Set cr (OverflowSubL zero op1)); 13337 13338 format %{ "cmp zr, $op1\t# overflow check long" %} 13339 ins_cost(INSN_COST); 13340 ins_encode %{ 13341 __ cmp(zr, $op1$$Register); 13342 %} 13343 13344 ins_pipe(icmp_reg_imm); 13345 %} 13346 13347 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13348 %{ 13349 match(Set cr (OverflowMulI op1 op2)); 13350 13351 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13352 "cmp rscratch1, rscratch1, sxtw\n\t" 13353 "movw rscratch1, #0x80000000\n\t" 13354 "cselw rscratch1, rscratch1, zr, NE\n\t" 13355 "cmpw rscratch1, #1" %} 13356 ins_cost(5 * INSN_COST); 13357 ins_encode %{ 13358 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13359 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13360 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13361 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13362 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13363 %} 13364 13365 ins_pipe(pipe_slow); 13366 %} 13367 13368 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13369 %{ 13370 match(If cmp (OverflowMulI op1 op2)); 13371 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13372 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13373 effect(USE labl, KILL cr); 13374 13375 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13376 "cmp rscratch1, rscratch1, sxtw\n\t" 13377 "b$cmp $labl" %} 13378 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13379 ins_encode %{ 13380 Label* L = $labl$$label; 13381 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13382 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13383 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13384 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13385 %} 13386 13387 ins_pipe(pipe_serial); 13388 %} 13389 13390 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13391 %{ 13392 match(Set cr (OverflowMulL op1 op2)); 13393 13394 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13395 "smulh rscratch2, $op1, $op2\n\t" 13396 "cmp rscratch2, rscratch1, ASR #63\n\t" 13397 "movw rscratch1, #0x80000000\n\t" 13398 "cselw rscratch1, rscratch1, zr, NE\n\t" 13399 "cmpw rscratch1, #1" %} 13400 ins_cost(6 * INSN_COST); 13401 ins_encode %{ 13402 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13403 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13404 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13405 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13406 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13407 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13408 %} 13409 13410 ins_pipe(pipe_slow); 13411 %} 13412 13413 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13414 %{ 13415 match(If cmp (OverflowMulL op1 op2)); 13416 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13417 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13418 effect(USE labl, KILL cr); 13419 13420 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13421 "smulh rscratch2, $op1, $op2\n\t" 13422 "cmp rscratch2, rscratch1, ASR #63\n\t" 13423 "b$cmp $labl" %} 13424 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13425 ins_encode %{ 13426 Label* L = $labl$$label; 13427 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13428 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13429 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13430 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13431 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13432 %} 13433 13434 ins_pipe(pipe_serial); 13435 %} 13436 13437 // ============================================================================ 13438 // Compare Instructions 13439 13440 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13441 %{ 13442 match(Set cr (CmpI op1 op2)); 13443 13444 effect(DEF cr, USE op1, USE op2); 13445 13446 ins_cost(INSN_COST); 13447 format %{ "cmpw $op1, $op2" %} 13448 13449 ins_encode(aarch64_enc_cmpw(op1, op2)); 13450 13451 ins_pipe(icmp_reg_reg); 13452 %} 13453 13454 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13455 %{ 13456 match(Set cr (CmpI op1 zero)); 13457 13458 effect(DEF cr, USE op1); 13459 13460 ins_cost(INSN_COST); 13461 format %{ "cmpw $op1, 0" %} 13462 13463 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13464 13465 ins_pipe(icmp_reg_imm); 13466 %} 13467 13468 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13469 %{ 13470 match(Set cr (CmpI op1 op2)); 13471 13472 effect(DEF cr, USE op1); 13473 13474 ins_cost(INSN_COST); 13475 format %{ "cmpw $op1, $op2" %} 13476 13477 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13478 13479 ins_pipe(icmp_reg_imm); 13480 %} 13481 13482 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 13483 %{ 13484 match(Set cr (CmpI op1 op2)); 13485 13486 effect(DEF cr, USE op1); 13487 13488 ins_cost(INSN_COST * 2); 13489 format %{ "cmpw $op1, $op2" %} 13490 13491 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13492 13493 ins_pipe(icmp_reg_imm); 13494 %} 13495 13496 // Unsigned compare Instructions; really, same as signed compare 13497 // except it should only be used to feed an If or a CMovI which takes a 13498 // cmpOpU. 13499 13500 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 13501 %{ 13502 match(Set cr (CmpU op1 op2)); 13503 13504 effect(DEF cr, USE op1, USE op2); 13505 13506 ins_cost(INSN_COST); 13507 format %{ "cmpw $op1, $op2\t# unsigned" %} 13508 13509 ins_encode(aarch64_enc_cmpw(op1, op2)); 13510 13511 ins_pipe(icmp_reg_reg); 13512 %} 13513 13514 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 13515 %{ 13516 match(Set cr (CmpU op1 zero)); 13517 13518 effect(DEF cr, USE op1); 13519 13520 ins_cost(INSN_COST); 13521 format %{ "cmpw $op1, #0\t# unsigned" %} 13522 13523 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13524 13525 ins_pipe(icmp_reg_imm); 13526 %} 13527 13528 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 13529 %{ 13530 match(Set cr (CmpU op1 op2)); 13531 13532 effect(DEF cr, USE op1); 13533 13534 ins_cost(INSN_COST); 13535 format %{ "cmpw $op1, $op2\t# unsigned" %} 13536 13537 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13538 13539 ins_pipe(icmp_reg_imm); 13540 %} 13541 13542 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 13543 %{ 13544 match(Set cr (CmpU op1 op2)); 13545 13546 effect(DEF cr, USE op1); 13547 13548 ins_cost(INSN_COST * 2); 13549 format %{ "cmpw $op1, $op2\t# unsigned" %} 13550 13551 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13552 13553 ins_pipe(icmp_reg_imm); 13554 %} 13555 13556 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13557 %{ 13558 match(Set cr (CmpL op1 op2)); 13559 13560 effect(DEF cr, USE op1, USE op2); 13561 13562 ins_cost(INSN_COST); 13563 format %{ "cmp $op1, $op2" %} 13564 13565 ins_encode(aarch64_enc_cmp(op1, op2)); 13566 13567 ins_pipe(icmp_reg_reg); 13568 %} 13569 13570 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 13571 %{ 13572 match(Set cr (CmpL op1 zero)); 13573 13574 effect(DEF cr, USE op1); 13575 13576 ins_cost(INSN_COST); 13577 format %{ "tst $op1" %} 13578 13579 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13580 13581 ins_pipe(icmp_reg_imm); 13582 %} 13583 13584 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 13585 %{ 13586 match(Set cr (CmpL op1 op2)); 13587 13588 effect(DEF cr, USE op1); 13589 13590 ins_cost(INSN_COST); 13591 format %{ "cmp $op1, $op2" %} 13592 13593 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13594 13595 ins_pipe(icmp_reg_imm); 13596 %} 13597 13598 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 13599 %{ 13600 match(Set cr (CmpL op1 op2)); 13601 13602 effect(DEF cr, USE op1); 13603 13604 ins_cost(INSN_COST * 2); 13605 format %{ "cmp $op1, $op2" %} 13606 13607 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13608 13609 ins_pipe(icmp_reg_imm); 13610 %} 13611 13612 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 13613 %{ 13614 match(Set cr (CmpUL op1 op2)); 13615 13616 effect(DEF cr, USE op1, USE op2); 13617 13618 ins_cost(INSN_COST); 13619 format %{ "cmp $op1, $op2" %} 13620 13621 ins_encode(aarch64_enc_cmp(op1, op2)); 13622 13623 ins_pipe(icmp_reg_reg); 13624 %} 13625 13626 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 13627 %{ 13628 match(Set cr (CmpUL op1 zero)); 13629 13630 effect(DEF cr, USE op1); 13631 13632 ins_cost(INSN_COST); 13633 format %{ "tst $op1" %} 13634 13635 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13636 13637 ins_pipe(icmp_reg_imm); 13638 %} 13639 13640 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 13641 %{ 13642 match(Set cr (CmpUL op1 op2)); 13643 13644 effect(DEF cr, USE op1); 13645 13646 ins_cost(INSN_COST); 13647 format %{ "cmp $op1, $op2" %} 13648 13649 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13650 13651 ins_pipe(icmp_reg_imm); 13652 %} 13653 13654 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 13655 %{ 13656 match(Set cr (CmpUL op1 op2)); 13657 13658 effect(DEF cr, USE op1); 13659 13660 ins_cost(INSN_COST * 2); 13661 format %{ "cmp $op1, $op2" %} 13662 13663 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13664 13665 ins_pipe(icmp_reg_imm); 13666 %} 13667 13668 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 13669 %{ 13670 match(Set cr (CmpP op1 op2)); 13671 13672 effect(DEF cr, USE op1, USE op2); 13673 13674 ins_cost(INSN_COST); 13675 format %{ "cmp $op1, $op2\t // ptr" %} 13676 13677 ins_encode(aarch64_enc_cmpp(op1, op2)); 13678 13679 ins_pipe(icmp_reg_reg); 13680 %} 13681 13682 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 13683 %{ 13684 match(Set cr (CmpN op1 op2)); 13685 13686 effect(DEF cr, USE op1, USE op2); 13687 13688 ins_cost(INSN_COST); 13689 format %{ "cmp $op1, $op2\t // compressed ptr" %} 13690 13691 ins_encode(aarch64_enc_cmpn(op1, op2)); 13692 13693 ins_pipe(icmp_reg_reg); 13694 %} 13695 13696 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 13697 %{ 13698 match(Set cr (CmpP op1 zero)); 13699 13700 effect(DEF cr, USE op1, USE zero); 13701 13702 ins_cost(INSN_COST); 13703 format %{ "cmp $op1, 0\t // ptr" %} 13704 13705 ins_encode(aarch64_enc_testp(op1)); 13706 13707 ins_pipe(icmp_reg_imm); 13708 %} 13709 13710 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 13711 %{ 13712 match(Set cr (CmpN op1 zero)); 13713 13714 effect(DEF cr, USE op1, USE zero); 13715 13716 ins_cost(INSN_COST); 13717 format %{ "cmp $op1, 0\t // compressed ptr" %} 13718 13719 ins_encode(aarch64_enc_testn(op1)); 13720 13721 ins_pipe(icmp_reg_imm); 13722 %} 13723 13724 // FP comparisons 13725 // 13726 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 13727 // using normal cmpOp. See declaration of rFlagsReg for details. 13728 13729 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 13730 %{ 13731 match(Set cr (CmpF src1 src2)); 13732 13733 ins_cost(3 * INSN_COST); 13734 format %{ "fcmps $src1, $src2" %} 13735 13736 ins_encode %{ 13737 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13738 %} 13739 13740 ins_pipe(pipe_class_compare); 13741 %} 13742 13743 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 13744 %{ 13745 match(Set cr (CmpF src1 src2)); 13746 13747 ins_cost(3 * INSN_COST); 13748 format %{ "fcmps $src1, 0.0" %} 13749 13750 ins_encode %{ 13751 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 13752 %} 13753 13754 ins_pipe(pipe_class_compare); 13755 %} 13756 // FROM HERE 13757 13758 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 13759 %{ 13760 match(Set cr (CmpD src1 src2)); 13761 13762 ins_cost(3 * INSN_COST); 13763 format %{ "fcmpd $src1, $src2" %} 13764 13765 ins_encode %{ 13766 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13767 %} 13768 13769 ins_pipe(pipe_class_compare); 13770 %} 13771 13772 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 13773 %{ 13774 match(Set cr (CmpD src1 src2)); 13775 13776 ins_cost(3 * INSN_COST); 13777 format %{ "fcmpd $src1, 0.0" %} 13778 13779 ins_encode %{ 13780 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 13781 %} 13782 13783 ins_pipe(pipe_class_compare); 13784 %} 13785 13786 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 13787 %{ 13788 match(Set dst (CmpF3 src1 src2)); 13789 effect(KILL cr); 13790 13791 ins_cost(5 * INSN_COST); 13792 format %{ "fcmps $src1, $src2\n\t" 13793 "csinvw($dst, zr, zr, eq\n\t" 13794 "csnegw($dst, $dst, $dst, lt)" 13795 %} 13796 13797 ins_encode %{ 13798 Label done; 13799 FloatRegister s1 = as_FloatRegister($src1$$reg); 13800 FloatRegister s2 = as_FloatRegister($src2$$reg); 13801 Register d = as_Register($dst$$reg); 13802 __ fcmps(s1, s2); 13803 // installs 0 if EQ else -1 13804 __ csinvw(d, zr, zr, Assembler::EQ); 13805 // keeps -1 if less or unordered else installs 1 13806 __ csnegw(d, d, d, Assembler::LT); 13807 __ bind(done); 13808 %} 13809 13810 ins_pipe(pipe_class_default); 13811 13812 %} 13813 13814 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 13815 %{ 13816 match(Set dst (CmpD3 src1 src2)); 13817 effect(KILL cr); 13818 13819 ins_cost(5 * INSN_COST); 13820 format %{ "fcmpd $src1, $src2\n\t" 13821 "csinvw($dst, zr, zr, eq\n\t" 13822 "csnegw($dst, $dst, $dst, lt)" 13823 %} 13824 13825 ins_encode %{ 13826 Label done; 13827 FloatRegister s1 = as_FloatRegister($src1$$reg); 13828 FloatRegister s2 = as_FloatRegister($src2$$reg); 13829 Register d = as_Register($dst$$reg); 13830 __ fcmpd(s1, s2); 13831 // installs 0 if EQ else -1 13832 __ csinvw(d, zr, zr, Assembler::EQ); 13833 // keeps -1 if less or unordered else installs 1 13834 __ csnegw(d, d, d, Assembler::LT); 13835 __ bind(done); 13836 %} 13837 ins_pipe(pipe_class_default); 13838 13839 %} 13840 13841 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 13842 %{ 13843 match(Set dst (CmpF3 src1 zero)); 13844 effect(KILL cr); 13845 13846 ins_cost(5 * INSN_COST); 13847 format %{ "fcmps $src1, 0.0\n\t" 13848 "csinvw($dst, zr, zr, eq\n\t" 13849 "csnegw($dst, $dst, $dst, lt)" 13850 %} 13851 13852 ins_encode %{ 13853 Label done; 13854 FloatRegister s1 = as_FloatRegister($src1$$reg); 13855 Register d = as_Register($dst$$reg); 13856 __ fcmps(s1, 0.0); 13857 // installs 0 if EQ else -1 13858 __ csinvw(d, zr, zr, Assembler::EQ); 13859 // keeps -1 if less or unordered else installs 1 13860 __ csnegw(d, d, d, Assembler::LT); 13861 __ bind(done); 13862 %} 13863 13864 ins_pipe(pipe_class_default); 13865 13866 %} 13867 13868 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 13869 %{ 13870 match(Set dst (CmpD3 src1 zero)); 13871 effect(KILL cr); 13872 13873 ins_cost(5 * INSN_COST); 13874 format %{ "fcmpd $src1, 0.0\n\t" 13875 "csinvw($dst, zr, zr, eq\n\t" 13876 "csnegw($dst, $dst, $dst, lt)" 13877 %} 13878 13879 ins_encode %{ 13880 Label done; 13881 FloatRegister s1 = as_FloatRegister($src1$$reg); 13882 Register d = as_Register($dst$$reg); 13883 __ fcmpd(s1, 0.0); 13884 // installs 0 if EQ else -1 13885 __ csinvw(d, zr, zr, Assembler::EQ); 13886 // keeps -1 if less or unordered else installs 1 13887 __ csnegw(d, d, d, Assembler::LT); 13888 __ bind(done); 13889 %} 13890 ins_pipe(pipe_class_default); 13891 13892 %} 13893 13894 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 13895 %{ 13896 match(Set dst (CmpLTMask p q)); 13897 effect(KILL cr); 13898 13899 ins_cost(3 * INSN_COST); 13900 13901 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 13902 "csetw $dst, lt\n\t" 13903 "subw $dst, zr, $dst" 13904 %} 13905 13906 ins_encode %{ 13907 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 13908 __ csetw(as_Register($dst$$reg), Assembler::LT); 13909 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 13910 %} 13911 13912 ins_pipe(ialu_reg_reg); 13913 %} 13914 13915 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 13916 %{ 13917 match(Set dst (CmpLTMask src zero)); 13918 effect(KILL cr); 13919 13920 ins_cost(INSN_COST); 13921 13922 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 13923 13924 ins_encode %{ 13925 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 13926 %} 13927 13928 ins_pipe(ialu_reg_shift); 13929 %} 13930 13931 // ============================================================================ 13932 // Max and Min 13933 13934 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13935 %{ 13936 match(Set dst (MinI src1 src2)); 13937 13938 effect(DEF dst, USE src1, USE src2, KILL cr); 13939 size(8); 13940 13941 ins_cost(INSN_COST * 3); 13942 format %{ 13943 "cmpw $src1 $src2\t signed int\n\t" 13944 "cselw $dst, $src1, $src2 lt\t" 13945 %} 13946 13947 ins_encode %{ 13948 __ cmpw(as_Register($src1$$reg), 13949 as_Register($src2$$reg)); 13950 __ cselw(as_Register($dst$$reg), 13951 as_Register($src1$$reg), 13952 as_Register($src2$$reg), 13953 Assembler::LT); 13954 %} 13955 13956 ins_pipe(ialu_reg_reg); 13957 %} 13958 // FROM HERE 13959 13960 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13961 %{ 13962 match(Set dst (MaxI src1 src2)); 13963 13964 effect(DEF dst, USE src1, USE src2, KILL cr); 13965 size(8); 13966 13967 ins_cost(INSN_COST * 3); 13968 format %{ 13969 "cmpw $src1 $src2\t signed int\n\t" 13970 "cselw $dst, $src1, $src2 gt\t" 13971 %} 13972 13973 ins_encode %{ 13974 __ cmpw(as_Register($src1$$reg), 13975 as_Register($src2$$reg)); 13976 __ cselw(as_Register($dst$$reg), 13977 as_Register($src1$$reg), 13978 as_Register($src2$$reg), 13979 Assembler::GT); 13980 %} 13981 13982 ins_pipe(ialu_reg_reg); 13983 %} 13984 13985 // ============================================================================ 13986 // Branch Instructions 13987 13988 // Direct Branch. 13989 instruct branch(label lbl) 13990 %{ 13991 match(Goto); 13992 13993 effect(USE lbl); 13994 13995 ins_cost(BRANCH_COST); 13996 format %{ "b $lbl" %} 13997 13998 ins_encode(aarch64_enc_b(lbl)); 13999 14000 ins_pipe(pipe_branch); 14001 %} 14002 14003 // Conditional Near Branch 14004 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14005 %{ 14006 // Same match rule as `branchConFar'. 14007 match(If cmp cr); 14008 14009 effect(USE lbl); 14010 14011 ins_cost(BRANCH_COST); 14012 // If set to 1 this indicates that the current instruction is a 14013 // short variant of a long branch. This avoids using this 14014 // instruction in first-pass matching. It will then only be used in 14015 // the `Shorten_branches' pass. 14016 // ins_short_branch(1); 14017 format %{ "b$cmp $lbl" %} 14018 14019 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14020 14021 ins_pipe(pipe_branch_cond); 14022 %} 14023 14024 // Conditional Near Branch Unsigned 14025 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14026 %{ 14027 // Same match rule as `branchConFar'. 14028 match(If cmp cr); 14029 14030 effect(USE lbl); 14031 14032 ins_cost(BRANCH_COST); 14033 // If set to 1 this indicates that the current instruction is a 14034 // short variant of a long branch. This avoids using this 14035 // instruction in first-pass matching. It will then only be used in 14036 // the `Shorten_branches' pass. 14037 // ins_short_branch(1); 14038 format %{ "b$cmp $lbl\t# unsigned" %} 14039 14040 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14041 14042 ins_pipe(pipe_branch_cond); 14043 %} 14044 14045 // Make use of CBZ and CBNZ. These instructions, as well as being 14046 // shorter than (cmp; branch), have the additional benefit of not 14047 // killing the flags. 14048 14049 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14050 match(If cmp (CmpI op1 op2)); 14051 effect(USE labl); 14052 14053 ins_cost(BRANCH_COST); 14054 format %{ "cbw$cmp $op1, $labl" %} 14055 ins_encode %{ 14056 Label* L = $labl$$label; 14057 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14058 if (cond == Assembler::EQ) 14059 __ cbzw($op1$$Register, *L); 14060 else 14061 __ cbnzw($op1$$Register, *L); 14062 %} 14063 ins_pipe(pipe_cmp_branch); 14064 %} 14065 14066 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14067 match(If cmp (CmpL op1 op2)); 14068 effect(USE labl); 14069 14070 ins_cost(BRANCH_COST); 14071 format %{ "cb$cmp $op1, $labl" %} 14072 ins_encode %{ 14073 Label* L = $labl$$label; 14074 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14075 if (cond == Assembler::EQ) 14076 __ cbz($op1$$Register, *L); 14077 else 14078 __ cbnz($op1$$Register, *L); 14079 %} 14080 ins_pipe(pipe_cmp_branch); 14081 %} 14082 14083 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14084 match(If cmp (CmpP op1 op2)); 14085 effect(USE labl); 14086 14087 ins_cost(BRANCH_COST); 14088 format %{ "cb$cmp $op1, $labl" %} 14089 ins_encode %{ 14090 Label* L = $labl$$label; 14091 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14092 if (cond == Assembler::EQ) 14093 __ cbz($op1$$Register, *L); 14094 else 14095 __ cbnz($op1$$Register, *L); 14096 %} 14097 ins_pipe(pipe_cmp_branch); 14098 %} 14099 14100 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14101 match(If cmp (CmpN op1 op2)); 14102 effect(USE labl); 14103 14104 ins_cost(BRANCH_COST); 14105 format %{ "cbw$cmp $op1, $labl" %} 14106 ins_encode %{ 14107 Label* L = $labl$$label; 14108 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14109 if (cond == Assembler::EQ) 14110 __ cbzw($op1$$Register, *L); 14111 else 14112 __ cbnzw($op1$$Register, *L); 14113 %} 14114 ins_pipe(pipe_cmp_branch); 14115 %} 14116 14117 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14118 match(If cmp (CmpP (DecodeN oop) zero)); 14119 effect(USE labl); 14120 14121 ins_cost(BRANCH_COST); 14122 format %{ "cb$cmp $oop, $labl" %} 14123 ins_encode %{ 14124 Label* L = $labl$$label; 14125 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14126 if (cond == Assembler::EQ) 14127 __ cbzw($oop$$Register, *L); 14128 else 14129 __ cbnzw($oop$$Register, *L); 14130 %} 14131 ins_pipe(pipe_cmp_branch); 14132 %} 14133 14134 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14135 match(If cmp (CmpU op1 op2)); 14136 effect(USE labl); 14137 14138 ins_cost(BRANCH_COST); 14139 format %{ "cbw$cmp $op1, $labl" %} 14140 ins_encode %{ 14141 Label* L = $labl$$label; 14142 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14143 if (cond == Assembler::EQ || cond == Assembler::LS) 14144 __ cbzw($op1$$Register, *L); 14145 else 14146 __ cbnzw($op1$$Register, *L); 14147 %} 14148 ins_pipe(pipe_cmp_branch); 14149 %} 14150 14151 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14152 match(If cmp (CmpUL op1 op2)); 14153 effect(USE labl); 14154 14155 ins_cost(BRANCH_COST); 14156 format %{ "cb$cmp $op1, $labl" %} 14157 ins_encode %{ 14158 Label* L = $labl$$label; 14159 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14160 if (cond == Assembler::EQ || cond == Assembler::LS) 14161 __ cbz($op1$$Register, *L); 14162 else 14163 __ cbnz($op1$$Register, *L); 14164 %} 14165 ins_pipe(pipe_cmp_branch); 14166 %} 14167 14168 // Test bit and Branch 14169 14170 // Patterns for short (< 32KiB) variants 14171 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14172 match(If cmp (CmpL op1 op2)); 14173 effect(USE labl); 14174 14175 ins_cost(BRANCH_COST); 14176 format %{ "cb$cmp $op1, $labl # long" %} 14177 ins_encode %{ 14178 Label* L = $labl$$label; 14179 Assembler::Condition cond = 14180 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14181 __ tbr(cond, $op1$$Register, 63, *L); 14182 %} 14183 ins_pipe(pipe_cmp_branch); 14184 ins_short_branch(1); 14185 %} 14186 14187 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14188 match(If cmp (CmpI op1 op2)); 14189 effect(USE labl); 14190 14191 ins_cost(BRANCH_COST); 14192 format %{ "cb$cmp $op1, $labl # int" %} 14193 ins_encode %{ 14194 Label* L = $labl$$label; 14195 Assembler::Condition cond = 14196 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14197 __ tbr(cond, $op1$$Register, 31, *L); 14198 %} 14199 ins_pipe(pipe_cmp_branch); 14200 ins_short_branch(1); 14201 %} 14202 14203 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14204 match(If cmp (CmpL (AndL op1 op2) op3)); 14205 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14206 effect(USE labl); 14207 14208 ins_cost(BRANCH_COST); 14209 format %{ "tb$cmp $op1, $op2, $labl" %} 14210 ins_encode %{ 14211 Label* L = $labl$$label; 14212 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14213 int bit = exact_log2($op2$$constant); 14214 __ tbr(cond, $op1$$Register, bit, *L); 14215 %} 14216 ins_pipe(pipe_cmp_branch); 14217 ins_short_branch(1); 14218 %} 14219 14220 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14221 match(If cmp (CmpI (AndI op1 op2) op3)); 14222 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14223 effect(USE labl); 14224 14225 ins_cost(BRANCH_COST); 14226 format %{ "tb$cmp $op1, $op2, $labl" %} 14227 ins_encode %{ 14228 Label* L = $labl$$label; 14229 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14230 int bit = exact_log2($op2$$constant); 14231 __ tbr(cond, $op1$$Register, bit, *L); 14232 %} 14233 ins_pipe(pipe_cmp_branch); 14234 ins_short_branch(1); 14235 %} 14236 14237 // And far variants 14238 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14239 match(If cmp (CmpL op1 op2)); 14240 effect(USE labl); 14241 14242 ins_cost(BRANCH_COST); 14243 format %{ "cb$cmp $op1, $labl # long" %} 14244 ins_encode %{ 14245 Label* L = $labl$$label; 14246 Assembler::Condition cond = 14247 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14248 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14249 %} 14250 ins_pipe(pipe_cmp_branch); 14251 %} 14252 14253 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14254 match(If cmp (CmpI op1 op2)); 14255 effect(USE labl); 14256 14257 ins_cost(BRANCH_COST); 14258 format %{ "cb$cmp $op1, $labl # int" %} 14259 ins_encode %{ 14260 Label* L = $labl$$label; 14261 Assembler::Condition cond = 14262 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14263 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14264 %} 14265 ins_pipe(pipe_cmp_branch); 14266 %} 14267 14268 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14269 match(If cmp (CmpL (AndL op1 op2) op3)); 14270 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14271 effect(USE labl); 14272 14273 ins_cost(BRANCH_COST); 14274 format %{ "tb$cmp $op1, $op2, $labl" %} 14275 ins_encode %{ 14276 Label* L = $labl$$label; 14277 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14278 int bit = exact_log2($op2$$constant); 14279 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14280 %} 14281 ins_pipe(pipe_cmp_branch); 14282 %} 14283 14284 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14285 match(If cmp (CmpI (AndI op1 op2) op3)); 14286 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14287 effect(USE labl); 14288 14289 ins_cost(BRANCH_COST); 14290 format %{ "tb$cmp $op1, $op2, $labl" %} 14291 ins_encode %{ 14292 Label* L = $labl$$label; 14293 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14294 int bit = exact_log2($op2$$constant); 14295 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14296 %} 14297 ins_pipe(pipe_cmp_branch); 14298 %} 14299 14300 // Test bits 14301 14302 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14303 match(Set cr (CmpL (AndL op1 op2) op3)); 14304 predicate(Assembler::operand_valid_for_logical_immediate 14305 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14306 14307 ins_cost(INSN_COST); 14308 format %{ "tst $op1, $op2 # long" %} 14309 ins_encode %{ 14310 __ tst($op1$$Register, $op2$$constant); 14311 %} 14312 ins_pipe(ialu_reg_reg); 14313 %} 14314 14315 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14316 match(Set cr (CmpI (AndI op1 op2) op3)); 14317 predicate(Assembler::operand_valid_for_logical_immediate 14318 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14319 14320 ins_cost(INSN_COST); 14321 format %{ "tst $op1, $op2 # int" %} 14322 ins_encode %{ 14323 __ tstw($op1$$Register, $op2$$constant); 14324 %} 14325 ins_pipe(ialu_reg_reg); 14326 %} 14327 14328 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14329 match(Set cr (CmpL (AndL op1 op2) op3)); 14330 14331 ins_cost(INSN_COST); 14332 format %{ "tst $op1, $op2 # long" %} 14333 ins_encode %{ 14334 __ tst($op1$$Register, $op2$$Register); 14335 %} 14336 ins_pipe(ialu_reg_reg); 14337 %} 14338 14339 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14340 match(Set cr (CmpI (AndI op1 op2) op3)); 14341 14342 ins_cost(INSN_COST); 14343 format %{ "tstw $op1, $op2 # int" %} 14344 ins_encode %{ 14345 __ tstw($op1$$Register, $op2$$Register); 14346 %} 14347 ins_pipe(ialu_reg_reg); 14348 %} 14349 14350 14351 // Conditional Far Branch 14352 // Conditional Far Branch Unsigned 14353 // TODO: fixme 14354 14355 // counted loop end branch near 14356 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14357 %{ 14358 match(CountedLoopEnd cmp cr); 14359 14360 effect(USE lbl); 14361 14362 ins_cost(BRANCH_COST); 14363 // short variant. 14364 // ins_short_branch(1); 14365 format %{ "b$cmp $lbl \t// counted loop end" %} 14366 14367 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14368 14369 ins_pipe(pipe_branch); 14370 %} 14371 14372 // counted loop end branch near Unsigned 14373 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14374 %{ 14375 match(CountedLoopEnd cmp cr); 14376 14377 effect(USE lbl); 14378 14379 ins_cost(BRANCH_COST); 14380 // short variant. 14381 // ins_short_branch(1); 14382 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14383 14384 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14385 14386 ins_pipe(pipe_branch); 14387 %} 14388 14389 // counted loop end branch far 14390 // counted loop end branch far unsigned 14391 // TODO: fixme 14392 14393 // ============================================================================ 14394 // inlined locking and unlocking 14395 14396 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14397 %{ 14398 match(Set cr (FastLock object box)); 14399 effect(TEMP tmp, TEMP tmp2); 14400 14401 // TODO 14402 // identify correct cost 14403 ins_cost(5 * INSN_COST); 14404 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14405 14406 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14407 14408 ins_pipe(pipe_serial); 14409 %} 14410 14411 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14412 %{ 14413 match(Set cr (FastUnlock object box)); 14414 effect(TEMP tmp, TEMP tmp2); 14415 14416 ins_cost(5 * INSN_COST); 14417 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14418 14419 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14420 14421 ins_pipe(pipe_serial); 14422 %} 14423 14424 14425 // ============================================================================ 14426 // Safepoint Instructions 14427 14428 // TODO 14429 // provide a near and far version of this code 14430 14431 instruct safePoint(rFlagsReg cr, iRegP poll) 14432 %{ 14433 match(SafePoint poll); 14434 effect(KILL cr); 14435 14436 format %{ 14437 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14438 %} 14439 ins_encode %{ 14440 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14441 %} 14442 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14443 %} 14444 14445 14446 // ============================================================================ 14447 // Procedure Call/Return Instructions 14448 14449 // Call Java Static Instruction 14450 14451 instruct CallStaticJavaDirect(method meth) 14452 %{ 14453 match(CallStaticJava); 14454 14455 effect(USE meth); 14456 14457 ins_cost(CALL_COST); 14458 14459 format %{ "call,static $meth \t// ==> " %} 14460 14461 ins_encode( aarch64_enc_java_static_call(meth), 14462 aarch64_enc_call_epilog ); 14463 14464 ins_pipe(pipe_class_call); 14465 %} 14466 14467 // TO HERE 14468 14469 // Call Java Dynamic Instruction 14470 instruct CallDynamicJavaDirect(method meth) 14471 %{ 14472 match(CallDynamicJava); 14473 14474 effect(USE meth); 14475 14476 ins_cost(CALL_COST); 14477 14478 format %{ "CALL,dynamic $meth \t// ==> " %} 14479 14480 ins_encode( aarch64_enc_java_dynamic_call(meth), 14481 aarch64_enc_call_epilog ); 14482 14483 ins_pipe(pipe_class_call); 14484 %} 14485 14486 // Call Runtime Instruction 14487 14488 instruct CallRuntimeDirect(method meth) 14489 %{ 14490 match(CallRuntime); 14491 14492 effect(USE meth); 14493 14494 ins_cost(CALL_COST); 14495 14496 format %{ "CALL, runtime $meth" %} 14497 14498 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14499 14500 ins_pipe(pipe_class_call); 14501 %} 14502 14503 // Call Runtime Instruction 14504 14505 instruct CallLeafDirect(method meth) 14506 %{ 14507 match(CallLeaf); 14508 14509 effect(USE meth); 14510 14511 ins_cost(CALL_COST); 14512 14513 format %{ "CALL, runtime leaf $meth" %} 14514 14515 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14516 14517 ins_pipe(pipe_class_call); 14518 %} 14519 14520 // Call Runtime Instruction 14521 14522 instruct CallLeafNoFPDirect(method meth) 14523 %{ 14524 match(CallLeafNoFP); 14525 14526 effect(USE meth); 14527 14528 ins_cost(CALL_COST); 14529 14530 format %{ "CALL, runtime leaf nofp $meth" %} 14531 14532 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14533 14534 ins_pipe(pipe_class_call); 14535 %} 14536 14537 // Tail Call; Jump from runtime stub to Java code. 14538 // Also known as an 'interprocedural jump'. 14539 // Target of jump will eventually return to caller. 14540 // TailJump below removes the return address. 14541 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 14542 %{ 14543 match(TailCall jump_target method_oop); 14544 14545 ins_cost(CALL_COST); 14546 14547 format %{ "br $jump_target\t# $method_oop holds method oop" %} 14548 14549 ins_encode(aarch64_enc_tail_call(jump_target)); 14550 14551 ins_pipe(pipe_class_call); 14552 %} 14553 14554 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 14555 %{ 14556 match(TailJump jump_target ex_oop); 14557 14558 ins_cost(CALL_COST); 14559 14560 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 14561 14562 ins_encode(aarch64_enc_tail_jmp(jump_target)); 14563 14564 ins_pipe(pipe_class_call); 14565 %} 14566 14567 // Create exception oop: created by stack-crawling runtime code. 14568 // Created exception is now available to this handler, and is setup 14569 // just prior to jumping to this handler. No code emitted. 14570 // TODO check 14571 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 14572 instruct CreateException(iRegP_R0 ex_oop) 14573 %{ 14574 match(Set ex_oop (CreateEx)); 14575 14576 format %{ " -- \t// exception oop; no code emitted" %} 14577 14578 size(0); 14579 14580 ins_encode( /*empty*/ ); 14581 14582 ins_pipe(pipe_class_empty); 14583 %} 14584 14585 // Rethrow exception: The exception oop will come in the first 14586 // argument position. Then JUMP (not call) to the rethrow stub code. 14587 instruct RethrowException() %{ 14588 match(Rethrow); 14589 ins_cost(CALL_COST); 14590 14591 format %{ "b rethrow_stub" %} 14592 14593 ins_encode( aarch64_enc_rethrow() ); 14594 14595 ins_pipe(pipe_class_call); 14596 %} 14597 14598 14599 // Return Instruction 14600 // epilog node loads ret address into lr as part of frame pop 14601 instruct Ret() 14602 %{ 14603 match(Return); 14604 14605 format %{ "ret\t// return register" %} 14606 14607 ins_encode( aarch64_enc_ret() ); 14608 14609 ins_pipe(pipe_branch); 14610 %} 14611 14612 // Die now. 14613 instruct ShouldNotReachHere() %{ 14614 match(Halt); 14615 14616 ins_cost(CALL_COST); 14617 format %{ "ShouldNotReachHere" %} 14618 14619 ins_encode %{ 14620 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 14621 // return true 14622 __ dpcs1(0xdead + 1); 14623 %} 14624 14625 ins_pipe(pipe_class_default); 14626 %} 14627 14628 // ============================================================================ 14629 // Partial Subtype Check 14630 // 14631 // superklass array for an instance of the superklass. Set a hidden 14632 // internal cache on a hit (cache is checked with exposed code in 14633 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14634 // encoding ALSO sets flags. 14635 14636 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 14637 %{ 14638 match(Set result (PartialSubtypeCheck sub super)); 14639 effect(KILL cr, KILL temp); 14640 14641 ins_cost(1100); // slightly larger than the next version 14642 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14643 14644 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14645 14646 opcode(0x1); // Force zero of result reg on hit 14647 14648 ins_pipe(pipe_class_memory); 14649 %} 14650 14651 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 14652 %{ 14653 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 14654 effect(KILL temp, KILL result); 14655 14656 ins_cost(1100); // slightly larger than the next version 14657 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 14658 14659 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14660 14661 opcode(0x0); // Don't zero result reg on hit 14662 14663 ins_pipe(pipe_class_memory); 14664 %} 14665 14666 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14667 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14668 %{ 14669 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 14670 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14671 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14672 14673 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14674 ins_encode %{ 14675 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14676 __ string_compare($str1$$Register, $str2$$Register, 14677 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14678 $tmp1$$Register, $tmp2$$Register, 14679 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 14680 %} 14681 ins_pipe(pipe_class_memory); 14682 %} 14683 14684 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14685 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14686 %{ 14687 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 14688 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14689 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14690 14691 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14692 ins_encode %{ 14693 __ string_compare($str1$$Register, $str2$$Register, 14694 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14695 $tmp1$$Register, $tmp2$$Register, 14696 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 14697 %} 14698 ins_pipe(pipe_class_memory); 14699 %} 14700 14701 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14702 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14703 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14704 %{ 14705 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 14706 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14707 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14708 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14709 14710 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14711 ins_encode %{ 14712 __ string_compare($str1$$Register, $str2$$Register, 14713 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14714 $tmp1$$Register, $tmp2$$Register, 14715 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14716 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 14717 %} 14718 ins_pipe(pipe_class_memory); 14719 %} 14720 14721 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14722 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14723 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14724 %{ 14725 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 14726 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14727 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14728 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14729 14730 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14731 ins_encode %{ 14732 __ string_compare($str1$$Register, $str2$$Register, 14733 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14734 $tmp1$$Register, $tmp2$$Register, 14735 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14736 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 14737 %} 14738 ins_pipe(pipe_class_memory); 14739 %} 14740 14741 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14742 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14743 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14744 %{ 14745 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14746 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14747 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14748 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14749 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 14750 14751 ins_encode %{ 14752 __ string_indexof($str1$$Register, $str2$$Register, 14753 $cnt1$$Register, $cnt2$$Register, 14754 $tmp1$$Register, $tmp2$$Register, 14755 $tmp3$$Register, $tmp4$$Register, 14756 $tmp5$$Register, $tmp6$$Register, 14757 -1, $result$$Register, StrIntrinsicNode::UU); 14758 %} 14759 ins_pipe(pipe_class_memory); 14760 %} 14761 14762 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14763 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14764 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14765 %{ 14766 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14767 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14768 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14769 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14770 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 14771 14772 ins_encode %{ 14773 __ string_indexof($str1$$Register, $str2$$Register, 14774 $cnt1$$Register, $cnt2$$Register, 14775 $tmp1$$Register, $tmp2$$Register, 14776 $tmp3$$Register, $tmp4$$Register, 14777 $tmp5$$Register, $tmp6$$Register, 14778 -1, $result$$Register, StrIntrinsicNode::LL); 14779 %} 14780 ins_pipe(pipe_class_memory); 14781 %} 14782 14783 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14784 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14785 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14786 %{ 14787 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14788 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14789 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14790 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14791 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 14792 14793 ins_encode %{ 14794 __ string_indexof($str1$$Register, $str2$$Register, 14795 $cnt1$$Register, $cnt2$$Register, 14796 $tmp1$$Register, $tmp2$$Register, 14797 $tmp3$$Register, $tmp4$$Register, 14798 $tmp5$$Register, $tmp6$$Register, 14799 -1, $result$$Register, StrIntrinsicNode::UL); 14800 %} 14801 ins_pipe(pipe_class_memory); 14802 %} 14803 14804 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14805 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14806 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14807 %{ 14808 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14809 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14810 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14811 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14812 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 14813 14814 ins_encode %{ 14815 int icnt2 = (int)$int_cnt2$$constant; 14816 __ string_indexof($str1$$Register, $str2$$Register, 14817 $cnt1$$Register, zr, 14818 $tmp1$$Register, $tmp2$$Register, 14819 $tmp3$$Register, $tmp4$$Register, zr, zr, 14820 icnt2, $result$$Register, StrIntrinsicNode::UU); 14821 %} 14822 ins_pipe(pipe_class_memory); 14823 %} 14824 14825 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14826 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14827 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14828 %{ 14829 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14830 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14831 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14832 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14833 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 14834 14835 ins_encode %{ 14836 int icnt2 = (int)$int_cnt2$$constant; 14837 __ string_indexof($str1$$Register, $str2$$Register, 14838 $cnt1$$Register, zr, 14839 $tmp1$$Register, $tmp2$$Register, 14840 $tmp3$$Register, $tmp4$$Register, zr, zr, 14841 icnt2, $result$$Register, StrIntrinsicNode::LL); 14842 %} 14843 ins_pipe(pipe_class_memory); 14844 %} 14845 14846 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14847 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14848 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14849 %{ 14850 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14851 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14852 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14853 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14854 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 14855 14856 ins_encode %{ 14857 int icnt2 = (int)$int_cnt2$$constant; 14858 __ string_indexof($str1$$Register, $str2$$Register, 14859 $cnt1$$Register, zr, 14860 $tmp1$$Register, $tmp2$$Register, 14861 $tmp3$$Register, $tmp4$$Register, zr, zr, 14862 icnt2, $result$$Register, StrIntrinsicNode::UL); 14863 %} 14864 ins_pipe(pipe_class_memory); 14865 %} 14866 14867 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 14868 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14869 iRegINoSp tmp3, rFlagsReg cr) 14870 %{ 14871 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 14872 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 14873 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14874 14875 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 14876 14877 ins_encode %{ 14878 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 14879 $result$$Register, $tmp1$$Register, $tmp2$$Register, 14880 $tmp3$$Register); 14881 %} 14882 ins_pipe(pipe_class_memory); 14883 %} 14884 14885 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14886 iRegI_R0 result, rFlagsReg cr) 14887 %{ 14888 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 14889 match(Set result (StrEquals (Binary str1 str2) cnt)); 14890 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14891 14892 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14893 ins_encode %{ 14894 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14895 __ string_equals($str1$$Register, $str2$$Register, 14896 $result$$Register, $cnt$$Register, 1); 14897 %} 14898 ins_pipe(pipe_class_memory); 14899 %} 14900 14901 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14902 iRegI_R0 result, rFlagsReg cr) 14903 %{ 14904 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 14905 match(Set result (StrEquals (Binary str1 str2) cnt)); 14906 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14907 14908 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14909 ins_encode %{ 14910 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14911 __ string_equals($str1$$Register, $str2$$Register, 14912 $result$$Register, $cnt$$Register, 2); 14913 %} 14914 ins_pipe(pipe_class_memory); 14915 %} 14916 14917 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14918 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14919 iRegP_R10 tmp, rFlagsReg cr) 14920 %{ 14921 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 14922 match(Set result (AryEq ary1 ary2)); 14923 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14924 14925 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14926 ins_encode %{ 14927 __ arrays_equals($ary1$$Register, $ary2$$Register, 14928 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14929 $result$$Register, $tmp$$Register, 1); 14930 %} 14931 ins_pipe(pipe_class_memory); 14932 %} 14933 14934 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14935 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14936 iRegP_R10 tmp, rFlagsReg cr) 14937 %{ 14938 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 14939 match(Set result (AryEq ary1 ary2)); 14940 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14941 14942 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14943 ins_encode %{ 14944 __ arrays_equals($ary1$$Register, $ary2$$Register, 14945 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14946 $result$$Register, $tmp$$Register, 2); 14947 %} 14948 ins_pipe(pipe_class_memory); 14949 %} 14950 14951 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 14952 %{ 14953 match(Set result (HasNegatives ary1 len)); 14954 effect(USE_KILL ary1, USE_KILL len, KILL cr); 14955 format %{ "has negatives byte[] $ary1,$len -> $result" %} 14956 ins_encode %{ 14957 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 14958 %} 14959 ins_pipe( pipe_slow ); 14960 %} 14961 14962 // fast char[] to byte[] compression 14963 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14964 vRegD_V0 tmp1, vRegD_V1 tmp2, 14965 vRegD_V2 tmp3, vRegD_V3 tmp4, 14966 iRegI_R0 result, rFlagsReg cr) 14967 %{ 14968 match(Set result (StrCompressedCopy src (Binary dst len))); 14969 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14970 14971 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 14972 ins_encode %{ 14973 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 14974 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 14975 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 14976 $result$$Register); 14977 %} 14978 ins_pipe( pipe_slow ); 14979 %} 14980 14981 // fast byte[] to char[] inflation 14982 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 14983 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 14984 %{ 14985 match(Set dummy (StrInflatedCopy src (Binary dst len))); 14986 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14987 14988 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 14989 ins_encode %{ 14990 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 14991 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 14992 %} 14993 ins_pipe(pipe_class_memory); 14994 %} 14995 14996 // encode char[] to byte[] in ISO_8859_1 14997 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14998 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 14999 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15000 iRegI_R0 result, rFlagsReg cr) 15001 %{ 15002 match(Set result (EncodeISOArray src (Binary dst len))); 15003 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15004 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15005 15006 format %{ "Encode array $src,$dst,$len -> $result" %} 15007 ins_encode %{ 15008 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15009 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15010 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15011 %} 15012 ins_pipe( pipe_class_memory ); 15013 %} 15014 15015 // ============================================================================ 15016 // This name is KNOWN by the ADLC and cannot be changed. 15017 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15018 // for this guy. 15019 instruct tlsLoadP(thread_RegP dst) 15020 %{ 15021 match(Set dst (ThreadLocal)); 15022 15023 ins_cost(0); 15024 15025 format %{ " -- \t// $dst=Thread::current(), empty" %} 15026 15027 size(0); 15028 15029 ins_encode( /*empty*/ ); 15030 15031 ins_pipe(pipe_class_empty); 15032 %} 15033 15034 // ====================VECTOR INSTRUCTIONS===================================== 15035 15036 // Load vector (32 bits) 15037 instruct loadV4(vecD dst, vmem4 mem) 15038 %{ 15039 predicate(n->as_LoadVector()->memory_size() == 4); 15040 match(Set dst (LoadVector mem)); 15041 ins_cost(4 * INSN_COST); 15042 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15043 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15044 ins_pipe(vload_reg_mem64); 15045 %} 15046 15047 // Load vector (64 bits) 15048 instruct loadV8(vecD dst, vmem8 mem) 15049 %{ 15050 predicate(n->as_LoadVector()->memory_size() == 8); 15051 match(Set dst (LoadVector mem)); 15052 ins_cost(4 * INSN_COST); 15053 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15054 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15055 ins_pipe(vload_reg_mem64); 15056 %} 15057 15058 // Load Vector (128 bits) 15059 instruct loadV16(vecX dst, vmem16 mem) 15060 %{ 15061 predicate(n->as_LoadVector()->memory_size() == 16); 15062 match(Set dst (LoadVector mem)); 15063 ins_cost(4 * INSN_COST); 15064 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15065 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15066 ins_pipe(vload_reg_mem128); 15067 %} 15068 15069 // Store Vector (32 bits) 15070 instruct storeV4(vecD src, vmem4 mem) 15071 %{ 15072 predicate(n->as_StoreVector()->memory_size() == 4); 15073 match(Set mem (StoreVector mem src)); 15074 ins_cost(4 * INSN_COST); 15075 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15076 ins_encode( aarch64_enc_strvS(src, mem) ); 15077 ins_pipe(vstore_reg_mem64); 15078 %} 15079 15080 // Store Vector (64 bits) 15081 instruct storeV8(vecD src, vmem8 mem) 15082 %{ 15083 predicate(n->as_StoreVector()->memory_size() == 8); 15084 match(Set mem (StoreVector mem src)); 15085 ins_cost(4 * INSN_COST); 15086 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15087 ins_encode( aarch64_enc_strvD(src, mem) ); 15088 ins_pipe(vstore_reg_mem64); 15089 %} 15090 15091 // Store Vector (128 bits) 15092 instruct storeV16(vecX src, vmem16 mem) 15093 %{ 15094 predicate(n->as_StoreVector()->memory_size() == 16); 15095 match(Set mem (StoreVector mem src)); 15096 ins_cost(4 * INSN_COST); 15097 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15098 ins_encode( aarch64_enc_strvQ(src, mem) ); 15099 ins_pipe(vstore_reg_mem128); 15100 %} 15101 15102 instruct replicate8B(vecD dst, iRegIorL2I src) 15103 %{ 15104 predicate(n->as_Vector()->length() == 4 || 15105 n->as_Vector()->length() == 8); 15106 match(Set dst (ReplicateB src)); 15107 ins_cost(INSN_COST); 15108 format %{ "dup $dst, $src\t# vector (8B)" %} 15109 ins_encode %{ 15110 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15111 %} 15112 ins_pipe(vdup_reg_reg64); 15113 %} 15114 15115 instruct replicate16B(vecX dst, iRegIorL2I src) 15116 %{ 15117 predicate(n->as_Vector()->length() == 16); 15118 match(Set dst (ReplicateB src)); 15119 ins_cost(INSN_COST); 15120 format %{ "dup $dst, $src\t# vector (16B)" %} 15121 ins_encode %{ 15122 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15123 %} 15124 ins_pipe(vdup_reg_reg128); 15125 %} 15126 15127 instruct replicate8B_imm(vecD dst, immI con) 15128 %{ 15129 predicate(n->as_Vector()->length() == 4 || 15130 n->as_Vector()->length() == 8); 15131 match(Set dst (ReplicateB con)); 15132 ins_cost(INSN_COST); 15133 format %{ "movi $dst, $con\t# vector(8B)" %} 15134 ins_encode %{ 15135 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15136 %} 15137 ins_pipe(vmovi_reg_imm64); 15138 %} 15139 15140 instruct replicate16B_imm(vecX dst, immI con) 15141 %{ 15142 predicate(n->as_Vector()->length() == 16); 15143 match(Set dst (ReplicateB con)); 15144 ins_cost(INSN_COST); 15145 format %{ "movi $dst, $con\t# vector(16B)" %} 15146 ins_encode %{ 15147 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15148 %} 15149 ins_pipe(vmovi_reg_imm128); 15150 %} 15151 15152 instruct replicate4S(vecD dst, iRegIorL2I src) 15153 %{ 15154 predicate(n->as_Vector()->length() == 2 || 15155 n->as_Vector()->length() == 4); 15156 match(Set dst (ReplicateS src)); 15157 ins_cost(INSN_COST); 15158 format %{ "dup $dst, $src\t# vector (4S)" %} 15159 ins_encode %{ 15160 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15161 %} 15162 ins_pipe(vdup_reg_reg64); 15163 %} 15164 15165 instruct replicate8S(vecX dst, iRegIorL2I src) 15166 %{ 15167 predicate(n->as_Vector()->length() == 8); 15168 match(Set dst (ReplicateS src)); 15169 ins_cost(INSN_COST); 15170 format %{ "dup $dst, $src\t# vector (8S)" %} 15171 ins_encode %{ 15172 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15173 %} 15174 ins_pipe(vdup_reg_reg128); 15175 %} 15176 15177 instruct replicate4S_imm(vecD dst, immI con) 15178 %{ 15179 predicate(n->as_Vector()->length() == 2 || 15180 n->as_Vector()->length() == 4); 15181 match(Set dst (ReplicateS con)); 15182 ins_cost(INSN_COST); 15183 format %{ "movi $dst, $con\t# vector(4H)" %} 15184 ins_encode %{ 15185 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15186 %} 15187 ins_pipe(vmovi_reg_imm64); 15188 %} 15189 15190 instruct replicate8S_imm(vecX dst, immI con) 15191 %{ 15192 predicate(n->as_Vector()->length() == 8); 15193 match(Set dst (ReplicateS con)); 15194 ins_cost(INSN_COST); 15195 format %{ "movi $dst, $con\t# vector(8H)" %} 15196 ins_encode %{ 15197 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15198 %} 15199 ins_pipe(vmovi_reg_imm128); 15200 %} 15201 15202 instruct replicate2I(vecD dst, iRegIorL2I src) 15203 %{ 15204 predicate(n->as_Vector()->length() == 2); 15205 match(Set dst (ReplicateI src)); 15206 ins_cost(INSN_COST); 15207 format %{ "dup $dst, $src\t# vector (2I)" %} 15208 ins_encode %{ 15209 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15210 %} 15211 ins_pipe(vdup_reg_reg64); 15212 %} 15213 15214 instruct replicate4I(vecX dst, iRegIorL2I src) 15215 %{ 15216 predicate(n->as_Vector()->length() == 4); 15217 match(Set dst (ReplicateI src)); 15218 ins_cost(INSN_COST); 15219 format %{ "dup $dst, $src\t# vector (4I)" %} 15220 ins_encode %{ 15221 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15222 %} 15223 ins_pipe(vdup_reg_reg128); 15224 %} 15225 15226 instruct replicate2I_imm(vecD dst, immI con) 15227 %{ 15228 predicate(n->as_Vector()->length() == 2); 15229 match(Set dst (ReplicateI con)); 15230 ins_cost(INSN_COST); 15231 format %{ "movi $dst, $con\t# vector(2I)" %} 15232 ins_encode %{ 15233 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15234 %} 15235 ins_pipe(vmovi_reg_imm64); 15236 %} 15237 15238 instruct replicate4I_imm(vecX dst, immI con) 15239 %{ 15240 predicate(n->as_Vector()->length() == 4); 15241 match(Set dst (ReplicateI con)); 15242 ins_cost(INSN_COST); 15243 format %{ "movi $dst, $con\t# vector(4I)" %} 15244 ins_encode %{ 15245 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15246 %} 15247 ins_pipe(vmovi_reg_imm128); 15248 %} 15249 15250 instruct replicate2L(vecX dst, iRegL src) 15251 %{ 15252 predicate(n->as_Vector()->length() == 2); 15253 match(Set dst (ReplicateL src)); 15254 ins_cost(INSN_COST); 15255 format %{ "dup $dst, $src\t# vector (2L)" %} 15256 ins_encode %{ 15257 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15258 %} 15259 ins_pipe(vdup_reg_reg128); 15260 %} 15261 15262 instruct replicate2L_zero(vecX dst, immI0 zero) 15263 %{ 15264 predicate(n->as_Vector()->length() == 2); 15265 match(Set dst (ReplicateI zero)); 15266 ins_cost(INSN_COST); 15267 format %{ "movi $dst, $zero\t# vector(4I)" %} 15268 ins_encode %{ 15269 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15270 as_FloatRegister($dst$$reg), 15271 as_FloatRegister($dst$$reg)); 15272 %} 15273 ins_pipe(vmovi_reg_imm128); 15274 %} 15275 15276 instruct replicate2F(vecD dst, vRegF src) 15277 %{ 15278 predicate(n->as_Vector()->length() == 2); 15279 match(Set dst (ReplicateF src)); 15280 ins_cost(INSN_COST); 15281 format %{ "dup $dst, $src\t# vector (2F)" %} 15282 ins_encode %{ 15283 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15284 as_FloatRegister($src$$reg)); 15285 %} 15286 ins_pipe(vdup_reg_freg64); 15287 %} 15288 15289 instruct replicate4F(vecX dst, vRegF src) 15290 %{ 15291 predicate(n->as_Vector()->length() == 4); 15292 match(Set dst (ReplicateF src)); 15293 ins_cost(INSN_COST); 15294 format %{ "dup $dst, $src\t# vector (4F)" %} 15295 ins_encode %{ 15296 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15297 as_FloatRegister($src$$reg)); 15298 %} 15299 ins_pipe(vdup_reg_freg128); 15300 %} 15301 15302 instruct replicate2D(vecX dst, vRegD src) 15303 %{ 15304 predicate(n->as_Vector()->length() == 2); 15305 match(Set dst (ReplicateD src)); 15306 ins_cost(INSN_COST); 15307 format %{ "dup $dst, $src\t# vector (2D)" %} 15308 ins_encode %{ 15309 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15310 as_FloatRegister($src$$reg)); 15311 %} 15312 ins_pipe(vdup_reg_dreg128); 15313 %} 15314 15315 // ====================REDUCTION ARITHMETIC==================================== 15316 15317 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15318 %{ 15319 match(Set dst (AddReductionVI src1 src2)); 15320 ins_cost(INSN_COST); 15321 effect(TEMP tmp, TEMP tmp2); 15322 format %{ "umov $tmp, $src2, S, 0\n\t" 15323 "umov $tmp2, $src2, S, 1\n\t" 15324 "addw $dst, $src1, $tmp\n\t" 15325 "addw $dst, $dst, $tmp2\t add reduction2i" 15326 %} 15327 ins_encode %{ 15328 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15329 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15330 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15331 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15332 %} 15333 ins_pipe(pipe_class_default); 15334 %} 15335 15336 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15337 %{ 15338 match(Set dst (AddReductionVI src1 src2)); 15339 ins_cost(INSN_COST); 15340 effect(TEMP tmp, TEMP tmp2); 15341 format %{ "addv $tmp, T4S, $src2\n\t" 15342 "umov $tmp2, $tmp, S, 0\n\t" 15343 "addw $dst, $tmp2, $src1\t add reduction4i" 15344 %} 15345 ins_encode %{ 15346 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15347 as_FloatRegister($src2$$reg)); 15348 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15349 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15350 %} 15351 ins_pipe(pipe_class_default); 15352 %} 15353 15354 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15355 %{ 15356 match(Set dst (MulReductionVI src1 src2)); 15357 ins_cost(INSN_COST); 15358 effect(TEMP tmp, TEMP dst); 15359 format %{ "umov $tmp, $src2, S, 0\n\t" 15360 "mul $dst, $tmp, $src1\n\t" 15361 "umov $tmp, $src2, S, 1\n\t" 15362 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15363 %} 15364 ins_encode %{ 15365 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15366 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15367 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15368 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15369 %} 15370 ins_pipe(pipe_class_default); 15371 %} 15372 15373 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15374 %{ 15375 match(Set dst (MulReductionVI src1 src2)); 15376 ins_cost(INSN_COST); 15377 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15378 format %{ "ins $tmp, $src2, 0, 1\n\t" 15379 "mul $tmp, $tmp, $src2\n\t" 15380 "umov $tmp2, $tmp, S, 0\n\t" 15381 "mul $dst, $tmp2, $src1\n\t" 15382 "umov $tmp2, $tmp, S, 1\n\t" 15383 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15384 %} 15385 ins_encode %{ 15386 __ ins(as_FloatRegister($tmp$$reg), __ D, 15387 as_FloatRegister($src2$$reg), 0, 1); 15388 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15389 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15390 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15391 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15392 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15393 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15394 %} 15395 ins_pipe(pipe_class_default); 15396 %} 15397 15398 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15399 %{ 15400 match(Set dst (AddReductionVF src1 src2)); 15401 ins_cost(INSN_COST); 15402 effect(TEMP tmp, TEMP dst); 15403 format %{ "fadds $dst, $src1, $src2\n\t" 15404 "ins $tmp, S, $src2, 0, 1\n\t" 15405 "fadds $dst, $dst, $tmp\t add reduction2f" 15406 %} 15407 ins_encode %{ 15408 __ fadds(as_FloatRegister($dst$$reg), 15409 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15410 __ ins(as_FloatRegister($tmp$$reg), __ S, 15411 as_FloatRegister($src2$$reg), 0, 1); 15412 __ fadds(as_FloatRegister($dst$$reg), 15413 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15414 %} 15415 ins_pipe(pipe_class_default); 15416 %} 15417 15418 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15419 %{ 15420 match(Set dst (AddReductionVF src1 src2)); 15421 ins_cost(INSN_COST); 15422 effect(TEMP tmp, TEMP dst); 15423 format %{ "fadds $dst, $src1, $src2\n\t" 15424 "ins $tmp, S, $src2, 0, 1\n\t" 15425 "fadds $dst, $dst, $tmp\n\t" 15426 "ins $tmp, S, $src2, 0, 2\n\t" 15427 "fadds $dst, $dst, $tmp\n\t" 15428 "ins $tmp, S, $src2, 0, 3\n\t" 15429 "fadds $dst, $dst, $tmp\t add reduction4f" 15430 %} 15431 ins_encode %{ 15432 __ fadds(as_FloatRegister($dst$$reg), 15433 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15434 __ ins(as_FloatRegister($tmp$$reg), __ S, 15435 as_FloatRegister($src2$$reg), 0, 1); 15436 __ fadds(as_FloatRegister($dst$$reg), 15437 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15438 __ ins(as_FloatRegister($tmp$$reg), __ S, 15439 as_FloatRegister($src2$$reg), 0, 2); 15440 __ fadds(as_FloatRegister($dst$$reg), 15441 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15442 __ ins(as_FloatRegister($tmp$$reg), __ S, 15443 as_FloatRegister($src2$$reg), 0, 3); 15444 __ fadds(as_FloatRegister($dst$$reg), 15445 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15446 %} 15447 ins_pipe(pipe_class_default); 15448 %} 15449 15450 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15451 %{ 15452 match(Set dst (MulReductionVF src1 src2)); 15453 ins_cost(INSN_COST); 15454 effect(TEMP tmp, TEMP dst); 15455 format %{ "fmuls $dst, $src1, $src2\n\t" 15456 "ins $tmp, S, $src2, 0, 1\n\t" 15457 "fmuls $dst, $dst, $tmp\t add reduction4f" 15458 %} 15459 ins_encode %{ 15460 __ fmuls(as_FloatRegister($dst$$reg), 15461 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15462 __ ins(as_FloatRegister($tmp$$reg), __ S, 15463 as_FloatRegister($src2$$reg), 0, 1); 15464 __ fmuls(as_FloatRegister($dst$$reg), 15465 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15466 %} 15467 ins_pipe(pipe_class_default); 15468 %} 15469 15470 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15471 %{ 15472 match(Set dst (MulReductionVF src1 src2)); 15473 ins_cost(INSN_COST); 15474 effect(TEMP tmp, TEMP dst); 15475 format %{ "fmuls $dst, $src1, $src2\n\t" 15476 "ins $tmp, S, $src2, 0, 1\n\t" 15477 "fmuls $dst, $dst, $tmp\n\t" 15478 "ins $tmp, S, $src2, 0, 2\n\t" 15479 "fmuls $dst, $dst, $tmp\n\t" 15480 "ins $tmp, S, $src2, 0, 3\n\t" 15481 "fmuls $dst, $dst, $tmp\t add reduction4f" 15482 %} 15483 ins_encode %{ 15484 __ fmuls(as_FloatRegister($dst$$reg), 15485 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15486 __ ins(as_FloatRegister($tmp$$reg), __ S, 15487 as_FloatRegister($src2$$reg), 0, 1); 15488 __ fmuls(as_FloatRegister($dst$$reg), 15489 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15490 __ ins(as_FloatRegister($tmp$$reg), __ S, 15491 as_FloatRegister($src2$$reg), 0, 2); 15492 __ fmuls(as_FloatRegister($dst$$reg), 15493 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15494 __ ins(as_FloatRegister($tmp$$reg), __ S, 15495 as_FloatRegister($src2$$reg), 0, 3); 15496 __ fmuls(as_FloatRegister($dst$$reg), 15497 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15498 %} 15499 ins_pipe(pipe_class_default); 15500 %} 15501 15502 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15503 %{ 15504 match(Set dst (AddReductionVD src1 src2)); 15505 ins_cost(INSN_COST); 15506 effect(TEMP tmp, TEMP dst); 15507 format %{ "faddd $dst, $src1, $src2\n\t" 15508 "ins $tmp, D, $src2, 0, 1\n\t" 15509 "faddd $dst, $dst, $tmp\t add reduction2d" 15510 %} 15511 ins_encode %{ 15512 __ faddd(as_FloatRegister($dst$$reg), 15513 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15514 __ ins(as_FloatRegister($tmp$$reg), __ D, 15515 as_FloatRegister($src2$$reg), 0, 1); 15516 __ faddd(as_FloatRegister($dst$$reg), 15517 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15518 %} 15519 ins_pipe(pipe_class_default); 15520 %} 15521 15522 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15523 %{ 15524 match(Set dst (MulReductionVD src1 src2)); 15525 ins_cost(INSN_COST); 15526 effect(TEMP tmp, TEMP dst); 15527 format %{ "fmuld $dst, $src1, $src2\n\t" 15528 "ins $tmp, D, $src2, 0, 1\n\t" 15529 "fmuld $dst, $dst, $tmp\t add reduction2d" 15530 %} 15531 ins_encode %{ 15532 __ fmuld(as_FloatRegister($dst$$reg), 15533 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15534 __ ins(as_FloatRegister($tmp$$reg), __ D, 15535 as_FloatRegister($src2$$reg), 0, 1); 15536 __ fmuld(as_FloatRegister($dst$$reg), 15537 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15538 %} 15539 ins_pipe(pipe_class_default); 15540 %} 15541 15542 // ====================VECTOR ARITHMETIC======================================= 15543 15544 // --------------------------------- ADD -------------------------------------- 15545 15546 instruct vadd8B(vecD dst, vecD src1, vecD src2) 15547 %{ 15548 predicate(n->as_Vector()->length() == 4 || 15549 n->as_Vector()->length() == 8); 15550 match(Set dst (AddVB src1 src2)); 15551 ins_cost(INSN_COST); 15552 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 15553 ins_encode %{ 15554 __ addv(as_FloatRegister($dst$$reg), __ T8B, 15555 as_FloatRegister($src1$$reg), 15556 as_FloatRegister($src2$$reg)); 15557 %} 15558 ins_pipe(vdop64); 15559 %} 15560 15561 instruct vadd16B(vecX dst, vecX src1, vecX src2) 15562 %{ 15563 predicate(n->as_Vector()->length() == 16); 15564 match(Set dst (AddVB src1 src2)); 15565 ins_cost(INSN_COST); 15566 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 15567 ins_encode %{ 15568 __ addv(as_FloatRegister($dst$$reg), __ T16B, 15569 as_FloatRegister($src1$$reg), 15570 as_FloatRegister($src2$$reg)); 15571 %} 15572 ins_pipe(vdop128); 15573 %} 15574 15575 instruct vadd4S(vecD dst, vecD src1, vecD src2) 15576 %{ 15577 predicate(n->as_Vector()->length() == 2 || 15578 n->as_Vector()->length() == 4); 15579 match(Set dst (AddVS src1 src2)); 15580 ins_cost(INSN_COST); 15581 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 15582 ins_encode %{ 15583 __ addv(as_FloatRegister($dst$$reg), __ T4H, 15584 as_FloatRegister($src1$$reg), 15585 as_FloatRegister($src2$$reg)); 15586 %} 15587 ins_pipe(vdop64); 15588 %} 15589 15590 instruct vadd8S(vecX dst, vecX src1, vecX src2) 15591 %{ 15592 predicate(n->as_Vector()->length() == 8); 15593 match(Set dst (AddVS src1 src2)); 15594 ins_cost(INSN_COST); 15595 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 15596 ins_encode %{ 15597 __ addv(as_FloatRegister($dst$$reg), __ T8H, 15598 as_FloatRegister($src1$$reg), 15599 as_FloatRegister($src2$$reg)); 15600 %} 15601 ins_pipe(vdop128); 15602 %} 15603 15604 instruct vadd2I(vecD dst, vecD src1, vecD src2) 15605 %{ 15606 predicate(n->as_Vector()->length() == 2); 15607 match(Set dst (AddVI src1 src2)); 15608 ins_cost(INSN_COST); 15609 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 15610 ins_encode %{ 15611 __ addv(as_FloatRegister($dst$$reg), __ T2S, 15612 as_FloatRegister($src1$$reg), 15613 as_FloatRegister($src2$$reg)); 15614 %} 15615 ins_pipe(vdop64); 15616 %} 15617 15618 instruct vadd4I(vecX dst, vecX src1, vecX src2) 15619 %{ 15620 predicate(n->as_Vector()->length() == 4); 15621 match(Set dst (AddVI src1 src2)); 15622 ins_cost(INSN_COST); 15623 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 15624 ins_encode %{ 15625 __ addv(as_FloatRegister($dst$$reg), __ T4S, 15626 as_FloatRegister($src1$$reg), 15627 as_FloatRegister($src2$$reg)); 15628 %} 15629 ins_pipe(vdop128); 15630 %} 15631 15632 instruct vadd2L(vecX dst, vecX src1, vecX src2) 15633 %{ 15634 predicate(n->as_Vector()->length() == 2); 15635 match(Set dst (AddVL src1 src2)); 15636 ins_cost(INSN_COST); 15637 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 15638 ins_encode %{ 15639 __ addv(as_FloatRegister($dst$$reg), __ T2D, 15640 as_FloatRegister($src1$$reg), 15641 as_FloatRegister($src2$$reg)); 15642 %} 15643 ins_pipe(vdop128); 15644 %} 15645 15646 instruct vadd2F(vecD dst, vecD src1, vecD src2) 15647 %{ 15648 predicate(n->as_Vector()->length() == 2); 15649 match(Set dst (AddVF src1 src2)); 15650 ins_cost(INSN_COST); 15651 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 15652 ins_encode %{ 15653 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 15654 as_FloatRegister($src1$$reg), 15655 as_FloatRegister($src2$$reg)); 15656 %} 15657 ins_pipe(vdop_fp64); 15658 %} 15659 15660 instruct vadd4F(vecX dst, vecX src1, vecX src2) 15661 %{ 15662 predicate(n->as_Vector()->length() == 4); 15663 match(Set dst (AddVF src1 src2)); 15664 ins_cost(INSN_COST); 15665 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 15666 ins_encode %{ 15667 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 15668 as_FloatRegister($src1$$reg), 15669 as_FloatRegister($src2$$reg)); 15670 %} 15671 ins_pipe(vdop_fp128); 15672 %} 15673 15674 instruct vadd2D(vecX dst, vecX src1, vecX src2) 15675 %{ 15676 match(Set dst (AddVD src1 src2)); 15677 ins_cost(INSN_COST); 15678 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 15679 ins_encode %{ 15680 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 15681 as_FloatRegister($src1$$reg), 15682 as_FloatRegister($src2$$reg)); 15683 %} 15684 ins_pipe(vdop_fp128); 15685 %} 15686 15687 // --------------------------------- SUB -------------------------------------- 15688 15689 instruct vsub8B(vecD dst, vecD src1, vecD src2) 15690 %{ 15691 predicate(n->as_Vector()->length() == 4 || 15692 n->as_Vector()->length() == 8); 15693 match(Set dst (SubVB src1 src2)); 15694 ins_cost(INSN_COST); 15695 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 15696 ins_encode %{ 15697 __ subv(as_FloatRegister($dst$$reg), __ T8B, 15698 as_FloatRegister($src1$$reg), 15699 as_FloatRegister($src2$$reg)); 15700 %} 15701 ins_pipe(vdop64); 15702 %} 15703 15704 instruct vsub16B(vecX dst, vecX src1, vecX src2) 15705 %{ 15706 predicate(n->as_Vector()->length() == 16); 15707 match(Set dst (SubVB src1 src2)); 15708 ins_cost(INSN_COST); 15709 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 15710 ins_encode %{ 15711 __ subv(as_FloatRegister($dst$$reg), __ T16B, 15712 as_FloatRegister($src1$$reg), 15713 as_FloatRegister($src2$$reg)); 15714 %} 15715 ins_pipe(vdop128); 15716 %} 15717 15718 instruct vsub4S(vecD dst, vecD src1, vecD src2) 15719 %{ 15720 predicate(n->as_Vector()->length() == 2 || 15721 n->as_Vector()->length() == 4); 15722 match(Set dst (SubVS src1 src2)); 15723 ins_cost(INSN_COST); 15724 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 15725 ins_encode %{ 15726 __ subv(as_FloatRegister($dst$$reg), __ T4H, 15727 as_FloatRegister($src1$$reg), 15728 as_FloatRegister($src2$$reg)); 15729 %} 15730 ins_pipe(vdop64); 15731 %} 15732 15733 instruct vsub8S(vecX dst, vecX src1, vecX src2) 15734 %{ 15735 predicate(n->as_Vector()->length() == 8); 15736 match(Set dst (SubVS src1 src2)); 15737 ins_cost(INSN_COST); 15738 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 15739 ins_encode %{ 15740 __ subv(as_FloatRegister($dst$$reg), __ T8H, 15741 as_FloatRegister($src1$$reg), 15742 as_FloatRegister($src2$$reg)); 15743 %} 15744 ins_pipe(vdop128); 15745 %} 15746 15747 instruct vsub2I(vecD dst, vecD src1, vecD src2) 15748 %{ 15749 predicate(n->as_Vector()->length() == 2); 15750 match(Set dst (SubVI src1 src2)); 15751 ins_cost(INSN_COST); 15752 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 15753 ins_encode %{ 15754 __ subv(as_FloatRegister($dst$$reg), __ T2S, 15755 as_FloatRegister($src1$$reg), 15756 as_FloatRegister($src2$$reg)); 15757 %} 15758 ins_pipe(vdop64); 15759 %} 15760 15761 instruct vsub4I(vecX dst, vecX src1, vecX src2) 15762 %{ 15763 predicate(n->as_Vector()->length() == 4); 15764 match(Set dst (SubVI src1 src2)); 15765 ins_cost(INSN_COST); 15766 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 15767 ins_encode %{ 15768 __ subv(as_FloatRegister($dst$$reg), __ T4S, 15769 as_FloatRegister($src1$$reg), 15770 as_FloatRegister($src2$$reg)); 15771 %} 15772 ins_pipe(vdop128); 15773 %} 15774 15775 instruct vsub2L(vecX dst, vecX src1, vecX src2) 15776 %{ 15777 predicate(n->as_Vector()->length() == 2); 15778 match(Set dst (SubVL src1 src2)); 15779 ins_cost(INSN_COST); 15780 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 15781 ins_encode %{ 15782 __ subv(as_FloatRegister($dst$$reg), __ T2D, 15783 as_FloatRegister($src1$$reg), 15784 as_FloatRegister($src2$$reg)); 15785 %} 15786 ins_pipe(vdop128); 15787 %} 15788 15789 instruct vsub2F(vecD dst, vecD src1, vecD src2) 15790 %{ 15791 predicate(n->as_Vector()->length() == 2); 15792 match(Set dst (SubVF src1 src2)); 15793 ins_cost(INSN_COST); 15794 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 15795 ins_encode %{ 15796 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 15797 as_FloatRegister($src1$$reg), 15798 as_FloatRegister($src2$$reg)); 15799 %} 15800 ins_pipe(vdop_fp64); 15801 %} 15802 15803 instruct vsub4F(vecX dst, vecX src1, vecX src2) 15804 %{ 15805 predicate(n->as_Vector()->length() == 4); 15806 match(Set dst (SubVF src1 src2)); 15807 ins_cost(INSN_COST); 15808 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 15809 ins_encode %{ 15810 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 15811 as_FloatRegister($src1$$reg), 15812 as_FloatRegister($src2$$reg)); 15813 %} 15814 ins_pipe(vdop_fp128); 15815 %} 15816 15817 instruct vsub2D(vecX dst, vecX src1, vecX src2) 15818 %{ 15819 predicate(n->as_Vector()->length() == 2); 15820 match(Set dst (SubVD src1 src2)); 15821 ins_cost(INSN_COST); 15822 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 15823 ins_encode %{ 15824 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 15825 as_FloatRegister($src1$$reg), 15826 as_FloatRegister($src2$$reg)); 15827 %} 15828 ins_pipe(vdop_fp128); 15829 %} 15830 15831 // --------------------------------- MUL -------------------------------------- 15832 15833 instruct vmul4S(vecD dst, vecD src1, vecD src2) 15834 %{ 15835 predicate(n->as_Vector()->length() == 2 || 15836 n->as_Vector()->length() == 4); 15837 match(Set dst (MulVS src1 src2)); 15838 ins_cost(INSN_COST); 15839 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 15840 ins_encode %{ 15841 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 15842 as_FloatRegister($src1$$reg), 15843 as_FloatRegister($src2$$reg)); 15844 %} 15845 ins_pipe(vmul64); 15846 %} 15847 15848 instruct vmul8S(vecX dst, vecX src1, vecX src2) 15849 %{ 15850 predicate(n->as_Vector()->length() == 8); 15851 match(Set dst (MulVS src1 src2)); 15852 ins_cost(INSN_COST); 15853 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 15854 ins_encode %{ 15855 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 15856 as_FloatRegister($src1$$reg), 15857 as_FloatRegister($src2$$reg)); 15858 %} 15859 ins_pipe(vmul128); 15860 %} 15861 15862 instruct vmul2I(vecD dst, vecD src1, vecD src2) 15863 %{ 15864 predicate(n->as_Vector()->length() == 2); 15865 match(Set dst (MulVI src1 src2)); 15866 ins_cost(INSN_COST); 15867 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 15868 ins_encode %{ 15869 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 15870 as_FloatRegister($src1$$reg), 15871 as_FloatRegister($src2$$reg)); 15872 %} 15873 ins_pipe(vmul64); 15874 %} 15875 15876 instruct vmul4I(vecX dst, vecX src1, vecX src2) 15877 %{ 15878 predicate(n->as_Vector()->length() == 4); 15879 match(Set dst (MulVI src1 src2)); 15880 ins_cost(INSN_COST); 15881 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 15882 ins_encode %{ 15883 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 15884 as_FloatRegister($src1$$reg), 15885 as_FloatRegister($src2$$reg)); 15886 %} 15887 ins_pipe(vmul128); 15888 %} 15889 15890 instruct vmul2F(vecD dst, vecD src1, vecD src2) 15891 %{ 15892 predicate(n->as_Vector()->length() == 2); 15893 match(Set dst (MulVF src1 src2)); 15894 ins_cost(INSN_COST); 15895 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 15896 ins_encode %{ 15897 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 15898 as_FloatRegister($src1$$reg), 15899 as_FloatRegister($src2$$reg)); 15900 %} 15901 ins_pipe(vmuldiv_fp64); 15902 %} 15903 15904 instruct vmul4F(vecX dst, vecX src1, vecX src2) 15905 %{ 15906 predicate(n->as_Vector()->length() == 4); 15907 match(Set dst (MulVF src1 src2)); 15908 ins_cost(INSN_COST); 15909 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 15910 ins_encode %{ 15911 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 15912 as_FloatRegister($src1$$reg), 15913 as_FloatRegister($src2$$reg)); 15914 %} 15915 ins_pipe(vmuldiv_fp128); 15916 %} 15917 15918 instruct vmul2D(vecX dst, vecX src1, vecX src2) 15919 %{ 15920 predicate(n->as_Vector()->length() == 2); 15921 match(Set dst (MulVD src1 src2)); 15922 ins_cost(INSN_COST); 15923 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 15924 ins_encode %{ 15925 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 15926 as_FloatRegister($src1$$reg), 15927 as_FloatRegister($src2$$reg)); 15928 %} 15929 ins_pipe(vmuldiv_fp128); 15930 %} 15931 15932 // --------------------------------- MLA -------------------------------------- 15933 15934 instruct vmla4S(vecD dst, vecD src1, vecD src2) 15935 %{ 15936 predicate(n->as_Vector()->length() == 2 || 15937 n->as_Vector()->length() == 4); 15938 match(Set dst (AddVS dst (MulVS src1 src2))); 15939 ins_cost(INSN_COST); 15940 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 15941 ins_encode %{ 15942 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 15943 as_FloatRegister($src1$$reg), 15944 as_FloatRegister($src2$$reg)); 15945 %} 15946 ins_pipe(vmla64); 15947 %} 15948 15949 instruct vmla8S(vecX dst, vecX src1, vecX src2) 15950 %{ 15951 predicate(n->as_Vector()->length() == 8); 15952 match(Set dst (AddVS dst (MulVS src1 src2))); 15953 ins_cost(INSN_COST); 15954 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 15955 ins_encode %{ 15956 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 15957 as_FloatRegister($src1$$reg), 15958 as_FloatRegister($src2$$reg)); 15959 %} 15960 ins_pipe(vmla128); 15961 %} 15962 15963 instruct vmla2I(vecD dst, vecD src1, vecD src2) 15964 %{ 15965 predicate(n->as_Vector()->length() == 2); 15966 match(Set dst (AddVI dst (MulVI src1 src2))); 15967 ins_cost(INSN_COST); 15968 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 15969 ins_encode %{ 15970 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 15971 as_FloatRegister($src1$$reg), 15972 as_FloatRegister($src2$$reg)); 15973 %} 15974 ins_pipe(vmla64); 15975 %} 15976 15977 instruct vmla4I(vecX dst, vecX src1, vecX src2) 15978 %{ 15979 predicate(n->as_Vector()->length() == 4); 15980 match(Set dst (AddVI dst (MulVI src1 src2))); 15981 ins_cost(INSN_COST); 15982 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 15983 ins_encode %{ 15984 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 15985 as_FloatRegister($src1$$reg), 15986 as_FloatRegister($src2$$reg)); 15987 %} 15988 ins_pipe(vmla128); 15989 %} 15990 15991 // dst + src1 * src2 15992 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 15993 predicate(UseFMA && n->as_Vector()->length() == 2); 15994 match(Set dst (FmaVF dst (Binary src1 src2))); 15995 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 15996 ins_cost(INSN_COST); 15997 ins_encode %{ 15998 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 15999 as_FloatRegister($src1$$reg), 16000 as_FloatRegister($src2$$reg)); 16001 %} 16002 ins_pipe(vmuldiv_fp64); 16003 %} 16004 16005 // dst + src1 * src2 16006 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16007 predicate(UseFMA && n->as_Vector()->length() == 4); 16008 match(Set dst (FmaVF dst (Binary src1 src2))); 16009 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16010 ins_cost(INSN_COST); 16011 ins_encode %{ 16012 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16013 as_FloatRegister($src1$$reg), 16014 as_FloatRegister($src2$$reg)); 16015 %} 16016 ins_pipe(vmuldiv_fp128); 16017 %} 16018 16019 // dst + src1 * src2 16020 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16021 predicate(UseFMA && n->as_Vector()->length() == 2); 16022 match(Set dst (FmaVD dst (Binary src1 src2))); 16023 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16024 ins_cost(INSN_COST); 16025 ins_encode %{ 16026 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16027 as_FloatRegister($src1$$reg), 16028 as_FloatRegister($src2$$reg)); 16029 %} 16030 ins_pipe(vmuldiv_fp128); 16031 %} 16032 16033 // --------------------------------- MLS -------------------------------------- 16034 16035 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16036 %{ 16037 predicate(n->as_Vector()->length() == 2 || 16038 n->as_Vector()->length() == 4); 16039 match(Set dst (SubVS dst (MulVS src1 src2))); 16040 ins_cost(INSN_COST); 16041 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16042 ins_encode %{ 16043 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16044 as_FloatRegister($src1$$reg), 16045 as_FloatRegister($src2$$reg)); 16046 %} 16047 ins_pipe(vmla64); 16048 %} 16049 16050 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16051 %{ 16052 predicate(n->as_Vector()->length() == 8); 16053 match(Set dst (SubVS dst (MulVS src1 src2))); 16054 ins_cost(INSN_COST); 16055 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16056 ins_encode %{ 16057 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16058 as_FloatRegister($src1$$reg), 16059 as_FloatRegister($src2$$reg)); 16060 %} 16061 ins_pipe(vmla128); 16062 %} 16063 16064 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16065 %{ 16066 predicate(n->as_Vector()->length() == 2); 16067 match(Set dst (SubVI dst (MulVI src1 src2))); 16068 ins_cost(INSN_COST); 16069 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16070 ins_encode %{ 16071 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16072 as_FloatRegister($src1$$reg), 16073 as_FloatRegister($src2$$reg)); 16074 %} 16075 ins_pipe(vmla64); 16076 %} 16077 16078 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16079 %{ 16080 predicate(n->as_Vector()->length() == 4); 16081 match(Set dst (SubVI dst (MulVI src1 src2))); 16082 ins_cost(INSN_COST); 16083 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16084 ins_encode %{ 16085 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16086 as_FloatRegister($src1$$reg), 16087 as_FloatRegister($src2$$reg)); 16088 %} 16089 ins_pipe(vmla128); 16090 %} 16091 16092 // dst - src1 * src2 16093 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16094 predicate(UseFMA && n->as_Vector()->length() == 2); 16095 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16096 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16097 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16098 ins_cost(INSN_COST); 16099 ins_encode %{ 16100 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16101 as_FloatRegister($src1$$reg), 16102 as_FloatRegister($src2$$reg)); 16103 %} 16104 ins_pipe(vmuldiv_fp64); 16105 %} 16106 16107 // dst - src1 * src2 16108 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16109 predicate(UseFMA && n->as_Vector()->length() == 4); 16110 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16111 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16112 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16113 ins_cost(INSN_COST); 16114 ins_encode %{ 16115 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16116 as_FloatRegister($src1$$reg), 16117 as_FloatRegister($src2$$reg)); 16118 %} 16119 ins_pipe(vmuldiv_fp128); 16120 %} 16121 16122 // dst - src1 * src2 16123 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16124 predicate(UseFMA && n->as_Vector()->length() == 2); 16125 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16126 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16127 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16128 ins_cost(INSN_COST); 16129 ins_encode %{ 16130 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16131 as_FloatRegister($src1$$reg), 16132 as_FloatRegister($src2$$reg)); 16133 %} 16134 ins_pipe(vmuldiv_fp128); 16135 %} 16136 16137 // --------------------------------- DIV -------------------------------------- 16138 16139 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16140 %{ 16141 predicate(n->as_Vector()->length() == 2); 16142 match(Set dst (DivVF src1 src2)); 16143 ins_cost(INSN_COST); 16144 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16145 ins_encode %{ 16146 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16147 as_FloatRegister($src1$$reg), 16148 as_FloatRegister($src2$$reg)); 16149 %} 16150 ins_pipe(vmuldiv_fp64); 16151 %} 16152 16153 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16154 %{ 16155 predicate(n->as_Vector()->length() == 4); 16156 match(Set dst (DivVF src1 src2)); 16157 ins_cost(INSN_COST); 16158 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16159 ins_encode %{ 16160 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16161 as_FloatRegister($src1$$reg), 16162 as_FloatRegister($src2$$reg)); 16163 %} 16164 ins_pipe(vmuldiv_fp128); 16165 %} 16166 16167 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 16168 %{ 16169 predicate(n->as_Vector()->length() == 2); 16170 match(Set dst (DivVD src1 src2)); 16171 ins_cost(INSN_COST); 16172 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 16173 ins_encode %{ 16174 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 16175 as_FloatRegister($src1$$reg), 16176 as_FloatRegister($src2$$reg)); 16177 %} 16178 ins_pipe(vmuldiv_fp128); 16179 %} 16180 16181 // --------------------------------- SQRT ------------------------------------- 16182 16183 instruct vsqrt2D(vecX dst, vecX src) 16184 %{ 16185 predicate(n->as_Vector()->length() == 2); 16186 match(Set dst (SqrtVD src)); 16187 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 16188 ins_encode %{ 16189 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 16190 as_FloatRegister($src$$reg)); 16191 %} 16192 ins_pipe(vsqrt_fp128); 16193 %} 16194 16195 // --------------------------------- ABS -------------------------------------- 16196 16197 instruct vabs2F(vecD dst, vecD src) 16198 %{ 16199 predicate(n->as_Vector()->length() == 2); 16200 match(Set dst (AbsVF src)); 16201 ins_cost(INSN_COST * 3); 16202 format %{ "fabs $dst,$src\t# vector (2S)" %} 16203 ins_encode %{ 16204 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 16205 as_FloatRegister($src$$reg)); 16206 %} 16207 ins_pipe(vunop_fp64); 16208 %} 16209 16210 instruct vabs4F(vecX dst, vecX src) 16211 %{ 16212 predicate(n->as_Vector()->length() == 4); 16213 match(Set dst (AbsVF src)); 16214 ins_cost(INSN_COST * 3); 16215 format %{ "fabs $dst,$src\t# vector (4S)" %} 16216 ins_encode %{ 16217 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16218 as_FloatRegister($src$$reg)); 16219 %} 16220 ins_pipe(vunop_fp128); 16221 %} 16222 16223 instruct vabs2D(vecX dst, vecX src) 16224 %{ 16225 predicate(n->as_Vector()->length() == 2); 16226 match(Set dst (AbsVD src)); 16227 ins_cost(INSN_COST * 3); 16228 format %{ "fabs $dst,$src\t# vector (2D)" %} 16229 ins_encode %{ 16230 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 16231 as_FloatRegister($src$$reg)); 16232 %} 16233 ins_pipe(vunop_fp128); 16234 %} 16235 16236 // --------------------------------- NEG -------------------------------------- 16237 16238 instruct vneg2F(vecD dst, vecD src) 16239 %{ 16240 predicate(n->as_Vector()->length() == 2); 16241 match(Set dst (NegVF src)); 16242 ins_cost(INSN_COST * 3); 16243 format %{ "fneg $dst,$src\t# vector (2S)" %} 16244 ins_encode %{ 16245 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 16246 as_FloatRegister($src$$reg)); 16247 %} 16248 ins_pipe(vunop_fp64); 16249 %} 16250 16251 instruct vneg4F(vecX dst, vecX src) 16252 %{ 16253 predicate(n->as_Vector()->length() == 4); 16254 match(Set dst (NegVF src)); 16255 ins_cost(INSN_COST * 3); 16256 format %{ "fneg $dst,$src\t# vector (4S)" %} 16257 ins_encode %{ 16258 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16259 as_FloatRegister($src$$reg)); 16260 %} 16261 ins_pipe(vunop_fp128); 16262 %} 16263 16264 instruct vneg2D(vecX dst, vecX src) 16265 %{ 16266 predicate(n->as_Vector()->length() == 2); 16267 match(Set dst (NegVD src)); 16268 ins_cost(INSN_COST * 3); 16269 format %{ "fneg $dst,$src\t# vector (2D)" %} 16270 ins_encode %{ 16271 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16272 as_FloatRegister($src$$reg)); 16273 %} 16274 ins_pipe(vunop_fp128); 16275 %} 16276 16277 // --------------------------------- AND -------------------------------------- 16278 16279 instruct vand8B(vecD dst, vecD src1, vecD src2) 16280 %{ 16281 predicate(n->as_Vector()->length_in_bytes() == 4 || 16282 n->as_Vector()->length_in_bytes() == 8); 16283 match(Set dst (AndV src1 src2)); 16284 ins_cost(INSN_COST); 16285 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16286 ins_encode %{ 16287 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16288 as_FloatRegister($src1$$reg), 16289 as_FloatRegister($src2$$reg)); 16290 %} 16291 ins_pipe(vlogical64); 16292 %} 16293 16294 instruct vand16B(vecX dst, vecX src1, vecX src2) 16295 %{ 16296 predicate(n->as_Vector()->length_in_bytes() == 16); 16297 match(Set dst (AndV src1 src2)); 16298 ins_cost(INSN_COST); 16299 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16300 ins_encode %{ 16301 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16302 as_FloatRegister($src1$$reg), 16303 as_FloatRegister($src2$$reg)); 16304 %} 16305 ins_pipe(vlogical128); 16306 %} 16307 16308 // --------------------------------- OR --------------------------------------- 16309 16310 instruct vor8B(vecD dst, vecD src1, vecD src2) 16311 %{ 16312 predicate(n->as_Vector()->length_in_bytes() == 4 || 16313 n->as_Vector()->length_in_bytes() == 8); 16314 match(Set dst (OrV src1 src2)); 16315 ins_cost(INSN_COST); 16316 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16317 ins_encode %{ 16318 __ orr(as_FloatRegister($dst$$reg), __ T8B, 16319 as_FloatRegister($src1$$reg), 16320 as_FloatRegister($src2$$reg)); 16321 %} 16322 ins_pipe(vlogical64); 16323 %} 16324 16325 instruct vor16B(vecX dst, vecX src1, vecX src2) 16326 %{ 16327 predicate(n->as_Vector()->length_in_bytes() == 16); 16328 match(Set dst (OrV src1 src2)); 16329 ins_cost(INSN_COST); 16330 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 16331 ins_encode %{ 16332 __ orr(as_FloatRegister($dst$$reg), __ T16B, 16333 as_FloatRegister($src1$$reg), 16334 as_FloatRegister($src2$$reg)); 16335 %} 16336 ins_pipe(vlogical128); 16337 %} 16338 16339 // --------------------------------- XOR -------------------------------------- 16340 16341 instruct vxor8B(vecD dst, vecD src1, vecD src2) 16342 %{ 16343 predicate(n->as_Vector()->length_in_bytes() == 4 || 16344 n->as_Vector()->length_in_bytes() == 8); 16345 match(Set dst (XorV src1 src2)); 16346 ins_cost(INSN_COST); 16347 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 16348 ins_encode %{ 16349 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16350 as_FloatRegister($src1$$reg), 16351 as_FloatRegister($src2$$reg)); 16352 %} 16353 ins_pipe(vlogical64); 16354 %} 16355 16356 instruct vxor16B(vecX dst, vecX src1, vecX src2) 16357 %{ 16358 predicate(n->as_Vector()->length_in_bytes() == 16); 16359 match(Set dst (XorV src1 src2)); 16360 ins_cost(INSN_COST); 16361 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 16362 ins_encode %{ 16363 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16364 as_FloatRegister($src1$$reg), 16365 as_FloatRegister($src2$$reg)); 16366 %} 16367 ins_pipe(vlogical128); 16368 %} 16369 16370 // ------------------------------ Shift --------------------------------------- 16371 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 16372 predicate(n->as_Vector()->length_in_bytes() == 8); 16373 match(Set dst (LShiftCntV cnt)); 16374 match(Set dst (RShiftCntV cnt)); 16375 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 16376 ins_encode %{ 16377 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 16378 %} 16379 ins_pipe(vdup_reg_reg64); 16380 %} 16381 16382 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 16383 predicate(n->as_Vector()->length_in_bytes() == 16); 16384 match(Set dst (LShiftCntV cnt)); 16385 match(Set dst (RShiftCntV cnt)); 16386 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 16387 ins_encode %{ 16388 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16389 %} 16390 ins_pipe(vdup_reg_reg128); 16391 %} 16392 16393 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 16394 predicate(n->as_Vector()->length() == 4 || 16395 n->as_Vector()->length() == 8); 16396 match(Set dst (LShiftVB src shift)); 16397 ins_cost(INSN_COST); 16398 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 16399 ins_encode %{ 16400 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16401 as_FloatRegister($src$$reg), 16402 as_FloatRegister($shift$$reg)); 16403 %} 16404 ins_pipe(vshift64); 16405 %} 16406 16407 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 16408 predicate(n->as_Vector()->length() == 16); 16409 match(Set dst (LShiftVB src shift)); 16410 ins_cost(INSN_COST); 16411 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 16412 ins_encode %{ 16413 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16414 as_FloatRegister($src$$reg), 16415 as_FloatRegister($shift$$reg)); 16416 %} 16417 ins_pipe(vshift128); 16418 %} 16419 16420 // Right shifts with vector shift count on aarch64 SIMD are implemented 16421 // as left shift by negative shift count. 16422 // There are two cases for vector shift count. 16423 // 16424 // Case 1: The vector shift count is from replication. 16425 // | | 16426 // LoadVector RShiftCntV 16427 // | / 16428 // RShiftVI 16429 // Note: In inner loop, multiple neg instructions are used, which can be 16430 // moved to outer loop and merge into one neg instruction. 16431 // 16432 // Case 2: The vector shift count is from loading. 16433 // This case isn't supported by middle-end now. But it's supported by 16434 // panama/vectorIntrinsics(JEP 338: Vector API). 16435 // | | 16436 // LoadVector LoadVector 16437 // | / 16438 // RShiftVI 16439 // 16440 16441 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16442 predicate(n->as_Vector()->length() == 4 || 16443 n->as_Vector()->length() == 8); 16444 match(Set dst (RShiftVB src shift)); 16445 ins_cost(INSN_COST); 16446 effect(TEMP tmp); 16447 format %{ "negr $tmp,$shift\t" 16448 "sshl $dst,$src,$tmp\t# vector (8B)" %} 16449 ins_encode %{ 16450 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16451 as_FloatRegister($shift$$reg)); 16452 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16453 as_FloatRegister($src$$reg), 16454 as_FloatRegister($tmp$$reg)); 16455 %} 16456 ins_pipe(vshift64); 16457 %} 16458 16459 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16460 predicate(n->as_Vector()->length() == 16); 16461 match(Set dst (RShiftVB src shift)); 16462 ins_cost(INSN_COST); 16463 effect(TEMP tmp); 16464 format %{ "negr $tmp,$shift\t" 16465 "sshl $dst,$src,$tmp\t# vector (16B)" %} 16466 ins_encode %{ 16467 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16468 as_FloatRegister($shift$$reg)); 16469 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16470 as_FloatRegister($src$$reg), 16471 as_FloatRegister($tmp$$reg)); 16472 %} 16473 ins_pipe(vshift128); 16474 %} 16475 16476 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16477 predicate(n->as_Vector()->length() == 4 || 16478 n->as_Vector()->length() == 8); 16479 match(Set dst (URShiftVB src shift)); 16480 ins_cost(INSN_COST); 16481 effect(TEMP tmp); 16482 format %{ "negr $tmp,$shift\t" 16483 "ushl $dst,$src,$tmp\t# vector (8B)" %} 16484 ins_encode %{ 16485 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16486 as_FloatRegister($shift$$reg)); 16487 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 16488 as_FloatRegister($src$$reg), 16489 as_FloatRegister($tmp$$reg)); 16490 %} 16491 ins_pipe(vshift64); 16492 %} 16493 16494 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16495 predicate(n->as_Vector()->length() == 16); 16496 match(Set dst (URShiftVB src shift)); 16497 ins_cost(INSN_COST); 16498 effect(TEMP tmp); 16499 format %{ "negr $tmp,$shift\t" 16500 "ushl $dst,$src,$tmp\t# vector (16B)" %} 16501 ins_encode %{ 16502 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16503 as_FloatRegister($shift$$reg)); 16504 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 16505 as_FloatRegister($src$$reg), 16506 as_FloatRegister($tmp$$reg)); 16507 %} 16508 ins_pipe(vshift128); 16509 %} 16510 16511 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 16512 predicate(n->as_Vector()->length() == 4 || 16513 n->as_Vector()->length() == 8); 16514 match(Set dst (LShiftVB src shift)); 16515 ins_cost(INSN_COST); 16516 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 16517 ins_encode %{ 16518 int sh = (int)$shift$$constant; 16519 if (sh >= 8) { 16520 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16521 as_FloatRegister($src$$reg), 16522 as_FloatRegister($src$$reg)); 16523 } else { 16524 __ shl(as_FloatRegister($dst$$reg), __ T8B, 16525 as_FloatRegister($src$$reg), sh); 16526 } 16527 %} 16528 ins_pipe(vshift64_imm); 16529 %} 16530 16531 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 16532 predicate(n->as_Vector()->length() == 16); 16533 match(Set dst (LShiftVB src shift)); 16534 ins_cost(INSN_COST); 16535 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 16536 ins_encode %{ 16537 int sh = (int)$shift$$constant; 16538 if (sh >= 8) { 16539 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16540 as_FloatRegister($src$$reg), 16541 as_FloatRegister($src$$reg)); 16542 } else { 16543 __ shl(as_FloatRegister($dst$$reg), __ T16B, 16544 as_FloatRegister($src$$reg), sh); 16545 } 16546 %} 16547 ins_pipe(vshift128_imm); 16548 %} 16549 16550 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 16551 predicate(n->as_Vector()->length() == 4 || 16552 n->as_Vector()->length() == 8); 16553 match(Set dst (RShiftVB src shift)); 16554 ins_cost(INSN_COST); 16555 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 16556 ins_encode %{ 16557 int sh = (int)$shift$$constant; 16558 if (sh >= 8) sh = 7; 16559 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 16560 as_FloatRegister($src$$reg), sh); 16561 %} 16562 ins_pipe(vshift64_imm); 16563 %} 16564 16565 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 16566 predicate(n->as_Vector()->length() == 16); 16567 match(Set dst (RShiftVB src shift)); 16568 ins_cost(INSN_COST); 16569 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 16570 ins_encode %{ 16571 int sh = (int)$shift$$constant; 16572 if (sh >= 8) sh = 7; 16573 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 16574 as_FloatRegister($src$$reg), sh); 16575 %} 16576 ins_pipe(vshift128_imm); 16577 %} 16578 16579 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 16580 predicate(n->as_Vector()->length() == 4 || 16581 n->as_Vector()->length() == 8); 16582 match(Set dst (URShiftVB src shift)); 16583 ins_cost(INSN_COST); 16584 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 16585 ins_encode %{ 16586 int sh = (int)$shift$$constant; 16587 if (sh >= 8) { 16588 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16589 as_FloatRegister($src$$reg), 16590 as_FloatRegister($src$$reg)); 16591 } else { 16592 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 16593 as_FloatRegister($src$$reg), sh); 16594 } 16595 %} 16596 ins_pipe(vshift64_imm); 16597 %} 16598 16599 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 16600 predicate(n->as_Vector()->length() == 16); 16601 match(Set dst (URShiftVB src shift)); 16602 ins_cost(INSN_COST); 16603 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 16604 ins_encode %{ 16605 int sh = (int)$shift$$constant; 16606 if (sh >= 8) { 16607 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16608 as_FloatRegister($src$$reg), 16609 as_FloatRegister($src$$reg)); 16610 } else { 16611 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 16612 as_FloatRegister($src$$reg), sh); 16613 } 16614 %} 16615 ins_pipe(vshift128_imm); 16616 %} 16617 16618 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 16619 predicate(n->as_Vector()->length() == 2 || 16620 n->as_Vector()->length() == 4); 16621 match(Set dst (LShiftVS src shift)); 16622 ins_cost(INSN_COST); 16623 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 16624 ins_encode %{ 16625 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16626 as_FloatRegister($src$$reg), 16627 as_FloatRegister($shift$$reg)); 16628 %} 16629 ins_pipe(vshift64); 16630 %} 16631 16632 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 16633 predicate(n->as_Vector()->length() == 8); 16634 match(Set dst (LShiftVS src shift)); 16635 ins_cost(INSN_COST); 16636 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 16637 ins_encode %{ 16638 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16639 as_FloatRegister($src$$reg), 16640 as_FloatRegister($shift$$reg)); 16641 %} 16642 ins_pipe(vshift128); 16643 %} 16644 16645 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16646 predicate(n->as_Vector()->length() == 2 || 16647 n->as_Vector()->length() == 4); 16648 match(Set dst (RShiftVS src shift)); 16649 ins_cost(INSN_COST); 16650 effect(TEMP tmp); 16651 format %{ "negr $tmp,$shift\t" 16652 "sshl $dst,$src,$tmp\t# vector (4H)" %} 16653 ins_encode %{ 16654 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16655 as_FloatRegister($shift$$reg)); 16656 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16657 as_FloatRegister($src$$reg), 16658 as_FloatRegister($tmp$$reg)); 16659 %} 16660 ins_pipe(vshift64); 16661 %} 16662 16663 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16664 predicate(n->as_Vector()->length() == 8); 16665 match(Set dst (RShiftVS src shift)); 16666 ins_cost(INSN_COST); 16667 effect(TEMP tmp); 16668 format %{ "negr $tmp,$shift\t" 16669 "sshl $dst,$src,$tmp\t# vector (8H)" %} 16670 ins_encode %{ 16671 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16672 as_FloatRegister($shift$$reg)); 16673 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16674 as_FloatRegister($src$$reg), 16675 as_FloatRegister($tmp$$reg)); 16676 %} 16677 ins_pipe(vshift128); 16678 %} 16679 16680 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16681 predicate(n->as_Vector()->length() == 2 || 16682 n->as_Vector()->length() == 4); 16683 match(Set dst (URShiftVS src shift)); 16684 ins_cost(INSN_COST); 16685 effect(TEMP tmp); 16686 format %{ "negr $tmp,$shift\t" 16687 "ushl $dst,$src,$tmp\t# vector (4H)" %} 16688 ins_encode %{ 16689 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16690 as_FloatRegister($shift$$reg)); 16691 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 16692 as_FloatRegister($src$$reg), 16693 as_FloatRegister($tmp$$reg)); 16694 %} 16695 ins_pipe(vshift64); 16696 %} 16697 16698 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16699 predicate(n->as_Vector()->length() == 8); 16700 match(Set dst (URShiftVS src shift)); 16701 ins_cost(INSN_COST); 16702 effect(TEMP tmp); 16703 format %{ "negr $tmp,$shift\t" 16704 "ushl $dst,$src,$tmp\t# vector (8H)" %} 16705 ins_encode %{ 16706 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16707 as_FloatRegister($shift$$reg)); 16708 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 16709 as_FloatRegister($src$$reg), 16710 as_FloatRegister($tmp$$reg)); 16711 %} 16712 ins_pipe(vshift128); 16713 %} 16714 16715 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 16716 predicate(n->as_Vector()->length() == 2 || 16717 n->as_Vector()->length() == 4); 16718 match(Set dst (LShiftVS src shift)); 16719 ins_cost(INSN_COST); 16720 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 16721 ins_encode %{ 16722 int sh = (int)$shift$$constant; 16723 if (sh >= 16) { 16724 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16725 as_FloatRegister($src$$reg), 16726 as_FloatRegister($src$$reg)); 16727 } else { 16728 __ shl(as_FloatRegister($dst$$reg), __ T4H, 16729 as_FloatRegister($src$$reg), sh); 16730 } 16731 %} 16732 ins_pipe(vshift64_imm); 16733 %} 16734 16735 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 16736 predicate(n->as_Vector()->length() == 8); 16737 match(Set dst (LShiftVS src shift)); 16738 ins_cost(INSN_COST); 16739 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 16740 ins_encode %{ 16741 int sh = (int)$shift$$constant; 16742 if (sh >= 16) { 16743 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16744 as_FloatRegister($src$$reg), 16745 as_FloatRegister($src$$reg)); 16746 } else { 16747 __ shl(as_FloatRegister($dst$$reg), __ T8H, 16748 as_FloatRegister($src$$reg), sh); 16749 } 16750 %} 16751 ins_pipe(vshift128_imm); 16752 %} 16753 16754 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 16755 predicate(n->as_Vector()->length() == 2 || 16756 n->as_Vector()->length() == 4); 16757 match(Set dst (RShiftVS src shift)); 16758 ins_cost(INSN_COST); 16759 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 16760 ins_encode %{ 16761 int sh = (int)$shift$$constant; 16762 if (sh >= 16) sh = 15; 16763 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 16764 as_FloatRegister($src$$reg), sh); 16765 %} 16766 ins_pipe(vshift64_imm); 16767 %} 16768 16769 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 16770 predicate(n->as_Vector()->length() == 8); 16771 match(Set dst (RShiftVS src shift)); 16772 ins_cost(INSN_COST); 16773 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 16774 ins_encode %{ 16775 int sh = (int)$shift$$constant; 16776 if (sh >= 16) sh = 15; 16777 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 16778 as_FloatRegister($src$$reg), sh); 16779 %} 16780 ins_pipe(vshift128_imm); 16781 %} 16782 16783 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 16784 predicate(n->as_Vector()->length() == 2 || 16785 n->as_Vector()->length() == 4); 16786 match(Set dst (URShiftVS src shift)); 16787 ins_cost(INSN_COST); 16788 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 16789 ins_encode %{ 16790 int sh = (int)$shift$$constant; 16791 if (sh >= 16) { 16792 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16793 as_FloatRegister($src$$reg), 16794 as_FloatRegister($src$$reg)); 16795 } else { 16796 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 16797 as_FloatRegister($src$$reg), sh); 16798 } 16799 %} 16800 ins_pipe(vshift64_imm); 16801 %} 16802 16803 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 16804 predicate(n->as_Vector()->length() == 8); 16805 match(Set dst (URShiftVS src shift)); 16806 ins_cost(INSN_COST); 16807 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 16808 ins_encode %{ 16809 int sh = (int)$shift$$constant; 16810 if (sh >= 16) { 16811 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16812 as_FloatRegister($src$$reg), 16813 as_FloatRegister($src$$reg)); 16814 } else { 16815 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 16816 as_FloatRegister($src$$reg), sh); 16817 } 16818 %} 16819 ins_pipe(vshift128_imm); 16820 %} 16821 16822 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 16823 predicate(n->as_Vector()->length() == 2); 16824 match(Set dst (LShiftVI src shift)); 16825 ins_cost(INSN_COST); 16826 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 16827 ins_encode %{ 16828 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16829 as_FloatRegister($src$$reg), 16830 as_FloatRegister($shift$$reg)); 16831 %} 16832 ins_pipe(vshift64); 16833 %} 16834 16835 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 16836 predicate(n->as_Vector()->length() == 4); 16837 match(Set dst (LShiftVI src shift)); 16838 ins_cost(INSN_COST); 16839 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 16840 ins_encode %{ 16841 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16842 as_FloatRegister($src$$reg), 16843 as_FloatRegister($shift$$reg)); 16844 %} 16845 ins_pipe(vshift128); 16846 %} 16847 16848 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16849 predicate(n->as_Vector()->length() == 2); 16850 match(Set dst (RShiftVI src shift)); 16851 ins_cost(INSN_COST); 16852 effect(TEMP tmp); 16853 format %{ "negr $tmp,$shift\t" 16854 "sshl $dst,$src,$tmp\t# vector (2S)" %} 16855 ins_encode %{ 16856 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16857 as_FloatRegister($shift$$reg)); 16858 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16859 as_FloatRegister($src$$reg), 16860 as_FloatRegister($tmp$$reg)); 16861 %} 16862 ins_pipe(vshift64); 16863 %} 16864 16865 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16866 predicate(n->as_Vector()->length() == 4); 16867 match(Set dst (RShiftVI src shift)); 16868 ins_cost(INSN_COST); 16869 effect(TEMP tmp); 16870 format %{ "negr $tmp,$shift\t" 16871 "sshl $dst,$src,$tmp\t# vector (4S)" %} 16872 ins_encode %{ 16873 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16874 as_FloatRegister($shift$$reg)); 16875 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16876 as_FloatRegister($src$$reg), 16877 as_FloatRegister($tmp$$reg)); 16878 %} 16879 ins_pipe(vshift128); 16880 %} 16881 16882 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16883 predicate(n->as_Vector()->length() == 2); 16884 match(Set dst (URShiftVI src shift)); 16885 ins_cost(INSN_COST); 16886 effect(TEMP tmp); 16887 format %{ "negr $tmp,$shift\t" 16888 "ushl $dst,$src,$tmp\t# vector (2S)" %} 16889 ins_encode %{ 16890 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16891 as_FloatRegister($shift$$reg)); 16892 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 16893 as_FloatRegister($src$$reg), 16894 as_FloatRegister($tmp$$reg)); 16895 %} 16896 ins_pipe(vshift64); 16897 %} 16898 16899 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16900 predicate(n->as_Vector()->length() == 4); 16901 match(Set dst (URShiftVI src shift)); 16902 ins_cost(INSN_COST); 16903 effect(TEMP tmp); 16904 format %{ "negr $tmp,$shift\t" 16905 "ushl $dst,$src,$tmp\t# vector (4S)" %} 16906 ins_encode %{ 16907 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16908 as_FloatRegister($shift$$reg)); 16909 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 16910 as_FloatRegister($src$$reg), 16911 as_FloatRegister($tmp$$reg)); 16912 %} 16913 ins_pipe(vshift128); 16914 %} 16915 16916 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 16917 predicate(n->as_Vector()->length() == 2); 16918 match(Set dst (LShiftVI src shift)); 16919 ins_cost(INSN_COST); 16920 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 16921 ins_encode %{ 16922 __ shl(as_FloatRegister($dst$$reg), __ T2S, 16923 as_FloatRegister($src$$reg), 16924 (int)$shift$$constant); 16925 %} 16926 ins_pipe(vshift64_imm); 16927 %} 16928 16929 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 16930 predicate(n->as_Vector()->length() == 4); 16931 match(Set dst (LShiftVI src shift)); 16932 ins_cost(INSN_COST); 16933 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 16934 ins_encode %{ 16935 __ shl(as_FloatRegister($dst$$reg), __ T4S, 16936 as_FloatRegister($src$$reg), 16937 (int)$shift$$constant); 16938 %} 16939 ins_pipe(vshift128_imm); 16940 %} 16941 16942 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 16943 predicate(n->as_Vector()->length() == 2); 16944 match(Set dst (RShiftVI src shift)); 16945 ins_cost(INSN_COST); 16946 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 16947 ins_encode %{ 16948 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 16949 as_FloatRegister($src$$reg), 16950 (int)$shift$$constant); 16951 %} 16952 ins_pipe(vshift64_imm); 16953 %} 16954 16955 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 16956 predicate(n->as_Vector()->length() == 4); 16957 match(Set dst (RShiftVI src shift)); 16958 ins_cost(INSN_COST); 16959 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 16960 ins_encode %{ 16961 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 16962 as_FloatRegister($src$$reg), 16963 (int)$shift$$constant); 16964 %} 16965 ins_pipe(vshift128_imm); 16966 %} 16967 16968 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 16969 predicate(n->as_Vector()->length() == 2); 16970 match(Set dst (URShiftVI src shift)); 16971 ins_cost(INSN_COST); 16972 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 16973 ins_encode %{ 16974 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 16975 as_FloatRegister($src$$reg), 16976 (int)$shift$$constant); 16977 %} 16978 ins_pipe(vshift64_imm); 16979 %} 16980 16981 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 16982 predicate(n->as_Vector()->length() == 4); 16983 match(Set dst (URShiftVI src shift)); 16984 ins_cost(INSN_COST); 16985 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 16986 ins_encode %{ 16987 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 16988 as_FloatRegister($src$$reg), 16989 (int)$shift$$constant); 16990 %} 16991 ins_pipe(vshift128_imm); 16992 %} 16993 16994 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 16995 predicate(n->as_Vector()->length() == 2); 16996 match(Set dst (LShiftVL src shift)); 16997 ins_cost(INSN_COST); 16998 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 16999 ins_encode %{ 17000 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17001 as_FloatRegister($src$$reg), 17002 as_FloatRegister($shift$$reg)); 17003 %} 17004 ins_pipe(vshift128); 17005 %} 17006 17007 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17008 predicate(n->as_Vector()->length() == 2); 17009 match(Set dst (RShiftVL src shift)); 17010 ins_cost(INSN_COST); 17011 effect(TEMP tmp); 17012 format %{ "negr $tmp,$shift\t" 17013 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17014 ins_encode %{ 17015 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17016 as_FloatRegister($shift$$reg)); 17017 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17018 as_FloatRegister($src$$reg), 17019 as_FloatRegister($tmp$$reg)); 17020 %} 17021 ins_pipe(vshift128); 17022 %} 17023 17024 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17025 predicate(n->as_Vector()->length() == 2); 17026 match(Set dst (URShiftVL src shift)); 17027 ins_cost(INSN_COST); 17028 effect(TEMP tmp); 17029 format %{ "negr $tmp,$shift\t" 17030 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17031 ins_encode %{ 17032 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17033 as_FloatRegister($shift$$reg)); 17034 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17035 as_FloatRegister($src$$reg), 17036 as_FloatRegister($tmp$$reg)); 17037 %} 17038 ins_pipe(vshift128); 17039 %} 17040 17041 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17042 predicate(n->as_Vector()->length() == 2); 17043 match(Set dst (LShiftVL src shift)); 17044 ins_cost(INSN_COST); 17045 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17046 ins_encode %{ 17047 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17048 as_FloatRegister($src$$reg), 17049 (int)$shift$$constant); 17050 %} 17051 ins_pipe(vshift128_imm); 17052 %} 17053 17054 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17055 predicate(n->as_Vector()->length() == 2); 17056 match(Set dst (RShiftVL src shift)); 17057 ins_cost(INSN_COST); 17058 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17059 ins_encode %{ 17060 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17061 as_FloatRegister($src$$reg), 17062 (int)$shift$$constant); 17063 %} 17064 ins_pipe(vshift128_imm); 17065 %} 17066 17067 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17068 predicate(n->as_Vector()->length() == 2); 17069 match(Set dst (URShiftVL src shift)); 17070 ins_cost(INSN_COST); 17071 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17072 ins_encode %{ 17073 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17074 as_FloatRegister($src$$reg), 17075 (int)$shift$$constant); 17076 %} 17077 ins_pipe(vshift128_imm); 17078 %} 17079 17080 //----------PEEPHOLE RULES----------------------------------------------------- 17081 // These must follow all instruction definitions as they use the names 17082 // defined in the instructions definitions. 17083 // 17084 // peepmatch ( root_instr_name [preceding_instruction]* ); 17085 // 17086 // peepconstraint %{ 17087 // (instruction_number.operand_name relational_op instruction_number.operand_name 17088 // [, ...] ); 17089 // // instruction numbers are zero-based using left to right order in peepmatch 17090 // 17091 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17092 // // provide an instruction_number.operand_name for each operand that appears 17093 // // in the replacement instruction's match rule 17094 // 17095 // ---------VM FLAGS--------------------------------------------------------- 17096 // 17097 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17098 // 17099 // Each peephole rule is given an identifying number starting with zero and 17100 // increasing by one in the order seen by the parser. An individual peephole 17101 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17102 // on the command-line. 17103 // 17104 // ---------CURRENT LIMITATIONS---------------------------------------------- 17105 // 17106 // Only match adjacent instructions in same basic block 17107 // Only equality constraints 17108 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17109 // Only one replacement instruction 17110 // 17111 // ---------EXAMPLE---------------------------------------------------------- 17112 // 17113 // // pertinent parts of existing instructions in architecture description 17114 // instruct movI(iRegINoSp dst, iRegI src) 17115 // %{ 17116 // match(Set dst (CopyI src)); 17117 // %} 17118 // 17119 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17120 // %{ 17121 // match(Set dst (AddI dst src)); 17122 // effect(KILL cr); 17123 // %} 17124 // 17125 // // Change (inc mov) to lea 17126 // peephole %{ 17127 // // increment preceeded by register-register move 17128 // peepmatch ( incI_iReg movI ); 17129 // // require that the destination register of the increment 17130 // // match the destination register of the move 17131 // peepconstraint ( 0.dst == 1.dst ); 17132 // // construct a replacement instruction that sets 17133 // // the destination to ( move's source register + one ) 17134 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17135 // %} 17136 // 17137 17138 // Implementation no longer uses movX instructions since 17139 // machine-independent system no longer uses CopyX nodes. 17140 // 17141 // peephole 17142 // %{ 17143 // peepmatch (incI_iReg movI); 17144 // peepconstraint (0.dst == 1.dst); 17145 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17146 // %} 17147 17148 // peephole 17149 // %{ 17150 // peepmatch (decI_iReg movI); 17151 // peepconstraint (0.dst == 1.dst); 17152 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17153 // %} 17154 17155 // peephole 17156 // %{ 17157 // peepmatch (addI_iReg_imm movI); 17158 // peepconstraint (0.dst == 1.dst); 17159 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17160 // %} 17161 17162 // peephole 17163 // %{ 17164 // peepmatch (incL_iReg movL); 17165 // peepconstraint (0.dst == 1.dst); 17166 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17167 // %} 17168 17169 // peephole 17170 // %{ 17171 // peepmatch (decL_iReg movL); 17172 // peepconstraint (0.dst == 1.dst); 17173 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17174 // %} 17175 17176 // peephole 17177 // %{ 17178 // peepmatch (addL_iReg_imm movL); 17179 // peepconstraint (0.dst == 1.dst); 17180 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17181 // %} 17182 17183 // peephole 17184 // %{ 17185 // peepmatch (addP_iReg_imm movP); 17186 // peepconstraint (0.dst == 1.dst); 17187 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17188 // %} 17189 17190 // // Change load of spilled value to only a spill 17191 // instruct storeI(memory mem, iRegI src) 17192 // %{ 17193 // match(Set mem (StoreI mem src)); 17194 // %} 17195 // 17196 // instruct loadI(iRegINoSp dst, memory mem) 17197 // %{ 17198 // match(Set dst (LoadI mem)); 17199 // %} 17200 // 17201 17202 //----------SMARTSPILL RULES--------------------------------------------------- 17203 // These must follow all instruction definitions as they use the names 17204 // defined in the instructions definitions. 17205 17206 // Local Variables: 17207 // mode: c++ 17208 // End: