1 // 2 // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 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); 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) 1263 // 1264 // return true if opcode is one of the possible CompareAndSwapX 1265 // values otherwise false. 1266 1267 bool is_CAS(int opcode) 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 return true; 1278 // These are TBD 1279 case Op_WeakCompareAndSwapB: 1280 case Op_WeakCompareAndSwapS: 1281 case Op_WeakCompareAndSwapI: 1282 case Op_WeakCompareAndSwapL: 1283 case Op_WeakCompareAndSwapP: 1284 case Op_WeakCompareAndSwapN: 1285 case Op_CompareAndExchangeB: 1286 case Op_CompareAndExchangeS: 1287 case Op_CompareAndExchangeI: 1288 case Op_CompareAndExchangeL: 1289 case Op_CompareAndExchangeP: 1290 case Op_CompareAndExchangeN: 1291 return false; 1292 default: 1293 return false; 1294 } 1295 } 1296 1297 // helper to determine the maximum number of Phi nodes we may need to 1298 // traverse when searching from a card mark membar for the merge mem 1299 // feeding a trailing membar or vice versa 1300 1301 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1302 1303 bool unnecessary_acquire(const Node *barrier) 1304 { 1305 assert(barrier->is_MemBar(), "expecting a membar"); 1306 1307 if (UseBarriersForVolatile) { 1308 // we need to plant a dmb 1309 return false; 1310 } 1311 1312 MemBarNode* mb = barrier->as_MemBar(); 1313 1314 if (mb->trailing_load()) { 1315 return true; 1316 } 1317 1318 if (mb->trailing_load_store()) { 1319 Node* load_store = mb->in(MemBarNode::Precedent); 1320 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1321 return is_CAS(load_store->Opcode()); 1322 } 1323 1324 return false; 1325 } 1326 1327 bool needs_acquiring_load(const Node *n) 1328 { 1329 assert(n->is_Load(), "expecting a load"); 1330 if (UseBarriersForVolatile) { 1331 // we use a normal load and a dmb 1332 return false; 1333 } 1334 1335 LoadNode *ld = n->as_Load(); 1336 1337 return ld->is_acquire(); 1338 } 1339 1340 bool unnecessary_release(const Node *n) 1341 { 1342 assert((n->is_MemBar() && 1343 n->Opcode() == Op_MemBarRelease), 1344 "expecting a release membar"); 1345 1346 if (UseBarriersForVolatile) { 1347 // we need to plant a dmb 1348 return false; 1349 } 1350 1351 MemBarNode *barrier = n->as_MemBar(); 1352 if (!barrier->leading()) { 1353 return false; 1354 } else { 1355 Node* trailing = barrier->trailing_membar(); 1356 MemBarNode* trailing_mb = trailing->as_MemBar(); 1357 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1358 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1359 1360 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1361 if (mem->is_Store()) { 1362 assert(mem->as_Store()->is_release(), ""); 1363 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1364 return true; 1365 } else { 1366 assert(mem->is_LoadStore(), ""); 1367 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1368 return is_CAS(mem->Opcode()); 1369 } 1370 } 1371 return false; 1372 } 1373 1374 bool unnecessary_volatile(const Node *n) 1375 { 1376 // assert n->is_MemBar(); 1377 if (UseBarriersForVolatile) { 1378 // we need to plant a dmb 1379 return false; 1380 } 1381 1382 MemBarNode *mbvol = n->as_MemBar(); 1383 1384 bool release = mbvol->trailing_store(); 1385 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1386 #ifdef ASSERT 1387 if (release) { 1388 Node* leading = mbvol->leading_membar(); 1389 assert(leading->Opcode() == Op_MemBarRelease, ""); 1390 assert(leading->as_MemBar()->leading_store(), ""); 1391 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1392 } 1393 #endif 1394 1395 return release; 1396 } 1397 1398 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1399 1400 bool needs_releasing_store(const Node *n) 1401 { 1402 // assert n->is_Store(); 1403 if (UseBarriersForVolatile) { 1404 // we use a normal store and dmb combination 1405 return false; 1406 } 1407 1408 StoreNode *st = n->as_Store(); 1409 1410 return st->trailing_membar() != NULL; 1411 } 1412 1413 // predicate controlling translation of CAS 1414 // 1415 // returns true if CAS needs to use an acquiring load otherwise false 1416 1417 bool needs_acquiring_load_exclusive(const Node *n) 1418 { 1419 assert(is_CAS(n->Opcode()), "expecting a compare and swap"); 1420 if (UseBarriersForVolatile) { 1421 return false; 1422 } 1423 1424 LoadStoreNode* ldst = n->as_LoadStore(); 1425 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1426 1427 // so we can just return true here 1428 return true; 1429 } 1430 1431 // predicate controlling translation of StoreCM 1432 // 1433 // returns true if a StoreStore must precede the card write otherwise 1434 // false 1435 1436 bool unnecessary_storestore(const Node *storecm) 1437 { 1438 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1439 1440 // we need to generate a dmb ishst between an object put and the 1441 // associated card mark when we are using CMS without conditional 1442 // card marking 1443 1444 if (UseConcMarkSweepGC && !UseCondCardMark) { 1445 return false; 1446 } 1447 1448 // a storestore is unnecesary in all other cases 1449 1450 return true; 1451 } 1452 1453 1454 #define __ _masm. 1455 1456 // advance declarations for helper functions to convert register 1457 // indices to register objects 1458 1459 // the ad file has to provide implementations of certain methods 1460 // expected by the generic code 1461 // 1462 // REQUIRED FUNCTIONALITY 1463 1464 //============================================================================= 1465 1466 // !!!!! Special hack to get all types of calls to specify the byte offset 1467 // from the start of the call to the point where the return address 1468 // will point. 1469 1470 int MachCallStaticJavaNode::ret_addr_offset() 1471 { 1472 // call should be a simple bl 1473 int off = 4; 1474 return off; 1475 } 1476 1477 int MachCallDynamicJavaNode::ret_addr_offset() 1478 { 1479 return 16; // movz, movk, movk, bl 1480 } 1481 1482 int MachCallRuntimeNode::ret_addr_offset() { 1483 // for generated stubs the call will be 1484 // far_call(addr) 1485 // for real runtime callouts it will be six instructions 1486 // see aarch64_enc_java_to_runtime 1487 // adr(rscratch2, retaddr) 1488 // lea(rscratch1, RuntimeAddress(addr) 1489 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1490 // blrt rscratch1 1491 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1492 if (cb) { 1493 return MacroAssembler::far_branch_size(); 1494 } else { 1495 return 6 * NativeInstruction::instruction_size; 1496 } 1497 } 1498 1499 // Indicate if the safepoint node needs the polling page as an input 1500 1501 // the shared code plants the oop data at the start of the generated 1502 // code for the safepoint node and that needs ot be at the load 1503 // instruction itself. so we cannot plant a mov of the safepoint poll 1504 // address followed by a load. setting this to true means the mov is 1505 // scheduled as a prior instruction. that's better for scheduling 1506 // anyway. 1507 1508 bool SafePointNode::needs_polling_address_input() 1509 { 1510 return true; 1511 } 1512 1513 //============================================================================= 1514 1515 #ifndef PRODUCT 1516 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1517 st->print("BREAKPOINT"); 1518 } 1519 #endif 1520 1521 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1522 MacroAssembler _masm(&cbuf); 1523 __ brk(0); 1524 } 1525 1526 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1527 return MachNode::size(ra_); 1528 } 1529 1530 //============================================================================= 1531 1532 #ifndef PRODUCT 1533 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1534 st->print("nop \t# %d bytes pad for loops and calls", _count); 1535 } 1536 #endif 1537 1538 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1539 MacroAssembler _masm(&cbuf); 1540 for (int i = 0; i < _count; i++) { 1541 __ nop(); 1542 } 1543 } 1544 1545 uint MachNopNode::size(PhaseRegAlloc*) const { 1546 return _count * NativeInstruction::instruction_size; 1547 } 1548 1549 //============================================================================= 1550 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1551 1552 int Compile::ConstantTable::calculate_table_base_offset() const { 1553 return 0; // absolute addressing, no offset 1554 } 1555 1556 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1557 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1558 ShouldNotReachHere(); 1559 } 1560 1561 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1562 // Empty encoding 1563 } 1564 1565 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1566 return 0; 1567 } 1568 1569 #ifndef PRODUCT 1570 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1571 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1572 } 1573 #endif 1574 1575 #ifndef PRODUCT 1576 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1577 Compile* C = ra_->C; 1578 1579 int framesize = C->frame_slots() << LogBytesPerInt; 1580 1581 if (C->need_stack_bang(framesize)) 1582 st->print("# stack bang size=%d\n\t", framesize); 1583 1584 if (framesize < ((1 << 9) + 2 * wordSize)) { 1585 st->print("sub sp, sp, #%d\n\t", framesize); 1586 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1587 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1588 } else { 1589 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1590 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1591 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1592 st->print("sub sp, sp, rscratch1"); 1593 } 1594 } 1595 #endif 1596 1597 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1598 Compile* C = ra_->C; 1599 MacroAssembler _masm(&cbuf); 1600 1601 // n.b. frame size includes space for return pc and rfp 1602 const long framesize = C->frame_size_in_bytes(); 1603 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1604 1605 // insert a nop at the start of the prolog so we can patch in a 1606 // branch if we need to invalidate the method later 1607 __ nop(); 1608 1609 int bangsize = C->bang_size_in_bytes(); 1610 if (C->need_stack_bang(bangsize) && UseStackBanging) 1611 __ generate_stack_overflow_check(bangsize); 1612 1613 __ build_frame(framesize); 1614 1615 if (NotifySimulator) { 1616 __ notify(Assembler::method_entry); 1617 } 1618 1619 if (VerifyStackAtCalls) { 1620 Unimplemented(); 1621 } 1622 1623 C->set_frame_complete(cbuf.insts_size()); 1624 1625 if (C->has_mach_constant_base_node()) { 1626 // NOTE: We set the table base offset here because users might be 1627 // emitted before MachConstantBaseNode. 1628 Compile::ConstantTable& constant_table = C->constant_table(); 1629 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1630 } 1631 } 1632 1633 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1634 { 1635 return MachNode::size(ra_); // too many variables; just compute it 1636 // the hard way 1637 } 1638 1639 int MachPrologNode::reloc() const 1640 { 1641 return 0; 1642 } 1643 1644 //============================================================================= 1645 1646 #ifndef PRODUCT 1647 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1648 Compile* C = ra_->C; 1649 int framesize = C->frame_slots() << LogBytesPerInt; 1650 1651 st->print("# pop frame %d\n\t",framesize); 1652 1653 if (framesize == 0) { 1654 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1655 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1656 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1657 st->print("add sp, sp, #%d\n\t", framesize); 1658 } else { 1659 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1660 st->print("add sp, sp, rscratch1\n\t"); 1661 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1662 } 1663 1664 if (do_polling() && C->is_method_compilation()) { 1665 st->print("# touch polling page\n\t"); 1666 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1667 st->print("ldr zr, [rscratch1]"); 1668 } 1669 } 1670 #endif 1671 1672 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1673 Compile* C = ra_->C; 1674 MacroAssembler _masm(&cbuf); 1675 int framesize = C->frame_slots() << LogBytesPerInt; 1676 1677 __ remove_frame(framesize); 1678 1679 if (NotifySimulator) { 1680 __ notify(Assembler::method_reentry); 1681 } 1682 1683 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1684 __ reserved_stack_check(); 1685 } 1686 1687 if (do_polling() && C->is_method_compilation()) { 1688 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1689 } 1690 } 1691 1692 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1693 // Variable size. Determine dynamically. 1694 return MachNode::size(ra_); 1695 } 1696 1697 int MachEpilogNode::reloc() const { 1698 // Return number of relocatable values contained in this instruction. 1699 return 1; // 1 for polling page. 1700 } 1701 1702 const Pipeline * MachEpilogNode::pipeline() const { 1703 return MachNode::pipeline_class(); 1704 } 1705 1706 // This method seems to be obsolete. It is declared in machnode.hpp 1707 // and defined in all *.ad files, but it is never called. Should we 1708 // get rid of it? 1709 int MachEpilogNode::safepoint_offset() const { 1710 assert(do_polling(), "no return for this epilog node"); 1711 return 4; 1712 } 1713 1714 //============================================================================= 1715 1716 // Figure out which register class each belongs in: rc_int, rc_float or 1717 // rc_stack. 1718 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1719 1720 static enum RC rc_class(OptoReg::Name reg) { 1721 1722 if (reg == OptoReg::Bad) { 1723 return rc_bad; 1724 } 1725 1726 // we have 30 int registers * 2 halves 1727 // (rscratch1 and rscratch2 are omitted) 1728 1729 if (reg < 60) { 1730 return rc_int; 1731 } 1732 1733 // we have 32 float register * 2 halves 1734 if (reg < 60 + 128) { 1735 return rc_float; 1736 } 1737 1738 // Between float regs & stack is the flags regs. 1739 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1740 1741 return rc_stack; 1742 } 1743 1744 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1745 Compile* C = ra_->C; 1746 1747 // Get registers to move. 1748 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1749 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1750 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1751 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1752 1753 enum RC src_hi_rc = rc_class(src_hi); 1754 enum RC src_lo_rc = rc_class(src_lo); 1755 enum RC dst_hi_rc = rc_class(dst_hi); 1756 enum RC dst_lo_rc = rc_class(dst_lo); 1757 1758 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1759 1760 if (src_hi != OptoReg::Bad) { 1761 assert((src_lo&1)==0 && src_lo+1==src_hi && 1762 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1763 "expected aligned-adjacent pairs"); 1764 } 1765 1766 if (src_lo == dst_lo && src_hi == dst_hi) { 1767 return 0; // Self copy, no move. 1768 } 1769 1770 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1771 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1772 int src_offset = ra_->reg2offset(src_lo); 1773 int dst_offset = ra_->reg2offset(dst_lo); 1774 1775 if (bottom_type()->isa_vect() != NULL) { 1776 uint ireg = ideal_reg(); 1777 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1778 if (cbuf) { 1779 MacroAssembler _masm(cbuf); 1780 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1781 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1782 // stack->stack 1783 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1784 if (ireg == Op_VecD) { 1785 __ unspill(rscratch1, true, src_offset); 1786 __ spill(rscratch1, true, dst_offset); 1787 } else { 1788 __ spill_copy128(src_offset, dst_offset); 1789 } 1790 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1791 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1792 ireg == Op_VecD ? __ T8B : __ T16B, 1793 as_FloatRegister(Matcher::_regEncode[src_lo])); 1794 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1795 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1796 ireg == Op_VecD ? __ D : __ Q, 1797 ra_->reg2offset(dst_lo)); 1798 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1799 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1800 ireg == Op_VecD ? __ D : __ Q, 1801 ra_->reg2offset(src_lo)); 1802 } else { 1803 ShouldNotReachHere(); 1804 } 1805 } 1806 } else if (cbuf) { 1807 MacroAssembler _masm(cbuf); 1808 switch (src_lo_rc) { 1809 case rc_int: 1810 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1811 if (is64) { 1812 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1813 as_Register(Matcher::_regEncode[src_lo])); 1814 } else { 1815 MacroAssembler _masm(cbuf); 1816 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1817 as_Register(Matcher::_regEncode[src_lo])); 1818 } 1819 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1820 if (is64) { 1821 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1822 as_Register(Matcher::_regEncode[src_lo])); 1823 } else { 1824 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1825 as_Register(Matcher::_regEncode[src_lo])); 1826 } 1827 } else { // gpr --> stack spill 1828 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1829 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1830 } 1831 break; 1832 case rc_float: 1833 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1834 if (is64) { 1835 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1836 as_FloatRegister(Matcher::_regEncode[src_lo])); 1837 } else { 1838 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1839 as_FloatRegister(Matcher::_regEncode[src_lo])); 1840 } 1841 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1842 if (cbuf) { 1843 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1844 as_FloatRegister(Matcher::_regEncode[src_lo])); 1845 } else { 1846 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1847 as_FloatRegister(Matcher::_regEncode[src_lo])); 1848 } 1849 } else { // fpr --> stack spill 1850 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1851 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1852 is64 ? __ D : __ S, dst_offset); 1853 } 1854 break; 1855 case rc_stack: 1856 if (dst_lo_rc == rc_int) { // stack --> gpr load 1857 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1858 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1859 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1860 is64 ? __ D : __ S, src_offset); 1861 } else { // stack --> stack copy 1862 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1863 __ unspill(rscratch1, is64, src_offset); 1864 __ spill(rscratch1, is64, dst_offset); 1865 } 1866 break; 1867 default: 1868 assert(false, "bad rc_class for spill"); 1869 ShouldNotReachHere(); 1870 } 1871 } 1872 1873 if (st) { 1874 st->print("spill "); 1875 if (src_lo_rc == rc_stack) { 1876 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1877 } else { 1878 st->print("%s -> ", Matcher::regName[src_lo]); 1879 } 1880 if (dst_lo_rc == rc_stack) { 1881 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1882 } else { 1883 st->print("%s", Matcher::regName[dst_lo]); 1884 } 1885 if (bottom_type()->isa_vect() != NULL) { 1886 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1887 } else { 1888 st->print("\t# spill size = %d", is64 ? 64:32); 1889 } 1890 } 1891 1892 return 0; 1893 1894 } 1895 1896 #ifndef PRODUCT 1897 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1898 if (!ra_) 1899 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1900 else 1901 implementation(NULL, ra_, false, st); 1902 } 1903 #endif 1904 1905 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1906 implementation(&cbuf, ra_, false, NULL); 1907 } 1908 1909 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1910 return MachNode::size(ra_); 1911 } 1912 1913 //============================================================================= 1914 1915 #ifndef PRODUCT 1916 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1917 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1918 int reg = ra_->get_reg_first(this); 1919 st->print("add %s, rsp, #%d]\t# box lock", 1920 Matcher::regName[reg], offset); 1921 } 1922 #endif 1923 1924 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1925 MacroAssembler _masm(&cbuf); 1926 1927 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1928 int reg = ra_->get_encode(this); 1929 1930 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1931 __ add(as_Register(reg), sp, offset); 1932 } else { 1933 ShouldNotReachHere(); 1934 } 1935 } 1936 1937 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1938 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1939 return 4; 1940 } 1941 1942 //============================================================================= 1943 1944 #ifndef PRODUCT 1945 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1946 { 1947 st->print_cr("# MachUEPNode"); 1948 if (UseCompressedClassPointers) { 1949 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1950 if (Universe::narrow_klass_shift() != 0) { 1951 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1952 } 1953 } else { 1954 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1955 } 1956 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1957 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1958 } 1959 #endif 1960 1961 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1962 { 1963 // This is the unverified entry point. 1964 MacroAssembler _masm(&cbuf); 1965 1966 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1967 Label skip; 1968 // TODO 1969 // can we avoid this skip and still use a reloc? 1970 __ br(Assembler::EQ, skip); 1971 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1972 __ bind(skip); 1973 } 1974 1975 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1976 { 1977 return MachNode::size(ra_); 1978 } 1979 1980 // REQUIRED EMIT CODE 1981 1982 //============================================================================= 1983 1984 // Emit exception handler code. 1985 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1986 { 1987 // mov rscratch1 #exception_blob_entry_point 1988 // br rscratch1 1989 // Note that the code buffer's insts_mark is always relative to insts. 1990 // That's why we must use the macroassembler to generate a handler. 1991 MacroAssembler _masm(&cbuf); 1992 address base = __ start_a_stub(size_exception_handler()); 1993 if (base == NULL) { 1994 ciEnv::current()->record_failure("CodeCache is full"); 1995 return 0; // CodeBuffer::expand failed 1996 } 1997 int offset = __ offset(); 1998 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1999 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2000 __ end_a_stub(); 2001 return offset; 2002 } 2003 2004 // Emit deopt handler code. 2005 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2006 { 2007 // Note that the code buffer's insts_mark is always relative to insts. 2008 // That's why we must use the macroassembler to generate a handler. 2009 MacroAssembler _masm(&cbuf); 2010 address base = __ start_a_stub(size_deopt_handler()); 2011 if (base == NULL) { 2012 ciEnv::current()->record_failure("CodeCache is full"); 2013 return 0; // CodeBuffer::expand failed 2014 } 2015 int offset = __ offset(); 2016 2017 __ adr(lr, __ pc()); 2018 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2019 2020 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2021 __ end_a_stub(); 2022 return offset; 2023 } 2024 2025 // REQUIRED MATCHER CODE 2026 2027 //============================================================================= 2028 2029 const bool Matcher::match_rule_supported(int opcode) { 2030 2031 switch (opcode) { 2032 default: 2033 break; 2034 } 2035 2036 if (!has_match_rule(opcode)) { 2037 return false; 2038 } 2039 2040 return true; // Per default match rules are supported. 2041 } 2042 2043 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2044 2045 // TODO 2046 // identify extra cases that we might want to provide match rules for 2047 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2048 bool ret_value = match_rule_supported(opcode); 2049 // Add rules here. 2050 2051 return ret_value; // Per default match rules are supported. 2052 } 2053 2054 const bool Matcher::has_predicated_vectors(void) { 2055 return false; 2056 } 2057 2058 const int Matcher::float_pressure(int default_pressure_threshold) { 2059 return default_pressure_threshold; 2060 } 2061 2062 int Matcher::regnum_to_fpu_offset(int regnum) 2063 { 2064 Unimplemented(); 2065 return 0; 2066 } 2067 2068 // Is this branch offset short enough that a short branch can be used? 2069 // 2070 // NOTE: If the platform does not provide any short branch variants, then 2071 // this method should return false for offset 0. 2072 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2073 // The passed offset is relative to address of the branch. 2074 2075 return (-32768 <= offset && offset < 32768); 2076 } 2077 2078 const bool Matcher::isSimpleConstant64(jlong value) { 2079 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2080 // Probably always true, even if a temp register is required. 2081 return true; 2082 } 2083 2084 // true just means we have fast l2f conversion 2085 const bool Matcher::convL2FSupported(void) { 2086 return true; 2087 } 2088 2089 // Vector width in bytes. 2090 const int Matcher::vector_width_in_bytes(BasicType bt) { 2091 int size = MIN2(16,(int)MaxVectorSize); 2092 // Minimum 2 values in vector 2093 if (size < 2*type2aelembytes(bt)) size = 0; 2094 // But never < 4 2095 if (size < 4) size = 0; 2096 return size; 2097 } 2098 2099 // Limits on vector size (number of elements) loaded into vector. 2100 const int Matcher::max_vector_size(const BasicType bt) { 2101 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2102 } 2103 const int Matcher::min_vector_size(const BasicType bt) { 2104 // For the moment limit the vector size to 8 bytes 2105 int size = 8 / type2aelembytes(bt); 2106 if (size < 2) size = 2; 2107 return size; 2108 } 2109 2110 // Vector ideal reg. 2111 const uint Matcher::vector_ideal_reg(int len) { 2112 switch(len) { 2113 case 8: return Op_VecD; 2114 case 16: return Op_VecX; 2115 } 2116 ShouldNotReachHere(); 2117 return 0; 2118 } 2119 2120 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2121 return Op_VecX; 2122 } 2123 2124 // AES support not yet implemented 2125 const bool Matcher::pass_original_key_for_aes() { 2126 return false; 2127 } 2128 2129 // x86 supports misaligned vectors store/load. 2130 const bool Matcher::misaligned_vectors_ok() { 2131 return !AlignVector; // can be changed by flag 2132 } 2133 2134 // false => size gets scaled to BytesPerLong, ok. 2135 const bool Matcher::init_array_count_is_in_bytes = false; 2136 2137 // Use conditional move (CMOVL) 2138 const int Matcher::long_cmove_cost() { 2139 // long cmoves are no more expensive than int cmoves 2140 return 0; 2141 } 2142 2143 const int Matcher::float_cmove_cost() { 2144 // float cmoves are no more expensive than int cmoves 2145 return 0; 2146 } 2147 2148 // Does the CPU require late expand (see block.cpp for description of late expand)? 2149 const bool Matcher::require_postalloc_expand = false; 2150 2151 // Do we need to mask the count passed to shift instructions or does 2152 // the cpu only look at the lower 5/6 bits anyway? 2153 const bool Matcher::need_masked_shift_count = false; 2154 2155 // This affects two different things: 2156 // - how Decode nodes are matched 2157 // - how ImplicitNullCheck opportunities are recognized 2158 // If true, the matcher will try to remove all Decodes and match them 2159 // (as operands) into nodes. NullChecks are not prepared to deal with 2160 // Decodes by final_graph_reshaping(). 2161 // If false, final_graph_reshaping() forces the decode behind the Cmp 2162 // for a NullCheck. The matcher matches the Decode node into a register. 2163 // Implicit_null_check optimization moves the Decode along with the 2164 // memory operation back up before the NullCheck. 2165 bool Matcher::narrow_oop_use_complex_address() { 2166 return Universe::narrow_oop_shift() == 0; 2167 } 2168 2169 bool Matcher::narrow_klass_use_complex_address() { 2170 // TODO 2171 // decide whether we need to set this to true 2172 return false; 2173 } 2174 2175 bool Matcher::const_oop_prefer_decode() { 2176 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2177 return Universe::narrow_oop_base() == NULL; 2178 } 2179 2180 bool Matcher::const_klass_prefer_decode() { 2181 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2182 return Universe::narrow_klass_base() == NULL; 2183 } 2184 2185 // Is it better to copy float constants, or load them directly from 2186 // memory? Intel can load a float constant from a direct address, 2187 // requiring no extra registers. Most RISCs will have to materialize 2188 // an address into a register first, so they would do better to copy 2189 // the constant from stack. 2190 const bool Matcher::rematerialize_float_constants = false; 2191 2192 // If CPU can load and store mis-aligned doubles directly then no 2193 // fixup is needed. Else we split the double into 2 integer pieces 2194 // and move it piece-by-piece. Only happens when passing doubles into 2195 // C code as the Java calling convention forces doubles to be aligned. 2196 const bool Matcher::misaligned_doubles_ok = true; 2197 2198 // No-op on amd64 2199 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2200 Unimplemented(); 2201 } 2202 2203 // Advertise here if the CPU requires explicit rounding operations to 2204 // implement the UseStrictFP mode. 2205 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2206 2207 // Are floats converted to double when stored to stack during 2208 // deoptimization? 2209 bool Matcher::float_in_double() { return false; } 2210 2211 // Do ints take an entire long register or just half? 2212 // The relevant question is how the int is callee-saved: 2213 // the whole long is written but de-opt'ing will have to extract 2214 // the relevant 32 bits. 2215 const bool Matcher::int_in_long = true; 2216 2217 // Return whether or not this register is ever used as an argument. 2218 // This function is used on startup to build the trampoline stubs in 2219 // generateOptoStub. Registers not mentioned will be killed by the VM 2220 // call in the trampoline, and arguments in those registers not be 2221 // available to the callee. 2222 bool Matcher::can_be_java_arg(int reg) 2223 { 2224 return 2225 reg == R0_num || reg == R0_H_num || 2226 reg == R1_num || reg == R1_H_num || 2227 reg == R2_num || reg == R2_H_num || 2228 reg == R3_num || reg == R3_H_num || 2229 reg == R4_num || reg == R4_H_num || 2230 reg == R5_num || reg == R5_H_num || 2231 reg == R6_num || reg == R6_H_num || 2232 reg == R7_num || reg == R7_H_num || 2233 reg == V0_num || reg == V0_H_num || 2234 reg == V1_num || reg == V1_H_num || 2235 reg == V2_num || reg == V2_H_num || 2236 reg == V3_num || reg == V3_H_num || 2237 reg == V4_num || reg == V4_H_num || 2238 reg == V5_num || reg == V5_H_num || 2239 reg == V6_num || reg == V6_H_num || 2240 reg == V7_num || reg == V7_H_num; 2241 } 2242 2243 bool Matcher::is_spillable_arg(int reg) 2244 { 2245 return can_be_java_arg(reg); 2246 } 2247 2248 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2249 return false; 2250 } 2251 2252 RegMask Matcher::divI_proj_mask() { 2253 ShouldNotReachHere(); 2254 return RegMask(); 2255 } 2256 2257 // Register for MODI projection of divmodI. 2258 RegMask Matcher::modI_proj_mask() { 2259 ShouldNotReachHere(); 2260 return RegMask(); 2261 } 2262 2263 // Register for DIVL projection of divmodL. 2264 RegMask Matcher::divL_proj_mask() { 2265 ShouldNotReachHere(); 2266 return RegMask(); 2267 } 2268 2269 // Register for MODL projection of divmodL. 2270 RegMask Matcher::modL_proj_mask() { 2271 ShouldNotReachHere(); 2272 return RegMask(); 2273 } 2274 2275 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2276 return FP_REG_mask(); 2277 } 2278 2279 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2280 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2281 Node* u = addp->fast_out(i); 2282 if (u->is_Mem()) { 2283 int opsize = u->as_Mem()->memory_size(); 2284 assert(opsize > 0, "unexpected memory operand size"); 2285 if (u->as_Mem()->memory_size() != (1<<shift)) { 2286 return false; 2287 } 2288 } 2289 } 2290 return true; 2291 } 2292 2293 const bool Matcher::convi2l_type_required = false; 2294 2295 // Should the Matcher clone shifts on addressing modes, expecting them 2296 // to be subsumed into complex addressing expressions or compute them 2297 // into registers? 2298 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2299 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2300 return true; 2301 } 2302 2303 Node *off = m->in(AddPNode::Offset); 2304 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2305 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2306 // Are there other uses besides address expressions? 2307 !is_visited(off)) { 2308 address_visited.set(off->_idx); // Flag as address_visited 2309 mstack.push(off->in(2), Visit); 2310 Node *conv = off->in(1); 2311 if (conv->Opcode() == Op_ConvI2L && 2312 // Are there other uses besides address expressions? 2313 !is_visited(conv)) { 2314 address_visited.set(conv->_idx); // Flag as address_visited 2315 mstack.push(conv->in(1), Pre_Visit); 2316 } else { 2317 mstack.push(conv, Pre_Visit); 2318 } 2319 address_visited.test_set(m->_idx); // Flag as address_visited 2320 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2321 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2322 return true; 2323 } else if (off->Opcode() == Op_ConvI2L && 2324 // Are there other uses besides address expressions? 2325 !is_visited(off)) { 2326 address_visited.test_set(m->_idx); // Flag as address_visited 2327 address_visited.set(off->_idx); // Flag as address_visited 2328 mstack.push(off->in(1), Pre_Visit); 2329 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2330 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2331 return true; 2332 } 2333 return false; 2334 } 2335 2336 void Compile::reshape_address(AddPNode* addp) { 2337 } 2338 2339 // helper for encoding java_to_runtime calls on sim 2340 // 2341 // this is needed to compute the extra arguments required when 2342 // planting a call to the simulator blrt instruction. the TypeFunc 2343 // can be queried to identify the counts for integral, and floating 2344 // arguments and the return type 2345 2346 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2347 { 2348 int gps = 0; 2349 int fps = 0; 2350 const TypeTuple *domain = tf->domain(); 2351 int max = domain->cnt(); 2352 for (int i = TypeFunc::Parms; i < max; i++) { 2353 const Type *t = domain->field_at(i); 2354 switch(t->basic_type()) { 2355 case T_FLOAT: 2356 case T_DOUBLE: 2357 fps++; 2358 default: 2359 gps++; 2360 } 2361 } 2362 gpcnt = gps; 2363 fpcnt = fps; 2364 BasicType rt = tf->return_type(); 2365 switch (rt) { 2366 case T_VOID: 2367 rtype = MacroAssembler::ret_type_void; 2368 break; 2369 default: 2370 rtype = MacroAssembler::ret_type_integral; 2371 break; 2372 case T_FLOAT: 2373 rtype = MacroAssembler::ret_type_float; 2374 break; 2375 case T_DOUBLE: 2376 rtype = MacroAssembler::ret_type_double; 2377 break; 2378 } 2379 } 2380 2381 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2382 MacroAssembler _masm(&cbuf); \ 2383 { \ 2384 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2385 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2386 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2387 __ INSN(REG, as_Register(BASE)); \ 2388 } 2389 2390 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2391 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2392 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2393 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2394 2395 // Used for all non-volatile memory accesses. The use of 2396 // $mem->opcode() to discover whether this pattern uses sign-extended 2397 // offsets is something of a kludge. 2398 static void loadStore(MacroAssembler masm, mem_insn insn, 2399 Register reg, int opcode, 2400 Register base, int index, int size, int disp) 2401 { 2402 Address::extend scale; 2403 2404 // Hooboy, this is fugly. We need a way to communicate to the 2405 // encoder that the index needs to be sign extended, so we have to 2406 // enumerate all the cases. 2407 switch (opcode) { 2408 case INDINDEXSCALEDI2L: 2409 case INDINDEXSCALEDI2LN: 2410 case INDINDEXI2L: 2411 case INDINDEXI2LN: 2412 scale = Address::sxtw(size); 2413 break; 2414 default: 2415 scale = Address::lsl(size); 2416 } 2417 2418 if (index == -1) { 2419 (masm.*insn)(reg, Address(base, disp)); 2420 } else { 2421 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2422 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2423 } 2424 } 2425 2426 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2427 FloatRegister reg, int opcode, 2428 Register base, int index, int size, int disp) 2429 { 2430 Address::extend scale; 2431 2432 switch (opcode) { 2433 case INDINDEXSCALEDI2L: 2434 case INDINDEXSCALEDI2LN: 2435 scale = Address::sxtw(size); 2436 break; 2437 default: 2438 scale = Address::lsl(size); 2439 } 2440 2441 if (index == -1) { 2442 (masm.*insn)(reg, Address(base, disp)); 2443 } else { 2444 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2445 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2446 } 2447 } 2448 2449 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2450 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2451 int opcode, Register base, int index, int size, int disp) 2452 { 2453 if (index == -1) { 2454 (masm.*insn)(reg, T, Address(base, disp)); 2455 } else { 2456 assert(disp == 0, "unsupported address mode"); 2457 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2458 } 2459 } 2460 2461 %} 2462 2463 2464 2465 //----------ENCODING BLOCK----------------------------------------------------- 2466 // This block specifies the encoding classes used by the compiler to 2467 // output byte streams. Encoding classes are parameterized macros 2468 // used by Machine Instruction Nodes in order to generate the bit 2469 // encoding of the instruction. Operands specify their base encoding 2470 // interface with the interface keyword. There are currently 2471 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2472 // COND_INTER. REG_INTER causes an operand to generate a function 2473 // which returns its register number when queried. CONST_INTER causes 2474 // an operand to generate a function which returns the value of the 2475 // constant when queried. MEMORY_INTER causes an operand to generate 2476 // four functions which return the Base Register, the Index Register, 2477 // the Scale Value, and the Offset Value of the operand when queried. 2478 // COND_INTER causes an operand to generate six functions which return 2479 // the encoding code (ie - encoding bits for the instruction) 2480 // associated with each basic boolean condition for a conditional 2481 // instruction. 2482 // 2483 // Instructions specify two basic values for encoding. Again, a 2484 // function is available to check if the constant displacement is an 2485 // oop. They use the ins_encode keyword to specify their encoding 2486 // classes (which must be a sequence of enc_class names, and their 2487 // parameters, specified in the encoding block), and they use the 2488 // opcode keyword to specify, in order, their primary, secondary, and 2489 // tertiary opcode. Only the opcode sections which a particular 2490 // instruction needs for encoding need to be specified. 2491 encode %{ 2492 // Build emit functions for each basic byte or larger field in the 2493 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2494 // from C++ code in the enc_class source block. Emit functions will 2495 // live in the main source block for now. In future, we can 2496 // generalize this by adding a syntax that specifies the sizes of 2497 // fields in an order, so that the adlc can build the emit functions 2498 // automagically 2499 2500 // catch all for unimplemented encodings 2501 enc_class enc_unimplemented %{ 2502 MacroAssembler _masm(&cbuf); 2503 __ unimplemented("C2 catch all"); 2504 %} 2505 2506 // BEGIN Non-volatile memory access 2507 2508 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2509 Register dst_reg = as_Register($dst$$reg); 2510 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2511 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2512 %} 2513 2514 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2515 Register dst_reg = as_Register($dst$$reg); 2516 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2517 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2518 %} 2519 2520 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2521 Register dst_reg = as_Register($dst$$reg); 2522 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2523 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2524 %} 2525 2526 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2527 Register dst_reg = as_Register($dst$$reg); 2528 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2529 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2530 %} 2531 2532 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2533 Register dst_reg = as_Register($dst$$reg); 2534 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2535 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2536 %} 2537 2538 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2539 Register dst_reg = as_Register($dst$$reg); 2540 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2541 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2542 %} 2543 2544 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2545 Register dst_reg = as_Register($dst$$reg); 2546 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2547 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2548 %} 2549 2550 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2551 Register dst_reg = as_Register($dst$$reg); 2552 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2553 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2554 %} 2555 2556 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2557 Register dst_reg = as_Register($dst$$reg); 2558 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2559 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2560 %} 2561 2562 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2563 Register dst_reg = as_Register($dst$$reg); 2564 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2565 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2566 %} 2567 2568 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2569 Register dst_reg = as_Register($dst$$reg); 2570 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2571 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2572 %} 2573 2574 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2575 Register dst_reg = as_Register($dst$$reg); 2576 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2577 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2578 %} 2579 2580 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2581 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2582 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2583 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2584 %} 2585 2586 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2587 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2588 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2589 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2590 %} 2591 2592 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2593 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2594 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2595 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2596 %} 2597 2598 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2599 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2600 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2601 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2602 %} 2603 2604 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2605 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2606 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2607 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2608 %} 2609 2610 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2611 Register src_reg = as_Register($src$$reg); 2612 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2613 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2614 %} 2615 2616 enc_class aarch64_enc_strb0(memory mem) %{ 2617 MacroAssembler _masm(&cbuf); 2618 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2619 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2620 %} 2621 2622 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2623 MacroAssembler _masm(&cbuf); 2624 __ membar(Assembler::StoreStore); 2625 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2626 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2627 %} 2628 2629 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2630 Register src_reg = as_Register($src$$reg); 2631 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2632 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2633 %} 2634 2635 enc_class aarch64_enc_strh0(memory mem) %{ 2636 MacroAssembler _masm(&cbuf); 2637 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2638 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2639 %} 2640 2641 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2642 Register src_reg = as_Register($src$$reg); 2643 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2644 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2645 %} 2646 2647 enc_class aarch64_enc_strw0(memory mem) %{ 2648 MacroAssembler _masm(&cbuf); 2649 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2650 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2651 %} 2652 2653 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2654 Register src_reg = as_Register($src$$reg); 2655 // we sometimes get asked to store the stack pointer into the 2656 // current thread -- we cannot do that directly on AArch64 2657 if (src_reg == r31_sp) { 2658 MacroAssembler _masm(&cbuf); 2659 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2660 __ mov(rscratch2, sp); 2661 src_reg = rscratch2; 2662 } 2663 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2664 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2665 %} 2666 2667 enc_class aarch64_enc_str0(memory mem) %{ 2668 MacroAssembler _masm(&cbuf); 2669 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2670 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2671 %} 2672 2673 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2674 FloatRegister src_reg = as_FloatRegister($src$$reg); 2675 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2676 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2677 %} 2678 2679 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2680 FloatRegister src_reg = as_FloatRegister($src$$reg); 2681 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2682 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2683 %} 2684 2685 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2686 FloatRegister src_reg = as_FloatRegister($src$$reg); 2687 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2688 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2689 %} 2690 2691 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2692 FloatRegister src_reg = as_FloatRegister($src$$reg); 2693 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2694 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2695 %} 2696 2697 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2698 FloatRegister src_reg = as_FloatRegister($src$$reg); 2699 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2700 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2701 %} 2702 2703 // END Non-volatile memory access 2704 2705 // volatile loads and stores 2706 2707 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2708 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2709 rscratch1, stlrb); 2710 %} 2711 2712 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2713 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2714 rscratch1, stlrh); 2715 %} 2716 2717 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2718 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2719 rscratch1, stlrw); 2720 %} 2721 2722 2723 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2724 Register dst_reg = as_Register($dst$$reg); 2725 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2726 rscratch1, ldarb); 2727 __ sxtbw(dst_reg, dst_reg); 2728 %} 2729 2730 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2731 Register dst_reg = as_Register($dst$$reg); 2732 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2733 rscratch1, ldarb); 2734 __ sxtb(dst_reg, dst_reg); 2735 %} 2736 2737 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2738 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2739 rscratch1, ldarb); 2740 %} 2741 2742 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2743 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2744 rscratch1, ldarb); 2745 %} 2746 2747 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2748 Register dst_reg = as_Register($dst$$reg); 2749 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2750 rscratch1, ldarh); 2751 __ sxthw(dst_reg, dst_reg); 2752 %} 2753 2754 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2755 Register dst_reg = as_Register($dst$$reg); 2756 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2757 rscratch1, ldarh); 2758 __ sxth(dst_reg, dst_reg); 2759 %} 2760 2761 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2762 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2763 rscratch1, ldarh); 2764 %} 2765 2766 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2767 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2768 rscratch1, ldarh); 2769 %} 2770 2771 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2772 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2773 rscratch1, ldarw); 2774 %} 2775 2776 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2777 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2778 rscratch1, ldarw); 2779 %} 2780 2781 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2782 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2783 rscratch1, ldar); 2784 %} 2785 2786 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2787 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2788 rscratch1, ldarw); 2789 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2790 %} 2791 2792 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2793 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2794 rscratch1, ldar); 2795 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2796 %} 2797 2798 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2799 Register src_reg = as_Register($src$$reg); 2800 // we sometimes get asked to store the stack pointer into the 2801 // current thread -- we cannot do that directly on AArch64 2802 if (src_reg == r31_sp) { 2803 MacroAssembler _masm(&cbuf); 2804 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2805 __ mov(rscratch2, sp); 2806 src_reg = rscratch2; 2807 } 2808 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2809 rscratch1, stlr); 2810 %} 2811 2812 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2813 { 2814 MacroAssembler _masm(&cbuf); 2815 FloatRegister src_reg = as_FloatRegister($src$$reg); 2816 __ fmovs(rscratch2, src_reg); 2817 } 2818 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2819 rscratch1, stlrw); 2820 %} 2821 2822 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2823 { 2824 MacroAssembler _masm(&cbuf); 2825 FloatRegister src_reg = as_FloatRegister($src$$reg); 2826 __ fmovd(rscratch2, src_reg); 2827 } 2828 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2829 rscratch1, stlr); 2830 %} 2831 2832 // synchronized read/update encodings 2833 2834 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2835 MacroAssembler _masm(&cbuf); 2836 Register dst_reg = as_Register($dst$$reg); 2837 Register base = as_Register($mem$$base); 2838 int index = $mem$$index; 2839 int scale = $mem$$scale; 2840 int disp = $mem$$disp; 2841 if (index == -1) { 2842 if (disp != 0) { 2843 __ lea(rscratch1, Address(base, disp)); 2844 __ ldaxr(dst_reg, rscratch1); 2845 } else { 2846 // TODO 2847 // should we ever get anything other than this case? 2848 __ ldaxr(dst_reg, base); 2849 } 2850 } else { 2851 Register index_reg = as_Register(index); 2852 if (disp == 0) { 2853 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2854 __ ldaxr(dst_reg, rscratch1); 2855 } else { 2856 __ lea(rscratch1, Address(base, disp)); 2857 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2858 __ ldaxr(dst_reg, rscratch1); 2859 } 2860 } 2861 %} 2862 2863 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2864 MacroAssembler _masm(&cbuf); 2865 Register src_reg = as_Register($src$$reg); 2866 Register base = as_Register($mem$$base); 2867 int index = $mem$$index; 2868 int scale = $mem$$scale; 2869 int disp = $mem$$disp; 2870 if (index == -1) { 2871 if (disp != 0) { 2872 __ lea(rscratch2, Address(base, disp)); 2873 __ stlxr(rscratch1, src_reg, rscratch2); 2874 } else { 2875 // TODO 2876 // should we ever get anything other than this case? 2877 __ stlxr(rscratch1, src_reg, base); 2878 } 2879 } else { 2880 Register index_reg = as_Register(index); 2881 if (disp == 0) { 2882 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2883 __ stlxr(rscratch1, src_reg, rscratch2); 2884 } else { 2885 __ lea(rscratch2, Address(base, disp)); 2886 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2887 __ stlxr(rscratch1, src_reg, rscratch2); 2888 } 2889 } 2890 __ cmpw(rscratch1, zr); 2891 %} 2892 2893 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2894 MacroAssembler _masm(&cbuf); 2895 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2896 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2897 Assembler::xword, /*acquire*/ false, /*release*/ true, 2898 /*weak*/ false, noreg); 2899 %} 2900 2901 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2902 MacroAssembler _masm(&cbuf); 2903 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2904 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2905 Assembler::word, /*acquire*/ false, /*release*/ true, 2906 /*weak*/ false, noreg); 2907 %} 2908 2909 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2910 MacroAssembler _masm(&cbuf); 2911 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2912 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2913 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2914 /*weak*/ false, noreg); 2915 %} 2916 2917 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2918 MacroAssembler _masm(&cbuf); 2919 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2920 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2921 Assembler::byte, /*acquire*/ false, /*release*/ true, 2922 /*weak*/ false, noreg); 2923 %} 2924 2925 2926 // The only difference between aarch64_enc_cmpxchg and 2927 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2928 // CompareAndSwap sequence to serve as a barrier on acquiring a 2929 // lock. 2930 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2931 MacroAssembler _masm(&cbuf); 2932 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2933 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2934 Assembler::xword, /*acquire*/ true, /*release*/ true, 2935 /*weak*/ false, noreg); 2936 %} 2937 2938 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2939 MacroAssembler _masm(&cbuf); 2940 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2941 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2942 Assembler::word, /*acquire*/ true, /*release*/ true, 2943 /*weak*/ false, noreg); 2944 %} 2945 2946 2947 // auxiliary used for CompareAndSwapX to set result register 2948 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2949 MacroAssembler _masm(&cbuf); 2950 Register res_reg = as_Register($res$$reg); 2951 __ cset(res_reg, Assembler::EQ); 2952 %} 2953 2954 // prefetch encodings 2955 2956 enc_class aarch64_enc_prefetchw(memory mem) %{ 2957 MacroAssembler _masm(&cbuf); 2958 Register base = as_Register($mem$$base); 2959 int index = $mem$$index; 2960 int scale = $mem$$scale; 2961 int disp = $mem$$disp; 2962 if (index == -1) { 2963 __ prfm(Address(base, disp), PSTL1KEEP); 2964 } else { 2965 Register index_reg = as_Register(index); 2966 if (disp == 0) { 2967 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2968 } else { 2969 __ lea(rscratch1, Address(base, disp)); 2970 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2971 } 2972 } 2973 %} 2974 2975 /// mov envcodings 2976 2977 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2978 MacroAssembler _masm(&cbuf); 2979 u_int32_t con = (u_int32_t)$src$$constant; 2980 Register dst_reg = as_Register($dst$$reg); 2981 if (con == 0) { 2982 __ movw(dst_reg, zr); 2983 } else { 2984 __ movw(dst_reg, con); 2985 } 2986 %} 2987 2988 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2989 MacroAssembler _masm(&cbuf); 2990 Register dst_reg = as_Register($dst$$reg); 2991 u_int64_t con = (u_int64_t)$src$$constant; 2992 if (con == 0) { 2993 __ mov(dst_reg, zr); 2994 } else { 2995 __ mov(dst_reg, con); 2996 } 2997 %} 2998 2999 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3000 MacroAssembler _masm(&cbuf); 3001 Register dst_reg = as_Register($dst$$reg); 3002 address con = (address)$src$$constant; 3003 if (con == NULL || con == (address)1) { 3004 ShouldNotReachHere(); 3005 } else { 3006 relocInfo::relocType rtype = $src->constant_reloc(); 3007 if (rtype == relocInfo::oop_type) { 3008 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3009 } else if (rtype == relocInfo::metadata_type) { 3010 __ mov_metadata(dst_reg, (Metadata*)con); 3011 } else { 3012 assert(rtype == relocInfo::none, "unexpected reloc type"); 3013 if (con < (address)(uintptr_t)os::vm_page_size()) { 3014 __ mov(dst_reg, con); 3015 } else { 3016 unsigned long offset; 3017 __ adrp(dst_reg, con, offset); 3018 __ add(dst_reg, dst_reg, offset); 3019 } 3020 } 3021 } 3022 %} 3023 3024 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3025 MacroAssembler _masm(&cbuf); 3026 Register dst_reg = as_Register($dst$$reg); 3027 __ mov(dst_reg, zr); 3028 %} 3029 3030 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3031 MacroAssembler _masm(&cbuf); 3032 Register dst_reg = as_Register($dst$$reg); 3033 __ mov(dst_reg, (u_int64_t)1); 3034 %} 3035 3036 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3037 MacroAssembler _masm(&cbuf); 3038 address page = (address)$src$$constant; 3039 Register dst_reg = as_Register($dst$$reg); 3040 unsigned long off; 3041 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3042 assert(off == 0, "assumed offset == 0"); 3043 %} 3044 3045 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3046 MacroAssembler _masm(&cbuf); 3047 __ load_byte_map_base($dst$$Register); 3048 %} 3049 3050 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3051 MacroAssembler _masm(&cbuf); 3052 Register dst_reg = as_Register($dst$$reg); 3053 address con = (address)$src$$constant; 3054 if (con == NULL) { 3055 ShouldNotReachHere(); 3056 } else { 3057 relocInfo::relocType rtype = $src->constant_reloc(); 3058 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3059 __ set_narrow_oop(dst_reg, (jobject)con); 3060 } 3061 %} 3062 3063 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3064 MacroAssembler _masm(&cbuf); 3065 Register dst_reg = as_Register($dst$$reg); 3066 __ mov(dst_reg, zr); 3067 %} 3068 3069 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3070 MacroAssembler _masm(&cbuf); 3071 Register dst_reg = as_Register($dst$$reg); 3072 address con = (address)$src$$constant; 3073 if (con == NULL) { 3074 ShouldNotReachHere(); 3075 } else { 3076 relocInfo::relocType rtype = $src->constant_reloc(); 3077 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3078 __ set_narrow_klass(dst_reg, (Klass *)con); 3079 } 3080 %} 3081 3082 // arithmetic encodings 3083 3084 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3085 MacroAssembler _masm(&cbuf); 3086 Register dst_reg = as_Register($dst$$reg); 3087 Register src_reg = as_Register($src1$$reg); 3088 int32_t con = (int32_t)$src2$$constant; 3089 // add has primary == 0, subtract has primary == 1 3090 if ($primary) { con = -con; } 3091 if (con < 0) { 3092 __ subw(dst_reg, src_reg, -con); 3093 } else { 3094 __ addw(dst_reg, src_reg, con); 3095 } 3096 %} 3097 3098 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3099 MacroAssembler _masm(&cbuf); 3100 Register dst_reg = as_Register($dst$$reg); 3101 Register src_reg = as_Register($src1$$reg); 3102 int32_t con = (int32_t)$src2$$constant; 3103 // add has primary == 0, subtract has primary == 1 3104 if ($primary) { con = -con; } 3105 if (con < 0) { 3106 __ sub(dst_reg, src_reg, -con); 3107 } else { 3108 __ add(dst_reg, src_reg, con); 3109 } 3110 %} 3111 3112 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3113 MacroAssembler _masm(&cbuf); 3114 Register dst_reg = as_Register($dst$$reg); 3115 Register src1_reg = as_Register($src1$$reg); 3116 Register src2_reg = as_Register($src2$$reg); 3117 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3118 %} 3119 3120 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3121 MacroAssembler _masm(&cbuf); 3122 Register dst_reg = as_Register($dst$$reg); 3123 Register src1_reg = as_Register($src1$$reg); 3124 Register src2_reg = as_Register($src2$$reg); 3125 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3126 %} 3127 3128 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3129 MacroAssembler _masm(&cbuf); 3130 Register dst_reg = as_Register($dst$$reg); 3131 Register src1_reg = as_Register($src1$$reg); 3132 Register src2_reg = as_Register($src2$$reg); 3133 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3134 %} 3135 3136 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3137 MacroAssembler _masm(&cbuf); 3138 Register dst_reg = as_Register($dst$$reg); 3139 Register src1_reg = as_Register($src1$$reg); 3140 Register src2_reg = as_Register($src2$$reg); 3141 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3142 %} 3143 3144 // compare instruction encodings 3145 3146 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3147 MacroAssembler _masm(&cbuf); 3148 Register reg1 = as_Register($src1$$reg); 3149 Register reg2 = as_Register($src2$$reg); 3150 __ cmpw(reg1, reg2); 3151 %} 3152 3153 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3154 MacroAssembler _masm(&cbuf); 3155 Register reg = as_Register($src1$$reg); 3156 int32_t val = $src2$$constant; 3157 if (val >= 0) { 3158 __ subsw(zr, reg, val); 3159 } else { 3160 __ addsw(zr, reg, -val); 3161 } 3162 %} 3163 3164 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3165 MacroAssembler _masm(&cbuf); 3166 Register reg1 = as_Register($src1$$reg); 3167 u_int32_t val = (u_int32_t)$src2$$constant; 3168 __ movw(rscratch1, val); 3169 __ cmpw(reg1, rscratch1); 3170 %} 3171 3172 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3173 MacroAssembler _masm(&cbuf); 3174 Register reg1 = as_Register($src1$$reg); 3175 Register reg2 = as_Register($src2$$reg); 3176 __ cmp(reg1, reg2); 3177 %} 3178 3179 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3180 MacroAssembler _masm(&cbuf); 3181 Register reg = as_Register($src1$$reg); 3182 int64_t val = $src2$$constant; 3183 if (val >= 0) { 3184 __ subs(zr, reg, val); 3185 } else if (val != -val) { 3186 __ adds(zr, reg, -val); 3187 } else { 3188 // aargh, Long.MIN_VALUE is a special case 3189 __ orr(rscratch1, zr, (u_int64_t)val); 3190 __ subs(zr, reg, rscratch1); 3191 } 3192 %} 3193 3194 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3195 MacroAssembler _masm(&cbuf); 3196 Register reg1 = as_Register($src1$$reg); 3197 u_int64_t val = (u_int64_t)$src2$$constant; 3198 __ mov(rscratch1, val); 3199 __ cmp(reg1, rscratch1); 3200 %} 3201 3202 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3203 MacroAssembler _masm(&cbuf); 3204 Register reg1 = as_Register($src1$$reg); 3205 Register reg2 = as_Register($src2$$reg); 3206 __ cmp(reg1, reg2); 3207 %} 3208 3209 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3210 MacroAssembler _masm(&cbuf); 3211 Register reg1 = as_Register($src1$$reg); 3212 Register reg2 = as_Register($src2$$reg); 3213 __ cmpw(reg1, reg2); 3214 %} 3215 3216 enc_class aarch64_enc_testp(iRegP src) %{ 3217 MacroAssembler _masm(&cbuf); 3218 Register reg = as_Register($src$$reg); 3219 __ cmp(reg, zr); 3220 %} 3221 3222 enc_class aarch64_enc_testn(iRegN src) %{ 3223 MacroAssembler _masm(&cbuf); 3224 Register reg = as_Register($src$$reg); 3225 __ cmpw(reg, zr); 3226 %} 3227 3228 enc_class aarch64_enc_b(label lbl) %{ 3229 MacroAssembler _masm(&cbuf); 3230 Label *L = $lbl$$label; 3231 __ b(*L); 3232 %} 3233 3234 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3235 MacroAssembler _masm(&cbuf); 3236 Label *L = $lbl$$label; 3237 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3238 %} 3239 3240 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3241 MacroAssembler _masm(&cbuf); 3242 Label *L = $lbl$$label; 3243 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3244 %} 3245 3246 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3247 %{ 3248 Register sub_reg = as_Register($sub$$reg); 3249 Register super_reg = as_Register($super$$reg); 3250 Register temp_reg = as_Register($temp$$reg); 3251 Register result_reg = as_Register($result$$reg); 3252 3253 Label miss; 3254 MacroAssembler _masm(&cbuf); 3255 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3256 NULL, &miss, 3257 /*set_cond_codes:*/ true); 3258 if ($primary) { 3259 __ mov(result_reg, zr); 3260 } 3261 __ bind(miss); 3262 %} 3263 3264 enc_class aarch64_enc_java_static_call(method meth) %{ 3265 MacroAssembler _masm(&cbuf); 3266 3267 address addr = (address)$meth$$method; 3268 address call; 3269 if (!_method) { 3270 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3271 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3272 } else { 3273 int method_index = resolved_method_index(cbuf); 3274 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3275 : static_call_Relocation::spec(method_index); 3276 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3277 3278 // Emit stub for static call 3279 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3280 if (stub == NULL) { 3281 ciEnv::current()->record_failure("CodeCache is full"); 3282 return; 3283 } 3284 } 3285 if (call == NULL) { 3286 ciEnv::current()->record_failure("CodeCache is full"); 3287 return; 3288 } 3289 %} 3290 3291 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3292 MacroAssembler _masm(&cbuf); 3293 int method_index = resolved_method_index(cbuf); 3294 address call = __ ic_call((address)$meth$$method, method_index); 3295 if (call == NULL) { 3296 ciEnv::current()->record_failure("CodeCache is full"); 3297 return; 3298 } 3299 %} 3300 3301 enc_class aarch64_enc_call_epilog() %{ 3302 MacroAssembler _masm(&cbuf); 3303 if (VerifyStackAtCalls) { 3304 // Check that stack depth is unchanged: find majik cookie on stack 3305 __ call_Unimplemented(); 3306 } 3307 %} 3308 3309 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3310 MacroAssembler _masm(&cbuf); 3311 3312 // some calls to generated routines (arraycopy code) are scheduled 3313 // by C2 as runtime calls. if so we can call them using a br (they 3314 // will be in a reachable segment) otherwise we have to use a blrt 3315 // which loads the absolute address into a register. 3316 address entry = (address)$meth$$method; 3317 CodeBlob *cb = CodeCache::find_blob(entry); 3318 if (cb) { 3319 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3320 if (call == NULL) { 3321 ciEnv::current()->record_failure("CodeCache is full"); 3322 return; 3323 } 3324 } else { 3325 int gpcnt; 3326 int fpcnt; 3327 int rtype; 3328 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3329 Label retaddr; 3330 __ adr(rscratch2, retaddr); 3331 __ lea(rscratch1, RuntimeAddress(entry)); 3332 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3333 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3334 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3335 __ bind(retaddr); 3336 __ add(sp, sp, 2 * wordSize); 3337 } 3338 %} 3339 3340 enc_class aarch64_enc_rethrow() %{ 3341 MacroAssembler _masm(&cbuf); 3342 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3343 %} 3344 3345 enc_class aarch64_enc_ret() %{ 3346 MacroAssembler _masm(&cbuf); 3347 __ ret(lr); 3348 %} 3349 3350 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3351 MacroAssembler _masm(&cbuf); 3352 Register target_reg = as_Register($jump_target$$reg); 3353 __ br(target_reg); 3354 %} 3355 3356 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3357 MacroAssembler _masm(&cbuf); 3358 Register target_reg = as_Register($jump_target$$reg); 3359 // exception oop should be in r0 3360 // ret addr has been popped into lr 3361 // callee expects it in r3 3362 __ mov(r3, lr); 3363 __ br(target_reg); 3364 %} 3365 3366 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3367 MacroAssembler _masm(&cbuf); 3368 Register oop = as_Register($object$$reg); 3369 Register box = as_Register($box$$reg); 3370 Register disp_hdr = as_Register($tmp$$reg); 3371 Register tmp = as_Register($tmp2$$reg); 3372 Label cont; 3373 Label object_has_monitor; 3374 Label cas_failed; 3375 3376 assert_different_registers(oop, box, tmp, disp_hdr); 3377 3378 // Load markOop from object into displaced_header. 3379 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3380 3381 if (UseBiasedLocking && !UseOptoBiasInlining) { 3382 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3383 } 3384 3385 // Handle existing monitor 3386 // we can use AArch64's bit test and branch here but 3387 // markoopDesc does not define a bit index just the bit value 3388 // so assert in case the bit pos changes 3389 # define __monitor_value_log2 1 3390 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 3391 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 3392 # undef __monitor_value_log2 3393 3394 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3395 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3396 3397 // Load Compare Value application register. 3398 3399 // Initialize the box. (Must happen before we update the object mark!) 3400 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3401 3402 // Compare object markOop with mark and if equal exchange scratch1 3403 // with object markOop. 3404 if (UseLSE) { 3405 __ mov(tmp, disp_hdr); 3406 __ casal(Assembler::xword, tmp, box, oop); 3407 __ cmp(tmp, disp_hdr); 3408 __ br(Assembler::EQ, cont); 3409 } else { 3410 Label retry_load; 3411 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3412 __ prfm(Address(oop), PSTL1STRM); 3413 __ bind(retry_load); 3414 __ ldaxr(tmp, oop); 3415 __ cmp(tmp, disp_hdr); 3416 __ br(Assembler::NE, cas_failed); 3417 // use stlxr to ensure update is immediately visible 3418 __ stlxr(tmp, box, oop); 3419 __ cbzw(tmp, cont); 3420 __ b(retry_load); 3421 } 3422 3423 // Formerly: 3424 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3425 // /*newv=*/box, 3426 // /*addr=*/oop, 3427 // /*tmp=*/tmp, 3428 // cont, 3429 // /*fail*/NULL); 3430 3431 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3432 3433 // If the compare-and-exchange succeeded, then we found an unlocked 3434 // object, will have now locked it will continue at label cont 3435 3436 __ bind(cas_failed); 3437 // We did not see an unlocked object so try the fast recursive case. 3438 3439 // Check if the owner is self by comparing the value in the 3440 // markOop of object (disp_hdr) with the stack pointer. 3441 __ mov(rscratch1, sp); 3442 __ sub(disp_hdr, disp_hdr, rscratch1); 3443 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3444 // If condition is true we are cont and hence we can store 0 as the 3445 // displaced header in the box, which indicates that it is a recursive lock. 3446 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3447 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3448 3449 // Handle existing monitor. 3450 __ b(cont); 3451 3452 __ bind(object_has_monitor); 3453 // The object's monitor m is unlocked iff m->owner == NULL, 3454 // otherwise m->owner may contain a thread or a stack address. 3455 // 3456 // Try to CAS m->owner from NULL to current thread. 3457 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3458 __ mov(disp_hdr, zr); 3459 3460 if (UseLSE) { 3461 __ mov(rscratch1, disp_hdr); 3462 __ casal(Assembler::xword, rscratch1, rthread, tmp); 3463 __ cmp(rscratch1, disp_hdr); 3464 } else { 3465 Label retry_load, fail; 3466 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) { 3467 __ prfm(Address(tmp), PSTL1STRM); 3468 } 3469 __ bind(retry_load); 3470 __ ldaxr(rscratch1, tmp); 3471 __ cmp(disp_hdr, rscratch1); 3472 __ br(Assembler::NE, fail); 3473 // use stlxr to ensure update is immediately visible 3474 __ stlxr(rscratch1, rthread, tmp); 3475 __ cbnzw(rscratch1, retry_load); 3476 __ bind(fail); 3477 } 3478 3479 // Label next; 3480 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3481 // /*newv=*/rthread, 3482 // /*addr=*/tmp, 3483 // /*tmp=*/rscratch1, 3484 // /*succeed*/next, 3485 // /*fail*/NULL); 3486 // __ bind(next); 3487 3488 // store a non-null value into the box. 3489 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3490 3491 // PPC port checks the following invariants 3492 // #ifdef ASSERT 3493 // bne(flag, cont); 3494 // We have acquired the monitor, check some invariants. 3495 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 3496 // Invariant 1: _recursions should be 0. 3497 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 3498 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 3499 // "monitor->_recursions should be 0", -1); 3500 // Invariant 2: OwnerIsThread shouldn't be 0. 3501 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 3502 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 3503 // "monitor->OwnerIsThread shouldn't be 0", -1); 3504 // #endif 3505 3506 __ bind(cont); 3507 // flag == EQ indicates success 3508 // flag == NE indicates failure 3509 3510 %} 3511 3512 // TODO 3513 // reimplement this with custom cmpxchgptr code 3514 // which avoids some of the unnecessary branching 3515 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3516 MacroAssembler _masm(&cbuf); 3517 Register oop = as_Register($object$$reg); 3518 Register box = as_Register($box$$reg); 3519 Register disp_hdr = as_Register($tmp$$reg); 3520 Register tmp = as_Register($tmp2$$reg); 3521 Label cont; 3522 Label object_has_monitor; 3523 Label cas_failed; 3524 3525 assert_different_registers(oop, box, tmp, disp_hdr); 3526 3527 if (UseBiasedLocking && !UseOptoBiasInlining) { 3528 __ biased_locking_exit(oop, tmp, cont); 3529 } 3530 3531 // Find the lock address and load the displaced header from the stack. 3532 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3533 3534 // If the displaced header is 0, we have a recursive unlock. 3535 __ cmp(disp_hdr, zr); 3536 __ br(Assembler::EQ, cont); 3537 3538 3539 // Handle existing monitor. 3540 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3541 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3542 3543 // Check if it is still a light weight lock, this is is true if we 3544 // see the stack address of the basicLock in the markOop of the 3545 // object. 3546 3547 if (UseLSE) { 3548 __ mov(tmp, box); 3549 __ casl(Assembler::xword, tmp, disp_hdr, oop); 3550 __ cmp(tmp, box); 3551 } else { 3552 Label retry_load; 3553 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3554 __ prfm(Address(oop), PSTL1STRM); 3555 __ bind(retry_load); 3556 __ ldxr(tmp, oop); 3557 __ cmp(box, tmp); 3558 __ br(Assembler::NE, cas_failed); 3559 // use stlxr to ensure update is immediately visible 3560 __ stlxr(tmp, disp_hdr, oop); 3561 __ cbzw(tmp, cont); 3562 __ b(retry_load); 3563 } 3564 3565 // __ cmpxchgptr(/*compare_value=*/box, 3566 // /*exchange_value=*/disp_hdr, 3567 // /*where=*/oop, 3568 // /*result=*/tmp, 3569 // cont, 3570 // /*cas_failed*/NULL); 3571 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3572 3573 __ bind(cas_failed); 3574 3575 // Handle existing monitor. 3576 __ b(cont); 3577 3578 __ bind(object_has_monitor); 3579 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3580 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3581 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3582 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3583 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3584 __ cmp(rscratch1, zr); 3585 __ br(Assembler::NE, cont); 3586 3587 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3588 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3589 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3590 __ cmp(rscratch1, zr); 3591 __ cbnz(rscratch1, cont); 3592 // need a release store here 3593 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3594 __ stlr(rscratch1, tmp); // rscratch1 is zero 3595 3596 __ bind(cont); 3597 // flag == EQ indicates success 3598 // flag == NE indicates failure 3599 %} 3600 3601 %} 3602 3603 //----------FRAME-------------------------------------------------------------- 3604 // Definition of frame structure and management information. 3605 // 3606 // S T A C K L A Y O U T Allocators stack-slot number 3607 // | (to get allocators register number 3608 // G Owned by | | v add OptoReg::stack0()) 3609 // r CALLER | | 3610 // o | +--------+ pad to even-align allocators stack-slot 3611 // w V | pad0 | numbers; owned by CALLER 3612 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3613 // h ^ | in | 5 3614 // | | args | 4 Holes in incoming args owned by SELF 3615 // | | | | 3 3616 // | | +--------+ 3617 // V | | old out| Empty on Intel, window on Sparc 3618 // | old |preserve| Must be even aligned. 3619 // | SP-+--------+----> Matcher::_old_SP, even aligned 3620 // | | in | 3 area for Intel ret address 3621 // Owned by |preserve| Empty on Sparc. 3622 // SELF +--------+ 3623 // | | pad2 | 2 pad to align old SP 3624 // | +--------+ 1 3625 // | | locks | 0 3626 // | +--------+----> OptoReg::stack0(), even aligned 3627 // | | pad1 | 11 pad to align new SP 3628 // | +--------+ 3629 // | | | 10 3630 // | | spills | 9 spills 3631 // V | | 8 (pad0 slot for callee) 3632 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3633 // ^ | out | 7 3634 // | | args | 6 Holes in outgoing args owned by CALLEE 3635 // Owned by +--------+ 3636 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3637 // | new |preserve| Must be even-aligned. 3638 // | SP-+--------+----> Matcher::_new_SP, even aligned 3639 // | | | 3640 // 3641 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3642 // known from SELF's arguments and the Java calling convention. 3643 // Region 6-7 is determined per call site. 3644 // Note 2: If the calling convention leaves holes in the incoming argument 3645 // area, those holes are owned by SELF. Holes in the outgoing area 3646 // are owned by the CALLEE. Holes should not be nessecary in the 3647 // incoming area, as the Java calling convention is completely under 3648 // the control of the AD file. Doubles can be sorted and packed to 3649 // avoid holes. Holes in the outgoing arguments may be nessecary for 3650 // varargs C calling conventions. 3651 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3652 // even aligned with pad0 as needed. 3653 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3654 // (the latter is true on Intel but is it false on AArch64?) 3655 // region 6-11 is even aligned; it may be padded out more so that 3656 // the region from SP to FP meets the minimum stack alignment. 3657 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3658 // alignment. Region 11, pad1, may be dynamically extended so that 3659 // SP meets the minimum alignment. 3660 3661 frame %{ 3662 // What direction does stack grow in (assumed to be same for C & Java) 3663 stack_direction(TOWARDS_LOW); 3664 3665 // These three registers define part of the calling convention 3666 // between compiled code and the interpreter. 3667 3668 // Inline Cache Register or methodOop for I2C. 3669 inline_cache_reg(R12); 3670 3671 // Method Oop Register when calling interpreter. 3672 interpreter_method_oop_reg(R12); 3673 3674 // Number of stack slots consumed by locking an object 3675 sync_stack_slots(2); 3676 3677 // Compiled code's Frame Pointer 3678 frame_pointer(R31); 3679 3680 // Interpreter stores its frame pointer in a register which is 3681 // stored to the stack by I2CAdaptors. 3682 // I2CAdaptors convert from interpreted java to compiled java. 3683 interpreter_frame_pointer(R29); 3684 3685 // Stack alignment requirement 3686 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3687 3688 // Number of stack slots between incoming argument block and the start of 3689 // a new frame. The PROLOG must add this many slots to the stack. The 3690 // EPILOG must remove this many slots. aarch64 needs two slots for 3691 // return address and fp. 3692 // TODO think this is correct but check 3693 in_preserve_stack_slots(4); 3694 3695 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3696 // for calls to C. Supports the var-args backing area for register parms. 3697 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3698 3699 // The after-PROLOG location of the return address. Location of 3700 // return address specifies a type (REG or STACK) and a number 3701 // representing the register number (i.e. - use a register name) or 3702 // stack slot. 3703 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3704 // Otherwise, it is above the locks and verification slot and alignment word 3705 // TODO this may well be correct but need to check why that - 2 is there 3706 // ppc port uses 0 but we definitely need to allow for fixed_slots 3707 // which folds in the space used for monitors 3708 return_addr(STACK - 2 + 3709 align_up((Compile::current()->in_preserve_stack_slots() + 3710 Compile::current()->fixed_slots()), 3711 stack_alignment_in_slots())); 3712 3713 // Body of function which returns an integer array locating 3714 // arguments either in registers or in stack slots. Passed an array 3715 // of ideal registers called "sig" and a "length" count. Stack-slot 3716 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3717 // arguments for a CALLEE. Incoming stack arguments are 3718 // automatically biased by the preserve_stack_slots field above. 3719 3720 calling_convention 3721 %{ 3722 // No difference between ingoing/outgoing just pass false 3723 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3724 %} 3725 3726 c_calling_convention 3727 %{ 3728 // This is obviously always outgoing 3729 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3730 %} 3731 3732 // Location of compiled Java return values. Same as C for now. 3733 return_value 3734 %{ 3735 // TODO do we allow ideal_reg == Op_RegN??? 3736 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3737 "only return normal values"); 3738 3739 static const int lo[Op_RegL + 1] = { // enum name 3740 0, // Op_Node 3741 0, // Op_Set 3742 R0_num, // Op_RegN 3743 R0_num, // Op_RegI 3744 R0_num, // Op_RegP 3745 V0_num, // Op_RegF 3746 V0_num, // Op_RegD 3747 R0_num // Op_RegL 3748 }; 3749 3750 static const int hi[Op_RegL + 1] = { // enum name 3751 0, // Op_Node 3752 0, // Op_Set 3753 OptoReg::Bad, // Op_RegN 3754 OptoReg::Bad, // Op_RegI 3755 R0_H_num, // Op_RegP 3756 OptoReg::Bad, // Op_RegF 3757 V0_H_num, // Op_RegD 3758 R0_H_num // Op_RegL 3759 }; 3760 3761 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3762 %} 3763 %} 3764 3765 //----------ATTRIBUTES--------------------------------------------------------- 3766 //----------Operand Attributes------------------------------------------------- 3767 op_attrib op_cost(1); // Required cost attribute 3768 3769 //----------Instruction Attributes--------------------------------------------- 3770 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3771 ins_attrib ins_size(32); // Required size attribute (in bits) 3772 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3773 // a non-matching short branch variant 3774 // of some long branch? 3775 ins_attrib ins_alignment(4); // Required alignment attribute (must 3776 // be a power of 2) specifies the 3777 // alignment that some part of the 3778 // instruction (not necessarily the 3779 // start) requires. If > 1, a 3780 // compute_padding() function must be 3781 // provided for the instruction 3782 3783 //----------OPERANDS----------------------------------------------------------- 3784 // Operand definitions must precede instruction definitions for correct parsing 3785 // in the ADLC because operands constitute user defined types which are used in 3786 // instruction definitions. 3787 3788 //----------Simple Operands---------------------------------------------------- 3789 3790 // Integer operands 32 bit 3791 // 32 bit immediate 3792 operand immI() 3793 %{ 3794 match(ConI); 3795 3796 op_cost(0); 3797 format %{ %} 3798 interface(CONST_INTER); 3799 %} 3800 3801 // 32 bit zero 3802 operand immI0() 3803 %{ 3804 predicate(n->get_int() == 0); 3805 match(ConI); 3806 3807 op_cost(0); 3808 format %{ %} 3809 interface(CONST_INTER); 3810 %} 3811 3812 // 32 bit unit increment 3813 operand immI_1() 3814 %{ 3815 predicate(n->get_int() == 1); 3816 match(ConI); 3817 3818 op_cost(0); 3819 format %{ %} 3820 interface(CONST_INTER); 3821 %} 3822 3823 // 32 bit unit decrement 3824 operand immI_M1() 3825 %{ 3826 predicate(n->get_int() == -1); 3827 match(ConI); 3828 3829 op_cost(0); 3830 format %{ %} 3831 interface(CONST_INTER); 3832 %} 3833 3834 // Shift values for add/sub extension shift 3835 operand immIExt() 3836 %{ 3837 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3838 match(ConI); 3839 3840 op_cost(0); 3841 format %{ %} 3842 interface(CONST_INTER); 3843 %} 3844 3845 operand immI_le_4() 3846 %{ 3847 predicate(n->get_int() <= 4); 3848 match(ConI); 3849 3850 op_cost(0); 3851 format %{ %} 3852 interface(CONST_INTER); 3853 %} 3854 3855 operand immI_31() 3856 %{ 3857 predicate(n->get_int() == 31); 3858 match(ConI); 3859 3860 op_cost(0); 3861 format %{ %} 3862 interface(CONST_INTER); 3863 %} 3864 3865 operand immI_8() 3866 %{ 3867 predicate(n->get_int() == 8); 3868 match(ConI); 3869 3870 op_cost(0); 3871 format %{ %} 3872 interface(CONST_INTER); 3873 %} 3874 3875 operand immI_16() 3876 %{ 3877 predicate(n->get_int() == 16); 3878 match(ConI); 3879 3880 op_cost(0); 3881 format %{ %} 3882 interface(CONST_INTER); 3883 %} 3884 3885 operand immI_24() 3886 %{ 3887 predicate(n->get_int() == 24); 3888 match(ConI); 3889 3890 op_cost(0); 3891 format %{ %} 3892 interface(CONST_INTER); 3893 %} 3894 3895 operand immI_32() 3896 %{ 3897 predicate(n->get_int() == 32); 3898 match(ConI); 3899 3900 op_cost(0); 3901 format %{ %} 3902 interface(CONST_INTER); 3903 %} 3904 3905 operand immI_48() 3906 %{ 3907 predicate(n->get_int() == 48); 3908 match(ConI); 3909 3910 op_cost(0); 3911 format %{ %} 3912 interface(CONST_INTER); 3913 %} 3914 3915 operand immI_56() 3916 %{ 3917 predicate(n->get_int() == 56); 3918 match(ConI); 3919 3920 op_cost(0); 3921 format %{ %} 3922 interface(CONST_INTER); 3923 %} 3924 3925 operand immI_63() 3926 %{ 3927 predicate(n->get_int() == 63); 3928 match(ConI); 3929 3930 op_cost(0); 3931 format %{ %} 3932 interface(CONST_INTER); 3933 %} 3934 3935 operand immI_64() 3936 %{ 3937 predicate(n->get_int() == 64); 3938 match(ConI); 3939 3940 op_cost(0); 3941 format %{ %} 3942 interface(CONST_INTER); 3943 %} 3944 3945 operand immI_255() 3946 %{ 3947 predicate(n->get_int() == 255); 3948 match(ConI); 3949 3950 op_cost(0); 3951 format %{ %} 3952 interface(CONST_INTER); 3953 %} 3954 3955 operand immI_65535() 3956 %{ 3957 predicate(n->get_int() == 65535); 3958 match(ConI); 3959 3960 op_cost(0); 3961 format %{ %} 3962 interface(CONST_INTER); 3963 %} 3964 3965 operand immL_255() 3966 %{ 3967 predicate(n->get_long() == 255L); 3968 match(ConL); 3969 3970 op_cost(0); 3971 format %{ %} 3972 interface(CONST_INTER); 3973 %} 3974 3975 operand immL_65535() 3976 %{ 3977 predicate(n->get_long() == 65535L); 3978 match(ConL); 3979 3980 op_cost(0); 3981 format %{ %} 3982 interface(CONST_INTER); 3983 %} 3984 3985 operand immL_4294967295() 3986 %{ 3987 predicate(n->get_long() == 4294967295L); 3988 match(ConL); 3989 3990 op_cost(0); 3991 format %{ %} 3992 interface(CONST_INTER); 3993 %} 3994 3995 operand immL_bitmask() 3996 %{ 3997 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3998 && is_power_of_2(n->get_long() + 1)); 3999 match(ConL); 4000 4001 op_cost(0); 4002 format %{ %} 4003 interface(CONST_INTER); 4004 %} 4005 4006 operand immI_bitmask() 4007 %{ 4008 predicate(((n->get_int() & 0xc0000000) == 0) 4009 && is_power_of_2(n->get_int() + 1)); 4010 match(ConI); 4011 4012 op_cost(0); 4013 format %{ %} 4014 interface(CONST_INTER); 4015 %} 4016 4017 // Scale values for scaled offset addressing modes (up to long but not quad) 4018 operand immIScale() 4019 %{ 4020 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4021 match(ConI); 4022 4023 op_cost(0); 4024 format %{ %} 4025 interface(CONST_INTER); 4026 %} 4027 4028 // 26 bit signed offset -- for pc-relative branches 4029 operand immI26() 4030 %{ 4031 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4032 match(ConI); 4033 4034 op_cost(0); 4035 format %{ %} 4036 interface(CONST_INTER); 4037 %} 4038 4039 // 19 bit signed offset -- for pc-relative loads 4040 operand immI19() 4041 %{ 4042 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4043 match(ConI); 4044 4045 op_cost(0); 4046 format %{ %} 4047 interface(CONST_INTER); 4048 %} 4049 4050 // 12 bit unsigned offset -- for base plus immediate loads 4051 operand immIU12() 4052 %{ 4053 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4054 match(ConI); 4055 4056 op_cost(0); 4057 format %{ %} 4058 interface(CONST_INTER); 4059 %} 4060 4061 operand immLU12() 4062 %{ 4063 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4064 match(ConL); 4065 4066 op_cost(0); 4067 format %{ %} 4068 interface(CONST_INTER); 4069 %} 4070 4071 // Offset for scaled or unscaled immediate loads and stores 4072 operand immIOffset() 4073 %{ 4074 predicate(Address::offset_ok_for_immed(n->get_int())); 4075 match(ConI); 4076 4077 op_cost(0); 4078 format %{ %} 4079 interface(CONST_INTER); 4080 %} 4081 4082 operand immIOffset4() 4083 %{ 4084 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4085 match(ConI); 4086 4087 op_cost(0); 4088 format %{ %} 4089 interface(CONST_INTER); 4090 %} 4091 4092 operand immIOffset8() 4093 %{ 4094 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4095 match(ConI); 4096 4097 op_cost(0); 4098 format %{ %} 4099 interface(CONST_INTER); 4100 %} 4101 4102 operand immIOffset16() 4103 %{ 4104 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4105 match(ConI); 4106 4107 op_cost(0); 4108 format %{ %} 4109 interface(CONST_INTER); 4110 %} 4111 4112 operand immLoffset() 4113 %{ 4114 predicate(Address::offset_ok_for_immed(n->get_long())); 4115 match(ConL); 4116 4117 op_cost(0); 4118 format %{ %} 4119 interface(CONST_INTER); 4120 %} 4121 4122 operand immLoffset4() 4123 %{ 4124 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4125 match(ConL); 4126 4127 op_cost(0); 4128 format %{ %} 4129 interface(CONST_INTER); 4130 %} 4131 4132 operand immLoffset8() 4133 %{ 4134 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4135 match(ConL); 4136 4137 op_cost(0); 4138 format %{ %} 4139 interface(CONST_INTER); 4140 %} 4141 4142 operand immLoffset16() 4143 %{ 4144 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4145 match(ConL); 4146 4147 op_cost(0); 4148 format %{ %} 4149 interface(CONST_INTER); 4150 %} 4151 4152 // 32 bit integer valid for add sub immediate 4153 operand immIAddSub() 4154 %{ 4155 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4156 match(ConI); 4157 op_cost(0); 4158 format %{ %} 4159 interface(CONST_INTER); 4160 %} 4161 4162 // 32 bit unsigned integer valid for logical immediate 4163 // TODO -- check this is right when e.g the mask is 0x80000000 4164 operand immILog() 4165 %{ 4166 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4167 match(ConI); 4168 4169 op_cost(0); 4170 format %{ %} 4171 interface(CONST_INTER); 4172 %} 4173 4174 // Integer operands 64 bit 4175 // 64 bit immediate 4176 operand immL() 4177 %{ 4178 match(ConL); 4179 4180 op_cost(0); 4181 format %{ %} 4182 interface(CONST_INTER); 4183 %} 4184 4185 // 64 bit zero 4186 operand immL0() 4187 %{ 4188 predicate(n->get_long() == 0); 4189 match(ConL); 4190 4191 op_cost(0); 4192 format %{ %} 4193 interface(CONST_INTER); 4194 %} 4195 4196 // 64 bit unit increment 4197 operand immL_1() 4198 %{ 4199 predicate(n->get_long() == 1); 4200 match(ConL); 4201 4202 op_cost(0); 4203 format %{ %} 4204 interface(CONST_INTER); 4205 %} 4206 4207 // 64 bit unit decrement 4208 operand immL_M1() 4209 %{ 4210 predicate(n->get_long() == -1); 4211 match(ConL); 4212 4213 op_cost(0); 4214 format %{ %} 4215 interface(CONST_INTER); 4216 %} 4217 4218 // 32 bit offset of pc in thread anchor 4219 4220 operand immL_pc_off() 4221 %{ 4222 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4223 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4224 match(ConL); 4225 4226 op_cost(0); 4227 format %{ %} 4228 interface(CONST_INTER); 4229 %} 4230 4231 // 64 bit integer valid for add sub immediate 4232 operand immLAddSub() 4233 %{ 4234 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4235 match(ConL); 4236 op_cost(0); 4237 format %{ %} 4238 interface(CONST_INTER); 4239 %} 4240 4241 // 64 bit integer valid for logical immediate 4242 operand immLLog() 4243 %{ 4244 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4245 match(ConL); 4246 op_cost(0); 4247 format %{ %} 4248 interface(CONST_INTER); 4249 %} 4250 4251 // Long Immediate: low 32-bit mask 4252 operand immL_32bits() 4253 %{ 4254 predicate(n->get_long() == 0xFFFFFFFFL); 4255 match(ConL); 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 // Pointer operands 4262 // Pointer Immediate 4263 operand immP() 4264 %{ 4265 match(ConP); 4266 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // NULL Pointer Immediate 4273 operand immP0() 4274 %{ 4275 predicate(n->get_ptr() == 0); 4276 match(ConP); 4277 4278 op_cost(0); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // Pointer Immediate One 4284 // this is used in object initialization (initial object header) 4285 operand immP_1() 4286 %{ 4287 predicate(n->get_ptr() == 1); 4288 match(ConP); 4289 4290 op_cost(0); 4291 format %{ %} 4292 interface(CONST_INTER); 4293 %} 4294 4295 // Polling Page Pointer Immediate 4296 operand immPollPage() 4297 %{ 4298 predicate((address)n->get_ptr() == os::get_polling_page()); 4299 match(ConP); 4300 4301 op_cost(0); 4302 format %{ %} 4303 interface(CONST_INTER); 4304 %} 4305 4306 // Card Table Byte Map Base 4307 operand immByteMapBase() 4308 %{ 4309 // Get base of card map 4310 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4311 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4312 match(ConP); 4313 4314 op_cost(0); 4315 format %{ %} 4316 interface(CONST_INTER); 4317 %} 4318 4319 // Pointer Immediate Minus One 4320 // this is used when we want to write the current PC to the thread anchor 4321 operand immP_M1() 4322 %{ 4323 predicate(n->get_ptr() == -1); 4324 match(ConP); 4325 4326 op_cost(0); 4327 format %{ %} 4328 interface(CONST_INTER); 4329 %} 4330 4331 // Pointer Immediate Minus Two 4332 // this is used when we want to write the current PC to the thread anchor 4333 operand immP_M2() 4334 %{ 4335 predicate(n->get_ptr() == -2); 4336 match(ConP); 4337 4338 op_cost(0); 4339 format %{ %} 4340 interface(CONST_INTER); 4341 %} 4342 4343 // Float and Double operands 4344 // Double Immediate 4345 operand immD() 4346 %{ 4347 match(ConD); 4348 op_cost(0); 4349 format %{ %} 4350 interface(CONST_INTER); 4351 %} 4352 4353 // Double Immediate: +0.0d 4354 operand immD0() 4355 %{ 4356 predicate(jlong_cast(n->getd()) == 0); 4357 match(ConD); 4358 4359 op_cost(0); 4360 format %{ %} 4361 interface(CONST_INTER); 4362 %} 4363 4364 // constant 'double +0.0'. 4365 operand immDPacked() 4366 %{ 4367 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4368 match(ConD); 4369 op_cost(0); 4370 format %{ %} 4371 interface(CONST_INTER); 4372 %} 4373 4374 // Float Immediate 4375 operand immF() 4376 %{ 4377 match(ConF); 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // Float Immediate: +0.0f. 4384 operand immF0() 4385 %{ 4386 predicate(jint_cast(n->getf()) == 0); 4387 match(ConF); 4388 4389 op_cost(0); 4390 format %{ %} 4391 interface(CONST_INTER); 4392 %} 4393 4394 // 4395 operand immFPacked() 4396 %{ 4397 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4398 match(ConF); 4399 op_cost(0); 4400 format %{ %} 4401 interface(CONST_INTER); 4402 %} 4403 4404 // Narrow pointer operands 4405 // Narrow Pointer Immediate 4406 operand immN() 4407 %{ 4408 match(ConN); 4409 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413 %} 4414 4415 // Narrow NULL Pointer Immediate 4416 operand immN0() 4417 %{ 4418 predicate(n->get_narrowcon() == 0); 4419 match(ConN); 4420 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 operand immNKlass() 4427 %{ 4428 match(ConNKlass); 4429 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 // Integer 32 bit Register Operands 4436 // Integer 32 bitRegister (excludes SP) 4437 operand iRegI() 4438 %{ 4439 constraint(ALLOC_IN_RC(any_reg32)); 4440 match(RegI); 4441 match(iRegINoSp); 4442 op_cost(0); 4443 format %{ %} 4444 interface(REG_INTER); 4445 %} 4446 4447 // Integer 32 bit Register not Special 4448 operand iRegINoSp() 4449 %{ 4450 constraint(ALLOC_IN_RC(no_special_reg32)); 4451 match(RegI); 4452 op_cost(0); 4453 format %{ %} 4454 interface(REG_INTER); 4455 %} 4456 4457 // Integer 64 bit Register Operands 4458 // Integer 64 bit Register (includes SP) 4459 operand iRegL() 4460 %{ 4461 constraint(ALLOC_IN_RC(any_reg)); 4462 match(RegL); 4463 match(iRegLNoSp); 4464 op_cost(0); 4465 format %{ %} 4466 interface(REG_INTER); 4467 %} 4468 4469 // Integer 64 bit Register not Special 4470 operand iRegLNoSp() 4471 %{ 4472 constraint(ALLOC_IN_RC(no_special_reg)); 4473 match(RegL); 4474 match(iRegL_R0); 4475 format %{ %} 4476 interface(REG_INTER); 4477 %} 4478 4479 // Pointer Register Operands 4480 // Pointer Register 4481 operand iRegP() 4482 %{ 4483 constraint(ALLOC_IN_RC(ptr_reg)); 4484 match(RegP); 4485 match(iRegPNoSp); 4486 match(iRegP_R0); 4487 //match(iRegP_R2); 4488 //match(iRegP_R4); 4489 //match(iRegP_R5); 4490 match(thread_RegP); 4491 op_cost(0); 4492 format %{ %} 4493 interface(REG_INTER); 4494 %} 4495 4496 // Pointer 64 bit Register not Special 4497 operand iRegPNoSp() 4498 %{ 4499 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4500 match(RegP); 4501 // match(iRegP); 4502 // match(iRegP_R0); 4503 // match(iRegP_R2); 4504 // match(iRegP_R4); 4505 // match(iRegP_R5); 4506 // match(thread_RegP); 4507 op_cost(0); 4508 format %{ %} 4509 interface(REG_INTER); 4510 %} 4511 4512 // Pointer 64 bit Register R0 only 4513 operand iRegP_R0() 4514 %{ 4515 constraint(ALLOC_IN_RC(r0_reg)); 4516 match(RegP); 4517 // match(iRegP); 4518 match(iRegPNoSp); 4519 op_cost(0); 4520 format %{ %} 4521 interface(REG_INTER); 4522 %} 4523 4524 // Pointer 64 bit Register R1 only 4525 operand iRegP_R1() 4526 %{ 4527 constraint(ALLOC_IN_RC(r1_reg)); 4528 match(RegP); 4529 // match(iRegP); 4530 match(iRegPNoSp); 4531 op_cost(0); 4532 format %{ %} 4533 interface(REG_INTER); 4534 %} 4535 4536 // Pointer 64 bit Register R2 only 4537 operand iRegP_R2() 4538 %{ 4539 constraint(ALLOC_IN_RC(r2_reg)); 4540 match(RegP); 4541 // match(iRegP); 4542 match(iRegPNoSp); 4543 op_cost(0); 4544 format %{ %} 4545 interface(REG_INTER); 4546 %} 4547 4548 // Pointer 64 bit Register R3 only 4549 operand iRegP_R3() 4550 %{ 4551 constraint(ALLOC_IN_RC(r3_reg)); 4552 match(RegP); 4553 // match(iRegP); 4554 match(iRegPNoSp); 4555 op_cost(0); 4556 format %{ %} 4557 interface(REG_INTER); 4558 %} 4559 4560 // Pointer 64 bit Register R4 only 4561 operand iRegP_R4() 4562 %{ 4563 constraint(ALLOC_IN_RC(r4_reg)); 4564 match(RegP); 4565 // match(iRegP); 4566 match(iRegPNoSp); 4567 op_cost(0); 4568 format %{ %} 4569 interface(REG_INTER); 4570 %} 4571 4572 // Pointer 64 bit Register R5 only 4573 operand iRegP_R5() 4574 %{ 4575 constraint(ALLOC_IN_RC(r5_reg)); 4576 match(RegP); 4577 // match(iRegP); 4578 match(iRegPNoSp); 4579 op_cost(0); 4580 format %{ %} 4581 interface(REG_INTER); 4582 %} 4583 4584 // Pointer 64 bit Register R10 only 4585 operand iRegP_R10() 4586 %{ 4587 constraint(ALLOC_IN_RC(r10_reg)); 4588 match(RegP); 4589 // match(iRegP); 4590 match(iRegPNoSp); 4591 op_cost(0); 4592 format %{ %} 4593 interface(REG_INTER); 4594 %} 4595 4596 // Long 64 bit Register R0 only 4597 operand iRegL_R0() 4598 %{ 4599 constraint(ALLOC_IN_RC(r0_reg)); 4600 match(RegL); 4601 match(iRegLNoSp); 4602 op_cost(0); 4603 format %{ %} 4604 interface(REG_INTER); 4605 %} 4606 4607 // Long 64 bit Register R2 only 4608 operand iRegL_R2() 4609 %{ 4610 constraint(ALLOC_IN_RC(r2_reg)); 4611 match(RegL); 4612 match(iRegLNoSp); 4613 op_cost(0); 4614 format %{ %} 4615 interface(REG_INTER); 4616 %} 4617 4618 // Long 64 bit Register R3 only 4619 operand iRegL_R3() 4620 %{ 4621 constraint(ALLOC_IN_RC(r3_reg)); 4622 match(RegL); 4623 match(iRegLNoSp); 4624 op_cost(0); 4625 format %{ %} 4626 interface(REG_INTER); 4627 %} 4628 4629 // Long 64 bit Register R11 only 4630 operand iRegL_R11() 4631 %{ 4632 constraint(ALLOC_IN_RC(r11_reg)); 4633 match(RegL); 4634 match(iRegLNoSp); 4635 op_cost(0); 4636 format %{ %} 4637 interface(REG_INTER); 4638 %} 4639 4640 // Pointer 64 bit Register FP only 4641 operand iRegP_FP() 4642 %{ 4643 constraint(ALLOC_IN_RC(fp_reg)); 4644 match(RegP); 4645 // match(iRegP); 4646 op_cost(0); 4647 format %{ %} 4648 interface(REG_INTER); 4649 %} 4650 4651 // Register R0 only 4652 operand iRegI_R0() 4653 %{ 4654 constraint(ALLOC_IN_RC(int_r0_reg)); 4655 match(RegI); 4656 match(iRegINoSp); 4657 op_cost(0); 4658 format %{ %} 4659 interface(REG_INTER); 4660 %} 4661 4662 // Register R2 only 4663 operand iRegI_R2() 4664 %{ 4665 constraint(ALLOC_IN_RC(int_r2_reg)); 4666 match(RegI); 4667 match(iRegINoSp); 4668 op_cost(0); 4669 format %{ %} 4670 interface(REG_INTER); 4671 %} 4672 4673 // Register R3 only 4674 operand iRegI_R3() 4675 %{ 4676 constraint(ALLOC_IN_RC(int_r3_reg)); 4677 match(RegI); 4678 match(iRegINoSp); 4679 op_cost(0); 4680 format %{ %} 4681 interface(REG_INTER); 4682 %} 4683 4684 4685 // Register R4 only 4686 operand iRegI_R4() 4687 %{ 4688 constraint(ALLOC_IN_RC(int_r4_reg)); 4689 match(RegI); 4690 match(iRegINoSp); 4691 op_cost(0); 4692 format %{ %} 4693 interface(REG_INTER); 4694 %} 4695 4696 4697 // Pointer Register Operands 4698 // Narrow Pointer Register 4699 operand iRegN() 4700 %{ 4701 constraint(ALLOC_IN_RC(any_reg32)); 4702 match(RegN); 4703 match(iRegNNoSp); 4704 op_cost(0); 4705 format %{ %} 4706 interface(REG_INTER); 4707 %} 4708 4709 operand iRegN_R0() 4710 %{ 4711 constraint(ALLOC_IN_RC(r0_reg)); 4712 match(iRegN); 4713 op_cost(0); 4714 format %{ %} 4715 interface(REG_INTER); 4716 %} 4717 4718 operand iRegN_R2() 4719 %{ 4720 constraint(ALLOC_IN_RC(r2_reg)); 4721 match(iRegN); 4722 op_cost(0); 4723 format %{ %} 4724 interface(REG_INTER); 4725 %} 4726 4727 operand iRegN_R3() 4728 %{ 4729 constraint(ALLOC_IN_RC(r3_reg)); 4730 match(iRegN); 4731 op_cost(0); 4732 format %{ %} 4733 interface(REG_INTER); 4734 %} 4735 4736 // Integer 64 bit Register not Special 4737 operand iRegNNoSp() 4738 %{ 4739 constraint(ALLOC_IN_RC(no_special_reg32)); 4740 match(RegN); 4741 op_cost(0); 4742 format %{ %} 4743 interface(REG_INTER); 4744 %} 4745 4746 // heap base register -- used for encoding immN0 4747 4748 operand iRegIHeapbase() 4749 %{ 4750 constraint(ALLOC_IN_RC(heapbase_reg)); 4751 match(RegI); 4752 op_cost(0); 4753 format %{ %} 4754 interface(REG_INTER); 4755 %} 4756 4757 // Float Register 4758 // Float register operands 4759 operand vRegF() 4760 %{ 4761 constraint(ALLOC_IN_RC(float_reg)); 4762 match(RegF); 4763 4764 op_cost(0); 4765 format %{ %} 4766 interface(REG_INTER); 4767 %} 4768 4769 // Double Register 4770 // Double register operands 4771 operand vRegD() 4772 %{ 4773 constraint(ALLOC_IN_RC(double_reg)); 4774 match(RegD); 4775 4776 op_cost(0); 4777 format %{ %} 4778 interface(REG_INTER); 4779 %} 4780 4781 operand vecD() 4782 %{ 4783 constraint(ALLOC_IN_RC(vectord_reg)); 4784 match(VecD); 4785 4786 op_cost(0); 4787 format %{ %} 4788 interface(REG_INTER); 4789 %} 4790 4791 operand vecX() 4792 %{ 4793 constraint(ALLOC_IN_RC(vectorx_reg)); 4794 match(VecX); 4795 4796 op_cost(0); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 operand vRegD_V0() 4802 %{ 4803 constraint(ALLOC_IN_RC(v0_reg)); 4804 match(RegD); 4805 op_cost(0); 4806 format %{ %} 4807 interface(REG_INTER); 4808 %} 4809 4810 operand vRegD_V1() 4811 %{ 4812 constraint(ALLOC_IN_RC(v1_reg)); 4813 match(RegD); 4814 op_cost(0); 4815 format %{ %} 4816 interface(REG_INTER); 4817 %} 4818 4819 operand vRegD_V2() 4820 %{ 4821 constraint(ALLOC_IN_RC(v2_reg)); 4822 match(RegD); 4823 op_cost(0); 4824 format %{ %} 4825 interface(REG_INTER); 4826 %} 4827 4828 operand vRegD_V3() 4829 %{ 4830 constraint(ALLOC_IN_RC(v3_reg)); 4831 match(RegD); 4832 op_cost(0); 4833 format %{ %} 4834 interface(REG_INTER); 4835 %} 4836 4837 // Flags register, used as output of signed compare instructions 4838 4839 // note that on AArch64 we also use this register as the output for 4840 // for floating point compare instructions (CmpF CmpD). this ensures 4841 // that ordered inequality tests use GT, GE, LT or LE none of which 4842 // pass through cases where the result is unordered i.e. one or both 4843 // inputs to the compare is a NaN. this means that the ideal code can 4844 // replace e.g. a GT with an LE and not end up capturing the NaN case 4845 // (where the comparison should always fail). EQ and NE tests are 4846 // always generated in ideal code so that unordered folds into the NE 4847 // case, matching the behaviour of AArch64 NE. 4848 // 4849 // This differs from x86 where the outputs of FP compares use a 4850 // special FP flags registers and where compares based on this 4851 // register are distinguished into ordered inequalities (cmpOpUCF) and 4852 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4853 // to explicitly handle the unordered case in branches. x86 also has 4854 // to include extra CMoveX rules to accept a cmpOpUCF input. 4855 4856 operand rFlagsReg() 4857 %{ 4858 constraint(ALLOC_IN_RC(int_flags)); 4859 match(RegFlags); 4860 4861 op_cost(0); 4862 format %{ "RFLAGS" %} 4863 interface(REG_INTER); 4864 %} 4865 4866 // Flags register, used as output of unsigned compare instructions 4867 operand rFlagsRegU() 4868 %{ 4869 constraint(ALLOC_IN_RC(int_flags)); 4870 match(RegFlags); 4871 4872 op_cost(0); 4873 format %{ "RFLAGSU" %} 4874 interface(REG_INTER); 4875 %} 4876 4877 // Special Registers 4878 4879 // Method Register 4880 operand inline_cache_RegP(iRegP reg) 4881 %{ 4882 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4883 match(reg); 4884 match(iRegPNoSp); 4885 op_cost(0); 4886 format %{ %} 4887 interface(REG_INTER); 4888 %} 4889 4890 operand interpreter_method_oop_RegP(iRegP reg) 4891 %{ 4892 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4893 match(reg); 4894 match(iRegPNoSp); 4895 op_cost(0); 4896 format %{ %} 4897 interface(REG_INTER); 4898 %} 4899 4900 // Thread Register 4901 operand thread_RegP(iRegP reg) 4902 %{ 4903 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4904 match(reg); 4905 op_cost(0); 4906 format %{ %} 4907 interface(REG_INTER); 4908 %} 4909 4910 operand lr_RegP(iRegP reg) 4911 %{ 4912 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4913 match(reg); 4914 op_cost(0); 4915 format %{ %} 4916 interface(REG_INTER); 4917 %} 4918 4919 //----------Memory Operands---------------------------------------------------- 4920 4921 operand indirect(iRegP reg) 4922 %{ 4923 constraint(ALLOC_IN_RC(ptr_reg)); 4924 match(reg); 4925 op_cost(0); 4926 format %{ "[$reg]" %} 4927 interface(MEMORY_INTER) %{ 4928 base($reg); 4929 index(0xffffffff); 4930 scale(0x0); 4931 disp(0x0); 4932 %} 4933 %} 4934 4935 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4936 %{ 4937 constraint(ALLOC_IN_RC(ptr_reg)); 4938 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4939 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4940 op_cost(0); 4941 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4942 interface(MEMORY_INTER) %{ 4943 base($reg); 4944 index($ireg); 4945 scale($scale); 4946 disp(0x0); 4947 %} 4948 %} 4949 4950 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4951 %{ 4952 constraint(ALLOC_IN_RC(ptr_reg)); 4953 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4954 match(AddP reg (LShiftL lreg scale)); 4955 op_cost(0); 4956 format %{ "$reg, $lreg lsl($scale)" %} 4957 interface(MEMORY_INTER) %{ 4958 base($reg); 4959 index($lreg); 4960 scale($scale); 4961 disp(0x0); 4962 %} 4963 %} 4964 4965 operand indIndexI2L(iRegP reg, iRegI ireg) 4966 %{ 4967 constraint(ALLOC_IN_RC(ptr_reg)); 4968 match(AddP reg (ConvI2L ireg)); 4969 op_cost(0); 4970 format %{ "$reg, $ireg, 0, I2L" %} 4971 interface(MEMORY_INTER) %{ 4972 base($reg); 4973 index($ireg); 4974 scale(0x0); 4975 disp(0x0); 4976 %} 4977 %} 4978 4979 operand indIndex(iRegP reg, iRegL lreg) 4980 %{ 4981 constraint(ALLOC_IN_RC(ptr_reg)); 4982 match(AddP reg lreg); 4983 op_cost(0); 4984 format %{ "$reg, $lreg" %} 4985 interface(MEMORY_INTER) %{ 4986 base($reg); 4987 index($lreg); 4988 scale(0x0); 4989 disp(0x0); 4990 %} 4991 %} 4992 4993 operand indOffI(iRegP reg, immIOffset off) 4994 %{ 4995 constraint(ALLOC_IN_RC(ptr_reg)); 4996 match(AddP reg off); 4997 op_cost(0); 4998 format %{ "[$reg, $off]" %} 4999 interface(MEMORY_INTER) %{ 5000 base($reg); 5001 index(0xffffffff); 5002 scale(0x0); 5003 disp($off); 5004 %} 5005 %} 5006 5007 operand indOffI4(iRegP reg, immIOffset4 off) 5008 %{ 5009 constraint(ALLOC_IN_RC(ptr_reg)); 5010 match(AddP reg off); 5011 op_cost(0); 5012 format %{ "[$reg, $off]" %} 5013 interface(MEMORY_INTER) %{ 5014 base($reg); 5015 index(0xffffffff); 5016 scale(0x0); 5017 disp($off); 5018 %} 5019 %} 5020 5021 operand indOffI8(iRegP reg, immIOffset8 off) 5022 %{ 5023 constraint(ALLOC_IN_RC(ptr_reg)); 5024 match(AddP reg off); 5025 op_cost(0); 5026 format %{ "[$reg, $off]" %} 5027 interface(MEMORY_INTER) %{ 5028 base($reg); 5029 index(0xffffffff); 5030 scale(0x0); 5031 disp($off); 5032 %} 5033 %} 5034 5035 operand indOffI16(iRegP reg, immIOffset16 off) 5036 %{ 5037 constraint(ALLOC_IN_RC(ptr_reg)); 5038 match(AddP reg off); 5039 op_cost(0); 5040 format %{ "[$reg, $off]" %} 5041 interface(MEMORY_INTER) %{ 5042 base($reg); 5043 index(0xffffffff); 5044 scale(0x0); 5045 disp($off); 5046 %} 5047 %} 5048 5049 operand indOffL(iRegP reg, immLoffset off) 5050 %{ 5051 constraint(ALLOC_IN_RC(ptr_reg)); 5052 match(AddP reg off); 5053 op_cost(0); 5054 format %{ "[$reg, $off]" %} 5055 interface(MEMORY_INTER) %{ 5056 base($reg); 5057 index(0xffffffff); 5058 scale(0x0); 5059 disp($off); 5060 %} 5061 %} 5062 5063 operand indOffL4(iRegP reg, immLoffset4 off) 5064 %{ 5065 constraint(ALLOC_IN_RC(ptr_reg)); 5066 match(AddP reg off); 5067 op_cost(0); 5068 format %{ "[$reg, $off]" %} 5069 interface(MEMORY_INTER) %{ 5070 base($reg); 5071 index(0xffffffff); 5072 scale(0x0); 5073 disp($off); 5074 %} 5075 %} 5076 5077 operand indOffL8(iRegP reg, immLoffset8 off) 5078 %{ 5079 constraint(ALLOC_IN_RC(ptr_reg)); 5080 match(AddP reg off); 5081 op_cost(0); 5082 format %{ "[$reg, $off]" %} 5083 interface(MEMORY_INTER) %{ 5084 base($reg); 5085 index(0xffffffff); 5086 scale(0x0); 5087 disp($off); 5088 %} 5089 %} 5090 5091 operand indOffL16(iRegP reg, immLoffset16 off) 5092 %{ 5093 constraint(ALLOC_IN_RC(ptr_reg)); 5094 match(AddP reg off); 5095 op_cost(0); 5096 format %{ "[$reg, $off]" %} 5097 interface(MEMORY_INTER) %{ 5098 base($reg); 5099 index(0xffffffff); 5100 scale(0x0); 5101 disp($off); 5102 %} 5103 %} 5104 5105 operand indirectN(iRegN reg) 5106 %{ 5107 predicate(Universe::narrow_oop_shift() == 0); 5108 constraint(ALLOC_IN_RC(ptr_reg)); 5109 match(DecodeN reg); 5110 op_cost(0); 5111 format %{ "[$reg]\t# narrow" %} 5112 interface(MEMORY_INTER) %{ 5113 base($reg); 5114 index(0xffffffff); 5115 scale(0x0); 5116 disp(0x0); 5117 %} 5118 %} 5119 5120 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5121 %{ 5122 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5123 constraint(ALLOC_IN_RC(ptr_reg)); 5124 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5125 op_cost(0); 5126 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5127 interface(MEMORY_INTER) %{ 5128 base($reg); 5129 index($ireg); 5130 scale($scale); 5131 disp(0x0); 5132 %} 5133 %} 5134 5135 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5136 %{ 5137 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5138 constraint(ALLOC_IN_RC(ptr_reg)); 5139 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5140 op_cost(0); 5141 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5142 interface(MEMORY_INTER) %{ 5143 base($reg); 5144 index($lreg); 5145 scale($scale); 5146 disp(0x0); 5147 %} 5148 %} 5149 5150 operand indIndexI2LN(iRegN reg, iRegI ireg) 5151 %{ 5152 predicate(Universe::narrow_oop_shift() == 0); 5153 constraint(ALLOC_IN_RC(ptr_reg)); 5154 match(AddP (DecodeN reg) (ConvI2L ireg)); 5155 op_cost(0); 5156 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5157 interface(MEMORY_INTER) %{ 5158 base($reg); 5159 index($ireg); 5160 scale(0x0); 5161 disp(0x0); 5162 %} 5163 %} 5164 5165 operand indIndexN(iRegN reg, iRegL lreg) 5166 %{ 5167 predicate(Universe::narrow_oop_shift() == 0); 5168 constraint(ALLOC_IN_RC(ptr_reg)); 5169 match(AddP (DecodeN reg) lreg); 5170 op_cost(0); 5171 format %{ "$reg, $lreg\t# narrow" %} 5172 interface(MEMORY_INTER) %{ 5173 base($reg); 5174 index($lreg); 5175 scale(0x0); 5176 disp(0x0); 5177 %} 5178 %} 5179 5180 operand indOffIN(iRegN reg, immIOffset off) 5181 %{ 5182 predicate(Universe::narrow_oop_shift() == 0); 5183 constraint(ALLOC_IN_RC(ptr_reg)); 5184 match(AddP (DecodeN reg) off); 5185 op_cost(0); 5186 format %{ "[$reg, $off]\t# narrow" %} 5187 interface(MEMORY_INTER) %{ 5188 base($reg); 5189 index(0xffffffff); 5190 scale(0x0); 5191 disp($off); 5192 %} 5193 %} 5194 5195 operand indOffLN(iRegN reg, immLoffset off) 5196 %{ 5197 predicate(Universe::narrow_oop_shift() == 0); 5198 constraint(ALLOC_IN_RC(ptr_reg)); 5199 match(AddP (DecodeN reg) off); 5200 op_cost(0); 5201 format %{ "[$reg, $off]\t# narrow" %} 5202 interface(MEMORY_INTER) %{ 5203 base($reg); 5204 index(0xffffffff); 5205 scale(0x0); 5206 disp($off); 5207 %} 5208 %} 5209 5210 5211 5212 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5213 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5214 %{ 5215 constraint(ALLOC_IN_RC(ptr_reg)); 5216 match(AddP reg off); 5217 op_cost(0); 5218 format %{ "[$reg, $off]" %} 5219 interface(MEMORY_INTER) %{ 5220 base($reg); 5221 index(0xffffffff); 5222 scale(0x0); 5223 disp($off); 5224 %} 5225 %} 5226 5227 //----------Special Memory Operands-------------------------------------------- 5228 // Stack Slot Operand - This operand is used for loading and storing temporary 5229 // values on the stack where a match requires a value to 5230 // flow through memory. 5231 operand stackSlotP(sRegP reg) 5232 %{ 5233 constraint(ALLOC_IN_RC(stack_slots)); 5234 op_cost(100); 5235 // No match rule because this operand is only generated in matching 5236 // match(RegP); 5237 format %{ "[$reg]" %} 5238 interface(MEMORY_INTER) %{ 5239 base(0x1e); // RSP 5240 index(0x0); // No Index 5241 scale(0x0); // No Scale 5242 disp($reg); // Stack Offset 5243 %} 5244 %} 5245 5246 operand stackSlotI(sRegI reg) 5247 %{ 5248 constraint(ALLOC_IN_RC(stack_slots)); 5249 // No match rule because this operand is only generated in matching 5250 // match(RegI); 5251 format %{ "[$reg]" %} 5252 interface(MEMORY_INTER) %{ 5253 base(0x1e); // RSP 5254 index(0x0); // No Index 5255 scale(0x0); // No Scale 5256 disp($reg); // Stack Offset 5257 %} 5258 %} 5259 5260 operand stackSlotF(sRegF reg) 5261 %{ 5262 constraint(ALLOC_IN_RC(stack_slots)); 5263 // No match rule because this operand is only generated in matching 5264 // match(RegF); 5265 format %{ "[$reg]" %} 5266 interface(MEMORY_INTER) %{ 5267 base(0x1e); // RSP 5268 index(0x0); // No Index 5269 scale(0x0); // No Scale 5270 disp($reg); // Stack Offset 5271 %} 5272 %} 5273 5274 operand stackSlotD(sRegD reg) 5275 %{ 5276 constraint(ALLOC_IN_RC(stack_slots)); 5277 // No match rule because this operand is only generated in matching 5278 // match(RegD); 5279 format %{ "[$reg]" %} 5280 interface(MEMORY_INTER) %{ 5281 base(0x1e); // RSP 5282 index(0x0); // No Index 5283 scale(0x0); // No Scale 5284 disp($reg); // Stack Offset 5285 %} 5286 %} 5287 5288 operand stackSlotL(sRegL reg) 5289 %{ 5290 constraint(ALLOC_IN_RC(stack_slots)); 5291 // No match rule because this operand is only generated in matching 5292 // match(RegL); 5293 format %{ "[$reg]" %} 5294 interface(MEMORY_INTER) %{ 5295 base(0x1e); // RSP 5296 index(0x0); // No Index 5297 scale(0x0); // No Scale 5298 disp($reg); // Stack Offset 5299 %} 5300 %} 5301 5302 // Operands for expressing Control Flow 5303 // NOTE: Label is a predefined operand which should not be redefined in 5304 // the AD file. It is generically handled within the ADLC. 5305 5306 //----------Conditional Branch Operands---------------------------------------- 5307 // Comparison Op - This is the operation of the comparison, and is limited to 5308 // the following set of codes: 5309 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5310 // 5311 // Other attributes of the comparison, such as unsignedness, are specified 5312 // by the comparison instruction that sets a condition code flags register. 5313 // That result is represented by a flags operand whose subtype is appropriate 5314 // to the unsignedness (etc.) of the comparison. 5315 // 5316 // Later, the instruction which matches both the Comparison Op (a Bool) and 5317 // the flags (produced by the Cmp) specifies the coding of the comparison op 5318 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5319 5320 // used for signed integral comparisons and fp comparisons 5321 5322 operand cmpOp() 5323 %{ 5324 match(Bool); 5325 5326 format %{ "" %} 5327 interface(COND_INTER) %{ 5328 equal(0x0, "eq"); 5329 not_equal(0x1, "ne"); 5330 less(0xb, "lt"); 5331 greater_equal(0xa, "ge"); 5332 less_equal(0xd, "le"); 5333 greater(0xc, "gt"); 5334 overflow(0x6, "vs"); 5335 no_overflow(0x7, "vc"); 5336 %} 5337 %} 5338 5339 // used for unsigned integral comparisons 5340 5341 operand cmpOpU() 5342 %{ 5343 match(Bool); 5344 5345 format %{ "" %} 5346 interface(COND_INTER) %{ 5347 equal(0x0, "eq"); 5348 not_equal(0x1, "ne"); 5349 less(0x3, "lo"); 5350 greater_equal(0x2, "hs"); 5351 less_equal(0x9, "ls"); 5352 greater(0x8, "hi"); 5353 overflow(0x6, "vs"); 5354 no_overflow(0x7, "vc"); 5355 %} 5356 %} 5357 5358 // used for certain integral comparisons which can be 5359 // converted to cbxx or tbxx instructions 5360 5361 operand cmpOpEqNe() 5362 %{ 5363 match(Bool); 5364 match(CmpOp); 5365 op_cost(0); 5366 predicate(n->as_Bool()->_test._test == BoolTest::ne 5367 || n->as_Bool()->_test._test == BoolTest::eq); 5368 5369 format %{ "" %} 5370 interface(COND_INTER) %{ 5371 equal(0x0, "eq"); 5372 not_equal(0x1, "ne"); 5373 less(0xb, "lt"); 5374 greater_equal(0xa, "ge"); 5375 less_equal(0xd, "le"); 5376 greater(0xc, "gt"); 5377 overflow(0x6, "vs"); 5378 no_overflow(0x7, "vc"); 5379 %} 5380 %} 5381 5382 // used for certain integral comparisons which can be 5383 // converted to cbxx or tbxx instructions 5384 5385 operand cmpOpLtGe() 5386 %{ 5387 match(Bool); 5388 match(CmpOp); 5389 op_cost(0); 5390 5391 predicate(n->as_Bool()->_test._test == BoolTest::lt 5392 || n->as_Bool()->_test._test == BoolTest::ge); 5393 5394 format %{ "" %} 5395 interface(COND_INTER) %{ 5396 equal(0x0, "eq"); 5397 not_equal(0x1, "ne"); 5398 less(0xb, "lt"); 5399 greater_equal(0xa, "ge"); 5400 less_equal(0xd, "le"); 5401 greater(0xc, "gt"); 5402 overflow(0x6, "vs"); 5403 no_overflow(0x7, "vc"); 5404 %} 5405 %} 5406 5407 // used for certain unsigned integral comparisons which can be 5408 // converted to cbxx or tbxx instructions 5409 5410 operand cmpOpUEqNeLtGe() 5411 %{ 5412 match(Bool); 5413 match(CmpOp); 5414 op_cost(0); 5415 5416 predicate(n->as_Bool()->_test._test == BoolTest::eq 5417 || n->as_Bool()->_test._test == BoolTest::ne 5418 || n->as_Bool()->_test._test == BoolTest::lt 5419 || n->as_Bool()->_test._test == BoolTest::ge); 5420 5421 format %{ "" %} 5422 interface(COND_INTER) %{ 5423 equal(0x0, "eq"); 5424 not_equal(0x1, "ne"); 5425 less(0xb, "lt"); 5426 greater_equal(0xa, "ge"); 5427 less_equal(0xd, "le"); 5428 greater(0xc, "gt"); 5429 overflow(0x6, "vs"); 5430 no_overflow(0x7, "vc"); 5431 %} 5432 %} 5433 5434 // Special operand allowing long args to int ops to be truncated for free 5435 5436 operand iRegL2I(iRegL reg) %{ 5437 5438 op_cost(0); 5439 5440 match(ConvL2I reg); 5441 5442 format %{ "l2i($reg)" %} 5443 5444 interface(REG_INTER) 5445 %} 5446 5447 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5448 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5449 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5450 5451 //----------OPERAND CLASSES---------------------------------------------------- 5452 // Operand Classes are groups of operands that are used as to simplify 5453 // instruction definitions by not requiring the AD writer to specify 5454 // separate instructions for every form of operand when the 5455 // instruction accepts multiple operand types with the same basic 5456 // encoding and format. The classic case of this is memory operands. 5457 5458 // memory is used to define read/write location for load/store 5459 // instruction defs. we can turn a memory op into an Address 5460 5461 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5462 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5463 5464 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5465 // operations. it allows the src to be either an iRegI or a (ConvL2I 5466 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5467 // can be elided because the 32-bit instruction will just employ the 5468 // lower 32 bits anyway. 5469 // 5470 // n.b. this does not elide all L2I conversions. if the truncated 5471 // value is consumed by more than one operation then the ConvL2I 5472 // cannot be bundled into the consuming nodes so an l2i gets planted 5473 // (actually a movw $dst $src) and the downstream instructions consume 5474 // the result of the l2i as an iRegI input. That's a shame since the 5475 // movw is actually redundant but its not too costly. 5476 5477 opclass iRegIorL2I(iRegI, iRegL2I); 5478 5479 //----------PIPELINE----------------------------------------------------------- 5480 // Rules which define the behavior of the target architectures pipeline. 5481 5482 // For specific pipelines, eg A53, define the stages of that pipeline 5483 //pipe_desc(ISS, EX1, EX2, WR); 5484 #define ISS S0 5485 #define EX1 S1 5486 #define EX2 S2 5487 #define WR S3 5488 5489 // Integer ALU reg operation 5490 pipeline %{ 5491 5492 attributes %{ 5493 // ARM instructions are of fixed length 5494 fixed_size_instructions; // Fixed size instructions TODO does 5495 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5496 // ARM instructions come in 32-bit word units 5497 instruction_unit_size = 4; // An instruction is 4 bytes long 5498 instruction_fetch_unit_size = 64; // The processor fetches one line 5499 instruction_fetch_units = 1; // of 64 bytes 5500 5501 // List of nop instructions 5502 nops( MachNop ); 5503 %} 5504 5505 // We don't use an actual pipeline model so don't care about resources 5506 // or description. we do use pipeline classes to introduce fixed 5507 // latencies 5508 5509 //----------RESOURCES---------------------------------------------------------- 5510 // Resources are the functional units available to the machine 5511 5512 resources( INS0, INS1, INS01 = INS0 | INS1, 5513 ALU0, ALU1, ALU = ALU0 | ALU1, 5514 MAC, 5515 DIV, 5516 BRANCH, 5517 LDST, 5518 NEON_FP); 5519 5520 //----------PIPELINE DESCRIPTION----------------------------------------------- 5521 // Pipeline Description specifies the stages in the machine's pipeline 5522 5523 // Define the pipeline as a generic 6 stage pipeline 5524 pipe_desc(S0, S1, S2, S3, S4, S5); 5525 5526 //----------PIPELINE CLASSES--------------------------------------------------- 5527 // Pipeline Classes describe the stages in which input and output are 5528 // referenced by the hardware pipeline. 5529 5530 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5531 %{ 5532 single_instruction; 5533 src1 : S1(read); 5534 src2 : S2(read); 5535 dst : S5(write); 5536 INS01 : ISS; 5537 NEON_FP : S5; 5538 %} 5539 5540 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5541 %{ 5542 single_instruction; 5543 src1 : S1(read); 5544 src2 : S2(read); 5545 dst : S5(write); 5546 INS01 : ISS; 5547 NEON_FP : S5; 5548 %} 5549 5550 pipe_class fp_uop_s(vRegF dst, vRegF src) 5551 %{ 5552 single_instruction; 5553 src : S1(read); 5554 dst : S5(write); 5555 INS01 : ISS; 5556 NEON_FP : S5; 5557 %} 5558 5559 pipe_class fp_uop_d(vRegD dst, vRegD src) 5560 %{ 5561 single_instruction; 5562 src : S1(read); 5563 dst : S5(write); 5564 INS01 : ISS; 5565 NEON_FP : S5; 5566 %} 5567 5568 pipe_class fp_d2f(vRegF dst, vRegD src) 5569 %{ 5570 single_instruction; 5571 src : S1(read); 5572 dst : S5(write); 5573 INS01 : ISS; 5574 NEON_FP : S5; 5575 %} 5576 5577 pipe_class fp_f2d(vRegD dst, vRegF src) 5578 %{ 5579 single_instruction; 5580 src : S1(read); 5581 dst : S5(write); 5582 INS01 : ISS; 5583 NEON_FP : S5; 5584 %} 5585 5586 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5587 %{ 5588 single_instruction; 5589 src : S1(read); 5590 dst : S5(write); 5591 INS01 : ISS; 5592 NEON_FP : S5; 5593 %} 5594 5595 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5596 %{ 5597 single_instruction; 5598 src : S1(read); 5599 dst : S5(write); 5600 INS01 : ISS; 5601 NEON_FP : S5; 5602 %} 5603 5604 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5605 %{ 5606 single_instruction; 5607 src : S1(read); 5608 dst : S5(write); 5609 INS01 : ISS; 5610 NEON_FP : S5; 5611 %} 5612 5613 pipe_class fp_l2f(vRegF dst, iRegL src) 5614 %{ 5615 single_instruction; 5616 src : S1(read); 5617 dst : S5(write); 5618 INS01 : ISS; 5619 NEON_FP : S5; 5620 %} 5621 5622 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5623 %{ 5624 single_instruction; 5625 src : S1(read); 5626 dst : S5(write); 5627 INS01 : ISS; 5628 NEON_FP : S5; 5629 %} 5630 5631 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5632 %{ 5633 single_instruction; 5634 src : S1(read); 5635 dst : S5(write); 5636 INS01 : ISS; 5637 NEON_FP : S5; 5638 %} 5639 5640 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5641 %{ 5642 single_instruction; 5643 src : S1(read); 5644 dst : S5(write); 5645 INS01 : ISS; 5646 NEON_FP : S5; 5647 %} 5648 5649 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5650 %{ 5651 single_instruction; 5652 src : S1(read); 5653 dst : S5(write); 5654 INS01 : ISS; 5655 NEON_FP : S5; 5656 %} 5657 5658 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5659 %{ 5660 single_instruction; 5661 src1 : S1(read); 5662 src2 : S2(read); 5663 dst : S5(write); 5664 INS0 : ISS; 5665 NEON_FP : S5; 5666 %} 5667 5668 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5669 %{ 5670 single_instruction; 5671 src1 : S1(read); 5672 src2 : S2(read); 5673 dst : S5(write); 5674 INS0 : ISS; 5675 NEON_FP : S5; 5676 %} 5677 5678 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5679 %{ 5680 single_instruction; 5681 cr : S1(read); 5682 src1 : S1(read); 5683 src2 : S1(read); 5684 dst : S3(write); 5685 INS01 : ISS; 5686 NEON_FP : S3; 5687 %} 5688 5689 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5690 %{ 5691 single_instruction; 5692 cr : S1(read); 5693 src1 : S1(read); 5694 src2 : S1(read); 5695 dst : S3(write); 5696 INS01 : ISS; 5697 NEON_FP : S3; 5698 %} 5699 5700 pipe_class fp_imm_s(vRegF dst) 5701 %{ 5702 single_instruction; 5703 dst : S3(write); 5704 INS01 : ISS; 5705 NEON_FP : S3; 5706 %} 5707 5708 pipe_class fp_imm_d(vRegD dst) 5709 %{ 5710 single_instruction; 5711 dst : S3(write); 5712 INS01 : ISS; 5713 NEON_FP : S3; 5714 %} 5715 5716 pipe_class fp_load_constant_s(vRegF dst) 5717 %{ 5718 single_instruction; 5719 dst : S4(write); 5720 INS01 : ISS; 5721 NEON_FP : S4; 5722 %} 5723 5724 pipe_class fp_load_constant_d(vRegD dst) 5725 %{ 5726 single_instruction; 5727 dst : S4(write); 5728 INS01 : ISS; 5729 NEON_FP : S4; 5730 %} 5731 5732 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5733 %{ 5734 single_instruction; 5735 dst : S5(write); 5736 src1 : S1(read); 5737 src2 : S1(read); 5738 INS01 : ISS; 5739 NEON_FP : S5; 5740 %} 5741 5742 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5743 %{ 5744 single_instruction; 5745 dst : S5(write); 5746 src1 : S1(read); 5747 src2 : S1(read); 5748 INS0 : ISS; 5749 NEON_FP : S5; 5750 %} 5751 5752 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5753 %{ 5754 single_instruction; 5755 dst : S5(write); 5756 src1 : S1(read); 5757 src2 : S1(read); 5758 dst : S1(read); 5759 INS01 : ISS; 5760 NEON_FP : S5; 5761 %} 5762 5763 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5764 %{ 5765 single_instruction; 5766 dst : S5(write); 5767 src1 : S1(read); 5768 src2 : S1(read); 5769 dst : S1(read); 5770 INS0 : ISS; 5771 NEON_FP : S5; 5772 %} 5773 5774 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5775 %{ 5776 single_instruction; 5777 dst : S4(write); 5778 src1 : S2(read); 5779 src2 : S2(read); 5780 INS01 : ISS; 5781 NEON_FP : S4; 5782 %} 5783 5784 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5785 %{ 5786 single_instruction; 5787 dst : S4(write); 5788 src1 : S2(read); 5789 src2 : S2(read); 5790 INS0 : ISS; 5791 NEON_FP : S4; 5792 %} 5793 5794 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5795 %{ 5796 single_instruction; 5797 dst : S3(write); 5798 src1 : S2(read); 5799 src2 : S2(read); 5800 INS01 : ISS; 5801 NEON_FP : S3; 5802 %} 5803 5804 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5805 %{ 5806 single_instruction; 5807 dst : S3(write); 5808 src1 : S2(read); 5809 src2 : S2(read); 5810 INS0 : ISS; 5811 NEON_FP : S3; 5812 %} 5813 5814 pipe_class vshift64(vecD dst, vecD src, vecX shift) 5815 %{ 5816 single_instruction; 5817 dst : S3(write); 5818 src : S1(read); 5819 shift : S1(read); 5820 INS01 : ISS; 5821 NEON_FP : S3; 5822 %} 5823 5824 pipe_class vshift128(vecX dst, vecX src, vecX shift) 5825 %{ 5826 single_instruction; 5827 dst : S3(write); 5828 src : S1(read); 5829 shift : S1(read); 5830 INS0 : ISS; 5831 NEON_FP : S3; 5832 %} 5833 5834 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5835 %{ 5836 single_instruction; 5837 dst : S3(write); 5838 src : S1(read); 5839 INS01 : ISS; 5840 NEON_FP : S3; 5841 %} 5842 5843 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5844 %{ 5845 single_instruction; 5846 dst : S3(write); 5847 src : S1(read); 5848 INS0 : ISS; 5849 NEON_FP : S3; 5850 %} 5851 5852 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5853 %{ 5854 single_instruction; 5855 dst : S5(write); 5856 src1 : S1(read); 5857 src2 : S1(read); 5858 INS01 : ISS; 5859 NEON_FP : S5; 5860 %} 5861 5862 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5863 %{ 5864 single_instruction; 5865 dst : S5(write); 5866 src1 : S1(read); 5867 src2 : S1(read); 5868 INS0 : ISS; 5869 NEON_FP : S5; 5870 %} 5871 5872 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5873 %{ 5874 single_instruction; 5875 dst : S5(write); 5876 src1 : S1(read); 5877 src2 : S1(read); 5878 INS0 : ISS; 5879 NEON_FP : S5; 5880 %} 5881 5882 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5883 %{ 5884 single_instruction; 5885 dst : S5(write); 5886 src1 : S1(read); 5887 src2 : S1(read); 5888 INS0 : ISS; 5889 NEON_FP : S5; 5890 %} 5891 5892 pipe_class vsqrt_fp128(vecX dst, vecX src) 5893 %{ 5894 single_instruction; 5895 dst : S5(write); 5896 src : S1(read); 5897 INS0 : ISS; 5898 NEON_FP : S5; 5899 %} 5900 5901 pipe_class vunop_fp64(vecD dst, vecD src) 5902 %{ 5903 single_instruction; 5904 dst : S5(write); 5905 src : S1(read); 5906 INS01 : ISS; 5907 NEON_FP : S5; 5908 %} 5909 5910 pipe_class vunop_fp128(vecX dst, vecX src) 5911 %{ 5912 single_instruction; 5913 dst : S5(write); 5914 src : S1(read); 5915 INS0 : ISS; 5916 NEON_FP : S5; 5917 %} 5918 5919 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5920 %{ 5921 single_instruction; 5922 dst : S3(write); 5923 src : S1(read); 5924 INS01 : ISS; 5925 NEON_FP : S3; 5926 %} 5927 5928 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5929 %{ 5930 single_instruction; 5931 dst : S3(write); 5932 src : S1(read); 5933 INS01 : ISS; 5934 NEON_FP : S3; 5935 %} 5936 5937 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5938 %{ 5939 single_instruction; 5940 dst : S3(write); 5941 src : S1(read); 5942 INS01 : ISS; 5943 NEON_FP : S3; 5944 %} 5945 5946 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5947 %{ 5948 single_instruction; 5949 dst : S3(write); 5950 src : S1(read); 5951 INS01 : ISS; 5952 NEON_FP : S3; 5953 %} 5954 5955 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5956 %{ 5957 single_instruction; 5958 dst : S3(write); 5959 src : S1(read); 5960 INS01 : ISS; 5961 NEON_FP : S3; 5962 %} 5963 5964 pipe_class vmovi_reg_imm64(vecD dst) 5965 %{ 5966 single_instruction; 5967 dst : S3(write); 5968 INS01 : ISS; 5969 NEON_FP : S3; 5970 %} 5971 5972 pipe_class vmovi_reg_imm128(vecX dst) 5973 %{ 5974 single_instruction; 5975 dst : S3(write); 5976 INS0 : ISS; 5977 NEON_FP : S3; 5978 %} 5979 5980 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 5981 %{ 5982 single_instruction; 5983 dst : S5(write); 5984 mem : ISS(read); 5985 INS01 : ISS; 5986 NEON_FP : S3; 5987 %} 5988 5989 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 5990 %{ 5991 single_instruction; 5992 dst : S5(write); 5993 mem : ISS(read); 5994 INS01 : ISS; 5995 NEON_FP : S3; 5996 %} 5997 5998 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 5999 %{ 6000 single_instruction; 6001 mem : ISS(read); 6002 src : S2(read); 6003 INS01 : ISS; 6004 NEON_FP : S3; 6005 %} 6006 6007 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6008 %{ 6009 single_instruction; 6010 mem : ISS(read); 6011 src : S2(read); 6012 INS01 : ISS; 6013 NEON_FP : S3; 6014 %} 6015 6016 //------- Integer ALU operations -------------------------- 6017 6018 // Integer ALU reg-reg operation 6019 // Operands needed in EX1, result generated in EX2 6020 // Eg. ADD x0, x1, x2 6021 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6022 %{ 6023 single_instruction; 6024 dst : EX2(write); 6025 src1 : EX1(read); 6026 src2 : EX1(read); 6027 INS01 : ISS; // Dual issue as instruction 0 or 1 6028 ALU : EX2; 6029 %} 6030 6031 // Integer ALU reg-reg operation with constant shift 6032 // Shifted register must be available in LATE_ISS instead of EX1 6033 // Eg. ADD x0, x1, x2, LSL #2 6034 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6035 %{ 6036 single_instruction; 6037 dst : EX2(write); 6038 src1 : EX1(read); 6039 src2 : ISS(read); 6040 INS01 : ISS; 6041 ALU : EX2; 6042 %} 6043 6044 // Integer ALU reg operation with constant shift 6045 // Eg. LSL x0, x1, #shift 6046 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6047 %{ 6048 single_instruction; 6049 dst : EX2(write); 6050 src1 : ISS(read); 6051 INS01 : ISS; 6052 ALU : EX2; 6053 %} 6054 6055 // Integer ALU reg-reg operation with variable shift 6056 // Both operands must be available in LATE_ISS instead of EX1 6057 // Result is available in EX1 instead of EX2 6058 // Eg. LSLV x0, x1, x2 6059 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6060 %{ 6061 single_instruction; 6062 dst : EX1(write); 6063 src1 : ISS(read); 6064 src2 : ISS(read); 6065 INS01 : ISS; 6066 ALU : EX1; 6067 %} 6068 6069 // Integer ALU reg-reg operation with extract 6070 // As for _vshift above, but result generated in EX2 6071 // Eg. EXTR x0, x1, x2, #N 6072 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6073 %{ 6074 single_instruction; 6075 dst : EX2(write); 6076 src1 : ISS(read); 6077 src2 : ISS(read); 6078 INS1 : ISS; // Can only dual issue as Instruction 1 6079 ALU : EX1; 6080 %} 6081 6082 // Integer ALU reg operation 6083 // Eg. NEG x0, x1 6084 pipe_class ialu_reg(iRegI dst, iRegI src) 6085 %{ 6086 single_instruction; 6087 dst : EX2(write); 6088 src : EX1(read); 6089 INS01 : ISS; 6090 ALU : EX2; 6091 %} 6092 6093 // Integer ALU reg mmediate operation 6094 // Eg. ADD x0, x1, #N 6095 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6096 %{ 6097 single_instruction; 6098 dst : EX2(write); 6099 src1 : EX1(read); 6100 INS01 : ISS; 6101 ALU : EX2; 6102 %} 6103 6104 // Integer ALU immediate operation (no source operands) 6105 // Eg. MOV x0, #N 6106 pipe_class ialu_imm(iRegI dst) 6107 %{ 6108 single_instruction; 6109 dst : EX1(write); 6110 INS01 : ISS; 6111 ALU : EX1; 6112 %} 6113 6114 //------- Compare operation ------------------------------- 6115 6116 // Compare reg-reg 6117 // Eg. CMP x0, x1 6118 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6119 %{ 6120 single_instruction; 6121 // fixed_latency(16); 6122 cr : EX2(write); 6123 op1 : EX1(read); 6124 op2 : EX1(read); 6125 INS01 : ISS; 6126 ALU : EX2; 6127 %} 6128 6129 // Compare reg-reg 6130 // Eg. CMP x0, #N 6131 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6132 %{ 6133 single_instruction; 6134 // fixed_latency(16); 6135 cr : EX2(write); 6136 op1 : EX1(read); 6137 INS01 : ISS; 6138 ALU : EX2; 6139 %} 6140 6141 //------- Conditional instructions ------------------------ 6142 6143 // Conditional no operands 6144 // Eg. CSINC x0, zr, zr, <cond> 6145 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6146 %{ 6147 single_instruction; 6148 cr : EX1(read); 6149 dst : EX2(write); 6150 INS01 : ISS; 6151 ALU : EX2; 6152 %} 6153 6154 // Conditional 2 operand 6155 // EG. CSEL X0, X1, X2, <cond> 6156 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6157 %{ 6158 single_instruction; 6159 cr : EX1(read); 6160 src1 : EX1(read); 6161 src2 : EX1(read); 6162 dst : EX2(write); 6163 INS01 : ISS; 6164 ALU : EX2; 6165 %} 6166 6167 // Conditional 2 operand 6168 // EG. CSEL X0, X1, X2, <cond> 6169 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6170 %{ 6171 single_instruction; 6172 cr : EX1(read); 6173 src : EX1(read); 6174 dst : EX2(write); 6175 INS01 : ISS; 6176 ALU : EX2; 6177 %} 6178 6179 //------- Multiply pipeline operations -------------------- 6180 6181 // Multiply reg-reg 6182 // Eg. MUL w0, w1, w2 6183 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6184 %{ 6185 single_instruction; 6186 dst : WR(write); 6187 src1 : ISS(read); 6188 src2 : ISS(read); 6189 INS01 : ISS; 6190 MAC : WR; 6191 %} 6192 6193 // Multiply accumulate 6194 // Eg. MADD w0, w1, w2, w3 6195 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6196 %{ 6197 single_instruction; 6198 dst : WR(write); 6199 src1 : ISS(read); 6200 src2 : ISS(read); 6201 src3 : ISS(read); 6202 INS01 : ISS; 6203 MAC : WR; 6204 %} 6205 6206 // Eg. MUL w0, w1, w2 6207 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6208 %{ 6209 single_instruction; 6210 fixed_latency(3); // Maximum latency for 64 bit mul 6211 dst : WR(write); 6212 src1 : ISS(read); 6213 src2 : ISS(read); 6214 INS01 : ISS; 6215 MAC : WR; 6216 %} 6217 6218 // Multiply accumulate 6219 // Eg. MADD w0, w1, w2, w3 6220 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6221 %{ 6222 single_instruction; 6223 fixed_latency(3); // Maximum latency for 64 bit mul 6224 dst : WR(write); 6225 src1 : ISS(read); 6226 src2 : ISS(read); 6227 src3 : ISS(read); 6228 INS01 : ISS; 6229 MAC : WR; 6230 %} 6231 6232 //------- Divide pipeline operations -------------------- 6233 6234 // Eg. SDIV w0, w1, w2 6235 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6236 %{ 6237 single_instruction; 6238 fixed_latency(8); // Maximum latency for 32 bit divide 6239 dst : WR(write); 6240 src1 : ISS(read); 6241 src2 : ISS(read); 6242 INS0 : ISS; // Can only dual issue as instruction 0 6243 DIV : WR; 6244 %} 6245 6246 // Eg. SDIV x0, x1, x2 6247 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6248 %{ 6249 single_instruction; 6250 fixed_latency(16); // Maximum latency for 64 bit divide 6251 dst : WR(write); 6252 src1 : ISS(read); 6253 src2 : ISS(read); 6254 INS0 : ISS; // Can only dual issue as instruction 0 6255 DIV : WR; 6256 %} 6257 6258 //------- Load pipeline operations ------------------------ 6259 6260 // Load - prefetch 6261 // Eg. PFRM <mem> 6262 pipe_class iload_prefetch(memory mem) 6263 %{ 6264 single_instruction; 6265 mem : ISS(read); 6266 INS01 : ISS; 6267 LDST : WR; 6268 %} 6269 6270 // Load - reg, mem 6271 // Eg. LDR x0, <mem> 6272 pipe_class iload_reg_mem(iRegI dst, memory mem) 6273 %{ 6274 single_instruction; 6275 dst : WR(write); 6276 mem : ISS(read); 6277 INS01 : ISS; 6278 LDST : WR; 6279 %} 6280 6281 // Load - reg, reg 6282 // Eg. LDR x0, [sp, x1] 6283 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6284 %{ 6285 single_instruction; 6286 dst : WR(write); 6287 src : ISS(read); 6288 INS01 : ISS; 6289 LDST : WR; 6290 %} 6291 6292 //------- Store pipeline operations ----------------------- 6293 6294 // Store - zr, mem 6295 // Eg. STR zr, <mem> 6296 pipe_class istore_mem(memory mem) 6297 %{ 6298 single_instruction; 6299 mem : ISS(read); 6300 INS01 : ISS; 6301 LDST : WR; 6302 %} 6303 6304 // Store - reg, mem 6305 // Eg. STR x0, <mem> 6306 pipe_class istore_reg_mem(iRegI src, memory mem) 6307 %{ 6308 single_instruction; 6309 mem : ISS(read); 6310 src : EX2(read); 6311 INS01 : ISS; 6312 LDST : WR; 6313 %} 6314 6315 // Store - reg, reg 6316 // Eg. STR x0, [sp, x1] 6317 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6318 %{ 6319 single_instruction; 6320 dst : ISS(read); 6321 src : EX2(read); 6322 INS01 : ISS; 6323 LDST : WR; 6324 %} 6325 6326 //------- Store pipeline operations ----------------------- 6327 6328 // Branch 6329 pipe_class pipe_branch() 6330 %{ 6331 single_instruction; 6332 INS01 : ISS; 6333 BRANCH : EX1; 6334 %} 6335 6336 // Conditional branch 6337 pipe_class pipe_branch_cond(rFlagsReg cr) 6338 %{ 6339 single_instruction; 6340 cr : EX1(read); 6341 INS01 : ISS; 6342 BRANCH : EX1; 6343 %} 6344 6345 // Compare & Branch 6346 // EG. CBZ/CBNZ 6347 pipe_class pipe_cmp_branch(iRegI op1) 6348 %{ 6349 single_instruction; 6350 op1 : EX1(read); 6351 INS01 : ISS; 6352 BRANCH : EX1; 6353 %} 6354 6355 //------- Synchronisation operations ---------------------- 6356 6357 // Any operation requiring serialization. 6358 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6359 pipe_class pipe_serial() 6360 %{ 6361 single_instruction; 6362 force_serialization; 6363 fixed_latency(16); 6364 INS01 : ISS(2); // Cannot dual issue with any other instruction 6365 LDST : WR; 6366 %} 6367 6368 // Generic big/slow expanded idiom - also serialized 6369 pipe_class pipe_slow() 6370 %{ 6371 instruction_count(10); 6372 multiple_bundles; 6373 force_serialization; 6374 fixed_latency(16); 6375 INS01 : ISS(2); // Cannot dual issue with any other instruction 6376 LDST : WR; 6377 %} 6378 6379 // Empty pipeline class 6380 pipe_class pipe_class_empty() 6381 %{ 6382 single_instruction; 6383 fixed_latency(0); 6384 %} 6385 6386 // Default pipeline class. 6387 pipe_class pipe_class_default() 6388 %{ 6389 single_instruction; 6390 fixed_latency(2); 6391 %} 6392 6393 // Pipeline class for compares. 6394 pipe_class pipe_class_compare() 6395 %{ 6396 single_instruction; 6397 fixed_latency(16); 6398 %} 6399 6400 // Pipeline class for memory operations. 6401 pipe_class pipe_class_memory() 6402 %{ 6403 single_instruction; 6404 fixed_latency(16); 6405 %} 6406 6407 // Pipeline class for call. 6408 pipe_class pipe_class_call() 6409 %{ 6410 single_instruction; 6411 fixed_latency(100); 6412 %} 6413 6414 // Define the class for the Nop node. 6415 define %{ 6416 MachNop = pipe_class_empty; 6417 %} 6418 6419 %} 6420 //----------INSTRUCTIONS------------------------------------------------------- 6421 // 6422 // match -- States which machine-independent subtree may be replaced 6423 // by this instruction. 6424 // ins_cost -- The estimated cost of this instruction is used by instruction 6425 // selection to identify a minimum cost tree of machine 6426 // instructions that matches a tree of machine-independent 6427 // instructions. 6428 // format -- A string providing the disassembly for this instruction. 6429 // The value of an instruction's operand may be inserted 6430 // by referring to it with a '$' prefix. 6431 // opcode -- Three instruction opcodes may be provided. These are referred 6432 // to within an encode class as $primary, $secondary, and $tertiary 6433 // rrspectively. The primary opcode is commonly used to 6434 // indicate the type of machine instruction, while secondary 6435 // and tertiary are often used for prefix options or addressing 6436 // modes. 6437 // ins_encode -- A list of encode classes with parameters. The encode class 6438 // name must have been defined in an 'enc_class' specification 6439 // in the encode section of the architecture description. 6440 6441 // ============================================================================ 6442 // Memory (Load/Store) Instructions 6443 6444 // Load Instructions 6445 6446 // Load Byte (8 bit signed) 6447 instruct loadB(iRegINoSp dst, memory mem) 6448 %{ 6449 match(Set dst (LoadB mem)); 6450 predicate(!needs_acquiring_load(n)); 6451 6452 ins_cost(4 * INSN_COST); 6453 format %{ "ldrsbw $dst, $mem\t# byte" %} 6454 6455 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6456 6457 ins_pipe(iload_reg_mem); 6458 %} 6459 6460 // Load Byte (8 bit signed) into long 6461 instruct loadB2L(iRegLNoSp dst, memory mem) 6462 %{ 6463 match(Set dst (ConvI2L (LoadB mem))); 6464 predicate(!needs_acquiring_load(n->in(1))); 6465 6466 ins_cost(4 * INSN_COST); 6467 format %{ "ldrsb $dst, $mem\t# byte" %} 6468 6469 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6470 6471 ins_pipe(iload_reg_mem); 6472 %} 6473 6474 // Load Byte (8 bit unsigned) 6475 instruct loadUB(iRegINoSp dst, memory mem) 6476 %{ 6477 match(Set dst (LoadUB mem)); 6478 predicate(!needs_acquiring_load(n)); 6479 6480 ins_cost(4 * INSN_COST); 6481 format %{ "ldrbw $dst, $mem\t# byte" %} 6482 6483 ins_encode(aarch64_enc_ldrb(dst, mem)); 6484 6485 ins_pipe(iload_reg_mem); 6486 %} 6487 6488 // Load Byte (8 bit unsigned) into long 6489 instruct loadUB2L(iRegLNoSp dst, memory mem) 6490 %{ 6491 match(Set dst (ConvI2L (LoadUB mem))); 6492 predicate(!needs_acquiring_load(n->in(1))); 6493 6494 ins_cost(4 * INSN_COST); 6495 format %{ "ldrb $dst, $mem\t# byte" %} 6496 6497 ins_encode(aarch64_enc_ldrb(dst, mem)); 6498 6499 ins_pipe(iload_reg_mem); 6500 %} 6501 6502 // Load Short (16 bit signed) 6503 instruct loadS(iRegINoSp dst, memory mem) 6504 %{ 6505 match(Set dst (LoadS mem)); 6506 predicate(!needs_acquiring_load(n)); 6507 6508 ins_cost(4 * INSN_COST); 6509 format %{ "ldrshw $dst, $mem\t# short" %} 6510 6511 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6512 6513 ins_pipe(iload_reg_mem); 6514 %} 6515 6516 // Load Short (16 bit signed) into long 6517 instruct loadS2L(iRegLNoSp dst, memory mem) 6518 %{ 6519 match(Set dst (ConvI2L (LoadS mem))); 6520 predicate(!needs_acquiring_load(n->in(1))); 6521 6522 ins_cost(4 * INSN_COST); 6523 format %{ "ldrsh $dst, $mem\t# short" %} 6524 6525 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6526 6527 ins_pipe(iload_reg_mem); 6528 %} 6529 6530 // Load Char (16 bit unsigned) 6531 instruct loadUS(iRegINoSp dst, memory mem) 6532 %{ 6533 match(Set dst (LoadUS mem)); 6534 predicate(!needs_acquiring_load(n)); 6535 6536 ins_cost(4 * INSN_COST); 6537 format %{ "ldrh $dst, $mem\t# short" %} 6538 6539 ins_encode(aarch64_enc_ldrh(dst, mem)); 6540 6541 ins_pipe(iload_reg_mem); 6542 %} 6543 6544 // Load Short/Char (16 bit unsigned) into long 6545 instruct loadUS2L(iRegLNoSp dst, memory mem) 6546 %{ 6547 match(Set dst (ConvI2L (LoadUS mem))); 6548 predicate(!needs_acquiring_load(n->in(1))); 6549 6550 ins_cost(4 * INSN_COST); 6551 format %{ "ldrh $dst, $mem\t# short" %} 6552 6553 ins_encode(aarch64_enc_ldrh(dst, mem)); 6554 6555 ins_pipe(iload_reg_mem); 6556 %} 6557 6558 // Load Integer (32 bit signed) 6559 instruct loadI(iRegINoSp dst, memory mem) 6560 %{ 6561 match(Set dst (LoadI mem)); 6562 predicate(!needs_acquiring_load(n)); 6563 6564 ins_cost(4 * INSN_COST); 6565 format %{ "ldrw $dst, $mem\t# int" %} 6566 6567 ins_encode(aarch64_enc_ldrw(dst, mem)); 6568 6569 ins_pipe(iload_reg_mem); 6570 %} 6571 6572 // Load Integer (32 bit signed) into long 6573 instruct loadI2L(iRegLNoSp dst, memory mem) 6574 %{ 6575 match(Set dst (ConvI2L (LoadI mem))); 6576 predicate(!needs_acquiring_load(n->in(1))); 6577 6578 ins_cost(4 * INSN_COST); 6579 format %{ "ldrsw $dst, $mem\t# int" %} 6580 6581 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6582 6583 ins_pipe(iload_reg_mem); 6584 %} 6585 6586 // Load Integer (32 bit unsigned) into long 6587 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6588 %{ 6589 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6590 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6591 6592 ins_cost(4 * INSN_COST); 6593 format %{ "ldrw $dst, $mem\t# int" %} 6594 6595 ins_encode(aarch64_enc_ldrw(dst, mem)); 6596 6597 ins_pipe(iload_reg_mem); 6598 %} 6599 6600 // Load Long (64 bit signed) 6601 instruct loadL(iRegLNoSp dst, memory mem) 6602 %{ 6603 match(Set dst (LoadL mem)); 6604 predicate(!needs_acquiring_load(n)); 6605 6606 ins_cost(4 * INSN_COST); 6607 format %{ "ldr $dst, $mem\t# int" %} 6608 6609 ins_encode(aarch64_enc_ldr(dst, mem)); 6610 6611 ins_pipe(iload_reg_mem); 6612 %} 6613 6614 // Load Range 6615 instruct loadRange(iRegINoSp dst, memory mem) 6616 %{ 6617 match(Set dst (LoadRange mem)); 6618 6619 ins_cost(4 * INSN_COST); 6620 format %{ "ldrw $dst, $mem\t# range" %} 6621 6622 ins_encode(aarch64_enc_ldrw(dst, mem)); 6623 6624 ins_pipe(iload_reg_mem); 6625 %} 6626 6627 // Load Pointer 6628 instruct loadP(iRegPNoSp dst, memory mem) 6629 %{ 6630 match(Set dst (LoadP mem)); 6631 predicate(!needs_acquiring_load(n)); 6632 6633 ins_cost(4 * INSN_COST); 6634 format %{ "ldr $dst, $mem\t# ptr" %} 6635 6636 ins_encode(aarch64_enc_ldr(dst, mem)); 6637 6638 ins_pipe(iload_reg_mem); 6639 %} 6640 6641 // Load Compressed Pointer 6642 instruct loadN(iRegNNoSp dst, memory mem) 6643 %{ 6644 match(Set dst (LoadN mem)); 6645 predicate(!needs_acquiring_load(n)); 6646 6647 ins_cost(4 * INSN_COST); 6648 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6649 6650 ins_encode(aarch64_enc_ldrw(dst, mem)); 6651 6652 ins_pipe(iload_reg_mem); 6653 %} 6654 6655 // Load Klass Pointer 6656 instruct loadKlass(iRegPNoSp dst, memory mem) 6657 %{ 6658 match(Set dst (LoadKlass mem)); 6659 predicate(!needs_acquiring_load(n)); 6660 6661 ins_cost(4 * INSN_COST); 6662 format %{ "ldr $dst, $mem\t# class" %} 6663 6664 ins_encode(aarch64_enc_ldr(dst, mem)); 6665 6666 ins_pipe(iload_reg_mem); 6667 %} 6668 6669 // Load Narrow Klass Pointer 6670 instruct loadNKlass(iRegNNoSp dst, memory mem) 6671 %{ 6672 match(Set dst (LoadNKlass mem)); 6673 predicate(!needs_acquiring_load(n)); 6674 6675 ins_cost(4 * INSN_COST); 6676 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6677 6678 ins_encode(aarch64_enc_ldrw(dst, mem)); 6679 6680 ins_pipe(iload_reg_mem); 6681 %} 6682 6683 // Load Float 6684 instruct loadF(vRegF dst, memory mem) 6685 %{ 6686 match(Set dst (LoadF mem)); 6687 predicate(!needs_acquiring_load(n)); 6688 6689 ins_cost(4 * INSN_COST); 6690 format %{ "ldrs $dst, $mem\t# float" %} 6691 6692 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6693 6694 ins_pipe(pipe_class_memory); 6695 %} 6696 6697 // Load Double 6698 instruct loadD(vRegD dst, memory mem) 6699 %{ 6700 match(Set dst (LoadD mem)); 6701 predicate(!needs_acquiring_load(n)); 6702 6703 ins_cost(4 * INSN_COST); 6704 format %{ "ldrd $dst, $mem\t# double" %} 6705 6706 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6707 6708 ins_pipe(pipe_class_memory); 6709 %} 6710 6711 6712 // Load Int Constant 6713 instruct loadConI(iRegINoSp dst, immI src) 6714 %{ 6715 match(Set dst src); 6716 6717 ins_cost(INSN_COST); 6718 format %{ "mov $dst, $src\t# int" %} 6719 6720 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6721 6722 ins_pipe(ialu_imm); 6723 %} 6724 6725 // Load Long Constant 6726 instruct loadConL(iRegLNoSp dst, immL src) 6727 %{ 6728 match(Set dst src); 6729 6730 ins_cost(INSN_COST); 6731 format %{ "mov $dst, $src\t# long" %} 6732 6733 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6734 6735 ins_pipe(ialu_imm); 6736 %} 6737 6738 // Load Pointer Constant 6739 6740 instruct loadConP(iRegPNoSp dst, immP con) 6741 %{ 6742 match(Set dst con); 6743 6744 ins_cost(INSN_COST * 4); 6745 format %{ 6746 "mov $dst, $con\t# ptr\n\t" 6747 %} 6748 6749 ins_encode(aarch64_enc_mov_p(dst, con)); 6750 6751 ins_pipe(ialu_imm); 6752 %} 6753 6754 // Load Null Pointer Constant 6755 6756 instruct loadConP0(iRegPNoSp dst, immP0 con) 6757 %{ 6758 match(Set dst con); 6759 6760 ins_cost(INSN_COST); 6761 format %{ "mov $dst, $con\t# NULL ptr" %} 6762 6763 ins_encode(aarch64_enc_mov_p0(dst, con)); 6764 6765 ins_pipe(ialu_imm); 6766 %} 6767 6768 // Load Pointer Constant One 6769 6770 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6771 %{ 6772 match(Set dst con); 6773 6774 ins_cost(INSN_COST); 6775 format %{ "mov $dst, $con\t# NULL ptr" %} 6776 6777 ins_encode(aarch64_enc_mov_p1(dst, con)); 6778 6779 ins_pipe(ialu_imm); 6780 %} 6781 6782 // Load Poll Page Constant 6783 6784 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6785 %{ 6786 match(Set dst con); 6787 6788 ins_cost(INSN_COST); 6789 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6790 6791 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6792 6793 ins_pipe(ialu_imm); 6794 %} 6795 6796 // Load Byte Map Base Constant 6797 6798 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6799 %{ 6800 match(Set dst con); 6801 6802 ins_cost(INSN_COST); 6803 format %{ "adr $dst, $con\t# Byte Map Base" %} 6804 6805 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6806 6807 ins_pipe(ialu_imm); 6808 %} 6809 6810 // Load Narrow Pointer Constant 6811 6812 instruct loadConN(iRegNNoSp dst, immN con) 6813 %{ 6814 match(Set dst con); 6815 6816 ins_cost(INSN_COST * 4); 6817 format %{ "mov $dst, $con\t# compressed ptr" %} 6818 6819 ins_encode(aarch64_enc_mov_n(dst, con)); 6820 6821 ins_pipe(ialu_imm); 6822 %} 6823 6824 // Load Narrow Null Pointer Constant 6825 6826 instruct loadConN0(iRegNNoSp dst, immN0 con) 6827 %{ 6828 match(Set dst con); 6829 6830 ins_cost(INSN_COST); 6831 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6832 6833 ins_encode(aarch64_enc_mov_n0(dst, con)); 6834 6835 ins_pipe(ialu_imm); 6836 %} 6837 6838 // Load Narrow Klass Constant 6839 6840 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6841 %{ 6842 match(Set dst con); 6843 6844 ins_cost(INSN_COST); 6845 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6846 6847 ins_encode(aarch64_enc_mov_nk(dst, con)); 6848 6849 ins_pipe(ialu_imm); 6850 %} 6851 6852 // Load Packed Float Constant 6853 6854 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6855 match(Set dst con); 6856 ins_cost(INSN_COST * 4); 6857 format %{ "fmovs $dst, $con"%} 6858 ins_encode %{ 6859 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6860 %} 6861 6862 ins_pipe(fp_imm_s); 6863 %} 6864 6865 // Load Float Constant 6866 6867 instruct loadConF(vRegF dst, immF con) %{ 6868 match(Set dst con); 6869 6870 ins_cost(INSN_COST * 4); 6871 6872 format %{ 6873 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6874 %} 6875 6876 ins_encode %{ 6877 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6878 %} 6879 6880 ins_pipe(fp_load_constant_s); 6881 %} 6882 6883 // Load Packed Double Constant 6884 6885 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6886 match(Set dst con); 6887 ins_cost(INSN_COST); 6888 format %{ "fmovd $dst, $con"%} 6889 ins_encode %{ 6890 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6891 %} 6892 6893 ins_pipe(fp_imm_d); 6894 %} 6895 6896 // Load Double Constant 6897 6898 instruct loadConD(vRegD dst, immD con) %{ 6899 match(Set dst con); 6900 6901 ins_cost(INSN_COST * 5); 6902 format %{ 6903 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6904 %} 6905 6906 ins_encode %{ 6907 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6908 %} 6909 6910 ins_pipe(fp_load_constant_d); 6911 %} 6912 6913 // Store Instructions 6914 6915 // Store CMS card-mark Immediate 6916 instruct storeimmCM0(immI0 zero, memory mem) 6917 %{ 6918 match(Set mem (StoreCM mem zero)); 6919 predicate(unnecessary_storestore(n)); 6920 6921 ins_cost(INSN_COST); 6922 format %{ "storestore (elided)\n\t" 6923 "strb zr, $mem\t# byte" %} 6924 6925 ins_encode(aarch64_enc_strb0(mem)); 6926 6927 ins_pipe(istore_mem); 6928 %} 6929 6930 // Store CMS card-mark Immediate with intervening StoreStore 6931 // needed when using CMS with no conditional card marking 6932 instruct storeimmCM0_ordered(immI0 zero, memory mem) 6933 %{ 6934 match(Set mem (StoreCM mem zero)); 6935 6936 ins_cost(INSN_COST * 2); 6937 format %{ "storestore\n\t" 6938 "dmb ishst" 6939 "\n\tstrb zr, $mem\t# byte" %} 6940 6941 ins_encode(aarch64_enc_strb0_ordered(mem)); 6942 6943 ins_pipe(istore_mem); 6944 %} 6945 6946 // Store Byte 6947 instruct storeB(iRegIorL2I src, memory mem) 6948 %{ 6949 match(Set mem (StoreB mem src)); 6950 predicate(!needs_releasing_store(n)); 6951 6952 ins_cost(INSN_COST); 6953 format %{ "strb $src, $mem\t# byte" %} 6954 6955 ins_encode(aarch64_enc_strb(src, mem)); 6956 6957 ins_pipe(istore_reg_mem); 6958 %} 6959 6960 6961 instruct storeimmB0(immI0 zero, memory mem) 6962 %{ 6963 match(Set mem (StoreB mem zero)); 6964 predicate(!needs_releasing_store(n)); 6965 6966 ins_cost(INSN_COST); 6967 format %{ "strb rscractch2, $mem\t# byte" %} 6968 6969 ins_encode(aarch64_enc_strb0(mem)); 6970 6971 ins_pipe(istore_mem); 6972 %} 6973 6974 // Store Char/Short 6975 instruct storeC(iRegIorL2I src, memory mem) 6976 %{ 6977 match(Set mem (StoreC mem src)); 6978 predicate(!needs_releasing_store(n)); 6979 6980 ins_cost(INSN_COST); 6981 format %{ "strh $src, $mem\t# short" %} 6982 6983 ins_encode(aarch64_enc_strh(src, mem)); 6984 6985 ins_pipe(istore_reg_mem); 6986 %} 6987 6988 instruct storeimmC0(immI0 zero, memory mem) 6989 %{ 6990 match(Set mem (StoreC mem zero)); 6991 predicate(!needs_releasing_store(n)); 6992 6993 ins_cost(INSN_COST); 6994 format %{ "strh zr, $mem\t# short" %} 6995 6996 ins_encode(aarch64_enc_strh0(mem)); 6997 6998 ins_pipe(istore_mem); 6999 %} 7000 7001 // Store Integer 7002 7003 instruct storeI(iRegIorL2I src, memory mem) 7004 %{ 7005 match(Set mem(StoreI mem src)); 7006 predicate(!needs_releasing_store(n)); 7007 7008 ins_cost(INSN_COST); 7009 format %{ "strw $src, $mem\t# int" %} 7010 7011 ins_encode(aarch64_enc_strw(src, mem)); 7012 7013 ins_pipe(istore_reg_mem); 7014 %} 7015 7016 instruct storeimmI0(immI0 zero, memory mem) 7017 %{ 7018 match(Set mem(StoreI mem zero)); 7019 predicate(!needs_releasing_store(n)); 7020 7021 ins_cost(INSN_COST); 7022 format %{ "strw zr, $mem\t# int" %} 7023 7024 ins_encode(aarch64_enc_strw0(mem)); 7025 7026 ins_pipe(istore_mem); 7027 %} 7028 7029 // Store Long (64 bit signed) 7030 instruct storeL(iRegL src, memory mem) 7031 %{ 7032 match(Set mem (StoreL mem src)); 7033 predicate(!needs_releasing_store(n)); 7034 7035 ins_cost(INSN_COST); 7036 format %{ "str $src, $mem\t# int" %} 7037 7038 ins_encode(aarch64_enc_str(src, mem)); 7039 7040 ins_pipe(istore_reg_mem); 7041 %} 7042 7043 // Store Long (64 bit signed) 7044 instruct storeimmL0(immL0 zero, memory mem) 7045 %{ 7046 match(Set mem (StoreL mem zero)); 7047 predicate(!needs_releasing_store(n)); 7048 7049 ins_cost(INSN_COST); 7050 format %{ "str zr, $mem\t# int" %} 7051 7052 ins_encode(aarch64_enc_str0(mem)); 7053 7054 ins_pipe(istore_mem); 7055 %} 7056 7057 // Store Pointer 7058 instruct storeP(iRegP src, memory mem) 7059 %{ 7060 match(Set mem (StoreP mem src)); 7061 predicate(!needs_releasing_store(n)); 7062 7063 ins_cost(INSN_COST); 7064 format %{ "str $src, $mem\t# ptr" %} 7065 7066 ins_encode(aarch64_enc_str(src, mem)); 7067 7068 ins_pipe(istore_reg_mem); 7069 %} 7070 7071 // Store Pointer 7072 instruct storeimmP0(immP0 zero, memory mem) 7073 %{ 7074 match(Set mem (StoreP mem zero)); 7075 predicate(!needs_releasing_store(n)); 7076 7077 ins_cost(INSN_COST); 7078 format %{ "str zr, $mem\t# ptr" %} 7079 7080 ins_encode(aarch64_enc_str0(mem)); 7081 7082 ins_pipe(istore_mem); 7083 %} 7084 7085 // Store Compressed Pointer 7086 instruct storeN(iRegN src, memory mem) 7087 %{ 7088 match(Set mem (StoreN mem src)); 7089 predicate(!needs_releasing_store(n)); 7090 7091 ins_cost(INSN_COST); 7092 format %{ "strw $src, $mem\t# compressed ptr" %} 7093 7094 ins_encode(aarch64_enc_strw(src, mem)); 7095 7096 ins_pipe(istore_reg_mem); 7097 %} 7098 7099 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7100 %{ 7101 match(Set mem (StoreN mem zero)); 7102 predicate(Universe::narrow_oop_base() == NULL && 7103 Universe::narrow_klass_base() == NULL && 7104 (!needs_releasing_store(n))); 7105 7106 ins_cost(INSN_COST); 7107 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7108 7109 ins_encode(aarch64_enc_strw(heapbase, mem)); 7110 7111 ins_pipe(istore_reg_mem); 7112 %} 7113 7114 // Store Float 7115 instruct storeF(vRegF src, memory mem) 7116 %{ 7117 match(Set mem (StoreF mem src)); 7118 predicate(!needs_releasing_store(n)); 7119 7120 ins_cost(INSN_COST); 7121 format %{ "strs $src, $mem\t# float" %} 7122 7123 ins_encode( aarch64_enc_strs(src, mem) ); 7124 7125 ins_pipe(pipe_class_memory); 7126 %} 7127 7128 // TODO 7129 // implement storeImmF0 and storeFImmPacked 7130 7131 // Store Double 7132 instruct storeD(vRegD src, memory mem) 7133 %{ 7134 match(Set mem (StoreD mem src)); 7135 predicate(!needs_releasing_store(n)); 7136 7137 ins_cost(INSN_COST); 7138 format %{ "strd $src, $mem\t# double" %} 7139 7140 ins_encode( aarch64_enc_strd(src, mem) ); 7141 7142 ins_pipe(pipe_class_memory); 7143 %} 7144 7145 // Store Compressed Klass Pointer 7146 instruct storeNKlass(iRegN src, memory mem) 7147 %{ 7148 predicate(!needs_releasing_store(n)); 7149 match(Set mem (StoreNKlass mem src)); 7150 7151 ins_cost(INSN_COST); 7152 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7153 7154 ins_encode(aarch64_enc_strw(src, mem)); 7155 7156 ins_pipe(istore_reg_mem); 7157 %} 7158 7159 // TODO 7160 // implement storeImmD0 and storeDImmPacked 7161 7162 // prefetch instructions 7163 // Must be safe to execute with invalid address (cannot fault). 7164 7165 instruct prefetchalloc( memory mem ) %{ 7166 match(PrefetchAllocation mem); 7167 7168 ins_cost(INSN_COST); 7169 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7170 7171 ins_encode( aarch64_enc_prefetchw(mem) ); 7172 7173 ins_pipe(iload_prefetch); 7174 %} 7175 7176 // ---------------- volatile loads and stores ---------------- 7177 7178 // Load Byte (8 bit signed) 7179 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7180 %{ 7181 match(Set dst (LoadB mem)); 7182 7183 ins_cost(VOLATILE_REF_COST); 7184 format %{ "ldarsb $dst, $mem\t# byte" %} 7185 7186 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7187 7188 ins_pipe(pipe_serial); 7189 %} 7190 7191 // Load Byte (8 bit signed) into long 7192 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7193 %{ 7194 match(Set dst (ConvI2L (LoadB mem))); 7195 7196 ins_cost(VOLATILE_REF_COST); 7197 format %{ "ldarsb $dst, $mem\t# byte" %} 7198 7199 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7200 7201 ins_pipe(pipe_serial); 7202 %} 7203 7204 // Load Byte (8 bit unsigned) 7205 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7206 %{ 7207 match(Set dst (LoadUB mem)); 7208 7209 ins_cost(VOLATILE_REF_COST); 7210 format %{ "ldarb $dst, $mem\t# byte" %} 7211 7212 ins_encode(aarch64_enc_ldarb(dst, mem)); 7213 7214 ins_pipe(pipe_serial); 7215 %} 7216 7217 // Load Byte (8 bit unsigned) into long 7218 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7219 %{ 7220 match(Set dst (ConvI2L (LoadUB mem))); 7221 7222 ins_cost(VOLATILE_REF_COST); 7223 format %{ "ldarb $dst, $mem\t# byte" %} 7224 7225 ins_encode(aarch64_enc_ldarb(dst, mem)); 7226 7227 ins_pipe(pipe_serial); 7228 %} 7229 7230 // Load Short (16 bit signed) 7231 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7232 %{ 7233 match(Set dst (LoadS mem)); 7234 7235 ins_cost(VOLATILE_REF_COST); 7236 format %{ "ldarshw $dst, $mem\t# short" %} 7237 7238 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7239 7240 ins_pipe(pipe_serial); 7241 %} 7242 7243 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7244 %{ 7245 match(Set dst (LoadUS mem)); 7246 7247 ins_cost(VOLATILE_REF_COST); 7248 format %{ "ldarhw $dst, $mem\t# short" %} 7249 7250 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7251 7252 ins_pipe(pipe_serial); 7253 %} 7254 7255 // Load Short/Char (16 bit unsigned) into long 7256 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7257 %{ 7258 match(Set dst (ConvI2L (LoadUS mem))); 7259 7260 ins_cost(VOLATILE_REF_COST); 7261 format %{ "ldarh $dst, $mem\t# short" %} 7262 7263 ins_encode(aarch64_enc_ldarh(dst, mem)); 7264 7265 ins_pipe(pipe_serial); 7266 %} 7267 7268 // Load Short/Char (16 bit signed) into long 7269 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7270 %{ 7271 match(Set dst (ConvI2L (LoadS mem))); 7272 7273 ins_cost(VOLATILE_REF_COST); 7274 format %{ "ldarh $dst, $mem\t# short" %} 7275 7276 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7277 7278 ins_pipe(pipe_serial); 7279 %} 7280 7281 // Load Integer (32 bit signed) 7282 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7283 %{ 7284 match(Set dst (LoadI mem)); 7285 7286 ins_cost(VOLATILE_REF_COST); 7287 format %{ "ldarw $dst, $mem\t# int" %} 7288 7289 ins_encode(aarch64_enc_ldarw(dst, mem)); 7290 7291 ins_pipe(pipe_serial); 7292 %} 7293 7294 // Load Integer (32 bit unsigned) into long 7295 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7296 %{ 7297 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7298 7299 ins_cost(VOLATILE_REF_COST); 7300 format %{ "ldarw $dst, $mem\t# int" %} 7301 7302 ins_encode(aarch64_enc_ldarw(dst, mem)); 7303 7304 ins_pipe(pipe_serial); 7305 %} 7306 7307 // Load Long (64 bit signed) 7308 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7309 %{ 7310 match(Set dst (LoadL mem)); 7311 7312 ins_cost(VOLATILE_REF_COST); 7313 format %{ "ldar $dst, $mem\t# int" %} 7314 7315 ins_encode(aarch64_enc_ldar(dst, mem)); 7316 7317 ins_pipe(pipe_serial); 7318 %} 7319 7320 // Load Pointer 7321 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7322 %{ 7323 match(Set dst (LoadP mem)); 7324 7325 ins_cost(VOLATILE_REF_COST); 7326 format %{ "ldar $dst, $mem\t# ptr" %} 7327 7328 ins_encode(aarch64_enc_ldar(dst, mem)); 7329 7330 ins_pipe(pipe_serial); 7331 %} 7332 7333 // Load Compressed Pointer 7334 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7335 %{ 7336 match(Set dst (LoadN mem)); 7337 7338 ins_cost(VOLATILE_REF_COST); 7339 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7340 7341 ins_encode(aarch64_enc_ldarw(dst, mem)); 7342 7343 ins_pipe(pipe_serial); 7344 %} 7345 7346 // Load Float 7347 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7348 %{ 7349 match(Set dst (LoadF mem)); 7350 7351 ins_cost(VOLATILE_REF_COST); 7352 format %{ "ldars $dst, $mem\t# float" %} 7353 7354 ins_encode( aarch64_enc_fldars(dst, mem) ); 7355 7356 ins_pipe(pipe_serial); 7357 %} 7358 7359 // Load Double 7360 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7361 %{ 7362 match(Set dst (LoadD mem)); 7363 7364 ins_cost(VOLATILE_REF_COST); 7365 format %{ "ldard $dst, $mem\t# double" %} 7366 7367 ins_encode( aarch64_enc_fldard(dst, mem) ); 7368 7369 ins_pipe(pipe_serial); 7370 %} 7371 7372 // Store Byte 7373 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7374 %{ 7375 match(Set mem (StoreB mem src)); 7376 7377 ins_cost(VOLATILE_REF_COST); 7378 format %{ "stlrb $src, $mem\t# byte" %} 7379 7380 ins_encode(aarch64_enc_stlrb(src, mem)); 7381 7382 ins_pipe(pipe_class_memory); 7383 %} 7384 7385 // Store Char/Short 7386 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7387 %{ 7388 match(Set mem (StoreC mem src)); 7389 7390 ins_cost(VOLATILE_REF_COST); 7391 format %{ "stlrh $src, $mem\t# short" %} 7392 7393 ins_encode(aarch64_enc_stlrh(src, mem)); 7394 7395 ins_pipe(pipe_class_memory); 7396 %} 7397 7398 // Store Integer 7399 7400 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7401 %{ 7402 match(Set mem(StoreI mem src)); 7403 7404 ins_cost(VOLATILE_REF_COST); 7405 format %{ "stlrw $src, $mem\t# int" %} 7406 7407 ins_encode(aarch64_enc_stlrw(src, mem)); 7408 7409 ins_pipe(pipe_class_memory); 7410 %} 7411 7412 // Store Long (64 bit signed) 7413 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7414 %{ 7415 match(Set mem (StoreL mem src)); 7416 7417 ins_cost(VOLATILE_REF_COST); 7418 format %{ "stlr $src, $mem\t# int" %} 7419 7420 ins_encode(aarch64_enc_stlr(src, mem)); 7421 7422 ins_pipe(pipe_class_memory); 7423 %} 7424 7425 // Store Pointer 7426 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7427 %{ 7428 match(Set mem (StoreP mem src)); 7429 7430 ins_cost(VOLATILE_REF_COST); 7431 format %{ "stlr $src, $mem\t# ptr" %} 7432 7433 ins_encode(aarch64_enc_stlr(src, mem)); 7434 7435 ins_pipe(pipe_class_memory); 7436 %} 7437 7438 // Store Compressed Pointer 7439 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7440 %{ 7441 match(Set mem (StoreN mem src)); 7442 7443 ins_cost(VOLATILE_REF_COST); 7444 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7445 7446 ins_encode(aarch64_enc_stlrw(src, mem)); 7447 7448 ins_pipe(pipe_class_memory); 7449 %} 7450 7451 // Store Float 7452 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7453 %{ 7454 match(Set mem (StoreF mem src)); 7455 7456 ins_cost(VOLATILE_REF_COST); 7457 format %{ "stlrs $src, $mem\t# float" %} 7458 7459 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7460 7461 ins_pipe(pipe_class_memory); 7462 %} 7463 7464 // TODO 7465 // implement storeImmF0 and storeFImmPacked 7466 7467 // Store Double 7468 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7469 %{ 7470 match(Set mem (StoreD mem src)); 7471 7472 ins_cost(VOLATILE_REF_COST); 7473 format %{ "stlrd $src, $mem\t# double" %} 7474 7475 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7476 7477 ins_pipe(pipe_class_memory); 7478 %} 7479 7480 // ---------------- end of volatile loads and stores ---------------- 7481 7482 // ============================================================================ 7483 // BSWAP Instructions 7484 7485 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7486 match(Set dst (ReverseBytesI src)); 7487 7488 ins_cost(INSN_COST); 7489 format %{ "revw $dst, $src" %} 7490 7491 ins_encode %{ 7492 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7493 %} 7494 7495 ins_pipe(ialu_reg); 7496 %} 7497 7498 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7499 match(Set dst (ReverseBytesL src)); 7500 7501 ins_cost(INSN_COST); 7502 format %{ "rev $dst, $src" %} 7503 7504 ins_encode %{ 7505 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7506 %} 7507 7508 ins_pipe(ialu_reg); 7509 %} 7510 7511 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7512 match(Set dst (ReverseBytesUS src)); 7513 7514 ins_cost(INSN_COST); 7515 format %{ "rev16w $dst, $src" %} 7516 7517 ins_encode %{ 7518 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7519 %} 7520 7521 ins_pipe(ialu_reg); 7522 %} 7523 7524 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7525 match(Set dst (ReverseBytesS src)); 7526 7527 ins_cost(INSN_COST); 7528 format %{ "rev16w $dst, $src\n\t" 7529 "sbfmw $dst, $dst, #0, #15" %} 7530 7531 ins_encode %{ 7532 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7533 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7534 %} 7535 7536 ins_pipe(ialu_reg); 7537 %} 7538 7539 // ============================================================================ 7540 // Zero Count Instructions 7541 7542 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7543 match(Set dst (CountLeadingZerosI src)); 7544 7545 ins_cost(INSN_COST); 7546 format %{ "clzw $dst, $src" %} 7547 ins_encode %{ 7548 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7549 %} 7550 7551 ins_pipe(ialu_reg); 7552 %} 7553 7554 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7555 match(Set dst (CountLeadingZerosL src)); 7556 7557 ins_cost(INSN_COST); 7558 format %{ "clz $dst, $src" %} 7559 ins_encode %{ 7560 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7561 %} 7562 7563 ins_pipe(ialu_reg); 7564 %} 7565 7566 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7567 match(Set dst (CountTrailingZerosI src)); 7568 7569 ins_cost(INSN_COST * 2); 7570 format %{ "rbitw $dst, $src\n\t" 7571 "clzw $dst, $dst" %} 7572 ins_encode %{ 7573 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7574 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7575 %} 7576 7577 ins_pipe(ialu_reg); 7578 %} 7579 7580 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7581 match(Set dst (CountTrailingZerosL src)); 7582 7583 ins_cost(INSN_COST * 2); 7584 format %{ "rbit $dst, $src\n\t" 7585 "clz $dst, $dst" %} 7586 ins_encode %{ 7587 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7588 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7589 %} 7590 7591 ins_pipe(ialu_reg); 7592 %} 7593 7594 //---------- Population Count Instructions ------------------------------------- 7595 // 7596 7597 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7598 predicate(UsePopCountInstruction); 7599 match(Set dst (PopCountI src)); 7600 effect(TEMP tmp); 7601 ins_cost(INSN_COST * 13); 7602 7603 format %{ "movw $src, $src\n\t" 7604 "mov $tmp, $src\t# vector (1D)\n\t" 7605 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7606 "addv $tmp, $tmp\t# vector (8B)\n\t" 7607 "mov $dst, $tmp\t# vector (1D)" %} 7608 ins_encode %{ 7609 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7610 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7611 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7612 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7613 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7614 %} 7615 7616 ins_pipe(pipe_class_default); 7617 %} 7618 7619 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7620 predicate(UsePopCountInstruction); 7621 match(Set dst (PopCountI (LoadI mem))); 7622 effect(TEMP tmp); 7623 ins_cost(INSN_COST * 13); 7624 7625 format %{ "ldrs $tmp, $mem\n\t" 7626 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7627 "addv $tmp, $tmp\t# vector (8B)\n\t" 7628 "mov $dst, $tmp\t# vector (1D)" %} 7629 ins_encode %{ 7630 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7631 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7632 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7633 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7634 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7635 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7636 %} 7637 7638 ins_pipe(pipe_class_default); 7639 %} 7640 7641 // Note: Long.bitCount(long) returns an int. 7642 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7643 predicate(UsePopCountInstruction); 7644 match(Set dst (PopCountL src)); 7645 effect(TEMP tmp); 7646 ins_cost(INSN_COST * 13); 7647 7648 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7649 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7650 "addv $tmp, $tmp\t# vector (8B)\n\t" 7651 "mov $dst, $tmp\t# vector (1D)" %} 7652 ins_encode %{ 7653 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7654 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7655 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7656 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7657 %} 7658 7659 ins_pipe(pipe_class_default); 7660 %} 7661 7662 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7663 predicate(UsePopCountInstruction); 7664 match(Set dst (PopCountL (LoadL mem))); 7665 effect(TEMP tmp); 7666 ins_cost(INSN_COST * 13); 7667 7668 format %{ "ldrd $tmp, $mem\n\t" 7669 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7670 "addv $tmp, $tmp\t# vector (8B)\n\t" 7671 "mov $dst, $tmp\t# vector (1D)" %} 7672 ins_encode %{ 7673 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7674 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7675 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7676 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7677 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7678 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7679 %} 7680 7681 ins_pipe(pipe_class_default); 7682 %} 7683 7684 // ============================================================================ 7685 // MemBar Instruction 7686 7687 instruct load_fence() %{ 7688 match(LoadFence); 7689 ins_cost(VOLATILE_REF_COST); 7690 7691 format %{ "load_fence" %} 7692 7693 ins_encode %{ 7694 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7695 %} 7696 ins_pipe(pipe_serial); 7697 %} 7698 7699 instruct unnecessary_membar_acquire() %{ 7700 predicate(unnecessary_acquire(n)); 7701 match(MemBarAcquire); 7702 ins_cost(0); 7703 7704 format %{ "membar_acquire (elided)" %} 7705 7706 ins_encode %{ 7707 __ block_comment("membar_acquire (elided)"); 7708 %} 7709 7710 ins_pipe(pipe_class_empty); 7711 %} 7712 7713 instruct membar_acquire() %{ 7714 match(MemBarAcquire); 7715 ins_cost(VOLATILE_REF_COST); 7716 7717 format %{ "membar_acquire\n\t" 7718 "dmb ish" %} 7719 7720 ins_encode %{ 7721 __ block_comment("membar_acquire"); 7722 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7723 %} 7724 7725 ins_pipe(pipe_serial); 7726 %} 7727 7728 7729 instruct membar_acquire_lock() %{ 7730 match(MemBarAcquireLock); 7731 ins_cost(VOLATILE_REF_COST); 7732 7733 format %{ "membar_acquire_lock (elided)" %} 7734 7735 ins_encode %{ 7736 __ block_comment("membar_acquire_lock (elided)"); 7737 %} 7738 7739 ins_pipe(pipe_serial); 7740 %} 7741 7742 instruct store_fence() %{ 7743 match(StoreFence); 7744 ins_cost(VOLATILE_REF_COST); 7745 7746 format %{ "store_fence" %} 7747 7748 ins_encode %{ 7749 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7750 %} 7751 ins_pipe(pipe_serial); 7752 %} 7753 7754 instruct unnecessary_membar_release() %{ 7755 predicate(unnecessary_release(n)); 7756 match(MemBarRelease); 7757 ins_cost(0); 7758 7759 format %{ "membar_release (elided)" %} 7760 7761 ins_encode %{ 7762 __ block_comment("membar_release (elided)"); 7763 %} 7764 ins_pipe(pipe_serial); 7765 %} 7766 7767 instruct membar_release() %{ 7768 match(MemBarRelease); 7769 ins_cost(VOLATILE_REF_COST); 7770 7771 format %{ "membar_release\n\t" 7772 "dmb ish" %} 7773 7774 ins_encode %{ 7775 __ block_comment("membar_release"); 7776 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7777 %} 7778 ins_pipe(pipe_serial); 7779 %} 7780 7781 instruct membar_storestore() %{ 7782 match(MemBarStoreStore); 7783 ins_cost(VOLATILE_REF_COST); 7784 7785 format %{ "MEMBAR-store-store" %} 7786 7787 ins_encode %{ 7788 __ membar(Assembler::StoreStore); 7789 %} 7790 ins_pipe(pipe_serial); 7791 %} 7792 7793 instruct membar_release_lock() %{ 7794 match(MemBarReleaseLock); 7795 ins_cost(VOLATILE_REF_COST); 7796 7797 format %{ "membar_release_lock (elided)" %} 7798 7799 ins_encode %{ 7800 __ block_comment("membar_release_lock (elided)"); 7801 %} 7802 7803 ins_pipe(pipe_serial); 7804 %} 7805 7806 instruct unnecessary_membar_volatile() %{ 7807 predicate(unnecessary_volatile(n)); 7808 match(MemBarVolatile); 7809 ins_cost(0); 7810 7811 format %{ "membar_volatile (elided)" %} 7812 7813 ins_encode %{ 7814 __ block_comment("membar_volatile (elided)"); 7815 %} 7816 7817 ins_pipe(pipe_serial); 7818 %} 7819 7820 instruct membar_volatile() %{ 7821 match(MemBarVolatile); 7822 ins_cost(VOLATILE_REF_COST*100); 7823 7824 format %{ "membar_volatile\n\t" 7825 "dmb ish"%} 7826 7827 ins_encode %{ 7828 __ block_comment("membar_volatile"); 7829 __ membar(Assembler::StoreLoad); 7830 %} 7831 7832 ins_pipe(pipe_serial); 7833 %} 7834 7835 // ============================================================================ 7836 // Cast/Convert Instructions 7837 7838 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7839 match(Set dst (CastX2P src)); 7840 7841 ins_cost(INSN_COST); 7842 format %{ "mov $dst, $src\t# long -> ptr" %} 7843 7844 ins_encode %{ 7845 if ($dst$$reg != $src$$reg) { 7846 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7847 } 7848 %} 7849 7850 ins_pipe(ialu_reg); 7851 %} 7852 7853 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7854 match(Set dst (CastP2X src)); 7855 7856 ins_cost(INSN_COST); 7857 format %{ "mov $dst, $src\t# ptr -> long" %} 7858 7859 ins_encode %{ 7860 if ($dst$$reg != $src$$reg) { 7861 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7862 } 7863 %} 7864 7865 ins_pipe(ialu_reg); 7866 %} 7867 7868 // Convert oop into int for vectors alignment masking 7869 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7870 match(Set dst (ConvL2I (CastP2X src))); 7871 7872 ins_cost(INSN_COST); 7873 format %{ "movw $dst, $src\t# ptr -> int" %} 7874 ins_encode %{ 7875 __ movw($dst$$Register, $src$$Register); 7876 %} 7877 7878 ins_pipe(ialu_reg); 7879 %} 7880 7881 // Convert compressed oop into int for vectors alignment masking 7882 // in case of 32bit oops (heap < 4Gb). 7883 instruct convN2I(iRegINoSp dst, iRegN src) 7884 %{ 7885 predicate(Universe::narrow_oop_shift() == 0); 7886 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7887 7888 ins_cost(INSN_COST); 7889 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7890 ins_encode %{ 7891 __ movw($dst$$Register, $src$$Register); 7892 %} 7893 7894 ins_pipe(ialu_reg); 7895 %} 7896 7897 7898 // Convert oop pointer into compressed form 7899 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7900 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7901 match(Set dst (EncodeP src)); 7902 effect(KILL cr); 7903 ins_cost(INSN_COST * 3); 7904 format %{ "encode_heap_oop $dst, $src" %} 7905 ins_encode %{ 7906 Register s = $src$$Register; 7907 Register d = $dst$$Register; 7908 __ encode_heap_oop(d, s); 7909 %} 7910 ins_pipe(ialu_reg); 7911 %} 7912 7913 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7914 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7915 match(Set dst (EncodeP src)); 7916 ins_cost(INSN_COST * 3); 7917 format %{ "encode_heap_oop_not_null $dst, $src" %} 7918 ins_encode %{ 7919 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7920 %} 7921 ins_pipe(ialu_reg); 7922 %} 7923 7924 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7925 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7926 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7927 match(Set dst (DecodeN src)); 7928 ins_cost(INSN_COST * 3); 7929 format %{ "decode_heap_oop $dst, $src" %} 7930 ins_encode %{ 7931 Register s = $src$$Register; 7932 Register d = $dst$$Register; 7933 __ decode_heap_oop(d, s); 7934 %} 7935 ins_pipe(ialu_reg); 7936 %} 7937 7938 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7939 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7940 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7941 match(Set dst (DecodeN src)); 7942 ins_cost(INSN_COST * 3); 7943 format %{ "decode_heap_oop_not_null $dst, $src" %} 7944 ins_encode %{ 7945 Register s = $src$$Register; 7946 Register d = $dst$$Register; 7947 __ decode_heap_oop_not_null(d, s); 7948 %} 7949 ins_pipe(ialu_reg); 7950 %} 7951 7952 // n.b. AArch64 implementations of encode_klass_not_null and 7953 // decode_klass_not_null do not modify the flags register so, unlike 7954 // Intel, we don't kill CR as a side effect here 7955 7956 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7957 match(Set dst (EncodePKlass src)); 7958 7959 ins_cost(INSN_COST * 3); 7960 format %{ "encode_klass_not_null $dst,$src" %} 7961 7962 ins_encode %{ 7963 Register src_reg = as_Register($src$$reg); 7964 Register dst_reg = as_Register($dst$$reg); 7965 __ encode_klass_not_null(dst_reg, src_reg); 7966 %} 7967 7968 ins_pipe(ialu_reg); 7969 %} 7970 7971 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7972 match(Set dst (DecodeNKlass src)); 7973 7974 ins_cost(INSN_COST * 3); 7975 format %{ "decode_klass_not_null $dst,$src" %} 7976 7977 ins_encode %{ 7978 Register src_reg = as_Register($src$$reg); 7979 Register dst_reg = as_Register($dst$$reg); 7980 if (dst_reg != src_reg) { 7981 __ decode_klass_not_null(dst_reg, src_reg); 7982 } else { 7983 __ decode_klass_not_null(dst_reg); 7984 } 7985 %} 7986 7987 ins_pipe(ialu_reg); 7988 %} 7989 7990 instruct checkCastPP(iRegPNoSp dst) 7991 %{ 7992 match(Set dst (CheckCastPP dst)); 7993 7994 size(0); 7995 format %{ "# checkcastPP of $dst" %} 7996 ins_encode(/* empty encoding */); 7997 ins_pipe(pipe_class_empty); 7998 %} 7999 8000 instruct castPP(iRegPNoSp dst) 8001 %{ 8002 match(Set dst (CastPP dst)); 8003 8004 size(0); 8005 format %{ "# castPP of $dst" %} 8006 ins_encode(/* empty encoding */); 8007 ins_pipe(pipe_class_empty); 8008 %} 8009 8010 instruct castII(iRegI dst) 8011 %{ 8012 match(Set dst (CastII dst)); 8013 8014 size(0); 8015 format %{ "# castII of $dst" %} 8016 ins_encode(/* empty encoding */); 8017 ins_cost(0); 8018 ins_pipe(pipe_class_empty); 8019 %} 8020 8021 // ============================================================================ 8022 // Atomic operation instructions 8023 // 8024 // Intel and SPARC both implement Ideal Node LoadPLocked and 8025 // Store{PIL}Conditional instructions using a normal load for the 8026 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8027 // 8028 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8029 // pair to lock object allocations from Eden space when not using 8030 // TLABs. 8031 // 8032 // There does not appear to be a Load{IL}Locked Ideal Node and the 8033 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8034 // and to use StoreIConditional only for 32-bit and StoreLConditional 8035 // only for 64-bit. 8036 // 8037 // We implement LoadPLocked and StorePLocked instructions using, 8038 // respectively the AArch64 hw load-exclusive and store-conditional 8039 // instructions. Whereas we must implement each of 8040 // Store{IL}Conditional using a CAS which employs a pair of 8041 // instructions comprising a load-exclusive followed by a 8042 // store-conditional. 8043 8044 8045 // Locked-load (linked load) of the current heap-top 8046 // used when updating the eden heap top 8047 // implemented using ldaxr on AArch64 8048 8049 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8050 %{ 8051 match(Set dst (LoadPLocked mem)); 8052 8053 ins_cost(VOLATILE_REF_COST); 8054 8055 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8056 8057 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8058 8059 ins_pipe(pipe_serial); 8060 %} 8061 8062 // Conditional-store of the updated heap-top. 8063 // Used during allocation of the shared heap. 8064 // Sets flag (EQ) on success. 8065 // implemented using stlxr on AArch64. 8066 8067 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8068 %{ 8069 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8070 8071 ins_cost(VOLATILE_REF_COST); 8072 8073 // TODO 8074 // do we need to do a store-conditional release or can we just use a 8075 // plain store-conditional? 8076 8077 format %{ 8078 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8079 "cmpw rscratch1, zr\t# EQ on successful write" 8080 %} 8081 8082 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8083 8084 ins_pipe(pipe_serial); 8085 %} 8086 8087 8088 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8089 // when attempting to rebias a lock towards the current thread. We 8090 // must use the acquire form of cmpxchg in order to guarantee acquire 8091 // semantics in this case. 8092 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8093 %{ 8094 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8095 8096 ins_cost(VOLATILE_REF_COST); 8097 8098 format %{ 8099 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8100 "cmpw rscratch1, zr\t# EQ on successful write" 8101 %} 8102 8103 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8104 8105 ins_pipe(pipe_slow); 8106 %} 8107 8108 // storeIConditional also has acquire semantics, for no better reason 8109 // than matching storeLConditional. At the time of writing this 8110 // comment storeIConditional was not used anywhere by AArch64. 8111 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8112 %{ 8113 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8114 8115 ins_cost(VOLATILE_REF_COST); 8116 8117 format %{ 8118 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8119 "cmpw rscratch1, zr\t# EQ on successful write" 8120 %} 8121 8122 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8123 8124 ins_pipe(pipe_slow); 8125 %} 8126 8127 // standard CompareAndSwapX when we are using barriers 8128 // these have higher priority than the rules selected by a predicate 8129 8130 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8131 // can't match them 8132 8133 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8134 8135 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8136 ins_cost(2 * VOLATILE_REF_COST); 8137 8138 effect(KILL cr); 8139 8140 format %{ 8141 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8142 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8143 %} 8144 8145 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8146 aarch64_enc_cset_eq(res)); 8147 8148 ins_pipe(pipe_slow); 8149 %} 8150 8151 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8152 8153 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8154 ins_cost(2 * VOLATILE_REF_COST); 8155 8156 effect(KILL cr); 8157 8158 format %{ 8159 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8160 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8161 %} 8162 8163 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8164 aarch64_enc_cset_eq(res)); 8165 8166 ins_pipe(pipe_slow); 8167 %} 8168 8169 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8170 8171 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8172 ins_cost(2 * VOLATILE_REF_COST); 8173 8174 effect(KILL cr); 8175 8176 format %{ 8177 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8178 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8179 %} 8180 8181 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8182 aarch64_enc_cset_eq(res)); 8183 8184 ins_pipe(pipe_slow); 8185 %} 8186 8187 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8188 8189 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8190 ins_cost(2 * VOLATILE_REF_COST); 8191 8192 effect(KILL cr); 8193 8194 format %{ 8195 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8196 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8197 %} 8198 8199 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8200 aarch64_enc_cset_eq(res)); 8201 8202 ins_pipe(pipe_slow); 8203 %} 8204 8205 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8206 8207 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8208 ins_cost(2 * VOLATILE_REF_COST); 8209 8210 effect(KILL cr); 8211 8212 format %{ 8213 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8214 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8215 %} 8216 8217 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8218 aarch64_enc_cset_eq(res)); 8219 8220 ins_pipe(pipe_slow); 8221 %} 8222 8223 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8224 8225 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8226 ins_cost(2 * VOLATILE_REF_COST); 8227 8228 effect(KILL cr); 8229 8230 format %{ 8231 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8232 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8233 %} 8234 8235 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8236 aarch64_enc_cset_eq(res)); 8237 8238 ins_pipe(pipe_slow); 8239 %} 8240 8241 // alternative CompareAndSwapX when we are eliding barriers 8242 8243 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8244 8245 predicate(needs_acquiring_load_exclusive(n)); 8246 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8247 ins_cost(VOLATILE_REF_COST); 8248 8249 effect(KILL cr); 8250 8251 format %{ 8252 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8253 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8254 %} 8255 8256 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8257 aarch64_enc_cset_eq(res)); 8258 8259 ins_pipe(pipe_slow); 8260 %} 8261 8262 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8263 8264 predicate(needs_acquiring_load_exclusive(n)); 8265 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8266 ins_cost(VOLATILE_REF_COST); 8267 8268 effect(KILL cr); 8269 8270 format %{ 8271 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8272 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8273 %} 8274 8275 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8276 aarch64_enc_cset_eq(res)); 8277 8278 ins_pipe(pipe_slow); 8279 %} 8280 8281 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8282 8283 predicate(needs_acquiring_load_exclusive(n)); 8284 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8285 ins_cost(VOLATILE_REF_COST); 8286 8287 effect(KILL cr); 8288 8289 format %{ 8290 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8291 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8292 %} 8293 8294 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8295 aarch64_enc_cset_eq(res)); 8296 8297 ins_pipe(pipe_slow); 8298 %} 8299 8300 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8301 8302 predicate(needs_acquiring_load_exclusive(n)); 8303 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8304 ins_cost(VOLATILE_REF_COST); 8305 8306 effect(KILL cr); 8307 8308 format %{ 8309 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8310 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8311 %} 8312 8313 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8314 aarch64_enc_cset_eq(res)); 8315 8316 ins_pipe(pipe_slow); 8317 %} 8318 8319 8320 // --------------------------------------------------------------------- 8321 8322 8323 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8324 8325 // Sundry CAS operations. Note that release is always true, 8326 // regardless of the memory ordering of the CAS. This is because we 8327 // need the volatile case to be sequentially consistent but there is 8328 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8329 // can't check the type of memory ordering here, so we always emit a 8330 // STLXR. 8331 8332 // This section is generated from aarch64_ad_cas.m4 8333 8334 8335 8336 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8337 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8338 ins_cost(2 * VOLATILE_REF_COST); 8339 effect(TEMP_DEF res, KILL cr); 8340 format %{ 8341 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8342 %} 8343 ins_encode %{ 8344 __ uxtbw(rscratch2, $oldval$$Register); 8345 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8346 Assembler::byte, /*acquire*/ false, /*release*/ true, 8347 /*weak*/ false, $res$$Register); 8348 __ sxtbw($res$$Register, $res$$Register); 8349 %} 8350 ins_pipe(pipe_slow); 8351 %} 8352 8353 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8354 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8355 ins_cost(2 * VOLATILE_REF_COST); 8356 effect(TEMP_DEF res, KILL cr); 8357 format %{ 8358 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8359 %} 8360 ins_encode %{ 8361 __ uxthw(rscratch2, $oldval$$Register); 8362 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8363 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8364 /*weak*/ false, $res$$Register); 8365 __ sxthw($res$$Register, $res$$Register); 8366 %} 8367 ins_pipe(pipe_slow); 8368 %} 8369 8370 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8371 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8372 ins_cost(2 * VOLATILE_REF_COST); 8373 effect(TEMP_DEF res, KILL cr); 8374 format %{ 8375 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8376 %} 8377 ins_encode %{ 8378 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8379 Assembler::word, /*acquire*/ false, /*release*/ true, 8380 /*weak*/ false, $res$$Register); 8381 %} 8382 ins_pipe(pipe_slow); 8383 %} 8384 8385 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8386 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8387 ins_cost(2 * VOLATILE_REF_COST); 8388 effect(TEMP_DEF res, KILL cr); 8389 format %{ 8390 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8391 %} 8392 ins_encode %{ 8393 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8394 Assembler::xword, /*acquire*/ false, /*release*/ true, 8395 /*weak*/ false, $res$$Register); 8396 %} 8397 ins_pipe(pipe_slow); 8398 %} 8399 8400 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8401 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8402 ins_cost(2 * VOLATILE_REF_COST); 8403 effect(TEMP_DEF res, KILL cr); 8404 format %{ 8405 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8406 %} 8407 ins_encode %{ 8408 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8409 Assembler::word, /*acquire*/ false, /*release*/ true, 8410 /*weak*/ false, $res$$Register); 8411 %} 8412 ins_pipe(pipe_slow); 8413 %} 8414 8415 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8416 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8417 ins_cost(2 * VOLATILE_REF_COST); 8418 effect(TEMP_DEF res, KILL cr); 8419 format %{ 8420 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8421 %} 8422 ins_encode %{ 8423 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8424 Assembler::xword, /*acquire*/ false, /*release*/ true, 8425 /*weak*/ false, $res$$Register); 8426 %} 8427 ins_pipe(pipe_slow); 8428 %} 8429 8430 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8431 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8432 ins_cost(2 * VOLATILE_REF_COST); 8433 effect(KILL cr); 8434 format %{ 8435 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8436 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8437 %} 8438 ins_encode %{ 8439 __ uxtbw(rscratch2, $oldval$$Register); 8440 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8441 Assembler::byte, /*acquire*/ false, /*release*/ true, 8442 /*weak*/ true, noreg); 8443 __ csetw($res$$Register, Assembler::EQ); 8444 %} 8445 ins_pipe(pipe_slow); 8446 %} 8447 8448 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8449 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8450 ins_cost(2 * VOLATILE_REF_COST); 8451 effect(KILL cr); 8452 format %{ 8453 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8454 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8455 %} 8456 ins_encode %{ 8457 __ uxthw(rscratch2, $oldval$$Register); 8458 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8459 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8460 /*weak*/ true, noreg); 8461 __ csetw($res$$Register, Assembler::EQ); 8462 %} 8463 ins_pipe(pipe_slow); 8464 %} 8465 8466 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8467 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8468 ins_cost(2 * VOLATILE_REF_COST); 8469 effect(KILL cr); 8470 format %{ 8471 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8472 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8473 %} 8474 ins_encode %{ 8475 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8476 Assembler::word, /*acquire*/ false, /*release*/ true, 8477 /*weak*/ true, noreg); 8478 __ csetw($res$$Register, Assembler::EQ); 8479 %} 8480 ins_pipe(pipe_slow); 8481 %} 8482 8483 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8484 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8485 ins_cost(2 * VOLATILE_REF_COST); 8486 effect(KILL cr); 8487 format %{ 8488 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8489 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8490 %} 8491 ins_encode %{ 8492 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8493 Assembler::xword, /*acquire*/ false, /*release*/ true, 8494 /*weak*/ true, noreg); 8495 __ csetw($res$$Register, Assembler::EQ); 8496 %} 8497 ins_pipe(pipe_slow); 8498 %} 8499 8500 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8501 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8502 ins_cost(2 * VOLATILE_REF_COST); 8503 effect(KILL cr); 8504 format %{ 8505 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8506 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8507 %} 8508 ins_encode %{ 8509 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8510 Assembler::word, /*acquire*/ false, /*release*/ true, 8511 /*weak*/ true, noreg); 8512 __ csetw($res$$Register, Assembler::EQ); 8513 %} 8514 ins_pipe(pipe_slow); 8515 %} 8516 8517 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8518 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8519 ins_cost(2 * VOLATILE_REF_COST); 8520 effect(KILL cr); 8521 format %{ 8522 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8523 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8524 %} 8525 ins_encode %{ 8526 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8527 Assembler::xword, /*acquire*/ false, /*release*/ true, 8528 /*weak*/ true, noreg); 8529 __ csetw($res$$Register, Assembler::EQ); 8530 %} 8531 ins_pipe(pipe_slow); 8532 %} 8533 8534 // END This section of the file is automatically generated. Do not edit -------------- 8535 // --------------------------------------------------------------------- 8536 8537 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8538 match(Set prev (GetAndSetI mem newv)); 8539 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8540 ins_encode %{ 8541 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8542 %} 8543 ins_pipe(pipe_serial); 8544 %} 8545 8546 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8547 match(Set prev (GetAndSetL mem newv)); 8548 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8549 ins_encode %{ 8550 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8551 %} 8552 ins_pipe(pipe_serial); 8553 %} 8554 8555 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8556 match(Set prev (GetAndSetN mem newv)); 8557 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8558 ins_encode %{ 8559 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8560 %} 8561 ins_pipe(pipe_serial); 8562 %} 8563 8564 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8565 match(Set prev (GetAndSetP mem newv)); 8566 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8567 ins_encode %{ 8568 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8569 %} 8570 ins_pipe(pipe_serial); 8571 %} 8572 8573 8574 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8575 match(Set newval (GetAndAddL mem incr)); 8576 ins_cost(INSN_COST * 10); 8577 format %{ "get_and_addL $newval, [$mem], $incr" %} 8578 ins_encode %{ 8579 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8580 %} 8581 ins_pipe(pipe_serial); 8582 %} 8583 8584 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8585 predicate(n->as_LoadStore()->result_not_used()); 8586 match(Set dummy (GetAndAddL mem incr)); 8587 ins_cost(INSN_COST * 9); 8588 format %{ "get_and_addL [$mem], $incr" %} 8589 ins_encode %{ 8590 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8591 %} 8592 ins_pipe(pipe_serial); 8593 %} 8594 8595 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8596 match(Set newval (GetAndAddL mem incr)); 8597 ins_cost(INSN_COST * 10); 8598 format %{ "get_and_addL $newval, [$mem], $incr" %} 8599 ins_encode %{ 8600 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8601 %} 8602 ins_pipe(pipe_serial); 8603 %} 8604 8605 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8606 predicate(n->as_LoadStore()->result_not_used()); 8607 match(Set dummy (GetAndAddL mem incr)); 8608 ins_cost(INSN_COST * 9); 8609 format %{ "get_and_addL [$mem], $incr" %} 8610 ins_encode %{ 8611 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8612 %} 8613 ins_pipe(pipe_serial); 8614 %} 8615 8616 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8617 match(Set newval (GetAndAddI mem incr)); 8618 ins_cost(INSN_COST * 10); 8619 format %{ "get_and_addI $newval, [$mem], $incr" %} 8620 ins_encode %{ 8621 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8622 %} 8623 ins_pipe(pipe_serial); 8624 %} 8625 8626 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8627 predicate(n->as_LoadStore()->result_not_used()); 8628 match(Set dummy (GetAndAddI mem incr)); 8629 ins_cost(INSN_COST * 9); 8630 format %{ "get_and_addI [$mem], $incr" %} 8631 ins_encode %{ 8632 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8633 %} 8634 ins_pipe(pipe_serial); 8635 %} 8636 8637 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8638 match(Set newval (GetAndAddI mem incr)); 8639 ins_cost(INSN_COST * 10); 8640 format %{ "get_and_addI $newval, [$mem], $incr" %} 8641 ins_encode %{ 8642 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8643 %} 8644 ins_pipe(pipe_serial); 8645 %} 8646 8647 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8648 predicate(n->as_LoadStore()->result_not_used()); 8649 match(Set dummy (GetAndAddI mem incr)); 8650 ins_cost(INSN_COST * 9); 8651 format %{ "get_and_addI [$mem], $incr" %} 8652 ins_encode %{ 8653 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8654 %} 8655 ins_pipe(pipe_serial); 8656 %} 8657 8658 // Manifest a CmpL result in an integer register. 8659 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8660 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8661 %{ 8662 match(Set dst (CmpL3 src1 src2)); 8663 effect(KILL flags); 8664 8665 ins_cost(INSN_COST * 6); 8666 format %{ 8667 "cmp $src1, $src2" 8668 "csetw $dst, ne" 8669 "cnegw $dst, lt" 8670 %} 8671 // format %{ "CmpL3 $dst, $src1, $src2" %} 8672 ins_encode %{ 8673 __ cmp($src1$$Register, $src2$$Register); 8674 __ csetw($dst$$Register, Assembler::NE); 8675 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8676 %} 8677 8678 ins_pipe(pipe_class_default); 8679 %} 8680 8681 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8682 %{ 8683 match(Set dst (CmpL3 src1 src2)); 8684 effect(KILL flags); 8685 8686 ins_cost(INSN_COST * 6); 8687 format %{ 8688 "cmp $src1, $src2" 8689 "csetw $dst, ne" 8690 "cnegw $dst, lt" 8691 %} 8692 ins_encode %{ 8693 int32_t con = (int32_t)$src2$$constant; 8694 if (con < 0) { 8695 __ adds(zr, $src1$$Register, -con); 8696 } else { 8697 __ subs(zr, $src1$$Register, con); 8698 } 8699 __ csetw($dst$$Register, Assembler::NE); 8700 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8701 %} 8702 8703 ins_pipe(pipe_class_default); 8704 %} 8705 8706 // ============================================================================ 8707 // Conditional Move Instructions 8708 8709 // n.b. we have identical rules for both a signed compare op (cmpOp) 8710 // and an unsigned compare op (cmpOpU). it would be nice if we could 8711 // define an op class which merged both inputs and use it to type the 8712 // argument to a single rule. unfortunatelyt his fails because the 8713 // opclass does not live up to the COND_INTER interface of its 8714 // component operands. When the generic code tries to negate the 8715 // operand it ends up running the generci Machoper::negate method 8716 // which throws a ShouldNotHappen. So, we have to provide two flavours 8717 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 8718 8719 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8720 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8721 8722 ins_cost(INSN_COST * 2); 8723 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 8724 8725 ins_encode %{ 8726 __ cselw(as_Register($dst$$reg), 8727 as_Register($src2$$reg), 8728 as_Register($src1$$reg), 8729 (Assembler::Condition)$cmp$$cmpcode); 8730 %} 8731 8732 ins_pipe(icond_reg_reg); 8733 %} 8734 8735 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8736 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8737 8738 ins_cost(INSN_COST * 2); 8739 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 8740 8741 ins_encode %{ 8742 __ cselw(as_Register($dst$$reg), 8743 as_Register($src2$$reg), 8744 as_Register($src1$$reg), 8745 (Assembler::Condition)$cmp$$cmpcode); 8746 %} 8747 8748 ins_pipe(icond_reg_reg); 8749 %} 8750 8751 // special cases where one arg is zero 8752 8753 // n.b. this is selected in preference to the rule above because it 8754 // avoids loading constant 0 into a source register 8755 8756 // TODO 8757 // we ought only to be able to cull one of these variants as the ideal 8758 // transforms ought always to order the zero consistently (to left/right?) 8759 8760 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8761 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8762 8763 ins_cost(INSN_COST * 2); 8764 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 8765 8766 ins_encode %{ 8767 __ cselw(as_Register($dst$$reg), 8768 as_Register($src$$reg), 8769 zr, 8770 (Assembler::Condition)$cmp$$cmpcode); 8771 %} 8772 8773 ins_pipe(icond_reg); 8774 %} 8775 8776 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8777 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8778 8779 ins_cost(INSN_COST * 2); 8780 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 8781 8782 ins_encode %{ 8783 __ cselw(as_Register($dst$$reg), 8784 as_Register($src$$reg), 8785 zr, 8786 (Assembler::Condition)$cmp$$cmpcode); 8787 %} 8788 8789 ins_pipe(icond_reg); 8790 %} 8791 8792 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8793 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8794 8795 ins_cost(INSN_COST * 2); 8796 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 8797 8798 ins_encode %{ 8799 __ cselw(as_Register($dst$$reg), 8800 zr, 8801 as_Register($src$$reg), 8802 (Assembler::Condition)$cmp$$cmpcode); 8803 %} 8804 8805 ins_pipe(icond_reg); 8806 %} 8807 8808 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8809 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8810 8811 ins_cost(INSN_COST * 2); 8812 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 8813 8814 ins_encode %{ 8815 __ cselw(as_Register($dst$$reg), 8816 zr, 8817 as_Register($src$$reg), 8818 (Assembler::Condition)$cmp$$cmpcode); 8819 %} 8820 8821 ins_pipe(icond_reg); 8822 %} 8823 8824 // special case for creating a boolean 0 or 1 8825 8826 // n.b. this is selected in preference to the rule above because it 8827 // avoids loading constants 0 and 1 into a source register 8828 8829 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8830 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8831 8832 ins_cost(INSN_COST * 2); 8833 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 8834 8835 ins_encode %{ 8836 // equivalently 8837 // cset(as_Register($dst$$reg), 8838 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8839 __ csincw(as_Register($dst$$reg), 8840 zr, 8841 zr, 8842 (Assembler::Condition)$cmp$$cmpcode); 8843 %} 8844 8845 ins_pipe(icond_none); 8846 %} 8847 8848 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8849 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8850 8851 ins_cost(INSN_COST * 2); 8852 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 8853 8854 ins_encode %{ 8855 // equivalently 8856 // cset(as_Register($dst$$reg), 8857 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8858 __ csincw(as_Register($dst$$reg), 8859 zr, 8860 zr, 8861 (Assembler::Condition)$cmp$$cmpcode); 8862 %} 8863 8864 ins_pipe(icond_none); 8865 %} 8866 8867 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8868 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8869 8870 ins_cost(INSN_COST * 2); 8871 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 8872 8873 ins_encode %{ 8874 __ csel(as_Register($dst$$reg), 8875 as_Register($src2$$reg), 8876 as_Register($src1$$reg), 8877 (Assembler::Condition)$cmp$$cmpcode); 8878 %} 8879 8880 ins_pipe(icond_reg_reg); 8881 %} 8882 8883 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8884 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8885 8886 ins_cost(INSN_COST * 2); 8887 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 8888 8889 ins_encode %{ 8890 __ csel(as_Register($dst$$reg), 8891 as_Register($src2$$reg), 8892 as_Register($src1$$reg), 8893 (Assembler::Condition)$cmp$$cmpcode); 8894 %} 8895 8896 ins_pipe(icond_reg_reg); 8897 %} 8898 8899 // special cases where one arg is zero 8900 8901 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8902 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8903 8904 ins_cost(INSN_COST * 2); 8905 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 8906 8907 ins_encode %{ 8908 __ csel(as_Register($dst$$reg), 8909 zr, 8910 as_Register($src$$reg), 8911 (Assembler::Condition)$cmp$$cmpcode); 8912 %} 8913 8914 ins_pipe(icond_reg); 8915 %} 8916 8917 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8918 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8919 8920 ins_cost(INSN_COST * 2); 8921 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 8922 8923 ins_encode %{ 8924 __ csel(as_Register($dst$$reg), 8925 zr, 8926 as_Register($src$$reg), 8927 (Assembler::Condition)$cmp$$cmpcode); 8928 %} 8929 8930 ins_pipe(icond_reg); 8931 %} 8932 8933 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8934 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8935 8936 ins_cost(INSN_COST * 2); 8937 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 8938 8939 ins_encode %{ 8940 __ csel(as_Register($dst$$reg), 8941 as_Register($src$$reg), 8942 zr, 8943 (Assembler::Condition)$cmp$$cmpcode); 8944 %} 8945 8946 ins_pipe(icond_reg); 8947 %} 8948 8949 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8950 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8951 8952 ins_cost(INSN_COST * 2); 8953 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 8954 8955 ins_encode %{ 8956 __ csel(as_Register($dst$$reg), 8957 as_Register($src$$reg), 8958 zr, 8959 (Assembler::Condition)$cmp$$cmpcode); 8960 %} 8961 8962 ins_pipe(icond_reg); 8963 %} 8964 8965 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8966 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8967 8968 ins_cost(INSN_COST * 2); 8969 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 8970 8971 ins_encode %{ 8972 __ csel(as_Register($dst$$reg), 8973 as_Register($src2$$reg), 8974 as_Register($src1$$reg), 8975 (Assembler::Condition)$cmp$$cmpcode); 8976 %} 8977 8978 ins_pipe(icond_reg_reg); 8979 %} 8980 8981 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8982 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8983 8984 ins_cost(INSN_COST * 2); 8985 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 8986 8987 ins_encode %{ 8988 __ csel(as_Register($dst$$reg), 8989 as_Register($src2$$reg), 8990 as_Register($src1$$reg), 8991 (Assembler::Condition)$cmp$$cmpcode); 8992 %} 8993 8994 ins_pipe(icond_reg_reg); 8995 %} 8996 8997 // special cases where one arg is zero 8998 8999 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9000 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9001 9002 ins_cost(INSN_COST * 2); 9003 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9004 9005 ins_encode %{ 9006 __ csel(as_Register($dst$$reg), 9007 zr, 9008 as_Register($src$$reg), 9009 (Assembler::Condition)$cmp$$cmpcode); 9010 %} 9011 9012 ins_pipe(icond_reg); 9013 %} 9014 9015 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9016 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9017 9018 ins_cost(INSN_COST * 2); 9019 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9020 9021 ins_encode %{ 9022 __ csel(as_Register($dst$$reg), 9023 zr, 9024 as_Register($src$$reg), 9025 (Assembler::Condition)$cmp$$cmpcode); 9026 %} 9027 9028 ins_pipe(icond_reg); 9029 %} 9030 9031 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9032 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9033 9034 ins_cost(INSN_COST * 2); 9035 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9036 9037 ins_encode %{ 9038 __ csel(as_Register($dst$$reg), 9039 as_Register($src$$reg), 9040 zr, 9041 (Assembler::Condition)$cmp$$cmpcode); 9042 %} 9043 9044 ins_pipe(icond_reg); 9045 %} 9046 9047 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9048 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9049 9050 ins_cost(INSN_COST * 2); 9051 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9052 9053 ins_encode %{ 9054 __ csel(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 cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9064 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9065 9066 ins_cost(INSN_COST * 2); 9067 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9068 9069 ins_encode %{ 9070 __ cselw(as_Register($dst$$reg), 9071 as_Register($src2$$reg), 9072 as_Register($src1$$reg), 9073 (Assembler::Condition)$cmp$$cmpcode); 9074 %} 9075 9076 ins_pipe(icond_reg_reg); 9077 %} 9078 9079 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9080 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9081 9082 ins_cost(INSN_COST * 2); 9083 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9084 9085 ins_encode %{ 9086 __ cselw(as_Register($dst$$reg), 9087 as_Register($src2$$reg), 9088 as_Register($src1$$reg), 9089 (Assembler::Condition)$cmp$$cmpcode); 9090 %} 9091 9092 ins_pipe(icond_reg_reg); 9093 %} 9094 9095 // special cases where one arg is zero 9096 9097 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9098 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9099 9100 ins_cost(INSN_COST * 2); 9101 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9102 9103 ins_encode %{ 9104 __ cselw(as_Register($dst$$reg), 9105 zr, 9106 as_Register($src$$reg), 9107 (Assembler::Condition)$cmp$$cmpcode); 9108 %} 9109 9110 ins_pipe(icond_reg); 9111 %} 9112 9113 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9114 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9115 9116 ins_cost(INSN_COST * 2); 9117 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9118 9119 ins_encode %{ 9120 __ cselw(as_Register($dst$$reg), 9121 zr, 9122 as_Register($src$$reg), 9123 (Assembler::Condition)$cmp$$cmpcode); 9124 %} 9125 9126 ins_pipe(icond_reg); 9127 %} 9128 9129 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9130 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9131 9132 ins_cost(INSN_COST * 2); 9133 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9134 9135 ins_encode %{ 9136 __ cselw(as_Register($dst$$reg), 9137 as_Register($src$$reg), 9138 zr, 9139 (Assembler::Condition)$cmp$$cmpcode); 9140 %} 9141 9142 ins_pipe(icond_reg); 9143 %} 9144 9145 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9146 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9147 9148 ins_cost(INSN_COST * 2); 9149 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9150 9151 ins_encode %{ 9152 __ cselw(as_Register($dst$$reg), 9153 as_Register($src$$reg), 9154 zr, 9155 (Assembler::Condition)$cmp$$cmpcode); 9156 %} 9157 9158 ins_pipe(icond_reg); 9159 %} 9160 9161 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9162 %{ 9163 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9164 9165 ins_cost(INSN_COST * 3); 9166 9167 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9168 ins_encode %{ 9169 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9170 __ fcsels(as_FloatRegister($dst$$reg), 9171 as_FloatRegister($src2$$reg), 9172 as_FloatRegister($src1$$reg), 9173 cond); 9174 %} 9175 9176 ins_pipe(fp_cond_reg_reg_s); 9177 %} 9178 9179 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9180 %{ 9181 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9182 9183 ins_cost(INSN_COST * 3); 9184 9185 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9186 ins_encode %{ 9187 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9188 __ fcsels(as_FloatRegister($dst$$reg), 9189 as_FloatRegister($src2$$reg), 9190 as_FloatRegister($src1$$reg), 9191 cond); 9192 %} 9193 9194 ins_pipe(fp_cond_reg_reg_s); 9195 %} 9196 9197 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9198 %{ 9199 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9200 9201 ins_cost(INSN_COST * 3); 9202 9203 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9204 ins_encode %{ 9205 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9206 __ fcseld(as_FloatRegister($dst$$reg), 9207 as_FloatRegister($src2$$reg), 9208 as_FloatRegister($src1$$reg), 9209 cond); 9210 %} 9211 9212 ins_pipe(fp_cond_reg_reg_d); 9213 %} 9214 9215 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9216 %{ 9217 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9218 9219 ins_cost(INSN_COST * 3); 9220 9221 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9222 ins_encode %{ 9223 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9224 __ fcseld(as_FloatRegister($dst$$reg), 9225 as_FloatRegister($src2$$reg), 9226 as_FloatRegister($src1$$reg), 9227 cond); 9228 %} 9229 9230 ins_pipe(fp_cond_reg_reg_d); 9231 %} 9232 9233 // ============================================================================ 9234 // Arithmetic Instructions 9235 // 9236 9237 // Integer Addition 9238 9239 // TODO 9240 // these currently employ operations which do not set CR and hence are 9241 // not flagged as killing CR but we would like to isolate the cases 9242 // where we want to set flags from those where we don't. need to work 9243 // out how to do that. 9244 9245 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9246 match(Set dst (AddI src1 src2)); 9247 9248 ins_cost(INSN_COST); 9249 format %{ "addw $dst, $src1, $src2" %} 9250 9251 ins_encode %{ 9252 __ addw(as_Register($dst$$reg), 9253 as_Register($src1$$reg), 9254 as_Register($src2$$reg)); 9255 %} 9256 9257 ins_pipe(ialu_reg_reg); 9258 %} 9259 9260 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9261 match(Set dst (AddI src1 src2)); 9262 9263 ins_cost(INSN_COST); 9264 format %{ "addw $dst, $src1, $src2" %} 9265 9266 // use opcode to indicate that this is an add not a sub 9267 opcode(0x0); 9268 9269 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9270 9271 ins_pipe(ialu_reg_imm); 9272 %} 9273 9274 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9275 match(Set dst (AddI (ConvL2I src1) src2)); 9276 9277 ins_cost(INSN_COST); 9278 format %{ "addw $dst, $src1, $src2" %} 9279 9280 // use opcode to indicate that this is an add not a sub 9281 opcode(0x0); 9282 9283 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9284 9285 ins_pipe(ialu_reg_imm); 9286 %} 9287 9288 // Pointer Addition 9289 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9290 match(Set dst (AddP src1 src2)); 9291 9292 ins_cost(INSN_COST); 9293 format %{ "add $dst, $src1, $src2\t# ptr" %} 9294 9295 ins_encode %{ 9296 __ add(as_Register($dst$$reg), 9297 as_Register($src1$$reg), 9298 as_Register($src2$$reg)); 9299 %} 9300 9301 ins_pipe(ialu_reg_reg); 9302 %} 9303 9304 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9305 match(Set dst (AddP src1 (ConvI2L src2))); 9306 9307 ins_cost(1.9 * INSN_COST); 9308 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9309 9310 ins_encode %{ 9311 __ add(as_Register($dst$$reg), 9312 as_Register($src1$$reg), 9313 as_Register($src2$$reg), ext::sxtw); 9314 %} 9315 9316 ins_pipe(ialu_reg_reg); 9317 %} 9318 9319 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9320 match(Set dst (AddP src1 (LShiftL src2 scale))); 9321 9322 ins_cost(1.9 * INSN_COST); 9323 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9324 9325 ins_encode %{ 9326 __ lea(as_Register($dst$$reg), 9327 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9328 Address::lsl($scale$$constant))); 9329 %} 9330 9331 ins_pipe(ialu_reg_reg_shift); 9332 %} 9333 9334 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9335 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9336 9337 ins_cost(1.9 * INSN_COST); 9338 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9339 9340 ins_encode %{ 9341 __ lea(as_Register($dst$$reg), 9342 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9343 Address::sxtw($scale$$constant))); 9344 %} 9345 9346 ins_pipe(ialu_reg_reg_shift); 9347 %} 9348 9349 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9350 match(Set dst (LShiftL (ConvI2L src) scale)); 9351 9352 ins_cost(INSN_COST); 9353 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9354 9355 ins_encode %{ 9356 __ sbfiz(as_Register($dst$$reg), 9357 as_Register($src$$reg), 9358 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 9359 %} 9360 9361 ins_pipe(ialu_reg_shift); 9362 %} 9363 9364 // Pointer Immediate Addition 9365 // n.b. this needs to be more expensive than using an indirect memory 9366 // operand 9367 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9368 match(Set dst (AddP src1 src2)); 9369 9370 ins_cost(INSN_COST); 9371 format %{ "add $dst, $src1, $src2\t# ptr" %} 9372 9373 // use opcode to indicate that this is an add not a sub 9374 opcode(0x0); 9375 9376 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9377 9378 ins_pipe(ialu_reg_imm); 9379 %} 9380 9381 // Long Addition 9382 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9383 9384 match(Set dst (AddL src1 src2)); 9385 9386 ins_cost(INSN_COST); 9387 format %{ "add $dst, $src1, $src2" %} 9388 9389 ins_encode %{ 9390 __ add(as_Register($dst$$reg), 9391 as_Register($src1$$reg), 9392 as_Register($src2$$reg)); 9393 %} 9394 9395 ins_pipe(ialu_reg_reg); 9396 %} 9397 9398 // No constant pool entries requiredLong Immediate Addition. 9399 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9400 match(Set dst (AddL src1 src2)); 9401 9402 ins_cost(INSN_COST); 9403 format %{ "add $dst, $src1, $src2" %} 9404 9405 // use opcode to indicate that this is an add not a sub 9406 opcode(0x0); 9407 9408 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9409 9410 ins_pipe(ialu_reg_imm); 9411 %} 9412 9413 // Integer Subtraction 9414 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9415 match(Set dst (SubI src1 src2)); 9416 9417 ins_cost(INSN_COST); 9418 format %{ "subw $dst, $src1, $src2" %} 9419 9420 ins_encode %{ 9421 __ subw(as_Register($dst$$reg), 9422 as_Register($src1$$reg), 9423 as_Register($src2$$reg)); 9424 %} 9425 9426 ins_pipe(ialu_reg_reg); 9427 %} 9428 9429 // Immediate Subtraction 9430 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9431 match(Set dst (SubI src1 src2)); 9432 9433 ins_cost(INSN_COST); 9434 format %{ "subw $dst, $src1, $src2" %} 9435 9436 // use opcode to indicate that this is a sub not an add 9437 opcode(0x1); 9438 9439 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9440 9441 ins_pipe(ialu_reg_imm); 9442 %} 9443 9444 // Long Subtraction 9445 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9446 9447 match(Set dst (SubL src1 src2)); 9448 9449 ins_cost(INSN_COST); 9450 format %{ "sub $dst, $src1, $src2" %} 9451 9452 ins_encode %{ 9453 __ sub(as_Register($dst$$reg), 9454 as_Register($src1$$reg), 9455 as_Register($src2$$reg)); 9456 %} 9457 9458 ins_pipe(ialu_reg_reg); 9459 %} 9460 9461 // No constant pool entries requiredLong Immediate Subtraction. 9462 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9463 match(Set dst (SubL src1 src2)); 9464 9465 ins_cost(INSN_COST); 9466 format %{ "sub$dst, $src1, $src2" %} 9467 9468 // use opcode to indicate that this is a sub not an add 9469 opcode(0x1); 9470 9471 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9472 9473 ins_pipe(ialu_reg_imm); 9474 %} 9475 9476 // Integer Negation (special case for sub) 9477 9478 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9479 match(Set dst (SubI zero src)); 9480 9481 ins_cost(INSN_COST); 9482 format %{ "negw $dst, $src\t# int" %} 9483 9484 ins_encode %{ 9485 __ negw(as_Register($dst$$reg), 9486 as_Register($src$$reg)); 9487 %} 9488 9489 ins_pipe(ialu_reg); 9490 %} 9491 9492 // Long Negation 9493 9494 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9495 match(Set dst (SubL zero src)); 9496 9497 ins_cost(INSN_COST); 9498 format %{ "neg $dst, $src\t# long" %} 9499 9500 ins_encode %{ 9501 __ neg(as_Register($dst$$reg), 9502 as_Register($src$$reg)); 9503 %} 9504 9505 ins_pipe(ialu_reg); 9506 %} 9507 9508 // Integer Multiply 9509 9510 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9511 match(Set dst (MulI src1 src2)); 9512 9513 ins_cost(INSN_COST * 3); 9514 format %{ "mulw $dst, $src1, $src2" %} 9515 9516 ins_encode %{ 9517 __ mulw(as_Register($dst$$reg), 9518 as_Register($src1$$reg), 9519 as_Register($src2$$reg)); 9520 %} 9521 9522 ins_pipe(imul_reg_reg); 9523 %} 9524 9525 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9526 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9527 9528 ins_cost(INSN_COST * 3); 9529 format %{ "smull $dst, $src1, $src2" %} 9530 9531 ins_encode %{ 9532 __ smull(as_Register($dst$$reg), 9533 as_Register($src1$$reg), 9534 as_Register($src2$$reg)); 9535 %} 9536 9537 ins_pipe(imul_reg_reg); 9538 %} 9539 9540 // Long Multiply 9541 9542 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9543 match(Set dst (MulL src1 src2)); 9544 9545 ins_cost(INSN_COST * 5); 9546 format %{ "mul $dst, $src1, $src2" %} 9547 9548 ins_encode %{ 9549 __ mul(as_Register($dst$$reg), 9550 as_Register($src1$$reg), 9551 as_Register($src2$$reg)); 9552 %} 9553 9554 ins_pipe(lmul_reg_reg); 9555 %} 9556 9557 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9558 %{ 9559 match(Set dst (MulHiL src1 src2)); 9560 9561 ins_cost(INSN_COST * 7); 9562 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9563 9564 ins_encode %{ 9565 __ smulh(as_Register($dst$$reg), 9566 as_Register($src1$$reg), 9567 as_Register($src2$$reg)); 9568 %} 9569 9570 ins_pipe(lmul_reg_reg); 9571 %} 9572 9573 // Combined Integer Multiply & Add/Sub 9574 9575 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9576 match(Set dst (AddI src3 (MulI src1 src2))); 9577 9578 ins_cost(INSN_COST * 3); 9579 format %{ "madd $dst, $src1, $src2, $src3" %} 9580 9581 ins_encode %{ 9582 __ maddw(as_Register($dst$$reg), 9583 as_Register($src1$$reg), 9584 as_Register($src2$$reg), 9585 as_Register($src3$$reg)); 9586 %} 9587 9588 ins_pipe(imac_reg_reg); 9589 %} 9590 9591 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9592 match(Set dst (SubI src3 (MulI src1 src2))); 9593 9594 ins_cost(INSN_COST * 3); 9595 format %{ "msub $dst, $src1, $src2, $src3" %} 9596 9597 ins_encode %{ 9598 __ msubw(as_Register($dst$$reg), 9599 as_Register($src1$$reg), 9600 as_Register($src2$$reg), 9601 as_Register($src3$$reg)); 9602 %} 9603 9604 ins_pipe(imac_reg_reg); 9605 %} 9606 9607 // Combined Integer Multiply & Neg 9608 9609 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 9610 match(Set dst (MulI (SubI zero src1) src2)); 9611 match(Set dst (MulI src1 (SubI zero src2))); 9612 9613 ins_cost(INSN_COST * 3); 9614 format %{ "mneg $dst, $src1, $src2" %} 9615 9616 ins_encode %{ 9617 __ mnegw(as_Register($dst$$reg), 9618 as_Register($src1$$reg), 9619 as_Register($src2$$reg)); 9620 %} 9621 9622 ins_pipe(imac_reg_reg); 9623 %} 9624 9625 // Combined Long Multiply & Add/Sub 9626 9627 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9628 match(Set dst (AddL src3 (MulL src1 src2))); 9629 9630 ins_cost(INSN_COST * 5); 9631 format %{ "madd $dst, $src1, $src2, $src3" %} 9632 9633 ins_encode %{ 9634 __ madd(as_Register($dst$$reg), 9635 as_Register($src1$$reg), 9636 as_Register($src2$$reg), 9637 as_Register($src3$$reg)); 9638 %} 9639 9640 ins_pipe(lmac_reg_reg); 9641 %} 9642 9643 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9644 match(Set dst (SubL src3 (MulL src1 src2))); 9645 9646 ins_cost(INSN_COST * 5); 9647 format %{ "msub $dst, $src1, $src2, $src3" %} 9648 9649 ins_encode %{ 9650 __ msub(as_Register($dst$$reg), 9651 as_Register($src1$$reg), 9652 as_Register($src2$$reg), 9653 as_Register($src3$$reg)); 9654 %} 9655 9656 ins_pipe(lmac_reg_reg); 9657 %} 9658 9659 // Combined Long Multiply & Neg 9660 9661 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 9662 match(Set dst (MulL (SubL zero src1) src2)); 9663 match(Set dst (MulL src1 (SubL zero src2))); 9664 9665 ins_cost(INSN_COST * 5); 9666 format %{ "mneg $dst, $src1, $src2" %} 9667 9668 ins_encode %{ 9669 __ mneg(as_Register($dst$$reg), 9670 as_Register($src1$$reg), 9671 as_Register($src2$$reg)); 9672 %} 9673 9674 ins_pipe(lmac_reg_reg); 9675 %} 9676 9677 // Integer Divide 9678 9679 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9680 match(Set dst (DivI src1 src2)); 9681 9682 ins_cost(INSN_COST * 19); 9683 format %{ "sdivw $dst, $src1, $src2" %} 9684 9685 ins_encode(aarch64_enc_divw(dst, src1, src2)); 9686 ins_pipe(idiv_reg_reg); 9687 %} 9688 9689 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 9690 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 9691 ins_cost(INSN_COST); 9692 format %{ "lsrw $dst, $src1, $div1" %} 9693 ins_encode %{ 9694 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 9695 %} 9696 ins_pipe(ialu_reg_shift); 9697 %} 9698 9699 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 9700 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 9701 ins_cost(INSN_COST); 9702 format %{ "addw $dst, $src, LSR $div1" %} 9703 9704 ins_encode %{ 9705 __ addw(as_Register($dst$$reg), 9706 as_Register($src$$reg), 9707 as_Register($src$$reg), 9708 Assembler::LSR, 31); 9709 %} 9710 ins_pipe(ialu_reg); 9711 %} 9712 9713 // Long Divide 9714 9715 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9716 match(Set dst (DivL src1 src2)); 9717 9718 ins_cost(INSN_COST * 35); 9719 format %{ "sdiv $dst, $src1, $src2" %} 9720 9721 ins_encode(aarch64_enc_div(dst, src1, src2)); 9722 ins_pipe(ldiv_reg_reg); 9723 %} 9724 9725 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 9726 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 9727 ins_cost(INSN_COST); 9728 format %{ "lsr $dst, $src1, $div1" %} 9729 ins_encode %{ 9730 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 9731 %} 9732 ins_pipe(ialu_reg_shift); 9733 %} 9734 9735 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 9736 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 9737 ins_cost(INSN_COST); 9738 format %{ "add $dst, $src, $div1" %} 9739 9740 ins_encode %{ 9741 __ add(as_Register($dst$$reg), 9742 as_Register($src$$reg), 9743 as_Register($src$$reg), 9744 Assembler::LSR, 63); 9745 %} 9746 ins_pipe(ialu_reg); 9747 %} 9748 9749 // Integer Remainder 9750 9751 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9752 match(Set dst (ModI src1 src2)); 9753 9754 ins_cost(INSN_COST * 22); 9755 format %{ "sdivw rscratch1, $src1, $src2\n\t" 9756 "msubw($dst, rscratch1, $src2, $src1" %} 9757 9758 ins_encode(aarch64_enc_modw(dst, src1, src2)); 9759 ins_pipe(idiv_reg_reg); 9760 %} 9761 9762 // Long Remainder 9763 9764 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9765 match(Set dst (ModL src1 src2)); 9766 9767 ins_cost(INSN_COST * 38); 9768 format %{ "sdiv rscratch1, $src1, $src2\n" 9769 "msub($dst, rscratch1, $src2, $src1" %} 9770 9771 ins_encode(aarch64_enc_mod(dst, src1, src2)); 9772 ins_pipe(ldiv_reg_reg); 9773 %} 9774 9775 // Integer Shifts 9776 9777 // Shift Left Register 9778 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9779 match(Set dst (LShiftI src1 src2)); 9780 9781 ins_cost(INSN_COST * 2); 9782 format %{ "lslvw $dst, $src1, $src2" %} 9783 9784 ins_encode %{ 9785 __ lslvw(as_Register($dst$$reg), 9786 as_Register($src1$$reg), 9787 as_Register($src2$$reg)); 9788 %} 9789 9790 ins_pipe(ialu_reg_reg_vshift); 9791 %} 9792 9793 // Shift Left Immediate 9794 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9795 match(Set dst (LShiftI src1 src2)); 9796 9797 ins_cost(INSN_COST); 9798 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 9799 9800 ins_encode %{ 9801 __ lslw(as_Register($dst$$reg), 9802 as_Register($src1$$reg), 9803 $src2$$constant & 0x1f); 9804 %} 9805 9806 ins_pipe(ialu_reg_shift); 9807 %} 9808 9809 // Shift Right Logical Register 9810 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9811 match(Set dst (URShiftI src1 src2)); 9812 9813 ins_cost(INSN_COST * 2); 9814 format %{ "lsrvw $dst, $src1, $src2" %} 9815 9816 ins_encode %{ 9817 __ lsrvw(as_Register($dst$$reg), 9818 as_Register($src1$$reg), 9819 as_Register($src2$$reg)); 9820 %} 9821 9822 ins_pipe(ialu_reg_reg_vshift); 9823 %} 9824 9825 // Shift Right Logical Immediate 9826 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9827 match(Set dst (URShiftI src1 src2)); 9828 9829 ins_cost(INSN_COST); 9830 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 9831 9832 ins_encode %{ 9833 __ lsrw(as_Register($dst$$reg), 9834 as_Register($src1$$reg), 9835 $src2$$constant & 0x1f); 9836 %} 9837 9838 ins_pipe(ialu_reg_shift); 9839 %} 9840 9841 // Shift Right Arithmetic Register 9842 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9843 match(Set dst (RShiftI src1 src2)); 9844 9845 ins_cost(INSN_COST * 2); 9846 format %{ "asrvw $dst, $src1, $src2" %} 9847 9848 ins_encode %{ 9849 __ asrvw(as_Register($dst$$reg), 9850 as_Register($src1$$reg), 9851 as_Register($src2$$reg)); 9852 %} 9853 9854 ins_pipe(ialu_reg_reg_vshift); 9855 %} 9856 9857 // Shift Right Arithmetic Immediate 9858 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9859 match(Set dst (RShiftI src1 src2)); 9860 9861 ins_cost(INSN_COST); 9862 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 9863 9864 ins_encode %{ 9865 __ asrw(as_Register($dst$$reg), 9866 as_Register($src1$$reg), 9867 $src2$$constant & 0x1f); 9868 %} 9869 9870 ins_pipe(ialu_reg_shift); 9871 %} 9872 9873 // Combined Int Mask and Right Shift (using UBFM) 9874 // TODO 9875 9876 // Long Shifts 9877 9878 // Shift Left Register 9879 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9880 match(Set dst (LShiftL src1 src2)); 9881 9882 ins_cost(INSN_COST * 2); 9883 format %{ "lslv $dst, $src1, $src2" %} 9884 9885 ins_encode %{ 9886 __ lslv(as_Register($dst$$reg), 9887 as_Register($src1$$reg), 9888 as_Register($src2$$reg)); 9889 %} 9890 9891 ins_pipe(ialu_reg_reg_vshift); 9892 %} 9893 9894 // Shift Left Immediate 9895 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9896 match(Set dst (LShiftL src1 src2)); 9897 9898 ins_cost(INSN_COST); 9899 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 9900 9901 ins_encode %{ 9902 __ lsl(as_Register($dst$$reg), 9903 as_Register($src1$$reg), 9904 $src2$$constant & 0x3f); 9905 %} 9906 9907 ins_pipe(ialu_reg_shift); 9908 %} 9909 9910 // Shift Right Logical Register 9911 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9912 match(Set dst (URShiftL src1 src2)); 9913 9914 ins_cost(INSN_COST * 2); 9915 format %{ "lsrv $dst, $src1, $src2" %} 9916 9917 ins_encode %{ 9918 __ lsrv(as_Register($dst$$reg), 9919 as_Register($src1$$reg), 9920 as_Register($src2$$reg)); 9921 %} 9922 9923 ins_pipe(ialu_reg_reg_vshift); 9924 %} 9925 9926 // Shift Right Logical Immediate 9927 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9928 match(Set dst (URShiftL src1 src2)); 9929 9930 ins_cost(INSN_COST); 9931 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 9932 9933 ins_encode %{ 9934 __ lsr(as_Register($dst$$reg), 9935 as_Register($src1$$reg), 9936 $src2$$constant & 0x3f); 9937 %} 9938 9939 ins_pipe(ialu_reg_shift); 9940 %} 9941 9942 // A special-case pattern for card table stores. 9943 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 9944 match(Set dst (URShiftL (CastP2X src1) src2)); 9945 9946 ins_cost(INSN_COST); 9947 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 9948 9949 ins_encode %{ 9950 __ lsr(as_Register($dst$$reg), 9951 as_Register($src1$$reg), 9952 $src2$$constant & 0x3f); 9953 %} 9954 9955 ins_pipe(ialu_reg_shift); 9956 %} 9957 9958 // Shift Right Arithmetic Register 9959 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9960 match(Set dst (RShiftL src1 src2)); 9961 9962 ins_cost(INSN_COST * 2); 9963 format %{ "asrv $dst, $src1, $src2" %} 9964 9965 ins_encode %{ 9966 __ asrv(as_Register($dst$$reg), 9967 as_Register($src1$$reg), 9968 as_Register($src2$$reg)); 9969 %} 9970 9971 ins_pipe(ialu_reg_reg_vshift); 9972 %} 9973 9974 // Shift Right Arithmetic Immediate 9975 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9976 match(Set dst (RShiftL src1 src2)); 9977 9978 ins_cost(INSN_COST); 9979 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 9980 9981 ins_encode %{ 9982 __ asr(as_Register($dst$$reg), 9983 as_Register($src1$$reg), 9984 $src2$$constant & 0x3f); 9985 %} 9986 9987 ins_pipe(ialu_reg_shift); 9988 %} 9989 9990 // BEGIN This section of the file is automatically generated. Do not edit -------------- 9991 9992 instruct regL_not_reg(iRegLNoSp dst, 9993 iRegL src1, immL_M1 m1, 9994 rFlagsReg cr) %{ 9995 match(Set dst (XorL src1 m1)); 9996 ins_cost(INSN_COST); 9997 format %{ "eon $dst, $src1, zr" %} 9998 9999 ins_encode %{ 10000 __ eon(as_Register($dst$$reg), 10001 as_Register($src1$$reg), 10002 zr, 10003 Assembler::LSL, 0); 10004 %} 10005 10006 ins_pipe(ialu_reg); 10007 %} 10008 instruct regI_not_reg(iRegINoSp dst, 10009 iRegIorL2I src1, immI_M1 m1, 10010 rFlagsReg cr) %{ 10011 match(Set dst (XorI src1 m1)); 10012 ins_cost(INSN_COST); 10013 format %{ "eonw $dst, $src1, zr" %} 10014 10015 ins_encode %{ 10016 __ eonw(as_Register($dst$$reg), 10017 as_Register($src1$$reg), 10018 zr, 10019 Assembler::LSL, 0); 10020 %} 10021 10022 ins_pipe(ialu_reg); 10023 %} 10024 10025 instruct AndI_reg_not_reg(iRegINoSp dst, 10026 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10027 rFlagsReg cr) %{ 10028 match(Set dst (AndI src1 (XorI src2 m1))); 10029 ins_cost(INSN_COST); 10030 format %{ "bicw $dst, $src1, $src2" %} 10031 10032 ins_encode %{ 10033 __ bicw(as_Register($dst$$reg), 10034 as_Register($src1$$reg), 10035 as_Register($src2$$reg), 10036 Assembler::LSL, 0); 10037 %} 10038 10039 ins_pipe(ialu_reg_reg); 10040 %} 10041 10042 instruct AndL_reg_not_reg(iRegLNoSp dst, 10043 iRegL src1, iRegL src2, immL_M1 m1, 10044 rFlagsReg cr) %{ 10045 match(Set dst (AndL src1 (XorL src2 m1))); 10046 ins_cost(INSN_COST); 10047 format %{ "bic $dst, $src1, $src2" %} 10048 10049 ins_encode %{ 10050 __ bic(as_Register($dst$$reg), 10051 as_Register($src1$$reg), 10052 as_Register($src2$$reg), 10053 Assembler::LSL, 0); 10054 %} 10055 10056 ins_pipe(ialu_reg_reg); 10057 %} 10058 10059 instruct OrI_reg_not_reg(iRegINoSp dst, 10060 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10061 rFlagsReg cr) %{ 10062 match(Set dst (OrI src1 (XorI src2 m1))); 10063 ins_cost(INSN_COST); 10064 format %{ "ornw $dst, $src1, $src2" %} 10065 10066 ins_encode %{ 10067 __ ornw(as_Register($dst$$reg), 10068 as_Register($src1$$reg), 10069 as_Register($src2$$reg), 10070 Assembler::LSL, 0); 10071 %} 10072 10073 ins_pipe(ialu_reg_reg); 10074 %} 10075 10076 instruct OrL_reg_not_reg(iRegLNoSp dst, 10077 iRegL src1, iRegL src2, immL_M1 m1, 10078 rFlagsReg cr) %{ 10079 match(Set dst (OrL src1 (XorL src2 m1))); 10080 ins_cost(INSN_COST); 10081 format %{ "orn $dst, $src1, $src2" %} 10082 10083 ins_encode %{ 10084 __ orn(as_Register($dst$$reg), 10085 as_Register($src1$$reg), 10086 as_Register($src2$$reg), 10087 Assembler::LSL, 0); 10088 %} 10089 10090 ins_pipe(ialu_reg_reg); 10091 %} 10092 10093 instruct XorI_reg_not_reg(iRegINoSp dst, 10094 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10095 rFlagsReg cr) %{ 10096 match(Set dst (XorI m1 (XorI src2 src1))); 10097 ins_cost(INSN_COST); 10098 format %{ "eonw $dst, $src1, $src2" %} 10099 10100 ins_encode %{ 10101 __ eonw(as_Register($dst$$reg), 10102 as_Register($src1$$reg), 10103 as_Register($src2$$reg), 10104 Assembler::LSL, 0); 10105 %} 10106 10107 ins_pipe(ialu_reg_reg); 10108 %} 10109 10110 instruct XorL_reg_not_reg(iRegLNoSp dst, 10111 iRegL src1, iRegL src2, immL_M1 m1, 10112 rFlagsReg cr) %{ 10113 match(Set dst (XorL m1 (XorL src2 src1))); 10114 ins_cost(INSN_COST); 10115 format %{ "eon $dst, $src1, $src2" %} 10116 10117 ins_encode %{ 10118 __ eon(as_Register($dst$$reg), 10119 as_Register($src1$$reg), 10120 as_Register($src2$$reg), 10121 Assembler::LSL, 0); 10122 %} 10123 10124 ins_pipe(ialu_reg_reg); 10125 %} 10126 10127 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10128 iRegIorL2I src1, iRegIorL2I src2, 10129 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10130 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10131 ins_cost(1.9 * INSN_COST); 10132 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10133 10134 ins_encode %{ 10135 __ bicw(as_Register($dst$$reg), 10136 as_Register($src1$$reg), 10137 as_Register($src2$$reg), 10138 Assembler::LSR, 10139 $src3$$constant & 0x1f); 10140 %} 10141 10142 ins_pipe(ialu_reg_reg_shift); 10143 %} 10144 10145 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10146 iRegL src1, iRegL src2, 10147 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10148 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10149 ins_cost(1.9 * INSN_COST); 10150 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10151 10152 ins_encode %{ 10153 __ bic(as_Register($dst$$reg), 10154 as_Register($src1$$reg), 10155 as_Register($src2$$reg), 10156 Assembler::LSR, 10157 $src3$$constant & 0x3f); 10158 %} 10159 10160 ins_pipe(ialu_reg_reg_shift); 10161 %} 10162 10163 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10164 iRegIorL2I src1, iRegIorL2I src2, 10165 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10166 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10167 ins_cost(1.9 * INSN_COST); 10168 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10169 10170 ins_encode %{ 10171 __ bicw(as_Register($dst$$reg), 10172 as_Register($src1$$reg), 10173 as_Register($src2$$reg), 10174 Assembler::ASR, 10175 $src3$$constant & 0x1f); 10176 %} 10177 10178 ins_pipe(ialu_reg_reg_shift); 10179 %} 10180 10181 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10182 iRegL src1, iRegL src2, 10183 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10184 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10185 ins_cost(1.9 * INSN_COST); 10186 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10187 10188 ins_encode %{ 10189 __ bic(as_Register($dst$$reg), 10190 as_Register($src1$$reg), 10191 as_Register($src2$$reg), 10192 Assembler::ASR, 10193 $src3$$constant & 0x3f); 10194 %} 10195 10196 ins_pipe(ialu_reg_reg_shift); 10197 %} 10198 10199 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10200 iRegIorL2I src1, iRegIorL2I src2, 10201 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10202 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10203 ins_cost(1.9 * INSN_COST); 10204 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10205 10206 ins_encode %{ 10207 __ bicw(as_Register($dst$$reg), 10208 as_Register($src1$$reg), 10209 as_Register($src2$$reg), 10210 Assembler::LSL, 10211 $src3$$constant & 0x1f); 10212 %} 10213 10214 ins_pipe(ialu_reg_reg_shift); 10215 %} 10216 10217 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10218 iRegL src1, iRegL src2, 10219 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10220 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10221 ins_cost(1.9 * INSN_COST); 10222 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10223 10224 ins_encode %{ 10225 __ bic(as_Register($dst$$reg), 10226 as_Register($src1$$reg), 10227 as_Register($src2$$reg), 10228 Assembler::LSL, 10229 $src3$$constant & 0x3f); 10230 %} 10231 10232 ins_pipe(ialu_reg_reg_shift); 10233 %} 10234 10235 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10236 iRegIorL2I src1, iRegIorL2I src2, 10237 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10238 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10239 ins_cost(1.9 * INSN_COST); 10240 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10241 10242 ins_encode %{ 10243 __ eonw(as_Register($dst$$reg), 10244 as_Register($src1$$reg), 10245 as_Register($src2$$reg), 10246 Assembler::LSR, 10247 $src3$$constant & 0x1f); 10248 %} 10249 10250 ins_pipe(ialu_reg_reg_shift); 10251 %} 10252 10253 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10254 iRegL src1, iRegL src2, 10255 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10256 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10257 ins_cost(1.9 * INSN_COST); 10258 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10259 10260 ins_encode %{ 10261 __ eon(as_Register($dst$$reg), 10262 as_Register($src1$$reg), 10263 as_Register($src2$$reg), 10264 Assembler::LSR, 10265 $src3$$constant & 0x3f); 10266 %} 10267 10268 ins_pipe(ialu_reg_reg_shift); 10269 %} 10270 10271 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10272 iRegIorL2I src1, iRegIorL2I src2, 10273 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10274 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10275 ins_cost(1.9 * INSN_COST); 10276 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10277 10278 ins_encode %{ 10279 __ eonw(as_Register($dst$$reg), 10280 as_Register($src1$$reg), 10281 as_Register($src2$$reg), 10282 Assembler::ASR, 10283 $src3$$constant & 0x1f); 10284 %} 10285 10286 ins_pipe(ialu_reg_reg_shift); 10287 %} 10288 10289 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10290 iRegL src1, iRegL src2, 10291 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10292 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10293 ins_cost(1.9 * INSN_COST); 10294 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10295 10296 ins_encode %{ 10297 __ eon(as_Register($dst$$reg), 10298 as_Register($src1$$reg), 10299 as_Register($src2$$reg), 10300 Assembler::ASR, 10301 $src3$$constant & 0x3f); 10302 %} 10303 10304 ins_pipe(ialu_reg_reg_shift); 10305 %} 10306 10307 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10308 iRegIorL2I src1, iRegIorL2I src2, 10309 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10310 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10311 ins_cost(1.9 * INSN_COST); 10312 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10313 10314 ins_encode %{ 10315 __ eonw(as_Register($dst$$reg), 10316 as_Register($src1$$reg), 10317 as_Register($src2$$reg), 10318 Assembler::LSL, 10319 $src3$$constant & 0x1f); 10320 %} 10321 10322 ins_pipe(ialu_reg_reg_shift); 10323 %} 10324 10325 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10326 iRegL src1, iRegL src2, 10327 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10328 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10329 ins_cost(1.9 * INSN_COST); 10330 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10331 10332 ins_encode %{ 10333 __ eon(as_Register($dst$$reg), 10334 as_Register($src1$$reg), 10335 as_Register($src2$$reg), 10336 Assembler::LSL, 10337 $src3$$constant & 0x3f); 10338 %} 10339 10340 ins_pipe(ialu_reg_reg_shift); 10341 %} 10342 10343 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10344 iRegIorL2I src1, iRegIorL2I src2, 10345 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10346 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10347 ins_cost(1.9 * INSN_COST); 10348 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10349 10350 ins_encode %{ 10351 __ ornw(as_Register($dst$$reg), 10352 as_Register($src1$$reg), 10353 as_Register($src2$$reg), 10354 Assembler::LSR, 10355 $src3$$constant & 0x1f); 10356 %} 10357 10358 ins_pipe(ialu_reg_reg_shift); 10359 %} 10360 10361 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10362 iRegL src1, iRegL src2, 10363 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10364 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10365 ins_cost(1.9 * INSN_COST); 10366 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10367 10368 ins_encode %{ 10369 __ orn(as_Register($dst$$reg), 10370 as_Register($src1$$reg), 10371 as_Register($src2$$reg), 10372 Assembler::LSR, 10373 $src3$$constant & 0x3f); 10374 %} 10375 10376 ins_pipe(ialu_reg_reg_shift); 10377 %} 10378 10379 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10380 iRegIorL2I src1, iRegIorL2I src2, 10381 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10382 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10383 ins_cost(1.9 * INSN_COST); 10384 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10385 10386 ins_encode %{ 10387 __ ornw(as_Register($dst$$reg), 10388 as_Register($src1$$reg), 10389 as_Register($src2$$reg), 10390 Assembler::ASR, 10391 $src3$$constant & 0x1f); 10392 %} 10393 10394 ins_pipe(ialu_reg_reg_shift); 10395 %} 10396 10397 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10398 iRegL src1, iRegL src2, 10399 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10400 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10401 ins_cost(1.9 * INSN_COST); 10402 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10403 10404 ins_encode %{ 10405 __ orn(as_Register($dst$$reg), 10406 as_Register($src1$$reg), 10407 as_Register($src2$$reg), 10408 Assembler::ASR, 10409 $src3$$constant & 0x3f); 10410 %} 10411 10412 ins_pipe(ialu_reg_reg_shift); 10413 %} 10414 10415 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10416 iRegIorL2I src1, iRegIorL2I src2, 10417 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10418 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10419 ins_cost(1.9 * INSN_COST); 10420 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10421 10422 ins_encode %{ 10423 __ ornw(as_Register($dst$$reg), 10424 as_Register($src1$$reg), 10425 as_Register($src2$$reg), 10426 Assembler::LSL, 10427 $src3$$constant & 0x1f); 10428 %} 10429 10430 ins_pipe(ialu_reg_reg_shift); 10431 %} 10432 10433 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10434 iRegL src1, iRegL src2, 10435 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10436 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10437 ins_cost(1.9 * INSN_COST); 10438 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10439 10440 ins_encode %{ 10441 __ orn(as_Register($dst$$reg), 10442 as_Register($src1$$reg), 10443 as_Register($src2$$reg), 10444 Assembler::LSL, 10445 $src3$$constant & 0x3f); 10446 %} 10447 10448 ins_pipe(ialu_reg_reg_shift); 10449 %} 10450 10451 instruct AndI_reg_URShift_reg(iRegINoSp dst, 10452 iRegIorL2I src1, iRegIorL2I src2, 10453 immI src3, rFlagsReg cr) %{ 10454 match(Set dst (AndI src1 (URShiftI src2 src3))); 10455 10456 ins_cost(1.9 * INSN_COST); 10457 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10458 10459 ins_encode %{ 10460 __ andw(as_Register($dst$$reg), 10461 as_Register($src1$$reg), 10462 as_Register($src2$$reg), 10463 Assembler::LSR, 10464 $src3$$constant & 0x1f); 10465 %} 10466 10467 ins_pipe(ialu_reg_reg_shift); 10468 %} 10469 10470 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 10471 iRegL src1, iRegL src2, 10472 immI src3, rFlagsReg cr) %{ 10473 match(Set dst (AndL src1 (URShiftL src2 src3))); 10474 10475 ins_cost(1.9 * INSN_COST); 10476 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10477 10478 ins_encode %{ 10479 __ andr(as_Register($dst$$reg), 10480 as_Register($src1$$reg), 10481 as_Register($src2$$reg), 10482 Assembler::LSR, 10483 $src3$$constant & 0x3f); 10484 %} 10485 10486 ins_pipe(ialu_reg_reg_shift); 10487 %} 10488 10489 instruct AndI_reg_RShift_reg(iRegINoSp dst, 10490 iRegIorL2I src1, iRegIorL2I src2, 10491 immI src3, rFlagsReg cr) %{ 10492 match(Set dst (AndI src1 (RShiftI src2 src3))); 10493 10494 ins_cost(1.9 * INSN_COST); 10495 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10496 10497 ins_encode %{ 10498 __ andw(as_Register($dst$$reg), 10499 as_Register($src1$$reg), 10500 as_Register($src2$$reg), 10501 Assembler::ASR, 10502 $src3$$constant & 0x1f); 10503 %} 10504 10505 ins_pipe(ialu_reg_reg_shift); 10506 %} 10507 10508 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10509 iRegL src1, iRegL src2, 10510 immI src3, rFlagsReg cr) %{ 10511 match(Set dst (AndL src1 (RShiftL src2 src3))); 10512 10513 ins_cost(1.9 * INSN_COST); 10514 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10515 10516 ins_encode %{ 10517 __ andr(as_Register($dst$$reg), 10518 as_Register($src1$$reg), 10519 as_Register($src2$$reg), 10520 Assembler::ASR, 10521 $src3$$constant & 0x3f); 10522 %} 10523 10524 ins_pipe(ialu_reg_reg_shift); 10525 %} 10526 10527 instruct AndI_reg_LShift_reg(iRegINoSp dst, 10528 iRegIorL2I src1, iRegIorL2I src2, 10529 immI src3, rFlagsReg cr) %{ 10530 match(Set dst (AndI src1 (LShiftI src2 src3))); 10531 10532 ins_cost(1.9 * INSN_COST); 10533 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10534 10535 ins_encode %{ 10536 __ andw(as_Register($dst$$reg), 10537 as_Register($src1$$reg), 10538 as_Register($src2$$reg), 10539 Assembler::LSL, 10540 $src3$$constant & 0x1f); 10541 %} 10542 10543 ins_pipe(ialu_reg_reg_shift); 10544 %} 10545 10546 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10547 iRegL src1, iRegL src2, 10548 immI src3, rFlagsReg cr) %{ 10549 match(Set dst (AndL src1 (LShiftL src2 src3))); 10550 10551 ins_cost(1.9 * INSN_COST); 10552 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10553 10554 ins_encode %{ 10555 __ andr(as_Register($dst$$reg), 10556 as_Register($src1$$reg), 10557 as_Register($src2$$reg), 10558 Assembler::LSL, 10559 $src3$$constant & 0x3f); 10560 %} 10561 10562 ins_pipe(ialu_reg_reg_shift); 10563 %} 10564 10565 instruct XorI_reg_URShift_reg(iRegINoSp dst, 10566 iRegIorL2I src1, iRegIorL2I src2, 10567 immI src3, rFlagsReg cr) %{ 10568 match(Set dst (XorI src1 (URShiftI src2 src3))); 10569 10570 ins_cost(1.9 * INSN_COST); 10571 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10572 10573 ins_encode %{ 10574 __ eorw(as_Register($dst$$reg), 10575 as_Register($src1$$reg), 10576 as_Register($src2$$reg), 10577 Assembler::LSR, 10578 $src3$$constant & 0x1f); 10579 %} 10580 10581 ins_pipe(ialu_reg_reg_shift); 10582 %} 10583 10584 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10585 iRegL src1, iRegL src2, 10586 immI src3, rFlagsReg cr) %{ 10587 match(Set dst (XorL src1 (URShiftL src2 src3))); 10588 10589 ins_cost(1.9 * INSN_COST); 10590 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10591 10592 ins_encode %{ 10593 __ eor(as_Register($dst$$reg), 10594 as_Register($src1$$reg), 10595 as_Register($src2$$reg), 10596 Assembler::LSR, 10597 $src3$$constant & 0x3f); 10598 %} 10599 10600 ins_pipe(ialu_reg_reg_shift); 10601 %} 10602 10603 instruct XorI_reg_RShift_reg(iRegINoSp dst, 10604 iRegIorL2I src1, iRegIorL2I src2, 10605 immI src3, rFlagsReg cr) %{ 10606 match(Set dst (XorI src1 (RShiftI src2 src3))); 10607 10608 ins_cost(1.9 * INSN_COST); 10609 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10610 10611 ins_encode %{ 10612 __ eorw(as_Register($dst$$reg), 10613 as_Register($src1$$reg), 10614 as_Register($src2$$reg), 10615 Assembler::ASR, 10616 $src3$$constant & 0x1f); 10617 %} 10618 10619 ins_pipe(ialu_reg_reg_shift); 10620 %} 10621 10622 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10623 iRegL src1, iRegL src2, 10624 immI src3, rFlagsReg cr) %{ 10625 match(Set dst (XorL src1 (RShiftL src2 src3))); 10626 10627 ins_cost(1.9 * INSN_COST); 10628 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10629 10630 ins_encode %{ 10631 __ eor(as_Register($dst$$reg), 10632 as_Register($src1$$reg), 10633 as_Register($src2$$reg), 10634 Assembler::ASR, 10635 $src3$$constant & 0x3f); 10636 %} 10637 10638 ins_pipe(ialu_reg_reg_shift); 10639 %} 10640 10641 instruct XorI_reg_LShift_reg(iRegINoSp dst, 10642 iRegIorL2I src1, iRegIorL2I src2, 10643 immI src3, rFlagsReg cr) %{ 10644 match(Set dst (XorI src1 (LShiftI src2 src3))); 10645 10646 ins_cost(1.9 * INSN_COST); 10647 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10648 10649 ins_encode %{ 10650 __ eorw(as_Register($dst$$reg), 10651 as_Register($src1$$reg), 10652 as_Register($src2$$reg), 10653 Assembler::LSL, 10654 $src3$$constant & 0x1f); 10655 %} 10656 10657 ins_pipe(ialu_reg_reg_shift); 10658 %} 10659 10660 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 10661 iRegL src1, iRegL src2, 10662 immI src3, rFlagsReg cr) %{ 10663 match(Set dst (XorL src1 (LShiftL src2 src3))); 10664 10665 ins_cost(1.9 * INSN_COST); 10666 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 10667 10668 ins_encode %{ 10669 __ eor(as_Register($dst$$reg), 10670 as_Register($src1$$reg), 10671 as_Register($src2$$reg), 10672 Assembler::LSL, 10673 $src3$$constant & 0x3f); 10674 %} 10675 10676 ins_pipe(ialu_reg_reg_shift); 10677 %} 10678 10679 instruct OrI_reg_URShift_reg(iRegINoSp dst, 10680 iRegIorL2I src1, iRegIorL2I src2, 10681 immI src3, rFlagsReg cr) %{ 10682 match(Set dst (OrI src1 (URShiftI src2 src3))); 10683 10684 ins_cost(1.9 * INSN_COST); 10685 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 10686 10687 ins_encode %{ 10688 __ orrw(as_Register($dst$$reg), 10689 as_Register($src1$$reg), 10690 as_Register($src2$$reg), 10691 Assembler::LSR, 10692 $src3$$constant & 0x1f); 10693 %} 10694 10695 ins_pipe(ialu_reg_reg_shift); 10696 %} 10697 10698 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 10699 iRegL src1, iRegL src2, 10700 immI src3, rFlagsReg cr) %{ 10701 match(Set dst (OrL src1 (URShiftL src2 src3))); 10702 10703 ins_cost(1.9 * INSN_COST); 10704 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 10705 10706 ins_encode %{ 10707 __ orr(as_Register($dst$$reg), 10708 as_Register($src1$$reg), 10709 as_Register($src2$$reg), 10710 Assembler::LSR, 10711 $src3$$constant & 0x3f); 10712 %} 10713 10714 ins_pipe(ialu_reg_reg_shift); 10715 %} 10716 10717 instruct OrI_reg_RShift_reg(iRegINoSp dst, 10718 iRegIorL2I src1, iRegIorL2I src2, 10719 immI src3, rFlagsReg cr) %{ 10720 match(Set dst (OrI src1 (RShiftI src2 src3))); 10721 10722 ins_cost(1.9 * INSN_COST); 10723 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 10724 10725 ins_encode %{ 10726 __ orrw(as_Register($dst$$reg), 10727 as_Register($src1$$reg), 10728 as_Register($src2$$reg), 10729 Assembler::ASR, 10730 $src3$$constant & 0x1f); 10731 %} 10732 10733 ins_pipe(ialu_reg_reg_shift); 10734 %} 10735 10736 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 10737 iRegL src1, iRegL src2, 10738 immI src3, rFlagsReg cr) %{ 10739 match(Set dst (OrL src1 (RShiftL src2 src3))); 10740 10741 ins_cost(1.9 * INSN_COST); 10742 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 10743 10744 ins_encode %{ 10745 __ orr(as_Register($dst$$reg), 10746 as_Register($src1$$reg), 10747 as_Register($src2$$reg), 10748 Assembler::ASR, 10749 $src3$$constant & 0x3f); 10750 %} 10751 10752 ins_pipe(ialu_reg_reg_shift); 10753 %} 10754 10755 instruct OrI_reg_LShift_reg(iRegINoSp dst, 10756 iRegIorL2I src1, iRegIorL2I src2, 10757 immI src3, rFlagsReg cr) %{ 10758 match(Set dst (OrI src1 (LShiftI src2 src3))); 10759 10760 ins_cost(1.9 * INSN_COST); 10761 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 10762 10763 ins_encode %{ 10764 __ orrw(as_Register($dst$$reg), 10765 as_Register($src1$$reg), 10766 as_Register($src2$$reg), 10767 Assembler::LSL, 10768 $src3$$constant & 0x1f); 10769 %} 10770 10771 ins_pipe(ialu_reg_reg_shift); 10772 %} 10773 10774 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 10775 iRegL src1, iRegL src2, 10776 immI src3, rFlagsReg cr) %{ 10777 match(Set dst (OrL src1 (LShiftL src2 src3))); 10778 10779 ins_cost(1.9 * INSN_COST); 10780 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 10781 10782 ins_encode %{ 10783 __ orr(as_Register($dst$$reg), 10784 as_Register($src1$$reg), 10785 as_Register($src2$$reg), 10786 Assembler::LSL, 10787 $src3$$constant & 0x3f); 10788 %} 10789 10790 ins_pipe(ialu_reg_reg_shift); 10791 %} 10792 10793 instruct AddI_reg_URShift_reg(iRegINoSp dst, 10794 iRegIorL2I src1, iRegIorL2I src2, 10795 immI src3, rFlagsReg cr) %{ 10796 match(Set dst (AddI src1 (URShiftI src2 src3))); 10797 10798 ins_cost(1.9 * INSN_COST); 10799 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 10800 10801 ins_encode %{ 10802 __ addw(as_Register($dst$$reg), 10803 as_Register($src1$$reg), 10804 as_Register($src2$$reg), 10805 Assembler::LSR, 10806 $src3$$constant & 0x1f); 10807 %} 10808 10809 ins_pipe(ialu_reg_reg_shift); 10810 %} 10811 10812 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 10813 iRegL src1, iRegL src2, 10814 immI src3, rFlagsReg cr) %{ 10815 match(Set dst (AddL src1 (URShiftL src2 src3))); 10816 10817 ins_cost(1.9 * INSN_COST); 10818 format %{ "add $dst, $src1, $src2, LSR $src3" %} 10819 10820 ins_encode %{ 10821 __ add(as_Register($dst$$reg), 10822 as_Register($src1$$reg), 10823 as_Register($src2$$reg), 10824 Assembler::LSR, 10825 $src3$$constant & 0x3f); 10826 %} 10827 10828 ins_pipe(ialu_reg_reg_shift); 10829 %} 10830 10831 instruct AddI_reg_RShift_reg(iRegINoSp dst, 10832 iRegIorL2I src1, iRegIorL2I src2, 10833 immI src3, rFlagsReg cr) %{ 10834 match(Set dst (AddI src1 (RShiftI src2 src3))); 10835 10836 ins_cost(1.9 * INSN_COST); 10837 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 10838 10839 ins_encode %{ 10840 __ addw(as_Register($dst$$reg), 10841 as_Register($src1$$reg), 10842 as_Register($src2$$reg), 10843 Assembler::ASR, 10844 $src3$$constant & 0x1f); 10845 %} 10846 10847 ins_pipe(ialu_reg_reg_shift); 10848 %} 10849 10850 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 10851 iRegL src1, iRegL src2, 10852 immI src3, rFlagsReg cr) %{ 10853 match(Set dst (AddL src1 (RShiftL src2 src3))); 10854 10855 ins_cost(1.9 * INSN_COST); 10856 format %{ "add $dst, $src1, $src2, ASR $src3" %} 10857 10858 ins_encode %{ 10859 __ add(as_Register($dst$$reg), 10860 as_Register($src1$$reg), 10861 as_Register($src2$$reg), 10862 Assembler::ASR, 10863 $src3$$constant & 0x3f); 10864 %} 10865 10866 ins_pipe(ialu_reg_reg_shift); 10867 %} 10868 10869 instruct AddI_reg_LShift_reg(iRegINoSp dst, 10870 iRegIorL2I src1, iRegIorL2I src2, 10871 immI src3, rFlagsReg cr) %{ 10872 match(Set dst (AddI src1 (LShiftI src2 src3))); 10873 10874 ins_cost(1.9 * INSN_COST); 10875 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 10876 10877 ins_encode %{ 10878 __ addw(as_Register($dst$$reg), 10879 as_Register($src1$$reg), 10880 as_Register($src2$$reg), 10881 Assembler::LSL, 10882 $src3$$constant & 0x1f); 10883 %} 10884 10885 ins_pipe(ialu_reg_reg_shift); 10886 %} 10887 10888 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 10889 iRegL src1, iRegL src2, 10890 immI src3, rFlagsReg cr) %{ 10891 match(Set dst (AddL src1 (LShiftL src2 src3))); 10892 10893 ins_cost(1.9 * INSN_COST); 10894 format %{ "add $dst, $src1, $src2, LSL $src3" %} 10895 10896 ins_encode %{ 10897 __ add(as_Register($dst$$reg), 10898 as_Register($src1$$reg), 10899 as_Register($src2$$reg), 10900 Assembler::LSL, 10901 $src3$$constant & 0x3f); 10902 %} 10903 10904 ins_pipe(ialu_reg_reg_shift); 10905 %} 10906 10907 instruct SubI_reg_URShift_reg(iRegINoSp dst, 10908 iRegIorL2I src1, iRegIorL2I src2, 10909 immI src3, rFlagsReg cr) %{ 10910 match(Set dst (SubI src1 (URShiftI src2 src3))); 10911 10912 ins_cost(1.9 * INSN_COST); 10913 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 10914 10915 ins_encode %{ 10916 __ subw(as_Register($dst$$reg), 10917 as_Register($src1$$reg), 10918 as_Register($src2$$reg), 10919 Assembler::LSR, 10920 $src3$$constant & 0x1f); 10921 %} 10922 10923 ins_pipe(ialu_reg_reg_shift); 10924 %} 10925 10926 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 10927 iRegL src1, iRegL src2, 10928 immI src3, rFlagsReg cr) %{ 10929 match(Set dst (SubL src1 (URShiftL src2 src3))); 10930 10931 ins_cost(1.9 * INSN_COST); 10932 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 10933 10934 ins_encode %{ 10935 __ sub(as_Register($dst$$reg), 10936 as_Register($src1$$reg), 10937 as_Register($src2$$reg), 10938 Assembler::LSR, 10939 $src3$$constant & 0x3f); 10940 %} 10941 10942 ins_pipe(ialu_reg_reg_shift); 10943 %} 10944 10945 instruct SubI_reg_RShift_reg(iRegINoSp dst, 10946 iRegIorL2I src1, iRegIorL2I src2, 10947 immI src3, rFlagsReg cr) %{ 10948 match(Set dst (SubI src1 (RShiftI src2 src3))); 10949 10950 ins_cost(1.9 * INSN_COST); 10951 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 10952 10953 ins_encode %{ 10954 __ subw(as_Register($dst$$reg), 10955 as_Register($src1$$reg), 10956 as_Register($src2$$reg), 10957 Assembler::ASR, 10958 $src3$$constant & 0x1f); 10959 %} 10960 10961 ins_pipe(ialu_reg_reg_shift); 10962 %} 10963 10964 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 10965 iRegL src1, iRegL src2, 10966 immI src3, rFlagsReg cr) %{ 10967 match(Set dst (SubL src1 (RShiftL src2 src3))); 10968 10969 ins_cost(1.9 * INSN_COST); 10970 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 10971 10972 ins_encode %{ 10973 __ sub(as_Register($dst$$reg), 10974 as_Register($src1$$reg), 10975 as_Register($src2$$reg), 10976 Assembler::ASR, 10977 $src3$$constant & 0x3f); 10978 %} 10979 10980 ins_pipe(ialu_reg_reg_shift); 10981 %} 10982 10983 instruct SubI_reg_LShift_reg(iRegINoSp dst, 10984 iRegIorL2I src1, iRegIorL2I src2, 10985 immI src3, rFlagsReg cr) %{ 10986 match(Set dst (SubI src1 (LShiftI src2 src3))); 10987 10988 ins_cost(1.9 * INSN_COST); 10989 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 10990 10991 ins_encode %{ 10992 __ subw(as_Register($dst$$reg), 10993 as_Register($src1$$reg), 10994 as_Register($src2$$reg), 10995 Assembler::LSL, 10996 $src3$$constant & 0x1f); 10997 %} 10998 10999 ins_pipe(ialu_reg_reg_shift); 11000 %} 11001 11002 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11003 iRegL src1, iRegL src2, 11004 immI src3, rFlagsReg cr) %{ 11005 match(Set dst (SubL src1 (LShiftL src2 src3))); 11006 11007 ins_cost(1.9 * INSN_COST); 11008 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11009 11010 ins_encode %{ 11011 __ sub(as_Register($dst$$reg), 11012 as_Register($src1$$reg), 11013 as_Register($src2$$reg), 11014 Assembler::LSL, 11015 $src3$$constant & 0x3f); 11016 %} 11017 11018 ins_pipe(ialu_reg_reg_shift); 11019 %} 11020 11021 11022 11023 // Shift Left followed by Shift Right. 11024 // This idiom is used by the compiler for the i2b bytecode etc. 11025 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11026 %{ 11027 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11028 // Make sure we are not going to exceed what sbfm can do. 11029 predicate((unsigned int)n->in(2)->get_int() <= 63 11030 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11031 11032 ins_cost(INSN_COST * 2); 11033 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11034 ins_encode %{ 11035 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11036 int s = 63 - lshift; 11037 int r = (rshift - lshift) & 63; 11038 __ sbfm(as_Register($dst$$reg), 11039 as_Register($src$$reg), 11040 r, s); 11041 %} 11042 11043 ins_pipe(ialu_reg_shift); 11044 %} 11045 11046 // Shift Left followed by Shift Right. 11047 // This idiom is used by the compiler for the i2b bytecode etc. 11048 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11049 %{ 11050 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11051 // Make sure we are not going to exceed what sbfmw can do. 11052 predicate((unsigned int)n->in(2)->get_int() <= 31 11053 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11054 11055 ins_cost(INSN_COST * 2); 11056 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11057 ins_encode %{ 11058 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11059 int s = 31 - lshift; 11060 int r = (rshift - lshift) & 31; 11061 __ sbfmw(as_Register($dst$$reg), 11062 as_Register($src$$reg), 11063 r, s); 11064 %} 11065 11066 ins_pipe(ialu_reg_shift); 11067 %} 11068 11069 // Shift Left followed by Shift Right. 11070 // This idiom is used by the compiler for the i2b bytecode etc. 11071 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11072 %{ 11073 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11074 // Make sure we are not going to exceed what ubfm can do. 11075 predicate((unsigned int)n->in(2)->get_int() <= 63 11076 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11077 11078 ins_cost(INSN_COST * 2); 11079 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11080 ins_encode %{ 11081 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11082 int s = 63 - lshift; 11083 int r = (rshift - lshift) & 63; 11084 __ ubfm(as_Register($dst$$reg), 11085 as_Register($src$$reg), 11086 r, s); 11087 %} 11088 11089 ins_pipe(ialu_reg_shift); 11090 %} 11091 11092 // Shift Left followed by Shift Right. 11093 // This idiom is used by the compiler for the i2b bytecode etc. 11094 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11095 %{ 11096 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11097 // Make sure we are not going to exceed what ubfmw can do. 11098 predicate((unsigned int)n->in(2)->get_int() <= 31 11099 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11100 11101 ins_cost(INSN_COST * 2); 11102 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11103 ins_encode %{ 11104 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11105 int s = 31 - lshift; 11106 int r = (rshift - lshift) & 31; 11107 __ ubfmw(as_Register($dst$$reg), 11108 as_Register($src$$reg), 11109 r, s); 11110 %} 11111 11112 ins_pipe(ialu_reg_shift); 11113 %} 11114 // Bitfield extract with shift & mask 11115 11116 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11117 %{ 11118 match(Set dst (AndI (URShiftI src rshift) mask)); 11119 11120 ins_cost(INSN_COST); 11121 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11122 ins_encode %{ 11123 int rshift = $rshift$$constant; 11124 long mask = $mask$$constant; 11125 int width = exact_log2(mask+1); 11126 __ ubfxw(as_Register($dst$$reg), 11127 as_Register($src$$reg), rshift, width); 11128 %} 11129 ins_pipe(ialu_reg_shift); 11130 %} 11131 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11132 %{ 11133 match(Set dst (AndL (URShiftL src rshift) mask)); 11134 11135 ins_cost(INSN_COST); 11136 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11137 ins_encode %{ 11138 int rshift = $rshift$$constant; 11139 long mask = $mask$$constant; 11140 int width = exact_log2(mask+1); 11141 __ ubfx(as_Register($dst$$reg), 11142 as_Register($src$$reg), rshift, width); 11143 %} 11144 ins_pipe(ialu_reg_shift); 11145 %} 11146 11147 // We can use ubfx when extending an And with a mask when we know mask 11148 // is positive. We know that because immI_bitmask guarantees it. 11149 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11150 %{ 11151 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11152 11153 ins_cost(INSN_COST * 2); 11154 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11155 ins_encode %{ 11156 int rshift = $rshift$$constant; 11157 long mask = $mask$$constant; 11158 int width = exact_log2(mask+1); 11159 __ ubfx(as_Register($dst$$reg), 11160 as_Register($src$$reg), rshift, width); 11161 %} 11162 ins_pipe(ialu_reg_shift); 11163 %} 11164 11165 // We can use ubfiz when masking by a positive number and then left shifting the result. 11166 // We know that the mask is positive because immI_bitmask guarantees it. 11167 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11168 %{ 11169 match(Set dst (LShiftI (AndI src mask) lshift)); 11170 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11171 (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1)); 11172 11173 ins_cost(INSN_COST); 11174 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11175 ins_encode %{ 11176 int lshift = $lshift$$constant; 11177 long mask = $mask$$constant; 11178 int width = exact_log2(mask+1); 11179 __ ubfizw(as_Register($dst$$reg), 11180 as_Register($src$$reg), lshift, width); 11181 %} 11182 ins_pipe(ialu_reg_shift); 11183 %} 11184 // We can use ubfiz when masking by a positive number and then left shifting the result. 11185 // We know that the mask is positive because immL_bitmask guarantees it. 11186 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11187 %{ 11188 match(Set dst (LShiftL (AndL src mask) lshift)); 11189 predicate((unsigned int)n->in(2)->get_int() <= 63 && 11190 (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1)); 11191 11192 ins_cost(INSN_COST); 11193 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11194 ins_encode %{ 11195 int lshift = $lshift$$constant; 11196 long mask = $mask$$constant; 11197 int width = exact_log2(mask+1); 11198 __ ubfiz(as_Register($dst$$reg), 11199 as_Register($src$$reg), lshift, width); 11200 %} 11201 ins_pipe(ialu_reg_shift); 11202 %} 11203 11204 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11205 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11206 %{ 11207 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); 11208 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11209 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); 11210 11211 ins_cost(INSN_COST); 11212 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11213 ins_encode %{ 11214 int lshift = $lshift$$constant; 11215 long mask = $mask$$constant; 11216 int width = exact_log2(mask+1); 11217 __ ubfiz(as_Register($dst$$reg), 11218 as_Register($src$$reg), lshift, width); 11219 %} 11220 ins_pipe(ialu_reg_shift); 11221 %} 11222 11223 // Rotations 11224 11225 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11226 %{ 11227 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11228 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11229 11230 ins_cost(INSN_COST); 11231 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11232 11233 ins_encode %{ 11234 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11235 $rshift$$constant & 63); 11236 %} 11237 ins_pipe(ialu_reg_reg_extr); 11238 %} 11239 11240 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11241 %{ 11242 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11243 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11244 11245 ins_cost(INSN_COST); 11246 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11247 11248 ins_encode %{ 11249 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11250 $rshift$$constant & 31); 11251 %} 11252 ins_pipe(ialu_reg_reg_extr); 11253 %} 11254 11255 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11256 %{ 11257 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11258 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11259 11260 ins_cost(INSN_COST); 11261 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11262 11263 ins_encode %{ 11264 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11265 $rshift$$constant & 63); 11266 %} 11267 ins_pipe(ialu_reg_reg_extr); 11268 %} 11269 11270 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11271 %{ 11272 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11273 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11274 11275 ins_cost(INSN_COST); 11276 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11277 11278 ins_encode %{ 11279 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11280 $rshift$$constant & 31); 11281 %} 11282 ins_pipe(ialu_reg_reg_extr); 11283 %} 11284 11285 11286 // rol expander 11287 11288 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11289 %{ 11290 effect(DEF dst, USE src, USE shift); 11291 11292 format %{ "rol $dst, $src, $shift" %} 11293 ins_cost(INSN_COST * 3); 11294 ins_encode %{ 11295 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11296 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11297 rscratch1); 11298 %} 11299 ins_pipe(ialu_reg_reg_vshift); 11300 %} 11301 11302 // rol expander 11303 11304 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11305 %{ 11306 effect(DEF dst, USE src, USE shift); 11307 11308 format %{ "rol $dst, $src, $shift" %} 11309 ins_cost(INSN_COST * 3); 11310 ins_encode %{ 11311 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11312 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11313 rscratch1); 11314 %} 11315 ins_pipe(ialu_reg_reg_vshift); 11316 %} 11317 11318 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11319 %{ 11320 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11321 11322 expand %{ 11323 rolL_rReg(dst, src, shift, cr); 11324 %} 11325 %} 11326 11327 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11328 %{ 11329 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11330 11331 expand %{ 11332 rolL_rReg(dst, src, shift, cr); 11333 %} 11334 %} 11335 11336 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11337 %{ 11338 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11339 11340 expand %{ 11341 rolI_rReg(dst, src, shift, cr); 11342 %} 11343 %} 11344 11345 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11346 %{ 11347 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11348 11349 expand %{ 11350 rolI_rReg(dst, src, shift, cr); 11351 %} 11352 %} 11353 11354 // ror expander 11355 11356 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11357 %{ 11358 effect(DEF dst, USE src, USE shift); 11359 11360 format %{ "ror $dst, $src, $shift" %} 11361 ins_cost(INSN_COST); 11362 ins_encode %{ 11363 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11364 as_Register($shift$$reg)); 11365 %} 11366 ins_pipe(ialu_reg_reg_vshift); 11367 %} 11368 11369 // ror expander 11370 11371 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11372 %{ 11373 effect(DEF dst, USE src, USE shift); 11374 11375 format %{ "ror $dst, $src, $shift" %} 11376 ins_cost(INSN_COST); 11377 ins_encode %{ 11378 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11379 as_Register($shift$$reg)); 11380 %} 11381 ins_pipe(ialu_reg_reg_vshift); 11382 %} 11383 11384 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11385 %{ 11386 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11387 11388 expand %{ 11389 rorL_rReg(dst, src, shift, cr); 11390 %} 11391 %} 11392 11393 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11394 %{ 11395 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11396 11397 expand %{ 11398 rorL_rReg(dst, src, shift, cr); 11399 %} 11400 %} 11401 11402 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11403 %{ 11404 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11405 11406 expand %{ 11407 rorI_rReg(dst, src, shift, cr); 11408 %} 11409 %} 11410 11411 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11412 %{ 11413 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11414 11415 expand %{ 11416 rorI_rReg(dst, src, shift, cr); 11417 %} 11418 %} 11419 11420 // Add/subtract (extended) 11421 11422 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11423 %{ 11424 match(Set dst (AddL src1 (ConvI2L src2))); 11425 ins_cost(INSN_COST); 11426 format %{ "add $dst, $src1, $src2, sxtw" %} 11427 11428 ins_encode %{ 11429 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11430 as_Register($src2$$reg), ext::sxtw); 11431 %} 11432 ins_pipe(ialu_reg_reg); 11433 %}; 11434 11435 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11436 %{ 11437 match(Set dst (SubL src1 (ConvI2L src2))); 11438 ins_cost(INSN_COST); 11439 format %{ "sub $dst, $src1, $src2, sxtw" %} 11440 11441 ins_encode %{ 11442 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11443 as_Register($src2$$reg), ext::sxtw); 11444 %} 11445 ins_pipe(ialu_reg_reg); 11446 %}; 11447 11448 11449 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11450 %{ 11451 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11452 ins_cost(INSN_COST); 11453 format %{ "add $dst, $src1, $src2, sxth" %} 11454 11455 ins_encode %{ 11456 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11457 as_Register($src2$$reg), ext::sxth); 11458 %} 11459 ins_pipe(ialu_reg_reg); 11460 %} 11461 11462 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11463 %{ 11464 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11465 ins_cost(INSN_COST); 11466 format %{ "add $dst, $src1, $src2, sxtb" %} 11467 11468 ins_encode %{ 11469 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11470 as_Register($src2$$reg), ext::sxtb); 11471 %} 11472 ins_pipe(ialu_reg_reg); 11473 %} 11474 11475 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11476 %{ 11477 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 11478 ins_cost(INSN_COST); 11479 format %{ "add $dst, $src1, $src2, uxtb" %} 11480 11481 ins_encode %{ 11482 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11483 as_Register($src2$$reg), ext::uxtb); 11484 %} 11485 ins_pipe(ialu_reg_reg); 11486 %} 11487 11488 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 11489 %{ 11490 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11491 ins_cost(INSN_COST); 11492 format %{ "add $dst, $src1, $src2, sxth" %} 11493 11494 ins_encode %{ 11495 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11496 as_Register($src2$$reg), ext::sxth); 11497 %} 11498 ins_pipe(ialu_reg_reg); 11499 %} 11500 11501 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 11502 %{ 11503 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11504 ins_cost(INSN_COST); 11505 format %{ "add $dst, $src1, $src2, sxtw" %} 11506 11507 ins_encode %{ 11508 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11509 as_Register($src2$$reg), ext::sxtw); 11510 %} 11511 ins_pipe(ialu_reg_reg); 11512 %} 11513 11514 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11515 %{ 11516 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11517 ins_cost(INSN_COST); 11518 format %{ "add $dst, $src1, $src2, sxtb" %} 11519 11520 ins_encode %{ 11521 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11522 as_Register($src2$$reg), ext::sxtb); 11523 %} 11524 ins_pipe(ialu_reg_reg); 11525 %} 11526 11527 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11528 %{ 11529 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 11530 ins_cost(INSN_COST); 11531 format %{ "add $dst, $src1, $src2, uxtb" %} 11532 11533 ins_encode %{ 11534 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11535 as_Register($src2$$reg), ext::uxtb); 11536 %} 11537 ins_pipe(ialu_reg_reg); 11538 %} 11539 11540 11541 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11542 %{ 11543 match(Set dst (AddI src1 (AndI src2 mask))); 11544 ins_cost(INSN_COST); 11545 format %{ "addw $dst, $src1, $src2, uxtb" %} 11546 11547 ins_encode %{ 11548 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11549 as_Register($src2$$reg), ext::uxtb); 11550 %} 11551 ins_pipe(ialu_reg_reg); 11552 %} 11553 11554 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11555 %{ 11556 match(Set dst (AddI src1 (AndI src2 mask))); 11557 ins_cost(INSN_COST); 11558 format %{ "addw $dst, $src1, $src2, uxth" %} 11559 11560 ins_encode %{ 11561 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11562 as_Register($src2$$reg), ext::uxth); 11563 %} 11564 ins_pipe(ialu_reg_reg); 11565 %} 11566 11567 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11568 %{ 11569 match(Set dst (AddL src1 (AndL src2 mask))); 11570 ins_cost(INSN_COST); 11571 format %{ "add $dst, $src1, $src2, uxtb" %} 11572 11573 ins_encode %{ 11574 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11575 as_Register($src2$$reg), ext::uxtb); 11576 %} 11577 ins_pipe(ialu_reg_reg); 11578 %} 11579 11580 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11581 %{ 11582 match(Set dst (AddL src1 (AndL src2 mask))); 11583 ins_cost(INSN_COST); 11584 format %{ "add $dst, $src1, $src2, uxth" %} 11585 11586 ins_encode %{ 11587 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11588 as_Register($src2$$reg), ext::uxth); 11589 %} 11590 ins_pipe(ialu_reg_reg); 11591 %} 11592 11593 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11594 %{ 11595 match(Set dst (AddL src1 (AndL src2 mask))); 11596 ins_cost(INSN_COST); 11597 format %{ "add $dst, $src1, $src2, uxtw" %} 11598 11599 ins_encode %{ 11600 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11601 as_Register($src2$$reg), ext::uxtw); 11602 %} 11603 ins_pipe(ialu_reg_reg); 11604 %} 11605 11606 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11607 %{ 11608 match(Set dst (SubI src1 (AndI src2 mask))); 11609 ins_cost(INSN_COST); 11610 format %{ "subw $dst, $src1, $src2, uxtb" %} 11611 11612 ins_encode %{ 11613 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11614 as_Register($src2$$reg), ext::uxtb); 11615 %} 11616 ins_pipe(ialu_reg_reg); 11617 %} 11618 11619 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11620 %{ 11621 match(Set dst (SubI src1 (AndI src2 mask))); 11622 ins_cost(INSN_COST); 11623 format %{ "subw $dst, $src1, $src2, uxth" %} 11624 11625 ins_encode %{ 11626 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11627 as_Register($src2$$reg), ext::uxth); 11628 %} 11629 ins_pipe(ialu_reg_reg); 11630 %} 11631 11632 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11633 %{ 11634 match(Set dst (SubL src1 (AndL src2 mask))); 11635 ins_cost(INSN_COST); 11636 format %{ "sub $dst, $src1, $src2, uxtb" %} 11637 11638 ins_encode %{ 11639 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11640 as_Register($src2$$reg), ext::uxtb); 11641 %} 11642 ins_pipe(ialu_reg_reg); 11643 %} 11644 11645 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11646 %{ 11647 match(Set dst (SubL src1 (AndL src2 mask))); 11648 ins_cost(INSN_COST); 11649 format %{ "sub $dst, $src1, $src2, uxth" %} 11650 11651 ins_encode %{ 11652 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11653 as_Register($src2$$reg), ext::uxth); 11654 %} 11655 ins_pipe(ialu_reg_reg); 11656 %} 11657 11658 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11659 %{ 11660 match(Set dst (SubL src1 (AndL src2 mask))); 11661 ins_cost(INSN_COST); 11662 format %{ "sub $dst, $src1, $src2, uxtw" %} 11663 11664 ins_encode %{ 11665 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11666 as_Register($src2$$reg), ext::uxtw); 11667 %} 11668 ins_pipe(ialu_reg_reg); 11669 %} 11670 11671 11672 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11673 %{ 11674 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11675 ins_cost(1.9 * INSN_COST); 11676 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 11677 11678 ins_encode %{ 11679 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11680 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11681 %} 11682 ins_pipe(ialu_reg_reg_shift); 11683 %} 11684 11685 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11686 %{ 11687 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11688 ins_cost(1.9 * INSN_COST); 11689 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 11690 11691 ins_encode %{ 11692 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11693 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11694 %} 11695 ins_pipe(ialu_reg_reg_shift); 11696 %} 11697 11698 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11699 %{ 11700 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11701 ins_cost(1.9 * INSN_COST); 11702 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 11703 11704 ins_encode %{ 11705 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11706 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11707 %} 11708 ins_pipe(ialu_reg_reg_shift); 11709 %} 11710 11711 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11712 %{ 11713 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11714 ins_cost(1.9 * INSN_COST); 11715 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 11716 11717 ins_encode %{ 11718 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11719 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11720 %} 11721 ins_pipe(ialu_reg_reg_shift); 11722 %} 11723 11724 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11725 %{ 11726 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11727 ins_cost(1.9 * INSN_COST); 11728 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 11729 11730 ins_encode %{ 11731 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11732 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11733 %} 11734 ins_pipe(ialu_reg_reg_shift); 11735 %} 11736 11737 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11738 %{ 11739 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11740 ins_cost(1.9 * INSN_COST); 11741 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 11742 11743 ins_encode %{ 11744 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11745 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11746 %} 11747 ins_pipe(ialu_reg_reg_shift); 11748 %} 11749 11750 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 11751 %{ 11752 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11753 ins_cost(1.9 * INSN_COST); 11754 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 11755 11756 ins_encode %{ 11757 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11758 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11759 %} 11760 ins_pipe(ialu_reg_reg_shift); 11761 %} 11762 11763 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 11764 %{ 11765 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11766 ins_cost(1.9 * INSN_COST); 11767 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 11768 11769 ins_encode %{ 11770 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11771 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11772 %} 11773 ins_pipe(ialu_reg_reg_shift); 11774 %} 11775 11776 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 11777 %{ 11778 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11779 ins_cost(1.9 * INSN_COST); 11780 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 11781 11782 ins_encode %{ 11783 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11784 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11785 %} 11786 ins_pipe(ialu_reg_reg_shift); 11787 %} 11788 11789 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 11790 %{ 11791 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11792 ins_cost(1.9 * INSN_COST); 11793 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 11794 11795 ins_encode %{ 11796 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11797 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11798 %} 11799 ins_pipe(ialu_reg_reg_shift); 11800 %} 11801 11802 11803 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 11804 %{ 11805 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 11806 ins_cost(1.9 * INSN_COST); 11807 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 11808 11809 ins_encode %{ 11810 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11811 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 11812 %} 11813 ins_pipe(ialu_reg_reg_shift); 11814 %}; 11815 11816 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 11817 %{ 11818 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 11819 ins_cost(1.9 * INSN_COST); 11820 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 11821 11822 ins_encode %{ 11823 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11824 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 11825 %} 11826 ins_pipe(ialu_reg_reg_shift); 11827 %}; 11828 11829 11830 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 11831 %{ 11832 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11833 ins_cost(1.9 * INSN_COST); 11834 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 11835 11836 ins_encode %{ 11837 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11838 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11839 %} 11840 ins_pipe(ialu_reg_reg_shift); 11841 %} 11842 11843 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 11844 %{ 11845 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11846 ins_cost(1.9 * INSN_COST); 11847 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 11848 11849 ins_encode %{ 11850 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11851 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11852 %} 11853 ins_pipe(ialu_reg_reg_shift); 11854 %} 11855 11856 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 11857 %{ 11858 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11859 ins_cost(1.9 * INSN_COST); 11860 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 11861 11862 ins_encode %{ 11863 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11864 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 11865 %} 11866 ins_pipe(ialu_reg_reg_shift); 11867 %} 11868 11869 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 11870 %{ 11871 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11872 ins_cost(1.9 * INSN_COST); 11873 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 11874 11875 ins_encode %{ 11876 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11877 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11878 %} 11879 ins_pipe(ialu_reg_reg_shift); 11880 %} 11881 11882 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 11883 %{ 11884 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11885 ins_cost(1.9 * INSN_COST); 11886 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 11887 11888 ins_encode %{ 11889 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11890 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11891 %} 11892 ins_pipe(ialu_reg_reg_shift); 11893 %} 11894 11895 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 11896 %{ 11897 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11898 ins_cost(1.9 * INSN_COST); 11899 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 11900 11901 ins_encode %{ 11902 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11903 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 11904 %} 11905 ins_pipe(ialu_reg_reg_shift); 11906 %} 11907 11908 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 11909 %{ 11910 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 11911 ins_cost(1.9 * INSN_COST); 11912 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 11913 11914 ins_encode %{ 11915 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11916 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11917 %} 11918 ins_pipe(ialu_reg_reg_shift); 11919 %} 11920 11921 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 11922 %{ 11923 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 11924 ins_cost(1.9 * INSN_COST); 11925 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 11926 11927 ins_encode %{ 11928 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11929 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11930 %} 11931 ins_pipe(ialu_reg_reg_shift); 11932 %} 11933 11934 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 11935 %{ 11936 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 11937 ins_cost(1.9 * INSN_COST); 11938 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 11939 11940 ins_encode %{ 11941 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11942 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11943 %} 11944 ins_pipe(ialu_reg_reg_shift); 11945 %} 11946 11947 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 11948 %{ 11949 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 11950 ins_cost(1.9 * INSN_COST); 11951 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 11952 11953 ins_encode %{ 11954 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11955 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11956 %} 11957 ins_pipe(ialu_reg_reg_shift); 11958 %} 11959 // END This section of the file is automatically generated. Do not edit -------------- 11960 11961 // ============================================================================ 11962 // Floating Point Arithmetic Instructions 11963 11964 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 11965 match(Set dst (AddF src1 src2)); 11966 11967 ins_cost(INSN_COST * 5); 11968 format %{ "fadds $dst, $src1, $src2" %} 11969 11970 ins_encode %{ 11971 __ fadds(as_FloatRegister($dst$$reg), 11972 as_FloatRegister($src1$$reg), 11973 as_FloatRegister($src2$$reg)); 11974 %} 11975 11976 ins_pipe(fp_dop_reg_reg_s); 11977 %} 11978 11979 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 11980 match(Set dst (AddD src1 src2)); 11981 11982 ins_cost(INSN_COST * 5); 11983 format %{ "faddd $dst, $src1, $src2" %} 11984 11985 ins_encode %{ 11986 __ faddd(as_FloatRegister($dst$$reg), 11987 as_FloatRegister($src1$$reg), 11988 as_FloatRegister($src2$$reg)); 11989 %} 11990 11991 ins_pipe(fp_dop_reg_reg_d); 11992 %} 11993 11994 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 11995 match(Set dst (SubF src1 src2)); 11996 11997 ins_cost(INSN_COST * 5); 11998 format %{ "fsubs $dst, $src1, $src2" %} 11999 12000 ins_encode %{ 12001 __ fsubs(as_FloatRegister($dst$$reg), 12002 as_FloatRegister($src1$$reg), 12003 as_FloatRegister($src2$$reg)); 12004 %} 12005 12006 ins_pipe(fp_dop_reg_reg_s); 12007 %} 12008 12009 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12010 match(Set dst (SubD src1 src2)); 12011 12012 ins_cost(INSN_COST * 5); 12013 format %{ "fsubd $dst, $src1, $src2" %} 12014 12015 ins_encode %{ 12016 __ fsubd(as_FloatRegister($dst$$reg), 12017 as_FloatRegister($src1$$reg), 12018 as_FloatRegister($src2$$reg)); 12019 %} 12020 12021 ins_pipe(fp_dop_reg_reg_d); 12022 %} 12023 12024 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12025 match(Set dst (MulF src1 src2)); 12026 12027 ins_cost(INSN_COST * 6); 12028 format %{ "fmuls $dst, $src1, $src2" %} 12029 12030 ins_encode %{ 12031 __ fmuls(as_FloatRegister($dst$$reg), 12032 as_FloatRegister($src1$$reg), 12033 as_FloatRegister($src2$$reg)); 12034 %} 12035 12036 ins_pipe(fp_dop_reg_reg_s); 12037 %} 12038 12039 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12040 match(Set dst (MulD src1 src2)); 12041 12042 ins_cost(INSN_COST * 6); 12043 format %{ "fmuld $dst, $src1, $src2" %} 12044 12045 ins_encode %{ 12046 __ fmuld(as_FloatRegister($dst$$reg), 12047 as_FloatRegister($src1$$reg), 12048 as_FloatRegister($src2$$reg)); 12049 %} 12050 12051 ins_pipe(fp_dop_reg_reg_d); 12052 %} 12053 12054 // src1 * src2 + src3 12055 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12056 predicate(UseFMA); 12057 match(Set dst (FmaF src3 (Binary src1 src2))); 12058 12059 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12060 12061 ins_encode %{ 12062 __ fmadds(as_FloatRegister($dst$$reg), 12063 as_FloatRegister($src1$$reg), 12064 as_FloatRegister($src2$$reg), 12065 as_FloatRegister($src3$$reg)); 12066 %} 12067 12068 ins_pipe(pipe_class_default); 12069 %} 12070 12071 // src1 * src2 + src3 12072 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12073 predicate(UseFMA); 12074 match(Set dst (FmaD src3 (Binary src1 src2))); 12075 12076 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12077 12078 ins_encode %{ 12079 __ fmaddd(as_FloatRegister($dst$$reg), 12080 as_FloatRegister($src1$$reg), 12081 as_FloatRegister($src2$$reg), 12082 as_FloatRegister($src3$$reg)); 12083 %} 12084 12085 ins_pipe(pipe_class_default); 12086 %} 12087 12088 // -src1 * src2 + src3 12089 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12090 predicate(UseFMA); 12091 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12092 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12093 12094 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12095 12096 ins_encode %{ 12097 __ fmsubs(as_FloatRegister($dst$$reg), 12098 as_FloatRegister($src1$$reg), 12099 as_FloatRegister($src2$$reg), 12100 as_FloatRegister($src3$$reg)); 12101 %} 12102 12103 ins_pipe(pipe_class_default); 12104 %} 12105 12106 // -src1 * src2 + src3 12107 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12108 predicate(UseFMA); 12109 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12110 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12111 12112 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12113 12114 ins_encode %{ 12115 __ fmsubd(as_FloatRegister($dst$$reg), 12116 as_FloatRegister($src1$$reg), 12117 as_FloatRegister($src2$$reg), 12118 as_FloatRegister($src3$$reg)); 12119 %} 12120 12121 ins_pipe(pipe_class_default); 12122 %} 12123 12124 // -src1 * src2 - src3 12125 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12126 predicate(UseFMA); 12127 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12128 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12129 12130 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12131 12132 ins_encode %{ 12133 __ fnmadds(as_FloatRegister($dst$$reg), 12134 as_FloatRegister($src1$$reg), 12135 as_FloatRegister($src2$$reg), 12136 as_FloatRegister($src3$$reg)); 12137 %} 12138 12139 ins_pipe(pipe_class_default); 12140 %} 12141 12142 // -src1 * src2 - src3 12143 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12144 predicate(UseFMA); 12145 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12146 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12147 12148 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12149 12150 ins_encode %{ 12151 __ fnmaddd(as_FloatRegister($dst$$reg), 12152 as_FloatRegister($src1$$reg), 12153 as_FloatRegister($src2$$reg), 12154 as_FloatRegister($src3$$reg)); 12155 %} 12156 12157 ins_pipe(pipe_class_default); 12158 %} 12159 12160 // src1 * src2 - src3 12161 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12162 predicate(UseFMA); 12163 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12164 12165 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12166 12167 ins_encode %{ 12168 __ fnmsubs(as_FloatRegister($dst$$reg), 12169 as_FloatRegister($src1$$reg), 12170 as_FloatRegister($src2$$reg), 12171 as_FloatRegister($src3$$reg)); 12172 %} 12173 12174 ins_pipe(pipe_class_default); 12175 %} 12176 12177 // src1 * src2 - src3 12178 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12179 predicate(UseFMA); 12180 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12181 12182 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12183 12184 ins_encode %{ 12185 // n.b. insn name should be fnmsubd 12186 __ fnmsub(as_FloatRegister($dst$$reg), 12187 as_FloatRegister($src1$$reg), 12188 as_FloatRegister($src2$$reg), 12189 as_FloatRegister($src3$$reg)); 12190 %} 12191 12192 ins_pipe(pipe_class_default); 12193 %} 12194 12195 12196 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12197 match(Set dst (DivF src1 src2)); 12198 12199 ins_cost(INSN_COST * 18); 12200 format %{ "fdivs $dst, $src1, $src2" %} 12201 12202 ins_encode %{ 12203 __ fdivs(as_FloatRegister($dst$$reg), 12204 as_FloatRegister($src1$$reg), 12205 as_FloatRegister($src2$$reg)); 12206 %} 12207 12208 ins_pipe(fp_div_s); 12209 %} 12210 12211 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12212 match(Set dst (DivD src1 src2)); 12213 12214 ins_cost(INSN_COST * 32); 12215 format %{ "fdivd $dst, $src1, $src2" %} 12216 12217 ins_encode %{ 12218 __ fdivd(as_FloatRegister($dst$$reg), 12219 as_FloatRegister($src1$$reg), 12220 as_FloatRegister($src2$$reg)); 12221 %} 12222 12223 ins_pipe(fp_div_d); 12224 %} 12225 12226 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12227 match(Set dst (NegF src)); 12228 12229 ins_cost(INSN_COST * 3); 12230 format %{ "fneg $dst, $src" %} 12231 12232 ins_encode %{ 12233 __ fnegs(as_FloatRegister($dst$$reg), 12234 as_FloatRegister($src$$reg)); 12235 %} 12236 12237 ins_pipe(fp_uop_s); 12238 %} 12239 12240 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12241 match(Set dst (NegD src)); 12242 12243 ins_cost(INSN_COST * 3); 12244 format %{ "fnegd $dst, $src" %} 12245 12246 ins_encode %{ 12247 __ fnegd(as_FloatRegister($dst$$reg), 12248 as_FloatRegister($src$$reg)); 12249 %} 12250 12251 ins_pipe(fp_uop_d); 12252 %} 12253 12254 instruct absF_reg(vRegF dst, vRegF src) %{ 12255 match(Set dst (AbsF src)); 12256 12257 ins_cost(INSN_COST * 3); 12258 format %{ "fabss $dst, $src" %} 12259 ins_encode %{ 12260 __ fabss(as_FloatRegister($dst$$reg), 12261 as_FloatRegister($src$$reg)); 12262 %} 12263 12264 ins_pipe(fp_uop_s); 12265 %} 12266 12267 instruct absD_reg(vRegD dst, vRegD src) %{ 12268 match(Set dst (AbsD src)); 12269 12270 ins_cost(INSN_COST * 3); 12271 format %{ "fabsd $dst, $src" %} 12272 ins_encode %{ 12273 __ fabsd(as_FloatRegister($dst$$reg), 12274 as_FloatRegister($src$$reg)); 12275 %} 12276 12277 ins_pipe(fp_uop_d); 12278 %} 12279 12280 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12281 match(Set dst (SqrtD src)); 12282 12283 ins_cost(INSN_COST * 50); 12284 format %{ "fsqrtd $dst, $src" %} 12285 ins_encode %{ 12286 __ fsqrtd(as_FloatRegister($dst$$reg), 12287 as_FloatRegister($src$$reg)); 12288 %} 12289 12290 ins_pipe(fp_div_s); 12291 %} 12292 12293 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12294 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 12295 12296 ins_cost(INSN_COST * 50); 12297 format %{ "fsqrts $dst, $src" %} 12298 ins_encode %{ 12299 __ fsqrts(as_FloatRegister($dst$$reg), 12300 as_FloatRegister($src$$reg)); 12301 %} 12302 12303 ins_pipe(fp_div_d); 12304 %} 12305 12306 // ============================================================================ 12307 // Logical Instructions 12308 12309 // Integer Logical Instructions 12310 12311 // And Instructions 12312 12313 12314 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 12315 match(Set dst (AndI src1 src2)); 12316 12317 format %{ "andw $dst, $src1, $src2\t# int" %} 12318 12319 ins_cost(INSN_COST); 12320 ins_encode %{ 12321 __ andw(as_Register($dst$$reg), 12322 as_Register($src1$$reg), 12323 as_Register($src2$$reg)); 12324 %} 12325 12326 ins_pipe(ialu_reg_reg); 12327 %} 12328 12329 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 12330 match(Set dst (AndI src1 src2)); 12331 12332 format %{ "andsw $dst, $src1, $src2\t# int" %} 12333 12334 ins_cost(INSN_COST); 12335 ins_encode %{ 12336 __ andw(as_Register($dst$$reg), 12337 as_Register($src1$$reg), 12338 (unsigned long)($src2$$constant)); 12339 %} 12340 12341 ins_pipe(ialu_reg_imm); 12342 %} 12343 12344 // Or Instructions 12345 12346 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12347 match(Set dst (OrI src1 src2)); 12348 12349 format %{ "orrw $dst, $src1, $src2\t# int" %} 12350 12351 ins_cost(INSN_COST); 12352 ins_encode %{ 12353 __ orrw(as_Register($dst$$reg), 12354 as_Register($src1$$reg), 12355 as_Register($src2$$reg)); 12356 %} 12357 12358 ins_pipe(ialu_reg_reg); 12359 %} 12360 12361 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12362 match(Set dst (OrI src1 src2)); 12363 12364 format %{ "orrw $dst, $src1, $src2\t# int" %} 12365 12366 ins_cost(INSN_COST); 12367 ins_encode %{ 12368 __ orrw(as_Register($dst$$reg), 12369 as_Register($src1$$reg), 12370 (unsigned long)($src2$$constant)); 12371 %} 12372 12373 ins_pipe(ialu_reg_imm); 12374 %} 12375 12376 // Xor Instructions 12377 12378 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12379 match(Set dst (XorI src1 src2)); 12380 12381 format %{ "eorw $dst, $src1, $src2\t# int" %} 12382 12383 ins_cost(INSN_COST); 12384 ins_encode %{ 12385 __ eorw(as_Register($dst$$reg), 12386 as_Register($src1$$reg), 12387 as_Register($src2$$reg)); 12388 %} 12389 12390 ins_pipe(ialu_reg_reg); 12391 %} 12392 12393 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12394 match(Set dst (XorI src1 src2)); 12395 12396 format %{ "eorw $dst, $src1, $src2\t# int" %} 12397 12398 ins_cost(INSN_COST); 12399 ins_encode %{ 12400 __ eorw(as_Register($dst$$reg), 12401 as_Register($src1$$reg), 12402 (unsigned long)($src2$$constant)); 12403 %} 12404 12405 ins_pipe(ialu_reg_imm); 12406 %} 12407 12408 // Long Logical Instructions 12409 // TODO 12410 12411 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 12412 match(Set dst (AndL src1 src2)); 12413 12414 format %{ "and $dst, $src1, $src2\t# int" %} 12415 12416 ins_cost(INSN_COST); 12417 ins_encode %{ 12418 __ andr(as_Register($dst$$reg), 12419 as_Register($src1$$reg), 12420 as_Register($src2$$reg)); 12421 %} 12422 12423 ins_pipe(ialu_reg_reg); 12424 %} 12425 12426 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 12427 match(Set dst (AndL src1 src2)); 12428 12429 format %{ "and $dst, $src1, $src2\t# int" %} 12430 12431 ins_cost(INSN_COST); 12432 ins_encode %{ 12433 __ andr(as_Register($dst$$reg), 12434 as_Register($src1$$reg), 12435 (unsigned long)($src2$$constant)); 12436 %} 12437 12438 ins_pipe(ialu_reg_imm); 12439 %} 12440 12441 // Or Instructions 12442 12443 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12444 match(Set dst (OrL src1 src2)); 12445 12446 format %{ "orr $dst, $src1, $src2\t# int" %} 12447 12448 ins_cost(INSN_COST); 12449 ins_encode %{ 12450 __ orr(as_Register($dst$$reg), 12451 as_Register($src1$$reg), 12452 as_Register($src2$$reg)); 12453 %} 12454 12455 ins_pipe(ialu_reg_reg); 12456 %} 12457 12458 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12459 match(Set dst (OrL src1 src2)); 12460 12461 format %{ "orr $dst, $src1, $src2\t# int" %} 12462 12463 ins_cost(INSN_COST); 12464 ins_encode %{ 12465 __ orr(as_Register($dst$$reg), 12466 as_Register($src1$$reg), 12467 (unsigned long)($src2$$constant)); 12468 %} 12469 12470 ins_pipe(ialu_reg_imm); 12471 %} 12472 12473 // Xor Instructions 12474 12475 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12476 match(Set dst (XorL src1 src2)); 12477 12478 format %{ "eor $dst, $src1, $src2\t# int" %} 12479 12480 ins_cost(INSN_COST); 12481 ins_encode %{ 12482 __ eor(as_Register($dst$$reg), 12483 as_Register($src1$$reg), 12484 as_Register($src2$$reg)); 12485 %} 12486 12487 ins_pipe(ialu_reg_reg); 12488 %} 12489 12490 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12491 match(Set dst (XorL src1 src2)); 12492 12493 ins_cost(INSN_COST); 12494 format %{ "eor $dst, $src1, $src2\t# int" %} 12495 12496 ins_encode %{ 12497 __ eor(as_Register($dst$$reg), 12498 as_Register($src1$$reg), 12499 (unsigned long)($src2$$constant)); 12500 %} 12501 12502 ins_pipe(ialu_reg_imm); 12503 %} 12504 12505 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 12506 %{ 12507 match(Set dst (ConvI2L src)); 12508 12509 ins_cost(INSN_COST); 12510 format %{ "sxtw $dst, $src\t# i2l" %} 12511 ins_encode %{ 12512 __ sbfm($dst$$Register, $src$$Register, 0, 31); 12513 %} 12514 ins_pipe(ialu_reg_shift); 12515 %} 12516 12517 // this pattern occurs in bigmath arithmetic 12518 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 12519 %{ 12520 match(Set dst (AndL (ConvI2L src) mask)); 12521 12522 ins_cost(INSN_COST); 12523 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 12524 ins_encode %{ 12525 __ ubfm($dst$$Register, $src$$Register, 0, 31); 12526 %} 12527 12528 ins_pipe(ialu_reg_shift); 12529 %} 12530 12531 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 12532 match(Set dst (ConvL2I src)); 12533 12534 ins_cost(INSN_COST); 12535 format %{ "movw $dst, $src \t// l2i" %} 12536 12537 ins_encode %{ 12538 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 12539 %} 12540 12541 ins_pipe(ialu_reg); 12542 %} 12543 12544 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12545 %{ 12546 match(Set dst (Conv2B src)); 12547 effect(KILL cr); 12548 12549 format %{ 12550 "cmpw $src, zr\n\t" 12551 "cset $dst, ne" 12552 %} 12553 12554 ins_encode %{ 12555 __ cmpw(as_Register($src$$reg), zr); 12556 __ cset(as_Register($dst$$reg), Assembler::NE); 12557 %} 12558 12559 ins_pipe(ialu_reg); 12560 %} 12561 12562 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 12563 %{ 12564 match(Set dst (Conv2B src)); 12565 effect(KILL cr); 12566 12567 format %{ 12568 "cmp $src, zr\n\t" 12569 "cset $dst, ne" 12570 %} 12571 12572 ins_encode %{ 12573 __ cmp(as_Register($src$$reg), zr); 12574 __ cset(as_Register($dst$$reg), Assembler::NE); 12575 %} 12576 12577 ins_pipe(ialu_reg); 12578 %} 12579 12580 instruct convD2F_reg(vRegF dst, vRegD src) %{ 12581 match(Set dst (ConvD2F src)); 12582 12583 ins_cost(INSN_COST * 5); 12584 format %{ "fcvtd $dst, $src \t// d2f" %} 12585 12586 ins_encode %{ 12587 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12588 %} 12589 12590 ins_pipe(fp_d2f); 12591 %} 12592 12593 instruct convF2D_reg(vRegD dst, vRegF src) %{ 12594 match(Set dst (ConvF2D src)); 12595 12596 ins_cost(INSN_COST * 5); 12597 format %{ "fcvts $dst, $src \t// f2d" %} 12598 12599 ins_encode %{ 12600 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12601 %} 12602 12603 ins_pipe(fp_f2d); 12604 %} 12605 12606 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12607 match(Set dst (ConvF2I src)); 12608 12609 ins_cost(INSN_COST * 5); 12610 format %{ "fcvtzsw $dst, $src \t// f2i" %} 12611 12612 ins_encode %{ 12613 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12614 %} 12615 12616 ins_pipe(fp_f2i); 12617 %} 12618 12619 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 12620 match(Set dst (ConvF2L src)); 12621 12622 ins_cost(INSN_COST * 5); 12623 format %{ "fcvtzs $dst, $src \t// f2l" %} 12624 12625 ins_encode %{ 12626 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12627 %} 12628 12629 ins_pipe(fp_f2l); 12630 %} 12631 12632 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 12633 match(Set dst (ConvI2F src)); 12634 12635 ins_cost(INSN_COST * 5); 12636 format %{ "scvtfws $dst, $src \t// i2f" %} 12637 12638 ins_encode %{ 12639 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12640 %} 12641 12642 ins_pipe(fp_i2f); 12643 %} 12644 12645 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 12646 match(Set dst (ConvL2F src)); 12647 12648 ins_cost(INSN_COST * 5); 12649 format %{ "scvtfs $dst, $src \t// l2f" %} 12650 12651 ins_encode %{ 12652 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12653 %} 12654 12655 ins_pipe(fp_l2f); 12656 %} 12657 12658 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 12659 match(Set dst (ConvD2I src)); 12660 12661 ins_cost(INSN_COST * 5); 12662 format %{ "fcvtzdw $dst, $src \t// d2i" %} 12663 12664 ins_encode %{ 12665 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12666 %} 12667 12668 ins_pipe(fp_d2i); 12669 %} 12670 12671 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12672 match(Set dst (ConvD2L src)); 12673 12674 ins_cost(INSN_COST * 5); 12675 format %{ "fcvtzd $dst, $src \t// d2l" %} 12676 12677 ins_encode %{ 12678 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12679 %} 12680 12681 ins_pipe(fp_d2l); 12682 %} 12683 12684 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 12685 match(Set dst (ConvI2D src)); 12686 12687 ins_cost(INSN_COST * 5); 12688 format %{ "scvtfwd $dst, $src \t// i2d" %} 12689 12690 ins_encode %{ 12691 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12692 %} 12693 12694 ins_pipe(fp_i2d); 12695 %} 12696 12697 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 12698 match(Set dst (ConvL2D src)); 12699 12700 ins_cost(INSN_COST * 5); 12701 format %{ "scvtfd $dst, $src \t// l2d" %} 12702 12703 ins_encode %{ 12704 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12705 %} 12706 12707 ins_pipe(fp_l2d); 12708 %} 12709 12710 // stack <-> reg and reg <-> reg shuffles with no conversion 12711 12712 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 12713 12714 match(Set dst (MoveF2I src)); 12715 12716 effect(DEF dst, USE src); 12717 12718 ins_cost(4 * INSN_COST); 12719 12720 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 12721 12722 ins_encode %{ 12723 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 12724 %} 12725 12726 ins_pipe(iload_reg_reg); 12727 12728 %} 12729 12730 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 12731 12732 match(Set dst (MoveI2F src)); 12733 12734 effect(DEF dst, USE src); 12735 12736 ins_cost(4 * INSN_COST); 12737 12738 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 12739 12740 ins_encode %{ 12741 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12742 %} 12743 12744 ins_pipe(pipe_class_memory); 12745 12746 %} 12747 12748 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 12749 12750 match(Set dst (MoveD2L src)); 12751 12752 effect(DEF dst, USE src); 12753 12754 ins_cost(4 * INSN_COST); 12755 12756 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 12757 12758 ins_encode %{ 12759 __ ldr($dst$$Register, Address(sp, $src$$disp)); 12760 %} 12761 12762 ins_pipe(iload_reg_reg); 12763 12764 %} 12765 12766 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 12767 12768 match(Set dst (MoveL2D src)); 12769 12770 effect(DEF dst, USE src); 12771 12772 ins_cost(4 * INSN_COST); 12773 12774 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 12775 12776 ins_encode %{ 12777 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12778 %} 12779 12780 ins_pipe(pipe_class_memory); 12781 12782 %} 12783 12784 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 12785 12786 match(Set dst (MoveF2I src)); 12787 12788 effect(DEF dst, USE src); 12789 12790 ins_cost(INSN_COST); 12791 12792 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 12793 12794 ins_encode %{ 12795 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 12796 %} 12797 12798 ins_pipe(pipe_class_memory); 12799 12800 %} 12801 12802 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 12803 12804 match(Set dst (MoveI2F src)); 12805 12806 effect(DEF dst, USE src); 12807 12808 ins_cost(INSN_COST); 12809 12810 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 12811 12812 ins_encode %{ 12813 __ strw($src$$Register, Address(sp, $dst$$disp)); 12814 %} 12815 12816 ins_pipe(istore_reg_reg); 12817 12818 %} 12819 12820 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 12821 12822 match(Set dst (MoveD2L src)); 12823 12824 effect(DEF dst, USE src); 12825 12826 ins_cost(INSN_COST); 12827 12828 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 12829 12830 ins_encode %{ 12831 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 12832 %} 12833 12834 ins_pipe(pipe_class_memory); 12835 12836 %} 12837 12838 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 12839 12840 match(Set dst (MoveL2D src)); 12841 12842 effect(DEF dst, USE src); 12843 12844 ins_cost(INSN_COST); 12845 12846 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 12847 12848 ins_encode %{ 12849 __ str($src$$Register, Address(sp, $dst$$disp)); 12850 %} 12851 12852 ins_pipe(istore_reg_reg); 12853 12854 %} 12855 12856 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12857 12858 match(Set dst (MoveF2I src)); 12859 12860 effect(DEF dst, USE src); 12861 12862 ins_cost(INSN_COST); 12863 12864 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 12865 12866 ins_encode %{ 12867 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 12868 %} 12869 12870 ins_pipe(fp_f2i); 12871 12872 %} 12873 12874 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 12875 12876 match(Set dst (MoveI2F src)); 12877 12878 effect(DEF dst, USE src); 12879 12880 ins_cost(INSN_COST); 12881 12882 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 12883 12884 ins_encode %{ 12885 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 12886 %} 12887 12888 ins_pipe(fp_i2f); 12889 12890 %} 12891 12892 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12893 12894 match(Set dst (MoveD2L src)); 12895 12896 effect(DEF dst, USE src); 12897 12898 ins_cost(INSN_COST); 12899 12900 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 12901 12902 ins_encode %{ 12903 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 12904 %} 12905 12906 ins_pipe(fp_d2l); 12907 12908 %} 12909 12910 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 12911 12912 match(Set dst (MoveL2D src)); 12913 12914 effect(DEF dst, USE src); 12915 12916 ins_cost(INSN_COST); 12917 12918 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 12919 12920 ins_encode %{ 12921 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 12922 %} 12923 12924 ins_pipe(fp_l2d); 12925 12926 %} 12927 12928 // ============================================================================ 12929 // clearing of an array 12930 12931 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 12932 %{ 12933 match(Set dummy (ClearArray cnt base)); 12934 effect(USE_KILL cnt, USE_KILL base); 12935 12936 ins_cost(4 * INSN_COST); 12937 format %{ "ClearArray $cnt, $base" %} 12938 12939 ins_encode %{ 12940 __ zero_words($base$$Register, $cnt$$Register); 12941 %} 12942 12943 ins_pipe(pipe_class_memory); 12944 %} 12945 12946 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 12947 %{ 12948 predicate((u_int64_t)n->in(2)->get_long() 12949 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 12950 match(Set dummy (ClearArray cnt base)); 12951 effect(USE_KILL base); 12952 12953 ins_cost(4 * INSN_COST); 12954 format %{ "ClearArray $cnt, $base" %} 12955 12956 ins_encode %{ 12957 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 12958 %} 12959 12960 ins_pipe(pipe_class_memory); 12961 %} 12962 12963 // ============================================================================ 12964 // Overflow Math Instructions 12965 12966 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 12967 %{ 12968 match(Set cr (OverflowAddI op1 op2)); 12969 12970 format %{ "cmnw $op1, $op2\t# overflow check int" %} 12971 ins_cost(INSN_COST); 12972 ins_encode %{ 12973 __ cmnw($op1$$Register, $op2$$Register); 12974 %} 12975 12976 ins_pipe(icmp_reg_reg); 12977 %} 12978 12979 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 12980 %{ 12981 match(Set cr (OverflowAddI op1 op2)); 12982 12983 format %{ "cmnw $op1, $op2\t# overflow check int" %} 12984 ins_cost(INSN_COST); 12985 ins_encode %{ 12986 __ cmnw($op1$$Register, $op2$$constant); 12987 %} 12988 12989 ins_pipe(icmp_reg_imm); 12990 %} 12991 12992 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 12993 %{ 12994 match(Set cr (OverflowAddL op1 op2)); 12995 12996 format %{ "cmn $op1, $op2\t# overflow check long" %} 12997 ins_cost(INSN_COST); 12998 ins_encode %{ 12999 __ cmn($op1$$Register, $op2$$Register); 13000 %} 13001 13002 ins_pipe(icmp_reg_reg); 13003 %} 13004 13005 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13006 %{ 13007 match(Set cr (OverflowAddL op1 op2)); 13008 13009 format %{ "cmn $op1, $op2\t# overflow check long" %} 13010 ins_cost(INSN_COST); 13011 ins_encode %{ 13012 __ cmn($op1$$Register, $op2$$constant); 13013 %} 13014 13015 ins_pipe(icmp_reg_imm); 13016 %} 13017 13018 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13019 %{ 13020 match(Set cr (OverflowSubI op1 op2)); 13021 13022 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13023 ins_cost(INSN_COST); 13024 ins_encode %{ 13025 __ cmpw($op1$$Register, $op2$$Register); 13026 %} 13027 13028 ins_pipe(icmp_reg_reg); 13029 %} 13030 13031 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13032 %{ 13033 match(Set cr (OverflowSubI op1 op2)); 13034 13035 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13036 ins_cost(INSN_COST); 13037 ins_encode %{ 13038 __ cmpw($op1$$Register, $op2$$constant); 13039 %} 13040 13041 ins_pipe(icmp_reg_imm); 13042 %} 13043 13044 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13045 %{ 13046 match(Set cr (OverflowSubL op1 op2)); 13047 13048 format %{ "cmp $op1, $op2\t# overflow check long" %} 13049 ins_cost(INSN_COST); 13050 ins_encode %{ 13051 __ cmp($op1$$Register, $op2$$Register); 13052 %} 13053 13054 ins_pipe(icmp_reg_reg); 13055 %} 13056 13057 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13058 %{ 13059 match(Set cr (OverflowSubL op1 op2)); 13060 13061 format %{ "cmp $op1, $op2\t# overflow check long" %} 13062 ins_cost(INSN_COST); 13063 ins_encode %{ 13064 __ subs(zr, $op1$$Register, $op2$$constant); 13065 %} 13066 13067 ins_pipe(icmp_reg_imm); 13068 %} 13069 13070 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13071 %{ 13072 match(Set cr (OverflowSubI zero op1)); 13073 13074 format %{ "cmpw zr, $op1\t# overflow check int" %} 13075 ins_cost(INSN_COST); 13076 ins_encode %{ 13077 __ cmpw(zr, $op1$$Register); 13078 %} 13079 13080 ins_pipe(icmp_reg_imm); 13081 %} 13082 13083 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13084 %{ 13085 match(Set cr (OverflowSubL zero op1)); 13086 13087 format %{ "cmp zr, $op1\t# overflow check long" %} 13088 ins_cost(INSN_COST); 13089 ins_encode %{ 13090 __ cmp(zr, $op1$$Register); 13091 %} 13092 13093 ins_pipe(icmp_reg_imm); 13094 %} 13095 13096 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13097 %{ 13098 match(Set cr (OverflowMulI op1 op2)); 13099 13100 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13101 "cmp rscratch1, rscratch1, sxtw\n\t" 13102 "movw rscratch1, #0x80000000\n\t" 13103 "cselw rscratch1, rscratch1, zr, NE\n\t" 13104 "cmpw rscratch1, #1" %} 13105 ins_cost(5 * INSN_COST); 13106 ins_encode %{ 13107 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13108 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13109 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13110 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13111 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13112 %} 13113 13114 ins_pipe(pipe_slow); 13115 %} 13116 13117 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13118 %{ 13119 match(If cmp (OverflowMulI op1 op2)); 13120 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13121 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13122 effect(USE labl, KILL cr); 13123 13124 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13125 "cmp rscratch1, rscratch1, sxtw\n\t" 13126 "b$cmp $labl" %} 13127 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13128 ins_encode %{ 13129 Label* L = $labl$$label; 13130 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13131 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13132 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13133 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13134 %} 13135 13136 ins_pipe(pipe_serial); 13137 %} 13138 13139 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13140 %{ 13141 match(Set cr (OverflowMulL op1 op2)); 13142 13143 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13144 "smulh rscratch2, $op1, $op2\n\t" 13145 "cmp rscratch2, rscratch1, ASR #63\n\t" 13146 "movw rscratch1, #0x80000000\n\t" 13147 "cselw rscratch1, rscratch1, zr, NE\n\t" 13148 "cmpw rscratch1, #1" %} 13149 ins_cost(6 * INSN_COST); 13150 ins_encode %{ 13151 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13152 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13153 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13154 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13155 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13156 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13157 %} 13158 13159 ins_pipe(pipe_slow); 13160 %} 13161 13162 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13163 %{ 13164 match(If cmp (OverflowMulL op1 op2)); 13165 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13166 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13167 effect(USE labl, KILL cr); 13168 13169 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13170 "smulh rscratch2, $op1, $op2\n\t" 13171 "cmp rscratch2, rscratch1, ASR #63\n\t" 13172 "b$cmp $labl" %} 13173 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13174 ins_encode %{ 13175 Label* L = $labl$$label; 13176 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13177 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13178 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13179 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13180 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13181 %} 13182 13183 ins_pipe(pipe_serial); 13184 %} 13185 13186 // ============================================================================ 13187 // Compare Instructions 13188 13189 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13190 %{ 13191 match(Set cr (CmpI op1 op2)); 13192 13193 effect(DEF cr, USE op1, USE op2); 13194 13195 ins_cost(INSN_COST); 13196 format %{ "cmpw $op1, $op2" %} 13197 13198 ins_encode(aarch64_enc_cmpw(op1, op2)); 13199 13200 ins_pipe(icmp_reg_reg); 13201 %} 13202 13203 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13204 %{ 13205 match(Set cr (CmpI op1 zero)); 13206 13207 effect(DEF cr, USE op1); 13208 13209 ins_cost(INSN_COST); 13210 format %{ "cmpw $op1, 0" %} 13211 13212 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13213 13214 ins_pipe(icmp_reg_imm); 13215 %} 13216 13217 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13218 %{ 13219 match(Set cr (CmpI op1 op2)); 13220 13221 effect(DEF cr, USE op1); 13222 13223 ins_cost(INSN_COST); 13224 format %{ "cmpw $op1, $op2" %} 13225 13226 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13227 13228 ins_pipe(icmp_reg_imm); 13229 %} 13230 13231 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 13232 %{ 13233 match(Set cr (CmpI op1 op2)); 13234 13235 effect(DEF cr, USE op1); 13236 13237 ins_cost(INSN_COST * 2); 13238 format %{ "cmpw $op1, $op2" %} 13239 13240 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13241 13242 ins_pipe(icmp_reg_imm); 13243 %} 13244 13245 // Unsigned compare Instructions; really, same as signed compare 13246 // except it should only be used to feed an If or a CMovI which takes a 13247 // cmpOpU. 13248 13249 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 13250 %{ 13251 match(Set cr (CmpU op1 op2)); 13252 13253 effect(DEF cr, USE op1, USE op2); 13254 13255 ins_cost(INSN_COST); 13256 format %{ "cmpw $op1, $op2\t# unsigned" %} 13257 13258 ins_encode(aarch64_enc_cmpw(op1, op2)); 13259 13260 ins_pipe(icmp_reg_reg); 13261 %} 13262 13263 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 13264 %{ 13265 match(Set cr (CmpU op1 zero)); 13266 13267 effect(DEF cr, USE op1); 13268 13269 ins_cost(INSN_COST); 13270 format %{ "cmpw $op1, #0\t# unsigned" %} 13271 13272 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13273 13274 ins_pipe(icmp_reg_imm); 13275 %} 13276 13277 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 13278 %{ 13279 match(Set cr (CmpU op1 op2)); 13280 13281 effect(DEF cr, USE op1); 13282 13283 ins_cost(INSN_COST); 13284 format %{ "cmpw $op1, $op2\t# unsigned" %} 13285 13286 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13287 13288 ins_pipe(icmp_reg_imm); 13289 %} 13290 13291 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 13292 %{ 13293 match(Set cr (CmpU op1 op2)); 13294 13295 effect(DEF cr, USE op1); 13296 13297 ins_cost(INSN_COST * 2); 13298 format %{ "cmpw $op1, $op2\t# unsigned" %} 13299 13300 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13301 13302 ins_pipe(icmp_reg_imm); 13303 %} 13304 13305 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13306 %{ 13307 match(Set cr (CmpL op1 op2)); 13308 13309 effect(DEF cr, USE op1, USE op2); 13310 13311 ins_cost(INSN_COST); 13312 format %{ "cmp $op1, $op2" %} 13313 13314 ins_encode(aarch64_enc_cmp(op1, op2)); 13315 13316 ins_pipe(icmp_reg_reg); 13317 %} 13318 13319 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 13320 %{ 13321 match(Set cr (CmpL op1 zero)); 13322 13323 effect(DEF cr, USE op1); 13324 13325 ins_cost(INSN_COST); 13326 format %{ "tst $op1" %} 13327 13328 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13329 13330 ins_pipe(icmp_reg_imm); 13331 %} 13332 13333 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 13334 %{ 13335 match(Set cr (CmpL op1 op2)); 13336 13337 effect(DEF cr, USE op1); 13338 13339 ins_cost(INSN_COST); 13340 format %{ "cmp $op1, $op2" %} 13341 13342 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13343 13344 ins_pipe(icmp_reg_imm); 13345 %} 13346 13347 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 13348 %{ 13349 match(Set cr (CmpL op1 op2)); 13350 13351 effect(DEF cr, USE op1); 13352 13353 ins_cost(INSN_COST * 2); 13354 format %{ "cmp $op1, $op2" %} 13355 13356 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13357 13358 ins_pipe(icmp_reg_imm); 13359 %} 13360 13361 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 13362 %{ 13363 match(Set cr (CmpUL op1 op2)); 13364 13365 effect(DEF cr, USE op1, USE op2); 13366 13367 ins_cost(INSN_COST); 13368 format %{ "cmp $op1, $op2" %} 13369 13370 ins_encode(aarch64_enc_cmp(op1, op2)); 13371 13372 ins_pipe(icmp_reg_reg); 13373 %} 13374 13375 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 13376 %{ 13377 match(Set cr (CmpUL op1 zero)); 13378 13379 effect(DEF cr, USE op1); 13380 13381 ins_cost(INSN_COST); 13382 format %{ "tst $op1" %} 13383 13384 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13385 13386 ins_pipe(icmp_reg_imm); 13387 %} 13388 13389 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 13390 %{ 13391 match(Set cr (CmpUL op1 op2)); 13392 13393 effect(DEF cr, USE op1); 13394 13395 ins_cost(INSN_COST); 13396 format %{ "cmp $op1, $op2" %} 13397 13398 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13399 13400 ins_pipe(icmp_reg_imm); 13401 %} 13402 13403 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 13404 %{ 13405 match(Set cr (CmpUL op1 op2)); 13406 13407 effect(DEF cr, USE op1); 13408 13409 ins_cost(INSN_COST * 2); 13410 format %{ "cmp $op1, $op2" %} 13411 13412 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13413 13414 ins_pipe(icmp_reg_imm); 13415 %} 13416 13417 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 13418 %{ 13419 match(Set cr (CmpP op1 op2)); 13420 13421 effect(DEF cr, USE op1, USE op2); 13422 13423 ins_cost(INSN_COST); 13424 format %{ "cmp $op1, $op2\t // ptr" %} 13425 13426 ins_encode(aarch64_enc_cmpp(op1, op2)); 13427 13428 ins_pipe(icmp_reg_reg); 13429 %} 13430 13431 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 13432 %{ 13433 match(Set cr (CmpN op1 op2)); 13434 13435 effect(DEF cr, USE op1, USE op2); 13436 13437 ins_cost(INSN_COST); 13438 format %{ "cmp $op1, $op2\t // compressed ptr" %} 13439 13440 ins_encode(aarch64_enc_cmpn(op1, op2)); 13441 13442 ins_pipe(icmp_reg_reg); 13443 %} 13444 13445 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 13446 %{ 13447 match(Set cr (CmpP op1 zero)); 13448 13449 effect(DEF cr, USE op1, USE zero); 13450 13451 ins_cost(INSN_COST); 13452 format %{ "cmp $op1, 0\t // ptr" %} 13453 13454 ins_encode(aarch64_enc_testp(op1)); 13455 13456 ins_pipe(icmp_reg_imm); 13457 %} 13458 13459 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 13460 %{ 13461 match(Set cr (CmpN op1 zero)); 13462 13463 effect(DEF cr, USE op1, USE zero); 13464 13465 ins_cost(INSN_COST); 13466 format %{ "cmp $op1, 0\t // compressed ptr" %} 13467 13468 ins_encode(aarch64_enc_testn(op1)); 13469 13470 ins_pipe(icmp_reg_imm); 13471 %} 13472 13473 // FP comparisons 13474 // 13475 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 13476 // using normal cmpOp. See declaration of rFlagsReg for details. 13477 13478 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 13479 %{ 13480 match(Set cr (CmpF src1 src2)); 13481 13482 ins_cost(3 * INSN_COST); 13483 format %{ "fcmps $src1, $src2" %} 13484 13485 ins_encode %{ 13486 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13487 %} 13488 13489 ins_pipe(pipe_class_compare); 13490 %} 13491 13492 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 13493 %{ 13494 match(Set cr (CmpF src1 src2)); 13495 13496 ins_cost(3 * INSN_COST); 13497 format %{ "fcmps $src1, 0.0" %} 13498 13499 ins_encode %{ 13500 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 13501 %} 13502 13503 ins_pipe(pipe_class_compare); 13504 %} 13505 // FROM HERE 13506 13507 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 13508 %{ 13509 match(Set cr (CmpD src1 src2)); 13510 13511 ins_cost(3 * INSN_COST); 13512 format %{ "fcmpd $src1, $src2" %} 13513 13514 ins_encode %{ 13515 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13516 %} 13517 13518 ins_pipe(pipe_class_compare); 13519 %} 13520 13521 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 13522 %{ 13523 match(Set cr (CmpD src1 src2)); 13524 13525 ins_cost(3 * INSN_COST); 13526 format %{ "fcmpd $src1, 0.0" %} 13527 13528 ins_encode %{ 13529 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 13530 %} 13531 13532 ins_pipe(pipe_class_compare); 13533 %} 13534 13535 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 13536 %{ 13537 match(Set dst (CmpF3 src1 src2)); 13538 effect(KILL cr); 13539 13540 ins_cost(5 * INSN_COST); 13541 format %{ "fcmps $src1, $src2\n\t" 13542 "csinvw($dst, zr, zr, eq\n\t" 13543 "csnegw($dst, $dst, $dst, lt)" 13544 %} 13545 13546 ins_encode %{ 13547 Label done; 13548 FloatRegister s1 = as_FloatRegister($src1$$reg); 13549 FloatRegister s2 = as_FloatRegister($src2$$reg); 13550 Register d = as_Register($dst$$reg); 13551 __ fcmps(s1, s2); 13552 // installs 0 if EQ else -1 13553 __ csinvw(d, zr, zr, Assembler::EQ); 13554 // keeps -1 if less or unordered else installs 1 13555 __ csnegw(d, d, d, Assembler::LT); 13556 __ bind(done); 13557 %} 13558 13559 ins_pipe(pipe_class_default); 13560 13561 %} 13562 13563 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 13564 %{ 13565 match(Set dst (CmpD3 src1 src2)); 13566 effect(KILL cr); 13567 13568 ins_cost(5 * INSN_COST); 13569 format %{ "fcmpd $src1, $src2\n\t" 13570 "csinvw($dst, zr, zr, eq\n\t" 13571 "csnegw($dst, $dst, $dst, lt)" 13572 %} 13573 13574 ins_encode %{ 13575 Label done; 13576 FloatRegister s1 = as_FloatRegister($src1$$reg); 13577 FloatRegister s2 = as_FloatRegister($src2$$reg); 13578 Register d = as_Register($dst$$reg); 13579 __ fcmpd(s1, s2); 13580 // installs 0 if EQ else -1 13581 __ csinvw(d, zr, zr, Assembler::EQ); 13582 // keeps -1 if less or unordered else installs 1 13583 __ csnegw(d, d, d, Assembler::LT); 13584 __ bind(done); 13585 %} 13586 ins_pipe(pipe_class_default); 13587 13588 %} 13589 13590 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 13591 %{ 13592 match(Set dst (CmpF3 src1 zero)); 13593 effect(KILL cr); 13594 13595 ins_cost(5 * INSN_COST); 13596 format %{ "fcmps $src1, 0.0\n\t" 13597 "csinvw($dst, zr, zr, eq\n\t" 13598 "csnegw($dst, $dst, $dst, lt)" 13599 %} 13600 13601 ins_encode %{ 13602 Label done; 13603 FloatRegister s1 = as_FloatRegister($src1$$reg); 13604 Register d = as_Register($dst$$reg); 13605 __ fcmps(s1, 0.0D); 13606 // installs 0 if EQ else -1 13607 __ csinvw(d, zr, zr, Assembler::EQ); 13608 // keeps -1 if less or unordered else installs 1 13609 __ csnegw(d, d, d, Assembler::LT); 13610 __ bind(done); 13611 %} 13612 13613 ins_pipe(pipe_class_default); 13614 13615 %} 13616 13617 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 13618 %{ 13619 match(Set dst (CmpD3 src1 zero)); 13620 effect(KILL cr); 13621 13622 ins_cost(5 * INSN_COST); 13623 format %{ "fcmpd $src1, 0.0\n\t" 13624 "csinvw($dst, zr, zr, eq\n\t" 13625 "csnegw($dst, $dst, $dst, lt)" 13626 %} 13627 13628 ins_encode %{ 13629 Label done; 13630 FloatRegister s1 = as_FloatRegister($src1$$reg); 13631 Register d = as_Register($dst$$reg); 13632 __ fcmpd(s1, 0.0D); 13633 // installs 0 if EQ else -1 13634 __ csinvw(d, zr, zr, Assembler::EQ); 13635 // keeps -1 if less or unordered else installs 1 13636 __ csnegw(d, d, d, Assembler::LT); 13637 __ bind(done); 13638 %} 13639 ins_pipe(pipe_class_default); 13640 13641 %} 13642 13643 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 13644 %{ 13645 match(Set dst (CmpLTMask p q)); 13646 effect(KILL cr); 13647 13648 ins_cost(3 * INSN_COST); 13649 13650 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 13651 "csetw $dst, lt\n\t" 13652 "subw $dst, zr, $dst" 13653 %} 13654 13655 ins_encode %{ 13656 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 13657 __ csetw(as_Register($dst$$reg), Assembler::LT); 13658 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 13659 %} 13660 13661 ins_pipe(ialu_reg_reg); 13662 %} 13663 13664 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 13665 %{ 13666 match(Set dst (CmpLTMask src zero)); 13667 effect(KILL cr); 13668 13669 ins_cost(INSN_COST); 13670 13671 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 13672 13673 ins_encode %{ 13674 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 13675 %} 13676 13677 ins_pipe(ialu_reg_shift); 13678 %} 13679 13680 // ============================================================================ 13681 // Max and Min 13682 13683 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13684 %{ 13685 match(Set dst (MinI src1 src2)); 13686 13687 effect(DEF dst, USE src1, USE src2, KILL cr); 13688 size(8); 13689 13690 ins_cost(INSN_COST * 3); 13691 format %{ 13692 "cmpw $src1 $src2\t signed int\n\t" 13693 "cselw $dst, $src1, $src2 lt\t" 13694 %} 13695 13696 ins_encode %{ 13697 __ cmpw(as_Register($src1$$reg), 13698 as_Register($src2$$reg)); 13699 __ cselw(as_Register($dst$$reg), 13700 as_Register($src1$$reg), 13701 as_Register($src2$$reg), 13702 Assembler::LT); 13703 %} 13704 13705 ins_pipe(ialu_reg_reg); 13706 %} 13707 // FROM HERE 13708 13709 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13710 %{ 13711 match(Set dst (MaxI src1 src2)); 13712 13713 effect(DEF dst, USE src1, USE src2, KILL cr); 13714 size(8); 13715 13716 ins_cost(INSN_COST * 3); 13717 format %{ 13718 "cmpw $src1 $src2\t signed int\n\t" 13719 "cselw $dst, $src1, $src2 gt\t" 13720 %} 13721 13722 ins_encode %{ 13723 __ cmpw(as_Register($src1$$reg), 13724 as_Register($src2$$reg)); 13725 __ cselw(as_Register($dst$$reg), 13726 as_Register($src1$$reg), 13727 as_Register($src2$$reg), 13728 Assembler::GT); 13729 %} 13730 13731 ins_pipe(ialu_reg_reg); 13732 %} 13733 13734 // ============================================================================ 13735 // Branch Instructions 13736 13737 // Direct Branch. 13738 instruct branch(label lbl) 13739 %{ 13740 match(Goto); 13741 13742 effect(USE lbl); 13743 13744 ins_cost(BRANCH_COST); 13745 format %{ "b $lbl" %} 13746 13747 ins_encode(aarch64_enc_b(lbl)); 13748 13749 ins_pipe(pipe_branch); 13750 %} 13751 13752 // Conditional Near Branch 13753 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 13754 %{ 13755 // Same match rule as `branchConFar'. 13756 match(If cmp cr); 13757 13758 effect(USE lbl); 13759 13760 ins_cost(BRANCH_COST); 13761 // If set to 1 this indicates that the current instruction is a 13762 // short variant of a long branch. This avoids using this 13763 // instruction in first-pass matching. It will then only be used in 13764 // the `Shorten_branches' pass. 13765 // ins_short_branch(1); 13766 format %{ "b$cmp $lbl" %} 13767 13768 ins_encode(aarch64_enc_br_con(cmp, lbl)); 13769 13770 ins_pipe(pipe_branch_cond); 13771 %} 13772 13773 // Conditional Near Branch Unsigned 13774 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 13775 %{ 13776 // Same match rule as `branchConFar'. 13777 match(If cmp cr); 13778 13779 effect(USE lbl); 13780 13781 ins_cost(BRANCH_COST); 13782 // If set to 1 this indicates that the current instruction is a 13783 // short variant of a long branch. This avoids using this 13784 // instruction in first-pass matching. It will then only be used in 13785 // the `Shorten_branches' pass. 13786 // ins_short_branch(1); 13787 format %{ "b$cmp $lbl\t# unsigned" %} 13788 13789 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 13790 13791 ins_pipe(pipe_branch_cond); 13792 %} 13793 13794 // Make use of CBZ and CBNZ. These instructions, as well as being 13795 // shorter than (cmp; branch), have the additional benefit of not 13796 // killing the flags. 13797 13798 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 13799 match(If cmp (CmpI op1 op2)); 13800 effect(USE labl); 13801 13802 ins_cost(BRANCH_COST); 13803 format %{ "cbw$cmp $op1, $labl" %} 13804 ins_encode %{ 13805 Label* L = $labl$$label; 13806 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13807 if (cond == Assembler::EQ) 13808 __ cbzw($op1$$Register, *L); 13809 else 13810 __ cbnzw($op1$$Register, *L); 13811 %} 13812 ins_pipe(pipe_cmp_branch); 13813 %} 13814 13815 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 13816 match(If cmp (CmpL op1 op2)); 13817 effect(USE labl); 13818 13819 ins_cost(BRANCH_COST); 13820 format %{ "cb$cmp $op1, $labl" %} 13821 ins_encode %{ 13822 Label* L = $labl$$label; 13823 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13824 if (cond == Assembler::EQ) 13825 __ cbz($op1$$Register, *L); 13826 else 13827 __ cbnz($op1$$Register, *L); 13828 %} 13829 ins_pipe(pipe_cmp_branch); 13830 %} 13831 13832 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 13833 match(If cmp (CmpP op1 op2)); 13834 effect(USE labl); 13835 13836 ins_cost(BRANCH_COST); 13837 format %{ "cb$cmp $op1, $labl" %} 13838 ins_encode %{ 13839 Label* L = $labl$$label; 13840 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13841 if (cond == Assembler::EQ) 13842 __ cbz($op1$$Register, *L); 13843 else 13844 __ cbnz($op1$$Register, *L); 13845 %} 13846 ins_pipe(pipe_cmp_branch); 13847 %} 13848 13849 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 13850 match(If cmp (CmpN op1 op2)); 13851 effect(USE labl); 13852 13853 ins_cost(BRANCH_COST); 13854 format %{ "cbw$cmp $op1, $labl" %} 13855 ins_encode %{ 13856 Label* L = $labl$$label; 13857 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13858 if (cond == Assembler::EQ) 13859 __ cbzw($op1$$Register, *L); 13860 else 13861 __ cbnzw($op1$$Register, *L); 13862 %} 13863 ins_pipe(pipe_cmp_branch); 13864 %} 13865 13866 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 13867 match(If cmp (CmpP (DecodeN oop) zero)); 13868 effect(USE labl); 13869 13870 ins_cost(BRANCH_COST); 13871 format %{ "cb$cmp $oop, $labl" %} 13872 ins_encode %{ 13873 Label* L = $labl$$label; 13874 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13875 if (cond == Assembler::EQ) 13876 __ cbzw($oop$$Register, *L); 13877 else 13878 __ cbnzw($oop$$Register, *L); 13879 %} 13880 ins_pipe(pipe_cmp_branch); 13881 %} 13882 13883 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 13884 match(If cmp (CmpU op1 op2)); 13885 effect(USE labl); 13886 13887 ins_cost(BRANCH_COST); 13888 format %{ "cbw$cmp $op1, $labl" %} 13889 ins_encode %{ 13890 Label* L = $labl$$label; 13891 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13892 if (cond == Assembler::EQ || cond == Assembler::LS) 13893 __ cbzw($op1$$Register, *L); 13894 else 13895 __ cbnzw($op1$$Register, *L); 13896 %} 13897 ins_pipe(pipe_cmp_branch); 13898 %} 13899 13900 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 13901 match(If cmp (CmpUL op1 op2)); 13902 effect(USE labl); 13903 13904 ins_cost(BRANCH_COST); 13905 format %{ "cb$cmp $op1, $labl" %} 13906 ins_encode %{ 13907 Label* L = $labl$$label; 13908 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13909 if (cond == Assembler::EQ || cond == Assembler::LS) 13910 __ cbz($op1$$Register, *L); 13911 else 13912 __ cbnz($op1$$Register, *L); 13913 %} 13914 ins_pipe(pipe_cmp_branch); 13915 %} 13916 13917 // Test bit and Branch 13918 13919 // Patterns for short (< 32KiB) variants 13920 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 13921 match(If cmp (CmpL op1 op2)); 13922 effect(USE labl); 13923 13924 ins_cost(BRANCH_COST); 13925 format %{ "cb$cmp $op1, $labl # long" %} 13926 ins_encode %{ 13927 Label* L = $labl$$label; 13928 Assembler::Condition cond = 13929 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 13930 __ tbr(cond, $op1$$Register, 63, *L); 13931 %} 13932 ins_pipe(pipe_cmp_branch); 13933 ins_short_branch(1); 13934 %} 13935 13936 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 13937 match(If cmp (CmpI op1 op2)); 13938 effect(USE labl); 13939 13940 ins_cost(BRANCH_COST); 13941 format %{ "cb$cmp $op1, $labl # int" %} 13942 ins_encode %{ 13943 Label* L = $labl$$label; 13944 Assembler::Condition cond = 13945 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 13946 __ tbr(cond, $op1$$Register, 31, *L); 13947 %} 13948 ins_pipe(pipe_cmp_branch); 13949 ins_short_branch(1); 13950 %} 13951 13952 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 13953 match(If cmp (CmpL (AndL op1 op2) op3)); 13954 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 13955 effect(USE labl); 13956 13957 ins_cost(BRANCH_COST); 13958 format %{ "tb$cmp $op1, $op2, $labl" %} 13959 ins_encode %{ 13960 Label* L = $labl$$label; 13961 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13962 int bit = exact_log2($op2$$constant); 13963 __ tbr(cond, $op1$$Register, bit, *L); 13964 %} 13965 ins_pipe(pipe_cmp_branch); 13966 ins_short_branch(1); 13967 %} 13968 13969 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 13970 match(If cmp (CmpI (AndI op1 op2) op3)); 13971 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 13972 effect(USE labl); 13973 13974 ins_cost(BRANCH_COST); 13975 format %{ "tb$cmp $op1, $op2, $labl" %} 13976 ins_encode %{ 13977 Label* L = $labl$$label; 13978 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13979 int bit = exact_log2($op2$$constant); 13980 __ tbr(cond, $op1$$Register, bit, *L); 13981 %} 13982 ins_pipe(pipe_cmp_branch); 13983 ins_short_branch(1); 13984 %} 13985 13986 // And far variants 13987 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 13988 match(If cmp (CmpL op1 op2)); 13989 effect(USE labl); 13990 13991 ins_cost(BRANCH_COST); 13992 format %{ "cb$cmp $op1, $labl # long" %} 13993 ins_encode %{ 13994 Label* L = $labl$$label; 13995 Assembler::Condition cond = 13996 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 13997 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 13998 %} 13999 ins_pipe(pipe_cmp_branch); 14000 %} 14001 14002 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14003 match(If cmp (CmpI op1 op2)); 14004 effect(USE labl); 14005 14006 ins_cost(BRANCH_COST); 14007 format %{ "cb$cmp $op1, $labl # int" %} 14008 ins_encode %{ 14009 Label* L = $labl$$label; 14010 Assembler::Condition cond = 14011 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14012 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14013 %} 14014 ins_pipe(pipe_cmp_branch); 14015 %} 14016 14017 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14018 match(If cmp (CmpL (AndL op1 op2) op3)); 14019 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14020 effect(USE labl); 14021 14022 ins_cost(BRANCH_COST); 14023 format %{ "tb$cmp $op1, $op2, $labl" %} 14024 ins_encode %{ 14025 Label* L = $labl$$label; 14026 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14027 int bit = exact_log2($op2$$constant); 14028 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14029 %} 14030 ins_pipe(pipe_cmp_branch); 14031 %} 14032 14033 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14034 match(If cmp (CmpI (AndI op1 op2) op3)); 14035 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14036 effect(USE labl); 14037 14038 ins_cost(BRANCH_COST); 14039 format %{ "tb$cmp $op1, $op2, $labl" %} 14040 ins_encode %{ 14041 Label* L = $labl$$label; 14042 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14043 int bit = exact_log2($op2$$constant); 14044 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14045 %} 14046 ins_pipe(pipe_cmp_branch); 14047 %} 14048 14049 // Test bits 14050 14051 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14052 match(Set cr (CmpL (AndL op1 op2) op3)); 14053 predicate(Assembler::operand_valid_for_logical_immediate 14054 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14055 14056 ins_cost(INSN_COST); 14057 format %{ "tst $op1, $op2 # long" %} 14058 ins_encode %{ 14059 __ tst($op1$$Register, $op2$$constant); 14060 %} 14061 ins_pipe(ialu_reg_reg); 14062 %} 14063 14064 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14065 match(Set cr (CmpI (AndI op1 op2) op3)); 14066 predicate(Assembler::operand_valid_for_logical_immediate 14067 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14068 14069 ins_cost(INSN_COST); 14070 format %{ "tst $op1, $op2 # int" %} 14071 ins_encode %{ 14072 __ tstw($op1$$Register, $op2$$constant); 14073 %} 14074 ins_pipe(ialu_reg_reg); 14075 %} 14076 14077 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14078 match(Set cr (CmpL (AndL op1 op2) op3)); 14079 14080 ins_cost(INSN_COST); 14081 format %{ "tst $op1, $op2 # long" %} 14082 ins_encode %{ 14083 __ tst($op1$$Register, $op2$$Register); 14084 %} 14085 ins_pipe(ialu_reg_reg); 14086 %} 14087 14088 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14089 match(Set cr (CmpI (AndI op1 op2) op3)); 14090 14091 ins_cost(INSN_COST); 14092 format %{ "tstw $op1, $op2 # int" %} 14093 ins_encode %{ 14094 __ tstw($op1$$Register, $op2$$Register); 14095 %} 14096 ins_pipe(ialu_reg_reg); 14097 %} 14098 14099 14100 // Conditional Far Branch 14101 // Conditional Far Branch Unsigned 14102 // TODO: fixme 14103 14104 // counted loop end branch near 14105 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14106 %{ 14107 match(CountedLoopEnd cmp cr); 14108 14109 effect(USE lbl); 14110 14111 ins_cost(BRANCH_COST); 14112 // short variant. 14113 // ins_short_branch(1); 14114 format %{ "b$cmp $lbl \t// counted loop end" %} 14115 14116 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14117 14118 ins_pipe(pipe_branch); 14119 %} 14120 14121 // counted loop end branch near Unsigned 14122 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14123 %{ 14124 match(CountedLoopEnd cmp cr); 14125 14126 effect(USE lbl); 14127 14128 ins_cost(BRANCH_COST); 14129 // short variant. 14130 // ins_short_branch(1); 14131 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14132 14133 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14134 14135 ins_pipe(pipe_branch); 14136 %} 14137 14138 // counted loop end branch far 14139 // counted loop end branch far unsigned 14140 // TODO: fixme 14141 14142 // ============================================================================ 14143 // inlined locking and unlocking 14144 14145 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14146 %{ 14147 match(Set cr (FastLock object box)); 14148 effect(TEMP tmp, TEMP tmp2); 14149 14150 // TODO 14151 // identify correct cost 14152 ins_cost(5 * INSN_COST); 14153 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14154 14155 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14156 14157 ins_pipe(pipe_serial); 14158 %} 14159 14160 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14161 %{ 14162 match(Set cr (FastUnlock object box)); 14163 effect(TEMP tmp, TEMP tmp2); 14164 14165 ins_cost(5 * INSN_COST); 14166 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14167 14168 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14169 14170 ins_pipe(pipe_serial); 14171 %} 14172 14173 14174 // ============================================================================ 14175 // Safepoint Instructions 14176 14177 // TODO 14178 // provide a near and far version of this code 14179 14180 instruct safePoint(iRegP poll) 14181 %{ 14182 match(SafePoint poll); 14183 14184 format %{ 14185 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14186 %} 14187 ins_encode %{ 14188 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14189 %} 14190 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14191 %} 14192 14193 14194 // ============================================================================ 14195 // Procedure Call/Return Instructions 14196 14197 // Call Java Static Instruction 14198 14199 instruct CallStaticJavaDirect(method meth) 14200 %{ 14201 match(CallStaticJava); 14202 14203 effect(USE meth); 14204 14205 ins_cost(CALL_COST); 14206 14207 format %{ "call,static $meth \t// ==> " %} 14208 14209 ins_encode( aarch64_enc_java_static_call(meth), 14210 aarch64_enc_call_epilog ); 14211 14212 ins_pipe(pipe_class_call); 14213 %} 14214 14215 // TO HERE 14216 14217 // Call Java Dynamic Instruction 14218 instruct CallDynamicJavaDirect(method meth) 14219 %{ 14220 match(CallDynamicJava); 14221 14222 effect(USE meth); 14223 14224 ins_cost(CALL_COST); 14225 14226 format %{ "CALL,dynamic $meth \t// ==> " %} 14227 14228 ins_encode( aarch64_enc_java_dynamic_call(meth), 14229 aarch64_enc_call_epilog ); 14230 14231 ins_pipe(pipe_class_call); 14232 %} 14233 14234 // Call Runtime Instruction 14235 14236 instruct CallRuntimeDirect(method meth) 14237 %{ 14238 match(CallRuntime); 14239 14240 effect(USE meth); 14241 14242 ins_cost(CALL_COST); 14243 14244 format %{ "CALL, runtime $meth" %} 14245 14246 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14247 14248 ins_pipe(pipe_class_call); 14249 %} 14250 14251 // Call Runtime Instruction 14252 14253 instruct CallLeafDirect(method meth) 14254 %{ 14255 match(CallLeaf); 14256 14257 effect(USE meth); 14258 14259 ins_cost(CALL_COST); 14260 14261 format %{ "CALL, runtime leaf $meth" %} 14262 14263 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14264 14265 ins_pipe(pipe_class_call); 14266 %} 14267 14268 // Call Runtime Instruction 14269 14270 instruct CallLeafNoFPDirect(method meth) 14271 %{ 14272 match(CallLeafNoFP); 14273 14274 effect(USE meth); 14275 14276 ins_cost(CALL_COST); 14277 14278 format %{ "CALL, runtime leaf nofp $meth" %} 14279 14280 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14281 14282 ins_pipe(pipe_class_call); 14283 %} 14284 14285 // Tail Call; Jump from runtime stub to Java code. 14286 // Also known as an 'interprocedural jump'. 14287 // Target of jump will eventually return to caller. 14288 // TailJump below removes the return address. 14289 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 14290 %{ 14291 match(TailCall jump_target method_oop); 14292 14293 ins_cost(CALL_COST); 14294 14295 format %{ "br $jump_target\t# $method_oop holds method oop" %} 14296 14297 ins_encode(aarch64_enc_tail_call(jump_target)); 14298 14299 ins_pipe(pipe_class_call); 14300 %} 14301 14302 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 14303 %{ 14304 match(TailJump jump_target ex_oop); 14305 14306 ins_cost(CALL_COST); 14307 14308 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 14309 14310 ins_encode(aarch64_enc_tail_jmp(jump_target)); 14311 14312 ins_pipe(pipe_class_call); 14313 %} 14314 14315 // Create exception oop: created by stack-crawling runtime code. 14316 // Created exception is now available to this handler, and is setup 14317 // just prior to jumping to this handler. No code emitted. 14318 // TODO check 14319 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 14320 instruct CreateException(iRegP_R0 ex_oop) 14321 %{ 14322 match(Set ex_oop (CreateEx)); 14323 14324 format %{ " -- \t// exception oop; no code emitted" %} 14325 14326 size(0); 14327 14328 ins_encode( /*empty*/ ); 14329 14330 ins_pipe(pipe_class_empty); 14331 %} 14332 14333 // Rethrow exception: The exception oop will come in the first 14334 // argument position. Then JUMP (not call) to the rethrow stub code. 14335 instruct RethrowException() %{ 14336 match(Rethrow); 14337 ins_cost(CALL_COST); 14338 14339 format %{ "b rethrow_stub" %} 14340 14341 ins_encode( aarch64_enc_rethrow() ); 14342 14343 ins_pipe(pipe_class_call); 14344 %} 14345 14346 14347 // Return Instruction 14348 // epilog node loads ret address into lr as part of frame pop 14349 instruct Ret() 14350 %{ 14351 match(Return); 14352 14353 format %{ "ret\t// return register" %} 14354 14355 ins_encode( aarch64_enc_ret() ); 14356 14357 ins_pipe(pipe_branch); 14358 %} 14359 14360 // Die now. 14361 instruct ShouldNotReachHere() %{ 14362 match(Halt); 14363 14364 ins_cost(CALL_COST); 14365 format %{ "ShouldNotReachHere" %} 14366 14367 ins_encode %{ 14368 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 14369 // return true 14370 __ dpcs1(0xdead + 1); 14371 %} 14372 14373 ins_pipe(pipe_class_default); 14374 %} 14375 14376 // ============================================================================ 14377 // Partial Subtype Check 14378 // 14379 // superklass array for an instance of the superklass. Set a hidden 14380 // internal cache on a hit (cache is checked with exposed code in 14381 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14382 // encoding ALSO sets flags. 14383 14384 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 14385 %{ 14386 match(Set result (PartialSubtypeCheck sub super)); 14387 effect(KILL cr, KILL temp); 14388 14389 ins_cost(1100); // slightly larger than the next version 14390 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14391 14392 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14393 14394 opcode(0x1); // Force zero of result reg on hit 14395 14396 ins_pipe(pipe_class_memory); 14397 %} 14398 14399 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 14400 %{ 14401 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 14402 effect(KILL temp, KILL result); 14403 14404 ins_cost(1100); // slightly larger than the next version 14405 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 14406 14407 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14408 14409 opcode(0x0); // Don't zero result reg on hit 14410 14411 ins_pipe(pipe_class_memory); 14412 %} 14413 14414 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14415 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14416 %{ 14417 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 14418 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14419 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14420 14421 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14422 ins_encode %{ 14423 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14424 __ string_compare($str1$$Register, $str2$$Register, 14425 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14426 $tmp1$$Register, $tmp2$$Register, 14427 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 14428 %} 14429 ins_pipe(pipe_class_memory); 14430 %} 14431 14432 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14433 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14434 %{ 14435 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 14436 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14437 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14438 14439 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14440 ins_encode %{ 14441 __ string_compare($str1$$Register, $str2$$Register, 14442 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14443 $tmp1$$Register, $tmp2$$Register, 14444 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 14445 %} 14446 ins_pipe(pipe_class_memory); 14447 %} 14448 14449 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14450 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14451 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14452 %{ 14453 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 14454 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14455 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14456 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14457 14458 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14459 ins_encode %{ 14460 __ string_compare($str1$$Register, $str2$$Register, 14461 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14462 $tmp1$$Register, $tmp2$$Register, 14463 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14464 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 14465 %} 14466 ins_pipe(pipe_class_memory); 14467 %} 14468 14469 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14470 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14471 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14472 %{ 14473 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 14474 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14475 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14476 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14477 14478 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14479 ins_encode %{ 14480 __ string_compare($str1$$Register, $str2$$Register, 14481 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14482 $tmp1$$Register, $tmp2$$Register, 14483 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14484 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 14485 %} 14486 ins_pipe(pipe_class_memory); 14487 %} 14488 14489 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14490 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14491 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14492 %{ 14493 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14494 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14495 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14496 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14497 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 14498 14499 ins_encode %{ 14500 __ string_indexof($str1$$Register, $str2$$Register, 14501 $cnt1$$Register, $cnt2$$Register, 14502 $tmp1$$Register, $tmp2$$Register, 14503 $tmp3$$Register, $tmp4$$Register, 14504 $tmp5$$Register, $tmp6$$Register, 14505 -1, $result$$Register, StrIntrinsicNode::UU); 14506 %} 14507 ins_pipe(pipe_class_memory); 14508 %} 14509 14510 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14511 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14512 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14513 %{ 14514 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14515 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14516 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14517 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14518 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 14519 14520 ins_encode %{ 14521 __ string_indexof($str1$$Register, $str2$$Register, 14522 $cnt1$$Register, $cnt2$$Register, 14523 $tmp1$$Register, $tmp2$$Register, 14524 $tmp3$$Register, $tmp4$$Register, 14525 $tmp5$$Register, $tmp6$$Register, 14526 -1, $result$$Register, StrIntrinsicNode::LL); 14527 %} 14528 ins_pipe(pipe_class_memory); 14529 %} 14530 14531 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14532 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14533 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14534 %{ 14535 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14536 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14537 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14538 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14539 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 14540 14541 ins_encode %{ 14542 __ string_indexof($str1$$Register, $str2$$Register, 14543 $cnt1$$Register, $cnt2$$Register, 14544 $tmp1$$Register, $tmp2$$Register, 14545 $tmp3$$Register, $tmp4$$Register, 14546 $tmp5$$Register, $tmp6$$Register, 14547 -1, $result$$Register, StrIntrinsicNode::UL); 14548 %} 14549 ins_pipe(pipe_class_memory); 14550 %} 14551 14552 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14553 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14554 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14555 %{ 14556 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14557 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14558 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14559 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14560 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 14561 14562 ins_encode %{ 14563 int icnt2 = (int)$int_cnt2$$constant; 14564 __ string_indexof($str1$$Register, $str2$$Register, 14565 $cnt1$$Register, zr, 14566 $tmp1$$Register, $tmp2$$Register, 14567 $tmp3$$Register, $tmp4$$Register, zr, zr, 14568 icnt2, $result$$Register, StrIntrinsicNode::UU); 14569 %} 14570 ins_pipe(pipe_class_memory); 14571 %} 14572 14573 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14574 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14575 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14576 %{ 14577 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14578 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14579 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14580 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14581 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 14582 14583 ins_encode %{ 14584 int icnt2 = (int)$int_cnt2$$constant; 14585 __ string_indexof($str1$$Register, $str2$$Register, 14586 $cnt1$$Register, zr, 14587 $tmp1$$Register, $tmp2$$Register, 14588 $tmp3$$Register, $tmp4$$Register, zr, zr, 14589 icnt2, $result$$Register, StrIntrinsicNode::LL); 14590 %} 14591 ins_pipe(pipe_class_memory); 14592 %} 14593 14594 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14595 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14596 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14597 %{ 14598 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14599 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14600 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14601 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14602 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 14603 14604 ins_encode %{ 14605 int icnt2 = (int)$int_cnt2$$constant; 14606 __ string_indexof($str1$$Register, $str2$$Register, 14607 $cnt1$$Register, zr, 14608 $tmp1$$Register, $tmp2$$Register, 14609 $tmp3$$Register, $tmp4$$Register, zr, zr, 14610 icnt2, $result$$Register, StrIntrinsicNode::UL); 14611 %} 14612 ins_pipe(pipe_class_memory); 14613 %} 14614 14615 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 14616 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14617 iRegINoSp tmp3, rFlagsReg cr) 14618 %{ 14619 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 14620 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 14621 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14622 14623 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 14624 14625 ins_encode %{ 14626 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 14627 $result$$Register, $tmp1$$Register, $tmp2$$Register, 14628 $tmp3$$Register); 14629 %} 14630 ins_pipe(pipe_class_memory); 14631 %} 14632 14633 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14634 iRegI_R0 result, rFlagsReg cr) 14635 %{ 14636 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 14637 match(Set result (StrEquals (Binary str1 str2) cnt)); 14638 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14639 14640 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14641 ins_encode %{ 14642 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14643 __ string_equals($str1$$Register, $str2$$Register, 14644 $result$$Register, $cnt$$Register, 1); 14645 %} 14646 ins_pipe(pipe_class_memory); 14647 %} 14648 14649 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14650 iRegI_R0 result, rFlagsReg cr) 14651 %{ 14652 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 14653 match(Set result (StrEquals (Binary str1 str2) cnt)); 14654 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14655 14656 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14657 ins_encode %{ 14658 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14659 __ string_equals($str1$$Register, $str2$$Register, 14660 $result$$Register, $cnt$$Register, 2); 14661 %} 14662 ins_pipe(pipe_class_memory); 14663 %} 14664 14665 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14666 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14667 iRegP_R10 tmp, rFlagsReg cr) 14668 %{ 14669 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 14670 match(Set result (AryEq ary1 ary2)); 14671 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14672 14673 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14674 ins_encode %{ 14675 __ arrays_equals($ary1$$Register, $ary2$$Register, 14676 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14677 $result$$Register, $tmp$$Register, 1); 14678 %} 14679 ins_pipe(pipe_class_memory); 14680 %} 14681 14682 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14683 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14684 iRegP_R10 tmp, rFlagsReg cr) 14685 %{ 14686 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 14687 match(Set result (AryEq ary1 ary2)); 14688 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14689 14690 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14691 ins_encode %{ 14692 __ arrays_equals($ary1$$Register, $ary2$$Register, 14693 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14694 $result$$Register, $tmp$$Register, 2); 14695 %} 14696 ins_pipe(pipe_class_memory); 14697 %} 14698 14699 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 14700 %{ 14701 match(Set result (HasNegatives ary1 len)); 14702 effect(USE_KILL ary1, USE_KILL len, KILL cr); 14703 format %{ "has negatives byte[] $ary1,$len -> $result" %} 14704 ins_encode %{ 14705 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 14706 %} 14707 ins_pipe( pipe_slow ); 14708 %} 14709 14710 // fast char[] to byte[] compression 14711 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14712 vRegD_V0 tmp1, vRegD_V1 tmp2, 14713 vRegD_V2 tmp3, vRegD_V3 tmp4, 14714 iRegI_R0 result, rFlagsReg cr) 14715 %{ 14716 match(Set result (StrCompressedCopy src (Binary dst len))); 14717 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14718 14719 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 14720 ins_encode %{ 14721 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 14722 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 14723 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 14724 $result$$Register); 14725 %} 14726 ins_pipe( pipe_slow ); 14727 %} 14728 14729 // fast byte[] to char[] inflation 14730 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 14731 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 14732 %{ 14733 match(Set dummy (StrInflatedCopy src (Binary dst len))); 14734 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14735 14736 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 14737 ins_encode %{ 14738 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 14739 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 14740 %} 14741 ins_pipe(pipe_class_memory); 14742 %} 14743 14744 // encode char[] to byte[] in ISO_8859_1 14745 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14746 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 14747 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 14748 iRegI_R0 result, rFlagsReg cr) 14749 %{ 14750 match(Set result (EncodeISOArray src (Binary dst len))); 14751 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 14752 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 14753 14754 format %{ "Encode array $src,$dst,$len -> $result" %} 14755 ins_encode %{ 14756 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 14757 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 14758 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 14759 %} 14760 ins_pipe( pipe_class_memory ); 14761 %} 14762 14763 // ============================================================================ 14764 // This name is KNOWN by the ADLC and cannot be changed. 14765 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14766 // for this guy. 14767 instruct tlsLoadP(thread_RegP dst) 14768 %{ 14769 match(Set dst (ThreadLocal)); 14770 14771 ins_cost(0); 14772 14773 format %{ " -- \t// $dst=Thread::current(), empty" %} 14774 14775 size(0); 14776 14777 ins_encode( /*empty*/ ); 14778 14779 ins_pipe(pipe_class_empty); 14780 %} 14781 14782 // ====================VECTOR INSTRUCTIONS===================================== 14783 14784 // Load vector (32 bits) 14785 instruct loadV4(vecD dst, vmem4 mem) 14786 %{ 14787 predicate(n->as_LoadVector()->memory_size() == 4); 14788 match(Set dst (LoadVector mem)); 14789 ins_cost(4 * INSN_COST); 14790 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 14791 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 14792 ins_pipe(vload_reg_mem64); 14793 %} 14794 14795 // Load vector (64 bits) 14796 instruct loadV8(vecD dst, vmem8 mem) 14797 %{ 14798 predicate(n->as_LoadVector()->memory_size() == 8); 14799 match(Set dst (LoadVector mem)); 14800 ins_cost(4 * INSN_COST); 14801 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 14802 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 14803 ins_pipe(vload_reg_mem64); 14804 %} 14805 14806 // Load Vector (128 bits) 14807 instruct loadV16(vecX dst, vmem16 mem) 14808 %{ 14809 predicate(n->as_LoadVector()->memory_size() == 16); 14810 match(Set dst (LoadVector mem)); 14811 ins_cost(4 * INSN_COST); 14812 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 14813 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 14814 ins_pipe(vload_reg_mem128); 14815 %} 14816 14817 // Store Vector (32 bits) 14818 instruct storeV4(vecD src, vmem4 mem) 14819 %{ 14820 predicate(n->as_StoreVector()->memory_size() == 4); 14821 match(Set mem (StoreVector mem src)); 14822 ins_cost(4 * INSN_COST); 14823 format %{ "strs $mem,$src\t# vector (32 bits)" %} 14824 ins_encode( aarch64_enc_strvS(src, mem) ); 14825 ins_pipe(vstore_reg_mem64); 14826 %} 14827 14828 // Store Vector (64 bits) 14829 instruct storeV8(vecD src, vmem8 mem) 14830 %{ 14831 predicate(n->as_StoreVector()->memory_size() == 8); 14832 match(Set mem (StoreVector mem src)); 14833 ins_cost(4 * INSN_COST); 14834 format %{ "strd $mem,$src\t# vector (64 bits)" %} 14835 ins_encode( aarch64_enc_strvD(src, mem) ); 14836 ins_pipe(vstore_reg_mem64); 14837 %} 14838 14839 // Store Vector (128 bits) 14840 instruct storeV16(vecX src, vmem16 mem) 14841 %{ 14842 predicate(n->as_StoreVector()->memory_size() == 16); 14843 match(Set mem (StoreVector mem src)); 14844 ins_cost(4 * INSN_COST); 14845 format %{ "strq $mem,$src\t# vector (128 bits)" %} 14846 ins_encode( aarch64_enc_strvQ(src, mem) ); 14847 ins_pipe(vstore_reg_mem128); 14848 %} 14849 14850 instruct replicate8B(vecD dst, iRegIorL2I src) 14851 %{ 14852 predicate(n->as_Vector()->length() == 4 || 14853 n->as_Vector()->length() == 8); 14854 match(Set dst (ReplicateB src)); 14855 ins_cost(INSN_COST); 14856 format %{ "dup $dst, $src\t# vector (8B)" %} 14857 ins_encode %{ 14858 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 14859 %} 14860 ins_pipe(vdup_reg_reg64); 14861 %} 14862 14863 instruct replicate16B(vecX dst, iRegIorL2I src) 14864 %{ 14865 predicate(n->as_Vector()->length() == 16); 14866 match(Set dst (ReplicateB src)); 14867 ins_cost(INSN_COST); 14868 format %{ "dup $dst, $src\t# vector (16B)" %} 14869 ins_encode %{ 14870 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 14871 %} 14872 ins_pipe(vdup_reg_reg128); 14873 %} 14874 14875 instruct replicate8B_imm(vecD dst, immI con) 14876 %{ 14877 predicate(n->as_Vector()->length() == 4 || 14878 n->as_Vector()->length() == 8); 14879 match(Set dst (ReplicateB con)); 14880 ins_cost(INSN_COST); 14881 format %{ "movi $dst, $con\t# vector(8B)" %} 14882 ins_encode %{ 14883 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 14884 %} 14885 ins_pipe(vmovi_reg_imm64); 14886 %} 14887 14888 instruct replicate16B_imm(vecX dst, immI con) 14889 %{ 14890 predicate(n->as_Vector()->length() == 16); 14891 match(Set dst (ReplicateB con)); 14892 ins_cost(INSN_COST); 14893 format %{ "movi $dst, $con\t# vector(16B)" %} 14894 ins_encode %{ 14895 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 14896 %} 14897 ins_pipe(vmovi_reg_imm128); 14898 %} 14899 14900 instruct replicate4S(vecD dst, iRegIorL2I src) 14901 %{ 14902 predicate(n->as_Vector()->length() == 2 || 14903 n->as_Vector()->length() == 4); 14904 match(Set dst (ReplicateS src)); 14905 ins_cost(INSN_COST); 14906 format %{ "dup $dst, $src\t# vector (4S)" %} 14907 ins_encode %{ 14908 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 14909 %} 14910 ins_pipe(vdup_reg_reg64); 14911 %} 14912 14913 instruct replicate8S(vecX dst, iRegIorL2I src) 14914 %{ 14915 predicate(n->as_Vector()->length() == 8); 14916 match(Set dst (ReplicateS src)); 14917 ins_cost(INSN_COST); 14918 format %{ "dup $dst, $src\t# vector (8S)" %} 14919 ins_encode %{ 14920 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 14921 %} 14922 ins_pipe(vdup_reg_reg128); 14923 %} 14924 14925 instruct replicate4S_imm(vecD dst, immI con) 14926 %{ 14927 predicate(n->as_Vector()->length() == 2 || 14928 n->as_Vector()->length() == 4); 14929 match(Set dst (ReplicateS con)); 14930 ins_cost(INSN_COST); 14931 format %{ "movi $dst, $con\t# vector(4H)" %} 14932 ins_encode %{ 14933 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 14934 %} 14935 ins_pipe(vmovi_reg_imm64); 14936 %} 14937 14938 instruct replicate8S_imm(vecX dst, immI con) 14939 %{ 14940 predicate(n->as_Vector()->length() == 8); 14941 match(Set dst (ReplicateS con)); 14942 ins_cost(INSN_COST); 14943 format %{ "movi $dst, $con\t# vector(8H)" %} 14944 ins_encode %{ 14945 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 14946 %} 14947 ins_pipe(vmovi_reg_imm128); 14948 %} 14949 14950 instruct replicate2I(vecD dst, iRegIorL2I src) 14951 %{ 14952 predicate(n->as_Vector()->length() == 2); 14953 match(Set dst (ReplicateI src)); 14954 ins_cost(INSN_COST); 14955 format %{ "dup $dst, $src\t# vector (2I)" %} 14956 ins_encode %{ 14957 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 14958 %} 14959 ins_pipe(vdup_reg_reg64); 14960 %} 14961 14962 instruct replicate4I(vecX dst, iRegIorL2I src) 14963 %{ 14964 predicate(n->as_Vector()->length() == 4); 14965 match(Set dst (ReplicateI src)); 14966 ins_cost(INSN_COST); 14967 format %{ "dup $dst, $src\t# vector (4I)" %} 14968 ins_encode %{ 14969 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 14970 %} 14971 ins_pipe(vdup_reg_reg128); 14972 %} 14973 14974 instruct replicate2I_imm(vecD dst, immI con) 14975 %{ 14976 predicate(n->as_Vector()->length() == 2); 14977 match(Set dst (ReplicateI con)); 14978 ins_cost(INSN_COST); 14979 format %{ "movi $dst, $con\t# vector(2I)" %} 14980 ins_encode %{ 14981 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 14982 %} 14983 ins_pipe(vmovi_reg_imm64); 14984 %} 14985 14986 instruct replicate4I_imm(vecX dst, immI con) 14987 %{ 14988 predicate(n->as_Vector()->length() == 4); 14989 match(Set dst (ReplicateI con)); 14990 ins_cost(INSN_COST); 14991 format %{ "movi $dst, $con\t# vector(4I)" %} 14992 ins_encode %{ 14993 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 14994 %} 14995 ins_pipe(vmovi_reg_imm128); 14996 %} 14997 14998 instruct replicate2L(vecX dst, iRegL src) 14999 %{ 15000 predicate(n->as_Vector()->length() == 2); 15001 match(Set dst (ReplicateL src)); 15002 ins_cost(INSN_COST); 15003 format %{ "dup $dst, $src\t# vector (2L)" %} 15004 ins_encode %{ 15005 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15006 %} 15007 ins_pipe(vdup_reg_reg128); 15008 %} 15009 15010 instruct replicate2L_zero(vecX dst, immI0 zero) 15011 %{ 15012 predicate(n->as_Vector()->length() == 2); 15013 match(Set dst (ReplicateI zero)); 15014 ins_cost(INSN_COST); 15015 format %{ "movi $dst, $zero\t# vector(4I)" %} 15016 ins_encode %{ 15017 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15018 as_FloatRegister($dst$$reg), 15019 as_FloatRegister($dst$$reg)); 15020 %} 15021 ins_pipe(vmovi_reg_imm128); 15022 %} 15023 15024 instruct replicate2F(vecD dst, vRegF src) 15025 %{ 15026 predicate(n->as_Vector()->length() == 2); 15027 match(Set dst (ReplicateF src)); 15028 ins_cost(INSN_COST); 15029 format %{ "dup $dst, $src\t# vector (2F)" %} 15030 ins_encode %{ 15031 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15032 as_FloatRegister($src$$reg)); 15033 %} 15034 ins_pipe(vdup_reg_freg64); 15035 %} 15036 15037 instruct replicate4F(vecX dst, vRegF src) 15038 %{ 15039 predicate(n->as_Vector()->length() == 4); 15040 match(Set dst (ReplicateF src)); 15041 ins_cost(INSN_COST); 15042 format %{ "dup $dst, $src\t# vector (4F)" %} 15043 ins_encode %{ 15044 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15045 as_FloatRegister($src$$reg)); 15046 %} 15047 ins_pipe(vdup_reg_freg128); 15048 %} 15049 15050 instruct replicate2D(vecX dst, vRegD src) 15051 %{ 15052 predicate(n->as_Vector()->length() == 2); 15053 match(Set dst (ReplicateD src)); 15054 ins_cost(INSN_COST); 15055 format %{ "dup $dst, $src\t# vector (2D)" %} 15056 ins_encode %{ 15057 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15058 as_FloatRegister($src$$reg)); 15059 %} 15060 ins_pipe(vdup_reg_dreg128); 15061 %} 15062 15063 // ====================REDUCTION ARITHMETIC==================================== 15064 15065 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15066 %{ 15067 match(Set dst (AddReductionVI src1 src2)); 15068 ins_cost(INSN_COST); 15069 effect(TEMP tmp, TEMP tmp2); 15070 format %{ "umov $tmp, $src2, S, 0\n\t" 15071 "umov $tmp2, $src2, S, 1\n\t" 15072 "addw $dst, $src1, $tmp\n\t" 15073 "addw $dst, $dst, $tmp2\t add reduction2i" 15074 %} 15075 ins_encode %{ 15076 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15077 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15078 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15079 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15080 %} 15081 ins_pipe(pipe_class_default); 15082 %} 15083 15084 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15085 %{ 15086 match(Set dst (AddReductionVI src1 src2)); 15087 ins_cost(INSN_COST); 15088 effect(TEMP tmp, TEMP tmp2); 15089 format %{ "addv $tmp, T4S, $src2\n\t" 15090 "umov $tmp2, $tmp, S, 0\n\t" 15091 "addw $dst, $tmp2, $src1\t add reduction4i" 15092 %} 15093 ins_encode %{ 15094 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15095 as_FloatRegister($src2$$reg)); 15096 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15097 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15098 %} 15099 ins_pipe(pipe_class_default); 15100 %} 15101 15102 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15103 %{ 15104 match(Set dst (MulReductionVI src1 src2)); 15105 ins_cost(INSN_COST); 15106 effect(TEMP tmp, TEMP dst); 15107 format %{ "umov $tmp, $src2, S, 0\n\t" 15108 "mul $dst, $tmp, $src1\n\t" 15109 "umov $tmp, $src2, S, 1\n\t" 15110 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15111 %} 15112 ins_encode %{ 15113 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15114 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15115 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15116 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15117 %} 15118 ins_pipe(pipe_class_default); 15119 %} 15120 15121 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15122 %{ 15123 match(Set dst (MulReductionVI src1 src2)); 15124 ins_cost(INSN_COST); 15125 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15126 format %{ "ins $tmp, $src2, 0, 1\n\t" 15127 "mul $tmp, $tmp, $src2\n\t" 15128 "umov $tmp2, $tmp, S, 0\n\t" 15129 "mul $dst, $tmp2, $src1\n\t" 15130 "umov $tmp2, $tmp, S, 1\n\t" 15131 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15132 %} 15133 ins_encode %{ 15134 __ ins(as_FloatRegister($tmp$$reg), __ D, 15135 as_FloatRegister($src2$$reg), 0, 1); 15136 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15137 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15138 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15139 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15140 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15141 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15142 %} 15143 ins_pipe(pipe_class_default); 15144 %} 15145 15146 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15147 %{ 15148 match(Set dst (AddReductionVF src1 src2)); 15149 ins_cost(INSN_COST); 15150 effect(TEMP tmp, TEMP dst); 15151 format %{ "fadds $dst, $src1, $src2\n\t" 15152 "ins $tmp, S, $src2, 0, 1\n\t" 15153 "fadds $dst, $dst, $tmp\t add reduction2f" 15154 %} 15155 ins_encode %{ 15156 __ fadds(as_FloatRegister($dst$$reg), 15157 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15158 __ ins(as_FloatRegister($tmp$$reg), __ S, 15159 as_FloatRegister($src2$$reg), 0, 1); 15160 __ fadds(as_FloatRegister($dst$$reg), 15161 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15162 %} 15163 ins_pipe(pipe_class_default); 15164 %} 15165 15166 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15167 %{ 15168 match(Set dst (AddReductionVF src1 src2)); 15169 ins_cost(INSN_COST); 15170 effect(TEMP tmp, TEMP dst); 15171 format %{ "fadds $dst, $src1, $src2\n\t" 15172 "ins $tmp, S, $src2, 0, 1\n\t" 15173 "fadds $dst, $dst, $tmp\n\t" 15174 "ins $tmp, S, $src2, 0, 2\n\t" 15175 "fadds $dst, $dst, $tmp\n\t" 15176 "ins $tmp, S, $src2, 0, 3\n\t" 15177 "fadds $dst, $dst, $tmp\t add reduction4f" 15178 %} 15179 ins_encode %{ 15180 __ fadds(as_FloatRegister($dst$$reg), 15181 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15182 __ ins(as_FloatRegister($tmp$$reg), __ S, 15183 as_FloatRegister($src2$$reg), 0, 1); 15184 __ fadds(as_FloatRegister($dst$$reg), 15185 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15186 __ ins(as_FloatRegister($tmp$$reg), __ S, 15187 as_FloatRegister($src2$$reg), 0, 2); 15188 __ fadds(as_FloatRegister($dst$$reg), 15189 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15190 __ ins(as_FloatRegister($tmp$$reg), __ S, 15191 as_FloatRegister($src2$$reg), 0, 3); 15192 __ fadds(as_FloatRegister($dst$$reg), 15193 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15194 %} 15195 ins_pipe(pipe_class_default); 15196 %} 15197 15198 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15199 %{ 15200 match(Set dst (MulReductionVF src1 src2)); 15201 ins_cost(INSN_COST); 15202 effect(TEMP tmp, TEMP dst); 15203 format %{ "fmuls $dst, $src1, $src2\n\t" 15204 "ins $tmp, S, $src2, 0, 1\n\t" 15205 "fmuls $dst, $dst, $tmp\t add reduction4f" 15206 %} 15207 ins_encode %{ 15208 __ fmuls(as_FloatRegister($dst$$reg), 15209 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15210 __ ins(as_FloatRegister($tmp$$reg), __ S, 15211 as_FloatRegister($src2$$reg), 0, 1); 15212 __ fmuls(as_FloatRegister($dst$$reg), 15213 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15214 %} 15215 ins_pipe(pipe_class_default); 15216 %} 15217 15218 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15219 %{ 15220 match(Set dst (MulReductionVF src1 src2)); 15221 ins_cost(INSN_COST); 15222 effect(TEMP tmp, TEMP dst); 15223 format %{ "fmuls $dst, $src1, $src2\n\t" 15224 "ins $tmp, S, $src2, 0, 1\n\t" 15225 "fmuls $dst, $dst, $tmp\n\t" 15226 "ins $tmp, S, $src2, 0, 2\n\t" 15227 "fmuls $dst, $dst, $tmp\n\t" 15228 "ins $tmp, S, $src2, 0, 3\n\t" 15229 "fmuls $dst, $dst, $tmp\t add reduction4f" 15230 %} 15231 ins_encode %{ 15232 __ fmuls(as_FloatRegister($dst$$reg), 15233 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15234 __ ins(as_FloatRegister($tmp$$reg), __ S, 15235 as_FloatRegister($src2$$reg), 0, 1); 15236 __ fmuls(as_FloatRegister($dst$$reg), 15237 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15238 __ ins(as_FloatRegister($tmp$$reg), __ S, 15239 as_FloatRegister($src2$$reg), 0, 2); 15240 __ fmuls(as_FloatRegister($dst$$reg), 15241 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15242 __ ins(as_FloatRegister($tmp$$reg), __ S, 15243 as_FloatRegister($src2$$reg), 0, 3); 15244 __ fmuls(as_FloatRegister($dst$$reg), 15245 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15246 %} 15247 ins_pipe(pipe_class_default); 15248 %} 15249 15250 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15251 %{ 15252 match(Set dst (AddReductionVD src1 src2)); 15253 ins_cost(INSN_COST); 15254 effect(TEMP tmp, TEMP dst); 15255 format %{ "faddd $dst, $src1, $src2\n\t" 15256 "ins $tmp, D, $src2, 0, 1\n\t" 15257 "faddd $dst, $dst, $tmp\t add reduction2d" 15258 %} 15259 ins_encode %{ 15260 __ faddd(as_FloatRegister($dst$$reg), 15261 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15262 __ ins(as_FloatRegister($tmp$$reg), __ D, 15263 as_FloatRegister($src2$$reg), 0, 1); 15264 __ faddd(as_FloatRegister($dst$$reg), 15265 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15266 %} 15267 ins_pipe(pipe_class_default); 15268 %} 15269 15270 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15271 %{ 15272 match(Set dst (MulReductionVD src1 src2)); 15273 ins_cost(INSN_COST); 15274 effect(TEMP tmp, TEMP dst); 15275 format %{ "fmuld $dst, $src1, $src2\n\t" 15276 "ins $tmp, D, $src2, 0, 1\n\t" 15277 "fmuld $dst, $dst, $tmp\t add reduction2d" 15278 %} 15279 ins_encode %{ 15280 __ fmuld(as_FloatRegister($dst$$reg), 15281 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15282 __ ins(as_FloatRegister($tmp$$reg), __ D, 15283 as_FloatRegister($src2$$reg), 0, 1); 15284 __ fmuld(as_FloatRegister($dst$$reg), 15285 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15286 %} 15287 ins_pipe(pipe_class_default); 15288 %} 15289 15290 // ====================VECTOR ARITHMETIC======================================= 15291 15292 // --------------------------------- ADD -------------------------------------- 15293 15294 instruct vadd8B(vecD dst, vecD src1, vecD src2) 15295 %{ 15296 predicate(n->as_Vector()->length() == 4 || 15297 n->as_Vector()->length() == 8); 15298 match(Set dst (AddVB src1 src2)); 15299 ins_cost(INSN_COST); 15300 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 15301 ins_encode %{ 15302 __ addv(as_FloatRegister($dst$$reg), __ T8B, 15303 as_FloatRegister($src1$$reg), 15304 as_FloatRegister($src2$$reg)); 15305 %} 15306 ins_pipe(vdop64); 15307 %} 15308 15309 instruct vadd16B(vecX dst, vecX src1, vecX src2) 15310 %{ 15311 predicate(n->as_Vector()->length() == 16); 15312 match(Set dst (AddVB src1 src2)); 15313 ins_cost(INSN_COST); 15314 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 15315 ins_encode %{ 15316 __ addv(as_FloatRegister($dst$$reg), __ T16B, 15317 as_FloatRegister($src1$$reg), 15318 as_FloatRegister($src2$$reg)); 15319 %} 15320 ins_pipe(vdop128); 15321 %} 15322 15323 instruct vadd4S(vecD dst, vecD src1, vecD src2) 15324 %{ 15325 predicate(n->as_Vector()->length() == 2 || 15326 n->as_Vector()->length() == 4); 15327 match(Set dst (AddVS src1 src2)); 15328 ins_cost(INSN_COST); 15329 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 15330 ins_encode %{ 15331 __ addv(as_FloatRegister($dst$$reg), __ T4H, 15332 as_FloatRegister($src1$$reg), 15333 as_FloatRegister($src2$$reg)); 15334 %} 15335 ins_pipe(vdop64); 15336 %} 15337 15338 instruct vadd8S(vecX dst, vecX src1, vecX src2) 15339 %{ 15340 predicate(n->as_Vector()->length() == 8); 15341 match(Set dst (AddVS src1 src2)); 15342 ins_cost(INSN_COST); 15343 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 15344 ins_encode %{ 15345 __ addv(as_FloatRegister($dst$$reg), __ T8H, 15346 as_FloatRegister($src1$$reg), 15347 as_FloatRegister($src2$$reg)); 15348 %} 15349 ins_pipe(vdop128); 15350 %} 15351 15352 instruct vadd2I(vecD dst, vecD src1, vecD src2) 15353 %{ 15354 predicate(n->as_Vector()->length() == 2); 15355 match(Set dst (AddVI src1 src2)); 15356 ins_cost(INSN_COST); 15357 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 15358 ins_encode %{ 15359 __ addv(as_FloatRegister($dst$$reg), __ T2S, 15360 as_FloatRegister($src1$$reg), 15361 as_FloatRegister($src2$$reg)); 15362 %} 15363 ins_pipe(vdop64); 15364 %} 15365 15366 instruct vadd4I(vecX dst, vecX src1, vecX src2) 15367 %{ 15368 predicate(n->as_Vector()->length() == 4); 15369 match(Set dst (AddVI src1 src2)); 15370 ins_cost(INSN_COST); 15371 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 15372 ins_encode %{ 15373 __ addv(as_FloatRegister($dst$$reg), __ T4S, 15374 as_FloatRegister($src1$$reg), 15375 as_FloatRegister($src2$$reg)); 15376 %} 15377 ins_pipe(vdop128); 15378 %} 15379 15380 instruct vadd2L(vecX dst, vecX src1, vecX src2) 15381 %{ 15382 predicate(n->as_Vector()->length() == 2); 15383 match(Set dst (AddVL src1 src2)); 15384 ins_cost(INSN_COST); 15385 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 15386 ins_encode %{ 15387 __ addv(as_FloatRegister($dst$$reg), __ T2D, 15388 as_FloatRegister($src1$$reg), 15389 as_FloatRegister($src2$$reg)); 15390 %} 15391 ins_pipe(vdop128); 15392 %} 15393 15394 instruct vadd2F(vecD dst, vecD src1, vecD src2) 15395 %{ 15396 predicate(n->as_Vector()->length() == 2); 15397 match(Set dst (AddVF src1 src2)); 15398 ins_cost(INSN_COST); 15399 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 15400 ins_encode %{ 15401 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 15402 as_FloatRegister($src1$$reg), 15403 as_FloatRegister($src2$$reg)); 15404 %} 15405 ins_pipe(vdop_fp64); 15406 %} 15407 15408 instruct vadd4F(vecX dst, vecX src1, vecX src2) 15409 %{ 15410 predicate(n->as_Vector()->length() == 4); 15411 match(Set dst (AddVF src1 src2)); 15412 ins_cost(INSN_COST); 15413 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 15414 ins_encode %{ 15415 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 15416 as_FloatRegister($src1$$reg), 15417 as_FloatRegister($src2$$reg)); 15418 %} 15419 ins_pipe(vdop_fp128); 15420 %} 15421 15422 instruct vadd2D(vecX dst, vecX src1, vecX src2) 15423 %{ 15424 match(Set dst (AddVD src1 src2)); 15425 ins_cost(INSN_COST); 15426 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 15427 ins_encode %{ 15428 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 15429 as_FloatRegister($src1$$reg), 15430 as_FloatRegister($src2$$reg)); 15431 %} 15432 ins_pipe(vdop_fp128); 15433 %} 15434 15435 // --------------------------------- SUB -------------------------------------- 15436 15437 instruct vsub8B(vecD dst, vecD src1, vecD src2) 15438 %{ 15439 predicate(n->as_Vector()->length() == 4 || 15440 n->as_Vector()->length() == 8); 15441 match(Set dst (SubVB src1 src2)); 15442 ins_cost(INSN_COST); 15443 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 15444 ins_encode %{ 15445 __ subv(as_FloatRegister($dst$$reg), __ T8B, 15446 as_FloatRegister($src1$$reg), 15447 as_FloatRegister($src2$$reg)); 15448 %} 15449 ins_pipe(vdop64); 15450 %} 15451 15452 instruct vsub16B(vecX dst, vecX src1, vecX src2) 15453 %{ 15454 predicate(n->as_Vector()->length() == 16); 15455 match(Set dst (SubVB src1 src2)); 15456 ins_cost(INSN_COST); 15457 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 15458 ins_encode %{ 15459 __ subv(as_FloatRegister($dst$$reg), __ T16B, 15460 as_FloatRegister($src1$$reg), 15461 as_FloatRegister($src2$$reg)); 15462 %} 15463 ins_pipe(vdop128); 15464 %} 15465 15466 instruct vsub4S(vecD dst, vecD src1, vecD src2) 15467 %{ 15468 predicate(n->as_Vector()->length() == 2 || 15469 n->as_Vector()->length() == 4); 15470 match(Set dst (SubVS src1 src2)); 15471 ins_cost(INSN_COST); 15472 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 15473 ins_encode %{ 15474 __ subv(as_FloatRegister($dst$$reg), __ T4H, 15475 as_FloatRegister($src1$$reg), 15476 as_FloatRegister($src2$$reg)); 15477 %} 15478 ins_pipe(vdop64); 15479 %} 15480 15481 instruct vsub8S(vecX dst, vecX src1, vecX src2) 15482 %{ 15483 predicate(n->as_Vector()->length() == 8); 15484 match(Set dst (SubVS src1 src2)); 15485 ins_cost(INSN_COST); 15486 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 15487 ins_encode %{ 15488 __ subv(as_FloatRegister($dst$$reg), __ T8H, 15489 as_FloatRegister($src1$$reg), 15490 as_FloatRegister($src2$$reg)); 15491 %} 15492 ins_pipe(vdop128); 15493 %} 15494 15495 instruct vsub2I(vecD dst, vecD src1, vecD src2) 15496 %{ 15497 predicate(n->as_Vector()->length() == 2); 15498 match(Set dst (SubVI src1 src2)); 15499 ins_cost(INSN_COST); 15500 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 15501 ins_encode %{ 15502 __ subv(as_FloatRegister($dst$$reg), __ T2S, 15503 as_FloatRegister($src1$$reg), 15504 as_FloatRegister($src2$$reg)); 15505 %} 15506 ins_pipe(vdop64); 15507 %} 15508 15509 instruct vsub4I(vecX dst, vecX src1, vecX src2) 15510 %{ 15511 predicate(n->as_Vector()->length() == 4); 15512 match(Set dst (SubVI src1 src2)); 15513 ins_cost(INSN_COST); 15514 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 15515 ins_encode %{ 15516 __ subv(as_FloatRegister($dst$$reg), __ T4S, 15517 as_FloatRegister($src1$$reg), 15518 as_FloatRegister($src2$$reg)); 15519 %} 15520 ins_pipe(vdop128); 15521 %} 15522 15523 instruct vsub2L(vecX dst, vecX src1, vecX src2) 15524 %{ 15525 predicate(n->as_Vector()->length() == 2); 15526 match(Set dst (SubVL src1 src2)); 15527 ins_cost(INSN_COST); 15528 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 15529 ins_encode %{ 15530 __ subv(as_FloatRegister($dst$$reg), __ T2D, 15531 as_FloatRegister($src1$$reg), 15532 as_FloatRegister($src2$$reg)); 15533 %} 15534 ins_pipe(vdop128); 15535 %} 15536 15537 instruct vsub2F(vecD dst, vecD src1, vecD src2) 15538 %{ 15539 predicate(n->as_Vector()->length() == 2); 15540 match(Set dst (SubVF src1 src2)); 15541 ins_cost(INSN_COST); 15542 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 15543 ins_encode %{ 15544 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 15545 as_FloatRegister($src1$$reg), 15546 as_FloatRegister($src2$$reg)); 15547 %} 15548 ins_pipe(vdop_fp64); 15549 %} 15550 15551 instruct vsub4F(vecX dst, vecX src1, vecX src2) 15552 %{ 15553 predicate(n->as_Vector()->length() == 4); 15554 match(Set dst (SubVF src1 src2)); 15555 ins_cost(INSN_COST); 15556 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 15557 ins_encode %{ 15558 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 15559 as_FloatRegister($src1$$reg), 15560 as_FloatRegister($src2$$reg)); 15561 %} 15562 ins_pipe(vdop_fp128); 15563 %} 15564 15565 instruct vsub2D(vecX dst, vecX src1, vecX src2) 15566 %{ 15567 predicate(n->as_Vector()->length() == 2); 15568 match(Set dst (SubVD src1 src2)); 15569 ins_cost(INSN_COST); 15570 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 15571 ins_encode %{ 15572 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 15573 as_FloatRegister($src1$$reg), 15574 as_FloatRegister($src2$$reg)); 15575 %} 15576 ins_pipe(vdop_fp128); 15577 %} 15578 15579 // --------------------------------- MUL -------------------------------------- 15580 15581 instruct vmul4S(vecD dst, vecD src1, vecD src2) 15582 %{ 15583 predicate(n->as_Vector()->length() == 2 || 15584 n->as_Vector()->length() == 4); 15585 match(Set dst (MulVS src1 src2)); 15586 ins_cost(INSN_COST); 15587 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 15588 ins_encode %{ 15589 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 15590 as_FloatRegister($src1$$reg), 15591 as_FloatRegister($src2$$reg)); 15592 %} 15593 ins_pipe(vmul64); 15594 %} 15595 15596 instruct vmul8S(vecX dst, vecX src1, vecX src2) 15597 %{ 15598 predicate(n->as_Vector()->length() == 8); 15599 match(Set dst (MulVS src1 src2)); 15600 ins_cost(INSN_COST); 15601 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 15602 ins_encode %{ 15603 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 15604 as_FloatRegister($src1$$reg), 15605 as_FloatRegister($src2$$reg)); 15606 %} 15607 ins_pipe(vmul128); 15608 %} 15609 15610 instruct vmul2I(vecD dst, vecD src1, vecD src2) 15611 %{ 15612 predicate(n->as_Vector()->length() == 2); 15613 match(Set dst (MulVI src1 src2)); 15614 ins_cost(INSN_COST); 15615 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 15616 ins_encode %{ 15617 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 15618 as_FloatRegister($src1$$reg), 15619 as_FloatRegister($src2$$reg)); 15620 %} 15621 ins_pipe(vmul64); 15622 %} 15623 15624 instruct vmul4I(vecX dst, vecX src1, vecX src2) 15625 %{ 15626 predicate(n->as_Vector()->length() == 4); 15627 match(Set dst (MulVI src1 src2)); 15628 ins_cost(INSN_COST); 15629 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 15630 ins_encode %{ 15631 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 15632 as_FloatRegister($src1$$reg), 15633 as_FloatRegister($src2$$reg)); 15634 %} 15635 ins_pipe(vmul128); 15636 %} 15637 15638 instruct vmul2F(vecD dst, vecD src1, vecD src2) 15639 %{ 15640 predicate(n->as_Vector()->length() == 2); 15641 match(Set dst (MulVF src1 src2)); 15642 ins_cost(INSN_COST); 15643 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 15644 ins_encode %{ 15645 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 15646 as_FloatRegister($src1$$reg), 15647 as_FloatRegister($src2$$reg)); 15648 %} 15649 ins_pipe(vmuldiv_fp64); 15650 %} 15651 15652 instruct vmul4F(vecX dst, vecX src1, vecX src2) 15653 %{ 15654 predicate(n->as_Vector()->length() == 4); 15655 match(Set dst (MulVF src1 src2)); 15656 ins_cost(INSN_COST); 15657 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 15658 ins_encode %{ 15659 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 15660 as_FloatRegister($src1$$reg), 15661 as_FloatRegister($src2$$reg)); 15662 %} 15663 ins_pipe(vmuldiv_fp128); 15664 %} 15665 15666 instruct vmul2D(vecX dst, vecX src1, vecX src2) 15667 %{ 15668 predicate(n->as_Vector()->length() == 2); 15669 match(Set dst (MulVD src1 src2)); 15670 ins_cost(INSN_COST); 15671 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 15672 ins_encode %{ 15673 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 15674 as_FloatRegister($src1$$reg), 15675 as_FloatRegister($src2$$reg)); 15676 %} 15677 ins_pipe(vmuldiv_fp128); 15678 %} 15679 15680 // --------------------------------- MLA -------------------------------------- 15681 15682 instruct vmla4S(vecD dst, vecD src1, vecD src2) 15683 %{ 15684 predicate(n->as_Vector()->length() == 2 || 15685 n->as_Vector()->length() == 4); 15686 match(Set dst (AddVS dst (MulVS src1 src2))); 15687 ins_cost(INSN_COST); 15688 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 15689 ins_encode %{ 15690 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 15691 as_FloatRegister($src1$$reg), 15692 as_FloatRegister($src2$$reg)); 15693 %} 15694 ins_pipe(vmla64); 15695 %} 15696 15697 instruct vmla8S(vecX dst, vecX src1, vecX src2) 15698 %{ 15699 predicate(n->as_Vector()->length() == 8); 15700 match(Set dst (AddVS dst (MulVS src1 src2))); 15701 ins_cost(INSN_COST); 15702 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 15703 ins_encode %{ 15704 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 15705 as_FloatRegister($src1$$reg), 15706 as_FloatRegister($src2$$reg)); 15707 %} 15708 ins_pipe(vmla128); 15709 %} 15710 15711 instruct vmla2I(vecD dst, vecD src1, vecD src2) 15712 %{ 15713 predicate(n->as_Vector()->length() == 2); 15714 match(Set dst (AddVI dst (MulVI src1 src2))); 15715 ins_cost(INSN_COST); 15716 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 15717 ins_encode %{ 15718 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 15719 as_FloatRegister($src1$$reg), 15720 as_FloatRegister($src2$$reg)); 15721 %} 15722 ins_pipe(vmla64); 15723 %} 15724 15725 instruct vmla4I(vecX dst, vecX src1, vecX src2) 15726 %{ 15727 predicate(n->as_Vector()->length() == 4); 15728 match(Set dst (AddVI dst (MulVI src1 src2))); 15729 ins_cost(INSN_COST); 15730 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 15731 ins_encode %{ 15732 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 15733 as_FloatRegister($src1$$reg), 15734 as_FloatRegister($src2$$reg)); 15735 %} 15736 ins_pipe(vmla128); 15737 %} 15738 15739 // dst + src1 * src2 15740 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 15741 predicate(UseFMA && n->as_Vector()->length() == 2); 15742 match(Set dst (FmaVF dst (Binary src1 src2))); 15743 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 15744 ins_cost(INSN_COST); 15745 ins_encode %{ 15746 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 15747 as_FloatRegister($src1$$reg), 15748 as_FloatRegister($src2$$reg)); 15749 %} 15750 ins_pipe(vmuldiv_fp64); 15751 %} 15752 15753 // dst + src1 * src2 15754 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 15755 predicate(UseFMA && n->as_Vector()->length() == 4); 15756 match(Set dst (FmaVF dst (Binary src1 src2))); 15757 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 15758 ins_cost(INSN_COST); 15759 ins_encode %{ 15760 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 15761 as_FloatRegister($src1$$reg), 15762 as_FloatRegister($src2$$reg)); 15763 %} 15764 ins_pipe(vmuldiv_fp128); 15765 %} 15766 15767 // dst + src1 * src2 15768 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 15769 predicate(UseFMA && n->as_Vector()->length() == 2); 15770 match(Set dst (FmaVD dst (Binary src1 src2))); 15771 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 15772 ins_cost(INSN_COST); 15773 ins_encode %{ 15774 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 15775 as_FloatRegister($src1$$reg), 15776 as_FloatRegister($src2$$reg)); 15777 %} 15778 ins_pipe(vmuldiv_fp128); 15779 %} 15780 15781 // --------------------------------- MLS -------------------------------------- 15782 15783 instruct vmls4S(vecD dst, vecD src1, vecD src2) 15784 %{ 15785 predicate(n->as_Vector()->length() == 2 || 15786 n->as_Vector()->length() == 4); 15787 match(Set dst (SubVS dst (MulVS src1 src2))); 15788 ins_cost(INSN_COST); 15789 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 15790 ins_encode %{ 15791 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 15792 as_FloatRegister($src1$$reg), 15793 as_FloatRegister($src2$$reg)); 15794 %} 15795 ins_pipe(vmla64); 15796 %} 15797 15798 instruct vmls8S(vecX dst, vecX src1, vecX src2) 15799 %{ 15800 predicate(n->as_Vector()->length() == 8); 15801 match(Set dst (SubVS dst (MulVS src1 src2))); 15802 ins_cost(INSN_COST); 15803 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 15804 ins_encode %{ 15805 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 15806 as_FloatRegister($src1$$reg), 15807 as_FloatRegister($src2$$reg)); 15808 %} 15809 ins_pipe(vmla128); 15810 %} 15811 15812 instruct vmls2I(vecD dst, vecD src1, vecD src2) 15813 %{ 15814 predicate(n->as_Vector()->length() == 2); 15815 match(Set dst (SubVI dst (MulVI src1 src2))); 15816 ins_cost(INSN_COST); 15817 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 15818 ins_encode %{ 15819 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 15820 as_FloatRegister($src1$$reg), 15821 as_FloatRegister($src2$$reg)); 15822 %} 15823 ins_pipe(vmla64); 15824 %} 15825 15826 instruct vmls4I(vecX dst, vecX src1, vecX src2) 15827 %{ 15828 predicate(n->as_Vector()->length() == 4); 15829 match(Set dst (SubVI dst (MulVI src1 src2))); 15830 ins_cost(INSN_COST); 15831 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 15832 ins_encode %{ 15833 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 15834 as_FloatRegister($src1$$reg), 15835 as_FloatRegister($src2$$reg)); 15836 %} 15837 ins_pipe(vmla128); 15838 %} 15839 15840 // dst - src1 * src2 15841 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 15842 predicate(UseFMA && n->as_Vector()->length() == 2); 15843 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 15844 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 15845 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 15846 ins_cost(INSN_COST); 15847 ins_encode %{ 15848 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 15849 as_FloatRegister($src1$$reg), 15850 as_FloatRegister($src2$$reg)); 15851 %} 15852 ins_pipe(vmuldiv_fp64); 15853 %} 15854 15855 // dst - src1 * src2 15856 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 15857 predicate(UseFMA && n->as_Vector()->length() == 4); 15858 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 15859 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 15860 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 15861 ins_cost(INSN_COST); 15862 ins_encode %{ 15863 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 15864 as_FloatRegister($src1$$reg), 15865 as_FloatRegister($src2$$reg)); 15866 %} 15867 ins_pipe(vmuldiv_fp128); 15868 %} 15869 15870 // dst - src1 * src2 15871 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 15872 predicate(UseFMA && n->as_Vector()->length() == 2); 15873 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 15874 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 15875 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 15876 ins_cost(INSN_COST); 15877 ins_encode %{ 15878 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 15879 as_FloatRegister($src1$$reg), 15880 as_FloatRegister($src2$$reg)); 15881 %} 15882 ins_pipe(vmuldiv_fp128); 15883 %} 15884 15885 // --------------------------------- DIV -------------------------------------- 15886 15887 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 15888 %{ 15889 predicate(n->as_Vector()->length() == 2); 15890 match(Set dst (DivVF src1 src2)); 15891 ins_cost(INSN_COST); 15892 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 15893 ins_encode %{ 15894 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 15895 as_FloatRegister($src1$$reg), 15896 as_FloatRegister($src2$$reg)); 15897 %} 15898 ins_pipe(vmuldiv_fp64); 15899 %} 15900 15901 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 15902 %{ 15903 predicate(n->as_Vector()->length() == 4); 15904 match(Set dst (DivVF src1 src2)); 15905 ins_cost(INSN_COST); 15906 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 15907 ins_encode %{ 15908 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 15909 as_FloatRegister($src1$$reg), 15910 as_FloatRegister($src2$$reg)); 15911 %} 15912 ins_pipe(vmuldiv_fp128); 15913 %} 15914 15915 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 15916 %{ 15917 predicate(n->as_Vector()->length() == 2); 15918 match(Set dst (DivVD src1 src2)); 15919 ins_cost(INSN_COST); 15920 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 15921 ins_encode %{ 15922 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 15923 as_FloatRegister($src1$$reg), 15924 as_FloatRegister($src2$$reg)); 15925 %} 15926 ins_pipe(vmuldiv_fp128); 15927 %} 15928 15929 // --------------------------------- SQRT ------------------------------------- 15930 15931 instruct vsqrt2D(vecX dst, vecX src) 15932 %{ 15933 predicate(n->as_Vector()->length() == 2); 15934 match(Set dst (SqrtVD src)); 15935 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 15936 ins_encode %{ 15937 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 15938 as_FloatRegister($src$$reg)); 15939 %} 15940 ins_pipe(vsqrt_fp128); 15941 %} 15942 15943 // --------------------------------- ABS -------------------------------------- 15944 15945 instruct vabs2F(vecD dst, vecD src) 15946 %{ 15947 predicate(n->as_Vector()->length() == 2); 15948 match(Set dst (AbsVF src)); 15949 ins_cost(INSN_COST * 3); 15950 format %{ "fabs $dst,$src\t# vector (2S)" %} 15951 ins_encode %{ 15952 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 15953 as_FloatRegister($src$$reg)); 15954 %} 15955 ins_pipe(vunop_fp64); 15956 %} 15957 15958 instruct vabs4F(vecX dst, vecX src) 15959 %{ 15960 predicate(n->as_Vector()->length() == 4); 15961 match(Set dst (AbsVF src)); 15962 ins_cost(INSN_COST * 3); 15963 format %{ "fabs $dst,$src\t# vector (4S)" %} 15964 ins_encode %{ 15965 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 15966 as_FloatRegister($src$$reg)); 15967 %} 15968 ins_pipe(vunop_fp128); 15969 %} 15970 15971 instruct vabs2D(vecX dst, vecX src) 15972 %{ 15973 predicate(n->as_Vector()->length() == 2); 15974 match(Set dst (AbsVD src)); 15975 ins_cost(INSN_COST * 3); 15976 format %{ "fabs $dst,$src\t# vector (2D)" %} 15977 ins_encode %{ 15978 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 15979 as_FloatRegister($src$$reg)); 15980 %} 15981 ins_pipe(vunop_fp128); 15982 %} 15983 15984 // --------------------------------- NEG -------------------------------------- 15985 15986 instruct vneg2F(vecD dst, vecD src) 15987 %{ 15988 predicate(n->as_Vector()->length() == 2); 15989 match(Set dst (NegVF src)); 15990 ins_cost(INSN_COST * 3); 15991 format %{ "fneg $dst,$src\t# vector (2S)" %} 15992 ins_encode %{ 15993 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 15994 as_FloatRegister($src$$reg)); 15995 %} 15996 ins_pipe(vunop_fp64); 15997 %} 15998 15999 instruct vneg4F(vecX dst, vecX src) 16000 %{ 16001 predicate(n->as_Vector()->length() == 4); 16002 match(Set dst (NegVF src)); 16003 ins_cost(INSN_COST * 3); 16004 format %{ "fneg $dst,$src\t# vector (4S)" %} 16005 ins_encode %{ 16006 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16007 as_FloatRegister($src$$reg)); 16008 %} 16009 ins_pipe(vunop_fp128); 16010 %} 16011 16012 instruct vneg2D(vecX dst, vecX src) 16013 %{ 16014 predicate(n->as_Vector()->length() == 2); 16015 match(Set dst (NegVD src)); 16016 ins_cost(INSN_COST * 3); 16017 format %{ "fneg $dst,$src\t# vector (2D)" %} 16018 ins_encode %{ 16019 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16020 as_FloatRegister($src$$reg)); 16021 %} 16022 ins_pipe(vunop_fp128); 16023 %} 16024 16025 // --------------------------------- AND -------------------------------------- 16026 16027 instruct vand8B(vecD dst, vecD src1, vecD src2) 16028 %{ 16029 predicate(n->as_Vector()->length_in_bytes() == 4 || 16030 n->as_Vector()->length_in_bytes() == 8); 16031 match(Set dst (AndV src1 src2)); 16032 ins_cost(INSN_COST); 16033 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16034 ins_encode %{ 16035 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16036 as_FloatRegister($src1$$reg), 16037 as_FloatRegister($src2$$reg)); 16038 %} 16039 ins_pipe(vlogical64); 16040 %} 16041 16042 instruct vand16B(vecX dst, vecX src1, vecX src2) 16043 %{ 16044 predicate(n->as_Vector()->length_in_bytes() == 16); 16045 match(Set dst (AndV src1 src2)); 16046 ins_cost(INSN_COST); 16047 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16048 ins_encode %{ 16049 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16050 as_FloatRegister($src1$$reg), 16051 as_FloatRegister($src2$$reg)); 16052 %} 16053 ins_pipe(vlogical128); 16054 %} 16055 16056 // --------------------------------- OR --------------------------------------- 16057 16058 instruct vor8B(vecD dst, vecD src1, vecD src2) 16059 %{ 16060 predicate(n->as_Vector()->length_in_bytes() == 4 || 16061 n->as_Vector()->length_in_bytes() == 8); 16062 match(Set dst (OrV src1 src2)); 16063 ins_cost(INSN_COST); 16064 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16065 ins_encode %{ 16066 __ orr(as_FloatRegister($dst$$reg), __ T8B, 16067 as_FloatRegister($src1$$reg), 16068 as_FloatRegister($src2$$reg)); 16069 %} 16070 ins_pipe(vlogical64); 16071 %} 16072 16073 instruct vor16B(vecX dst, vecX src1, vecX src2) 16074 %{ 16075 predicate(n->as_Vector()->length_in_bytes() == 16); 16076 match(Set dst (OrV src1 src2)); 16077 ins_cost(INSN_COST); 16078 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 16079 ins_encode %{ 16080 __ orr(as_FloatRegister($dst$$reg), __ T16B, 16081 as_FloatRegister($src1$$reg), 16082 as_FloatRegister($src2$$reg)); 16083 %} 16084 ins_pipe(vlogical128); 16085 %} 16086 16087 // --------------------------------- XOR -------------------------------------- 16088 16089 instruct vxor8B(vecD dst, vecD src1, vecD src2) 16090 %{ 16091 predicate(n->as_Vector()->length_in_bytes() == 4 || 16092 n->as_Vector()->length_in_bytes() == 8); 16093 match(Set dst (XorV src1 src2)); 16094 ins_cost(INSN_COST); 16095 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 16096 ins_encode %{ 16097 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16098 as_FloatRegister($src1$$reg), 16099 as_FloatRegister($src2$$reg)); 16100 %} 16101 ins_pipe(vlogical64); 16102 %} 16103 16104 instruct vxor16B(vecX dst, vecX src1, vecX src2) 16105 %{ 16106 predicate(n->as_Vector()->length_in_bytes() == 16); 16107 match(Set dst (XorV src1 src2)); 16108 ins_cost(INSN_COST); 16109 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 16110 ins_encode %{ 16111 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16112 as_FloatRegister($src1$$reg), 16113 as_FloatRegister($src2$$reg)); 16114 %} 16115 ins_pipe(vlogical128); 16116 %} 16117 16118 // ------------------------------ Shift --------------------------------------- 16119 16120 instruct vshiftcntL(vecX dst, iRegIorL2I cnt) %{ 16121 match(Set dst (LShiftCntV cnt)); 16122 format %{ "dup $dst, $cnt\t# shift count (vecX)" %} 16123 ins_encode %{ 16124 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16125 %} 16126 ins_pipe(vdup_reg_reg128); 16127 %} 16128 16129 // Right shifts on aarch64 SIMD are implemented as left shift by -ve amount 16130 instruct vshiftcntR(vecX dst, iRegIorL2I cnt) %{ 16131 match(Set dst (RShiftCntV cnt)); 16132 format %{ "dup $dst, $cnt\t# shift count (vecX)\n\tneg $dst, $dst\t T16B" %} 16133 ins_encode %{ 16134 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16135 __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg)); 16136 %} 16137 ins_pipe(vdup_reg_reg128); 16138 %} 16139 16140 instruct vsll8B(vecD dst, vecD src, vecX shift) %{ 16141 predicate(n->as_Vector()->length() == 4 || 16142 n->as_Vector()->length() == 8); 16143 match(Set dst (LShiftVB src shift)); 16144 match(Set dst (RShiftVB src shift)); 16145 ins_cost(INSN_COST); 16146 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 16147 ins_encode %{ 16148 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16149 as_FloatRegister($src$$reg), 16150 as_FloatRegister($shift$$reg)); 16151 %} 16152 ins_pipe(vshift64); 16153 %} 16154 16155 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 16156 predicate(n->as_Vector()->length() == 16); 16157 match(Set dst (LShiftVB src shift)); 16158 match(Set dst (RShiftVB src shift)); 16159 ins_cost(INSN_COST); 16160 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 16161 ins_encode %{ 16162 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16163 as_FloatRegister($src$$reg), 16164 as_FloatRegister($shift$$reg)); 16165 %} 16166 ins_pipe(vshift128); 16167 %} 16168 16169 instruct vsrl8B(vecD dst, vecD src, vecX shift) %{ 16170 predicate(n->as_Vector()->length() == 4 || 16171 n->as_Vector()->length() == 8); 16172 match(Set dst (URShiftVB src shift)); 16173 ins_cost(INSN_COST); 16174 format %{ "ushl $dst,$src,$shift\t# vector (8B)" %} 16175 ins_encode %{ 16176 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 16177 as_FloatRegister($src$$reg), 16178 as_FloatRegister($shift$$reg)); 16179 %} 16180 ins_pipe(vshift64); 16181 %} 16182 16183 instruct vsrl16B(vecX dst, vecX src, vecX shift) %{ 16184 predicate(n->as_Vector()->length() == 16); 16185 match(Set dst (URShiftVB src shift)); 16186 ins_cost(INSN_COST); 16187 format %{ "ushl $dst,$src,$shift\t# vector (16B)" %} 16188 ins_encode %{ 16189 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 16190 as_FloatRegister($src$$reg), 16191 as_FloatRegister($shift$$reg)); 16192 %} 16193 ins_pipe(vshift128); 16194 %} 16195 16196 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 16197 predicate(n->as_Vector()->length() == 4 || 16198 n->as_Vector()->length() == 8); 16199 match(Set dst (LShiftVB src shift)); 16200 ins_cost(INSN_COST); 16201 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 16202 ins_encode %{ 16203 int sh = (int)$shift$$constant; 16204 if (sh >= 8) { 16205 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16206 as_FloatRegister($src$$reg), 16207 as_FloatRegister($src$$reg)); 16208 } else { 16209 __ shl(as_FloatRegister($dst$$reg), __ T8B, 16210 as_FloatRegister($src$$reg), sh); 16211 } 16212 %} 16213 ins_pipe(vshift64_imm); 16214 %} 16215 16216 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 16217 predicate(n->as_Vector()->length() == 16); 16218 match(Set dst (LShiftVB src shift)); 16219 ins_cost(INSN_COST); 16220 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 16221 ins_encode %{ 16222 int sh = (int)$shift$$constant; 16223 if (sh >= 8) { 16224 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16225 as_FloatRegister($src$$reg), 16226 as_FloatRegister($src$$reg)); 16227 } else { 16228 __ shl(as_FloatRegister($dst$$reg), __ T16B, 16229 as_FloatRegister($src$$reg), sh); 16230 } 16231 %} 16232 ins_pipe(vshift128_imm); 16233 %} 16234 16235 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 16236 predicate(n->as_Vector()->length() == 4 || 16237 n->as_Vector()->length() == 8); 16238 match(Set dst (RShiftVB src shift)); 16239 ins_cost(INSN_COST); 16240 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 16241 ins_encode %{ 16242 int sh = (int)$shift$$constant; 16243 if (sh >= 8) sh = 7; 16244 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 16245 as_FloatRegister($src$$reg), sh); 16246 %} 16247 ins_pipe(vshift64_imm); 16248 %} 16249 16250 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 16251 predicate(n->as_Vector()->length() == 16); 16252 match(Set dst (RShiftVB src shift)); 16253 ins_cost(INSN_COST); 16254 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 16255 ins_encode %{ 16256 int sh = (int)$shift$$constant; 16257 if (sh >= 8) sh = 7; 16258 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 16259 as_FloatRegister($src$$reg), sh); 16260 %} 16261 ins_pipe(vshift128_imm); 16262 %} 16263 16264 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 16265 predicate(n->as_Vector()->length() == 4 || 16266 n->as_Vector()->length() == 8); 16267 match(Set dst (URShiftVB src shift)); 16268 ins_cost(INSN_COST); 16269 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 16270 ins_encode %{ 16271 int sh = (int)$shift$$constant; 16272 if (sh >= 8) { 16273 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16274 as_FloatRegister($src$$reg), 16275 as_FloatRegister($src$$reg)); 16276 } else { 16277 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 16278 as_FloatRegister($src$$reg), sh); 16279 } 16280 %} 16281 ins_pipe(vshift64_imm); 16282 %} 16283 16284 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 16285 predicate(n->as_Vector()->length() == 16); 16286 match(Set dst (URShiftVB src shift)); 16287 ins_cost(INSN_COST); 16288 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 16289 ins_encode %{ 16290 int sh = (int)$shift$$constant; 16291 if (sh >= 8) { 16292 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16293 as_FloatRegister($src$$reg), 16294 as_FloatRegister($src$$reg)); 16295 } else { 16296 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 16297 as_FloatRegister($src$$reg), sh); 16298 } 16299 %} 16300 ins_pipe(vshift128_imm); 16301 %} 16302 16303 instruct vsll4S(vecD dst, vecD src, vecX shift) %{ 16304 predicate(n->as_Vector()->length() == 2 || 16305 n->as_Vector()->length() == 4); 16306 match(Set dst (LShiftVS src shift)); 16307 match(Set dst (RShiftVS src shift)); 16308 ins_cost(INSN_COST); 16309 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 16310 ins_encode %{ 16311 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16312 as_FloatRegister($src$$reg), 16313 as_FloatRegister($shift$$reg)); 16314 %} 16315 ins_pipe(vshift64); 16316 %} 16317 16318 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 16319 predicate(n->as_Vector()->length() == 8); 16320 match(Set dst (LShiftVS src shift)); 16321 match(Set dst (RShiftVS src shift)); 16322 ins_cost(INSN_COST); 16323 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 16324 ins_encode %{ 16325 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16326 as_FloatRegister($src$$reg), 16327 as_FloatRegister($shift$$reg)); 16328 %} 16329 ins_pipe(vshift128); 16330 %} 16331 16332 instruct vsrl4S(vecD dst, vecD src, vecX shift) %{ 16333 predicate(n->as_Vector()->length() == 2 || 16334 n->as_Vector()->length() == 4); 16335 match(Set dst (URShiftVS src shift)); 16336 ins_cost(INSN_COST); 16337 format %{ "ushl $dst,$src,$shift\t# vector (4H)" %} 16338 ins_encode %{ 16339 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 16340 as_FloatRegister($src$$reg), 16341 as_FloatRegister($shift$$reg)); 16342 %} 16343 ins_pipe(vshift64); 16344 %} 16345 16346 instruct vsrl8S(vecX dst, vecX src, vecX shift) %{ 16347 predicate(n->as_Vector()->length() == 8); 16348 match(Set dst (URShiftVS src shift)); 16349 ins_cost(INSN_COST); 16350 format %{ "ushl $dst,$src,$shift\t# vector (8H)" %} 16351 ins_encode %{ 16352 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 16353 as_FloatRegister($src$$reg), 16354 as_FloatRegister($shift$$reg)); 16355 %} 16356 ins_pipe(vshift128); 16357 %} 16358 16359 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 16360 predicate(n->as_Vector()->length() == 2 || 16361 n->as_Vector()->length() == 4); 16362 match(Set dst (LShiftVS src shift)); 16363 ins_cost(INSN_COST); 16364 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 16365 ins_encode %{ 16366 int sh = (int)$shift$$constant; 16367 if (sh >= 16) { 16368 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16369 as_FloatRegister($src$$reg), 16370 as_FloatRegister($src$$reg)); 16371 } else { 16372 __ shl(as_FloatRegister($dst$$reg), __ T4H, 16373 as_FloatRegister($src$$reg), sh); 16374 } 16375 %} 16376 ins_pipe(vshift64_imm); 16377 %} 16378 16379 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 16380 predicate(n->as_Vector()->length() == 8); 16381 match(Set dst (LShiftVS src shift)); 16382 ins_cost(INSN_COST); 16383 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 16384 ins_encode %{ 16385 int sh = (int)$shift$$constant; 16386 if (sh >= 16) { 16387 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16388 as_FloatRegister($src$$reg), 16389 as_FloatRegister($src$$reg)); 16390 } else { 16391 __ shl(as_FloatRegister($dst$$reg), __ T8H, 16392 as_FloatRegister($src$$reg), sh); 16393 } 16394 %} 16395 ins_pipe(vshift128_imm); 16396 %} 16397 16398 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 16399 predicate(n->as_Vector()->length() == 2 || 16400 n->as_Vector()->length() == 4); 16401 match(Set dst (RShiftVS src shift)); 16402 ins_cost(INSN_COST); 16403 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 16404 ins_encode %{ 16405 int sh = (int)$shift$$constant; 16406 if (sh >= 16) sh = 15; 16407 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 16408 as_FloatRegister($src$$reg), sh); 16409 %} 16410 ins_pipe(vshift64_imm); 16411 %} 16412 16413 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 16414 predicate(n->as_Vector()->length() == 8); 16415 match(Set dst (RShiftVS src shift)); 16416 ins_cost(INSN_COST); 16417 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 16418 ins_encode %{ 16419 int sh = (int)$shift$$constant; 16420 if (sh >= 16) sh = 15; 16421 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 16422 as_FloatRegister($src$$reg), sh); 16423 %} 16424 ins_pipe(vshift128_imm); 16425 %} 16426 16427 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 16428 predicate(n->as_Vector()->length() == 2 || 16429 n->as_Vector()->length() == 4); 16430 match(Set dst (URShiftVS src shift)); 16431 ins_cost(INSN_COST); 16432 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 16433 ins_encode %{ 16434 int sh = (int)$shift$$constant; 16435 if (sh >= 16) { 16436 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16437 as_FloatRegister($src$$reg), 16438 as_FloatRegister($src$$reg)); 16439 } else { 16440 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 16441 as_FloatRegister($src$$reg), sh); 16442 } 16443 %} 16444 ins_pipe(vshift64_imm); 16445 %} 16446 16447 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 16448 predicate(n->as_Vector()->length() == 8); 16449 match(Set dst (URShiftVS src shift)); 16450 ins_cost(INSN_COST); 16451 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 16452 ins_encode %{ 16453 int sh = (int)$shift$$constant; 16454 if (sh >= 16) { 16455 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16456 as_FloatRegister($src$$reg), 16457 as_FloatRegister($src$$reg)); 16458 } else { 16459 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 16460 as_FloatRegister($src$$reg), sh); 16461 } 16462 %} 16463 ins_pipe(vshift128_imm); 16464 %} 16465 16466 instruct vsll2I(vecD dst, vecD src, vecX shift) %{ 16467 predicate(n->as_Vector()->length() == 2); 16468 match(Set dst (LShiftVI src shift)); 16469 match(Set dst (RShiftVI src shift)); 16470 ins_cost(INSN_COST); 16471 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 16472 ins_encode %{ 16473 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16474 as_FloatRegister($src$$reg), 16475 as_FloatRegister($shift$$reg)); 16476 %} 16477 ins_pipe(vshift64); 16478 %} 16479 16480 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 16481 predicate(n->as_Vector()->length() == 4); 16482 match(Set dst (LShiftVI src shift)); 16483 match(Set dst (RShiftVI src shift)); 16484 ins_cost(INSN_COST); 16485 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 16486 ins_encode %{ 16487 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16488 as_FloatRegister($src$$reg), 16489 as_FloatRegister($shift$$reg)); 16490 %} 16491 ins_pipe(vshift128); 16492 %} 16493 16494 instruct vsrl2I(vecD dst, vecD src, vecX shift) %{ 16495 predicate(n->as_Vector()->length() == 2); 16496 match(Set dst (URShiftVI src shift)); 16497 ins_cost(INSN_COST); 16498 format %{ "ushl $dst,$src,$shift\t# vector (2S)" %} 16499 ins_encode %{ 16500 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 16501 as_FloatRegister($src$$reg), 16502 as_FloatRegister($shift$$reg)); 16503 %} 16504 ins_pipe(vshift64); 16505 %} 16506 16507 instruct vsrl4I(vecX dst, vecX src, vecX shift) %{ 16508 predicate(n->as_Vector()->length() == 4); 16509 match(Set dst (URShiftVI src shift)); 16510 ins_cost(INSN_COST); 16511 format %{ "ushl $dst,$src,$shift\t# vector (4S)" %} 16512 ins_encode %{ 16513 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 16514 as_FloatRegister($src$$reg), 16515 as_FloatRegister($shift$$reg)); 16516 %} 16517 ins_pipe(vshift128); 16518 %} 16519 16520 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 16521 predicate(n->as_Vector()->length() == 2); 16522 match(Set dst (LShiftVI src shift)); 16523 ins_cost(INSN_COST); 16524 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 16525 ins_encode %{ 16526 __ shl(as_FloatRegister($dst$$reg), __ T2S, 16527 as_FloatRegister($src$$reg), 16528 (int)$shift$$constant); 16529 %} 16530 ins_pipe(vshift64_imm); 16531 %} 16532 16533 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 16534 predicate(n->as_Vector()->length() == 4); 16535 match(Set dst (LShiftVI src shift)); 16536 ins_cost(INSN_COST); 16537 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 16538 ins_encode %{ 16539 __ shl(as_FloatRegister($dst$$reg), __ T4S, 16540 as_FloatRegister($src$$reg), 16541 (int)$shift$$constant); 16542 %} 16543 ins_pipe(vshift128_imm); 16544 %} 16545 16546 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 16547 predicate(n->as_Vector()->length() == 2); 16548 match(Set dst (RShiftVI src shift)); 16549 ins_cost(INSN_COST); 16550 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 16551 ins_encode %{ 16552 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 16553 as_FloatRegister($src$$reg), 16554 (int)$shift$$constant); 16555 %} 16556 ins_pipe(vshift64_imm); 16557 %} 16558 16559 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 16560 predicate(n->as_Vector()->length() == 4); 16561 match(Set dst (RShiftVI src shift)); 16562 ins_cost(INSN_COST); 16563 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 16564 ins_encode %{ 16565 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 16566 as_FloatRegister($src$$reg), 16567 (int)$shift$$constant); 16568 %} 16569 ins_pipe(vshift128_imm); 16570 %} 16571 16572 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 16573 predicate(n->as_Vector()->length() == 2); 16574 match(Set dst (URShiftVI src shift)); 16575 ins_cost(INSN_COST); 16576 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 16577 ins_encode %{ 16578 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 16579 as_FloatRegister($src$$reg), 16580 (int)$shift$$constant); 16581 %} 16582 ins_pipe(vshift64_imm); 16583 %} 16584 16585 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 16586 predicate(n->as_Vector()->length() == 4); 16587 match(Set dst (URShiftVI src shift)); 16588 ins_cost(INSN_COST); 16589 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 16590 ins_encode %{ 16591 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 16592 as_FloatRegister($src$$reg), 16593 (int)$shift$$constant); 16594 %} 16595 ins_pipe(vshift128_imm); 16596 %} 16597 16598 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 16599 predicate(n->as_Vector()->length() == 2); 16600 match(Set dst (LShiftVL src shift)); 16601 match(Set dst (RShiftVL src shift)); 16602 ins_cost(INSN_COST); 16603 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 16604 ins_encode %{ 16605 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 16606 as_FloatRegister($src$$reg), 16607 as_FloatRegister($shift$$reg)); 16608 %} 16609 ins_pipe(vshift128); 16610 %} 16611 16612 instruct vsrl2L(vecX dst, vecX src, vecX shift) %{ 16613 predicate(n->as_Vector()->length() == 2); 16614 match(Set dst (URShiftVL src shift)); 16615 ins_cost(INSN_COST); 16616 format %{ "ushl $dst,$src,$shift\t# vector (2D)" %} 16617 ins_encode %{ 16618 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 16619 as_FloatRegister($src$$reg), 16620 as_FloatRegister($shift$$reg)); 16621 %} 16622 ins_pipe(vshift128); 16623 %} 16624 16625 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 16626 predicate(n->as_Vector()->length() == 2); 16627 match(Set dst (LShiftVL src shift)); 16628 ins_cost(INSN_COST); 16629 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 16630 ins_encode %{ 16631 __ shl(as_FloatRegister($dst$$reg), __ T2D, 16632 as_FloatRegister($src$$reg), 16633 (int)$shift$$constant); 16634 %} 16635 ins_pipe(vshift128_imm); 16636 %} 16637 16638 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 16639 predicate(n->as_Vector()->length() == 2); 16640 match(Set dst (RShiftVL src shift)); 16641 ins_cost(INSN_COST); 16642 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 16643 ins_encode %{ 16644 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 16645 as_FloatRegister($src$$reg), 16646 (int)$shift$$constant); 16647 %} 16648 ins_pipe(vshift128_imm); 16649 %} 16650 16651 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 16652 predicate(n->as_Vector()->length() == 2); 16653 match(Set dst (URShiftVL src shift)); 16654 ins_cost(INSN_COST); 16655 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 16656 ins_encode %{ 16657 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 16658 as_FloatRegister($src$$reg), 16659 (int)$shift$$constant); 16660 %} 16661 ins_pipe(vshift128_imm); 16662 %} 16663 16664 //----------PEEPHOLE RULES----------------------------------------------------- 16665 // These must follow all instruction definitions as they use the names 16666 // defined in the instructions definitions. 16667 // 16668 // peepmatch ( root_instr_name [preceding_instruction]* ); 16669 // 16670 // peepconstraint %{ 16671 // (instruction_number.operand_name relational_op instruction_number.operand_name 16672 // [, ...] ); 16673 // // instruction numbers are zero-based using left to right order in peepmatch 16674 // 16675 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 16676 // // provide an instruction_number.operand_name for each operand that appears 16677 // // in the replacement instruction's match rule 16678 // 16679 // ---------VM FLAGS--------------------------------------------------------- 16680 // 16681 // All peephole optimizations can be turned off using -XX:-OptoPeephole 16682 // 16683 // Each peephole rule is given an identifying number starting with zero and 16684 // increasing by one in the order seen by the parser. An individual peephole 16685 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 16686 // on the command-line. 16687 // 16688 // ---------CURRENT LIMITATIONS---------------------------------------------- 16689 // 16690 // Only match adjacent instructions in same basic block 16691 // Only equality constraints 16692 // Only constraints between operands, not (0.dest_reg == RAX_enc) 16693 // Only one replacement instruction 16694 // 16695 // ---------EXAMPLE---------------------------------------------------------- 16696 // 16697 // // pertinent parts of existing instructions in architecture description 16698 // instruct movI(iRegINoSp dst, iRegI src) 16699 // %{ 16700 // match(Set dst (CopyI src)); 16701 // %} 16702 // 16703 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 16704 // %{ 16705 // match(Set dst (AddI dst src)); 16706 // effect(KILL cr); 16707 // %} 16708 // 16709 // // Change (inc mov) to lea 16710 // peephole %{ 16711 // // increment preceeded by register-register move 16712 // peepmatch ( incI_iReg movI ); 16713 // // require that the destination register of the increment 16714 // // match the destination register of the move 16715 // peepconstraint ( 0.dst == 1.dst ); 16716 // // construct a replacement instruction that sets 16717 // // the destination to ( move's source register + one ) 16718 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 16719 // %} 16720 // 16721 16722 // Implementation no longer uses movX instructions since 16723 // machine-independent system no longer uses CopyX nodes. 16724 // 16725 // peephole 16726 // %{ 16727 // peepmatch (incI_iReg movI); 16728 // peepconstraint (0.dst == 1.dst); 16729 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16730 // %} 16731 16732 // peephole 16733 // %{ 16734 // peepmatch (decI_iReg movI); 16735 // peepconstraint (0.dst == 1.dst); 16736 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16737 // %} 16738 16739 // peephole 16740 // %{ 16741 // peepmatch (addI_iReg_imm movI); 16742 // peepconstraint (0.dst == 1.dst); 16743 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16744 // %} 16745 16746 // peephole 16747 // %{ 16748 // peepmatch (incL_iReg movL); 16749 // peepconstraint (0.dst == 1.dst); 16750 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16751 // %} 16752 16753 // peephole 16754 // %{ 16755 // peepmatch (decL_iReg movL); 16756 // peepconstraint (0.dst == 1.dst); 16757 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16758 // %} 16759 16760 // peephole 16761 // %{ 16762 // peepmatch (addL_iReg_imm movL); 16763 // peepconstraint (0.dst == 1.dst); 16764 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16765 // %} 16766 16767 // peephole 16768 // %{ 16769 // peepmatch (addP_iReg_imm movP); 16770 // peepconstraint (0.dst == 1.dst); 16771 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 16772 // %} 16773 16774 // // Change load of spilled value to only a spill 16775 // instruct storeI(memory mem, iRegI src) 16776 // %{ 16777 // match(Set mem (StoreI mem src)); 16778 // %} 16779 // 16780 // instruct loadI(iRegINoSp dst, memory mem) 16781 // %{ 16782 // match(Set dst (LoadI mem)); 16783 // %} 16784 // 16785 16786 //----------SMARTSPILL RULES--------------------------------------------------- 16787 // These must follow all instruction definitions as they use the names 16788 // defined in the instructions definitions. 16789 16790 // Local Variables: 16791 // mode: c++ 16792 // End: