1 // 2 // Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2019, Red Hat, Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 167 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 168 169 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 170 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 171 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 172 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 173 174 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 175 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 176 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 177 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 178 179 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 180 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 181 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 182 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 183 184 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 185 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 186 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 187 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 188 189 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 190 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 191 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 192 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 193 194 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 195 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 196 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 197 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 198 199 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 200 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 201 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 202 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 203 204 reg_def V8 ( SOC, SOC, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next() ); 206 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 207 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 208 209 reg_def V9 ( SOC, SOC, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next() ); 211 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 212 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 213 214 reg_def V10 ( SOC, SOC, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() ); 216 reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2)); 217 reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3)); 218 219 reg_def V11 ( SOC, SOC, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() ); 221 reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2)); 222 reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3)); 223 224 reg_def V12 ( SOC, SOC, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() ); 226 reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2)); 227 reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3)); 228 229 reg_def V13 ( SOC, SOC, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() ); 231 reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2)); 232 reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3)); 233 234 reg_def V14 ( SOC, SOC, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() ); 236 reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2)); 237 reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3)); 238 239 reg_def V15 ( SOC, SOC, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() ); 241 reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2)); 242 reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3)); 243 244 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 245 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 246 reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2)); 247 reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3)); 248 249 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 250 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 251 reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2)); 252 reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3)); 253 254 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 255 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 256 reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2)); 257 reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3)); 258 259 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 260 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 261 reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2)); 262 reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3)); 263 264 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 265 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 266 reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2)); 267 reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3)); 268 269 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 270 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 271 reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2)); 272 reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3)); 273 274 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 275 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 276 reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2)); 277 reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3)); 278 279 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 280 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 281 reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2)); 282 reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3)); 283 284 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 285 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 286 reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2)); 287 reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3)); 288 289 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 290 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 291 reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2)); 292 reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3)); 293 294 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 295 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 296 reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2)); 297 reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3)); 298 299 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 300 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 301 reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2)); 302 reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3)); 303 304 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 305 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 306 reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2)); 307 reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3)); 308 309 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 310 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 311 reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2)); 312 reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3)); 313 314 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 315 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 316 reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2)); 317 reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3)); 318 319 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 320 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 321 reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2)); 322 reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3)); 323 324 // ---------------------------- 325 // Special Registers 326 // ---------------------------- 327 328 // the AArch64 CSPR status flag register is not directly acessible as 329 // instruction operand. the FPSR status flag register is a system 330 // register which can be written/read using MSR/MRS but again does not 331 // appear as an operand (a code identifying the FSPR occurs as an 332 // immediate value in the instruction). 333 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 335 336 337 // Specify priority of register selection within phases of register 338 // allocation. Highest priority is first. A useful heuristic is to 339 // give registers a low priority when they are required by machine 340 // instructions, like EAX and EDX on I486, and choose no-save registers 341 // before save-on-call, & save-on-call before save-on-entry. Registers 342 // which participate in fixed calling sequences should come last. 343 // Registers which are used as pairs must fall on an even boundary. 344 345 alloc_class chunk0( 346 // volatiles 347 R10, R10_H, 348 R11, R11_H, 349 R12, R12_H, 350 R13, R13_H, 351 R14, R14_H, 352 R15, R15_H, 353 R16, R16_H, 354 R17, R17_H, 355 R18, R18_H, 356 357 // arg registers 358 R0, R0_H, 359 R1, R1_H, 360 R2, R2_H, 361 R3, R3_H, 362 R4, R4_H, 363 R5, R5_H, 364 R6, R6_H, 365 R7, R7_H, 366 367 // non-volatiles 368 R19, R19_H, 369 R20, R20_H, 370 R21, R21_H, 371 R22, R22_H, 372 R23, R23_H, 373 R24, R24_H, 374 R25, R25_H, 375 R26, R26_H, 376 377 // non-allocatable registers 378 379 R27, R27_H, // heapbase 380 R28, R28_H, // thread 381 R29, R29_H, // fp 382 R30, R30_H, // lr 383 R31, R31_H, // sp 384 ); 385 386 alloc_class chunk1( 387 388 // no save 389 V16, V16_H, V16_J, V16_K, 390 V17, V17_H, V17_J, V17_K, 391 V18, V18_H, V18_J, V18_K, 392 V19, V19_H, V19_J, V19_K, 393 V20, V20_H, V20_J, V20_K, 394 V21, V21_H, V21_J, V21_K, 395 V22, V22_H, V22_J, V22_K, 396 V23, V23_H, V23_J, V23_K, 397 V24, V24_H, V24_J, V24_K, 398 V25, V25_H, V25_J, V25_K, 399 V26, V26_H, V26_J, V26_K, 400 V27, V27_H, V27_J, V27_K, 401 V28, V28_H, V28_J, V28_K, 402 V29, V29_H, V29_J, V29_K, 403 V30, V30_H, V30_J, V30_K, 404 V31, V31_H, V31_J, V31_K, 405 406 // arg registers 407 V0, V0_H, V0_J, V0_K, 408 V1, V1_H, V1_J, V1_K, 409 V2, V2_H, V2_J, V2_K, 410 V3, V3_H, V3_J, V3_K, 411 V4, V4_H, V4_J, V4_K, 412 V5, V5_H, V5_J, V5_K, 413 V6, V6_H, V6_J, V6_K, 414 V7, V7_H, V7_J, V7_K, 415 416 // non-volatiles 417 V8, V8_H, V8_J, V8_K, 418 V9, V9_H, V9_J, V9_K, 419 V10, V10_H, V10_J, V10_K, 420 V11, V11_H, V11_J, V11_K, 421 V12, V12_H, V12_J, V12_K, 422 V13, V13_H, V13_J, V13_K, 423 V14, V14_H, V14_J, V14_K, 424 V15, V15_H, V15_J, V15_K, 425 ); 426 427 alloc_class chunk2(RFLAGS); 428 429 //----------Architecture Description Register Classes-------------------------- 430 // Several register classes are automatically defined based upon information in 431 // this architecture description. 432 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 433 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 436 // 437 438 // Class for all 32 bit integer registers -- excludes SP which will 439 // never be used as an integer register 440 reg_class any_reg32( 441 R0, 442 R1, 443 R2, 444 R3, 445 R4, 446 R5, 447 R6, 448 R7, 449 R10, 450 R11, 451 R12, 452 R13, 453 R14, 454 R15, 455 R16, 456 R17, 457 R18, 458 R19, 459 R20, 460 R21, 461 R22, 462 R23, 463 R24, 464 R25, 465 R26, 466 R27, 467 R28, 468 R29, 469 R30 470 ); 471 472 // Singleton class for R0 int register 473 reg_class int_r0_reg(R0); 474 475 // Singleton class for R2 int register 476 reg_class int_r2_reg(R2); 477 478 // Singleton class for R3 int register 479 reg_class int_r3_reg(R3); 480 481 // Singleton class for R4 int register 482 reg_class int_r4_reg(R4); 483 484 // Class for all long integer registers (including RSP) 485 reg_class any_reg( 486 R0, R0_H, 487 R1, R1_H, 488 R2, R2_H, 489 R3, R3_H, 490 R4, R4_H, 491 R5, R5_H, 492 R6, R6_H, 493 R7, R7_H, 494 R10, R10_H, 495 R11, R11_H, 496 R12, R12_H, 497 R13, R13_H, 498 R14, R14_H, 499 R15, R15_H, 500 R16, R16_H, 501 R17, R17_H, 502 R18, R18_H, 503 R19, R19_H, 504 R20, R20_H, 505 R21, R21_H, 506 R22, R22_H, 507 R23, R23_H, 508 R24, R24_H, 509 R25, R25_H, 510 R26, R26_H, 511 R27, R27_H, 512 R28, R28_H, 513 R29, R29_H, 514 R30, R30_H, 515 R31, R31_H 516 ); 517 518 // Class for all non-special integer registers 519 reg_class no_special_reg32_no_fp( 520 R0, 521 R1, 522 R2, 523 R3, 524 R4, 525 R5, 526 R6, 527 R7, 528 R10, 529 R11, 530 R12, // rmethod 531 R13, 532 R14, 533 R15, 534 R16, 535 R17, 536 R18, 537 R19, 538 R20, 539 R21, 540 R22, 541 R23, 542 R24, 543 R25, 544 R26 545 /* R27, */ // heapbase 546 /* R28, */ // thread 547 /* R29, */ // fp 548 /* R30, */ // lr 549 /* R31 */ // sp 550 ); 551 552 reg_class no_special_reg32_with_fp( 553 R0, 554 R1, 555 R2, 556 R3, 557 R4, 558 R5, 559 R6, 560 R7, 561 R10, 562 R11, 563 R12, // rmethod 564 R13, 565 R14, 566 R15, 567 R16, 568 R17, 569 R18, 570 R19, 571 R20, 572 R21, 573 R22, 574 R23, 575 R24, 576 R25, 577 R26 578 /* R27, */ // heapbase 579 /* R28, */ // thread 580 R29, // fp 581 /* R30, */ // lr 582 /* R31 */ // sp 583 ); 584 585 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); 586 587 // Class for all non-special long integer registers 588 reg_class no_special_reg_no_fp( 589 R0, R0_H, 590 R1, R1_H, 591 R2, R2_H, 592 R3, R3_H, 593 R4, R4_H, 594 R5, R5_H, 595 R6, R6_H, 596 R7, R7_H, 597 R10, R10_H, 598 R11, R11_H, 599 R12, R12_H, // rmethod 600 R13, R13_H, 601 R14, R14_H, 602 R15, R15_H, 603 R16, R16_H, 604 R17, R17_H, 605 R18, R18_H, 606 R19, R19_H, 607 R20, R20_H, 608 R21, R21_H, 609 R22, R22_H, 610 R23, R23_H, 611 R24, R24_H, 612 R25, R25_H, 613 R26, R26_H, 614 /* R27, R27_H, */ // heapbase 615 /* R28, R28_H, */ // thread 616 /* R29, R29_H, */ // fp 617 /* R30, R30_H, */ // lr 618 /* R31, R31_H */ // sp 619 ); 620 621 reg_class no_special_reg_with_fp( 622 R0, R0_H, 623 R1, R1_H, 624 R2, R2_H, 625 R3, R3_H, 626 R4, R4_H, 627 R5, R5_H, 628 R6, R6_H, 629 R7, R7_H, 630 R10, R10_H, 631 R11, R11_H, 632 R12, R12_H, // rmethod 633 R13, R13_H, 634 R14, R14_H, 635 R15, R15_H, 636 R16, R16_H, 637 R17, R17_H, 638 R18, R18_H, 639 R19, R19_H, 640 R20, R20_H, 641 R21, R21_H, 642 R22, R22_H, 643 R23, R23_H, 644 R24, R24_H, 645 R25, R25_H, 646 R26, R26_H, 647 /* R27, R27_H, */ // heapbase 648 /* R28, R28_H, */ // thread 649 R29, R29_H, // fp 650 /* R30, R30_H, */ // lr 651 /* R31, R31_H */ // sp 652 ); 653 654 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 655 656 // Class for 64 bit register r0 657 reg_class r0_reg( 658 R0, R0_H 659 ); 660 661 // Class for 64 bit register r1 662 reg_class r1_reg( 663 R1, R1_H 664 ); 665 666 // Class for 64 bit register r2 667 reg_class r2_reg( 668 R2, R2_H 669 ); 670 671 // Class for 64 bit register r3 672 reg_class r3_reg( 673 R3, R3_H 674 ); 675 676 // Class for 64 bit register r4 677 reg_class r4_reg( 678 R4, R4_H 679 ); 680 681 // Class for 64 bit register r5 682 reg_class r5_reg( 683 R5, R5_H 684 ); 685 686 // Class for 64 bit register r10 687 reg_class r10_reg( 688 R10, R10_H 689 ); 690 691 // Class for 64 bit register r11 692 reg_class r11_reg( 693 R11, R11_H 694 ); 695 696 // Class for method register 697 reg_class method_reg( 698 R12, R12_H 699 ); 700 701 // Class for heapbase register 702 reg_class heapbase_reg( 703 R27, R27_H 704 ); 705 706 // Class for thread register 707 reg_class thread_reg( 708 R28, R28_H 709 ); 710 711 // Class for frame pointer register 712 reg_class fp_reg( 713 R29, R29_H 714 ); 715 716 // Class for link register 717 reg_class lr_reg( 718 R30, R30_H 719 ); 720 721 // Class for long sp register 722 reg_class sp_reg( 723 R31, R31_H 724 ); 725 726 // Class for all pointer registers 727 reg_class ptr_reg( 728 R0, R0_H, 729 R1, R1_H, 730 R2, R2_H, 731 R3, R3_H, 732 R4, R4_H, 733 R5, R5_H, 734 R6, R6_H, 735 R7, R7_H, 736 R10, R10_H, 737 R11, R11_H, 738 R12, R12_H, 739 R13, R13_H, 740 R14, R14_H, 741 R15, R15_H, 742 R16, R16_H, 743 R17, R17_H, 744 R18, R18_H, 745 R19, R19_H, 746 R20, R20_H, 747 R21, R21_H, 748 R22, R22_H, 749 R23, R23_H, 750 R24, R24_H, 751 R25, R25_H, 752 R26, R26_H, 753 R27, R27_H, 754 R28, R28_H, 755 R29, R29_H, 756 R30, R30_H, 757 R31, R31_H 758 ); 759 760 // Class for all non_special pointer registers 761 reg_class no_special_ptr_reg( 762 R0, R0_H, 763 R1, R1_H, 764 R2, R2_H, 765 R3, R3_H, 766 R4, R4_H, 767 R5, R5_H, 768 R6, R6_H, 769 R7, R7_H, 770 R10, R10_H, 771 R11, R11_H, 772 R12, R12_H, 773 R13, R13_H, 774 R14, R14_H, 775 R15, R15_H, 776 R16, R16_H, 777 R17, R17_H, 778 R18, R18_H, 779 R19, R19_H, 780 R20, R20_H, 781 R21, R21_H, 782 R22, R22_H, 783 R23, R23_H, 784 R24, R24_H, 785 R25, R25_H, 786 R26, R26_H, 787 /* R27, R27_H, */ // heapbase 788 /* R28, R28_H, */ // thread 789 /* R29, R29_H, */ // fp 790 /* R30, R30_H, */ // lr 791 /* R31, R31_H */ // sp 792 ); 793 794 // Class for all float registers 795 reg_class float_reg( 796 V0, 797 V1, 798 V2, 799 V3, 800 V4, 801 V5, 802 V6, 803 V7, 804 V8, 805 V9, 806 V10, 807 V11, 808 V12, 809 V13, 810 V14, 811 V15, 812 V16, 813 V17, 814 V18, 815 V19, 816 V20, 817 V21, 818 V22, 819 V23, 820 V24, 821 V25, 822 V26, 823 V27, 824 V28, 825 V29, 826 V30, 827 V31 828 ); 829 830 // Double precision float registers have virtual `high halves' that 831 // are needed by the allocator. 832 // Class for all double registers 833 reg_class double_reg( 834 V0, V0_H, 835 V1, V1_H, 836 V2, V2_H, 837 V3, V3_H, 838 V4, V4_H, 839 V5, V5_H, 840 V6, V6_H, 841 V7, V7_H, 842 V8, V8_H, 843 V9, V9_H, 844 V10, V10_H, 845 V11, V11_H, 846 V12, V12_H, 847 V13, V13_H, 848 V14, V14_H, 849 V15, V15_H, 850 V16, V16_H, 851 V17, V17_H, 852 V18, V18_H, 853 V19, V19_H, 854 V20, V20_H, 855 V21, V21_H, 856 V22, V22_H, 857 V23, V23_H, 858 V24, V24_H, 859 V25, V25_H, 860 V26, V26_H, 861 V27, V27_H, 862 V28, V28_H, 863 V29, V29_H, 864 V30, V30_H, 865 V31, V31_H 866 ); 867 868 // Class for all 64bit vector registers 869 reg_class vectord_reg( 870 V0, V0_H, 871 V1, V1_H, 872 V2, V2_H, 873 V3, V3_H, 874 V4, V4_H, 875 V5, V5_H, 876 V6, V6_H, 877 V7, V7_H, 878 V8, V8_H, 879 V9, V9_H, 880 V10, V10_H, 881 V11, V11_H, 882 V12, V12_H, 883 V13, V13_H, 884 V14, V14_H, 885 V15, V15_H, 886 V16, V16_H, 887 V17, V17_H, 888 V18, V18_H, 889 V19, V19_H, 890 V20, V20_H, 891 V21, V21_H, 892 V22, V22_H, 893 V23, V23_H, 894 V24, V24_H, 895 V25, V25_H, 896 V26, V26_H, 897 V27, V27_H, 898 V28, V28_H, 899 V29, V29_H, 900 V30, V30_H, 901 V31, V31_H 902 ); 903 904 // Class for all 128bit vector registers 905 reg_class vectorx_reg( 906 V0, V0_H, V0_J, V0_K, 907 V1, V1_H, V1_J, V1_K, 908 V2, V2_H, V2_J, V2_K, 909 V3, V3_H, V3_J, V3_K, 910 V4, V4_H, V4_J, V4_K, 911 V5, V5_H, V5_J, V5_K, 912 V6, V6_H, V6_J, V6_K, 913 V7, V7_H, V7_J, V7_K, 914 V8, V8_H, V8_J, V8_K, 915 V9, V9_H, V9_J, V9_K, 916 V10, V10_H, V10_J, V10_K, 917 V11, V11_H, V11_J, V11_K, 918 V12, V12_H, V12_J, V12_K, 919 V13, V13_H, V13_J, V13_K, 920 V14, V14_H, V14_J, V14_K, 921 V15, V15_H, V15_J, V15_K, 922 V16, V16_H, V16_J, V16_K, 923 V17, V17_H, V17_J, V17_K, 924 V18, V18_H, V18_J, V18_K, 925 V19, V19_H, V19_J, V19_K, 926 V20, V20_H, V20_J, V20_K, 927 V21, V21_H, V21_J, V21_K, 928 V22, V22_H, V22_J, V22_K, 929 V23, V23_H, V23_J, V23_K, 930 V24, V24_H, V24_J, V24_K, 931 V25, V25_H, V25_J, V25_K, 932 V26, V26_H, V26_J, V26_K, 933 V27, V27_H, V27_J, V27_K, 934 V28, V28_H, V28_J, V28_K, 935 V29, V29_H, V29_J, V29_K, 936 V30, V30_H, V30_J, V30_K, 937 V31, V31_H, V31_J, V31_K 938 ); 939 940 // Class for 128 bit register v0 941 reg_class v0_reg( 942 V0, V0_H 943 ); 944 945 // Class for 128 bit register v1 946 reg_class v1_reg( 947 V1, V1_H 948 ); 949 950 // Class for 128 bit register v2 951 reg_class v2_reg( 952 V2, V2_H 953 ); 954 955 // Class for 128 bit register v3 956 reg_class v3_reg( 957 V3, V3_H 958 ); 959 960 // Singleton class for condition codes 961 reg_class int_flags(RFLAGS); 962 963 %} 964 965 //----------DEFINITION BLOCK--------------------------------------------------- 966 // Define name --> value mappings to inform the ADLC of an integer valued name 967 // Current support includes integer values in the range [0, 0x7FFFFFFF] 968 // Format: 969 // int_def <name> ( <int_value>, <expression>); 970 // Generated Code in ad_<arch>.hpp 971 // #define <name> (<expression>) 972 // // value == <int_value> 973 // Generated code in ad_<arch>.cpp adlc_verification() 974 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 975 // 976 977 // we follow the ppc-aix port in using a simple cost model which ranks 978 // register operations as cheap, memory ops as more expensive and 979 // branches as most expensive. the first two have a low as well as a 980 // normal cost. huge cost appears to be a way of saying don't do 981 // something 982 983 definitions %{ 984 // The default cost (of a register move instruction). 985 int_def INSN_COST ( 100, 100); 986 int_def BRANCH_COST ( 200, 2 * INSN_COST); 987 int_def CALL_COST ( 200, 2 * INSN_COST); 988 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 989 %} 990 991 992 //----------SOURCE BLOCK------------------------------------------------------- 993 // This is a block of C++ code which provides values, functions, and 994 // definitions necessary in the rest of the architecture description 995 996 source_hpp %{ 997 998 #include "asm/macroAssembler.hpp" 999 #include "gc/shared/cardTable.hpp" 1000 #include "gc/shared/cardTableBarrierSet.hpp" 1001 #include "gc/shared/collectedHeap.hpp" 1002 #include "opto/addnode.hpp" 1003 1004 class CallStubImpl { 1005 1006 //-------------------------------------------------------------- 1007 //---< Used for optimization in Compile::shorten_branches >--- 1008 //-------------------------------------------------------------- 1009 1010 public: 1011 // Size of call trampoline stub. 1012 static uint size_call_trampoline() { 1013 return 0; // no call trampolines on this platform 1014 } 1015 1016 // number of relocations needed by a call trampoline stub 1017 static uint reloc_call_trampoline() { 1018 return 0; // no call trampolines on this platform 1019 } 1020 }; 1021 1022 class HandlerImpl { 1023 1024 public: 1025 1026 static int emit_exception_handler(CodeBuffer &cbuf); 1027 static int emit_deopt_handler(CodeBuffer& cbuf); 1028 1029 static uint size_exception_handler() { 1030 return MacroAssembler::far_branch_size(); 1031 } 1032 1033 static uint size_deopt_handler() { 1034 // count one adr and one far branch instruction 1035 return 4 * NativeInstruction::instruction_size; 1036 } 1037 }; 1038 1039 bool is_CAS(int opcode, bool maybe_volatile); 1040 1041 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1042 1043 bool unnecessary_acquire(const Node *barrier); 1044 bool needs_acquiring_load(const Node *load); 1045 1046 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1047 1048 bool unnecessary_release(const Node *barrier); 1049 bool unnecessary_volatile(const Node *barrier); 1050 bool needs_releasing_store(const Node *store); 1051 1052 // predicate controlling translation of CompareAndSwapX 1053 bool needs_acquiring_load_exclusive(const Node *load); 1054 1055 // predicate controlling translation of StoreCM 1056 bool unnecessary_storestore(const Node *storecm); 1057 1058 // predicate controlling addressing modes 1059 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1060 %} 1061 1062 source %{ 1063 1064 // Optimizaton of volatile gets and puts 1065 // ------------------------------------- 1066 // 1067 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1068 // use to implement volatile reads and writes. For a volatile read 1069 // we simply need 1070 // 1071 // ldar<x> 1072 // 1073 // and for a volatile write we need 1074 // 1075 // stlr<x> 1076 // 1077 // Alternatively, we can implement them by pairing a normal 1078 // load/store with a memory barrier. For a volatile read we need 1079 // 1080 // ldr<x> 1081 // dmb ishld 1082 // 1083 // for a volatile write 1084 // 1085 // dmb ish 1086 // str<x> 1087 // dmb ish 1088 // 1089 // We can also use ldaxr and stlxr to implement compare and swap CAS 1090 // sequences. These are normally translated to an instruction 1091 // sequence like the following 1092 // 1093 // dmb ish 1094 // retry: 1095 // ldxr<x> rval raddr 1096 // cmp rval rold 1097 // b.ne done 1098 // stlxr<x> rval, rnew, rold 1099 // cbnz rval retry 1100 // done: 1101 // cset r0, eq 1102 // dmb ishld 1103 // 1104 // Note that the exclusive store is already using an stlxr 1105 // instruction. That is required to ensure visibility to other 1106 // threads of the exclusive write (assuming it succeeds) before that 1107 // of any subsequent writes. 1108 // 1109 // The following instruction sequence is an improvement on the above 1110 // 1111 // retry: 1112 // ldaxr<x> rval raddr 1113 // cmp rval rold 1114 // b.ne done 1115 // stlxr<x> rval, rnew, rold 1116 // cbnz rval retry 1117 // done: 1118 // cset r0, eq 1119 // 1120 // We don't need the leading dmb ish since the stlxr guarantees 1121 // visibility of prior writes in the case that the swap is 1122 // successful. Crucially we don't have to worry about the case where 1123 // the swap is not successful since no valid program should be 1124 // relying on visibility of prior changes by the attempting thread 1125 // in the case where the CAS fails. 1126 // 1127 // Similarly, we don't need the trailing dmb ishld if we substitute 1128 // an ldaxr instruction since that will provide all the guarantees we 1129 // require regarding observation of changes made by other threads 1130 // before any change to the CAS address observed by the load. 1131 // 1132 // In order to generate the desired instruction sequence we need to 1133 // be able to identify specific 'signature' ideal graph node 1134 // sequences which i) occur as a translation of a volatile reads or 1135 // writes or CAS operations and ii) do not occur through any other 1136 // translation or graph transformation. We can then provide 1137 // alternative aldc matching rules which translate these node 1138 // sequences to the desired machine code sequences. Selection of the 1139 // alternative rules can be implemented by predicates which identify 1140 // the relevant node sequences. 1141 // 1142 // The ideal graph generator translates a volatile read to the node 1143 // sequence 1144 // 1145 // LoadX[mo_acquire] 1146 // MemBarAcquire 1147 // 1148 // As a special case when using the compressed oops optimization we 1149 // may also see this variant 1150 // 1151 // LoadN[mo_acquire] 1152 // DecodeN 1153 // MemBarAcquire 1154 // 1155 // A volatile write is translated to the node sequence 1156 // 1157 // MemBarRelease 1158 // StoreX[mo_release] {CardMark}-optional 1159 // MemBarVolatile 1160 // 1161 // n.b. the above node patterns are generated with a strict 1162 // 'signature' configuration of input and output dependencies (see 1163 // the predicates below for exact details). The card mark may be as 1164 // simple as a few extra nodes or, in a few GC configurations, may 1165 // include more complex control flow between the leading and 1166 // trailing memory barriers. However, whatever the card mark 1167 // configuration these signatures are unique to translated volatile 1168 // reads/stores -- they will not appear as a result of any other 1169 // bytecode translation or inlining nor as a consequence of 1170 // optimizing transforms. 1171 // 1172 // We also want to catch inlined unsafe volatile gets and puts and 1173 // be able to implement them using either ldar<x>/stlr<x> or some 1174 // combination of ldr<x>/stlr<x> and dmb instructions. 1175 // 1176 // Inlined unsafe volatiles puts manifest as a minor variant of the 1177 // normal volatile put node sequence containing an extra cpuorder 1178 // membar 1179 // 1180 // MemBarRelease 1181 // MemBarCPUOrder 1182 // StoreX[mo_release] {CardMark}-optional 1183 // MemBarCPUOrder 1184 // MemBarVolatile 1185 // 1186 // n.b. as an aside, a cpuorder membar is not itself subject to 1187 // matching and translation by adlc rules. However, the rule 1188 // predicates need to detect its presence in order to correctly 1189 // select the desired adlc rules. 1190 // 1191 // Inlined unsafe volatile gets manifest as a slightly different 1192 // node sequence to a normal volatile get because of the 1193 // introduction of some CPUOrder memory barriers to bracket the 1194 // Load. However, but the same basic skeleton of a LoadX feeding a 1195 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1196 // present 1197 // 1198 // MemBarCPUOrder 1199 // || \\ 1200 // MemBarCPUOrder LoadX[mo_acquire] 1201 // || | 1202 // || {DecodeN} optional 1203 // || / 1204 // MemBarAcquire 1205 // 1206 // In this case the acquire membar does not directly depend on the 1207 // load. However, we can be sure that the load is generated from an 1208 // inlined unsafe volatile get if we see it dependent on this unique 1209 // sequence of membar nodes. Similarly, given an acquire membar we 1210 // can know that it was added because of an inlined unsafe volatile 1211 // get if it is fed and feeds a cpuorder membar and if its feed 1212 // membar also feeds an acquiring load. 1213 // 1214 // Finally an inlined (Unsafe) CAS operation is translated to the 1215 // following ideal graph 1216 // 1217 // MemBarRelease 1218 // MemBarCPUOrder 1219 // CompareAndSwapX {CardMark}-optional 1220 // MemBarCPUOrder 1221 // MemBarAcquire 1222 // 1223 // So, where we can identify these volatile read and write 1224 // signatures we can choose to plant either of the above two code 1225 // sequences. For a volatile read we can simply plant a normal 1226 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1227 // also choose to inhibit translation of the MemBarAcquire and 1228 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1229 // 1230 // When we recognise a volatile store signature we can choose to 1231 // plant at a dmb ish as a translation for the MemBarRelease, a 1232 // normal str<x> and then a dmb ish for the MemBarVolatile. 1233 // Alternatively, we can inhibit translation of the MemBarRelease 1234 // and MemBarVolatile and instead plant a simple stlr<x> 1235 // instruction. 1236 // 1237 // when we recognise a CAS signature we can choose to plant a dmb 1238 // ish as a translation for the MemBarRelease, the conventional 1239 // macro-instruction sequence for the CompareAndSwap node (which 1240 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1241 // Alternatively, we can elide generation of the dmb instructions 1242 // and plant the alternative CompareAndSwap macro-instruction 1243 // sequence (which uses ldaxr<x>). 1244 // 1245 // Of course, the above only applies when we see these signature 1246 // configurations. We still want to plant dmb instructions in any 1247 // other cases where we may see a MemBarAcquire, MemBarRelease or 1248 // MemBarVolatile. For example, at the end of a constructor which 1249 // writes final/volatile fields we will see a MemBarRelease 1250 // instruction and this needs a 'dmb ish' lest we risk the 1251 // constructed object being visible without making the 1252 // final/volatile field writes visible. 1253 // 1254 // n.b. the translation rules below which rely on detection of the 1255 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1256 // If we see anything other than the signature configurations we 1257 // always just translate the loads and stores to ldr<x> and str<x> 1258 // and translate acquire, release and volatile membars to the 1259 // relevant dmb instructions. 1260 // 1261 1262 // is_CAS(int opcode, bool maybe_volatile) 1263 // 1264 // return true if opcode is one of the possible CompareAndSwapX 1265 // values otherwise false. 1266 1267 bool is_CAS(int opcode, bool maybe_volatile) 1268 { 1269 switch(opcode) { 1270 // We handle these 1271 case Op_CompareAndSwapI: 1272 case Op_CompareAndSwapL: 1273 case Op_CompareAndSwapP: 1274 case Op_CompareAndSwapN: 1275 case Op_ShenandoahCompareAndSwapP: 1276 case Op_ShenandoahCompareAndSwapN: 1277 case Op_CompareAndSwapB: 1278 case Op_CompareAndSwapS: 1279 case Op_GetAndSetI: 1280 case Op_GetAndSetL: 1281 case Op_GetAndSetP: 1282 case Op_GetAndSetN: 1283 case Op_GetAndAddI: 1284 case Op_GetAndAddL: 1285 return true; 1286 case Op_CompareAndExchangeI: 1287 case Op_CompareAndExchangeN: 1288 case Op_CompareAndExchangeB: 1289 case Op_CompareAndExchangeS: 1290 case Op_CompareAndExchangeL: 1291 case Op_CompareAndExchangeP: 1292 case Op_WeakCompareAndSwapB: 1293 case Op_WeakCompareAndSwapS: 1294 case Op_WeakCompareAndSwapI: 1295 case Op_WeakCompareAndSwapL: 1296 case Op_WeakCompareAndSwapP: 1297 case Op_WeakCompareAndSwapN: 1298 case Op_ShenandoahWeakCompareAndSwapP: 1299 case Op_ShenandoahWeakCompareAndSwapN: 1300 case Op_ShenandoahCompareAndExchangeP: 1301 case Op_ShenandoahCompareAndExchangeN: 1302 return maybe_volatile; 1303 default: 1304 return false; 1305 } 1306 } 1307 1308 // helper to determine the maximum number of Phi nodes we may need to 1309 // traverse when searching from a card mark membar for the merge mem 1310 // feeding a trailing membar or vice versa 1311 1312 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1313 1314 bool unnecessary_acquire(const Node *barrier) 1315 { 1316 assert(barrier->is_MemBar(), "expecting a membar"); 1317 1318 if (UseBarriersForVolatile) { 1319 // we need to plant a dmb 1320 return false; 1321 } 1322 1323 MemBarNode* mb = barrier->as_MemBar(); 1324 1325 if (mb->trailing_load()) { 1326 return true; 1327 } 1328 1329 if (mb->trailing_load_store()) { 1330 Node* load_store = mb->in(MemBarNode::Precedent); 1331 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1332 return is_CAS(load_store->Opcode(), true); 1333 } 1334 1335 return false; 1336 } 1337 1338 bool needs_acquiring_load(const Node *n) 1339 { 1340 assert(n->is_Load(), "expecting a load"); 1341 if (UseBarriersForVolatile) { 1342 // we use a normal load and a dmb 1343 return false; 1344 } 1345 1346 LoadNode *ld = n->as_Load(); 1347 1348 return ld->is_acquire(); 1349 } 1350 1351 bool unnecessary_release(const Node *n) 1352 { 1353 assert((n->is_MemBar() && 1354 n->Opcode() == Op_MemBarRelease), 1355 "expecting a release membar"); 1356 1357 if (UseBarriersForVolatile) { 1358 // we need to plant a dmb 1359 return false; 1360 } 1361 1362 MemBarNode *barrier = n->as_MemBar(); 1363 if (!barrier->leading()) { 1364 return false; 1365 } else { 1366 Node* trailing = barrier->trailing_membar(); 1367 MemBarNode* trailing_mb = trailing->as_MemBar(); 1368 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1369 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1370 1371 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1372 if (mem->is_Store()) { 1373 assert(mem->as_Store()->is_release(), ""); 1374 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1375 return true; 1376 } else { 1377 assert(mem->is_LoadStore(), ""); 1378 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1379 return is_CAS(mem->Opcode(), true); 1380 } 1381 } 1382 return false; 1383 } 1384 1385 bool unnecessary_volatile(const Node *n) 1386 { 1387 // assert n->is_MemBar(); 1388 if (UseBarriersForVolatile) { 1389 // we need to plant a dmb 1390 return false; 1391 } 1392 1393 MemBarNode *mbvol = n->as_MemBar(); 1394 1395 bool release = mbvol->trailing_store(); 1396 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1397 #ifdef ASSERT 1398 if (release) { 1399 Node* leading = mbvol->leading_membar(); 1400 assert(leading->Opcode() == Op_MemBarRelease, ""); 1401 assert(leading->as_MemBar()->leading_store(), ""); 1402 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1403 } 1404 #endif 1405 1406 return release; 1407 } 1408 1409 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1410 1411 bool needs_releasing_store(const Node *n) 1412 { 1413 // assert n->is_Store(); 1414 if (UseBarriersForVolatile) { 1415 // we use a normal store and dmb combination 1416 return false; 1417 } 1418 1419 StoreNode *st = n->as_Store(); 1420 1421 return st->trailing_membar() != NULL; 1422 } 1423 1424 // predicate controlling translation of CAS 1425 // 1426 // returns true if CAS needs to use an acquiring load otherwise false 1427 1428 bool needs_acquiring_load_exclusive(const Node *n) 1429 { 1430 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1431 if (UseBarriersForVolatile) { 1432 return false; 1433 } 1434 1435 LoadStoreNode* ldst = n->as_LoadStore(); 1436 if (is_CAS(n->Opcode(), false)) { 1437 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1438 } else { 1439 return ldst->trailing_membar() != NULL; 1440 } 1441 1442 // so we can just return true here 1443 return true; 1444 } 1445 1446 // predicate controlling translation of StoreCM 1447 // 1448 // returns true if a StoreStore must precede the card write otherwise 1449 // false 1450 1451 bool unnecessary_storestore(const Node *storecm) 1452 { 1453 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1454 1455 // we need to generate a dmb ishst between an object put and the 1456 // associated card mark when we are using CMS without conditional 1457 // card marking 1458 1459 if (UseConcMarkSweepGC && !UseCondCardMark) { 1460 return false; 1461 } 1462 1463 // a storestore is unnecesary in all other cases 1464 1465 return true; 1466 } 1467 1468 1469 #define __ _masm. 1470 1471 // advance declarations for helper functions to convert register 1472 // indices to register objects 1473 1474 // the ad file has to provide implementations of certain methods 1475 // expected by the generic code 1476 // 1477 // REQUIRED FUNCTIONALITY 1478 1479 //============================================================================= 1480 1481 // !!!!! Special hack to get all types of calls to specify the byte offset 1482 // from the start of the call to the point where the return address 1483 // will point. 1484 1485 int MachCallStaticJavaNode::ret_addr_offset() 1486 { 1487 // call should be a simple bl 1488 int off = 4; 1489 return off; 1490 } 1491 1492 int MachCallDynamicJavaNode::ret_addr_offset() 1493 { 1494 return 16; // movz, movk, movk, bl 1495 } 1496 1497 int MachCallRuntimeNode::ret_addr_offset() { 1498 // for generated stubs the call will be 1499 // far_call(addr) 1500 // for real runtime callouts it will be six instructions 1501 // see aarch64_enc_java_to_runtime 1502 // adr(rscratch2, retaddr) 1503 // lea(rscratch1, RuntimeAddress(addr) 1504 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1505 // blrt rscratch1 1506 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1507 if (cb) { 1508 return MacroAssembler::far_branch_size(); 1509 } else { 1510 return 6 * NativeInstruction::instruction_size; 1511 } 1512 } 1513 1514 // Indicate if the safepoint node needs the polling page as an input 1515 1516 // the shared code plants the oop data at the start of the generated 1517 // code for the safepoint node and that needs ot be at the load 1518 // instruction itself. so we cannot plant a mov of the safepoint poll 1519 // address followed by a load. setting this to true means the mov is 1520 // scheduled as a prior instruction. that's better for scheduling 1521 // anyway. 1522 1523 bool SafePointNode::needs_polling_address_input() 1524 { 1525 return true; 1526 } 1527 1528 //============================================================================= 1529 1530 #ifndef PRODUCT 1531 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1532 st->print("BREAKPOINT"); 1533 } 1534 #endif 1535 1536 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1537 MacroAssembler _masm(&cbuf); 1538 __ brk(0); 1539 } 1540 1541 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1542 return MachNode::size(ra_); 1543 } 1544 1545 //============================================================================= 1546 1547 #ifndef PRODUCT 1548 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1549 st->print("nop \t# %d bytes pad for loops and calls", _count); 1550 } 1551 #endif 1552 1553 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1554 MacroAssembler _masm(&cbuf); 1555 for (int i = 0; i < _count; i++) { 1556 __ nop(); 1557 } 1558 } 1559 1560 uint MachNopNode::size(PhaseRegAlloc*) const { 1561 return _count * NativeInstruction::instruction_size; 1562 } 1563 1564 //============================================================================= 1565 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1566 1567 int Compile::ConstantTable::calculate_table_base_offset() const { 1568 return 0; // absolute addressing, no offset 1569 } 1570 1571 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1572 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1573 ShouldNotReachHere(); 1574 } 1575 1576 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1577 // Empty encoding 1578 } 1579 1580 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1581 return 0; 1582 } 1583 1584 #ifndef PRODUCT 1585 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1586 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1587 } 1588 #endif 1589 1590 #ifndef PRODUCT 1591 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1592 Compile* C = ra_->C; 1593 1594 int framesize = C->frame_slots() << LogBytesPerInt; 1595 1596 if (C->need_stack_bang(framesize)) 1597 st->print("# stack bang size=%d\n\t", framesize); 1598 1599 if (framesize < ((1 << 9) + 2 * wordSize)) { 1600 st->print("sub sp, sp, #%d\n\t", framesize); 1601 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1602 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1603 } else { 1604 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1605 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1606 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1607 st->print("sub sp, sp, rscratch1"); 1608 } 1609 } 1610 #endif 1611 1612 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1613 Compile* C = ra_->C; 1614 MacroAssembler _masm(&cbuf); 1615 1616 // n.b. frame size includes space for return pc and rfp 1617 const long framesize = C->frame_size_in_bytes(); 1618 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1619 1620 // insert a nop at the start of the prolog so we can patch in a 1621 // branch if we need to invalidate the method later 1622 __ nop(); 1623 1624 int bangsize = C->bang_size_in_bytes(); 1625 if (C->need_stack_bang(bangsize) && UseStackBanging) 1626 __ generate_stack_overflow_check(bangsize); 1627 1628 __ build_frame(framesize); 1629 1630 if (NotifySimulator) { 1631 __ notify(Assembler::method_entry); 1632 } 1633 1634 if (VerifyStackAtCalls) { 1635 Unimplemented(); 1636 } 1637 1638 C->set_frame_complete(cbuf.insts_size()); 1639 1640 if (C->has_mach_constant_base_node()) { 1641 // NOTE: We set the table base offset here because users might be 1642 // emitted before MachConstantBaseNode. 1643 Compile::ConstantTable& constant_table = C->constant_table(); 1644 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1645 } 1646 } 1647 1648 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1649 { 1650 return MachNode::size(ra_); // too many variables; just compute it 1651 // the hard way 1652 } 1653 1654 int MachPrologNode::reloc() const 1655 { 1656 return 0; 1657 } 1658 1659 //============================================================================= 1660 1661 #ifndef PRODUCT 1662 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1663 Compile* C = ra_->C; 1664 int framesize = C->frame_slots() << LogBytesPerInt; 1665 1666 st->print("# pop frame %d\n\t",framesize); 1667 1668 if (framesize == 0) { 1669 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1670 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1671 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1672 st->print("add sp, sp, #%d\n\t", framesize); 1673 } else { 1674 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1675 st->print("add sp, sp, rscratch1\n\t"); 1676 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1677 } 1678 1679 if (do_polling() && C->is_method_compilation()) { 1680 st->print("# touch polling page\n\t"); 1681 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1682 st->print("ldr zr, [rscratch1]"); 1683 } 1684 } 1685 #endif 1686 1687 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1688 Compile* C = ra_->C; 1689 MacroAssembler _masm(&cbuf); 1690 int framesize = C->frame_slots() << LogBytesPerInt; 1691 1692 __ remove_frame(framesize); 1693 1694 if (NotifySimulator) { 1695 __ notify(Assembler::method_reentry); 1696 } 1697 1698 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1699 __ reserved_stack_check(); 1700 } 1701 1702 if (do_polling() && C->is_method_compilation()) { 1703 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1704 } 1705 } 1706 1707 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1708 // Variable size. Determine dynamically. 1709 return MachNode::size(ra_); 1710 } 1711 1712 int MachEpilogNode::reloc() const { 1713 // Return number of relocatable values contained in this instruction. 1714 return 1; // 1 for polling page. 1715 } 1716 1717 const Pipeline * MachEpilogNode::pipeline() const { 1718 return MachNode::pipeline_class(); 1719 } 1720 1721 // This method seems to be obsolete. It is declared in machnode.hpp 1722 // and defined in all *.ad files, but it is never called. Should we 1723 // get rid of it? 1724 int MachEpilogNode::safepoint_offset() const { 1725 assert(do_polling(), "no return for this epilog node"); 1726 return 4; 1727 } 1728 1729 //============================================================================= 1730 1731 // Figure out which register class each belongs in: rc_int, rc_float or 1732 // rc_stack. 1733 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1734 1735 static enum RC rc_class(OptoReg::Name reg) { 1736 1737 if (reg == OptoReg::Bad) { 1738 return rc_bad; 1739 } 1740 1741 // we have 30 int registers * 2 halves 1742 // (rscratch1 and rscratch2 are omitted) 1743 1744 if (reg < 60) { 1745 return rc_int; 1746 } 1747 1748 // we have 32 float register * 2 halves 1749 if (reg < 60 + 128) { 1750 return rc_float; 1751 } 1752 1753 // Between float regs & stack is the flags regs. 1754 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1755 1756 return rc_stack; 1757 } 1758 1759 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1760 Compile* C = ra_->C; 1761 1762 // Get registers to move. 1763 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1764 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1765 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1766 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1767 1768 enum RC src_hi_rc = rc_class(src_hi); 1769 enum RC src_lo_rc = rc_class(src_lo); 1770 enum RC dst_hi_rc = rc_class(dst_hi); 1771 enum RC dst_lo_rc = rc_class(dst_lo); 1772 1773 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1774 1775 if (src_hi != OptoReg::Bad) { 1776 assert((src_lo&1)==0 && src_lo+1==src_hi && 1777 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1778 "expected aligned-adjacent pairs"); 1779 } 1780 1781 if (src_lo == dst_lo && src_hi == dst_hi) { 1782 return 0; // Self copy, no move. 1783 } 1784 1785 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1786 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1787 int src_offset = ra_->reg2offset(src_lo); 1788 int dst_offset = ra_->reg2offset(dst_lo); 1789 1790 if (bottom_type()->isa_vect() != NULL) { 1791 uint ireg = ideal_reg(); 1792 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1793 if (cbuf) { 1794 MacroAssembler _masm(cbuf); 1795 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1796 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1797 // stack->stack 1798 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1799 if (ireg == Op_VecD) { 1800 __ unspill(rscratch1, true, src_offset); 1801 __ spill(rscratch1, true, dst_offset); 1802 } else { 1803 __ spill_copy128(src_offset, dst_offset); 1804 } 1805 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1806 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1807 ireg == Op_VecD ? __ T8B : __ T16B, 1808 as_FloatRegister(Matcher::_regEncode[src_lo])); 1809 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1810 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1811 ireg == Op_VecD ? __ D : __ Q, 1812 ra_->reg2offset(dst_lo)); 1813 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1814 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1815 ireg == Op_VecD ? __ D : __ Q, 1816 ra_->reg2offset(src_lo)); 1817 } else { 1818 ShouldNotReachHere(); 1819 } 1820 } 1821 } else if (cbuf) { 1822 MacroAssembler _masm(cbuf); 1823 switch (src_lo_rc) { 1824 case rc_int: 1825 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1826 if (is64) { 1827 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1828 as_Register(Matcher::_regEncode[src_lo])); 1829 } else { 1830 MacroAssembler _masm(cbuf); 1831 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1832 as_Register(Matcher::_regEncode[src_lo])); 1833 } 1834 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1835 if (is64) { 1836 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1837 as_Register(Matcher::_regEncode[src_lo])); 1838 } else { 1839 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1840 as_Register(Matcher::_regEncode[src_lo])); 1841 } 1842 } else { // gpr --> stack spill 1843 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1844 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1845 } 1846 break; 1847 case rc_float: 1848 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1849 if (is64) { 1850 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1851 as_FloatRegister(Matcher::_regEncode[src_lo])); 1852 } else { 1853 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1854 as_FloatRegister(Matcher::_regEncode[src_lo])); 1855 } 1856 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1857 if (cbuf) { 1858 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1859 as_FloatRegister(Matcher::_regEncode[src_lo])); 1860 } else { 1861 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1862 as_FloatRegister(Matcher::_regEncode[src_lo])); 1863 } 1864 } else { // fpr --> stack spill 1865 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1866 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1867 is64 ? __ D : __ S, dst_offset); 1868 } 1869 break; 1870 case rc_stack: 1871 if (dst_lo_rc == rc_int) { // stack --> gpr load 1872 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1873 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1874 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1875 is64 ? __ D : __ S, src_offset); 1876 } else { // stack --> stack copy 1877 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1878 __ unspill(rscratch1, is64, src_offset); 1879 __ spill(rscratch1, is64, dst_offset); 1880 } 1881 break; 1882 default: 1883 assert(false, "bad rc_class for spill"); 1884 ShouldNotReachHere(); 1885 } 1886 } 1887 1888 if (st) { 1889 st->print("spill "); 1890 if (src_lo_rc == rc_stack) { 1891 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1892 } else { 1893 st->print("%s -> ", Matcher::regName[src_lo]); 1894 } 1895 if (dst_lo_rc == rc_stack) { 1896 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1897 } else { 1898 st->print("%s", Matcher::regName[dst_lo]); 1899 } 1900 if (bottom_type()->isa_vect() != NULL) { 1901 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1902 } else { 1903 st->print("\t# spill size = %d", is64 ? 64:32); 1904 } 1905 } 1906 1907 return 0; 1908 1909 } 1910 1911 #ifndef PRODUCT 1912 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1913 if (!ra_) 1914 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1915 else 1916 implementation(NULL, ra_, false, st); 1917 } 1918 #endif 1919 1920 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1921 implementation(&cbuf, ra_, false, NULL); 1922 } 1923 1924 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1925 return MachNode::size(ra_); 1926 } 1927 1928 //============================================================================= 1929 1930 #ifndef PRODUCT 1931 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1932 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1933 int reg = ra_->get_reg_first(this); 1934 st->print("add %s, rsp, #%d]\t# box lock", 1935 Matcher::regName[reg], offset); 1936 } 1937 #endif 1938 1939 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1940 MacroAssembler _masm(&cbuf); 1941 1942 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1943 int reg = ra_->get_encode(this); 1944 1945 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1946 __ add(as_Register(reg), sp, offset); 1947 } else { 1948 ShouldNotReachHere(); 1949 } 1950 } 1951 1952 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1953 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1954 return 4; 1955 } 1956 1957 //============================================================================= 1958 1959 #ifndef PRODUCT 1960 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1961 { 1962 st->print_cr("# MachUEPNode"); 1963 if (UseCompressedClassPointers) { 1964 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1965 if (Universe::narrow_klass_shift() != 0) { 1966 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1967 } 1968 } else { 1969 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1970 } 1971 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1972 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1973 } 1974 #endif 1975 1976 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1977 { 1978 // This is the unverified entry point. 1979 MacroAssembler _masm(&cbuf); 1980 1981 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1982 Label skip; 1983 // TODO 1984 // can we avoid this skip and still use a reloc? 1985 __ br(Assembler::EQ, skip); 1986 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1987 __ bind(skip); 1988 } 1989 1990 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1991 { 1992 return MachNode::size(ra_); 1993 } 1994 1995 // REQUIRED EMIT CODE 1996 1997 //============================================================================= 1998 1999 // Emit exception handler code. 2000 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2001 { 2002 // mov rscratch1 #exception_blob_entry_point 2003 // br rscratch1 2004 // Note that the code buffer's insts_mark is always relative to insts. 2005 // That's why we must use the macroassembler to generate a handler. 2006 MacroAssembler _masm(&cbuf); 2007 address base = __ start_a_stub(size_exception_handler()); 2008 if (base == NULL) { 2009 ciEnv::current()->record_failure("CodeCache is full"); 2010 return 0; // CodeBuffer::expand failed 2011 } 2012 int offset = __ offset(); 2013 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2014 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2015 __ end_a_stub(); 2016 return offset; 2017 } 2018 2019 // Emit deopt handler code. 2020 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2021 { 2022 // Note that the code buffer's insts_mark is always relative to insts. 2023 // That's why we must use the macroassembler to generate a handler. 2024 MacroAssembler _masm(&cbuf); 2025 address base = __ start_a_stub(size_deopt_handler()); 2026 if (base == NULL) { 2027 ciEnv::current()->record_failure("CodeCache is full"); 2028 return 0; // CodeBuffer::expand failed 2029 } 2030 int offset = __ offset(); 2031 2032 __ adr(lr, __ pc()); 2033 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2034 2035 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2036 __ end_a_stub(); 2037 return offset; 2038 } 2039 2040 // REQUIRED MATCHER CODE 2041 2042 //============================================================================= 2043 2044 const bool Matcher::match_rule_supported(int opcode) { 2045 2046 switch (opcode) { 2047 default: 2048 break; 2049 } 2050 2051 if (!has_match_rule(opcode)) { 2052 return false; 2053 } 2054 2055 return true; // Per default match rules are supported. 2056 } 2057 2058 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2059 2060 // TODO 2061 // identify extra cases that we might want to provide match rules for 2062 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2063 bool ret_value = match_rule_supported(opcode); 2064 // Add rules here. 2065 2066 return ret_value; // Per default match rules are supported. 2067 } 2068 2069 const bool Matcher::has_predicated_vectors(void) { 2070 return false; 2071 } 2072 2073 const int Matcher::float_pressure(int default_pressure_threshold) { 2074 return default_pressure_threshold; 2075 } 2076 2077 int Matcher::regnum_to_fpu_offset(int regnum) 2078 { 2079 Unimplemented(); 2080 return 0; 2081 } 2082 2083 // Is this branch offset short enough that a short branch can be used? 2084 // 2085 // NOTE: If the platform does not provide any short branch variants, then 2086 // this method should return false for offset 0. 2087 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2088 // The passed offset is relative to address of the branch. 2089 2090 return (-32768 <= offset && offset < 32768); 2091 } 2092 2093 const bool Matcher::isSimpleConstant64(jlong value) { 2094 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2095 // Probably always true, even if a temp register is required. 2096 return true; 2097 } 2098 2099 // true just means we have fast l2f conversion 2100 const bool Matcher::convL2FSupported(void) { 2101 return true; 2102 } 2103 2104 // Vector width in bytes. 2105 const int Matcher::vector_width_in_bytes(BasicType bt) { 2106 int size = MIN2(16,(int)MaxVectorSize); 2107 // Minimum 2 values in vector 2108 if (size < 2*type2aelembytes(bt)) size = 0; 2109 // But never < 4 2110 if (size < 4) size = 0; 2111 return size; 2112 } 2113 2114 // Limits on vector size (number of elements) loaded into vector. 2115 const int Matcher::max_vector_size(const BasicType bt) { 2116 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2117 } 2118 const int Matcher::min_vector_size(const BasicType bt) { 2119 // For the moment limit the vector size to 8 bytes 2120 int size = 8 / type2aelembytes(bt); 2121 if (size < 2) size = 2; 2122 return size; 2123 } 2124 2125 // Vector ideal reg. 2126 const uint Matcher::vector_ideal_reg(int len) { 2127 switch(len) { 2128 case 8: return Op_VecD; 2129 case 16: return Op_VecX; 2130 } 2131 ShouldNotReachHere(); 2132 return 0; 2133 } 2134 2135 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2136 switch(size) { 2137 case 8: return Op_VecD; 2138 case 16: return Op_VecX; 2139 } 2140 ShouldNotReachHere(); 2141 return 0; 2142 } 2143 2144 // AES support not yet implemented 2145 const bool Matcher::pass_original_key_for_aes() { 2146 return false; 2147 } 2148 2149 // x86 supports misaligned vectors store/load. 2150 const bool Matcher::misaligned_vectors_ok() { 2151 return !AlignVector; // can be changed by flag 2152 } 2153 2154 // false => size gets scaled to BytesPerLong, ok. 2155 const bool Matcher::init_array_count_is_in_bytes = false; 2156 2157 // Use conditional move (CMOVL) 2158 const int Matcher::long_cmove_cost() { 2159 // long cmoves are no more expensive than int cmoves 2160 return 0; 2161 } 2162 2163 const int Matcher::float_cmove_cost() { 2164 // float cmoves are no more expensive than int cmoves 2165 return 0; 2166 } 2167 2168 // Does the CPU require late expand (see block.cpp for description of late expand)? 2169 const bool Matcher::require_postalloc_expand = false; 2170 2171 // Do we need to mask the count passed to shift instructions or does 2172 // the cpu only look at the lower 5/6 bits anyway? 2173 const bool Matcher::need_masked_shift_count = false; 2174 2175 // This affects two different things: 2176 // - how Decode nodes are matched 2177 // - how ImplicitNullCheck opportunities are recognized 2178 // If true, the matcher will try to remove all Decodes and match them 2179 // (as operands) into nodes. NullChecks are not prepared to deal with 2180 // Decodes by final_graph_reshaping(). 2181 // If false, final_graph_reshaping() forces the decode behind the Cmp 2182 // for a NullCheck. The matcher matches the Decode node into a register. 2183 // Implicit_null_check optimization moves the Decode along with the 2184 // memory operation back up before the NullCheck. 2185 bool Matcher::narrow_oop_use_complex_address() { 2186 return Universe::narrow_oop_shift() == 0; 2187 } 2188 2189 bool Matcher::narrow_klass_use_complex_address() { 2190 // TODO 2191 // decide whether we need to set this to true 2192 return false; 2193 } 2194 2195 bool Matcher::const_oop_prefer_decode() { 2196 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2197 return Universe::narrow_oop_base() == NULL; 2198 } 2199 2200 bool Matcher::const_klass_prefer_decode() { 2201 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2202 return Universe::narrow_klass_base() == NULL; 2203 } 2204 2205 // Is it better to copy float constants, or load them directly from 2206 // memory? Intel can load a float constant from a direct address, 2207 // requiring no extra registers. Most RISCs will have to materialize 2208 // an address into a register first, so they would do better to copy 2209 // the constant from stack. 2210 const bool Matcher::rematerialize_float_constants = false; 2211 2212 // If CPU can load and store mis-aligned doubles directly then no 2213 // fixup is needed. Else we split the double into 2 integer pieces 2214 // and move it piece-by-piece. Only happens when passing doubles into 2215 // C code as the Java calling convention forces doubles to be aligned. 2216 const bool Matcher::misaligned_doubles_ok = true; 2217 2218 // No-op on amd64 2219 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2220 Unimplemented(); 2221 } 2222 2223 // Advertise here if the CPU requires explicit rounding operations to 2224 // implement the UseStrictFP mode. 2225 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2226 2227 // Are floats converted to double when stored to stack during 2228 // deoptimization? 2229 bool Matcher::float_in_double() { return false; } 2230 2231 // Do ints take an entire long register or just half? 2232 // The relevant question is how the int is callee-saved: 2233 // the whole long is written but de-opt'ing will have to extract 2234 // the relevant 32 bits. 2235 const bool Matcher::int_in_long = true; 2236 2237 // Return whether or not this register is ever used as an argument. 2238 // This function is used on startup to build the trampoline stubs in 2239 // generateOptoStub. Registers not mentioned will be killed by the VM 2240 // call in the trampoline, and arguments in those registers not be 2241 // available to the callee. 2242 bool Matcher::can_be_java_arg(int reg) 2243 { 2244 return 2245 reg == R0_num || reg == R0_H_num || 2246 reg == R1_num || reg == R1_H_num || 2247 reg == R2_num || reg == R2_H_num || 2248 reg == R3_num || reg == R3_H_num || 2249 reg == R4_num || reg == R4_H_num || 2250 reg == R5_num || reg == R5_H_num || 2251 reg == R6_num || reg == R6_H_num || 2252 reg == R7_num || reg == R7_H_num || 2253 reg == V0_num || reg == V0_H_num || 2254 reg == V1_num || reg == V1_H_num || 2255 reg == V2_num || reg == V2_H_num || 2256 reg == V3_num || reg == V3_H_num || 2257 reg == V4_num || reg == V4_H_num || 2258 reg == V5_num || reg == V5_H_num || 2259 reg == V6_num || reg == V6_H_num || 2260 reg == V7_num || reg == V7_H_num; 2261 } 2262 2263 bool Matcher::is_spillable_arg(int reg) 2264 { 2265 return can_be_java_arg(reg); 2266 } 2267 2268 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2269 return false; 2270 } 2271 2272 RegMask Matcher::divI_proj_mask() { 2273 ShouldNotReachHere(); 2274 return RegMask(); 2275 } 2276 2277 // Register for MODI projection of divmodI. 2278 RegMask Matcher::modI_proj_mask() { 2279 ShouldNotReachHere(); 2280 return RegMask(); 2281 } 2282 2283 // Register for DIVL projection of divmodL. 2284 RegMask Matcher::divL_proj_mask() { 2285 ShouldNotReachHere(); 2286 return RegMask(); 2287 } 2288 2289 // Register for MODL projection of divmodL. 2290 RegMask Matcher::modL_proj_mask() { 2291 ShouldNotReachHere(); 2292 return RegMask(); 2293 } 2294 2295 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2296 return FP_REG_mask(); 2297 } 2298 2299 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2300 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2301 Node* u = addp->fast_out(i); 2302 if (u->is_Mem()) { 2303 int opsize = u->as_Mem()->memory_size(); 2304 assert(opsize > 0, "unexpected memory operand size"); 2305 if (u->as_Mem()->memory_size() != (1<<shift)) { 2306 return false; 2307 } 2308 } 2309 } 2310 return true; 2311 } 2312 2313 const bool Matcher::convi2l_type_required = false; 2314 2315 // Should the Matcher clone shifts on addressing modes, expecting them 2316 // to be subsumed into complex addressing expressions or compute them 2317 // into registers? 2318 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2319 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2320 return true; 2321 } 2322 2323 Node *off = m->in(AddPNode::Offset); 2324 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2325 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2326 // Are there other uses besides address expressions? 2327 !is_visited(off)) { 2328 address_visited.set(off->_idx); // Flag as address_visited 2329 mstack.push(off->in(2), Visit); 2330 Node *conv = off->in(1); 2331 if (conv->Opcode() == Op_ConvI2L && 2332 // Are there other uses besides address expressions? 2333 !is_visited(conv)) { 2334 address_visited.set(conv->_idx); // Flag as address_visited 2335 mstack.push(conv->in(1), Pre_Visit); 2336 } else { 2337 mstack.push(conv, Pre_Visit); 2338 } 2339 address_visited.test_set(m->_idx); // Flag as address_visited 2340 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2341 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2342 return true; 2343 } else if (off->Opcode() == Op_ConvI2L && 2344 // Are there other uses besides address expressions? 2345 !is_visited(off)) { 2346 address_visited.test_set(m->_idx); // Flag as address_visited 2347 address_visited.set(off->_idx); // Flag as address_visited 2348 mstack.push(off->in(1), Pre_Visit); 2349 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2350 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2351 return true; 2352 } 2353 return false; 2354 } 2355 2356 void Compile::reshape_address(AddPNode* addp) { 2357 } 2358 2359 // helper for encoding java_to_runtime calls on sim 2360 // 2361 // this is needed to compute the extra arguments required when 2362 // planting a call to the simulator blrt instruction. the TypeFunc 2363 // can be queried to identify the counts for integral, and floating 2364 // arguments and the return type 2365 2366 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2367 { 2368 int gps = 0; 2369 int fps = 0; 2370 const TypeTuple *domain = tf->domain(); 2371 int max = domain->cnt(); 2372 for (int i = TypeFunc::Parms; i < max; i++) { 2373 const Type *t = domain->field_at(i); 2374 switch(t->basic_type()) { 2375 case T_FLOAT: 2376 case T_DOUBLE: 2377 fps++; 2378 default: 2379 gps++; 2380 } 2381 } 2382 gpcnt = gps; 2383 fpcnt = fps; 2384 BasicType rt = tf->return_type(); 2385 switch (rt) { 2386 case T_VOID: 2387 rtype = MacroAssembler::ret_type_void; 2388 break; 2389 default: 2390 rtype = MacroAssembler::ret_type_integral; 2391 break; 2392 case T_FLOAT: 2393 rtype = MacroAssembler::ret_type_float; 2394 break; 2395 case T_DOUBLE: 2396 rtype = MacroAssembler::ret_type_double; 2397 break; 2398 } 2399 } 2400 2401 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2402 MacroAssembler _masm(&cbuf); \ 2403 { \ 2404 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2405 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2406 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2407 __ INSN(REG, as_Register(BASE)); \ 2408 } 2409 2410 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2411 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2412 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2413 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2414 2415 // Used for all non-volatile memory accesses. The use of 2416 // $mem->opcode() to discover whether this pattern uses sign-extended 2417 // offsets is something of a kludge. 2418 static void loadStore(MacroAssembler masm, mem_insn insn, 2419 Register reg, int opcode, 2420 Register base, int index, int size, int disp) 2421 { 2422 Address::extend scale; 2423 2424 // Hooboy, this is fugly. We need a way to communicate to the 2425 // encoder that the index needs to be sign extended, so we have to 2426 // enumerate all the cases. 2427 switch (opcode) { 2428 case INDINDEXSCALEDI2L: 2429 case INDINDEXSCALEDI2LN: 2430 case INDINDEXI2L: 2431 case INDINDEXI2LN: 2432 scale = Address::sxtw(size); 2433 break; 2434 default: 2435 scale = Address::lsl(size); 2436 } 2437 2438 if (index == -1) { 2439 (masm.*insn)(reg, Address(base, disp)); 2440 } else { 2441 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2442 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2443 } 2444 } 2445 2446 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2447 FloatRegister reg, int opcode, 2448 Register base, int index, int size, int disp) 2449 { 2450 Address::extend scale; 2451 2452 switch (opcode) { 2453 case INDINDEXSCALEDI2L: 2454 case INDINDEXSCALEDI2LN: 2455 scale = Address::sxtw(size); 2456 break; 2457 default: 2458 scale = Address::lsl(size); 2459 } 2460 2461 if (index == -1) { 2462 (masm.*insn)(reg, Address(base, disp)); 2463 } else { 2464 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2465 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2466 } 2467 } 2468 2469 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2470 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2471 int opcode, Register base, int index, int size, int disp) 2472 { 2473 if (index == -1) { 2474 (masm.*insn)(reg, T, Address(base, disp)); 2475 } else { 2476 assert(disp == 0, "unsupported address mode"); 2477 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2478 } 2479 } 2480 2481 %} 2482 2483 2484 2485 //----------ENCODING BLOCK----------------------------------------------------- 2486 // This block specifies the encoding classes used by the compiler to 2487 // output byte streams. Encoding classes are parameterized macros 2488 // used by Machine Instruction Nodes in order to generate the bit 2489 // encoding of the instruction. Operands specify their base encoding 2490 // interface with the interface keyword. There are currently 2491 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2492 // COND_INTER. REG_INTER causes an operand to generate a function 2493 // which returns its register number when queried. CONST_INTER causes 2494 // an operand to generate a function which returns the value of the 2495 // constant when queried. MEMORY_INTER causes an operand to generate 2496 // four functions which return the Base Register, the Index Register, 2497 // the Scale Value, and the Offset Value of the operand when queried. 2498 // COND_INTER causes an operand to generate six functions which return 2499 // the encoding code (ie - encoding bits for the instruction) 2500 // associated with each basic boolean condition for a conditional 2501 // instruction. 2502 // 2503 // Instructions specify two basic values for encoding. Again, a 2504 // function is available to check if the constant displacement is an 2505 // oop. They use the ins_encode keyword to specify their encoding 2506 // classes (which must be a sequence of enc_class names, and their 2507 // parameters, specified in the encoding block), and they use the 2508 // opcode keyword to specify, in order, their primary, secondary, and 2509 // tertiary opcode. Only the opcode sections which a particular 2510 // instruction needs for encoding need to be specified. 2511 encode %{ 2512 // Build emit functions for each basic byte or larger field in the 2513 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2514 // from C++ code in the enc_class source block. Emit functions will 2515 // live in the main source block for now. In future, we can 2516 // generalize this by adding a syntax that specifies the sizes of 2517 // fields in an order, so that the adlc can build the emit functions 2518 // automagically 2519 2520 // catch all for unimplemented encodings 2521 enc_class enc_unimplemented %{ 2522 MacroAssembler _masm(&cbuf); 2523 __ unimplemented("C2 catch all"); 2524 %} 2525 2526 // BEGIN Non-volatile memory access 2527 2528 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2529 Register dst_reg = as_Register($dst$$reg); 2530 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2531 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2532 %} 2533 2534 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2535 Register dst_reg = as_Register($dst$$reg); 2536 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2537 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2538 %} 2539 2540 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2541 Register dst_reg = as_Register($dst$$reg); 2542 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2543 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2544 %} 2545 2546 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2547 Register dst_reg = as_Register($dst$$reg); 2548 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2549 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2550 %} 2551 2552 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2553 Register dst_reg = as_Register($dst$$reg); 2554 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2555 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2556 %} 2557 2558 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2559 Register dst_reg = as_Register($dst$$reg); 2560 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2561 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2562 %} 2563 2564 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2565 Register dst_reg = as_Register($dst$$reg); 2566 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2567 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2568 %} 2569 2570 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2571 Register dst_reg = as_Register($dst$$reg); 2572 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2573 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2574 %} 2575 2576 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2577 Register dst_reg = as_Register($dst$$reg); 2578 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2579 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2580 %} 2581 2582 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2583 Register dst_reg = as_Register($dst$$reg); 2584 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2585 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2586 %} 2587 2588 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2589 Register dst_reg = as_Register($dst$$reg); 2590 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2591 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2592 %} 2593 2594 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2595 Register dst_reg = as_Register($dst$$reg); 2596 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2597 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2598 %} 2599 2600 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2601 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2602 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2603 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2604 %} 2605 2606 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2607 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2608 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2609 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2610 %} 2611 2612 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2613 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2614 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2615 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2616 %} 2617 2618 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2619 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2620 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2621 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2622 %} 2623 2624 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2625 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2626 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2627 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2628 %} 2629 2630 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2631 Register src_reg = as_Register($src$$reg); 2632 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2633 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2634 %} 2635 2636 enc_class aarch64_enc_strb0(memory mem) %{ 2637 MacroAssembler _masm(&cbuf); 2638 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2639 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2640 %} 2641 2642 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2643 MacroAssembler _masm(&cbuf); 2644 __ membar(Assembler::StoreStore); 2645 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2646 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2647 %} 2648 2649 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2650 Register src_reg = as_Register($src$$reg); 2651 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2652 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2653 %} 2654 2655 enc_class aarch64_enc_strh0(memory mem) %{ 2656 MacroAssembler _masm(&cbuf); 2657 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2658 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2659 %} 2660 2661 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2662 Register src_reg = as_Register($src$$reg); 2663 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2664 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2665 %} 2666 2667 enc_class aarch64_enc_strw0(memory mem) %{ 2668 MacroAssembler _masm(&cbuf); 2669 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2670 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2671 %} 2672 2673 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2674 Register src_reg = as_Register($src$$reg); 2675 // we sometimes get asked to store the stack pointer into the 2676 // current thread -- we cannot do that directly on AArch64 2677 if (src_reg == r31_sp) { 2678 MacroAssembler _masm(&cbuf); 2679 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2680 __ mov(rscratch2, sp); 2681 src_reg = rscratch2; 2682 } 2683 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2684 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2685 %} 2686 2687 enc_class aarch64_enc_str0(memory mem) %{ 2688 MacroAssembler _masm(&cbuf); 2689 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2690 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2691 %} 2692 2693 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2694 FloatRegister src_reg = as_FloatRegister($src$$reg); 2695 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2696 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2697 %} 2698 2699 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2700 FloatRegister src_reg = as_FloatRegister($src$$reg); 2701 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2702 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2703 %} 2704 2705 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2706 FloatRegister src_reg = as_FloatRegister($src$$reg); 2707 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2708 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2709 %} 2710 2711 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2712 FloatRegister src_reg = as_FloatRegister($src$$reg); 2713 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2714 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2715 %} 2716 2717 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2718 FloatRegister src_reg = as_FloatRegister($src$$reg); 2719 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2720 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2721 %} 2722 2723 // END Non-volatile memory access 2724 2725 // volatile loads and stores 2726 2727 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2728 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2729 rscratch1, stlrb); 2730 %} 2731 2732 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2733 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2734 rscratch1, stlrh); 2735 %} 2736 2737 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2738 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2739 rscratch1, stlrw); 2740 %} 2741 2742 2743 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2744 Register dst_reg = as_Register($dst$$reg); 2745 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2746 rscratch1, ldarb); 2747 __ sxtbw(dst_reg, dst_reg); 2748 %} 2749 2750 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2751 Register dst_reg = as_Register($dst$$reg); 2752 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2753 rscratch1, ldarb); 2754 __ sxtb(dst_reg, dst_reg); 2755 %} 2756 2757 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2758 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2759 rscratch1, ldarb); 2760 %} 2761 2762 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2763 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2764 rscratch1, ldarb); 2765 %} 2766 2767 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2768 Register dst_reg = as_Register($dst$$reg); 2769 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2770 rscratch1, ldarh); 2771 __ sxthw(dst_reg, dst_reg); 2772 %} 2773 2774 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2775 Register dst_reg = as_Register($dst$$reg); 2776 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2777 rscratch1, ldarh); 2778 __ sxth(dst_reg, dst_reg); 2779 %} 2780 2781 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2782 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2783 rscratch1, ldarh); 2784 %} 2785 2786 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2787 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2788 rscratch1, ldarh); 2789 %} 2790 2791 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2792 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2793 rscratch1, ldarw); 2794 %} 2795 2796 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2797 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2798 rscratch1, ldarw); 2799 %} 2800 2801 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2802 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2803 rscratch1, ldar); 2804 %} 2805 2806 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2807 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2808 rscratch1, ldarw); 2809 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2810 %} 2811 2812 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2813 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2814 rscratch1, ldar); 2815 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2816 %} 2817 2818 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2819 Register src_reg = as_Register($src$$reg); 2820 // we sometimes get asked to store the stack pointer into the 2821 // current thread -- we cannot do that directly on AArch64 2822 if (src_reg == r31_sp) { 2823 MacroAssembler _masm(&cbuf); 2824 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2825 __ mov(rscratch2, sp); 2826 src_reg = rscratch2; 2827 } 2828 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2829 rscratch1, stlr); 2830 %} 2831 2832 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2833 { 2834 MacroAssembler _masm(&cbuf); 2835 FloatRegister src_reg = as_FloatRegister($src$$reg); 2836 __ fmovs(rscratch2, src_reg); 2837 } 2838 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2839 rscratch1, stlrw); 2840 %} 2841 2842 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2843 { 2844 MacroAssembler _masm(&cbuf); 2845 FloatRegister src_reg = as_FloatRegister($src$$reg); 2846 __ fmovd(rscratch2, src_reg); 2847 } 2848 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2849 rscratch1, stlr); 2850 %} 2851 2852 // synchronized read/update encodings 2853 2854 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2855 MacroAssembler _masm(&cbuf); 2856 Register dst_reg = as_Register($dst$$reg); 2857 Register base = as_Register($mem$$base); 2858 int index = $mem$$index; 2859 int scale = $mem$$scale; 2860 int disp = $mem$$disp; 2861 if (index == -1) { 2862 if (disp != 0) { 2863 __ lea(rscratch1, Address(base, disp)); 2864 __ ldaxr(dst_reg, rscratch1); 2865 } else { 2866 // TODO 2867 // should we ever get anything other than this case? 2868 __ ldaxr(dst_reg, base); 2869 } 2870 } else { 2871 Register index_reg = as_Register(index); 2872 if (disp == 0) { 2873 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2874 __ ldaxr(dst_reg, rscratch1); 2875 } else { 2876 __ lea(rscratch1, Address(base, disp)); 2877 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2878 __ ldaxr(dst_reg, rscratch1); 2879 } 2880 } 2881 %} 2882 2883 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2884 MacroAssembler _masm(&cbuf); 2885 Register src_reg = as_Register($src$$reg); 2886 Register base = as_Register($mem$$base); 2887 int index = $mem$$index; 2888 int scale = $mem$$scale; 2889 int disp = $mem$$disp; 2890 if (index == -1) { 2891 if (disp != 0) { 2892 __ lea(rscratch2, Address(base, disp)); 2893 __ stlxr(rscratch1, src_reg, rscratch2); 2894 } else { 2895 // TODO 2896 // should we ever get anything other than this case? 2897 __ stlxr(rscratch1, src_reg, base); 2898 } 2899 } else { 2900 Register index_reg = as_Register(index); 2901 if (disp == 0) { 2902 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2903 __ stlxr(rscratch1, src_reg, rscratch2); 2904 } else { 2905 __ lea(rscratch2, Address(base, disp)); 2906 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2907 __ stlxr(rscratch1, src_reg, rscratch2); 2908 } 2909 } 2910 __ cmpw(rscratch1, zr); 2911 %} 2912 2913 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2914 MacroAssembler _masm(&cbuf); 2915 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2916 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2917 Assembler::xword, /*acquire*/ false, /*release*/ true, 2918 /*weak*/ false, noreg); 2919 %} 2920 2921 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2922 MacroAssembler _masm(&cbuf); 2923 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2924 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2925 Assembler::word, /*acquire*/ false, /*release*/ true, 2926 /*weak*/ false, noreg); 2927 %} 2928 2929 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2930 MacroAssembler _masm(&cbuf); 2931 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2932 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2933 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2934 /*weak*/ false, noreg); 2935 %} 2936 2937 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2938 MacroAssembler _masm(&cbuf); 2939 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2940 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2941 Assembler::byte, /*acquire*/ false, /*release*/ true, 2942 /*weak*/ false, noreg); 2943 %} 2944 2945 2946 // The only difference between aarch64_enc_cmpxchg and 2947 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2948 // CompareAndSwap sequence to serve as a barrier on acquiring a 2949 // lock. 2950 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2951 MacroAssembler _masm(&cbuf); 2952 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2953 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2954 Assembler::xword, /*acquire*/ true, /*release*/ true, 2955 /*weak*/ false, noreg); 2956 %} 2957 2958 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2959 MacroAssembler _masm(&cbuf); 2960 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2961 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2962 Assembler::word, /*acquire*/ true, /*release*/ true, 2963 /*weak*/ false, noreg); 2964 %} 2965 2966 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2967 MacroAssembler _masm(&cbuf); 2968 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2969 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2970 Assembler::halfword, /*acquire*/ true, /*release*/ true, 2971 /*weak*/ false, noreg); 2972 %} 2973 2974 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2975 MacroAssembler _masm(&cbuf); 2976 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2977 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2978 Assembler::byte, /*acquire*/ true, /*release*/ true, 2979 /*weak*/ false, noreg); 2980 %} 2981 2982 // auxiliary used for CompareAndSwapX to set result register 2983 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2984 MacroAssembler _masm(&cbuf); 2985 Register res_reg = as_Register($res$$reg); 2986 __ cset(res_reg, Assembler::EQ); 2987 %} 2988 2989 // prefetch encodings 2990 2991 enc_class aarch64_enc_prefetchw(memory mem) %{ 2992 MacroAssembler _masm(&cbuf); 2993 Register base = as_Register($mem$$base); 2994 int index = $mem$$index; 2995 int scale = $mem$$scale; 2996 int disp = $mem$$disp; 2997 if (index == -1) { 2998 __ prfm(Address(base, disp), PSTL1KEEP); 2999 } else { 3000 Register index_reg = as_Register(index); 3001 if (disp == 0) { 3002 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3003 } else { 3004 __ lea(rscratch1, Address(base, disp)); 3005 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3006 } 3007 } 3008 %} 3009 3010 /// mov envcodings 3011 3012 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3013 MacroAssembler _masm(&cbuf); 3014 u_int32_t con = (u_int32_t)$src$$constant; 3015 Register dst_reg = as_Register($dst$$reg); 3016 if (con == 0) { 3017 __ movw(dst_reg, zr); 3018 } else { 3019 __ movw(dst_reg, con); 3020 } 3021 %} 3022 3023 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3024 MacroAssembler _masm(&cbuf); 3025 Register dst_reg = as_Register($dst$$reg); 3026 u_int64_t con = (u_int64_t)$src$$constant; 3027 if (con == 0) { 3028 __ mov(dst_reg, zr); 3029 } else { 3030 __ mov(dst_reg, con); 3031 } 3032 %} 3033 3034 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3035 MacroAssembler _masm(&cbuf); 3036 Register dst_reg = as_Register($dst$$reg); 3037 address con = (address)$src$$constant; 3038 if (con == NULL || con == (address)1) { 3039 ShouldNotReachHere(); 3040 } else { 3041 relocInfo::relocType rtype = $src->constant_reloc(); 3042 if (rtype == relocInfo::oop_type) { 3043 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3044 } else if (rtype == relocInfo::metadata_type) { 3045 __ mov_metadata(dst_reg, (Metadata*)con); 3046 } else { 3047 assert(rtype == relocInfo::none, "unexpected reloc type"); 3048 if (con < (address)(uintptr_t)os::vm_page_size()) { 3049 __ mov(dst_reg, con); 3050 } else { 3051 unsigned long offset; 3052 __ adrp(dst_reg, con, offset); 3053 __ add(dst_reg, dst_reg, offset); 3054 } 3055 } 3056 } 3057 %} 3058 3059 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3060 MacroAssembler _masm(&cbuf); 3061 Register dst_reg = as_Register($dst$$reg); 3062 __ mov(dst_reg, zr); 3063 %} 3064 3065 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3066 MacroAssembler _masm(&cbuf); 3067 Register dst_reg = as_Register($dst$$reg); 3068 __ mov(dst_reg, (u_int64_t)1); 3069 %} 3070 3071 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3072 MacroAssembler _masm(&cbuf); 3073 address page = (address)$src$$constant; 3074 Register dst_reg = as_Register($dst$$reg); 3075 unsigned long off; 3076 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3077 assert(off == 0, "assumed offset == 0"); 3078 %} 3079 3080 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3081 MacroAssembler _masm(&cbuf); 3082 __ load_byte_map_base($dst$$Register); 3083 %} 3084 3085 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3086 MacroAssembler _masm(&cbuf); 3087 Register dst_reg = as_Register($dst$$reg); 3088 address con = (address)$src$$constant; 3089 if (con == NULL) { 3090 ShouldNotReachHere(); 3091 } else { 3092 relocInfo::relocType rtype = $src->constant_reloc(); 3093 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3094 __ set_narrow_oop(dst_reg, (jobject)con); 3095 } 3096 %} 3097 3098 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3099 MacroAssembler _masm(&cbuf); 3100 Register dst_reg = as_Register($dst$$reg); 3101 __ mov(dst_reg, zr); 3102 %} 3103 3104 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3105 MacroAssembler _masm(&cbuf); 3106 Register dst_reg = as_Register($dst$$reg); 3107 address con = (address)$src$$constant; 3108 if (con == NULL) { 3109 ShouldNotReachHere(); 3110 } else { 3111 relocInfo::relocType rtype = $src->constant_reloc(); 3112 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3113 __ set_narrow_klass(dst_reg, (Klass *)con); 3114 } 3115 %} 3116 3117 // arithmetic encodings 3118 3119 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3120 MacroAssembler _masm(&cbuf); 3121 Register dst_reg = as_Register($dst$$reg); 3122 Register src_reg = as_Register($src1$$reg); 3123 int32_t con = (int32_t)$src2$$constant; 3124 // add has primary == 0, subtract has primary == 1 3125 if ($primary) { con = -con; } 3126 if (con < 0) { 3127 __ subw(dst_reg, src_reg, -con); 3128 } else { 3129 __ addw(dst_reg, src_reg, con); 3130 } 3131 %} 3132 3133 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3134 MacroAssembler _masm(&cbuf); 3135 Register dst_reg = as_Register($dst$$reg); 3136 Register src_reg = as_Register($src1$$reg); 3137 int32_t con = (int32_t)$src2$$constant; 3138 // add has primary == 0, subtract has primary == 1 3139 if ($primary) { con = -con; } 3140 if (con < 0) { 3141 __ sub(dst_reg, src_reg, -con); 3142 } else { 3143 __ add(dst_reg, src_reg, con); 3144 } 3145 %} 3146 3147 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3148 MacroAssembler _masm(&cbuf); 3149 Register dst_reg = as_Register($dst$$reg); 3150 Register src1_reg = as_Register($src1$$reg); 3151 Register src2_reg = as_Register($src2$$reg); 3152 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3153 %} 3154 3155 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3156 MacroAssembler _masm(&cbuf); 3157 Register dst_reg = as_Register($dst$$reg); 3158 Register src1_reg = as_Register($src1$$reg); 3159 Register src2_reg = as_Register($src2$$reg); 3160 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3161 %} 3162 3163 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3164 MacroAssembler _masm(&cbuf); 3165 Register dst_reg = as_Register($dst$$reg); 3166 Register src1_reg = as_Register($src1$$reg); 3167 Register src2_reg = as_Register($src2$$reg); 3168 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3169 %} 3170 3171 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3172 MacroAssembler _masm(&cbuf); 3173 Register dst_reg = as_Register($dst$$reg); 3174 Register src1_reg = as_Register($src1$$reg); 3175 Register src2_reg = as_Register($src2$$reg); 3176 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3177 %} 3178 3179 // compare instruction encodings 3180 3181 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3182 MacroAssembler _masm(&cbuf); 3183 Register reg1 = as_Register($src1$$reg); 3184 Register reg2 = as_Register($src2$$reg); 3185 __ cmpw(reg1, reg2); 3186 %} 3187 3188 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3189 MacroAssembler _masm(&cbuf); 3190 Register reg = as_Register($src1$$reg); 3191 int32_t val = $src2$$constant; 3192 if (val >= 0) { 3193 __ subsw(zr, reg, val); 3194 } else { 3195 __ addsw(zr, reg, -val); 3196 } 3197 %} 3198 3199 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3200 MacroAssembler _masm(&cbuf); 3201 Register reg1 = as_Register($src1$$reg); 3202 u_int32_t val = (u_int32_t)$src2$$constant; 3203 __ movw(rscratch1, val); 3204 __ cmpw(reg1, rscratch1); 3205 %} 3206 3207 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3208 MacroAssembler _masm(&cbuf); 3209 Register reg1 = as_Register($src1$$reg); 3210 Register reg2 = as_Register($src2$$reg); 3211 __ cmp(reg1, reg2); 3212 %} 3213 3214 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3215 MacroAssembler _masm(&cbuf); 3216 Register reg = as_Register($src1$$reg); 3217 int64_t val = $src2$$constant; 3218 if (val >= 0) { 3219 __ subs(zr, reg, val); 3220 } else if (val != -val) { 3221 __ adds(zr, reg, -val); 3222 } else { 3223 // aargh, Long.MIN_VALUE is a special case 3224 __ orr(rscratch1, zr, (u_int64_t)val); 3225 __ subs(zr, reg, rscratch1); 3226 } 3227 %} 3228 3229 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3230 MacroAssembler _masm(&cbuf); 3231 Register reg1 = as_Register($src1$$reg); 3232 u_int64_t val = (u_int64_t)$src2$$constant; 3233 __ mov(rscratch1, val); 3234 __ cmp(reg1, rscratch1); 3235 %} 3236 3237 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3238 MacroAssembler _masm(&cbuf); 3239 Register reg1 = as_Register($src1$$reg); 3240 Register reg2 = as_Register($src2$$reg); 3241 __ cmp(reg1, reg2); 3242 %} 3243 3244 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3245 MacroAssembler _masm(&cbuf); 3246 Register reg1 = as_Register($src1$$reg); 3247 Register reg2 = as_Register($src2$$reg); 3248 __ cmpw(reg1, reg2); 3249 %} 3250 3251 enc_class aarch64_enc_testp(iRegP src) %{ 3252 MacroAssembler _masm(&cbuf); 3253 Register reg = as_Register($src$$reg); 3254 __ cmp(reg, zr); 3255 %} 3256 3257 enc_class aarch64_enc_testn(iRegN src) %{ 3258 MacroAssembler _masm(&cbuf); 3259 Register reg = as_Register($src$$reg); 3260 __ cmpw(reg, zr); 3261 %} 3262 3263 enc_class aarch64_enc_b(label lbl) %{ 3264 MacroAssembler _masm(&cbuf); 3265 Label *L = $lbl$$label; 3266 __ b(*L); 3267 %} 3268 3269 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3270 MacroAssembler _masm(&cbuf); 3271 Label *L = $lbl$$label; 3272 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3273 %} 3274 3275 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3276 MacroAssembler _masm(&cbuf); 3277 Label *L = $lbl$$label; 3278 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3279 %} 3280 3281 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3282 %{ 3283 Register sub_reg = as_Register($sub$$reg); 3284 Register super_reg = as_Register($super$$reg); 3285 Register temp_reg = as_Register($temp$$reg); 3286 Register result_reg = as_Register($result$$reg); 3287 3288 Label miss; 3289 MacroAssembler _masm(&cbuf); 3290 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3291 NULL, &miss, 3292 /*set_cond_codes:*/ true); 3293 if ($primary) { 3294 __ mov(result_reg, zr); 3295 } 3296 __ bind(miss); 3297 %} 3298 3299 enc_class aarch64_enc_java_static_call(method meth) %{ 3300 MacroAssembler _masm(&cbuf); 3301 3302 address addr = (address)$meth$$method; 3303 address call; 3304 if (!_method) { 3305 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3306 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3307 } else { 3308 int method_index = resolved_method_index(cbuf); 3309 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3310 : static_call_Relocation::spec(method_index); 3311 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3312 3313 // Emit stub for static call 3314 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3315 if (stub == NULL) { 3316 ciEnv::current()->record_failure("CodeCache is full"); 3317 return; 3318 } 3319 } 3320 if (call == NULL) { 3321 ciEnv::current()->record_failure("CodeCache is full"); 3322 return; 3323 } 3324 %} 3325 3326 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3327 MacroAssembler _masm(&cbuf); 3328 int method_index = resolved_method_index(cbuf); 3329 address call = __ ic_call((address)$meth$$method, method_index); 3330 if (call == NULL) { 3331 ciEnv::current()->record_failure("CodeCache is full"); 3332 return; 3333 } 3334 %} 3335 3336 enc_class aarch64_enc_call_epilog() %{ 3337 MacroAssembler _masm(&cbuf); 3338 if (VerifyStackAtCalls) { 3339 // Check that stack depth is unchanged: find majik cookie on stack 3340 __ call_Unimplemented(); 3341 } 3342 %} 3343 3344 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3345 MacroAssembler _masm(&cbuf); 3346 3347 // some calls to generated routines (arraycopy code) are scheduled 3348 // by C2 as runtime calls. if so we can call them using a br (they 3349 // will be in a reachable segment) otherwise we have to use a blrt 3350 // which loads the absolute address into a register. 3351 address entry = (address)$meth$$method; 3352 CodeBlob *cb = CodeCache::find_blob(entry); 3353 if (cb) { 3354 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3355 if (call == NULL) { 3356 ciEnv::current()->record_failure("CodeCache is full"); 3357 return; 3358 } 3359 } else { 3360 int gpcnt; 3361 int fpcnt; 3362 int rtype; 3363 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3364 Label retaddr; 3365 __ adr(rscratch2, retaddr); 3366 __ lea(rscratch1, RuntimeAddress(entry)); 3367 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3368 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3369 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3370 __ bind(retaddr); 3371 __ add(sp, sp, 2 * wordSize); 3372 } 3373 %} 3374 3375 enc_class aarch64_enc_rethrow() %{ 3376 MacroAssembler _masm(&cbuf); 3377 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3378 %} 3379 3380 enc_class aarch64_enc_ret() %{ 3381 MacroAssembler _masm(&cbuf); 3382 __ ret(lr); 3383 %} 3384 3385 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3386 MacroAssembler _masm(&cbuf); 3387 Register target_reg = as_Register($jump_target$$reg); 3388 __ br(target_reg); 3389 %} 3390 3391 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3392 MacroAssembler _masm(&cbuf); 3393 Register target_reg = as_Register($jump_target$$reg); 3394 // exception oop should be in r0 3395 // ret addr has been popped into lr 3396 // callee expects it in r3 3397 __ mov(r3, lr); 3398 __ br(target_reg); 3399 %} 3400 3401 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3402 MacroAssembler _masm(&cbuf); 3403 Register oop = as_Register($object$$reg); 3404 Register box = as_Register($box$$reg); 3405 Register disp_hdr = as_Register($tmp$$reg); 3406 Register tmp = as_Register($tmp2$$reg); 3407 Label cont; 3408 Label object_has_monitor; 3409 Label cas_failed; 3410 3411 assert_different_registers(oop, box, tmp, disp_hdr); 3412 3413 // Load markOop from object into displaced_header. 3414 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3415 3416 if (UseBiasedLocking && !UseOptoBiasInlining) { 3417 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3418 } 3419 3420 // Handle existing monitor 3421 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3422 3423 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3424 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3425 3426 // Load Compare Value application register. 3427 3428 // Initialize the box. (Must happen before we update the object mark!) 3429 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3430 3431 // Compare object markOop with mark and if equal exchange scratch1 3432 // with object markOop. 3433 if (UseLSE) { 3434 __ mov(tmp, disp_hdr); 3435 __ casal(Assembler::xword, tmp, box, oop); 3436 __ cmp(tmp, disp_hdr); 3437 __ br(Assembler::EQ, cont); 3438 } else { 3439 Label retry_load; 3440 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3441 __ prfm(Address(oop), PSTL1STRM); 3442 __ bind(retry_load); 3443 __ ldaxr(tmp, oop); 3444 __ cmp(tmp, disp_hdr); 3445 __ br(Assembler::NE, cas_failed); 3446 // use stlxr to ensure update is immediately visible 3447 __ stlxr(tmp, box, oop); 3448 __ cbzw(tmp, cont); 3449 __ b(retry_load); 3450 } 3451 3452 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3453 3454 // If the compare-and-exchange succeeded, then we found an unlocked 3455 // object, will have now locked it will continue at label cont 3456 3457 __ bind(cas_failed); 3458 // We did not see an unlocked object so try the fast recursive case. 3459 3460 // Check if the owner is self by comparing the value in the 3461 // markOop of object (disp_hdr) with the stack pointer. 3462 __ mov(rscratch1, sp); 3463 __ sub(disp_hdr, disp_hdr, rscratch1); 3464 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3465 // If condition is true we are cont and hence we can store 0 as the 3466 // displaced header in the box, which indicates that it is a recursive lock. 3467 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3468 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3469 3470 // Handle existing monitor. 3471 __ b(cont); 3472 3473 __ bind(object_has_monitor); 3474 // The object's monitor m is unlocked iff m->owner == NULL, 3475 // otherwise m->owner may contain a thread or a stack address. 3476 // 3477 // Try to CAS m->owner from NULL to current thread. 3478 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3479 __ mov(disp_hdr, zr); 3480 3481 if (UseLSE) { 3482 __ mov(rscratch1, disp_hdr); 3483 __ casal(Assembler::xword, rscratch1, rthread, tmp); 3484 __ cmp(rscratch1, disp_hdr); 3485 } else { 3486 Label retry_load, fail; 3487 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) { 3488 __ prfm(Address(tmp), PSTL1STRM); 3489 } 3490 __ bind(retry_load); 3491 __ ldaxr(rscratch1, tmp); 3492 __ cmp(disp_hdr, rscratch1); 3493 __ br(Assembler::NE, fail); 3494 // use stlxr to ensure update is immediately visible 3495 __ stlxr(rscratch1, rthread, tmp); 3496 __ cbnzw(rscratch1, retry_load); 3497 __ bind(fail); 3498 } 3499 3500 // Store a non-null value into the box to avoid looking like a re-entrant 3501 // lock. The fast-path monitor unlock code checks for 3502 // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the 3503 // relevant bit set, and also matches ObjectSynchronizer::slow_enter. 3504 __ mov(tmp, (address)markOopDesc::unused_mark()); 3505 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3506 3507 __ bind(cont); 3508 // flag == EQ indicates success 3509 // flag == NE indicates failure 3510 %} 3511 3512 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3513 MacroAssembler _masm(&cbuf); 3514 Register oop = as_Register($object$$reg); 3515 Register box = as_Register($box$$reg); 3516 Register disp_hdr = as_Register($tmp$$reg); 3517 Register tmp = as_Register($tmp2$$reg); 3518 Label cont; 3519 Label object_has_monitor; 3520 3521 assert_different_registers(oop, box, tmp, disp_hdr); 3522 3523 if (UseBiasedLocking && !UseOptoBiasInlining) { 3524 __ biased_locking_exit(oop, tmp, cont); 3525 } 3526 3527 // Find the lock address and load the displaced header from the stack. 3528 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3529 3530 // If the displaced header is 0, we have a recursive unlock. 3531 __ cmp(disp_hdr, zr); 3532 __ br(Assembler::EQ, cont); 3533 3534 // Handle existing monitor. 3535 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3536 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3537 3538 // Check if it is still a light weight lock, this is is true if we 3539 // see the stack address of the basicLock in the markOop of the 3540 // object. 3541 3542 if (UseLSE) { 3543 __ mov(tmp, box); 3544 __ casl(Assembler::xword, tmp, disp_hdr, oop); 3545 __ cmp(tmp, box); 3546 __ b(cont); 3547 } else { 3548 Label retry_load; 3549 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3550 __ prfm(Address(oop), PSTL1STRM); 3551 __ bind(retry_load); 3552 __ ldxr(tmp, oop); 3553 __ cmp(box, tmp); 3554 __ br(Assembler::NE, cont); 3555 // use stlxr to ensure update is immediately visible 3556 __ stlxr(tmp, disp_hdr, oop); 3557 __ cbzw(tmp, cont); 3558 __ b(retry_load); 3559 } 3560 3561 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3562 3563 // Handle existing monitor. 3564 __ bind(object_has_monitor); 3565 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3566 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3567 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3568 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3569 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3570 __ cmp(rscratch1, zr); 3571 __ br(Assembler::NE, cont); 3572 3573 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3574 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3575 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3576 __ cmp(rscratch1, zr); 3577 __ cbnz(rscratch1, cont); 3578 // need a release store here 3579 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3580 __ stlr(zr, tmp); // set unowned 3581 3582 __ bind(cont); 3583 // flag == EQ indicates success 3584 // flag == NE indicates failure 3585 %} 3586 3587 %} 3588 3589 //----------FRAME-------------------------------------------------------------- 3590 // Definition of frame structure and management information. 3591 // 3592 // S T A C K L A Y O U T Allocators stack-slot number 3593 // | (to get allocators register number 3594 // G Owned by | | v add OptoReg::stack0()) 3595 // r CALLER | | 3596 // o | +--------+ pad to even-align allocators stack-slot 3597 // w V | pad0 | numbers; owned by CALLER 3598 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3599 // h ^ | in | 5 3600 // | | args | 4 Holes in incoming args owned by SELF 3601 // | | | | 3 3602 // | | +--------+ 3603 // V | | old out| Empty on Intel, window on Sparc 3604 // | old |preserve| Must be even aligned. 3605 // | SP-+--------+----> Matcher::_old_SP, even aligned 3606 // | | in | 3 area for Intel ret address 3607 // Owned by |preserve| Empty on Sparc. 3608 // SELF +--------+ 3609 // | | pad2 | 2 pad to align old SP 3610 // | +--------+ 1 3611 // | | locks | 0 3612 // | +--------+----> OptoReg::stack0(), even aligned 3613 // | | pad1 | 11 pad to align new SP 3614 // | +--------+ 3615 // | | | 10 3616 // | | spills | 9 spills 3617 // V | | 8 (pad0 slot for callee) 3618 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3619 // ^ | out | 7 3620 // | | args | 6 Holes in outgoing args owned by CALLEE 3621 // Owned by +--------+ 3622 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3623 // | new |preserve| Must be even-aligned. 3624 // | SP-+--------+----> Matcher::_new_SP, even aligned 3625 // | | | 3626 // 3627 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3628 // known from SELF's arguments and the Java calling convention. 3629 // Region 6-7 is determined per call site. 3630 // Note 2: If the calling convention leaves holes in the incoming argument 3631 // area, those holes are owned by SELF. Holes in the outgoing area 3632 // are owned by the CALLEE. Holes should not be nessecary in the 3633 // incoming area, as the Java calling convention is completely under 3634 // the control of the AD file. Doubles can be sorted and packed to 3635 // avoid holes. Holes in the outgoing arguments may be nessecary for 3636 // varargs C calling conventions. 3637 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3638 // even aligned with pad0 as needed. 3639 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3640 // (the latter is true on Intel but is it false on AArch64?) 3641 // region 6-11 is even aligned; it may be padded out more so that 3642 // the region from SP to FP meets the minimum stack alignment. 3643 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3644 // alignment. Region 11, pad1, may be dynamically extended so that 3645 // SP meets the minimum alignment. 3646 3647 frame %{ 3648 // What direction does stack grow in (assumed to be same for C & Java) 3649 stack_direction(TOWARDS_LOW); 3650 3651 // These three registers define part of the calling convention 3652 // between compiled code and the interpreter. 3653 3654 // Inline Cache Register or methodOop for I2C. 3655 inline_cache_reg(R12); 3656 3657 // Method Oop Register when calling interpreter. 3658 interpreter_method_oop_reg(R12); 3659 3660 // Number of stack slots consumed by locking an object 3661 sync_stack_slots(2); 3662 3663 // Compiled code's Frame Pointer 3664 frame_pointer(R31); 3665 3666 // Interpreter stores its frame pointer in a register which is 3667 // stored to the stack by I2CAdaptors. 3668 // I2CAdaptors convert from interpreted java to compiled java. 3669 interpreter_frame_pointer(R29); 3670 3671 // Stack alignment requirement 3672 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3673 3674 // Number of stack slots between incoming argument block and the start of 3675 // a new frame. The PROLOG must add this many slots to the stack. The 3676 // EPILOG must remove this many slots. aarch64 needs two slots for 3677 // return address and fp. 3678 // TODO think this is correct but check 3679 in_preserve_stack_slots(4); 3680 3681 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3682 // for calls to C. Supports the var-args backing area for register parms. 3683 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3684 3685 // The after-PROLOG location of the return address. Location of 3686 // return address specifies a type (REG or STACK) and a number 3687 // representing the register number (i.e. - use a register name) or 3688 // stack slot. 3689 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3690 // Otherwise, it is above the locks and verification slot and alignment word 3691 // TODO this may well be correct but need to check why that - 2 is there 3692 // ppc port uses 0 but we definitely need to allow for fixed_slots 3693 // which folds in the space used for monitors 3694 return_addr(STACK - 2 + 3695 align_up((Compile::current()->in_preserve_stack_slots() + 3696 Compile::current()->fixed_slots()), 3697 stack_alignment_in_slots())); 3698 3699 // Body of function which returns an integer array locating 3700 // arguments either in registers or in stack slots. Passed an array 3701 // of ideal registers called "sig" and a "length" count. Stack-slot 3702 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3703 // arguments for a CALLEE. Incoming stack arguments are 3704 // automatically biased by the preserve_stack_slots field above. 3705 3706 calling_convention 3707 %{ 3708 // No difference between ingoing/outgoing just pass false 3709 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3710 %} 3711 3712 c_calling_convention 3713 %{ 3714 // This is obviously always outgoing 3715 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3716 %} 3717 3718 // Location of compiled Java return values. Same as C for now. 3719 return_value 3720 %{ 3721 // TODO do we allow ideal_reg == Op_RegN??? 3722 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3723 "only return normal values"); 3724 3725 static const int lo[Op_RegL + 1] = { // enum name 3726 0, // Op_Node 3727 0, // Op_Set 3728 R0_num, // Op_RegN 3729 R0_num, // Op_RegI 3730 R0_num, // Op_RegP 3731 V0_num, // Op_RegF 3732 V0_num, // Op_RegD 3733 R0_num // Op_RegL 3734 }; 3735 3736 static const int hi[Op_RegL + 1] = { // enum name 3737 0, // Op_Node 3738 0, // Op_Set 3739 OptoReg::Bad, // Op_RegN 3740 OptoReg::Bad, // Op_RegI 3741 R0_H_num, // Op_RegP 3742 OptoReg::Bad, // Op_RegF 3743 V0_H_num, // Op_RegD 3744 R0_H_num // Op_RegL 3745 }; 3746 3747 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3748 %} 3749 %} 3750 3751 //----------ATTRIBUTES--------------------------------------------------------- 3752 //----------Operand Attributes------------------------------------------------- 3753 op_attrib op_cost(1); // Required cost attribute 3754 3755 //----------Instruction Attributes--------------------------------------------- 3756 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3757 ins_attrib ins_size(32); // Required size attribute (in bits) 3758 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3759 // a non-matching short branch variant 3760 // of some long branch? 3761 ins_attrib ins_alignment(4); // Required alignment attribute (must 3762 // be a power of 2) specifies the 3763 // alignment that some part of the 3764 // instruction (not necessarily the 3765 // start) requires. If > 1, a 3766 // compute_padding() function must be 3767 // provided for the instruction 3768 3769 //----------OPERANDS----------------------------------------------------------- 3770 // Operand definitions must precede instruction definitions for correct parsing 3771 // in the ADLC because operands constitute user defined types which are used in 3772 // instruction definitions. 3773 3774 //----------Simple Operands---------------------------------------------------- 3775 3776 // Integer operands 32 bit 3777 // 32 bit immediate 3778 operand immI() 3779 %{ 3780 match(ConI); 3781 3782 op_cost(0); 3783 format %{ %} 3784 interface(CONST_INTER); 3785 %} 3786 3787 // 32 bit zero 3788 operand immI0() 3789 %{ 3790 predicate(n->get_int() == 0); 3791 match(ConI); 3792 3793 op_cost(0); 3794 format %{ %} 3795 interface(CONST_INTER); 3796 %} 3797 3798 // 32 bit unit increment 3799 operand immI_1() 3800 %{ 3801 predicate(n->get_int() == 1); 3802 match(ConI); 3803 3804 op_cost(0); 3805 format %{ %} 3806 interface(CONST_INTER); 3807 %} 3808 3809 // 32 bit unit decrement 3810 operand immI_M1() 3811 %{ 3812 predicate(n->get_int() == -1); 3813 match(ConI); 3814 3815 op_cost(0); 3816 format %{ %} 3817 interface(CONST_INTER); 3818 %} 3819 3820 // Shift values for add/sub extension shift 3821 operand immIExt() 3822 %{ 3823 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3824 match(ConI); 3825 3826 op_cost(0); 3827 format %{ %} 3828 interface(CONST_INTER); 3829 %} 3830 3831 operand immI_le_4() 3832 %{ 3833 predicate(n->get_int() <= 4); 3834 match(ConI); 3835 3836 op_cost(0); 3837 format %{ %} 3838 interface(CONST_INTER); 3839 %} 3840 3841 operand immI_31() 3842 %{ 3843 predicate(n->get_int() == 31); 3844 match(ConI); 3845 3846 op_cost(0); 3847 format %{ %} 3848 interface(CONST_INTER); 3849 %} 3850 3851 operand immI_8() 3852 %{ 3853 predicate(n->get_int() == 8); 3854 match(ConI); 3855 3856 op_cost(0); 3857 format %{ %} 3858 interface(CONST_INTER); 3859 %} 3860 3861 operand immI_16() 3862 %{ 3863 predicate(n->get_int() == 16); 3864 match(ConI); 3865 3866 op_cost(0); 3867 format %{ %} 3868 interface(CONST_INTER); 3869 %} 3870 3871 operand immI_24() 3872 %{ 3873 predicate(n->get_int() == 24); 3874 match(ConI); 3875 3876 op_cost(0); 3877 format %{ %} 3878 interface(CONST_INTER); 3879 %} 3880 3881 operand immI_32() 3882 %{ 3883 predicate(n->get_int() == 32); 3884 match(ConI); 3885 3886 op_cost(0); 3887 format %{ %} 3888 interface(CONST_INTER); 3889 %} 3890 3891 operand immI_48() 3892 %{ 3893 predicate(n->get_int() == 48); 3894 match(ConI); 3895 3896 op_cost(0); 3897 format %{ %} 3898 interface(CONST_INTER); 3899 %} 3900 3901 operand immI_56() 3902 %{ 3903 predicate(n->get_int() == 56); 3904 match(ConI); 3905 3906 op_cost(0); 3907 format %{ %} 3908 interface(CONST_INTER); 3909 %} 3910 3911 operand immI_63() 3912 %{ 3913 predicate(n->get_int() == 63); 3914 match(ConI); 3915 3916 op_cost(0); 3917 format %{ %} 3918 interface(CONST_INTER); 3919 %} 3920 3921 operand immI_64() 3922 %{ 3923 predicate(n->get_int() == 64); 3924 match(ConI); 3925 3926 op_cost(0); 3927 format %{ %} 3928 interface(CONST_INTER); 3929 %} 3930 3931 operand immI_255() 3932 %{ 3933 predicate(n->get_int() == 255); 3934 match(ConI); 3935 3936 op_cost(0); 3937 format %{ %} 3938 interface(CONST_INTER); 3939 %} 3940 3941 operand immI_65535() 3942 %{ 3943 predicate(n->get_int() == 65535); 3944 match(ConI); 3945 3946 op_cost(0); 3947 format %{ %} 3948 interface(CONST_INTER); 3949 %} 3950 3951 operand immL_255() 3952 %{ 3953 predicate(n->get_long() == 255L); 3954 match(ConL); 3955 3956 op_cost(0); 3957 format %{ %} 3958 interface(CONST_INTER); 3959 %} 3960 3961 operand immL_65535() 3962 %{ 3963 predicate(n->get_long() == 65535L); 3964 match(ConL); 3965 3966 op_cost(0); 3967 format %{ %} 3968 interface(CONST_INTER); 3969 %} 3970 3971 operand immL_4294967295() 3972 %{ 3973 predicate(n->get_long() == 4294967295L); 3974 match(ConL); 3975 3976 op_cost(0); 3977 format %{ %} 3978 interface(CONST_INTER); 3979 %} 3980 3981 operand immL_bitmask() 3982 %{ 3983 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3984 && is_power_of_2(n->get_long() + 1)); 3985 match(ConL); 3986 3987 op_cost(0); 3988 format %{ %} 3989 interface(CONST_INTER); 3990 %} 3991 3992 operand immI_bitmask() 3993 %{ 3994 predicate(((n->get_int() & 0xc0000000) == 0) 3995 && is_power_of_2(n->get_int() + 1)); 3996 match(ConI); 3997 3998 op_cost(0); 3999 format %{ %} 4000 interface(CONST_INTER); 4001 %} 4002 4003 // Scale values for scaled offset addressing modes (up to long but not quad) 4004 operand immIScale() 4005 %{ 4006 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4007 match(ConI); 4008 4009 op_cost(0); 4010 format %{ %} 4011 interface(CONST_INTER); 4012 %} 4013 4014 // 26 bit signed offset -- for pc-relative branches 4015 operand immI26() 4016 %{ 4017 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4018 match(ConI); 4019 4020 op_cost(0); 4021 format %{ %} 4022 interface(CONST_INTER); 4023 %} 4024 4025 // 19 bit signed offset -- for pc-relative loads 4026 operand immI19() 4027 %{ 4028 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4029 match(ConI); 4030 4031 op_cost(0); 4032 format %{ %} 4033 interface(CONST_INTER); 4034 %} 4035 4036 // 12 bit unsigned offset -- for base plus immediate loads 4037 operand immIU12() 4038 %{ 4039 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4040 match(ConI); 4041 4042 op_cost(0); 4043 format %{ %} 4044 interface(CONST_INTER); 4045 %} 4046 4047 operand immLU12() 4048 %{ 4049 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4050 match(ConL); 4051 4052 op_cost(0); 4053 format %{ %} 4054 interface(CONST_INTER); 4055 %} 4056 4057 // Offset for scaled or unscaled immediate loads and stores 4058 operand immIOffset() 4059 %{ 4060 predicate(Address::offset_ok_for_immed(n->get_int())); 4061 match(ConI); 4062 4063 op_cost(0); 4064 format %{ %} 4065 interface(CONST_INTER); 4066 %} 4067 4068 operand immIOffset4() 4069 %{ 4070 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4071 match(ConI); 4072 4073 op_cost(0); 4074 format %{ %} 4075 interface(CONST_INTER); 4076 %} 4077 4078 operand immIOffset8() 4079 %{ 4080 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4081 match(ConI); 4082 4083 op_cost(0); 4084 format %{ %} 4085 interface(CONST_INTER); 4086 %} 4087 4088 operand immIOffset16() 4089 %{ 4090 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4091 match(ConI); 4092 4093 op_cost(0); 4094 format %{ %} 4095 interface(CONST_INTER); 4096 %} 4097 4098 operand immLoffset() 4099 %{ 4100 predicate(Address::offset_ok_for_immed(n->get_long())); 4101 match(ConL); 4102 4103 op_cost(0); 4104 format %{ %} 4105 interface(CONST_INTER); 4106 %} 4107 4108 operand immLoffset4() 4109 %{ 4110 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4111 match(ConL); 4112 4113 op_cost(0); 4114 format %{ %} 4115 interface(CONST_INTER); 4116 %} 4117 4118 operand immLoffset8() 4119 %{ 4120 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4121 match(ConL); 4122 4123 op_cost(0); 4124 format %{ %} 4125 interface(CONST_INTER); 4126 %} 4127 4128 operand immLoffset16() 4129 %{ 4130 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4131 match(ConL); 4132 4133 op_cost(0); 4134 format %{ %} 4135 interface(CONST_INTER); 4136 %} 4137 4138 // 32 bit integer valid for add sub immediate 4139 operand immIAddSub() 4140 %{ 4141 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4142 match(ConI); 4143 op_cost(0); 4144 format %{ %} 4145 interface(CONST_INTER); 4146 %} 4147 4148 // 32 bit unsigned integer valid for logical immediate 4149 // TODO -- check this is right when e.g the mask is 0x80000000 4150 operand immILog() 4151 %{ 4152 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4153 match(ConI); 4154 4155 op_cost(0); 4156 format %{ %} 4157 interface(CONST_INTER); 4158 %} 4159 4160 // Integer operands 64 bit 4161 // 64 bit immediate 4162 operand immL() 4163 %{ 4164 match(ConL); 4165 4166 op_cost(0); 4167 format %{ %} 4168 interface(CONST_INTER); 4169 %} 4170 4171 // 64 bit zero 4172 operand immL0() 4173 %{ 4174 predicate(n->get_long() == 0); 4175 match(ConL); 4176 4177 op_cost(0); 4178 format %{ %} 4179 interface(CONST_INTER); 4180 %} 4181 4182 // 64 bit unit increment 4183 operand immL_1() 4184 %{ 4185 predicate(n->get_long() == 1); 4186 match(ConL); 4187 4188 op_cost(0); 4189 format %{ %} 4190 interface(CONST_INTER); 4191 %} 4192 4193 // 64 bit unit decrement 4194 operand immL_M1() 4195 %{ 4196 predicate(n->get_long() == -1); 4197 match(ConL); 4198 4199 op_cost(0); 4200 format %{ %} 4201 interface(CONST_INTER); 4202 %} 4203 4204 // 32 bit offset of pc in thread anchor 4205 4206 operand immL_pc_off() 4207 %{ 4208 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4209 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4210 match(ConL); 4211 4212 op_cost(0); 4213 format %{ %} 4214 interface(CONST_INTER); 4215 %} 4216 4217 // 64 bit integer valid for add sub immediate 4218 operand immLAddSub() 4219 %{ 4220 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4221 match(ConL); 4222 op_cost(0); 4223 format %{ %} 4224 interface(CONST_INTER); 4225 %} 4226 4227 // 64 bit integer valid for logical immediate 4228 operand immLLog() 4229 %{ 4230 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4231 match(ConL); 4232 op_cost(0); 4233 format %{ %} 4234 interface(CONST_INTER); 4235 %} 4236 4237 // Long Immediate: low 32-bit mask 4238 operand immL_32bits() 4239 %{ 4240 predicate(n->get_long() == 0xFFFFFFFFL); 4241 match(ConL); 4242 op_cost(0); 4243 format %{ %} 4244 interface(CONST_INTER); 4245 %} 4246 4247 // Pointer operands 4248 // Pointer Immediate 4249 operand immP() 4250 %{ 4251 match(ConP); 4252 4253 op_cost(0); 4254 format %{ %} 4255 interface(CONST_INTER); 4256 %} 4257 4258 // NULL Pointer Immediate 4259 operand immP0() 4260 %{ 4261 predicate(n->get_ptr() == 0); 4262 match(ConP); 4263 4264 op_cost(0); 4265 format %{ %} 4266 interface(CONST_INTER); 4267 %} 4268 4269 // Pointer Immediate One 4270 // this is used in object initialization (initial object header) 4271 operand immP_1() 4272 %{ 4273 predicate(n->get_ptr() == 1); 4274 match(ConP); 4275 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // Polling Page Pointer Immediate 4282 operand immPollPage() 4283 %{ 4284 predicate((address)n->get_ptr() == os::get_polling_page()); 4285 match(ConP); 4286 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 // Card Table Byte Map Base 4293 operand immByteMapBase() 4294 %{ 4295 // Get base of card map 4296 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4297 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4298 match(ConP); 4299 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 // Pointer Immediate Minus One 4306 // this is used when we want to write the current PC to the thread anchor 4307 operand immP_M1() 4308 %{ 4309 predicate(n->get_ptr() == -1); 4310 match(ConP); 4311 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // Pointer Immediate Minus Two 4318 // this is used when we want to write the current PC to the thread anchor 4319 operand immP_M2() 4320 %{ 4321 predicate(n->get_ptr() == -2); 4322 match(ConP); 4323 4324 op_cost(0); 4325 format %{ %} 4326 interface(CONST_INTER); 4327 %} 4328 4329 // Float and Double operands 4330 // Double Immediate 4331 operand immD() 4332 %{ 4333 match(ConD); 4334 op_cost(0); 4335 format %{ %} 4336 interface(CONST_INTER); 4337 %} 4338 4339 // Double Immediate: +0.0d 4340 operand immD0() 4341 %{ 4342 predicate(jlong_cast(n->getd()) == 0); 4343 match(ConD); 4344 4345 op_cost(0); 4346 format %{ %} 4347 interface(CONST_INTER); 4348 %} 4349 4350 // constant 'double +0.0'. 4351 operand immDPacked() 4352 %{ 4353 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4354 match(ConD); 4355 op_cost(0); 4356 format %{ %} 4357 interface(CONST_INTER); 4358 %} 4359 4360 // Float Immediate 4361 operand immF() 4362 %{ 4363 match(ConF); 4364 op_cost(0); 4365 format %{ %} 4366 interface(CONST_INTER); 4367 %} 4368 4369 // Float Immediate: +0.0f. 4370 operand immF0() 4371 %{ 4372 predicate(jint_cast(n->getf()) == 0); 4373 match(ConF); 4374 4375 op_cost(0); 4376 format %{ %} 4377 interface(CONST_INTER); 4378 %} 4379 4380 // 4381 operand immFPacked() 4382 %{ 4383 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4384 match(ConF); 4385 op_cost(0); 4386 format %{ %} 4387 interface(CONST_INTER); 4388 %} 4389 4390 // Narrow pointer operands 4391 // Narrow Pointer Immediate 4392 operand immN() 4393 %{ 4394 match(ConN); 4395 4396 op_cost(0); 4397 format %{ %} 4398 interface(CONST_INTER); 4399 %} 4400 4401 // Narrow NULL Pointer Immediate 4402 operand immN0() 4403 %{ 4404 predicate(n->get_narrowcon() == 0); 4405 match(ConN); 4406 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410 %} 4411 4412 operand immNKlass() 4413 %{ 4414 match(ConNKlass); 4415 4416 op_cost(0); 4417 format %{ %} 4418 interface(CONST_INTER); 4419 %} 4420 4421 // Integer 32 bit Register Operands 4422 // Integer 32 bitRegister (excludes SP) 4423 operand iRegI() 4424 %{ 4425 constraint(ALLOC_IN_RC(any_reg32)); 4426 match(RegI); 4427 match(iRegINoSp); 4428 op_cost(0); 4429 format %{ %} 4430 interface(REG_INTER); 4431 %} 4432 4433 // Integer 32 bit Register not Special 4434 operand iRegINoSp() 4435 %{ 4436 constraint(ALLOC_IN_RC(no_special_reg32)); 4437 match(RegI); 4438 op_cost(0); 4439 format %{ %} 4440 interface(REG_INTER); 4441 %} 4442 4443 // Integer 64 bit Register Operands 4444 // Integer 64 bit Register (includes SP) 4445 operand iRegL() 4446 %{ 4447 constraint(ALLOC_IN_RC(any_reg)); 4448 match(RegL); 4449 match(iRegLNoSp); 4450 op_cost(0); 4451 format %{ %} 4452 interface(REG_INTER); 4453 %} 4454 4455 // Integer 64 bit Register not Special 4456 operand iRegLNoSp() 4457 %{ 4458 constraint(ALLOC_IN_RC(no_special_reg)); 4459 match(RegL); 4460 match(iRegL_R0); 4461 format %{ %} 4462 interface(REG_INTER); 4463 %} 4464 4465 // Pointer Register Operands 4466 // Pointer Register 4467 operand iRegP() 4468 %{ 4469 constraint(ALLOC_IN_RC(ptr_reg)); 4470 match(RegP); 4471 match(iRegPNoSp); 4472 match(iRegP_R0); 4473 //match(iRegP_R2); 4474 //match(iRegP_R4); 4475 //match(iRegP_R5); 4476 match(thread_RegP); 4477 op_cost(0); 4478 format %{ %} 4479 interface(REG_INTER); 4480 %} 4481 4482 // Pointer 64 bit Register not Special 4483 operand iRegPNoSp() 4484 %{ 4485 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4486 match(RegP); 4487 // match(iRegP); 4488 // match(iRegP_R0); 4489 // match(iRegP_R2); 4490 // match(iRegP_R4); 4491 // match(iRegP_R5); 4492 // match(thread_RegP); 4493 op_cost(0); 4494 format %{ %} 4495 interface(REG_INTER); 4496 %} 4497 4498 // Pointer 64 bit Register R0 only 4499 operand iRegP_R0() 4500 %{ 4501 constraint(ALLOC_IN_RC(r0_reg)); 4502 match(RegP); 4503 // match(iRegP); 4504 match(iRegPNoSp); 4505 op_cost(0); 4506 format %{ %} 4507 interface(REG_INTER); 4508 %} 4509 4510 // Pointer 64 bit Register R1 only 4511 operand iRegP_R1() 4512 %{ 4513 constraint(ALLOC_IN_RC(r1_reg)); 4514 match(RegP); 4515 // match(iRegP); 4516 match(iRegPNoSp); 4517 op_cost(0); 4518 format %{ %} 4519 interface(REG_INTER); 4520 %} 4521 4522 // Pointer 64 bit Register R2 only 4523 operand iRegP_R2() 4524 %{ 4525 constraint(ALLOC_IN_RC(r2_reg)); 4526 match(RegP); 4527 // match(iRegP); 4528 match(iRegPNoSp); 4529 op_cost(0); 4530 format %{ %} 4531 interface(REG_INTER); 4532 %} 4533 4534 // Pointer 64 bit Register R3 only 4535 operand iRegP_R3() 4536 %{ 4537 constraint(ALLOC_IN_RC(r3_reg)); 4538 match(RegP); 4539 // match(iRegP); 4540 match(iRegPNoSp); 4541 op_cost(0); 4542 format %{ %} 4543 interface(REG_INTER); 4544 %} 4545 4546 // Pointer 64 bit Register R4 only 4547 operand iRegP_R4() 4548 %{ 4549 constraint(ALLOC_IN_RC(r4_reg)); 4550 match(RegP); 4551 // match(iRegP); 4552 match(iRegPNoSp); 4553 op_cost(0); 4554 format %{ %} 4555 interface(REG_INTER); 4556 %} 4557 4558 // Pointer 64 bit Register R5 only 4559 operand iRegP_R5() 4560 %{ 4561 constraint(ALLOC_IN_RC(r5_reg)); 4562 match(RegP); 4563 // match(iRegP); 4564 match(iRegPNoSp); 4565 op_cost(0); 4566 format %{ %} 4567 interface(REG_INTER); 4568 %} 4569 4570 // Pointer 64 bit Register R10 only 4571 operand iRegP_R10() 4572 %{ 4573 constraint(ALLOC_IN_RC(r10_reg)); 4574 match(RegP); 4575 // match(iRegP); 4576 match(iRegPNoSp); 4577 op_cost(0); 4578 format %{ %} 4579 interface(REG_INTER); 4580 %} 4581 4582 // Long 64 bit Register R0 only 4583 operand iRegL_R0() 4584 %{ 4585 constraint(ALLOC_IN_RC(r0_reg)); 4586 match(RegL); 4587 match(iRegLNoSp); 4588 op_cost(0); 4589 format %{ %} 4590 interface(REG_INTER); 4591 %} 4592 4593 // Long 64 bit Register R2 only 4594 operand iRegL_R2() 4595 %{ 4596 constraint(ALLOC_IN_RC(r2_reg)); 4597 match(RegL); 4598 match(iRegLNoSp); 4599 op_cost(0); 4600 format %{ %} 4601 interface(REG_INTER); 4602 %} 4603 4604 // Long 64 bit Register R3 only 4605 operand iRegL_R3() 4606 %{ 4607 constraint(ALLOC_IN_RC(r3_reg)); 4608 match(RegL); 4609 match(iRegLNoSp); 4610 op_cost(0); 4611 format %{ %} 4612 interface(REG_INTER); 4613 %} 4614 4615 // Long 64 bit Register R11 only 4616 operand iRegL_R11() 4617 %{ 4618 constraint(ALLOC_IN_RC(r11_reg)); 4619 match(RegL); 4620 match(iRegLNoSp); 4621 op_cost(0); 4622 format %{ %} 4623 interface(REG_INTER); 4624 %} 4625 4626 // Pointer 64 bit Register FP only 4627 operand iRegP_FP() 4628 %{ 4629 constraint(ALLOC_IN_RC(fp_reg)); 4630 match(RegP); 4631 // match(iRegP); 4632 op_cost(0); 4633 format %{ %} 4634 interface(REG_INTER); 4635 %} 4636 4637 // Register R0 only 4638 operand iRegI_R0() 4639 %{ 4640 constraint(ALLOC_IN_RC(int_r0_reg)); 4641 match(RegI); 4642 match(iRegINoSp); 4643 op_cost(0); 4644 format %{ %} 4645 interface(REG_INTER); 4646 %} 4647 4648 // Register R2 only 4649 operand iRegI_R2() 4650 %{ 4651 constraint(ALLOC_IN_RC(int_r2_reg)); 4652 match(RegI); 4653 match(iRegINoSp); 4654 op_cost(0); 4655 format %{ %} 4656 interface(REG_INTER); 4657 %} 4658 4659 // Register R3 only 4660 operand iRegI_R3() 4661 %{ 4662 constraint(ALLOC_IN_RC(int_r3_reg)); 4663 match(RegI); 4664 match(iRegINoSp); 4665 op_cost(0); 4666 format %{ %} 4667 interface(REG_INTER); 4668 %} 4669 4670 4671 // Register R4 only 4672 operand iRegI_R4() 4673 %{ 4674 constraint(ALLOC_IN_RC(int_r4_reg)); 4675 match(RegI); 4676 match(iRegINoSp); 4677 op_cost(0); 4678 format %{ %} 4679 interface(REG_INTER); 4680 %} 4681 4682 4683 // Pointer Register Operands 4684 // Narrow Pointer Register 4685 operand iRegN() 4686 %{ 4687 constraint(ALLOC_IN_RC(any_reg32)); 4688 match(RegN); 4689 match(iRegNNoSp); 4690 op_cost(0); 4691 format %{ %} 4692 interface(REG_INTER); 4693 %} 4694 4695 operand iRegN_R0() 4696 %{ 4697 constraint(ALLOC_IN_RC(r0_reg)); 4698 match(iRegN); 4699 op_cost(0); 4700 format %{ %} 4701 interface(REG_INTER); 4702 %} 4703 4704 operand iRegN_R2() 4705 %{ 4706 constraint(ALLOC_IN_RC(r2_reg)); 4707 match(iRegN); 4708 op_cost(0); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 operand iRegN_R3() 4714 %{ 4715 constraint(ALLOC_IN_RC(r3_reg)); 4716 match(iRegN); 4717 op_cost(0); 4718 format %{ %} 4719 interface(REG_INTER); 4720 %} 4721 4722 // Integer 64 bit Register not Special 4723 operand iRegNNoSp() 4724 %{ 4725 constraint(ALLOC_IN_RC(no_special_reg32)); 4726 match(RegN); 4727 op_cost(0); 4728 format %{ %} 4729 interface(REG_INTER); 4730 %} 4731 4732 // heap base register -- used for encoding immN0 4733 4734 operand iRegIHeapbase() 4735 %{ 4736 constraint(ALLOC_IN_RC(heapbase_reg)); 4737 match(RegI); 4738 op_cost(0); 4739 format %{ %} 4740 interface(REG_INTER); 4741 %} 4742 4743 // Float Register 4744 // Float register operands 4745 operand vRegF() 4746 %{ 4747 constraint(ALLOC_IN_RC(float_reg)); 4748 match(RegF); 4749 4750 op_cost(0); 4751 format %{ %} 4752 interface(REG_INTER); 4753 %} 4754 4755 // Double Register 4756 // Double register operands 4757 operand vRegD() 4758 %{ 4759 constraint(ALLOC_IN_RC(double_reg)); 4760 match(RegD); 4761 4762 op_cost(0); 4763 format %{ %} 4764 interface(REG_INTER); 4765 %} 4766 4767 operand vecD() 4768 %{ 4769 constraint(ALLOC_IN_RC(vectord_reg)); 4770 match(VecD); 4771 4772 op_cost(0); 4773 format %{ %} 4774 interface(REG_INTER); 4775 %} 4776 4777 operand vecX() 4778 %{ 4779 constraint(ALLOC_IN_RC(vectorx_reg)); 4780 match(VecX); 4781 4782 op_cost(0); 4783 format %{ %} 4784 interface(REG_INTER); 4785 %} 4786 4787 operand vRegD_V0() 4788 %{ 4789 constraint(ALLOC_IN_RC(v0_reg)); 4790 match(RegD); 4791 op_cost(0); 4792 format %{ %} 4793 interface(REG_INTER); 4794 %} 4795 4796 operand vRegD_V1() 4797 %{ 4798 constraint(ALLOC_IN_RC(v1_reg)); 4799 match(RegD); 4800 op_cost(0); 4801 format %{ %} 4802 interface(REG_INTER); 4803 %} 4804 4805 operand vRegD_V2() 4806 %{ 4807 constraint(ALLOC_IN_RC(v2_reg)); 4808 match(RegD); 4809 op_cost(0); 4810 format %{ %} 4811 interface(REG_INTER); 4812 %} 4813 4814 operand vRegD_V3() 4815 %{ 4816 constraint(ALLOC_IN_RC(v3_reg)); 4817 match(RegD); 4818 op_cost(0); 4819 format %{ %} 4820 interface(REG_INTER); 4821 %} 4822 4823 // Flags register, used as output of signed compare instructions 4824 4825 // note that on AArch64 we also use this register as the output for 4826 // for floating point compare instructions (CmpF CmpD). this ensures 4827 // that ordered inequality tests use GT, GE, LT or LE none of which 4828 // pass through cases where the result is unordered i.e. one or both 4829 // inputs to the compare is a NaN. this means that the ideal code can 4830 // replace e.g. a GT with an LE and not end up capturing the NaN case 4831 // (where the comparison should always fail). EQ and NE tests are 4832 // always generated in ideal code so that unordered folds into the NE 4833 // case, matching the behaviour of AArch64 NE. 4834 // 4835 // This differs from x86 where the outputs of FP compares use a 4836 // special FP flags registers and where compares based on this 4837 // register are distinguished into ordered inequalities (cmpOpUCF) and 4838 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4839 // to explicitly handle the unordered case in branches. x86 also has 4840 // to include extra CMoveX rules to accept a cmpOpUCF input. 4841 4842 operand rFlagsReg() 4843 %{ 4844 constraint(ALLOC_IN_RC(int_flags)); 4845 match(RegFlags); 4846 4847 op_cost(0); 4848 format %{ "RFLAGS" %} 4849 interface(REG_INTER); 4850 %} 4851 4852 // Flags register, used as output of unsigned compare instructions 4853 operand rFlagsRegU() 4854 %{ 4855 constraint(ALLOC_IN_RC(int_flags)); 4856 match(RegFlags); 4857 4858 op_cost(0); 4859 format %{ "RFLAGSU" %} 4860 interface(REG_INTER); 4861 %} 4862 4863 // Special Registers 4864 4865 // Method Register 4866 operand inline_cache_RegP(iRegP reg) 4867 %{ 4868 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4869 match(reg); 4870 match(iRegPNoSp); 4871 op_cost(0); 4872 format %{ %} 4873 interface(REG_INTER); 4874 %} 4875 4876 operand interpreter_method_oop_RegP(iRegP reg) 4877 %{ 4878 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4879 match(reg); 4880 match(iRegPNoSp); 4881 op_cost(0); 4882 format %{ %} 4883 interface(REG_INTER); 4884 %} 4885 4886 // Thread Register 4887 operand thread_RegP(iRegP reg) 4888 %{ 4889 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4890 match(reg); 4891 op_cost(0); 4892 format %{ %} 4893 interface(REG_INTER); 4894 %} 4895 4896 operand lr_RegP(iRegP reg) 4897 %{ 4898 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4899 match(reg); 4900 op_cost(0); 4901 format %{ %} 4902 interface(REG_INTER); 4903 %} 4904 4905 //----------Memory Operands---------------------------------------------------- 4906 4907 operand indirect(iRegP reg) 4908 %{ 4909 constraint(ALLOC_IN_RC(ptr_reg)); 4910 match(reg); 4911 op_cost(0); 4912 format %{ "[$reg]" %} 4913 interface(MEMORY_INTER) %{ 4914 base($reg); 4915 index(0xffffffff); 4916 scale(0x0); 4917 disp(0x0); 4918 %} 4919 %} 4920 4921 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4922 %{ 4923 constraint(ALLOC_IN_RC(ptr_reg)); 4924 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4925 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4926 op_cost(0); 4927 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4928 interface(MEMORY_INTER) %{ 4929 base($reg); 4930 index($ireg); 4931 scale($scale); 4932 disp(0x0); 4933 %} 4934 %} 4935 4936 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4937 %{ 4938 constraint(ALLOC_IN_RC(ptr_reg)); 4939 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4940 match(AddP reg (LShiftL lreg scale)); 4941 op_cost(0); 4942 format %{ "$reg, $lreg lsl($scale)" %} 4943 interface(MEMORY_INTER) %{ 4944 base($reg); 4945 index($lreg); 4946 scale($scale); 4947 disp(0x0); 4948 %} 4949 %} 4950 4951 operand indIndexI2L(iRegP reg, iRegI ireg) 4952 %{ 4953 constraint(ALLOC_IN_RC(ptr_reg)); 4954 match(AddP reg (ConvI2L ireg)); 4955 op_cost(0); 4956 format %{ "$reg, $ireg, 0, I2L" %} 4957 interface(MEMORY_INTER) %{ 4958 base($reg); 4959 index($ireg); 4960 scale(0x0); 4961 disp(0x0); 4962 %} 4963 %} 4964 4965 operand indIndex(iRegP reg, iRegL lreg) 4966 %{ 4967 constraint(ALLOC_IN_RC(ptr_reg)); 4968 match(AddP reg lreg); 4969 op_cost(0); 4970 format %{ "$reg, $lreg" %} 4971 interface(MEMORY_INTER) %{ 4972 base($reg); 4973 index($lreg); 4974 scale(0x0); 4975 disp(0x0); 4976 %} 4977 %} 4978 4979 operand indOffI(iRegP reg, immIOffset off) 4980 %{ 4981 constraint(ALLOC_IN_RC(ptr_reg)); 4982 match(AddP reg off); 4983 op_cost(0); 4984 format %{ "[$reg, $off]" %} 4985 interface(MEMORY_INTER) %{ 4986 base($reg); 4987 index(0xffffffff); 4988 scale(0x0); 4989 disp($off); 4990 %} 4991 %} 4992 4993 operand indOffI4(iRegP reg, immIOffset4 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 indOffI8(iRegP reg, immIOffset8 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 indOffI16(iRegP reg, immIOffset16 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 indOffL(iRegP reg, immLoffset 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 indOffL4(iRegP reg, immLoffset4 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 indOffL8(iRegP reg, immLoffset8 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 indOffL16(iRegP reg, immLoffset16 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 indirectN(iRegN reg) 5092 %{ 5093 predicate(Universe::narrow_oop_shift() == 0); 5094 constraint(ALLOC_IN_RC(ptr_reg)); 5095 match(DecodeN reg); 5096 op_cost(0); 5097 format %{ "[$reg]\t# narrow" %} 5098 interface(MEMORY_INTER) %{ 5099 base($reg); 5100 index(0xffffffff); 5101 scale(0x0); 5102 disp(0x0); 5103 %} 5104 %} 5105 5106 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5107 %{ 5108 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5109 constraint(ALLOC_IN_RC(ptr_reg)); 5110 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5111 op_cost(0); 5112 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5113 interface(MEMORY_INTER) %{ 5114 base($reg); 5115 index($ireg); 5116 scale($scale); 5117 disp(0x0); 5118 %} 5119 %} 5120 5121 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5122 %{ 5123 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5124 constraint(ALLOC_IN_RC(ptr_reg)); 5125 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5126 op_cost(0); 5127 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5128 interface(MEMORY_INTER) %{ 5129 base($reg); 5130 index($lreg); 5131 scale($scale); 5132 disp(0x0); 5133 %} 5134 %} 5135 5136 operand indIndexI2LN(iRegN reg, iRegI ireg) 5137 %{ 5138 predicate(Universe::narrow_oop_shift() == 0); 5139 constraint(ALLOC_IN_RC(ptr_reg)); 5140 match(AddP (DecodeN reg) (ConvI2L ireg)); 5141 op_cost(0); 5142 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5143 interface(MEMORY_INTER) %{ 5144 base($reg); 5145 index($ireg); 5146 scale(0x0); 5147 disp(0x0); 5148 %} 5149 %} 5150 5151 operand indIndexN(iRegN reg, iRegL lreg) 5152 %{ 5153 predicate(Universe::narrow_oop_shift() == 0); 5154 constraint(ALLOC_IN_RC(ptr_reg)); 5155 match(AddP (DecodeN reg) lreg); 5156 op_cost(0); 5157 format %{ "$reg, $lreg\t# narrow" %} 5158 interface(MEMORY_INTER) %{ 5159 base($reg); 5160 index($lreg); 5161 scale(0x0); 5162 disp(0x0); 5163 %} 5164 %} 5165 5166 operand indOffIN(iRegN reg, immIOffset off) 5167 %{ 5168 predicate(Universe::narrow_oop_shift() == 0); 5169 constraint(ALLOC_IN_RC(ptr_reg)); 5170 match(AddP (DecodeN reg) off); 5171 op_cost(0); 5172 format %{ "[$reg, $off]\t# narrow" %} 5173 interface(MEMORY_INTER) %{ 5174 base($reg); 5175 index(0xffffffff); 5176 scale(0x0); 5177 disp($off); 5178 %} 5179 %} 5180 5181 operand indOffLN(iRegN reg, immLoffset off) 5182 %{ 5183 predicate(Universe::narrow_oop_shift() == 0); 5184 constraint(ALLOC_IN_RC(ptr_reg)); 5185 match(AddP (DecodeN reg) off); 5186 op_cost(0); 5187 format %{ "[$reg, $off]\t# narrow" %} 5188 interface(MEMORY_INTER) %{ 5189 base($reg); 5190 index(0xffffffff); 5191 scale(0x0); 5192 disp($off); 5193 %} 5194 %} 5195 5196 5197 5198 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5199 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5200 %{ 5201 constraint(ALLOC_IN_RC(ptr_reg)); 5202 match(AddP reg off); 5203 op_cost(0); 5204 format %{ "[$reg, $off]" %} 5205 interface(MEMORY_INTER) %{ 5206 base($reg); 5207 index(0xffffffff); 5208 scale(0x0); 5209 disp($off); 5210 %} 5211 %} 5212 5213 //----------Special Memory Operands-------------------------------------------- 5214 // Stack Slot Operand - This operand is used for loading and storing temporary 5215 // values on the stack where a match requires a value to 5216 // flow through memory. 5217 operand stackSlotP(sRegP reg) 5218 %{ 5219 constraint(ALLOC_IN_RC(stack_slots)); 5220 op_cost(100); 5221 // No match rule because this operand is only generated in matching 5222 // match(RegP); 5223 format %{ "[$reg]" %} 5224 interface(MEMORY_INTER) %{ 5225 base(0x1e); // RSP 5226 index(0x0); // No Index 5227 scale(0x0); // No Scale 5228 disp($reg); // Stack Offset 5229 %} 5230 %} 5231 5232 operand stackSlotI(sRegI reg) 5233 %{ 5234 constraint(ALLOC_IN_RC(stack_slots)); 5235 // No match rule because this operand is only generated in matching 5236 // match(RegI); 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 stackSlotF(sRegF reg) 5247 %{ 5248 constraint(ALLOC_IN_RC(stack_slots)); 5249 // No match rule because this operand is only generated in matching 5250 // match(RegF); 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 stackSlotD(sRegD reg) 5261 %{ 5262 constraint(ALLOC_IN_RC(stack_slots)); 5263 // No match rule because this operand is only generated in matching 5264 // match(RegD); 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 stackSlotL(sRegL reg) 5275 %{ 5276 constraint(ALLOC_IN_RC(stack_slots)); 5277 // No match rule because this operand is only generated in matching 5278 // match(RegL); 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 // Operands for expressing Control Flow 5289 // NOTE: Label is a predefined operand which should not be redefined in 5290 // the AD file. It is generically handled within the ADLC. 5291 5292 //----------Conditional Branch Operands---------------------------------------- 5293 // Comparison Op - This is the operation of the comparison, and is limited to 5294 // the following set of codes: 5295 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5296 // 5297 // Other attributes of the comparison, such as unsignedness, are specified 5298 // by the comparison instruction that sets a condition code flags register. 5299 // That result is represented by a flags operand whose subtype is appropriate 5300 // to the unsignedness (etc.) of the comparison. 5301 // 5302 // Later, the instruction which matches both the Comparison Op (a Bool) and 5303 // the flags (produced by the Cmp) specifies the coding of the comparison op 5304 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5305 5306 // used for signed integral comparisons and fp comparisons 5307 5308 operand cmpOp() 5309 %{ 5310 match(Bool); 5311 5312 format %{ "" %} 5313 interface(COND_INTER) %{ 5314 equal(0x0, "eq"); 5315 not_equal(0x1, "ne"); 5316 less(0xb, "lt"); 5317 greater_equal(0xa, "ge"); 5318 less_equal(0xd, "le"); 5319 greater(0xc, "gt"); 5320 overflow(0x6, "vs"); 5321 no_overflow(0x7, "vc"); 5322 %} 5323 %} 5324 5325 // used for unsigned integral comparisons 5326 5327 operand cmpOpU() 5328 %{ 5329 match(Bool); 5330 5331 format %{ "" %} 5332 interface(COND_INTER) %{ 5333 equal(0x0, "eq"); 5334 not_equal(0x1, "ne"); 5335 less(0x3, "lo"); 5336 greater_equal(0x2, "hs"); 5337 less_equal(0x9, "ls"); 5338 greater(0x8, "hi"); 5339 overflow(0x6, "vs"); 5340 no_overflow(0x7, "vc"); 5341 %} 5342 %} 5343 5344 // used for certain integral comparisons which can be 5345 // converted to cbxx or tbxx instructions 5346 5347 operand cmpOpEqNe() 5348 %{ 5349 match(Bool); 5350 match(CmpOp); 5351 op_cost(0); 5352 predicate(n->as_Bool()->_test._test == BoolTest::ne 5353 || n->as_Bool()->_test._test == BoolTest::eq); 5354 5355 format %{ "" %} 5356 interface(COND_INTER) %{ 5357 equal(0x0, "eq"); 5358 not_equal(0x1, "ne"); 5359 less(0xb, "lt"); 5360 greater_equal(0xa, "ge"); 5361 less_equal(0xd, "le"); 5362 greater(0xc, "gt"); 5363 overflow(0x6, "vs"); 5364 no_overflow(0x7, "vc"); 5365 %} 5366 %} 5367 5368 // used for certain integral comparisons which can be 5369 // converted to cbxx or tbxx instructions 5370 5371 operand cmpOpLtGe() 5372 %{ 5373 match(Bool); 5374 match(CmpOp); 5375 op_cost(0); 5376 5377 predicate(n->as_Bool()->_test._test == BoolTest::lt 5378 || n->as_Bool()->_test._test == BoolTest::ge); 5379 5380 format %{ "" %} 5381 interface(COND_INTER) %{ 5382 equal(0x0, "eq"); 5383 not_equal(0x1, "ne"); 5384 less(0xb, "lt"); 5385 greater_equal(0xa, "ge"); 5386 less_equal(0xd, "le"); 5387 greater(0xc, "gt"); 5388 overflow(0x6, "vs"); 5389 no_overflow(0x7, "vc"); 5390 %} 5391 %} 5392 5393 // used for certain unsigned integral comparisons which can be 5394 // converted to cbxx or tbxx instructions 5395 5396 operand cmpOpUEqNeLtGe() 5397 %{ 5398 match(Bool); 5399 match(CmpOp); 5400 op_cost(0); 5401 5402 predicate(n->as_Bool()->_test._test == BoolTest::eq 5403 || n->as_Bool()->_test._test == BoolTest::ne 5404 || n->as_Bool()->_test._test == BoolTest::lt 5405 || n->as_Bool()->_test._test == BoolTest::ge); 5406 5407 format %{ "" %} 5408 interface(COND_INTER) %{ 5409 equal(0x0, "eq"); 5410 not_equal(0x1, "ne"); 5411 less(0xb, "lt"); 5412 greater_equal(0xa, "ge"); 5413 less_equal(0xd, "le"); 5414 greater(0xc, "gt"); 5415 overflow(0x6, "vs"); 5416 no_overflow(0x7, "vc"); 5417 %} 5418 %} 5419 5420 // Special operand allowing long args to int ops to be truncated for free 5421 5422 operand iRegL2I(iRegL reg) %{ 5423 5424 op_cost(0); 5425 5426 match(ConvL2I reg); 5427 5428 format %{ "l2i($reg)" %} 5429 5430 interface(REG_INTER) 5431 %} 5432 5433 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5434 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5435 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5436 5437 //----------OPERAND CLASSES---------------------------------------------------- 5438 // Operand Classes are groups of operands that are used as to simplify 5439 // instruction definitions by not requiring the AD writer to specify 5440 // separate instructions for every form of operand when the 5441 // instruction accepts multiple operand types with the same basic 5442 // encoding and format. The classic case of this is memory operands. 5443 5444 // memory is used to define read/write location for load/store 5445 // instruction defs. we can turn a memory op into an Address 5446 5447 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5448 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5449 5450 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5451 // operations. it allows the src to be either an iRegI or a (ConvL2I 5452 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5453 // can be elided because the 32-bit instruction will just employ the 5454 // lower 32 bits anyway. 5455 // 5456 // n.b. this does not elide all L2I conversions. if the truncated 5457 // value is consumed by more than one operation then the ConvL2I 5458 // cannot be bundled into the consuming nodes so an l2i gets planted 5459 // (actually a movw $dst $src) and the downstream instructions consume 5460 // the result of the l2i as an iRegI input. That's a shame since the 5461 // movw is actually redundant but its not too costly. 5462 5463 opclass iRegIorL2I(iRegI, iRegL2I); 5464 5465 //----------PIPELINE----------------------------------------------------------- 5466 // Rules which define the behavior of the target architectures pipeline. 5467 5468 // For specific pipelines, eg A53, define the stages of that pipeline 5469 //pipe_desc(ISS, EX1, EX2, WR); 5470 #define ISS S0 5471 #define EX1 S1 5472 #define EX2 S2 5473 #define WR S3 5474 5475 // Integer ALU reg operation 5476 pipeline %{ 5477 5478 attributes %{ 5479 // ARM instructions are of fixed length 5480 fixed_size_instructions; // Fixed size instructions TODO does 5481 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5482 // ARM instructions come in 32-bit word units 5483 instruction_unit_size = 4; // An instruction is 4 bytes long 5484 instruction_fetch_unit_size = 64; // The processor fetches one line 5485 instruction_fetch_units = 1; // of 64 bytes 5486 5487 // List of nop instructions 5488 nops( MachNop ); 5489 %} 5490 5491 // We don't use an actual pipeline model so don't care about resources 5492 // or description. we do use pipeline classes to introduce fixed 5493 // latencies 5494 5495 //----------RESOURCES---------------------------------------------------------- 5496 // Resources are the functional units available to the machine 5497 5498 resources( INS0, INS1, INS01 = INS0 | INS1, 5499 ALU0, ALU1, ALU = ALU0 | ALU1, 5500 MAC, 5501 DIV, 5502 BRANCH, 5503 LDST, 5504 NEON_FP); 5505 5506 //----------PIPELINE DESCRIPTION----------------------------------------------- 5507 // Pipeline Description specifies the stages in the machine's pipeline 5508 5509 // Define the pipeline as a generic 6 stage pipeline 5510 pipe_desc(S0, S1, S2, S3, S4, S5); 5511 5512 //----------PIPELINE CLASSES--------------------------------------------------- 5513 // Pipeline Classes describe the stages in which input and output are 5514 // referenced by the hardware pipeline. 5515 5516 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5517 %{ 5518 single_instruction; 5519 src1 : S1(read); 5520 src2 : S2(read); 5521 dst : S5(write); 5522 INS01 : ISS; 5523 NEON_FP : S5; 5524 %} 5525 5526 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5527 %{ 5528 single_instruction; 5529 src1 : S1(read); 5530 src2 : S2(read); 5531 dst : S5(write); 5532 INS01 : ISS; 5533 NEON_FP : S5; 5534 %} 5535 5536 pipe_class fp_uop_s(vRegF dst, vRegF src) 5537 %{ 5538 single_instruction; 5539 src : S1(read); 5540 dst : S5(write); 5541 INS01 : ISS; 5542 NEON_FP : S5; 5543 %} 5544 5545 pipe_class fp_uop_d(vRegD dst, vRegD src) 5546 %{ 5547 single_instruction; 5548 src : S1(read); 5549 dst : S5(write); 5550 INS01 : ISS; 5551 NEON_FP : S5; 5552 %} 5553 5554 pipe_class fp_d2f(vRegF dst, vRegD src) 5555 %{ 5556 single_instruction; 5557 src : S1(read); 5558 dst : S5(write); 5559 INS01 : ISS; 5560 NEON_FP : S5; 5561 %} 5562 5563 pipe_class fp_f2d(vRegD dst, vRegF src) 5564 %{ 5565 single_instruction; 5566 src : S1(read); 5567 dst : S5(write); 5568 INS01 : ISS; 5569 NEON_FP : S5; 5570 %} 5571 5572 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5573 %{ 5574 single_instruction; 5575 src : S1(read); 5576 dst : S5(write); 5577 INS01 : ISS; 5578 NEON_FP : S5; 5579 %} 5580 5581 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5582 %{ 5583 single_instruction; 5584 src : S1(read); 5585 dst : S5(write); 5586 INS01 : ISS; 5587 NEON_FP : S5; 5588 %} 5589 5590 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5591 %{ 5592 single_instruction; 5593 src : S1(read); 5594 dst : S5(write); 5595 INS01 : ISS; 5596 NEON_FP : S5; 5597 %} 5598 5599 pipe_class fp_l2f(vRegF dst, iRegL src) 5600 %{ 5601 single_instruction; 5602 src : S1(read); 5603 dst : S5(write); 5604 INS01 : ISS; 5605 NEON_FP : S5; 5606 %} 5607 5608 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5609 %{ 5610 single_instruction; 5611 src : S1(read); 5612 dst : S5(write); 5613 INS01 : ISS; 5614 NEON_FP : S5; 5615 %} 5616 5617 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5618 %{ 5619 single_instruction; 5620 src : S1(read); 5621 dst : S5(write); 5622 INS01 : ISS; 5623 NEON_FP : S5; 5624 %} 5625 5626 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5627 %{ 5628 single_instruction; 5629 src : S1(read); 5630 dst : S5(write); 5631 INS01 : ISS; 5632 NEON_FP : S5; 5633 %} 5634 5635 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5636 %{ 5637 single_instruction; 5638 src : S1(read); 5639 dst : S5(write); 5640 INS01 : ISS; 5641 NEON_FP : S5; 5642 %} 5643 5644 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5645 %{ 5646 single_instruction; 5647 src1 : S1(read); 5648 src2 : S2(read); 5649 dst : S5(write); 5650 INS0 : ISS; 5651 NEON_FP : S5; 5652 %} 5653 5654 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5655 %{ 5656 single_instruction; 5657 src1 : S1(read); 5658 src2 : S2(read); 5659 dst : S5(write); 5660 INS0 : ISS; 5661 NEON_FP : S5; 5662 %} 5663 5664 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5665 %{ 5666 single_instruction; 5667 cr : S1(read); 5668 src1 : S1(read); 5669 src2 : S1(read); 5670 dst : S3(write); 5671 INS01 : ISS; 5672 NEON_FP : S3; 5673 %} 5674 5675 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5676 %{ 5677 single_instruction; 5678 cr : S1(read); 5679 src1 : S1(read); 5680 src2 : S1(read); 5681 dst : S3(write); 5682 INS01 : ISS; 5683 NEON_FP : S3; 5684 %} 5685 5686 pipe_class fp_imm_s(vRegF dst) 5687 %{ 5688 single_instruction; 5689 dst : S3(write); 5690 INS01 : ISS; 5691 NEON_FP : S3; 5692 %} 5693 5694 pipe_class fp_imm_d(vRegD dst) 5695 %{ 5696 single_instruction; 5697 dst : S3(write); 5698 INS01 : ISS; 5699 NEON_FP : S3; 5700 %} 5701 5702 pipe_class fp_load_constant_s(vRegF dst) 5703 %{ 5704 single_instruction; 5705 dst : S4(write); 5706 INS01 : ISS; 5707 NEON_FP : S4; 5708 %} 5709 5710 pipe_class fp_load_constant_d(vRegD dst) 5711 %{ 5712 single_instruction; 5713 dst : S4(write); 5714 INS01 : ISS; 5715 NEON_FP : S4; 5716 %} 5717 5718 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5719 %{ 5720 single_instruction; 5721 dst : S5(write); 5722 src1 : S1(read); 5723 src2 : S1(read); 5724 INS01 : ISS; 5725 NEON_FP : S5; 5726 %} 5727 5728 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5729 %{ 5730 single_instruction; 5731 dst : S5(write); 5732 src1 : S1(read); 5733 src2 : S1(read); 5734 INS0 : ISS; 5735 NEON_FP : S5; 5736 %} 5737 5738 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5739 %{ 5740 single_instruction; 5741 dst : S5(write); 5742 src1 : S1(read); 5743 src2 : S1(read); 5744 dst : S1(read); 5745 INS01 : ISS; 5746 NEON_FP : S5; 5747 %} 5748 5749 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5750 %{ 5751 single_instruction; 5752 dst : S5(write); 5753 src1 : S1(read); 5754 src2 : S1(read); 5755 dst : S1(read); 5756 INS0 : ISS; 5757 NEON_FP : S5; 5758 %} 5759 5760 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5761 %{ 5762 single_instruction; 5763 dst : S4(write); 5764 src1 : S2(read); 5765 src2 : S2(read); 5766 INS01 : ISS; 5767 NEON_FP : S4; 5768 %} 5769 5770 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5771 %{ 5772 single_instruction; 5773 dst : S4(write); 5774 src1 : S2(read); 5775 src2 : S2(read); 5776 INS0 : ISS; 5777 NEON_FP : S4; 5778 %} 5779 5780 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5781 %{ 5782 single_instruction; 5783 dst : S3(write); 5784 src1 : S2(read); 5785 src2 : S2(read); 5786 INS01 : ISS; 5787 NEON_FP : S3; 5788 %} 5789 5790 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5791 %{ 5792 single_instruction; 5793 dst : S3(write); 5794 src1 : S2(read); 5795 src2 : S2(read); 5796 INS0 : ISS; 5797 NEON_FP : S3; 5798 %} 5799 5800 pipe_class vshift64(vecD dst, vecD src, vecX shift) 5801 %{ 5802 single_instruction; 5803 dst : S3(write); 5804 src : S1(read); 5805 shift : S1(read); 5806 INS01 : ISS; 5807 NEON_FP : S3; 5808 %} 5809 5810 pipe_class vshift128(vecX dst, vecX src, vecX shift) 5811 %{ 5812 single_instruction; 5813 dst : S3(write); 5814 src : S1(read); 5815 shift : S1(read); 5816 INS0 : ISS; 5817 NEON_FP : S3; 5818 %} 5819 5820 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5821 %{ 5822 single_instruction; 5823 dst : S3(write); 5824 src : S1(read); 5825 INS01 : ISS; 5826 NEON_FP : S3; 5827 %} 5828 5829 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5830 %{ 5831 single_instruction; 5832 dst : S3(write); 5833 src : S1(read); 5834 INS0 : ISS; 5835 NEON_FP : S3; 5836 %} 5837 5838 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5839 %{ 5840 single_instruction; 5841 dst : S5(write); 5842 src1 : S1(read); 5843 src2 : S1(read); 5844 INS01 : ISS; 5845 NEON_FP : S5; 5846 %} 5847 5848 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5849 %{ 5850 single_instruction; 5851 dst : S5(write); 5852 src1 : S1(read); 5853 src2 : S1(read); 5854 INS0 : ISS; 5855 NEON_FP : S5; 5856 %} 5857 5858 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5859 %{ 5860 single_instruction; 5861 dst : S5(write); 5862 src1 : S1(read); 5863 src2 : S1(read); 5864 INS0 : ISS; 5865 NEON_FP : S5; 5866 %} 5867 5868 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5869 %{ 5870 single_instruction; 5871 dst : S5(write); 5872 src1 : S1(read); 5873 src2 : S1(read); 5874 INS0 : ISS; 5875 NEON_FP : S5; 5876 %} 5877 5878 pipe_class vsqrt_fp128(vecX dst, vecX src) 5879 %{ 5880 single_instruction; 5881 dst : S5(write); 5882 src : S1(read); 5883 INS0 : ISS; 5884 NEON_FP : S5; 5885 %} 5886 5887 pipe_class vunop_fp64(vecD dst, vecD src) 5888 %{ 5889 single_instruction; 5890 dst : S5(write); 5891 src : S1(read); 5892 INS01 : ISS; 5893 NEON_FP : S5; 5894 %} 5895 5896 pipe_class vunop_fp128(vecX dst, vecX src) 5897 %{ 5898 single_instruction; 5899 dst : S5(write); 5900 src : S1(read); 5901 INS0 : ISS; 5902 NEON_FP : S5; 5903 %} 5904 5905 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5906 %{ 5907 single_instruction; 5908 dst : S3(write); 5909 src : S1(read); 5910 INS01 : ISS; 5911 NEON_FP : S3; 5912 %} 5913 5914 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5915 %{ 5916 single_instruction; 5917 dst : S3(write); 5918 src : S1(read); 5919 INS01 : ISS; 5920 NEON_FP : S3; 5921 %} 5922 5923 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5924 %{ 5925 single_instruction; 5926 dst : S3(write); 5927 src : S1(read); 5928 INS01 : ISS; 5929 NEON_FP : S3; 5930 %} 5931 5932 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5933 %{ 5934 single_instruction; 5935 dst : S3(write); 5936 src : S1(read); 5937 INS01 : ISS; 5938 NEON_FP : S3; 5939 %} 5940 5941 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5942 %{ 5943 single_instruction; 5944 dst : S3(write); 5945 src : S1(read); 5946 INS01 : ISS; 5947 NEON_FP : S3; 5948 %} 5949 5950 pipe_class vmovi_reg_imm64(vecD dst) 5951 %{ 5952 single_instruction; 5953 dst : S3(write); 5954 INS01 : ISS; 5955 NEON_FP : S3; 5956 %} 5957 5958 pipe_class vmovi_reg_imm128(vecX dst) 5959 %{ 5960 single_instruction; 5961 dst : S3(write); 5962 INS0 : ISS; 5963 NEON_FP : S3; 5964 %} 5965 5966 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 5967 %{ 5968 single_instruction; 5969 dst : S5(write); 5970 mem : ISS(read); 5971 INS01 : ISS; 5972 NEON_FP : S3; 5973 %} 5974 5975 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 5976 %{ 5977 single_instruction; 5978 dst : S5(write); 5979 mem : ISS(read); 5980 INS01 : ISS; 5981 NEON_FP : S3; 5982 %} 5983 5984 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 5985 %{ 5986 single_instruction; 5987 mem : ISS(read); 5988 src : S2(read); 5989 INS01 : ISS; 5990 NEON_FP : S3; 5991 %} 5992 5993 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 5994 %{ 5995 single_instruction; 5996 mem : ISS(read); 5997 src : S2(read); 5998 INS01 : ISS; 5999 NEON_FP : S3; 6000 %} 6001 6002 //------- Integer ALU operations -------------------------- 6003 6004 // Integer ALU reg-reg operation 6005 // Operands needed in EX1, result generated in EX2 6006 // Eg. ADD x0, x1, x2 6007 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6008 %{ 6009 single_instruction; 6010 dst : EX2(write); 6011 src1 : EX1(read); 6012 src2 : EX1(read); 6013 INS01 : ISS; // Dual issue as instruction 0 or 1 6014 ALU : EX2; 6015 %} 6016 6017 // Integer ALU reg-reg operation with constant shift 6018 // Shifted register must be available in LATE_ISS instead of EX1 6019 // Eg. ADD x0, x1, x2, LSL #2 6020 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6021 %{ 6022 single_instruction; 6023 dst : EX2(write); 6024 src1 : EX1(read); 6025 src2 : ISS(read); 6026 INS01 : ISS; 6027 ALU : EX2; 6028 %} 6029 6030 // Integer ALU reg operation with constant shift 6031 // Eg. LSL x0, x1, #shift 6032 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6033 %{ 6034 single_instruction; 6035 dst : EX2(write); 6036 src1 : ISS(read); 6037 INS01 : ISS; 6038 ALU : EX2; 6039 %} 6040 6041 // Integer ALU reg-reg operation with variable shift 6042 // Both operands must be available in LATE_ISS instead of EX1 6043 // Result is available in EX1 instead of EX2 6044 // Eg. LSLV x0, x1, x2 6045 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6046 %{ 6047 single_instruction; 6048 dst : EX1(write); 6049 src1 : ISS(read); 6050 src2 : ISS(read); 6051 INS01 : ISS; 6052 ALU : EX1; 6053 %} 6054 6055 // Integer ALU reg-reg operation with extract 6056 // As for _vshift above, but result generated in EX2 6057 // Eg. EXTR x0, x1, x2, #N 6058 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6059 %{ 6060 single_instruction; 6061 dst : EX2(write); 6062 src1 : ISS(read); 6063 src2 : ISS(read); 6064 INS1 : ISS; // Can only dual issue as Instruction 1 6065 ALU : EX1; 6066 %} 6067 6068 // Integer ALU reg operation 6069 // Eg. NEG x0, x1 6070 pipe_class ialu_reg(iRegI dst, iRegI src) 6071 %{ 6072 single_instruction; 6073 dst : EX2(write); 6074 src : EX1(read); 6075 INS01 : ISS; 6076 ALU : EX2; 6077 %} 6078 6079 // Integer ALU reg mmediate operation 6080 // Eg. ADD x0, x1, #N 6081 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6082 %{ 6083 single_instruction; 6084 dst : EX2(write); 6085 src1 : EX1(read); 6086 INS01 : ISS; 6087 ALU : EX2; 6088 %} 6089 6090 // Integer ALU immediate operation (no source operands) 6091 // Eg. MOV x0, #N 6092 pipe_class ialu_imm(iRegI dst) 6093 %{ 6094 single_instruction; 6095 dst : EX1(write); 6096 INS01 : ISS; 6097 ALU : EX1; 6098 %} 6099 6100 //------- Compare operation ------------------------------- 6101 6102 // Compare reg-reg 6103 // Eg. CMP x0, x1 6104 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6105 %{ 6106 single_instruction; 6107 // fixed_latency(16); 6108 cr : EX2(write); 6109 op1 : EX1(read); 6110 op2 : EX1(read); 6111 INS01 : ISS; 6112 ALU : EX2; 6113 %} 6114 6115 // Compare reg-reg 6116 // Eg. CMP x0, #N 6117 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6118 %{ 6119 single_instruction; 6120 // fixed_latency(16); 6121 cr : EX2(write); 6122 op1 : EX1(read); 6123 INS01 : ISS; 6124 ALU : EX2; 6125 %} 6126 6127 //------- Conditional instructions ------------------------ 6128 6129 // Conditional no operands 6130 // Eg. CSINC x0, zr, zr, <cond> 6131 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6132 %{ 6133 single_instruction; 6134 cr : EX1(read); 6135 dst : EX2(write); 6136 INS01 : ISS; 6137 ALU : EX2; 6138 %} 6139 6140 // Conditional 2 operand 6141 // EG. CSEL X0, X1, X2, <cond> 6142 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6143 %{ 6144 single_instruction; 6145 cr : EX1(read); 6146 src1 : EX1(read); 6147 src2 : EX1(read); 6148 dst : EX2(write); 6149 INS01 : ISS; 6150 ALU : EX2; 6151 %} 6152 6153 // Conditional 2 operand 6154 // EG. CSEL X0, X1, X2, <cond> 6155 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6156 %{ 6157 single_instruction; 6158 cr : EX1(read); 6159 src : EX1(read); 6160 dst : EX2(write); 6161 INS01 : ISS; 6162 ALU : EX2; 6163 %} 6164 6165 //------- Multiply pipeline operations -------------------- 6166 6167 // Multiply reg-reg 6168 // Eg. MUL w0, w1, w2 6169 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6170 %{ 6171 single_instruction; 6172 dst : WR(write); 6173 src1 : ISS(read); 6174 src2 : ISS(read); 6175 INS01 : ISS; 6176 MAC : WR; 6177 %} 6178 6179 // Multiply accumulate 6180 // Eg. MADD w0, w1, w2, w3 6181 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6182 %{ 6183 single_instruction; 6184 dst : WR(write); 6185 src1 : ISS(read); 6186 src2 : ISS(read); 6187 src3 : ISS(read); 6188 INS01 : ISS; 6189 MAC : WR; 6190 %} 6191 6192 // Eg. MUL w0, w1, w2 6193 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6194 %{ 6195 single_instruction; 6196 fixed_latency(3); // Maximum latency for 64 bit mul 6197 dst : WR(write); 6198 src1 : ISS(read); 6199 src2 : ISS(read); 6200 INS01 : ISS; 6201 MAC : WR; 6202 %} 6203 6204 // Multiply accumulate 6205 // Eg. MADD w0, w1, w2, w3 6206 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6207 %{ 6208 single_instruction; 6209 fixed_latency(3); // Maximum latency for 64 bit mul 6210 dst : WR(write); 6211 src1 : ISS(read); 6212 src2 : ISS(read); 6213 src3 : ISS(read); 6214 INS01 : ISS; 6215 MAC : WR; 6216 %} 6217 6218 //------- Divide pipeline operations -------------------- 6219 6220 // Eg. SDIV w0, w1, w2 6221 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6222 %{ 6223 single_instruction; 6224 fixed_latency(8); // Maximum latency for 32 bit divide 6225 dst : WR(write); 6226 src1 : ISS(read); 6227 src2 : ISS(read); 6228 INS0 : ISS; // Can only dual issue as instruction 0 6229 DIV : WR; 6230 %} 6231 6232 // Eg. SDIV x0, x1, x2 6233 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6234 %{ 6235 single_instruction; 6236 fixed_latency(16); // Maximum latency for 64 bit divide 6237 dst : WR(write); 6238 src1 : ISS(read); 6239 src2 : ISS(read); 6240 INS0 : ISS; // Can only dual issue as instruction 0 6241 DIV : WR; 6242 %} 6243 6244 //------- Load pipeline operations ------------------------ 6245 6246 // Load - prefetch 6247 // Eg. PFRM <mem> 6248 pipe_class iload_prefetch(memory mem) 6249 %{ 6250 single_instruction; 6251 mem : ISS(read); 6252 INS01 : ISS; 6253 LDST : WR; 6254 %} 6255 6256 // Load - reg, mem 6257 // Eg. LDR x0, <mem> 6258 pipe_class iload_reg_mem(iRegI dst, memory mem) 6259 %{ 6260 single_instruction; 6261 dst : WR(write); 6262 mem : ISS(read); 6263 INS01 : ISS; 6264 LDST : WR; 6265 %} 6266 6267 // Load - reg, reg 6268 // Eg. LDR x0, [sp, x1] 6269 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6270 %{ 6271 single_instruction; 6272 dst : WR(write); 6273 src : ISS(read); 6274 INS01 : ISS; 6275 LDST : WR; 6276 %} 6277 6278 //------- Store pipeline operations ----------------------- 6279 6280 // Store - zr, mem 6281 // Eg. STR zr, <mem> 6282 pipe_class istore_mem(memory mem) 6283 %{ 6284 single_instruction; 6285 mem : ISS(read); 6286 INS01 : ISS; 6287 LDST : WR; 6288 %} 6289 6290 // Store - reg, mem 6291 // Eg. STR x0, <mem> 6292 pipe_class istore_reg_mem(iRegI src, memory mem) 6293 %{ 6294 single_instruction; 6295 mem : ISS(read); 6296 src : EX2(read); 6297 INS01 : ISS; 6298 LDST : WR; 6299 %} 6300 6301 // Store - reg, reg 6302 // Eg. STR x0, [sp, x1] 6303 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6304 %{ 6305 single_instruction; 6306 dst : ISS(read); 6307 src : EX2(read); 6308 INS01 : ISS; 6309 LDST : WR; 6310 %} 6311 6312 //------- Store pipeline operations ----------------------- 6313 6314 // Branch 6315 pipe_class pipe_branch() 6316 %{ 6317 single_instruction; 6318 INS01 : ISS; 6319 BRANCH : EX1; 6320 %} 6321 6322 // Conditional branch 6323 pipe_class pipe_branch_cond(rFlagsReg cr) 6324 %{ 6325 single_instruction; 6326 cr : EX1(read); 6327 INS01 : ISS; 6328 BRANCH : EX1; 6329 %} 6330 6331 // Compare & Branch 6332 // EG. CBZ/CBNZ 6333 pipe_class pipe_cmp_branch(iRegI op1) 6334 %{ 6335 single_instruction; 6336 op1 : EX1(read); 6337 INS01 : ISS; 6338 BRANCH : EX1; 6339 %} 6340 6341 //------- Synchronisation operations ---------------------- 6342 6343 // Any operation requiring serialization. 6344 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6345 pipe_class pipe_serial() 6346 %{ 6347 single_instruction; 6348 force_serialization; 6349 fixed_latency(16); 6350 INS01 : ISS(2); // Cannot dual issue with any other instruction 6351 LDST : WR; 6352 %} 6353 6354 // Generic big/slow expanded idiom - also serialized 6355 pipe_class pipe_slow() 6356 %{ 6357 instruction_count(10); 6358 multiple_bundles; 6359 force_serialization; 6360 fixed_latency(16); 6361 INS01 : ISS(2); // Cannot dual issue with any other instruction 6362 LDST : WR; 6363 %} 6364 6365 // Empty pipeline class 6366 pipe_class pipe_class_empty() 6367 %{ 6368 single_instruction; 6369 fixed_latency(0); 6370 %} 6371 6372 // Default pipeline class. 6373 pipe_class pipe_class_default() 6374 %{ 6375 single_instruction; 6376 fixed_latency(2); 6377 %} 6378 6379 // Pipeline class for compares. 6380 pipe_class pipe_class_compare() 6381 %{ 6382 single_instruction; 6383 fixed_latency(16); 6384 %} 6385 6386 // Pipeline class for memory operations. 6387 pipe_class pipe_class_memory() 6388 %{ 6389 single_instruction; 6390 fixed_latency(16); 6391 %} 6392 6393 // Pipeline class for call. 6394 pipe_class pipe_class_call() 6395 %{ 6396 single_instruction; 6397 fixed_latency(100); 6398 %} 6399 6400 // Define the class for the Nop node. 6401 define %{ 6402 MachNop = pipe_class_empty; 6403 %} 6404 6405 %} 6406 //----------INSTRUCTIONS------------------------------------------------------- 6407 // 6408 // match -- States which machine-independent subtree may be replaced 6409 // by this instruction. 6410 // ins_cost -- The estimated cost of this instruction is used by instruction 6411 // selection to identify a minimum cost tree of machine 6412 // instructions that matches a tree of machine-independent 6413 // instructions. 6414 // format -- A string providing the disassembly for this instruction. 6415 // The value of an instruction's operand may be inserted 6416 // by referring to it with a '$' prefix. 6417 // opcode -- Three instruction opcodes may be provided. These are referred 6418 // to within an encode class as $primary, $secondary, and $tertiary 6419 // rrspectively. The primary opcode is commonly used to 6420 // indicate the type of machine instruction, while secondary 6421 // and tertiary are often used for prefix options or addressing 6422 // modes. 6423 // ins_encode -- A list of encode classes with parameters. The encode class 6424 // name must have been defined in an 'enc_class' specification 6425 // in the encode section of the architecture description. 6426 6427 // ============================================================================ 6428 // Memory (Load/Store) Instructions 6429 6430 // Load Instructions 6431 6432 // Load Byte (8 bit signed) 6433 instruct loadB(iRegINoSp dst, memory mem) 6434 %{ 6435 match(Set dst (LoadB mem)); 6436 predicate(!needs_acquiring_load(n)); 6437 6438 ins_cost(4 * INSN_COST); 6439 format %{ "ldrsbw $dst, $mem\t# byte" %} 6440 6441 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6442 6443 ins_pipe(iload_reg_mem); 6444 %} 6445 6446 // Load Byte (8 bit signed) into long 6447 instruct loadB2L(iRegLNoSp dst, memory mem) 6448 %{ 6449 match(Set dst (ConvI2L (LoadB mem))); 6450 predicate(!needs_acquiring_load(n->in(1))); 6451 6452 ins_cost(4 * INSN_COST); 6453 format %{ "ldrsb $dst, $mem\t# byte" %} 6454 6455 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6456 6457 ins_pipe(iload_reg_mem); 6458 %} 6459 6460 // Load Byte (8 bit unsigned) 6461 instruct loadUB(iRegINoSp dst, memory mem) 6462 %{ 6463 match(Set dst (LoadUB mem)); 6464 predicate(!needs_acquiring_load(n)); 6465 6466 ins_cost(4 * INSN_COST); 6467 format %{ "ldrbw $dst, $mem\t# byte" %} 6468 6469 ins_encode(aarch64_enc_ldrb(dst, mem)); 6470 6471 ins_pipe(iload_reg_mem); 6472 %} 6473 6474 // Load Byte (8 bit unsigned) into long 6475 instruct loadUB2L(iRegLNoSp dst, memory mem) 6476 %{ 6477 match(Set dst (ConvI2L (LoadUB mem))); 6478 predicate(!needs_acquiring_load(n->in(1))); 6479 6480 ins_cost(4 * INSN_COST); 6481 format %{ "ldrb $dst, $mem\t# byte" %} 6482 6483 ins_encode(aarch64_enc_ldrb(dst, mem)); 6484 6485 ins_pipe(iload_reg_mem); 6486 %} 6487 6488 // Load Short (16 bit signed) 6489 instruct loadS(iRegINoSp dst, memory mem) 6490 %{ 6491 match(Set dst (LoadS mem)); 6492 predicate(!needs_acquiring_load(n)); 6493 6494 ins_cost(4 * INSN_COST); 6495 format %{ "ldrshw $dst, $mem\t# short" %} 6496 6497 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6498 6499 ins_pipe(iload_reg_mem); 6500 %} 6501 6502 // Load Short (16 bit signed) into long 6503 instruct loadS2L(iRegLNoSp dst, memory mem) 6504 %{ 6505 match(Set dst (ConvI2L (LoadS mem))); 6506 predicate(!needs_acquiring_load(n->in(1))); 6507 6508 ins_cost(4 * INSN_COST); 6509 format %{ "ldrsh $dst, $mem\t# short" %} 6510 6511 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6512 6513 ins_pipe(iload_reg_mem); 6514 %} 6515 6516 // Load Char (16 bit unsigned) 6517 instruct loadUS(iRegINoSp dst, memory mem) 6518 %{ 6519 match(Set dst (LoadUS mem)); 6520 predicate(!needs_acquiring_load(n)); 6521 6522 ins_cost(4 * INSN_COST); 6523 format %{ "ldrh $dst, $mem\t# short" %} 6524 6525 ins_encode(aarch64_enc_ldrh(dst, mem)); 6526 6527 ins_pipe(iload_reg_mem); 6528 %} 6529 6530 // Load Short/Char (16 bit unsigned) into long 6531 instruct loadUS2L(iRegLNoSp dst, memory mem) 6532 %{ 6533 match(Set dst (ConvI2L (LoadUS mem))); 6534 predicate(!needs_acquiring_load(n->in(1))); 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 Integer (32 bit signed) 6545 instruct loadI(iRegINoSp dst, memory mem) 6546 %{ 6547 match(Set dst (LoadI mem)); 6548 predicate(!needs_acquiring_load(n)); 6549 6550 ins_cost(4 * INSN_COST); 6551 format %{ "ldrw $dst, $mem\t# int" %} 6552 6553 ins_encode(aarch64_enc_ldrw(dst, mem)); 6554 6555 ins_pipe(iload_reg_mem); 6556 %} 6557 6558 // Load Integer (32 bit signed) into long 6559 instruct loadI2L(iRegLNoSp dst, memory mem) 6560 %{ 6561 match(Set dst (ConvI2L (LoadI mem))); 6562 predicate(!needs_acquiring_load(n->in(1))); 6563 6564 ins_cost(4 * INSN_COST); 6565 format %{ "ldrsw $dst, $mem\t# int" %} 6566 6567 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6568 6569 ins_pipe(iload_reg_mem); 6570 %} 6571 6572 // Load Integer (32 bit unsigned) into long 6573 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6574 %{ 6575 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6576 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6577 6578 ins_cost(4 * INSN_COST); 6579 format %{ "ldrw $dst, $mem\t# int" %} 6580 6581 ins_encode(aarch64_enc_ldrw(dst, mem)); 6582 6583 ins_pipe(iload_reg_mem); 6584 %} 6585 6586 // Load Long (64 bit signed) 6587 instruct loadL(iRegLNoSp dst, memory mem) 6588 %{ 6589 match(Set dst (LoadL mem)); 6590 predicate(!needs_acquiring_load(n)); 6591 6592 ins_cost(4 * INSN_COST); 6593 format %{ "ldr $dst, $mem\t# int" %} 6594 6595 ins_encode(aarch64_enc_ldr(dst, mem)); 6596 6597 ins_pipe(iload_reg_mem); 6598 %} 6599 6600 // Load Range 6601 instruct loadRange(iRegINoSp dst, memory mem) 6602 %{ 6603 match(Set dst (LoadRange mem)); 6604 6605 ins_cost(4 * INSN_COST); 6606 format %{ "ldrw $dst, $mem\t# range" %} 6607 6608 ins_encode(aarch64_enc_ldrw(dst, mem)); 6609 6610 ins_pipe(iload_reg_mem); 6611 %} 6612 6613 // Load Pointer 6614 instruct loadP(iRegPNoSp dst, memory mem) 6615 %{ 6616 match(Set dst (LoadP mem)); 6617 predicate(!needs_acquiring_load(n)); 6618 6619 ins_cost(4 * INSN_COST); 6620 format %{ "ldr $dst, $mem\t# ptr" %} 6621 6622 ins_encode(aarch64_enc_ldr(dst, mem)); 6623 6624 ins_pipe(iload_reg_mem); 6625 %} 6626 6627 // Load Compressed Pointer 6628 instruct loadN(iRegNNoSp dst, memory mem) 6629 %{ 6630 match(Set dst (LoadN mem)); 6631 predicate(!needs_acquiring_load(n)); 6632 6633 ins_cost(4 * INSN_COST); 6634 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6635 6636 ins_encode(aarch64_enc_ldrw(dst, mem)); 6637 6638 ins_pipe(iload_reg_mem); 6639 %} 6640 6641 // Load Klass Pointer 6642 instruct loadKlass(iRegPNoSp dst, memory mem) 6643 %{ 6644 match(Set dst (LoadKlass mem)); 6645 predicate(!needs_acquiring_load(n)); 6646 6647 ins_cost(4 * INSN_COST); 6648 format %{ "ldr $dst, $mem\t# class" %} 6649 6650 ins_encode(aarch64_enc_ldr(dst, mem)); 6651 6652 ins_pipe(iload_reg_mem); 6653 %} 6654 6655 // Load Narrow Klass Pointer 6656 instruct loadNKlass(iRegNNoSp dst, memory mem) 6657 %{ 6658 match(Set dst (LoadNKlass mem)); 6659 predicate(!needs_acquiring_load(n)); 6660 6661 ins_cost(4 * INSN_COST); 6662 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6663 6664 ins_encode(aarch64_enc_ldrw(dst, mem)); 6665 6666 ins_pipe(iload_reg_mem); 6667 %} 6668 6669 // Load Float 6670 instruct loadF(vRegF dst, memory mem) 6671 %{ 6672 match(Set dst (LoadF mem)); 6673 predicate(!needs_acquiring_load(n)); 6674 6675 ins_cost(4 * INSN_COST); 6676 format %{ "ldrs $dst, $mem\t# float" %} 6677 6678 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6679 6680 ins_pipe(pipe_class_memory); 6681 %} 6682 6683 // Load Double 6684 instruct loadD(vRegD dst, memory mem) 6685 %{ 6686 match(Set dst (LoadD mem)); 6687 predicate(!needs_acquiring_load(n)); 6688 6689 ins_cost(4 * INSN_COST); 6690 format %{ "ldrd $dst, $mem\t# double" %} 6691 6692 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6693 6694 ins_pipe(pipe_class_memory); 6695 %} 6696 6697 6698 // Load Int Constant 6699 instruct loadConI(iRegINoSp dst, immI src) 6700 %{ 6701 match(Set dst src); 6702 6703 ins_cost(INSN_COST); 6704 format %{ "mov $dst, $src\t# int" %} 6705 6706 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6707 6708 ins_pipe(ialu_imm); 6709 %} 6710 6711 // Load Long Constant 6712 instruct loadConL(iRegLNoSp dst, immL src) 6713 %{ 6714 match(Set dst src); 6715 6716 ins_cost(INSN_COST); 6717 format %{ "mov $dst, $src\t# long" %} 6718 6719 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6720 6721 ins_pipe(ialu_imm); 6722 %} 6723 6724 // Load Pointer Constant 6725 6726 instruct loadConP(iRegPNoSp dst, immP con) 6727 %{ 6728 match(Set dst con); 6729 6730 ins_cost(INSN_COST * 4); 6731 format %{ 6732 "mov $dst, $con\t# ptr\n\t" 6733 %} 6734 6735 ins_encode(aarch64_enc_mov_p(dst, con)); 6736 6737 ins_pipe(ialu_imm); 6738 %} 6739 6740 // Load Null Pointer Constant 6741 6742 instruct loadConP0(iRegPNoSp dst, immP0 con) 6743 %{ 6744 match(Set dst con); 6745 6746 ins_cost(INSN_COST); 6747 format %{ "mov $dst, $con\t# NULL ptr" %} 6748 6749 ins_encode(aarch64_enc_mov_p0(dst, con)); 6750 6751 ins_pipe(ialu_imm); 6752 %} 6753 6754 // Load Pointer Constant One 6755 6756 instruct loadConP1(iRegPNoSp dst, immP_1 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_p1(dst, con)); 6764 6765 ins_pipe(ialu_imm); 6766 %} 6767 6768 // Load Poll Page Constant 6769 6770 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6771 %{ 6772 match(Set dst con); 6773 6774 ins_cost(INSN_COST); 6775 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6776 6777 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6778 6779 ins_pipe(ialu_imm); 6780 %} 6781 6782 // Load Byte Map Base Constant 6783 6784 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6785 %{ 6786 match(Set dst con); 6787 6788 ins_cost(INSN_COST); 6789 format %{ "adr $dst, $con\t# Byte Map Base" %} 6790 6791 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6792 6793 ins_pipe(ialu_imm); 6794 %} 6795 6796 // Load Narrow Pointer Constant 6797 6798 instruct loadConN(iRegNNoSp dst, immN con) 6799 %{ 6800 match(Set dst con); 6801 6802 ins_cost(INSN_COST * 4); 6803 format %{ "mov $dst, $con\t# compressed ptr" %} 6804 6805 ins_encode(aarch64_enc_mov_n(dst, con)); 6806 6807 ins_pipe(ialu_imm); 6808 %} 6809 6810 // Load Narrow Null Pointer Constant 6811 6812 instruct loadConN0(iRegNNoSp dst, immN0 con) 6813 %{ 6814 match(Set dst con); 6815 6816 ins_cost(INSN_COST); 6817 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6818 6819 ins_encode(aarch64_enc_mov_n0(dst, con)); 6820 6821 ins_pipe(ialu_imm); 6822 %} 6823 6824 // Load Narrow Klass Constant 6825 6826 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6827 %{ 6828 match(Set dst con); 6829 6830 ins_cost(INSN_COST); 6831 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6832 6833 ins_encode(aarch64_enc_mov_nk(dst, con)); 6834 6835 ins_pipe(ialu_imm); 6836 %} 6837 6838 // Load Packed Float Constant 6839 6840 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6841 match(Set dst con); 6842 ins_cost(INSN_COST * 4); 6843 format %{ "fmovs $dst, $con"%} 6844 ins_encode %{ 6845 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6846 %} 6847 6848 ins_pipe(fp_imm_s); 6849 %} 6850 6851 // Load Float Constant 6852 6853 instruct loadConF(vRegF dst, immF con) %{ 6854 match(Set dst con); 6855 6856 ins_cost(INSN_COST * 4); 6857 6858 format %{ 6859 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6860 %} 6861 6862 ins_encode %{ 6863 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6864 %} 6865 6866 ins_pipe(fp_load_constant_s); 6867 %} 6868 6869 // Load Packed Double Constant 6870 6871 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6872 match(Set dst con); 6873 ins_cost(INSN_COST); 6874 format %{ "fmovd $dst, $con"%} 6875 ins_encode %{ 6876 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6877 %} 6878 6879 ins_pipe(fp_imm_d); 6880 %} 6881 6882 // Load Double Constant 6883 6884 instruct loadConD(vRegD dst, immD con) %{ 6885 match(Set dst con); 6886 6887 ins_cost(INSN_COST * 5); 6888 format %{ 6889 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6890 %} 6891 6892 ins_encode %{ 6893 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6894 %} 6895 6896 ins_pipe(fp_load_constant_d); 6897 %} 6898 6899 // Store Instructions 6900 6901 // Store CMS card-mark Immediate 6902 instruct storeimmCM0(immI0 zero, memory mem) 6903 %{ 6904 match(Set mem (StoreCM mem zero)); 6905 predicate(unnecessary_storestore(n)); 6906 6907 ins_cost(INSN_COST); 6908 format %{ "storestore (elided)\n\t" 6909 "strb zr, $mem\t# byte" %} 6910 6911 ins_encode(aarch64_enc_strb0(mem)); 6912 6913 ins_pipe(istore_mem); 6914 %} 6915 6916 // Store CMS card-mark Immediate with intervening StoreStore 6917 // needed when using CMS with no conditional card marking 6918 instruct storeimmCM0_ordered(immI0 zero, memory mem) 6919 %{ 6920 match(Set mem (StoreCM mem zero)); 6921 6922 ins_cost(INSN_COST * 2); 6923 format %{ "storestore\n\t" 6924 "dmb ishst" 6925 "\n\tstrb zr, $mem\t# byte" %} 6926 6927 ins_encode(aarch64_enc_strb0_ordered(mem)); 6928 6929 ins_pipe(istore_mem); 6930 %} 6931 6932 // Store Byte 6933 instruct storeB(iRegIorL2I src, memory mem) 6934 %{ 6935 match(Set mem (StoreB mem src)); 6936 predicate(!needs_releasing_store(n)); 6937 6938 ins_cost(INSN_COST); 6939 format %{ "strb $src, $mem\t# byte" %} 6940 6941 ins_encode(aarch64_enc_strb(src, mem)); 6942 6943 ins_pipe(istore_reg_mem); 6944 %} 6945 6946 6947 instruct storeimmB0(immI0 zero, memory mem) 6948 %{ 6949 match(Set mem (StoreB mem zero)); 6950 predicate(!needs_releasing_store(n)); 6951 6952 ins_cost(INSN_COST); 6953 format %{ "strb rscractch2, $mem\t# byte" %} 6954 6955 ins_encode(aarch64_enc_strb0(mem)); 6956 6957 ins_pipe(istore_mem); 6958 %} 6959 6960 // Store Char/Short 6961 instruct storeC(iRegIorL2I src, memory mem) 6962 %{ 6963 match(Set mem (StoreC mem src)); 6964 predicate(!needs_releasing_store(n)); 6965 6966 ins_cost(INSN_COST); 6967 format %{ "strh $src, $mem\t# short" %} 6968 6969 ins_encode(aarch64_enc_strh(src, mem)); 6970 6971 ins_pipe(istore_reg_mem); 6972 %} 6973 6974 instruct storeimmC0(immI0 zero, memory mem) 6975 %{ 6976 match(Set mem (StoreC mem zero)); 6977 predicate(!needs_releasing_store(n)); 6978 6979 ins_cost(INSN_COST); 6980 format %{ "strh zr, $mem\t# short" %} 6981 6982 ins_encode(aarch64_enc_strh0(mem)); 6983 6984 ins_pipe(istore_mem); 6985 %} 6986 6987 // Store Integer 6988 6989 instruct storeI(iRegIorL2I src, memory mem) 6990 %{ 6991 match(Set mem(StoreI mem src)); 6992 predicate(!needs_releasing_store(n)); 6993 6994 ins_cost(INSN_COST); 6995 format %{ "strw $src, $mem\t# int" %} 6996 6997 ins_encode(aarch64_enc_strw(src, mem)); 6998 6999 ins_pipe(istore_reg_mem); 7000 %} 7001 7002 instruct storeimmI0(immI0 zero, memory mem) 7003 %{ 7004 match(Set mem(StoreI mem zero)); 7005 predicate(!needs_releasing_store(n)); 7006 7007 ins_cost(INSN_COST); 7008 format %{ "strw zr, $mem\t# int" %} 7009 7010 ins_encode(aarch64_enc_strw0(mem)); 7011 7012 ins_pipe(istore_mem); 7013 %} 7014 7015 // Store Long (64 bit signed) 7016 instruct storeL(iRegL src, memory mem) 7017 %{ 7018 match(Set mem (StoreL mem src)); 7019 predicate(!needs_releasing_store(n)); 7020 7021 ins_cost(INSN_COST); 7022 format %{ "str $src, $mem\t# int" %} 7023 7024 ins_encode(aarch64_enc_str(src, mem)); 7025 7026 ins_pipe(istore_reg_mem); 7027 %} 7028 7029 // Store Long (64 bit signed) 7030 instruct storeimmL0(immL0 zero, memory mem) 7031 %{ 7032 match(Set mem (StoreL mem zero)); 7033 predicate(!needs_releasing_store(n)); 7034 7035 ins_cost(INSN_COST); 7036 format %{ "str zr, $mem\t# int" %} 7037 7038 ins_encode(aarch64_enc_str0(mem)); 7039 7040 ins_pipe(istore_mem); 7041 %} 7042 7043 // Store Pointer 7044 instruct storeP(iRegP src, memory mem) 7045 %{ 7046 match(Set mem (StoreP mem src)); 7047 predicate(!needs_releasing_store(n)); 7048 7049 ins_cost(INSN_COST); 7050 format %{ "str $src, $mem\t# ptr" %} 7051 7052 ins_encode(aarch64_enc_str(src, mem)); 7053 7054 ins_pipe(istore_reg_mem); 7055 %} 7056 7057 // Store Pointer 7058 instruct storeimmP0(immP0 zero, memory mem) 7059 %{ 7060 match(Set mem (StoreP mem zero)); 7061 predicate(!needs_releasing_store(n)); 7062 7063 ins_cost(INSN_COST); 7064 format %{ "str zr, $mem\t# ptr" %} 7065 7066 ins_encode(aarch64_enc_str0(mem)); 7067 7068 ins_pipe(istore_mem); 7069 %} 7070 7071 // Store Compressed Pointer 7072 instruct storeN(iRegN src, memory mem) 7073 %{ 7074 match(Set mem (StoreN mem src)); 7075 predicate(!needs_releasing_store(n)); 7076 7077 ins_cost(INSN_COST); 7078 format %{ "strw $src, $mem\t# compressed ptr" %} 7079 7080 ins_encode(aarch64_enc_strw(src, mem)); 7081 7082 ins_pipe(istore_reg_mem); 7083 %} 7084 7085 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7086 %{ 7087 match(Set mem (StoreN mem zero)); 7088 predicate(Universe::narrow_oop_base() == NULL && 7089 Universe::narrow_klass_base() == NULL && 7090 (!needs_releasing_store(n))); 7091 7092 ins_cost(INSN_COST); 7093 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7094 7095 ins_encode(aarch64_enc_strw(heapbase, mem)); 7096 7097 ins_pipe(istore_reg_mem); 7098 %} 7099 7100 // Store Float 7101 instruct storeF(vRegF src, memory mem) 7102 %{ 7103 match(Set mem (StoreF mem src)); 7104 predicate(!needs_releasing_store(n)); 7105 7106 ins_cost(INSN_COST); 7107 format %{ "strs $src, $mem\t# float" %} 7108 7109 ins_encode( aarch64_enc_strs(src, mem) ); 7110 7111 ins_pipe(pipe_class_memory); 7112 %} 7113 7114 // TODO 7115 // implement storeImmF0 and storeFImmPacked 7116 7117 // Store Double 7118 instruct storeD(vRegD src, memory mem) 7119 %{ 7120 match(Set mem (StoreD mem src)); 7121 predicate(!needs_releasing_store(n)); 7122 7123 ins_cost(INSN_COST); 7124 format %{ "strd $src, $mem\t# double" %} 7125 7126 ins_encode( aarch64_enc_strd(src, mem) ); 7127 7128 ins_pipe(pipe_class_memory); 7129 %} 7130 7131 // Store Compressed Klass Pointer 7132 instruct storeNKlass(iRegN src, memory mem) 7133 %{ 7134 predicate(!needs_releasing_store(n)); 7135 match(Set mem (StoreNKlass mem src)); 7136 7137 ins_cost(INSN_COST); 7138 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7139 7140 ins_encode(aarch64_enc_strw(src, mem)); 7141 7142 ins_pipe(istore_reg_mem); 7143 %} 7144 7145 // TODO 7146 // implement storeImmD0 and storeDImmPacked 7147 7148 // prefetch instructions 7149 // Must be safe to execute with invalid address (cannot fault). 7150 7151 instruct prefetchalloc( memory mem ) %{ 7152 match(PrefetchAllocation mem); 7153 7154 ins_cost(INSN_COST); 7155 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7156 7157 ins_encode( aarch64_enc_prefetchw(mem) ); 7158 7159 ins_pipe(iload_prefetch); 7160 %} 7161 7162 // ---------------- volatile loads and stores ---------------- 7163 7164 // Load Byte (8 bit signed) 7165 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7166 %{ 7167 match(Set dst (LoadB mem)); 7168 7169 ins_cost(VOLATILE_REF_COST); 7170 format %{ "ldarsb $dst, $mem\t# byte" %} 7171 7172 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7173 7174 ins_pipe(pipe_serial); 7175 %} 7176 7177 // Load Byte (8 bit signed) into long 7178 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7179 %{ 7180 match(Set dst (ConvI2L (LoadB mem))); 7181 7182 ins_cost(VOLATILE_REF_COST); 7183 format %{ "ldarsb $dst, $mem\t# byte" %} 7184 7185 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7186 7187 ins_pipe(pipe_serial); 7188 %} 7189 7190 // Load Byte (8 bit unsigned) 7191 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7192 %{ 7193 match(Set dst (LoadUB mem)); 7194 7195 ins_cost(VOLATILE_REF_COST); 7196 format %{ "ldarb $dst, $mem\t# byte" %} 7197 7198 ins_encode(aarch64_enc_ldarb(dst, mem)); 7199 7200 ins_pipe(pipe_serial); 7201 %} 7202 7203 // Load Byte (8 bit unsigned) into long 7204 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7205 %{ 7206 match(Set dst (ConvI2L (LoadUB mem))); 7207 7208 ins_cost(VOLATILE_REF_COST); 7209 format %{ "ldarb $dst, $mem\t# byte" %} 7210 7211 ins_encode(aarch64_enc_ldarb(dst, mem)); 7212 7213 ins_pipe(pipe_serial); 7214 %} 7215 7216 // Load Short (16 bit signed) 7217 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7218 %{ 7219 match(Set dst (LoadS mem)); 7220 7221 ins_cost(VOLATILE_REF_COST); 7222 format %{ "ldarshw $dst, $mem\t# short" %} 7223 7224 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7225 7226 ins_pipe(pipe_serial); 7227 %} 7228 7229 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7230 %{ 7231 match(Set dst (LoadUS mem)); 7232 7233 ins_cost(VOLATILE_REF_COST); 7234 format %{ "ldarhw $dst, $mem\t# short" %} 7235 7236 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7237 7238 ins_pipe(pipe_serial); 7239 %} 7240 7241 // Load Short/Char (16 bit unsigned) into long 7242 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7243 %{ 7244 match(Set dst (ConvI2L (LoadUS mem))); 7245 7246 ins_cost(VOLATILE_REF_COST); 7247 format %{ "ldarh $dst, $mem\t# short" %} 7248 7249 ins_encode(aarch64_enc_ldarh(dst, mem)); 7250 7251 ins_pipe(pipe_serial); 7252 %} 7253 7254 // Load Short/Char (16 bit signed) into long 7255 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7256 %{ 7257 match(Set dst (ConvI2L (LoadS mem))); 7258 7259 ins_cost(VOLATILE_REF_COST); 7260 format %{ "ldarh $dst, $mem\t# short" %} 7261 7262 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7263 7264 ins_pipe(pipe_serial); 7265 %} 7266 7267 // Load Integer (32 bit signed) 7268 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7269 %{ 7270 match(Set dst (LoadI mem)); 7271 7272 ins_cost(VOLATILE_REF_COST); 7273 format %{ "ldarw $dst, $mem\t# int" %} 7274 7275 ins_encode(aarch64_enc_ldarw(dst, mem)); 7276 7277 ins_pipe(pipe_serial); 7278 %} 7279 7280 // Load Integer (32 bit unsigned) into long 7281 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7282 %{ 7283 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7284 7285 ins_cost(VOLATILE_REF_COST); 7286 format %{ "ldarw $dst, $mem\t# int" %} 7287 7288 ins_encode(aarch64_enc_ldarw(dst, mem)); 7289 7290 ins_pipe(pipe_serial); 7291 %} 7292 7293 // Load Long (64 bit signed) 7294 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7295 %{ 7296 match(Set dst (LoadL mem)); 7297 7298 ins_cost(VOLATILE_REF_COST); 7299 format %{ "ldar $dst, $mem\t# int" %} 7300 7301 ins_encode(aarch64_enc_ldar(dst, mem)); 7302 7303 ins_pipe(pipe_serial); 7304 %} 7305 7306 // Load Pointer 7307 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7308 %{ 7309 match(Set dst (LoadP mem)); 7310 7311 ins_cost(VOLATILE_REF_COST); 7312 format %{ "ldar $dst, $mem\t# ptr" %} 7313 7314 ins_encode(aarch64_enc_ldar(dst, mem)); 7315 7316 ins_pipe(pipe_serial); 7317 %} 7318 7319 // Load Compressed Pointer 7320 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7321 %{ 7322 match(Set dst (LoadN mem)); 7323 7324 ins_cost(VOLATILE_REF_COST); 7325 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7326 7327 ins_encode(aarch64_enc_ldarw(dst, mem)); 7328 7329 ins_pipe(pipe_serial); 7330 %} 7331 7332 // Load Float 7333 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7334 %{ 7335 match(Set dst (LoadF mem)); 7336 7337 ins_cost(VOLATILE_REF_COST); 7338 format %{ "ldars $dst, $mem\t# float" %} 7339 7340 ins_encode( aarch64_enc_fldars(dst, mem) ); 7341 7342 ins_pipe(pipe_serial); 7343 %} 7344 7345 // Load Double 7346 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7347 %{ 7348 match(Set dst (LoadD mem)); 7349 7350 ins_cost(VOLATILE_REF_COST); 7351 format %{ "ldard $dst, $mem\t# double" %} 7352 7353 ins_encode( aarch64_enc_fldard(dst, mem) ); 7354 7355 ins_pipe(pipe_serial); 7356 %} 7357 7358 // Store Byte 7359 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7360 %{ 7361 match(Set mem (StoreB mem src)); 7362 7363 ins_cost(VOLATILE_REF_COST); 7364 format %{ "stlrb $src, $mem\t# byte" %} 7365 7366 ins_encode(aarch64_enc_stlrb(src, mem)); 7367 7368 ins_pipe(pipe_class_memory); 7369 %} 7370 7371 // Store Char/Short 7372 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7373 %{ 7374 match(Set mem (StoreC mem src)); 7375 7376 ins_cost(VOLATILE_REF_COST); 7377 format %{ "stlrh $src, $mem\t# short" %} 7378 7379 ins_encode(aarch64_enc_stlrh(src, mem)); 7380 7381 ins_pipe(pipe_class_memory); 7382 %} 7383 7384 // Store Integer 7385 7386 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7387 %{ 7388 match(Set mem(StoreI mem src)); 7389 7390 ins_cost(VOLATILE_REF_COST); 7391 format %{ "stlrw $src, $mem\t# int" %} 7392 7393 ins_encode(aarch64_enc_stlrw(src, mem)); 7394 7395 ins_pipe(pipe_class_memory); 7396 %} 7397 7398 // Store Long (64 bit signed) 7399 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7400 %{ 7401 match(Set mem (StoreL mem src)); 7402 7403 ins_cost(VOLATILE_REF_COST); 7404 format %{ "stlr $src, $mem\t# int" %} 7405 7406 ins_encode(aarch64_enc_stlr(src, mem)); 7407 7408 ins_pipe(pipe_class_memory); 7409 %} 7410 7411 // Store Pointer 7412 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7413 %{ 7414 match(Set mem (StoreP mem src)); 7415 7416 ins_cost(VOLATILE_REF_COST); 7417 format %{ "stlr $src, $mem\t# ptr" %} 7418 7419 ins_encode(aarch64_enc_stlr(src, mem)); 7420 7421 ins_pipe(pipe_class_memory); 7422 %} 7423 7424 // Store Compressed Pointer 7425 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7426 %{ 7427 match(Set mem (StoreN mem src)); 7428 7429 ins_cost(VOLATILE_REF_COST); 7430 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7431 7432 ins_encode(aarch64_enc_stlrw(src, mem)); 7433 7434 ins_pipe(pipe_class_memory); 7435 %} 7436 7437 // Store Float 7438 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7439 %{ 7440 match(Set mem (StoreF mem src)); 7441 7442 ins_cost(VOLATILE_REF_COST); 7443 format %{ "stlrs $src, $mem\t# float" %} 7444 7445 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7446 7447 ins_pipe(pipe_class_memory); 7448 %} 7449 7450 // TODO 7451 // implement storeImmF0 and storeFImmPacked 7452 7453 // Store Double 7454 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7455 %{ 7456 match(Set mem (StoreD mem src)); 7457 7458 ins_cost(VOLATILE_REF_COST); 7459 format %{ "stlrd $src, $mem\t# double" %} 7460 7461 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7462 7463 ins_pipe(pipe_class_memory); 7464 %} 7465 7466 // ---------------- end of volatile loads and stores ---------------- 7467 7468 // ============================================================================ 7469 // BSWAP Instructions 7470 7471 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7472 match(Set dst (ReverseBytesI src)); 7473 7474 ins_cost(INSN_COST); 7475 format %{ "revw $dst, $src" %} 7476 7477 ins_encode %{ 7478 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7479 %} 7480 7481 ins_pipe(ialu_reg); 7482 %} 7483 7484 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7485 match(Set dst (ReverseBytesL src)); 7486 7487 ins_cost(INSN_COST); 7488 format %{ "rev $dst, $src" %} 7489 7490 ins_encode %{ 7491 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7492 %} 7493 7494 ins_pipe(ialu_reg); 7495 %} 7496 7497 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7498 match(Set dst (ReverseBytesUS src)); 7499 7500 ins_cost(INSN_COST); 7501 format %{ "rev16w $dst, $src" %} 7502 7503 ins_encode %{ 7504 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7505 %} 7506 7507 ins_pipe(ialu_reg); 7508 %} 7509 7510 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7511 match(Set dst (ReverseBytesS src)); 7512 7513 ins_cost(INSN_COST); 7514 format %{ "rev16w $dst, $src\n\t" 7515 "sbfmw $dst, $dst, #0, #15" %} 7516 7517 ins_encode %{ 7518 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7519 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7520 %} 7521 7522 ins_pipe(ialu_reg); 7523 %} 7524 7525 // ============================================================================ 7526 // Zero Count Instructions 7527 7528 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7529 match(Set dst (CountLeadingZerosI src)); 7530 7531 ins_cost(INSN_COST); 7532 format %{ "clzw $dst, $src" %} 7533 ins_encode %{ 7534 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7535 %} 7536 7537 ins_pipe(ialu_reg); 7538 %} 7539 7540 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7541 match(Set dst (CountLeadingZerosL src)); 7542 7543 ins_cost(INSN_COST); 7544 format %{ "clz $dst, $src" %} 7545 ins_encode %{ 7546 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7547 %} 7548 7549 ins_pipe(ialu_reg); 7550 %} 7551 7552 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7553 match(Set dst (CountTrailingZerosI src)); 7554 7555 ins_cost(INSN_COST * 2); 7556 format %{ "rbitw $dst, $src\n\t" 7557 "clzw $dst, $dst" %} 7558 ins_encode %{ 7559 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7560 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7561 %} 7562 7563 ins_pipe(ialu_reg); 7564 %} 7565 7566 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7567 match(Set dst (CountTrailingZerosL src)); 7568 7569 ins_cost(INSN_COST * 2); 7570 format %{ "rbit $dst, $src\n\t" 7571 "clz $dst, $dst" %} 7572 ins_encode %{ 7573 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7574 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7575 %} 7576 7577 ins_pipe(ialu_reg); 7578 %} 7579 7580 //---------- Population Count Instructions ------------------------------------- 7581 // 7582 7583 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7584 predicate(UsePopCountInstruction); 7585 match(Set dst (PopCountI src)); 7586 effect(TEMP tmp); 7587 ins_cost(INSN_COST * 13); 7588 7589 format %{ "movw $src, $src\n\t" 7590 "mov $tmp, $src\t# vector (1D)\n\t" 7591 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7592 "addv $tmp, $tmp\t# vector (8B)\n\t" 7593 "mov $dst, $tmp\t# vector (1D)" %} 7594 ins_encode %{ 7595 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7596 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7597 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7598 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7599 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7600 %} 7601 7602 ins_pipe(pipe_class_default); 7603 %} 7604 7605 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7606 predicate(UsePopCountInstruction); 7607 match(Set dst (PopCountI (LoadI mem))); 7608 effect(TEMP tmp); 7609 ins_cost(INSN_COST * 13); 7610 7611 format %{ "ldrs $tmp, $mem\n\t" 7612 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7613 "addv $tmp, $tmp\t# vector (8B)\n\t" 7614 "mov $dst, $tmp\t# vector (1D)" %} 7615 ins_encode %{ 7616 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7617 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7618 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7619 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7620 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7621 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7622 %} 7623 7624 ins_pipe(pipe_class_default); 7625 %} 7626 7627 // Note: Long.bitCount(long) returns an int. 7628 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7629 predicate(UsePopCountInstruction); 7630 match(Set dst (PopCountL src)); 7631 effect(TEMP tmp); 7632 ins_cost(INSN_COST * 13); 7633 7634 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7635 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7636 "addv $tmp, $tmp\t# vector (8B)\n\t" 7637 "mov $dst, $tmp\t# vector (1D)" %} 7638 ins_encode %{ 7639 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7640 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7641 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7642 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7643 %} 7644 7645 ins_pipe(pipe_class_default); 7646 %} 7647 7648 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7649 predicate(UsePopCountInstruction); 7650 match(Set dst (PopCountL (LoadL mem))); 7651 effect(TEMP tmp); 7652 ins_cost(INSN_COST * 13); 7653 7654 format %{ "ldrd $tmp, $mem\n\t" 7655 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7656 "addv $tmp, $tmp\t# vector (8B)\n\t" 7657 "mov $dst, $tmp\t# vector (1D)" %} 7658 ins_encode %{ 7659 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7660 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7661 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7662 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7663 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7664 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7665 %} 7666 7667 ins_pipe(pipe_class_default); 7668 %} 7669 7670 // ============================================================================ 7671 // MemBar Instruction 7672 7673 instruct load_fence() %{ 7674 match(LoadFence); 7675 ins_cost(VOLATILE_REF_COST); 7676 7677 format %{ "load_fence" %} 7678 7679 ins_encode %{ 7680 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7681 %} 7682 ins_pipe(pipe_serial); 7683 %} 7684 7685 instruct unnecessary_membar_acquire() %{ 7686 predicate(unnecessary_acquire(n)); 7687 match(MemBarAcquire); 7688 ins_cost(0); 7689 7690 format %{ "membar_acquire (elided)" %} 7691 7692 ins_encode %{ 7693 __ block_comment("membar_acquire (elided)"); 7694 %} 7695 7696 ins_pipe(pipe_class_empty); 7697 %} 7698 7699 instruct membar_acquire() %{ 7700 match(MemBarAcquire); 7701 ins_cost(VOLATILE_REF_COST); 7702 7703 format %{ "membar_acquire\n\t" 7704 "dmb ish" %} 7705 7706 ins_encode %{ 7707 __ block_comment("membar_acquire"); 7708 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7709 %} 7710 7711 ins_pipe(pipe_serial); 7712 %} 7713 7714 7715 instruct membar_acquire_lock() %{ 7716 match(MemBarAcquireLock); 7717 ins_cost(VOLATILE_REF_COST); 7718 7719 format %{ "membar_acquire_lock (elided)" %} 7720 7721 ins_encode %{ 7722 __ block_comment("membar_acquire_lock (elided)"); 7723 %} 7724 7725 ins_pipe(pipe_serial); 7726 %} 7727 7728 instruct store_fence() %{ 7729 match(StoreFence); 7730 ins_cost(VOLATILE_REF_COST); 7731 7732 format %{ "store_fence" %} 7733 7734 ins_encode %{ 7735 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7736 %} 7737 ins_pipe(pipe_serial); 7738 %} 7739 7740 instruct unnecessary_membar_release() %{ 7741 predicate(unnecessary_release(n)); 7742 match(MemBarRelease); 7743 ins_cost(0); 7744 7745 format %{ "membar_release (elided)" %} 7746 7747 ins_encode %{ 7748 __ block_comment("membar_release (elided)"); 7749 %} 7750 ins_pipe(pipe_serial); 7751 %} 7752 7753 instruct membar_release() %{ 7754 match(MemBarRelease); 7755 ins_cost(VOLATILE_REF_COST); 7756 7757 format %{ "membar_release\n\t" 7758 "dmb ish" %} 7759 7760 ins_encode %{ 7761 __ block_comment("membar_release"); 7762 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7763 %} 7764 ins_pipe(pipe_serial); 7765 %} 7766 7767 instruct membar_storestore() %{ 7768 match(MemBarStoreStore); 7769 ins_cost(VOLATILE_REF_COST); 7770 7771 format %{ "MEMBAR-store-store" %} 7772 7773 ins_encode %{ 7774 __ membar(Assembler::StoreStore); 7775 %} 7776 ins_pipe(pipe_serial); 7777 %} 7778 7779 instruct membar_release_lock() %{ 7780 match(MemBarReleaseLock); 7781 ins_cost(VOLATILE_REF_COST); 7782 7783 format %{ "membar_release_lock (elided)" %} 7784 7785 ins_encode %{ 7786 __ block_comment("membar_release_lock (elided)"); 7787 %} 7788 7789 ins_pipe(pipe_serial); 7790 %} 7791 7792 instruct unnecessary_membar_volatile() %{ 7793 predicate(unnecessary_volatile(n)); 7794 match(MemBarVolatile); 7795 ins_cost(0); 7796 7797 format %{ "membar_volatile (elided)" %} 7798 7799 ins_encode %{ 7800 __ block_comment("membar_volatile (elided)"); 7801 %} 7802 7803 ins_pipe(pipe_serial); 7804 %} 7805 7806 instruct membar_volatile() %{ 7807 match(MemBarVolatile); 7808 ins_cost(VOLATILE_REF_COST*100); 7809 7810 format %{ "membar_volatile\n\t" 7811 "dmb ish"%} 7812 7813 ins_encode %{ 7814 __ block_comment("membar_volatile"); 7815 __ membar(Assembler::StoreLoad); 7816 %} 7817 7818 ins_pipe(pipe_serial); 7819 %} 7820 7821 // ============================================================================ 7822 // Cast/Convert Instructions 7823 7824 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7825 match(Set dst (CastX2P src)); 7826 7827 ins_cost(INSN_COST); 7828 format %{ "mov $dst, $src\t# long -> ptr" %} 7829 7830 ins_encode %{ 7831 if ($dst$$reg != $src$$reg) { 7832 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7833 } 7834 %} 7835 7836 ins_pipe(ialu_reg); 7837 %} 7838 7839 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7840 match(Set dst (CastP2X src)); 7841 7842 ins_cost(INSN_COST); 7843 format %{ "mov $dst, $src\t# ptr -> long" %} 7844 7845 ins_encode %{ 7846 if ($dst$$reg != $src$$reg) { 7847 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7848 } 7849 %} 7850 7851 ins_pipe(ialu_reg); 7852 %} 7853 7854 // Convert oop into int for vectors alignment masking 7855 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7856 match(Set dst (ConvL2I (CastP2X src))); 7857 7858 ins_cost(INSN_COST); 7859 format %{ "movw $dst, $src\t# ptr -> int" %} 7860 ins_encode %{ 7861 __ movw($dst$$Register, $src$$Register); 7862 %} 7863 7864 ins_pipe(ialu_reg); 7865 %} 7866 7867 // Convert compressed oop into int for vectors alignment masking 7868 // in case of 32bit oops (heap < 4Gb). 7869 instruct convN2I(iRegINoSp dst, iRegN src) 7870 %{ 7871 predicate(Universe::narrow_oop_shift() == 0); 7872 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7873 7874 ins_cost(INSN_COST); 7875 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7876 ins_encode %{ 7877 __ movw($dst$$Register, $src$$Register); 7878 %} 7879 7880 ins_pipe(ialu_reg); 7881 %} 7882 7883 7884 // Convert oop pointer into compressed form 7885 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7886 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7887 match(Set dst (EncodeP src)); 7888 effect(KILL cr); 7889 ins_cost(INSN_COST * 3); 7890 format %{ "encode_heap_oop $dst, $src" %} 7891 ins_encode %{ 7892 Register s = $src$$Register; 7893 Register d = $dst$$Register; 7894 __ encode_heap_oop(d, s); 7895 %} 7896 ins_pipe(ialu_reg); 7897 %} 7898 7899 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7900 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7901 match(Set dst (EncodeP src)); 7902 ins_cost(INSN_COST * 3); 7903 format %{ "encode_heap_oop_not_null $dst, $src" %} 7904 ins_encode %{ 7905 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7906 %} 7907 ins_pipe(ialu_reg); 7908 %} 7909 7910 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7911 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7912 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7913 match(Set dst (DecodeN src)); 7914 ins_cost(INSN_COST * 3); 7915 format %{ "decode_heap_oop $dst, $src" %} 7916 ins_encode %{ 7917 Register s = $src$$Register; 7918 Register d = $dst$$Register; 7919 __ decode_heap_oop(d, s); 7920 %} 7921 ins_pipe(ialu_reg); 7922 %} 7923 7924 instruct decodeHeapOop_not_null(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_not_null $dst, $src" %} 7930 ins_encode %{ 7931 Register s = $src$$Register; 7932 Register d = $dst$$Register; 7933 __ decode_heap_oop_not_null(d, s); 7934 %} 7935 ins_pipe(ialu_reg); 7936 %} 7937 7938 // n.b. AArch64 implementations of encode_klass_not_null and 7939 // decode_klass_not_null do not modify the flags register so, unlike 7940 // Intel, we don't kill CR as a side effect here 7941 7942 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7943 match(Set dst (EncodePKlass src)); 7944 7945 ins_cost(INSN_COST * 3); 7946 format %{ "encode_klass_not_null $dst,$src" %} 7947 7948 ins_encode %{ 7949 Register src_reg = as_Register($src$$reg); 7950 Register dst_reg = as_Register($dst$$reg); 7951 __ encode_klass_not_null(dst_reg, src_reg); 7952 %} 7953 7954 ins_pipe(ialu_reg); 7955 %} 7956 7957 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7958 match(Set dst (DecodeNKlass src)); 7959 7960 ins_cost(INSN_COST * 3); 7961 format %{ "decode_klass_not_null $dst,$src" %} 7962 7963 ins_encode %{ 7964 Register src_reg = as_Register($src$$reg); 7965 Register dst_reg = as_Register($dst$$reg); 7966 if (dst_reg != src_reg) { 7967 __ decode_klass_not_null(dst_reg, src_reg); 7968 } else { 7969 __ decode_klass_not_null(dst_reg); 7970 } 7971 %} 7972 7973 ins_pipe(ialu_reg); 7974 %} 7975 7976 instruct checkCastPP(iRegPNoSp dst) 7977 %{ 7978 match(Set dst (CheckCastPP dst)); 7979 7980 size(0); 7981 format %{ "# checkcastPP of $dst" %} 7982 ins_encode(/* empty encoding */); 7983 ins_pipe(pipe_class_empty); 7984 %} 7985 7986 instruct castPP(iRegPNoSp dst) 7987 %{ 7988 match(Set dst (CastPP dst)); 7989 7990 size(0); 7991 format %{ "# castPP of $dst" %} 7992 ins_encode(/* empty encoding */); 7993 ins_pipe(pipe_class_empty); 7994 %} 7995 7996 instruct castII(iRegI dst) 7997 %{ 7998 match(Set dst (CastII dst)); 7999 8000 size(0); 8001 format %{ "# castII of $dst" %} 8002 ins_encode(/* empty encoding */); 8003 ins_cost(0); 8004 ins_pipe(pipe_class_empty); 8005 %} 8006 8007 // ============================================================================ 8008 // Atomic operation instructions 8009 // 8010 // Intel and SPARC both implement Ideal Node LoadPLocked and 8011 // Store{PIL}Conditional instructions using a normal load for the 8012 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8013 // 8014 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8015 // pair to lock object allocations from Eden space when not using 8016 // TLABs. 8017 // 8018 // There does not appear to be a Load{IL}Locked Ideal Node and the 8019 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8020 // and to use StoreIConditional only for 32-bit and StoreLConditional 8021 // only for 64-bit. 8022 // 8023 // We implement LoadPLocked and StorePLocked instructions using, 8024 // respectively the AArch64 hw load-exclusive and store-conditional 8025 // instructions. Whereas we must implement each of 8026 // Store{IL}Conditional using a CAS which employs a pair of 8027 // instructions comprising a load-exclusive followed by a 8028 // store-conditional. 8029 8030 8031 // Locked-load (linked load) of the current heap-top 8032 // used when updating the eden heap top 8033 // implemented using ldaxr on AArch64 8034 8035 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8036 %{ 8037 match(Set dst (LoadPLocked mem)); 8038 8039 ins_cost(VOLATILE_REF_COST); 8040 8041 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8042 8043 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8044 8045 ins_pipe(pipe_serial); 8046 %} 8047 8048 // Conditional-store of the updated heap-top. 8049 // Used during allocation of the shared heap. 8050 // Sets flag (EQ) on success. 8051 // implemented using stlxr on AArch64. 8052 8053 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8054 %{ 8055 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8056 8057 ins_cost(VOLATILE_REF_COST); 8058 8059 // TODO 8060 // do we need to do a store-conditional release or can we just use a 8061 // plain store-conditional? 8062 8063 format %{ 8064 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8065 "cmpw rscratch1, zr\t# EQ on successful write" 8066 %} 8067 8068 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8069 8070 ins_pipe(pipe_serial); 8071 %} 8072 8073 8074 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8075 // when attempting to rebias a lock towards the current thread. We 8076 // must use the acquire form of cmpxchg in order to guarantee acquire 8077 // semantics in this case. 8078 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8079 %{ 8080 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8081 8082 ins_cost(VOLATILE_REF_COST); 8083 8084 format %{ 8085 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8086 "cmpw rscratch1, zr\t# EQ on successful write" 8087 %} 8088 8089 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8090 8091 ins_pipe(pipe_slow); 8092 %} 8093 8094 // storeIConditional also has acquire semantics, for no better reason 8095 // than matching storeLConditional. At the time of writing this 8096 // comment storeIConditional was not used anywhere by AArch64. 8097 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8098 %{ 8099 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8100 8101 ins_cost(VOLATILE_REF_COST); 8102 8103 format %{ 8104 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8105 "cmpw rscratch1, zr\t# EQ on successful write" 8106 %} 8107 8108 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8109 8110 ins_pipe(pipe_slow); 8111 %} 8112 8113 // standard CompareAndSwapX when we are using barriers 8114 // these have higher priority than the rules selected by a predicate 8115 8116 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8117 // can't match them 8118 8119 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8120 8121 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8122 ins_cost(2 * VOLATILE_REF_COST); 8123 8124 effect(KILL cr); 8125 8126 format %{ 8127 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8128 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8129 %} 8130 8131 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8132 aarch64_enc_cset_eq(res)); 8133 8134 ins_pipe(pipe_slow); 8135 %} 8136 8137 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8138 8139 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8140 ins_cost(2 * VOLATILE_REF_COST); 8141 8142 effect(KILL cr); 8143 8144 format %{ 8145 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8146 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8147 %} 8148 8149 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8150 aarch64_enc_cset_eq(res)); 8151 8152 ins_pipe(pipe_slow); 8153 %} 8154 8155 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8156 8157 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8158 ins_cost(2 * VOLATILE_REF_COST); 8159 8160 effect(KILL cr); 8161 8162 format %{ 8163 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8164 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8165 %} 8166 8167 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8168 aarch64_enc_cset_eq(res)); 8169 8170 ins_pipe(pipe_slow); 8171 %} 8172 8173 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8174 8175 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8176 ins_cost(2 * VOLATILE_REF_COST); 8177 8178 effect(KILL cr); 8179 8180 format %{ 8181 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8182 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8183 %} 8184 8185 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8186 aarch64_enc_cset_eq(res)); 8187 8188 ins_pipe(pipe_slow); 8189 %} 8190 8191 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8192 8193 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8194 ins_cost(2 * VOLATILE_REF_COST); 8195 8196 effect(KILL cr); 8197 8198 format %{ 8199 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8200 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8201 %} 8202 8203 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8204 aarch64_enc_cset_eq(res)); 8205 8206 ins_pipe(pipe_slow); 8207 %} 8208 8209 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8210 8211 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8212 ins_cost(2 * VOLATILE_REF_COST); 8213 8214 effect(KILL cr); 8215 8216 format %{ 8217 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8218 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8219 %} 8220 8221 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8222 aarch64_enc_cset_eq(res)); 8223 8224 ins_pipe(pipe_slow); 8225 %} 8226 8227 // alternative CompareAndSwapX when we are eliding barriers 8228 8229 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8230 8231 predicate(needs_acquiring_load_exclusive(n)); 8232 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8233 ins_cost(VOLATILE_REF_COST); 8234 8235 effect(KILL cr); 8236 8237 format %{ 8238 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8239 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8240 %} 8241 8242 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8243 aarch64_enc_cset_eq(res)); 8244 8245 ins_pipe(pipe_slow); 8246 %} 8247 8248 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8249 8250 predicate(needs_acquiring_load_exclusive(n)); 8251 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8252 ins_cost(VOLATILE_REF_COST); 8253 8254 effect(KILL cr); 8255 8256 format %{ 8257 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8258 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8259 %} 8260 8261 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8262 aarch64_enc_cset_eq(res)); 8263 8264 ins_pipe(pipe_slow); 8265 %} 8266 8267 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8268 8269 predicate(needs_acquiring_load_exclusive(n)); 8270 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8271 ins_cost(VOLATILE_REF_COST); 8272 8273 effect(KILL cr); 8274 8275 format %{ 8276 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8277 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8278 %} 8279 8280 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8281 aarch64_enc_cset_eq(res)); 8282 8283 ins_pipe(pipe_slow); 8284 %} 8285 8286 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8287 8288 predicate(needs_acquiring_load_exclusive(n)); 8289 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8290 ins_cost(VOLATILE_REF_COST); 8291 8292 effect(KILL cr); 8293 8294 format %{ 8295 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8296 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8297 %} 8298 8299 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8300 aarch64_enc_cset_eq(res)); 8301 8302 ins_pipe(pipe_slow); 8303 %} 8304 8305 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8306 8307 predicate(needs_acquiring_load_exclusive(n)); 8308 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8309 ins_cost(VOLATILE_REF_COST); 8310 8311 effect(KILL cr); 8312 8313 format %{ 8314 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8315 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8316 %} 8317 8318 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8319 aarch64_enc_cset_eq(res)); 8320 8321 ins_pipe(pipe_slow); 8322 %} 8323 8324 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8325 8326 predicate(needs_acquiring_load_exclusive(n)); 8327 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8328 ins_cost(VOLATILE_REF_COST); 8329 8330 effect(KILL cr); 8331 8332 format %{ 8333 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8334 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8335 %} 8336 8337 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8338 aarch64_enc_cset_eq(res)); 8339 8340 ins_pipe(pipe_slow); 8341 %} 8342 8343 8344 // --------------------------------------------------------------------- 8345 8346 8347 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8348 8349 // Sundry CAS operations. Note that release is always true, 8350 // regardless of the memory ordering of the CAS. This is because we 8351 // need the volatile case to be sequentially consistent but there is 8352 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8353 // can't check the type of memory ordering here, so we always emit a 8354 // STLXR. 8355 8356 // This section is generated from aarch64_ad_cas.m4 8357 8358 8359 8360 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8361 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8362 ins_cost(2 * VOLATILE_REF_COST); 8363 effect(TEMP_DEF res, KILL cr); 8364 format %{ 8365 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8366 %} 8367 ins_encode %{ 8368 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8369 Assembler::byte, /*acquire*/ false, /*release*/ true, 8370 /*weak*/ false, $res$$Register); 8371 __ sxtbw($res$$Register, $res$$Register); 8372 %} 8373 ins_pipe(pipe_slow); 8374 %} 8375 8376 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8377 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8378 ins_cost(2 * VOLATILE_REF_COST); 8379 effect(TEMP_DEF res, KILL cr); 8380 format %{ 8381 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8382 %} 8383 ins_encode %{ 8384 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8385 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8386 /*weak*/ false, $res$$Register); 8387 __ sxthw($res$$Register, $res$$Register); 8388 %} 8389 ins_pipe(pipe_slow); 8390 %} 8391 8392 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8393 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8394 ins_cost(2 * VOLATILE_REF_COST); 8395 effect(TEMP_DEF res, KILL cr); 8396 format %{ 8397 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8398 %} 8399 ins_encode %{ 8400 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8401 Assembler::word, /*acquire*/ false, /*release*/ true, 8402 /*weak*/ false, $res$$Register); 8403 %} 8404 ins_pipe(pipe_slow); 8405 %} 8406 8407 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8408 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8409 ins_cost(2 * VOLATILE_REF_COST); 8410 effect(TEMP_DEF res, KILL cr); 8411 format %{ 8412 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8413 %} 8414 ins_encode %{ 8415 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8416 Assembler::xword, /*acquire*/ false, /*release*/ true, 8417 /*weak*/ false, $res$$Register); 8418 %} 8419 ins_pipe(pipe_slow); 8420 %} 8421 8422 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8423 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8424 ins_cost(2 * VOLATILE_REF_COST); 8425 effect(TEMP_DEF res, KILL cr); 8426 format %{ 8427 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8428 %} 8429 ins_encode %{ 8430 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8431 Assembler::word, /*acquire*/ false, /*release*/ true, 8432 /*weak*/ false, $res$$Register); 8433 %} 8434 ins_pipe(pipe_slow); 8435 %} 8436 8437 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8438 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8439 ins_cost(2 * VOLATILE_REF_COST); 8440 effect(TEMP_DEF res, KILL cr); 8441 format %{ 8442 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8443 %} 8444 ins_encode %{ 8445 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8446 Assembler::xword, /*acquire*/ false, /*release*/ true, 8447 /*weak*/ false, $res$$Register); 8448 %} 8449 ins_pipe(pipe_slow); 8450 %} 8451 8452 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8453 predicate(needs_acquiring_load_exclusive(n)); 8454 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8455 ins_cost(VOLATILE_REF_COST); 8456 effect(TEMP_DEF res, KILL cr); 8457 format %{ 8458 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8459 %} 8460 ins_encode %{ 8461 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8462 Assembler::byte, /*acquire*/ true, /*release*/ true, 8463 /*weak*/ false, $res$$Register); 8464 __ sxtbw($res$$Register, $res$$Register); 8465 %} 8466 ins_pipe(pipe_slow); 8467 %} 8468 8469 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8470 predicate(needs_acquiring_load_exclusive(n)); 8471 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8472 ins_cost(VOLATILE_REF_COST); 8473 effect(TEMP_DEF res, KILL cr); 8474 format %{ 8475 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8476 %} 8477 ins_encode %{ 8478 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8479 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8480 /*weak*/ false, $res$$Register); 8481 __ sxthw($res$$Register, $res$$Register); 8482 %} 8483 ins_pipe(pipe_slow); 8484 %} 8485 8486 8487 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8488 predicate(needs_acquiring_load_exclusive(n)); 8489 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8490 ins_cost(VOLATILE_REF_COST); 8491 effect(TEMP_DEF res, KILL cr); 8492 format %{ 8493 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8494 %} 8495 ins_encode %{ 8496 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8497 Assembler::word, /*acquire*/ true, /*release*/ true, 8498 /*weak*/ false, $res$$Register); 8499 %} 8500 ins_pipe(pipe_slow); 8501 %} 8502 8503 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8504 predicate(needs_acquiring_load_exclusive(n)); 8505 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8506 ins_cost(VOLATILE_REF_COST); 8507 effect(TEMP_DEF res, KILL cr); 8508 format %{ 8509 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8510 %} 8511 ins_encode %{ 8512 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8513 Assembler::xword, /*acquire*/ true, /*release*/ true, 8514 /*weak*/ false, $res$$Register); 8515 %} 8516 ins_pipe(pipe_slow); 8517 %} 8518 8519 8520 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8521 predicate(needs_acquiring_load_exclusive(n)); 8522 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8523 ins_cost(VOLATILE_REF_COST); 8524 effect(TEMP_DEF res, KILL cr); 8525 format %{ 8526 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8527 %} 8528 ins_encode %{ 8529 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8530 Assembler::word, /*acquire*/ true, /*release*/ true, 8531 /*weak*/ false, $res$$Register); 8532 %} 8533 ins_pipe(pipe_slow); 8534 %} 8535 8536 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8537 predicate(needs_acquiring_load_exclusive(n)); 8538 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8539 ins_cost(VOLATILE_REF_COST); 8540 effect(TEMP_DEF res, KILL cr); 8541 format %{ 8542 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8543 %} 8544 ins_encode %{ 8545 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8546 Assembler::xword, /*acquire*/ true, /*release*/ true, 8547 /*weak*/ false, $res$$Register); 8548 %} 8549 ins_pipe(pipe_slow); 8550 %} 8551 8552 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8553 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8554 ins_cost(2 * VOLATILE_REF_COST); 8555 effect(KILL cr); 8556 format %{ 8557 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8558 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8559 %} 8560 ins_encode %{ 8561 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8562 Assembler::byte, /*acquire*/ false, /*release*/ true, 8563 /*weak*/ true, noreg); 8564 __ csetw($res$$Register, Assembler::EQ); 8565 %} 8566 ins_pipe(pipe_slow); 8567 %} 8568 8569 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8570 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8571 ins_cost(2 * VOLATILE_REF_COST); 8572 effect(KILL cr); 8573 format %{ 8574 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8575 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8576 %} 8577 ins_encode %{ 8578 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8579 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8580 /*weak*/ true, noreg); 8581 __ csetw($res$$Register, Assembler::EQ); 8582 %} 8583 ins_pipe(pipe_slow); 8584 %} 8585 8586 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8587 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8588 ins_cost(2 * VOLATILE_REF_COST); 8589 effect(KILL cr); 8590 format %{ 8591 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8592 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8593 %} 8594 ins_encode %{ 8595 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8596 Assembler::word, /*acquire*/ false, /*release*/ true, 8597 /*weak*/ true, noreg); 8598 __ csetw($res$$Register, Assembler::EQ); 8599 %} 8600 ins_pipe(pipe_slow); 8601 %} 8602 8603 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8604 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8605 ins_cost(2 * VOLATILE_REF_COST); 8606 effect(KILL cr); 8607 format %{ 8608 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8609 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8610 %} 8611 ins_encode %{ 8612 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8613 Assembler::xword, /*acquire*/ false, /*release*/ true, 8614 /*weak*/ true, noreg); 8615 __ csetw($res$$Register, Assembler::EQ); 8616 %} 8617 ins_pipe(pipe_slow); 8618 %} 8619 8620 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8621 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8622 ins_cost(2 * VOLATILE_REF_COST); 8623 effect(KILL cr); 8624 format %{ 8625 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8626 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8627 %} 8628 ins_encode %{ 8629 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8630 Assembler::word, /*acquire*/ false, /*release*/ true, 8631 /*weak*/ true, noreg); 8632 __ csetw($res$$Register, Assembler::EQ); 8633 %} 8634 ins_pipe(pipe_slow); 8635 %} 8636 8637 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8638 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8639 ins_cost(2 * VOLATILE_REF_COST); 8640 effect(KILL cr); 8641 format %{ 8642 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8643 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8644 %} 8645 ins_encode %{ 8646 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8647 Assembler::xword, /*acquire*/ false, /*release*/ true, 8648 /*weak*/ true, noreg); 8649 __ csetw($res$$Register, Assembler::EQ); 8650 %} 8651 ins_pipe(pipe_slow); 8652 %} 8653 8654 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8655 predicate(needs_acquiring_load_exclusive(n)); 8656 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8657 ins_cost(VOLATILE_REF_COST); 8658 effect(KILL cr); 8659 format %{ 8660 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8661 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8662 %} 8663 ins_encode %{ 8664 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8665 Assembler::byte, /*acquire*/ true, /*release*/ true, 8666 /*weak*/ true, noreg); 8667 __ csetw($res$$Register, Assembler::EQ); 8668 %} 8669 ins_pipe(pipe_slow); 8670 %} 8671 8672 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8673 predicate(needs_acquiring_load_exclusive(n)); 8674 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8675 ins_cost(VOLATILE_REF_COST); 8676 effect(KILL cr); 8677 format %{ 8678 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8679 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8680 %} 8681 ins_encode %{ 8682 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8683 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8684 /*weak*/ true, noreg); 8685 __ csetw($res$$Register, Assembler::EQ); 8686 %} 8687 ins_pipe(pipe_slow); 8688 %} 8689 8690 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8691 predicate(needs_acquiring_load_exclusive(n)); 8692 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8693 ins_cost(VOLATILE_REF_COST); 8694 effect(KILL cr); 8695 format %{ 8696 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8697 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8698 %} 8699 ins_encode %{ 8700 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8701 Assembler::word, /*acquire*/ true, /*release*/ true, 8702 /*weak*/ true, noreg); 8703 __ csetw($res$$Register, Assembler::EQ); 8704 %} 8705 ins_pipe(pipe_slow); 8706 %} 8707 8708 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8709 predicate(needs_acquiring_load_exclusive(n)); 8710 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8711 ins_cost(VOLATILE_REF_COST); 8712 effect(KILL cr); 8713 format %{ 8714 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8715 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8716 %} 8717 ins_encode %{ 8718 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8719 Assembler::xword, /*acquire*/ true, /*release*/ true, 8720 /*weak*/ true, noreg); 8721 __ csetw($res$$Register, Assembler::EQ); 8722 %} 8723 ins_pipe(pipe_slow); 8724 %} 8725 8726 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8727 predicate(needs_acquiring_load_exclusive(n)); 8728 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8729 ins_cost(VOLATILE_REF_COST); 8730 effect(KILL cr); 8731 format %{ 8732 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8733 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8734 %} 8735 ins_encode %{ 8736 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8737 Assembler::word, /*acquire*/ true, /*release*/ true, 8738 /*weak*/ true, noreg); 8739 __ csetw($res$$Register, Assembler::EQ); 8740 %} 8741 ins_pipe(pipe_slow); 8742 %} 8743 8744 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8745 predicate(needs_acquiring_load_exclusive(n)); 8746 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8747 ins_cost(VOLATILE_REF_COST); 8748 effect(KILL cr); 8749 format %{ 8750 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8751 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8752 %} 8753 ins_encode %{ 8754 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8755 Assembler::xword, /*acquire*/ true, /*release*/ true, 8756 /*weak*/ true, noreg); 8757 __ csetw($res$$Register, Assembler::EQ); 8758 %} 8759 ins_pipe(pipe_slow); 8760 %} 8761 8762 // END This section of the file is automatically generated. Do not edit -------------- 8763 // --------------------------------------------------------------------- 8764 8765 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8766 match(Set prev (GetAndSetI mem newv)); 8767 ins_cost(2 * VOLATILE_REF_COST); 8768 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8769 ins_encode %{ 8770 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8771 %} 8772 ins_pipe(pipe_serial); 8773 %} 8774 8775 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8776 match(Set prev (GetAndSetL mem newv)); 8777 ins_cost(2 * VOLATILE_REF_COST); 8778 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8779 ins_encode %{ 8780 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8781 %} 8782 ins_pipe(pipe_serial); 8783 %} 8784 8785 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8786 match(Set prev (GetAndSetN mem newv)); 8787 ins_cost(2 * VOLATILE_REF_COST); 8788 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8789 ins_encode %{ 8790 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8791 %} 8792 ins_pipe(pipe_serial); 8793 %} 8794 8795 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8796 match(Set prev (GetAndSetP mem newv)); 8797 ins_cost(2 * VOLATILE_REF_COST); 8798 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8799 ins_encode %{ 8800 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8801 %} 8802 ins_pipe(pipe_serial); 8803 %} 8804 8805 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 8806 predicate(needs_acquiring_load_exclusive(n)); 8807 match(Set prev (GetAndSetI mem newv)); 8808 ins_cost(VOLATILE_REF_COST); 8809 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8810 ins_encode %{ 8811 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8812 %} 8813 ins_pipe(pipe_serial); 8814 %} 8815 8816 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8817 predicate(needs_acquiring_load_exclusive(n)); 8818 match(Set prev (GetAndSetL mem newv)); 8819 ins_cost(VOLATILE_REF_COST); 8820 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8821 ins_encode %{ 8822 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8823 %} 8824 ins_pipe(pipe_serial); 8825 %} 8826 8827 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 8828 predicate(needs_acquiring_load_exclusive(n)); 8829 match(Set prev (GetAndSetN mem newv)); 8830 ins_cost(VOLATILE_REF_COST); 8831 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8832 ins_encode %{ 8833 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8834 %} 8835 ins_pipe(pipe_serial); 8836 %} 8837 8838 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8839 predicate(needs_acquiring_load_exclusive(n)); 8840 match(Set prev (GetAndSetP mem newv)); 8841 ins_cost(VOLATILE_REF_COST); 8842 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8843 ins_encode %{ 8844 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8845 %} 8846 ins_pipe(pipe_serial); 8847 %} 8848 8849 8850 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8851 match(Set newval (GetAndAddL mem incr)); 8852 ins_cost(2 * VOLATILE_REF_COST + 1); 8853 format %{ "get_and_addL $newval, [$mem], $incr" %} 8854 ins_encode %{ 8855 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8856 %} 8857 ins_pipe(pipe_serial); 8858 %} 8859 8860 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8861 predicate(n->as_LoadStore()->result_not_used()); 8862 match(Set dummy (GetAndAddL mem incr)); 8863 ins_cost(2 * VOLATILE_REF_COST); 8864 format %{ "get_and_addL [$mem], $incr" %} 8865 ins_encode %{ 8866 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8867 %} 8868 ins_pipe(pipe_serial); 8869 %} 8870 8871 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8872 match(Set newval (GetAndAddL mem incr)); 8873 ins_cost(2 * VOLATILE_REF_COST + 1); 8874 format %{ "get_and_addL $newval, [$mem], $incr" %} 8875 ins_encode %{ 8876 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8877 %} 8878 ins_pipe(pipe_serial); 8879 %} 8880 8881 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8882 predicate(n->as_LoadStore()->result_not_used()); 8883 match(Set dummy (GetAndAddL mem incr)); 8884 ins_cost(2 * VOLATILE_REF_COST); 8885 format %{ "get_and_addL [$mem], $incr" %} 8886 ins_encode %{ 8887 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8888 %} 8889 ins_pipe(pipe_serial); 8890 %} 8891 8892 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8893 match(Set newval (GetAndAddI mem incr)); 8894 ins_cost(2 * VOLATILE_REF_COST + 1); 8895 format %{ "get_and_addI $newval, [$mem], $incr" %} 8896 ins_encode %{ 8897 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8898 %} 8899 ins_pipe(pipe_serial); 8900 %} 8901 8902 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8903 predicate(n->as_LoadStore()->result_not_used()); 8904 match(Set dummy (GetAndAddI mem incr)); 8905 ins_cost(2 * VOLATILE_REF_COST); 8906 format %{ "get_and_addI [$mem], $incr" %} 8907 ins_encode %{ 8908 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8909 %} 8910 ins_pipe(pipe_serial); 8911 %} 8912 8913 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8914 match(Set newval (GetAndAddI mem incr)); 8915 ins_cost(2 * VOLATILE_REF_COST + 1); 8916 format %{ "get_and_addI $newval, [$mem], $incr" %} 8917 ins_encode %{ 8918 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8919 %} 8920 ins_pipe(pipe_serial); 8921 %} 8922 8923 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8924 predicate(n->as_LoadStore()->result_not_used()); 8925 match(Set dummy (GetAndAddI mem incr)); 8926 ins_cost(2 * VOLATILE_REF_COST); 8927 format %{ "get_and_addI [$mem], $incr" %} 8928 ins_encode %{ 8929 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8930 %} 8931 ins_pipe(pipe_serial); 8932 %} 8933 8934 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8935 predicate(needs_acquiring_load_exclusive(n)); 8936 match(Set newval (GetAndAddL mem incr)); 8937 ins_cost(VOLATILE_REF_COST + 1); 8938 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8939 ins_encode %{ 8940 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8941 %} 8942 ins_pipe(pipe_serial); 8943 %} 8944 8945 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 8946 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8947 match(Set dummy (GetAndAddL mem incr)); 8948 ins_cost(VOLATILE_REF_COST); 8949 format %{ "get_and_addL_acq [$mem], $incr" %} 8950 ins_encode %{ 8951 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 8952 %} 8953 ins_pipe(pipe_serial); 8954 %} 8955 8956 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8957 predicate(needs_acquiring_load_exclusive(n)); 8958 match(Set newval (GetAndAddL mem incr)); 8959 ins_cost(VOLATILE_REF_COST + 1); 8960 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8961 ins_encode %{ 8962 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8963 %} 8964 ins_pipe(pipe_serial); 8965 %} 8966 8967 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 8968 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8969 match(Set dummy (GetAndAddL mem incr)); 8970 ins_cost(VOLATILE_REF_COST); 8971 format %{ "get_and_addL_acq [$mem], $incr" %} 8972 ins_encode %{ 8973 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 8974 %} 8975 ins_pipe(pipe_serial); 8976 %} 8977 8978 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8979 predicate(needs_acquiring_load_exclusive(n)); 8980 match(Set newval (GetAndAddI mem incr)); 8981 ins_cost(VOLATILE_REF_COST + 1); 8982 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8983 ins_encode %{ 8984 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8985 %} 8986 ins_pipe(pipe_serial); 8987 %} 8988 8989 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8990 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8991 match(Set dummy (GetAndAddI mem incr)); 8992 ins_cost(VOLATILE_REF_COST); 8993 format %{ "get_and_addI_acq [$mem], $incr" %} 8994 ins_encode %{ 8995 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 8996 %} 8997 ins_pipe(pipe_serial); 8998 %} 8999 9000 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9001 predicate(needs_acquiring_load_exclusive(n)); 9002 match(Set newval (GetAndAddI mem incr)); 9003 ins_cost(VOLATILE_REF_COST + 1); 9004 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9005 ins_encode %{ 9006 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9007 %} 9008 ins_pipe(pipe_serial); 9009 %} 9010 9011 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9012 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9013 match(Set dummy (GetAndAddI mem incr)); 9014 ins_cost(VOLATILE_REF_COST); 9015 format %{ "get_and_addI_acq [$mem], $incr" %} 9016 ins_encode %{ 9017 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9018 %} 9019 ins_pipe(pipe_serial); 9020 %} 9021 9022 // Manifest a CmpL result in an integer register. 9023 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9024 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9025 %{ 9026 match(Set dst (CmpL3 src1 src2)); 9027 effect(KILL flags); 9028 9029 ins_cost(INSN_COST * 6); 9030 format %{ 9031 "cmp $src1, $src2" 9032 "csetw $dst, ne" 9033 "cnegw $dst, lt" 9034 %} 9035 // format %{ "CmpL3 $dst, $src1, $src2" %} 9036 ins_encode %{ 9037 __ cmp($src1$$Register, $src2$$Register); 9038 __ csetw($dst$$Register, Assembler::NE); 9039 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9040 %} 9041 9042 ins_pipe(pipe_class_default); 9043 %} 9044 9045 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9046 %{ 9047 match(Set dst (CmpL3 src1 src2)); 9048 effect(KILL flags); 9049 9050 ins_cost(INSN_COST * 6); 9051 format %{ 9052 "cmp $src1, $src2" 9053 "csetw $dst, ne" 9054 "cnegw $dst, lt" 9055 %} 9056 ins_encode %{ 9057 int32_t con = (int32_t)$src2$$constant; 9058 if (con < 0) { 9059 __ adds(zr, $src1$$Register, -con); 9060 } else { 9061 __ subs(zr, $src1$$Register, con); 9062 } 9063 __ csetw($dst$$Register, Assembler::NE); 9064 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9065 %} 9066 9067 ins_pipe(pipe_class_default); 9068 %} 9069 9070 // ============================================================================ 9071 // Conditional Move Instructions 9072 9073 // n.b. we have identical rules for both a signed compare op (cmpOp) 9074 // and an unsigned compare op (cmpOpU). it would be nice if we could 9075 // define an op class which merged both inputs and use it to type the 9076 // argument to a single rule. unfortunatelyt his fails because the 9077 // opclass does not live up to the COND_INTER interface of its 9078 // component operands. When the generic code tries to negate the 9079 // operand it ends up running the generci Machoper::negate method 9080 // which throws a ShouldNotHappen. So, we have to provide two flavours 9081 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9082 9083 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9084 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9085 9086 ins_cost(INSN_COST * 2); 9087 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9088 9089 ins_encode %{ 9090 __ cselw(as_Register($dst$$reg), 9091 as_Register($src2$$reg), 9092 as_Register($src1$$reg), 9093 (Assembler::Condition)$cmp$$cmpcode); 9094 %} 9095 9096 ins_pipe(icond_reg_reg); 9097 %} 9098 9099 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9100 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9101 9102 ins_cost(INSN_COST * 2); 9103 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9104 9105 ins_encode %{ 9106 __ cselw(as_Register($dst$$reg), 9107 as_Register($src2$$reg), 9108 as_Register($src1$$reg), 9109 (Assembler::Condition)$cmp$$cmpcode); 9110 %} 9111 9112 ins_pipe(icond_reg_reg); 9113 %} 9114 9115 // special cases where one arg is zero 9116 9117 // n.b. this is selected in preference to the rule above because it 9118 // avoids loading constant 0 into a source register 9119 9120 // TODO 9121 // we ought only to be able to cull one of these variants as the ideal 9122 // transforms ought always to order the zero consistently (to left/right?) 9123 9124 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9125 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9126 9127 ins_cost(INSN_COST * 2); 9128 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9129 9130 ins_encode %{ 9131 __ cselw(as_Register($dst$$reg), 9132 as_Register($src$$reg), 9133 zr, 9134 (Assembler::Condition)$cmp$$cmpcode); 9135 %} 9136 9137 ins_pipe(icond_reg); 9138 %} 9139 9140 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9141 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9142 9143 ins_cost(INSN_COST * 2); 9144 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9145 9146 ins_encode %{ 9147 __ cselw(as_Register($dst$$reg), 9148 as_Register($src$$reg), 9149 zr, 9150 (Assembler::Condition)$cmp$$cmpcode); 9151 %} 9152 9153 ins_pipe(icond_reg); 9154 %} 9155 9156 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9157 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9158 9159 ins_cost(INSN_COST * 2); 9160 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9161 9162 ins_encode %{ 9163 __ cselw(as_Register($dst$$reg), 9164 zr, 9165 as_Register($src$$reg), 9166 (Assembler::Condition)$cmp$$cmpcode); 9167 %} 9168 9169 ins_pipe(icond_reg); 9170 %} 9171 9172 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9173 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9174 9175 ins_cost(INSN_COST * 2); 9176 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9177 9178 ins_encode %{ 9179 __ cselw(as_Register($dst$$reg), 9180 zr, 9181 as_Register($src$$reg), 9182 (Assembler::Condition)$cmp$$cmpcode); 9183 %} 9184 9185 ins_pipe(icond_reg); 9186 %} 9187 9188 // special case for creating a boolean 0 or 1 9189 9190 // n.b. this is selected in preference to the rule above because it 9191 // avoids loading constants 0 and 1 into a source register 9192 9193 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9194 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9195 9196 ins_cost(INSN_COST * 2); 9197 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9198 9199 ins_encode %{ 9200 // equivalently 9201 // cset(as_Register($dst$$reg), 9202 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9203 __ csincw(as_Register($dst$$reg), 9204 zr, 9205 zr, 9206 (Assembler::Condition)$cmp$$cmpcode); 9207 %} 9208 9209 ins_pipe(icond_none); 9210 %} 9211 9212 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9213 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9214 9215 ins_cost(INSN_COST * 2); 9216 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9217 9218 ins_encode %{ 9219 // equivalently 9220 // cset(as_Register($dst$$reg), 9221 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9222 __ csincw(as_Register($dst$$reg), 9223 zr, 9224 zr, 9225 (Assembler::Condition)$cmp$$cmpcode); 9226 %} 9227 9228 ins_pipe(icond_none); 9229 %} 9230 9231 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9232 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9233 9234 ins_cost(INSN_COST * 2); 9235 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9236 9237 ins_encode %{ 9238 __ csel(as_Register($dst$$reg), 9239 as_Register($src2$$reg), 9240 as_Register($src1$$reg), 9241 (Assembler::Condition)$cmp$$cmpcode); 9242 %} 9243 9244 ins_pipe(icond_reg_reg); 9245 %} 9246 9247 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9248 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9249 9250 ins_cost(INSN_COST * 2); 9251 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9252 9253 ins_encode %{ 9254 __ csel(as_Register($dst$$reg), 9255 as_Register($src2$$reg), 9256 as_Register($src1$$reg), 9257 (Assembler::Condition)$cmp$$cmpcode); 9258 %} 9259 9260 ins_pipe(icond_reg_reg); 9261 %} 9262 9263 // special cases where one arg is zero 9264 9265 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9266 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9267 9268 ins_cost(INSN_COST * 2); 9269 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9270 9271 ins_encode %{ 9272 __ csel(as_Register($dst$$reg), 9273 zr, 9274 as_Register($src$$reg), 9275 (Assembler::Condition)$cmp$$cmpcode); 9276 %} 9277 9278 ins_pipe(icond_reg); 9279 %} 9280 9281 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9282 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9283 9284 ins_cost(INSN_COST * 2); 9285 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9286 9287 ins_encode %{ 9288 __ csel(as_Register($dst$$reg), 9289 zr, 9290 as_Register($src$$reg), 9291 (Assembler::Condition)$cmp$$cmpcode); 9292 %} 9293 9294 ins_pipe(icond_reg); 9295 %} 9296 9297 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9298 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9299 9300 ins_cost(INSN_COST * 2); 9301 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9302 9303 ins_encode %{ 9304 __ csel(as_Register($dst$$reg), 9305 as_Register($src$$reg), 9306 zr, 9307 (Assembler::Condition)$cmp$$cmpcode); 9308 %} 9309 9310 ins_pipe(icond_reg); 9311 %} 9312 9313 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9314 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9315 9316 ins_cost(INSN_COST * 2); 9317 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9318 9319 ins_encode %{ 9320 __ csel(as_Register($dst$$reg), 9321 as_Register($src$$reg), 9322 zr, 9323 (Assembler::Condition)$cmp$$cmpcode); 9324 %} 9325 9326 ins_pipe(icond_reg); 9327 %} 9328 9329 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9330 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9331 9332 ins_cost(INSN_COST * 2); 9333 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9334 9335 ins_encode %{ 9336 __ csel(as_Register($dst$$reg), 9337 as_Register($src2$$reg), 9338 as_Register($src1$$reg), 9339 (Assembler::Condition)$cmp$$cmpcode); 9340 %} 9341 9342 ins_pipe(icond_reg_reg); 9343 %} 9344 9345 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9346 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9347 9348 ins_cost(INSN_COST * 2); 9349 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9350 9351 ins_encode %{ 9352 __ csel(as_Register($dst$$reg), 9353 as_Register($src2$$reg), 9354 as_Register($src1$$reg), 9355 (Assembler::Condition)$cmp$$cmpcode); 9356 %} 9357 9358 ins_pipe(icond_reg_reg); 9359 %} 9360 9361 // special cases where one arg is zero 9362 9363 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9364 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9365 9366 ins_cost(INSN_COST * 2); 9367 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9368 9369 ins_encode %{ 9370 __ csel(as_Register($dst$$reg), 9371 zr, 9372 as_Register($src$$reg), 9373 (Assembler::Condition)$cmp$$cmpcode); 9374 %} 9375 9376 ins_pipe(icond_reg); 9377 %} 9378 9379 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9380 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9381 9382 ins_cost(INSN_COST * 2); 9383 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9384 9385 ins_encode %{ 9386 __ csel(as_Register($dst$$reg), 9387 zr, 9388 as_Register($src$$reg), 9389 (Assembler::Condition)$cmp$$cmpcode); 9390 %} 9391 9392 ins_pipe(icond_reg); 9393 %} 9394 9395 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9396 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9397 9398 ins_cost(INSN_COST * 2); 9399 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9400 9401 ins_encode %{ 9402 __ csel(as_Register($dst$$reg), 9403 as_Register($src$$reg), 9404 zr, 9405 (Assembler::Condition)$cmp$$cmpcode); 9406 %} 9407 9408 ins_pipe(icond_reg); 9409 %} 9410 9411 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9412 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9413 9414 ins_cost(INSN_COST * 2); 9415 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9416 9417 ins_encode %{ 9418 __ csel(as_Register($dst$$reg), 9419 as_Register($src$$reg), 9420 zr, 9421 (Assembler::Condition)$cmp$$cmpcode); 9422 %} 9423 9424 ins_pipe(icond_reg); 9425 %} 9426 9427 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9428 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9429 9430 ins_cost(INSN_COST * 2); 9431 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9432 9433 ins_encode %{ 9434 __ cselw(as_Register($dst$$reg), 9435 as_Register($src2$$reg), 9436 as_Register($src1$$reg), 9437 (Assembler::Condition)$cmp$$cmpcode); 9438 %} 9439 9440 ins_pipe(icond_reg_reg); 9441 %} 9442 9443 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9444 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9445 9446 ins_cost(INSN_COST * 2); 9447 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9448 9449 ins_encode %{ 9450 __ cselw(as_Register($dst$$reg), 9451 as_Register($src2$$reg), 9452 as_Register($src1$$reg), 9453 (Assembler::Condition)$cmp$$cmpcode); 9454 %} 9455 9456 ins_pipe(icond_reg_reg); 9457 %} 9458 9459 // special cases where one arg is zero 9460 9461 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9462 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9463 9464 ins_cost(INSN_COST * 2); 9465 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9466 9467 ins_encode %{ 9468 __ cselw(as_Register($dst$$reg), 9469 zr, 9470 as_Register($src$$reg), 9471 (Assembler::Condition)$cmp$$cmpcode); 9472 %} 9473 9474 ins_pipe(icond_reg); 9475 %} 9476 9477 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9478 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9479 9480 ins_cost(INSN_COST * 2); 9481 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9482 9483 ins_encode %{ 9484 __ cselw(as_Register($dst$$reg), 9485 zr, 9486 as_Register($src$$reg), 9487 (Assembler::Condition)$cmp$$cmpcode); 9488 %} 9489 9490 ins_pipe(icond_reg); 9491 %} 9492 9493 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9494 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9495 9496 ins_cost(INSN_COST * 2); 9497 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9498 9499 ins_encode %{ 9500 __ cselw(as_Register($dst$$reg), 9501 as_Register($src$$reg), 9502 zr, 9503 (Assembler::Condition)$cmp$$cmpcode); 9504 %} 9505 9506 ins_pipe(icond_reg); 9507 %} 9508 9509 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9510 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9511 9512 ins_cost(INSN_COST * 2); 9513 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9514 9515 ins_encode %{ 9516 __ cselw(as_Register($dst$$reg), 9517 as_Register($src$$reg), 9518 zr, 9519 (Assembler::Condition)$cmp$$cmpcode); 9520 %} 9521 9522 ins_pipe(icond_reg); 9523 %} 9524 9525 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9526 %{ 9527 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9528 9529 ins_cost(INSN_COST * 3); 9530 9531 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9532 ins_encode %{ 9533 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9534 __ fcsels(as_FloatRegister($dst$$reg), 9535 as_FloatRegister($src2$$reg), 9536 as_FloatRegister($src1$$reg), 9537 cond); 9538 %} 9539 9540 ins_pipe(fp_cond_reg_reg_s); 9541 %} 9542 9543 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9544 %{ 9545 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9546 9547 ins_cost(INSN_COST * 3); 9548 9549 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9550 ins_encode %{ 9551 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9552 __ fcsels(as_FloatRegister($dst$$reg), 9553 as_FloatRegister($src2$$reg), 9554 as_FloatRegister($src1$$reg), 9555 cond); 9556 %} 9557 9558 ins_pipe(fp_cond_reg_reg_s); 9559 %} 9560 9561 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9562 %{ 9563 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9564 9565 ins_cost(INSN_COST * 3); 9566 9567 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9568 ins_encode %{ 9569 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9570 __ fcseld(as_FloatRegister($dst$$reg), 9571 as_FloatRegister($src2$$reg), 9572 as_FloatRegister($src1$$reg), 9573 cond); 9574 %} 9575 9576 ins_pipe(fp_cond_reg_reg_d); 9577 %} 9578 9579 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9580 %{ 9581 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9582 9583 ins_cost(INSN_COST * 3); 9584 9585 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9586 ins_encode %{ 9587 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9588 __ fcseld(as_FloatRegister($dst$$reg), 9589 as_FloatRegister($src2$$reg), 9590 as_FloatRegister($src1$$reg), 9591 cond); 9592 %} 9593 9594 ins_pipe(fp_cond_reg_reg_d); 9595 %} 9596 9597 // ============================================================================ 9598 // Arithmetic Instructions 9599 // 9600 9601 // Integer Addition 9602 9603 // TODO 9604 // these currently employ operations which do not set CR and hence are 9605 // not flagged as killing CR but we would like to isolate the cases 9606 // where we want to set flags from those where we don't. need to work 9607 // out how to do that. 9608 9609 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9610 match(Set dst (AddI src1 src2)); 9611 9612 ins_cost(INSN_COST); 9613 format %{ "addw $dst, $src1, $src2" %} 9614 9615 ins_encode %{ 9616 __ addw(as_Register($dst$$reg), 9617 as_Register($src1$$reg), 9618 as_Register($src2$$reg)); 9619 %} 9620 9621 ins_pipe(ialu_reg_reg); 9622 %} 9623 9624 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9625 match(Set dst (AddI src1 src2)); 9626 9627 ins_cost(INSN_COST); 9628 format %{ "addw $dst, $src1, $src2" %} 9629 9630 // use opcode to indicate that this is an add not a sub 9631 opcode(0x0); 9632 9633 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9634 9635 ins_pipe(ialu_reg_imm); 9636 %} 9637 9638 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9639 match(Set dst (AddI (ConvL2I src1) src2)); 9640 9641 ins_cost(INSN_COST); 9642 format %{ "addw $dst, $src1, $src2" %} 9643 9644 // use opcode to indicate that this is an add not a sub 9645 opcode(0x0); 9646 9647 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9648 9649 ins_pipe(ialu_reg_imm); 9650 %} 9651 9652 // Pointer Addition 9653 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9654 match(Set dst (AddP src1 src2)); 9655 9656 ins_cost(INSN_COST); 9657 format %{ "add $dst, $src1, $src2\t# ptr" %} 9658 9659 ins_encode %{ 9660 __ add(as_Register($dst$$reg), 9661 as_Register($src1$$reg), 9662 as_Register($src2$$reg)); 9663 %} 9664 9665 ins_pipe(ialu_reg_reg); 9666 %} 9667 9668 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9669 match(Set dst (AddP src1 (ConvI2L src2))); 9670 9671 ins_cost(1.9 * INSN_COST); 9672 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9673 9674 ins_encode %{ 9675 __ add(as_Register($dst$$reg), 9676 as_Register($src1$$reg), 9677 as_Register($src2$$reg), ext::sxtw); 9678 %} 9679 9680 ins_pipe(ialu_reg_reg); 9681 %} 9682 9683 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9684 match(Set dst (AddP src1 (LShiftL src2 scale))); 9685 9686 ins_cost(1.9 * INSN_COST); 9687 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9688 9689 ins_encode %{ 9690 __ lea(as_Register($dst$$reg), 9691 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9692 Address::lsl($scale$$constant))); 9693 %} 9694 9695 ins_pipe(ialu_reg_reg_shift); 9696 %} 9697 9698 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9699 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9700 9701 ins_cost(1.9 * INSN_COST); 9702 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9703 9704 ins_encode %{ 9705 __ lea(as_Register($dst$$reg), 9706 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9707 Address::sxtw($scale$$constant))); 9708 %} 9709 9710 ins_pipe(ialu_reg_reg_shift); 9711 %} 9712 9713 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9714 match(Set dst (LShiftL (ConvI2L src) scale)); 9715 9716 ins_cost(INSN_COST); 9717 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9718 9719 ins_encode %{ 9720 __ sbfiz(as_Register($dst$$reg), 9721 as_Register($src$$reg), 9722 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 9723 %} 9724 9725 ins_pipe(ialu_reg_shift); 9726 %} 9727 9728 // Pointer Immediate Addition 9729 // n.b. this needs to be more expensive than using an indirect memory 9730 // operand 9731 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9732 match(Set dst (AddP src1 src2)); 9733 9734 ins_cost(INSN_COST); 9735 format %{ "add $dst, $src1, $src2\t# ptr" %} 9736 9737 // use opcode to indicate that this is an add not a sub 9738 opcode(0x0); 9739 9740 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9741 9742 ins_pipe(ialu_reg_imm); 9743 %} 9744 9745 // Long Addition 9746 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9747 9748 match(Set dst (AddL src1 src2)); 9749 9750 ins_cost(INSN_COST); 9751 format %{ "add $dst, $src1, $src2" %} 9752 9753 ins_encode %{ 9754 __ add(as_Register($dst$$reg), 9755 as_Register($src1$$reg), 9756 as_Register($src2$$reg)); 9757 %} 9758 9759 ins_pipe(ialu_reg_reg); 9760 %} 9761 9762 // No constant pool entries requiredLong Immediate Addition. 9763 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9764 match(Set dst (AddL src1 src2)); 9765 9766 ins_cost(INSN_COST); 9767 format %{ "add $dst, $src1, $src2" %} 9768 9769 // use opcode to indicate that this is an add not a sub 9770 opcode(0x0); 9771 9772 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9773 9774 ins_pipe(ialu_reg_imm); 9775 %} 9776 9777 // Integer Subtraction 9778 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9779 match(Set dst (SubI src1 src2)); 9780 9781 ins_cost(INSN_COST); 9782 format %{ "subw $dst, $src1, $src2" %} 9783 9784 ins_encode %{ 9785 __ subw(as_Register($dst$$reg), 9786 as_Register($src1$$reg), 9787 as_Register($src2$$reg)); 9788 %} 9789 9790 ins_pipe(ialu_reg_reg); 9791 %} 9792 9793 // Immediate Subtraction 9794 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9795 match(Set dst (SubI src1 src2)); 9796 9797 ins_cost(INSN_COST); 9798 format %{ "subw $dst, $src1, $src2" %} 9799 9800 // use opcode to indicate that this is a sub not an add 9801 opcode(0x1); 9802 9803 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9804 9805 ins_pipe(ialu_reg_imm); 9806 %} 9807 9808 // Long Subtraction 9809 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9810 9811 match(Set dst (SubL src1 src2)); 9812 9813 ins_cost(INSN_COST); 9814 format %{ "sub $dst, $src1, $src2" %} 9815 9816 ins_encode %{ 9817 __ sub(as_Register($dst$$reg), 9818 as_Register($src1$$reg), 9819 as_Register($src2$$reg)); 9820 %} 9821 9822 ins_pipe(ialu_reg_reg); 9823 %} 9824 9825 // No constant pool entries requiredLong Immediate Subtraction. 9826 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9827 match(Set dst (SubL src1 src2)); 9828 9829 ins_cost(INSN_COST); 9830 format %{ "sub$dst, $src1, $src2" %} 9831 9832 // use opcode to indicate that this is a sub not an add 9833 opcode(0x1); 9834 9835 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9836 9837 ins_pipe(ialu_reg_imm); 9838 %} 9839 9840 // Integer Negation (special case for sub) 9841 9842 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9843 match(Set dst (SubI zero src)); 9844 9845 ins_cost(INSN_COST); 9846 format %{ "negw $dst, $src\t# int" %} 9847 9848 ins_encode %{ 9849 __ negw(as_Register($dst$$reg), 9850 as_Register($src$$reg)); 9851 %} 9852 9853 ins_pipe(ialu_reg); 9854 %} 9855 9856 // Long Negation 9857 9858 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9859 match(Set dst (SubL zero src)); 9860 9861 ins_cost(INSN_COST); 9862 format %{ "neg $dst, $src\t# long" %} 9863 9864 ins_encode %{ 9865 __ neg(as_Register($dst$$reg), 9866 as_Register($src$$reg)); 9867 %} 9868 9869 ins_pipe(ialu_reg); 9870 %} 9871 9872 // Integer Multiply 9873 9874 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9875 match(Set dst (MulI src1 src2)); 9876 9877 ins_cost(INSN_COST * 3); 9878 format %{ "mulw $dst, $src1, $src2" %} 9879 9880 ins_encode %{ 9881 __ mulw(as_Register($dst$$reg), 9882 as_Register($src1$$reg), 9883 as_Register($src2$$reg)); 9884 %} 9885 9886 ins_pipe(imul_reg_reg); 9887 %} 9888 9889 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9890 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9891 9892 ins_cost(INSN_COST * 3); 9893 format %{ "smull $dst, $src1, $src2" %} 9894 9895 ins_encode %{ 9896 __ smull(as_Register($dst$$reg), 9897 as_Register($src1$$reg), 9898 as_Register($src2$$reg)); 9899 %} 9900 9901 ins_pipe(imul_reg_reg); 9902 %} 9903 9904 // Long Multiply 9905 9906 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9907 match(Set dst (MulL src1 src2)); 9908 9909 ins_cost(INSN_COST * 5); 9910 format %{ "mul $dst, $src1, $src2" %} 9911 9912 ins_encode %{ 9913 __ mul(as_Register($dst$$reg), 9914 as_Register($src1$$reg), 9915 as_Register($src2$$reg)); 9916 %} 9917 9918 ins_pipe(lmul_reg_reg); 9919 %} 9920 9921 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9922 %{ 9923 match(Set dst (MulHiL src1 src2)); 9924 9925 ins_cost(INSN_COST * 7); 9926 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9927 9928 ins_encode %{ 9929 __ smulh(as_Register($dst$$reg), 9930 as_Register($src1$$reg), 9931 as_Register($src2$$reg)); 9932 %} 9933 9934 ins_pipe(lmul_reg_reg); 9935 %} 9936 9937 // Combined Integer Multiply & Add/Sub 9938 9939 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9940 match(Set dst (AddI src3 (MulI src1 src2))); 9941 9942 ins_cost(INSN_COST * 3); 9943 format %{ "madd $dst, $src1, $src2, $src3" %} 9944 9945 ins_encode %{ 9946 __ maddw(as_Register($dst$$reg), 9947 as_Register($src1$$reg), 9948 as_Register($src2$$reg), 9949 as_Register($src3$$reg)); 9950 %} 9951 9952 ins_pipe(imac_reg_reg); 9953 %} 9954 9955 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9956 match(Set dst (SubI src3 (MulI src1 src2))); 9957 9958 ins_cost(INSN_COST * 3); 9959 format %{ "msub $dst, $src1, $src2, $src3" %} 9960 9961 ins_encode %{ 9962 __ msubw(as_Register($dst$$reg), 9963 as_Register($src1$$reg), 9964 as_Register($src2$$reg), 9965 as_Register($src3$$reg)); 9966 %} 9967 9968 ins_pipe(imac_reg_reg); 9969 %} 9970 9971 // Combined Integer Multiply & Neg 9972 9973 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 9974 match(Set dst (MulI (SubI zero src1) src2)); 9975 match(Set dst (MulI src1 (SubI zero src2))); 9976 9977 ins_cost(INSN_COST * 3); 9978 format %{ "mneg $dst, $src1, $src2" %} 9979 9980 ins_encode %{ 9981 __ mnegw(as_Register($dst$$reg), 9982 as_Register($src1$$reg), 9983 as_Register($src2$$reg)); 9984 %} 9985 9986 ins_pipe(imac_reg_reg); 9987 %} 9988 9989 // Combined Long Multiply & Add/Sub 9990 9991 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9992 match(Set dst (AddL src3 (MulL src1 src2))); 9993 9994 ins_cost(INSN_COST * 5); 9995 format %{ "madd $dst, $src1, $src2, $src3" %} 9996 9997 ins_encode %{ 9998 __ madd(as_Register($dst$$reg), 9999 as_Register($src1$$reg), 10000 as_Register($src2$$reg), 10001 as_Register($src3$$reg)); 10002 %} 10003 10004 ins_pipe(lmac_reg_reg); 10005 %} 10006 10007 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10008 match(Set dst (SubL src3 (MulL src1 src2))); 10009 10010 ins_cost(INSN_COST * 5); 10011 format %{ "msub $dst, $src1, $src2, $src3" %} 10012 10013 ins_encode %{ 10014 __ msub(as_Register($dst$$reg), 10015 as_Register($src1$$reg), 10016 as_Register($src2$$reg), 10017 as_Register($src3$$reg)); 10018 %} 10019 10020 ins_pipe(lmac_reg_reg); 10021 %} 10022 10023 // Combined Long Multiply & Neg 10024 10025 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10026 match(Set dst (MulL (SubL zero src1) src2)); 10027 match(Set dst (MulL src1 (SubL zero src2))); 10028 10029 ins_cost(INSN_COST * 5); 10030 format %{ "mneg $dst, $src1, $src2" %} 10031 10032 ins_encode %{ 10033 __ mneg(as_Register($dst$$reg), 10034 as_Register($src1$$reg), 10035 as_Register($src2$$reg)); 10036 %} 10037 10038 ins_pipe(lmac_reg_reg); 10039 %} 10040 10041 // Integer Divide 10042 10043 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10044 match(Set dst (DivI src1 src2)); 10045 10046 ins_cost(INSN_COST * 19); 10047 format %{ "sdivw $dst, $src1, $src2" %} 10048 10049 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10050 ins_pipe(idiv_reg_reg); 10051 %} 10052 10053 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 10054 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 10055 ins_cost(INSN_COST); 10056 format %{ "lsrw $dst, $src1, $div1" %} 10057 ins_encode %{ 10058 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 10059 %} 10060 ins_pipe(ialu_reg_shift); 10061 %} 10062 10063 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 10064 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 10065 ins_cost(INSN_COST); 10066 format %{ "addw $dst, $src, LSR $div1" %} 10067 10068 ins_encode %{ 10069 __ addw(as_Register($dst$$reg), 10070 as_Register($src$$reg), 10071 as_Register($src$$reg), 10072 Assembler::LSR, 31); 10073 %} 10074 ins_pipe(ialu_reg); 10075 %} 10076 10077 // Long Divide 10078 10079 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10080 match(Set dst (DivL src1 src2)); 10081 10082 ins_cost(INSN_COST * 35); 10083 format %{ "sdiv $dst, $src1, $src2" %} 10084 10085 ins_encode(aarch64_enc_div(dst, src1, src2)); 10086 ins_pipe(ldiv_reg_reg); 10087 %} 10088 10089 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 10090 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 10091 ins_cost(INSN_COST); 10092 format %{ "lsr $dst, $src1, $div1" %} 10093 ins_encode %{ 10094 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 10095 %} 10096 ins_pipe(ialu_reg_shift); 10097 %} 10098 10099 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 10100 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 10101 ins_cost(INSN_COST); 10102 format %{ "add $dst, $src, $div1" %} 10103 10104 ins_encode %{ 10105 __ add(as_Register($dst$$reg), 10106 as_Register($src$$reg), 10107 as_Register($src$$reg), 10108 Assembler::LSR, 63); 10109 %} 10110 ins_pipe(ialu_reg); 10111 %} 10112 10113 // Integer Remainder 10114 10115 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10116 match(Set dst (ModI src1 src2)); 10117 10118 ins_cost(INSN_COST * 22); 10119 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10120 "msubw($dst, rscratch1, $src2, $src1" %} 10121 10122 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10123 ins_pipe(idiv_reg_reg); 10124 %} 10125 10126 // Long Remainder 10127 10128 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10129 match(Set dst (ModL src1 src2)); 10130 10131 ins_cost(INSN_COST * 38); 10132 format %{ "sdiv rscratch1, $src1, $src2\n" 10133 "msub($dst, rscratch1, $src2, $src1" %} 10134 10135 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10136 ins_pipe(ldiv_reg_reg); 10137 %} 10138 10139 // Integer Shifts 10140 10141 // Shift Left Register 10142 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10143 match(Set dst (LShiftI src1 src2)); 10144 10145 ins_cost(INSN_COST * 2); 10146 format %{ "lslvw $dst, $src1, $src2" %} 10147 10148 ins_encode %{ 10149 __ lslvw(as_Register($dst$$reg), 10150 as_Register($src1$$reg), 10151 as_Register($src2$$reg)); 10152 %} 10153 10154 ins_pipe(ialu_reg_reg_vshift); 10155 %} 10156 10157 // Shift Left Immediate 10158 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10159 match(Set dst (LShiftI src1 src2)); 10160 10161 ins_cost(INSN_COST); 10162 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10163 10164 ins_encode %{ 10165 __ lslw(as_Register($dst$$reg), 10166 as_Register($src1$$reg), 10167 $src2$$constant & 0x1f); 10168 %} 10169 10170 ins_pipe(ialu_reg_shift); 10171 %} 10172 10173 // Shift Right Logical Register 10174 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10175 match(Set dst (URShiftI src1 src2)); 10176 10177 ins_cost(INSN_COST * 2); 10178 format %{ "lsrvw $dst, $src1, $src2" %} 10179 10180 ins_encode %{ 10181 __ lsrvw(as_Register($dst$$reg), 10182 as_Register($src1$$reg), 10183 as_Register($src2$$reg)); 10184 %} 10185 10186 ins_pipe(ialu_reg_reg_vshift); 10187 %} 10188 10189 // Shift Right Logical Immediate 10190 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10191 match(Set dst (URShiftI src1 src2)); 10192 10193 ins_cost(INSN_COST); 10194 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10195 10196 ins_encode %{ 10197 __ lsrw(as_Register($dst$$reg), 10198 as_Register($src1$$reg), 10199 $src2$$constant & 0x1f); 10200 %} 10201 10202 ins_pipe(ialu_reg_shift); 10203 %} 10204 10205 // Shift Right Arithmetic Register 10206 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10207 match(Set dst (RShiftI src1 src2)); 10208 10209 ins_cost(INSN_COST * 2); 10210 format %{ "asrvw $dst, $src1, $src2" %} 10211 10212 ins_encode %{ 10213 __ asrvw(as_Register($dst$$reg), 10214 as_Register($src1$$reg), 10215 as_Register($src2$$reg)); 10216 %} 10217 10218 ins_pipe(ialu_reg_reg_vshift); 10219 %} 10220 10221 // Shift Right Arithmetic Immediate 10222 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10223 match(Set dst (RShiftI src1 src2)); 10224 10225 ins_cost(INSN_COST); 10226 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10227 10228 ins_encode %{ 10229 __ asrw(as_Register($dst$$reg), 10230 as_Register($src1$$reg), 10231 $src2$$constant & 0x1f); 10232 %} 10233 10234 ins_pipe(ialu_reg_shift); 10235 %} 10236 10237 // Combined Int Mask and Right Shift (using UBFM) 10238 // TODO 10239 10240 // Long Shifts 10241 10242 // Shift Left Register 10243 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10244 match(Set dst (LShiftL src1 src2)); 10245 10246 ins_cost(INSN_COST * 2); 10247 format %{ "lslv $dst, $src1, $src2" %} 10248 10249 ins_encode %{ 10250 __ lslv(as_Register($dst$$reg), 10251 as_Register($src1$$reg), 10252 as_Register($src2$$reg)); 10253 %} 10254 10255 ins_pipe(ialu_reg_reg_vshift); 10256 %} 10257 10258 // Shift Left Immediate 10259 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10260 match(Set dst (LShiftL src1 src2)); 10261 10262 ins_cost(INSN_COST); 10263 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10264 10265 ins_encode %{ 10266 __ lsl(as_Register($dst$$reg), 10267 as_Register($src1$$reg), 10268 $src2$$constant & 0x3f); 10269 %} 10270 10271 ins_pipe(ialu_reg_shift); 10272 %} 10273 10274 // Shift Right Logical Register 10275 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10276 match(Set dst (URShiftL src1 src2)); 10277 10278 ins_cost(INSN_COST * 2); 10279 format %{ "lsrv $dst, $src1, $src2" %} 10280 10281 ins_encode %{ 10282 __ lsrv(as_Register($dst$$reg), 10283 as_Register($src1$$reg), 10284 as_Register($src2$$reg)); 10285 %} 10286 10287 ins_pipe(ialu_reg_reg_vshift); 10288 %} 10289 10290 // Shift Right Logical Immediate 10291 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10292 match(Set dst (URShiftL src1 src2)); 10293 10294 ins_cost(INSN_COST); 10295 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10296 10297 ins_encode %{ 10298 __ lsr(as_Register($dst$$reg), 10299 as_Register($src1$$reg), 10300 $src2$$constant & 0x3f); 10301 %} 10302 10303 ins_pipe(ialu_reg_shift); 10304 %} 10305 10306 // A special-case pattern for card table stores. 10307 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10308 match(Set dst (URShiftL (CastP2X src1) src2)); 10309 10310 ins_cost(INSN_COST); 10311 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10312 10313 ins_encode %{ 10314 __ lsr(as_Register($dst$$reg), 10315 as_Register($src1$$reg), 10316 $src2$$constant & 0x3f); 10317 %} 10318 10319 ins_pipe(ialu_reg_shift); 10320 %} 10321 10322 // Shift Right Arithmetic Register 10323 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10324 match(Set dst (RShiftL src1 src2)); 10325 10326 ins_cost(INSN_COST * 2); 10327 format %{ "asrv $dst, $src1, $src2" %} 10328 10329 ins_encode %{ 10330 __ asrv(as_Register($dst$$reg), 10331 as_Register($src1$$reg), 10332 as_Register($src2$$reg)); 10333 %} 10334 10335 ins_pipe(ialu_reg_reg_vshift); 10336 %} 10337 10338 // Shift Right Arithmetic Immediate 10339 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10340 match(Set dst (RShiftL src1 src2)); 10341 10342 ins_cost(INSN_COST); 10343 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10344 10345 ins_encode %{ 10346 __ asr(as_Register($dst$$reg), 10347 as_Register($src1$$reg), 10348 $src2$$constant & 0x3f); 10349 %} 10350 10351 ins_pipe(ialu_reg_shift); 10352 %} 10353 10354 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10355 10356 instruct regL_not_reg(iRegLNoSp dst, 10357 iRegL src1, immL_M1 m1, 10358 rFlagsReg cr) %{ 10359 match(Set dst (XorL src1 m1)); 10360 ins_cost(INSN_COST); 10361 format %{ "eon $dst, $src1, zr" %} 10362 10363 ins_encode %{ 10364 __ eon(as_Register($dst$$reg), 10365 as_Register($src1$$reg), 10366 zr, 10367 Assembler::LSL, 0); 10368 %} 10369 10370 ins_pipe(ialu_reg); 10371 %} 10372 instruct regI_not_reg(iRegINoSp dst, 10373 iRegIorL2I src1, immI_M1 m1, 10374 rFlagsReg cr) %{ 10375 match(Set dst (XorI src1 m1)); 10376 ins_cost(INSN_COST); 10377 format %{ "eonw $dst, $src1, zr" %} 10378 10379 ins_encode %{ 10380 __ eonw(as_Register($dst$$reg), 10381 as_Register($src1$$reg), 10382 zr, 10383 Assembler::LSL, 0); 10384 %} 10385 10386 ins_pipe(ialu_reg); 10387 %} 10388 10389 instruct AndI_reg_not_reg(iRegINoSp dst, 10390 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10391 rFlagsReg cr) %{ 10392 match(Set dst (AndI src1 (XorI src2 m1))); 10393 ins_cost(INSN_COST); 10394 format %{ "bicw $dst, $src1, $src2" %} 10395 10396 ins_encode %{ 10397 __ bicw(as_Register($dst$$reg), 10398 as_Register($src1$$reg), 10399 as_Register($src2$$reg), 10400 Assembler::LSL, 0); 10401 %} 10402 10403 ins_pipe(ialu_reg_reg); 10404 %} 10405 10406 instruct AndL_reg_not_reg(iRegLNoSp dst, 10407 iRegL src1, iRegL src2, immL_M1 m1, 10408 rFlagsReg cr) %{ 10409 match(Set dst (AndL src1 (XorL src2 m1))); 10410 ins_cost(INSN_COST); 10411 format %{ "bic $dst, $src1, $src2" %} 10412 10413 ins_encode %{ 10414 __ bic(as_Register($dst$$reg), 10415 as_Register($src1$$reg), 10416 as_Register($src2$$reg), 10417 Assembler::LSL, 0); 10418 %} 10419 10420 ins_pipe(ialu_reg_reg); 10421 %} 10422 10423 instruct OrI_reg_not_reg(iRegINoSp dst, 10424 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10425 rFlagsReg cr) %{ 10426 match(Set dst (OrI src1 (XorI src2 m1))); 10427 ins_cost(INSN_COST); 10428 format %{ "ornw $dst, $src1, $src2" %} 10429 10430 ins_encode %{ 10431 __ ornw(as_Register($dst$$reg), 10432 as_Register($src1$$reg), 10433 as_Register($src2$$reg), 10434 Assembler::LSL, 0); 10435 %} 10436 10437 ins_pipe(ialu_reg_reg); 10438 %} 10439 10440 instruct OrL_reg_not_reg(iRegLNoSp dst, 10441 iRegL src1, iRegL src2, immL_M1 m1, 10442 rFlagsReg cr) %{ 10443 match(Set dst (OrL src1 (XorL src2 m1))); 10444 ins_cost(INSN_COST); 10445 format %{ "orn $dst, $src1, $src2" %} 10446 10447 ins_encode %{ 10448 __ orn(as_Register($dst$$reg), 10449 as_Register($src1$$reg), 10450 as_Register($src2$$reg), 10451 Assembler::LSL, 0); 10452 %} 10453 10454 ins_pipe(ialu_reg_reg); 10455 %} 10456 10457 instruct XorI_reg_not_reg(iRegINoSp dst, 10458 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10459 rFlagsReg cr) %{ 10460 match(Set dst (XorI m1 (XorI src2 src1))); 10461 ins_cost(INSN_COST); 10462 format %{ "eonw $dst, $src1, $src2" %} 10463 10464 ins_encode %{ 10465 __ eonw(as_Register($dst$$reg), 10466 as_Register($src1$$reg), 10467 as_Register($src2$$reg), 10468 Assembler::LSL, 0); 10469 %} 10470 10471 ins_pipe(ialu_reg_reg); 10472 %} 10473 10474 instruct XorL_reg_not_reg(iRegLNoSp dst, 10475 iRegL src1, iRegL src2, immL_M1 m1, 10476 rFlagsReg cr) %{ 10477 match(Set dst (XorL m1 (XorL src2 src1))); 10478 ins_cost(INSN_COST); 10479 format %{ "eon $dst, $src1, $src2" %} 10480 10481 ins_encode %{ 10482 __ eon(as_Register($dst$$reg), 10483 as_Register($src1$$reg), 10484 as_Register($src2$$reg), 10485 Assembler::LSL, 0); 10486 %} 10487 10488 ins_pipe(ialu_reg_reg); 10489 %} 10490 10491 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10492 iRegIorL2I src1, iRegIorL2I src2, 10493 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10494 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10495 ins_cost(1.9 * INSN_COST); 10496 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10497 10498 ins_encode %{ 10499 __ bicw(as_Register($dst$$reg), 10500 as_Register($src1$$reg), 10501 as_Register($src2$$reg), 10502 Assembler::LSR, 10503 $src3$$constant & 0x1f); 10504 %} 10505 10506 ins_pipe(ialu_reg_reg_shift); 10507 %} 10508 10509 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10510 iRegL src1, iRegL src2, 10511 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10512 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10513 ins_cost(1.9 * INSN_COST); 10514 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10515 10516 ins_encode %{ 10517 __ bic(as_Register($dst$$reg), 10518 as_Register($src1$$reg), 10519 as_Register($src2$$reg), 10520 Assembler::LSR, 10521 $src3$$constant & 0x3f); 10522 %} 10523 10524 ins_pipe(ialu_reg_reg_shift); 10525 %} 10526 10527 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10528 iRegIorL2I src1, iRegIorL2I src2, 10529 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10530 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10531 ins_cost(1.9 * INSN_COST); 10532 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10533 10534 ins_encode %{ 10535 __ bicw(as_Register($dst$$reg), 10536 as_Register($src1$$reg), 10537 as_Register($src2$$reg), 10538 Assembler::ASR, 10539 $src3$$constant & 0x1f); 10540 %} 10541 10542 ins_pipe(ialu_reg_reg_shift); 10543 %} 10544 10545 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10546 iRegL src1, iRegL src2, 10547 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10548 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10549 ins_cost(1.9 * INSN_COST); 10550 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10551 10552 ins_encode %{ 10553 __ bic(as_Register($dst$$reg), 10554 as_Register($src1$$reg), 10555 as_Register($src2$$reg), 10556 Assembler::ASR, 10557 $src3$$constant & 0x3f); 10558 %} 10559 10560 ins_pipe(ialu_reg_reg_shift); 10561 %} 10562 10563 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10564 iRegIorL2I src1, iRegIorL2I src2, 10565 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10566 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10567 ins_cost(1.9 * INSN_COST); 10568 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10569 10570 ins_encode %{ 10571 __ bicw(as_Register($dst$$reg), 10572 as_Register($src1$$reg), 10573 as_Register($src2$$reg), 10574 Assembler::LSL, 10575 $src3$$constant & 0x1f); 10576 %} 10577 10578 ins_pipe(ialu_reg_reg_shift); 10579 %} 10580 10581 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10582 iRegL src1, iRegL src2, 10583 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10584 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10585 ins_cost(1.9 * INSN_COST); 10586 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10587 10588 ins_encode %{ 10589 __ bic(as_Register($dst$$reg), 10590 as_Register($src1$$reg), 10591 as_Register($src2$$reg), 10592 Assembler::LSL, 10593 $src3$$constant & 0x3f); 10594 %} 10595 10596 ins_pipe(ialu_reg_reg_shift); 10597 %} 10598 10599 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10600 iRegIorL2I src1, iRegIorL2I src2, 10601 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10602 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10603 ins_cost(1.9 * INSN_COST); 10604 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10605 10606 ins_encode %{ 10607 __ eonw(as_Register($dst$$reg), 10608 as_Register($src1$$reg), 10609 as_Register($src2$$reg), 10610 Assembler::LSR, 10611 $src3$$constant & 0x1f); 10612 %} 10613 10614 ins_pipe(ialu_reg_reg_shift); 10615 %} 10616 10617 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10618 iRegL src1, iRegL src2, 10619 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10620 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10621 ins_cost(1.9 * INSN_COST); 10622 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10623 10624 ins_encode %{ 10625 __ eon(as_Register($dst$$reg), 10626 as_Register($src1$$reg), 10627 as_Register($src2$$reg), 10628 Assembler::LSR, 10629 $src3$$constant & 0x3f); 10630 %} 10631 10632 ins_pipe(ialu_reg_reg_shift); 10633 %} 10634 10635 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10636 iRegIorL2I src1, iRegIorL2I src2, 10637 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10638 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10639 ins_cost(1.9 * INSN_COST); 10640 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10641 10642 ins_encode %{ 10643 __ eonw(as_Register($dst$$reg), 10644 as_Register($src1$$reg), 10645 as_Register($src2$$reg), 10646 Assembler::ASR, 10647 $src3$$constant & 0x1f); 10648 %} 10649 10650 ins_pipe(ialu_reg_reg_shift); 10651 %} 10652 10653 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10654 iRegL src1, iRegL src2, 10655 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10656 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10657 ins_cost(1.9 * INSN_COST); 10658 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10659 10660 ins_encode %{ 10661 __ eon(as_Register($dst$$reg), 10662 as_Register($src1$$reg), 10663 as_Register($src2$$reg), 10664 Assembler::ASR, 10665 $src3$$constant & 0x3f); 10666 %} 10667 10668 ins_pipe(ialu_reg_reg_shift); 10669 %} 10670 10671 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10672 iRegIorL2I src1, iRegIorL2I src2, 10673 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10674 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10675 ins_cost(1.9 * INSN_COST); 10676 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10677 10678 ins_encode %{ 10679 __ eonw(as_Register($dst$$reg), 10680 as_Register($src1$$reg), 10681 as_Register($src2$$reg), 10682 Assembler::LSL, 10683 $src3$$constant & 0x1f); 10684 %} 10685 10686 ins_pipe(ialu_reg_reg_shift); 10687 %} 10688 10689 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10690 iRegL src1, iRegL src2, 10691 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10692 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10693 ins_cost(1.9 * INSN_COST); 10694 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10695 10696 ins_encode %{ 10697 __ eon(as_Register($dst$$reg), 10698 as_Register($src1$$reg), 10699 as_Register($src2$$reg), 10700 Assembler::LSL, 10701 $src3$$constant & 0x3f); 10702 %} 10703 10704 ins_pipe(ialu_reg_reg_shift); 10705 %} 10706 10707 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10708 iRegIorL2I src1, iRegIorL2I src2, 10709 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10710 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10711 ins_cost(1.9 * INSN_COST); 10712 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10713 10714 ins_encode %{ 10715 __ ornw(as_Register($dst$$reg), 10716 as_Register($src1$$reg), 10717 as_Register($src2$$reg), 10718 Assembler::LSR, 10719 $src3$$constant & 0x1f); 10720 %} 10721 10722 ins_pipe(ialu_reg_reg_shift); 10723 %} 10724 10725 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10726 iRegL src1, iRegL src2, 10727 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10728 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10729 ins_cost(1.9 * INSN_COST); 10730 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10731 10732 ins_encode %{ 10733 __ orn(as_Register($dst$$reg), 10734 as_Register($src1$$reg), 10735 as_Register($src2$$reg), 10736 Assembler::LSR, 10737 $src3$$constant & 0x3f); 10738 %} 10739 10740 ins_pipe(ialu_reg_reg_shift); 10741 %} 10742 10743 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10744 iRegIorL2I src1, iRegIorL2I src2, 10745 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10746 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10747 ins_cost(1.9 * INSN_COST); 10748 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10749 10750 ins_encode %{ 10751 __ ornw(as_Register($dst$$reg), 10752 as_Register($src1$$reg), 10753 as_Register($src2$$reg), 10754 Assembler::ASR, 10755 $src3$$constant & 0x1f); 10756 %} 10757 10758 ins_pipe(ialu_reg_reg_shift); 10759 %} 10760 10761 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10762 iRegL src1, iRegL src2, 10763 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10764 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10765 ins_cost(1.9 * INSN_COST); 10766 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10767 10768 ins_encode %{ 10769 __ orn(as_Register($dst$$reg), 10770 as_Register($src1$$reg), 10771 as_Register($src2$$reg), 10772 Assembler::ASR, 10773 $src3$$constant & 0x3f); 10774 %} 10775 10776 ins_pipe(ialu_reg_reg_shift); 10777 %} 10778 10779 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10780 iRegIorL2I src1, iRegIorL2I src2, 10781 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10782 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10783 ins_cost(1.9 * INSN_COST); 10784 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10785 10786 ins_encode %{ 10787 __ ornw(as_Register($dst$$reg), 10788 as_Register($src1$$reg), 10789 as_Register($src2$$reg), 10790 Assembler::LSL, 10791 $src3$$constant & 0x1f); 10792 %} 10793 10794 ins_pipe(ialu_reg_reg_shift); 10795 %} 10796 10797 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10798 iRegL src1, iRegL src2, 10799 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10800 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10801 ins_cost(1.9 * INSN_COST); 10802 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10803 10804 ins_encode %{ 10805 __ orn(as_Register($dst$$reg), 10806 as_Register($src1$$reg), 10807 as_Register($src2$$reg), 10808 Assembler::LSL, 10809 $src3$$constant & 0x3f); 10810 %} 10811 10812 ins_pipe(ialu_reg_reg_shift); 10813 %} 10814 10815 instruct AndI_reg_URShift_reg(iRegINoSp dst, 10816 iRegIorL2I src1, iRegIorL2I src2, 10817 immI src3, rFlagsReg cr) %{ 10818 match(Set dst (AndI src1 (URShiftI src2 src3))); 10819 10820 ins_cost(1.9 * INSN_COST); 10821 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10822 10823 ins_encode %{ 10824 __ andw(as_Register($dst$$reg), 10825 as_Register($src1$$reg), 10826 as_Register($src2$$reg), 10827 Assembler::LSR, 10828 $src3$$constant & 0x1f); 10829 %} 10830 10831 ins_pipe(ialu_reg_reg_shift); 10832 %} 10833 10834 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 10835 iRegL src1, iRegL src2, 10836 immI src3, rFlagsReg cr) %{ 10837 match(Set dst (AndL src1 (URShiftL src2 src3))); 10838 10839 ins_cost(1.9 * INSN_COST); 10840 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10841 10842 ins_encode %{ 10843 __ andr(as_Register($dst$$reg), 10844 as_Register($src1$$reg), 10845 as_Register($src2$$reg), 10846 Assembler::LSR, 10847 $src3$$constant & 0x3f); 10848 %} 10849 10850 ins_pipe(ialu_reg_reg_shift); 10851 %} 10852 10853 instruct AndI_reg_RShift_reg(iRegINoSp dst, 10854 iRegIorL2I src1, iRegIorL2I src2, 10855 immI src3, rFlagsReg cr) %{ 10856 match(Set dst (AndI src1 (RShiftI src2 src3))); 10857 10858 ins_cost(1.9 * INSN_COST); 10859 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10860 10861 ins_encode %{ 10862 __ andw(as_Register($dst$$reg), 10863 as_Register($src1$$reg), 10864 as_Register($src2$$reg), 10865 Assembler::ASR, 10866 $src3$$constant & 0x1f); 10867 %} 10868 10869 ins_pipe(ialu_reg_reg_shift); 10870 %} 10871 10872 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10873 iRegL src1, iRegL src2, 10874 immI src3, rFlagsReg cr) %{ 10875 match(Set dst (AndL src1 (RShiftL src2 src3))); 10876 10877 ins_cost(1.9 * INSN_COST); 10878 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10879 10880 ins_encode %{ 10881 __ andr(as_Register($dst$$reg), 10882 as_Register($src1$$reg), 10883 as_Register($src2$$reg), 10884 Assembler::ASR, 10885 $src3$$constant & 0x3f); 10886 %} 10887 10888 ins_pipe(ialu_reg_reg_shift); 10889 %} 10890 10891 instruct AndI_reg_LShift_reg(iRegINoSp dst, 10892 iRegIorL2I src1, iRegIorL2I src2, 10893 immI src3, rFlagsReg cr) %{ 10894 match(Set dst (AndI src1 (LShiftI src2 src3))); 10895 10896 ins_cost(1.9 * INSN_COST); 10897 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10898 10899 ins_encode %{ 10900 __ andw(as_Register($dst$$reg), 10901 as_Register($src1$$reg), 10902 as_Register($src2$$reg), 10903 Assembler::LSL, 10904 $src3$$constant & 0x1f); 10905 %} 10906 10907 ins_pipe(ialu_reg_reg_shift); 10908 %} 10909 10910 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10911 iRegL src1, iRegL src2, 10912 immI src3, rFlagsReg cr) %{ 10913 match(Set dst (AndL src1 (LShiftL src2 src3))); 10914 10915 ins_cost(1.9 * INSN_COST); 10916 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10917 10918 ins_encode %{ 10919 __ andr(as_Register($dst$$reg), 10920 as_Register($src1$$reg), 10921 as_Register($src2$$reg), 10922 Assembler::LSL, 10923 $src3$$constant & 0x3f); 10924 %} 10925 10926 ins_pipe(ialu_reg_reg_shift); 10927 %} 10928 10929 instruct XorI_reg_URShift_reg(iRegINoSp dst, 10930 iRegIorL2I src1, iRegIorL2I src2, 10931 immI src3, rFlagsReg cr) %{ 10932 match(Set dst (XorI src1 (URShiftI src2 src3))); 10933 10934 ins_cost(1.9 * INSN_COST); 10935 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10936 10937 ins_encode %{ 10938 __ eorw(as_Register($dst$$reg), 10939 as_Register($src1$$reg), 10940 as_Register($src2$$reg), 10941 Assembler::LSR, 10942 $src3$$constant & 0x1f); 10943 %} 10944 10945 ins_pipe(ialu_reg_reg_shift); 10946 %} 10947 10948 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10949 iRegL src1, iRegL src2, 10950 immI src3, rFlagsReg cr) %{ 10951 match(Set dst (XorL src1 (URShiftL src2 src3))); 10952 10953 ins_cost(1.9 * INSN_COST); 10954 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10955 10956 ins_encode %{ 10957 __ eor(as_Register($dst$$reg), 10958 as_Register($src1$$reg), 10959 as_Register($src2$$reg), 10960 Assembler::LSR, 10961 $src3$$constant & 0x3f); 10962 %} 10963 10964 ins_pipe(ialu_reg_reg_shift); 10965 %} 10966 10967 instruct XorI_reg_RShift_reg(iRegINoSp dst, 10968 iRegIorL2I src1, iRegIorL2I src2, 10969 immI src3, rFlagsReg cr) %{ 10970 match(Set dst (XorI src1 (RShiftI src2 src3))); 10971 10972 ins_cost(1.9 * INSN_COST); 10973 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10974 10975 ins_encode %{ 10976 __ eorw(as_Register($dst$$reg), 10977 as_Register($src1$$reg), 10978 as_Register($src2$$reg), 10979 Assembler::ASR, 10980 $src3$$constant & 0x1f); 10981 %} 10982 10983 ins_pipe(ialu_reg_reg_shift); 10984 %} 10985 10986 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10987 iRegL src1, iRegL src2, 10988 immI src3, rFlagsReg cr) %{ 10989 match(Set dst (XorL src1 (RShiftL src2 src3))); 10990 10991 ins_cost(1.9 * INSN_COST); 10992 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10993 10994 ins_encode %{ 10995 __ eor(as_Register($dst$$reg), 10996 as_Register($src1$$reg), 10997 as_Register($src2$$reg), 10998 Assembler::ASR, 10999 $src3$$constant & 0x3f); 11000 %} 11001 11002 ins_pipe(ialu_reg_reg_shift); 11003 %} 11004 11005 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11006 iRegIorL2I src1, iRegIorL2I src2, 11007 immI src3, rFlagsReg cr) %{ 11008 match(Set dst (XorI src1 (LShiftI src2 src3))); 11009 11010 ins_cost(1.9 * INSN_COST); 11011 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11012 11013 ins_encode %{ 11014 __ eorw(as_Register($dst$$reg), 11015 as_Register($src1$$reg), 11016 as_Register($src2$$reg), 11017 Assembler::LSL, 11018 $src3$$constant & 0x1f); 11019 %} 11020 11021 ins_pipe(ialu_reg_reg_shift); 11022 %} 11023 11024 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11025 iRegL src1, iRegL src2, 11026 immI src3, rFlagsReg cr) %{ 11027 match(Set dst (XorL src1 (LShiftL src2 src3))); 11028 11029 ins_cost(1.9 * INSN_COST); 11030 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11031 11032 ins_encode %{ 11033 __ eor(as_Register($dst$$reg), 11034 as_Register($src1$$reg), 11035 as_Register($src2$$reg), 11036 Assembler::LSL, 11037 $src3$$constant & 0x3f); 11038 %} 11039 11040 ins_pipe(ialu_reg_reg_shift); 11041 %} 11042 11043 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11044 iRegIorL2I src1, iRegIorL2I src2, 11045 immI src3, rFlagsReg cr) %{ 11046 match(Set dst (OrI src1 (URShiftI src2 src3))); 11047 11048 ins_cost(1.9 * INSN_COST); 11049 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11050 11051 ins_encode %{ 11052 __ orrw(as_Register($dst$$reg), 11053 as_Register($src1$$reg), 11054 as_Register($src2$$reg), 11055 Assembler::LSR, 11056 $src3$$constant & 0x1f); 11057 %} 11058 11059 ins_pipe(ialu_reg_reg_shift); 11060 %} 11061 11062 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11063 iRegL src1, iRegL src2, 11064 immI src3, rFlagsReg cr) %{ 11065 match(Set dst (OrL src1 (URShiftL src2 src3))); 11066 11067 ins_cost(1.9 * INSN_COST); 11068 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11069 11070 ins_encode %{ 11071 __ orr(as_Register($dst$$reg), 11072 as_Register($src1$$reg), 11073 as_Register($src2$$reg), 11074 Assembler::LSR, 11075 $src3$$constant & 0x3f); 11076 %} 11077 11078 ins_pipe(ialu_reg_reg_shift); 11079 %} 11080 11081 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11082 iRegIorL2I src1, iRegIorL2I src2, 11083 immI src3, rFlagsReg cr) %{ 11084 match(Set dst (OrI src1 (RShiftI src2 src3))); 11085 11086 ins_cost(1.9 * INSN_COST); 11087 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11088 11089 ins_encode %{ 11090 __ orrw(as_Register($dst$$reg), 11091 as_Register($src1$$reg), 11092 as_Register($src2$$reg), 11093 Assembler::ASR, 11094 $src3$$constant & 0x1f); 11095 %} 11096 11097 ins_pipe(ialu_reg_reg_shift); 11098 %} 11099 11100 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11101 iRegL src1, iRegL src2, 11102 immI src3, rFlagsReg cr) %{ 11103 match(Set dst (OrL src1 (RShiftL src2 src3))); 11104 11105 ins_cost(1.9 * INSN_COST); 11106 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11107 11108 ins_encode %{ 11109 __ orr(as_Register($dst$$reg), 11110 as_Register($src1$$reg), 11111 as_Register($src2$$reg), 11112 Assembler::ASR, 11113 $src3$$constant & 0x3f); 11114 %} 11115 11116 ins_pipe(ialu_reg_reg_shift); 11117 %} 11118 11119 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11120 iRegIorL2I src1, iRegIorL2I src2, 11121 immI src3, rFlagsReg cr) %{ 11122 match(Set dst (OrI src1 (LShiftI src2 src3))); 11123 11124 ins_cost(1.9 * INSN_COST); 11125 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11126 11127 ins_encode %{ 11128 __ orrw(as_Register($dst$$reg), 11129 as_Register($src1$$reg), 11130 as_Register($src2$$reg), 11131 Assembler::LSL, 11132 $src3$$constant & 0x1f); 11133 %} 11134 11135 ins_pipe(ialu_reg_reg_shift); 11136 %} 11137 11138 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11139 iRegL src1, iRegL src2, 11140 immI src3, rFlagsReg cr) %{ 11141 match(Set dst (OrL src1 (LShiftL src2 src3))); 11142 11143 ins_cost(1.9 * INSN_COST); 11144 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11145 11146 ins_encode %{ 11147 __ orr(as_Register($dst$$reg), 11148 as_Register($src1$$reg), 11149 as_Register($src2$$reg), 11150 Assembler::LSL, 11151 $src3$$constant & 0x3f); 11152 %} 11153 11154 ins_pipe(ialu_reg_reg_shift); 11155 %} 11156 11157 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11158 iRegIorL2I src1, iRegIorL2I src2, 11159 immI src3, rFlagsReg cr) %{ 11160 match(Set dst (AddI src1 (URShiftI src2 src3))); 11161 11162 ins_cost(1.9 * INSN_COST); 11163 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11164 11165 ins_encode %{ 11166 __ addw(as_Register($dst$$reg), 11167 as_Register($src1$$reg), 11168 as_Register($src2$$reg), 11169 Assembler::LSR, 11170 $src3$$constant & 0x1f); 11171 %} 11172 11173 ins_pipe(ialu_reg_reg_shift); 11174 %} 11175 11176 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11177 iRegL src1, iRegL src2, 11178 immI src3, rFlagsReg cr) %{ 11179 match(Set dst (AddL src1 (URShiftL src2 src3))); 11180 11181 ins_cost(1.9 * INSN_COST); 11182 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11183 11184 ins_encode %{ 11185 __ add(as_Register($dst$$reg), 11186 as_Register($src1$$reg), 11187 as_Register($src2$$reg), 11188 Assembler::LSR, 11189 $src3$$constant & 0x3f); 11190 %} 11191 11192 ins_pipe(ialu_reg_reg_shift); 11193 %} 11194 11195 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11196 iRegIorL2I src1, iRegIorL2I src2, 11197 immI src3, rFlagsReg cr) %{ 11198 match(Set dst (AddI src1 (RShiftI src2 src3))); 11199 11200 ins_cost(1.9 * INSN_COST); 11201 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11202 11203 ins_encode %{ 11204 __ addw(as_Register($dst$$reg), 11205 as_Register($src1$$reg), 11206 as_Register($src2$$reg), 11207 Assembler::ASR, 11208 $src3$$constant & 0x1f); 11209 %} 11210 11211 ins_pipe(ialu_reg_reg_shift); 11212 %} 11213 11214 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11215 iRegL src1, iRegL src2, 11216 immI src3, rFlagsReg cr) %{ 11217 match(Set dst (AddL src1 (RShiftL src2 src3))); 11218 11219 ins_cost(1.9 * INSN_COST); 11220 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11221 11222 ins_encode %{ 11223 __ add(as_Register($dst$$reg), 11224 as_Register($src1$$reg), 11225 as_Register($src2$$reg), 11226 Assembler::ASR, 11227 $src3$$constant & 0x3f); 11228 %} 11229 11230 ins_pipe(ialu_reg_reg_shift); 11231 %} 11232 11233 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11234 iRegIorL2I src1, iRegIorL2I src2, 11235 immI src3, rFlagsReg cr) %{ 11236 match(Set dst (AddI src1 (LShiftI src2 src3))); 11237 11238 ins_cost(1.9 * INSN_COST); 11239 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11240 11241 ins_encode %{ 11242 __ addw(as_Register($dst$$reg), 11243 as_Register($src1$$reg), 11244 as_Register($src2$$reg), 11245 Assembler::LSL, 11246 $src3$$constant & 0x1f); 11247 %} 11248 11249 ins_pipe(ialu_reg_reg_shift); 11250 %} 11251 11252 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11253 iRegL src1, iRegL src2, 11254 immI src3, rFlagsReg cr) %{ 11255 match(Set dst (AddL src1 (LShiftL src2 src3))); 11256 11257 ins_cost(1.9 * INSN_COST); 11258 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11259 11260 ins_encode %{ 11261 __ add(as_Register($dst$$reg), 11262 as_Register($src1$$reg), 11263 as_Register($src2$$reg), 11264 Assembler::LSL, 11265 $src3$$constant & 0x3f); 11266 %} 11267 11268 ins_pipe(ialu_reg_reg_shift); 11269 %} 11270 11271 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11272 iRegIorL2I src1, iRegIorL2I src2, 11273 immI src3, rFlagsReg cr) %{ 11274 match(Set dst (SubI src1 (URShiftI src2 src3))); 11275 11276 ins_cost(1.9 * INSN_COST); 11277 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11278 11279 ins_encode %{ 11280 __ subw(as_Register($dst$$reg), 11281 as_Register($src1$$reg), 11282 as_Register($src2$$reg), 11283 Assembler::LSR, 11284 $src3$$constant & 0x1f); 11285 %} 11286 11287 ins_pipe(ialu_reg_reg_shift); 11288 %} 11289 11290 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11291 iRegL src1, iRegL src2, 11292 immI src3, rFlagsReg cr) %{ 11293 match(Set dst (SubL src1 (URShiftL src2 src3))); 11294 11295 ins_cost(1.9 * INSN_COST); 11296 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11297 11298 ins_encode %{ 11299 __ sub(as_Register($dst$$reg), 11300 as_Register($src1$$reg), 11301 as_Register($src2$$reg), 11302 Assembler::LSR, 11303 $src3$$constant & 0x3f); 11304 %} 11305 11306 ins_pipe(ialu_reg_reg_shift); 11307 %} 11308 11309 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11310 iRegIorL2I src1, iRegIorL2I src2, 11311 immI src3, rFlagsReg cr) %{ 11312 match(Set dst (SubI src1 (RShiftI src2 src3))); 11313 11314 ins_cost(1.9 * INSN_COST); 11315 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11316 11317 ins_encode %{ 11318 __ subw(as_Register($dst$$reg), 11319 as_Register($src1$$reg), 11320 as_Register($src2$$reg), 11321 Assembler::ASR, 11322 $src3$$constant & 0x1f); 11323 %} 11324 11325 ins_pipe(ialu_reg_reg_shift); 11326 %} 11327 11328 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11329 iRegL src1, iRegL src2, 11330 immI src3, rFlagsReg cr) %{ 11331 match(Set dst (SubL src1 (RShiftL src2 src3))); 11332 11333 ins_cost(1.9 * INSN_COST); 11334 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11335 11336 ins_encode %{ 11337 __ sub(as_Register($dst$$reg), 11338 as_Register($src1$$reg), 11339 as_Register($src2$$reg), 11340 Assembler::ASR, 11341 $src3$$constant & 0x3f); 11342 %} 11343 11344 ins_pipe(ialu_reg_reg_shift); 11345 %} 11346 11347 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11348 iRegIorL2I src1, iRegIorL2I src2, 11349 immI src3, rFlagsReg cr) %{ 11350 match(Set dst (SubI src1 (LShiftI src2 src3))); 11351 11352 ins_cost(1.9 * INSN_COST); 11353 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11354 11355 ins_encode %{ 11356 __ subw(as_Register($dst$$reg), 11357 as_Register($src1$$reg), 11358 as_Register($src2$$reg), 11359 Assembler::LSL, 11360 $src3$$constant & 0x1f); 11361 %} 11362 11363 ins_pipe(ialu_reg_reg_shift); 11364 %} 11365 11366 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11367 iRegL src1, iRegL src2, 11368 immI src3, rFlagsReg cr) %{ 11369 match(Set dst (SubL src1 (LShiftL src2 src3))); 11370 11371 ins_cost(1.9 * INSN_COST); 11372 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11373 11374 ins_encode %{ 11375 __ sub(as_Register($dst$$reg), 11376 as_Register($src1$$reg), 11377 as_Register($src2$$reg), 11378 Assembler::LSL, 11379 $src3$$constant & 0x3f); 11380 %} 11381 11382 ins_pipe(ialu_reg_reg_shift); 11383 %} 11384 11385 11386 11387 // Shift Left followed by Shift Right. 11388 // This idiom is used by the compiler for the i2b bytecode etc. 11389 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11390 %{ 11391 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11392 // Make sure we are not going to exceed what sbfm can do. 11393 predicate((unsigned int)n->in(2)->get_int() <= 63 11394 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11395 11396 ins_cost(INSN_COST * 2); 11397 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11398 ins_encode %{ 11399 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11400 int s = 63 - lshift; 11401 int r = (rshift - lshift) & 63; 11402 __ sbfm(as_Register($dst$$reg), 11403 as_Register($src$$reg), 11404 r, s); 11405 %} 11406 11407 ins_pipe(ialu_reg_shift); 11408 %} 11409 11410 // Shift Left followed by Shift Right. 11411 // This idiom is used by the compiler for the i2b bytecode etc. 11412 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11413 %{ 11414 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11415 // Make sure we are not going to exceed what sbfmw can do. 11416 predicate((unsigned int)n->in(2)->get_int() <= 31 11417 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11418 11419 ins_cost(INSN_COST * 2); 11420 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11421 ins_encode %{ 11422 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11423 int s = 31 - lshift; 11424 int r = (rshift - lshift) & 31; 11425 __ sbfmw(as_Register($dst$$reg), 11426 as_Register($src$$reg), 11427 r, s); 11428 %} 11429 11430 ins_pipe(ialu_reg_shift); 11431 %} 11432 11433 // Shift Left followed by Shift Right. 11434 // This idiom is used by the compiler for the i2b bytecode etc. 11435 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11436 %{ 11437 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11438 // Make sure we are not going to exceed what ubfm can do. 11439 predicate((unsigned int)n->in(2)->get_int() <= 63 11440 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11441 11442 ins_cost(INSN_COST * 2); 11443 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11444 ins_encode %{ 11445 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11446 int s = 63 - lshift; 11447 int r = (rshift - lshift) & 63; 11448 __ ubfm(as_Register($dst$$reg), 11449 as_Register($src$$reg), 11450 r, s); 11451 %} 11452 11453 ins_pipe(ialu_reg_shift); 11454 %} 11455 11456 // Shift Left followed by Shift Right. 11457 // This idiom is used by the compiler for the i2b bytecode etc. 11458 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11459 %{ 11460 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11461 // Make sure we are not going to exceed what ubfmw can do. 11462 predicate((unsigned int)n->in(2)->get_int() <= 31 11463 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11464 11465 ins_cost(INSN_COST * 2); 11466 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11467 ins_encode %{ 11468 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11469 int s = 31 - lshift; 11470 int r = (rshift - lshift) & 31; 11471 __ ubfmw(as_Register($dst$$reg), 11472 as_Register($src$$reg), 11473 r, s); 11474 %} 11475 11476 ins_pipe(ialu_reg_shift); 11477 %} 11478 // Bitfield extract with shift & mask 11479 11480 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11481 %{ 11482 match(Set dst (AndI (URShiftI src rshift) mask)); 11483 11484 ins_cost(INSN_COST); 11485 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11486 ins_encode %{ 11487 int rshift = $rshift$$constant; 11488 long mask = $mask$$constant; 11489 int width = exact_log2(mask+1); 11490 __ ubfxw(as_Register($dst$$reg), 11491 as_Register($src$$reg), rshift, width); 11492 %} 11493 ins_pipe(ialu_reg_shift); 11494 %} 11495 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11496 %{ 11497 match(Set dst (AndL (URShiftL src rshift) mask)); 11498 11499 ins_cost(INSN_COST); 11500 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11501 ins_encode %{ 11502 int rshift = $rshift$$constant; 11503 long mask = $mask$$constant; 11504 int width = exact_log2(mask+1); 11505 __ ubfx(as_Register($dst$$reg), 11506 as_Register($src$$reg), rshift, width); 11507 %} 11508 ins_pipe(ialu_reg_shift); 11509 %} 11510 11511 // We can use ubfx when extending an And with a mask when we know mask 11512 // is positive. We know that because immI_bitmask guarantees it. 11513 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11514 %{ 11515 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11516 11517 ins_cost(INSN_COST * 2); 11518 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11519 ins_encode %{ 11520 int rshift = $rshift$$constant; 11521 long mask = $mask$$constant; 11522 int width = exact_log2(mask+1); 11523 __ ubfx(as_Register($dst$$reg), 11524 as_Register($src$$reg), rshift, width); 11525 %} 11526 ins_pipe(ialu_reg_shift); 11527 %} 11528 11529 // We can use ubfiz when masking by a positive number and then left shifting the result. 11530 // We know that the mask is positive because immI_bitmask guarantees it. 11531 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11532 %{ 11533 match(Set dst (LShiftI (AndI src mask) lshift)); 11534 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11535 (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1)); 11536 11537 ins_cost(INSN_COST); 11538 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11539 ins_encode %{ 11540 int lshift = $lshift$$constant; 11541 long mask = $mask$$constant; 11542 int width = exact_log2(mask+1); 11543 __ ubfizw(as_Register($dst$$reg), 11544 as_Register($src$$reg), lshift, width); 11545 %} 11546 ins_pipe(ialu_reg_shift); 11547 %} 11548 // We can use ubfiz when masking by a positive number and then left shifting the result. 11549 // We know that the mask is positive because immL_bitmask guarantees it. 11550 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11551 %{ 11552 match(Set dst (LShiftL (AndL src mask) lshift)); 11553 predicate((unsigned int)n->in(2)->get_int() <= 63 && 11554 (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1)); 11555 11556 ins_cost(INSN_COST); 11557 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11558 ins_encode %{ 11559 int lshift = $lshift$$constant; 11560 long mask = $mask$$constant; 11561 int width = exact_log2(mask+1); 11562 __ ubfiz(as_Register($dst$$reg), 11563 as_Register($src$$reg), lshift, width); 11564 %} 11565 ins_pipe(ialu_reg_shift); 11566 %} 11567 11568 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11569 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11570 %{ 11571 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); 11572 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11573 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); 11574 11575 ins_cost(INSN_COST); 11576 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11577 ins_encode %{ 11578 int lshift = $lshift$$constant; 11579 long mask = $mask$$constant; 11580 int width = exact_log2(mask+1); 11581 __ ubfiz(as_Register($dst$$reg), 11582 as_Register($src$$reg), lshift, width); 11583 %} 11584 ins_pipe(ialu_reg_shift); 11585 %} 11586 11587 // Rotations 11588 11589 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11590 %{ 11591 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11592 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11593 11594 ins_cost(INSN_COST); 11595 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11596 11597 ins_encode %{ 11598 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11599 $rshift$$constant & 63); 11600 %} 11601 ins_pipe(ialu_reg_reg_extr); 11602 %} 11603 11604 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11605 %{ 11606 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11607 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11608 11609 ins_cost(INSN_COST); 11610 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11611 11612 ins_encode %{ 11613 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11614 $rshift$$constant & 31); 11615 %} 11616 ins_pipe(ialu_reg_reg_extr); 11617 %} 11618 11619 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11620 %{ 11621 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11622 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11623 11624 ins_cost(INSN_COST); 11625 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11626 11627 ins_encode %{ 11628 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11629 $rshift$$constant & 63); 11630 %} 11631 ins_pipe(ialu_reg_reg_extr); 11632 %} 11633 11634 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11635 %{ 11636 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11637 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11638 11639 ins_cost(INSN_COST); 11640 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11641 11642 ins_encode %{ 11643 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11644 $rshift$$constant & 31); 11645 %} 11646 ins_pipe(ialu_reg_reg_extr); 11647 %} 11648 11649 11650 // rol expander 11651 11652 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11653 %{ 11654 effect(DEF dst, USE src, USE shift); 11655 11656 format %{ "rol $dst, $src, $shift" %} 11657 ins_cost(INSN_COST * 3); 11658 ins_encode %{ 11659 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11660 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11661 rscratch1); 11662 %} 11663 ins_pipe(ialu_reg_reg_vshift); 11664 %} 11665 11666 // rol expander 11667 11668 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11669 %{ 11670 effect(DEF dst, USE src, USE shift); 11671 11672 format %{ "rol $dst, $src, $shift" %} 11673 ins_cost(INSN_COST * 3); 11674 ins_encode %{ 11675 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11676 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11677 rscratch1); 11678 %} 11679 ins_pipe(ialu_reg_reg_vshift); 11680 %} 11681 11682 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11683 %{ 11684 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11685 11686 expand %{ 11687 rolL_rReg(dst, src, shift, cr); 11688 %} 11689 %} 11690 11691 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11692 %{ 11693 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11694 11695 expand %{ 11696 rolL_rReg(dst, src, shift, cr); 11697 %} 11698 %} 11699 11700 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11701 %{ 11702 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11703 11704 expand %{ 11705 rolI_rReg(dst, src, shift, cr); 11706 %} 11707 %} 11708 11709 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11710 %{ 11711 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11712 11713 expand %{ 11714 rolI_rReg(dst, src, shift, cr); 11715 %} 11716 %} 11717 11718 // ror expander 11719 11720 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11721 %{ 11722 effect(DEF dst, USE src, USE shift); 11723 11724 format %{ "ror $dst, $src, $shift" %} 11725 ins_cost(INSN_COST); 11726 ins_encode %{ 11727 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11728 as_Register($shift$$reg)); 11729 %} 11730 ins_pipe(ialu_reg_reg_vshift); 11731 %} 11732 11733 // ror expander 11734 11735 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11736 %{ 11737 effect(DEF dst, USE src, USE shift); 11738 11739 format %{ "ror $dst, $src, $shift" %} 11740 ins_cost(INSN_COST); 11741 ins_encode %{ 11742 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11743 as_Register($shift$$reg)); 11744 %} 11745 ins_pipe(ialu_reg_reg_vshift); 11746 %} 11747 11748 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11749 %{ 11750 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11751 11752 expand %{ 11753 rorL_rReg(dst, src, shift, cr); 11754 %} 11755 %} 11756 11757 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11758 %{ 11759 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11760 11761 expand %{ 11762 rorL_rReg(dst, src, shift, cr); 11763 %} 11764 %} 11765 11766 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11767 %{ 11768 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11769 11770 expand %{ 11771 rorI_rReg(dst, src, shift, cr); 11772 %} 11773 %} 11774 11775 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11776 %{ 11777 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11778 11779 expand %{ 11780 rorI_rReg(dst, src, shift, cr); 11781 %} 11782 %} 11783 11784 // Add/subtract (extended) 11785 11786 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11787 %{ 11788 match(Set dst (AddL src1 (ConvI2L src2))); 11789 ins_cost(INSN_COST); 11790 format %{ "add $dst, $src1, $src2, sxtw" %} 11791 11792 ins_encode %{ 11793 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11794 as_Register($src2$$reg), ext::sxtw); 11795 %} 11796 ins_pipe(ialu_reg_reg); 11797 %}; 11798 11799 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11800 %{ 11801 match(Set dst (SubL src1 (ConvI2L src2))); 11802 ins_cost(INSN_COST); 11803 format %{ "sub $dst, $src1, $src2, sxtw" %} 11804 11805 ins_encode %{ 11806 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11807 as_Register($src2$$reg), ext::sxtw); 11808 %} 11809 ins_pipe(ialu_reg_reg); 11810 %}; 11811 11812 11813 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11814 %{ 11815 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11816 ins_cost(INSN_COST); 11817 format %{ "add $dst, $src1, $src2, sxth" %} 11818 11819 ins_encode %{ 11820 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11821 as_Register($src2$$reg), ext::sxth); 11822 %} 11823 ins_pipe(ialu_reg_reg); 11824 %} 11825 11826 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11827 %{ 11828 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11829 ins_cost(INSN_COST); 11830 format %{ "add $dst, $src1, $src2, sxtb" %} 11831 11832 ins_encode %{ 11833 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11834 as_Register($src2$$reg), ext::sxtb); 11835 %} 11836 ins_pipe(ialu_reg_reg); 11837 %} 11838 11839 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11840 %{ 11841 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 11842 ins_cost(INSN_COST); 11843 format %{ "add $dst, $src1, $src2, uxtb" %} 11844 11845 ins_encode %{ 11846 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11847 as_Register($src2$$reg), ext::uxtb); 11848 %} 11849 ins_pipe(ialu_reg_reg); 11850 %} 11851 11852 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 11853 %{ 11854 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11855 ins_cost(INSN_COST); 11856 format %{ "add $dst, $src1, $src2, sxth" %} 11857 11858 ins_encode %{ 11859 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11860 as_Register($src2$$reg), ext::sxth); 11861 %} 11862 ins_pipe(ialu_reg_reg); 11863 %} 11864 11865 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 11866 %{ 11867 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11868 ins_cost(INSN_COST); 11869 format %{ "add $dst, $src1, $src2, sxtw" %} 11870 11871 ins_encode %{ 11872 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11873 as_Register($src2$$reg), ext::sxtw); 11874 %} 11875 ins_pipe(ialu_reg_reg); 11876 %} 11877 11878 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11879 %{ 11880 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11881 ins_cost(INSN_COST); 11882 format %{ "add $dst, $src1, $src2, sxtb" %} 11883 11884 ins_encode %{ 11885 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11886 as_Register($src2$$reg), ext::sxtb); 11887 %} 11888 ins_pipe(ialu_reg_reg); 11889 %} 11890 11891 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11892 %{ 11893 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 11894 ins_cost(INSN_COST); 11895 format %{ "add $dst, $src1, $src2, uxtb" %} 11896 11897 ins_encode %{ 11898 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11899 as_Register($src2$$reg), ext::uxtb); 11900 %} 11901 ins_pipe(ialu_reg_reg); 11902 %} 11903 11904 11905 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11906 %{ 11907 match(Set dst (AddI src1 (AndI src2 mask))); 11908 ins_cost(INSN_COST); 11909 format %{ "addw $dst, $src1, $src2, uxtb" %} 11910 11911 ins_encode %{ 11912 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11913 as_Register($src2$$reg), ext::uxtb); 11914 %} 11915 ins_pipe(ialu_reg_reg); 11916 %} 11917 11918 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11919 %{ 11920 match(Set dst (AddI src1 (AndI src2 mask))); 11921 ins_cost(INSN_COST); 11922 format %{ "addw $dst, $src1, $src2, uxth" %} 11923 11924 ins_encode %{ 11925 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11926 as_Register($src2$$reg), ext::uxth); 11927 %} 11928 ins_pipe(ialu_reg_reg); 11929 %} 11930 11931 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11932 %{ 11933 match(Set dst (AddL src1 (AndL src2 mask))); 11934 ins_cost(INSN_COST); 11935 format %{ "add $dst, $src1, $src2, uxtb" %} 11936 11937 ins_encode %{ 11938 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11939 as_Register($src2$$reg), ext::uxtb); 11940 %} 11941 ins_pipe(ialu_reg_reg); 11942 %} 11943 11944 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11945 %{ 11946 match(Set dst (AddL src1 (AndL src2 mask))); 11947 ins_cost(INSN_COST); 11948 format %{ "add $dst, $src1, $src2, uxth" %} 11949 11950 ins_encode %{ 11951 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11952 as_Register($src2$$reg), ext::uxth); 11953 %} 11954 ins_pipe(ialu_reg_reg); 11955 %} 11956 11957 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11958 %{ 11959 match(Set dst (AddL src1 (AndL src2 mask))); 11960 ins_cost(INSN_COST); 11961 format %{ "add $dst, $src1, $src2, uxtw" %} 11962 11963 ins_encode %{ 11964 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11965 as_Register($src2$$reg), ext::uxtw); 11966 %} 11967 ins_pipe(ialu_reg_reg); 11968 %} 11969 11970 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11971 %{ 11972 match(Set dst (SubI src1 (AndI src2 mask))); 11973 ins_cost(INSN_COST); 11974 format %{ "subw $dst, $src1, $src2, uxtb" %} 11975 11976 ins_encode %{ 11977 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11978 as_Register($src2$$reg), ext::uxtb); 11979 %} 11980 ins_pipe(ialu_reg_reg); 11981 %} 11982 11983 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11984 %{ 11985 match(Set dst (SubI src1 (AndI src2 mask))); 11986 ins_cost(INSN_COST); 11987 format %{ "subw $dst, $src1, $src2, uxth" %} 11988 11989 ins_encode %{ 11990 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11991 as_Register($src2$$reg), ext::uxth); 11992 %} 11993 ins_pipe(ialu_reg_reg); 11994 %} 11995 11996 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11997 %{ 11998 match(Set dst (SubL src1 (AndL src2 mask))); 11999 ins_cost(INSN_COST); 12000 format %{ "sub $dst, $src1, $src2, uxtb" %} 12001 12002 ins_encode %{ 12003 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12004 as_Register($src2$$reg), ext::uxtb); 12005 %} 12006 ins_pipe(ialu_reg_reg); 12007 %} 12008 12009 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12010 %{ 12011 match(Set dst (SubL src1 (AndL src2 mask))); 12012 ins_cost(INSN_COST); 12013 format %{ "sub $dst, $src1, $src2, uxth" %} 12014 12015 ins_encode %{ 12016 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12017 as_Register($src2$$reg), ext::uxth); 12018 %} 12019 ins_pipe(ialu_reg_reg); 12020 %} 12021 12022 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12023 %{ 12024 match(Set dst (SubL src1 (AndL src2 mask))); 12025 ins_cost(INSN_COST); 12026 format %{ "sub $dst, $src1, $src2, uxtw" %} 12027 12028 ins_encode %{ 12029 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12030 as_Register($src2$$reg), ext::uxtw); 12031 %} 12032 ins_pipe(ialu_reg_reg); 12033 %} 12034 12035 12036 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12037 %{ 12038 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12039 ins_cost(1.9 * INSN_COST); 12040 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12041 12042 ins_encode %{ 12043 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12044 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12045 %} 12046 ins_pipe(ialu_reg_reg_shift); 12047 %} 12048 12049 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12050 %{ 12051 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12052 ins_cost(1.9 * INSN_COST); 12053 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12054 12055 ins_encode %{ 12056 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12057 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12058 %} 12059 ins_pipe(ialu_reg_reg_shift); 12060 %} 12061 12062 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12063 %{ 12064 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12065 ins_cost(1.9 * INSN_COST); 12066 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12067 12068 ins_encode %{ 12069 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12070 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12071 %} 12072 ins_pipe(ialu_reg_reg_shift); 12073 %} 12074 12075 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12076 %{ 12077 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12078 ins_cost(1.9 * INSN_COST); 12079 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12080 12081 ins_encode %{ 12082 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12083 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12084 %} 12085 ins_pipe(ialu_reg_reg_shift); 12086 %} 12087 12088 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12089 %{ 12090 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12091 ins_cost(1.9 * INSN_COST); 12092 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12093 12094 ins_encode %{ 12095 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12096 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12097 %} 12098 ins_pipe(ialu_reg_reg_shift); 12099 %} 12100 12101 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12102 %{ 12103 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12104 ins_cost(1.9 * INSN_COST); 12105 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12106 12107 ins_encode %{ 12108 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12109 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12110 %} 12111 ins_pipe(ialu_reg_reg_shift); 12112 %} 12113 12114 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12115 %{ 12116 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12117 ins_cost(1.9 * INSN_COST); 12118 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12119 12120 ins_encode %{ 12121 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12122 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12123 %} 12124 ins_pipe(ialu_reg_reg_shift); 12125 %} 12126 12127 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12128 %{ 12129 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12130 ins_cost(1.9 * INSN_COST); 12131 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12132 12133 ins_encode %{ 12134 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12135 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12136 %} 12137 ins_pipe(ialu_reg_reg_shift); 12138 %} 12139 12140 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12141 %{ 12142 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12143 ins_cost(1.9 * INSN_COST); 12144 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12145 12146 ins_encode %{ 12147 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12148 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12149 %} 12150 ins_pipe(ialu_reg_reg_shift); 12151 %} 12152 12153 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12154 %{ 12155 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12156 ins_cost(1.9 * INSN_COST); 12157 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12158 12159 ins_encode %{ 12160 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12161 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12162 %} 12163 ins_pipe(ialu_reg_reg_shift); 12164 %} 12165 12166 12167 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12168 %{ 12169 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12170 ins_cost(1.9 * INSN_COST); 12171 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12172 12173 ins_encode %{ 12174 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12175 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12176 %} 12177 ins_pipe(ialu_reg_reg_shift); 12178 %}; 12179 12180 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12181 %{ 12182 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12183 ins_cost(1.9 * INSN_COST); 12184 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12185 12186 ins_encode %{ 12187 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12188 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12189 %} 12190 ins_pipe(ialu_reg_reg_shift); 12191 %}; 12192 12193 12194 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12195 %{ 12196 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12197 ins_cost(1.9 * INSN_COST); 12198 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12199 12200 ins_encode %{ 12201 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12202 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12203 %} 12204 ins_pipe(ialu_reg_reg_shift); 12205 %} 12206 12207 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12208 %{ 12209 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12210 ins_cost(1.9 * INSN_COST); 12211 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12212 12213 ins_encode %{ 12214 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12215 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12216 %} 12217 ins_pipe(ialu_reg_reg_shift); 12218 %} 12219 12220 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12221 %{ 12222 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12223 ins_cost(1.9 * INSN_COST); 12224 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12225 12226 ins_encode %{ 12227 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12228 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12229 %} 12230 ins_pipe(ialu_reg_reg_shift); 12231 %} 12232 12233 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12234 %{ 12235 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12236 ins_cost(1.9 * INSN_COST); 12237 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12238 12239 ins_encode %{ 12240 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12241 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12242 %} 12243 ins_pipe(ialu_reg_reg_shift); 12244 %} 12245 12246 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12247 %{ 12248 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12249 ins_cost(1.9 * INSN_COST); 12250 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12251 12252 ins_encode %{ 12253 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12254 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12255 %} 12256 ins_pipe(ialu_reg_reg_shift); 12257 %} 12258 12259 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12260 %{ 12261 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12262 ins_cost(1.9 * INSN_COST); 12263 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12264 12265 ins_encode %{ 12266 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12267 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12268 %} 12269 ins_pipe(ialu_reg_reg_shift); 12270 %} 12271 12272 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12273 %{ 12274 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12275 ins_cost(1.9 * INSN_COST); 12276 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12277 12278 ins_encode %{ 12279 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12280 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12281 %} 12282 ins_pipe(ialu_reg_reg_shift); 12283 %} 12284 12285 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12286 %{ 12287 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12288 ins_cost(1.9 * INSN_COST); 12289 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12290 12291 ins_encode %{ 12292 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12293 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12294 %} 12295 ins_pipe(ialu_reg_reg_shift); 12296 %} 12297 12298 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12299 %{ 12300 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12301 ins_cost(1.9 * INSN_COST); 12302 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12303 12304 ins_encode %{ 12305 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12306 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12307 %} 12308 ins_pipe(ialu_reg_reg_shift); 12309 %} 12310 12311 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12312 %{ 12313 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12314 ins_cost(1.9 * INSN_COST); 12315 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12316 12317 ins_encode %{ 12318 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12319 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12320 %} 12321 ins_pipe(ialu_reg_reg_shift); 12322 %} 12323 // END This section of the file is automatically generated. Do not edit -------------- 12324 12325 // ============================================================================ 12326 // Floating Point Arithmetic Instructions 12327 12328 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12329 match(Set dst (AddF src1 src2)); 12330 12331 ins_cost(INSN_COST * 5); 12332 format %{ "fadds $dst, $src1, $src2" %} 12333 12334 ins_encode %{ 12335 __ fadds(as_FloatRegister($dst$$reg), 12336 as_FloatRegister($src1$$reg), 12337 as_FloatRegister($src2$$reg)); 12338 %} 12339 12340 ins_pipe(fp_dop_reg_reg_s); 12341 %} 12342 12343 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12344 match(Set dst (AddD src1 src2)); 12345 12346 ins_cost(INSN_COST * 5); 12347 format %{ "faddd $dst, $src1, $src2" %} 12348 12349 ins_encode %{ 12350 __ faddd(as_FloatRegister($dst$$reg), 12351 as_FloatRegister($src1$$reg), 12352 as_FloatRegister($src2$$reg)); 12353 %} 12354 12355 ins_pipe(fp_dop_reg_reg_d); 12356 %} 12357 12358 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12359 match(Set dst (SubF src1 src2)); 12360 12361 ins_cost(INSN_COST * 5); 12362 format %{ "fsubs $dst, $src1, $src2" %} 12363 12364 ins_encode %{ 12365 __ fsubs(as_FloatRegister($dst$$reg), 12366 as_FloatRegister($src1$$reg), 12367 as_FloatRegister($src2$$reg)); 12368 %} 12369 12370 ins_pipe(fp_dop_reg_reg_s); 12371 %} 12372 12373 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12374 match(Set dst (SubD src1 src2)); 12375 12376 ins_cost(INSN_COST * 5); 12377 format %{ "fsubd $dst, $src1, $src2" %} 12378 12379 ins_encode %{ 12380 __ fsubd(as_FloatRegister($dst$$reg), 12381 as_FloatRegister($src1$$reg), 12382 as_FloatRegister($src2$$reg)); 12383 %} 12384 12385 ins_pipe(fp_dop_reg_reg_d); 12386 %} 12387 12388 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12389 match(Set dst (MulF src1 src2)); 12390 12391 ins_cost(INSN_COST * 6); 12392 format %{ "fmuls $dst, $src1, $src2" %} 12393 12394 ins_encode %{ 12395 __ fmuls(as_FloatRegister($dst$$reg), 12396 as_FloatRegister($src1$$reg), 12397 as_FloatRegister($src2$$reg)); 12398 %} 12399 12400 ins_pipe(fp_dop_reg_reg_s); 12401 %} 12402 12403 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12404 match(Set dst (MulD src1 src2)); 12405 12406 ins_cost(INSN_COST * 6); 12407 format %{ "fmuld $dst, $src1, $src2" %} 12408 12409 ins_encode %{ 12410 __ fmuld(as_FloatRegister($dst$$reg), 12411 as_FloatRegister($src1$$reg), 12412 as_FloatRegister($src2$$reg)); 12413 %} 12414 12415 ins_pipe(fp_dop_reg_reg_d); 12416 %} 12417 12418 // src1 * src2 + src3 12419 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12420 predicate(UseFMA); 12421 match(Set dst (FmaF src3 (Binary src1 src2))); 12422 12423 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12424 12425 ins_encode %{ 12426 __ fmadds(as_FloatRegister($dst$$reg), 12427 as_FloatRegister($src1$$reg), 12428 as_FloatRegister($src2$$reg), 12429 as_FloatRegister($src3$$reg)); 12430 %} 12431 12432 ins_pipe(pipe_class_default); 12433 %} 12434 12435 // src1 * src2 + src3 12436 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12437 predicate(UseFMA); 12438 match(Set dst (FmaD src3 (Binary src1 src2))); 12439 12440 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12441 12442 ins_encode %{ 12443 __ fmaddd(as_FloatRegister($dst$$reg), 12444 as_FloatRegister($src1$$reg), 12445 as_FloatRegister($src2$$reg), 12446 as_FloatRegister($src3$$reg)); 12447 %} 12448 12449 ins_pipe(pipe_class_default); 12450 %} 12451 12452 // -src1 * src2 + src3 12453 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12454 predicate(UseFMA); 12455 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12456 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12457 12458 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12459 12460 ins_encode %{ 12461 __ fmsubs(as_FloatRegister($dst$$reg), 12462 as_FloatRegister($src1$$reg), 12463 as_FloatRegister($src2$$reg), 12464 as_FloatRegister($src3$$reg)); 12465 %} 12466 12467 ins_pipe(pipe_class_default); 12468 %} 12469 12470 // -src1 * src2 + src3 12471 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12472 predicate(UseFMA); 12473 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12474 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12475 12476 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12477 12478 ins_encode %{ 12479 __ fmsubd(as_FloatRegister($dst$$reg), 12480 as_FloatRegister($src1$$reg), 12481 as_FloatRegister($src2$$reg), 12482 as_FloatRegister($src3$$reg)); 12483 %} 12484 12485 ins_pipe(pipe_class_default); 12486 %} 12487 12488 // -src1 * src2 - src3 12489 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12490 predicate(UseFMA); 12491 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12492 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12493 12494 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12495 12496 ins_encode %{ 12497 __ fnmadds(as_FloatRegister($dst$$reg), 12498 as_FloatRegister($src1$$reg), 12499 as_FloatRegister($src2$$reg), 12500 as_FloatRegister($src3$$reg)); 12501 %} 12502 12503 ins_pipe(pipe_class_default); 12504 %} 12505 12506 // -src1 * src2 - src3 12507 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12508 predicate(UseFMA); 12509 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12510 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12511 12512 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12513 12514 ins_encode %{ 12515 __ fnmaddd(as_FloatRegister($dst$$reg), 12516 as_FloatRegister($src1$$reg), 12517 as_FloatRegister($src2$$reg), 12518 as_FloatRegister($src3$$reg)); 12519 %} 12520 12521 ins_pipe(pipe_class_default); 12522 %} 12523 12524 // src1 * src2 - src3 12525 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12526 predicate(UseFMA); 12527 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12528 12529 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12530 12531 ins_encode %{ 12532 __ fnmsubs(as_FloatRegister($dst$$reg), 12533 as_FloatRegister($src1$$reg), 12534 as_FloatRegister($src2$$reg), 12535 as_FloatRegister($src3$$reg)); 12536 %} 12537 12538 ins_pipe(pipe_class_default); 12539 %} 12540 12541 // src1 * src2 - src3 12542 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12543 predicate(UseFMA); 12544 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12545 12546 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12547 12548 ins_encode %{ 12549 // n.b. insn name should be fnmsubd 12550 __ fnmsub(as_FloatRegister($dst$$reg), 12551 as_FloatRegister($src1$$reg), 12552 as_FloatRegister($src2$$reg), 12553 as_FloatRegister($src3$$reg)); 12554 %} 12555 12556 ins_pipe(pipe_class_default); 12557 %} 12558 12559 12560 // Math.max(FF)F 12561 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12562 match(Set dst (MaxF src1 src2)); 12563 12564 format %{ "fmaxs $dst, $src1, $src2" %} 12565 ins_encode %{ 12566 __ fmaxs(as_FloatRegister($dst$$reg), 12567 as_FloatRegister($src1$$reg), 12568 as_FloatRegister($src2$$reg)); 12569 %} 12570 12571 ins_pipe(fp_dop_reg_reg_s); 12572 %} 12573 12574 // Math.min(FF)F 12575 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12576 match(Set dst (MinF src1 src2)); 12577 12578 format %{ "fmins $dst, $src1, $src2" %} 12579 ins_encode %{ 12580 __ fmins(as_FloatRegister($dst$$reg), 12581 as_FloatRegister($src1$$reg), 12582 as_FloatRegister($src2$$reg)); 12583 %} 12584 12585 ins_pipe(fp_dop_reg_reg_s); 12586 %} 12587 12588 // Math.max(DD)D 12589 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12590 match(Set dst (MaxD src1 src2)); 12591 12592 format %{ "fmaxd $dst, $src1, $src2" %} 12593 ins_encode %{ 12594 __ fmaxd(as_FloatRegister($dst$$reg), 12595 as_FloatRegister($src1$$reg), 12596 as_FloatRegister($src2$$reg)); 12597 %} 12598 12599 ins_pipe(fp_dop_reg_reg_d); 12600 %} 12601 12602 // Math.min(DD)D 12603 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12604 match(Set dst (MinD src1 src2)); 12605 12606 format %{ "fmind $dst, $src1, $src2" %} 12607 ins_encode %{ 12608 __ fmind(as_FloatRegister($dst$$reg), 12609 as_FloatRegister($src1$$reg), 12610 as_FloatRegister($src2$$reg)); 12611 %} 12612 12613 ins_pipe(fp_dop_reg_reg_d); 12614 %} 12615 12616 12617 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12618 match(Set dst (DivF src1 src2)); 12619 12620 ins_cost(INSN_COST * 18); 12621 format %{ "fdivs $dst, $src1, $src2" %} 12622 12623 ins_encode %{ 12624 __ fdivs(as_FloatRegister($dst$$reg), 12625 as_FloatRegister($src1$$reg), 12626 as_FloatRegister($src2$$reg)); 12627 %} 12628 12629 ins_pipe(fp_div_s); 12630 %} 12631 12632 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12633 match(Set dst (DivD src1 src2)); 12634 12635 ins_cost(INSN_COST * 32); 12636 format %{ "fdivd $dst, $src1, $src2" %} 12637 12638 ins_encode %{ 12639 __ fdivd(as_FloatRegister($dst$$reg), 12640 as_FloatRegister($src1$$reg), 12641 as_FloatRegister($src2$$reg)); 12642 %} 12643 12644 ins_pipe(fp_div_d); 12645 %} 12646 12647 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12648 match(Set dst (NegF src)); 12649 12650 ins_cost(INSN_COST * 3); 12651 format %{ "fneg $dst, $src" %} 12652 12653 ins_encode %{ 12654 __ fnegs(as_FloatRegister($dst$$reg), 12655 as_FloatRegister($src$$reg)); 12656 %} 12657 12658 ins_pipe(fp_uop_s); 12659 %} 12660 12661 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12662 match(Set dst (NegD src)); 12663 12664 ins_cost(INSN_COST * 3); 12665 format %{ "fnegd $dst, $src" %} 12666 12667 ins_encode %{ 12668 __ fnegd(as_FloatRegister($dst$$reg), 12669 as_FloatRegister($src$$reg)); 12670 %} 12671 12672 ins_pipe(fp_uop_d); 12673 %} 12674 12675 instruct absF_reg(vRegF dst, vRegF src) %{ 12676 match(Set dst (AbsF src)); 12677 12678 ins_cost(INSN_COST * 3); 12679 format %{ "fabss $dst, $src" %} 12680 ins_encode %{ 12681 __ fabss(as_FloatRegister($dst$$reg), 12682 as_FloatRegister($src$$reg)); 12683 %} 12684 12685 ins_pipe(fp_uop_s); 12686 %} 12687 12688 instruct absD_reg(vRegD dst, vRegD src) %{ 12689 match(Set dst (AbsD src)); 12690 12691 ins_cost(INSN_COST * 3); 12692 format %{ "fabsd $dst, $src" %} 12693 ins_encode %{ 12694 __ fabsd(as_FloatRegister($dst$$reg), 12695 as_FloatRegister($src$$reg)); 12696 %} 12697 12698 ins_pipe(fp_uop_d); 12699 %} 12700 12701 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12702 match(Set dst (SqrtD src)); 12703 12704 ins_cost(INSN_COST * 50); 12705 format %{ "fsqrtd $dst, $src" %} 12706 ins_encode %{ 12707 __ fsqrtd(as_FloatRegister($dst$$reg), 12708 as_FloatRegister($src$$reg)); 12709 %} 12710 12711 ins_pipe(fp_div_s); 12712 %} 12713 12714 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12715 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 12716 12717 ins_cost(INSN_COST * 50); 12718 format %{ "fsqrts $dst, $src" %} 12719 ins_encode %{ 12720 __ fsqrts(as_FloatRegister($dst$$reg), 12721 as_FloatRegister($src$$reg)); 12722 %} 12723 12724 ins_pipe(fp_div_d); 12725 %} 12726 12727 // ============================================================================ 12728 // Logical Instructions 12729 12730 // Integer Logical Instructions 12731 12732 // And Instructions 12733 12734 12735 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 12736 match(Set dst (AndI src1 src2)); 12737 12738 format %{ "andw $dst, $src1, $src2\t# int" %} 12739 12740 ins_cost(INSN_COST); 12741 ins_encode %{ 12742 __ andw(as_Register($dst$$reg), 12743 as_Register($src1$$reg), 12744 as_Register($src2$$reg)); 12745 %} 12746 12747 ins_pipe(ialu_reg_reg); 12748 %} 12749 12750 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 12751 match(Set dst (AndI src1 src2)); 12752 12753 format %{ "andsw $dst, $src1, $src2\t# int" %} 12754 12755 ins_cost(INSN_COST); 12756 ins_encode %{ 12757 __ andw(as_Register($dst$$reg), 12758 as_Register($src1$$reg), 12759 (unsigned long)($src2$$constant)); 12760 %} 12761 12762 ins_pipe(ialu_reg_imm); 12763 %} 12764 12765 // Or Instructions 12766 12767 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12768 match(Set dst (OrI src1 src2)); 12769 12770 format %{ "orrw $dst, $src1, $src2\t# int" %} 12771 12772 ins_cost(INSN_COST); 12773 ins_encode %{ 12774 __ orrw(as_Register($dst$$reg), 12775 as_Register($src1$$reg), 12776 as_Register($src2$$reg)); 12777 %} 12778 12779 ins_pipe(ialu_reg_reg); 12780 %} 12781 12782 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12783 match(Set dst (OrI src1 src2)); 12784 12785 format %{ "orrw $dst, $src1, $src2\t# int" %} 12786 12787 ins_cost(INSN_COST); 12788 ins_encode %{ 12789 __ orrw(as_Register($dst$$reg), 12790 as_Register($src1$$reg), 12791 (unsigned long)($src2$$constant)); 12792 %} 12793 12794 ins_pipe(ialu_reg_imm); 12795 %} 12796 12797 // Xor Instructions 12798 12799 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12800 match(Set dst (XorI src1 src2)); 12801 12802 format %{ "eorw $dst, $src1, $src2\t# int" %} 12803 12804 ins_cost(INSN_COST); 12805 ins_encode %{ 12806 __ eorw(as_Register($dst$$reg), 12807 as_Register($src1$$reg), 12808 as_Register($src2$$reg)); 12809 %} 12810 12811 ins_pipe(ialu_reg_reg); 12812 %} 12813 12814 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12815 match(Set dst (XorI src1 src2)); 12816 12817 format %{ "eorw $dst, $src1, $src2\t# int" %} 12818 12819 ins_cost(INSN_COST); 12820 ins_encode %{ 12821 __ eorw(as_Register($dst$$reg), 12822 as_Register($src1$$reg), 12823 (unsigned long)($src2$$constant)); 12824 %} 12825 12826 ins_pipe(ialu_reg_imm); 12827 %} 12828 12829 // Long Logical Instructions 12830 // TODO 12831 12832 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 12833 match(Set dst (AndL src1 src2)); 12834 12835 format %{ "and $dst, $src1, $src2\t# int" %} 12836 12837 ins_cost(INSN_COST); 12838 ins_encode %{ 12839 __ andr(as_Register($dst$$reg), 12840 as_Register($src1$$reg), 12841 as_Register($src2$$reg)); 12842 %} 12843 12844 ins_pipe(ialu_reg_reg); 12845 %} 12846 12847 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 12848 match(Set dst (AndL src1 src2)); 12849 12850 format %{ "and $dst, $src1, $src2\t# int" %} 12851 12852 ins_cost(INSN_COST); 12853 ins_encode %{ 12854 __ andr(as_Register($dst$$reg), 12855 as_Register($src1$$reg), 12856 (unsigned long)($src2$$constant)); 12857 %} 12858 12859 ins_pipe(ialu_reg_imm); 12860 %} 12861 12862 // Or Instructions 12863 12864 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12865 match(Set dst (OrL src1 src2)); 12866 12867 format %{ "orr $dst, $src1, $src2\t# int" %} 12868 12869 ins_cost(INSN_COST); 12870 ins_encode %{ 12871 __ orr(as_Register($dst$$reg), 12872 as_Register($src1$$reg), 12873 as_Register($src2$$reg)); 12874 %} 12875 12876 ins_pipe(ialu_reg_reg); 12877 %} 12878 12879 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12880 match(Set dst (OrL src1 src2)); 12881 12882 format %{ "orr $dst, $src1, $src2\t# int" %} 12883 12884 ins_cost(INSN_COST); 12885 ins_encode %{ 12886 __ orr(as_Register($dst$$reg), 12887 as_Register($src1$$reg), 12888 (unsigned long)($src2$$constant)); 12889 %} 12890 12891 ins_pipe(ialu_reg_imm); 12892 %} 12893 12894 // Xor Instructions 12895 12896 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12897 match(Set dst (XorL src1 src2)); 12898 12899 format %{ "eor $dst, $src1, $src2\t# int" %} 12900 12901 ins_cost(INSN_COST); 12902 ins_encode %{ 12903 __ eor(as_Register($dst$$reg), 12904 as_Register($src1$$reg), 12905 as_Register($src2$$reg)); 12906 %} 12907 12908 ins_pipe(ialu_reg_reg); 12909 %} 12910 12911 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12912 match(Set dst (XorL src1 src2)); 12913 12914 ins_cost(INSN_COST); 12915 format %{ "eor $dst, $src1, $src2\t# int" %} 12916 12917 ins_encode %{ 12918 __ eor(as_Register($dst$$reg), 12919 as_Register($src1$$reg), 12920 (unsigned long)($src2$$constant)); 12921 %} 12922 12923 ins_pipe(ialu_reg_imm); 12924 %} 12925 12926 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 12927 %{ 12928 match(Set dst (ConvI2L src)); 12929 12930 ins_cost(INSN_COST); 12931 format %{ "sxtw $dst, $src\t# i2l" %} 12932 ins_encode %{ 12933 __ sbfm($dst$$Register, $src$$Register, 0, 31); 12934 %} 12935 ins_pipe(ialu_reg_shift); 12936 %} 12937 12938 // this pattern occurs in bigmath arithmetic 12939 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 12940 %{ 12941 match(Set dst (AndL (ConvI2L src) mask)); 12942 12943 ins_cost(INSN_COST); 12944 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 12945 ins_encode %{ 12946 __ ubfm($dst$$Register, $src$$Register, 0, 31); 12947 %} 12948 12949 ins_pipe(ialu_reg_shift); 12950 %} 12951 12952 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 12953 match(Set dst (ConvL2I src)); 12954 12955 ins_cost(INSN_COST); 12956 format %{ "movw $dst, $src \t// l2i" %} 12957 12958 ins_encode %{ 12959 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 12960 %} 12961 12962 ins_pipe(ialu_reg); 12963 %} 12964 12965 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12966 %{ 12967 match(Set dst (Conv2B src)); 12968 effect(KILL cr); 12969 12970 format %{ 12971 "cmpw $src, zr\n\t" 12972 "cset $dst, ne" 12973 %} 12974 12975 ins_encode %{ 12976 __ cmpw(as_Register($src$$reg), zr); 12977 __ cset(as_Register($dst$$reg), Assembler::NE); 12978 %} 12979 12980 ins_pipe(ialu_reg); 12981 %} 12982 12983 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 12984 %{ 12985 match(Set dst (Conv2B src)); 12986 effect(KILL cr); 12987 12988 format %{ 12989 "cmp $src, zr\n\t" 12990 "cset $dst, ne" 12991 %} 12992 12993 ins_encode %{ 12994 __ cmp(as_Register($src$$reg), zr); 12995 __ cset(as_Register($dst$$reg), Assembler::NE); 12996 %} 12997 12998 ins_pipe(ialu_reg); 12999 %} 13000 13001 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13002 match(Set dst (ConvD2F src)); 13003 13004 ins_cost(INSN_COST * 5); 13005 format %{ "fcvtd $dst, $src \t// d2f" %} 13006 13007 ins_encode %{ 13008 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13009 %} 13010 13011 ins_pipe(fp_d2f); 13012 %} 13013 13014 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13015 match(Set dst (ConvF2D src)); 13016 13017 ins_cost(INSN_COST * 5); 13018 format %{ "fcvts $dst, $src \t// f2d" %} 13019 13020 ins_encode %{ 13021 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13022 %} 13023 13024 ins_pipe(fp_f2d); 13025 %} 13026 13027 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13028 match(Set dst (ConvF2I src)); 13029 13030 ins_cost(INSN_COST * 5); 13031 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13032 13033 ins_encode %{ 13034 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13035 %} 13036 13037 ins_pipe(fp_f2i); 13038 %} 13039 13040 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13041 match(Set dst (ConvF2L src)); 13042 13043 ins_cost(INSN_COST * 5); 13044 format %{ "fcvtzs $dst, $src \t// f2l" %} 13045 13046 ins_encode %{ 13047 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13048 %} 13049 13050 ins_pipe(fp_f2l); 13051 %} 13052 13053 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13054 match(Set dst (ConvI2F src)); 13055 13056 ins_cost(INSN_COST * 5); 13057 format %{ "scvtfws $dst, $src \t// i2f" %} 13058 13059 ins_encode %{ 13060 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13061 %} 13062 13063 ins_pipe(fp_i2f); 13064 %} 13065 13066 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13067 match(Set dst (ConvL2F src)); 13068 13069 ins_cost(INSN_COST * 5); 13070 format %{ "scvtfs $dst, $src \t// l2f" %} 13071 13072 ins_encode %{ 13073 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13074 %} 13075 13076 ins_pipe(fp_l2f); 13077 %} 13078 13079 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13080 match(Set dst (ConvD2I src)); 13081 13082 ins_cost(INSN_COST * 5); 13083 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13084 13085 ins_encode %{ 13086 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13087 %} 13088 13089 ins_pipe(fp_d2i); 13090 %} 13091 13092 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13093 match(Set dst (ConvD2L src)); 13094 13095 ins_cost(INSN_COST * 5); 13096 format %{ "fcvtzd $dst, $src \t// d2l" %} 13097 13098 ins_encode %{ 13099 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13100 %} 13101 13102 ins_pipe(fp_d2l); 13103 %} 13104 13105 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13106 match(Set dst (ConvI2D src)); 13107 13108 ins_cost(INSN_COST * 5); 13109 format %{ "scvtfwd $dst, $src \t// i2d" %} 13110 13111 ins_encode %{ 13112 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13113 %} 13114 13115 ins_pipe(fp_i2d); 13116 %} 13117 13118 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13119 match(Set dst (ConvL2D src)); 13120 13121 ins_cost(INSN_COST * 5); 13122 format %{ "scvtfd $dst, $src \t// l2d" %} 13123 13124 ins_encode %{ 13125 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13126 %} 13127 13128 ins_pipe(fp_l2d); 13129 %} 13130 13131 // stack <-> reg and reg <-> reg shuffles with no conversion 13132 13133 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13134 13135 match(Set dst (MoveF2I src)); 13136 13137 effect(DEF dst, USE src); 13138 13139 ins_cost(4 * INSN_COST); 13140 13141 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13142 13143 ins_encode %{ 13144 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13145 %} 13146 13147 ins_pipe(iload_reg_reg); 13148 13149 %} 13150 13151 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13152 13153 match(Set dst (MoveI2F src)); 13154 13155 effect(DEF dst, USE src); 13156 13157 ins_cost(4 * INSN_COST); 13158 13159 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13160 13161 ins_encode %{ 13162 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13163 %} 13164 13165 ins_pipe(pipe_class_memory); 13166 13167 %} 13168 13169 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13170 13171 match(Set dst (MoveD2L src)); 13172 13173 effect(DEF dst, USE src); 13174 13175 ins_cost(4 * INSN_COST); 13176 13177 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13178 13179 ins_encode %{ 13180 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13181 %} 13182 13183 ins_pipe(iload_reg_reg); 13184 13185 %} 13186 13187 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13188 13189 match(Set dst (MoveL2D src)); 13190 13191 effect(DEF dst, USE src); 13192 13193 ins_cost(4 * INSN_COST); 13194 13195 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13196 13197 ins_encode %{ 13198 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13199 %} 13200 13201 ins_pipe(pipe_class_memory); 13202 13203 %} 13204 13205 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13206 13207 match(Set dst (MoveF2I src)); 13208 13209 effect(DEF dst, USE src); 13210 13211 ins_cost(INSN_COST); 13212 13213 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13214 13215 ins_encode %{ 13216 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13217 %} 13218 13219 ins_pipe(pipe_class_memory); 13220 13221 %} 13222 13223 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13224 13225 match(Set dst (MoveI2F src)); 13226 13227 effect(DEF dst, USE src); 13228 13229 ins_cost(INSN_COST); 13230 13231 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13232 13233 ins_encode %{ 13234 __ strw($src$$Register, Address(sp, $dst$$disp)); 13235 %} 13236 13237 ins_pipe(istore_reg_reg); 13238 13239 %} 13240 13241 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13242 13243 match(Set dst (MoveD2L src)); 13244 13245 effect(DEF dst, USE src); 13246 13247 ins_cost(INSN_COST); 13248 13249 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13250 13251 ins_encode %{ 13252 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13253 %} 13254 13255 ins_pipe(pipe_class_memory); 13256 13257 %} 13258 13259 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13260 13261 match(Set dst (MoveL2D src)); 13262 13263 effect(DEF dst, USE src); 13264 13265 ins_cost(INSN_COST); 13266 13267 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13268 13269 ins_encode %{ 13270 __ str($src$$Register, Address(sp, $dst$$disp)); 13271 %} 13272 13273 ins_pipe(istore_reg_reg); 13274 13275 %} 13276 13277 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13278 13279 match(Set dst (MoveF2I src)); 13280 13281 effect(DEF dst, USE src); 13282 13283 ins_cost(INSN_COST); 13284 13285 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13286 13287 ins_encode %{ 13288 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13289 %} 13290 13291 ins_pipe(fp_f2i); 13292 13293 %} 13294 13295 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13296 13297 match(Set dst (MoveI2F src)); 13298 13299 effect(DEF dst, USE src); 13300 13301 ins_cost(INSN_COST); 13302 13303 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13304 13305 ins_encode %{ 13306 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13307 %} 13308 13309 ins_pipe(fp_i2f); 13310 13311 %} 13312 13313 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13314 13315 match(Set dst (MoveD2L src)); 13316 13317 effect(DEF dst, USE src); 13318 13319 ins_cost(INSN_COST); 13320 13321 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13322 13323 ins_encode %{ 13324 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13325 %} 13326 13327 ins_pipe(fp_d2l); 13328 13329 %} 13330 13331 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13332 13333 match(Set dst (MoveL2D src)); 13334 13335 effect(DEF dst, USE src); 13336 13337 ins_cost(INSN_COST); 13338 13339 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13340 13341 ins_encode %{ 13342 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13343 %} 13344 13345 ins_pipe(fp_l2d); 13346 13347 %} 13348 13349 // ============================================================================ 13350 // clearing of an array 13351 13352 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13353 %{ 13354 match(Set dummy (ClearArray cnt base)); 13355 effect(USE_KILL cnt, USE_KILL base); 13356 13357 ins_cost(4 * INSN_COST); 13358 format %{ "ClearArray $cnt, $base" %} 13359 13360 ins_encode %{ 13361 __ zero_words($base$$Register, $cnt$$Register); 13362 %} 13363 13364 ins_pipe(pipe_class_memory); 13365 %} 13366 13367 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13368 %{ 13369 predicate((u_int64_t)n->in(2)->get_long() 13370 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13371 match(Set dummy (ClearArray cnt base)); 13372 effect(USE_KILL base); 13373 13374 ins_cost(4 * INSN_COST); 13375 format %{ "ClearArray $cnt, $base" %} 13376 13377 ins_encode %{ 13378 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13379 %} 13380 13381 ins_pipe(pipe_class_memory); 13382 %} 13383 13384 // ============================================================================ 13385 // Overflow Math Instructions 13386 13387 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13388 %{ 13389 match(Set cr (OverflowAddI op1 op2)); 13390 13391 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13392 ins_cost(INSN_COST); 13393 ins_encode %{ 13394 __ cmnw($op1$$Register, $op2$$Register); 13395 %} 13396 13397 ins_pipe(icmp_reg_reg); 13398 %} 13399 13400 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13401 %{ 13402 match(Set cr (OverflowAddI op1 op2)); 13403 13404 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13405 ins_cost(INSN_COST); 13406 ins_encode %{ 13407 __ cmnw($op1$$Register, $op2$$constant); 13408 %} 13409 13410 ins_pipe(icmp_reg_imm); 13411 %} 13412 13413 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13414 %{ 13415 match(Set cr (OverflowAddL op1 op2)); 13416 13417 format %{ "cmn $op1, $op2\t# overflow check long" %} 13418 ins_cost(INSN_COST); 13419 ins_encode %{ 13420 __ cmn($op1$$Register, $op2$$Register); 13421 %} 13422 13423 ins_pipe(icmp_reg_reg); 13424 %} 13425 13426 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13427 %{ 13428 match(Set cr (OverflowAddL op1 op2)); 13429 13430 format %{ "cmn $op1, $op2\t# overflow check long" %} 13431 ins_cost(INSN_COST); 13432 ins_encode %{ 13433 __ cmn($op1$$Register, $op2$$constant); 13434 %} 13435 13436 ins_pipe(icmp_reg_imm); 13437 %} 13438 13439 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13440 %{ 13441 match(Set cr (OverflowSubI op1 op2)); 13442 13443 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13444 ins_cost(INSN_COST); 13445 ins_encode %{ 13446 __ cmpw($op1$$Register, $op2$$Register); 13447 %} 13448 13449 ins_pipe(icmp_reg_reg); 13450 %} 13451 13452 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13453 %{ 13454 match(Set cr (OverflowSubI op1 op2)); 13455 13456 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13457 ins_cost(INSN_COST); 13458 ins_encode %{ 13459 __ cmpw($op1$$Register, $op2$$constant); 13460 %} 13461 13462 ins_pipe(icmp_reg_imm); 13463 %} 13464 13465 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13466 %{ 13467 match(Set cr (OverflowSubL op1 op2)); 13468 13469 format %{ "cmp $op1, $op2\t# overflow check long" %} 13470 ins_cost(INSN_COST); 13471 ins_encode %{ 13472 __ cmp($op1$$Register, $op2$$Register); 13473 %} 13474 13475 ins_pipe(icmp_reg_reg); 13476 %} 13477 13478 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13479 %{ 13480 match(Set cr (OverflowSubL op1 op2)); 13481 13482 format %{ "cmp $op1, $op2\t# overflow check long" %} 13483 ins_cost(INSN_COST); 13484 ins_encode %{ 13485 __ subs(zr, $op1$$Register, $op2$$constant); 13486 %} 13487 13488 ins_pipe(icmp_reg_imm); 13489 %} 13490 13491 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13492 %{ 13493 match(Set cr (OverflowSubI zero op1)); 13494 13495 format %{ "cmpw zr, $op1\t# overflow check int" %} 13496 ins_cost(INSN_COST); 13497 ins_encode %{ 13498 __ cmpw(zr, $op1$$Register); 13499 %} 13500 13501 ins_pipe(icmp_reg_imm); 13502 %} 13503 13504 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13505 %{ 13506 match(Set cr (OverflowSubL zero op1)); 13507 13508 format %{ "cmp zr, $op1\t# overflow check long" %} 13509 ins_cost(INSN_COST); 13510 ins_encode %{ 13511 __ cmp(zr, $op1$$Register); 13512 %} 13513 13514 ins_pipe(icmp_reg_imm); 13515 %} 13516 13517 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13518 %{ 13519 match(Set cr (OverflowMulI op1 op2)); 13520 13521 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13522 "cmp rscratch1, rscratch1, sxtw\n\t" 13523 "movw rscratch1, #0x80000000\n\t" 13524 "cselw rscratch1, rscratch1, zr, NE\n\t" 13525 "cmpw rscratch1, #1" %} 13526 ins_cost(5 * INSN_COST); 13527 ins_encode %{ 13528 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13529 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13530 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13531 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13532 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13533 %} 13534 13535 ins_pipe(pipe_slow); 13536 %} 13537 13538 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13539 %{ 13540 match(If cmp (OverflowMulI op1 op2)); 13541 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13542 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13543 effect(USE labl, KILL cr); 13544 13545 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13546 "cmp rscratch1, rscratch1, sxtw\n\t" 13547 "b$cmp $labl" %} 13548 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13549 ins_encode %{ 13550 Label* L = $labl$$label; 13551 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13552 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13553 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13554 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13555 %} 13556 13557 ins_pipe(pipe_serial); 13558 %} 13559 13560 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13561 %{ 13562 match(Set cr (OverflowMulL op1 op2)); 13563 13564 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13565 "smulh rscratch2, $op1, $op2\n\t" 13566 "cmp rscratch2, rscratch1, ASR #63\n\t" 13567 "movw rscratch1, #0x80000000\n\t" 13568 "cselw rscratch1, rscratch1, zr, NE\n\t" 13569 "cmpw rscratch1, #1" %} 13570 ins_cost(6 * INSN_COST); 13571 ins_encode %{ 13572 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13573 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13574 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13575 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13576 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13577 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13578 %} 13579 13580 ins_pipe(pipe_slow); 13581 %} 13582 13583 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13584 %{ 13585 match(If cmp (OverflowMulL op1 op2)); 13586 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13587 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13588 effect(USE labl, KILL cr); 13589 13590 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13591 "smulh rscratch2, $op1, $op2\n\t" 13592 "cmp rscratch2, rscratch1, ASR #63\n\t" 13593 "b$cmp $labl" %} 13594 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13595 ins_encode %{ 13596 Label* L = $labl$$label; 13597 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13598 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13599 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13600 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13601 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13602 %} 13603 13604 ins_pipe(pipe_serial); 13605 %} 13606 13607 // ============================================================================ 13608 // Compare Instructions 13609 13610 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13611 %{ 13612 match(Set cr (CmpI op1 op2)); 13613 13614 effect(DEF cr, USE op1, USE op2); 13615 13616 ins_cost(INSN_COST); 13617 format %{ "cmpw $op1, $op2" %} 13618 13619 ins_encode(aarch64_enc_cmpw(op1, op2)); 13620 13621 ins_pipe(icmp_reg_reg); 13622 %} 13623 13624 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13625 %{ 13626 match(Set cr (CmpI op1 zero)); 13627 13628 effect(DEF cr, USE op1); 13629 13630 ins_cost(INSN_COST); 13631 format %{ "cmpw $op1, 0" %} 13632 13633 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13634 13635 ins_pipe(icmp_reg_imm); 13636 %} 13637 13638 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13639 %{ 13640 match(Set cr (CmpI op1 op2)); 13641 13642 effect(DEF cr, USE op1); 13643 13644 ins_cost(INSN_COST); 13645 format %{ "cmpw $op1, $op2" %} 13646 13647 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13648 13649 ins_pipe(icmp_reg_imm); 13650 %} 13651 13652 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 13653 %{ 13654 match(Set cr (CmpI op1 op2)); 13655 13656 effect(DEF cr, USE op1); 13657 13658 ins_cost(INSN_COST * 2); 13659 format %{ "cmpw $op1, $op2" %} 13660 13661 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13662 13663 ins_pipe(icmp_reg_imm); 13664 %} 13665 13666 // Unsigned compare Instructions; really, same as signed compare 13667 // except it should only be used to feed an If or a CMovI which takes a 13668 // cmpOpU. 13669 13670 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 13671 %{ 13672 match(Set cr (CmpU op1 op2)); 13673 13674 effect(DEF cr, USE op1, USE op2); 13675 13676 ins_cost(INSN_COST); 13677 format %{ "cmpw $op1, $op2\t# unsigned" %} 13678 13679 ins_encode(aarch64_enc_cmpw(op1, op2)); 13680 13681 ins_pipe(icmp_reg_reg); 13682 %} 13683 13684 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 13685 %{ 13686 match(Set cr (CmpU op1 zero)); 13687 13688 effect(DEF cr, USE op1); 13689 13690 ins_cost(INSN_COST); 13691 format %{ "cmpw $op1, #0\t# unsigned" %} 13692 13693 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13694 13695 ins_pipe(icmp_reg_imm); 13696 %} 13697 13698 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 13699 %{ 13700 match(Set cr (CmpU op1 op2)); 13701 13702 effect(DEF cr, USE op1); 13703 13704 ins_cost(INSN_COST); 13705 format %{ "cmpw $op1, $op2\t# unsigned" %} 13706 13707 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13708 13709 ins_pipe(icmp_reg_imm); 13710 %} 13711 13712 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 13713 %{ 13714 match(Set cr (CmpU op1 op2)); 13715 13716 effect(DEF cr, USE op1); 13717 13718 ins_cost(INSN_COST * 2); 13719 format %{ "cmpw $op1, $op2\t# unsigned" %} 13720 13721 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13722 13723 ins_pipe(icmp_reg_imm); 13724 %} 13725 13726 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13727 %{ 13728 match(Set cr (CmpL op1 op2)); 13729 13730 effect(DEF cr, USE op1, USE op2); 13731 13732 ins_cost(INSN_COST); 13733 format %{ "cmp $op1, $op2" %} 13734 13735 ins_encode(aarch64_enc_cmp(op1, op2)); 13736 13737 ins_pipe(icmp_reg_reg); 13738 %} 13739 13740 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 13741 %{ 13742 match(Set cr (CmpL op1 zero)); 13743 13744 effect(DEF cr, USE op1); 13745 13746 ins_cost(INSN_COST); 13747 format %{ "tst $op1" %} 13748 13749 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13750 13751 ins_pipe(icmp_reg_imm); 13752 %} 13753 13754 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 13755 %{ 13756 match(Set cr (CmpL op1 op2)); 13757 13758 effect(DEF cr, USE op1); 13759 13760 ins_cost(INSN_COST); 13761 format %{ "cmp $op1, $op2" %} 13762 13763 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13764 13765 ins_pipe(icmp_reg_imm); 13766 %} 13767 13768 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 13769 %{ 13770 match(Set cr (CmpL op1 op2)); 13771 13772 effect(DEF cr, USE op1); 13773 13774 ins_cost(INSN_COST * 2); 13775 format %{ "cmp $op1, $op2" %} 13776 13777 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13778 13779 ins_pipe(icmp_reg_imm); 13780 %} 13781 13782 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 13783 %{ 13784 match(Set cr (CmpUL op1 op2)); 13785 13786 effect(DEF cr, USE op1, USE op2); 13787 13788 ins_cost(INSN_COST); 13789 format %{ "cmp $op1, $op2" %} 13790 13791 ins_encode(aarch64_enc_cmp(op1, op2)); 13792 13793 ins_pipe(icmp_reg_reg); 13794 %} 13795 13796 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 13797 %{ 13798 match(Set cr (CmpUL op1 zero)); 13799 13800 effect(DEF cr, USE op1); 13801 13802 ins_cost(INSN_COST); 13803 format %{ "tst $op1" %} 13804 13805 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13806 13807 ins_pipe(icmp_reg_imm); 13808 %} 13809 13810 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 13811 %{ 13812 match(Set cr (CmpUL op1 op2)); 13813 13814 effect(DEF cr, USE op1); 13815 13816 ins_cost(INSN_COST); 13817 format %{ "cmp $op1, $op2" %} 13818 13819 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13820 13821 ins_pipe(icmp_reg_imm); 13822 %} 13823 13824 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 13825 %{ 13826 match(Set cr (CmpUL op1 op2)); 13827 13828 effect(DEF cr, USE op1); 13829 13830 ins_cost(INSN_COST * 2); 13831 format %{ "cmp $op1, $op2" %} 13832 13833 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13834 13835 ins_pipe(icmp_reg_imm); 13836 %} 13837 13838 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 13839 %{ 13840 match(Set cr (CmpP op1 op2)); 13841 13842 effect(DEF cr, USE op1, USE op2); 13843 13844 ins_cost(INSN_COST); 13845 format %{ "cmp $op1, $op2\t // ptr" %} 13846 13847 ins_encode(aarch64_enc_cmpp(op1, op2)); 13848 13849 ins_pipe(icmp_reg_reg); 13850 %} 13851 13852 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 13853 %{ 13854 match(Set cr (CmpN op1 op2)); 13855 13856 effect(DEF cr, USE op1, USE op2); 13857 13858 ins_cost(INSN_COST); 13859 format %{ "cmp $op1, $op2\t // compressed ptr" %} 13860 13861 ins_encode(aarch64_enc_cmpn(op1, op2)); 13862 13863 ins_pipe(icmp_reg_reg); 13864 %} 13865 13866 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 13867 %{ 13868 match(Set cr (CmpP op1 zero)); 13869 13870 effect(DEF cr, USE op1, USE zero); 13871 13872 ins_cost(INSN_COST); 13873 format %{ "cmp $op1, 0\t // ptr" %} 13874 13875 ins_encode(aarch64_enc_testp(op1)); 13876 13877 ins_pipe(icmp_reg_imm); 13878 %} 13879 13880 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 13881 %{ 13882 match(Set cr (CmpN op1 zero)); 13883 13884 effect(DEF cr, USE op1, USE zero); 13885 13886 ins_cost(INSN_COST); 13887 format %{ "cmp $op1, 0\t // compressed ptr" %} 13888 13889 ins_encode(aarch64_enc_testn(op1)); 13890 13891 ins_pipe(icmp_reg_imm); 13892 %} 13893 13894 // FP comparisons 13895 // 13896 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 13897 // using normal cmpOp. See declaration of rFlagsReg for details. 13898 13899 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 13900 %{ 13901 match(Set cr (CmpF src1 src2)); 13902 13903 ins_cost(3 * INSN_COST); 13904 format %{ "fcmps $src1, $src2" %} 13905 13906 ins_encode %{ 13907 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13908 %} 13909 13910 ins_pipe(pipe_class_compare); 13911 %} 13912 13913 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 13914 %{ 13915 match(Set cr (CmpF src1 src2)); 13916 13917 ins_cost(3 * INSN_COST); 13918 format %{ "fcmps $src1, 0.0" %} 13919 13920 ins_encode %{ 13921 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 13922 %} 13923 13924 ins_pipe(pipe_class_compare); 13925 %} 13926 // FROM HERE 13927 13928 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 13929 %{ 13930 match(Set cr (CmpD src1 src2)); 13931 13932 ins_cost(3 * INSN_COST); 13933 format %{ "fcmpd $src1, $src2" %} 13934 13935 ins_encode %{ 13936 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13937 %} 13938 13939 ins_pipe(pipe_class_compare); 13940 %} 13941 13942 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 13943 %{ 13944 match(Set cr (CmpD src1 src2)); 13945 13946 ins_cost(3 * INSN_COST); 13947 format %{ "fcmpd $src1, 0.0" %} 13948 13949 ins_encode %{ 13950 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 13951 %} 13952 13953 ins_pipe(pipe_class_compare); 13954 %} 13955 13956 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 13957 %{ 13958 match(Set dst (CmpF3 src1 src2)); 13959 effect(KILL cr); 13960 13961 ins_cost(5 * INSN_COST); 13962 format %{ "fcmps $src1, $src2\n\t" 13963 "csinvw($dst, zr, zr, eq\n\t" 13964 "csnegw($dst, $dst, $dst, lt)" 13965 %} 13966 13967 ins_encode %{ 13968 Label done; 13969 FloatRegister s1 = as_FloatRegister($src1$$reg); 13970 FloatRegister s2 = as_FloatRegister($src2$$reg); 13971 Register d = as_Register($dst$$reg); 13972 __ fcmps(s1, s2); 13973 // installs 0 if EQ else -1 13974 __ csinvw(d, zr, zr, Assembler::EQ); 13975 // keeps -1 if less or unordered else installs 1 13976 __ csnegw(d, d, d, Assembler::LT); 13977 __ bind(done); 13978 %} 13979 13980 ins_pipe(pipe_class_default); 13981 13982 %} 13983 13984 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 13985 %{ 13986 match(Set dst (CmpD3 src1 src2)); 13987 effect(KILL cr); 13988 13989 ins_cost(5 * INSN_COST); 13990 format %{ "fcmpd $src1, $src2\n\t" 13991 "csinvw($dst, zr, zr, eq\n\t" 13992 "csnegw($dst, $dst, $dst, lt)" 13993 %} 13994 13995 ins_encode %{ 13996 Label done; 13997 FloatRegister s1 = as_FloatRegister($src1$$reg); 13998 FloatRegister s2 = as_FloatRegister($src2$$reg); 13999 Register d = as_Register($dst$$reg); 14000 __ fcmpd(s1, s2); 14001 // installs 0 if EQ else -1 14002 __ csinvw(d, zr, zr, Assembler::EQ); 14003 // keeps -1 if less or unordered else installs 1 14004 __ csnegw(d, d, d, Assembler::LT); 14005 __ bind(done); 14006 %} 14007 ins_pipe(pipe_class_default); 14008 14009 %} 14010 14011 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14012 %{ 14013 match(Set dst (CmpF3 src1 zero)); 14014 effect(KILL cr); 14015 14016 ins_cost(5 * INSN_COST); 14017 format %{ "fcmps $src1, 0.0\n\t" 14018 "csinvw($dst, zr, zr, eq\n\t" 14019 "csnegw($dst, $dst, $dst, lt)" 14020 %} 14021 14022 ins_encode %{ 14023 Label done; 14024 FloatRegister s1 = as_FloatRegister($src1$$reg); 14025 Register d = as_Register($dst$$reg); 14026 __ fcmps(s1, 0.0D); 14027 // installs 0 if EQ else -1 14028 __ csinvw(d, zr, zr, Assembler::EQ); 14029 // keeps -1 if less or unordered else installs 1 14030 __ csnegw(d, d, d, Assembler::LT); 14031 __ bind(done); 14032 %} 14033 14034 ins_pipe(pipe_class_default); 14035 14036 %} 14037 14038 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14039 %{ 14040 match(Set dst (CmpD3 src1 zero)); 14041 effect(KILL cr); 14042 14043 ins_cost(5 * INSN_COST); 14044 format %{ "fcmpd $src1, 0.0\n\t" 14045 "csinvw($dst, zr, zr, eq\n\t" 14046 "csnegw($dst, $dst, $dst, lt)" 14047 %} 14048 14049 ins_encode %{ 14050 Label done; 14051 FloatRegister s1 = as_FloatRegister($src1$$reg); 14052 Register d = as_Register($dst$$reg); 14053 __ fcmpd(s1, 0.0D); 14054 // installs 0 if EQ else -1 14055 __ csinvw(d, zr, zr, Assembler::EQ); 14056 // keeps -1 if less or unordered else installs 1 14057 __ csnegw(d, d, d, Assembler::LT); 14058 __ bind(done); 14059 %} 14060 ins_pipe(pipe_class_default); 14061 14062 %} 14063 14064 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14065 %{ 14066 match(Set dst (CmpLTMask p q)); 14067 effect(KILL cr); 14068 14069 ins_cost(3 * INSN_COST); 14070 14071 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14072 "csetw $dst, lt\n\t" 14073 "subw $dst, zr, $dst" 14074 %} 14075 14076 ins_encode %{ 14077 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14078 __ csetw(as_Register($dst$$reg), Assembler::LT); 14079 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14080 %} 14081 14082 ins_pipe(ialu_reg_reg); 14083 %} 14084 14085 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14086 %{ 14087 match(Set dst (CmpLTMask src zero)); 14088 effect(KILL cr); 14089 14090 ins_cost(INSN_COST); 14091 14092 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14093 14094 ins_encode %{ 14095 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14096 %} 14097 14098 ins_pipe(ialu_reg_shift); 14099 %} 14100 14101 // ============================================================================ 14102 // Max and Min 14103 14104 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14105 %{ 14106 match(Set dst (MinI src1 src2)); 14107 14108 effect(DEF dst, USE src1, USE src2, KILL cr); 14109 size(8); 14110 14111 ins_cost(INSN_COST * 3); 14112 format %{ 14113 "cmpw $src1 $src2\t signed int\n\t" 14114 "cselw $dst, $src1, $src2 lt\t" 14115 %} 14116 14117 ins_encode %{ 14118 __ cmpw(as_Register($src1$$reg), 14119 as_Register($src2$$reg)); 14120 __ cselw(as_Register($dst$$reg), 14121 as_Register($src1$$reg), 14122 as_Register($src2$$reg), 14123 Assembler::LT); 14124 %} 14125 14126 ins_pipe(ialu_reg_reg); 14127 %} 14128 // FROM HERE 14129 14130 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14131 %{ 14132 match(Set dst (MaxI src1 src2)); 14133 14134 effect(DEF dst, USE src1, USE src2, KILL cr); 14135 size(8); 14136 14137 ins_cost(INSN_COST * 3); 14138 format %{ 14139 "cmpw $src1 $src2\t signed int\n\t" 14140 "cselw $dst, $src1, $src2 gt\t" 14141 %} 14142 14143 ins_encode %{ 14144 __ cmpw(as_Register($src1$$reg), 14145 as_Register($src2$$reg)); 14146 __ cselw(as_Register($dst$$reg), 14147 as_Register($src1$$reg), 14148 as_Register($src2$$reg), 14149 Assembler::GT); 14150 %} 14151 14152 ins_pipe(ialu_reg_reg); 14153 %} 14154 14155 // ============================================================================ 14156 // Branch Instructions 14157 14158 // Direct Branch. 14159 instruct branch(label lbl) 14160 %{ 14161 match(Goto); 14162 14163 effect(USE lbl); 14164 14165 ins_cost(BRANCH_COST); 14166 format %{ "b $lbl" %} 14167 14168 ins_encode(aarch64_enc_b(lbl)); 14169 14170 ins_pipe(pipe_branch); 14171 %} 14172 14173 // Conditional Near Branch 14174 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14175 %{ 14176 // Same match rule as `branchConFar'. 14177 match(If cmp cr); 14178 14179 effect(USE lbl); 14180 14181 ins_cost(BRANCH_COST); 14182 // If set to 1 this indicates that the current instruction is a 14183 // short variant of a long branch. This avoids using this 14184 // instruction in first-pass matching. It will then only be used in 14185 // the `Shorten_branches' pass. 14186 // ins_short_branch(1); 14187 format %{ "b$cmp $lbl" %} 14188 14189 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14190 14191 ins_pipe(pipe_branch_cond); 14192 %} 14193 14194 // Conditional Near Branch Unsigned 14195 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14196 %{ 14197 // Same match rule as `branchConFar'. 14198 match(If cmp cr); 14199 14200 effect(USE lbl); 14201 14202 ins_cost(BRANCH_COST); 14203 // If set to 1 this indicates that the current instruction is a 14204 // short variant of a long branch. This avoids using this 14205 // instruction in first-pass matching. It will then only be used in 14206 // the `Shorten_branches' pass. 14207 // ins_short_branch(1); 14208 format %{ "b$cmp $lbl\t# unsigned" %} 14209 14210 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14211 14212 ins_pipe(pipe_branch_cond); 14213 %} 14214 14215 // Make use of CBZ and CBNZ. These instructions, as well as being 14216 // shorter than (cmp; branch), have the additional benefit of not 14217 // killing the flags. 14218 14219 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14220 match(If cmp (CmpI op1 op2)); 14221 effect(USE labl); 14222 14223 ins_cost(BRANCH_COST); 14224 format %{ "cbw$cmp $op1, $labl" %} 14225 ins_encode %{ 14226 Label* L = $labl$$label; 14227 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14228 if (cond == Assembler::EQ) 14229 __ cbzw($op1$$Register, *L); 14230 else 14231 __ cbnzw($op1$$Register, *L); 14232 %} 14233 ins_pipe(pipe_cmp_branch); 14234 %} 14235 14236 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14237 match(If cmp (CmpL op1 op2)); 14238 effect(USE labl); 14239 14240 ins_cost(BRANCH_COST); 14241 format %{ "cb$cmp $op1, $labl" %} 14242 ins_encode %{ 14243 Label* L = $labl$$label; 14244 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14245 if (cond == Assembler::EQ) 14246 __ cbz($op1$$Register, *L); 14247 else 14248 __ cbnz($op1$$Register, *L); 14249 %} 14250 ins_pipe(pipe_cmp_branch); 14251 %} 14252 14253 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14254 match(If cmp (CmpP op1 op2)); 14255 effect(USE labl); 14256 14257 ins_cost(BRANCH_COST); 14258 format %{ "cb$cmp $op1, $labl" %} 14259 ins_encode %{ 14260 Label* L = $labl$$label; 14261 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14262 if (cond == Assembler::EQ) 14263 __ cbz($op1$$Register, *L); 14264 else 14265 __ cbnz($op1$$Register, *L); 14266 %} 14267 ins_pipe(pipe_cmp_branch); 14268 %} 14269 14270 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14271 match(If cmp (CmpN op1 op2)); 14272 effect(USE labl); 14273 14274 ins_cost(BRANCH_COST); 14275 format %{ "cbw$cmp $op1, $labl" %} 14276 ins_encode %{ 14277 Label* L = $labl$$label; 14278 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14279 if (cond == Assembler::EQ) 14280 __ cbzw($op1$$Register, *L); 14281 else 14282 __ cbnzw($op1$$Register, *L); 14283 %} 14284 ins_pipe(pipe_cmp_branch); 14285 %} 14286 14287 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14288 match(If cmp (CmpP (DecodeN oop) zero)); 14289 effect(USE labl); 14290 14291 ins_cost(BRANCH_COST); 14292 format %{ "cb$cmp $oop, $labl" %} 14293 ins_encode %{ 14294 Label* L = $labl$$label; 14295 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14296 if (cond == Assembler::EQ) 14297 __ cbzw($oop$$Register, *L); 14298 else 14299 __ cbnzw($oop$$Register, *L); 14300 %} 14301 ins_pipe(pipe_cmp_branch); 14302 %} 14303 14304 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14305 match(If cmp (CmpU op1 op2)); 14306 effect(USE labl); 14307 14308 ins_cost(BRANCH_COST); 14309 format %{ "cbw$cmp $op1, $labl" %} 14310 ins_encode %{ 14311 Label* L = $labl$$label; 14312 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14313 if (cond == Assembler::EQ || cond == Assembler::LS) 14314 __ cbzw($op1$$Register, *L); 14315 else 14316 __ cbnzw($op1$$Register, *L); 14317 %} 14318 ins_pipe(pipe_cmp_branch); 14319 %} 14320 14321 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14322 match(If cmp (CmpUL op1 op2)); 14323 effect(USE labl); 14324 14325 ins_cost(BRANCH_COST); 14326 format %{ "cb$cmp $op1, $labl" %} 14327 ins_encode %{ 14328 Label* L = $labl$$label; 14329 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14330 if (cond == Assembler::EQ || cond == Assembler::LS) 14331 __ cbz($op1$$Register, *L); 14332 else 14333 __ cbnz($op1$$Register, *L); 14334 %} 14335 ins_pipe(pipe_cmp_branch); 14336 %} 14337 14338 // Test bit and Branch 14339 14340 // Patterns for short (< 32KiB) variants 14341 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14342 match(If cmp (CmpL op1 op2)); 14343 effect(USE labl); 14344 14345 ins_cost(BRANCH_COST); 14346 format %{ "cb$cmp $op1, $labl # long" %} 14347 ins_encode %{ 14348 Label* L = $labl$$label; 14349 Assembler::Condition cond = 14350 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14351 __ tbr(cond, $op1$$Register, 63, *L); 14352 %} 14353 ins_pipe(pipe_cmp_branch); 14354 ins_short_branch(1); 14355 %} 14356 14357 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14358 match(If cmp (CmpI op1 op2)); 14359 effect(USE labl); 14360 14361 ins_cost(BRANCH_COST); 14362 format %{ "cb$cmp $op1, $labl # int" %} 14363 ins_encode %{ 14364 Label* L = $labl$$label; 14365 Assembler::Condition cond = 14366 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14367 __ tbr(cond, $op1$$Register, 31, *L); 14368 %} 14369 ins_pipe(pipe_cmp_branch); 14370 ins_short_branch(1); 14371 %} 14372 14373 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14374 match(If cmp (CmpL (AndL op1 op2) op3)); 14375 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14376 effect(USE labl); 14377 14378 ins_cost(BRANCH_COST); 14379 format %{ "tb$cmp $op1, $op2, $labl" %} 14380 ins_encode %{ 14381 Label* L = $labl$$label; 14382 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14383 int bit = exact_log2($op2$$constant); 14384 __ tbr(cond, $op1$$Register, bit, *L); 14385 %} 14386 ins_pipe(pipe_cmp_branch); 14387 ins_short_branch(1); 14388 %} 14389 14390 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14391 match(If cmp (CmpI (AndI op1 op2) op3)); 14392 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14393 effect(USE labl); 14394 14395 ins_cost(BRANCH_COST); 14396 format %{ "tb$cmp $op1, $op2, $labl" %} 14397 ins_encode %{ 14398 Label* L = $labl$$label; 14399 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14400 int bit = exact_log2($op2$$constant); 14401 __ tbr(cond, $op1$$Register, bit, *L); 14402 %} 14403 ins_pipe(pipe_cmp_branch); 14404 ins_short_branch(1); 14405 %} 14406 14407 // And far variants 14408 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14409 match(If cmp (CmpL op1 op2)); 14410 effect(USE labl); 14411 14412 ins_cost(BRANCH_COST); 14413 format %{ "cb$cmp $op1, $labl # long" %} 14414 ins_encode %{ 14415 Label* L = $labl$$label; 14416 Assembler::Condition cond = 14417 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14418 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14419 %} 14420 ins_pipe(pipe_cmp_branch); 14421 %} 14422 14423 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14424 match(If cmp (CmpI op1 op2)); 14425 effect(USE labl); 14426 14427 ins_cost(BRANCH_COST); 14428 format %{ "cb$cmp $op1, $labl # int" %} 14429 ins_encode %{ 14430 Label* L = $labl$$label; 14431 Assembler::Condition cond = 14432 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14433 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14434 %} 14435 ins_pipe(pipe_cmp_branch); 14436 %} 14437 14438 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14439 match(If cmp (CmpL (AndL op1 op2) op3)); 14440 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14441 effect(USE labl); 14442 14443 ins_cost(BRANCH_COST); 14444 format %{ "tb$cmp $op1, $op2, $labl" %} 14445 ins_encode %{ 14446 Label* L = $labl$$label; 14447 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14448 int bit = exact_log2($op2$$constant); 14449 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14450 %} 14451 ins_pipe(pipe_cmp_branch); 14452 %} 14453 14454 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14455 match(If cmp (CmpI (AndI op1 op2) op3)); 14456 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14457 effect(USE labl); 14458 14459 ins_cost(BRANCH_COST); 14460 format %{ "tb$cmp $op1, $op2, $labl" %} 14461 ins_encode %{ 14462 Label* L = $labl$$label; 14463 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14464 int bit = exact_log2($op2$$constant); 14465 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14466 %} 14467 ins_pipe(pipe_cmp_branch); 14468 %} 14469 14470 // Test bits 14471 14472 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14473 match(Set cr (CmpL (AndL op1 op2) op3)); 14474 predicate(Assembler::operand_valid_for_logical_immediate 14475 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14476 14477 ins_cost(INSN_COST); 14478 format %{ "tst $op1, $op2 # long" %} 14479 ins_encode %{ 14480 __ tst($op1$$Register, $op2$$constant); 14481 %} 14482 ins_pipe(ialu_reg_reg); 14483 %} 14484 14485 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14486 match(Set cr (CmpI (AndI op1 op2) op3)); 14487 predicate(Assembler::operand_valid_for_logical_immediate 14488 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14489 14490 ins_cost(INSN_COST); 14491 format %{ "tst $op1, $op2 # int" %} 14492 ins_encode %{ 14493 __ tstw($op1$$Register, $op2$$constant); 14494 %} 14495 ins_pipe(ialu_reg_reg); 14496 %} 14497 14498 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14499 match(Set cr (CmpL (AndL op1 op2) op3)); 14500 14501 ins_cost(INSN_COST); 14502 format %{ "tst $op1, $op2 # long" %} 14503 ins_encode %{ 14504 __ tst($op1$$Register, $op2$$Register); 14505 %} 14506 ins_pipe(ialu_reg_reg); 14507 %} 14508 14509 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14510 match(Set cr (CmpI (AndI op1 op2) op3)); 14511 14512 ins_cost(INSN_COST); 14513 format %{ "tstw $op1, $op2 # int" %} 14514 ins_encode %{ 14515 __ tstw($op1$$Register, $op2$$Register); 14516 %} 14517 ins_pipe(ialu_reg_reg); 14518 %} 14519 14520 14521 // Conditional Far Branch 14522 // Conditional Far Branch Unsigned 14523 // TODO: fixme 14524 14525 // counted loop end branch near 14526 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14527 %{ 14528 match(CountedLoopEnd cmp cr); 14529 14530 effect(USE lbl); 14531 14532 ins_cost(BRANCH_COST); 14533 // short variant. 14534 // ins_short_branch(1); 14535 format %{ "b$cmp $lbl \t// counted loop end" %} 14536 14537 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14538 14539 ins_pipe(pipe_branch); 14540 %} 14541 14542 // counted loop end branch near Unsigned 14543 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14544 %{ 14545 match(CountedLoopEnd cmp cr); 14546 14547 effect(USE lbl); 14548 14549 ins_cost(BRANCH_COST); 14550 // short variant. 14551 // ins_short_branch(1); 14552 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14553 14554 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14555 14556 ins_pipe(pipe_branch); 14557 %} 14558 14559 // counted loop end branch far 14560 // counted loop end branch far unsigned 14561 // TODO: fixme 14562 14563 // ============================================================================ 14564 // inlined locking and unlocking 14565 14566 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14567 %{ 14568 match(Set cr (FastLock object box)); 14569 effect(TEMP tmp, TEMP tmp2); 14570 14571 // TODO 14572 // identify correct cost 14573 ins_cost(5 * INSN_COST); 14574 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14575 14576 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14577 14578 ins_pipe(pipe_serial); 14579 %} 14580 14581 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14582 %{ 14583 match(Set cr (FastUnlock object box)); 14584 effect(TEMP tmp, TEMP tmp2); 14585 14586 ins_cost(5 * INSN_COST); 14587 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14588 14589 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14590 14591 ins_pipe(pipe_serial); 14592 %} 14593 14594 14595 // ============================================================================ 14596 // Safepoint Instructions 14597 14598 // TODO 14599 // provide a near and far version of this code 14600 14601 instruct safePoint(iRegP poll) 14602 %{ 14603 match(SafePoint poll); 14604 14605 format %{ 14606 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14607 %} 14608 ins_encode %{ 14609 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14610 %} 14611 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14612 %} 14613 14614 14615 // ============================================================================ 14616 // Procedure Call/Return Instructions 14617 14618 // Call Java Static Instruction 14619 14620 instruct CallStaticJavaDirect(method meth) 14621 %{ 14622 match(CallStaticJava); 14623 14624 effect(USE meth); 14625 14626 ins_cost(CALL_COST); 14627 14628 format %{ "call,static $meth \t// ==> " %} 14629 14630 ins_encode( aarch64_enc_java_static_call(meth), 14631 aarch64_enc_call_epilog ); 14632 14633 ins_pipe(pipe_class_call); 14634 %} 14635 14636 // TO HERE 14637 14638 // Call Java Dynamic Instruction 14639 instruct CallDynamicJavaDirect(method meth) 14640 %{ 14641 match(CallDynamicJava); 14642 14643 effect(USE meth); 14644 14645 ins_cost(CALL_COST); 14646 14647 format %{ "CALL,dynamic $meth \t// ==> " %} 14648 14649 ins_encode( aarch64_enc_java_dynamic_call(meth), 14650 aarch64_enc_call_epilog ); 14651 14652 ins_pipe(pipe_class_call); 14653 %} 14654 14655 // Call Runtime Instruction 14656 14657 instruct CallRuntimeDirect(method meth) 14658 %{ 14659 match(CallRuntime); 14660 14661 effect(USE meth); 14662 14663 ins_cost(CALL_COST); 14664 14665 format %{ "CALL, runtime $meth" %} 14666 14667 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14668 14669 ins_pipe(pipe_class_call); 14670 %} 14671 14672 // Call Runtime Instruction 14673 14674 instruct CallLeafDirect(method meth) 14675 %{ 14676 match(CallLeaf); 14677 14678 effect(USE meth); 14679 14680 ins_cost(CALL_COST); 14681 14682 format %{ "CALL, runtime leaf $meth" %} 14683 14684 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14685 14686 ins_pipe(pipe_class_call); 14687 %} 14688 14689 // Call Runtime Instruction 14690 14691 instruct CallLeafNoFPDirect(method meth) 14692 %{ 14693 match(CallLeafNoFP); 14694 14695 effect(USE meth); 14696 14697 ins_cost(CALL_COST); 14698 14699 format %{ "CALL, runtime leaf nofp $meth" %} 14700 14701 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14702 14703 ins_pipe(pipe_class_call); 14704 %} 14705 14706 // Tail Call; Jump from runtime stub to Java code. 14707 // Also known as an 'interprocedural jump'. 14708 // Target of jump will eventually return to caller. 14709 // TailJump below removes the return address. 14710 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 14711 %{ 14712 match(TailCall jump_target method_oop); 14713 14714 ins_cost(CALL_COST); 14715 14716 format %{ "br $jump_target\t# $method_oop holds method oop" %} 14717 14718 ins_encode(aarch64_enc_tail_call(jump_target)); 14719 14720 ins_pipe(pipe_class_call); 14721 %} 14722 14723 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 14724 %{ 14725 match(TailJump jump_target ex_oop); 14726 14727 ins_cost(CALL_COST); 14728 14729 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 14730 14731 ins_encode(aarch64_enc_tail_jmp(jump_target)); 14732 14733 ins_pipe(pipe_class_call); 14734 %} 14735 14736 // Create exception oop: created by stack-crawling runtime code. 14737 // Created exception is now available to this handler, and is setup 14738 // just prior to jumping to this handler. No code emitted. 14739 // TODO check 14740 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 14741 instruct CreateException(iRegP_R0 ex_oop) 14742 %{ 14743 match(Set ex_oop (CreateEx)); 14744 14745 format %{ " -- \t// exception oop; no code emitted" %} 14746 14747 size(0); 14748 14749 ins_encode( /*empty*/ ); 14750 14751 ins_pipe(pipe_class_empty); 14752 %} 14753 14754 // Rethrow exception: The exception oop will come in the first 14755 // argument position. Then JUMP (not call) to the rethrow stub code. 14756 instruct RethrowException() %{ 14757 match(Rethrow); 14758 ins_cost(CALL_COST); 14759 14760 format %{ "b rethrow_stub" %} 14761 14762 ins_encode( aarch64_enc_rethrow() ); 14763 14764 ins_pipe(pipe_class_call); 14765 %} 14766 14767 14768 // Return Instruction 14769 // epilog node loads ret address into lr as part of frame pop 14770 instruct Ret() 14771 %{ 14772 match(Return); 14773 14774 format %{ "ret\t// return register" %} 14775 14776 ins_encode( aarch64_enc_ret() ); 14777 14778 ins_pipe(pipe_branch); 14779 %} 14780 14781 // Die now. 14782 instruct ShouldNotReachHere() %{ 14783 match(Halt); 14784 14785 ins_cost(CALL_COST); 14786 format %{ "ShouldNotReachHere" %} 14787 14788 ins_encode %{ 14789 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 14790 // return true 14791 __ dpcs1(0xdead + 1); 14792 %} 14793 14794 ins_pipe(pipe_class_default); 14795 %} 14796 14797 // ============================================================================ 14798 // Partial Subtype Check 14799 // 14800 // superklass array for an instance of the superklass. Set a hidden 14801 // internal cache on a hit (cache is checked with exposed code in 14802 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14803 // encoding ALSO sets flags. 14804 14805 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 14806 %{ 14807 match(Set result (PartialSubtypeCheck sub super)); 14808 effect(KILL cr, KILL temp); 14809 14810 ins_cost(1100); // slightly larger than the next version 14811 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14812 14813 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14814 14815 opcode(0x1); // Force zero of result reg on hit 14816 14817 ins_pipe(pipe_class_memory); 14818 %} 14819 14820 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 14821 %{ 14822 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 14823 effect(KILL temp, KILL result); 14824 14825 ins_cost(1100); // slightly larger than the next version 14826 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 14827 14828 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14829 14830 opcode(0x0); // Don't zero result reg on hit 14831 14832 ins_pipe(pipe_class_memory); 14833 %} 14834 14835 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14836 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14837 %{ 14838 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 14839 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14840 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14841 14842 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14843 ins_encode %{ 14844 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14845 __ string_compare($str1$$Register, $str2$$Register, 14846 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14847 $tmp1$$Register, $tmp2$$Register, 14848 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 14849 %} 14850 ins_pipe(pipe_class_memory); 14851 %} 14852 14853 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14854 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14855 %{ 14856 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 14857 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14858 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14859 14860 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14861 ins_encode %{ 14862 __ string_compare($str1$$Register, $str2$$Register, 14863 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14864 $tmp1$$Register, $tmp2$$Register, 14865 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 14866 %} 14867 ins_pipe(pipe_class_memory); 14868 %} 14869 14870 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14871 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14872 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14873 %{ 14874 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 14875 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14876 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14877 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14878 14879 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14880 ins_encode %{ 14881 __ string_compare($str1$$Register, $str2$$Register, 14882 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14883 $tmp1$$Register, $tmp2$$Register, 14884 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14885 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 14886 %} 14887 ins_pipe(pipe_class_memory); 14888 %} 14889 14890 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14891 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14892 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14893 %{ 14894 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 14895 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14896 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14897 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14898 14899 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14900 ins_encode %{ 14901 __ string_compare($str1$$Register, $str2$$Register, 14902 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14903 $tmp1$$Register, $tmp2$$Register, 14904 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14905 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 14906 %} 14907 ins_pipe(pipe_class_memory); 14908 %} 14909 14910 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14911 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14912 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14913 %{ 14914 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14915 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14916 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14917 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14918 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 14919 14920 ins_encode %{ 14921 __ string_indexof($str1$$Register, $str2$$Register, 14922 $cnt1$$Register, $cnt2$$Register, 14923 $tmp1$$Register, $tmp2$$Register, 14924 $tmp3$$Register, $tmp4$$Register, 14925 $tmp5$$Register, $tmp6$$Register, 14926 -1, $result$$Register, StrIntrinsicNode::UU); 14927 %} 14928 ins_pipe(pipe_class_memory); 14929 %} 14930 14931 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14932 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14933 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14934 %{ 14935 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14936 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14937 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14938 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14939 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 14940 14941 ins_encode %{ 14942 __ string_indexof($str1$$Register, $str2$$Register, 14943 $cnt1$$Register, $cnt2$$Register, 14944 $tmp1$$Register, $tmp2$$Register, 14945 $tmp3$$Register, $tmp4$$Register, 14946 $tmp5$$Register, $tmp6$$Register, 14947 -1, $result$$Register, StrIntrinsicNode::LL); 14948 %} 14949 ins_pipe(pipe_class_memory); 14950 %} 14951 14952 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14953 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14954 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14955 %{ 14956 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14957 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14958 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14959 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14960 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 14961 14962 ins_encode %{ 14963 __ string_indexof($str1$$Register, $str2$$Register, 14964 $cnt1$$Register, $cnt2$$Register, 14965 $tmp1$$Register, $tmp2$$Register, 14966 $tmp3$$Register, $tmp4$$Register, 14967 $tmp5$$Register, $tmp6$$Register, 14968 -1, $result$$Register, StrIntrinsicNode::UL); 14969 %} 14970 ins_pipe(pipe_class_memory); 14971 %} 14972 14973 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14974 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14975 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14976 %{ 14977 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14978 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14979 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14980 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14981 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 14982 14983 ins_encode %{ 14984 int icnt2 = (int)$int_cnt2$$constant; 14985 __ string_indexof($str1$$Register, $str2$$Register, 14986 $cnt1$$Register, zr, 14987 $tmp1$$Register, $tmp2$$Register, 14988 $tmp3$$Register, $tmp4$$Register, zr, zr, 14989 icnt2, $result$$Register, StrIntrinsicNode::UU); 14990 %} 14991 ins_pipe(pipe_class_memory); 14992 %} 14993 14994 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14995 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14996 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14997 %{ 14998 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14999 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15000 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15001 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15002 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15003 15004 ins_encode %{ 15005 int icnt2 = (int)$int_cnt2$$constant; 15006 __ string_indexof($str1$$Register, $str2$$Register, 15007 $cnt1$$Register, zr, 15008 $tmp1$$Register, $tmp2$$Register, 15009 $tmp3$$Register, $tmp4$$Register, zr, zr, 15010 icnt2, $result$$Register, StrIntrinsicNode::LL); 15011 %} 15012 ins_pipe(pipe_class_memory); 15013 %} 15014 15015 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15016 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15017 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15018 %{ 15019 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15020 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15021 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15022 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15023 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15024 15025 ins_encode %{ 15026 int icnt2 = (int)$int_cnt2$$constant; 15027 __ string_indexof($str1$$Register, $str2$$Register, 15028 $cnt1$$Register, zr, 15029 $tmp1$$Register, $tmp2$$Register, 15030 $tmp3$$Register, $tmp4$$Register, zr, zr, 15031 icnt2, $result$$Register, StrIntrinsicNode::UL); 15032 %} 15033 ins_pipe(pipe_class_memory); 15034 %} 15035 15036 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15037 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15038 iRegINoSp tmp3, rFlagsReg cr) 15039 %{ 15040 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15041 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15042 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15043 15044 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15045 15046 ins_encode %{ 15047 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15048 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15049 $tmp3$$Register); 15050 %} 15051 ins_pipe(pipe_class_memory); 15052 %} 15053 15054 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15055 iRegI_R0 result, rFlagsReg cr) 15056 %{ 15057 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15058 match(Set result (StrEquals (Binary str1 str2) cnt)); 15059 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15060 15061 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15062 ins_encode %{ 15063 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15064 __ string_equals($str1$$Register, $str2$$Register, 15065 $result$$Register, $cnt$$Register, 1); 15066 %} 15067 ins_pipe(pipe_class_memory); 15068 %} 15069 15070 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15071 iRegI_R0 result, rFlagsReg cr) 15072 %{ 15073 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15074 match(Set result (StrEquals (Binary str1 str2) cnt)); 15075 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15076 15077 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15078 ins_encode %{ 15079 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15080 __ string_equals($str1$$Register, $str2$$Register, 15081 $result$$Register, $cnt$$Register, 2); 15082 %} 15083 ins_pipe(pipe_class_memory); 15084 %} 15085 15086 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15087 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15088 iRegP_R10 tmp, rFlagsReg cr) 15089 %{ 15090 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15091 match(Set result (AryEq ary1 ary2)); 15092 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15093 15094 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15095 ins_encode %{ 15096 __ arrays_equals($ary1$$Register, $ary2$$Register, 15097 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15098 $result$$Register, $tmp$$Register, 1); 15099 %} 15100 ins_pipe(pipe_class_memory); 15101 %} 15102 15103 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15104 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15105 iRegP_R10 tmp, rFlagsReg cr) 15106 %{ 15107 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15108 match(Set result (AryEq ary1 ary2)); 15109 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15110 15111 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15112 ins_encode %{ 15113 __ arrays_equals($ary1$$Register, $ary2$$Register, 15114 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15115 $result$$Register, $tmp$$Register, 2); 15116 %} 15117 ins_pipe(pipe_class_memory); 15118 %} 15119 15120 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15121 %{ 15122 match(Set result (HasNegatives ary1 len)); 15123 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15124 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15125 ins_encode %{ 15126 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15127 %} 15128 ins_pipe( pipe_slow ); 15129 %} 15130 15131 // fast char[] to byte[] compression 15132 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15133 vRegD_V0 tmp1, vRegD_V1 tmp2, 15134 vRegD_V2 tmp3, vRegD_V3 tmp4, 15135 iRegI_R0 result, rFlagsReg cr) 15136 %{ 15137 match(Set result (StrCompressedCopy src (Binary dst len))); 15138 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15139 15140 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15141 ins_encode %{ 15142 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15143 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15144 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15145 $result$$Register); 15146 %} 15147 ins_pipe( pipe_slow ); 15148 %} 15149 15150 // fast byte[] to char[] inflation 15151 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15152 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15153 %{ 15154 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15155 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15156 15157 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15158 ins_encode %{ 15159 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15160 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15161 %} 15162 ins_pipe(pipe_class_memory); 15163 %} 15164 15165 // encode char[] to byte[] in ISO_8859_1 15166 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15167 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15168 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15169 iRegI_R0 result, rFlagsReg cr) 15170 %{ 15171 match(Set result (EncodeISOArray src (Binary dst len))); 15172 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15173 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15174 15175 format %{ "Encode array $src,$dst,$len -> $result" %} 15176 ins_encode %{ 15177 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15178 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15179 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15180 %} 15181 ins_pipe( pipe_class_memory ); 15182 %} 15183 15184 // ============================================================================ 15185 // This name is KNOWN by the ADLC and cannot be changed. 15186 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15187 // for this guy. 15188 instruct tlsLoadP(thread_RegP dst) 15189 %{ 15190 match(Set dst (ThreadLocal)); 15191 15192 ins_cost(0); 15193 15194 format %{ " -- \t// $dst=Thread::current(), empty" %} 15195 15196 size(0); 15197 15198 ins_encode( /*empty*/ ); 15199 15200 ins_pipe(pipe_class_empty); 15201 %} 15202 15203 // ====================VECTOR INSTRUCTIONS===================================== 15204 15205 // Load vector (32 bits) 15206 instruct loadV4(vecD dst, vmem4 mem) 15207 %{ 15208 predicate(n->as_LoadVector()->memory_size() == 4); 15209 match(Set dst (LoadVector mem)); 15210 ins_cost(4 * INSN_COST); 15211 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15212 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15213 ins_pipe(vload_reg_mem64); 15214 %} 15215 15216 // Load vector (64 bits) 15217 instruct loadV8(vecD dst, vmem8 mem) 15218 %{ 15219 predicate(n->as_LoadVector()->memory_size() == 8); 15220 match(Set dst (LoadVector mem)); 15221 ins_cost(4 * INSN_COST); 15222 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15223 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15224 ins_pipe(vload_reg_mem64); 15225 %} 15226 15227 // Load Vector (128 bits) 15228 instruct loadV16(vecX dst, vmem16 mem) 15229 %{ 15230 predicate(n->as_LoadVector()->memory_size() == 16); 15231 match(Set dst (LoadVector mem)); 15232 ins_cost(4 * INSN_COST); 15233 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15234 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15235 ins_pipe(vload_reg_mem128); 15236 %} 15237 15238 // Store Vector (32 bits) 15239 instruct storeV4(vecD src, vmem4 mem) 15240 %{ 15241 predicate(n->as_StoreVector()->memory_size() == 4); 15242 match(Set mem (StoreVector mem src)); 15243 ins_cost(4 * INSN_COST); 15244 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15245 ins_encode( aarch64_enc_strvS(src, mem) ); 15246 ins_pipe(vstore_reg_mem64); 15247 %} 15248 15249 // Store Vector (64 bits) 15250 instruct storeV8(vecD src, vmem8 mem) 15251 %{ 15252 predicate(n->as_StoreVector()->memory_size() == 8); 15253 match(Set mem (StoreVector mem src)); 15254 ins_cost(4 * INSN_COST); 15255 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15256 ins_encode( aarch64_enc_strvD(src, mem) ); 15257 ins_pipe(vstore_reg_mem64); 15258 %} 15259 15260 // Store Vector (128 bits) 15261 instruct storeV16(vecX src, vmem16 mem) 15262 %{ 15263 predicate(n->as_StoreVector()->memory_size() == 16); 15264 match(Set mem (StoreVector mem src)); 15265 ins_cost(4 * INSN_COST); 15266 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15267 ins_encode( aarch64_enc_strvQ(src, mem) ); 15268 ins_pipe(vstore_reg_mem128); 15269 %} 15270 15271 instruct replicate8B(vecD dst, iRegIorL2I src) 15272 %{ 15273 predicate(n->as_Vector()->length() == 4 || 15274 n->as_Vector()->length() == 8); 15275 match(Set dst (ReplicateB src)); 15276 ins_cost(INSN_COST); 15277 format %{ "dup $dst, $src\t# vector (8B)" %} 15278 ins_encode %{ 15279 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15280 %} 15281 ins_pipe(vdup_reg_reg64); 15282 %} 15283 15284 instruct replicate16B(vecX dst, iRegIorL2I src) 15285 %{ 15286 predicate(n->as_Vector()->length() == 16); 15287 match(Set dst (ReplicateB src)); 15288 ins_cost(INSN_COST); 15289 format %{ "dup $dst, $src\t# vector (16B)" %} 15290 ins_encode %{ 15291 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15292 %} 15293 ins_pipe(vdup_reg_reg128); 15294 %} 15295 15296 instruct replicate8B_imm(vecD dst, immI con) 15297 %{ 15298 predicate(n->as_Vector()->length() == 4 || 15299 n->as_Vector()->length() == 8); 15300 match(Set dst (ReplicateB con)); 15301 ins_cost(INSN_COST); 15302 format %{ "movi $dst, $con\t# vector(8B)" %} 15303 ins_encode %{ 15304 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15305 %} 15306 ins_pipe(vmovi_reg_imm64); 15307 %} 15308 15309 instruct replicate16B_imm(vecX dst, immI con) 15310 %{ 15311 predicate(n->as_Vector()->length() == 16); 15312 match(Set dst (ReplicateB con)); 15313 ins_cost(INSN_COST); 15314 format %{ "movi $dst, $con\t# vector(16B)" %} 15315 ins_encode %{ 15316 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15317 %} 15318 ins_pipe(vmovi_reg_imm128); 15319 %} 15320 15321 instruct replicate4S(vecD dst, iRegIorL2I src) 15322 %{ 15323 predicate(n->as_Vector()->length() == 2 || 15324 n->as_Vector()->length() == 4); 15325 match(Set dst (ReplicateS src)); 15326 ins_cost(INSN_COST); 15327 format %{ "dup $dst, $src\t# vector (4S)" %} 15328 ins_encode %{ 15329 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15330 %} 15331 ins_pipe(vdup_reg_reg64); 15332 %} 15333 15334 instruct replicate8S(vecX dst, iRegIorL2I src) 15335 %{ 15336 predicate(n->as_Vector()->length() == 8); 15337 match(Set dst (ReplicateS src)); 15338 ins_cost(INSN_COST); 15339 format %{ "dup $dst, $src\t# vector (8S)" %} 15340 ins_encode %{ 15341 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15342 %} 15343 ins_pipe(vdup_reg_reg128); 15344 %} 15345 15346 instruct replicate4S_imm(vecD dst, immI con) 15347 %{ 15348 predicate(n->as_Vector()->length() == 2 || 15349 n->as_Vector()->length() == 4); 15350 match(Set dst (ReplicateS con)); 15351 ins_cost(INSN_COST); 15352 format %{ "movi $dst, $con\t# vector(4H)" %} 15353 ins_encode %{ 15354 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15355 %} 15356 ins_pipe(vmovi_reg_imm64); 15357 %} 15358 15359 instruct replicate8S_imm(vecX dst, immI con) 15360 %{ 15361 predicate(n->as_Vector()->length() == 8); 15362 match(Set dst (ReplicateS con)); 15363 ins_cost(INSN_COST); 15364 format %{ "movi $dst, $con\t# vector(8H)" %} 15365 ins_encode %{ 15366 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15367 %} 15368 ins_pipe(vmovi_reg_imm128); 15369 %} 15370 15371 instruct replicate2I(vecD dst, iRegIorL2I src) 15372 %{ 15373 predicate(n->as_Vector()->length() == 2); 15374 match(Set dst (ReplicateI src)); 15375 ins_cost(INSN_COST); 15376 format %{ "dup $dst, $src\t# vector (2I)" %} 15377 ins_encode %{ 15378 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15379 %} 15380 ins_pipe(vdup_reg_reg64); 15381 %} 15382 15383 instruct replicate4I(vecX dst, iRegIorL2I src) 15384 %{ 15385 predicate(n->as_Vector()->length() == 4); 15386 match(Set dst (ReplicateI src)); 15387 ins_cost(INSN_COST); 15388 format %{ "dup $dst, $src\t# vector (4I)" %} 15389 ins_encode %{ 15390 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15391 %} 15392 ins_pipe(vdup_reg_reg128); 15393 %} 15394 15395 instruct replicate2I_imm(vecD dst, immI con) 15396 %{ 15397 predicate(n->as_Vector()->length() == 2); 15398 match(Set dst (ReplicateI con)); 15399 ins_cost(INSN_COST); 15400 format %{ "movi $dst, $con\t# vector(2I)" %} 15401 ins_encode %{ 15402 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15403 %} 15404 ins_pipe(vmovi_reg_imm64); 15405 %} 15406 15407 instruct replicate4I_imm(vecX dst, immI con) 15408 %{ 15409 predicate(n->as_Vector()->length() == 4); 15410 match(Set dst (ReplicateI con)); 15411 ins_cost(INSN_COST); 15412 format %{ "movi $dst, $con\t# vector(4I)" %} 15413 ins_encode %{ 15414 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15415 %} 15416 ins_pipe(vmovi_reg_imm128); 15417 %} 15418 15419 instruct replicate2L(vecX dst, iRegL src) 15420 %{ 15421 predicate(n->as_Vector()->length() == 2); 15422 match(Set dst (ReplicateL src)); 15423 ins_cost(INSN_COST); 15424 format %{ "dup $dst, $src\t# vector (2L)" %} 15425 ins_encode %{ 15426 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15427 %} 15428 ins_pipe(vdup_reg_reg128); 15429 %} 15430 15431 instruct replicate2L_zero(vecX dst, immI0 zero) 15432 %{ 15433 predicate(n->as_Vector()->length() == 2); 15434 match(Set dst (ReplicateI zero)); 15435 ins_cost(INSN_COST); 15436 format %{ "movi $dst, $zero\t# vector(4I)" %} 15437 ins_encode %{ 15438 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15439 as_FloatRegister($dst$$reg), 15440 as_FloatRegister($dst$$reg)); 15441 %} 15442 ins_pipe(vmovi_reg_imm128); 15443 %} 15444 15445 instruct replicate2F(vecD dst, vRegF src) 15446 %{ 15447 predicate(n->as_Vector()->length() == 2); 15448 match(Set dst (ReplicateF src)); 15449 ins_cost(INSN_COST); 15450 format %{ "dup $dst, $src\t# vector (2F)" %} 15451 ins_encode %{ 15452 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15453 as_FloatRegister($src$$reg)); 15454 %} 15455 ins_pipe(vdup_reg_freg64); 15456 %} 15457 15458 instruct replicate4F(vecX dst, vRegF src) 15459 %{ 15460 predicate(n->as_Vector()->length() == 4); 15461 match(Set dst (ReplicateF src)); 15462 ins_cost(INSN_COST); 15463 format %{ "dup $dst, $src\t# vector (4F)" %} 15464 ins_encode %{ 15465 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15466 as_FloatRegister($src$$reg)); 15467 %} 15468 ins_pipe(vdup_reg_freg128); 15469 %} 15470 15471 instruct replicate2D(vecX dst, vRegD src) 15472 %{ 15473 predicate(n->as_Vector()->length() == 2); 15474 match(Set dst (ReplicateD src)); 15475 ins_cost(INSN_COST); 15476 format %{ "dup $dst, $src\t# vector (2D)" %} 15477 ins_encode %{ 15478 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15479 as_FloatRegister($src$$reg)); 15480 %} 15481 ins_pipe(vdup_reg_dreg128); 15482 %} 15483 15484 // ====================REDUCTION ARITHMETIC==================================== 15485 15486 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15487 %{ 15488 match(Set dst (AddReductionVI src1 src2)); 15489 ins_cost(INSN_COST); 15490 effect(TEMP tmp, TEMP tmp2); 15491 format %{ "umov $tmp, $src2, S, 0\n\t" 15492 "umov $tmp2, $src2, S, 1\n\t" 15493 "addw $dst, $src1, $tmp\n\t" 15494 "addw $dst, $dst, $tmp2\t add reduction2i" 15495 %} 15496 ins_encode %{ 15497 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15498 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15499 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15500 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15501 %} 15502 ins_pipe(pipe_class_default); 15503 %} 15504 15505 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15506 %{ 15507 match(Set dst (AddReductionVI src1 src2)); 15508 ins_cost(INSN_COST); 15509 effect(TEMP tmp, TEMP tmp2); 15510 format %{ "addv $tmp, T4S, $src2\n\t" 15511 "umov $tmp2, $tmp, S, 0\n\t" 15512 "addw $dst, $tmp2, $src1\t add reduction4i" 15513 %} 15514 ins_encode %{ 15515 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15516 as_FloatRegister($src2$$reg)); 15517 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15518 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15519 %} 15520 ins_pipe(pipe_class_default); 15521 %} 15522 15523 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15524 %{ 15525 match(Set dst (MulReductionVI src1 src2)); 15526 ins_cost(INSN_COST); 15527 effect(TEMP tmp, TEMP dst); 15528 format %{ "umov $tmp, $src2, S, 0\n\t" 15529 "mul $dst, $tmp, $src1\n\t" 15530 "umov $tmp, $src2, S, 1\n\t" 15531 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15532 %} 15533 ins_encode %{ 15534 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15535 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15536 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15537 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15538 %} 15539 ins_pipe(pipe_class_default); 15540 %} 15541 15542 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15543 %{ 15544 match(Set dst (MulReductionVI src1 src2)); 15545 ins_cost(INSN_COST); 15546 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15547 format %{ "ins $tmp, $src2, 0, 1\n\t" 15548 "mul $tmp, $tmp, $src2\n\t" 15549 "umov $tmp2, $tmp, S, 0\n\t" 15550 "mul $dst, $tmp2, $src1\n\t" 15551 "umov $tmp2, $tmp, S, 1\n\t" 15552 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15553 %} 15554 ins_encode %{ 15555 __ ins(as_FloatRegister($tmp$$reg), __ D, 15556 as_FloatRegister($src2$$reg), 0, 1); 15557 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15558 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15559 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15560 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15561 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15562 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15563 %} 15564 ins_pipe(pipe_class_default); 15565 %} 15566 15567 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15568 %{ 15569 match(Set dst (AddReductionVF src1 src2)); 15570 ins_cost(INSN_COST); 15571 effect(TEMP tmp, TEMP dst); 15572 format %{ "fadds $dst, $src1, $src2\n\t" 15573 "ins $tmp, S, $src2, 0, 1\n\t" 15574 "fadds $dst, $dst, $tmp\t add reduction2f" 15575 %} 15576 ins_encode %{ 15577 __ fadds(as_FloatRegister($dst$$reg), 15578 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15579 __ ins(as_FloatRegister($tmp$$reg), __ S, 15580 as_FloatRegister($src2$$reg), 0, 1); 15581 __ fadds(as_FloatRegister($dst$$reg), 15582 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15583 %} 15584 ins_pipe(pipe_class_default); 15585 %} 15586 15587 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15588 %{ 15589 match(Set dst (AddReductionVF src1 src2)); 15590 ins_cost(INSN_COST); 15591 effect(TEMP tmp, TEMP dst); 15592 format %{ "fadds $dst, $src1, $src2\n\t" 15593 "ins $tmp, S, $src2, 0, 1\n\t" 15594 "fadds $dst, $dst, $tmp\n\t" 15595 "ins $tmp, S, $src2, 0, 2\n\t" 15596 "fadds $dst, $dst, $tmp\n\t" 15597 "ins $tmp, S, $src2, 0, 3\n\t" 15598 "fadds $dst, $dst, $tmp\t add reduction4f" 15599 %} 15600 ins_encode %{ 15601 __ fadds(as_FloatRegister($dst$$reg), 15602 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15603 __ ins(as_FloatRegister($tmp$$reg), __ S, 15604 as_FloatRegister($src2$$reg), 0, 1); 15605 __ fadds(as_FloatRegister($dst$$reg), 15606 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15607 __ ins(as_FloatRegister($tmp$$reg), __ S, 15608 as_FloatRegister($src2$$reg), 0, 2); 15609 __ fadds(as_FloatRegister($dst$$reg), 15610 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15611 __ ins(as_FloatRegister($tmp$$reg), __ S, 15612 as_FloatRegister($src2$$reg), 0, 3); 15613 __ fadds(as_FloatRegister($dst$$reg), 15614 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15615 %} 15616 ins_pipe(pipe_class_default); 15617 %} 15618 15619 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15620 %{ 15621 match(Set dst (MulReductionVF src1 src2)); 15622 ins_cost(INSN_COST); 15623 effect(TEMP tmp, TEMP dst); 15624 format %{ "fmuls $dst, $src1, $src2\n\t" 15625 "ins $tmp, S, $src2, 0, 1\n\t" 15626 "fmuls $dst, $dst, $tmp\t add reduction4f" 15627 %} 15628 ins_encode %{ 15629 __ fmuls(as_FloatRegister($dst$$reg), 15630 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15631 __ ins(as_FloatRegister($tmp$$reg), __ S, 15632 as_FloatRegister($src2$$reg), 0, 1); 15633 __ fmuls(as_FloatRegister($dst$$reg), 15634 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15635 %} 15636 ins_pipe(pipe_class_default); 15637 %} 15638 15639 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15640 %{ 15641 match(Set dst (MulReductionVF src1 src2)); 15642 ins_cost(INSN_COST); 15643 effect(TEMP tmp, TEMP dst); 15644 format %{ "fmuls $dst, $src1, $src2\n\t" 15645 "ins $tmp, S, $src2, 0, 1\n\t" 15646 "fmuls $dst, $dst, $tmp\n\t" 15647 "ins $tmp, S, $src2, 0, 2\n\t" 15648 "fmuls $dst, $dst, $tmp\n\t" 15649 "ins $tmp, S, $src2, 0, 3\n\t" 15650 "fmuls $dst, $dst, $tmp\t add reduction4f" 15651 %} 15652 ins_encode %{ 15653 __ fmuls(as_FloatRegister($dst$$reg), 15654 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15655 __ ins(as_FloatRegister($tmp$$reg), __ S, 15656 as_FloatRegister($src2$$reg), 0, 1); 15657 __ fmuls(as_FloatRegister($dst$$reg), 15658 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15659 __ ins(as_FloatRegister($tmp$$reg), __ S, 15660 as_FloatRegister($src2$$reg), 0, 2); 15661 __ fmuls(as_FloatRegister($dst$$reg), 15662 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15663 __ ins(as_FloatRegister($tmp$$reg), __ S, 15664 as_FloatRegister($src2$$reg), 0, 3); 15665 __ fmuls(as_FloatRegister($dst$$reg), 15666 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15667 %} 15668 ins_pipe(pipe_class_default); 15669 %} 15670 15671 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15672 %{ 15673 match(Set dst (AddReductionVD src1 src2)); 15674 ins_cost(INSN_COST); 15675 effect(TEMP tmp, TEMP dst); 15676 format %{ "faddd $dst, $src1, $src2\n\t" 15677 "ins $tmp, D, $src2, 0, 1\n\t" 15678 "faddd $dst, $dst, $tmp\t add reduction2d" 15679 %} 15680 ins_encode %{ 15681 __ faddd(as_FloatRegister($dst$$reg), 15682 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15683 __ ins(as_FloatRegister($tmp$$reg), __ D, 15684 as_FloatRegister($src2$$reg), 0, 1); 15685 __ faddd(as_FloatRegister($dst$$reg), 15686 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15687 %} 15688 ins_pipe(pipe_class_default); 15689 %} 15690 15691 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15692 %{ 15693 match(Set dst (MulReductionVD src1 src2)); 15694 ins_cost(INSN_COST); 15695 effect(TEMP tmp, TEMP dst); 15696 format %{ "fmuld $dst, $src1, $src2\n\t" 15697 "ins $tmp, D, $src2, 0, 1\n\t" 15698 "fmuld $dst, $dst, $tmp\t add reduction2d" 15699 %} 15700 ins_encode %{ 15701 __ fmuld(as_FloatRegister($dst$$reg), 15702 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15703 __ ins(as_FloatRegister($tmp$$reg), __ D, 15704 as_FloatRegister($src2$$reg), 0, 1); 15705 __ fmuld(as_FloatRegister($dst$$reg), 15706 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15707 %} 15708 ins_pipe(pipe_class_default); 15709 %} 15710 15711 // ====================VECTOR ARITHMETIC======================================= 15712 15713 // --------------------------------- ADD -------------------------------------- 15714 15715 instruct vadd8B(vecD dst, vecD src1, vecD src2) 15716 %{ 15717 predicate(n->as_Vector()->length() == 4 || 15718 n->as_Vector()->length() == 8); 15719 match(Set dst (AddVB src1 src2)); 15720 ins_cost(INSN_COST); 15721 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 15722 ins_encode %{ 15723 __ addv(as_FloatRegister($dst$$reg), __ T8B, 15724 as_FloatRegister($src1$$reg), 15725 as_FloatRegister($src2$$reg)); 15726 %} 15727 ins_pipe(vdop64); 15728 %} 15729 15730 instruct vadd16B(vecX dst, vecX src1, vecX src2) 15731 %{ 15732 predicate(n->as_Vector()->length() == 16); 15733 match(Set dst (AddVB src1 src2)); 15734 ins_cost(INSN_COST); 15735 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 15736 ins_encode %{ 15737 __ addv(as_FloatRegister($dst$$reg), __ T16B, 15738 as_FloatRegister($src1$$reg), 15739 as_FloatRegister($src2$$reg)); 15740 %} 15741 ins_pipe(vdop128); 15742 %} 15743 15744 instruct vadd4S(vecD dst, vecD src1, vecD src2) 15745 %{ 15746 predicate(n->as_Vector()->length() == 2 || 15747 n->as_Vector()->length() == 4); 15748 match(Set dst (AddVS src1 src2)); 15749 ins_cost(INSN_COST); 15750 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 15751 ins_encode %{ 15752 __ addv(as_FloatRegister($dst$$reg), __ T4H, 15753 as_FloatRegister($src1$$reg), 15754 as_FloatRegister($src2$$reg)); 15755 %} 15756 ins_pipe(vdop64); 15757 %} 15758 15759 instruct vadd8S(vecX dst, vecX src1, vecX src2) 15760 %{ 15761 predicate(n->as_Vector()->length() == 8); 15762 match(Set dst (AddVS src1 src2)); 15763 ins_cost(INSN_COST); 15764 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 15765 ins_encode %{ 15766 __ addv(as_FloatRegister($dst$$reg), __ T8H, 15767 as_FloatRegister($src1$$reg), 15768 as_FloatRegister($src2$$reg)); 15769 %} 15770 ins_pipe(vdop128); 15771 %} 15772 15773 instruct vadd2I(vecD dst, vecD src1, vecD src2) 15774 %{ 15775 predicate(n->as_Vector()->length() == 2); 15776 match(Set dst (AddVI src1 src2)); 15777 ins_cost(INSN_COST); 15778 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 15779 ins_encode %{ 15780 __ addv(as_FloatRegister($dst$$reg), __ T2S, 15781 as_FloatRegister($src1$$reg), 15782 as_FloatRegister($src2$$reg)); 15783 %} 15784 ins_pipe(vdop64); 15785 %} 15786 15787 instruct vadd4I(vecX dst, vecX src1, vecX src2) 15788 %{ 15789 predicate(n->as_Vector()->length() == 4); 15790 match(Set dst (AddVI src1 src2)); 15791 ins_cost(INSN_COST); 15792 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 15793 ins_encode %{ 15794 __ addv(as_FloatRegister($dst$$reg), __ T4S, 15795 as_FloatRegister($src1$$reg), 15796 as_FloatRegister($src2$$reg)); 15797 %} 15798 ins_pipe(vdop128); 15799 %} 15800 15801 instruct vadd2L(vecX dst, vecX src1, vecX src2) 15802 %{ 15803 predicate(n->as_Vector()->length() == 2); 15804 match(Set dst (AddVL src1 src2)); 15805 ins_cost(INSN_COST); 15806 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 15807 ins_encode %{ 15808 __ addv(as_FloatRegister($dst$$reg), __ T2D, 15809 as_FloatRegister($src1$$reg), 15810 as_FloatRegister($src2$$reg)); 15811 %} 15812 ins_pipe(vdop128); 15813 %} 15814 15815 instruct vadd2F(vecD dst, vecD src1, vecD src2) 15816 %{ 15817 predicate(n->as_Vector()->length() == 2); 15818 match(Set dst (AddVF src1 src2)); 15819 ins_cost(INSN_COST); 15820 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 15821 ins_encode %{ 15822 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 15823 as_FloatRegister($src1$$reg), 15824 as_FloatRegister($src2$$reg)); 15825 %} 15826 ins_pipe(vdop_fp64); 15827 %} 15828 15829 instruct vadd4F(vecX dst, vecX src1, vecX src2) 15830 %{ 15831 predicate(n->as_Vector()->length() == 4); 15832 match(Set dst (AddVF src1 src2)); 15833 ins_cost(INSN_COST); 15834 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 15835 ins_encode %{ 15836 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 15837 as_FloatRegister($src1$$reg), 15838 as_FloatRegister($src2$$reg)); 15839 %} 15840 ins_pipe(vdop_fp128); 15841 %} 15842 15843 instruct vadd2D(vecX dst, vecX src1, vecX src2) 15844 %{ 15845 match(Set dst (AddVD src1 src2)); 15846 ins_cost(INSN_COST); 15847 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 15848 ins_encode %{ 15849 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 15850 as_FloatRegister($src1$$reg), 15851 as_FloatRegister($src2$$reg)); 15852 %} 15853 ins_pipe(vdop_fp128); 15854 %} 15855 15856 // --------------------------------- SUB -------------------------------------- 15857 15858 instruct vsub8B(vecD dst, vecD src1, vecD src2) 15859 %{ 15860 predicate(n->as_Vector()->length() == 4 || 15861 n->as_Vector()->length() == 8); 15862 match(Set dst (SubVB src1 src2)); 15863 ins_cost(INSN_COST); 15864 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 15865 ins_encode %{ 15866 __ subv(as_FloatRegister($dst$$reg), __ T8B, 15867 as_FloatRegister($src1$$reg), 15868 as_FloatRegister($src2$$reg)); 15869 %} 15870 ins_pipe(vdop64); 15871 %} 15872 15873 instruct vsub16B(vecX dst, vecX src1, vecX src2) 15874 %{ 15875 predicate(n->as_Vector()->length() == 16); 15876 match(Set dst (SubVB src1 src2)); 15877 ins_cost(INSN_COST); 15878 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 15879 ins_encode %{ 15880 __ subv(as_FloatRegister($dst$$reg), __ T16B, 15881 as_FloatRegister($src1$$reg), 15882 as_FloatRegister($src2$$reg)); 15883 %} 15884 ins_pipe(vdop128); 15885 %} 15886 15887 instruct vsub4S(vecD dst, vecD src1, vecD src2) 15888 %{ 15889 predicate(n->as_Vector()->length() == 2 || 15890 n->as_Vector()->length() == 4); 15891 match(Set dst (SubVS src1 src2)); 15892 ins_cost(INSN_COST); 15893 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 15894 ins_encode %{ 15895 __ subv(as_FloatRegister($dst$$reg), __ T4H, 15896 as_FloatRegister($src1$$reg), 15897 as_FloatRegister($src2$$reg)); 15898 %} 15899 ins_pipe(vdop64); 15900 %} 15901 15902 instruct vsub8S(vecX dst, vecX src1, vecX src2) 15903 %{ 15904 predicate(n->as_Vector()->length() == 8); 15905 match(Set dst (SubVS src1 src2)); 15906 ins_cost(INSN_COST); 15907 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 15908 ins_encode %{ 15909 __ subv(as_FloatRegister($dst$$reg), __ T8H, 15910 as_FloatRegister($src1$$reg), 15911 as_FloatRegister($src2$$reg)); 15912 %} 15913 ins_pipe(vdop128); 15914 %} 15915 15916 instruct vsub2I(vecD dst, vecD src1, vecD src2) 15917 %{ 15918 predicate(n->as_Vector()->length() == 2); 15919 match(Set dst (SubVI src1 src2)); 15920 ins_cost(INSN_COST); 15921 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 15922 ins_encode %{ 15923 __ subv(as_FloatRegister($dst$$reg), __ T2S, 15924 as_FloatRegister($src1$$reg), 15925 as_FloatRegister($src2$$reg)); 15926 %} 15927 ins_pipe(vdop64); 15928 %} 15929 15930 instruct vsub4I(vecX dst, vecX src1, vecX src2) 15931 %{ 15932 predicate(n->as_Vector()->length() == 4); 15933 match(Set dst (SubVI src1 src2)); 15934 ins_cost(INSN_COST); 15935 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 15936 ins_encode %{ 15937 __ subv(as_FloatRegister($dst$$reg), __ T4S, 15938 as_FloatRegister($src1$$reg), 15939 as_FloatRegister($src2$$reg)); 15940 %} 15941 ins_pipe(vdop128); 15942 %} 15943 15944 instruct vsub2L(vecX dst, vecX src1, vecX src2) 15945 %{ 15946 predicate(n->as_Vector()->length() == 2); 15947 match(Set dst (SubVL src1 src2)); 15948 ins_cost(INSN_COST); 15949 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 15950 ins_encode %{ 15951 __ subv(as_FloatRegister($dst$$reg), __ T2D, 15952 as_FloatRegister($src1$$reg), 15953 as_FloatRegister($src2$$reg)); 15954 %} 15955 ins_pipe(vdop128); 15956 %} 15957 15958 instruct vsub2F(vecD dst, vecD src1, vecD src2) 15959 %{ 15960 predicate(n->as_Vector()->length() == 2); 15961 match(Set dst (SubVF src1 src2)); 15962 ins_cost(INSN_COST); 15963 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 15964 ins_encode %{ 15965 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 15966 as_FloatRegister($src1$$reg), 15967 as_FloatRegister($src2$$reg)); 15968 %} 15969 ins_pipe(vdop_fp64); 15970 %} 15971 15972 instruct vsub4F(vecX dst, vecX src1, vecX src2) 15973 %{ 15974 predicate(n->as_Vector()->length() == 4); 15975 match(Set dst (SubVF src1 src2)); 15976 ins_cost(INSN_COST); 15977 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 15978 ins_encode %{ 15979 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 15980 as_FloatRegister($src1$$reg), 15981 as_FloatRegister($src2$$reg)); 15982 %} 15983 ins_pipe(vdop_fp128); 15984 %} 15985 15986 instruct vsub2D(vecX dst, vecX src1, vecX src2) 15987 %{ 15988 predicate(n->as_Vector()->length() == 2); 15989 match(Set dst (SubVD src1 src2)); 15990 ins_cost(INSN_COST); 15991 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 15992 ins_encode %{ 15993 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 15994 as_FloatRegister($src1$$reg), 15995 as_FloatRegister($src2$$reg)); 15996 %} 15997 ins_pipe(vdop_fp128); 15998 %} 15999 16000 // --------------------------------- MUL -------------------------------------- 16001 16002 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16003 %{ 16004 predicate(n->as_Vector()->length() == 2 || 16005 n->as_Vector()->length() == 4); 16006 match(Set dst (MulVS src1 src2)); 16007 ins_cost(INSN_COST); 16008 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16009 ins_encode %{ 16010 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16011 as_FloatRegister($src1$$reg), 16012 as_FloatRegister($src2$$reg)); 16013 %} 16014 ins_pipe(vmul64); 16015 %} 16016 16017 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16018 %{ 16019 predicate(n->as_Vector()->length() == 8); 16020 match(Set dst (MulVS src1 src2)); 16021 ins_cost(INSN_COST); 16022 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16023 ins_encode %{ 16024 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16025 as_FloatRegister($src1$$reg), 16026 as_FloatRegister($src2$$reg)); 16027 %} 16028 ins_pipe(vmul128); 16029 %} 16030 16031 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16032 %{ 16033 predicate(n->as_Vector()->length() == 2); 16034 match(Set dst (MulVI src1 src2)); 16035 ins_cost(INSN_COST); 16036 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16037 ins_encode %{ 16038 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16039 as_FloatRegister($src1$$reg), 16040 as_FloatRegister($src2$$reg)); 16041 %} 16042 ins_pipe(vmul64); 16043 %} 16044 16045 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16046 %{ 16047 predicate(n->as_Vector()->length() == 4); 16048 match(Set dst (MulVI src1 src2)); 16049 ins_cost(INSN_COST); 16050 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16051 ins_encode %{ 16052 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16053 as_FloatRegister($src1$$reg), 16054 as_FloatRegister($src2$$reg)); 16055 %} 16056 ins_pipe(vmul128); 16057 %} 16058 16059 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16060 %{ 16061 predicate(n->as_Vector()->length() == 2); 16062 match(Set dst (MulVF src1 src2)); 16063 ins_cost(INSN_COST); 16064 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16065 ins_encode %{ 16066 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16067 as_FloatRegister($src1$$reg), 16068 as_FloatRegister($src2$$reg)); 16069 %} 16070 ins_pipe(vmuldiv_fp64); 16071 %} 16072 16073 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16074 %{ 16075 predicate(n->as_Vector()->length() == 4); 16076 match(Set dst (MulVF src1 src2)); 16077 ins_cost(INSN_COST); 16078 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16079 ins_encode %{ 16080 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16081 as_FloatRegister($src1$$reg), 16082 as_FloatRegister($src2$$reg)); 16083 %} 16084 ins_pipe(vmuldiv_fp128); 16085 %} 16086 16087 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16088 %{ 16089 predicate(n->as_Vector()->length() == 2); 16090 match(Set dst (MulVD src1 src2)); 16091 ins_cost(INSN_COST); 16092 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16093 ins_encode %{ 16094 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16095 as_FloatRegister($src1$$reg), 16096 as_FloatRegister($src2$$reg)); 16097 %} 16098 ins_pipe(vmuldiv_fp128); 16099 %} 16100 16101 // --------------------------------- MLA -------------------------------------- 16102 16103 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16104 %{ 16105 predicate(n->as_Vector()->length() == 2 || 16106 n->as_Vector()->length() == 4); 16107 match(Set dst (AddVS dst (MulVS src1 src2))); 16108 ins_cost(INSN_COST); 16109 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16110 ins_encode %{ 16111 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16112 as_FloatRegister($src1$$reg), 16113 as_FloatRegister($src2$$reg)); 16114 %} 16115 ins_pipe(vmla64); 16116 %} 16117 16118 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16119 %{ 16120 predicate(n->as_Vector()->length() == 8); 16121 match(Set dst (AddVS dst (MulVS src1 src2))); 16122 ins_cost(INSN_COST); 16123 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16124 ins_encode %{ 16125 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16126 as_FloatRegister($src1$$reg), 16127 as_FloatRegister($src2$$reg)); 16128 %} 16129 ins_pipe(vmla128); 16130 %} 16131 16132 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16133 %{ 16134 predicate(n->as_Vector()->length() == 2); 16135 match(Set dst (AddVI dst (MulVI src1 src2))); 16136 ins_cost(INSN_COST); 16137 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16138 ins_encode %{ 16139 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16140 as_FloatRegister($src1$$reg), 16141 as_FloatRegister($src2$$reg)); 16142 %} 16143 ins_pipe(vmla64); 16144 %} 16145 16146 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16147 %{ 16148 predicate(n->as_Vector()->length() == 4); 16149 match(Set dst (AddVI dst (MulVI src1 src2))); 16150 ins_cost(INSN_COST); 16151 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16152 ins_encode %{ 16153 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16154 as_FloatRegister($src1$$reg), 16155 as_FloatRegister($src2$$reg)); 16156 %} 16157 ins_pipe(vmla128); 16158 %} 16159 16160 // dst + src1 * src2 16161 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16162 predicate(UseFMA && n->as_Vector()->length() == 2); 16163 match(Set dst (FmaVF dst (Binary src1 src2))); 16164 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16165 ins_cost(INSN_COST); 16166 ins_encode %{ 16167 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16168 as_FloatRegister($src1$$reg), 16169 as_FloatRegister($src2$$reg)); 16170 %} 16171 ins_pipe(vmuldiv_fp64); 16172 %} 16173 16174 // dst + src1 * src2 16175 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16176 predicate(UseFMA && n->as_Vector()->length() == 4); 16177 match(Set dst (FmaVF dst (Binary src1 src2))); 16178 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16179 ins_cost(INSN_COST); 16180 ins_encode %{ 16181 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16182 as_FloatRegister($src1$$reg), 16183 as_FloatRegister($src2$$reg)); 16184 %} 16185 ins_pipe(vmuldiv_fp128); 16186 %} 16187 16188 // dst + src1 * src2 16189 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16190 predicate(UseFMA && n->as_Vector()->length() == 2); 16191 match(Set dst (FmaVD dst (Binary src1 src2))); 16192 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16193 ins_cost(INSN_COST); 16194 ins_encode %{ 16195 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16196 as_FloatRegister($src1$$reg), 16197 as_FloatRegister($src2$$reg)); 16198 %} 16199 ins_pipe(vmuldiv_fp128); 16200 %} 16201 16202 // --------------------------------- MLS -------------------------------------- 16203 16204 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16205 %{ 16206 predicate(n->as_Vector()->length() == 2 || 16207 n->as_Vector()->length() == 4); 16208 match(Set dst (SubVS dst (MulVS src1 src2))); 16209 ins_cost(INSN_COST); 16210 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16211 ins_encode %{ 16212 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16213 as_FloatRegister($src1$$reg), 16214 as_FloatRegister($src2$$reg)); 16215 %} 16216 ins_pipe(vmla64); 16217 %} 16218 16219 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16220 %{ 16221 predicate(n->as_Vector()->length() == 8); 16222 match(Set dst (SubVS dst (MulVS src1 src2))); 16223 ins_cost(INSN_COST); 16224 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16225 ins_encode %{ 16226 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16227 as_FloatRegister($src1$$reg), 16228 as_FloatRegister($src2$$reg)); 16229 %} 16230 ins_pipe(vmla128); 16231 %} 16232 16233 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16234 %{ 16235 predicate(n->as_Vector()->length() == 2); 16236 match(Set dst (SubVI dst (MulVI src1 src2))); 16237 ins_cost(INSN_COST); 16238 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16239 ins_encode %{ 16240 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16241 as_FloatRegister($src1$$reg), 16242 as_FloatRegister($src2$$reg)); 16243 %} 16244 ins_pipe(vmla64); 16245 %} 16246 16247 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16248 %{ 16249 predicate(n->as_Vector()->length() == 4); 16250 match(Set dst (SubVI dst (MulVI src1 src2))); 16251 ins_cost(INSN_COST); 16252 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16253 ins_encode %{ 16254 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16255 as_FloatRegister($src1$$reg), 16256 as_FloatRegister($src2$$reg)); 16257 %} 16258 ins_pipe(vmla128); 16259 %} 16260 16261 // dst - src1 * src2 16262 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16263 predicate(UseFMA && n->as_Vector()->length() == 2); 16264 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16265 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16266 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16267 ins_cost(INSN_COST); 16268 ins_encode %{ 16269 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16270 as_FloatRegister($src1$$reg), 16271 as_FloatRegister($src2$$reg)); 16272 %} 16273 ins_pipe(vmuldiv_fp64); 16274 %} 16275 16276 // dst - src1 * src2 16277 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16278 predicate(UseFMA && n->as_Vector()->length() == 4); 16279 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16280 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16281 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16282 ins_cost(INSN_COST); 16283 ins_encode %{ 16284 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16285 as_FloatRegister($src1$$reg), 16286 as_FloatRegister($src2$$reg)); 16287 %} 16288 ins_pipe(vmuldiv_fp128); 16289 %} 16290 16291 // dst - src1 * src2 16292 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16293 predicate(UseFMA && n->as_Vector()->length() == 2); 16294 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16295 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16296 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16297 ins_cost(INSN_COST); 16298 ins_encode %{ 16299 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16300 as_FloatRegister($src1$$reg), 16301 as_FloatRegister($src2$$reg)); 16302 %} 16303 ins_pipe(vmuldiv_fp128); 16304 %} 16305 16306 // --------------------------------- DIV -------------------------------------- 16307 16308 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16309 %{ 16310 predicate(n->as_Vector()->length() == 2); 16311 match(Set dst (DivVF src1 src2)); 16312 ins_cost(INSN_COST); 16313 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16314 ins_encode %{ 16315 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16316 as_FloatRegister($src1$$reg), 16317 as_FloatRegister($src2$$reg)); 16318 %} 16319 ins_pipe(vmuldiv_fp64); 16320 %} 16321 16322 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16323 %{ 16324 predicate(n->as_Vector()->length() == 4); 16325 match(Set dst (DivVF src1 src2)); 16326 ins_cost(INSN_COST); 16327 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16328 ins_encode %{ 16329 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16330 as_FloatRegister($src1$$reg), 16331 as_FloatRegister($src2$$reg)); 16332 %} 16333 ins_pipe(vmuldiv_fp128); 16334 %} 16335 16336 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 16337 %{ 16338 predicate(n->as_Vector()->length() == 2); 16339 match(Set dst (DivVD src1 src2)); 16340 ins_cost(INSN_COST); 16341 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 16342 ins_encode %{ 16343 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 16344 as_FloatRegister($src1$$reg), 16345 as_FloatRegister($src2$$reg)); 16346 %} 16347 ins_pipe(vmuldiv_fp128); 16348 %} 16349 16350 // --------------------------------- SQRT ------------------------------------- 16351 16352 instruct vsqrt2D(vecX dst, vecX src) 16353 %{ 16354 predicate(n->as_Vector()->length() == 2); 16355 match(Set dst (SqrtVD src)); 16356 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 16357 ins_encode %{ 16358 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 16359 as_FloatRegister($src$$reg)); 16360 %} 16361 ins_pipe(vsqrt_fp128); 16362 %} 16363 16364 // --------------------------------- ABS -------------------------------------- 16365 16366 instruct vabs2F(vecD dst, vecD src) 16367 %{ 16368 predicate(n->as_Vector()->length() == 2); 16369 match(Set dst (AbsVF src)); 16370 ins_cost(INSN_COST * 3); 16371 format %{ "fabs $dst,$src\t# vector (2S)" %} 16372 ins_encode %{ 16373 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 16374 as_FloatRegister($src$$reg)); 16375 %} 16376 ins_pipe(vunop_fp64); 16377 %} 16378 16379 instruct vabs4F(vecX dst, vecX src) 16380 %{ 16381 predicate(n->as_Vector()->length() == 4); 16382 match(Set dst (AbsVF src)); 16383 ins_cost(INSN_COST * 3); 16384 format %{ "fabs $dst,$src\t# vector (4S)" %} 16385 ins_encode %{ 16386 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16387 as_FloatRegister($src$$reg)); 16388 %} 16389 ins_pipe(vunop_fp128); 16390 %} 16391 16392 instruct vabs2D(vecX dst, vecX src) 16393 %{ 16394 predicate(n->as_Vector()->length() == 2); 16395 match(Set dst (AbsVD src)); 16396 ins_cost(INSN_COST * 3); 16397 format %{ "fabs $dst,$src\t# vector (2D)" %} 16398 ins_encode %{ 16399 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 16400 as_FloatRegister($src$$reg)); 16401 %} 16402 ins_pipe(vunop_fp128); 16403 %} 16404 16405 // --------------------------------- NEG -------------------------------------- 16406 16407 instruct vneg2F(vecD dst, vecD src) 16408 %{ 16409 predicate(n->as_Vector()->length() == 2); 16410 match(Set dst (NegVF src)); 16411 ins_cost(INSN_COST * 3); 16412 format %{ "fneg $dst,$src\t# vector (2S)" %} 16413 ins_encode %{ 16414 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 16415 as_FloatRegister($src$$reg)); 16416 %} 16417 ins_pipe(vunop_fp64); 16418 %} 16419 16420 instruct vneg4F(vecX dst, vecX src) 16421 %{ 16422 predicate(n->as_Vector()->length() == 4); 16423 match(Set dst (NegVF src)); 16424 ins_cost(INSN_COST * 3); 16425 format %{ "fneg $dst,$src\t# vector (4S)" %} 16426 ins_encode %{ 16427 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16428 as_FloatRegister($src$$reg)); 16429 %} 16430 ins_pipe(vunop_fp128); 16431 %} 16432 16433 instruct vneg2D(vecX dst, vecX src) 16434 %{ 16435 predicate(n->as_Vector()->length() == 2); 16436 match(Set dst (NegVD src)); 16437 ins_cost(INSN_COST * 3); 16438 format %{ "fneg $dst,$src\t# vector (2D)" %} 16439 ins_encode %{ 16440 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16441 as_FloatRegister($src$$reg)); 16442 %} 16443 ins_pipe(vunop_fp128); 16444 %} 16445 16446 // --------------------------------- AND -------------------------------------- 16447 16448 instruct vand8B(vecD dst, vecD src1, vecD src2) 16449 %{ 16450 predicate(n->as_Vector()->length_in_bytes() == 4 || 16451 n->as_Vector()->length_in_bytes() == 8); 16452 match(Set dst (AndV src1 src2)); 16453 ins_cost(INSN_COST); 16454 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16455 ins_encode %{ 16456 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16457 as_FloatRegister($src1$$reg), 16458 as_FloatRegister($src2$$reg)); 16459 %} 16460 ins_pipe(vlogical64); 16461 %} 16462 16463 instruct vand16B(vecX dst, vecX src1, vecX src2) 16464 %{ 16465 predicate(n->as_Vector()->length_in_bytes() == 16); 16466 match(Set dst (AndV src1 src2)); 16467 ins_cost(INSN_COST); 16468 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16469 ins_encode %{ 16470 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16471 as_FloatRegister($src1$$reg), 16472 as_FloatRegister($src2$$reg)); 16473 %} 16474 ins_pipe(vlogical128); 16475 %} 16476 16477 // --------------------------------- OR --------------------------------------- 16478 16479 instruct vor8B(vecD dst, vecD src1, vecD src2) 16480 %{ 16481 predicate(n->as_Vector()->length_in_bytes() == 4 || 16482 n->as_Vector()->length_in_bytes() == 8); 16483 match(Set dst (OrV src1 src2)); 16484 ins_cost(INSN_COST); 16485 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16486 ins_encode %{ 16487 __ orr(as_FloatRegister($dst$$reg), __ T8B, 16488 as_FloatRegister($src1$$reg), 16489 as_FloatRegister($src2$$reg)); 16490 %} 16491 ins_pipe(vlogical64); 16492 %} 16493 16494 instruct vor16B(vecX dst, vecX src1, vecX src2) 16495 %{ 16496 predicate(n->as_Vector()->length_in_bytes() == 16); 16497 match(Set dst (OrV src1 src2)); 16498 ins_cost(INSN_COST); 16499 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 16500 ins_encode %{ 16501 __ orr(as_FloatRegister($dst$$reg), __ T16B, 16502 as_FloatRegister($src1$$reg), 16503 as_FloatRegister($src2$$reg)); 16504 %} 16505 ins_pipe(vlogical128); 16506 %} 16507 16508 // --------------------------------- XOR -------------------------------------- 16509 16510 instruct vxor8B(vecD dst, vecD src1, vecD src2) 16511 %{ 16512 predicate(n->as_Vector()->length_in_bytes() == 4 || 16513 n->as_Vector()->length_in_bytes() == 8); 16514 match(Set dst (XorV src1 src2)); 16515 ins_cost(INSN_COST); 16516 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 16517 ins_encode %{ 16518 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16519 as_FloatRegister($src1$$reg), 16520 as_FloatRegister($src2$$reg)); 16521 %} 16522 ins_pipe(vlogical64); 16523 %} 16524 16525 instruct vxor16B(vecX dst, vecX src1, vecX src2) 16526 %{ 16527 predicate(n->as_Vector()->length_in_bytes() == 16); 16528 match(Set dst (XorV src1 src2)); 16529 ins_cost(INSN_COST); 16530 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 16531 ins_encode %{ 16532 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16533 as_FloatRegister($src1$$reg), 16534 as_FloatRegister($src2$$reg)); 16535 %} 16536 ins_pipe(vlogical128); 16537 %} 16538 16539 // ------------------------------ Shift --------------------------------------- 16540 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 16541 predicate(n->as_Vector()->length_in_bytes() == 8); 16542 match(Set dst (LShiftCntV cnt)); 16543 match(Set dst (RShiftCntV cnt)); 16544 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 16545 ins_encode %{ 16546 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 16547 %} 16548 ins_pipe(vdup_reg_reg64); 16549 %} 16550 16551 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 16552 predicate(n->as_Vector()->length_in_bytes() == 16); 16553 match(Set dst (LShiftCntV cnt)); 16554 match(Set dst (RShiftCntV cnt)); 16555 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 16556 ins_encode %{ 16557 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16558 %} 16559 ins_pipe(vdup_reg_reg128); 16560 %} 16561 16562 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 16563 predicate(n->as_Vector()->length() == 4 || 16564 n->as_Vector()->length() == 8); 16565 match(Set dst (LShiftVB src shift)); 16566 ins_cost(INSN_COST); 16567 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 16568 ins_encode %{ 16569 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16570 as_FloatRegister($src$$reg), 16571 as_FloatRegister($shift$$reg)); 16572 %} 16573 ins_pipe(vshift64); 16574 %} 16575 16576 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 16577 predicate(n->as_Vector()->length() == 16); 16578 match(Set dst (LShiftVB src shift)); 16579 ins_cost(INSN_COST); 16580 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 16581 ins_encode %{ 16582 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16583 as_FloatRegister($src$$reg), 16584 as_FloatRegister($shift$$reg)); 16585 %} 16586 ins_pipe(vshift128); 16587 %} 16588 16589 // Right shifts with vector shift count on aarch64 SIMD are implemented 16590 // as left shift by negative shift count. 16591 // There are two cases for vector shift count. 16592 // 16593 // Case 1: The vector shift count is from replication. 16594 // | | 16595 // LoadVector RShiftCntV 16596 // | / 16597 // RShiftVI 16598 // Note: In inner loop, multiple neg instructions are used, which can be 16599 // moved to outer loop and merge into one neg instruction. 16600 // 16601 // Case 2: The vector shift count is from loading. 16602 // This case isn't supported by middle-end now. But it's supported by 16603 // panama/vectorIntrinsics(JEP 338: Vector API). 16604 // | | 16605 // LoadVector LoadVector 16606 // | / 16607 // RShiftVI 16608 // 16609 16610 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16611 predicate(n->as_Vector()->length() == 4 || 16612 n->as_Vector()->length() == 8); 16613 match(Set dst (RShiftVB src shift)); 16614 ins_cost(INSN_COST); 16615 effect(TEMP tmp); 16616 format %{ "negr $tmp,$shift\t" 16617 "sshl $dst,$src,$tmp\t# vector (8B)" %} 16618 ins_encode %{ 16619 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16620 as_FloatRegister($shift$$reg)); 16621 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16622 as_FloatRegister($src$$reg), 16623 as_FloatRegister($tmp$$reg)); 16624 %} 16625 ins_pipe(vshift64); 16626 %} 16627 16628 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16629 predicate(n->as_Vector()->length() == 16); 16630 match(Set dst (RShiftVB src shift)); 16631 ins_cost(INSN_COST); 16632 effect(TEMP tmp); 16633 format %{ "negr $tmp,$shift\t" 16634 "sshl $dst,$src,$tmp\t# vector (16B)" %} 16635 ins_encode %{ 16636 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16637 as_FloatRegister($shift$$reg)); 16638 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16639 as_FloatRegister($src$$reg), 16640 as_FloatRegister($tmp$$reg)); 16641 %} 16642 ins_pipe(vshift128); 16643 %} 16644 16645 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16646 predicate(n->as_Vector()->length() == 4 || 16647 n->as_Vector()->length() == 8); 16648 match(Set dst (URShiftVB src shift)); 16649 ins_cost(INSN_COST); 16650 effect(TEMP tmp); 16651 format %{ "negr $tmp,$shift\t" 16652 "ushl $dst,$src,$tmp\t# vector (8B)" %} 16653 ins_encode %{ 16654 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16655 as_FloatRegister($shift$$reg)); 16656 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 16657 as_FloatRegister($src$$reg), 16658 as_FloatRegister($tmp$$reg)); 16659 %} 16660 ins_pipe(vshift64); 16661 %} 16662 16663 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16664 predicate(n->as_Vector()->length() == 16); 16665 match(Set dst (URShiftVB src shift)); 16666 ins_cost(INSN_COST); 16667 effect(TEMP tmp); 16668 format %{ "negr $tmp,$shift\t" 16669 "ushl $dst,$src,$tmp\t# vector (16B)" %} 16670 ins_encode %{ 16671 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16672 as_FloatRegister($shift$$reg)); 16673 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 16674 as_FloatRegister($src$$reg), 16675 as_FloatRegister($tmp$$reg)); 16676 %} 16677 ins_pipe(vshift128); 16678 %} 16679 16680 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 16681 predicate(n->as_Vector()->length() == 4 || 16682 n->as_Vector()->length() == 8); 16683 match(Set dst (LShiftVB src shift)); 16684 ins_cost(INSN_COST); 16685 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 16686 ins_encode %{ 16687 int sh = (int)$shift$$constant; 16688 if (sh >= 8) { 16689 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16690 as_FloatRegister($src$$reg), 16691 as_FloatRegister($src$$reg)); 16692 } else { 16693 __ shl(as_FloatRegister($dst$$reg), __ T8B, 16694 as_FloatRegister($src$$reg), sh); 16695 } 16696 %} 16697 ins_pipe(vshift64_imm); 16698 %} 16699 16700 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 16701 predicate(n->as_Vector()->length() == 16); 16702 match(Set dst (LShiftVB src shift)); 16703 ins_cost(INSN_COST); 16704 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 16705 ins_encode %{ 16706 int sh = (int)$shift$$constant; 16707 if (sh >= 8) { 16708 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16709 as_FloatRegister($src$$reg), 16710 as_FloatRegister($src$$reg)); 16711 } else { 16712 __ shl(as_FloatRegister($dst$$reg), __ T16B, 16713 as_FloatRegister($src$$reg), sh); 16714 } 16715 %} 16716 ins_pipe(vshift128_imm); 16717 %} 16718 16719 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 16720 predicate(n->as_Vector()->length() == 4 || 16721 n->as_Vector()->length() == 8); 16722 match(Set dst (RShiftVB src shift)); 16723 ins_cost(INSN_COST); 16724 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 16725 ins_encode %{ 16726 int sh = (int)$shift$$constant; 16727 if (sh >= 8) sh = 7; 16728 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 16729 as_FloatRegister($src$$reg), sh); 16730 %} 16731 ins_pipe(vshift64_imm); 16732 %} 16733 16734 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 16735 predicate(n->as_Vector()->length() == 16); 16736 match(Set dst (RShiftVB src shift)); 16737 ins_cost(INSN_COST); 16738 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 16739 ins_encode %{ 16740 int sh = (int)$shift$$constant; 16741 if (sh >= 8) sh = 7; 16742 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 16743 as_FloatRegister($src$$reg), sh); 16744 %} 16745 ins_pipe(vshift128_imm); 16746 %} 16747 16748 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 16749 predicate(n->as_Vector()->length() == 4 || 16750 n->as_Vector()->length() == 8); 16751 match(Set dst (URShiftVB src shift)); 16752 ins_cost(INSN_COST); 16753 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 16754 ins_encode %{ 16755 int sh = (int)$shift$$constant; 16756 if (sh >= 8) { 16757 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16758 as_FloatRegister($src$$reg), 16759 as_FloatRegister($src$$reg)); 16760 } else { 16761 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 16762 as_FloatRegister($src$$reg), sh); 16763 } 16764 %} 16765 ins_pipe(vshift64_imm); 16766 %} 16767 16768 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 16769 predicate(n->as_Vector()->length() == 16); 16770 match(Set dst (URShiftVB src shift)); 16771 ins_cost(INSN_COST); 16772 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 16773 ins_encode %{ 16774 int sh = (int)$shift$$constant; 16775 if (sh >= 8) { 16776 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16777 as_FloatRegister($src$$reg), 16778 as_FloatRegister($src$$reg)); 16779 } else { 16780 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 16781 as_FloatRegister($src$$reg), sh); 16782 } 16783 %} 16784 ins_pipe(vshift128_imm); 16785 %} 16786 16787 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 16788 predicate(n->as_Vector()->length() == 2 || 16789 n->as_Vector()->length() == 4); 16790 match(Set dst (LShiftVS src shift)); 16791 ins_cost(INSN_COST); 16792 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 16793 ins_encode %{ 16794 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16795 as_FloatRegister($src$$reg), 16796 as_FloatRegister($shift$$reg)); 16797 %} 16798 ins_pipe(vshift64); 16799 %} 16800 16801 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 16802 predicate(n->as_Vector()->length() == 8); 16803 match(Set dst (LShiftVS src shift)); 16804 ins_cost(INSN_COST); 16805 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 16806 ins_encode %{ 16807 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16808 as_FloatRegister($src$$reg), 16809 as_FloatRegister($shift$$reg)); 16810 %} 16811 ins_pipe(vshift128); 16812 %} 16813 16814 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16815 predicate(n->as_Vector()->length() == 2 || 16816 n->as_Vector()->length() == 4); 16817 match(Set dst (RShiftVS src shift)); 16818 ins_cost(INSN_COST); 16819 effect(TEMP tmp); 16820 format %{ "negr $tmp,$shift\t" 16821 "sshl $dst,$src,$tmp\t# vector (4H)" %} 16822 ins_encode %{ 16823 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16824 as_FloatRegister($shift$$reg)); 16825 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16826 as_FloatRegister($src$$reg), 16827 as_FloatRegister($tmp$$reg)); 16828 %} 16829 ins_pipe(vshift64); 16830 %} 16831 16832 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16833 predicate(n->as_Vector()->length() == 8); 16834 match(Set dst (RShiftVS src shift)); 16835 ins_cost(INSN_COST); 16836 effect(TEMP tmp); 16837 format %{ "negr $tmp,$shift\t" 16838 "sshl $dst,$src,$tmp\t# vector (8H)" %} 16839 ins_encode %{ 16840 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16841 as_FloatRegister($shift$$reg)); 16842 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16843 as_FloatRegister($src$$reg), 16844 as_FloatRegister($tmp$$reg)); 16845 %} 16846 ins_pipe(vshift128); 16847 %} 16848 16849 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16850 predicate(n->as_Vector()->length() == 2 || 16851 n->as_Vector()->length() == 4); 16852 match(Set dst (URShiftVS src shift)); 16853 ins_cost(INSN_COST); 16854 effect(TEMP tmp); 16855 format %{ "negr $tmp,$shift\t" 16856 "ushl $dst,$src,$tmp\t# vector (4H)" %} 16857 ins_encode %{ 16858 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16859 as_FloatRegister($shift$$reg)); 16860 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 16861 as_FloatRegister($src$$reg), 16862 as_FloatRegister($tmp$$reg)); 16863 %} 16864 ins_pipe(vshift64); 16865 %} 16866 16867 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16868 predicate(n->as_Vector()->length() == 8); 16869 match(Set dst (URShiftVS src shift)); 16870 ins_cost(INSN_COST); 16871 effect(TEMP tmp); 16872 format %{ "negr $tmp,$shift\t" 16873 "ushl $dst,$src,$tmp\t# vector (8H)" %} 16874 ins_encode %{ 16875 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16876 as_FloatRegister($shift$$reg)); 16877 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 16878 as_FloatRegister($src$$reg), 16879 as_FloatRegister($tmp$$reg)); 16880 %} 16881 ins_pipe(vshift128); 16882 %} 16883 16884 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 16885 predicate(n->as_Vector()->length() == 2 || 16886 n->as_Vector()->length() == 4); 16887 match(Set dst (LShiftVS src shift)); 16888 ins_cost(INSN_COST); 16889 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 16890 ins_encode %{ 16891 int sh = (int)$shift$$constant; 16892 if (sh >= 16) { 16893 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16894 as_FloatRegister($src$$reg), 16895 as_FloatRegister($src$$reg)); 16896 } else { 16897 __ shl(as_FloatRegister($dst$$reg), __ T4H, 16898 as_FloatRegister($src$$reg), sh); 16899 } 16900 %} 16901 ins_pipe(vshift64_imm); 16902 %} 16903 16904 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 16905 predicate(n->as_Vector()->length() == 8); 16906 match(Set dst (LShiftVS src shift)); 16907 ins_cost(INSN_COST); 16908 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 16909 ins_encode %{ 16910 int sh = (int)$shift$$constant; 16911 if (sh >= 16) { 16912 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16913 as_FloatRegister($src$$reg), 16914 as_FloatRegister($src$$reg)); 16915 } else { 16916 __ shl(as_FloatRegister($dst$$reg), __ T8H, 16917 as_FloatRegister($src$$reg), sh); 16918 } 16919 %} 16920 ins_pipe(vshift128_imm); 16921 %} 16922 16923 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 16924 predicate(n->as_Vector()->length() == 2 || 16925 n->as_Vector()->length() == 4); 16926 match(Set dst (RShiftVS src shift)); 16927 ins_cost(INSN_COST); 16928 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 16929 ins_encode %{ 16930 int sh = (int)$shift$$constant; 16931 if (sh >= 16) sh = 15; 16932 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 16933 as_FloatRegister($src$$reg), sh); 16934 %} 16935 ins_pipe(vshift64_imm); 16936 %} 16937 16938 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 16939 predicate(n->as_Vector()->length() == 8); 16940 match(Set dst (RShiftVS src shift)); 16941 ins_cost(INSN_COST); 16942 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 16943 ins_encode %{ 16944 int sh = (int)$shift$$constant; 16945 if (sh >= 16) sh = 15; 16946 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 16947 as_FloatRegister($src$$reg), sh); 16948 %} 16949 ins_pipe(vshift128_imm); 16950 %} 16951 16952 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 16953 predicate(n->as_Vector()->length() == 2 || 16954 n->as_Vector()->length() == 4); 16955 match(Set dst (URShiftVS src shift)); 16956 ins_cost(INSN_COST); 16957 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 16958 ins_encode %{ 16959 int sh = (int)$shift$$constant; 16960 if (sh >= 16) { 16961 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16962 as_FloatRegister($src$$reg), 16963 as_FloatRegister($src$$reg)); 16964 } else { 16965 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 16966 as_FloatRegister($src$$reg), sh); 16967 } 16968 %} 16969 ins_pipe(vshift64_imm); 16970 %} 16971 16972 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 16973 predicate(n->as_Vector()->length() == 8); 16974 match(Set dst (URShiftVS src shift)); 16975 ins_cost(INSN_COST); 16976 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 16977 ins_encode %{ 16978 int sh = (int)$shift$$constant; 16979 if (sh >= 16) { 16980 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16981 as_FloatRegister($src$$reg), 16982 as_FloatRegister($src$$reg)); 16983 } else { 16984 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 16985 as_FloatRegister($src$$reg), sh); 16986 } 16987 %} 16988 ins_pipe(vshift128_imm); 16989 %} 16990 16991 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 16992 predicate(n->as_Vector()->length() == 2); 16993 match(Set dst (LShiftVI src shift)); 16994 ins_cost(INSN_COST); 16995 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 16996 ins_encode %{ 16997 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16998 as_FloatRegister($src$$reg), 16999 as_FloatRegister($shift$$reg)); 17000 %} 17001 ins_pipe(vshift64); 17002 %} 17003 17004 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17005 predicate(n->as_Vector()->length() == 4); 17006 match(Set dst (LShiftVI src shift)); 17007 ins_cost(INSN_COST); 17008 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17009 ins_encode %{ 17010 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17011 as_FloatRegister($src$$reg), 17012 as_FloatRegister($shift$$reg)); 17013 %} 17014 ins_pipe(vshift128); 17015 %} 17016 17017 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17018 predicate(n->as_Vector()->length() == 2); 17019 match(Set dst (RShiftVI src shift)); 17020 ins_cost(INSN_COST); 17021 effect(TEMP tmp); 17022 format %{ "negr $tmp,$shift\t" 17023 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17024 ins_encode %{ 17025 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17026 as_FloatRegister($shift$$reg)); 17027 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17028 as_FloatRegister($src$$reg), 17029 as_FloatRegister($tmp$$reg)); 17030 %} 17031 ins_pipe(vshift64); 17032 %} 17033 17034 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17035 predicate(n->as_Vector()->length() == 4); 17036 match(Set dst (RShiftVI src shift)); 17037 ins_cost(INSN_COST); 17038 effect(TEMP tmp); 17039 format %{ "negr $tmp,$shift\t" 17040 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17041 ins_encode %{ 17042 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17043 as_FloatRegister($shift$$reg)); 17044 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17045 as_FloatRegister($src$$reg), 17046 as_FloatRegister($tmp$$reg)); 17047 %} 17048 ins_pipe(vshift128); 17049 %} 17050 17051 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17052 predicate(n->as_Vector()->length() == 2); 17053 match(Set dst (URShiftVI src shift)); 17054 ins_cost(INSN_COST); 17055 effect(TEMP tmp); 17056 format %{ "negr $tmp,$shift\t" 17057 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17058 ins_encode %{ 17059 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17060 as_FloatRegister($shift$$reg)); 17061 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17062 as_FloatRegister($src$$reg), 17063 as_FloatRegister($tmp$$reg)); 17064 %} 17065 ins_pipe(vshift64); 17066 %} 17067 17068 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17069 predicate(n->as_Vector()->length() == 4); 17070 match(Set dst (URShiftVI src shift)); 17071 ins_cost(INSN_COST); 17072 effect(TEMP tmp); 17073 format %{ "negr $tmp,$shift\t" 17074 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17075 ins_encode %{ 17076 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17077 as_FloatRegister($shift$$reg)); 17078 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17079 as_FloatRegister($src$$reg), 17080 as_FloatRegister($tmp$$reg)); 17081 %} 17082 ins_pipe(vshift128); 17083 %} 17084 17085 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17086 predicate(n->as_Vector()->length() == 2); 17087 match(Set dst (LShiftVI src shift)); 17088 ins_cost(INSN_COST); 17089 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17090 ins_encode %{ 17091 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17092 as_FloatRegister($src$$reg), 17093 (int)$shift$$constant); 17094 %} 17095 ins_pipe(vshift64_imm); 17096 %} 17097 17098 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17099 predicate(n->as_Vector()->length() == 4); 17100 match(Set dst (LShiftVI src shift)); 17101 ins_cost(INSN_COST); 17102 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17103 ins_encode %{ 17104 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17105 as_FloatRegister($src$$reg), 17106 (int)$shift$$constant); 17107 %} 17108 ins_pipe(vshift128_imm); 17109 %} 17110 17111 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17112 predicate(n->as_Vector()->length() == 2); 17113 match(Set dst (RShiftVI src shift)); 17114 ins_cost(INSN_COST); 17115 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17116 ins_encode %{ 17117 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17118 as_FloatRegister($src$$reg), 17119 (int)$shift$$constant); 17120 %} 17121 ins_pipe(vshift64_imm); 17122 %} 17123 17124 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17125 predicate(n->as_Vector()->length() == 4); 17126 match(Set dst (RShiftVI src shift)); 17127 ins_cost(INSN_COST); 17128 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17129 ins_encode %{ 17130 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17131 as_FloatRegister($src$$reg), 17132 (int)$shift$$constant); 17133 %} 17134 ins_pipe(vshift128_imm); 17135 %} 17136 17137 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17138 predicate(n->as_Vector()->length() == 2); 17139 match(Set dst (URShiftVI src shift)); 17140 ins_cost(INSN_COST); 17141 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17142 ins_encode %{ 17143 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17144 as_FloatRegister($src$$reg), 17145 (int)$shift$$constant); 17146 %} 17147 ins_pipe(vshift64_imm); 17148 %} 17149 17150 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17151 predicate(n->as_Vector()->length() == 4); 17152 match(Set dst (URShiftVI src shift)); 17153 ins_cost(INSN_COST); 17154 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17155 ins_encode %{ 17156 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17157 as_FloatRegister($src$$reg), 17158 (int)$shift$$constant); 17159 %} 17160 ins_pipe(vshift128_imm); 17161 %} 17162 17163 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17164 predicate(n->as_Vector()->length() == 2); 17165 match(Set dst (LShiftVL src shift)); 17166 ins_cost(INSN_COST); 17167 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17168 ins_encode %{ 17169 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17170 as_FloatRegister($src$$reg), 17171 as_FloatRegister($shift$$reg)); 17172 %} 17173 ins_pipe(vshift128); 17174 %} 17175 17176 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17177 predicate(n->as_Vector()->length() == 2); 17178 match(Set dst (RShiftVL src shift)); 17179 ins_cost(INSN_COST); 17180 effect(TEMP tmp); 17181 format %{ "negr $tmp,$shift\t" 17182 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17183 ins_encode %{ 17184 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17185 as_FloatRegister($shift$$reg)); 17186 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17187 as_FloatRegister($src$$reg), 17188 as_FloatRegister($tmp$$reg)); 17189 %} 17190 ins_pipe(vshift128); 17191 %} 17192 17193 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17194 predicate(n->as_Vector()->length() == 2); 17195 match(Set dst (URShiftVL src shift)); 17196 ins_cost(INSN_COST); 17197 effect(TEMP tmp); 17198 format %{ "negr $tmp,$shift\t" 17199 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17200 ins_encode %{ 17201 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17202 as_FloatRegister($shift$$reg)); 17203 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17204 as_FloatRegister($src$$reg), 17205 as_FloatRegister($tmp$$reg)); 17206 %} 17207 ins_pipe(vshift128); 17208 %} 17209 17210 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17211 predicate(n->as_Vector()->length() == 2); 17212 match(Set dst (LShiftVL src shift)); 17213 ins_cost(INSN_COST); 17214 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17215 ins_encode %{ 17216 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17217 as_FloatRegister($src$$reg), 17218 (int)$shift$$constant); 17219 %} 17220 ins_pipe(vshift128_imm); 17221 %} 17222 17223 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17224 predicate(n->as_Vector()->length() == 2); 17225 match(Set dst (RShiftVL src shift)); 17226 ins_cost(INSN_COST); 17227 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17228 ins_encode %{ 17229 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17230 as_FloatRegister($src$$reg), 17231 (int)$shift$$constant); 17232 %} 17233 ins_pipe(vshift128_imm); 17234 %} 17235 17236 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17237 predicate(n->as_Vector()->length() == 2); 17238 match(Set dst (URShiftVL src shift)); 17239 ins_cost(INSN_COST); 17240 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17241 ins_encode %{ 17242 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17243 as_FloatRegister($src$$reg), 17244 (int)$shift$$constant); 17245 %} 17246 ins_pipe(vshift128_imm); 17247 %} 17248 17249 //----------PEEPHOLE RULES----------------------------------------------------- 17250 // These must follow all instruction definitions as they use the names 17251 // defined in the instructions definitions. 17252 // 17253 // peepmatch ( root_instr_name [preceding_instruction]* ); 17254 // 17255 // peepconstraint %{ 17256 // (instruction_number.operand_name relational_op instruction_number.operand_name 17257 // [, ...] ); 17258 // // instruction numbers are zero-based using left to right order in peepmatch 17259 // 17260 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17261 // // provide an instruction_number.operand_name for each operand that appears 17262 // // in the replacement instruction's match rule 17263 // 17264 // ---------VM FLAGS--------------------------------------------------------- 17265 // 17266 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17267 // 17268 // Each peephole rule is given an identifying number starting with zero and 17269 // increasing by one in the order seen by the parser. An individual peephole 17270 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17271 // on the command-line. 17272 // 17273 // ---------CURRENT LIMITATIONS---------------------------------------------- 17274 // 17275 // Only match adjacent instructions in same basic block 17276 // Only equality constraints 17277 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17278 // Only one replacement instruction 17279 // 17280 // ---------EXAMPLE---------------------------------------------------------- 17281 // 17282 // // pertinent parts of existing instructions in architecture description 17283 // instruct movI(iRegINoSp dst, iRegI src) 17284 // %{ 17285 // match(Set dst (CopyI src)); 17286 // %} 17287 // 17288 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17289 // %{ 17290 // match(Set dst (AddI dst src)); 17291 // effect(KILL cr); 17292 // %} 17293 // 17294 // // Change (inc mov) to lea 17295 // peephole %{ 17296 // // increment preceeded by register-register move 17297 // peepmatch ( incI_iReg movI ); 17298 // // require that the destination register of the increment 17299 // // match the destination register of the move 17300 // peepconstraint ( 0.dst == 1.dst ); 17301 // // construct a replacement instruction that sets 17302 // // the destination to ( move's source register + one ) 17303 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17304 // %} 17305 // 17306 17307 // Implementation no longer uses movX instructions since 17308 // machine-independent system no longer uses CopyX nodes. 17309 // 17310 // peephole 17311 // %{ 17312 // peepmatch (incI_iReg movI); 17313 // peepconstraint (0.dst == 1.dst); 17314 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17315 // %} 17316 17317 // peephole 17318 // %{ 17319 // peepmatch (decI_iReg movI); 17320 // peepconstraint (0.dst == 1.dst); 17321 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17322 // %} 17323 17324 // peephole 17325 // %{ 17326 // peepmatch (addI_iReg_imm movI); 17327 // peepconstraint (0.dst == 1.dst); 17328 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17329 // %} 17330 17331 // peephole 17332 // %{ 17333 // peepmatch (incL_iReg movL); 17334 // peepconstraint (0.dst == 1.dst); 17335 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17336 // %} 17337 17338 // peephole 17339 // %{ 17340 // peepmatch (decL_iReg movL); 17341 // peepconstraint (0.dst == 1.dst); 17342 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17343 // %} 17344 17345 // peephole 17346 // %{ 17347 // peepmatch (addL_iReg_imm movL); 17348 // peepconstraint (0.dst == 1.dst); 17349 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17350 // %} 17351 17352 // peephole 17353 // %{ 17354 // peepmatch (addP_iReg_imm movP); 17355 // peepconstraint (0.dst == 1.dst); 17356 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17357 // %} 17358 17359 // // Change load of spilled value to only a spill 17360 // instruct storeI(memory mem, iRegI src) 17361 // %{ 17362 // match(Set mem (StoreI mem src)); 17363 // %} 17364 // 17365 // instruct loadI(iRegINoSp dst, memory mem) 17366 // %{ 17367 // match(Set dst (LoadI mem)); 17368 // %} 17369 // 17370 17371 //----------SMARTSPILL RULES--------------------------------------------------- 17372 // These must follow all instruction definitions as they use the names 17373 // defined in the instructions definitions. 17374 17375 // Local Variables: 17376 // mode: c++ 17377 // End: