1 // 2 // Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2019, Red Hat, Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 167 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 168 169 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 170 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 171 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 172 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 173 174 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 175 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 176 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 177 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 178 179 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 180 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 181 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 182 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 183 184 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 185 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 186 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 187 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 188 189 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 190 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 191 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 192 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 193 194 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 195 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 196 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 197 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 198 199 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 200 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 201 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 202 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 203 204 reg_def V8 ( SOC, SOC, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next() ); 206 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 207 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 208 209 reg_def V9 ( SOC, SOC, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next() ); 211 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 212 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 213 214 reg_def V10 ( SOC, SOC, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() ); 216 reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2)); 217 reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3)); 218 219 reg_def V11 ( SOC, SOC, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() ); 221 reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2)); 222 reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3)); 223 224 reg_def V12 ( SOC, SOC, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() ); 226 reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2)); 227 reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3)); 228 229 reg_def V13 ( SOC, SOC, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() ); 231 reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2)); 232 reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3)); 233 234 reg_def V14 ( SOC, SOC, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() ); 236 reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2)); 237 reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3)); 238 239 reg_def V15 ( SOC, SOC, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() ); 241 reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2)); 242 reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3)); 243 244 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 245 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 246 reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2)); 247 reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3)); 248 249 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 250 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 251 reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2)); 252 reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3)); 253 254 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 255 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 256 reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2)); 257 reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3)); 258 259 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 260 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 261 reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2)); 262 reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3)); 263 264 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 265 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 266 reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2)); 267 reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3)); 268 269 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 270 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 271 reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2)); 272 reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3)); 273 274 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 275 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 276 reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2)); 277 reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3)); 278 279 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 280 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 281 reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2)); 282 reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3)); 283 284 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 285 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 286 reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2)); 287 reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3)); 288 289 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 290 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 291 reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2)); 292 reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3)); 293 294 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 295 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 296 reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2)); 297 reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3)); 298 299 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 300 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 301 reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2)); 302 reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3)); 303 304 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 305 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 306 reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2)); 307 reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3)); 308 309 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 310 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 311 reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2)); 312 reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3)); 313 314 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 315 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 316 reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2)); 317 reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3)); 318 319 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 320 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 321 reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2)); 322 reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3)); 323 324 // ---------------------------- 325 // Special Registers 326 // ---------------------------- 327 328 // the AArch64 CSPR status flag register is not directly acessible as 329 // instruction operand. the FPSR status flag register is a system 330 // register which can be written/read using MSR/MRS but again does not 331 // appear as an operand (a code identifying the FSPR occurs as an 332 // immediate value in the instruction). 333 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 335 336 337 // Specify priority of register selection within phases of register 338 // allocation. Highest priority is first. A useful heuristic is to 339 // give registers a low priority when they are required by machine 340 // instructions, like EAX and EDX on I486, and choose no-save registers 341 // before save-on-call, & save-on-call before save-on-entry. Registers 342 // which participate in fixed calling sequences should come last. 343 // Registers which are used as pairs must fall on an even boundary. 344 345 alloc_class chunk0( 346 // volatiles 347 R10, R10_H, 348 R11, R11_H, 349 R12, R12_H, 350 R13, R13_H, 351 R14, R14_H, 352 R15, R15_H, 353 R16, R16_H, 354 R17, R17_H, 355 R18, R18_H, 356 357 // arg registers 358 R0, R0_H, 359 R1, R1_H, 360 R2, R2_H, 361 R3, R3_H, 362 R4, R4_H, 363 R5, R5_H, 364 R6, R6_H, 365 R7, R7_H, 366 367 // non-volatiles 368 R19, R19_H, 369 R20, R20_H, 370 R21, R21_H, 371 R22, R22_H, 372 R23, R23_H, 373 R24, R24_H, 374 R25, R25_H, 375 R26, R26_H, 376 377 // non-allocatable registers 378 379 R27, R27_H, // heapbase 380 R28, R28_H, // thread 381 R29, R29_H, // fp 382 R30, R30_H, // lr 383 R31, R31_H, // sp 384 ); 385 386 alloc_class chunk1( 387 388 // no save 389 V16, V16_H, V16_J, V16_K, 390 V17, V17_H, V17_J, V17_K, 391 V18, V18_H, V18_J, V18_K, 392 V19, V19_H, V19_J, V19_K, 393 V20, V20_H, V20_J, V20_K, 394 V21, V21_H, V21_J, V21_K, 395 V22, V22_H, V22_J, V22_K, 396 V23, V23_H, V23_J, V23_K, 397 V24, V24_H, V24_J, V24_K, 398 V25, V25_H, V25_J, V25_K, 399 V26, V26_H, V26_J, V26_K, 400 V27, V27_H, V27_J, V27_K, 401 V28, V28_H, V28_J, V28_K, 402 V29, V29_H, V29_J, V29_K, 403 V30, V30_H, V30_J, V30_K, 404 V31, V31_H, V31_J, V31_K, 405 406 // arg registers 407 V0, V0_H, V0_J, V0_K, 408 V1, V1_H, V1_J, V1_K, 409 V2, V2_H, V2_J, V2_K, 410 V3, V3_H, V3_J, V3_K, 411 V4, V4_H, V4_J, V4_K, 412 V5, V5_H, V5_J, V5_K, 413 V6, V6_H, V6_J, V6_K, 414 V7, V7_H, V7_J, V7_K, 415 416 // non-volatiles 417 V8, V8_H, V8_J, V8_K, 418 V9, V9_H, V9_J, V9_K, 419 V10, V10_H, V10_J, V10_K, 420 V11, V11_H, V11_J, V11_K, 421 V12, V12_H, V12_J, V12_K, 422 V13, V13_H, V13_J, V13_K, 423 V14, V14_H, V14_J, V14_K, 424 V15, V15_H, V15_J, V15_K, 425 ); 426 427 alloc_class chunk2(RFLAGS); 428 429 //----------Architecture Description Register Classes-------------------------- 430 // Several register classes are automatically defined based upon information in 431 // this architecture description. 432 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 433 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 436 // 437 438 // Class for all 32 bit integer registers -- excludes SP which will 439 // never be used as an integer register 440 reg_class any_reg32( 441 R0, 442 R1, 443 R2, 444 R3, 445 R4, 446 R5, 447 R6, 448 R7, 449 R10, 450 R11, 451 R12, 452 R13, 453 R14, 454 R15, 455 R16, 456 R17, 457 R18, 458 R19, 459 R20, 460 R21, 461 R22, 462 R23, 463 R24, 464 R25, 465 R26, 466 R27, 467 R28, 468 R29, 469 R30 470 ); 471 472 // Singleton class for R0 int register 473 reg_class int_r0_reg(R0); 474 475 // Singleton class for R2 int register 476 reg_class int_r2_reg(R2); 477 478 // Singleton class for R3 int register 479 reg_class int_r3_reg(R3); 480 481 // Singleton class for R4 int register 482 reg_class int_r4_reg(R4); 483 484 // Class for all long integer registers (including RSP) 485 reg_class any_reg( 486 R0, R0_H, 487 R1, R1_H, 488 R2, R2_H, 489 R3, R3_H, 490 R4, R4_H, 491 R5, R5_H, 492 R6, R6_H, 493 R7, R7_H, 494 R10, R10_H, 495 R11, R11_H, 496 R12, R12_H, 497 R13, R13_H, 498 R14, R14_H, 499 R15, R15_H, 500 R16, R16_H, 501 R17, R17_H, 502 R18, R18_H, 503 R19, R19_H, 504 R20, R20_H, 505 R21, R21_H, 506 R22, R22_H, 507 R23, R23_H, 508 R24, R24_H, 509 R25, R25_H, 510 R26, R26_H, 511 R27, R27_H, 512 R28, R28_H, 513 R29, R29_H, 514 R30, R30_H, 515 R31, R31_H 516 ); 517 518 // Class for all non-special integer registers 519 reg_class no_special_reg32_no_fp( 520 R0, 521 R1, 522 R2, 523 R3, 524 R4, 525 R5, 526 R6, 527 R7, 528 R10, 529 R11, 530 R12, // rmethod 531 R13, 532 R14, 533 R15, 534 R16, 535 R17, 536 R18, 537 R19, 538 R20, 539 R21, 540 R22, 541 R23, 542 R24, 543 R25, 544 R26 545 /* R27, */ // heapbase 546 /* R28, */ // thread 547 /* R29, */ // fp 548 /* R30, */ // lr 549 /* R31 */ // sp 550 ); 551 552 reg_class no_special_reg32_with_fp( 553 R0, 554 R1, 555 R2, 556 R3, 557 R4, 558 R5, 559 R6, 560 R7, 561 R10, 562 R11, 563 R12, // rmethod 564 R13, 565 R14, 566 R15, 567 R16, 568 R17, 569 R18, 570 R19, 571 R20, 572 R21, 573 R22, 574 R23, 575 R24, 576 R25, 577 R26 578 /* R27, */ // heapbase 579 /* R28, */ // thread 580 R29, // fp 581 /* R30, */ // lr 582 /* R31 */ // sp 583 ); 584 585 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); 586 587 // Class for all non-special long integer registers 588 reg_class no_special_reg_no_fp( 589 R0, R0_H, 590 R1, R1_H, 591 R2, R2_H, 592 R3, R3_H, 593 R4, R4_H, 594 R5, R5_H, 595 R6, R6_H, 596 R7, R7_H, 597 R10, R10_H, 598 R11, R11_H, 599 R12, R12_H, // rmethod 600 R13, R13_H, 601 R14, R14_H, 602 R15, R15_H, 603 R16, R16_H, 604 R17, R17_H, 605 R18, R18_H, 606 R19, R19_H, 607 R20, R20_H, 608 R21, R21_H, 609 R22, R22_H, 610 R23, R23_H, 611 R24, R24_H, 612 R25, R25_H, 613 R26, R26_H, 614 /* R27, R27_H, */ // heapbase 615 /* R28, R28_H, */ // thread 616 /* R29, R29_H, */ // fp 617 /* R30, R30_H, */ // lr 618 /* R31, R31_H */ // sp 619 ); 620 621 reg_class no_special_reg_with_fp( 622 R0, R0_H, 623 R1, R1_H, 624 R2, R2_H, 625 R3, R3_H, 626 R4, R4_H, 627 R5, R5_H, 628 R6, R6_H, 629 R7, R7_H, 630 R10, R10_H, 631 R11, R11_H, 632 R12, R12_H, // rmethod 633 R13, R13_H, 634 R14, R14_H, 635 R15, R15_H, 636 R16, R16_H, 637 R17, R17_H, 638 R18, R18_H, 639 R19, R19_H, 640 R20, R20_H, 641 R21, R21_H, 642 R22, R22_H, 643 R23, R23_H, 644 R24, R24_H, 645 R25, R25_H, 646 R26, R26_H, 647 /* R27, R27_H, */ // heapbase 648 /* R28, R28_H, */ // thread 649 R29, R29_H, // fp 650 /* R30, R30_H, */ // lr 651 /* R31, R31_H */ // sp 652 ); 653 654 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 655 656 // Class for 64 bit register r0 657 reg_class r0_reg( 658 R0, R0_H 659 ); 660 661 // Class for 64 bit register r1 662 reg_class r1_reg( 663 R1, R1_H 664 ); 665 666 // Class for 64 bit register r2 667 reg_class r2_reg( 668 R2, R2_H 669 ); 670 671 // Class for 64 bit register r3 672 reg_class r3_reg( 673 R3, R3_H 674 ); 675 676 // Class for 64 bit register r4 677 reg_class r4_reg( 678 R4, R4_H 679 ); 680 681 // Class for 64 bit register r5 682 reg_class r5_reg( 683 R5, R5_H 684 ); 685 686 // Class for 64 bit register r10 687 reg_class r10_reg( 688 R10, R10_H 689 ); 690 691 // Class for 64 bit register r11 692 reg_class r11_reg( 693 R11, R11_H 694 ); 695 696 // Class for method register 697 reg_class method_reg( 698 R12, R12_H 699 ); 700 701 // Class for heapbase register 702 reg_class heapbase_reg( 703 R27, R27_H 704 ); 705 706 // Class for thread register 707 reg_class thread_reg( 708 R28, R28_H 709 ); 710 711 // Class for frame pointer register 712 reg_class fp_reg( 713 R29, R29_H 714 ); 715 716 // Class for link register 717 reg_class lr_reg( 718 R30, R30_H 719 ); 720 721 // Class for long sp register 722 reg_class sp_reg( 723 R31, R31_H 724 ); 725 726 // Class for all pointer registers 727 reg_class ptr_reg( 728 R0, R0_H, 729 R1, R1_H, 730 R2, R2_H, 731 R3, R3_H, 732 R4, R4_H, 733 R5, R5_H, 734 R6, R6_H, 735 R7, R7_H, 736 R10, R10_H, 737 R11, R11_H, 738 R12, R12_H, 739 R13, R13_H, 740 R14, R14_H, 741 R15, R15_H, 742 R16, R16_H, 743 R17, R17_H, 744 R18, R18_H, 745 R19, R19_H, 746 R20, R20_H, 747 R21, R21_H, 748 R22, R22_H, 749 R23, R23_H, 750 R24, R24_H, 751 R25, R25_H, 752 R26, R26_H, 753 R27, R27_H, 754 R28, R28_H, 755 R29, R29_H, 756 R30, R30_H, 757 R31, R31_H 758 ); 759 760 // Class for all non_special pointer registers 761 reg_class no_special_ptr_reg( 762 R0, R0_H, 763 R1, R1_H, 764 R2, R2_H, 765 R3, R3_H, 766 R4, R4_H, 767 R5, R5_H, 768 R6, R6_H, 769 R7, R7_H, 770 R10, R10_H, 771 R11, R11_H, 772 R12, R12_H, 773 R13, R13_H, 774 R14, R14_H, 775 R15, R15_H, 776 R16, R16_H, 777 R17, R17_H, 778 R18, R18_H, 779 R19, R19_H, 780 R20, R20_H, 781 R21, R21_H, 782 R22, R22_H, 783 R23, R23_H, 784 R24, R24_H, 785 R25, R25_H, 786 R26, R26_H, 787 /* R27, R27_H, */ // heapbase 788 /* R28, R28_H, */ // thread 789 /* R29, R29_H, */ // fp 790 /* R30, R30_H, */ // lr 791 /* R31, R31_H */ // sp 792 ); 793 794 // Class for all float registers 795 reg_class float_reg( 796 V0, 797 V1, 798 V2, 799 V3, 800 V4, 801 V5, 802 V6, 803 V7, 804 V8, 805 V9, 806 V10, 807 V11, 808 V12, 809 V13, 810 V14, 811 V15, 812 V16, 813 V17, 814 V18, 815 V19, 816 V20, 817 V21, 818 V22, 819 V23, 820 V24, 821 V25, 822 V26, 823 V27, 824 V28, 825 V29, 826 V30, 827 V31 828 ); 829 830 // Double precision float registers have virtual `high halves' that 831 // are needed by the allocator. 832 // Class for all double registers 833 reg_class double_reg( 834 V0, V0_H, 835 V1, V1_H, 836 V2, V2_H, 837 V3, V3_H, 838 V4, V4_H, 839 V5, V5_H, 840 V6, V6_H, 841 V7, V7_H, 842 V8, V8_H, 843 V9, V9_H, 844 V10, V10_H, 845 V11, V11_H, 846 V12, V12_H, 847 V13, V13_H, 848 V14, V14_H, 849 V15, V15_H, 850 V16, V16_H, 851 V17, V17_H, 852 V18, V18_H, 853 V19, V19_H, 854 V20, V20_H, 855 V21, V21_H, 856 V22, V22_H, 857 V23, V23_H, 858 V24, V24_H, 859 V25, V25_H, 860 V26, V26_H, 861 V27, V27_H, 862 V28, V28_H, 863 V29, V29_H, 864 V30, V30_H, 865 V31, V31_H 866 ); 867 868 // Class for all 64bit vector registers 869 reg_class vectord_reg( 870 V0, V0_H, 871 V1, V1_H, 872 V2, V2_H, 873 V3, V3_H, 874 V4, V4_H, 875 V5, V5_H, 876 V6, V6_H, 877 V7, V7_H, 878 V8, V8_H, 879 V9, V9_H, 880 V10, V10_H, 881 V11, V11_H, 882 V12, V12_H, 883 V13, V13_H, 884 V14, V14_H, 885 V15, V15_H, 886 V16, V16_H, 887 V17, V17_H, 888 V18, V18_H, 889 V19, V19_H, 890 V20, V20_H, 891 V21, V21_H, 892 V22, V22_H, 893 V23, V23_H, 894 V24, V24_H, 895 V25, V25_H, 896 V26, V26_H, 897 V27, V27_H, 898 V28, V28_H, 899 V29, V29_H, 900 V30, V30_H, 901 V31, V31_H 902 ); 903 904 // Class for all 128bit vector registers 905 reg_class vectorx_reg( 906 V0, V0_H, V0_J, V0_K, 907 V1, V1_H, V1_J, V1_K, 908 V2, V2_H, V2_J, V2_K, 909 V3, V3_H, V3_J, V3_K, 910 V4, V4_H, V4_J, V4_K, 911 V5, V5_H, V5_J, V5_K, 912 V6, V6_H, V6_J, V6_K, 913 V7, V7_H, V7_J, V7_K, 914 V8, V8_H, V8_J, V8_K, 915 V9, V9_H, V9_J, V9_K, 916 V10, V10_H, V10_J, V10_K, 917 V11, V11_H, V11_J, V11_K, 918 V12, V12_H, V12_J, V12_K, 919 V13, V13_H, V13_J, V13_K, 920 V14, V14_H, V14_J, V14_K, 921 V15, V15_H, V15_J, V15_K, 922 V16, V16_H, V16_J, V16_K, 923 V17, V17_H, V17_J, V17_K, 924 V18, V18_H, V18_J, V18_K, 925 V19, V19_H, V19_J, V19_K, 926 V20, V20_H, V20_J, V20_K, 927 V21, V21_H, V21_J, V21_K, 928 V22, V22_H, V22_J, V22_K, 929 V23, V23_H, V23_J, V23_K, 930 V24, V24_H, V24_J, V24_K, 931 V25, V25_H, V25_J, V25_K, 932 V26, V26_H, V26_J, V26_K, 933 V27, V27_H, V27_J, V27_K, 934 V28, V28_H, V28_J, V28_K, 935 V29, V29_H, V29_J, V29_K, 936 V30, V30_H, V30_J, V30_K, 937 V31, V31_H, V31_J, V31_K 938 ); 939 940 // Class for 128 bit register v0 941 reg_class v0_reg( 942 V0, V0_H 943 ); 944 945 // Class for 128 bit register v1 946 reg_class v1_reg( 947 V1, V1_H 948 ); 949 950 // Class for 128 bit register v2 951 reg_class v2_reg( 952 V2, V2_H 953 ); 954 955 // Class for 128 bit register v3 956 reg_class v3_reg( 957 V3, V3_H 958 ); 959 960 // Singleton class for condition codes 961 reg_class int_flags(RFLAGS); 962 963 %} 964 965 //----------DEFINITION BLOCK--------------------------------------------------- 966 // Define name --> value mappings to inform the ADLC of an integer valued name 967 // Current support includes integer values in the range [0, 0x7FFFFFFF] 968 // Format: 969 // int_def <name> ( <int_value>, <expression>); 970 // Generated Code in ad_<arch>.hpp 971 // #define <name> (<expression>) 972 // // value == <int_value> 973 // Generated code in ad_<arch>.cpp adlc_verification() 974 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 975 // 976 977 // we follow the ppc-aix port in using a simple cost model which ranks 978 // register operations as cheap, memory ops as more expensive and 979 // branches as most expensive. the first two have a low as well as a 980 // normal cost. huge cost appears to be a way of saying don't do 981 // something 982 983 definitions %{ 984 // The default cost (of a register move instruction). 985 int_def INSN_COST ( 100, 100); 986 int_def BRANCH_COST ( 200, 2 * INSN_COST); 987 int_def CALL_COST ( 200, 2 * INSN_COST); 988 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 989 %} 990 991 992 //----------SOURCE BLOCK------------------------------------------------------- 993 // This is a block of C++ code which provides values, functions, and 994 // definitions necessary in the rest of the architecture description 995 996 source_hpp %{ 997 998 #include "asm/macroAssembler.hpp" 999 #include "gc/shared/cardTable.hpp" 1000 #include "gc/shared/cardTableBarrierSet.hpp" 1001 #include "gc/shared/collectedHeap.hpp" 1002 #include "opto/addnode.hpp" 1003 1004 class CallStubImpl { 1005 1006 //-------------------------------------------------------------- 1007 //---< Used for optimization in Compile::shorten_branches >--- 1008 //-------------------------------------------------------------- 1009 1010 public: 1011 // Size of call trampoline stub. 1012 static uint size_call_trampoline() { 1013 return 0; // no call trampolines on this platform 1014 } 1015 1016 // number of relocations needed by a call trampoline stub 1017 static uint reloc_call_trampoline() { 1018 return 0; // no call trampolines on this platform 1019 } 1020 }; 1021 1022 class HandlerImpl { 1023 1024 public: 1025 1026 static int emit_exception_handler(CodeBuffer &cbuf); 1027 static int emit_deopt_handler(CodeBuffer& cbuf); 1028 1029 static uint size_exception_handler() { 1030 return MacroAssembler::far_branch_size(); 1031 } 1032 1033 static uint size_deopt_handler() { 1034 // count one adr and one far branch instruction 1035 return 4 * NativeInstruction::instruction_size; 1036 } 1037 }; 1038 1039 bool is_CAS(int opcode, bool maybe_volatile); 1040 1041 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1042 1043 bool unnecessary_acquire(const Node *barrier); 1044 bool needs_acquiring_load(const Node *load); 1045 1046 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1047 1048 bool unnecessary_release(const Node *barrier); 1049 bool unnecessary_volatile(const Node *barrier); 1050 bool needs_releasing_store(const Node *store); 1051 1052 // predicate controlling translation of CompareAndSwapX 1053 bool needs_acquiring_load_exclusive(const Node *load); 1054 1055 // predicate controlling translation of StoreCM 1056 bool unnecessary_storestore(const Node *storecm); 1057 1058 // predicate controlling addressing modes 1059 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1060 %} 1061 1062 source %{ 1063 1064 // Optimizaton of volatile gets and puts 1065 // ------------------------------------- 1066 // 1067 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1068 // use to implement volatile reads and writes. For a volatile read 1069 // we simply need 1070 // 1071 // ldar<x> 1072 // 1073 // and for a volatile write we need 1074 // 1075 // stlr<x> 1076 // 1077 // Alternatively, we can implement them by pairing a normal 1078 // load/store with a memory barrier. For a volatile read we need 1079 // 1080 // ldr<x> 1081 // dmb ishld 1082 // 1083 // for a volatile write 1084 // 1085 // dmb ish 1086 // str<x> 1087 // dmb ish 1088 // 1089 // We can also use ldaxr and stlxr to implement compare and swap CAS 1090 // sequences. These are normally translated to an instruction 1091 // sequence like the following 1092 // 1093 // dmb ish 1094 // retry: 1095 // ldxr<x> rval raddr 1096 // cmp rval rold 1097 // b.ne done 1098 // stlxr<x> rval, rnew, rold 1099 // cbnz rval retry 1100 // done: 1101 // cset r0, eq 1102 // dmb ishld 1103 // 1104 // Note that the exclusive store is already using an stlxr 1105 // instruction. That is required to ensure visibility to other 1106 // threads of the exclusive write (assuming it succeeds) before that 1107 // of any subsequent writes. 1108 // 1109 // The following instruction sequence is an improvement on the above 1110 // 1111 // retry: 1112 // ldaxr<x> rval raddr 1113 // cmp rval rold 1114 // b.ne done 1115 // stlxr<x> rval, rnew, rold 1116 // cbnz rval retry 1117 // done: 1118 // cset r0, eq 1119 // 1120 // We don't need the leading dmb ish since the stlxr guarantees 1121 // visibility of prior writes in the case that the swap is 1122 // successful. Crucially we don't have to worry about the case where 1123 // the swap is not successful since no valid program should be 1124 // relying on visibility of prior changes by the attempting thread 1125 // in the case where the CAS fails. 1126 // 1127 // Similarly, we don't need the trailing dmb ishld if we substitute 1128 // an ldaxr instruction since that will provide all the guarantees we 1129 // require regarding observation of changes made by other threads 1130 // before any change to the CAS address observed by the load. 1131 // 1132 // In order to generate the desired instruction sequence we need to 1133 // be able to identify specific 'signature' ideal graph node 1134 // sequences which i) occur as a translation of a volatile reads or 1135 // writes or CAS operations and ii) do not occur through any other 1136 // translation or graph transformation. We can then provide 1137 // alternative aldc matching rules which translate these node 1138 // sequences to the desired machine code sequences. Selection of the 1139 // alternative rules can be implemented by predicates which identify 1140 // the relevant node sequences. 1141 // 1142 // The ideal graph generator translates a volatile read to the node 1143 // sequence 1144 // 1145 // LoadX[mo_acquire] 1146 // MemBarAcquire 1147 // 1148 // As a special case when using the compressed oops optimization we 1149 // may also see this variant 1150 // 1151 // LoadN[mo_acquire] 1152 // DecodeN 1153 // MemBarAcquire 1154 // 1155 // A volatile write is translated to the node sequence 1156 // 1157 // MemBarRelease 1158 // StoreX[mo_release] {CardMark}-optional 1159 // MemBarVolatile 1160 // 1161 // n.b. the above node patterns are generated with a strict 1162 // 'signature' configuration of input and output dependencies (see 1163 // the predicates below for exact details). The card mark may be as 1164 // simple as a few extra nodes or, in a few GC configurations, may 1165 // include more complex control flow between the leading and 1166 // trailing memory barriers. However, whatever the card mark 1167 // configuration these signatures are unique to translated volatile 1168 // reads/stores -- they will not appear as a result of any other 1169 // bytecode translation or inlining nor as a consequence of 1170 // optimizing transforms. 1171 // 1172 // We also want to catch inlined unsafe volatile gets and puts and 1173 // be able to implement them using either ldar<x>/stlr<x> or some 1174 // combination of ldr<x>/stlr<x> and dmb instructions. 1175 // 1176 // Inlined unsafe volatiles puts manifest as a minor variant of the 1177 // normal volatile put node sequence containing an extra cpuorder 1178 // membar 1179 // 1180 // MemBarRelease 1181 // MemBarCPUOrder 1182 // StoreX[mo_release] {CardMark}-optional 1183 // MemBarCPUOrder 1184 // MemBarVolatile 1185 // 1186 // n.b. as an aside, a cpuorder membar is not itself subject to 1187 // matching and translation by adlc rules. However, the rule 1188 // predicates need to detect its presence in order to correctly 1189 // select the desired adlc rules. 1190 // 1191 // Inlined unsafe volatile gets manifest as a slightly different 1192 // node sequence to a normal volatile get because of the 1193 // introduction of some CPUOrder memory barriers to bracket the 1194 // Load. However, but the same basic skeleton of a LoadX feeding a 1195 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1196 // present 1197 // 1198 // MemBarCPUOrder 1199 // || \\ 1200 // MemBarCPUOrder LoadX[mo_acquire] 1201 // || | 1202 // || {DecodeN} optional 1203 // || / 1204 // MemBarAcquire 1205 // 1206 // In this case the acquire membar does not directly depend on the 1207 // load. However, we can be sure that the load is generated from an 1208 // inlined unsafe volatile get if we see it dependent on this unique 1209 // sequence of membar nodes. Similarly, given an acquire membar we 1210 // can know that it was added because of an inlined unsafe volatile 1211 // get if it is fed and feeds a cpuorder membar and if its feed 1212 // membar also feeds an acquiring load. 1213 // 1214 // Finally an inlined (Unsafe) CAS operation is translated to the 1215 // following ideal graph 1216 // 1217 // MemBarRelease 1218 // MemBarCPUOrder 1219 // CompareAndSwapX {CardMark}-optional 1220 // MemBarCPUOrder 1221 // MemBarAcquire 1222 // 1223 // So, where we can identify these volatile read and write 1224 // signatures we can choose to plant either of the above two code 1225 // sequences. For a volatile read we can simply plant a normal 1226 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1227 // also choose to inhibit translation of the MemBarAcquire and 1228 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1229 // 1230 // When we recognise a volatile store signature we can choose to 1231 // plant at a dmb ish as a translation for the MemBarRelease, a 1232 // normal str<x> and then a dmb ish for the MemBarVolatile. 1233 // Alternatively, we can inhibit translation of the MemBarRelease 1234 // and MemBarVolatile and instead plant a simple stlr<x> 1235 // instruction. 1236 // 1237 // when we recognise a CAS signature we can choose to plant a dmb 1238 // ish as a translation for the MemBarRelease, the conventional 1239 // macro-instruction sequence for the CompareAndSwap node (which 1240 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1241 // Alternatively, we can elide generation of the dmb instructions 1242 // and plant the alternative CompareAndSwap macro-instruction 1243 // sequence (which uses ldaxr<x>). 1244 // 1245 // Of course, the above only applies when we see these signature 1246 // configurations. We still want to plant dmb instructions in any 1247 // other cases where we may see a MemBarAcquire, MemBarRelease or 1248 // MemBarVolatile. For example, at the end of a constructor which 1249 // writes final/volatile fields we will see a MemBarRelease 1250 // instruction and this needs a 'dmb ish' lest we risk the 1251 // constructed object being visible without making the 1252 // final/volatile field writes visible. 1253 // 1254 // n.b. the translation rules below which rely on detection of the 1255 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1256 // If we see anything other than the signature configurations we 1257 // always just translate the loads and stores to ldr<x> and str<x> 1258 // and translate acquire, release and volatile membars to the 1259 // relevant dmb instructions. 1260 // 1261 1262 // is_CAS(int opcode, bool maybe_volatile) 1263 // 1264 // return true if opcode is one of the possible CompareAndSwapX 1265 // values otherwise false. 1266 1267 bool is_CAS(int opcode, bool maybe_volatile) 1268 { 1269 switch(opcode) { 1270 // We handle these 1271 case Op_CompareAndSwapI: 1272 case Op_CompareAndSwapL: 1273 case Op_CompareAndSwapP: 1274 case Op_CompareAndSwapN: 1275 case Op_CompareAndSwapB: 1276 case Op_CompareAndSwapS: 1277 case Op_GetAndSetI: 1278 case Op_GetAndSetL: 1279 case Op_GetAndSetP: 1280 case Op_GetAndSetN: 1281 case Op_GetAndAddI: 1282 case Op_GetAndAddL: 1283 #if INCLUDE_SHENANDOAHGC 1284 case Op_ShenandoahCompareAndSwapP: 1285 case Op_ShenandoahCompareAndSwapN: 1286 #endif 1287 return true; 1288 case Op_CompareAndExchangeI: 1289 case Op_CompareAndExchangeN: 1290 case Op_CompareAndExchangeB: 1291 case Op_CompareAndExchangeS: 1292 case Op_CompareAndExchangeL: 1293 case Op_CompareAndExchangeP: 1294 case Op_WeakCompareAndSwapB: 1295 case Op_WeakCompareAndSwapS: 1296 case Op_WeakCompareAndSwapI: 1297 case Op_WeakCompareAndSwapL: 1298 case Op_WeakCompareAndSwapP: 1299 case Op_WeakCompareAndSwapN: 1300 return maybe_volatile; 1301 default: 1302 return false; 1303 } 1304 } 1305 1306 // helper to determine the maximum number of Phi nodes we may need to 1307 // traverse when searching from a card mark membar for the merge mem 1308 // feeding a trailing membar or vice versa 1309 1310 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1311 1312 bool unnecessary_acquire(const Node *barrier) 1313 { 1314 assert(barrier->is_MemBar(), "expecting a membar"); 1315 1316 if (UseBarriersForVolatile) { 1317 // we need to plant a dmb 1318 return false; 1319 } 1320 1321 MemBarNode* mb = barrier->as_MemBar(); 1322 1323 if (mb->trailing_load()) { 1324 return true; 1325 } 1326 1327 if (mb->trailing_load_store()) { 1328 Node* load_store = mb->in(MemBarNode::Precedent); 1329 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1330 return is_CAS(load_store->Opcode(), true); 1331 } 1332 1333 return false; 1334 } 1335 1336 bool needs_acquiring_load(const Node *n) 1337 { 1338 assert(n->is_Load(), "expecting a load"); 1339 if (UseBarriersForVolatile) { 1340 // we use a normal load and a dmb 1341 return false; 1342 } 1343 1344 LoadNode *ld = n->as_Load(); 1345 1346 return ld->is_acquire(); 1347 } 1348 1349 bool unnecessary_release(const Node *n) 1350 { 1351 assert((n->is_MemBar() && 1352 n->Opcode() == Op_MemBarRelease), 1353 "expecting a release membar"); 1354 1355 if (UseBarriersForVolatile) { 1356 // we need to plant a dmb 1357 return false; 1358 } 1359 1360 MemBarNode *barrier = n->as_MemBar(); 1361 if (!barrier->leading()) { 1362 return false; 1363 } else { 1364 Node* trailing = barrier->trailing_membar(); 1365 MemBarNode* trailing_mb = trailing->as_MemBar(); 1366 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1367 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1368 1369 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1370 if (mem->is_Store()) { 1371 assert(mem->as_Store()->is_release(), ""); 1372 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1373 return true; 1374 } else { 1375 assert(mem->is_LoadStore(), ""); 1376 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1377 return is_CAS(mem->Opcode(), true); 1378 } 1379 } 1380 return false; 1381 } 1382 1383 bool unnecessary_volatile(const Node *n) 1384 { 1385 // assert n->is_MemBar(); 1386 if (UseBarriersForVolatile) { 1387 // we need to plant a dmb 1388 return false; 1389 } 1390 1391 MemBarNode *mbvol = n->as_MemBar(); 1392 1393 bool release = mbvol->trailing_store(); 1394 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1395 #ifdef ASSERT 1396 if (release) { 1397 Node* leading = mbvol->leading_membar(); 1398 assert(leading->Opcode() == Op_MemBarRelease, ""); 1399 assert(leading->as_MemBar()->leading_store(), ""); 1400 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1401 } 1402 #endif 1403 1404 return release; 1405 } 1406 1407 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1408 1409 bool needs_releasing_store(const Node *n) 1410 { 1411 // assert n->is_Store(); 1412 if (UseBarriersForVolatile) { 1413 // we use a normal store and dmb combination 1414 return false; 1415 } 1416 1417 StoreNode *st = n->as_Store(); 1418 1419 return st->trailing_membar() != NULL; 1420 } 1421 1422 // predicate controlling translation of CAS 1423 // 1424 // returns true if CAS needs to use an acquiring load otherwise false 1425 1426 bool needs_acquiring_load_exclusive(const Node *n) 1427 { 1428 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1429 if (UseBarriersForVolatile) { 1430 return false; 1431 } 1432 1433 LoadStoreNode* ldst = n->as_LoadStore(); 1434 if (is_CAS(n->Opcode(), false)) { 1435 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1436 } else { 1437 return ldst->trailing_membar() != NULL; 1438 } 1439 1440 // so we can just return true here 1441 return true; 1442 } 1443 1444 // predicate controlling translation of StoreCM 1445 // 1446 // returns true if a StoreStore must precede the card write otherwise 1447 // false 1448 1449 bool unnecessary_storestore(const Node *storecm) 1450 { 1451 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1452 1453 // we need to generate a dmb ishst between an object put and the 1454 // associated card mark when we are using CMS without conditional 1455 // card marking 1456 1457 if (UseConcMarkSweepGC && !UseCondCardMark) { 1458 return false; 1459 } 1460 1461 // a storestore is unnecesary in all other cases 1462 1463 return true; 1464 } 1465 1466 1467 #define __ _masm. 1468 1469 // advance declarations for helper functions to convert register 1470 // indices to register objects 1471 1472 // the ad file has to provide implementations of certain methods 1473 // expected by the generic code 1474 // 1475 // REQUIRED FUNCTIONALITY 1476 1477 //============================================================================= 1478 1479 // !!!!! Special hack to get all types of calls to specify the byte offset 1480 // from the start of the call to the point where the return address 1481 // will point. 1482 1483 int MachCallStaticJavaNode::ret_addr_offset() 1484 { 1485 // call should be a simple bl 1486 int off = 4; 1487 return off; 1488 } 1489 1490 int MachCallDynamicJavaNode::ret_addr_offset() 1491 { 1492 return 16; // movz, movk, movk, bl 1493 } 1494 1495 int MachCallRuntimeNode::ret_addr_offset() { 1496 // for generated stubs the call will be 1497 // far_call(addr) 1498 // for real runtime callouts it will be six instructions 1499 // see aarch64_enc_java_to_runtime 1500 // adr(rscratch2, retaddr) 1501 // lea(rscratch1, RuntimeAddress(addr) 1502 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1503 // blr(rscratch1) 1504 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1505 if (cb) { 1506 return MacroAssembler::far_branch_size(); 1507 } else { 1508 return 6 * NativeInstruction::instruction_size; 1509 } 1510 } 1511 1512 // Indicate if the safepoint node needs the polling page as an input 1513 1514 // the shared code plants the oop data at the start of the generated 1515 // code for the safepoint node and that needs ot be at the load 1516 // instruction itself. so we cannot plant a mov of the safepoint poll 1517 // address followed by a load. setting this to true means the mov is 1518 // scheduled as a prior instruction. that's better for scheduling 1519 // anyway. 1520 1521 bool SafePointNode::needs_polling_address_input() 1522 { 1523 return true; 1524 } 1525 1526 //============================================================================= 1527 1528 #ifndef PRODUCT 1529 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1530 st->print("BREAKPOINT"); 1531 } 1532 #endif 1533 1534 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1535 MacroAssembler _masm(&cbuf); 1536 __ brk(0); 1537 } 1538 1539 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1540 return MachNode::size(ra_); 1541 } 1542 1543 //============================================================================= 1544 1545 #ifndef PRODUCT 1546 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1547 st->print("nop \t# %d bytes pad for loops and calls", _count); 1548 } 1549 #endif 1550 1551 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1552 MacroAssembler _masm(&cbuf); 1553 for (int i = 0; i < _count; i++) { 1554 __ nop(); 1555 } 1556 } 1557 1558 uint MachNopNode::size(PhaseRegAlloc*) const { 1559 return _count * NativeInstruction::instruction_size; 1560 } 1561 1562 //============================================================================= 1563 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1564 1565 int Compile::ConstantTable::calculate_table_base_offset() const { 1566 return 0; // absolute addressing, no offset 1567 } 1568 1569 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1570 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1571 ShouldNotReachHere(); 1572 } 1573 1574 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1575 // Empty encoding 1576 } 1577 1578 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1579 return 0; 1580 } 1581 1582 #ifndef PRODUCT 1583 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1584 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1585 } 1586 #endif 1587 1588 #ifndef PRODUCT 1589 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1590 Compile* C = ra_->C; 1591 1592 int framesize = C->frame_slots() << LogBytesPerInt; 1593 1594 if (C->need_stack_bang(framesize)) 1595 st->print("# stack bang size=%d\n\t", framesize); 1596 1597 if (framesize < ((1 << 9) + 2 * wordSize)) { 1598 st->print("sub sp, sp, #%d\n\t", framesize); 1599 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1600 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1601 } else { 1602 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1603 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1604 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1605 st->print("sub sp, sp, rscratch1"); 1606 } 1607 } 1608 #endif 1609 1610 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1611 Compile* C = ra_->C; 1612 MacroAssembler _masm(&cbuf); 1613 1614 // n.b. frame size includes space for return pc and rfp 1615 const long framesize = C->frame_size_in_bytes(); 1616 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1617 1618 // insert a nop at the start of the prolog so we can patch in a 1619 // branch if we need to invalidate the method later 1620 __ nop(); 1621 1622 int bangsize = C->bang_size_in_bytes(); 1623 if (C->need_stack_bang(bangsize) && UseStackBanging) 1624 __ generate_stack_overflow_check(bangsize); 1625 1626 __ build_frame(framesize); 1627 1628 if (VerifyStackAtCalls) { 1629 Unimplemented(); 1630 } 1631 1632 C->set_frame_complete(cbuf.insts_size()); 1633 1634 if (C->has_mach_constant_base_node()) { 1635 // NOTE: We set the table base offset here because users might be 1636 // emitted before MachConstantBaseNode. 1637 Compile::ConstantTable& constant_table = C->constant_table(); 1638 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1639 } 1640 } 1641 1642 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1643 { 1644 return MachNode::size(ra_); // too many variables; just compute it 1645 // the hard way 1646 } 1647 1648 int MachPrologNode::reloc() const 1649 { 1650 return 0; 1651 } 1652 1653 //============================================================================= 1654 1655 #ifndef PRODUCT 1656 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1657 Compile* C = ra_->C; 1658 int framesize = C->frame_slots() << LogBytesPerInt; 1659 1660 st->print("# pop frame %d\n\t",framesize); 1661 1662 if (framesize == 0) { 1663 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1664 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1665 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1666 st->print("add sp, sp, #%d\n\t", framesize); 1667 } else { 1668 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1669 st->print("add sp, sp, rscratch1\n\t"); 1670 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1671 } 1672 1673 if (do_polling() && C->is_method_compilation()) { 1674 st->print("# touch polling page\n\t"); 1675 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1676 st->print("ldr zr, [rscratch1]"); 1677 } 1678 } 1679 #endif 1680 1681 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1682 Compile* C = ra_->C; 1683 MacroAssembler _masm(&cbuf); 1684 int framesize = C->frame_slots() << LogBytesPerInt; 1685 1686 __ remove_frame(framesize); 1687 1688 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1689 __ reserved_stack_check(); 1690 } 1691 1692 if (do_polling() && C->is_method_compilation()) { 1693 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1694 } 1695 } 1696 1697 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1698 // Variable size. Determine dynamically. 1699 return MachNode::size(ra_); 1700 } 1701 1702 int MachEpilogNode::reloc() const { 1703 // Return number of relocatable values contained in this instruction. 1704 return 1; // 1 for polling page. 1705 } 1706 1707 const Pipeline * MachEpilogNode::pipeline() const { 1708 return MachNode::pipeline_class(); 1709 } 1710 1711 // This method seems to be obsolete. It is declared in machnode.hpp 1712 // and defined in all *.ad files, but it is never called. Should we 1713 // get rid of it? 1714 int MachEpilogNode::safepoint_offset() const { 1715 assert(do_polling(), "no return for this epilog node"); 1716 return 4; 1717 } 1718 1719 //============================================================================= 1720 1721 // Figure out which register class each belongs in: rc_int, rc_float or 1722 // rc_stack. 1723 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1724 1725 static enum RC rc_class(OptoReg::Name reg) { 1726 1727 if (reg == OptoReg::Bad) { 1728 return rc_bad; 1729 } 1730 1731 // we have 30 int registers * 2 halves 1732 // (rscratch1 and rscratch2 are omitted) 1733 1734 if (reg < 60) { 1735 return rc_int; 1736 } 1737 1738 // we have 32 float register * 2 halves 1739 if (reg < 60 + 128) { 1740 return rc_float; 1741 } 1742 1743 // Between float regs & stack is the flags regs. 1744 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1745 1746 return rc_stack; 1747 } 1748 1749 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1750 Compile* C = ra_->C; 1751 1752 // Get registers to move. 1753 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1754 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1755 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1756 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1757 1758 enum RC src_hi_rc = rc_class(src_hi); 1759 enum RC src_lo_rc = rc_class(src_lo); 1760 enum RC dst_hi_rc = rc_class(dst_hi); 1761 enum RC dst_lo_rc = rc_class(dst_lo); 1762 1763 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1764 1765 if (src_hi != OptoReg::Bad) { 1766 assert((src_lo&1)==0 && src_lo+1==src_hi && 1767 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1768 "expected aligned-adjacent pairs"); 1769 } 1770 1771 if (src_lo == dst_lo && src_hi == dst_hi) { 1772 return 0; // Self copy, no move. 1773 } 1774 1775 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1776 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1777 int src_offset = ra_->reg2offset(src_lo); 1778 int dst_offset = ra_->reg2offset(dst_lo); 1779 1780 if (bottom_type()->isa_vect() != NULL) { 1781 uint ireg = ideal_reg(); 1782 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1783 if (cbuf) { 1784 MacroAssembler _masm(cbuf); 1785 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1786 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1787 // stack->stack 1788 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1789 if (ireg == Op_VecD) { 1790 __ unspill(rscratch1, true, src_offset); 1791 __ spill(rscratch1, true, dst_offset); 1792 } else { 1793 __ spill_copy128(src_offset, dst_offset); 1794 } 1795 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1796 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1797 ireg == Op_VecD ? __ T8B : __ T16B, 1798 as_FloatRegister(Matcher::_regEncode[src_lo])); 1799 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1800 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1801 ireg == Op_VecD ? __ D : __ Q, 1802 ra_->reg2offset(dst_lo)); 1803 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1804 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1805 ireg == Op_VecD ? __ D : __ Q, 1806 ra_->reg2offset(src_lo)); 1807 } else { 1808 ShouldNotReachHere(); 1809 } 1810 } 1811 } else if (cbuf) { 1812 MacroAssembler _masm(cbuf); 1813 switch (src_lo_rc) { 1814 case rc_int: 1815 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1816 if (is64) { 1817 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1818 as_Register(Matcher::_regEncode[src_lo])); 1819 } else { 1820 MacroAssembler _masm(cbuf); 1821 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1822 as_Register(Matcher::_regEncode[src_lo])); 1823 } 1824 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1825 if (is64) { 1826 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1827 as_Register(Matcher::_regEncode[src_lo])); 1828 } else { 1829 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1830 as_Register(Matcher::_regEncode[src_lo])); 1831 } 1832 } else { // gpr --> stack spill 1833 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1834 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1835 } 1836 break; 1837 case rc_float: 1838 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1839 if (is64) { 1840 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1841 as_FloatRegister(Matcher::_regEncode[src_lo])); 1842 } else { 1843 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1844 as_FloatRegister(Matcher::_regEncode[src_lo])); 1845 } 1846 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1847 if (cbuf) { 1848 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1849 as_FloatRegister(Matcher::_regEncode[src_lo])); 1850 } else { 1851 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1852 as_FloatRegister(Matcher::_regEncode[src_lo])); 1853 } 1854 } else { // fpr --> stack spill 1855 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1856 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1857 is64 ? __ D : __ S, dst_offset); 1858 } 1859 break; 1860 case rc_stack: 1861 if (dst_lo_rc == rc_int) { // stack --> gpr load 1862 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1863 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1864 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1865 is64 ? __ D : __ S, src_offset); 1866 } else { // stack --> stack copy 1867 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1868 __ unspill(rscratch1, is64, src_offset); 1869 __ spill(rscratch1, is64, dst_offset); 1870 } 1871 break; 1872 default: 1873 assert(false, "bad rc_class for spill"); 1874 ShouldNotReachHere(); 1875 } 1876 } 1877 1878 if (st) { 1879 st->print("spill "); 1880 if (src_lo_rc == rc_stack) { 1881 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1882 } else { 1883 st->print("%s -> ", Matcher::regName[src_lo]); 1884 } 1885 if (dst_lo_rc == rc_stack) { 1886 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1887 } else { 1888 st->print("%s", Matcher::regName[dst_lo]); 1889 } 1890 if (bottom_type()->isa_vect() != NULL) { 1891 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1892 } else { 1893 st->print("\t# spill size = %d", is64 ? 64:32); 1894 } 1895 } 1896 1897 return 0; 1898 1899 } 1900 1901 #ifndef PRODUCT 1902 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1903 if (!ra_) 1904 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1905 else 1906 implementation(NULL, ra_, false, st); 1907 } 1908 #endif 1909 1910 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1911 implementation(&cbuf, ra_, false, NULL); 1912 } 1913 1914 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1915 return MachNode::size(ra_); 1916 } 1917 1918 //============================================================================= 1919 1920 #ifndef PRODUCT 1921 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1922 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1923 int reg = ra_->get_reg_first(this); 1924 st->print("add %s, rsp, #%d]\t# box lock", 1925 Matcher::regName[reg], offset); 1926 } 1927 #endif 1928 1929 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1930 MacroAssembler _masm(&cbuf); 1931 1932 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1933 int reg = ra_->get_encode(this); 1934 1935 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1936 __ add(as_Register(reg), sp, offset); 1937 } else { 1938 ShouldNotReachHere(); 1939 } 1940 } 1941 1942 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1943 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1944 return 4; 1945 } 1946 1947 //============================================================================= 1948 1949 #ifndef PRODUCT 1950 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1951 { 1952 st->print_cr("# MachUEPNode"); 1953 if (UseCompressedClassPointers) { 1954 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1955 if (Universe::narrow_klass_shift() != 0) { 1956 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1957 } 1958 } else { 1959 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1960 } 1961 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1962 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1963 } 1964 #endif 1965 1966 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1967 { 1968 // This is the unverified entry point. 1969 MacroAssembler _masm(&cbuf); 1970 1971 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1972 Label skip; 1973 // TODO 1974 // can we avoid this skip and still use a reloc? 1975 __ br(Assembler::EQ, skip); 1976 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1977 __ bind(skip); 1978 } 1979 1980 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1981 { 1982 return MachNode::size(ra_); 1983 } 1984 1985 // REQUIRED EMIT CODE 1986 1987 //============================================================================= 1988 1989 // Emit exception handler code. 1990 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1991 { 1992 // mov rscratch1 #exception_blob_entry_point 1993 // br rscratch1 1994 // Note that the code buffer's insts_mark is always relative to insts. 1995 // That's why we must use the macroassembler to generate a handler. 1996 MacroAssembler _masm(&cbuf); 1997 address base = __ start_a_stub(size_exception_handler()); 1998 if (base == NULL) { 1999 ciEnv::current()->record_failure("CodeCache is full"); 2000 return 0; // CodeBuffer::expand failed 2001 } 2002 int offset = __ offset(); 2003 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2004 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2005 __ end_a_stub(); 2006 return offset; 2007 } 2008 2009 // Emit deopt handler code. 2010 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2011 { 2012 // Note that the code buffer's insts_mark is always relative to insts. 2013 // That's why we must use the macroassembler to generate a handler. 2014 MacroAssembler _masm(&cbuf); 2015 address base = __ start_a_stub(size_deopt_handler()); 2016 if (base == NULL) { 2017 ciEnv::current()->record_failure("CodeCache is full"); 2018 return 0; // CodeBuffer::expand failed 2019 } 2020 int offset = __ offset(); 2021 2022 __ adr(lr, __ pc()); 2023 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2024 2025 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2026 __ end_a_stub(); 2027 return offset; 2028 } 2029 2030 // REQUIRED MATCHER CODE 2031 2032 //============================================================================= 2033 2034 const bool Matcher::match_rule_supported(int opcode) { 2035 2036 switch (opcode) { 2037 default: 2038 break; 2039 } 2040 2041 if (!has_match_rule(opcode)) { 2042 return false; 2043 } 2044 2045 return true; // Per default match rules are supported. 2046 } 2047 2048 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2049 2050 // TODO 2051 // identify extra cases that we might want to provide match rules for 2052 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2053 bool ret_value = match_rule_supported(opcode); 2054 // Add rules here. 2055 2056 return ret_value; // Per default match rules are supported. 2057 } 2058 2059 const bool Matcher::has_predicated_vectors(void) { 2060 return false; 2061 } 2062 2063 const int Matcher::float_pressure(int default_pressure_threshold) { 2064 return default_pressure_threshold; 2065 } 2066 2067 int Matcher::regnum_to_fpu_offset(int regnum) 2068 { 2069 Unimplemented(); 2070 return 0; 2071 } 2072 2073 // Is this branch offset short enough that a short branch can be used? 2074 // 2075 // NOTE: If the platform does not provide any short branch variants, then 2076 // this method should return false for offset 0. 2077 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2078 // The passed offset is relative to address of the branch. 2079 2080 return (-32768 <= offset && offset < 32768); 2081 } 2082 2083 const bool Matcher::isSimpleConstant64(jlong value) { 2084 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2085 // Probably always true, even if a temp register is required. 2086 return true; 2087 } 2088 2089 // true just means we have fast l2f conversion 2090 const bool Matcher::convL2FSupported(void) { 2091 return true; 2092 } 2093 2094 // Vector width in bytes. 2095 const int Matcher::vector_width_in_bytes(BasicType bt) { 2096 int size = MIN2(16,(int)MaxVectorSize); 2097 // Minimum 2 values in vector 2098 if (size < 2*type2aelembytes(bt)) size = 0; 2099 // But never < 4 2100 if (size < 4) size = 0; 2101 return size; 2102 } 2103 2104 // Limits on vector size (number of elements) loaded into vector. 2105 const int Matcher::max_vector_size(const BasicType bt) { 2106 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2107 } 2108 const int Matcher::min_vector_size(const BasicType bt) { 2109 // For the moment limit the vector size to 8 bytes 2110 int size = 8 / type2aelembytes(bt); 2111 if (size < 2) size = 2; 2112 return size; 2113 } 2114 2115 // Vector ideal reg. 2116 const uint Matcher::vector_ideal_reg(int len) { 2117 switch(len) { 2118 case 8: return Op_VecD; 2119 case 16: return Op_VecX; 2120 } 2121 ShouldNotReachHere(); 2122 return 0; 2123 } 2124 2125 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2126 switch(size) { 2127 case 8: return Op_VecD; 2128 case 16: return Op_VecX; 2129 } 2130 ShouldNotReachHere(); 2131 return 0; 2132 } 2133 2134 // AES support not yet implemented 2135 const bool Matcher::pass_original_key_for_aes() { 2136 return false; 2137 } 2138 2139 // aarch64 supports misaligned vectors store/load. 2140 const bool Matcher::misaligned_vectors_ok() { 2141 return true; 2142 } 2143 2144 // false => size gets scaled to BytesPerLong, ok. 2145 const bool Matcher::init_array_count_is_in_bytes = false; 2146 2147 // Use conditional move (CMOVL) 2148 const int Matcher::long_cmove_cost() { 2149 // long cmoves are no more expensive than int cmoves 2150 return 0; 2151 } 2152 2153 const int Matcher::float_cmove_cost() { 2154 // float cmoves are no more expensive than int cmoves 2155 return 0; 2156 } 2157 2158 // Does the CPU require late expand (see block.cpp for description of late expand)? 2159 const bool Matcher::require_postalloc_expand = false; 2160 2161 // Do we need to mask the count passed to shift instructions or does 2162 // the cpu only look at the lower 5/6 bits anyway? 2163 const bool Matcher::need_masked_shift_count = false; 2164 2165 // This affects two different things: 2166 // - how Decode nodes are matched 2167 // - how ImplicitNullCheck opportunities are recognized 2168 // If true, the matcher will try to remove all Decodes and match them 2169 // (as operands) into nodes. NullChecks are not prepared to deal with 2170 // Decodes by final_graph_reshaping(). 2171 // If false, final_graph_reshaping() forces the decode behind the Cmp 2172 // for a NullCheck. The matcher matches the Decode node into a register. 2173 // Implicit_null_check optimization moves the Decode along with the 2174 // memory operation back up before the NullCheck. 2175 bool Matcher::narrow_oop_use_complex_address() { 2176 return Universe::narrow_oop_shift() == 0; 2177 } 2178 2179 bool Matcher::narrow_klass_use_complex_address() { 2180 // TODO 2181 // decide whether we need to set this to true 2182 return false; 2183 } 2184 2185 bool Matcher::const_oop_prefer_decode() { 2186 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2187 return Universe::narrow_oop_base() == NULL; 2188 } 2189 2190 bool Matcher::const_klass_prefer_decode() { 2191 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2192 return Universe::narrow_klass_base() == NULL; 2193 } 2194 2195 // Is it better to copy float constants, or load them directly from 2196 // memory? Intel can load a float constant from a direct address, 2197 // requiring no extra registers. Most RISCs will have to materialize 2198 // an address into a register first, so they would do better to copy 2199 // the constant from stack. 2200 const bool Matcher::rematerialize_float_constants = false; 2201 2202 // If CPU can load and store mis-aligned doubles directly then no 2203 // fixup is needed. Else we split the double into 2 integer pieces 2204 // and move it piece-by-piece. Only happens when passing doubles into 2205 // C code as the Java calling convention forces doubles to be aligned. 2206 const bool Matcher::misaligned_doubles_ok = true; 2207 2208 // No-op on amd64 2209 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2210 Unimplemented(); 2211 } 2212 2213 // Advertise here if the CPU requires explicit rounding operations to 2214 // implement the UseStrictFP mode. 2215 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2216 2217 // Are floats converted to double when stored to stack during 2218 // deoptimization? 2219 bool Matcher::float_in_double() { return false; } 2220 2221 // Do ints take an entire long register or just half? 2222 // The relevant question is how the int is callee-saved: 2223 // the whole long is written but de-opt'ing will have to extract 2224 // the relevant 32 bits. 2225 const bool Matcher::int_in_long = true; 2226 2227 // Return whether or not this register is ever used as an argument. 2228 // This function is used on startup to build the trampoline stubs in 2229 // generateOptoStub. Registers not mentioned will be killed by the VM 2230 // call in the trampoline, and arguments in those registers not be 2231 // available to the callee. 2232 bool Matcher::can_be_java_arg(int reg) 2233 { 2234 return 2235 reg == R0_num || reg == R0_H_num || 2236 reg == R1_num || reg == R1_H_num || 2237 reg == R2_num || reg == R2_H_num || 2238 reg == R3_num || reg == R3_H_num || 2239 reg == R4_num || reg == R4_H_num || 2240 reg == R5_num || reg == R5_H_num || 2241 reg == R6_num || reg == R6_H_num || 2242 reg == R7_num || reg == R7_H_num || 2243 reg == V0_num || reg == V0_H_num || 2244 reg == V1_num || reg == V1_H_num || 2245 reg == V2_num || reg == V2_H_num || 2246 reg == V3_num || reg == V3_H_num || 2247 reg == V4_num || reg == V4_H_num || 2248 reg == V5_num || reg == V5_H_num || 2249 reg == V6_num || reg == V6_H_num || 2250 reg == V7_num || reg == V7_H_num; 2251 } 2252 2253 bool Matcher::is_spillable_arg(int reg) 2254 { 2255 return can_be_java_arg(reg); 2256 } 2257 2258 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2259 return false; 2260 } 2261 2262 RegMask Matcher::divI_proj_mask() { 2263 ShouldNotReachHere(); 2264 return RegMask(); 2265 } 2266 2267 // Register for MODI projection of divmodI. 2268 RegMask Matcher::modI_proj_mask() { 2269 ShouldNotReachHere(); 2270 return RegMask(); 2271 } 2272 2273 // Register for DIVL projection of divmodL. 2274 RegMask Matcher::divL_proj_mask() { 2275 ShouldNotReachHere(); 2276 return RegMask(); 2277 } 2278 2279 // Register for MODL projection of divmodL. 2280 RegMask Matcher::modL_proj_mask() { 2281 ShouldNotReachHere(); 2282 return RegMask(); 2283 } 2284 2285 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2286 return FP_REG_mask(); 2287 } 2288 2289 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2290 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2291 Node* u = addp->fast_out(i); 2292 if (u->is_Mem()) { 2293 int opsize = u->as_Mem()->memory_size(); 2294 assert(opsize > 0, "unexpected memory operand size"); 2295 if (u->as_Mem()->memory_size() != (1<<shift)) { 2296 return false; 2297 } 2298 } 2299 } 2300 return true; 2301 } 2302 2303 const bool Matcher::convi2l_type_required = false; 2304 2305 // Should the Matcher clone shifts on addressing modes, expecting them 2306 // to be subsumed into complex addressing expressions or compute them 2307 // into registers? 2308 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2309 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2310 return true; 2311 } 2312 2313 Node *off = m->in(AddPNode::Offset); 2314 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2315 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2316 // Are there other uses besides address expressions? 2317 !is_visited(off)) { 2318 address_visited.set(off->_idx); // Flag as address_visited 2319 mstack.push(off->in(2), Visit); 2320 Node *conv = off->in(1); 2321 if (conv->Opcode() == Op_ConvI2L && 2322 // Are there other uses besides address expressions? 2323 !is_visited(conv)) { 2324 address_visited.set(conv->_idx); // Flag as address_visited 2325 mstack.push(conv->in(1), Pre_Visit); 2326 } else { 2327 mstack.push(conv, Pre_Visit); 2328 } 2329 address_visited.test_set(m->_idx); // Flag as address_visited 2330 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2331 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2332 return true; 2333 } else if (off->Opcode() == Op_ConvI2L && 2334 // Are there other uses besides address expressions? 2335 !is_visited(off)) { 2336 address_visited.test_set(m->_idx); // Flag as address_visited 2337 address_visited.set(off->_idx); // Flag as address_visited 2338 mstack.push(off->in(1), Pre_Visit); 2339 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2340 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2341 return true; 2342 } 2343 return false; 2344 } 2345 2346 void Compile::reshape_address(AddPNode* addp) { 2347 } 2348 2349 2350 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2351 MacroAssembler _masm(&cbuf); \ 2352 { \ 2353 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2354 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2355 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2356 __ INSN(REG, as_Register(BASE)); \ 2357 } 2358 2359 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2360 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2361 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2362 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2363 2364 // Used for all non-volatile memory accesses. The use of 2365 // $mem->opcode() to discover whether this pattern uses sign-extended 2366 // offsets is something of a kludge. 2367 static void loadStore(MacroAssembler masm, mem_insn insn, 2368 Register reg, int opcode, 2369 Register base, int index, int size, int disp) 2370 { 2371 Address::extend scale; 2372 2373 // Hooboy, this is fugly. We need a way to communicate to the 2374 // encoder that the index needs to be sign extended, so we have to 2375 // enumerate all the cases. 2376 switch (opcode) { 2377 case INDINDEXSCALEDI2L: 2378 case INDINDEXSCALEDI2LN: 2379 case INDINDEXI2L: 2380 case INDINDEXI2LN: 2381 scale = Address::sxtw(size); 2382 break; 2383 default: 2384 scale = Address::lsl(size); 2385 } 2386 2387 if (index == -1) { 2388 (masm.*insn)(reg, Address(base, disp)); 2389 } else { 2390 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2391 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2392 } 2393 } 2394 2395 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2396 FloatRegister reg, int opcode, 2397 Register base, int index, int size, int disp) 2398 { 2399 Address::extend scale; 2400 2401 switch (opcode) { 2402 case INDINDEXSCALEDI2L: 2403 case INDINDEXSCALEDI2LN: 2404 scale = Address::sxtw(size); 2405 break; 2406 default: 2407 scale = Address::lsl(size); 2408 } 2409 2410 if (index == -1) { 2411 (masm.*insn)(reg, Address(base, disp)); 2412 } else { 2413 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2414 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2415 } 2416 } 2417 2418 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2419 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2420 int opcode, Register base, int index, int size, int disp) 2421 { 2422 if (index == -1) { 2423 (masm.*insn)(reg, T, Address(base, disp)); 2424 } else { 2425 assert(disp == 0, "unsupported address mode"); 2426 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2427 } 2428 } 2429 2430 %} 2431 2432 2433 2434 //----------ENCODING BLOCK----------------------------------------------------- 2435 // This block specifies the encoding classes used by the compiler to 2436 // output byte streams. Encoding classes are parameterized macros 2437 // used by Machine Instruction Nodes in order to generate the bit 2438 // encoding of the instruction. Operands specify their base encoding 2439 // interface with the interface keyword. There are currently 2440 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2441 // COND_INTER. REG_INTER causes an operand to generate a function 2442 // which returns its register number when queried. CONST_INTER causes 2443 // an operand to generate a function which returns the value of the 2444 // constant when queried. MEMORY_INTER causes an operand to generate 2445 // four functions which return the Base Register, the Index Register, 2446 // the Scale Value, and the Offset Value of the operand when queried. 2447 // COND_INTER causes an operand to generate six functions which return 2448 // the encoding code (ie - encoding bits for the instruction) 2449 // associated with each basic boolean condition for a conditional 2450 // instruction. 2451 // 2452 // Instructions specify two basic values for encoding. Again, a 2453 // function is available to check if the constant displacement is an 2454 // oop. They use the ins_encode keyword to specify their encoding 2455 // classes (which must be a sequence of enc_class names, and their 2456 // parameters, specified in the encoding block), and they use the 2457 // opcode keyword to specify, in order, their primary, secondary, and 2458 // tertiary opcode. Only the opcode sections which a particular 2459 // instruction needs for encoding need to be specified. 2460 encode %{ 2461 // Build emit functions for each basic byte or larger field in the 2462 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2463 // from C++ code in the enc_class source block. Emit functions will 2464 // live in the main source block for now. In future, we can 2465 // generalize this by adding a syntax that specifies the sizes of 2466 // fields in an order, so that the adlc can build the emit functions 2467 // automagically 2468 2469 // catch all for unimplemented encodings 2470 enc_class enc_unimplemented %{ 2471 MacroAssembler _masm(&cbuf); 2472 __ unimplemented("C2 catch all"); 2473 %} 2474 2475 // BEGIN Non-volatile memory access 2476 2477 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2478 Register dst_reg = as_Register($dst$$reg); 2479 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2480 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2481 %} 2482 2483 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2484 Register dst_reg = as_Register($dst$$reg); 2485 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2486 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2487 %} 2488 2489 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2490 Register dst_reg = as_Register($dst$$reg); 2491 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2492 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2493 %} 2494 2495 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2496 Register dst_reg = as_Register($dst$$reg); 2497 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2498 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2499 %} 2500 2501 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2502 Register dst_reg = as_Register($dst$$reg); 2503 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2504 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2505 %} 2506 2507 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2508 Register dst_reg = as_Register($dst$$reg); 2509 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2510 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2511 %} 2512 2513 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2514 Register dst_reg = as_Register($dst$$reg); 2515 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2516 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2517 %} 2518 2519 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2520 Register dst_reg = as_Register($dst$$reg); 2521 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2522 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2523 %} 2524 2525 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2526 Register dst_reg = as_Register($dst$$reg); 2527 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2528 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2529 %} 2530 2531 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2532 Register dst_reg = as_Register($dst$$reg); 2533 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2534 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2535 %} 2536 2537 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2538 Register dst_reg = as_Register($dst$$reg); 2539 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2540 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2541 %} 2542 2543 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2544 Register dst_reg = as_Register($dst$$reg); 2545 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2546 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2547 %} 2548 2549 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2550 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2551 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2552 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2553 %} 2554 2555 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2556 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2557 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2558 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2559 %} 2560 2561 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2562 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2563 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2564 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2565 %} 2566 2567 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2568 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2569 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2570 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2571 %} 2572 2573 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2574 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2575 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2576 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2577 %} 2578 2579 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2580 Register src_reg = as_Register($src$$reg); 2581 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2582 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2583 %} 2584 2585 enc_class aarch64_enc_strb0(memory mem) %{ 2586 MacroAssembler _masm(&cbuf); 2587 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2588 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2589 %} 2590 2591 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2592 MacroAssembler _masm(&cbuf); 2593 __ membar(Assembler::StoreStore); 2594 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2595 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2596 %} 2597 2598 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2599 Register src_reg = as_Register($src$$reg); 2600 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2601 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2602 %} 2603 2604 enc_class aarch64_enc_strh0(memory mem) %{ 2605 MacroAssembler _masm(&cbuf); 2606 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2607 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2608 %} 2609 2610 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2611 Register src_reg = as_Register($src$$reg); 2612 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2613 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2614 %} 2615 2616 enc_class aarch64_enc_strw0(memory mem) %{ 2617 MacroAssembler _masm(&cbuf); 2618 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2619 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2620 %} 2621 2622 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2623 Register src_reg = as_Register($src$$reg); 2624 // we sometimes get asked to store the stack pointer into the 2625 // current thread -- we cannot do that directly on AArch64 2626 if (src_reg == r31_sp) { 2627 MacroAssembler _masm(&cbuf); 2628 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2629 __ mov(rscratch2, sp); 2630 src_reg = rscratch2; 2631 } 2632 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2633 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2634 %} 2635 2636 enc_class aarch64_enc_str0(memory mem) %{ 2637 MacroAssembler _masm(&cbuf); 2638 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2639 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2640 %} 2641 2642 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2643 FloatRegister src_reg = as_FloatRegister($src$$reg); 2644 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2645 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2646 %} 2647 2648 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2649 FloatRegister src_reg = as_FloatRegister($src$$reg); 2650 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2651 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2652 %} 2653 2654 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2655 FloatRegister src_reg = as_FloatRegister($src$$reg); 2656 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2657 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2658 %} 2659 2660 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2661 FloatRegister src_reg = as_FloatRegister($src$$reg); 2662 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2663 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2664 %} 2665 2666 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2667 FloatRegister src_reg = as_FloatRegister($src$$reg); 2668 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2669 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2670 %} 2671 2672 // END Non-volatile memory access 2673 2674 // volatile loads and stores 2675 2676 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2677 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2678 rscratch1, stlrb); 2679 %} 2680 2681 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2682 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2683 rscratch1, stlrh); 2684 %} 2685 2686 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2687 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2688 rscratch1, stlrw); 2689 %} 2690 2691 2692 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2693 Register dst_reg = as_Register($dst$$reg); 2694 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2695 rscratch1, ldarb); 2696 __ sxtbw(dst_reg, dst_reg); 2697 %} 2698 2699 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2700 Register dst_reg = as_Register($dst$$reg); 2701 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2702 rscratch1, ldarb); 2703 __ sxtb(dst_reg, dst_reg); 2704 %} 2705 2706 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2707 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2708 rscratch1, ldarb); 2709 %} 2710 2711 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2712 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2713 rscratch1, ldarb); 2714 %} 2715 2716 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2717 Register dst_reg = as_Register($dst$$reg); 2718 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2719 rscratch1, ldarh); 2720 __ sxthw(dst_reg, dst_reg); 2721 %} 2722 2723 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2724 Register dst_reg = as_Register($dst$$reg); 2725 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2726 rscratch1, ldarh); 2727 __ sxth(dst_reg, dst_reg); 2728 %} 2729 2730 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2731 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2732 rscratch1, ldarh); 2733 %} 2734 2735 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2736 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2737 rscratch1, ldarh); 2738 %} 2739 2740 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2741 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2742 rscratch1, ldarw); 2743 %} 2744 2745 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2746 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2747 rscratch1, ldarw); 2748 %} 2749 2750 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2751 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2752 rscratch1, ldar); 2753 %} 2754 2755 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2756 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2757 rscratch1, ldarw); 2758 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2759 %} 2760 2761 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2762 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2763 rscratch1, ldar); 2764 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2765 %} 2766 2767 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2768 Register src_reg = as_Register($src$$reg); 2769 // we sometimes get asked to store the stack pointer into the 2770 // current thread -- we cannot do that directly on AArch64 2771 if (src_reg == r31_sp) { 2772 MacroAssembler _masm(&cbuf); 2773 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2774 __ mov(rscratch2, sp); 2775 src_reg = rscratch2; 2776 } 2777 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2778 rscratch1, stlr); 2779 %} 2780 2781 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2782 { 2783 MacroAssembler _masm(&cbuf); 2784 FloatRegister src_reg = as_FloatRegister($src$$reg); 2785 __ fmovs(rscratch2, src_reg); 2786 } 2787 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2788 rscratch1, stlrw); 2789 %} 2790 2791 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2792 { 2793 MacroAssembler _masm(&cbuf); 2794 FloatRegister src_reg = as_FloatRegister($src$$reg); 2795 __ fmovd(rscratch2, src_reg); 2796 } 2797 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2798 rscratch1, stlr); 2799 %} 2800 2801 // synchronized read/update encodings 2802 2803 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2804 MacroAssembler _masm(&cbuf); 2805 Register dst_reg = as_Register($dst$$reg); 2806 Register base = as_Register($mem$$base); 2807 int index = $mem$$index; 2808 int scale = $mem$$scale; 2809 int disp = $mem$$disp; 2810 if (index == -1) { 2811 if (disp != 0) { 2812 __ lea(rscratch1, Address(base, disp)); 2813 __ ldaxr(dst_reg, rscratch1); 2814 } else { 2815 // TODO 2816 // should we ever get anything other than this case? 2817 __ ldaxr(dst_reg, base); 2818 } 2819 } else { 2820 Register index_reg = as_Register(index); 2821 if (disp == 0) { 2822 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2823 __ ldaxr(dst_reg, rscratch1); 2824 } else { 2825 __ lea(rscratch1, Address(base, disp)); 2826 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2827 __ ldaxr(dst_reg, rscratch1); 2828 } 2829 } 2830 %} 2831 2832 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2833 MacroAssembler _masm(&cbuf); 2834 Register src_reg = as_Register($src$$reg); 2835 Register base = as_Register($mem$$base); 2836 int index = $mem$$index; 2837 int scale = $mem$$scale; 2838 int disp = $mem$$disp; 2839 if (index == -1) { 2840 if (disp != 0) { 2841 __ lea(rscratch2, Address(base, disp)); 2842 __ stlxr(rscratch1, src_reg, rscratch2); 2843 } else { 2844 // TODO 2845 // should we ever get anything other than this case? 2846 __ stlxr(rscratch1, src_reg, base); 2847 } 2848 } else { 2849 Register index_reg = as_Register(index); 2850 if (disp == 0) { 2851 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2852 __ stlxr(rscratch1, src_reg, rscratch2); 2853 } else { 2854 __ lea(rscratch2, Address(base, disp)); 2855 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2856 __ stlxr(rscratch1, src_reg, rscratch2); 2857 } 2858 } 2859 __ cmpw(rscratch1, zr); 2860 %} 2861 2862 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2863 MacroAssembler _masm(&cbuf); 2864 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2865 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2866 Assembler::xword, /*acquire*/ false, /*release*/ true, 2867 /*weak*/ false, noreg); 2868 %} 2869 2870 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2871 MacroAssembler _masm(&cbuf); 2872 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2873 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2874 Assembler::word, /*acquire*/ false, /*release*/ true, 2875 /*weak*/ false, noreg); 2876 %} 2877 2878 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2879 MacroAssembler _masm(&cbuf); 2880 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2881 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2882 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2883 /*weak*/ false, noreg); 2884 %} 2885 2886 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2887 MacroAssembler _masm(&cbuf); 2888 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2889 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2890 Assembler::byte, /*acquire*/ false, /*release*/ true, 2891 /*weak*/ false, noreg); 2892 %} 2893 2894 2895 // The only difference between aarch64_enc_cmpxchg and 2896 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2897 // CompareAndSwap sequence to serve as a barrier on acquiring a 2898 // lock. 2899 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2900 MacroAssembler _masm(&cbuf); 2901 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2902 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2903 Assembler::xword, /*acquire*/ true, /*release*/ true, 2904 /*weak*/ false, noreg); 2905 %} 2906 2907 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2908 MacroAssembler _masm(&cbuf); 2909 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2910 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2911 Assembler::word, /*acquire*/ true, /*release*/ true, 2912 /*weak*/ false, noreg); 2913 %} 2914 2915 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2916 MacroAssembler _masm(&cbuf); 2917 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2918 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2919 Assembler::halfword, /*acquire*/ true, /*release*/ true, 2920 /*weak*/ false, noreg); 2921 %} 2922 2923 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2924 MacroAssembler _masm(&cbuf); 2925 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2926 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2927 Assembler::byte, /*acquire*/ true, /*release*/ true, 2928 /*weak*/ false, noreg); 2929 %} 2930 2931 // auxiliary used for CompareAndSwapX to set result register 2932 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2933 MacroAssembler _masm(&cbuf); 2934 Register res_reg = as_Register($res$$reg); 2935 __ cset(res_reg, Assembler::EQ); 2936 %} 2937 2938 // prefetch encodings 2939 2940 enc_class aarch64_enc_prefetchw(memory mem) %{ 2941 MacroAssembler _masm(&cbuf); 2942 Register base = as_Register($mem$$base); 2943 int index = $mem$$index; 2944 int scale = $mem$$scale; 2945 int disp = $mem$$disp; 2946 if (index == -1) { 2947 __ prfm(Address(base, disp), PSTL1KEEP); 2948 } else { 2949 Register index_reg = as_Register(index); 2950 if (disp == 0) { 2951 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2952 } else { 2953 __ lea(rscratch1, Address(base, disp)); 2954 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2955 } 2956 } 2957 %} 2958 2959 /// mov envcodings 2960 2961 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2962 MacroAssembler _masm(&cbuf); 2963 u_int32_t con = (u_int32_t)$src$$constant; 2964 Register dst_reg = as_Register($dst$$reg); 2965 if (con == 0) { 2966 __ movw(dst_reg, zr); 2967 } else { 2968 __ movw(dst_reg, con); 2969 } 2970 %} 2971 2972 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2973 MacroAssembler _masm(&cbuf); 2974 Register dst_reg = as_Register($dst$$reg); 2975 u_int64_t con = (u_int64_t)$src$$constant; 2976 if (con == 0) { 2977 __ mov(dst_reg, zr); 2978 } else { 2979 __ mov(dst_reg, con); 2980 } 2981 %} 2982 2983 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 2984 MacroAssembler _masm(&cbuf); 2985 Register dst_reg = as_Register($dst$$reg); 2986 address con = (address)$src$$constant; 2987 if (con == NULL || con == (address)1) { 2988 ShouldNotReachHere(); 2989 } else { 2990 relocInfo::relocType rtype = $src->constant_reloc(); 2991 if (rtype == relocInfo::oop_type) { 2992 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 2993 } else if (rtype == relocInfo::metadata_type) { 2994 __ mov_metadata(dst_reg, (Metadata*)con); 2995 } else { 2996 assert(rtype == relocInfo::none, "unexpected reloc type"); 2997 if (con < (address)(uintptr_t)os::vm_page_size()) { 2998 __ mov(dst_reg, con); 2999 } else { 3000 unsigned long offset; 3001 __ adrp(dst_reg, con, offset); 3002 __ add(dst_reg, dst_reg, offset); 3003 } 3004 } 3005 } 3006 %} 3007 3008 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3009 MacroAssembler _masm(&cbuf); 3010 Register dst_reg = as_Register($dst$$reg); 3011 __ mov(dst_reg, zr); 3012 %} 3013 3014 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3015 MacroAssembler _masm(&cbuf); 3016 Register dst_reg = as_Register($dst$$reg); 3017 __ mov(dst_reg, (u_int64_t)1); 3018 %} 3019 3020 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3021 MacroAssembler _masm(&cbuf); 3022 address page = (address)$src$$constant; 3023 Register dst_reg = as_Register($dst$$reg); 3024 unsigned long off; 3025 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3026 assert(off == 0, "assumed offset == 0"); 3027 %} 3028 3029 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3030 MacroAssembler _masm(&cbuf); 3031 __ load_byte_map_base($dst$$Register); 3032 %} 3033 3034 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3035 MacroAssembler _masm(&cbuf); 3036 Register dst_reg = as_Register($dst$$reg); 3037 address con = (address)$src$$constant; 3038 if (con == NULL) { 3039 ShouldNotReachHere(); 3040 } else { 3041 relocInfo::relocType rtype = $src->constant_reloc(); 3042 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3043 __ set_narrow_oop(dst_reg, (jobject)con); 3044 } 3045 %} 3046 3047 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3048 MacroAssembler _masm(&cbuf); 3049 Register dst_reg = as_Register($dst$$reg); 3050 __ mov(dst_reg, zr); 3051 %} 3052 3053 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3054 MacroAssembler _masm(&cbuf); 3055 Register dst_reg = as_Register($dst$$reg); 3056 address con = (address)$src$$constant; 3057 if (con == NULL) { 3058 ShouldNotReachHere(); 3059 } else { 3060 relocInfo::relocType rtype = $src->constant_reloc(); 3061 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3062 __ set_narrow_klass(dst_reg, (Klass *)con); 3063 } 3064 %} 3065 3066 // arithmetic encodings 3067 3068 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3069 MacroAssembler _masm(&cbuf); 3070 Register dst_reg = as_Register($dst$$reg); 3071 Register src_reg = as_Register($src1$$reg); 3072 int32_t con = (int32_t)$src2$$constant; 3073 // add has primary == 0, subtract has primary == 1 3074 if ($primary) { con = -con; } 3075 if (con < 0) { 3076 __ subw(dst_reg, src_reg, -con); 3077 } else { 3078 __ addw(dst_reg, src_reg, con); 3079 } 3080 %} 3081 3082 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3083 MacroAssembler _masm(&cbuf); 3084 Register dst_reg = as_Register($dst$$reg); 3085 Register src_reg = as_Register($src1$$reg); 3086 int32_t con = (int32_t)$src2$$constant; 3087 // add has primary == 0, subtract has primary == 1 3088 if ($primary) { con = -con; } 3089 if (con < 0) { 3090 __ sub(dst_reg, src_reg, -con); 3091 } else { 3092 __ add(dst_reg, src_reg, con); 3093 } 3094 %} 3095 3096 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3097 MacroAssembler _masm(&cbuf); 3098 Register dst_reg = as_Register($dst$$reg); 3099 Register src1_reg = as_Register($src1$$reg); 3100 Register src2_reg = as_Register($src2$$reg); 3101 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3102 %} 3103 3104 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3105 MacroAssembler _masm(&cbuf); 3106 Register dst_reg = as_Register($dst$$reg); 3107 Register src1_reg = as_Register($src1$$reg); 3108 Register src2_reg = as_Register($src2$$reg); 3109 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3110 %} 3111 3112 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3113 MacroAssembler _masm(&cbuf); 3114 Register dst_reg = as_Register($dst$$reg); 3115 Register src1_reg = as_Register($src1$$reg); 3116 Register src2_reg = as_Register($src2$$reg); 3117 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3118 %} 3119 3120 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3121 MacroAssembler _masm(&cbuf); 3122 Register dst_reg = as_Register($dst$$reg); 3123 Register src1_reg = as_Register($src1$$reg); 3124 Register src2_reg = as_Register($src2$$reg); 3125 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3126 %} 3127 3128 // compare instruction encodings 3129 3130 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3131 MacroAssembler _masm(&cbuf); 3132 Register reg1 = as_Register($src1$$reg); 3133 Register reg2 = as_Register($src2$$reg); 3134 __ cmpw(reg1, reg2); 3135 %} 3136 3137 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3138 MacroAssembler _masm(&cbuf); 3139 Register reg = as_Register($src1$$reg); 3140 int32_t val = $src2$$constant; 3141 if (val >= 0) { 3142 __ subsw(zr, reg, val); 3143 } else { 3144 __ addsw(zr, reg, -val); 3145 } 3146 %} 3147 3148 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3149 MacroAssembler _masm(&cbuf); 3150 Register reg1 = as_Register($src1$$reg); 3151 u_int32_t val = (u_int32_t)$src2$$constant; 3152 __ movw(rscratch1, val); 3153 __ cmpw(reg1, rscratch1); 3154 %} 3155 3156 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3157 MacroAssembler _masm(&cbuf); 3158 Register reg1 = as_Register($src1$$reg); 3159 Register reg2 = as_Register($src2$$reg); 3160 __ cmp(reg1, reg2); 3161 %} 3162 3163 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3164 MacroAssembler _masm(&cbuf); 3165 Register reg = as_Register($src1$$reg); 3166 int64_t val = $src2$$constant; 3167 if (val >= 0) { 3168 __ subs(zr, reg, val); 3169 } else if (val != -val) { 3170 __ adds(zr, reg, -val); 3171 } else { 3172 // aargh, Long.MIN_VALUE is a special case 3173 __ orr(rscratch1, zr, (u_int64_t)val); 3174 __ subs(zr, reg, rscratch1); 3175 } 3176 %} 3177 3178 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3179 MacroAssembler _masm(&cbuf); 3180 Register reg1 = as_Register($src1$$reg); 3181 u_int64_t val = (u_int64_t)$src2$$constant; 3182 __ mov(rscratch1, val); 3183 __ cmp(reg1, rscratch1); 3184 %} 3185 3186 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3187 MacroAssembler _masm(&cbuf); 3188 Register reg1 = as_Register($src1$$reg); 3189 Register reg2 = as_Register($src2$$reg); 3190 __ cmp(reg1, reg2); 3191 %} 3192 3193 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3194 MacroAssembler _masm(&cbuf); 3195 Register reg1 = as_Register($src1$$reg); 3196 Register reg2 = as_Register($src2$$reg); 3197 __ cmpw(reg1, reg2); 3198 %} 3199 3200 enc_class aarch64_enc_testp(iRegP src) %{ 3201 MacroAssembler _masm(&cbuf); 3202 Register reg = as_Register($src$$reg); 3203 __ cmp(reg, zr); 3204 %} 3205 3206 enc_class aarch64_enc_testn(iRegN src) %{ 3207 MacroAssembler _masm(&cbuf); 3208 Register reg = as_Register($src$$reg); 3209 __ cmpw(reg, zr); 3210 %} 3211 3212 enc_class aarch64_enc_b(label lbl) %{ 3213 MacroAssembler _masm(&cbuf); 3214 Label *L = $lbl$$label; 3215 __ b(*L); 3216 %} 3217 3218 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3219 MacroAssembler _masm(&cbuf); 3220 Label *L = $lbl$$label; 3221 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3222 %} 3223 3224 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3225 MacroAssembler _masm(&cbuf); 3226 Label *L = $lbl$$label; 3227 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3228 %} 3229 3230 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3231 %{ 3232 Register sub_reg = as_Register($sub$$reg); 3233 Register super_reg = as_Register($super$$reg); 3234 Register temp_reg = as_Register($temp$$reg); 3235 Register result_reg = as_Register($result$$reg); 3236 3237 Label miss; 3238 MacroAssembler _masm(&cbuf); 3239 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3240 NULL, &miss, 3241 /*set_cond_codes:*/ true); 3242 if ($primary) { 3243 __ mov(result_reg, zr); 3244 } 3245 __ bind(miss); 3246 %} 3247 3248 enc_class aarch64_enc_java_static_call(method meth) %{ 3249 MacroAssembler _masm(&cbuf); 3250 3251 address addr = (address)$meth$$method; 3252 address call; 3253 if (!_method) { 3254 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3255 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3256 } else { 3257 int method_index = resolved_method_index(cbuf); 3258 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3259 : static_call_Relocation::spec(method_index); 3260 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3261 3262 // Emit stub for static call 3263 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3264 if (stub == NULL) { 3265 ciEnv::current()->record_failure("CodeCache is full"); 3266 return; 3267 } 3268 } 3269 if (call == NULL) { 3270 ciEnv::current()->record_failure("CodeCache is full"); 3271 return; 3272 } 3273 %} 3274 3275 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3276 MacroAssembler _masm(&cbuf); 3277 int method_index = resolved_method_index(cbuf); 3278 address call = __ ic_call((address)$meth$$method, method_index); 3279 if (call == NULL) { 3280 ciEnv::current()->record_failure("CodeCache is full"); 3281 return; 3282 } 3283 %} 3284 3285 enc_class aarch64_enc_call_epilog() %{ 3286 MacroAssembler _masm(&cbuf); 3287 if (VerifyStackAtCalls) { 3288 // Check that stack depth is unchanged: find majik cookie on stack 3289 __ call_Unimplemented(); 3290 } 3291 %} 3292 3293 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3294 MacroAssembler _masm(&cbuf); 3295 3296 // some calls to generated routines (arraycopy code) are scheduled 3297 // by C2 as runtime calls. if so we can call them using a br (they 3298 // will be in a reachable segment) otherwise we have to use a blr 3299 // which loads the absolute address into a register. 3300 address entry = (address)$meth$$method; 3301 CodeBlob *cb = CodeCache::find_blob(entry); 3302 if (cb) { 3303 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3304 if (call == NULL) { 3305 ciEnv::current()->record_failure("CodeCache is full"); 3306 return; 3307 } 3308 } else { 3309 Label retaddr; 3310 __ adr(rscratch2, retaddr); 3311 __ lea(rscratch1, RuntimeAddress(entry)); 3312 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3313 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3314 __ blr(rscratch1); 3315 __ bind(retaddr); 3316 __ add(sp, sp, 2 * wordSize); 3317 } 3318 %} 3319 3320 enc_class aarch64_enc_rethrow() %{ 3321 MacroAssembler _masm(&cbuf); 3322 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3323 %} 3324 3325 enc_class aarch64_enc_ret() %{ 3326 MacroAssembler _masm(&cbuf); 3327 __ ret(lr); 3328 %} 3329 3330 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3331 MacroAssembler _masm(&cbuf); 3332 Register target_reg = as_Register($jump_target$$reg); 3333 __ br(target_reg); 3334 %} 3335 3336 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3337 MacroAssembler _masm(&cbuf); 3338 Register target_reg = as_Register($jump_target$$reg); 3339 // exception oop should be in r0 3340 // ret addr has been popped into lr 3341 // callee expects it in r3 3342 __ mov(r3, lr); 3343 __ br(target_reg); 3344 %} 3345 3346 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3347 MacroAssembler _masm(&cbuf); 3348 Register oop = as_Register($object$$reg); 3349 Register box = as_Register($box$$reg); 3350 Register disp_hdr = as_Register($tmp$$reg); 3351 Register tmp = as_Register($tmp2$$reg); 3352 Label cont; 3353 Label object_has_monitor; 3354 Label cas_failed; 3355 3356 assert_different_registers(oop, box, tmp, disp_hdr); 3357 3358 // Load markOop from object into displaced_header. 3359 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3360 3361 // Always do locking in runtime. 3362 if (EmitSync & 0x01) { 3363 __ cmp(oop, zr); 3364 return; 3365 } 3366 3367 if (UseBiasedLocking && !UseOptoBiasInlining) { 3368 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3369 } 3370 3371 // Check for existing monitor 3372 if ((EmitSync & 0x02) == 0) { 3373 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3374 } 3375 3376 // Set tmp to be (markOop of object | UNLOCK_VALUE). 3377 __ orr(tmp, disp_hdr, markOopDesc::unlocked_value); 3378 3379 // Initialize the box. (Must happen before we update the object mark!) 3380 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3381 3382 // Compare object markOop with an unlocked value (tmp) and if 3383 // equal exchange the stack address of our box with object markOop. 3384 // On failure disp_hdr contains the possibly locked markOop. 3385 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3386 /*release*/ true, /*weak*/ false, disp_hdr); 3387 __ br(Assembler::EQ, cont); 3388 3389 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3390 3391 // If the compare-and-exchange succeeded, then we found an unlocked 3392 // object, will have now locked it will continue at label cont 3393 3394 __ bind(cas_failed); 3395 // We did not see an unlocked object so try the fast recursive case. 3396 3397 // Check if the owner is self by comparing the value in the 3398 // markOop of object (disp_hdr) with the stack pointer. 3399 __ mov(rscratch1, sp); 3400 __ sub(disp_hdr, disp_hdr, rscratch1); 3401 __ mov(tmp, (address) (~(os::vm_page_size()-1) | (uintptr_t)markOopDesc::lock_mask_in_place)); 3402 // If condition is true we are cont and hence we can store 0 as the 3403 // displaced header in the box, which indicates that it is a recursive lock. 3404 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3405 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3406 3407 if ((EmitSync & 0x02) == 0) { 3408 __ b(cont); 3409 3410 // Handle existing monitor. 3411 __ bind(object_has_monitor); 3412 // The object's monitor m is unlocked iff m->owner == NULL, 3413 // otherwise m->owner may contain a thread or a stack address. 3414 // 3415 // Try to CAS m->owner from NULL to current thread. 3416 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3417 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3418 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3419 3420 // Store a non-null value into the box to avoid looking like a re-entrant 3421 // lock. The fast-path monitor unlock code checks for 3422 // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the 3423 // relevant bit set, and also matches ObjectSynchronizer::slow_enter. 3424 __ mov(tmp, (address)markOopDesc::unused_mark()); 3425 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3426 } 3427 3428 __ bind(cont); 3429 // flag == EQ indicates success 3430 // flag == NE indicates failure 3431 %} 3432 3433 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3434 MacroAssembler _masm(&cbuf); 3435 Register oop = as_Register($object$$reg); 3436 Register box = as_Register($box$$reg); 3437 Register disp_hdr = as_Register($tmp$$reg); 3438 Register tmp = as_Register($tmp2$$reg); 3439 Label cont; 3440 Label object_has_monitor; 3441 3442 assert_different_registers(oop, box, tmp, disp_hdr); 3443 3444 // Always do locking in runtime. 3445 if (EmitSync & 0x01) { 3446 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3447 return; 3448 } 3449 3450 if (UseBiasedLocking && !UseOptoBiasInlining) { 3451 __ biased_locking_exit(oop, tmp, cont); 3452 } 3453 3454 // Find the lock address and load the displaced header from the stack. 3455 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3456 3457 // If the displaced header is 0, we have a recursive unlock. 3458 __ cmp(disp_hdr, zr); 3459 __ br(Assembler::EQ, cont); 3460 3461 // Handle existing monitor. 3462 if ((EmitSync & 0x02) == 0) { 3463 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3464 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3465 } 3466 3467 // Check if it is still a light weight lock, this is is true if we 3468 // see the stack address of the basicLock in the markOop of the 3469 // object. 3470 3471 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3472 /*release*/ true, /*weak*/ false, tmp); 3473 __ b(cont); 3474 3475 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3476 3477 // Handle existing monitor. 3478 if ((EmitSync & 0x02) == 0) { 3479 __ bind(object_has_monitor); 3480 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3481 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3482 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3483 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3484 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3485 __ cmp(rscratch1, zr); // Sets flags for result 3486 __ br(Assembler::NE, cont); 3487 3488 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3489 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3490 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3491 __ cmp(rscratch1, zr); // Sets flags for result 3492 __ cbnz(rscratch1, cont); 3493 // need a release store here 3494 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3495 __ stlr(zr, tmp); // set unowned 3496 } 3497 3498 __ bind(cont); 3499 // flag == EQ indicates success 3500 // flag == NE indicates failure 3501 %} 3502 3503 %} 3504 3505 //----------FRAME-------------------------------------------------------------- 3506 // Definition of frame structure and management information. 3507 // 3508 // S T A C K L A Y O U T Allocators stack-slot number 3509 // | (to get allocators register number 3510 // G Owned by | | v add OptoReg::stack0()) 3511 // r CALLER | | 3512 // o | +--------+ pad to even-align allocators stack-slot 3513 // w V | pad0 | numbers; owned by CALLER 3514 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3515 // h ^ | in | 5 3516 // | | args | 4 Holes in incoming args owned by SELF 3517 // | | | | 3 3518 // | | +--------+ 3519 // V | | old out| Empty on Intel, window on Sparc 3520 // | old |preserve| Must be even aligned. 3521 // | SP-+--------+----> Matcher::_old_SP, even aligned 3522 // | | in | 3 area for Intel ret address 3523 // Owned by |preserve| Empty on Sparc. 3524 // SELF +--------+ 3525 // | | pad2 | 2 pad to align old SP 3526 // | +--------+ 1 3527 // | | locks | 0 3528 // | +--------+----> OptoReg::stack0(), even aligned 3529 // | | pad1 | 11 pad to align new SP 3530 // | +--------+ 3531 // | | | 10 3532 // | | spills | 9 spills 3533 // V | | 8 (pad0 slot for callee) 3534 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3535 // ^ | out | 7 3536 // | | args | 6 Holes in outgoing args owned by CALLEE 3537 // Owned by +--------+ 3538 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3539 // | new |preserve| Must be even-aligned. 3540 // | SP-+--------+----> Matcher::_new_SP, even aligned 3541 // | | | 3542 // 3543 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3544 // known from SELF's arguments and the Java calling convention. 3545 // Region 6-7 is determined per call site. 3546 // Note 2: If the calling convention leaves holes in the incoming argument 3547 // area, those holes are owned by SELF. Holes in the outgoing area 3548 // are owned by the CALLEE. Holes should not be nessecary in the 3549 // incoming area, as the Java calling convention is completely under 3550 // the control of the AD file. Doubles can be sorted and packed to 3551 // avoid holes. Holes in the outgoing arguments may be nessecary for 3552 // varargs C calling conventions. 3553 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3554 // even aligned with pad0 as needed. 3555 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3556 // (the latter is true on Intel but is it false on AArch64?) 3557 // region 6-11 is even aligned; it may be padded out more so that 3558 // the region from SP to FP meets the minimum stack alignment. 3559 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3560 // alignment. Region 11, pad1, may be dynamically extended so that 3561 // SP meets the minimum alignment. 3562 3563 frame %{ 3564 // What direction does stack grow in (assumed to be same for C & Java) 3565 stack_direction(TOWARDS_LOW); 3566 3567 // These three registers define part of the calling convention 3568 // between compiled code and the interpreter. 3569 3570 // Inline Cache Register or methodOop for I2C. 3571 inline_cache_reg(R12); 3572 3573 // Method Oop Register when calling interpreter. 3574 interpreter_method_oop_reg(R12); 3575 3576 // Number of stack slots consumed by locking an object 3577 sync_stack_slots(2); 3578 3579 // Compiled code's Frame Pointer 3580 frame_pointer(R31); 3581 3582 // Interpreter stores its frame pointer in a register which is 3583 // stored to the stack by I2CAdaptors. 3584 // I2CAdaptors convert from interpreted java to compiled java. 3585 interpreter_frame_pointer(R29); 3586 3587 // Stack alignment requirement 3588 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3589 3590 // Number of stack slots between incoming argument block and the start of 3591 // a new frame. The PROLOG must add this many slots to the stack. The 3592 // EPILOG must remove this many slots. aarch64 needs two slots for 3593 // return address and fp. 3594 // TODO think this is correct but check 3595 in_preserve_stack_slots(4); 3596 3597 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3598 // for calls to C. Supports the var-args backing area for register parms. 3599 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3600 3601 // The after-PROLOG location of the return address. Location of 3602 // return address specifies a type (REG or STACK) and a number 3603 // representing the register number (i.e. - use a register name) or 3604 // stack slot. 3605 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3606 // Otherwise, it is above the locks and verification slot and alignment word 3607 // TODO this may well be correct but need to check why that - 2 is there 3608 // ppc port uses 0 but we definitely need to allow for fixed_slots 3609 // which folds in the space used for monitors 3610 return_addr(STACK - 2 + 3611 align_up((Compile::current()->in_preserve_stack_slots() + 3612 Compile::current()->fixed_slots()), 3613 stack_alignment_in_slots())); 3614 3615 // Body of function which returns an integer array locating 3616 // arguments either in registers or in stack slots. Passed an array 3617 // of ideal registers called "sig" and a "length" count. Stack-slot 3618 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3619 // arguments for a CALLEE. Incoming stack arguments are 3620 // automatically biased by the preserve_stack_slots field above. 3621 3622 calling_convention 3623 %{ 3624 // No difference between ingoing/outgoing just pass false 3625 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3626 %} 3627 3628 c_calling_convention 3629 %{ 3630 // This is obviously always outgoing 3631 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3632 %} 3633 3634 // Location of compiled Java return values. Same as C for now. 3635 return_value 3636 %{ 3637 // TODO do we allow ideal_reg == Op_RegN??? 3638 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3639 "only return normal values"); 3640 3641 static const int lo[Op_RegL + 1] = { // enum name 3642 0, // Op_Node 3643 0, // Op_Set 3644 R0_num, // Op_RegN 3645 R0_num, // Op_RegI 3646 R0_num, // Op_RegP 3647 V0_num, // Op_RegF 3648 V0_num, // Op_RegD 3649 R0_num // Op_RegL 3650 }; 3651 3652 static const int hi[Op_RegL + 1] = { // enum name 3653 0, // Op_Node 3654 0, // Op_Set 3655 OptoReg::Bad, // Op_RegN 3656 OptoReg::Bad, // Op_RegI 3657 R0_H_num, // Op_RegP 3658 OptoReg::Bad, // Op_RegF 3659 V0_H_num, // Op_RegD 3660 R0_H_num // Op_RegL 3661 }; 3662 3663 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3664 %} 3665 %} 3666 3667 //----------ATTRIBUTES--------------------------------------------------------- 3668 //----------Operand Attributes------------------------------------------------- 3669 op_attrib op_cost(1); // Required cost attribute 3670 3671 //----------Instruction Attributes--------------------------------------------- 3672 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3673 ins_attrib ins_size(32); // Required size attribute (in bits) 3674 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3675 // a non-matching short branch variant 3676 // of some long branch? 3677 ins_attrib ins_alignment(4); // Required alignment attribute (must 3678 // be a power of 2) specifies the 3679 // alignment that some part of the 3680 // instruction (not necessarily the 3681 // start) requires. If > 1, a 3682 // compute_padding() function must be 3683 // provided for the instruction 3684 3685 //----------OPERANDS----------------------------------------------------------- 3686 // Operand definitions must precede instruction definitions for correct parsing 3687 // in the ADLC because operands constitute user defined types which are used in 3688 // instruction definitions. 3689 3690 //----------Simple Operands---------------------------------------------------- 3691 3692 // Integer operands 32 bit 3693 // 32 bit immediate 3694 operand immI() 3695 %{ 3696 match(ConI); 3697 3698 op_cost(0); 3699 format %{ %} 3700 interface(CONST_INTER); 3701 %} 3702 3703 // 32 bit zero 3704 operand immI0() 3705 %{ 3706 predicate(n->get_int() == 0); 3707 match(ConI); 3708 3709 op_cost(0); 3710 format %{ %} 3711 interface(CONST_INTER); 3712 %} 3713 3714 // 32 bit unit increment 3715 operand immI_1() 3716 %{ 3717 predicate(n->get_int() == 1); 3718 match(ConI); 3719 3720 op_cost(0); 3721 format %{ %} 3722 interface(CONST_INTER); 3723 %} 3724 3725 // 32 bit unit decrement 3726 operand immI_M1() 3727 %{ 3728 predicate(n->get_int() == -1); 3729 match(ConI); 3730 3731 op_cost(0); 3732 format %{ %} 3733 interface(CONST_INTER); 3734 %} 3735 3736 // Shift values for add/sub extension shift 3737 operand immIExt() 3738 %{ 3739 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3740 match(ConI); 3741 3742 op_cost(0); 3743 format %{ %} 3744 interface(CONST_INTER); 3745 %} 3746 3747 operand immI_le_4() 3748 %{ 3749 predicate(n->get_int() <= 4); 3750 match(ConI); 3751 3752 op_cost(0); 3753 format %{ %} 3754 interface(CONST_INTER); 3755 %} 3756 3757 operand immI_31() 3758 %{ 3759 predicate(n->get_int() == 31); 3760 match(ConI); 3761 3762 op_cost(0); 3763 format %{ %} 3764 interface(CONST_INTER); 3765 %} 3766 3767 operand immI_8() 3768 %{ 3769 predicate(n->get_int() == 8); 3770 match(ConI); 3771 3772 op_cost(0); 3773 format %{ %} 3774 interface(CONST_INTER); 3775 %} 3776 3777 operand immI_16() 3778 %{ 3779 predicate(n->get_int() == 16); 3780 match(ConI); 3781 3782 op_cost(0); 3783 format %{ %} 3784 interface(CONST_INTER); 3785 %} 3786 3787 operand immI_24() 3788 %{ 3789 predicate(n->get_int() == 24); 3790 match(ConI); 3791 3792 op_cost(0); 3793 format %{ %} 3794 interface(CONST_INTER); 3795 %} 3796 3797 operand immI_32() 3798 %{ 3799 predicate(n->get_int() == 32); 3800 match(ConI); 3801 3802 op_cost(0); 3803 format %{ %} 3804 interface(CONST_INTER); 3805 %} 3806 3807 operand immI_48() 3808 %{ 3809 predicate(n->get_int() == 48); 3810 match(ConI); 3811 3812 op_cost(0); 3813 format %{ %} 3814 interface(CONST_INTER); 3815 %} 3816 3817 operand immI_56() 3818 %{ 3819 predicate(n->get_int() == 56); 3820 match(ConI); 3821 3822 op_cost(0); 3823 format %{ %} 3824 interface(CONST_INTER); 3825 %} 3826 3827 operand immI_63() 3828 %{ 3829 predicate(n->get_int() == 63); 3830 match(ConI); 3831 3832 op_cost(0); 3833 format %{ %} 3834 interface(CONST_INTER); 3835 %} 3836 3837 operand immI_64() 3838 %{ 3839 predicate(n->get_int() == 64); 3840 match(ConI); 3841 3842 op_cost(0); 3843 format %{ %} 3844 interface(CONST_INTER); 3845 %} 3846 3847 operand immI_255() 3848 %{ 3849 predicate(n->get_int() == 255); 3850 match(ConI); 3851 3852 op_cost(0); 3853 format %{ %} 3854 interface(CONST_INTER); 3855 %} 3856 3857 operand immI_65535() 3858 %{ 3859 predicate(n->get_int() == 65535); 3860 match(ConI); 3861 3862 op_cost(0); 3863 format %{ %} 3864 interface(CONST_INTER); 3865 %} 3866 3867 operand immL_255() 3868 %{ 3869 predicate(n->get_long() == 255L); 3870 match(ConL); 3871 3872 op_cost(0); 3873 format %{ %} 3874 interface(CONST_INTER); 3875 %} 3876 3877 operand immL_65535() 3878 %{ 3879 predicate(n->get_long() == 65535L); 3880 match(ConL); 3881 3882 op_cost(0); 3883 format %{ %} 3884 interface(CONST_INTER); 3885 %} 3886 3887 operand immL_4294967295() 3888 %{ 3889 predicate(n->get_long() == 4294967295L); 3890 match(ConL); 3891 3892 op_cost(0); 3893 format %{ %} 3894 interface(CONST_INTER); 3895 %} 3896 3897 operand immL_bitmask() 3898 %{ 3899 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3900 && is_power_of_2(n->get_long() + 1)); 3901 match(ConL); 3902 3903 op_cost(0); 3904 format %{ %} 3905 interface(CONST_INTER); 3906 %} 3907 3908 operand immI_bitmask() 3909 %{ 3910 predicate(((n->get_int() & 0xc0000000) == 0) 3911 && is_power_of_2(n->get_int() + 1)); 3912 match(ConI); 3913 3914 op_cost(0); 3915 format %{ %} 3916 interface(CONST_INTER); 3917 %} 3918 3919 // Scale values for scaled offset addressing modes (up to long but not quad) 3920 operand immIScale() 3921 %{ 3922 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3923 match(ConI); 3924 3925 op_cost(0); 3926 format %{ %} 3927 interface(CONST_INTER); 3928 %} 3929 3930 // 26 bit signed offset -- for pc-relative branches 3931 operand immI26() 3932 %{ 3933 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 3934 match(ConI); 3935 3936 op_cost(0); 3937 format %{ %} 3938 interface(CONST_INTER); 3939 %} 3940 3941 // 19 bit signed offset -- for pc-relative loads 3942 operand immI19() 3943 %{ 3944 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 3945 match(ConI); 3946 3947 op_cost(0); 3948 format %{ %} 3949 interface(CONST_INTER); 3950 %} 3951 3952 // 12 bit unsigned offset -- for base plus immediate loads 3953 operand immIU12() 3954 %{ 3955 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 3956 match(ConI); 3957 3958 op_cost(0); 3959 format %{ %} 3960 interface(CONST_INTER); 3961 %} 3962 3963 operand immLU12() 3964 %{ 3965 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 3966 match(ConL); 3967 3968 op_cost(0); 3969 format %{ %} 3970 interface(CONST_INTER); 3971 %} 3972 3973 // Offset for scaled or unscaled immediate loads and stores 3974 operand immIOffset() 3975 %{ 3976 predicate(Address::offset_ok_for_immed(n->get_int())); 3977 match(ConI); 3978 3979 op_cost(0); 3980 format %{ %} 3981 interface(CONST_INTER); 3982 %} 3983 3984 operand immIOffset4() 3985 %{ 3986 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 3987 match(ConI); 3988 3989 op_cost(0); 3990 format %{ %} 3991 interface(CONST_INTER); 3992 %} 3993 3994 operand immIOffset8() 3995 %{ 3996 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 3997 match(ConI); 3998 3999 op_cost(0); 4000 format %{ %} 4001 interface(CONST_INTER); 4002 %} 4003 4004 operand immIOffset16() 4005 %{ 4006 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4007 match(ConI); 4008 4009 op_cost(0); 4010 format %{ %} 4011 interface(CONST_INTER); 4012 %} 4013 4014 operand immLoffset() 4015 %{ 4016 predicate(Address::offset_ok_for_immed(n->get_long())); 4017 match(ConL); 4018 4019 op_cost(0); 4020 format %{ %} 4021 interface(CONST_INTER); 4022 %} 4023 4024 operand immLoffset4() 4025 %{ 4026 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4027 match(ConL); 4028 4029 op_cost(0); 4030 format %{ %} 4031 interface(CONST_INTER); 4032 %} 4033 4034 operand immLoffset8() 4035 %{ 4036 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4037 match(ConL); 4038 4039 op_cost(0); 4040 format %{ %} 4041 interface(CONST_INTER); 4042 %} 4043 4044 operand immLoffset16() 4045 %{ 4046 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4047 match(ConL); 4048 4049 op_cost(0); 4050 format %{ %} 4051 interface(CONST_INTER); 4052 %} 4053 4054 // 32 bit integer valid for add sub immediate 4055 operand immIAddSub() 4056 %{ 4057 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4058 match(ConI); 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 // 32 bit unsigned integer valid for logical immediate 4065 // TODO -- check this is right when e.g the mask is 0x80000000 4066 operand immILog() 4067 %{ 4068 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4069 match(ConI); 4070 4071 op_cost(0); 4072 format %{ %} 4073 interface(CONST_INTER); 4074 %} 4075 4076 // Integer operands 64 bit 4077 // 64 bit immediate 4078 operand immL() 4079 %{ 4080 match(ConL); 4081 4082 op_cost(0); 4083 format %{ %} 4084 interface(CONST_INTER); 4085 %} 4086 4087 // 64 bit zero 4088 operand immL0() 4089 %{ 4090 predicate(n->get_long() == 0); 4091 match(ConL); 4092 4093 op_cost(0); 4094 format %{ %} 4095 interface(CONST_INTER); 4096 %} 4097 4098 // 64 bit unit increment 4099 operand immL_1() 4100 %{ 4101 predicate(n->get_long() == 1); 4102 match(ConL); 4103 4104 op_cost(0); 4105 format %{ %} 4106 interface(CONST_INTER); 4107 %} 4108 4109 // 64 bit unit decrement 4110 operand immL_M1() 4111 %{ 4112 predicate(n->get_long() == -1); 4113 match(ConL); 4114 4115 op_cost(0); 4116 format %{ %} 4117 interface(CONST_INTER); 4118 %} 4119 4120 // 32 bit offset of pc in thread anchor 4121 4122 operand immL_pc_off() 4123 %{ 4124 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4125 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4126 match(ConL); 4127 4128 op_cost(0); 4129 format %{ %} 4130 interface(CONST_INTER); 4131 %} 4132 4133 // 64 bit integer valid for add sub immediate 4134 operand immLAddSub() 4135 %{ 4136 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4137 match(ConL); 4138 op_cost(0); 4139 format %{ %} 4140 interface(CONST_INTER); 4141 %} 4142 4143 // 64 bit integer valid for logical immediate 4144 operand immLLog() 4145 %{ 4146 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4147 match(ConL); 4148 op_cost(0); 4149 format %{ %} 4150 interface(CONST_INTER); 4151 %} 4152 4153 // Long Immediate: low 32-bit mask 4154 operand immL_32bits() 4155 %{ 4156 predicate(n->get_long() == 0xFFFFFFFFL); 4157 match(ConL); 4158 op_cost(0); 4159 format %{ %} 4160 interface(CONST_INTER); 4161 %} 4162 4163 // Pointer operands 4164 // Pointer Immediate 4165 operand immP() 4166 %{ 4167 match(ConP); 4168 4169 op_cost(0); 4170 format %{ %} 4171 interface(CONST_INTER); 4172 %} 4173 4174 // NULL Pointer Immediate 4175 operand immP0() 4176 %{ 4177 predicate(n->get_ptr() == 0); 4178 match(ConP); 4179 4180 op_cost(0); 4181 format %{ %} 4182 interface(CONST_INTER); 4183 %} 4184 4185 // Pointer Immediate One 4186 // this is used in object initialization (initial object header) 4187 operand immP_1() 4188 %{ 4189 predicate(n->get_ptr() == 1); 4190 match(ConP); 4191 4192 op_cost(0); 4193 format %{ %} 4194 interface(CONST_INTER); 4195 %} 4196 4197 // Polling Page Pointer Immediate 4198 operand immPollPage() 4199 %{ 4200 predicate((address)n->get_ptr() == os::get_polling_page()); 4201 match(ConP); 4202 4203 op_cost(0); 4204 format %{ %} 4205 interface(CONST_INTER); 4206 %} 4207 4208 // Card Table Byte Map Base 4209 operand immByteMapBase() 4210 %{ 4211 // Get base of card map 4212 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4213 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4214 match(ConP); 4215 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219 %} 4220 4221 // Pointer Immediate Minus One 4222 // this is used when we want to write the current PC to the thread anchor 4223 operand immP_M1() 4224 %{ 4225 predicate(n->get_ptr() == -1); 4226 match(ConP); 4227 4228 op_cost(0); 4229 format %{ %} 4230 interface(CONST_INTER); 4231 %} 4232 4233 // Pointer Immediate Minus Two 4234 // this is used when we want to write the current PC to the thread anchor 4235 operand immP_M2() 4236 %{ 4237 predicate(n->get_ptr() == -2); 4238 match(ConP); 4239 4240 op_cost(0); 4241 format %{ %} 4242 interface(CONST_INTER); 4243 %} 4244 4245 // Float and Double operands 4246 // Double Immediate 4247 operand immD() 4248 %{ 4249 match(ConD); 4250 op_cost(0); 4251 format %{ %} 4252 interface(CONST_INTER); 4253 %} 4254 4255 // Double Immediate: +0.0d 4256 operand immD0() 4257 %{ 4258 predicate(jlong_cast(n->getd()) == 0); 4259 match(ConD); 4260 4261 op_cost(0); 4262 format %{ %} 4263 interface(CONST_INTER); 4264 %} 4265 4266 // constant 'double +0.0'. 4267 operand immDPacked() 4268 %{ 4269 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4270 match(ConD); 4271 op_cost(0); 4272 format %{ %} 4273 interface(CONST_INTER); 4274 %} 4275 4276 // Float Immediate 4277 operand immF() 4278 %{ 4279 match(ConF); 4280 op_cost(0); 4281 format %{ %} 4282 interface(CONST_INTER); 4283 %} 4284 4285 // Float Immediate: +0.0f. 4286 operand immF0() 4287 %{ 4288 predicate(jint_cast(n->getf()) == 0); 4289 match(ConF); 4290 4291 op_cost(0); 4292 format %{ %} 4293 interface(CONST_INTER); 4294 %} 4295 4296 // 4297 operand immFPacked() 4298 %{ 4299 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4300 match(ConF); 4301 op_cost(0); 4302 format %{ %} 4303 interface(CONST_INTER); 4304 %} 4305 4306 // Narrow pointer operands 4307 // Narrow Pointer Immediate 4308 operand immN() 4309 %{ 4310 match(ConN); 4311 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // Narrow NULL Pointer Immediate 4318 operand immN0() 4319 %{ 4320 predicate(n->get_narrowcon() == 0); 4321 match(ConN); 4322 4323 op_cost(0); 4324 format %{ %} 4325 interface(CONST_INTER); 4326 %} 4327 4328 operand immNKlass() 4329 %{ 4330 match(ConNKlass); 4331 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // Integer 32 bit Register Operands 4338 // Integer 32 bitRegister (excludes SP) 4339 operand iRegI() 4340 %{ 4341 constraint(ALLOC_IN_RC(any_reg32)); 4342 match(RegI); 4343 match(iRegINoSp); 4344 op_cost(0); 4345 format %{ %} 4346 interface(REG_INTER); 4347 %} 4348 4349 // Integer 32 bit Register not Special 4350 operand iRegINoSp() 4351 %{ 4352 constraint(ALLOC_IN_RC(no_special_reg32)); 4353 match(RegI); 4354 op_cost(0); 4355 format %{ %} 4356 interface(REG_INTER); 4357 %} 4358 4359 // Integer 64 bit Register Operands 4360 // Integer 64 bit Register (includes SP) 4361 operand iRegL() 4362 %{ 4363 constraint(ALLOC_IN_RC(any_reg)); 4364 match(RegL); 4365 match(iRegLNoSp); 4366 op_cost(0); 4367 format %{ %} 4368 interface(REG_INTER); 4369 %} 4370 4371 // Integer 64 bit Register not Special 4372 operand iRegLNoSp() 4373 %{ 4374 constraint(ALLOC_IN_RC(no_special_reg)); 4375 match(RegL); 4376 match(iRegL_R0); 4377 format %{ %} 4378 interface(REG_INTER); 4379 %} 4380 4381 // Pointer Register Operands 4382 // Pointer Register 4383 operand iRegP() 4384 %{ 4385 constraint(ALLOC_IN_RC(ptr_reg)); 4386 match(RegP); 4387 match(iRegPNoSp); 4388 match(iRegP_R0); 4389 //match(iRegP_R2); 4390 //match(iRegP_R4); 4391 //match(iRegP_R5); 4392 match(thread_RegP); 4393 op_cost(0); 4394 format %{ %} 4395 interface(REG_INTER); 4396 %} 4397 4398 // Pointer 64 bit Register not Special 4399 operand iRegPNoSp() 4400 %{ 4401 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4402 match(RegP); 4403 // match(iRegP); 4404 // match(iRegP_R0); 4405 // match(iRegP_R2); 4406 // match(iRegP_R4); 4407 // match(iRegP_R5); 4408 // match(thread_RegP); 4409 op_cost(0); 4410 format %{ %} 4411 interface(REG_INTER); 4412 %} 4413 4414 // Pointer 64 bit Register R0 only 4415 operand iRegP_R0() 4416 %{ 4417 constraint(ALLOC_IN_RC(r0_reg)); 4418 match(RegP); 4419 // match(iRegP); 4420 match(iRegPNoSp); 4421 op_cost(0); 4422 format %{ %} 4423 interface(REG_INTER); 4424 %} 4425 4426 // Pointer 64 bit Register R1 only 4427 operand iRegP_R1() 4428 %{ 4429 constraint(ALLOC_IN_RC(r1_reg)); 4430 match(RegP); 4431 // match(iRegP); 4432 match(iRegPNoSp); 4433 op_cost(0); 4434 format %{ %} 4435 interface(REG_INTER); 4436 %} 4437 4438 // Pointer 64 bit Register R2 only 4439 operand iRegP_R2() 4440 %{ 4441 constraint(ALLOC_IN_RC(r2_reg)); 4442 match(RegP); 4443 // match(iRegP); 4444 match(iRegPNoSp); 4445 op_cost(0); 4446 format %{ %} 4447 interface(REG_INTER); 4448 %} 4449 4450 // Pointer 64 bit Register R3 only 4451 operand iRegP_R3() 4452 %{ 4453 constraint(ALLOC_IN_RC(r3_reg)); 4454 match(RegP); 4455 // match(iRegP); 4456 match(iRegPNoSp); 4457 op_cost(0); 4458 format %{ %} 4459 interface(REG_INTER); 4460 %} 4461 4462 // Pointer 64 bit Register R4 only 4463 operand iRegP_R4() 4464 %{ 4465 constraint(ALLOC_IN_RC(r4_reg)); 4466 match(RegP); 4467 // match(iRegP); 4468 match(iRegPNoSp); 4469 op_cost(0); 4470 format %{ %} 4471 interface(REG_INTER); 4472 %} 4473 4474 // Pointer 64 bit Register R5 only 4475 operand iRegP_R5() 4476 %{ 4477 constraint(ALLOC_IN_RC(r5_reg)); 4478 match(RegP); 4479 // match(iRegP); 4480 match(iRegPNoSp); 4481 op_cost(0); 4482 format %{ %} 4483 interface(REG_INTER); 4484 %} 4485 4486 // Pointer 64 bit Register R10 only 4487 operand iRegP_R10() 4488 %{ 4489 constraint(ALLOC_IN_RC(r10_reg)); 4490 match(RegP); 4491 // match(iRegP); 4492 match(iRegPNoSp); 4493 op_cost(0); 4494 format %{ %} 4495 interface(REG_INTER); 4496 %} 4497 4498 // Long 64 bit Register R0 only 4499 operand iRegL_R0() 4500 %{ 4501 constraint(ALLOC_IN_RC(r0_reg)); 4502 match(RegL); 4503 match(iRegLNoSp); 4504 op_cost(0); 4505 format %{ %} 4506 interface(REG_INTER); 4507 %} 4508 4509 // Long 64 bit Register R2 only 4510 operand iRegL_R2() 4511 %{ 4512 constraint(ALLOC_IN_RC(r2_reg)); 4513 match(RegL); 4514 match(iRegLNoSp); 4515 op_cost(0); 4516 format %{ %} 4517 interface(REG_INTER); 4518 %} 4519 4520 // Long 64 bit Register R3 only 4521 operand iRegL_R3() 4522 %{ 4523 constraint(ALLOC_IN_RC(r3_reg)); 4524 match(RegL); 4525 match(iRegLNoSp); 4526 op_cost(0); 4527 format %{ %} 4528 interface(REG_INTER); 4529 %} 4530 4531 // Long 64 bit Register R11 only 4532 operand iRegL_R11() 4533 %{ 4534 constraint(ALLOC_IN_RC(r11_reg)); 4535 match(RegL); 4536 match(iRegLNoSp); 4537 op_cost(0); 4538 format %{ %} 4539 interface(REG_INTER); 4540 %} 4541 4542 // Pointer 64 bit Register FP only 4543 operand iRegP_FP() 4544 %{ 4545 constraint(ALLOC_IN_RC(fp_reg)); 4546 match(RegP); 4547 // match(iRegP); 4548 op_cost(0); 4549 format %{ %} 4550 interface(REG_INTER); 4551 %} 4552 4553 // Register R0 only 4554 operand iRegI_R0() 4555 %{ 4556 constraint(ALLOC_IN_RC(int_r0_reg)); 4557 match(RegI); 4558 match(iRegINoSp); 4559 op_cost(0); 4560 format %{ %} 4561 interface(REG_INTER); 4562 %} 4563 4564 // Register R2 only 4565 operand iRegI_R2() 4566 %{ 4567 constraint(ALLOC_IN_RC(int_r2_reg)); 4568 match(RegI); 4569 match(iRegINoSp); 4570 op_cost(0); 4571 format %{ %} 4572 interface(REG_INTER); 4573 %} 4574 4575 // Register R3 only 4576 operand iRegI_R3() 4577 %{ 4578 constraint(ALLOC_IN_RC(int_r3_reg)); 4579 match(RegI); 4580 match(iRegINoSp); 4581 op_cost(0); 4582 format %{ %} 4583 interface(REG_INTER); 4584 %} 4585 4586 4587 // Register R4 only 4588 operand iRegI_R4() 4589 %{ 4590 constraint(ALLOC_IN_RC(int_r4_reg)); 4591 match(RegI); 4592 match(iRegINoSp); 4593 op_cost(0); 4594 format %{ %} 4595 interface(REG_INTER); 4596 %} 4597 4598 4599 // Pointer Register Operands 4600 // Narrow Pointer Register 4601 operand iRegN() 4602 %{ 4603 constraint(ALLOC_IN_RC(any_reg32)); 4604 match(RegN); 4605 match(iRegNNoSp); 4606 op_cost(0); 4607 format %{ %} 4608 interface(REG_INTER); 4609 %} 4610 4611 operand iRegN_R0() 4612 %{ 4613 constraint(ALLOC_IN_RC(r0_reg)); 4614 match(iRegN); 4615 op_cost(0); 4616 format %{ %} 4617 interface(REG_INTER); 4618 %} 4619 4620 operand iRegN_R2() 4621 %{ 4622 constraint(ALLOC_IN_RC(r2_reg)); 4623 match(iRegN); 4624 op_cost(0); 4625 format %{ %} 4626 interface(REG_INTER); 4627 %} 4628 4629 operand iRegN_R3() 4630 %{ 4631 constraint(ALLOC_IN_RC(r3_reg)); 4632 match(iRegN); 4633 op_cost(0); 4634 format %{ %} 4635 interface(REG_INTER); 4636 %} 4637 4638 // Integer 64 bit Register not Special 4639 operand iRegNNoSp() 4640 %{ 4641 constraint(ALLOC_IN_RC(no_special_reg32)); 4642 match(RegN); 4643 op_cost(0); 4644 format %{ %} 4645 interface(REG_INTER); 4646 %} 4647 4648 // heap base register -- used for encoding immN0 4649 4650 operand iRegIHeapbase() 4651 %{ 4652 constraint(ALLOC_IN_RC(heapbase_reg)); 4653 match(RegI); 4654 op_cost(0); 4655 format %{ %} 4656 interface(REG_INTER); 4657 %} 4658 4659 // Float Register 4660 // Float register operands 4661 operand vRegF() 4662 %{ 4663 constraint(ALLOC_IN_RC(float_reg)); 4664 match(RegF); 4665 4666 op_cost(0); 4667 format %{ %} 4668 interface(REG_INTER); 4669 %} 4670 4671 // Double Register 4672 // Double register operands 4673 operand vRegD() 4674 %{ 4675 constraint(ALLOC_IN_RC(double_reg)); 4676 match(RegD); 4677 4678 op_cost(0); 4679 format %{ %} 4680 interface(REG_INTER); 4681 %} 4682 4683 operand vecD() 4684 %{ 4685 constraint(ALLOC_IN_RC(vectord_reg)); 4686 match(VecD); 4687 4688 op_cost(0); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 operand vecX() 4694 %{ 4695 constraint(ALLOC_IN_RC(vectorx_reg)); 4696 match(VecX); 4697 4698 op_cost(0); 4699 format %{ %} 4700 interface(REG_INTER); 4701 %} 4702 4703 operand vRegD_V0() 4704 %{ 4705 constraint(ALLOC_IN_RC(v0_reg)); 4706 match(RegD); 4707 op_cost(0); 4708 format %{ %} 4709 interface(REG_INTER); 4710 %} 4711 4712 operand vRegD_V1() 4713 %{ 4714 constraint(ALLOC_IN_RC(v1_reg)); 4715 match(RegD); 4716 op_cost(0); 4717 format %{ %} 4718 interface(REG_INTER); 4719 %} 4720 4721 operand vRegD_V2() 4722 %{ 4723 constraint(ALLOC_IN_RC(v2_reg)); 4724 match(RegD); 4725 op_cost(0); 4726 format %{ %} 4727 interface(REG_INTER); 4728 %} 4729 4730 operand vRegD_V3() 4731 %{ 4732 constraint(ALLOC_IN_RC(v3_reg)); 4733 match(RegD); 4734 op_cost(0); 4735 format %{ %} 4736 interface(REG_INTER); 4737 %} 4738 4739 // Flags register, used as output of signed compare instructions 4740 4741 // note that on AArch64 we also use this register as the output for 4742 // for floating point compare instructions (CmpF CmpD). this ensures 4743 // that ordered inequality tests use GT, GE, LT or LE none of which 4744 // pass through cases where the result is unordered i.e. one or both 4745 // inputs to the compare is a NaN. this means that the ideal code can 4746 // replace e.g. a GT with an LE and not end up capturing the NaN case 4747 // (where the comparison should always fail). EQ and NE tests are 4748 // always generated in ideal code so that unordered folds into the NE 4749 // case, matching the behaviour of AArch64 NE. 4750 // 4751 // This differs from x86 where the outputs of FP compares use a 4752 // special FP flags registers and where compares based on this 4753 // register are distinguished into ordered inequalities (cmpOpUCF) and 4754 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4755 // to explicitly handle the unordered case in branches. x86 also has 4756 // to include extra CMoveX rules to accept a cmpOpUCF input. 4757 4758 operand rFlagsReg() 4759 %{ 4760 constraint(ALLOC_IN_RC(int_flags)); 4761 match(RegFlags); 4762 4763 op_cost(0); 4764 format %{ "RFLAGS" %} 4765 interface(REG_INTER); 4766 %} 4767 4768 // Flags register, used as output of unsigned compare instructions 4769 operand rFlagsRegU() 4770 %{ 4771 constraint(ALLOC_IN_RC(int_flags)); 4772 match(RegFlags); 4773 4774 op_cost(0); 4775 format %{ "RFLAGSU" %} 4776 interface(REG_INTER); 4777 %} 4778 4779 // Special Registers 4780 4781 // Method Register 4782 operand inline_cache_RegP(iRegP reg) 4783 %{ 4784 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4785 match(reg); 4786 match(iRegPNoSp); 4787 op_cost(0); 4788 format %{ %} 4789 interface(REG_INTER); 4790 %} 4791 4792 operand interpreter_method_oop_RegP(iRegP reg) 4793 %{ 4794 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4795 match(reg); 4796 match(iRegPNoSp); 4797 op_cost(0); 4798 format %{ %} 4799 interface(REG_INTER); 4800 %} 4801 4802 // Thread Register 4803 operand thread_RegP(iRegP reg) 4804 %{ 4805 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4806 match(reg); 4807 op_cost(0); 4808 format %{ %} 4809 interface(REG_INTER); 4810 %} 4811 4812 operand lr_RegP(iRegP reg) 4813 %{ 4814 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4815 match(reg); 4816 op_cost(0); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 //----------Memory Operands---------------------------------------------------- 4822 4823 operand indirect(iRegP reg) 4824 %{ 4825 constraint(ALLOC_IN_RC(ptr_reg)); 4826 match(reg); 4827 op_cost(0); 4828 format %{ "[$reg]" %} 4829 interface(MEMORY_INTER) %{ 4830 base($reg); 4831 index(0xffffffff); 4832 scale(0x0); 4833 disp(0x0); 4834 %} 4835 %} 4836 4837 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4838 %{ 4839 constraint(ALLOC_IN_RC(ptr_reg)); 4840 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4841 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4842 op_cost(0); 4843 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4844 interface(MEMORY_INTER) %{ 4845 base($reg); 4846 index($ireg); 4847 scale($scale); 4848 disp(0x0); 4849 %} 4850 %} 4851 4852 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4853 %{ 4854 constraint(ALLOC_IN_RC(ptr_reg)); 4855 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4856 match(AddP reg (LShiftL lreg scale)); 4857 op_cost(0); 4858 format %{ "$reg, $lreg lsl($scale)" %} 4859 interface(MEMORY_INTER) %{ 4860 base($reg); 4861 index($lreg); 4862 scale($scale); 4863 disp(0x0); 4864 %} 4865 %} 4866 4867 operand indIndexI2L(iRegP reg, iRegI ireg) 4868 %{ 4869 constraint(ALLOC_IN_RC(ptr_reg)); 4870 match(AddP reg (ConvI2L ireg)); 4871 op_cost(0); 4872 format %{ "$reg, $ireg, 0, I2L" %} 4873 interface(MEMORY_INTER) %{ 4874 base($reg); 4875 index($ireg); 4876 scale(0x0); 4877 disp(0x0); 4878 %} 4879 %} 4880 4881 operand indIndex(iRegP reg, iRegL lreg) 4882 %{ 4883 constraint(ALLOC_IN_RC(ptr_reg)); 4884 match(AddP reg lreg); 4885 op_cost(0); 4886 format %{ "$reg, $lreg" %} 4887 interface(MEMORY_INTER) %{ 4888 base($reg); 4889 index($lreg); 4890 scale(0x0); 4891 disp(0x0); 4892 %} 4893 %} 4894 4895 operand indOffI(iRegP reg, immIOffset off) 4896 %{ 4897 constraint(ALLOC_IN_RC(ptr_reg)); 4898 match(AddP reg off); 4899 op_cost(0); 4900 format %{ "[$reg, $off]" %} 4901 interface(MEMORY_INTER) %{ 4902 base($reg); 4903 index(0xffffffff); 4904 scale(0x0); 4905 disp($off); 4906 %} 4907 %} 4908 4909 operand indOffI4(iRegP reg, immIOffset4 off) 4910 %{ 4911 constraint(ALLOC_IN_RC(ptr_reg)); 4912 match(AddP reg off); 4913 op_cost(0); 4914 format %{ "[$reg, $off]" %} 4915 interface(MEMORY_INTER) %{ 4916 base($reg); 4917 index(0xffffffff); 4918 scale(0x0); 4919 disp($off); 4920 %} 4921 %} 4922 4923 operand indOffI8(iRegP reg, immIOffset8 off) 4924 %{ 4925 constraint(ALLOC_IN_RC(ptr_reg)); 4926 match(AddP reg off); 4927 op_cost(0); 4928 format %{ "[$reg, $off]" %} 4929 interface(MEMORY_INTER) %{ 4930 base($reg); 4931 index(0xffffffff); 4932 scale(0x0); 4933 disp($off); 4934 %} 4935 %} 4936 4937 operand indOffI16(iRegP reg, immIOffset16 off) 4938 %{ 4939 constraint(ALLOC_IN_RC(ptr_reg)); 4940 match(AddP reg off); 4941 op_cost(0); 4942 format %{ "[$reg, $off]" %} 4943 interface(MEMORY_INTER) %{ 4944 base($reg); 4945 index(0xffffffff); 4946 scale(0x0); 4947 disp($off); 4948 %} 4949 %} 4950 4951 operand indOffL(iRegP reg, immLoffset off) 4952 %{ 4953 constraint(ALLOC_IN_RC(ptr_reg)); 4954 match(AddP reg off); 4955 op_cost(0); 4956 format %{ "[$reg, $off]" %} 4957 interface(MEMORY_INTER) %{ 4958 base($reg); 4959 index(0xffffffff); 4960 scale(0x0); 4961 disp($off); 4962 %} 4963 %} 4964 4965 operand indOffL4(iRegP reg, immLoffset4 off) 4966 %{ 4967 constraint(ALLOC_IN_RC(ptr_reg)); 4968 match(AddP reg off); 4969 op_cost(0); 4970 format %{ "[$reg, $off]" %} 4971 interface(MEMORY_INTER) %{ 4972 base($reg); 4973 index(0xffffffff); 4974 scale(0x0); 4975 disp($off); 4976 %} 4977 %} 4978 4979 operand indOffL8(iRegP reg, immLoffset8 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 indOffL16(iRegP reg, immLoffset16 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 indirectN(iRegN reg) 5008 %{ 5009 predicate(Universe::narrow_oop_shift() == 0); 5010 constraint(ALLOC_IN_RC(ptr_reg)); 5011 match(DecodeN reg); 5012 op_cost(0); 5013 format %{ "[$reg]\t# narrow" %} 5014 interface(MEMORY_INTER) %{ 5015 base($reg); 5016 index(0xffffffff); 5017 scale(0x0); 5018 disp(0x0); 5019 %} 5020 %} 5021 5022 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5023 %{ 5024 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5025 constraint(ALLOC_IN_RC(ptr_reg)); 5026 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5027 op_cost(0); 5028 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5029 interface(MEMORY_INTER) %{ 5030 base($reg); 5031 index($ireg); 5032 scale($scale); 5033 disp(0x0); 5034 %} 5035 %} 5036 5037 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5038 %{ 5039 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5040 constraint(ALLOC_IN_RC(ptr_reg)); 5041 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5042 op_cost(0); 5043 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5044 interface(MEMORY_INTER) %{ 5045 base($reg); 5046 index($lreg); 5047 scale($scale); 5048 disp(0x0); 5049 %} 5050 %} 5051 5052 operand indIndexI2LN(iRegN reg, iRegI ireg) 5053 %{ 5054 predicate(Universe::narrow_oop_shift() == 0); 5055 constraint(ALLOC_IN_RC(ptr_reg)); 5056 match(AddP (DecodeN reg) (ConvI2L ireg)); 5057 op_cost(0); 5058 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5059 interface(MEMORY_INTER) %{ 5060 base($reg); 5061 index($ireg); 5062 scale(0x0); 5063 disp(0x0); 5064 %} 5065 %} 5066 5067 operand indIndexN(iRegN reg, iRegL lreg) 5068 %{ 5069 predicate(Universe::narrow_oop_shift() == 0); 5070 constraint(ALLOC_IN_RC(ptr_reg)); 5071 match(AddP (DecodeN reg) lreg); 5072 op_cost(0); 5073 format %{ "$reg, $lreg\t# narrow" %} 5074 interface(MEMORY_INTER) %{ 5075 base($reg); 5076 index($lreg); 5077 scale(0x0); 5078 disp(0x0); 5079 %} 5080 %} 5081 5082 operand indOffIN(iRegN reg, immIOffset off) 5083 %{ 5084 predicate(Universe::narrow_oop_shift() == 0); 5085 constraint(ALLOC_IN_RC(ptr_reg)); 5086 match(AddP (DecodeN reg) off); 5087 op_cost(0); 5088 format %{ "[$reg, $off]\t# narrow" %} 5089 interface(MEMORY_INTER) %{ 5090 base($reg); 5091 index(0xffffffff); 5092 scale(0x0); 5093 disp($off); 5094 %} 5095 %} 5096 5097 operand indOffLN(iRegN reg, immLoffset off) 5098 %{ 5099 predicate(Universe::narrow_oop_shift() == 0); 5100 constraint(ALLOC_IN_RC(ptr_reg)); 5101 match(AddP (DecodeN reg) off); 5102 op_cost(0); 5103 format %{ "[$reg, $off]\t# narrow" %} 5104 interface(MEMORY_INTER) %{ 5105 base($reg); 5106 index(0xffffffff); 5107 scale(0x0); 5108 disp($off); 5109 %} 5110 %} 5111 5112 5113 5114 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5115 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5116 %{ 5117 constraint(ALLOC_IN_RC(ptr_reg)); 5118 match(AddP reg off); 5119 op_cost(0); 5120 format %{ "[$reg, $off]" %} 5121 interface(MEMORY_INTER) %{ 5122 base($reg); 5123 index(0xffffffff); 5124 scale(0x0); 5125 disp($off); 5126 %} 5127 %} 5128 5129 //----------Special Memory Operands-------------------------------------------- 5130 // Stack Slot Operand - This operand is used for loading and storing temporary 5131 // values on the stack where a match requires a value to 5132 // flow through memory. 5133 operand stackSlotP(sRegP reg) 5134 %{ 5135 constraint(ALLOC_IN_RC(stack_slots)); 5136 op_cost(100); 5137 // No match rule because this operand is only generated in matching 5138 // match(RegP); 5139 format %{ "[$reg]" %} 5140 interface(MEMORY_INTER) %{ 5141 base(0x1e); // RSP 5142 index(0x0); // No Index 5143 scale(0x0); // No Scale 5144 disp($reg); // Stack Offset 5145 %} 5146 %} 5147 5148 operand stackSlotI(sRegI reg) 5149 %{ 5150 constraint(ALLOC_IN_RC(stack_slots)); 5151 // No match rule because this operand is only generated in matching 5152 // match(RegI); 5153 format %{ "[$reg]" %} 5154 interface(MEMORY_INTER) %{ 5155 base(0x1e); // RSP 5156 index(0x0); // No Index 5157 scale(0x0); // No Scale 5158 disp($reg); // Stack Offset 5159 %} 5160 %} 5161 5162 operand stackSlotF(sRegF reg) 5163 %{ 5164 constraint(ALLOC_IN_RC(stack_slots)); 5165 // No match rule because this operand is only generated in matching 5166 // match(RegF); 5167 format %{ "[$reg]" %} 5168 interface(MEMORY_INTER) %{ 5169 base(0x1e); // RSP 5170 index(0x0); // No Index 5171 scale(0x0); // No Scale 5172 disp($reg); // Stack Offset 5173 %} 5174 %} 5175 5176 operand stackSlotD(sRegD reg) 5177 %{ 5178 constraint(ALLOC_IN_RC(stack_slots)); 5179 // No match rule because this operand is only generated in matching 5180 // match(RegD); 5181 format %{ "[$reg]" %} 5182 interface(MEMORY_INTER) %{ 5183 base(0x1e); // RSP 5184 index(0x0); // No Index 5185 scale(0x0); // No Scale 5186 disp($reg); // Stack Offset 5187 %} 5188 %} 5189 5190 operand stackSlotL(sRegL reg) 5191 %{ 5192 constraint(ALLOC_IN_RC(stack_slots)); 5193 // No match rule because this operand is only generated in matching 5194 // match(RegL); 5195 format %{ "[$reg]" %} 5196 interface(MEMORY_INTER) %{ 5197 base(0x1e); // RSP 5198 index(0x0); // No Index 5199 scale(0x0); // No Scale 5200 disp($reg); // Stack Offset 5201 %} 5202 %} 5203 5204 // Operands for expressing Control Flow 5205 // NOTE: Label is a predefined operand which should not be redefined in 5206 // the AD file. It is generically handled within the ADLC. 5207 5208 //----------Conditional Branch Operands---------------------------------------- 5209 // Comparison Op - This is the operation of the comparison, and is limited to 5210 // the following set of codes: 5211 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5212 // 5213 // Other attributes of the comparison, such as unsignedness, are specified 5214 // by the comparison instruction that sets a condition code flags register. 5215 // That result is represented by a flags operand whose subtype is appropriate 5216 // to the unsignedness (etc.) of the comparison. 5217 // 5218 // Later, the instruction which matches both the Comparison Op (a Bool) and 5219 // the flags (produced by the Cmp) specifies the coding of the comparison op 5220 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5221 5222 // used for signed integral comparisons and fp comparisons 5223 5224 operand cmpOp() 5225 %{ 5226 match(Bool); 5227 5228 format %{ "" %} 5229 interface(COND_INTER) %{ 5230 equal(0x0, "eq"); 5231 not_equal(0x1, "ne"); 5232 less(0xb, "lt"); 5233 greater_equal(0xa, "ge"); 5234 less_equal(0xd, "le"); 5235 greater(0xc, "gt"); 5236 overflow(0x6, "vs"); 5237 no_overflow(0x7, "vc"); 5238 %} 5239 %} 5240 5241 // used for unsigned integral comparisons 5242 5243 operand cmpOpU() 5244 %{ 5245 match(Bool); 5246 5247 format %{ "" %} 5248 interface(COND_INTER) %{ 5249 equal(0x0, "eq"); 5250 not_equal(0x1, "ne"); 5251 less(0x3, "lo"); 5252 greater_equal(0x2, "hs"); 5253 less_equal(0x9, "ls"); 5254 greater(0x8, "hi"); 5255 overflow(0x6, "vs"); 5256 no_overflow(0x7, "vc"); 5257 %} 5258 %} 5259 5260 // used for certain integral comparisons which can be 5261 // converted to cbxx or tbxx instructions 5262 5263 operand cmpOpEqNe() 5264 %{ 5265 match(Bool); 5266 match(CmpOp); 5267 op_cost(0); 5268 predicate(n->as_Bool()->_test._test == BoolTest::ne 5269 || n->as_Bool()->_test._test == BoolTest::eq); 5270 5271 format %{ "" %} 5272 interface(COND_INTER) %{ 5273 equal(0x0, "eq"); 5274 not_equal(0x1, "ne"); 5275 less(0xb, "lt"); 5276 greater_equal(0xa, "ge"); 5277 less_equal(0xd, "le"); 5278 greater(0xc, "gt"); 5279 overflow(0x6, "vs"); 5280 no_overflow(0x7, "vc"); 5281 %} 5282 %} 5283 5284 // used for certain integral comparisons which can be 5285 // converted to cbxx or tbxx instructions 5286 5287 operand cmpOpLtGe() 5288 %{ 5289 match(Bool); 5290 match(CmpOp); 5291 op_cost(0); 5292 5293 predicate(n->as_Bool()->_test._test == BoolTest::lt 5294 || n->as_Bool()->_test._test == BoolTest::ge); 5295 5296 format %{ "" %} 5297 interface(COND_INTER) %{ 5298 equal(0x0, "eq"); 5299 not_equal(0x1, "ne"); 5300 less(0xb, "lt"); 5301 greater_equal(0xa, "ge"); 5302 less_equal(0xd, "le"); 5303 greater(0xc, "gt"); 5304 overflow(0x6, "vs"); 5305 no_overflow(0x7, "vc"); 5306 %} 5307 %} 5308 5309 // used for certain unsigned integral comparisons which can be 5310 // converted to cbxx or tbxx instructions 5311 5312 operand cmpOpUEqNeLtGe() 5313 %{ 5314 match(Bool); 5315 match(CmpOp); 5316 op_cost(0); 5317 5318 predicate(n->as_Bool()->_test._test == BoolTest::eq 5319 || n->as_Bool()->_test._test == BoolTest::ne 5320 || n->as_Bool()->_test._test == BoolTest::lt 5321 || n->as_Bool()->_test._test == BoolTest::ge); 5322 5323 format %{ "" %} 5324 interface(COND_INTER) %{ 5325 equal(0x0, "eq"); 5326 not_equal(0x1, "ne"); 5327 less(0xb, "lt"); 5328 greater_equal(0xa, "ge"); 5329 less_equal(0xd, "le"); 5330 greater(0xc, "gt"); 5331 overflow(0x6, "vs"); 5332 no_overflow(0x7, "vc"); 5333 %} 5334 %} 5335 5336 // Special operand allowing long args to int ops to be truncated for free 5337 5338 operand iRegL2I(iRegL reg) %{ 5339 5340 op_cost(0); 5341 5342 match(ConvL2I reg); 5343 5344 format %{ "l2i($reg)" %} 5345 5346 interface(REG_INTER) 5347 %} 5348 5349 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5350 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5351 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5352 5353 //----------OPERAND CLASSES---------------------------------------------------- 5354 // Operand Classes are groups of operands that are used as to simplify 5355 // instruction definitions by not requiring the AD writer to specify 5356 // separate instructions for every form of operand when the 5357 // instruction accepts multiple operand types with the same basic 5358 // encoding and format. The classic case of this is memory operands. 5359 5360 // memory is used to define read/write location for load/store 5361 // instruction defs. we can turn a memory op into an Address 5362 5363 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5364 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5365 5366 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5367 // operations. it allows the src to be either an iRegI or a (ConvL2I 5368 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5369 // can be elided because the 32-bit instruction will just employ the 5370 // lower 32 bits anyway. 5371 // 5372 // n.b. this does not elide all L2I conversions. if the truncated 5373 // value is consumed by more than one operation then the ConvL2I 5374 // cannot be bundled into the consuming nodes so an l2i gets planted 5375 // (actually a movw $dst $src) and the downstream instructions consume 5376 // the result of the l2i as an iRegI input. That's a shame since the 5377 // movw is actually redundant but its not too costly. 5378 5379 opclass iRegIorL2I(iRegI, iRegL2I); 5380 5381 //----------PIPELINE----------------------------------------------------------- 5382 // Rules which define the behavior of the target architectures pipeline. 5383 5384 // For specific pipelines, eg A53, define the stages of that pipeline 5385 //pipe_desc(ISS, EX1, EX2, WR); 5386 #define ISS S0 5387 #define EX1 S1 5388 #define EX2 S2 5389 #define WR S3 5390 5391 // Integer ALU reg operation 5392 pipeline %{ 5393 5394 attributes %{ 5395 // ARM instructions are of fixed length 5396 fixed_size_instructions; // Fixed size instructions TODO does 5397 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5398 // ARM instructions come in 32-bit word units 5399 instruction_unit_size = 4; // An instruction is 4 bytes long 5400 instruction_fetch_unit_size = 64; // The processor fetches one line 5401 instruction_fetch_units = 1; // of 64 bytes 5402 5403 // List of nop instructions 5404 nops( MachNop ); 5405 %} 5406 5407 // We don't use an actual pipeline model so don't care about resources 5408 // or description. we do use pipeline classes to introduce fixed 5409 // latencies 5410 5411 //----------RESOURCES---------------------------------------------------------- 5412 // Resources are the functional units available to the machine 5413 5414 resources( INS0, INS1, INS01 = INS0 | INS1, 5415 ALU0, ALU1, ALU = ALU0 | ALU1, 5416 MAC, 5417 DIV, 5418 BRANCH, 5419 LDST, 5420 NEON_FP); 5421 5422 //----------PIPELINE DESCRIPTION----------------------------------------------- 5423 // Pipeline Description specifies the stages in the machine's pipeline 5424 5425 // Define the pipeline as a generic 6 stage pipeline 5426 pipe_desc(S0, S1, S2, S3, S4, S5); 5427 5428 //----------PIPELINE CLASSES--------------------------------------------------- 5429 // Pipeline Classes describe the stages in which input and output are 5430 // referenced by the hardware pipeline. 5431 5432 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5433 %{ 5434 single_instruction; 5435 src1 : S1(read); 5436 src2 : S2(read); 5437 dst : S5(write); 5438 INS01 : ISS; 5439 NEON_FP : S5; 5440 %} 5441 5442 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5443 %{ 5444 single_instruction; 5445 src1 : S1(read); 5446 src2 : S2(read); 5447 dst : S5(write); 5448 INS01 : ISS; 5449 NEON_FP : S5; 5450 %} 5451 5452 pipe_class fp_uop_s(vRegF dst, vRegF src) 5453 %{ 5454 single_instruction; 5455 src : S1(read); 5456 dst : S5(write); 5457 INS01 : ISS; 5458 NEON_FP : S5; 5459 %} 5460 5461 pipe_class fp_uop_d(vRegD dst, vRegD src) 5462 %{ 5463 single_instruction; 5464 src : S1(read); 5465 dst : S5(write); 5466 INS01 : ISS; 5467 NEON_FP : S5; 5468 %} 5469 5470 pipe_class fp_d2f(vRegF dst, vRegD src) 5471 %{ 5472 single_instruction; 5473 src : S1(read); 5474 dst : S5(write); 5475 INS01 : ISS; 5476 NEON_FP : S5; 5477 %} 5478 5479 pipe_class fp_f2d(vRegD dst, vRegF src) 5480 %{ 5481 single_instruction; 5482 src : S1(read); 5483 dst : S5(write); 5484 INS01 : ISS; 5485 NEON_FP : S5; 5486 %} 5487 5488 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5489 %{ 5490 single_instruction; 5491 src : S1(read); 5492 dst : S5(write); 5493 INS01 : ISS; 5494 NEON_FP : S5; 5495 %} 5496 5497 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5498 %{ 5499 single_instruction; 5500 src : S1(read); 5501 dst : S5(write); 5502 INS01 : ISS; 5503 NEON_FP : S5; 5504 %} 5505 5506 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5507 %{ 5508 single_instruction; 5509 src : S1(read); 5510 dst : S5(write); 5511 INS01 : ISS; 5512 NEON_FP : S5; 5513 %} 5514 5515 pipe_class fp_l2f(vRegF dst, iRegL src) 5516 %{ 5517 single_instruction; 5518 src : S1(read); 5519 dst : S5(write); 5520 INS01 : ISS; 5521 NEON_FP : S5; 5522 %} 5523 5524 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5525 %{ 5526 single_instruction; 5527 src : S1(read); 5528 dst : S5(write); 5529 INS01 : ISS; 5530 NEON_FP : S5; 5531 %} 5532 5533 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5534 %{ 5535 single_instruction; 5536 src : S1(read); 5537 dst : S5(write); 5538 INS01 : ISS; 5539 NEON_FP : S5; 5540 %} 5541 5542 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5543 %{ 5544 single_instruction; 5545 src : S1(read); 5546 dst : S5(write); 5547 INS01 : ISS; 5548 NEON_FP : S5; 5549 %} 5550 5551 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5552 %{ 5553 single_instruction; 5554 src : S1(read); 5555 dst : S5(write); 5556 INS01 : ISS; 5557 NEON_FP : S5; 5558 %} 5559 5560 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5561 %{ 5562 single_instruction; 5563 src1 : S1(read); 5564 src2 : S2(read); 5565 dst : S5(write); 5566 INS0 : ISS; 5567 NEON_FP : S5; 5568 %} 5569 5570 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5571 %{ 5572 single_instruction; 5573 src1 : S1(read); 5574 src2 : S2(read); 5575 dst : S5(write); 5576 INS0 : ISS; 5577 NEON_FP : S5; 5578 %} 5579 5580 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5581 %{ 5582 single_instruction; 5583 cr : S1(read); 5584 src1 : S1(read); 5585 src2 : S1(read); 5586 dst : S3(write); 5587 INS01 : ISS; 5588 NEON_FP : S3; 5589 %} 5590 5591 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5592 %{ 5593 single_instruction; 5594 cr : S1(read); 5595 src1 : S1(read); 5596 src2 : S1(read); 5597 dst : S3(write); 5598 INS01 : ISS; 5599 NEON_FP : S3; 5600 %} 5601 5602 pipe_class fp_imm_s(vRegF dst) 5603 %{ 5604 single_instruction; 5605 dst : S3(write); 5606 INS01 : ISS; 5607 NEON_FP : S3; 5608 %} 5609 5610 pipe_class fp_imm_d(vRegD dst) 5611 %{ 5612 single_instruction; 5613 dst : S3(write); 5614 INS01 : ISS; 5615 NEON_FP : S3; 5616 %} 5617 5618 pipe_class fp_load_constant_s(vRegF dst) 5619 %{ 5620 single_instruction; 5621 dst : S4(write); 5622 INS01 : ISS; 5623 NEON_FP : S4; 5624 %} 5625 5626 pipe_class fp_load_constant_d(vRegD dst) 5627 %{ 5628 single_instruction; 5629 dst : S4(write); 5630 INS01 : ISS; 5631 NEON_FP : S4; 5632 %} 5633 5634 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5635 %{ 5636 single_instruction; 5637 dst : S5(write); 5638 src1 : S1(read); 5639 src2 : S1(read); 5640 INS01 : ISS; 5641 NEON_FP : S5; 5642 %} 5643 5644 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5645 %{ 5646 single_instruction; 5647 dst : S5(write); 5648 src1 : S1(read); 5649 src2 : S1(read); 5650 INS0 : ISS; 5651 NEON_FP : S5; 5652 %} 5653 5654 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5655 %{ 5656 single_instruction; 5657 dst : S5(write); 5658 src1 : S1(read); 5659 src2 : S1(read); 5660 dst : S1(read); 5661 INS01 : ISS; 5662 NEON_FP : S5; 5663 %} 5664 5665 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5666 %{ 5667 single_instruction; 5668 dst : S5(write); 5669 src1 : S1(read); 5670 src2 : S1(read); 5671 dst : S1(read); 5672 INS0 : ISS; 5673 NEON_FP : S5; 5674 %} 5675 5676 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5677 %{ 5678 single_instruction; 5679 dst : S4(write); 5680 src1 : S2(read); 5681 src2 : S2(read); 5682 INS01 : ISS; 5683 NEON_FP : S4; 5684 %} 5685 5686 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5687 %{ 5688 single_instruction; 5689 dst : S4(write); 5690 src1 : S2(read); 5691 src2 : S2(read); 5692 INS0 : ISS; 5693 NEON_FP : S4; 5694 %} 5695 5696 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5697 %{ 5698 single_instruction; 5699 dst : S3(write); 5700 src1 : S2(read); 5701 src2 : S2(read); 5702 INS01 : ISS; 5703 NEON_FP : S3; 5704 %} 5705 5706 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5707 %{ 5708 single_instruction; 5709 dst : S3(write); 5710 src1 : S2(read); 5711 src2 : S2(read); 5712 INS0 : ISS; 5713 NEON_FP : S3; 5714 %} 5715 5716 pipe_class vshift64(vecD dst, vecD src, vecX shift) 5717 %{ 5718 single_instruction; 5719 dst : S3(write); 5720 src : S1(read); 5721 shift : S1(read); 5722 INS01 : ISS; 5723 NEON_FP : S3; 5724 %} 5725 5726 pipe_class vshift128(vecX dst, vecX src, vecX shift) 5727 %{ 5728 single_instruction; 5729 dst : S3(write); 5730 src : S1(read); 5731 shift : S1(read); 5732 INS0 : ISS; 5733 NEON_FP : S3; 5734 %} 5735 5736 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5737 %{ 5738 single_instruction; 5739 dst : S3(write); 5740 src : S1(read); 5741 INS01 : ISS; 5742 NEON_FP : S3; 5743 %} 5744 5745 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5746 %{ 5747 single_instruction; 5748 dst : S3(write); 5749 src : S1(read); 5750 INS0 : ISS; 5751 NEON_FP : S3; 5752 %} 5753 5754 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5755 %{ 5756 single_instruction; 5757 dst : S5(write); 5758 src1 : S1(read); 5759 src2 : S1(read); 5760 INS01 : ISS; 5761 NEON_FP : S5; 5762 %} 5763 5764 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5765 %{ 5766 single_instruction; 5767 dst : S5(write); 5768 src1 : S1(read); 5769 src2 : S1(read); 5770 INS0 : ISS; 5771 NEON_FP : S5; 5772 %} 5773 5774 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5775 %{ 5776 single_instruction; 5777 dst : S5(write); 5778 src1 : S1(read); 5779 src2 : S1(read); 5780 INS0 : ISS; 5781 NEON_FP : S5; 5782 %} 5783 5784 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5785 %{ 5786 single_instruction; 5787 dst : S5(write); 5788 src1 : S1(read); 5789 src2 : S1(read); 5790 INS0 : ISS; 5791 NEON_FP : S5; 5792 %} 5793 5794 pipe_class vsqrt_fp128(vecX dst, vecX src) 5795 %{ 5796 single_instruction; 5797 dst : S5(write); 5798 src : S1(read); 5799 INS0 : ISS; 5800 NEON_FP : S5; 5801 %} 5802 5803 pipe_class vunop_fp64(vecD dst, vecD src) 5804 %{ 5805 single_instruction; 5806 dst : S5(write); 5807 src : S1(read); 5808 INS01 : ISS; 5809 NEON_FP : S5; 5810 %} 5811 5812 pipe_class vunop_fp128(vecX dst, vecX src) 5813 %{ 5814 single_instruction; 5815 dst : S5(write); 5816 src : S1(read); 5817 INS0 : ISS; 5818 NEON_FP : S5; 5819 %} 5820 5821 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5822 %{ 5823 single_instruction; 5824 dst : S3(write); 5825 src : S1(read); 5826 INS01 : ISS; 5827 NEON_FP : S3; 5828 %} 5829 5830 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5831 %{ 5832 single_instruction; 5833 dst : S3(write); 5834 src : S1(read); 5835 INS01 : ISS; 5836 NEON_FP : S3; 5837 %} 5838 5839 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5840 %{ 5841 single_instruction; 5842 dst : S3(write); 5843 src : S1(read); 5844 INS01 : ISS; 5845 NEON_FP : S3; 5846 %} 5847 5848 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5849 %{ 5850 single_instruction; 5851 dst : S3(write); 5852 src : S1(read); 5853 INS01 : ISS; 5854 NEON_FP : S3; 5855 %} 5856 5857 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5858 %{ 5859 single_instruction; 5860 dst : S3(write); 5861 src : S1(read); 5862 INS01 : ISS; 5863 NEON_FP : S3; 5864 %} 5865 5866 pipe_class vmovi_reg_imm64(vecD dst) 5867 %{ 5868 single_instruction; 5869 dst : S3(write); 5870 INS01 : ISS; 5871 NEON_FP : S3; 5872 %} 5873 5874 pipe_class vmovi_reg_imm128(vecX dst) 5875 %{ 5876 single_instruction; 5877 dst : S3(write); 5878 INS0 : ISS; 5879 NEON_FP : S3; 5880 %} 5881 5882 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 5883 %{ 5884 single_instruction; 5885 dst : S5(write); 5886 mem : ISS(read); 5887 INS01 : ISS; 5888 NEON_FP : S3; 5889 %} 5890 5891 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 5892 %{ 5893 single_instruction; 5894 dst : S5(write); 5895 mem : ISS(read); 5896 INS01 : ISS; 5897 NEON_FP : S3; 5898 %} 5899 5900 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 5901 %{ 5902 single_instruction; 5903 mem : ISS(read); 5904 src : S2(read); 5905 INS01 : ISS; 5906 NEON_FP : S3; 5907 %} 5908 5909 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 5910 %{ 5911 single_instruction; 5912 mem : ISS(read); 5913 src : S2(read); 5914 INS01 : ISS; 5915 NEON_FP : S3; 5916 %} 5917 5918 //------- Integer ALU operations -------------------------- 5919 5920 // Integer ALU reg-reg operation 5921 // Operands needed in EX1, result generated in EX2 5922 // Eg. ADD x0, x1, x2 5923 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5924 %{ 5925 single_instruction; 5926 dst : EX2(write); 5927 src1 : EX1(read); 5928 src2 : EX1(read); 5929 INS01 : ISS; // Dual issue as instruction 0 or 1 5930 ALU : EX2; 5931 %} 5932 5933 // Integer ALU reg-reg operation with constant shift 5934 // Shifted register must be available in LATE_ISS instead of EX1 5935 // Eg. ADD x0, x1, x2, LSL #2 5936 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5937 %{ 5938 single_instruction; 5939 dst : EX2(write); 5940 src1 : EX1(read); 5941 src2 : ISS(read); 5942 INS01 : ISS; 5943 ALU : EX2; 5944 %} 5945 5946 // Integer ALU reg operation with constant shift 5947 // Eg. LSL x0, x1, #shift 5948 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5949 %{ 5950 single_instruction; 5951 dst : EX2(write); 5952 src1 : ISS(read); 5953 INS01 : ISS; 5954 ALU : EX2; 5955 %} 5956 5957 // Integer ALU reg-reg operation with variable shift 5958 // Both operands must be available in LATE_ISS instead of EX1 5959 // Result is available in EX1 instead of EX2 5960 // Eg. LSLV x0, x1, x2 5961 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5962 %{ 5963 single_instruction; 5964 dst : EX1(write); 5965 src1 : ISS(read); 5966 src2 : ISS(read); 5967 INS01 : ISS; 5968 ALU : EX1; 5969 %} 5970 5971 // Integer ALU reg-reg operation with extract 5972 // As for _vshift above, but result generated in EX2 5973 // Eg. EXTR x0, x1, x2, #N 5974 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 5975 %{ 5976 single_instruction; 5977 dst : EX2(write); 5978 src1 : ISS(read); 5979 src2 : ISS(read); 5980 INS1 : ISS; // Can only dual issue as Instruction 1 5981 ALU : EX1; 5982 %} 5983 5984 // Integer ALU reg operation 5985 // Eg. NEG x0, x1 5986 pipe_class ialu_reg(iRegI dst, iRegI src) 5987 %{ 5988 single_instruction; 5989 dst : EX2(write); 5990 src : EX1(read); 5991 INS01 : ISS; 5992 ALU : EX2; 5993 %} 5994 5995 // Integer ALU reg mmediate operation 5996 // Eg. ADD x0, x1, #N 5997 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 5998 %{ 5999 single_instruction; 6000 dst : EX2(write); 6001 src1 : EX1(read); 6002 INS01 : ISS; 6003 ALU : EX2; 6004 %} 6005 6006 // Integer ALU immediate operation (no source operands) 6007 // Eg. MOV x0, #N 6008 pipe_class ialu_imm(iRegI dst) 6009 %{ 6010 single_instruction; 6011 dst : EX1(write); 6012 INS01 : ISS; 6013 ALU : EX1; 6014 %} 6015 6016 //------- Compare operation ------------------------------- 6017 6018 // Compare reg-reg 6019 // Eg. CMP x0, x1 6020 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6021 %{ 6022 single_instruction; 6023 // fixed_latency(16); 6024 cr : EX2(write); 6025 op1 : EX1(read); 6026 op2 : EX1(read); 6027 INS01 : ISS; 6028 ALU : EX2; 6029 %} 6030 6031 // Compare reg-reg 6032 // Eg. CMP x0, #N 6033 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6034 %{ 6035 single_instruction; 6036 // fixed_latency(16); 6037 cr : EX2(write); 6038 op1 : EX1(read); 6039 INS01 : ISS; 6040 ALU : EX2; 6041 %} 6042 6043 //------- Conditional instructions ------------------------ 6044 6045 // Conditional no operands 6046 // Eg. CSINC x0, zr, zr, <cond> 6047 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6048 %{ 6049 single_instruction; 6050 cr : EX1(read); 6051 dst : EX2(write); 6052 INS01 : ISS; 6053 ALU : EX2; 6054 %} 6055 6056 // Conditional 2 operand 6057 // EG. CSEL X0, X1, X2, <cond> 6058 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6059 %{ 6060 single_instruction; 6061 cr : EX1(read); 6062 src1 : EX1(read); 6063 src2 : EX1(read); 6064 dst : EX2(write); 6065 INS01 : ISS; 6066 ALU : EX2; 6067 %} 6068 6069 // Conditional 2 operand 6070 // EG. CSEL X0, X1, X2, <cond> 6071 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6072 %{ 6073 single_instruction; 6074 cr : EX1(read); 6075 src : EX1(read); 6076 dst : EX2(write); 6077 INS01 : ISS; 6078 ALU : EX2; 6079 %} 6080 6081 //------- Multiply pipeline operations -------------------- 6082 6083 // Multiply reg-reg 6084 // Eg. MUL w0, w1, w2 6085 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6086 %{ 6087 single_instruction; 6088 dst : WR(write); 6089 src1 : ISS(read); 6090 src2 : ISS(read); 6091 INS01 : ISS; 6092 MAC : WR; 6093 %} 6094 6095 // Multiply accumulate 6096 // Eg. MADD w0, w1, w2, w3 6097 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6098 %{ 6099 single_instruction; 6100 dst : WR(write); 6101 src1 : ISS(read); 6102 src2 : ISS(read); 6103 src3 : ISS(read); 6104 INS01 : ISS; 6105 MAC : WR; 6106 %} 6107 6108 // Eg. MUL w0, w1, w2 6109 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6110 %{ 6111 single_instruction; 6112 fixed_latency(3); // Maximum latency for 64 bit mul 6113 dst : WR(write); 6114 src1 : ISS(read); 6115 src2 : ISS(read); 6116 INS01 : ISS; 6117 MAC : WR; 6118 %} 6119 6120 // Multiply accumulate 6121 // Eg. MADD w0, w1, w2, w3 6122 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6123 %{ 6124 single_instruction; 6125 fixed_latency(3); // Maximum latency for 64 bit mul 6126 dst : WR(write); 6127 src1 : ISS(read); 6128 src2 : ISS(read); 6129 src3 : ISS(read); 6130 INS01 : ISS; 6131 MAC : WR; 6132 %} 6133 6134 //------- Divide pipeline operations -------------------- 6135 6136 // Eg. SDIV w0, w1, w2 6137 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6138 %{ 6139 single_instruction; 6140 fixed_latency(8); // Maximum latency for 32 bit divide 6141 dst : WR(write); 6142 src1 : ISS(read); 6143 src2 : ISS(read); 6144 INS0 : ISS; // Can only dual issue as instruction 0 6145 DIV : WR; 6146 %} 6147 6148 // Eg. SDIV x0, x1, x2 6149 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6150 %{ 6151 single_instruction; 6152 fixed_latency(16); // Maximum latency for 64 bit divide 6153 dst : WR(write); 6154 src1 : ISS(read); 6155 src2 : ISS(read); 6156 INS0 : ISS; // Can only dual issue as instruction 0 6157 DIV : WR; 6158 %} 6159 6160 //------- Load pipeline operations ------------------------ 6161 6162 // Load - prefetch 6163 // Eg. PFRM <mem> 6164 pipe_class iload_prefetch(memory mem) 6165 %{ 6166 single_instruction; 6167 mem : ISS(read); 6168 INS01 : ISS; 6169 LDST : WR; 6170 %} 6171 6172 // Load - reg, mem 6173 // Eg. LDR x0, <mem> 6174 pipe_class iload_reg_mem(iRegI dst, memory mem) 6175 %{ 6176 single_instruction; 6177 dst : WR(write); 6178 mem : ISS(read); 6179 INS01 : ISS; 6180 LDST : WR; 6181 %} 6182 6183 // Load - reg, reg 6184 // Eg. LDR x0, [sp, x1] 6185 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6186 %{ 6187 single_instruction; 6188 dst : WR(write); 6189 src : ISS(read); 6190 INS01 : ISS; 6191 LDST : WR; 6192 %} 6193 6194 //------- Store pipeline operations ----------------------- 6195 6196 // Store - zr, mem 6197 // Eg. STR zr, <mem> 6198 pipe_class istore_mem(memory mem) 6199 %{ 6200 single_instruction; 6201 mem : ISS(read); 6202 INS01 : ISS; 6203 LDST : WR; 6204 %} 6205 6206 // Store - reg, mem 6207 // Eg. STR x0, <mem> 6208 pipe_class istore_reg_mem(iRegI src, memory mem) 6209 %{ 6210 single_instruction; 6211 mem : ISS(read); 6212 src : EX2(read); 6213 INS01 : ISS; 6214 LDST : WR; 6215 %} 6216 6217 // Store - reg, reg 6218 // Eg. STR x0, [sp, x1] 6219 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6220 %{ 6221 single_instruction; 6222 dst : ISS(read); 6223 src : EX2(read); 6224 INS01 : ISS; 6225 LDST : WR; 6226 %} 6227 6228 //------- Store pipeline operations ----------------------- 6229 6230 // Branch 6231 pipe_class pipe_branch() 6232 %{ 6233 single_instruction; 6234 INS01 : ISS; 6235 BRANCH : EX1; 6236 %} 6237 6238 // Conditional branch 6239 pipe_class pipe_branch_cond(rFlagsReg cr) 6240 %{ 6241 single_instruction; 6242 cr : EX1(read); 6243 INS01 : ISS; 6244 BRANCH : EX1; 6245 %} 6246 6247 // Compare & Branch 6248 // EG. CBZ/CBNZ 6249 pipe_class pipe_cmp_branch(iRegI op1) 6250 %{ 6251 single_instruction; 6252 op1 : EX1(read); 6253 INS01 : ISS; 6254 BRANCH : EX1; 6255 %} 6256 6257 //------- Synchronisation operations ---------------------- 6258 6259 // Any operation requiring serialization. 6260 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6261 pipe_class pipe_serial() 6262 %{ 6263 single_instruction; 6264 force_serialization; 6265 fixed_latency(16); 6266 INS01 : ISS(2); // Cannot dual issue with any other instruction 6267 LDST : WR; 6268 %} 6269 6270 // Generic big/slow expanded idiom - also serialized 6271 pipe_class pipe_slow() 6272 %{ 6273 instruction_count(10); 6274 multiple_bundles; 6275 force_serialization; 6276 fixed_latency(16); 6277 INS01 : ISS(2); // Cannot dual issue with any other instruction 6278 LDST : WR; 6279 %} 6280 6281 // Empty pipeline class 6282 pipe_class pipe_class_empty() 6283 %{ 6284 single_instruction; 6285 fixed_latency(0); 6286 %} 6287 6288 // Default pipeline class. 6289 pipe_class pipe_class_default() 6290 %{ 6291 single_instruction; 6292 fixed_latency(2); 6293 %} 6294 6295 // Pipeline class for compares. 6296 pipe_class pipe_class_compare() 6297 %{ 6298 single_instruction; 6299 fixed_latency(16); 6300 %} 6301 6302 // Pipeline class for memory operations. 6303 pipe_class pipe_class_memory() 6304 %{ 6305 single_instruction; 6306 fixed_latency(16); 6307 %} 6308 6309 // Pipeline class for call. 6310 pipe_class pipe_class_call() 6311 %{ 6312 single_instruction; 6313 fixed_latency(100); 6314 %} 6315 6316 // Define the class for the Nop node. 6317 define %{ 6318 MachNop = pipe_class_empty; 6319 %} 6320 6321 %} 6322 //----------INSTRUCTIONS------------------------------------------------------- 6323 // 6324 // match -- States which machine-independent subtree may be replaced 6325 // by this instruction. 6326 // ins_cost -- The estimated cost of this instruction is used by instruction 6327 // selection to identify a minimum cost tree of machine 6328 // instructions that matches a tree of machine-independent 6329 // instructions. 6330 // format -- A string providing the disassembly for this instruction. 6331 // The value of an instruction's operand may be inserted 6332 // by referring to it with a '$' prefix. 6333 // opcode -- Three instruction opcodes may be provided. These are referred 6334 // to within an encode class as $primary, $secondary, and $tertiary 6335 // rrspectively. The primary opcode is commonly used to 6336 // indicate the type of machine instruction, while secondary 6337 // and tertiary are often used for prefix options or addressing 6338 // modes. 6339 // ins_encode -- A list of encode classes with parameters. The encode class 6340 // name must have been defined in an 'enc_class' specification 6341 // in the encode section of the architecture description. 6342 6343 // ============================================================================ 6344 // Memory (Load/Store) Instructions 6345 6346 // Load Instructions 6347 6348 // Load Byte (8 bit signed) 6349 instruct loadB(iRegINoSp dst, memory mem) 6350 %{ 6351 match(Set dst (LoadB mem)); 6352 predicate(!needs_acquiring_load(n)); 6353 6354 ins_cost(4 * INSN_COST); 6355 format %{ "ldrsbw $dst, $mem\t# byte" %} 6356 6357 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6358 6359 ins_pipe(iload_reg_mem); 6360 %} 6361 6362 // Load Byte (8 bit signed) into long 6363 instruct loadB2L(iRegLNoSp dst, memory mem) 6364 %{ 6365 match(Set dst (ConvI2L (LoadB mem))); 6366 predicate(!needs_acquiring_load(n->in(1))); 6367 6368 ins_cost(4 * INSN_COST); 6369 format %{ "ldrsb $dst, $mem\t# byte" %} 6370 6371 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6372 6373 ins_pipe(iload_reg_mem); 6374 %} 6375 6376 // Load Byte (8 bit unsigned) 6377 instruct loadUB(iRegINoSp dst, memory mem) 6378 %{ 6379 match(Set dst (LoadUB mem)); 6380 predicate(!needs_acquiring_load(n)); 6381 6382 ins_cost(4 * INSN_COST); 6383 format %{ "ldrbw $dst, $mem\t# byte" %} 6384 6385 ins_encode(aarch64_enc_ldrb(dst, mem)); 6386 6387 ins_pipe(iload_reg_mem); 6388 %} 6389 6390 // Load Byte (8 bit unsigned) into long 6391 instruct loadUB2L(iRegLNoSp dst, memory mem) 6392 %{ 6393 match(Set dst (ConvI2L (LoadUB mem))); 6394 predicate(!needs_acquiring_load(n->in(1))); 6395 6396 ins_cost(4 * INSN_COST); 6397 format %{ "ldrb $dst, $mem\t# byte" %} 6398 6399 ins_encode(aarch64_enc_ldrb(dst, mem)); 6400 6401 ins_pipe(iload_reg_mem); 6402 %} 6403 6404 // Load Short (16 bit signed) 6405 instruct loadS(iRegINoSp dst, memory mem) 6406 %{ 6407 match(Set dst (LoadS mem)); 6408 predicate(!needs_acquiring_load(n)); 6409 6410 ins_cost(4 * INSN_COST); 6411 format %{ "ldrshw $dst, $mem\t# short" %} 6412 6413 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6414 6415 ins_pipe(iload_reg_mem); 6416 %} 6417 6418 // Load Short (16 bit signed) into long 6419 instruct loadS2L(iRegLNoSp dst, memory mem) 6420 %{ 6421 match(Set dst (ConvI2L (LoadS mem))); 6422 predicate(!needs_acquiring_load(n->in(1))); 6423 6424 ins_cost(4 * INSN_COST); 6425 format %{ "ldrsh $dst, $mem\t# short" %} 6426 6427 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6428 6429 ins_pipe(iload_reg_mem); 6430 %} 6431 6432 // Load Char (16 bit unsigned) 6433 instruct loadUS(iRegINoSp dst, memory mem) 6434 %{ 6435 match(Set dst (LoadUS mem)); 6436 predicate(!needs_acquiring_load(n)); 6437 6438 ins_cost(4 * INSN_COST); 6439 format %{ "ldrh $dst, $mem\t# short" %} 6440 6441 ins_encode(aarch64_enc_ldrh(dst, mem)); 6442 6443 ins_pipe(iload_reg_mem); 6444 %} 6445 6446 // Load Short/Char (16 bit unsigned) into long 6447 instruct loadUS2L(iRegLNoSp dst, memory mem) 6448 %{ 6449 match(Set dst (ConvI2L (LoadUS mem))); 6450 predicate(!needs_acquiring_load(n->in(1))); 6451 6452 ins_cost(4 * INSN_COST); 6453 format %{ "ldrh $dst, $mem\t# short" %} 6454 6455 ins_encode(aarch64_enc_ldrh(dst, mem)); 6456 6457 ins_pipe(iload_reg_mem); 6458 %} 6459 6460 // Load Integer (32 bit signed) 6461 instruct loadI(iRegINoSp dst, memory mem) 6462 %{ 6463 match(Set dst (LoadI mem)); 6464 predicate(!needs_acquiring_load(n)); 6465 6466 ins_cost(4 * INSN_COST); 6467 format %{ "ldrw $dst, $mem\t# int" %} 6468 6469 ins_encode(aarch64_enc_ldrw(dst, mem)); 6470 6471 ins_pipe(iload_reg_mem); 6472 %} 6473 6474 // Load Integer (32 bit signed) into long 6475 instruct loadI2L(iRegLNoSp dst, memory mem) 6476 %{ 6477 match(Set dst (ConvI2L (LoadI mem))); 6478 predicate(!needs_acquiring_load(n->in(1))); 6479 6480 ins_cost(4 * INSN_COST); 6481 format %{ "ldrsw $dst, $mem\t# int" %} 6482 6483 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6484 6485 ins_pipe(iload_reg_mem); 6486 %} 6487 6488 // Load Integer (32 bit unsigned) into long 6489 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6490 %{ 6491 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6492 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6493 6494 ins_cost(4 * INSN_COST); 6495 format %{ "ldrw $dst, $mem\t# int" %} 6496 6497 ins_encode(aarch64_enc_ldrw(dst, mem)); 6498 6499 ins_pipe(iload_reg_mem); 6500 %} 6501 6502 // Load Long (64 bit signed) 6503 instruct loadL(iRegLNoSp dst, memory mem) 6504 %{ 6505 match(Set dst (LoadL mem)); 6506 predicate(!needs_acquiring_load(n)); 6507 6508 ins_cost(4 * INSN_COST); 6509 format %{ "ldr $dst, $mem\t# int" %} 6510 6511 ins_encode(aarch64_enc_ldr(dst, mem)); 6512 6513 ins_pipe(iload_reg_mem); 6514 %} 6515 6516 // Load Range 6517 instruct loadRange(iRegINoSp dst, memory mem) 6518 %{ 6519 match(Set dst (LoadRange mem)); 6520 6521 ins_cost(4 * INSN_COST); 6522 format %{ "ldrw $dst, $mem\t# range" %} 6523 6524 ins_encode(aarch64_enc_ldrw(dst, mem)); 6525 6526 ins_pipe(iload_reg_mem); 6527 %} 6528 6529 // Load Pointer 6530 instruct loadP(iRegPNoSp dst, memory mem) 6531 %{ 6532 match(Set dst (LoadP mem)); 6533 predicate(!needs_acquiring_load(n)); 6534 6535 ins_cost(4 * INSN_COST); 6536 format %{ "ldr $dst, $mem\t# ptr" %} 6537 6538 ins_encode(aarch64_enc_ldr(dst, mem)); 6539 6540 ins_pipe(iload_reg_mem); 6541 %} 6542 6543 // Load Compressed Pointer 6544 instruct loadN(iRegNNoSp dst, memory mem) 6545 %{ 6546 match(Set dst (LoadN mem)); 6547 predicate(!needs_acquiring_load(n)); 6548 6549 ins_cost(4 * INSN_COST); 6550 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6551 6552 ins_encode(aarch64_enc_ldrw(dst, mem)); 6553 6554 ins_pipe(iload_reg_mem); 6555 %} 6556 6557 // Load Klass Pointer 6558 instruct loadKlass(iRegPNoSp dst, memory mem) 6559 %{ 6560 match(Set dst (LoadKlass mem)); 6561 predicate(!needs_acquiring_load(n)); 6562 6563 ins_cost(4 * INSN_COST); 6564 format %{ "ldr $dst, $mem\t# class" %} 6565 6566 ins_encode(aarch64_enc_ldr(dst, mem)); 6567 6568 ins_pipe(iload_reg_mem); 6569 %} 6570 6571 // Load Narrow Klass Pointer 6572 instruct loadNKlass(iRegNNoSp dst, memory mem) 6573 %{ 6574 match(Set dst (LoadNKlass mem)); 6575 predicate(!needs_acquiring_load(n)); 6576 6577 ins_cost(4 * INSN_COST); 6578 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6579 6580 ins_encode(aarch64_enc_ldrw(dst, mem)); 6581 6582 ins_pipe(iload_reg_mem); 6583 %} 6584 6585 // Load Float 6586 instruct loadF(vRegF dst, memory mem) 6587 %{ 6588 match(Set dst (LoadF mem)); 6589 predicate(!needs_acquiring_load(n)); 6590 6591 ins_cost(4 * INSN_COST); 6592 format %{ "ldrs $dst, $mem\t# float" %} 6593 6594 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6595 6596 ins_pipe(pipe_class_memory); 6597 %} 6598 6599 // Load Double 6600 instruct loadD(vRegD dst, memory mem) 6601 %{ 6602 match(Set dst (LoadD mem)); 6603 predicate(!needs_acquiring_load(n)); 6604 6605 ins_cost(4 * INSN_COST); 6606 format %{ "ldrd $dst, $mem\t# double" %} 6607 6608 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6609 6610 ins_pipe(pipe_class_memory); 6611 %} 6612 6613 6614 // Load Int Constant 6615 instruct loadConI(iRegINoSp dst, immI src) 6616 %{ 6617 match(Set dst src); 6618 6619 ins_cost(INSN_COST); 6620 format %{ "mov $dst, $src\t# int" %} 6621 6622 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6623 6624 ins_pipe(ialu_imm); 6625 %} 6626 6627 // Load Long Constant 6628 instruct loadConL(iRegLNoSp dst, immL src) 6629 %{ 6630 match(Set dst src); 6631 6632 ins_cost(INSN_COST); 6633 format %{ "mov $dst, $src\t# long" %} 6634 6635 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6636 6637 ins_pipe(ialu_imm); 6638 %} 6639 6640 // Load Pointer Constant 6641 6642 instruct loadConP(iRegPNoSp dst, immP con) 6643 %{ 6644 match(Set dst con); 6645 6646 ins_cost(INSN_COST * 4); 6647 format %{ 6648 "mov $dst, $con\t# ptr\n\t" 6649 %} 6650 6651 ins_encode(aarch64_enc_mov_p(dst, con)); 6652 6653 ins_pipe(ialu_imm); 6654 %} 6655 6656 // Load Null Pointer Constant 6657 6658 instruct loadConP0(iRegPNoSp dst, immP0 con) 6659 %{ 6660 match(Set dst con); 6661 6662 ins_cost(INSN_COST); 6663 format %{ "mov $dst, $con\t# NULL ptr" %} 6664 6665 ins_encode(aarch64_enc_mov_p0(dst, con)); 6666 6667 ins_pipe(ialu_imm); 6668 %} 6669 6670 // Load Pointer Constant One 6671 6672 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6673 %{ 6674 match(Set dst con); 6675 6676 ins_cost(INSN_COST); 6677 format %{ "mov $dst, $con\t# NULL ptr" %} 6678 6679 ins_encode(aarch64_enc_mov_p1(dst, con)); 6680 6681 ins_pipe(ialu_imm); 6682 %} 6683 6684 // Load Poll Page Constant 6685 6686 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6687 %{ 6688 match(Set dst con); 6689 6690 ins_cost(INSN_COST); 6691 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6692 6693 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6694 6695 ins_pipe(ialu_imm); 6696 %} 6697 6698 // Load Byte Map Base Constant 6699 6700 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6701 %{ 6702 match(Set dst con); 6703 6704 ins_cost(INSN_COST); 6705 format %{ "adr $dst, $con\t# Byte Map Base" %} 6706 6707 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6708 6709 ins_pipe(ialu_imm); 6710 %} 6711 6712 // Load Narrow Pointer Constant 6713 6714 instruct loadConN(iRegNNoSp dst, immN con) 6715 %{ 6716 match(Set dst con); 6717 6718 ins_cost(INSN_COST * 4); 6719 format %{ "mov $dst, $con\t# compressed ptr" %} 6720 6721 ins_encode(aarch64_enc_mov_n(dst, con)); 6722 6723 ins_pipe(ialu_imm); 6724 %} 6725 6726 // Load Narrow Null Pointer Constant 6727 6728 instruct loadConN0(iRegNNoSp dst, immN0 con) 6729 %{ 6730 match(Set dst con); 6731 6732 ins_cost(INSN_COST); 6733 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6734 6735 ins_encode(aarch64_enc_mov_n0(dst, con)); 6736 6737 ins_pipe(ialu_imm); 6738 %} 6739 6740 // Load Narrow Klass Constant 6741 6742 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6743 %{ 6744 match(Set dst con); 6745 6746 ins_cost(INSN_COST); 6747 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6748 6749 ins_encode(aarch64_enc_mov_nk(dst, con)); 6750 6751 ins_pipe(ialu_imm); 6752 %} 6753 6754 // Load Packed Float Constant 6755 6756 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6757 match(Set dst con); 6758 ins_cost(INSN_COST * 4); 6759 format %{ "fmovs $dst, $con"%} 6760 ins_encode %{ 6761 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6762 %} 6763 6764 ins_pipe(fp_imm_s); 6765 %} 6766 6767 // Load Float Constant 6768 6769 instruct loadConF(vRegF dst, immF con) %{ 6770 match(Set dst con); 6771 6772 ins_cost(INSN_COST * 4); 6773 6774 format %{ 6775 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6776 %} 6777 6778 ins_encode %{ 6779 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6780 %} 6781 6782 ins_pipe(fp_load_constant_s); 6783 %} 6784 6785 // Load Packed Double Constant 6786 6787 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6788 match(Set dst con); 6789 ins_cost(INSN_COST); 6790 format %{ "fmovd $dst, $con"%} 6791 ins_encode %{ 6792 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6793 %} 6794 6795 ins_pipe(fp_imm_d); 6796 %} 6797 6798 // Load Double Constant 6799 6800 instruct loadConD(vRegD dst, immD con) %{ 6801 match(Set dst con); 6802 6803 ins_cost(INSN_COST * 5); 6804 format %{ 6805 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6806 %} 6807 6808 ins_encode %{ 6809 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6810 %} 6811 6812 ins_pipe(fp_load_constant_d); 6813 %} 6814 6815 // Store Instructions 6816 6817 // Store CMS card-mark Immediate 6818 instruct storeimmCM0(immI0 zero, memory mem) 6819 %{ 6820 match(Set mem (StoreCM mem zero)); 6821 predicate(unnecessary_storestore(n)); 6822 6823 ins_cost(INSN_COST); 6824 format %{ "storestore (elided)\n\t" 6825 "strb zr, $mem\t# byte" %} 6826 6827 ins_encode(aarch64_enc_strb0(mem)); 6828 6829 ins_pipe(istore_mem); 6830 %} 6831 6832 // Store CMS card-mark Immediate with intervening StoreStore 6833 // needed when using CMS with no conditional card marking 6834 instruct storeimmCM0_ordered(immI0 zero, memory mem) 6835 %{ 6836 match(Set mem (StoreCM mem zero)); 6837 6838 ins_cost(INSN_COST * 2); 6839 format %{ "storestore\n\t" 6840 "dmb ishst" 6841 "\n\tstrb zr, $mem\t# byte" %} 6842 6843 ins_encode(aarch64_enc_strb0_ordered(mem)); 6844 6845 ins_pipe(istore_mem); 6846 %} 6847 6848 // Store Byte 6849 instruct storeB(iRegIorL2I src, memory mem) 6850 %{ 6851 match(Set mem (StoreB mem src)); 6852 predicate(!needs_releasing_store(n)); 6853 6854 ins_cost(INSN_COST); 6855 format %{ "strb $src, $mem\t# byte" %} 6856 6857 ins_encode(aarch64_enc_strb(src, mem)); 6858 6859 ins_pipe(istore_reg_mem); 6860 %} 6861 6862 6863 instruct storeimmB0(immI0 zero, memory mem) 6864 %{ 6865 match(Set mem (StoreB mem zero)); 6866 predicate(!needs_releasing_store(n)); 6867 6868 ins_cost(INSN_COST); 6869 format %{ "strb rscractch2, $mem\t# byte" %} 6870 6871 ins_encode(aarch64_enc_strb0(mem)); 6872 6873 ins_pipe(istore_mem); 6874 %} 6875 6876 // Store Char/Short 6877 instruct storeC(iRegIorL2I src, memory mem) 6878 %{ 6879 match(Set mem (StoreC mem src)); 6880 predicate(!needs_releasing_store(n)); 6881 6882 ins_cost(INSN_COST); 6883 format %{ "strh $src, $mem\t# short" %} 6884 6885 ins_encode(aarch64_enc_strh(src, mem)); 6886 6887 ins_pipe(istore_reg_mem); 6888 %} 6889 6890 instruct storeimmC0(immI0 zero, memory mem) 6891 %{ 6892 match(Set mem (StoreC mem zero)); 6893 predicate(!needs_releasing_store(n)); 6894 6895 ins_cost(INSN_COST); 6896 format %{ "strh zr, $mem\t# short" %} 6897 6898 ins_encode(aarch64_enc_strh0(mem)); 6899 6900 ins_pipe(istore_mem); 6901 %} 6902 6903 // Store Integer 6904 6905 instruct storeI(iRegIorL2I src, memory mem) 6906 %{ 6907 match(Set mem(StoreI mem src)); 6908 predicate(!needs_releasing_store(n)); 6909 6910 ins_cost(INSN_COST); 6911 format %{ "strw $src, $mem\t# int" %} 6912 6913 ins_encode(aarch64_enc_strw(src, mem)); 6914 6915 ins_pipe(istore_reg_mem); 6916 %} 6917 6918 instruct storeimmI0(immI0 zero, memory mem) 6919 %{ 6920 match(Set mem(StoreI mem zero)); 6921 predicate(!needs_releasing_store(n)); 6922 6923 ins_cost(INSN_COST); 6924 format %{ "strw zr, $mem\t# int" %} 6925 6926 ins_encode(aarch64_enc_strw0(mem)); 6927 6928 ins_pipe(istore_mem); 6929 %} 6930 6931 // Store Long (64 bit signed) 6932 instruct storeL(iRegL src, memory mem) 6933 %{ 6934 match(Set mem (StoreL mem src)); 6935 predicate(!needs_releasing_store(n)); 6936 6937 ins_cost(INSN_COST); 6938 format %{ "str $src, $mem\t# int" %} 6939 6940 ins_encode(aarch64_enc_str(src, mem)); 6941 6942 ins_pipe(istore_reg_mem); 6943 %} 6944 6945 // Store Long (64 bit signed) 6946 instruct storeimmL0(immL0 zero, memory mem) 6947 %{ 6948 match(Set mem (StoreL mem zero)); 6949 predicate(!needs_releasing_store(n)); 6950 6951 ins_cost(INSN_COST); 6952 format %{ "str zr, $mem\t# int" %} 6953 6954 ins_encode(aarch64_enc_str0(mem)); 6955 6956 ins_pipe(istore_mem); 6957 %} 6958 6959 // Store Pointer 6960 instruct storeP(iRegP src, memory mem) 6961 %{ 6962 match(Set mem (StoreP mem src)); 6963 predicate(!needs_releasing_store(n)); 6964 6965 ins_cost(INSN_COST); 6966 format %{ "str $src, $mem\t# ptr" %} 6967 6968 ins_encode(aarch64_enc_str(src, mem)); 6969 6970 ins_pipe(istore_reg_mem); 6971 %} 6972 6973 // Store Pointer 6974 instruct storeimmP0(immP0 zero, memory mem) 6975 %{ 6976 match(Set mem (StoreP mem zero)); 6977 predicate(!needs_releasing_store(n)); 6978 6979 ins_cost(INSN_COST); 6980 format %{ "str zr, $mem\t# ptr" %} 6981 6982 ins_encode(aarch64_enc_str0(mem)); 6983 6984 ins_pipe(istore_mem); 6985 %} 6986 6987 // Store Compressed Pointer 6988 instruct storeN(iRegN src, memory mem) 6989 %{ 6990 match(Set mem (StoreN mem src)); 6991 predicate(!needs_releasing_store(n)); 6992 6993 ins_cost(INSN_COST); 6994 format %{ "strw $src, $mem\t# compressed ptr" %} 6995 6996 ins_encode(aarch64_enc_strw(src, mem)); 6997 6998 ins_pipe(istore_reg_mem); 6999 %} 7000 7001 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7002 %{ 7003 match(Set mem (StoreN mem zero)); 7004 predicate(Universe::narrow_oop_base() == NULL && 7005 Universe::narrow_klass_base() == NULL && 7006 (!needs_releasing_store(n))); 7007 7008 ins_cost(INSN_COST); 7009 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7010 7011 ins_encode(aarch64_enc_strw(heapbase, mem)); 7012 7013 ins_pipe(istore_reg_mem); 7014 %} 7015 7016 // Store Float 7017 instruct storeF(vRegF src, memory mem) 7018 %{ 7019 match(Set mem (StoreF mem src)); 7020 predicate(!needs_releasing_store(n)); 7021 7022 ins_cost(INSN_COST); 7023 format %{ "strs $src, $mem\t# float" %} 7024 7025 ins_encode( aarch64_enc_strs(src, mem) ); 7026 7027 ins_pipe(pipe_class_memory); 7028 %} 7029 7030 // TODO 7031 // implement storeImmF0 and storeFImmPacked 7032 7033 // Store Double 7034 instruct storeD(vRegD src, memory mem) 7035 %{ 7036 match(Set mem (StoreD mem src)); 7037 predicate(!needs_releasing_store(n)); 7038 7039 ins_cost(INSN_COST); 7040 format %{ "strd $src, $mem\t# double" %} 7041 7042 ins_encode( aarch64_enc_strd(src, mem) ); 7043 7044 ins_pipe(pipe_class_memory); 7045 %} 7046 7047 // Store Compressed Klass Pointer 7048 instruct storeNKlass(iRegN src, memory mem) 7049 %{ 7050 predicate(!needs_releasing_store(n)); 7051 match(Set mem (StoreNKlass mem src)); 7052 7053 ins_cost(INSN_COST); 7054 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7055 7056 ins_encode(aarch64_enc_strw(src, mem)); 7057 7058 ins_pipe(istore_reg_mem); 7059 %} 7060 7061 // TODO 7062 // implement storeImmD0 and storeDImmPacked 7063 7064 // prefetch instructions 7065 // Must be safe to execute with invalid address (cannot fault). 7066 7067 instruct prefetchalloc( memory mem ) %{ 7068 match(PrefetchAllocation mem); 7069 7070 ins_cost(INSN_COST); 7071 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7072 7073 ins_encode( aarch64_enc_prefetchw(mem) ); 7074 7075 ins_pipe(iload_prefetch); 7076 %} 7077 7078 // ---------------- volatile loads and stores ---------------- 7079 7080 // Load Byte (8 bit signed) 7081 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7082 %{ 7083 match(Set dst (LoadB mem)); 7084 7085 ins_cost(VOLATILE_REF_COST); 7086 format %{ "ldarsb $dst, $mem\t# byte" %} 7087 7088 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7089 7090 ins_pipe(pipe_serial); 7091 %} 7092 7093 // Load Byte (8 bit signed) into long 7094 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7095 %{ 7096 match(Set dst (ConvI2L (LoadB mem))); 7097 7098 ins_cost(VOLATILE_REF_COST); 7099 format %{ "ldarsb $dst, $mem\t# byte" %} 7100 7101 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7102 7103 ins_pipe(pipe_serial); 7104 %} 7105 7106 // Load Byte (8 bit unsigned) 7107 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7108 %{ 7109 match(Set dst (LoadUB mem)); 7110 7111 ins_cost(VOLATILE_REF_COST); 7112 format %{ "ldarb $dst, $mem\t# byte" %} 7113 7114 ins_encode(aarch64_enc_ldarb(dst, mem)); 7115 7116 ins_pipe(pipe_serial); 7117 %} 7118 7119 // Load Byte (8 bit unsigned) into long 7120 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7121 %{ 7122 match(Set dst (ConvI2L (LoadUB mem))); 7123 7124 ins_cost(VOLATILE_REF_COST); 7125 format %{ "ldarb $dst, $mem\t# byte" %} 7126 7127 ins_encode(aarch64_enc_ldarb(dst, mem)); 7128 7129 ins_pipe(pipe_serial); 7130 %} 7131 7132 // Load Short (16 bit signed) 7133 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7134 %{ 7135 match(Set dst (LoadS mem)); 7136 7137 ins_cost(VOLATILE_REF_COST); 7138 format %{ "ldarshw $dst, $mem\t# short" %} 7139 7140 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7141 7142 ins_pipe(pipe_serial); 7143 %} 7144 7145 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7146 %{ 7147 match(Set dst (LoadUS mem)); 7148 7149 ins_cost(VOLATILE_REF_COST); 7150 format %{ "ldarhw $dst, $mem\t# short" %} 7151 7152 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7153 7154 ins_pipe(pipe_serial); 7155 %} 7156 7157 // Load Short/Char (16 bit unsigned) into long 7158 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7159 %{ 7160 match(Set dst (ConvI2L (LoadUS mem))); 7161 7162 ins_cost(VOLATILE_REF_COST); 7163 format %{ "ldarh $dst, $mem\t# short" %} 7164 7165 ins_encode(aarch64_enc_ldarh(dst, mem)); 7166 7167 ins_pipe(pipe_serial); 7168 %} 7169 7170 // Load Short/Char (16 bit signed) into long 7171 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7172 %{ 7173 match(Set dst (ConvI2L (LoadS mem))); 7174 7175 ins_cost(VOLATILE_REF_COST); 7176 format %{ "ldarh $dst, $mem\t# short" %} 7177 7178 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7179 7180 ins_pipe(pipe_serial); 7181 %} 7182 7183 // Load Integer (32 bit signed) 7184 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7185 %{ 7186 match(Set dst (LoadI mem)); 7187 7188 ins_cost(VOLATILE_REF_COST); 7189 format %{ "ldarw $dst, $mem\t# int" %} 7190 7191 ins_encode(aarch64_enc_ldarw(dst, mem)); 7192 7193 ins_pipe(pipe_serial); 7194 %} 7195 7196 // Load Integer (32 bit unsigned) into long 7197 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7198 %{ 7199 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7200 7201 ins_cost(VOLATILE_REF_COST); 7202 format %{ "ldarw $dst, $mem\t# int" %} 7203 7204 ins_encode(aarch64_enc_ldarw(dst, mem)); 7205 7206 ins_pipe(pipe_serial); 7207 %} 7208 7209 // Load Long (64 bit signed) 7210 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7211 %{ 7212 match(Set dst (LoadL mem)); 7213 7214 ins_cost(VOLATILE_REF_COST); 7215 format %{ "ldar $dst, $mem\t# int" %} 7216 7217 ins_encode(aarch64_enc_ldar(dst, mem)); 7218 7219 ins_pipe(pipe_serial); 7220 %} 7221 7222 // Load Pointer 7223 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7224 %{ 7225 match(Set dst (LoadP mem)); 7226 7227 ins_cost(VOLATILE_REF_COST); 7228 format %{ "ldar $dst, $mem\t# ptr" %} 7229 7230 ins_encode(aarch64_enc_ldar(dst, mem)); 7231 7232 ins_pipe(pipe_serial); 7233 %} 7234 7235 // Load Compressed Pointer 7236 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7237 %{ 7238 match(Set dst (LoadN mem)); 7239 7240 ins_cost(VOLATILE_REF_COST); 7241 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7242 7243 ins_encode(aarch64_enc_ldarw(dst, mem)); 7244 7245 ins_pipe(pipe_serial); 7246 %} 7247 7248 // Load Float 7249 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7250 %{ 7251 match(Set dst (LoadF mem)); 7252 7253 ins_cost(VOLATILE_REF_COST); 7254 format %{ "ldars $dst, $mem\t# float" %} 7255 7256 ins_encode( aarch64_enc_fldars(dst, mem) ); 7257 7258 ins_pipe(pipe_serial); 7259 %} 7260 7261 // Load Double 7262 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7263 %{ 7264 match(Set dst (LoadD mem)); 7265 7266 ins_cost(VOLATILE_REF_COST); 7267 format %{ "ldard $dst, $mem\t# double" %} 7268 7269 ins_encode( aarch64_enc_fldard(dst, mem) ); 7270 7271 ins_pipe(pipe_serial); 7272 %} 7273 7274 // Store Byte 7275 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7276 %{ 7277 match(Set mem (StoreB mem src)); 7278 7279 ins_cost(VOLATILE_REF_COST); 7280 format %{ "stlrb $src, $mem\t# byte" %} 7281 7282 ins_encode(aarch64_enc_stlrb(src, mem)); 7283 7284 ins_pipe(pipe_class_memory); 7285 %} 7286 7287 // Store Char/Short 7288 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7289 %{ 7290 match(Set mem (StoreC mem src)); 7291 7292 ins_cost(VOLATILE_REF_COST); 7293 format %{ "stlrh $src, $mem\t# short" %} 7294 7295 ins_encode(aarch64_enc_stlrh(src, mem)); 7296 7297 ins_pipe(pipe_class_memory); 7298 %} 7299 7300 // Store Integer 7301 7302 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7303 %{ 7304 match(Set mem(StoreI mem src)); 7305 7306 ins_cost(VOLATILE_REF_COST); 7307 format %{ "stlrw $src, $mem\t# int" %} 7308 7309 ins_encode(aarch64_enc_stlrw(src, mem)); 7310 7311 ins_pipe(pipe_class_memory); 7312 %} 7313 7314 // Store Long (64 bit signed) 7315 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7316 %{ 7317 match(Set mem (StoreL mem src)); 7318 7319 ins_cost(VOLATILE_REF_COST); 7320 format %{ "stlr $src, $mem\t# int" %} 7321 7322 ins_encode(aarch64_enc_stlr(src, mem)); 7323 7324 ins_pipe(pipe_class_memory); 7325 %} 7326 7327 // Store Pointer 7328 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7329 %{ 7330 match(Set mem (StoreP mem src)); 7331 7332 ins_cost(VOLATILE_REF_COST); 7333 format %{ "stlr $src, $mem\t# ptr" %} 7334 7335 ins_encode(aarch64_enc_stlr(src, mem)); 7336 7337 ins_pipe(pipe_class_memory); 7338 %} 7339 7340 // Store Compressed Pointer 7341 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7342 %{ 7343 match(Set mem (StoreN mem src)); 7344 7345 ins_cost(VOLATILE_REF_COST); 7346 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7347 7348 ins_encode(aarch64_enc_stlrw(src, mem)); 7349 7350 ins_pipe(pipe_class_memory); 7351 %} 7352 7353 // Store Float 7354 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7355 %{ 7356 match(Set mem (StoreF mem src)); 7357 7358 ins_cost(VOLATILE_REF_COST); 7359 format %{ "stlrs $src, $mem\t# float" %} 7360 7361 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7362 7363 ins_pipe(pipe_class_memory); 7364 %} 7365 7366 // TODO 7367 // implement storeImmF0 and storeFImmPacked 7368 7369 // Store Double 7370 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7371 %{ 7372 match(Set mem (StoreD mem src)); 7373 7374 ins_cost(VOLATILE_REF_COST); 7375 format %{ "stlrd $src, $mem\t# double" %} 7376 7377 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7378 7379 ins_pipe(pipe_class_memory); 7380 %} 7381 7382 // ---------------- end of volatile loads and stores ---------------- 7383 7384 // ============================================================================ 7385 // BSWAP Instructions 7386 7387 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7388 match(Set dst (ReverseBytesI src)); 7389 7390 ins_cost(INSN_COST); 7391 format %{ "revw $dst, $src" %} 7392 7393 ins_encode %{ 7394 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7395 %} 7396 7397 ins_pipe(ialu_reg); 7398 %} 7399 7400 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7401 match(Set dst (ReverseBytesL src)); 7402 7403 ins_cost(INSN_COST); 7404 format %{ "rev $dst, $src" %} 7405 7406 ins_encode %{ 7407 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7408 %} 7409 7410 ins_pipe(ialu_reg); 7411 %} 7412 7413 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7414 match(Set dst (ReverseBytesUS src)); 7415 7416 ins_cost(INSN_COST); 7417 format %{ "rev16w $dst, $src" %} 7418 7419 ins_encode %{ 7420 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7421 %} 7422 7423 ins_pipe(ialu_reg); 7424 %} 7425 7426 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7427 match(Set dst (ReverseBytesS src)); 7428 7429 ins_cost(INSN_COST); 7430 format %{ "rev16w $dst, $src\n\t" 7431 "sbfmw $dst, $dst, #0, #15" %} 7432 7433 ins_encode %{ 7434 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7435 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7436 %} 7437 7438 ins_pipe(ialu_reg); 7439 %} 7440 7441 // ============================================================================ 7442 // Zero Count Instructions 7443 7444 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7445 match(Set dst (CountLeadingZerosI src)); 7446 7447 ins_cost(INSN_COST); 7448 format %{ "clzw $dst, $src" %} 7449 ins_encode %{ 7450 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7451 %} 7452 7453 ins_pipe(ialu_reg); 7454 %} 7455 7456 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7457 match(Set dst (CountLeadingZerosL src)); 7458 7459 ins_cost(INSN_COST); 7460 format %{ "clz $dst, $src" %} 7461 ins_encode %{ 7462 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7463 %} 7464 7465 ins_pipe(ialu_reg); 7466 %} 7467 7468 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7469 match(Set dst (CountTrailingZerosI src)); 7470 7471 ins_cost(INSN_COST * 2); 7472 format %{ "rbitw $dst, $src\n\t" 7473 "clzw $dst, $dst" %} 7474 ins_encode %{ 7475 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7476 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7477 %} 7478 7479 ins_pipe(ialu_reg); 7480 %} 7481 7482 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7483 match(Set dst (CountTrailingZerosL src)); 7484 7485 ins_cost(INSN_COST * 2); 7486 format %{ "rbit $dst, $src\n\t" 7487 "clz $dst, $dst" %} 7488 ins_encode %{ 7489 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7490 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7491 %} 7492 7493 ins_pipe(ialu_reg); 7494 %} 7495 7496 //---------- Population Count Instructions ------------------------------------- 7497 // 7498 7499 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7500 predicate(UsePopCountInstruction); 7501 match(Set dst (PopCountI src)); 7502 effect(TEMP tmp); 7503 ins_cost(INSN_COST * 13); 7504 7505 format %{ "movw $src, $src\n\t" 7506 "mov $tmp, $src\t# vector (1D)\n\t" 7507 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7508 "addv $tmp, $tmp\t# vector (8B)\n\t" 7509 "mov $dst, $tmp\t# vector (1D)" %} 7510 ins_encode %{ 7511 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7512 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7513 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7514 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7515 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7516 %} 7517 7518 ins_pipe(pipe_class_default); 7519 %} 7520 7521 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7522 predicate(UsePopCountInstruction); 7523 match(Set dst (PopCountI (LoadI mem))); 7524 effect(TEMP tmp); 7525 ins_cost(INSN_COST * 13); 7526 7527 format %{ "ldrs $tmp, $mem\n\t" 7528 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7529 "addv $tmp, $tmp\t# vector (8B)\n\t" 7530 "mov $dst, $tmp\t# vector (1D)" %} 7531 ins_encode %{ 7532 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7533 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7534 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7535 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7536 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7537 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7538 %} 7539 7540 ins_pipe(pipe_class_default); 7541 %} 7542 7543 // Note: Long.bitCount(long) returns an int. 7544 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7545 predicate(UsePopCountInstruction); 7546 match(Set dst (PopCountL src)); 7547 effect(TEMP tmp); 7548 ins_cost(INSN_COST * 13); 7549 7550 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7551 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7552 "addv $tmp, $tmp\t# vector (8B)\n\t" 7553 "mov $dst, $tmp\t# vector (1D)" %} 7554 ins_encode %{ 7555 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7556 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7557 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7558 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7559 %} 7560 7561 ins_pipe(pipe_class_default); 7562 %} 7563 7564 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7565 predicate(UsePopCountInstruction); 7566 match(Set dst (PopCountL (LoadL mem))); 7567 effect(TEMP tmp); 7568 ins_cost(INSN_COST * 13); 7569 7570 format %{ "ldrd $tmp, $mem\n\t" 7571 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7572 "addv $tmp, $tmp\t# vector (8B)\n\t" 7573 "mov $dst, $tmp\t# vector (1D)" %} 7574 ins_encode %{ 7575 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7576 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7577 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7578 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7579 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7580 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7581 %} 7582 7583 ins_pipe(pipe_class_default); 7584 %} 7585 7586 // ============================================================================ 7587 // MemBar Instruction 7588 7589 instruct load_fence() %{ 7590 match(LoadFence); 7591 ins_cost(VOLATILE_REF_COST); 7592 7593 format %{ "load_fence" %} 7594 7595 ins_encode %{ 7596 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7597 %} 7598 ins_pipe(pipe_serial); 7599 %} 7600 7601 instruct unnecessary_membar_acquire() %{ 7602 predicate(unnecessary_acquire(n)); 7603 match(MemBarAcquire); 7604 ins_cost(0); 7605 7606 format %{ "membar_acquire (elided)" %} 7607 7608 ins_encode %{ 7609 __ block_comment("membar_acquire (elided)"); 7610 %} 7611 7612 ins_pipe(pipe_class_empty); 7613 %} 7614 7615 instruct membar_acquire() %{ 7616 match(MemBarAcquire); 7617 ins_cost(VOLATILE_REF_COST); 7618 7619 format %{ "membar_acquire\n\t" 7620 "dmb ish" %} 7621 7622 ins_encode %{ 7623 __ block_comment("membar_acquire"); 7624 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7625 %} 7626 7627 ins_pipe(pipe_serial); 7628 %} 7629 7630 7631 instruct membar_acquire_lock() %{ 7632 match(MemBarAcquireLock); 7633 ins_cost(VOLATILE_REF_COST); 7634 7635 format %{ "membar_acquire_lock (elided)" %} 7636 7637 ins_encode %{ 7638 __ block_comment("membar_acquire_lock (elided)"); 7639 %} 7640 7641 ins_pipe(pipe_serial); 7642 %} 7643 7644 instruct store_fence() %{ 7645 match(StoreFence); 7646 ins_cost(VOLATILE_REF_COST); 7647 7648 format %{ "store_fence" %} 7649 7650 ins_encode %{ 7651 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7652 %} 7653 ins_pipe(pipe_serial); 7654 %} 7655 7656 instruct unnecessary_membar_release() %{ 7657 predicate(unnecessary_release(n)); 7658 match(MemBarRelease); 7659 ins_cost(0); 7660 7661 format %{ "membar_release (elided)" %} 7662 7663 ins_encode %{ 7664 __ block_comment("membar_release (elided)"); 7665 %} 7666 ins_pipe(pipe_serial); 7667 %} 7668 7669 instruct membar_release() %{ 7670 match(MemBarRelease); 7671 ins_cost(VOLATILE_REF_COST); 7672 7673 format %{ "membar_release\n\t" 7674 "dmb ish" %} 7675 7676 ins_encode %{ 7677 __ block_comment("membar_release"); 7678 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7679 %} 7680 ins_pipe(pipe_serial); 7681 %} 7682 7683 instruct membar_storestore() %{ 7684 match(MemBarStoreStore); 7685 ins_cost(VOLATILE_REF_COST); 7686 7687 format %{ "MEMBAR-store-store" %} 7688 7689 ins_encode %{ 7690 __ membar(Assembler::StoreStore); 7691 %} 7692 ins_pipe(pipe_serial); 7693 %} 7694 7695 instruct membar_release_lock() %{ 7696 match(MemBarReleaseLock); 7697 ins_cost(VOLATILE_REF_COST); 7698 7699 format %{ "membar_release_lock (elided)" %} 7700 7701 ins_encode %{ 7702 __ block_comment("membar_release_lock (elided)"); 7703 %} 7704 7705 ins_pipe(pipe_serial); 7706 %} 7707 7708 instruct unnecessary_membar_volatile() %{ 7709 predicate(unnecessary_volatile(n)); 7710 match(MemBarVolatile); 7711 ins_cost(0); 7712 7713 format %{ "membar_volatile (elided)" %} 7714 7715 ins_encode %{ 7716 __ block_comment("membar_volatile (elided)"); 7717 %} 7718 7719 ins_pipe(pipe_serial); 7720 %} 7721 7722 instruct membar_volatile() %{ 7723 match(MemBarVolatile); 7724 ins_cost(VOLATILE_REF_COST*100); 7725 7726 format %{ "membar_volatile\n\t" 7727 "dmb ish"%} 7728 7729 ins_encode %{ 7730 __ block_comment("membar_volatile"); 7731 __ membar(Assembler::StoreLoad); 7732 %} 7733 7734 ins_pipe(pipe_serial); 7735 %} 7736 7737 // ============================================================================ 7738 // Cast/Convert Instructions 7739 7740 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7741 match(Set dst (CastX2P src)); 7742 7743 ins_cost(INSN_COST); 7744 format %{ "mov $dst, $src\t# long -> ptr" %} 7745 7746 ins_encode %{ 7747 if ($dst$$reg != $src$$reg) { 7748 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7749 } 7750 %} 7751 7752 ins_pipe(ialu_reg); 7753 %} 7754 7755 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7756 match(Set dst (CastP2X src)); 7757 7758 ins_cost(INSN_COST); 7759 format %{ "mov $dst, $src\t# ptr -> long" %} 7760 7761 ins_encode %{ 7762 if ($dst$$reg != $src$$reg) { 7763 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7764 } 7765 %} 7766 7767 ins_pipe(ialu_reg); 7768 %} 7769 7770 // Convert oop into int for vectors alignment masking 7771 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7772 match(Set dst (ConvL2I (CastP2X src))); 7773 7774 ins_cost(INSN_COST); 7775 format %{ "movw $dst, $src\t# ptr -> int" %} 7776 ins_encode %{ 7777 __ movw($dst$$Register, $src$$Register); 7778 %} 7779 7780 ins_pipe(ialu_reg); 7781 %} 7782 7783 // Convert compressed oop into int for vectors alignment masking 7784 // in case of 32bit oops (heap < 4Gb). 7785 instruct convN2I(iRegINoSp dst, iRegN src) 7786 %{ 7787 predicate(Universe::narrow_oop_shift() == 0); 7788 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7789 7790 ins_cost(INSN_COST); 7791 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7792 ins_encode %{ 7793 __ movw($dst$$Register, $src$$Register); 7794 %} 7795 7796 ins_pipe(ialu_reg); 7797 %} 7798 7799 7800 // Convert oop pointer into compressed form 7801 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7802 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7803 match(Set dst (EncodeP src)); 7804 effect(KILL cr); 7805 ins_cost(INSN_COST * 3); 7806 format %{ "encode_heap_oop $dst, $src" %} 7807 ins_encode %{ 7808 Register s = $src$$Register; 7809 Register d = $dst$$Register; 7810 __ encode_heap_oop(d, s); 7811 %} 7812 ins_pipe(ialu_reg); 7813 %} 7814 7815 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7816 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7817 match(Set dst (EncodeP src)); 7818 ins_cost(INSN_COST * 3); 7819 format %{ "encode_heap_oop_not_null $dst, $src" %} 7820 ins_encode %{ 7821 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7822 %} 7823 ins_pipe(ialu_reg); 7824 %} 7825 7826 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7827 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7828 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7829 match(Set dst (DecodeN src)); 7830 ins_cost(INSN_COST * 3); 7831 format %{ "decode_heap_oop $dst, $src" %} 7832 ins_encode %{ 7833 Register s = $src$$Register; 7834 Register d = $dst$$Register; 7835 __ decode_heap_oop(d, s); 7836 %} 7837 ins_pipe(ialu_reg); 7838 %} 7839 7840 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7841 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7842 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7843 match(Set dst (DecodeN src)); 7844 ins_cost(INSN_COST * 3); 7845 format %{ "decode_heap_oop_not_null $dst, $src" %} 7846 ins_encode %{ 7847 Register s = $src$$Register; 7848 Register d = $dst$$Register; 7849 __ decode_heap_oop_not_null(d, s); 7850 %} 7851 ins_pipe(ialu_reg); 7852 %} 7853 7854 // n.b. AArch64 implementations of encode_klass_not_null and 7855 // decode_klass_not_null do not modify the flags register so, unlike 7856 // Intel, we don't kill CR as a side effect here 7857 7858 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7859 match(Set dst (EncodePKlass src)); 7860 7861 ins_cost(INSN_COST * 3); 7862 format %{ "encode_klass_not_null $dst,$src" %} 7863 7864 ins_encode %{ 7865 Register src_reg = as_Register($src$$reg); 7866 Register dst_reg = as_Register($dst$$reg); 7867 __ encode_klass_not_null(dst_reg, src_reg); 7868 %} 7869 7870 ins_pipe(ialu_reg); 7871 %} 7872 7873 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7874 match(Set dst (DecodeNKlass src)); 7875 7876 ins_cost(INSN_COST * 3); 7877 format %{ "decode_klass_not_null $dst,$src" %} 7878 7879 ins_encode %{ 7880 Register src_reg = as_Register($src$$reg); 7881 Register dst_reg = as_Register($dst$$reg); 7882 if (dst_reg != src_reg) { 7883 __ decode_klass_not_null(dst_reg, src_reg); 7884 } else { 7885 __ decode_klass_not_null(dst_reg); 7886 } 7887 %} 7888 7889 ins_pipe(ialu_reg); 7890 %} 7891 7892 instruct checkCastPP(iRegPNoSp dst) 7893 %{ 7894 match(Set dst (CheckCastPP dst)); 7895 7896 size(0); 7897 format %{ "# checkcastPP of $dst" %} 7898 ins_encode(/* empty encoding */); 7899 ins_pipe(pipe_class_empty); 7900 %} 7901 7902 instruct castPP(iRegPNoSp dst) 7903 %{ 7904 match(Set dst (CastPP dst)); 7905 7906 size(0); 7907 format %{ "# castPP of $dst" %} 7908 ins_encode(/* empty encoding */); 7909 ins_pipe(pipe_class_empty); 7910 %} 7911 7912 instruct castII(iRegI dst) 7913 %{ 7914 match(Set dst (CastII dst)); 7915 7916 size(0); 7917 format %{ "# castII of $dst" %} 7918 ins_encode(/* empty encoding */); 7919 ins_cost(0); 7920 ins_pipe(pipe_class_empty); 7921 %} 7922 7923 instruct castLL(iRegL dst) 7924 %{ 7925 match(Set dst (CastLL dst)); 7926 7927 size(0); 7928 format %{ "# castLL of $dst" %} 7929 ins_encode(/* empty encoding */); 7930 ins_cost(0); 7931 ins_pipe(pipe_class_empty); 7932 %} 7933 7934 // ============================================================================ 7935 // Atomic operation instructions 7936 // 7937 // Intel and SPARC both implement Ideal Node LoadPLocked and 7938 // Store{PIL}Conditional instructions using a normal load for the 7939 // LoadPLocked and a CAS for the Store{PIL}Conditional. 7940 // 7941 // The ideal code appears only to use LoadPLocked/StorePLocked as a 7942 // pair to lock object allocations from Eden space when not using 7943 // TLABs. 7944 // 7945 // There does not appear to be a Load{IL}Locked Ideal Node and the 7946 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 7947 // and to use StoreIConditional only for 32-bit and StoreLConditional 7948 // only for 64-bit. 7949 // 7950 // We implement LoadPLocked and StorePLocked instructions using, 7951 // respectively the AArch64 hw load-exclusive and store-conditional 7952 // instructions. Whereas we must implement each of 7953 // Store{IL}Conditional using a CAS which employs a pair of 7954 // instructions comprising a load-exclusive followed by a 7955 // store-conditional. 7956 7957 7958 // Locked-load (linked load) of the current heap-top 7959 // used when updating the eden heap top 7960 // implemented using ldaxr on AArch64 7961 7962 instruct loadPLocked(iRegPNoSp dst, indirect mem) 7963 %{ 7964 match(Set dst (LoadPLocked mem)); 7965 7966 ins_cost(VOLATILE_REF_COST); 7967 7968 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7969 7970 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7971 7972 ins_pipe(pipe_serial); 7973 %} 7974 7975 // Conditional-store of the updated heap-top. 7976 // Used during allocation of the shared heap. 7977 // Sets flag (EQ) on success. 7978 // implemented using stlxr on AArch64. 7979 7980 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7981 %{ 7982 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7983 7984 ins_cost(VOLATILE_REF_COST); 7985 7986 // TODO 7987 // do we need to do a store-conditional release or can we just use a 7988 // plain store-conditional? 7989 7990 format %{ 7991 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 7992 "cmpw rscratch1, zr\t# EQ on successful write" 7993 %} 7994 7995 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 7996 7997 ins_pipe(pipe_serial); 7998 %} 7999 8000 8001 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8002 // when attempting to rebias a lock towards the current thread. We 8003 // must use the acquire form of cmpxchg in order to guarantee acquire 8004 // semantics in this case. 8005 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8006 %{ 8007 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8008 8009 ins_cost(VOLATILE_REF_COST); 8010 8011 format %{ 8012 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8013 "cmpw rscratch1, zr\t# EQ on successful write" 8014 %} 8015 8016 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8017 8018 ins_pipe(pipe_slow); 8019 %} 8020 8021 // storeIConditional also has acquire semantics, for no better reason 8022 // than matching storeLConditional. At the time of writing this 8023 // comment storeIConditional was not used anywhere by AArch64. 8024 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8025 %{ 8026 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8027 8028 ins_cost(VOLATILE_REF_COST); 8029 8030 format %{ 8031 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8032 "cmpw rscratch1, zr\t# EQ on successful write" 8033 %} 8034 8035 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8036 8037 ins_pipe(pipe_slow); 8038 %} 8039 8040 // standard CompareAndSwapX when we are using barriers 8041 // these have higher priority than the rules selected by a predicate 8042 8043 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8044 // can't match them 8045 8046 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8047 8048 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8049 ins_cost(2 * VOLATILE_REF_COST); 8050 8051 effect(KILL cr); 8052 8053 format %{ 8054 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8055 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8056 %} 8057 8058 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8059 aarch64_enc_cset_eq(res)); 8060 8061 ins_pipe(pipe_slow); 8062 %} 8063 8064 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8065 8066 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8067 ins_cost(2 * VOLATILE_REF_COST); 8068 8069 effect(KILL cr); 8070 8071 format %{ 8072 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8073 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8074 %} 8075 8076 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8077 aarch64_enc_cset_eq(res)); 8078 8079 ins_pipe(pipe_slow); 8080 %} 8081 8082 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8083 8084 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8085 ins_cost(2 * VOLATILE_REF_COST); 8086 8087 effect(KILL cr); 8088 8089 format %{ 8090 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8091 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8092 %} 8093 8094 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8095 aarch64_enc_cset_eq(res)); 8096 8097 ins_pipe(pipe_slow); 8098 %} 8099 8100 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8101 8102 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8103 ins_cost(2 * VOLATILE_REF_COST); 8104 8105 effect(KILL cr); 8106 8107 format %{ 8108 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8109 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8110 %} 8111 8112 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8113 aarch64_enc_cset_eq(res)); 8114 8115 ins_pipe(pipe_slow); 8116 %} 8117 8118 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8119 8120 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8121 ins_cost(2 * VOLATILE_REF_COST); 8122 8123 effect(KILL cr); 8124 8125 format %{ 8126 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8127 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8128 %} 8129 8130 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8131 aarch64_enc_cset_eq(res)); 8132 8133 ins_pipe(pipe_slow); 8134 %} 8135 8136 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8137 8138 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8139 ins_cost(2 * VOLATILE_REF_COST); 8140 8141 effect(KILL cr); 8142 8143 format %{ 8144 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8145 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8146 %} 8147 8148 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8149 aarch64_enc_cset_eq(res)); 8150 8151 ins_pipe(pipe_slow); 8152 %} 8153 8154 // alternative CompareAndSwapX when we are eliding barriers 8155 8156 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8157 8158 predicate(needs_acquiring_load_exclusive(n)); 8159 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8160 ins_cost(VOLATILE_REF_COST); 8161 8162 effect(KILL cr); 8163 8164 format %{ 8165 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8166 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8167 %} 8168 8169 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8170 aarch64_enc_cset_eq(res)); 8171 8172 ins_pipe(pipe_slow); 8173 %} 8174 8175 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8176 8177 predicate(needs_acquiring_load_exclusive(n)); 8178 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8179 ins_cost(VOLATILE_REF_COST); 8180 8181 effect(KILL cr); 8182 8183 format %{ 8184 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8185 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8186 %} 8187 8188 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8189 aarch64_enc_cset_eq(res)); 8190 8191 ins_pipe(pipe_slow); 8192 %} 8193 8194 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8195 8196 predicate(needs_acquiring_load_exclusive(n)); 8197 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8198 ins_cost(VOLATILE_REF_COST); 8199 8200 effect(KILL cr); 8201 8202 format %{ 8203 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8204 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8205 %} 8206 8207 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8208 aarch64_enc_cset_eq(res)); 8209 8210 ins_pipe(pipe_slow); 8211 %} 8212 8213 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8214 8215 predicate(needs_acquiring_load_exclusive(n)); 8216 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8217 ins_cost(VOLATILE_REF_COST); 8218 8219 effect(KILL cr); 8220 8221 format %{ 8222 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8223 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8224 %} 8225 8226 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8227 aarch64_enc_cset_eq(res)); 8228 8229 ins_pipe(pipe_slow); 8230 %} 8231 8232 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8233 8234 predicate(needs_acquiring_load_exclusive(n)); 8235 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8236 ins_cost(VOLATILE_REF_COST); 8237 8238 effect(KILL cr); 8239 8240 format %{ 8241 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8242 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8243 %} 8244 8245 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8246 aarch64_enc_cset_eq(res)); 8247 8248 ins_pipe(pipe_slow); 8249 %} 8250 8251 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8252 8253 predicate(needs_acquiring_load_exclusive(n)); 8254 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8255 ins_cost(VOLATILE_REF_COST); 8256 8257 effect(KILL cr); 8258 8259 format %{ 8260 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8261 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8262 %} 8263 8264 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8265 aarch64_enc_cset_eq(res)); 8266 8267 ins_pipe(pipe_slow); 8268 %} 8269 8270 8271 // --------------------------------------------------------------------- 8272 8273 8274 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8275 8276 // Sundry CAS operations. Note that release is always true, 8277 // regardless of the memory ordering of the CAS. This is because we 8278 // need the volatile case to be sequentially consistent but there is 8279 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8280 // can't check the type of memory ordering here, so we always emit a 8281 // STLXR. 8282 8283 // This section is generated from aarch64_ad_cas.m4 8284 8285 8286 8287 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8288 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8289 ins_cost(2 * VOLATILE_REF_COST); 8290 effect(TEMP_DEF res, KILL cr); 8291 format %{ 8292 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8293 %} 8294 ins_encode %{ 8295 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8296 Assembler::byte, /*acquire*/ false, /*release*/ true, 8297 /*weak*/ false, $res$$Register); 8298 __ sxtbw($res$$Register, $res$$Register); 8299 %} 8300 ins_pipe(pipe_slow); 8301 %} 8302 8303 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8304 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8305 ins_cost(2 * VOLATILE_REF_COST); 8306 effect(TEMP_DEF res, KILL cr); 8307 format %{ 8308 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8309 %} 8310 ins_encode %{ 8311 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8312 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8313 /*weak*/ false, $res$$Register); 8314 __ sxthw($res$$Register, $res$$Register); 8315 %} 8316 ins_pipe(pipe_slow); 8317 %} 8318 8319 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8320 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8321 ins_cost(2 * VOLATILE_REF_COST); 8322 effect(TEMP_DEF res, KILL cr); 8323 format %{ 8324 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8325 %} 8326 ins_encode %{ 8327 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8328 Assembler::word, /*acquire*/ false, /*release*/ true, 8329 /*weak*/ false, $res$$Register); 8330 %} 8331 ins_pipe(pipe_slow); 8332 %} 8333 8334 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8335 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8336 ins_cost(2 * VOLATILE_REF_COST); 8337 effect(TEMP_DEF res, KILL cr); 8338 format %{ 8339 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8340 %} 8341 ins_encode %{ 8342 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8343 Assembler::xword, /*acquire*/ false, /*release*/ true, 8344 /*weak*/ false, $res$$Register); 8345 %} 8346 ins_pipe(pipe_slow); 8347 %} 8348 8349 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8350 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8351 ins_cost(2 * VOLATILE_REF_COST); 8352 effect(TEMP_DEF res, KILL cr); 8353 format %{ 8354 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8355 %} 8356 ins_encode %{ 8357 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8358 Assembler::word, /*acquire*/ false, /*release*/ true, 8359 /*weak*/ false, $res$$Register); 8360 %} 8361 ins_pipe(pipe_slow); 8362 %} 8363 8364 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8365 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8366 ins_cost(2 * VOLATILE_REF_COST); 8367 effect(TEMP_DEF res, KILL cr); 8368 format %{ 8369 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8370 %} 8371 ins_encode %{ 8372 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8373 Assembler::xword, /*acquire*/ false, /*release*/ true, 8374 /*weak*/ false, $res$$Register); 8375 %} 8376 ins_pipe(pipe_slow); 8377 %} 8378 8379 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8380 predicate(needs_acquiring_load_exclusive(n)); 8381 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8382 ins_cost(VOLATILE_REF_COST); 8383 effect(TEMP_DEF res, KILL cr); 8384 format %{ 8385 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8386 %} 8387 ins_encode %{ 8388 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8389 Assembler::byte, /*acquire*/ true, /*release*/ true, 8390 /*weak*/ false, $res$$Register); 8391 __ sxtbw($res$$Register, $res$$Register); 8392 %} 8393 ins_pipe(pipe_slow); 8394 %} 8395 8396 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8397 predicate(needs_acquiring_load_exclusive(n)); 8398 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8399 ins_cost(VOLATILE_REF_COST); 8400 effect(TEMP_DEF res, KILL cr); 8401 format %{ 8402 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8403 %} 8404 ins_encode %{ 8405 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8406 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8407 /*weak*/ false, $res$$Register); 8408 __ sxthw($res$$Register, $res$$Register); 8409 %} 8410 ins_pipe(pipe_slow); 8411 %} 8412 8413 8414 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8415 predicate(needs_acquiring_load_exclusive(n)); 8416 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8417 ins_cost(VOLATILE_REF_COST); 8418 effect(TEMP_DEF res, KILL cr); 8419 format %{ 8420 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8421 %} 8422 ins_encode %{ 8423 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8424 Assembler::word, /*acquire*/ true, /*release*/ true, 8425 /*weak*/ false, $res$$Register); 8426 %} 8427 ins_pipe(pipe_slow); 8428 %} 8429 8430 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8431 predicate(needs_acquiring_load_exclusive(n)); 8432 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8433 ins_cost(VOLATILE_REF_COST); 8434 effect(TEMP_DEF res, KILL cr); 8435 format %{ 8436 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8437 %} 8438 ins_encode %{ 8439 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8440 Assembler::xword, /*acquire*/ true, /*release*/ true, 8441 /*weak*/ false, $res$$Register); 8442 %} 8443 ins_pipe(pipe_slow); 8444 %} 8445 8446 8447 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8448 predicate(needs_acquiring_load_exclusive(n)); 8449 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8450 ins_cost(VOLATILE_REF_COST); 8451 effect(TEMP_DEF res, KILL cr); 8452 format %{ 8453 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8454 %} 8455 ins_encode %{ 8456 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8457 Assembler::word, /*acquire*/ true, /*release*/ true, 8458 /*weak*/ false, $res$$Register); 8459 %} 8460 ins_pipe(pipe_slow); 8461 %} 8462 8463 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8464 predicate(needs_acquiring_load_exclusive(n)); 8465 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8466 ins_cost(VOLATILE_REF_COST); 8467 effect(TEMP_DEF res, KILL cr); 8468 format %{ 8469 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8470 %} 8471 ins_encode %{ 8472 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8473 Assembler::xword, /*acquire*/ true, /*release*/ true, 8474 /*weak*/ false, $res$$Register); 8475 %} 8476 ins_pipe(pipe_slow); 8477 %} 8478 8479 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8480 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8481 ins_cost(2 * VOLATILE_REF_COST); 8482 effect(KILL cr); 8483 format %{ 8484 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8485 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8486 %} 8487 ins_encode %{ 8488 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8489 Assembler::byte, /*acquire*/ false, /*release*/ true, 8490 /*weak*/ true, noreg); 8491 __ csetw($res$$Register, Assembler::EQ); 8492 %} 8493 ins_pipe(pipe_slow); 8494 %} 8495 8496 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8497 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8498 ins_cost(2 * VOLATILE_REF_COST); 8499 effect(KILL cr); 8500 format %{ 8501 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8502 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8503 %} 8504 ins_encode %{ 8505 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8506 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8507 /*weak*/ true, noreg); 8508 __ csetw($res$$Register, Assembler::EQ); 8509 %} 8510 ins_pipe(pipe_slow); 8511 %} 8512 8513 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8514 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8515 ins_cost(2 * VOLATILE_REF_COST); 8516 effect(KILL cr); 8517 format %{ 8518 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8519 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8520 %} 8521 ins_encode %{ 8522 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8523 Assembler::word, /*acquire*/ false, /*release*/ true, 8524 /*weak*/ true, noreg); 8525 __ csetw($res$$Register, Assembler::EQ); 8526 %} 8527 ins_pipe(pipe_slow); 8528 %} 8529 8530 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8531 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8532 ins_cost(2 * VOLATILE_REF_COST); 8533 effect(KILL cr); 8534 format %{ 8535 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8536 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8537 %} 8538 ins_encode %{ 8539 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8540 Assembler::xword, /*acquire*/ false, /*release*/ true, 8541 /*weak*/ true, noreg); 8542 __ csetw($res$$Register, Assembler::EQ); 8543 %} 8544 ins_pipe(pipe_slow); 8545 %} 8546 8547 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8548 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8549 ins_cost(2 * VOLATILE_REF_COST); 8550 effect(KILL cr); 8551 format %{ 8552 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8553 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8554 %} 8555 ins_encode %{ 8556 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8557 Assembler::word, /*acquire*/ false, /*release*/ true, 8558 /*weak*/ true, noreg); 8559 __ csetw($res$$Register, Assembler::EQ); 8560 %} 8561 ins_pipe(pipe_slow); 8562 %} 8563 8564 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8565 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8566 ins_cost(2 * VOLATILE_REF_COST); 8567 effect(KILL cr); 8568 format %{ 8569 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8570 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8571 %} 8572 ins_encode %{ 8573 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8574 Assembler::xword, /*acquire*/ false, /*release*/ true, 8575 /*weak*/ true, noreg); 8576 __ csetw($res$$Register, Assembler::EQ); 8577 %} 8578 ins_pipe(pipe_slow); 8579 %} 8580 8581 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8582 predicate(needs_acquiring_load_exclusive(n)); 8583 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8584 ins_cost(VOLATILE_REF_COST); 8585 effect(KILL cr); 8586 format %{ 8587 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8588 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8589 %} 8590 ins_encode %{ 8591 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8592 Assembler::byte, /*acquire*/ true, /*release*/ true, 8593 /*weak*/ true, noreg); 8594 __ csetw($res$$Register, Assembler::EQ); 8595 %} 8596 ins_pipe(pipe_slow); 8597 %} 8598 8599 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8600 predicate(needs_acquiring_load_exclusive(n)); 8601 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8602 ins_cost(VOLATILE_REF_COST); 8603 effect(KILL cr); 8604 format %{ 8605 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8606 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8607 %} 8608 ins_encode %{ 8609 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8610 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8611 /*weak*/ true, noreg); 8612 __ csetw($res$$Register, Assembler::EQ); 8613 %} 8614 ins_pipe(pipe_slow); 8615 %} 8616 8617 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8618 predicate(needs_acquiring_load_exclusive(n)); 8619 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8620 ins_cost(VOLATILE_REF_COST); 8621 effect(KILL cr); 8622 format %{ 8623 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8624 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8625 %} 8626 ins_encode %{ 8627 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8628 Assembler::word, /*acquire*/ true, /*release*/ true, 8629 /*weak*/ true, noreg); 8630 __ csetw($res$$Register, Assembler::EQ); 8631 %} 8632 ins_pipe(pipe_slow); 8633 %} 8634 8635 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8636 predicate(needs_acquiring_load_exclusive(n)); 8637 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8638 ins_cost(VOLATILE_REF_COST); 8639 effect(KILL cr); 8640 format %{ 8641 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8642 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8643 %} 8644 ins_encode %{ 8645 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8646 Assembler::xword, /*acquire*/ true, /*release*/ true, 8647 /*weak*/ true, noreg); 8648 __ csetw($res$$Register, Assembler::EQ); 8649 %} 8650 ins_pipe(pipe_slow); 8651 %} 8652 8653 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8654 predicate(needs_acquiring_load_exclusive(n)); 8655 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8656 ins_cost(VOLATILE_REF_COST); 8657 effect(KILL cr); 8658 format %{ 8659 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8660 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8661 %} 8662 ins_encode %{ 8663 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8664 Assembler::word, /*acquire*/ true, /*release*/ true, 8665 /*weak*/ true, noreg); 8666 __ csetw($res$$Register, Assembler::EQ); 8667 %} 8668 ins_pipe(pipe_slow); 8669 %} 8670 8671 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8672 predicate(needs_acquiring_load_exclusive(n)); 8673 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8674 ins_cost(VOLATILE_REF_COST); 8675 effect(KILL cr); 8676 format %{ 8677 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8678 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8679 %} 8680 ins_encode %{ 8681 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8682 Assembler::xword, /*acquire*/ true, /*release*/ true, 8683 /*weak*/ true, noreg); 8684 __ csetw($res$$Register, Assembler::EQ); 8685 %} 8686 ins_pipe(pipe_slow); 8687 %} 8688 8689 // END This section of the file is automatically generated. Do not edit -------------- 8690 // --------------------------------------------------------------------- 8691 8692 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8693 match(Set prev (GetAndSetI mem newv)); 8694 ins_cost(2 * VOLATILE_REF_COST); 8695 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8696 ins_encode %{ 8697 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8698 %} 8699 ins_pipe(pipe_serial); 8700 %} 8701 8702 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8703 match(Set prev (GetAndSetL mem newv)); 8704 ins_cost(2 * VOLATILE_REF_COST); 8705 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8706 ins_encode %{ 8707 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8708 %} 8709 ins_pipe(pipe_serial); 8710 %} 8711 8712 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8713 match(Set prev (GetAndSetN mem newv)); 8714 ins_cost(2 * VOLATILE_REF_COST); 8715 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8716 ins_encode %{ 8717 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8718 %} 8719 ins_pipe(pipe_serial); 8720 %} 8721 8722 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8723 match(Set prev (GetAndSetP mem newv)); 8724 ins_cost(2 * VOLATILE_REF_COST); 8725 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8726 ins_encode %{ 8727 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8728 %} 8729 ins_pipe(pipe_serial); 8730 %} 8731 8732 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 8733 predicate(needs_acquiring_load_exclusive(n)); 8734 match(Set prev (GetAndSetI mem newv)); 8735 ins_cost(VOLATILE_REF_COST); 8736 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8737 ins_encode %{ 8738 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8739 %} 8740 ins_pipe(pipe_serial); 8741 %} 8742 8743 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8744 predicate(needs_acquiring_load_exclusive(n)); 8745 match(Set prev (GetAndSetL mem newv)); 8746 ins_cost(VOLATILE_REF_COST); 8747 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8748 ins_encode %{ 8749 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8750 %} 8751 ins_pipe(pipe_serial); 8752 %} 8753 8754 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 8755 predicate(needs_acquiring_load_exclusive(n)); 8756 match(Set prev (GetAndSetN mem newv)); 8757 ins_cost(VOLATILE_REF_COST); 8758 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8759 ins_encode %{ 8760 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8761 %} 8762 ins_pipe(pipe_serial); 8763 %} 8764 8765 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8766 predicate(needs_acquiring_load_exclusive(n)); 8767 match(Set prev (GetAndSetP mem newv)); 8768 ins_cost(VOLATILE_REF_COST); 8769 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8770 ins_encode %{ 8771 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8772 %} 8773 ins_pipe(pipe_serial); 8774 %} 8775 8776 8777 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8778 match(Set newval (GetAndAddL mem incr)); 8779 ins_cost(2 * VOLATILE_REF_COST + 1); 8780 format %{ "get_and_addL $newval, [$mem], $incr" %} 8781 ins_encode %{ 8782 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8783 %} 8784 ins_pipe(pipe_serial); 8785 %} 8786 8787 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8788 predicate(n->as_LoadStore()->result_not_used()); 8789 match(Set dummy (GetAndAddL mem incr)); 8790 ins_cost(2 * VOLATILE_REF_COST); 8791 format %{ "get_and_addL [$mem], $incr" %} 8792 ins_encode %{ 8793 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8794 %} 8795 ins_pipe(pipe_serial); 8796 %} 8797 8798 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8799 match(Set newval (GetAndAddL mem incr)); 8800 ins_cost(2 * VOLATILE_REF_COST + 1); 8801 format %{ "get_and_addL $newval, [$mem], $incr" %} 8802 ins_encode %{ 8803 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8804 %} 8805 ins_pipe(pipe_serial); 8806 %} 8807 8808 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8809 predicate(n->as_LoadStore()->result_not_used()); 8810 match(Set dummy (GetAndAddL mem incr)); 8811 ins_cost(2 * VOLATILE_REF_COST); 8812 format %{ "get_and_addL [$mem], $incr" %} 8813 ins_encode %{ 8814 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8815 %} 8816 ins_pipe(pipe_serial); 8817 %} 8818 8819 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8820 match(Set newval (GetAndAddI mem incr)); 8821 ins_cost(2 * VOLATILE_REF_COST + 1); 8822 format %{ "get_and_addI $newval, [$mem], $incr" %} 8823 ins_encode %{ 8824 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8825 %} 8826 ins_pipe(pipe_serial); 8827 %} 8828 8829 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8830 predicate(n->as_LoadStore()->result_not_used()); 8831 match(Set dummy (GetAndAddI mem incr)); 8832 ins_cost(2 * VOLATILE_REF_COST); 8833 format %{ "get_and_addI [$mem], $incr" %} 8834 ins_encode %{ 8835 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8836 %} 8837 ins_pipe(pipe_serial); 8838 %} 8839 8840 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8841 match(Set newval (GetAndAddI mem incr)); 8842 ins_cost(2 * VOLATILE_REF_COST + 1); 8843 format %{ "get_and_addI $newval, [$mem], $incr" %} 8844 ins_encode %{ 8845 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8846 %} 8847 ins_pipe(pipe_serial); 8848 %} 8849 8850 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8851 predicate(n->as_LoadStore()->result_not_used()); 8852 match(Set dummy (GetAndAddI mem incr)); 8853 ins_cost(2 * VOLATILE_REF_COST); 8854 format %{ "get_and_addI [$mem], $incr" %} 8855 ins_encode %{ 8856 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8857 %} 8858 ins_pipe(pipe_serial); 8859 %} 8860 8861 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8862 predicate(needs_acquiring_load_exclusive(n)); 8863 match(Set newval (GetAndAddL mem incr)); 8864 ins_cost(VOLATILE_REF_COST + 1); 8865 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8866 ins_encode %{ 8867 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8868 %} 8869 ins_pipe(pipe_serial); 8870 %} 8871 8872 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 8873 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8874 match(Set dummy (GetAndAddL mem incr)); 8875 ins_cost(VOLATILE_REF_COST); 8876 format %{ "get_and_addL_acq [$mem], $incr" %} 8877 ins_encode %{ 8878 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 8879 %} 8880 ins_pipe(pipe_serial); 8881 %} 8882 8883 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8884 predicate(needs_acquiring_load_exclusive(n)); 8885 match(Set newval (GetAndAddL mem incr)); 8886 ins_cost(VOLATILE_REF_COST + 1); 8887 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8888 ins_encode %{ 8889 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8890 %} 8891 ins_pipe(pipe_serial); 8892 %} 8893 8894 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 8895 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8896 match(Set dummy (GetAndAddL mem incr)); 8897 ins_cost(VOLATILE_REF_COST); 8898 format %{ "get_and_addL_acq [$mem], $incr" %} 8899 ins_encode %{ 8900 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 8901 %} 8902 ins_pipe(pipe_serial); 8903 %} 8904 8905 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8906 predicate(needs_acquiring_load_exclusive(n)); 8907 match(Set newval (GetAndAddI mem incr)); 8908 ins_cost(VOLATILE_REF_COST + 1); 8909 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8910 ins_encode %{ 8911 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8912 %} 8913 ins_pipe(pipe_serial); 8914 %} 8915 8916 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8917 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8918 match(Set dummy (GetAndAddI mem incr)); 8919 ins_cost(VOLATILE_REF_COST); 8920 format %{ "get_and_addI_acq [$mem], $incr" %} 8921 ins_encode %{ 8922 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 8923 %} 8924 ins_pipe(pipe_serial); 8925 %} 8926 8927 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8928 predicate(needs_acquiring_load_exclusive(n)); 8929 match(Set newval (GetAndAddI mem incr)); 8930 ins_cost(VOLATILE_REF_COST + 1); 8931 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8932 ins_encode %{ 8933 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8934 %} 8935 ins_pipe(pipe_serial); 8936 %} 8937 8938 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 8939 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8940 match(Set dummy (GetAndAddI mem incr)); 8941 ins_cost(VOLATILE_REF_COST); 8942 format %{ "get_and_addI_acq [$mem], $incr" %} 8943 ins_encode %{ 8944 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 8945 %} 8946 ins_pipe(pipe_serial); 8947 %} 8948 8949 // Manifest a CmpL result in an integer register. 8950 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8951 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8952 %{ 8953 match(Set dst (CmpL3 src1 src2)); 8954 effect(KILL flags); 8955 8956 ins_cost(INSN_COST * 6); 8957 format %{ 8958 "cmp $src1, $src2" 8959 "csetw $dst, ne" 8960 "cnegw $dst, lt" 8961 %} 8962 // format %{ "CmpL3 $dst, $src1, $src2" %} 8963 ins_encode %{ 8964 __ cmp($src1$$Register, $src2$$Register); 8965 __ csetw($dst$$Register, Assembler::NE); 8966 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8967 %} 8968 8969 ins_pipe(pipe_class_default); 8970 %} 8971 8972 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8973 %{ 8974 match(Set dst (CmpL3 src1 src2)); 8975 effect(KILL flags); 8976 8977 ins_cost(INSN_COST * 6); 8978 format %{ 8979 "cmp $src1, $src2" 8980 "csetw $dst, ne" 8981 "cnegw $dst, lt" 8982 %} 8983 ins_encode %{ 8984 int32_t con = (int32_t)$src2$$constant; 8985 if (con < 0) { 8986 __ adds(zr, $src1$$Register, -con); 8987 } else { 8988 __ subs(zr, $src1$$Register, con); 8989 } 8990 __ csetw($dst$$Register, Assembler::NE); 8991 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8992 %} 8993 8994 ins_pipe(pipe_class_default); 8995 %} 8996 8997 // ============================================================================ 8998 // Conditional Move Instructions 8999 9000 // n.b. we have identical rules for both a signed compare op (cmpOp) 9001 // and an unsigned compare op (cmpOpU). it would be nice if we could 9002 // define an op class which merged both inputs and use it to type the 9003 // argument to a single rule. unfortunatelyt his fails because the 9004 // opclass does not live up to the COND_INTER interface of its 9005 // component operands. When the generic code tries to negate the 9006 // operand it ends up running the generci Machoper::negate method 9007 // which throws a ShouldNotHappen. So, we have to provide two flavours 9008 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9009 9010 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9011 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9012 9013 ins_cost(INSN_COST * 2); 9014 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9015 9016 ins_encode %{ 9017 __ cselw(as_Register($dst$$reg), 9018 as_Register($src2$$reg), 9019 as_Register($src1$$reg), 9020 (Assembler::Condition)$cmp$$cmpcode); 9021 %} 9022 9023 ins_pipe(icond_reg_reg); 9024 %} 9025 9026 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9027 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9028 9029 ins_cost(INSN_COST * 2); 9030 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9031 9032 ins_encode %{ 9033 __ cselw(as_Register($dst$$reg), 9034 as_Register($src2$$reg), 9035 as_Register($src1$$reg), 9036 (Assembler::Condition)$cmp$$cmpcode); 9037 %} 9038 9039 ins_pipe(icond_reg_reg); 9040 %} 9041 9042 // special cases where one arg is zero 9043 9044 // n.b. this is selected in preference to the rule above because it 9045 // avoids loading constant 0 into a source register 9046 9047 // TODO 9048 // we ought only to be able to cull one of these variants as the ideal 9049 // transforms ought always to order the zero consistently (to left/right?) 9050 9051 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9052 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9053 9054 ins_cost(INSN_COST * 2); 9055 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9056 9057 ins_encode %{ 9058 __ cselw(as_Register($dst$$reg), 9059 as_Register($src$$reg), 9060 zr, 9061 (Assembler::Condition)$cmp$$cmpcode); 9062 %} 9063 9064 ins_pipe(icond_reg); 9065 %} 9066 9067 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9068 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9069 9070 ins_cost(INSN_COST * 2); 9071 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9072 9073 ins_encode %{ 9074 __ cselw(as_Register($dst$$reg), 9075 as_Register($src$$reg), 9076 zr, 9077 (Assembler::Condition)$cmp$$cmpcode); 9078 %} 9079 9080 ins_pipe(icond_reg); 9081 %} 9082 9083 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9084 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9085 9086 ins_cost(INSN_COST * 2); 9087 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9088 9089 ins_encode %{ 9090 __ cselw(as_Register($dst$$reg), 9091 zr, 9092 as_Register($src$$reg), 9093 (Assembler::Condition)$cmp$$cmpcode); 9094 %} 9095 9096 ins_pipe(icond_reg); 9097 %} 9098 9099 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9100 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9101 9102 ins_cost(INSN_COST * 2); 9103 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9104 9105 ins_encode %{ 9106 __ cselw(as_Register($dst$$reg), 9107 zr, 9108 as_Register($src$$reg), 9109 (Assembler::Condition)$cmp$$cmpcode); 9110 %} 9111 9112 ins_pipe(icond_reg); 9113 %} 9114 9115 // special case for creating a boolean 0 or 1 9116 9117 // n.b. this is selected in preference to the rule above because it 9118 // avoids loading constants 0 and 1 into a source register 9119 9120 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9121 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9122 9123 ins_cost(INSN_COST * 2); 9124 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9125 9126 ins_encode %{ 9127 // equivalently 9128 // cset(as_Register($dst$$reg), 9129 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9130 __ csincw(as_Register($dst$$reg), 9131 zr, 9132 zr, 9133 (Assembler::Condition)$cmp$$cmpcode); 9134 %} 9135 9136 ins_pipe(icond_none); 9137 %} 9138 9139 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9140 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9141 9142 ins_cost(INSN_COST * 2); 9143 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9144 9145 ins_encode %{ 9146 // equivalently 9147 // cset(as_Register($dst$$reg), 9148 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9149 __ csincw(as_Register($dst$$reg), 9150 zr, 9151 zr, 9152 (Assembler::Condition)$cmp$$cmpcode); 9153 %} 9154 9155 ins_pipe(icond_none); 9156 %} 9157 9158 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9159 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9160 9161 ins_cost(INSN_COST * 2); 9162 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9163 9164 ins_encode %{ 9165 __ csel(as_Register($dst$$reg), 9166 as_Register($src2$$reg), 9167 as_Register($src1$$reg), 9168 (Assembler::Condition)$cmp$$cmpcode); 9169 %} 9170 9171 ins_pipe(icond_reg_reg); 9172 %} 9173 9174 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9175 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9176 9177 ins_cost(INSN_COST * 2); 9178 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9179 9180 ins_encode %{ 9181 __ csel(as_Register($dst$$reg), 9182 as_Register($src2$$reg), 9183 as_Register($src1$$reg), 9184 (Assembler::Condition)$cmp$$cmpcode); 9185 %} 9186 9187 ins_pipe(icond_reg_reg); 9188 %} 9189 9190 // special cases where one arg is zero 9191 9192 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9193 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9194 9195 ins_cost(INSN_COST * 2); 9196 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9197 9198 ins_encode %{ 9199 __ csel(as_Register($dst$$reg), 9200 zr, 9201 as_Register($src$$reg), 9202 (Assembler::Condition)$cmp$$cmpcode); 9203 %} 9204 9205 ins_pipe(icond_reg); 9206 %} 9207 9208 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9209 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9210 9211 ins_cost(INSN_COST * 2); 9212 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9213 9214 ins_encode %{ 9215 __ csel(as_Register($dst$$reg), 9216 zr, 9217 as_Register($src$$reg), 9218 (Assembler::Condition)$cmp$$cmpcode); 9219 %} 9220 9221 ins_pipe(icond_reg); 9222 %} 9223 9224 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9225 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9226 9227 ins_cost(INSN_COST * 2); 9228 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9229 9230 ins_encode %{ 9231 __ csel(as_Register($dst$$reg), 9232 as_Register($src$$reg), 9233 zr, 9234 (Assembler::Condition)$cmp$$cmpcode); 9235 %} 9236 9237 ins_pipe(icond_reg); 9238 %} 9239 9240 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9241 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9242 9243 ins_cost(INSN_COST * 2); 9244 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9245 9246 ins_encode %{ 9247 __ csel(as_Register($dst$$reg), 9248 as_Register($src$$reg), 9249 zr, 9250 (Assembler::Condition)$cmp$$cmpcode); 9251 %} 9252 9253 ins_pipe(icond_reg); 9254 %} 9255 9256 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9257 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9258 9259 ins_cost(INSN_COST * 2); 9260 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9261 9262 ins_encode %{ 9263 __ csel(as_Register($dst$$reg), 9264 as_Register($src2$$reg), 9265 as_Register($src1$$reg), 9266 (Assembler::Condition)$cmp$$cmpcode); 9267 %} 9268 9269 ins_pipe(icond_reg_reg); 9270 %} 9271 9272 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9273 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9274 9275 ins_cost(INSN_COST * 2); 9276 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9277 9278 ins_encode %{ 9279 __ csel(as_Register($dst$$reg), 9280 as_Register($src2$$reg), 9281 as_Register($src1$$reg), 9282 (Assembler::Condition)$cmp$$cmpcode); 9283 %} 9284 9285 ins_pipe(icond_reg_reg); 9286 %} 9287 9288 // special cases where one arg is zero 9289 9290 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9291 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9292 9293 ins_cost(INSN_COST * 2); 9294 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9295 9296 ins_encode %{ 9297 __ csel(as_Register($dst$$reg), 9298 zr, 9299 as_Register($src$$reg), 9300 (Assembler::Condition)$cmp$$cmpcode); 9301 %} 9302 9303 ins_pipe(icond_reg); 9304 %} 9305 9306 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9307 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9308 9309 ins_cost(INSN_COST * 2); 9310 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9311 9312 ins_encode %{ 9313 __ csel(as_Register($dst$$reg), 9314 zr, 9315 as_Register($src$$reg), 9316 (Assembler::Condition)$cmp$$cmpcode); 9317 %} 9318 9319 ins_pipe(icond_reg); 9320 %} 9321 9322 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9323 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9324 9325 ins_cost(INSN_COST * 2); 9326 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9327 9328 ins_encode %{ 9329 __ csel(as_Register($dst$$reg), 9330 as_Register($src$$reg), 9331 zr, 9332 (Assembler::Condition)$cmp$$cmpcode); 9333 %} 9334 9335 ins_pipe(icond_reg); 9336 %} 9337 9338 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9339 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9340 9341 ins_cost(INSN_COST * 2); 9342 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9343 9344 ins_encode %{ 9345 __ csel(as_Register($dst$$reg), 9346 as_Register($src$$reg), 9347 zr, 9348 (Assembler::Condition)$cmp$$cmpcode); 9349 %} 9350 9351 ins_pipe(icond_reg); 9352 %} 9353 9354 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9355 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9356 9357 ins_cost(INSN_COST * 2); 9358 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9359 9360 ins_encode %{ 9361 __ cselw(as_Register($dst$$reg), 9362 as_Register($src2$$reg), 9363 as_Register($src1$$reg), 9364 (Assembler::Condition)$cmp$$cmpcode); 9365 %} 9366 9367 ins_pipe(icond_reg_reg); 9368 %} 9369 9370 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9371 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9372 9373 ins_cost(INSN_COST * 2); 9374 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9375 9376 ins_encode %{ 9377 __ cselw(as_Register($dst$$reg), 9378 as_Register($src2$$reg), 9379 as_Register($src1$$reg), 9380 (Assembler::Condition)$cmp$$cmpcode); 9381 %} 9382 9383 ins_pipe(icond_reg_reg); 9384 %} 9385 9386 // special cases where one arg is zero 9387 9388 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9389 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9390 9391 ins_cost(INSN_COST * 2); 9392 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9393 9394 ins_encode %{ 9395 __ cselw(as_Register($dst$$reg), 9396 zr, 9397 as_Register($src$$reg), 9398 (Assembler::Condition)$cmp$$cmpcode); 9399 %} 9400 9401 ins_pipe(icond_reg); 9402 %} 9403 9404 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9405 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9406 9407 ins_cost(INSN_COST * 2); 9408 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9409 9410 ins_encode %{ 9411 __ cselw(as_Register($dst$$reg), 9412 zr, 9413 as_Register($src$$reg), 9414 (Assembler::Condition)$cmp$$cmpcode); 9415 %} 9416 9417 ins_pipe(icond_reg); 9418 %} 9419 9420 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9421 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9422 9423 ins_cost(INSN_COST * 2); 9424 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9425 9426 ins_encode %{ 9427 __ cselw(as_Register($dst$$reg), 9428 as_Register($src$$reg), 9429 zr, 9430 (Assembler::Condition)$cmp$$cmpcode); 9431 %} 9432 9433 ins_pipe(icond_reg); 9434 %} 9435 9436 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9437 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9438 9439 ins_cost(INSN_COST * 2); 9440 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9441 9442 ins_encode %{ 9443 __ cselw(as_Register($dst$$reg), 9444 as_Register($src$$reg), 9445 zr, 9446 (Assembler::Condition)$cmp$$cmpcode); 9447 %} 9448 9449 ins_pipe(icond_reg); 9450 %} 9451 9452 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9453 %{ 9454 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9455 9456 ins_cost(INSN_COST * 3); 9457 9458 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9459 ins_encode %{ 9460 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9461 __ fcsels(as_FloatRegister($dst$$reg), 9462 as_FloatRegister($src2$$reg), 9463 as_FloatRegister($src1$$reg), 9464 cond); 9465 %} 9466 9467 ins_pipe(fp_cond_reg_reg_s); 9468 %} 9469 9470 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9471 %{ 9472 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9473 9474 ins_cost(INSN_COST * 3); 9475 9476 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9477 ins_encode %{ 9478 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9479 __ fcsels(as_FloatRegister($dst$$reg), 9480 as_FloatRegister($src2$$reg), 9481 as_FloatRegister($src1$$reg), 9482 cond); 9483 %} 9484 9485 ins_pipe(fp_cond_reg_reg_s); 9486 %} 9487 9488 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9489 %{ 9490 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9491 9492 ins_cost(INSN_COST * 3); 9493 9494 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9495 ins_encode %{ 9496 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9497 __ fcseld(as_FloatRegister($dst$$reg), 9498 as_FloatRegister($src2$$reg), 9499 as_FloatRegister($src1$$reg), 9500 cond); 9501 %} 9502 9503 ins_pipe(fp_cond_reg_reg_d); 9504 %} 9505 9506 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9507 %{ 9508 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9509 9510 ins_cost(INSN_COST * 3); 9511 9512 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9513 ins_encode %{ 9514 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9515 __ fcseld(as_FloatRegister($dst$$reg), 9516 as_FloatRegister($src2$$reg), 9517 as_FloatRegister($src1$$reg), 9518 cond); 9519 %} 9520 9521 ins_pipe(fp_cond_reg_reg_d); 9522 %} 9523 9524 // ============================================================================ 9525 // Arithmetic Instructions 9526 // 9527 9528 // Integer Addition 9529 9530 // TODO 9531 // these currently employ operations which do not set CR and hence are 9532 // not flagged as killing CR but we would like to isolate the cases 9533 // where we want to set flags from those where we don't. need to work 9534 // out how to do that. 9535 9536 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9537 match(Set dst (AddI src1 src2)); 9538 9539 ins_cost(INSN_COST); 9540 format %{ "addw $dst, $src1, $src2" %} 9541 9542 ins_encode %{ 9543 __ addw(as_Register($dst$$reg), 9544 as_Register($src1$$reg), 9545 as_Register($src2$$reg)); 9546 %} 9547 9548 ins_pipe(ialu_reg_reg); 9549 %} 9550 9551 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9552 match(Set dst (AddI src1 src2)); 9553 9554 ins_cost(INSN_COST); 9555 format %{ "addw $dst, $src1, $src2" %} 9556 9557 // use opcode to indicate that this is an add not a sub 9558 opcode(0x0); 9559 9560 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9561 9562 ins_pipe(ialu_reg_imm); 9563 %} 9564 9565 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9566 match(Set dst (AddI (ConvL2I src1) src2)); 9567 9568 ins_cost(INSN_COST); 9569 format %{ "addw $dst, $src1, $src2" %} 9570 9571 // use opcode to indicate that this is an add not a sub 9572 opcode(0x0); 9573 9574 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9575 9576 ins_pipe(ialu_reg_imm); 9577 %} 9578 9579 // Pointer Addition 9580 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9581 match(Set dst (AddP src1 src2)); 9582 9583 ins_cost(INSN_COST); 9584 format %{ "add $dst, $src1, $src2\t# ptr" %} 9585 9586 ins_encode %{ 9587 __ add(as_Register($dst$$reg), 9588 as_Register($src1$$reg), 9589 as_Register($src2$$reg)); 9590 %} 9591 9592 ins_pipe(ialu_reg_reg); 9593 %} 9594 9595 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9596 match(Set dst (AddP src1 (ConvI2L src2))); 9597 9598 ins_cost(1.9 * INSN_COST); 9599 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9600 9601 ins_encode %{ 9602 __ add(as_Register($dst$$reg), 9603 as_Register($src1$$reg), 9604 as_Register($src2$$reg), ext::sxtw); 9605 %} 9606 9607 ins_pipe(ialu_reg_reg); 9608 %} 9609 9610 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9611 match(Set dst (AddP src1 (LShiftL src2 scale))); 9612 9613 ins_cost(1.9 * INSN_COST); 9614 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9615 9616 ins_encode %{ 9617 __ lea(as_Register($dst$$reg), 9618 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9619 Address::lsl($scale$$constant))); 9620 %} 9621 9622 ins_pipe(ialu_reg_reg_shift); 9623 %} 9624 9625 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9626 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9627 9628 ins_cost(1.9 * INSN_COST); 9629 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9630 9631 ins_encode %{ 9632 __ lea(as_Register($dst$$reg), 9633 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9634 Address::sxtw($scale$$constant))); 9635 %} 9636 9637 ins_pipe(ialu_reg_reg_shift); 9638 %} 9639 9640 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9641 match(Set dst (LShiftL (ConvI2L src) scale)); 9642 9643 ins_cost(INSN_COST); 9644 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9645 9646 ins_encode %{ 9647 __ sbfiz(as_Register($dst$$reg), 9648 as_Register($src$$reg), 9649 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 9650 %} 9651 9652 ins_pipe(ialu_reg_shift); 9653 %} 9654 9655 // Pointer Immediate Addition 9656 // n.b. this needs to be more expensive than using an indirect memory 9657 // operand 9658 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9659 match(Set dst (AddP src1 src2)); 9660 9661 ins_cost(INSN_COST); 9662 format %{ "add $dst, $src1, $src2\t# ptr" %} 9663 9664 // use opcode to indicate that this is an add not a sub 9665 opcode(0x0); 9666 9667 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9668 9669 ins_pipe(ialu_reg_imm); 9670 %} 9671 9672 // Long Addition 9673 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9674 9675 match(Set dst (AddL src1 src2)); 9676 9677 ins_cost(INSN_COST); 9678 format %{ "add $dst, $src1, $src2" %} 9679 9680 ins_encode %{ 9681 __ add(as_Register($dst$$reg), 9682 as_Register($src1$$reg), 9683 as_Register($src2$$reg)); 9684 %} 9685 9686 ins_pipe(ialu_reg_reg); 9687 %} 9688 9689 // No constant pool entries requiredLong Immediate Addition. 9690 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9691 match(Set dst (AddL src1 src2)); 9692 9693 ins_cost(INSN_COST); 9694 format %{ "add $dst, $src1, $src2" %} 9695 9696 // use opcode to indicate that this is an add not a sub 9697 opcode(0x0); 9698 9699 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9700 9701 ins_pipe(ialu_reg_imm); 9702 %} 9703 9704 // Integer Subtraction 9705 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9706 match(Set dst (SubI src1 src2)); 9707 9708 ins_cost(INSN_COST); 9709 format %{ "subw $dst, $src1, $src2" %} 9710 9711 ins_encode %{ 9712 __ subw(as_Register($dst$$reg), 9713 as_Register($src1$$reg), 9714 as_Register($src2$$reg)); 9715 %} 9716 9717 ins_pipe(ialu_reg_reg); 9718 %} 9719 9720 // Immediate Subtraction 9721 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9722 match(Set dst (SubI src1 src2)); 9723 9724 ins_cost(INSN_COST); 9725 format %{ "subw $dst, $src1, $src2" %} 9726 9727 // use opcode to indicate that this is a sub not an add 9728 opcode(0x1); 9729 9730 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9731 9732 ins_pipe(ialu_reg_imm); 9733 %} 9734 9735 // Long Subtraction 9736 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9737 9738 match(Set dst (SubL src1 src2)); 9739 9740 ins_cost(INSN_COST); 9741 format %{ "sub $dst, $src1, $src2" %} 9742 9743 ins_encode %{ 9744 __ sub(as_Register($dst$$reg), 9745 as_Register($src1$$reg), 9746 as_Register($src2$$reg)); 9747 %} 9748 9749 ins_pipe(ialu_reg_reg); 9750 %} 9751 9752 // No constant pool entries requiredLong Immediate Subtraction. 9753 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9754 match(Set dst (SubL src1 src2)); 9755 9756 ins_cost(INSN_COST); 9757 format %{ "sub$dst, $src1, $src2" %} 9758 9759 // use opcode to indicate that this is a sub not an add 9760 opcode(0x1); 9761 9762 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9763 9764 ins_pipe(ialu_reg_imm); 9765 %} 9766 9767 // Integer Negation (special case for sub) 9768 9769 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9770 match(Set dst (SubI zero src)); 9771 9772 ins_cost(INSN_COST); 9773 format %{ "negw $dst, $src\t# int" %} 9774 9775 ins_encode %{ 9776 __ negw(as_Register($dst$$reg), 9777 as_Register($src$$reg)); 9778 %} 9779 9780 ins_pipe(ialu_reg); 9781 %} 9782 9783 // Long Negation 9784 9785 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9786 match(Set dst (SubL zero src)); 9787 9788 ins_cost(INSN_COST); 9789 format %{ "neg $dst, $src\t# long" %} 9790 9791 ins_encode %{ 9792 __ neg(as_Register($dst$$reg), 9793 as_Register($src$$reg)); 9794 %} 9795 9796 ins_pipe(ialu_reg); 9797 %} 9798 9799 // Integer Multiply 9800 9801 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9802 match(Set dst (MulI src1 src2)); 9803 9804 ins_cost(INSN_COST * 3); 9805 format %{ "mulw $dst, $src1, $src2" %} 9806 9807 ins_encode %{ 9808 __ mulw(as_Register($dst$$reg), 9809 as_Register($src1$$reg), 9810 as_Register($src2$$reg)); 9811 %} 9812 9813 ins_pipe(imul_reg_reg); 9814 %} 9815 9816 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9817 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9818 9819 ins_cost(INSN_COST * 3); 9820 format %{ "smull $dst, $src1, $src2" %} 9821 9822 ins_encode %{ 9823 __ smull(as_Register($dst$$reg), 9824 as_Register($src1$$reg), 9825 as_Register($src2$$reg)); 9826 %} 9827 9828 ins_pipe(imul_reg_reg); 9829 %} 9830 9831 // Long Multiply 9832 9833 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9834 match(Set dst (MulL src1 src2)); 9835 9836 ins_cost(INSN_COST * 5); 9837 format %{ "mul $dst, $src1, $src2" %} 9838 9839 ins_encode %{ 9840 __ mul(as_Register($dst$$reg), 9841 as_Register($src1$$reg), 9842 as_Register($src2$$reg)); 9843 %} 9844 9845 ins_pipe(lmul_reg_reg); 9846 %} 9847 9848 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9849 %{ 9850 match(Set dst (MulHiL src1 src2)); 9851 9852 ins_cost(INSN_COST * 7); 9853 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9854 9855 ins_encode %{ 9856 __ smulh(as_Register($dst$$reg), 9857 as_Register($src1$$reg), 9858 as_Register($src2$$reg)); 9859 %} 9860 9861 ins_pipe(lmul_reg_reg); 9862 %} 9863 9864 // Combined Integer Multiply & Add/Sub 9865 9866 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9867 match(Set dst (AddI src3 (MulI src1 src2))); 9868 9869 ins_cost(INSN_COST * 3); 9870 format %{ "madd $dst, $src1, $src2, $src3" %} 9871 9872 ins_encode %{ 9873 __ maddw(as_Register($dst$$reg), 9874 as_Register($src1$$reg), 9875 as_Register($src2$$reg), 9876 as_Register($src3$$reg)); 9877 %} 9878 9879 ins_pipe(imac_reg_reg); 9880 %} 9881 9882 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9883 match(Set dst (SubI src3 (MulI src1 src2))); 9884 9885 ins_cost(INSN_COST * 3); 9886 format %{ "msub $dst, $src1, $src2, $src3" %} 9887 9888 ins_encode %{ 9889 __ msubw(as_Register($dst$$reg), 9890 as_Register($src1$$reg), 9891 as_Register($src2$$reg), 9892 as_Register($src3$$reg)); 9893 %} 9894 9895 ins_pipe(imac_reg_reg); 9896 %} 9897 9898 // Combined Long Multiply & Add/Sub 9899 9900 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9901 match(Set dst (AddL src3 (MulL src1 src2))); 9902 9903 ins_cost(INSN_COST * 5); 9904 format %{ "madd $dst, $src1, $src2, $src3" %} 9905 9906 ins_encode %{ 9907 __ madd(as_Register($dst$$reg), 9908 as_Register($src1$$reg), 9909 as_Register($src2$$reg), 9910 as_Register($src3$$reg)); 9911 %} 9912 9913 ins_pipe(lmac_reg_reg); 9914 %} 9915 9916 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9917 match(Set dst (SubL src3 (MulL src1 src2))); 9918 9919 ins_cost(INSN_COST * 5); 9920 format %{ "msub $dst, $src1, $src2, $src3" %} 9921 9922 ins_encode %{ 9923 __ msub(as_Register($dst$$reg), 9924 as_Register($src1$$reg), 9925 as_Register($src2$$reg), 9926 as_Register($src3$$reg)); 9927 %} 9928 9929 ins_pipe(lmac_reg_reg); 9930 %} 9931 9932 // Integer Divide 9933 9934 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9935 match(Set dst (DivI src1 src2)); 9936 9937 ins_cost(INSN_COST * 19); 9938 format %{ "sdivw $dst, $src1, $src2" %} 9939 9940 ins_encode(aarch64_enc_divw(dst, src1, src2)); 9941 ins_pipe(idiv_reg_reg); 9942 %} 9943 9944 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 9945 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 9946 ins_cost(INSN_COST); 9947 format %{ "lsrw $dst, $src1, $div1" %} 9948 ins_encode %{ 9949 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 9950 %} 9951 ins_pipe(ialu_reg_shift); 9952 %} 9953 9954 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 9955 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 9956 ins_cost(INSN_COST); 9957 format %{ "addw $dst, $src, LSR $div1" %} 9958 9959 ins_encode %{ 9960 __ addw(as_Register($dst$$reg), 9961 as_Register($src$$reg), 9962 as_Register($src$$reg), 9963 Assembler::LSR, 31); 9964 %} 9965 ins_pipe(ialu_reg); 9966 %} 9967 9968 // Long Divide 9969 9970 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9971 match(Set dst (DivL src1 src2)); 9972 9973 ins_cost(INSN_COST * 35); 9974 format %{ "sdiv $dst, $src1, $src2" %} 9975 9976 ins_encode(aarch64_enc_div(dst, src1, src2)); 9977 ins_pipe(ldiv_reg_reg); 9978 %} 9979 9980 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 9981 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 9982 ins_cost(INSN_COST); 9983 format %{ "lsr $dst, $src1, $div1" %} 9984 ins_encode %{ 9985 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 9986 %} 9987 ins_pipe(ialu_reg_shift); 9988 %} 9989 9990 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 9991 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 9992 ins_cost(INSN_COST); 9993 format %{ "add $dst, $src, $div1" %} 9994 9995 ins_encode %{ 9996 __ add(as_Register($dst$$reg), 9997 as_Register($src$$reg), 9998 as_Register($src$$reg), 9999 Assembler::LSR, 63); 10000 %} 10001 ins_pipe(ialu_reg); 10002 %} 10003 10004 // Integer Remainder 10005 10006 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10007 match(Set dst (ModI src1 src2)); 10008 10009 ins_cost(INSN_COST * 22); 10010 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10011 "msubw($dst, rscratch1, $src2, $src1" %} 10012 10013 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10014 ins_pipe(idiv_reg_reg); 10015 %} 10016 10017 // Long Remainder 10018 10019 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10020 match(Set dst (ModL src1 src2)); 10021 10022 ins_cost(INSN_COST * 38); 10023 format %{ "sdiv rscratch1, $src1, $src2\n" 10024 "msub($dst, rscratch1, $src2, $src1" %} 10025 10026 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10027 ins_pipe(ldiv_reg_reg); 10028 %} 10029 10030 // Integer Shifts 10031 10032 // Shift Left Register 10033 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10034 match(Set dst (LShiftI src1 src2)); 10035 10036 ins_cost(INSN_COST * 2); 10037 format %{ "lslvw $dst, $src1, $src2" %} 10038 10039 ins_encode %{ 10040 __ lslvw(as_Register($dst$$reg), 10041 as_Register($src1$$reg), 10042 as_Register($src2$$reg)); 10043 %} 10044 10045 ins_pipe(ialu_reg_reg_vshift); 10046 %} 10047 10048 // Shift Left Immediate 10049 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10050 match(Set dst (LShiftI src1 src2)); 10051 10052 ins_cost(INSN_COST); 10053 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10054 10055 ins_encode %{ 10056 __ lslw(as_Register($dst$$reg), 10057 as_Register($src1$$reg), 10058 $src2$$constant & 0x1f); 10059 %} 10060 10061 ins_pipe(ialu_reg_shift); 10062 %} 10063 10064 // Shift Right Logical Register 10065 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10066 match(Set dst (URShiftI src1 src2)); 10067 10068 ins_cost(INSN_COST * 2); 10069 format %{ "lsrvw $dst, $src1, $src2" %} 10070 10071 ins_encode %{ 10072 __ lsrvw(as_Register($dst$$reg), 10073 as_Register($src1$$reg), 10074 as_Register($src2$$reg)); 10075 %} 10076 10077 ins_pipe(ialu_reg_reg_vshift); 10078 %} 10079 10080 // Shift Right Logical Immediate 10081 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10082 match(Set dst (URShiftI src1 src2)); 10083 10084 ins_cost(INSN_COST); 10085 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10086 10087 ins_encode %{ 10088 __ lsrw(as_Register($dst$$reg), 10089 as_Register($src1$$reg), 10090 $src2$$constant & 0x1f); 10091 %} 10092 10093 ins_pipe(ialu_reg_shift); 10094 %} 10095 10096 // Shift Right Arithmetic Register 10097 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10098 match(Set dst (RShiftI src1 src2)); 10099 10100 ins_cost(INSN_COST * 2); 10101 format %{ "asrvw $dst, $src1, $src2" %} 10102 10103 ins_encode %{ 10104 __ asrvw(as_Register($dst$$reg), 10105 as_Register($src1$$reg), 10106 as_Register($src2$$reg)); 10107 %} 10108 10109 ins_pipe(ialu_reg_reg_vshift); 10110 %} 10111 10112 // Shift Right Arithmetic Immediate 10113 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10114 match(Set dst (RShiftI src1 src2)); 10115 10116 ins_cost(INSN_COST); 10117 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10118 10119 ins_encode %{ 10120 __ asrw(as_Register($dst$$reg), 10121 as_Register($src1$$reg), 10122 $src2$$constant & 0x1f); 10123 %} 10124 10125 ins_pipe(ialu_reg_shift); 10126 %} 10127 10128 // Combined Int Mask and Right Shift (using UBFM) 10129 // TODO 10130 10131 // Long Shifts 10132 10133 // Shift Left Register 10134 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10135 match(Set dst (LShiftL src1 src2)); 10136 10137 ins_cost(INSN_COST * 2); 10138 format %{ "lslv $dst, $src1, $src2" %} 10139 10140 ins_encode %{ 10141 __ lslv(as_Register($dst$$reg), 10142 as_Register($src1$$reg), 10143 as_Register($src2$$reg)); 10144 %} 10145 10146 ins_pipe(ialu_reg_reg_vshift); 10147 %} 10148 10149 // Shift Left Immediate 10150 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10151 match(Set dst (LShiftL src1 src2)); 10152 10153 ins_cost(INSN_COST); 10154 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10155 10156 ins_encode %{ 10157 __ lsl(as_Register($dst$$reg), 10158 as_Register($src1$$reg), 10159 $src2$$constant & 0x3f); 10160 %} 10161 10162 ins_pipe(ialu_reg_shift); 10163 %} 10164 10165 // Shift Right Logical Register 10166 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10167 match(Set dst (URShiftL src1 src2)); 10168 10169 ins_cost(INSN_COST * 2); 10170 format %{ "lsrv $dst, $src1, $src2" %} 10171 10172 ins_encode %{ 10173 __ lsrv(as_Register($dst$$reg), 10174 as_Register($src1$$reg), 10175 as_Register($src2$$reg)); 10176 %} 10177 10178 ins_pipe(ialu_reg_reg_vshift); 10179 %} 10180 10181 // Shift Right Logical Immediate 10182 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10183 match(Set dst (URShiftL src1 src2)); 10184 10185 ins_cost(INSN_COST); 10186 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10187 10188 ins_encode %{ 10189 __ lsr(as_Register($dst$$reg), 10190 as_Register($src1$$reg), 10191 $src2$$constant & 0x3f); 10192 %} 10193 10194 ins_pipe(ialu_reg_shift); 10195 %} 10196 10197 // A special-case pattern for card table stores. 10198 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10199 match(Set dst (URShiftL (CastP2X src1) src2)); 10200 10201 ins_cost(INSN_COST); 10202 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10203 10204 ins_encode %{ 10205 __ lsr(as_Register($dst$$reg), 10206 as_Register($src1$$reg), 10207 $src2$$constant & 0x3f); 10208 %} 10209 10210 ins_pipe(ialu_reg_shift); 10211 %} 10212 10213 // Shift Right Arithmetic Register 10214 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10215 match(Set dst (RShiftL src1 src2)); 10216 10217 ins_cost(INSN_COST * 2); 10218 format %{ "asrv $dst, $src1, $src2" %} 10219 10220 ins_encode %{ 10221 __ asrv(as_Register($dst$$reg), 10222 as_Register($src1$$reg), 10223 as_Register($src2$$reg)); 10224 %} 10225 10226 ins_pipe(ialu_reg_reg_vshift); 10227 %} 10228 10229 // Shift Right Arithmetic Immediate 10230 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10231 match(Set dst (RShiftL src1 src2)); 10232 10233 ins_cost(INSN_COST); 10234 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10235 10236 ins_encode %{ 10237 __ asr(as_Register($dst$$reg), 10238 as_Register($src1$$reg), 10239 $src2$$constant & 0x3f); 10240 %} 10241 10242 ins_pipe(ialu_reg_shift); 10243 %} 10244 10245 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10246 10247 instruct regL_not_reg(iRegLNoSp dst, 10248 iRegL src1, immL_M1 m1, 10249 rFlagsReg cr) %{ 10250 match(Set dst (XorL src1 m1)); 10251 ins_cost(INSN_COST); 10252 format %{ "eon $dst, $src1, zr" %} 10253 10254 ins_encode %{ 10255 __ eon(as_Register($dst$$reg), 10256 as_Register($src1$$reg), 10257 zr, 10258 Assembler::LSL, 0); 10259 %} 10260 10261 ins_pipe(ialu_reg); 10262 %} 10263 instruct regI_not_reg(iRegINoSp dst, 10264 iRegIorL2I src1, immI_M1 m1, 10265 rFlagsReg cr) %{ 10266 match(Set dst (XorI src1 m1)); 10267 ins_cost(INSN_COST); 10268 format %{ "eonw $dst, $src1, zr" %} 10269 10270 ins_encode %{ 10271 __ eonw(as_Register($dst$$reg), 10272 as_Register($src1$$reg), 10273 zr, 10274 Assembler::LSL, 0); 10275 %} 10276 10277 ins_pipe(ialu_reg); 10278 %} 10279 10280 instruct AndI_reg_not_reg(iRegINoSp dst, 10281 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10282 rFlagsReg cr) %{ 10283 match(Set dst (AndI src1 (XorI src2 m1))); 10284 ins_cost(INSN_COST); 10285 format %{ "bicw $dst, $src1, $src2" %} 10286 10287 ins_encode %{ 10288 __ bicw(as_Register($dst$$reg), 10289 as_Register($src1$$reg), 10290 as_Register($src2$$reg), 10291 Assembler::LSL, 0); 10292 %} 10293 10294 ins_pipe(ialu_reg_reg); 10295 %} 10296 10297 instruct AndL_reg_not_reg(iRegLNoSp dst, 10298 iRegL src1, iRegL src2, immL_M1 m1, 10299 rFlagsReg cr) %{ 10300 match(Set dst (AndL src1 (XorL src2 m1))); 10301 ins_cost(INSN_COST); 10302 format %{ "bic $dst, $src1, $src2" %} 10303 10304 ins_encode %{ 10305 __ bic(as_Register($dst$$reg), 10306 as_Register($src1$$reg), 10307 as_Register($src2$$reg), 10308 Assembler::LSL, 0); 10309 %} 10310 10311 ins_pipe(ialu_reg_reg); 10312 %} 10313 10314 instruct OrI_reg_not_reg(iRegINoSp dst, 10315 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10316 rFlagsReg cr) %{ 10317 match(Set dst (OrI src1 (XorI src2 m1))); 10318 ins_cost(INSN_COST); 10319 format %{ "ornw $dst, $src1, $src2" %} 10320 10321 ins_encode %{ 10322 __ ornw(as_Register($dst$$reg), 10323 as_Register($src1$$reg), 10324 as_Register($src2$$reg), 10325 Assembler::LSL, 0); 10326 %} 10327 10328 ins_pipe(ialu_reg_reg); 10329 %} 10330 10331 instruct OrL_reg_not_reg(iRegLNoSp dst, 10332 iRegL src1, iRegL src2, immL_M1 m1, 10333 rFlagsReg cr) %{ 10334 match(Set dst (OrL src1 (XorL src2 m1))); 10335 ins_cost(INSN_COST); 10336 format %{ "orn $dst, $src1, $src2" %} 10337 10338 ins_encode %{ 10339 __ orn(as_Register($dst$$reg), 10340 as_Register($src1$$reg), 10341 as_Register($src2$$reg), 10342 Assembler::LSL, 0); 10343 %} 10344 10345 ins_pipe(ialu_reg_reg); 10346 %} 10347 10348 instruct XorI_reg_not_reg(iRegINoSp dst, 10349 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10350 rFlagsReg cr) %{ 10351 match(Set dst (XorI m1 (XorI src2 src1))); 10352 ins_cost(INSN_COST); 10353 format %{ "eonw $dst, $src1, $src2" %} 10354 10355 ins_encode %{ 10356 __ eonw(as_Register($dst$$reg), 10357 as_Register($src1$$reg), 10358 as_Register($src2$$reg), 10359 Assembler::LSL, 0); 10360 %} 10361 10362 ins_pipe(ialu_reg_reg); 10363 %} 10364 10365 instruct XorL_reg_not_reg(iRegLNoSp dst, 10366 iRegL src1, iRegL src2, immL_M1 m1, 10367 rFlagsReg cr) %{ 10368 match(Set dst (XorL m1 (XorL src2 src1))); 10369 ins_cost(INSN_COST); 10370 format %{ "eon $dst, $src1, $src2" %} 10371 10372 ins_encode %{ 10373 __ eon(as_Register($dst$$reg), 10374 as_Register($src1$$reg), 10375 as_Register($src2$$reg), 10376 Assembler::LSL, 0); 10377 %} 10378 10379 ins_pipe(ialu_reg_reg); 10380 %} 10381 10382 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10383 iRegIorL2I src1, iRegIorL2I src2, 10384 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10385 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10386 ins_cost(1.9 * INSN_COST); 10387 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10388 10389 ins_encode %{ 10390 __ bicw(as_Register($dst$$reg), 10391 as_Register($src1$$reg), 10392 as_Register($src2$$reg), 10393 Assembler::LSR, 10394 $src3$$constant & 0x1f); 10395 %} 10396 10397 ins_pipe(ialu_reg_reg_shift); 10398 %} 10399 10400 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10401 iRegL src1, iRegL src2, 10402 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10403 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10404 ins_cost(1.9 * INSN_COST); 10405 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10406 10407 ins_encode %{ 10408 __ bic(as_Register($dst$$reg), 10409 as_Register($src1$$reg), 10410 as_Register($src2$$reg), 10411 Assembler::LSR, 10412 $src3$$constant & 0x3f); 10413 %} 10414 10415 ins_pipe(ialu_reg_reg_shift); 10416 %} 10417 10418 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10419 iRegIorL2I src1, iRegIorL2I src2, 10420 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10421 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10422 ins_cost(1.9 * INSN_COST); 10423 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10424 10425 ins_encode %{ 10426 __ bicw(as_Register($dst$$reg), 10427 as_Register($src1$$reg), 10428 as_Register($src2$$reg), 10429 Assembler::ASR, 10430 $src3$$constant & 0x1f); 10431 %} 10432 10433 ins_pipe(ialu_reg_reg_shift); 10434 %} 10435 10436 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10437 iRegL src1, iRegL src2, 10438 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10439 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10440 ins_cost(1.9 * INSN_COST); 10441 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10442 10443 ins_encode %{ 10444 __ bic(as_Register($dst$$reg), 10445 as_Register($src1$$reg), 10446 as_Register($src2$$reg), 10447 Assembler::ASR, 10448 $src3$$constant & 0x3f); 10449 %} 10450 10451 ins_pipe(ialu_reg_reg_shift); 10452 %} 10453 10454 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10455 iRegIorL2I src1, iRegIorL2I src2, 10456 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10457 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10458 ins_cost(1.9 * INSN_COST); 10459 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10460 10461 ins_encode %{ 10462 __ bicw(as_Register($dst$$reg), 10463 as_Register($src1$$reg), 10464 as_Register($src2$$reg), 10465 Assembler::LSL, 10466 $src3$$constant & 0x1f); 10467 %} 10468 10469 ins_pipe(ialu_reg_reg_shift); 10470 %} 10471 10472 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10473 iRegL src1, iRegL src2, 10474 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10475 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10476 ins_cost(1.9 * INSN_COST); 10477 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10478 10479 ins_encode %{ 10480 __ bic(as_Register($dst$$reg), 10481 as_Register($src1$$reg), 10482 as_Register($src2$$reg), 10483 Assembler::LSL, 10484 $src3$$constant & 0x3f); 10485 %} 10486 10487 ins_pipe(ialu_reg_reg_shift); 10488 %} 10489 10490 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10491 iRegIorL2I src1, iRegIorL2I src2, 10492 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10493 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10494 ins_cost(1.9 * INSN_COST); 10495 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10496 10497 ins_encode %{ 10498 __ eonw(as_Register($dst$$reg), 10499 as_Register($src1$$reg), 10500 as_Register($src2$$reg), 10501 Assembler::LSR, 10502 $src3$$constant & 0x1f); 10503 %} 10504 10505 ins_pipe(ialu_reg_reg_shift); 10506 %} 10507 10508 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10509 iRegL src1, iRegL src2, 10510 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10511 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10512 ins_cost(1.9 * INSN_COST); 10513 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10514 10515 ins_encode %{ 10516 __ eon(as_Register($dst$$reg), 10517 as_Register($src1$$reg), 10518 as_Register($src2$$reg), 10519 Assembler::LSR, 10520 $src3$$constant & 0x3f); 10521 %} 10522 10523 ins_pipe(ialu_reg_reg_shift); 10524 %} 10525 10526 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10527 iRegIorL2I src1, iRegIorL2I src2, 10528 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10529 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10530 ins_cost(1.9 * INSN_COST); 10531 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10532 10533 ins_encode %{ 10534 __ eonw(as_Register($dst$$reg), 10535 as_Register($src1$$reg), 10536 as_Register($src2$$reg), 10537 Assembler::ASR, 10538 $src3$$constant & 0x1f); 10539 %} 10540 10541 ins_pipe(ialu_reg_reg_shift); 10542 %} 10543 10544 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10545 iRegL src1, iRegL src2, 10546 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10547 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10548 ins_cost(1.9 * INSN_COST); 10549 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10550 10551 ins_encode %{ 10552 __ eon(as_Register($dst$$reg), 10553 as_Register($src1$$reg), 10554 as_Register($src2$$reg), 10555 Assembler::ASR, 10556 $src3$$constant & 0x3f); 10557 %} 10558 10559 ins_pipe(ialu_reg_reg_shift); 10560 %} 10561 10562 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10563 iRegIorL2I src1, iRegIorL2I src2, 10564 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10565 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10566 ins_cost(1.9 * INSN_COST); 10567 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10568 10569 ins_encode %{ 10570 __ eonw(as_Register($dst$$reg), 10571 as_Register($src1$$reg), 10572 as_Register($src2$$reg), 10573 Assembler::LSL, 10574 $src3$$constant & 0x1f); 10575 %} 10576 10577 ins_pipe(ialu_reg_reg_shift); 10578 %} 10579 10580 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10581 iRegL src1, iRegL src2, 10582 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10583 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10584 ins_cost(1.9 * INSN_COST); 10585 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10586 10587 ins_encode %{ 10588 __ eon(as_Register($dst$$reg), 10589 as_Register($src1$$reg), 10590 as_Register($src2$$reg), 10591 Assembler::LSL, 10592 $src3$$constant & 0x3f); 10593 %} 10594 10595 ins_pipe(ialu_reg_reg_shift); 10596 %} 10597 10598 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10599 iRegIorL2I src1, iRegIorL2I src2, 10600 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10601 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10602 ins_cost(1.9 * INSN_COST); 10603 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10604 10605 ins_encode %{ 10606 __ ornw(as_Register($dst$$reg), 10607 as_Register($src1$$reg), 10608 as_Register($src2$$reg), 10609 Assembler::LSR, 10610 $src3$$constant & 0x1f); 10611 %} 10612 10613 ins_pipe(ialu_reg_reg_shift); 10614 %} 10615 10616 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10617 iRegL src1, iRegL src2, 10618 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10619 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10620 ins_cost(1.9 * INSN_COST); 10621 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10622 10623 ins_encode %{ 10624 __ orn(as_Register($dst$$reg), 10625 as_Register($src1$$reg), 10626 as_Register($src2$$reg), 10627 Assembler::LSR, 10628 $src3$$constant & 0x3f); 10629 %} 10630 10631 ins_pipe(ialu_reg_reg_shift); 10632 %} 10633 10634 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10635 iRegIorL2I src1, iRegIorL2I src2, 10636 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10637 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10638 ins_cost(1.9 * INSN_COST); 10639 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10640 10641 ins_encode %{ 10642 __ ornw(as_Register($dst$$reg), 10643 as_Register($src1$$reg), 10644 as_Register($src2$$reg), 10645 Assembler::ASR, 10646 $src3$$constant & 0x1f); 10647 %} 10648 10649 ins_pipe(ialu_reg_reg_shift); 10650 %} 10651 10652 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10653 iRegL src1, iRegL src2, 10654 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10655 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10656 ins_cost(1.9 * INSN_COST); 10657 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10658 10659 ins_encode %{ 10660 __ orn(as_Register($dst$$reg), 10661 as_Register($src1$$reg), 10662 as_Register($src2$$reg), 10663 Assembler::ASR, 10664 $src3$$constant & 0x3f); 10665 %} 10666 10667 ins_pipe(ialu_reg_reg_shift); 10668 %} 10669 10670 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10671 iRegIorL2I src1, iRegIorL2I src2, 10672 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10673 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10674 ins_cost(1.9 * INSN_COST); 10675 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10676 10677 ins_encode %{ 10678 __ ornw(as_Register($dst$$reg), 10679 as_Register($src1$$reg), 10680 as_Register($src2$$reg), 10681 Assembler::LSL, 10682 $src3$$constant & 0x1f); 10683 %} 10684 10685 ins_pipe(ialu_reg_reg_shift); 10686 %} 10687 10688 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10689 iRegL src1, iRegL src2, 10690 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10691 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10692 ins_cost(1.9 * INSN_COST); 10693 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10694 10695 ins_encode %{ 10696 __ orn(as_Register($dst$$reg), 10697 as_Register($src1$$reg), 10698 as_Register($src2$$reg), 10699 Assembler::LSL, 10700 $src3$$constant & 0x3f); 10701 %} 10702 10703 ins_pipe(ialu_reg_reg_shift); 10704 %} 10705 10706 instruct AndI_reg_URShift_reg(iRegINoSp dst, 10707 iRegIorL2I src1, iRegIorL2I src2, 10708 immI src3, rFlagsReg cr) %{ 10709 match(Set dst (AndI src1 (URShiftI src2 src3))); 10710 10711 ins_cost(1.9 * INSN_COST); 10712 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10713 10714 ins_encode %{ 10715 __ andw(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 AndL_reg_URShift_reg(iRegLNoSp dst, 10726 iRegL src1, iRegL src2, 10727 immI src3, rFlagsReg cr) %{ 10728 match(Set dst (AndL src1 (URShiftL src2 src3))); 10729 10730 ins_cost(1.9 * INSN_COST); 10731 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10732 10733 ins_encode %{ 10734 __ andr(as_Register($dst$$reg), 10735 as_Register($src1$$reg), 10736 as_Register($src2$$reg), 10737 Assembler::LSR, 10738 $src3$$constant & 0x3f); 10739 %} 10740 10741 ins_pipe(ialu_reg_reg_shift); 10742 %} 10743 10744 instruct AndI_reg_RShift_reg(iRegINoSp dst, 10745 iRegIorL2I src1, iRegIorL2I src2, 10746 immI src3, rFlagsReg cr) %{ 10747 match(Set dst (AndI src1 (RShiftI src2 src3))); 10748 10749 ins_cost(1.9 * INSN_COST); 10750 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10751 10752 ins_encode %{ 10753 __ andw(as_Register($dst$$reg), 10754 as_Register($src1$$reg), 10755 as_Register($src2$$reg), 10756 Assembler::ASR, 10757 $src3$$constant & 0x1f); 10758 %} 10759 10760 ins_pipe(ialu_reg_reg_shift); 10761 %} 10762 10763 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10764 iRegL src1, iRegL src2, 10765 immI src3, rFlagsReg cr) %{ 10766 match(Set dst (AndL src1 (RShiftL src2 src3))); 10767 10768 ins_cost(1.9 * INSN_COST); 10769 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10770 10771 ins_encode %{ 10772 __ andr(as_Register($dst$$reg), 10773 as_Register($src1$$reg), 10774 as_Register($src2$$reg), 10775 Assembler::ASR, 10776 $src3$$constant & 0x3f); 10777 %} 10778 10779 ins_pipe(ialu_reg_reg_shift); 10780 %} 10781 10782 instruct AndI_reg_LShift_reg(iRegINoSp dst, 10783 iRegIorL2I src1, iRegIorL2I src2, 10784 immI src3, rFlagsReg cr) %{ 10785 match(Set dst (AndI src1 (LShiftI src2 src3))); 10786 10787 ins_cost(1.9 * INSN_COST); 10788 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10789 10790 ins_encode %{ 10791 __ andw(as_Register($dst$$reg), 10792 as_Register($src1$$reg), 10793 as_Register($src2$$reg), 10794 Assembler::LSL, 10795 $src3$$constant & 0x1f); 10796 %} 10797 10798 ins_pipe(ialu_reg_reg_shift); 10799 %} 10800 10801 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10802 iRegL src1, iRegL src2, 10803 immI src3, rFlagsReg cr) %{ 10804 match(Set dst (AndL src1 (LShiftL src2 src3))); 10805 10806 ins_cost(1.9 * INSN_COST); 10807 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10808 10809 ins_encode %{ 10810 __ andr(as_Register($dst$$reg), 10811 as_Register($src1$$reg), 10812 as_Register($src2$$reg), 10813 Assembler::LSL, 10814 $src3$$constant & 0x3f); 10815 %} 10816 10817 ins_pipe(ialu_reg_reg_shift); 10818 %} 10819 10820 instruct XorI_reg_URShift_reg(iRegINoSp dst, 10821 iRegIorL2I src1, iRegIorL2I src2, 10822 immI src3, rFlagsReg cr) %{ 10823 match(Set dst (XorI src1 (URShiftI src2 src3))); 10824 10825 ins_cost(1.9 * INSN_COST); 10826 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10827 10828 ins_encode %{ 10829 __ eorw(as_Register($dst$$reg), 10830 as_Register($src1$$reg), 10831 as_Register($src2$$reg), 10832 Assembler::LSR, 10833 $src3$$constant & 0x1f); 10834 %} 10835 10836 ins_pipe(ialu_reg_reg_shift); 10837 %} 10838 10839 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10840 iRegL src1, iRegL src2, 10841 immI src3, rFlagsReg cr) %{ 10842 match(Set dst (XorL src1 (URShiftL src2 src3))); 10843 10844 ins_cost(1.9 * INSN_COST); 10845 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10846 10847 ins_encode %{ 10848 __ eor(as_Register($dst$$reg), 10849 as_Register($src1$$reg), 10850 as_Register($src2$$reg), 10851 Assembler::LSR, 10852 $src3$$constant & 0x3f); 10853 %} 10854 10855 ins_pipe(ialu_reg_reg_shift); 10856 %} 10857 10858 instruct XorI_reg_RShift_reg(iRegINoSp dst, 10859 iRegIorL2I src1, iRegIorL2I src2, 10860 immI src3, rFlagsReg cr) %{ 10861 match(Set dst (XorI src1 (RShiftI src2 src3))); 10862 10863 ins_cost(1.9 * INSN_COST); 10864 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10865 10866 ins_encode %{ 10867 __ eorw(as_Register($dst$$reg), 10868 as_Register($src1$$reg), 10869 as_Register($src2$$reg), 10870 Assembler::ASR, 10871 $src3$$constant & 0x1f); 10872 %} 10873 10874 ins_pipe(ialu_reg_reg_shift); 10875 %} 10876 10877 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10878 iRegL src1, iRegL src2, 10879 immI src3, rFlagsReg cr) %{ 10880 match(Set dst (XorL src1 (RShiftL src2 src3))); 10881 10882 ins_cost(1.9 * INSN_COST); 10883 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10884 10885 ins_encode %{ 10886 __ eor(as_Register($dst$$reg), 10887 as_Register($src1$$reg), 10888 as_Register($src2$$reg), 10889 Assembler::ASR, 10890 $src3$$constant & 0x3f); 10891 %} 10892 10893 ins_pipe(ialu_reg_reg_shift); 10894 %} 10895 10896 instruct XorI_reg_LShift_reg(iRegINoSp dst, 10897 iRegIorL2I src1, iRegIorL2I src2, 10898 immI src3, rFlagsReg cr) %{ 10899 match(Set dst (XorI src1 (LShiftI src2 src3))); 10900 10901 ins_cost(1.9 * INSN_COST); 10902 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10903 10904 ins_encode %{ 10905 __ eorw(as_Register($dst$$reg), 10906 as_Register($src1$$reg), 10907 as_Register($src2$$reg), 10908 Assembler::LSL, 10909 $src3$$constant & 0x1f); 10910 %} 10911 10912 ins_pipe(ialu_reg_reg_shift); 10913 %} 10914 10915 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 10916 iRegL src1, iRegL src2, 10917 immI src3, rFlagsReg cr) %{ 10918 match(Set dst (XorL src1 (LShiftL src2 src3))); 10919 10920 ins_cost(1.9 * INSN_COST); 10921 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 10922 10923 ins_encode %{ 10924 __ eor(as_Register($dst$$reg), 10925 as_Register($src1$$reg), 10926 as_Register($src2$$reg), 10927 Assembler::LSL, 10928 $src3$$constant & 0x3f); 10929 %} 10930 10931 ins_pipe(ialu_reg_reg_shift); 10932 %} 10933 10934 instruct OrI_reg_URShift_reg(iRegINoSp dst, 10935 iRegIorL2I src1, iRegIorL2I src2, 10936 immI src3, rFlagsReg cr) %{ 10937 match(Set dst (OrI src1 (URShiftI src2 src3))); 10938 10939 ins_cost(1.9 * INSN_COST); 10940 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 10941 10942 ins_encode %{ 10943 __ orrw(as_Register($dst$$reg), 10944 as_Register($src1$$reg), 10945 as_Register($src2$$reg), 10946 Assembler::LSR, 10947 $src3$$constant & 0x1f); 10948 %} 10949 10950 ins_pipe(ialu_reg_reg_shift); 10951 %} 10952 10953 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 10954 iRegL src1, iRegL src2, 10955 immI src3, rFlagsReg cr) %{ 10956 match(Set dst (OrL src1 (URShiftL src2 src3))); 10957 10958 ins_cost(1.9 * INSN_COST); 10959 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 10960 10961 ins_encode %{ 10962 __ orr(as_Register($dst$$reg), 10963 as_Register($src1$$reg), 10964 as_Register($src2$$reg), 10965 Assembler::LSR, 10966 $src3$$constant & 0x3f); 10967 %} 10968 10969 ins_pipe(ialu_reg_reg_shift); 10970 %} 10971 10972 instruct OrI_reg_RShift_reg(iRegINoSp dst, 10973 iRegIorL2I src1, iRegIorL2I src2, 10974 immI src3, rFlagsReg cr) %{ 10975 match(Set dst (OrI src1 (RShiftI src2 src3))); 10976 10977 ins_cost(1.9 * INSN_COST); 10978 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 10979 10980 ins_encode %{ 10981 __ orrw(as_Register($dst$$reg), 10982 as_Register($src1$$reg), 10983 as_Register($src2$$reg), 10984 Assembler::ASR, 10985 $src3$$constant & 0x1f); 10986 %} 10987 10988 ins_pipe(ialu_reg_reg_shift); 10989 %} 10990 10991 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 10992 iRegL src1, iRegL src2, 10993 immI src3, rFlagsReg cr) %{ 10994 match(Set dst (OrL src1 (RShiftL src2 src3))); 10995 10996 ins_cost(1.9 * INSN_COST); 10997 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 10998 10999 ins_encode %{ 11000 __ orr(as_Register($dst$$reg), 11001 as_Register($src1$$reg), 11002 as_Register($src2$$reg), 11003 Assembler::ASR, 11004 $src3$$constant & 0x3f); 11005 %} 11006 11007 ins_pipe(ialu_reg_reg_shift); 11008 %} 11009 11010 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11011 iRegIorL2I src1, iRegIorL2I src2, 11012 immI src3, rFlagsReg cr) %{ 11013 match(Set dst (OrI src1 (LShiftI src2 src3))); 11014 11015 ins_cost(1.9 * INSN_COST); 11016 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11017 11018 ins_encode %{ 11019 __ orrw(as_Register($dst$$reg), 11020 as_Register($src1$$reg), 11021 as_Register($src2$$reg), 11022 Assembler::LSL, 11023 $src3$$constant & 0x1f); 11024 %} 11025 11026 ins_pipe(ialu_reg_reg_shift); 11027 %} 11028 11029 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11030 iRegL src1, iRegL src2, 11031 immI src3, rFlagsReg cr) %{ 11032 match(Set dst (OrL src1 (LShiftL src2 src3))); 11033 11034 ins_cost(1.9 * INSN_COST); 11035 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11036 11037 ins_encode %{ 11038 __ orr(as_Register($dst$$reg), 11039 as_Register($src1$$reg), 11040 as_Register($src2$$reg), 11041 Assembler::LSL, 11042 $src3$$constant & 0x3f); 11043 %} 11044 11045 ins_pipe(ialu_reg_reg_shift); 11046 %} 11047 11048 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11049 iRegIorL2I src1, iRegIorL2I src2, 11050 immI src3, rFlagsReg cr) %{ 11051 match(Set dst (AddI src1 (URShiftI src2 src3))); 11052 11053 ins_cost(1.9 * INSN_COST); 11054 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11055 11056 ins_encode %{ 11057 __ addw(as_Register($dst$$reg), 11058 as_Register($src1$$reg), 11059 as_Register($src2$$reg), 11060 Assembler::LSR, 11061 $src3$$constant & 0x1f); 11062 %} 11063 11064 ins_pipe(ialu_reg_reg_shift); 11065 %} 11066 11067 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11068 iRegL src1, iRegL src2, 11069 immI src3, rFlagsReg cr) %{ 11070 match(Set dst (AddL src1 (URShiftL src2 src3))); 11071 11072 ins_cost(1.9 * INSN_COST); 11073 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11074 11075 ins_encode %{ 11076 __ add(as_Register($dst$$reg), 11077 as_Register($src1$$reg), 11078 as_Register($src2$$reg), 11079 Assembler::LSR, 11080 $src3$$constant & 0x3f); 11081 %} 11082 11083 ins_pipe(ialu_reg_reg_shift); 11084 %} 11085 11086 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11087 iRegIorL2I src1, iRegIorL2I src2, 11088 immI src3, rFlagsReg cr) %{ 11089 match(Set dst (AddI src1 (RShiftI src2 src3))); 11090 11091 ins_cost(1.9 * INSN_COST); 11092 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11093 11094 ins_encode %{ 11095 __ addw(as_Register($dst$$reg), 11096 as_Register($src1$$reg), 11097 as_Register($src2$$reg), 11098 Assembler::ASR, 11099 $src3$$constant & 0x1f); 11100 %} 11101 11102 ins_pipe(ialu_reg_reg_shift); 11103 %} 11104 11105 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11106 iRegL src1, iRegL src2, 11107 immI src3, rFlagsReg cr) %{ 11108 match(Set dst (AddL src1 (RShiftL src2 src3))); 11109 11110 ins_cost(1.9 * INSN_COST); 11111 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11112 11113 ins_encode %{ 11114 __ add(as_Register($dst$$reg), 11115 as_Register($src1$$reg), 11116 as_Register($src2$$reg), 11117 Assembler::ASR, 11118 $src3$$constant & 0x3f); 11119 %} 11120 11121 ins_pipe(ialu_reg_reg_shift); 11122 %} 11123 11124 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11125 iRegIorL2I src1, iRegIorL2I src2, 11126 immI src3, rFlagsReg cr) %{ 11127 match(Set dst (AddI src1 (LShiftI src2 src3))); 11128 11129 ins_cost(1.9 * INSN_COST); 11130 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11131 11132 ins_encode %{ 11133 __ addw(as_Register($dst$$reg), 11134 as_Register($src1$$reg), 11135 as_Register($src2$$reg), 11136 Assembler::LSL, 11137 $src3$$constant & 0x1f); 11138 %} 11139 11140 ins_pipe(ialu_reg_reg_shift); 11141 %} 11142 11143 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11144 iRegL src1, iRegL src2, 11145 immI src3, rFlagsReg cr) %{ 11146 match(Set dst (AddL src1 (LShiftL src2 src3))); 11147 11148 ins_cost(1.9 * INSN_COST); 11149 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11150 11151 ins_encode %{ 11152 __ add(as_Register($dst$$reg), 11153 as_Register($src1$$reg), 11154 as_Register($src2$$reg), 11155 Assembler::LSL, 11156 $src3$$constant & 0x3f); 11157 %} 11158 11159 ins_pipe(ialu_reg_reg_shift); 11160 %} 11161 11162 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11163 iRegIorL2I src1, iRegIorL2I src2, 11164 immI src3, rFlagsReg cr) %{ 11165 match(Set dst (SubI src1 (URShiftI src2 src3))); 11166 11167 ins_cost(1.9 * INSN_COST); 11168 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11169 11170 ins_encode %{ 11171 __ subw(as_Register($dst$$reg), 11172 as_Register($src1$$reg), 11173 as_Register($src2$$reg), 11174 Assembler::LSR, 11175 $src3$$constant & 0x1f); 11176 %} 11177 11178 ins_pipe(ialu_reg_reg_shift); 11179 %} 11180 11181 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11182 iRegL src1, iRegL src2, 11183 immI src3, rFlagsReg cr) %{ 11184 match(Set dst (SubL src1 (URShiftL src2 src3))); 11185 11186 ins_cost(1.9 * INSN_COST); 11187 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11188 11189 ins_encode %{ 11190 __ sub(as_Register($dst$$reg), 11191 as_Register($src1$$reg), 11192 as_Register($src2$$reg), 11193 Assembler::LSR, 11194 $src3$$constant & 0x3f); 11195 %} 11196 11197 ins_pipe(ialu_reg_reg_shift); 11198 %} 11199 11200 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11201 iRegIorL2I src1, iRegIorL2I src2, 11202 immI src3, rFlagsReg cr) %{ 11203 match(Set dst (SubI src1 (RShiftI src2 src3))); 11204 11205 ins_cost(1.9 * INSN_COST); 11206 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11207 11208 ins_encode %{ 11209 __ subw(as_Register($dst$$reg), 11210 as_Register($src1$$reg), 11211 as_Register($src2$$reg), 11212 Assembler::ASR, 11213 $src3$$constant & 0x1f); 11214 %} 11215 11216 ins_pipe(ialu_reg_reg_shift); 11217 %} 11218 11219 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11220 iRegL src1, iRegL src2, 11221 immI src3, rFlagsReg cr) %{ 11222 match(Set dst (SubL src1 (RShiftL src2 src3))); 11223 11224 ins_cost(1.9 * INSN_COST); 11225 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11226 11227 ins_encode %{ 11228 __ sub(as_Register($dst$$reg), 11229 as_Register($src1$$reg), 11230 as_Register($src2$$reg), 11231 Assembler::ASR, 11232 $src3$$constant & 0x3f); 11233 %} 11234 11235 ins_pipe(ialu_reg_reg_shift); 11236 %} 11237 11238 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11239 iRegIorL2I src1, iRegIorL2I src2, 11240 immI src3, rFlagsReg cr) %{ 11241 match(Set dst (SubI src1 (LShiftI src2 src3))); 11242 11243 ins_cost(1.9 * INSN_COST); 11244 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11245 11246 ins_encode %{ 11247 __ subw(as_Register($dst$$reg), 11248 as_Register($src1$$reg), 11249 as_Register($src2$$reg), 11250 Assembler::LSL, 11251 $src3$$constant & 0x1f); 11252 %} 11253 11254 ins_pipe(ialu_reg_reg_shift); 11255 %} 11256 11257 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11258 iRegL src1, iRegL src2, 11259 immI src3, rFlagsReg cr) %{ 11260 match(Set dst (SubL src1 (LShiftL src2 src3))); 11261 11262 ins_cost(1.9 * INSN_COST); 11263 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11264 11265 ins_encode %{ 11266 __ sub(as_Register($dst$$reg), 11267 as_Register($src1$$reg), 11268 as_Register($src2$$reg), 11269 Assembler::LSL, 11270 $src3$$constant & 0x3f); 11271 %} 11272 11273 ins_pipe(ialu_reg_reg_shift); 11274 %} 11275 11276 11277 11278 // Shift Left followed by Shift Right. 11279 // This idiom is used by the compiler for the i2b bytecode etc. 11280 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11281 %{ 11282 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11283 // Make sure we are not going to exceed what sbfm can do. 11284 predicate((unsigned int)n->in(2)->get_int() <= 63 11285 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11286 11287 ins_cost(INSN_COST * 2); 11288 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11289 ins_encode %{ 11290 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11291 int s = 63 - lshift; 11292 int r = (rshift - lshift) & 63; 11293 __ sbfm(as_Register($dst$$reg), 11294 as_Register($src$$reg), 11295 r, s); 11296 %} 11297 11298 ins_pipe(ialu_reg_shift); 11299 %} 11300 11301 // Shift Left followed by Shift Right. 11302 // This idiom is used by the compiler for the i2b bytecode etc. 11303 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11304 %{ 11305 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11306 // Make sure we are not going to exceed what sbfmw can do. 11307 predicate((unsigned int)n->in(2)->get_int() <= 31 11308 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11309 11310 ins_cost(INSN_COST * 2); 11311 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11312 ins_encode %{ 11313 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11314 int s = 31 - lshift; 11315 int r = (rshift - lshift) & 31; 11316 __ sbfmw(as_Register($dst$$reg), 11317 as_Register($src$$reg), 11318 r, s); 11319 %} 11320 11321 ins_pipe(ialu_reg_shift); 11322 %} 11323 11324 // Shift Left followed by Shift Right. 11325 // This idiom is used by the compiler for the i2b bytecode etc. 11326 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11327 %{ 11328 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11329 // Make sure we are not going to exceed what ubfm can do. 11330 predicate((unsigned int)n->in(2)->get_int() <= 63 11331 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11332 11333 ins_cost(INSN_COST * 2); 11334 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11335 ins_encode %{ 11336 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11337 int s = 63 - lshift; 11338 int r = (rshift - lshift) & 63; 11339 __ ubfm(as_Register($dst$$reg), 11340 as_Register($src$$reg), 11341 r, s); 11342 %} 11343 11344 ins_pipe(ialu_reg_shift); 11345 %} 11346 11347 // Shift Left followed by Shift Right. 11348 // This idiom is used by the compiler for the i2b bytecode etc. 11349 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11350 %{ 11351 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11352 // Make sure we are not going to exceed what ubfmw can do. 11353 predicate((unsigned int)n->in(2)->get_int() <= 31 11354 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11355 11356 ins_cost(INSN_COST * 2); 11357 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11358 ins_encode %{ 11359 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11360 int s = 31 - lshift; 11361 int r = (rshift - lshift) & 31; 11362 __ ubfmw(as_Register($dst$$reg), 11363 as_Register($src$$reg), 11364 r, s); 11365 %} 11366 11367 ins_pipe(ialu_reg_shift); 11368 %} 11369 // Bitfield extract with shift & mask 11370 11371 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11372 %{ 11373 match(Set dst (AndI (URShiftI src rshift) mask)); 11374 11375 ins_cost(INSN_COST); 11376 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11377 ins_encode %{ 11378 int rshift = $rshift$$constant; 11379 long mask = $mask$$constant; 11380 int width = exact_log2(mask+1); 11381 __ ubfxw(as_Register($dst$$reg), 11382 as_Register($src$$reg), rshift, width); 11383 %} 11384 ins_pipe(ialu_reg_shift); 11385 %} 11386 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11387 %{ 11388 match(Set dst (AndL (URShiftL src rshift) mask)); 11389 11390 ins_cost(INSN_COST); 11391 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11392 ins_encode %{ 11393 int rshift = $rshift$$constant; 11394 long mask = $mask$$constant; 11395 int width = exact_log2(mask+1); 11396 __ ubfx(as_Register($dst$$reg), 11397 as_Register($src$$reg), rshift, width); 11398 %} 11399 ins_pipe(ialu_reg_shift); 11400 %} 11401 11402 // We can use ubfx when extending an And with a mask when we know mask 11403 // is positive. We know that because immI_bitmask guarantees it. 11404 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11405 %{ 11406 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11407 11408 ins_cost(INSN_COST * 2); 11409 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11410 ins_encode %{ 11411 int rshift = $rshift$$constant; 11412 long mask = $mask$$constant; 11413 int width = exact_log2(mask+1); 11414 __ ubfx(as_Register($dst$$reg), 11415 as_Register($src$$reg), rshift, width); 11416 %} 11417 ins_pipe(ialu_reg_shift); 11418 %} 11419 11420 // We can use ubfiz when masking by a positive number and then left shifting the result. 11421 // We know that the mask is positive because immI_bitmask guarantees it. 11422 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11423 %{ 11424 match(Set dst (LShiftI (AndI src mask) lshift)); 11425 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11426 (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1)); 11427 11428 ins_cost(INSN_COST); 11429 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11430 ins_encode %{ 11431 int lshift = $lshift$$constant; 11432 long mask = $mask$$constant; 11433 int width = exact_log2(mask+1); 11434 __ ubfizw(as_Register($dst$$reg), 11435 as_Register($src$$reg), lshift, width); 11436 %} 11437 ins_pipe(ialu_reg_shift); 11438 %} 11439 // We can use ubfiz when masking by a positive number and then left shifting the result. 11440 // We know that the mask is positive because immL_bitmask guarantees it. 11441 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11442 %{ 11443 match(Set dst (LShiftL (AndL src mask) lshift)); 11444 predicate((unsigned int)n->in(2)->get_int() <= 63 && 11445 (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1)); 11446 11447 ins_cost(INSN_COST); 11448 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11449 ins_encode %{ 11450 int lshift = $lshift$$constant; 11451 long mask = $mask$$constant; 11452 int width = exact_log2(mask+1); 11453 __ ubfiz(as_Register($dst$$reg), 11454 as_Register($src$$reg), lshift, width); 11455 %} 11456 ins_pipe(ialu_reg_shift); 11457 %} 11458 11459 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11460 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11461 %{ 11462 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); 11463 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11464 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); 11465 11466 ins_cost(INSN_COST); 11467 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11468 ins_encode %{ 11469 int lshift = $lshift$$constant; 11470 long mask = $mask$$constant; 11471 int width = exact_log2(mask+1); 11472 __ ubfiz(as_Register($dst$$reg), 11473 as_Register($src$$reg), lshift, width); 11474 %} 11475 ins_pipe(ialu_reg_shift); 11476 %} 11477 11478 // Rotations 11479 11480 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11481 %{ 11482 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11483 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11484 11485 ins_cost(INSN_COST); 11486 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11487 11488 ins_encode %{ 11489 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11490 $rshift$$constant & 63); 11491 %} 11492 ins_pipe(ialu_reg_reg_extr); 11493 %} 11494 11495 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11496 %{ 11497 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11498 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11499 11500 ins_cost(INSN_COST); 11501 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11502 11503 ins_encode %{ 11504 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11505 $rshift$$constant & 31); 11506 %} 11507 ins_pipe(ialu_reg_reg_extr); 11508 %} 11509 11510 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11511 %{ 11512 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11513 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11514 11515 ins_cost(INSN_COST); 11516 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11517 11518 ins_encode %{ 11519 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11520 $rshift$$constant & 63); 11521 %} 11522 ins_pipe(ialu_reg_reg_extr); 11523 %} 11524 11525 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11526 %{ 11527 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11528 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11529 11530 ins_cost(INSN_COST); 11531 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11532 11533 ins_encode %{ 11534 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11535 $rshift$$constant & 31); 11536 %} 11537 ins_pipe(ialu_reg_reg_extr); 11538 %} 11539 11540 11541 // rol expander 11542 11543 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11544 %{ 11545 effect(DEF dst, USE src, USE shift); 11546 11547 format %{ "rol $dst, $src, $shift" %} 11548 ins_cost(INSN_COST * 3); 11549 ins_encode %{ 11550 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11551 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11552 rscratch1); 11553 %} 11554 ins_pipe(ialu_reg_reg_vshift); 11555 %} 11556 11557 // rol expander 11558 11559 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11560 %{ 11561 effect(DEF dst, USE src, USE shift); 11562 11563 format %{ "rol $dst, $src, $shift" %} 11564 ins_cost(INSN_COST * 3); 11565 ins_encode %{ 11566 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11567 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11568 rscratch1); 11569 %} 11570 ins_pipe(ialu_reg_reg_vshift); 11571 %} 11572 11573 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11574 %{ 11575 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11576 11577 expand %{ 11578 rolL_rReg(dst, src, shift, cr); 11579 %} 11580 %} 11581 11582 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11583 %{ 11584 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11585 11586 expand %{ 11587 rolL_rReg(dst, src, shift, cr); 11588 %} 11589 %} 11590 11591 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11592 %{ 11593 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11594 11595 expand %{ 11596 rolI_rReg(dst, src, shift, cr); 11597 %} 11598 %} 11599 11600 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11601 %{ 11602 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11603 11604 expand %{ 11605 rolI_rReg(dst, src, shift, cr); 11606 %} 11607 %} 11608 11609 // ror expander 11610 11611 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11612 %{ 11613 effect(DEF dst, USE src, USE shift); 11614 11615 format %{ "ror $dst, $src, $shift" %} 11616 ins_cost(INSN_COST); 11617 ins_encode %{ 11618 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11619 as_Register($shift$$reg)); 11620 %} 11621 ins_pipe(ialu_reg_reg_vshift); 11622 %} 11623 11624 // ror expander 11625 11626 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11627 %{ 11628 effect(DEF dst, USE src, USE shift); 11629 11630 format %{ "ror $dst, $src, $shift" %} 11631 ins_cost(INSN_COST); 11632 ins_encode %{ 11633 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11634 as_Register($shift$$reg)); 11635 %} 11636 ins_pipe(ialu_reg_reg_vshift); 11637 %} 11638 11639 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11640 %{ 11641 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11642 11643 expand %{ 11644 rorL_rReg(dst, src, shift, cr); 11645 %} 11646 %} 11647 11648 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11649 %{ 11650 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11651 11652 expand %{ 11653 rorL_rReg(dst, src, shift, cr); 11654 %} 11655 %} 11656 11657 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11658 %{ 11659 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11660 11661 expand %{ 11662 rorI_rReg(dst, src, shift, cr); 11663 %} 11664 %} 11665 11666 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11667 %{ 11668 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11669 11670 expand %{ 11671 rorI_rReg(dst, src, shift, cr); 11672 %} 11673 %} 11674 11675 // Add/subtract (extended) 11676 11677 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11678 %{ 11679 match(Set dst (AddL src1 (ConvI2L src2))); 11680 ins_cost(INSN_COST); 11681 format %{ "add $dst, $src1, $src2, sxtw" %} 11682 11683 ins_encode %{ 11684 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11685 as_Register($src2$$reg), ext::sxtw); 11686 %} 11687 ins_pipe(ialu_reg_reg); 11688 %}; 11689 11690 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11691 %{ 11692 match(Set dst (SubL src1 (ConvI2L src2))); 11693 ins_cost(INSN_COST); 11694 format %{ "sub $dst, $src1, $src2, sxtw" %} 11695 11696 ins_encode %{ 11697 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11698 as_Register($src2$$reg), ext::sxtw); 11699 %} 11700 ins_pipe(ialu_reg_reg); 11701 %}; 11702 11703 11704 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11705 %{ 11706 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11707 ins_cost(INSN_COST); 11708 format %{ "add $dst, $src1, $src2, sxth" %} 11709 11710 ins_encode %{ 11711 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11712 as_Register($src2$$reg), ext::sxth); 11713 %} 11714 ins_pipe(ialu_reg_reg); 11715 %} 11716 11717 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11718 %{ 11719 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11720 ins_cost(INSN_COST); 11721 format %{ "add $dst, $src1, $src2, sxtb" %} 11722 11723 ins_encode %{ 11724 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11725 as_Register($src2$$reg), ext::sxtb); 11726 %} 11727 ins_pipe(ialu_reg_reg); 11728 %} 11729 11730 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11731 %{ 11732 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 11733 ins_cost(INSN_COST); 11734 format %{ "add $dst, $src1, $src2, uxtb" %} 11735 11736 ins_encode %{ 11737 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11738 as_Register($src2$$reg), ext::uxtb); 11739 %} 11740 ins_pipe(ialu_reg_reg); 11741 %} 11742 11743 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 11744 %{ 11745 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11746 ins_cost(INSN_COST); 11747 format %{ "add $dst, $src1, $src2, sxth" %} 11748 11749 ins_encode %{ 11750 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11751 as_Register($src2$$reg), ext::sxth); 11752 %} 11753 ins_pipe(ialu_reg_reg); 11754 %} 11755 11756 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 11757 %{ 11758 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11759 ins_cost(INSN_COST); 11760 format %{ "add $dst, $src1, $src2, sxtw" %} 11761 11762 ins_encode %{ 11763 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11764 as_Register($src2$$reg), ext::sxtw); 11765 %} 11766 ins_pipe(ialu_reg_reg); 11767 %} 11768 11769 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11770 %{ 11771 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11772 ins_cost(INSN_COST); 11773 format %{ "add $dst, $src1, $src2, sxtb" %} 11774 11775 ins_encode %{ 11776 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11777 as_Register($src2$$reg), ext::sxtb); 11778 %} 11779 ins_pipe(ialu_reg_reg); 11780 %} 11781 11782 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11783 %{ 11784 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 11785 ins_cost(INSN_COST); 11786 format %{ "add $dst, $src1, $src2, uxtb" %} 11787 11788 ins_encode %{ 11789 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11790 as_Register($src2$$reg), ext::uxtb); 11791 %} 11792 ins_pipe(ialu_reg_reg); 11793 %} 11794 11795 11796 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11797 %{ 11798 match(Set dst (AddI src1 (AndI src2 mask))); 11799 ins_cost(INSN_COST); 11800 format %{ "addw $dst, $src1, $src2, uxtb" %} 11801 11802 ins_encode %{ 11803 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11804 as_Register($src2$$reg), ext::uxtb); 11805 %} 11806 ins_pipe(ialu_reg_reg); 11807 %} 11808 11809 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11810 %{ 11811 match(Set dst (AddI src1 (AndI src2 mask))); 11812 ins_cost(INSN_COST); 11813 format %{ "addw $dst, $src1, $src2, uxth" %} 11814 11815 ins_encode %{ 11816 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11817 as_Register($src2$$reg), ext::uxth); 11818 %} 11819 ins_pipe(ialu_reg_reg); 11820 %} 11821 11822 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11823 %{ 11824 match(Set dst (AddL src1 (AndL src2 mask))); 11825 ins_cost(INSN_COST); 11826 format %{ "add $dst, $src1, $src2, uxtb" %} 11827 11828 ins_encode %{ 11829 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11830 as_Register($src2$$reg), ext::uxtb); 11831 %} 11832 ins_pipe(ialu_reg_reg); 11833 %} 11834 11835 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11836 %{ 11837 match(Set dst (AddL src1 (AndL src2 mask))); 11838 ins_cost(INSN_COST); 11839 format %{ "add $dst, $src1, $src2, uxth" %} 11840 11841 ins_encode %{ 11842 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11843 as_Register($src2$$reg), ext::uxth); 11844 %} 11845 ins_pipe(ialu_reg_reg); 11846 %} 11847 11848 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11849 %{ 11850 match(Set dst (AddL src1 (AndL src2 mask))); 11851 ins_cost(INSN_COST); 11852 format %{ "add $dst, $src1, $src2, uxtw" %} 11853 11854 ins_encode %{ 11855 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11856 as_Register($src2$$reg), ext::uxtw); 11857 %} 11858 ins_pipe(ialu_reg_reg); 11859 %} 11860 11861 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11862 %{ 11863 match(Set dst (SubI src1 (AndI src2 mask))); 11864 ins_cost(INSN_COST); 11865 format %{ "subw $dst, $src1, $src2, uxtb" %} 11866 11867 ins_encode %{ 11868 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11869 as_Register($src2$$reg), ext::uxtb); 11870 %} 11871 ins_pipe(ialu_reg_reg); 11872 %} 11873 11874 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11875 %{ 11876 match(Set dst (SubI src1 (AndI src2 mask))); 11877 ins_cost(INSN_COST); 11878 format %{ "subw $dst, $src1, $src2, uxth" %} 11879 11880 ins_encode %{ 11881 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11882 as_Register($src2$$reg), ext::uxth); 11883 %} 11884 ins_pipe(ialu_reg_reg); 11885 %} 11886 11887 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11888 %{ 11889 match(Set dst (SubL src1 (AndL src2 mask))); 11890 ins_cost(INSN_COST); 11891 format %{ "sub $dst, $src1, $src2, uxtb" %} 11892 11893 ins_encode %{ 11894 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11895 as_Register($src2$$reg), ext::uxtb); 11896 %} 11897 ins_pipe(ialu_reg_reg); 11898 %} 11899 11900 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11901 %{ 11902 match(Set dst (SubL src1 (AndL src2 mask))); 11903 ins_cost(INSN_COST); 11904 format %{ "sub $dst, $src1, $src2, uxth" %} 11905 11906 ins_encode %{ 11907 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11908 as_Register($src2$$reg), ext::uxth); 11909 %} 11910 ins_pipe(ialu_reg_reg); 11911 %} 11912 11913 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11914 %{ 11915 match(Set dst (SubL src1 (AndL src2 mask))); 11916 ins_cost(INSN_COST); 11917 format %{ "sub $dst, $src1, $src2, uxtw" %} 11918 11919 ins_encode %{ 11920 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11921 as_Register($src2$$reg), ext::uxtw); 11922 %} 11923 ins_pipe(ialu_reg_reg); 11924 %} 11925 11926 11927 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11928 %{ 11929 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11930 ins_cost(1.9 * INSN_COST); 11931 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 11932 11933 ins_encode %{ 11934 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11935 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11936 %} 11937 ins_pipe(ialu_reg_reg_shift); 11938 %} 11939 11940 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11941 %{ 11942 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11943 ins_cost(1.9 * INSN_COST); 11944 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 11945 11946 ins_encode %{ 11947 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11948 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11949 %} 11950 ins_pipe(ialu_reg_reg_shift); 11951 %} 11952 11953 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11954 %{ 11955 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11956 ins_cost(1.9 * INSN_COST); 11957 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 11958 11959 ins_encode %{ 11960 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11961 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11962 %} 11963 ins_pipe(ialu_reg_reg_shift); 11964 %} 11965 11966 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11967 %{ 11968 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11969 ins_cost(1.9 * INSN_COST); 11970 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 11971 11972 ins_encode %{ 11973 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11974 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11975 %} 11976 ins_pipe(ialu_reg_reg_shift); 11977 %} 11978 11979 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11980 %{ 11981 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11982 ins_cost(1.9 * INSN_COST); 11983 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 11984 11985 ins_encode %{ 11986 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11987 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11988 %} 11989 ins_pipe(ialu_reg_reg_shift); 11990 %} 11991 11992 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11993 %{ 11994 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11995 ins_cost(1.9 * INSN_COST); 11996 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 11997 11998 ins_encode %{ 11999 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12000 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12001 %} 12002 ins_pipe(ialu_reg_reg_shift); 12003 %} 12004 12005 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12006 %{ 12007 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12008 ins_cost(1.9 * INSN_COST); 12009 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12010 12011 ins_encode %{ 12012 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12013 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12014 %} 12015 ins_pipe(ialu_reg_reg_shift); 12016 %} 12017 12018 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12019 %{ 12020 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12021 ins_cost(1.9 * INSN_COST); 12022 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12023 12024 ins_encode %{ 12025 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12026 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12027 %} 12028 ins_pipe(ialu_reg_reg_shift); 12029 %} 12030 12031 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12032 %{ 12033 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12034 ins_cost(1.9 * INSN_COST); 12035 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12036 12037 ins_encode %{ 12038 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12039 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12040 %} 12041 ins_pipe(ialu_reg_reg_shift); 12042 %} 12043 12044 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12045 %{ 12046 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12047 ins_cost(1.9 * INSN_COST); 12048 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12049 12050 ins_encode %{ 12051 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12052 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12053 %} 12054 ins_pipe(ialu_reg_reg_shift); 12055 %} 12056 12057 12058 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12059 %{ 12060 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12061 ins_cost(1.9 * INSN_COST); 12062 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12063 12064 ins_encode %{ 12065 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12066 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12067 %} 12068 ins_pipe(ialu_reg_reg_shift); 12069 %}; 12070 12071 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12072 %{ 12073 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12074 ins_cost(1.9 * INSN_COST); 12075 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12076 12077 ins_encode %{ 12078 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12079 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12080 %} 12081 ins_pipe(ialu_reg_reg_shift); 12082 %}; 12083 12084 12085 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12086 %{ 12087 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12088 ins_cost(1.9 * INSN_COST); 12089 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12090 12091 ins_encode %{ 12092 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12093 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12094 %} 12095 ins_pipe(ialu_reg_reg_shift); 12096 %} 12097 12098 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12099 %{ 12100 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12101 ins_cost(1.9 * INSN_COST); 12102 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12103 12104 ins_encode %{ 12105 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12106 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12107 %} 12108 ins_pipe(ialu_reg_reg_shift); 12109 %} 12110 12111 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12112 %{ 12113 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12114 ins_cost(1.9 * INSN_COST); 12115 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12116 12117 ins_encode %{ 12118 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12119 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12120 %} 12121 ins_pipe(ialu_reg_reg_shift); 12122 %} 12123 12124 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12125 %{ 12126 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12127 ins_cost(1.9 * INSN_COST); 12128 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12129 12130 ins_encode %{ 12131 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12132 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12133 %} 12134 ins_pipe(ialu_reg_reg_shift); 12135 %} 12136 12137 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12138 %{ 12139 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12140 ins_cost(1.9 * INSN_COST); 12141 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12142 12143 ins_encode %{ 12144 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12145 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12146 %} 12147 ins_pipe(ialu_reg_reg_shift); 12148 %} 12149 12150 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12151 %{ 12152 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12153 ins_cost(1.9 * INSN_COST); 12154 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12155 12156 ins_encode %{ 12157 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12158 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12159 %} 12160 ins_pipe(ialu_reg_reg_shift); 12161 %} 12162 12163 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12164 %{ 12165 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12166 ins_cost(1.9 * INSN_COST); 12167 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12168 12169 ins_encode %{ 12170 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12171 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12172 %} 12173 ins_pipe(ialu_reg_reg_shift); 12174 %} 12175 12176 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12177 %{ 12178 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12179 ins_cost(1.9 * INSN_COST); 12180 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12181 12182 ins_encode %{ 12183 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12184 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12185 %} 12186 ins_pipe(ialu_reg_reg_shift); 12187 %} 12188 12189 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12190 %{ 12191 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12192 ins_cost(1.9 * INSN_COST); 12193 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12194 12195 ins_encode %{ 12196 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12197 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12198 %} 12199 ins_pipe(ialu_reg_reg_shift); 12200 %} 12201 12202 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12203 %{ 12204 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12205 ins_cost(1.9 * INSN_COST); 12206 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12207 12208 ins_encode %{ 12209 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12210 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12211 %} 12212 ins_pipe(ialu_reg_reg_shift); 12213 %} 12214 // END This section of the file is automatically generated. Do not edit -------------- 12215 12216 // ============================================================================ 12217 // Floating Point Arithmetic Instructions 12218 12219 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12220 match(Set dst (AddF src1 src2)); 12221 12222 ins_cost(INSN_COST * 5); 12223 format %{ "fadds $dst, $src1, $src2" %} 12224 12225 ins_encode %{ 12226 __ fadds(as_FloatRegister($dst$$reg), 12227 as_FloatRegister($src1$$reg), 12228 as_FloatRegister($src2$$reg)); 12229 %} 12230 12231 ins_pipe(fp_dop_reg_reg_s); 12232 %} 12233 12234 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12235 match(Set dst (AddD src1 src2)); 12236 12237 ins_cost(INSN_COST * 5); 12238 format %{ "faddd $dst, $src1, $src2" %} 12239 12240 ins_encode %{ 12241 __ faddd(as_FloatRegister($dst$$reg), 12242 as_FloatRegister($src1$$reg), 12243 as_FloatRegister($src2$$reg)); 12244 %} 12245 12246 ins_pipe(fp_dop_reg_reg_d); 12247 %} 12248 12249 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12250 match(Set dst (SubF src1 src2)); 12251 12252 ins_cost(INSN_COST * 5); 12253 format %{ "fsubs $dst, $src1, $src2" %} 12254 12255 ins_encode %{ 12256 __ fsubs(as_FloatRegister($dst$$reg), 12257 as_FloatRegister($src1$$reg), 12258 as_FloatRegister($src2$$reg)); 12259 %} 12260 12261 ins_pipe(fp_dop_reg_reg_s); 12262 %} 12263 12264 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12265 match(Set dst (SubD src1 src2)); 12266 12267 ins_cost(INSN_COST * 5); 12268 format %{ "fsubd $dst, $src1, $src2" %} 12269 12270 ins_encode %{ 12271 __ fsubd(as_FloatRegister($dst$$reg), 12272 as_FloatRegister($src1$$reg), 12273 as_FloatRegister($src2$$reg)); 12274 %} 12275 12276 ins_pipe(fp_dop_reg_reg_d); 12277 %} 12278 12279 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12280 match(Set dst (MulF src1 src2)); 12281 12282 ins_cost(INSN_COST * 6); 12283 format %{ "fmuls $dst, $src1, $src2" %} 12284 12285 ins_encode %{ 12286 __ fmuls(as_FloatRegister($dst$$reg), 12287 as_FloatRegister($src1$$reg), 12288 as_FloatRegister($src2$$reg)); 12289 %} 12290 12291 ins_pipe(fp_dop_reg_reg_s); 12292 %} 12293 12294 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12295 match(Set dst (MulD src1 src2)); 12296 12297 ins_cost(INSN_COST * 6); 12298 format %{ "fmuld $dst, $src1, $src2" %} 12299 12300 ins_encode %{ 12301 __ fmuld(as_FloatRegister($dst$$reg), 12302 as_FloatRegister($src1$$reg), 12303 as_FloatRegister($src2$$reg)); 12304 %} 12305 12306 ins_pipe(fp_dop_reg_reg_d); 12307 %} 12308 12309 // src1 * src2 + src3 12310 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12311 predicate(UseFMA); 12312 match(Set dst (FmaF src3 (Binary src1 src2))); 12313 12314 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12315 12316 ins_encode %{ 12317 __ fmadds(as_FloatRegister($dst$$reg), 12318 as_FloatRegister($src1$$reg), 12319 as_FloatRegister($src2$$reg), 12320 as_FloatRegister($src3$$reg)); 12321 %} 12322 12323 ins_pipe(pipe_class_default); 12324 %} 12325 12326 // src1 * src2 + src3 12327 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12328 predicate(UseFMA); 12329 match(Set dst (FmaD src3 (Binary src1 src2))); 12330 12331 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12332 12333 ins_encode %{ 12334 __ fmaddd(as_FloatRegister($dst$$reg), 12335 as_FloatRegister($src1$$reg), 12336 as_FloatRegister($src2$$reg), 12337 as_FloatRegister($src3$$reg)); 12338 %} 12339 12340 ins_pipe(pipe_class_default); 12341 %} 12342 12343 // -src1 * src2 + src3 12344 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12345 predicate(UseFMA); 12346 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12347 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12348 12349 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12350 12351 ins_encode %{ 12352 __ fmsubs(as_FloatRegister($dst$$reg), 12353 as_FloatRegister($src1$$reg), 12354 as_FloatRegister($src2$$reg), 12355 as_FloatRegister($src3$$reg)); 12356 %} 12357 12358 ins_pipe(pipe_class_default); 12359 %} 12360 12361 // -src1 * src2 + src3 12362 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12363 predicate(UseFMA); 12364 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12365 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12366 12367 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12368 12369 ins_encode %{ 12370 __ fmsubd(as_FloatRegister($dst$$reg), 12371 as_FloatRegister($src1$$reg), 12372 as_FloatRegister($src2$$reg), 12373 as_FloatRegister($src3$$reg)); 12374 %} 12375 12376 ins_pipe(pipe_class_default); 12377 %} 12378 12379 // -src1 * src2 - src3 12380 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12381 predicate(UseFMA); 12382 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12383 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12384 12385 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12386 12387 ins_encode %{ 12388 __ fnmadds(as_FloatRegister($dst$$reg), 12389 as_FloatRegister($src1$$reg), 12390 as_FloatRegister($src2$$reg), 12391 as_FloatRegister($src3$$reg)); 12392 %} 12393 12394 ins_pipe(pipe_class_default); 12395 %} 12396 12397 // -src1 * src2 - src3 12398 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12399 predicate(UseFMA); 12400 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12401 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12402 12403 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12404 12405 ins_encode %{ 12406 __ fnmaddd(as_FloatRegister($dst$$reg), 12407 as_FloatRegister($src1$$reg), 12408 as_FloatRegister($src2$$reg), 12409 as_FloatRegister($src3$$reg)); 12410 %} 12411 12412 ins_pipe(pipe_class_default); 12413 %} 12414 12415 // src1 * src2 - src3 12416 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12417 predicate(UseFMA); 12418 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12419 12420 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12421 12422 ins_encode %{ 12423 __ fnmsubs(as_FloatRegister($dst$$reg), 12424 as_FloatRegister($src1$$reg), 12425 as_FloatRegister($src2$$reg), 12426 as_FloatRegister($src3$$reg)); 12427 %} 12428 12429 ins_pipe(pipe_class_default); 12430 %} 12431 12432 // src1 * src2 - src3 12433 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12434 predicate(UseFMA); 12435 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12436 12437 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12438 12439 ins_encode %{ 12440 // n.b. insn name should be fnmsubd 12441 __ fnmsub(as_FloatRegister($dst$$reg), 12442 as_FloatRegister($src1$$reg), 12443 as_FloatRegister($src2$$reg), 12444 as_FloatRegister($src3$$reg)); 12445 %} 12446 12447 ins_pipe(pipe_class_default); 12448 %} 12449 12450 12451 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12452 match(Set dst (DivF src1 src2)); 12453 12454 ins_cost(INSN_COST * 18); 12455 format %{ "fdivs $dst, $src1, $src2" %} 12456 12457 ins_encode %{ 12458 __ fdivs(as_FloatRegister($dst$$reg), 12459 as_FloatRegister($src1$$reg), 12460 as_FloatRegister($src2$$reg)); 12461 %} 12462 12463 ins_pipe(fp_div_s); 12464 %} 12465 12466 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12467 match(Set dst (DivD src1 src2)); 12468 12469 ins_cost(INSN_COST * 32); 12470 format %{ "fdivd $dst, $src1, $src2" %} 12471 12472 ins_encode %{ 12473 __ fdivd(as_FloatRegister($dst$$reg), 12474 as_FloatRegister($src1$$reg), 12475 as_FloatRegister($src2$$reg)); 12476 %} 12477 12478 ins_pipe(fp_div_d); 12479 %} 12480 12481 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12482 match(Set dst (NegF src)); 12483 12484 ins_cost(INSN_COST * 3); 12485 format %{ "fneg $dst, $src" %} 12486 12487 ins_encode %{ 12488 __ fnegs(as_FloatRegister($dst$$reg), 12489 as_FloatRegister($src$$reg)); 12490 %} 12491 12492 ins_pipe(fp_uop_s); 12493 %} 12494 12495 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12496 match(Set dst (NegD src)); 12497 12498 ins_cost(INSN_COST * 3); 12499 format %{ "fnegd $dst, $src" %} 12500 12501 ins_encode %{ 12502 __ fnegd(as_FloatRegister($dst$$reg), 12503 as_FloatRegister($src$$reg)); 12504 %} 12505 12506 ins_pipe(fp_uop_d); 12507 %} 12508 12509 instruct absF_reg(vRegF dst, vRegF src) %{ 12510 match(Set dst (AbsF src)); 12511 12512 ins_cost(INSN_COST * 3); 12513 format %{ "fabss $dst, $src" %} 12514 ins_encode %{ 12515 __ fabss(as_FloatRegister($dst$$reg), 12516 as_FloatRegister($src$$reg)); 12517 %} 12518 12519 ins_pipe(fp_uop_s); 12520 %} 12521 12522 instruct absD_reg(vRegD dst, vRegD src) %{ 12523 match(Set dst (AbsD src)); 12524 12525 ins_cost(INSN_COST * 3); 12526 format %{ "fabsd $dst, $src" %} 12527 ins_encode %{ 12528 __ fabsd(as_FloatRegister($dst$$reg), 12529 as_FloatRegister($src$$reg)); 12530 %} 12531 12532 ins_pipe(fp_uop_d); 12533 %} 12534 12535 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12536 match(Set dst (SqrtD src)); 12537 12538 ins_cost(INSN_COST * 50); 12539 format %{ "fsqrtd $dst, $src" %} 12540 ins_encode %{ 12541 __ fsqrtd(as_FloatRegister($dst$$reg), 12542 as_FloatRegister($src$$reg)); 12543 %} 12544 12545 ins_pipe(fp_div_s); 12546 %} 12547 12548 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12549 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 12550 12551 ins_cost(INSN_COST * 50); 12552 format %{ "fsqrts $dst, $src" %} 12553 ins_encode %{ 12554 __ fsqrts(as_FloatRegister($dst$$reg), 12555 as_FloatRegister($src$$reg)); 12556 %} 12557 12558 ins_pipe(fp_div_d); 12559 %} 12560 12561 // ============================================================================ 12562 // Logical Instructions 12563 12564 // Integer Logical Instructions 12565 12566 // And Instructions 12567 12568 12569 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 12570 match(Set dst (AndI src1 src2)); 12571 12572 format %{ "andw $dst, $src1, $src2\t# int" %} 12573 12574 ins_cost(INSN_COST); 12575 ins_encode %{ 12576 __ andw(as_Register($dst$$reg), 12577 as_Register($src1$$reg), 12578 as_Register($src2$$reg)); 12579 %} 12580 12581 ins_pipe(ialu_reg_reg); 12582 %} 12583 12584 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 12585 match(Set dst (AndI src1 src2)); 12586 12587 format %{ "andsw $dst, $src1, $src2\t# int" %} 12588 12589 ins_cost(INSN_COST); 12590 ins_encode %{ 12591 __ andw(as_Register($dst$$reg), 12592 as_Register($src1$$reg), 12593 (unsigned long)($src2$$constant)); 12594 %} 12595 12596 ins_pipe(ialu_reg_imm); 12597 %} 12598 12599 // Or Instructions 12600 12601 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12602 match(Set dst (OrI src1 src2)); 12603 12604 format %{ "orrw $dst, $src1, $src2\t# int" %} 12605 12606 ins_cost(INSN_COST); 12607 ins_encode %{ 12608 __ orrw(as_Register($dst$$reg), 12609 as_Register($src1$$reg), 12610 as_Register($src2$$reg)); 12611 %} 12612 12613 ins_pipe(ialu_reg_reg); 12614 %} 12615 12616 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12617 match(Set dst (OrI src1 src2)); 12618 12619 format %{ "orrw $dst, $src1, $src2\t# int" %} 12620 12621 ins_cost(INSN_COST); 12622 ins_encode %{ 12623 __ orrw(as_Register($dst$$reg), 12624 as_Register($src1$$reg), 12625 (unsigned long)($src2$$constant)); 12626 %} 12627 12628 ins_pipe(ialu_reg_imm); 12629 %} 12630 12631 // Xor Instructions 12632 12633 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12634 match(Set dst (XorI src1 src2)); 12635 12636 format %{ "eorw $dst, $src1, $src2\t# int" %} 12637 12638 ins_cost(INSN_COST); 12639 ins_encode %{ 12640 __ eorw(as_Register($dst$$reg), 12641 as_Register($src1$$reg), 12642 as_Register($src2$$reg)); 12643 %} 12644 12645 ins_pipe(ialu_reg_reg); 12646 %} 12647 12648 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12649 match(Set dst (XorI src1 src2)); 12650 12651 format %{ "eorw $dst, $src1, $src2\t# int" %} 12652 12653 ins_cost(INSN_COST); 12654 ins_encode %{ 12655 __ eorw(as_Register($dst$$reg), 12656 as_Register($src1$$reg), 12657 (unsigned long)($src2$$constant)); 12658 %} 12659 12660 ins_pipe(ialu_reg_imm); 12661 %} 12662 12663 // Long Logical Instructions 12664 // TODO 12665 12666 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 12667 match(Set dst (AndL src1 src2)); 12668 12669 format %{ "and $dst, $src1, $src2\t# int" %} 12670 12671 ins_cost(INSN_COST); 12672 ins_encode %{ 12673 __ andr(as_Register($dst$$reg), 12674 as_Register($src1$$reg), 12675 as_Register($src2$$reg)); 12676 %} 12677 12678 ins_pipe(ialu_reg_reg); 12679 %} 12680 12681 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 12682 match(Set dst (AndL src1 src2)); 12683 12684 format %{ "and $dst, $src1, $src2\t# int" %} 12685 12686 ins_cost(INSN_COST); 12687 ins_encode %{ 12688 __ andr(as_Register($dst$$reg), 12689 as_Register($src1$$reg), 12690 (unsigned long)($src2$$constant)); 12691 %} 12692 12693 ins_pipe(ialu_reg_imm); 12694 %} 12695 12696 // Or Instructions 12697 12698 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12699 match(Set dst (OrL src1 src2)); 12700 12701 format %{ "orr $dst, $src1, $src2\t# int" %} 12702 12703 ins_cost(INSN_COST); 12704 ins_encode %{ 12705 __ orr(as_Register($dst$$reg), 12706 as_Register($src1$$reg), 12707 as_Register($src2$$reg)); 12708 %} 12709 12710 ins_pipe(ialu_reg_reg); 12711 %} 12712 12713 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12714 match(Set dst (OrL src1 src2)); 12715 12716 format %{ "orr $dst, $src1, $src2\t# int" %} 12717 12718 ins_cost(INSN_COST); 12719 ins_encode %{ 12720 __ orr(as_Register($dst$$reg), 12721 as_Register($src1$$reg), 12722 (unsigned long)($src2$$constant)); 12723 %} 12724 12725 ins_pipe(ialu_reg_imm); 12726 %} 12727 12728 // Xor Instructions 12729 12730 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12731 match(Set dst (XorL src1 src2)); 12732 12733 format %{ "eor $dst, $src1, $src2\t# int" %} 12734 12735 ins_cost(INSN_COST); 12736 ins_encode %{ 12737 __ eor(as_Register($dst$$reg), 12738 as_Register($src1$$reg), 12739 as_Register($src2$$reg)); 12740 %} 12741 12742 ins_pipe(ialu_reg_reg); 12743 %} 12744 12745 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12746 match(Set dst (XorL src1 src2)); 12747 12748 ins_cost(INSN_COST); 12749 format %{ "eor $dst, $src1, $src2\t# int" %} 12750 12751 ins_encode %{ 12752 __ eor(as_Register($dst$$reg), 12753 as_Register($src1$$reg), 12754 (unsigned long)($src2$$constant)); 12755 %} 12756 12757 ins_pipe(ialu_reg_imm); 12758 %} 12759 12760 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 12761 %{ 12762 match(Set dst (ConvI2L src)); 12763 12764 ins_cost(INSN_COST); 12765 format %{ "sxtw $dst, $src\t# i2l" %} 12766 ins_encode %{ 12767 __ sbfm($dst$$Register, $src$$Register, 0, 31); 12768 %} 12769 ins_pipe(ialu_reg_shift); 12770 %} 12771 12772 // this pattern occurs in bigmath arithmetic 12773 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 12774 %{ 12775 match(Set dst (AndL (ConvI2L src) mask)); 12776 12777 ins_cost(INSN_COST); 12778 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 12779 ins_encode %{ 12780 __ ubfm($dst$$Register, $src$$Register, 0, 31); 12781 %} 12782 12783 ins_pipe(ialu_reg_shift); 12784 %} 12785 12786 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 12787 match(Set dst (ConvL2I src)); 12788 12789 ins_cost(INSN_COST); 12790 format %{ "movw $dst, $src \t// l2i" %} 12791 12792 ins_encode %{ 12793 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 12794 %} 12795 12796 ins_pipe(ialu_reg); 12797 %} 12798 12799 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12800 %{ 12801 match(Set dst (Conv2B src)); 12802 effect(KILL cr); 12803 12804 format %{ 12805 "cmpw $src, zr\n\t" 12806 "cset $dst, ne" 12807 %} 12808 12809 ins_encode %{ 12810 __ cmpw(as_Register($src$$reg), zr); 12811 __ cset(as_Register($dst$$reg), Assembler::NE); 12812 %} 12813 12814 ins_pipe(ialu_reg); 12815 %} 12816 12817 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 12818 %{ 12819 match(Set dst (Conv2B src)); 12820 effect(KILL cr); 12821 12822 format %{ 12823 "cmp $src, zr\n\t" 12824 "cset $dst, ne" 12825 %} 12826 12827 ins_encode %{ 12828 __ cmp(as_Register($src$$reg), zr); 12829 __ cset(as_Register($dst$$reg), Assembler::NE); 12830 %} 12831 12832 ins_pipe(ialu_reg); 12833 %} 12834 12835 instruct convD2F_reg(vRegF dst, vRegD src) %{ 12836 match(Set dst (ConvD2F src)); 12837 12838 ins_cost(INSN_COST * 5); 12839 format %{ "fcvtd $dst, $src \t// d2f" %} 12840 12841 ins_encode %{ 12842 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12843 %} 12844 12845 ins_pipe(fp_d2f); 12846 %} 12847 12848 instruct convF2D_reg(vRegD dst, vRegF src) %{ 12849 match(Set dst (ConvF2D src)); 12850 12851 ins_cost(INSN_COST * 5); 12852 format %{ "fcvts $dst, $src \t// f2d" %} 12853 12854 ins_encode %{ 12855 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12856 %} 12857 12858 ins_pipe(fp_f2d); 12859 %} 12860 12861 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12862 match(Set dst (ConvF2I src)); 12863 12864 ins_cost(INSN_COST * 5); 12865 format %{ "fcvtzsw $dst, $src \t// f2i" %} 12866 12867 ins_encode %{ 12868 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12869 %} 12870 12871 ins_pipe(fp_f2i); 12872 %} 12873 12874 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 12875 match(Set dst (ConvF2L src)); 12876 12877 ins_cost(INSN_COST * 5); 12878 format %{ "fcvtzs $dst, $src \t// f2l" %} 12879 12880 ins_encode %{ 12881 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12882 %} 12883 12884 ins_pipe(fp_f2l); 12885 %} 12886 12887 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 12888 match(Set dst (ConvI2F src)); 12889 12890 ins_cost(INSN_COST * 5); 12891 format %{ "scvtfws $dst, $src \t// i2f" %} 12892 12893 ins_encode %{ 12894 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12895 %} 12896 12897 ins_pipe(fp_i2f); 12898 %} 12899 12900 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 12901 match(Set dst (ConvL2F src)); 12902 12903 ins_cost(INSN_COST * 5); 12904 format %{ "scvtfs $dst, $src \t// l2f" %} 12905 12906 ins_encode %{ 12907 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12908 %} 12909 12910 ins_pipe(fp_l2f); 12911 %} 12912 12913 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 12914 match(Set dst (ConvD2I src)); 12915 12916 ins_cost(INSN_COST * 5); 12917 format %{ "fcvtzdw $dst, $src \t// d2i" %} 12918 12919 ins_encode %{ 12920 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12921 %} 12922 12923 ins_pipe(fp_d2i); 12924 %} 12925 12926 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12927 match(Set dst (ConvD2L src)); 12928 12929 ins_cost(INSN_COST * 5); 12930 format %{ "fcvtzd $dst, $src \t// d2l" %} 12931 12932 ins_encode %{ 12933 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12934 %} 12935 12936 ins_pipe(fp_d2l); 12937 %} 12938 12939 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 12940 match(Set dst (ConvI2D src)); 12941 12942 ins_cost(INSN_COST * 5); 12943 format %{ "scvtfwd $dst, $src \t// i2d" %} 12944 12945 ins_encode %{ 12946 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12947 %} 12948 12949 ins_pipe(fp_i2d); 12950 %} 12951 12952 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 12953 match(Set dst (ConvL2D src)); 12954 12955 ins_cost(INSN_COST * 5); 12956 format %{ "scvtfd $dst, $src \t// l2d" %} 12957 12958 ins_encode %{ 12959 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12960 %} 12961 12962 ins_pipe(fp_l2d); 12963 %} 12964 12965 // stack <-> reg and reg <-> reg shuffles with no conversion 12966 12967 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 12968 12969 match(Set dst (MoveF2I src)); 12970 12971 effect(DEF dst, USE src); 12972 12973 ins_cost(4 * INSN_COST); 12974 12975 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 12976 12977 ins_encode %{ 12978 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 12979 %} 12980 12981 ins_pipe(iload_reg_reg); 12982 12983 %} 12984 12985 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 12986 12987 match(Set dst (MoveI2F src)); 12988 12989 effect(DEF dst, USE src); 12990 12991 ins_cost(4 * INSN_COST); 12992 12993 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 12994 12995 ins_encode %{ 12996 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12997 %} 12998 12999 ins_pipe(pipe_class_memory); 13000 13001 %} 13002 13003 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13004 13005 match(Set dst (MoveD2L src)); 13006 13007 effect(DEF dst, USE src); 13008 13009 ins_cost(4 * INSN_COST); 13010 13011 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13012 13013 ins_encode %{ 13014 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13015 %} 13016 13017 ins_pipe(iload_reg_reg); 13018 13019 %} 13020 13021 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13022 13023 match(Set dst (MoveL2D src)); 13024 13025 effect(DEF dst, USE src); 13026 13027 ins_cost(4 * INSN_COST); 13028 13029 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13030 13031 ins_encode %{ 13032 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13033 %} 13034 13035 ins_pipe(pipe_class_memory); 13036 13037 %} 13038 13039 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13040 13041 match(Set dst (MoveF2I src)); 13042 13043 effect(DEF dst, USE src); 13044 13045 ins_cost(INSN_COST); 13046 13047 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13048 13049 ins_encode %{ 13050 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13051 %} 13052 13053 ins_pipe(pipe_class_memory); 13054 13055 %} 13056 13057 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13058 13059 match(Set dst (MoveI2F src)); 13060 13061 effect(DEF dst, USE src); 13062 13063 ins_cost(INSN_COST); 13064 13065 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13066 13067 ins_encode %{ 13068 __ strw($src$$Register, Address(sp, $dst$$disp)); 13069 %} 13070 13071 ins_pipe(istore_reg_reg); 13072 13073 %} 13074 13075 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13076 13077 match(Set dst (MoveD2L src)); 13078 13079 effect(DEF dst, USE src); 13080 13081 ins_cost(INSN_COST); 13082 13083 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13084 13085 ins_encode %{ 13086 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13087 %} 13088 13089 ins_pipe(pipe_class_memory); 13090 13091 %} 13092 13093 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13094 13095 match(Set dst (MoveL2D src)); 13096 13097 effect(DEF dst, USE src); 13098 13099 ins_cost(INSN_COST); 13100 13101 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13102 13103 ins_encode %{ 13104 __ str($src$$Register, Address(sp, $dst$$disp)); 13105 %} 13106 13107 ins_pipe(istore_reg_reg); 13108 13109 %} 13110 13111 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13112 13113 match(Set dst (MoveF2I src)); 13114 13115 effect(DEF dst, USE src); 13116 13117 ins_cost(INSN_COST); 13118 13119 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13120 13121 ins_encode %{ 13122 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13123 %} 13124 13125 ins_pipe(fp_f2i); 13126 13127 %} 13128 13129 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13130 13131 match(Set dst (MoveI2F src)); 13132 13133 effect(DEF dst, USE src); 13134 13135 ins_cost(INSN_COST); 13136 13137 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13138 13139 ins_encode %{ 13140 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13141 %} 13142 13143 ins_pipe(fp_i2f); 13144 13145 %} 13146 13147 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13148 13149 match(Set dst (MoveD2L src)); 13150 13151 effect(DEF dst, USE src); 13152 13153 ins_cost(INSN_COST); 13154 13155 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13156 13157 ins_encode %{ 13158 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13159 %} 13160 13161 ins_pipe(fp_d2l); 13162 13163 %} 13164 13165 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13166 13167 match(Set dst (MoveL2D src)); 13168 13169 effect(DEF dst, USE src); 13170 13171 ins_cost(INSN_COST); 13172 13173 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13174 13175 ins_encode %{ 13176 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13177 %} 13178 13179 ins_pipe(fp_l2d); 13180 13181 %} 13182 13183 // ============================================================================ 13184 // clearing of an array 13185 13186 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13187 %{ 13188 match(Set dummy (ClearArray cnt base)); 13189 effect(USE_KILL cnt, USE_KILL base); 13190 13191 ins_cost(4 * INSN_COST); 13192 format %{ "ClearArray $cnt, $base" %} 13193 13194 ins_encode %{ 13195 __ zero_words($base$$Register, $cnt$$Register); 13196 %} 13197 13198 ins_pipe(pipe_class_memory); 13199 %} 13200 13201 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13202 %{ 13203 predicate((u_int64_t)n->in(2)->get_long() 13204 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13205 match(Set dummy (ClearArray cnt base)); 13206 effect(USE_KILL base); 13207 13208 ins_cost(4 * INSN_COST); 13209 format %{ "ClearArray $cnt, $base" %} 13210 13211 ins_encode %{ 13212 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13213 %} 13214 13215 ins_pipe(pipe_class_memory); 13216 %} 13217 13218 // ============================================================================ 13219 // Overflow Math Instructions 13220 13221 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13222 %{ 13223 match(Set cr (OverflowAddI op1 op2)); 13224 13225 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13226 ins_cost(INSN_COST); 13227 ins_encode %{ 13228 __ cmnw($op1$$Register, $op2$$Register); 13229 %} 13230 13231 ins_pipe(icmp_reg_reg); 13232 %} 13233 13234 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13235 %{ 13236 match(Set cr (OverflowAddI op1 op2)); 13237 13238 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13239 ins_cost(INSN_COST); 13240 ins_encode %{ 13241 __ cmnw($op1$$Register, $op2$$constant); 13242 %} 13243 13244 ins_pipe(icmp_reg_imm); 13245 %} 13246 13247 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13248 %{ 13249 match(Set cr (OverflowAddL op1 op2)); 13250 13251 format %{ "cmn $op1, $op2\t# overflow check long" %} 13252 ins_cost(INSN_COST); 13253 ins_encode %{ 13254 __ cmn($op1$$Register, $op2$$Register); 13255 %} 13256 13257 ins_pipe(icmp_reg_reg); 13258 %} 13259 13260 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13261 %{ 13262 match(Set cr (OverflowAddL op1 op2)); 13263 13264 format %{ "cmn $op1, $op2\t# overflow check long" %} 13265 ins_cost(INSN_COST); 13266 ins_encode %{ 13267 __ cmn($op1$$Register, $op2$$constant); 13268 %} 13269 13270 ins_pipe(icmp_reg_imm); 13271 %} 13272 13273 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13274 %{ 13275 match(Set cr (OverflowSubI op1 op2)); 13276 13277 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13278 ins_cost(INSN_COST); 13279 ins_encode %{ 13280 __ cmpw($op1$$Register, $op2$$Register); 13281 %} 13282 13283 ins_pipe(icmp_reg_reg); 13284 %} 13285 13286 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13287 %{ 13288 match(Set cr (OverflowSubI op1 op2)); 13289 13290 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13291 ins_cost(INSN_COST); 13292 ins_encode %{ 13293 __ cmpw($op1$$Register, $op2$$constant); 13294 %} 13295 13296 ins_pipe(icmp_reg_imm); 13297 %} 13298 13299 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13300 %{ 13301 match(Set cr (OverflowSubL op1 op2)); 13302 13303 format %{ "cmp $op1, $op2\t# overflow check long" %} 13304 ins_cost(INSN_COST); 13305 ins_encode %{ 13306 __ cmp($op1$$Register, $op2$$Register); 13307 %} 13308 13309 ins_pipe(icmp_reg_reg); 13310 %} 13311 13312 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13313 %{ 13314 match(Set cr (OverflowSubL op1 op2)); 13315 13316 format %{ "cmp $op1, $op2\t# overflow check long" %} 13317 ins_cost(INSN_COST); 13318 ins_encode %{ 13319 __ cmp($op1$$Register, $op2$$constant); 13320 %} 13321 13322 ins_pipe(icmp_reg_imm); 13323 %} 13324 13325 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13326 %{ 13327 match(Set cr (OverflowSubI zero op1)); 13328 13329 format %{ "cmpw zr, $op1\t# overflow check int" %} 13330 ins_cost(INSN_COST); 13331 ins_encode %{ 13332 __ cmpw(zr, $op1$$Register); 13333 %} 13334 13335 ins_pipe(icmp_reg_imm); 13336 %} 13337 13338 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13339 %{ 13340 match(Set cr (OverflowSubL zero op1)); 13341 13342 format %{ "cmp zr, $op1\t# overflow check long" %} 13343 ins_cost(INSN_COST); 13344 ins_encode %{ 13345 __ cmp(zr, $op1$$Register); 13346 %} 13347 13348 ins_pipe(icmp_reg_imm); 13349 %} 13350 13351 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13352 %{ 13353 match(Set cr (OverflowMulI op1 op2)); 13354 13355 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13356 "cmp rscratch1, rscratch1, sxtw\n\t" 13357 "movw rscratch1, #0x80000000\n\t" 13358 "cselw rscratch1, rscratch1, zr, NE\n\t" 13359 "cmpw rscratch1, #1" %} 13360 ins_cost(5 * INSN_COST); 13361 ins_encode %{ 13362 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13363 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13364 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13365 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13366 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13367 %} 13368 13369 ins_pipe(pipe_slow); 13370 %} 13371 13372 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13373 %{ 13374 match(If cmp (OverflowMulI op1 op2)); 13375 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13376 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13377 effect(USE labl, KILL cr); 13378 13379 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13380 "cmp rscratch1, rscratch1, sxtw\n\t" 13381 "b$cmp $labl" %} 13382 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13383 ins_encode %{ 13384 Label* L = $labl$$label; 13385 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13386 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13387 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13388 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13389 %} 13390 13391 ins_pipe(pipe_serial); 13392 %} 13393 13394 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13395 %{ 13396 match(Set cr (OverflowMulL op1 op2)); 13397 13398 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13399 "smulh rscratch2, $op1, $op2\n\t" 13400 "cmp rscratch2, rscratch1, ASR #63\n\t" 13401 "movw rscratch1, #0x80000000\n\t" 13402 "cselw rscratch1, rscratch1, zr, NE\n\t" 13403 "cmpw rscratch1, #1" %} 13404 ins_cost(6 * INSN_COST); 13405 ins_encode %{ 13406 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13407 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13408 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13409 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13410 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13411 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13412 %} 13413 13414 ins_pipe(pipe_slow); 13415 %} 13416 13417 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13418 %{ 13419 match(If cmp (OverflowMulL op1 op2)); 13420 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13421 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13422 effect(USE labl, KILL cr); 13423 13424 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13425 "smulh rscratch2, $op1, $op2\n\t" 13426 "cmp rscratch2, rscratch1, ASR #63\n\t" 13427 "b$cmp $labl" %} 13428 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13429 ins_encode %{ 13430 Label* L = $labl$$label; 13431 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13432 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13433 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13434 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13435 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13436 %} 13437 13438 ins_pipe(pipe_serial); 13439 %} 13440 13441 // ============================================================================ 13442 // Compare Instructions 13443 13444 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13445 %{ 13446 match(Set cr (CmpI op1 op2)); 13447 13448 effect(DEF cr, USE op1, USE op2); 13449 13450 ins_cost(INSN_COST); 13451 format %{ "cmpw $op1, $op2" %} 13452 13453 ins_encode(aarch64_enc_cmpw(op1, op2)); 13454 13455 ins_pipe(icmp_reg_reg); 13456 %} 13457 13458 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13459 %{ 13460 match(Set cr (CmpI op1 zero)); 13461 13462 effect(DEF cr, USE op1); 13463 13464 ins_cost(INSN_COST); 13465 format %{ "cmpw $op1, 0" %} 13466 13467 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13468 13469 ins_pipe(icmp_reg_imm); 13470 %} 13471 13472 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13473 %{ 13474 match(Set cr (CmpI op1 op2)); 13475 13476 effect(DEF cr, USE op1); 13477 13478 ins_cost(INSN_COST); 13479 format %{ "cmpw $op1, $op2" %} 13480 13481 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13482 13483 ins_pipe(icmp_reg_imm); 13484 %} 13485 13486 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 13487 %{ 13488 match(Set cr (CmpI op1 op2)); 13489 13490 effect(DEF cr, USE op1); 13491 13492 ins_cost(INSN_COST * 2); 13493 format %{ "cmpw $op1, $op2" %} 13494 13495 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13496 13497 ins_pipe(icmp_reg_imm); 13498 %} 13499 13500 // Unsigned compare Instructions; really, same as signed compare 13501 // except it should only be used to feed an If or a CMovI which takes a 13502 // cmpOpU. 13503 13504 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 13505 %{ 13506 match(Set cr (CmpU op1 op2)); 13507 13508 effect(DEF cr, USE op1, USE op2); 13509 13510 ins_cost(INSN_COST); 13511 format %{ "cmpw $op1, $op2\t# unsigned" %} 13512 13513 ins_encode(aarch64_enc_cmpw(op1, op2)); 13514 13515 ins_pipe(icmp_reg_reg); 13516 %} 13517 13518 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 13519 %{ 13520 match(Set cr (CmpU op1 zero)); 13521 13522 effect(DEF cr, USE op1); 13523 13524 ins_cost(INSN_COST); 13525 format %{ "cmpw $op1, #0\t# unsigned" %} 13526 13527 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13528 13529 ins_pipe(icmp_reg_imm); 13530 %} 13531 13532 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 13533 %{ 13534 match(Set cr (CmpU op1 op2)); 13535 13536 effect(DEF cr, USE op1); 13537 13538 ins_cost(INSN_COST); 13539 format %{ "cmpw $op1, $op2\t# unsigned" %} 13540 13541 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13542 13543 ins_pipe(icmp_reg_imm); 13544 %} 13545 13546 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 13547 %{ 13548 match(Set cr (CmpU op1 op2)); 13549 13550 effect(DEF cr, USE op1); 13551 13552 ins_cost(INSN_COST * 2); 13553 format %{ "cmpw $op1, $op2\t# unsigned" %} 13554 13555 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13556 13557 ins_pipe(icmp_reg_imm); 13558 %} 13559 13560 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13561 %{ 13562 match(Set cr (CmpL op1 op2)); 13563 13564 effect(DEF cr, USE op1, USE op2); 13565 13566 ins_cost(INSN_COST); 13567 format %{ "cmp $op1, $op2" %} 13568 13569 ins_encode(aarch64_enc_cmp(op1, op2)); 13570 13571 ins_pipe(icmp_reg_reg); 13572 %} 13573 13574 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 13575 %{ 13576 match(Set cr (CmpL op1 zero)); 13577 13578 effect(DEF cr, USE op1); 13579 13580 ins_cost(INSN_COST); 13581 format %{ "tst $op1" %} 13582 13583 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13584 13585 ins_pipe(icmp_reg_imm); 13586 %} 13587 13588 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 13589 %{ 13590 match(Set cr (CmpL op1 op2)); 13591 13592 effect(DEF cr, USE op1); 13593 13594 ins_cost(INSN_COST); 13595 format %{ "cmp $op1, $op2" %} 13596 13597 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13598 13599 ins_pipe(icmp_reg_imm); 13600 %} 13601 13602 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 13603 %{ 13604 match(Set cr (CmpL op1 op2)); 13605 13606 effect(DEF cr, USE op1); 13607 13608 ins_cost(INSN_COST * 2); 13609 format %{ "cmp $op1, $op2" %} 13610 13611 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13612 13613 ins_pipe(icmp_reg_imm); 13614 %} 13615 13616 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 13617 %{ 13618 match(Set cr (CmpUL op1 op2)); 13619 13620 effect(DEF cr, USE op1, USE op2); 13621 13622 ins_cost(INSN_COST); 13623 format %{ "cmp $op1, $op2" %} 13624 13625 ins_encode(aarch64_enc_cmp(op1, op2)); 13626 13627 ins_pipe(icmp_reg_reg); 13628 %} 13629 13630 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 13631 %{ 13632 match(Set cr (CmpUL op1 zero)); 13633 13634 effect(DEF cr, USE op1); 13635 13636 ins_cost(INSN_COST); 13637 format %{ "tst $op1" %} 13638 13639 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13640 13641 ins_pipe(icmp_reg_imm); 13642 %} 13643 13644 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 13645 %{ 13646 match(Set cr (CmpUL op1 op2)); 13647 13648 effect(DEF cr, USE op1); 13649 13650 ins_cost(INSN_COST); 13651 format %{ "cmp $op1, $op2" %} 13652 13653 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13654 13655 ins_pipe(icmp_reg_imm); 13656 %} 13657 13658 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 13659 %{ 13660 match(Set cr (CmpUL op1 op2)); 13661 13662 effect(DEF cr, USE op1); 13663 13664 ins_cost(INSN_COST * 2); 13665 format %{ "cmp $op1, $op2" %} 13666 13667 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13668 13669 ins_pipe(icmp_reg_imm); 13670 %} 13671 13672 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 13673 %{ 13674 match(Set cr (CmpP op1 op2)); 13675 13676 effect(DEF cr, USE op1, USE op2); 13677 13678 ins_cost(INSN_COST); 13679 format %{ "cmp $op1, $op2\t // ptr" %} 13680 13681 ins_encode(aarch64_enc_cmpp(op1, op2)); 13682 13683 ins_pipe(icmp_reg_reg); 13684 %} 13685 13686 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 13687 %{ 13688 match(Set cr (CmpN op1 op2)); 13689 13690 effect(DEF cr, USE op1, USE op2); 13691 13692 ins_cost(INSN_COST); 13693 format %{ "cmp $op1, $op2\t // compressed ptr" %} 13694 13695 ins_encode(aarch64_enc_cmpn(op1, op2)); 13696 13697 ins_pipe(icmp_reg_reg); 13698 %} 13699 13700 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 13701 %{ 13702 match(Set cr (CmpP op1 zero)); 13703 13704 effect(DEF cr, USE op1, USE zero); 13705 13706 ins_cost(INSN_COST); 13707 format %{ "cmp $op1, 0\t // ptr" %} 13708 13709 ins_encode(aarch64_enc_testp(op1)); 13710 13711 ins_pipe(icmp_reg_imm); 13712 %} 13713 13714 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 13715 %{ 13716 match(Set cr (CmpN op1 zero)); 13717 13718 effect(DEF cr, USE op1, USE zero); 13719 13720 ins_cost(INSN_COST); 13721 format %{ "cmp $op1, 0\t // compressed ptr" %} 13722 13723 ins_encode(aarch64_enc_testn(op1)); 13724 13725 ins_pipe(icmp_reg_imm); 13726 %} 13727 13728 // FP comparisons 13729 // 13730 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 13731 // using normal cmpOp. See declaration of rFlagsReg for details. 13732 13733 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 13734 %{ 13735 match(Set cr (CmpF src1 src2)); 13736 13737 ins_cost(3 * INSN_COST); 13738 format %{ "fcmps $src1, $src2" %} 13739 13740 ins_encode %{ 13741 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13742 %} 13743 13744 ins_pipe(pipe_class_compare); 13745 %} 13746 13747 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 13748 %{ 13749 match(Set cr (CmpF src1 src2)); 13750 13751 ins_cost(3 * INSN_COST); 13752 format %{ "fcmps $src1, 0.0" %} 13753 13754 ins_encode %{ 13755 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 13756 %} 13757 13758 ins_pipe(pipe_class_compare); 13759 %} 13760 // FROM HERE 13761 13762 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 13763 %{ 13764 match(Set cr (CmpD src1 src2)); 13765 13766 ins_cost(3 * INSN_COST); 13767 format %{ "fcmpd $src1, $src2" %} 13768 13769 ins_encode %{ 13770 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13771 %} 13772 13773 ins_pipe(pipe_class_compare); 13774 %} 13775 13776 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 13777 %{ 13778 match(Set cr (CmpD src1 src2)); 13779 13780 ins_cost(3 * INSN_COST); 13781 format %{ "fcmpd $src1, 0.0" %} 13782 13783 ins_encode %{ 13784 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 13785 %} 13786 13787 ins_pipe(pipe_class_compare); 13788 %} 13789 13790 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 13791 %{ 13792 match(Set dst (CmpF3 src1 src2)); 13793 effect(KILL cr); 13794 13795 ins_cost(5 * INSN_COST); 13796 format %{ "fcmps $src1, $src2\n\t" 13797 "csinvw($dst, zr, zr, eq\n\t" 13798 "csnegw($dst, $dst, $dst, lt)" 13799 %} 13800 13801 ins_encode %{ 13802 Label done; 13803 FloatRegister s1 = as_FloatRegister($src1$$reg); 13804 FloatRegister s2 = as_FloatRegister($src2$$reg); 13805 Register d = as_Register($dst$$reg); 13806 __ fcmps(s1, s2); 13807 // installs 0 if EQ else -1 13808 __ csinvw(d, zr, zr, Assembler::EQ); 13809 // keeps -1 if less or unordered else installs 1 13810 __ csnegw(d, d, d, Assembler::LT); 13811 __ bind(done); 13812 %} 13813 13814 ins_pipe(pipe_class_default); 13815 13816 %} 13817 13818 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 13819 %{ 13820 match(Set dst (CmpD3 src1 src2)); 13821 effect(KILL cr); 13822 13823 ins_cost(5 * INSN_COST); 13824 format %{ "fcmpd $src1, $src2\n\t" 13825 "csinvw($dst, zr, zr, eq\n\t" 13826 "csnegw($dst, $dst, $dst, lt)" 13827 %} 13828 13829 ins_encode %{ 13830 Label done; 13831 FloatRegister s1 = as_FloatRegister($src1$$reg); 13832 FloatRegister s2 = as_FloatRegister($src2$$reg); 13833 Register d = as_Register($dst$$reg); 13834 __ fcmpd(s1, s2); 13835 // installs 0 if EQ else -1 13836 __ csinvw(d, zr, zr, Assembler::EQ); 13837 // keeps -1 if less or unordered else installs 1 13838 __ csnegw(d, d, d, Assembler::LT); 13839 __ bind(done); 13840 %} 13841 ins_pipe(pipe_class_default); 13842 13843 %} 13844 13845 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 13846 %{ 13847 match(Set dst (CmpF3 src1 zero)); 13848 effect(KILL cr); 13849 13850 ins_cost(5 * INSN_COST); 13851 format %{ "fcmps $src1, 0.0\n\t" 13852 "csinvw($dst, zr, zr, eq\n\t" 13853 "csnegw($dst, $dst, $dst, lt)" 13854 %} 13855 13856 ins_encode %{ 13857 Label done; 13858 FloatRegister s1 = as_FloatRegister($src1$$reg); 13859 Register d = as_Register($dst$$reg); 13860 __ fcmps(s1, 0.0D); 13861 // installs 0 if EQ else -1 13862 __ csinvw(d, zr, zr, Assembler::EQ); 13863 // keeps -1 if less or unordered else installs 1 13864 __ csnegw(d, d, d, Assembler::LT); 13865 __ bind(done); 13866 %} 13867 13868 ins_pipe(pipe_class_default); 13869 13870 %} 13871 13872 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 13873 %{ 13874 match(Set dst (CmpD3 src1 zero)); 13875 effect(KILL cr); 13876 13877 ins_cost(5 * INSN_COST); 13878 format %{ "fcmpd $src1, 0.0\n\t" 13879 "csinvw($dst, zr, zr, eq\n\t" 13880 "csnegw($dst, $dst, $dst, lt)" 13881 %} 13882 13883 ins_encode %{ 13884 Label done; 13885 FloatRegister s1 = as_FloatRegister($src1$$reg); 13886 Register d = as_Register($dst$$reg); 13887 __ fcmpd(s1, 0.0D); 13888 // installs 0 if EQ else -1 13889 __ csinvw(d, zr, zr, Assembler::EQ); 13890 // keeps -1 if less or unordered else installs 1 13891 __ csnegw(d, d, d, Assembler::LT); 13892 __ bind(done); 13893 %} 13894 ins_pipe(pipe_class_default); 13895 13896 %} 13897 13898 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 13899 %{ 13900 match(Set dst (CmpLTMask p q)); 13901 effect(KILL cr); 13902 13903 ins_cost(3 * INSN_COST); 13904 13905 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 13906 "csetw $dst, lt\n\t" 13907 "subw $dst, zr, $dst" 13908 %} 13909 13910 ins_encode %{ 13911 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 13912 __ csetw(as_Register($dst$$reg), Assembler::LT); 13913 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 13914 %} 13915 13916 ins_pipe(ialu_reg_reg); 13917 %} 13918 13919 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 13920 %{ 13921 match(Set dst (CmpLTMask src zero)); 13922 effect(KILL cr); 13923 13924 ins_cost(INSN_COST); 13925 13926 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 13927 13928 ins_encode %{ 13929 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 13930 %} 13931 13932 ins_pipe(ialu_reg_shift); 13933 %} 13934 13935 // ============================================================================ 13936 // Max and Min 13937 13938 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13939 %{ 13940 match(Set dst (MinI src1 src2)); 13941 13942 effect(DEF dst, USE src1, USE src2, KILL cr); 13943 size(8); 13944 13945 ins_cost(INSN_COST * 3); 13946 format %{ 13947 "cmpw $src1 $src2\t signed int\n\t" 13948 "cselw $dst, $src1, $src2 lt\t" 13949 %} 13950 13951 ins_encode %{ 13952 __ cmpw(as_Register($src1$$reg), 13953 as_Register($src2$$reg)); 13954 __ cselw(as_Register($dst$$reg), 13955 as_Register($src1$$reg), 13956 as_Register($src2$$reg), 13957 Assembler::LT); 13958 %} 13959 13960 ins_pipe(ialu_reg_reg); 13961 %} 13962 // FROM HERE 13963 13964 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13965 %{ 13966 match(Set dst (MaxI src1 src2)); 13967 13968 effect(DEF dst, USE src1, USE src2, KILL cr); 13969 size(8); 13970 13971 ins_cost(INSN_COST * 3); 13972 format %{ 13973 "cmpw $src1 $src2\t signed int\n\t" 13974 "cselw $dst, $src1, $src2 gt\t" 13975 %} 13976 13977 ins_encode %{ 13978 __ cmpw(as_Register($src1$$reg), 13979 as_Register($src2$$reg)); 13980 __ cselw(as_Register($dst$$reg), 13981 as_Register($src1$$reg), 13982 as_Register($src2$$reg), 13983 Assembler::GT); 13984 %} 13985 13986 ins_pipe(ialu_reg_reg); 13987 %} 13988 13989 // ============================================================================ 13990 // Branch Instructions 13991 13992 // Direct Branch. 13993 instruct branch(label lbl) 13994 %{ 13995 match(Goto); 13996 13997 effect(USE lbl); 13998 13999 ins_cost(BRANCH_COST); 14000 format %{ "b $lbl" %} 14001 14002 ins_encode(aarch64_enc_b(lbl)); 14003 14004 ins_pipe(pipe_branch); 14005 %} 14006 14007 // Conditional Near Branch 14008 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14009 %{ 14010 // Same match rule as `branchConFar'. 14011 match(If cmp cr); 14012 14013 effect(USE lbl); 14014 14015 ins_cost(BRANCH_COST); 14016 // If set to 1 this indicates that the current instruction is a 14017 // short variant of a long branch. This avoids using this 14018 // instruction in first-pass matching. It will then only be used in 14019 // the `Shorten_branches' pass. 14020 // ins_short_branch(1); 14021 format %{ "b$cmp $lbl" %} 14022 14023 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14024 14025 ins_pipe(pipe_branch_cond); 14026 %} 14027 14028 // Conditional Near Branch Unsigned 14029 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14030 %{ 14031 // Same match rule as `branchConFar'. 14032 match(If cmp cr); 14033 14034 effect(USE lbl); 14035 14036 ins_cost(BRANCH_COST); 14037 // If set to 1 this indicates that the current instruction is a 14038 // short variant of a long branch. This avoids using this 14039 // instruction in first-pass matching. It will then only be used in 14040 // the `Shorten_branches' pass. 14041 // ins_short_branch(1); 14042 format %{ "b$cmp $lbl\t# unsigned" %} 14043 14044 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14045 14046 ins_pipe(pipe_branch_cond); 14047 %} 14048 14049 // Make use of CBZ and CBNZ. These instructions, as well as being 14050 // shorter than (cmp; branch), have the additional benefit of not 14051 // killing the flags. 14052 14053 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14054 match(If cmp (CmpI op1 op2)); 14055 effect(USE labl); 14056 14057 ins_cost(BRANCH_COST); 14058 format %{ "cbw$cmp $op1, $labl" %} 14059 ins_encode %{ 14060 Label* L = $labl$$label; 14061 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14062 if (cond == Assembler::EQ) 14063 __ cbzw($op1$$Register, *L); 14064 else 14065 __ cbnzw($op1$$Register, *L); 14066 %} 14067 ins_pipe(pipe_cmp_branch); 14068 %} 14069 14070 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14071 match(If cmp (CmpL op1 op2)); 14072 effect(USE labl); 14073 14074 ins_cost(BRANCH_COST); 14075 format %{ "cb$cmp $op1, $labl" %} 14076 ins_encode %{ 14077 Label* L = $labl$$label; 14078 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14079 if (cond == Assembler::EQ) 14080 __ cbz($op1$$Register, *L); 14081 else 14082 __ cbnz($op1$$Register, *L); 14083 %} 14084 ins_pipe(pipe_cmp_branch); 14085 %} 14086 14087 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14088 match(If cmp (CmpP op1 op2)); 14089 effect(USE labl); 14090 14091 ins_cost(BRANCH_COST); 14092 format %{ "cb$cmp $op1, $labl" %} 14093 ins_encode %{ 14094 Label* L = $labl$$label; 14095 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14096 if (cond == Assembler::EQ) 14097 __ cbz($op1$$Register, *L); 14098 else 14099 __ cbnz($op1$$Register, *L); 14100 %} 14101 ins_pipe(pipe_cmp_branch); 14102 %} 14103 14104 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14105 match(If cmp (CmpN op1 op2)); 14106 effect(USE labl); 14107 14108 ins_cost(BRANCH_COST); 14109 format %{ "cbw$cmp $op1, $labl" %} 14110 ins_encode %{ 14111 Label* L = $labl$$label; 14112 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14113 if (cond == Assembler::EQ) 14114 __ cbzw($op1$$Register, *L); 14115 else 14116 __ cbnzw($op1$$Register, *L); 14117 %} 14118 ins_pipe(pipe_cmp_branch); 14119 %} 14120 14121 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14122 match(If cmp (CmpP (DecodeN oop) zero)); 14123 effect(USE labl); 14124 14125 ins_cost(BRANCH_COST); 14126 format %{ "cb$cmp $oop, $labl" %} 14127 ins_encode %{ 14128 Label* L = $labl$$label; 14129 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14130 if (cond == Assembler::EQ) 14131 __ cbzw($oop$$Register, *L); 14132 else 14133 __ cbnzw($oop$$Register, *L); 14134 %} 14135 ins_pipe(pipe_cmp_branch); 14136 %} 14137 14138 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14139 match(If cmp (CmpU op1 op2)); 14140 effect(USE labl); 14141 14142 ins_cost(BRANCH_COST); 14143 format %{ "cbw$cmp $op1, $labl" %} 14144 ins_encode %{ 14145 Label* L = $labl$$label; 14146 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14147 if (cond == Assembler::EQ || cond == Assembler::LS) 14148 __ cbzw($op1$$Register, *L); 14149 else 14150 __ cbnzw($op1$$Register, *L); 14151 %} 14152 ins_pipe(pipe_cmp_branch); 14153 %} 14154 14155 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14156 match(If cmp (CmpUL op1 op2)); 14157 effect(USE labl); 14158 14159 ins_cost(BRANCH_COST); 14160 format %{ "cb$cmp $op1, $labl" %} 14161 ins_encode %{ 14162 Label* L = $labl$$label; 14163 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14164 if (cond == Assembler::EQ || cond == Assembler::LS) 14165 __ cbz($op1$$Register, *L); 14166 else 14167 __ cbnz($op1$$Register, *L); 14168 %} 14169 ins_pipe(pipe_cmp_branch); 14170 %} 14171 14172 // Test bit and Branch 14173 14174 // Patterns for short (< 32KiB) variants 14175 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14176 match(If cmp (CmpL op1 op2)); 14177 effect(USE labl); 14178 14179 ins_cost(BRANCH_COST); 14180 format %{ "cb$cmp $op1, $labl # long" %} 14181 ins_encode %{ 14182 Label* L = $labl$$label; 14183 Assembler::Condition cond = 14184 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14185 __ tbr(cond, $op1$$Register, 63, *L); 14186 %} 14187 ins_pipe(pipe_cmp_branch); 14188 ins_short_branch(1); 14189 %} 14190 14191 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14192 match(If cmp (CmpI op1 op2)); 14193 effect(USE labl); 14194 14195 ins_cost(BRANCH_COST); 14196 format %{ "cb$cmp $op1, $labl # int" %} 14197 ins_encode %{ 14198 Label* L = $labl$$label; 14199 Assembler::Condition cond = 14200 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14201 __ tbr(cond, $op1$$Register, 31, *L); 14202 %} 14203 ins_pipe(pipe_cmp_branch); 14204 ins_short_branch(1); 14205 %} 14206 14207 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14208 match(If cmp (CmpL (AndL op1 op2) op3)); 14209 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14210 effect(USE labl); 14211 14212 ins_cost(BRANCH_COST); 14213 format %{ "tb$cmp $op1, $op2, $labl" %} 14214 ins_encode %{ 14215 Label* L = $labl$$label; 14216 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14217 int bit = exact_log2($op2$$constant); 14218 __ tbr(cond, $op1$$Register, bit, *L); 14219 %} 14220 ins_pipe(pipe_cmp_branch); 14221 ins_short_branch(1); 14222 %} 14223 14224 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14225 match(If cmp (CmpI (AndI op1 op2) op3)); 14226 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14227 effect(USE labl); 14228 14229 ins_cost(BRANCH_COST); 14230 format %{ "tb$cmp $op1, $op2, $labl" %} 14231 ins_encode %{ 14232 Label* L = $labl$$label; 14233 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14234 int bit = exact_log2($op2$$constant); 14235 __ tbr(cond, $op1$$Register, bit, *L); 14236 %} 14237 ins_pipe(pipe_cmp_branch); 14238 ins_short_branch(1); 14239 %} 14240 14241 // And far variants 14242 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14243 match(If cmp (CmpL op1 op2)); 14244 effect(USE labl); 14245 14246 ins_cost(BRANCH_COST); 14247 format %{ "cb$cmp $op1, $labl # long" %} 14248 ins_encode %{ 14249 Label* L = $labl$$label; 14250 Assembler::Condition cond = 14251 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14252 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14253 %} 14254 ins_pipe(pipe_cmp_branch); 14255 %} 14256 14257 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14258 match(If cmp (CmpI op1 op2)); 14259 effect(USE labl); 14260 14261 ins_cost(BRANCH_COST); 14262 format %{ "cb$cmp $op1, $labl # int" %} 14263 ins_encode %{ 14264 Label* L = $labl$$label; 14265 Assembler::Condition cond = 14266 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14267 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14268 %} 14269 ins_pipe(pipe_cmp_branch); 14270 %} 14271 14272 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14273 match(If cmp (CmpL (AndL op1 op2) op3)); 14274 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14275 effect(USE labl); 14276 14277 ins_cost(BRANCH_COST); 14278 format %{ "tb$cmp $op1, $op2, $labl" %} 14279 ins_encode %{ 14280 Label* L = $labl$$label; 14281 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14282 int bit = exact_log2($op2$$constant); 14283 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14284 %} 14285 ins_pipe(pipe_cmp_branch); 14286 %} 14287 14288 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14289 match(If cmp (CmpI (AndI op1 op2) op3)); 14290 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14291 effect(USE labl); 14292 14293 ins_cost(BRANCH_COST); 14294 format %{ "tb$cmp $op1, $op2, $labl" %} 14295 ins_encode %{ 14296 Label* L = $labl$$label; 14297 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14298 int bit = exact_log2($op2$$constant); 14299 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14300 %} 14301 ins_pipe(pipe_cmp_branch); 14302 %} 14303 14304 // Test bits 14305 14306 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14307 match(Set cr (CmpL (AndL op1 op2) op3)); 14308 predicate(Assembler::operand_valid_for_logical_immediate 14309 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14310 14311 ins_cost(INSN_COST); 14312 format %{ "tst $op1, $op2 # long" %} 14313 ins_encode %{ 14314 __ tst($op1$$Register, $op2$$constant); 14315 %} 14316 ins_pipe(ialu_reg_reg); 14317 %} 14318 14319 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14320 match(Set cr (CmpI (AndI op1 op2) op3)); 14321 predicate(Assembler::operand_valid_for_logical_immediate 14322 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14323 14324 ins_cost(INSN_COST); 14325 format %{ "tst $op1, $op2 # int" %} 14326 ins_encode %{ 14327 __ tstw($op1$$Register, $op2$$constant); 14328 %} 14329 ins_pipe(ialu_reg_reg); 14330 %} 14331 14332 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14333 match(Set cr (CmpL (AndL op1 op2) op3)); 14334 14335 ins_cost(INSN_COST); 14336 format %{ "tst $op1, $op2 # long" %} 14337 ins_encode %{ 14338 __ tst($op1$$Register, $op2$$Register); 14339 %} 14340 ins_pipe(ialu_reg_reg); 14341 %} 14342 14343 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14344 match(Set cr (CmpI (AndI op1 op2) op3)); 14345 14346 ins_cost(INSN_COST); 14347 format %{ "tstw $op1, $op2 # int" %} 14348 ins_encode %{ 14349 __ tstw($op1$$Register, $op2$$Register); 14350 %} 14351 ins_pipe(ialu_reg_reg); 14352 %} 14353 14354 14355 // Conditional Far Branch 14356 // Conditional Far Branch Unsigned 14357 // TODO: fixme 14358 14359 // counted loop end branch near 14360 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14361 %{ 14362 match(CountedLoopEnd cmp cr); 14363 14364 effect(USE lbl); 14365 14366 ins_cost(BRANCH_COST); 14367 // short variant. 14368 // ins_short_branch(1); 14369 format %{ "b$cmp $lbl \t// counted loop end" %} 14370 14371 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14372 14373 ins_pipe(pipe_branch); 14374 %} 14375 14376 // counted loop end branch near Unsigned 14377 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14378 %{ 14379 match(CountedLoopEnd cmp cr); 14380 14381 effect(USE lbl); 14382 14383 ins_cost(BRANCH_COST); 14384 // short variant. 14385 // ins_short_branch(1); 14386 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14387 14388 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14389 14390 ins_pipe(pipe_branch); 14391 %} 14392 14393 // counted loop end branch far 14394 // counted loop end branch far unsigned 14395 // TODO: fixme 14396 14397 // ============================================================================ 14398 // inlined locking and unlocking 14399 14400 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14401 %{ 14402 match(Set cr (FastLock object box)); 14403 effect(TEMP tmp, TEMP tmp2); 14404 14405 // TODO 14406 // identify correct cost 14407 ins_cost(5 * INSN_COST); 14408 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14409 14410 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14411 14412 ins_pipe(pipe_serial); 14413 %} 14414 14415 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14416 %{ 14417 match(Set cr (FastUnlock object box)); 14418 effect(TEMP tmp, TEMP tmp2); 14419 14420 ins_cost(5 * INSN_COST); 14421 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14422 14423 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14424 14425 ins_pipe(pipe_serial); 14426 %} 14427 14428 14429 // ============================================================================ 14430 // Safepoint Instructions 14431 14432 // TODO 14433 // provide a near and far version of this code 14434 14435 instruct safePoint(rFlagsReg cr, iRegP poll) 14436 %{ 14437 match(SafePoint poll); 14438 effect(KILL cr); 14439 14440 format %{ 14441 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14442 %} 14443 ins_encode %{ 14444 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14445 %} 14446 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14447 %} 14448 14449 14450 // ============================================================================ 14451 // Procedure Call/Return Instructions 14452 14453 // Call Java Static Instruction 14454 14455 instruct CallStaticJavaDirect(method meth) 14456 %{ 14457 match(CallStaticJava); 14458 14459 effect(USE meth); 14460 14461 ins_cost(CALL_COST); 14462 14463 format %{ "call,static $meth \t// ==> " %} 14464 14465 ins_encode( aarch64_enc_java_static_call(meth), 14466 aarch64_enc_call_epilog ); 14467 14468 ins_pipe(pipe_class_call); 14469 %} 14470 14471 // TO HERE 14472 14473 // Call Java Dynamic Instruction 14474 instruct CallDynamicJavaDirect(method meth) 14475 %{ 14476 match(CallDynamicJava); 14477 14478 effect(USE meth); 14479 14480 ins_cost(CALL_COST); 14481 14482 format %{ "CALL,dynamic $meth \t// ==> " %} 14483 14484 ins_encode( aarch64_enc_java_dynamic_call(meth), 14485 aarch64_enc_call_epilog ); 14486 14487 ins_pipe(pipe_class_call); 14488 %} 14489 14490 // Call Runtime Instruction 14491 14492 instruct CallRuntimeDirect(method meth) 14493 %{ 14494 match(CallRuntime); 14495 14496 effect(USE meth); 14497 14498 ins_cost(CALL_COST); 14499 14500 format %{ "CALL, runtime $meth" %} 14501 14502 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14503 14504 ins_pipe(pipe_class_call); 14505 %} 14506 14507 // Call Runtime Instruction 14508 14509 instruct CallLeafDirect(method meth) 14510 %{ 14511 match(CallLeaf); 14512 14513 effect(USE meth); 14514 14515 ins_cost(CALL_COST); 14516 14517 format %{ "CALL, runtime leaf $meth" %} 14518 14519 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14520 14521 ins_pipe(pipe_class_call); 14522 %} 14523 14524 // Call Runtime Instruction 14525 14526 instruct CallLeafNoFPDirect(method meth) 14527 %{ 14528 match(CallLeafNoFP); 14529 14530 effect(USE meth); 14531 14532 ins_cost(CALL_COST); 14533 14534 format %{ "CALL, runtime leaf nofp $meth" %} 14535 14536 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14537 14538 ins_pipe(pipe_class_call); 14539 %} 14540 14541 // Tail Call; Jump from runtime stub to Java code. 14542 // Also known as an 'interprocedural jump'. 14543 // Target of jump will eventually return to caller. 14544 // TailJump below removes the return address. 14545 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 14546 %{ 14547 match(TailCall jump_target method_oop); 14548 14549 ins_cost(CALL_COST); 14550 14551 format %{ "br $jump_target\t# $method_oop holds method oop" %} 14552 14553 ins_encode(aarch64_enc_tail_call(jump_target)); 14554 14555 ins_pipe(pipe_class_call); 14556 %} 14557 14558 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 14559 %{ 14560 match(TailJump jump_target ex_oop); 14561 14562 ins_cost(CALL_COST); 14563 14564 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 14565 14566 ins_encode(aarch64_enc_tail_jmp(jump_target)); 14567 14568 ins_pipe(pipe_class_call); 14569 %} 14570 14571 // Create exception oop: created by stack-crawling runtime code. 14572 // Created exception is now available to this handler, and is setup 14573 // just prior to jumping to this handler. No code emitted. 14574 // TODO check 14575 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 14576 instruct CreateException(iRegP_R0 ex_oop) 14577 %{ 14578 match(Set ex_oop (CreateEx)); 14579 14580 format %{ " -- \t// exception oop; no code emitted" %} 14581 14582 size(0); 14583 14584 ins_encode( /*empty*/ ); 14585 14586 ins_pipe(pipe_class_empty); 14587 %} 14588 14589 // Rethrow exception: The exception oop will come in the first 14590 // argument position. Then JUMP (not call) to the rethrow stub code. 14591 instruct RethrowException() %{ 14592 match(Rethrow); 14593 ins_cost(CALL_COST); 14594 14595 format %{ "b rethrow_stub" %} 14596 14597 ins_encode( aarch64_enc_rethrow() ); 14598 14599 ins_pipe(pipe_class_call); 14600 %} 14601 14602 14603 // Return Instruction 14604 // epilog node loads ret address into lr as part of frame pop 14605 instruct Ret() 14606 %{ 14607 match(Return); 14608 14609 format %{ "ret\t// return register" %} 14610 14611 ins_encode( aarch64_enc_ret() ); 14612 14613 ins_pipe(pipe_branch); 14614 %} 14615 14616 // Die now. 14617 instruct ShouldNotReachHere() %{ 14618 match(Halt); 14619 14620 ins_cost(CALL_COST); 14621 format %{ "ShouldNotReachHere" %} 14622 14623 ins_encode %{ 14624 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 14625 // return true 14626 __ dpcs1(0xdead + 1); 14627 %} 14628 14629 ins_pipe(pipe_class_default); 14630 %} 14631 14632 // ============================================================================ 14633 // Partial Subtype Check 14634 // 14635 // superklass array for an instance of the superklass. Set a hidden 14636 // internal cache on a hit (cache is checked with exposed code in 14637 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14638 // encoding ALSO sets flags. 14639 14640 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 14641 %{ 14642 match(Set result (PartialSubtypeCheck sub super)); 14643 effect(KILL cr, KILL temp); 14644 14645 ins_cost(1100); // slightly larger than the next version 14646 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14647 14648 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14649 14650 opcode(0x1); // Force zero of result reg on hit 14651 14652 ins_pipe(pipe_class_memory); 14653 %} 14654 14655 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 14656 %{ 14657 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 14658 effect(KILL temp, KILL result); 14659 14660 ins_cost(1100); // slightly larger than the next version 14661 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 14662 14663 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14664 14665 opcode(0x0); // Don't zero result reg on hit 14666 14667 ins_pipe(pipe_class_memory); 14668 %} 14669 14670 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14671 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14672 %{ 14673 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 14674 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14675 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14676 14677 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14678 ins_encode %{ 14679 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14680 __ string_compare($str1$$Register, $str2$$Register, 14681 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14682 $tmp1$$Register, $tmp2$$Register, 14683 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 14684 %} 14685 ins_pipe(pipe_class_memory); 14686 %} 14687 14688 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14689 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14690 %{ 14691 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 14692 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14693 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14694 14695 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14696 ins_encode %{ 14697 __ string_compare($str1$$Register, $str2$$Register, 14698 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14699 $tmp1$$Register, $tmp2$$Register, 14700 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 14701 %} 14702 ins_pipe(pipe_class_memory); 14703 %} 14704 14705 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14706 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14707 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14708 %{ 14709 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 14710 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14711 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14712 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14713 14714 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14715 ins_encode %{ 14716 __ string_compare($str1$$Register, $str2$$Register, 14717 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14718 $tmp1$$Register, $tmp2$$Register, 14719 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14720 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 14721 %} 14722 ins_pipe(pipe_class_memory); 14723 %} 14724 14725 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14726 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14727 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14728 %{ 14729 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 14730 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14731 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14732 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14733 14734 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14735 ins_encode %{ 14736 __ string_compare($str1$$Register, $str2$$Register, 14737 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14738 $tmp1$$Register, $tmp2$$Register, 14739 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14740 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 14741 %} 14742 ins_pipe(pipe_class_memory); 14743 %} 14744 14745 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14746 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14747 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14748 %{ 14749 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14750 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14751 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14752 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14753 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 14754 14755 ins_encode %{ 14756 __ string_indexof($str1$$Register, $str2$$Register, 14757 $cnt1$$Register, $cnt2$$Register, 14758 $tmp1$$Register, $tmp2$$Register, 14759 $tmp3$$Register, $tmp4$$Register, 14760 $tmp5$$Register, $tmp6$$Register, 14761 -1, $result$$Register, StrIntrinsicNode::UU); 14762 %} 14763 ins_pipe(pipe_class_memory); 14764 %} 14765 14766 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14767 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14768 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14769 %{ 14770 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14771 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14772 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14773 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14774 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 14775 14776 ins_encode %{ 14777 __ string_indexof($str1$$Register, $str2$$Register, 14778 $cnt1$$Register, $cnt2$$Register, 14779 $tmp1$$Register, $tmp2$$Register, 14780 $tmp3$$Register, $tmp4$$Register, 14781 $tmp5$$Register, $tmp6$$Register, 14782 -1, $result$$Register, StrIntrinsicNode::LL); 14783 %} 14784 ins_pipe(pipe_class_memory); 14785 %} 14786 14787 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14788 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14789 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14790 %{ 14791 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14792 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14793 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14794 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14795 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 14796 14797 ins_encode %{ 14798 __ string_indexof($str1$$Register, $str2$$Register, 14799 $cnt1$$Register, $cnt2$$Register, 14800 $tmp1$$Register, $tmp2$$Register, 14801 $tmp3$$Register, $tmp4$$Register, 14802 $tmp5$$Register, $tmp6$$Register, 14803 -1, $result$$Register, StrIntrinsicNode::UL); 14804 %} 14805 ins_pipe(pipe_class_memory); 14806 %} 14807 14808 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14809 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14810 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14811 %{ 14812 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14813 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14814 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14815 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14816 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 14817 14818 ins_encode %{ 14819 int icnt2 = (int)$int_cnt2$$constant; 14820 __ string_indexof($str1$$Register, $str2$$Register, 14821 $cnt1$$Register, zr, 14822 $tmp1$$Register, $tmp2$$Register, 14823 $tmp3$$Register, $tmp4$$Register, zr, zr, 14824 icnt2, $result$$Register, StrIntrinsicNode::UU); 14825 %} 14826 ins_pipe(pipe_class_memory); 14827 %} 14828 14829 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14830 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14831 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14832 %{ 14833 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14834 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14835 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14836 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14837 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 14838 14839 ins_encode %{ 14840 int icnt2 = (int)$int_cnt2$$constant; 14841 __ string_indexof($str1$$Register, $str2$$Register, 14842 $cnt1$$Register, zr, 14843 $tmp1$$Register, $tmp2$$Register, 14844 $tmp3$$Register, $tmp4$$Register, zr, zr, 14845 icnt2, $result$$Register, StrIntrinsicNode::LL); 14846 %} 14847 ins_pipe(pipe_class_memory); 14848 %} 14849 14850 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14851 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14852 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14853 %{ 14854 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14855 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14856 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14857 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14858 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 14859 14860 ins_encode %{ 14861 int icnt2 = (int)$int_cnt2$$constant; 14862 __ string_indexof($str1$$Register, $str2$$Register, 14863 $cnt1$$Register, zr, 14864 $tmp1$$Register, $tmp2$$Register, 14865 $tmp3$$Register, $tmp4$$Register, zr, zr, 14866 icnt2, $result$$Register, StrIntrinsicNode::UL); 14867 %} 14868 ins_pipe(pipe_class_memory); 14869 %} 14870 14871 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 14872 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14873 iRegINoSp tmp3, rFlagsReg cr) 14874 %{ 14875 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 14876 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 14877 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14878 14879 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 14880 14881 ins_encode %{ 14882 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 14883 $result$$Register, $tmp1$$Register, $tmp2$$Register, 14884 $tmp3$$Register); 14885 %} 14886 ins_pipe(pipe_class_memory); 14887 %} 14888 14889 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14890 iRegI_R0 result, rFlagsReg cr) 14891 %{ 14892 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 14893 match(Set result (StrEquals (Binary str1 str2) cnt)); 14894 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14895 14896 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14897 ins_encode %{ 14898 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14899 __ string_equals($str1$$Register, $str2$$Register, 14900 $result$$Register, $cnt$$Register, 1); 14901 %} 14902 ins_pipe(pipe_class_memory); 14903 %} 14904 14905 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14906 iRegI_R0 result, rFlagsReg cr) 14907 %{ 14908 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 14909 match(Set result (StrEquals (Binary str1 str2) cnt)); 14910 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14911 14912 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14913 ins_encode %{ 14914 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14915 __ string_equals($str1$$Register, $str2$$Register, 14916 $result$$Register, $cnt$$Register, 2); 14917 %} 14918 ins_pipe(pipe_class_memory); 14919 %} 14920 14921 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14922 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14923 iRegP_R10 tmp, rFlagsReg cr) 14924 %{ 14925 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 14926 match(Set result (AryEq ary1 ary2)); 14927 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14928 14929 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14930 ins_encode %{ 14931 __ arrays_equals($ary1$$Register, $ary2$$Register, 14932 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14933 $result$$Register, $tmp$$Register, 1); 14934 %} 14935 ins_pipe(pipe_class_memory); 14936 %} 14937 14938 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14939 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14940 iRegP_R10 tmp, rFlagsReg cr) 14941 %{ 14942 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 14943 match(Set result (AryEq ary1 ary2)); 14944 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14945 14946 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14947 ins_encode %{ 14948 __ arrays_equals($ary1$$Register, $ary2$$Register, 14949 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14950 $result$$Register, $tmp$$Register, 2); 14951 %} 14952 ins_pipe(pipe_class_memory); 14953 %} 14954 14955 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 14956 %{ 14957 match(Set result (HasNegatives ary1 len)); 14958 effect(USE_KILL ary1, USE_KILL len, KILL cr); 14959 format %{ "has negatives byte[] $ary1,$len -> $result" %} 14960 ins_encode %{ 14961 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 14962 %} 14963 ins_pipe( pipe_slow ); 14964 %} 14965 14966 // fast char[] to byte[] compression 14967 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14968 vRegD_V0 tmp1, vRegD_V1 tmp2, 14969 vRegD_V2 tmp3, vRegD_V3 tmp4, 14970 iRegI_R0 result, rFlagsReg cr) 14971 %{ 14972 match(Set result (StrCompressedCopy src (Binary dst len))); 14973 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14974 14975 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 14976 ins_encode %{ 14977 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 14978 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 14979 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 14980 $result$$Register); 14981 %} 14982 ins_pipe( pipe_slow ); 14983 %} 14984 14985 // fast byte[] to char[] inflation 14986 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 14987 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 14988 %{ 14989 match(Set dummy (StrInflatedCopy src (Binary dst len))); 14990 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14991 14992 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 14993 ins_encode %{ 14994 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 14995 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 14996 %} 14997 ins_pipe(pipe_class_memory); 14998 %} 14999 15000 // encode char[] to byte[] in ISO_8859_1 15001 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15002 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15003 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15004 iRegI_R0 result, rFlagsReg cr) 15005 %{ 15006 match(Set result (EncodeISOArray src (Binary dst len))); 15007 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15008 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15009 15010 format %{ "Encode array $src,$dst,$len -> $result" %} 15011 ins_encode %{ 15012 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15013 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15014 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15015 %} 15016 ins_pipe( pipe_class_memory ); 15017 %} 15018 15019 // ============================================================================ 15020 // This name is KNOWN by the ADLC and cannot be changed. 15021 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15022 // for this guy. 15023 instruct tlsLoadP(thread_RegP dst) 15024 %{ 15025 match(Set dst (ThreadLocal)); 15026 15027 ins_cost(0); 15028 15029 format %{ " -- \t// $dst=Thread::current(), empty" %} 15030 15031 size(0); 15032 15033 ins_encode( /*empty*/ ); 15034 15035 ins_pipe(pipe_class_empty); 15036 %} 15037 15038 // ====================VECTOR INSTRUCTIONS===================================== 15039 15040 // Load vector (32 bits) 15041 instruct loadV4(vecD dst, vmem4 mem) 15042 %{ 15043 predicate(n->as_LoadVector()->memory_size() == 4); 15044 match(Set dst (LoadVector mem)); 15045 ins_cost(4 * INSN_COST); 15046 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15047 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15048 ins_pipe(vload_reg_mem64); 15049 %} 15050 15051 // Load vector (64 bits) 15052 instruct loadV8(vecD dst, vmem8 mem) 15053 %{ 15054 predicate(n->as_LoadVector()->memory_size() == 8); 15055 match(Set dst (LoadVector mem)); 15056 ins_cost(4 * INSN_COST); 15057 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15058 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15059 ins_pipe(vload_reg_mem64); 15060 %} 15061 15062 // Load Vector (128 bits) 15063 instruct loadV16(vecX dst, vmem16 mem) 15064 %{ 15065 predicate(n->as_LoadVector()->memory_size() == 16); 15066 match(Set dst (LoadVector mem)); 15067 ins_cost(4 * INSN_COST); 15068 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15069 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15070 ins_pipe(vload_reg_mem128); 15071 %} 15072 15073 // Store Vector (32 bits) 15074 instruct storeV4(vecD src, vmem4 mem) 15075 %{ 15076 predicate(n->as_StoreVector()->memory_size() == 4); 15077 match(Set mem (StoreVector mem src)); 15078 ins_cost(4 * INSN_COST); 15079 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15080 ins_encode( aarch64_enc_strvS(src, mem) ); 15081 ins_pipe(vstore_reg_mem64); 15082 %} 15083 15084 // Store Vector (64 bits) 15085 instruct storeV8(vecD src, vmem8 mem) 15086 %{ 15087 predicate(n->as_StoreVector()->memory_size() == 8); 15088 match(Set mem (StoreVector mem src)); 15089 ins_cost(4 * INSN_COST); 15090 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15091 ins_encode( aarch64_enc_strvD(src, mem) ); 15092 ins_pipe(vstore_reg_mem64); 15093 %} 15094 15095 // Store Vector (128 bits) 15096 instruct storeV16(vecX src, vmem16 mem) 15097 %{ 15098 predicate(n->as_StoreVector()->memory_size() == 16); 15099 match(Set mem (StoreVector mem src)); 15100 ins_cost(4 * INSN_COST); 15101 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15102 ins_encode( aarch64_enc_strvQ(src, mem) ); 15103 ins_pipe(vstore_reg_mem128); 15104 %} 15105 15106 instruct replicate8B(vecD dst, iRegIorL2I src) 15107 %{ 15108 predicate(n->as_Vector()->length() == 4 || 15109 n->as_Vector()->length() == 8); 15110 match(Set dst (ReplicateB src)); 15111 ins_cost(INSN_COST); 15112 format %{ "dup $dst, $src\t# vector (8B)" %} 15113 ins_encode %{ 15114 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15115 %} 15116 ins_pipe(vdup_reg_reg64); 15117 %} 15118 15119 instruct replicate16B(vecX dst, iRegIorL2I src) 15120 %{ 15121 predicate(n->as_Vector()->length() == 16); 15122 match(Set dst (ReplicateB src)); 15123 ins_cost(INSN_COST); 15124 format %{ "dup $dst, $src\t# vector (16B)" %} 15125 ins_encode %{ 15126 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15127 %} 15128 ins_pipe(vdup_reg_reg128); 15129 %} 15130 15131 instruct replicate8B_imm(vecD dst, immI con) 15132 %{ 15133 predicate(n->as_Vector()->length() == 4 || 15134 n->as_Vector()->length() == 8); 15135 match(Set dst (ReplicateB con)); 15136 ins_cost(INSN_COST); 15137 format %{ "movi $dst, $con\t# vector(8B)" %} 15138 ins_encode %{ 15139 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15140 %} 15141 ins_pipe(vmovi_reg_imm64); 15142 %} 15143 15144 instruct replicate16B_imm(vecX dst, immI con) 15145 %{ 15146 predicate(n->as_Vector()->length() == 16); 15147 match(Set dst (ReplicateB con)); 15148 ins_cost(INSN_COST); 15149 format %{ "movi $dst, $con\t# vector(16B)" %} 15150 ins_encode %{ 15151 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15152 %} 15153 ins_pipe(vmovi_reg_imm128); 15154 %} 15155 15156 instruct replicate4S(vecD dst, iRegIorL2I src) 15157 %{ 15158 predicate(n->as_Vector()->length() == 2 || 15159 n->as_Vector()->length() == 4); 15160 match(Set dst (ReplicateS src)); 15161 ins_cost(INSN_COST); 15162 format %{ "dup $dst, $src\t# vector (4S)" %} 15163 ins_encode %{ 15164 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15165 %} 15166 ins_pipe(vdup_reg_reg64); 15167 %} 15168 15169 instruct replicate8S(vecX dst, iRegIorL2I src) 15170 %{ 15171 predicate(n->as_Vector()->length() == 8); 15172 match(Set dst (ReplicateS src)); 15173 ins_cost(INSN_COST); 15174 format %{ "dup $dst, $src\t# vector (8S)" %} 15175 ins_encode %{ 15176 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15177 %} 15178 ins_pipe(vdup_reg_reg128); 15179 %} 15180 15181 instruct replicate4S_imm(vecD dst, immI con) 15182 %{ 15183 predicate(n->as_Vector()->length() == 2 || 15184 n->as_Vector()->length() == 4); 15185 match(Set dst (ReplicateS con)); 15186 ins_cost(INSN_COST); 15187 format %{ "movi $dst, $con\t# vector(4H)" %} 15188 ins_encode %{ 15189 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15190 %} 15191 ins_pipe(vmovi_reg_imm64); 15192 %} 15193 15194 instruct replicate8S_imm(vecX dst, immI con) 15195 %{ 15196 predicate(n->as_Vector()->length() == 8); 15197 match(Set dst (ReplicateS con)); 15198 ins_cost(INSN_COST); 15199 format %{ "movi $dst, $con\t# vector(8H)" %} 15200 ins_encode %{ 15201 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15202 %} 15203 ins_pipe(vmovi_reg_imm128); 15204 %} 15205 15206 instruct replicate2I(vecD dst, iRegIorL2I src) 15207 %{ 15208 predicate(n->as_Vector()->length() == 2); 15209 match(Set dst (ReplicateI src)); 15210 ins_cost(INSN_COST); 15211 format %{ "dup $dst, $src\t# vector (2I)" %} 15212 ins_encode %{ 15213 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15214 %} 15215 ins_pipe(vdup_reg_reg64); 15216 %} 15217 15218 instruct replicate4I(vecX dst, iRegIorL2I src) 15219 %{ 15220 predicate(n->as_Vector()->length() == 4); 15221 match(Set dst (ReplicateI src)); 15222 ins_cost(INSN_COST); 15223 format %{ "dup $dst, $src\t# vector (4I)" %} 15224 ins_encode %{ 15225 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15226 %} 15227 ins_pipe(vdup_reg_reg128); 15228 %} 15229 15230 instruct replicate2I_imm(vecD dst, immI con) 15231 %{ 15232 predicate(n->as_Vector()->length() == 2); 15233 match(Set dst (ReplicateI con)); 15234 ins_cost(INSN_COST); 15235 format %{ "movi $dst, $con\t# vector(2I)" %} 15236 ins_encode %{ 15237 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15238 %} 15239 ins_pipe(vmovi_reg_imm64); 15240 %} 15241 15242 instruct replicate4I_imm(vecX dst, immI con) 15243 %{ 15244 predicate(n->as_Vector()->length() == 4); 15245 match(Set dst (ReplicateI con)); 15246 ins_cost(INSN_COST); 15247 format %{ "movi $dst, $con\t# vector(4I)" %} 15248 ins_encode %{ 15249 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15250 %} 15251 ins_pipe(vmovi_reg_imm128); 15252 %} 15253 15254 instruct replicate2L(vecX dst, iRegL src) 15255 %{ 15256 predicate(n->as_Vector()->length() == 2); 15257 match(Set dst (ReplicateL src)); 15258 ins_cost(INSN_COST); 15259 format %{ "dup $dst, $src\t# vector (2L)" %} 15260 ins_encode %{ 15261 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15262 %} 15263 ins_pipe(vdup_reg_reg128); 15264 %} 15265 15266 instruct replicate2L_zero(vecX dst, immI0 zero) 15267 %{ 15268 predicate(n->as_Vector()->length() == 2); 15269 match(Set dst (ReplicateI zero)); 15270 ins_cost(INSN_COST); 15271 format %{ "movi $dst, $zero\t# vector(4I)" %} 15272 ins_encode %{ 15273 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15274 as_FloatRegister($dst$$reg), 15275 as_FloatRegister($dst$$reg)); 15276 %} 15277 ins_pipe(vmovi_reg_imm128); 15278 %} 15279 15280 instruct replicate2F(vecD dst, vRegF src) 15281 %{ 15282 predicate(n->as_Vector()->length() == 2); 15283 match(Set dst (ReplicateF src)); 15284 ins_cost(INSN_COST); 15285 format %{ "dup $dst, $src\t# vector (2F)" %} 15286 ins_encode %{ 15287 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15288 as_FloatRegister($src$$reg)); 15289 %} 15290 ins_pipe(vdup_reg_freg64); 15291 %} 15292 15293 instruct replicate4F(vecX dst, vRegF src) 15294 %{ 15295 predicate(n->as_Vector()->length() == 4); 15296 match(Set dst (ReplicateF src)); 15297 ins_cost(INSN_COST); 15298 format %{ "dup $dst, $src\t# vector (4F)" %} 15299 ins_encode %{ 15300 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15301 as_FloatRegister($src$$reg)); 15302 %} 15303 ins_pipe(vdup_reg_freg128); 15304 %} 15305 15306 instruct replicate2D(vecX dst, vRegD src) 15307 %{ 15308 predicate(n->as_Vector()->length() == 2); 15309 match(Set dst (ReplicateD src)); 15310 ins_cost(INSN_COST); 15311 format %{ "dup $dst, $src\t# vector (2D)" %} 15312 ins_encode %{ 15313 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15314 as_FloatRegister($src$$reg)); 15315 %} 15316 ins_pipe(vdup_reg_dreg128); 15317 %} 15318 15319 // ====================REDUCTION ARITHMETIC==================================== 15320 15321 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15322 %{ 15323 match(Set dst (AddReductionVI src1 src2)); 15324 ins_cost(INSN_COST); 15325 effect(TEMP tmp, TEMP tmp2); 15326 format %{ "umov $tmp, $src2, S, 0\n\t" 15327 "umov $tmp2, $src2, S, 1\n\t" 15328 "addw $dst, $src1, $tmp\n\t" 15329 "addw $dst, $dst, $tmp2\t add reduction2i" 15330 %} 15331 ins_encode %{ 15332 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15333 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15334 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15335 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15336 %} 15337 ins_pipe(pipe_class_default); 15338 %} 15339 15340 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15341 %{ 15342 match(Set dst (AddReductionVI src1 src2)); 15343 ins_cost(INSN_COST); 15344 effect(TEMP tmp, TEMP tmp2); 15345 format %{ "addv $tmp, T4S, $src2\n\t" 15346 "umov $tmp2, $tmp, S, 0\n\t" 15347 "addw $dst, $tmp2, $src1\t add reduction4i" 15348 %} 15349 ins_encode %{ 15350 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15351 as_FloatRegister($src2$$reg)); 15352 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15353 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15354 %} 15355 ins_pipe(pipe_class_default); 15356 %} 15357 15358 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15359 %{ 15360 match(Set dst (MulReductionVI src1 src2)); 15361 ins_cost(INSN_COST); 15362 effect(TEMP tmp, TEMP dst); 15363 format %{ "umov $tmp, $src2, S, 0\n\t" 15364 "mul $dst, $tmp, $src1\n\t" 15365 "umov $tmp, $src2, S, 1\n\t" 15366 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15367 %} 15368 ins_encode %{ 15369 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15370 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15371 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15372 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15373 %} 15374 ins_pipe(pipe_class_default); 15375 %} 15376 15377 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15378 %{ 15379 match(Set dst (MulReductionVI src1 src2)); 15380 ins_cost(INSN_COST); 15381 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15382 format %{ "ins $tmp, $src2, 0, 1\n\t" 15383 "mul $tmp, $tmp, $src2\n\t" 15384 "umov $tmp2, $tmp, S, 0\n\t" 15385 "mul $dst, $tmp2, $src1\n\t" 15386 "umov $tmp2, $tmp, S, 1\n\t" 15387 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15388 %} 15389 ins_encode %{ 15390 __ ins(as_FloatRegister($tmp$$reg), __ D, 15391 as_FloatRegister($src2$$reg), 0, 1); 15392 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15393 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15394 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15395 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15396 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15397 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15398 %} 15399 ins_pipe(pipe_class_default); 15400 %} 15401 15402 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15403 %{ 15404 match(Set dst (AddReductionVF src1 src2)); 15405 ins_cost(INSN_COST); 15406 effect(TEMP tmp, TEMP dst); 15407 format %{ "fadds $dst, $src1, $src2\n\t" 15408 "ins $tmp, S, $src2, 0, 1\n\t" 15409 "fadds $dst, $dst, $tmp\t add reduction2f" 15410 %} 15411 ins_encode %{ 15412 __ fadds(as_FloatRegister($dst$$reg), 15413 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15414 __ ins(as_FloatRegister($tmp$$reg), __ S, 15415 as_FloatRegister($src2$$reg), 0, 1); 15416 __ fadds(as_FloatRegister($dst$$reg), 15417 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15418 %} 15419 ins_pipe(pipe_class_default); 15420 %} 15421 15422 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15423 %{ 15424 match(Set dst (AddReductionVF src1 src2)); 15425 ins_cost(INSN_COST); 15426 effect(TEMP tmp, TEMP dst); 15427 format %{ "fadds $dst, $src1, $src2\n\t" 15428 "ins $tmp, S, $src2, 0, 1\n\t" 15429 "fadds $dst, $dst, $tmp\n\t" 15430 "ins $tmp, S, $src2, 0, 2\n\t" 15431 "fadds $dst, $dst, $tmp\n\t" 15432 "ins $tmp, S, $src2, 0, 3\n\t" 15433 "fadds $dst, $dst, $tmp\t add reduction4f" 15434 %} 15435 ins_encode %{ 15436 __ fadds(as_FloatRegister($dst$$reg), 15437 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15438 __ ins(as_FloatRegister($tmp$$reg), __ S, 15439 as_FloatRegister($src2$$reg), 0, 1); 15440 __ fadds(as_FloatRegister($dst$$reg), 15441 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15442 __ ins(as_FloatRegister($tmp$$reg), __ S, 15443 as_FloatRegister($src2$$reg), 0, 2); 15444 __ fadds(as_FloatRegister($dst$$reg), 15445 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15446 __ ins(as_FloatRegister($tmp$$reg), __ S, 15447 as_FloatRegister($src2$$reg), 0, 3); 15448 __ fadds(as_FloatRegister($dst$$reg), 15449 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15450 %} 15451 ins_pipe(pipe_class_default); 15452 %} 15453 15454 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15455 %{ 15456 match(Set dst (MulReductionVF src1 src2)); 15457 ins_cost(INSN_COST); 15458 effect(TEMP tmp, TEMP dst); 15459 format %{ "fmuls $dst, $src1, $src2\n\t" 15460 "ins $tmp, S, $src2, 0, 1\n\t" 15461 "fmuls $dst, $dst, $tmp\t add reduction4f" 15462 %} 15463 ins_encode %{ 15464 __ fmuls(as_FloatRegister($dst$$reg), 15465 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15466 __ ins(as_FloatRegister($tmp$$reg), __ S, 15467 as_FloatRegister($src2$$reg), 0, 1); 15468 __ fmuls(as_FloatRegister($dst$$reg), 15469 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15470 %} 15471 ins_pipe(pipe_class_default); 15472 %} 15473 15474 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15475 %{ 15476 match(Set dst (MulReductionVF src1 src2)); 15477 ins_cost(INSN_COST); 15478 effect(TEMP tmp, TEMP dst); 15479 format %{ "fmuls $dst, $src1, $src2\n\t" 15480 "ins $tmp, S, $src2, 0, 1\n\t" 15481 "fmuls $dst, $dst, $tmp\n\t" 15482 "ins $tmp, S, $src2, 0, 2\n\t" 15483 "fmuls $dst, $dst, $tmp\n\t" 15484 "ins $tmp, S, $src2, 0, 3\n\t" 15485 "fmuls $dst, $dst, $tmp\t add reduction4f" 15486 %} 15487 ins_encode %{ 15488 __ fmuls(as_FloatRegister($dst$$reg), 15489 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15490 __ ins(as_FloatRegister($tmp$$reg), __ S, 15491 as_FloatRegister($src2$$reg), 0, 1); 15492 __ fmuls(as_FloatRegister($dst$$reg), 15493 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15494 __ ins(as_FloatRegister($tmp$$reg), __ S, 15495 as_FloatRegister($src2$$reg), 0, 2); 15496 __ fmuls(as_FloatRegister($dst$$reg), 15497 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15498 __ ins(as_FloatRegister($tmp$$reg), __ S, 15499 as_FloatRegister($src2$$reg), 0, 3); 15500 __ fmuls(as_FloatRegister($dst$$reg), 15501 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15502 %} 15503 ins_pipe(pipe_class_default); 15504 %} 15505 15506 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15507 %{ 15508 match(Set dst (AddReductionVD src1 src2)); 15509 ins_cost(INSN_COST); 15510 effect(TEMP tmp, TEMP dst); 15511 format %{ "faddd $dst, $src1, $src2\n\t" 15512 "ins $tmp, D, $src2, 0, 1\n\t" 15513 "faddd $dst, $dst, $tmp\t add reduction2d" 15514 %} 15515 ins_encode %{ 15516 __ faddd(as_FloatRegister($dst$$reg), 15517 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15518 __ ins(as_FloatRegister($tmp$$reg), __ D, 15519 as_FloatRegister($src2$$reg), 0, 1); 15520 __ faddd(as_FloatRegister($dst$$reg), 15521 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15522 %} 15523 ins_pipe(pipe_class_default); 15524 %} 15525 15526 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15527 %{ 15528 match(Set dst (MulReductionVD src1 src2)); 15529 ins_cost(INSN_COST); 15530 effect(TEMP tmp, TEMP dst); 15531 format %{ "fmuld $dst, $src1, $src2\n\t" 15532 "ins $tmp, D, $src2, 0, 1\n\t" 15533 "fmuld $dst, $dst, $tmp\t add reduction2d" 15534 %} 15535 ins_encode %{ 15536 __ fmuld(as_FloatRegister($dst$$reg), 15537 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15538 __ ins(as_FloatRegister($tmp$$reg), __ D, 15539 as_FloatRegister($src2$$reg), 0, 1); 15540 __ fmuld(as_FloatRegister($dst$$reg), 15541 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15542 %} 15543 ins_pipe(pipe_class_default); 15544 %} 15545 15546 // ====================VECTOR ARITHMETIC======================================= 15547 15548 // --------------------------------- ADD -------------------------------------- 15549 15550 instruct vadd8B(vecD dst, vecD src1, vecD src2) 15551 %{ 15552 predicate(n->as_Vector()->length() == 4 || 15553 n->as_Vector()->length() == 8); 15554 match(Set dst (AddVB src1 src2)); 15555 ins_cost(INSN_COST); 15556 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 15557 ins_encode %{ 15558 __ addv(as_FloatRegister($dst$$reg), __ T8B, 15559 as_FloatRegister($src1$$reg), 15560 as_FloatRegister($src2$$reg)); 15561 %} 15562 ins_pipe(vdop64); 15563 %} 15564 15565 instruct vadd16B(vecX dst, vecX src1, vecX src2) 15566 %{ 15567 predicate(n->as_Vector()->length() == 16); 15568 match(Set dst (AddVB src1 src2)); 15569 ins_cost(INSN_COST); 15570 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 15571 ins_encode %{ 15572 __ addv(as_FloatRegister($dst$$reg), __ T16B, 15573 as_FloatRegister($src1$$reg), 15574 as_FloatRegister($src2$$reg)); 15575 %} 15576 ins_pipe(vdop128); 15577 %} 15578 15579 instruct vadd4S(vecD dst, vecD src1, vecD src2) 15580 %{ 15581 predicate(n->as_Vector()->length() == 2 || 15582 n->as_Vector()->length() == 4); 15583 match(Set dst (AddVS src1 src2)); 15584 ins_cost(INSN_COST); 15585 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 15586 ins_encode %{ 15587 __ addv(as_FloatRegister($dst$$reg), __ T4H, 15588 as_FloatRegister($src1$$reg), 15589 as_FloatRegister($src2$$reg)); 15590 %} 15591 ins_pipe(vdop64); 15592 %} 15593 15594 instruct vadd8S(vecX dst, vecX src1, vecX src2) 15595 %{ 15596 predicate(n->as_Vector()->length() == 8); 15597 match(Set dst (AddVS src1 src2)); 15598 ins_cost(INSN_COST); 15599 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 15600 ins_encode %{ 15601 __ addv(as_FloatRegister($dst$$reg), __ T8H, 15602 as_FloatRegister($src1$$reg), 15603 as_FloatRegister($src2$$reg)); 15604 %} 15605 ins_pipe(vdop128); 15606 %} 15607 15608 instruct vadd2I(vecD dst, vecD src1, vecD src2) 15609 %{ 15610 predicate(n->as_Vector()->length() == 2); 15611 match(Set dst (AddVI src1 src2)); 15612 ins_cost(INSN_COST); 15613 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 15614 ins_encode %{ 15615 __ addv(as_FloatRegister($dst$$reg), __ T2S, 15616 as_FloatRegister($src1$$reg), 15617 as_FloatRegister($src2$$reg)); 15618 %} 15619 ins_pipe(vdop64); 15620 %} 15621 15622 instruct vadd4I(vecX dst, vecX src1, vecX src2) 15623 %{ 15624 predicate(n->as_Vector()->length() == 4); 15625 match(Set dst (AddVI src1 src2)); 15626 ins_cost(INSN_COST); 15627 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 15628 ins_encode %{ 15629 __ addv(as_FloatRegister($dst$$reg), __ T4S, 15630 as_FloatRegister($src1$$reg), 15631 as_FloatRegister($src2$$reg)); 15632 %} 15633 ins_pipe(vdop128); 15634 %} 15635 15636 instruct vadd2L(vecX dst, vecX src1, vecX src2) 15637 %{ 15638 predicate(n->as_Vector()->length() == 2); 15639 match(Set dst (AddVL src1 src2)); 15640 ins_cost(INSN_COST); 15641 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 15642 ins_encode %{ 15643 __ addv(as_FloatRegister($dst$$reg), __ T2D, 15644 as_FloatRegister($src1$$reg), 15645 as_FloatRegister($src2$$reg)); 15646 %} 15647 ins_pipe(vdop128); 15648 %} 15649 15650 instruct vadd2F(vecD dst, vecD src1, vecD src2) 15651 %{ 15652 predicate(n->as_Vector()->length() == 2); 15653 match(Set dst (AddVF src1 src2)); 15654 ins_cost(INSN_COST); 15655 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 15656 ins_encode %{ 15657 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 15658 as_FloatRegister($src1$$reg), 15659 as_FloatRegister($src2$$reg)); 15660 %} 15661 ins_pipe(vdop_fp64); 15662 %} 15663 15664 instruct vadd4F(vecX dst, vecX src1, vecX src2) 15665 %{ 15666 predicate(n->as_Vector()->length() == 4); 15667 match(Set dst (AddVF src1 src2)); 15668 ins_cost(INSN_COST); 15669 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 15670 ins_encode %{ 15671 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 15672 as_FloatRegister($src1$$reg), 15673 as_FloatRegister($src2$$reg)); 15674 %} 15675 ins_pipe(vdop_fp128); 15676 %} 15677 15678 instruct vadd2D(vecX dst, vecX src1, vecX src2) 15679 %{ 15680 match(Set dst (AddVD src1 src2)); 15681 ins_cost(INSN_COST); 15682 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 15683 ins_encode %{ 15684 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 15685 as_FloatRegister($src1$$reg), 15686 as_FloatRegister($src2$$reg)); 15687 %} 15688 ins_pipe(vdop_fp128); 15689 %} 15690 15691 // --------------------------------- SUB -------------------------------------- 15692 15693 instruct vsub8B(vecD dst, vecD src1, vecD src2) 15694 %{ 15695 predicate(n->as_Vector()->length() == 4 || 15696 n->as_Vector()->length() == 8); 15697 match(Set dst (SubVB src1 src2)); 15698 ins_cost(INSN_COST); 15699 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 15700 ins_encode %{ 15701 __ subv(as_FloatRegister($dst$$reg), __ T8B, 15702 as_FloatRegister($src1$$reg), 15703 as_FloatRegister($src2$$reg)); 15704 %} 15705 ins_pipe(vdop64); 15706 %} 15707 15708 instruct vsub16B(vecX dst, vecX src1, vecX src2) 15709 %{ 15710 predicate(n->as_Vector()->length() == 16); 15711 match(Set dst (SubVB src1 src2)); 15712 ins_cost(INSN_COST); 15713 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 15714 ins_encode %{ 15715 __ subv(as_FloatRegister($dst$$reg), __ T16B, 15716 as_FloatRegister($src1$$reg), 15717 as_FloatRegister($src2$$reg)); 15718 %} 15719 ins_pipe(vdop128); 15720 %} 15721 15722 instruct vsub4S(vecD dst, vecD src1, vecD src2) 15723 %{ 15724 predicate(n->as_Vector()->length() == 2 || 15725 n->as_Vector()->length() == 4); 15726 match(Set dst (SubVS src1 src2)); 15727 ins_cost(INSN_COST); 15728 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 15729 ins_encode %{ 15730 __ subv(as_FloatRegister($dst$$reg), __ T4H, 15731 as_FloatRegister($src1$$reg), 15732 as_FloatRegister($src2$$reg)); 15733 %} 15734 ins_pipe(vdop64); 15735 %} 15736 15737 instruct vsub8S(vecX dst, vecX src1, vecX src2) 15738 %{ 15739 predicate(n->as_Vector()->length() == 8); 15740 match(Set dst (SubVS src1 src2)); 15741 ins_cost(INSN_COST); 15742 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 15743 ins_encode %{ 15744 __ subv(as_FloatRegister($dst$$reg), __ T8H, 15745 as_FloatRegister($src1$$reg), 15746 as_FloatRegister($src2$$reg)); 15747 %} 15748 ins_pipe(vdop128); 15749 %} 15750 15751 instruct vsub2I(vecD dst, vecD src1, vecD src2) 15752 %{ 15753 predicate(n->as_Vector()->length() == 2); 15754 match(Set dst (SubVI src1 src2)); 15755 ins_cost(INSN_COST); 15756 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 15757 ins_encode %{ 15758 __ subv(as_FloatRegister($dst$$reg), __ T2S, 15759 as_FloatRegister($src1$$reg), 15760 as_FloatRegister($src2$$reg)); 15761 %} 15762 ins_pipe(vdop64); 15763 %} 15764 15765 instruct vsub4I(vecX dst, vecX src1, vecX src2) 15766 %{ 15767 predicate(n->as_Vector()->length() == 4); 15768 match(Set dst (SubVI src1 src2)); 15769 ins_cost(INSN_COST); 15770 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 15771 ins_encode %{ 15772 __ subv(as_FloatRegister($dst$$reg), __ T4S, 15773 as_FloatRegister($src1$$reg), 15774 as_FloatRegister($src2$$reg)); 15775 %} 15776 ins_pipe(vdop128); 15777 %} 15778 15779 instruct vsub2L(vecX dst, vecX src1, vecX src2) 15780 %{ 15781 predicate(n->as_Vector()->length() == 2); 15782 match(Set dst (SubVL src1 src2)); 15783 ins_cost(INSN_COST); 15784 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 15785 ins_encode %{ 15786 __ subv(as_FloatRegister($dst$$reg), __ T2D, 15787 as_FloatRegister($src1$$reg), 15788 as_FloatRegister($src2$$reg)); 15789 %} 15790 ins_pipe(vdop128); 15791 %} 15792 15793 instruct vsub2F(vecD dst, vecD src1, vecD src2) 15794 %{ 15795 predicate(n->as_Vector()->length() == 2); 15796 match(Set dst (SubVF src1 src2)); 15797 ins_cost(INSN_COST); 15798 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 15799 ins_encode %{ 15800 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 15801 as_FloatRegister($src1$$reg), 15802 as_FloatRegister($src2$$reg)); 15803 %} 15804 ins_pipe(vdop_fp64); 15805 %} 15806 15807 instruct vsub4F(vecX dst, vecX src1, vecX src2) 15808 %{ 15809 predicate(n->as_Vector()->length() == 4); 15810 match(Set dst (SubVF src1 src2)); 15811 ins_cost(INSN_COST); 15812 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 15813 ins_encode %{ 15814 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 15815 as_FloatRegister($src1$$reg), 15816 as_FloatRegister($src2$$reg)); 15817 %} 15818 ins_pipe(vdop_fp128); 15819 %} 15820 15821 instruct vsub2D(vecX dst, vecX src1, vecX src2) 15822 %{ 15823 predicate(n->as_Vector()->length() == 2); 15824 match(Set dst (SubVD src1 src2)); 15825 ins_cost(INSN_COST); 15826 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 15827 ins_encode %{ 15828 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 15829 as_FloatRegister($src1$$reg), 15830 as_FloatRegister($src2$$reg)); 15831 %} 15832 ins_pipe(vdop_fp128); 15833 %} 15834 15835 // --------------------------------- MUL -------------------------------------- 15836 15837 instruct vmul4S(vecD dst, vecD src1, vecD src2) 15838 %{ 15839 predicate(n->as_Vector()->length() == 2 || 15840 n->as_Vector()->length() == 4); 15841 match(Set dst (MulVS src1 src2)); 15842 ins_cost(INSN_COST); 15843 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 15844 ins_encode %{ 15845 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 15846 as_FloatRegister($src1$$reg), 15847 as_FloatRegister($src2$$reg)); 15848 %} 15849 ins_pipe(vmul64); 15850 %} 15851 15852 instruct vmul8S(vecX dst, vecX src1, vecX src2) 15853 %{ 15854 predicate(n->as_Vector()->length() == 8); 15855 match(Set dst (MulVS src1 src2)); 15856 ins_cost(INSN_COST); 15857 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 15858 ins_encode %{ 15859 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 15860 as_FloatRegister($src1$$reg), 15861 as_FloatRegister($src2$$reg)); 15862 %} 15863 ins_pipe(vmul128); 15864 %} 15865 15866 instruct vmul2I(vecD dst, vecD src1, vecD src2) 15867 %{ 15868 predicate(n->as_Vector()->length() == 2); 15869 match(Set dst (MulVI src1 src2)); 15870 ins_cost(INSN_COST); 15871 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 15872 ins_encode %{ 15873 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 15874 as_FloatRegister($src1$$reg), 15875 as_FloatRegister($src2$$reg)); 15876 %} 15877 ins_pipe(vmul64); 15878 %} 15879 15880 instruct vmul4I(vecX dst, vecX src1, vecX src2) 15881 %{ 15882 predicate(n->as_Vector()->length() == 4); 15883 match(Set dst (MulVI src1 src2)); 15884 ins_cost(INSN_COST); 15885 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 15886 ins_encode %{ 15887 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 15888 as_FloatRegister($src1$$reg), 15889 as_FloatRegister($src2$$reg)); 15890 %} 15891 ins_pipe(vmul128); 15892 %} 15893 15894 instruct vmul2F(vecD dst, vecD src1, vecD src2) 15895 %{ 15896 predicate(n->as_Vector()->length() == 2); 15897 match(Set dst (MulVF src1 src2)); 15898 ins_cost(INSN_COST); 15899 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 15900 ins_encode %{ 15901 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 15902 as_FloatRegister($src1$$reg), 15903 as_FloatRegister($src2$$reg)); 15904 %} 15905 ins_pipe(vmuldiv_fp64); 15906 %} 15907 15908 instruct vmul4F(vecX dst, vecX src1, vecX src2) 15909 %{ 15910 predicate(n->as_Vector()->length() == 4); 15911 match(Set dst (MulVF src1 src2)); 15912 ins_cost(INSN_COST); 15913 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 15914 ins_encode %{ 15915 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 15916 as_FloatRegister($src1$$reg), 15917 as_FloatRegister($src2$$reg)); 15918 %} 15919 ins_pipe(vmuldiv_fp128); 15920 %} 15921 15922 instruct vmul2D(vecX dst, vecX src1, vecX src2) 15923 %{ 15924 predicate(n->as_Vector()->length() == 2); 15925 match(Set dst (MulVD src1 src2)); 15926 ins_cost(INSN_COST); 15927 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 15928 ins_encode %{ 15929 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 15930 as_FloatRegister($src1$$reg), 15931 as_FloatRegister($src2$$reg)); 15932 %} 15933 ins_pipe(vmuldiv_fp128); 15934 %} 15935 15936 // --------------------------------- MLA -------------------------------------- 15937 15938 instruct vmla4S(vecD dst, vecD src1, vecD src2) 15939 %{ 15940 predicate(n->as_Vector()->length() == 2 || 15941 n->as_Vector()->length() == 4); 15942 match(Set dst (AddVS dst (MulVS src1 src2))); 15943 ins_cost(INSN_COST); 15944 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 15945 ins_encode %{ 15946 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 15947 as_FloatRegister($src1$$reg), 15948 as_FloatRegister($src2$$reg)); 15949 %} 15950 ins_pipe(vmla64); 15951 %} 15952 15953 instruct vmla8S(vecX dst, vecX src1, vecX src2) 15954 %{ 15955 predicate(n->as_Vector()->length() == 8); 15956 match(Set dst (AddVS dst (MulVS src1 src2))); 15957 ins_cost(INSN_COST); 15958 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 15959 ins_encode %{ 15960 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 15961 as_FloatRegister($src1$$reg), 15962 as_FloatRegister($src2$$reg)); 15963 %} 15964 ins_pipe(vmla128); 15965 %} 15966 15967 instruct vmla2I(vecD dst, vecD src1, vecD src2) 15968 %{ 15969 predicate(n->as_Vector()->length() == 2); 15970 match(Set dst (AddVI dst (MulVI src1 src2))); 15971 ins_cost(INSN_COST); 15972 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 15973 ins_encode %{ 15974 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 15975 as_FloatRegister($src1$$reg), 15976 as_FloatRegister($src2$$reg)); 15977 %} 15978 ins_pipe(vmla64); 15979 %} 15980 15981 instruct vmla4I(vecX dst, vecX src1, vecX src2) 15982 %{ 15983 predicate(n->as_Vector()->length() == 4); 15984 match(Set dst (AddVI dst (MulVI src1 src2))); 15985 ins_cost(INSN_COST); 15986 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 15987 ins_encode %{ 15988 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 15989 as_FloatRegister($src1$$reg), 15990 as_FloatRegister($src2$$reg)); 15991 %} 15992 ins_pipe(vmla128); 15993 %} 15994 15995 // dst + src1 * src2 15996 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 15997 predicate(UseFMA && n->as_Vector()->length() == 2); 15998 match(Set dst (FmaVF dst (Binary src1 src2))); 15999 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16000 ins_cost(INSN_COST); 16001 ins_encode %{ 16002 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16003 as_FloatRegister($src1$$reg), 16004 as_FloatRegister($src2$$reg)); 16005 %} 16006 ins_pipe(vmuldiv_fp64); 16007 %} 16008 16009 // dst + src1 * src2 16010 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16011 predicate(UseFMA && n->as_Vector()->length() == 4); 16012 match(Set dst (FmaVF dst (Binary src1 src2))); 16013 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16014 ins_cost(INSN_COST); 16015 ins_encode %{ 16016 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16017 as_FloatRegister($src1$$reg), 16018 as_FloatRegister($src2$$reg)); 16019 %} 16020 ins_pipe(vmuldiv_fp128); 16021 %} 16022 16023 // dst + src1 * src2 16024 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16025 predicate(UseFMA && n->as_Vector()->length() == 2); 16026 match(Set dst (FmaVD dst (Binary src1 src2))); 16027 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16028 ins_cost(INSN_COST); 16029 ins_encode %{ 16030 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16031 as_FloatRegister($src1$$reg), 16032 as_FloatRegister($src2$$reg)); 16033 %} 16034 ins_pipe(vmuldiv_fp128); 16035 %} 16036 16037 // --------------------------------- MLS -------------------------------------- 16038 16039 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16040 %{ 16041 predicate(n->as_Vector()->length() == 2 || 16042 n->as_Vector()->length() == 4); 16043 match(Set dst (SubVS dst (MulVS src1 src2))); 16044 ins_cost(INSN_COST); 16045 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16046 ins_encode %{ 16047 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16048 as_FloatRegister($src1$$reg), 16049 as_FloatRegister($src2$$reg)); 16050 %} 16051 ins_pipe(vmla64); 16052 %} 16053 16054 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16055 %{ 16056 predicate(n->as_Vector()->length() == 8); 16057 match(Set dst (SubVS dst (MulVS src1 src2))); 16058 ins_cost(INSN_COST); 16059 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16060 ins_encode %{ 16061 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16062 as_FloatRegister($src1$$reg), 16063 as_FloatRegister($src2$$reg)); 16064 %} 16065 ins_pipe(vmla128); 16066 %} 16067 16068 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16069 %{ 16070 predicate(n->as_Vector()->length() == 2); 16071 match(Set dst (SubVI dst (MulVI src1 src2))); 16072 ins_cost(INSN_COST); 16073 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16074 ins_encode %{ 16075 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16076 as_FloatRegister($src1$$reg), 16077 as_FloatRegister($src2$$reg)); 16078 %} 16079 ins_pipe(vmla64); 16080 %} 16081 16082 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16083 %{ 16084 predicate(n->as_Vector()->length() == 4); 16085 match(Set dst (SubVI dst (MulVI src1 src2))); 16086 ins_cost(INSN_COST); 16087 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16088 ins_encode %{ 16089 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16090 as_FloatRegister($src1$$reg), 16091 as_FloatRegister($src2$$reg)); 16092 %} 16093 ins_pipe(vmla128); 16094 %} 16095 16096 // dst - src1 * src2 16097 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16098 predicate(UseFMA && n->as_Vector()->length() == 2); 16099 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16100 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16101 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16102 ins_cost(INSN_COST); 16103 ins_encode %{ 16104 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16105 as_FloatRegister($src1$$reg), 16106 as_FloatRegister($src2$$reg)); 16107 %} 16108 ins_pipe(vmuldiv_fp64); 16109 %} 16110 16111 // dst - src1 * src2 16112 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16113 predicate(UseFMA && n->as_Vector()->length() == 4); 16114 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16115 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16116 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16117 ins_cost(INSN_COST); 16118 ins_encode %{ 16119 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16120 as_FloatRegister($src1$$reg), 16121 as_FloatRegister($src2$$reg)); 16122 %} 16123 ins_pipe(vmuldiv_fp128); 16124 %} 16125 16126 // dst - src1 * src2 16127 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16128 predicate(UseFMA && n->as_Vector()->length() == 2); 16129 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16130 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16131 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16132 ins_cost(INSN_COST); 16133 ins_encode %{ 16134 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16135 as_FloatRegister($src1$$reg), 16136 as_FloatRegister($src2$$reg)); 16137 %} 16138 ins_pipe(vmuldiv_fp128); 16139 %} 16140 16141 // --------------------------------- DIV -------------------------------------- 16142 16143 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16144 %{ 16145 predicate(n->as_Vector()->length() == 2); 16146 match(Set dst (DivVF src1 src2)); 16147 ins_cost(INSN_COST); 16148 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16149 ins_encode %{ 16150 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16151 as_FloatRegister($src1$$reg), 16152 as_FloatRegister($src2$$reg)); 16153 %} 16154 ins_pipe(vmuldiv_fp64); 16155 %} 16156 16157 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16158 %{ 16159 predicate(n->as_Vector()->length() == 4); 16160 match(Set dst (DivVF src1 src2)); 16161 ins_cost(INSN_COST); 16162 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16163 ins_encode %{ 16164 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16165 as_FloatRegister($src1$$reg), 16166 as_FloatRegister($src2$$reg)); 16167 %} 16168 ins_pipe(vmuldiv_fp128); 16169 %} 16170 16171 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 16172 %{ 16173 predicate(n->as_Vector()->length() == 2); 16174 match(Set dst (DivVD src1 src2)); 16175 ins_cost(INSN_COST); 16176 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 16177 ins_encode %{ 16178 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 16179 as_FloatRegister($src1$$reg), 16180 as_FloatRegister($src2$$reg)); 16181 %} 16182 ins_pipe(vmuldiv_fp128); 16183 %} 16184 16185 // --------------------------------- SQRT ------------------------------------- 16186 16187 instruct vsqrt2D(vecX dst, vecX src) 16188 %{ 16189 predicate(n->as_Vector()->length() == 2); 16190 match(Set dst (SqrtVD src)); 16191 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 16192 ins_encode %{ 16193 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 16194 as_FloatRegister($src$$reg)); 16195 %} 16196 ins_pipe(vsqrt_fp128); 16197 %} 16198 16199 // --------------------------------- ABS -------------------------------------- 16200 16201 instruct vabs2F(vecD dst, vecD src) 16202 %{ 16203 predicate(n->as_Vector()->length() == 2); 16204 match(Set dst (AbsVF src)); 16205 ins_cost(INSN_COST * 3); 16206 format %{ "fabs $dst,$src\t# vector (2S)" %} 16207 ins_encode %{ 16208 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 16209 as_FloatRegister($src$$reg)); 16210 %} 16211 ins_pipe(vunop_fp64); 16212 %} 16213 16214 instruct vabs4F(vecX dst, vecX src) 16215 %{ 16216 predicate(n->as_Vector()->length() == 4); 16217 match(Set dst (AbsVF src)); 16218 ins_cost(INSN_COST * 3); 16219 format %{ "fabs $dst,$src\t# vector (4S)" %} 16220 ins_encode %{ 16221 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16222 as_FloatRegister($src$$reg)); 16223 %} 16224 ins_pipe(vunop_fp128); 16225 %} 16226 16227 instruct vabs2D(vecX dst, vecX src) 16228 %{ 16229 predicate(n->as_Vector()->length() == 2); 16230 match(Set dst (AbsVD src)); 16231 ins_cost(INSN_COST * 3); 16232 format %{ "fabs $dst,$src\t# vector (2D)" %} 16233 ins_encode %{ 16234 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 16235 as_FloatRegister($src$$reg)); 16236 %} 16237 ins_pipe(vunop_fp128); 16238 %} 16239 16240 // --------------------------------- NEG -------------------------------------- 16241 16242 instruct vneg2F(vecD dst, vecD src) 16243 %{ 16244 predicate(n->as_Vector()->length() == 2); 16245 match(Set dst (NegVF src)); 16246 ins_cost(INSN_COST * 3); 16247 format %{ "fneg $dst,$src\t# vector (2S)" %} 16248 ins_encode %{ 16249 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 16250 as_FloatRegister($src$$reg)); 16251 %} 16252 ins_pipe(vunop_fp64); 16253 %} 16254 16255 instruct vneg4F(vecX dst, vecX src) 16256 %{ 16257 predicate(n->as_Vector()->length() == 4); 16258 match(Set dst (NegVF src)); 16259 ins_cost(INSN_COST * 3); 16260 format %{ "fneg $dst,$src\t# vector (4S)" %} 16261 ins_encode %{ 16262 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16263 as_FloatRegister($src$$reg)); 16264 %} 16265 ins_pipe(vunop_fp128); 16266 %} 16267 16268 instruct vneg2D(vecX dst, vecX src) 16269 %{ 16270 predicate(n->as_Vector()->length() == 2); 16271 match(Set dst (NegVD src)); 16272 ins_cost(INSN_COST * 3); 16273 format %{ "fneg $dst,$src\t# vector (2D)" %} 16274 ins_encode %{ 16275 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16276 as_FloatRegister($src$$reg)); 16277 %} 16278 ins_pipe(vunop_fp128); 16279 %} 16280 16281 // --------------------------------- AND -------------------------------------- 16282 16283 instruct vand8B(vecD dst, vecD src1, vecD src2) 16284 %{ 16285 predicate(n->as_Vector()->length_in_bytes() == 4 || 16286 n->as_Vector()->length_in_bytes() == 8); 16287 match(Set dst (AndV src1 src2)); 16288 ins_cost(INSN_COST); 16289 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16290 ins_encode %{ 16291 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16292 as_FloatRegister($src1$$reg), 16293 as_FloatRegister($src2$$reg)); 16294 %} 16295 ins_pipe(vlogical64); 16296 %} 16297 16298 instruct vand16B(vecX dst, vecX src1, vecX src2) 16299 %{ 16300 predicate(n->as_Vector()->length_in_bytes() == 16); 16301 match(Set dst (AndV src1 src2)); 16302 ins_cost(INSN_COST); 16303 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16304 ins_encode %{ 16305 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16306 as_FloatRegister($src1$$reg), 16307 as_FloatRegister($src2$$reg)); 16308 %} 16309 ins_pipe(vlogical128); 16310 %} 16311 16312 // --------------------------------- OR --------------------------------------- 16313 16314 instruct vor8B(vecD dst, vecD src1, vecD src2) 16315 %{ 16316 predicate(n->as_Vector()->length_in_bytes() == 4 || 16317 n->as_Vector()->length_in_bytes() == 8); 16318 match(Set dst (OrV src1 src2)); 16319 ins_cost(INSN_COST); 16320 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16321 ins_encode %{ 16322 __ orr(as_FloatRegister($dst$$reg), __ T8B, 16323 as_FloatRegister($src1$$reg), 16324 as_FloatRegister($src2$$reg)); 16325 %} 16326 ins_pipe(vlogical64); 16327 %} 16328 16329 instruct vor16B(vecX dst, vecX src1, vecX src2) 16330 %{ 16331 predicate(n->as_Vector()->length_in_bytes() == 16); 16332 match(Set dst (OrV src1 src2)); 16333 ins_cost(INSN_COST); 16334 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 16335 ins_encode %{ 16336 __ orr(as_FloatRegister($dst$$reg), __ T16B, 16337 as_FloatRegister($src1$$reg), 16338 as_FloatRegister($src2$$reg)); 16339 %} 16340 ins_pipe(vlogical128); 16341 %} 16342 16343 // --------------------------------- XOR -------------------------------------- 16344 16345 instruct vxor8B(vecD dst, vecD src1, vecD src2) 16346 %{ 16347 predicate(n->as_Vector()->length_in_bytes() == 4 || 16348 n->as_Vector()->length_in_bytes() == 8); 16349 match(Set dst (XorV src1 src2)); 16350 ins_cost(INSN_COST); 16351 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 16352 ins_encode %{ 16353 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16354 as_FloatRegister($src1$$reg), 16355 as_FloatRegister($src2$$reg)); 16356 %} 16357 ins_pipe(vlogical64); 16358 %} 16359 16360 instruct vxor16B(vecX dst, vecX src1, vecX src2) 16361 %{ 16362 predicate(n->as_Vector()->length_in_bytes() == 16); 16363 match(Set dst (XorV src1 src2)); 16364 ins_cost(INSN_COST); 16365 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 16366 ins_encode %{ 16367 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16368 as_FloatRegister($src1$$reg), 16369 as_FloatRegister($src2$$reg)); 16370 %} 16371 ins_pipe(vlogical128); 16372 %} 16373 16374 // ------------------------------ Shift --------------------------------------- 16375 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 16376 predicate(n->as_Vector()->length_in_bytes() == 8); 16377 match(Set dst (LShiftCntV cnt)); 16378 match(Set dst (RShiftCntV cnt)); 16379 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 16380 ins_encode %{ 16381 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 16382 %} 16383 ins_pipe(vdup_reg_reg64); 16384 %} 16385 16386 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 16387 predicate(n->as_Vector()->length_in_bytes() == 16); 16388 match(Set dst (LShiftCntV cnt)); 16389 match(Set dst (RShiftCntV cnt)); 16390 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 16391 ins_encode %{ 16392 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16393 %} 16394 ins_pipe(vdup_reg_reg128); 16395 %} 16396 16397 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 16398 predicate(n->as_Vector()->length() == 4 || 16399 n->as_Vector()->length() == 8); 16400 match(Set dst (LShiftVB src shift)); 16401 ins_cost(INSN_COST); 16402 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 16403 ins_encode %{ 16404 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16405 as_FloatRegister($src$$reg), 16406 as_FloatRegister($shift$$reg)); 16407 %} 16408 ins_pipe(vshift64); 16409 %} 16410 16411 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 16412 predicate(n->as_Vector()->length() == 16); 16413 match(Set dst (LShiftVB src shift)); 16414 ins_cost(INSN_COST); 16415 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 16416 ins_encode %{ 16417 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16418 as_FloatRegister($src$$reg), 16419 as_FloatRegister($shift$$reg)); 16420 %} 16421 ins_pipe(vshift128); 16422 %} 16423 16424 // Right shifts with vector shift count on aarch64 SIMD are implemented 16425 // as left shift by negative shift count. 16426 // There are two cases for vector shift count. 16427 // 16428 // Case 1: The vector shift count is from replication. 16429 // | | 16430 // LoadVector RShiftCntV 16431 // | / 16432 // RShiftVI 16433 // Note: In inner loop, multiple neg instructions are used, which can be 16434 // moved to outer loop and merge into one neg instruction. 16435 // 16436 // Case 2: The vector shift count is from loading. 16437 // This case isn't supported by middle-end now. But it's supported by 16438 // panama/vectorIntrinsics(JEP 338: Vector API). 16439 // | | 16440 // LoadVector LoadVector 16441 // | / 16442 // RShiftVI 16443 // 16444 16445 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16446 predicate(n->as_Vector()->length() == 4 || 16447 n->as_Vector()->length() == 8); 16448 match(Set dst (RShiftVB src shift)); 16449 ins_cost(INSN_COST); 16450 effect(TEMP tmp); 16451 format %{ "negr $tmp,$shift\t" 16452 "sshl $dst,$src,$tmp\t# vector (8B)" %} 16453 ins_encode %{ 16454 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16455 as_FloatRegister($shift$$reg)); 16456 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16457 as_FloatRegister($src$$reg), 16458 as_FloatRegister($tmp$$reg)); 16459 %} 16460 ins_pipe(vshift64); 16461 %} 16462 16463 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16464 predicate(n->as_Vector()->length() == 16); 16465 match(Set dst (RShiftVB src shift)); 16466 ins_cost(INSN_COST); 16467 effect(TEMP tmp); 16468 format %{ "negr $tmp,$shift\t" 16469 "sshl $dst,$src,$tmp\t# vector (16B)" %} 16470 ins_encode %{ 16471 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16472 as_FloatRegister($shift$$reg)); 16473 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16474 as_FloatRegister($src$$reg), 16475 as_FloatRegister($tmp$$reg)); 16476 %} 16477 ins_pipe(vshift128); 16478 %} 16479 16480 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16481 predicate(n->as_Vector()->length() == 4 || 16482 n->as_Vector()->length() == 8); 16483 match(Set dst (URShiftVB src shift)); 16484 ins_cost(INSN_COST); 16485 effect(TEMP tmp); 16486 format %{ "negr $tmp,$shift\t" 16487 "ushl $dst,$src,$tmp\t# vector (8B)" %} 16488 ins_encode %{ 16489 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16490 as_FloatRegister($shift$$reg)); 16491 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 16492 as_FloatRegister($src$$reg), 16493 as_FloatRegister($tmp$$reg)); 16494 %} 16495 ins_pipe(vshift64); 16496 %} 16497 16498 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16499 predicate(n->as_Vector()->length() == 16); 16500 match(Set dst (URShiftVB src shift)); 16501 ins_cost(INSN_COST); 16502 effect(TEMP tmp); 16503 format %{ "negr $tmp,$shift\t" 16504 "ushl $dst,$src,$tmp\t# vector (16B)" %} 16505 ins_encode %{ 16506 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16507 as_FloatRegister($shift$$reg)); 16508 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 16509 as_FloatRegister($src$$reg), 16510 as_FloatRegister($tmp$$reg)); 16511 %} 16512 ins_pipe(vshift128); 16513 %} 16514 16515 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 16516 predicate(n->as_Vector()->length() == 4 || 16517 n->as_Vector()->length() == 8); 16518 match(Set dst (LShiftVB src shift)); 16519 ins_cost(INSN_COST); 16520 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 16521 ins_encode %{ 16522 int sh = (int)$shift$$constant; 16523 if (sh >= 8) { 16524 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16525 as_FloatRegister($src$$reg), 16526 as_FloatRegister($src$$reg)); 16527 } else { 16528 __ shl(as_FloatRegister($dst$$reg), __ T8B, 16529 as_FloatRegister($src$$reg), sh); 16530 } 16531 %} 16532 ins_pipe(vshift64_imm); 16533 %} 16534 16535 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 16536 predicate(n->as_Vector()->length() == 16); 16537 match(Set dst (LShiftVB src shift)); 16538 ins_cost(INSN_COST); 16539 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 16540 ins_encode %{ 16541 int sh = (int)$shift$$constant; 16542 if (sh >= 8) { 16543 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16544 as_FloatRegister($src$$reg), 16545 as_FloatRegister($src$$reg)); 16546 } else { 16547 __ shl(as_FloatRegister($dst$$reg), __ T16B, 16548 as_FloatRegister($src$$reg), sh); 16549 } 16550 %} 16551 ins_pipe(vshift128_imm); 16552 %} 16553 16554 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 16555 predicate(n->as_Vector()->length() == 4 || 16556 n->as_Vector()->length() == 8); 16557 match(Set dst (RShiftVB src shift)); 16558 ins_cost(INSN_COST); 16559 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 16560 ins_encode %{ 16561 int sh = (int)$shift$$constant; 16562 if (sh >= 8) sh = 7; 16563 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 16564 as_FloatRegister($src$$reg), sh); 16565 %} 16566 ins_pipe(vshift64_imm); 16567 %} 16568 16569 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 16570 predicate(n->as_Vector()->length() == 16); 16571 match(Set dst (RShiftVB src shift)); 16572 ins_cost(INSN_COST); 16573 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 16574 ins_encode %{ 16575 int sh = (int)$shift$$constant; 16576 if (sh >= 8) sh = 7; 16577 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 16578 as_FloatRegister($src$$reg), sh); 16579 %} 16580 ins_pipe(vshift128_imm); 16581 %} 16582 16583 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 16584 predicate(n->as_Vector()->length() == 4 || 16585 n->as_Vector()->length() == 8); 16586 match(Set dst (URShiftVB src shift)); 16587 ins_cost(INSN_COST); 16588 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 16589 ins_encode %{ 16590 int sh = (int)$shift$$constant; 16591 if (sh >= 8) { 16592 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16593 as_FloatRegister($src$$reg), 16594 as_FloatRegister($src$$reg)); 16595 } else { 16596 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 16597 as_FloatRegister($src$$reg), sh); 16598 } 16599 %} 16600 ins_pipe(vshift64_imm); 16601 %} 16602 16603 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 16604 predicate(n->as_Vector()->length() == 16); 16605 match(Set dst (URShiftVB src shift)); 16606 ins_cost(INSN_COST); 16607 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 16608 ins_encode %{ 16609 int sh = (int)$shift$$constant; 16610 if (sh >= 8) { 16611 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16612 as_FloatRegister($src$$reg), 16613 as_FloatRegister($src$$reg)); 16614 } else { 16615 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 16616 as_FloatRegister($src$$reg), sh); 16617 } 16618 %} 16619 ins_pipe(vshift128_imm); 16620 %} 16621 16622 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 16623 predicate(n->as_Vector()->length() == 2 || 16624 n->as_Vector()->length() == 4); 16625 match(Set dst (LShiftVS src shift)); 16626 ins_cost(INSN_COST); 16627 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 16628 ins_encode %{ 16629 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16630 as_FloatRegister($src$$reg), 16631 as_FloatRegister($shift$$reg)); 16632 %} 16633 ins_pipe(vshift64); 16634 %} 16635 16636 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 16637 predicate(n->as_Vector()->length() == 8); 16638 match(Set dst (LShiftVS src shift)); 16639 ins_cost(INSN_COST); 16640 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 16641 ins_encode %{ 16642 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16643 as_FloatRegister($src$$reg), 16644 as_FloatRegister($shift$$reg)); 16645 %} 16646 ins_pipe(vshift128); 16647 %} 16648 16649 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16650 predicate(n->as_Vector()->length() == 2 || 16651 n->as_Vector()->length() == 4); 16652 match(Set dst (RShiftVS src shift)); 16653 ins_cost(INSN_COST); 16654 effect(TEMP tmp); 16655 format %{ "negr $tmp,$shift\t" 16656 "sshl $dst,$src,$tmp\t# vector (4H)" %} 16657 ins_encode %{ 16658 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16659 as_FloatRegister($shift$$reg)); 16660 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16661 as_FloatRegister($src$$reg), 16662 as_FloatRegister($tmp$$reg)); 16663 %} 16664 ins_pipe(vshift64); 16665 %} 16666 16667 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16668 predicate(n->as_Vector()->length() == 8); 16669 match(Set dst (RShiftVS src shift)); 16670 ins_cost(INSN_COST); 16671 effect(TEMP tmp); 16672 format %{ "negr $tmp,$shift\t" 16673 "sshl $dst,$src,$tmp\t# vector (8H)" %} 16674 ins_encode %{ 16675 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16676 as_FloatRegister($shift$$reg)); 16677 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16678 as_FloatRegister($src$$reg), 16679 as_FloatRegister($tmp$$reg)); 16680 %} 16681 ins_pipe(vshift128); 16682 %} 16683 16684 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16685 predicate(n->as_Vector()->length() == 2 || 16686 n->as_Vector()->length() == 4); 16687 match(Set dst (URShiftVS src shift)); 16688 ins_cost(INSN_COST); 16689 effect(TEMP tmp); 16690 format %{ "negr $tmp,$shift\t" 16691 "ushl $dst,$src,$tmp\t# vector (4H)" %} 16692 ins_encode %{ 16693 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16694 as_FloatRegister($shift$$reg)); 16695 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 16696 as_FloatRegister($src$$reg), 16697 as_FloatRegister($tmp$$reg)); 16698 %} 16699 ins_pipe(vshift64); 16700 %} 16701 16702 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16703 predicate(n->as_Vector()->length() == 8); 16704 match(Set dst (URShiftVS src shift)); 16705 ins_cost(INSN_COST); 16706 effect(TEMP tmp); 16707 format %{ "negr $tmp,$shift\t" 16708 "ushl $dst,$src,$tmp\t# vector (8H)" %} 16709 ins_encode %{ 16710 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16711 as_FloatRegister($shift$$reg)); 16712 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 16713 as_FloatRegister($src$$reg), 16714 as_FloatRegister($tmp$$reg)); 16715 %} 16716 ins_pipe(vshift128); 16717 %} 16718 16719 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 16720 predicate(n->as_Vector()->length() == 2 || 16721 n->as_Vector()->length() == 4); 16722 match(Set dst (LShiftVS src shift)); 16723 ins_cost(INSN_COST); 16724 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 16725 ins_encode %{ 16726 int sh = (int)$shift$$constant; 16727 if (sh >= 16) { 16728 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16729 as_FloatRegister($src$$reg), 16730 as_FloatRegister($src$$reg)); 16731 } else { 16732 __ shl(as_FloatRegister($dst$$reg), __ T4H, 16733 as_FloatRegister($src$$reg), sh); 16734 } 16735 %} 16736 ins_pipe(vshift64_imm); 16737 %} 16738 16739 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 16740 predicate(n->as_Vector()->length() == 8); 16741 match(Set dst (LShiftVS src shift)); 16742 ins_cost(INSN_COST); 16743 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 16744 ins_encode %{ 16745 int sh = (int)$shift$$constant; 16746 if (sh >= 16) { 16747 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16748 as_FloatRegister($src$$reg), 16749 as_FloatRegister($src$$reg)); 16750 } else { 16751 __ shl(as_FloatRegister($dst$$reg), __ T8H, 16752 as_FloatRegister($src$$reg), sh); 16753 } 16754 %} 16755 ins_pipe(vshift128_imm); 16756 %} 16757 16758 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 16759 predicate(n->as_Vector()->length() == 2 || 16760 n->as_Vector()->length() == 4); 16761 match(Set dst (RShiftVS src shift)); 16762 ins_cost(INSN_COST); 16763 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 16764 ins_encode %{ 16765 int sh = (int)$shift$$constant; 16766 if (sh >= 16) sh = 15; 16767 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 16768 as_FloatRegister($src$$reg), sh); 16769 %} 16770 ins_pipe(vshift64_imm); 16771 %} 16772 16773 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 16774 predicate(n->as_Vector()->length() == 8); 16775 match(Set dst (RShiftVS src shift)); 16776 ins_cost(INSN_COST); 16777 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 16778 ins_encode %{ 16779 int sh = (int)$shift$$constant; 16780 if (sh >= 16) sh = 15; 16781 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 16782 as_FloatRegister($src$$reg), sh); 16783 %} 16784 ins_pipe(vshift128_imm); 16785 %} 16786 16787 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 16788 predicate(n->as_Vector()->length() == 2 || 16789 n->as_Vector()->length() == 4); 16790 match(Set dst (URShiftVS src shift)); 16791 ins_cost(INSN_COST); 16792 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 16793 ins_encode %{ 16794 int sh = (int)$shift$$constant; 16795 if (sh >= 16) { 16796 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16797 as_FloatRegister($src$$reg), 16798 as_FloatRegister($src$$reg)); 16799 } else { 16800 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 16801 as_FloatRegister($src$$reg), sh); 16802 } 16803 %} 16804 ins_pipe(vshift64_imm); 16805 %} 16806 16807 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 16808 predicate(n->as_Vector()->length() == 8); 16809 match(Set dst (URShiftVS src shift)); 16810 ins_cost(INSN_COST); 16811 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 16812 ins_encode %{ 16813 int sh = (int)$shift$$constant; 16814 if (sh >= 16) { 16815 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16816 as_FloatRegister($src$$reg), 16817 as_FloatRegister($src$$reg)); 16818 } else { 16819 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 16820 as_FloatRegister($src$$reg), sh); 16821 } 16822 %} 16823 ins_pipe(vshift128_imm); 16824 %} 16825 16826 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 16827 predicate(n->as_Vector()->length() == 2); 16828 match(Set dst (LShiftVI src shift)); 16829 ins_cost(INSN_COST); 16830 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 16831 ins_encode %{ 16832 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16833 as_FloatRegister($src$$reg), 16834 as_FloatRegister($shift$$reg)); 16835 %} 16836 ins_pipe(vshift64); 16837 %} 16838 16839 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 16840 predicate(n->as_Vector()->length() == 4); 16841 match(Set dst (LShiftVI src shift)); 16842 ins_cost(INSN_COST); 16843 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 16844 ins_encode %{ 16845 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16846 as_FloatRegister($src$$reg), 16847 as_FloatRegister($shift$$reg)); 16848 %} 16849 ins_pipe(vshift128); 16850 %} 16851 16852 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16853 predicate(n->as_Vector()->length() == 2); 16854 match(Set dst (RShiftVI src shift)); 16855 ins_cost(INSN_COST); 16856 effect(TEMP tmp); 16857 format %{ "negr $tmp,$shift\t" 16858 "sshl $dst,$src,$tmp\t# vector (2S)" %} 16859 ins_encode %{ 16860 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16861 as_FloatRegister($shift$$reg)); 16862 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16863 as_FloatRegister($src$$reg), 16864 as_FloatRegister($tmp$$reg)); 16865 %} 16866 ins_pipe(vshift64); 16867 %} 16868 16869 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16870 predicate(n->as_Vector()->length() == 4); 16871 match(Set dst (RShiftVI src shift)); 16872 ins_cost(INSN_COST); 16873 effect(TEMP tmp); 16874 format %{ "negr $tmp,$shift\t" 16875 "sshl $dst,$src,$tmp\t# vector (4S)" %} 16876 ins_encode %{ 16877 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16878 as_FloatRegister($shift$$reg)); 16879 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16880 as_FloatRegister($src$$reg), 16881 as_FloatRegister($tmp$$reg)); 16882 %} 16883 ins_pipe(vshift128); 16884 %} 16885 16886 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 16887 predicate(n->as_Vector()->length() == 2); 16888 match(Set dst (URShiftVI src shift)); 16889 ins_cost(INSN_COST); 16890 effect(TEMP tmp); 16891 format %{ "negr $tmp,$shift\t" 16892 "ushl $dst,$src,$tmp\t# vector (2S)" %} 16893 ins_encode %{ 16894 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 16895 as_FloatRegister($shift$$reg)); 16896 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 16897 as_FloatRegister($src$$reg), 16898 as_FloatRegister($tmp$$reg)); 16899 %} 16900 ins_pipe(vshift64); 16901 %} 16902 16903 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 16904 predicate(n->as_Vector()->length() == 4); 16905 match(Set dst (URShiftVI src shift)); 16906 ins_cost(INSN_COST); 16907 effect(TEMP tmp); 16908 format %{ "negr $tmp,$shift\t" 16909 "ushl $dst,$src,$tmp\t# vector (4S)" %} 16910 ins_encode %{ 16911 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 16912 as_FloatRegister($shift$$reg)); 16913 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 16914 as_FloatRegister($src$$reg), 16915 as_FloatRegister($tmp$$reg)); 16916 %} 16917 ins_pipe(vshift128); 16918 %} 16919 16920 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 16921 predicate(n->as_Vector()->length() == 2); 16922 match(Set dst (LShiftVI src shift)); 16923 ins_cost(INSN_COST); 16924 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 16925 ins_encode %{ 16926 __ shl(as_FloatRegister($dst$$reg), __ T2S, 16927 as_FloatRegister($src$$reg), 16928 (int)$shift$$constant); 16929 %} 16930 ins_pipe(vshift64_imm); 16931 %} 16932 16933 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 16934 predicate(n->as_Vector()->length() == 4); 16935 match(Set dst (LShiftVI src shift)); 16936 ins_cost(INSN_COST); 16937 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 16938 ins_encode %{ 16939 __ shl(as_FloatRegister($dst$$reg), __ T4S, 16940 as_FloatRegister($src$$reg), 16941 (int)$shift$$constant); 16942 %} 16943 ins_pipe(vshift128_imm); 16944 %} 16945 16946 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 16947 predicate(n->as_Vector()->length() == 2); 16948 match(Set dst (RShiftVI src shift)); 16949 ins_cost(INSN_COST); 16950 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 16951 ins_encode %{ 16952 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 16953 as_FloatRegister($src$$reg), 16954 (int)$shift$$constant); 16955 %} 16956 ins_pipe(vshift64_imm); 16957 %} 16958 16959 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 16960 predicate(n->as_Vector()->length() == 4); 16961 match(Set dst (RShiftVI src shift)); 16962 ins_cost(INSN_COST); 16963 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 16964 ins_encode %{ 16965 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 16966 as_FloatRegister($src$$reg), 16967 (int)$shift$$constant); 16968 %} 16969 ins_pipe(vshift128_imm); 16970 %} 16971 16972 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 16973 predicate(n->as_Vector()->length() == 2); 16974 match(Set dst (URShiftVI src shift)); 16975 ins_cost(INSN_COST); 16976 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 16977 ins_encode %{ 16978 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 16979 as_FloatRegister($src$$reg), 16980 (int)$shift$$constant); 16981 %} 16982 ins_pipe(vshift64_imm); 16983 %} 16984 16985 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 16986 predicate(n->as_Vector()->length() == 4); 16987 match(Set dst (URShiftVI src shift)); 16988 ins_cost(INSN_COST); 16989 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 16990 ins_encode %{ 16991 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 16992 as_FloatRegister($src$$reg), 16993 (int)$shift$$constant); 16994 %} 16995 ins_pipe(vshift128_imm); 16996 %} 16997 16998 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 16999 predicate(n->as_Vector()->length() == 2); 17000 match(Set dst (LShiftVL src shift)); 17001 ins_cost(INSN_COST); 17002 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17003 ins_encode %{ 17004 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17005 as_FloatRegister($src$$reg), 17006 as_FloatRegister($shift$$reg)); 17007 %} 17008 ins_pipe(vshift128); 17009 %} 17010 17011 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17012 predicate(n->as_Vector()->length() == 2); 17013 match(Set dst (RShiftVL src shift)); 17014 ins_cost(INSN_COST); 17015 effect(TEMP tmp); 17016 format %{ "negr $tmp,$shift\t" 17017 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17018 ins_encode %{ 17019 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17020 as_FloatRegister($shift$$reg)); 17021 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17022 as_FloatRegister($src$$reg), 17023 as_FloatRegister($tmp$$reg)); 17024 %} 17025 ins_pipe(vshift128); 17026 %} 17027 17028 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17029 predicate(n->as_Vector()->length() == 2); 17030 match(Set dst (URShiftVL src shift)); 17031 ins_cost(INSN_COST); 17032 effect(TEMP tmp); 17033 format %{ "negr $tmp,$shift\t" 17034 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17035 ins_encode %{ 17036 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17037 as_FloatRegister($shift$$reg)); 17038 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17039 as_FloatRegister($src$$reg), 17040 as_FloatRegister($tmp$$reg)); 17041 %} 17042 ins_pipe(vshift128); 17043 %} 17044 17045 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17046 predicate(n->as_Vector()->length() == 2); 17047 match(Set dst (LShiftVL src shift)); 17048 ins_cost(INSN_COST); 17049 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17050 ins_encode %{ 17051 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17052 as_FloatRegister($src$$reg), 17053 (int)$shift$$constant); 17054 %} 17055 ins_pipe(vshift128_imm); 17056 %} 17057 17058 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17059 predicate(n->as_Vector()->length() == 2); 17060 match(Set dst (RShiftVL src shift)); 17061 ins_cost(INSN_COST); 17062 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17063 ins_encode %{ 17064 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17065 as_FloatRegister($src$$reg), 17066 (int)$shift$$constant); 17067 %} 17068 ins_pipe(vshift128_imm); 17069 %} 17070 17071 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17072 predicate(n->as_Vector()->length() == 2); 17073 match(Set dst (URShiftVL src shift)); 17074 ins_cost(INSN_COST); 17075 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17076 ins_encode %{ 17077 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17078 as_FloatRegister($src$$reg), 17079 (int)$shift$$constant); 17080 %} 17081 ins_pipe(vshift128_imm); 17082 %} 17083 17084 //----------PEEPHOLE RULES----------------------------------------------------- 17085 // These must follow all instruction definitions as they use the names 17086 // defined in the instructions definitions. 17087 // 17088 // peepmatch ( root_instr_name [preceding_instruction]* ); 17089 // 17090 // peepconstraint %{ 17091 // (instruction_number.operand_name relational_op instruction_number.operand_name 17092 // [, ...] ); 17093 // // instruction numbers are zero-based using left to right order in peepmatch 17094 // 17095 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17096 // // provide an instruction_number.operand_name for each operand that appears 17097 // // in the replacement instruction's match rule 17098 // 17099 // ---------VM FLAGS--------------------------------------------------------- 17100 // 17101 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17102 // 17103 // Each peephole rule is given an identifying number starting with zero and 17104 // increasing by one in the order seen by the parser. An individual peephole 17105 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17106 // on the command-line. 17107 // 17108 // ---------CURRENT LIMITATIONS---------------------------------------------- 17109 // 17110 // Only match adjacent instructions in same basic block 17111 // Only equality constraints 17112 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17113 // Only one replacement instruction 17114 // 17115 // ---------EXAMPLE---------------------------------------------------------- 17116 // 17117 // // pertinent parts of existing instructions in architecture description 17118 // instruct movI(iRegINoSp dst, iRegI src) 17119 // %{ 17120 // match(Set dst (CopyI src)); 17121 // %} 17122 // 17123 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17124 // %{ 17125 // match(Set dst (AddI dst src)); 17126 // effect(KILL cr); 17127 // %} 17128 // 17129 // // Change (inc mov) to lea 17130 // peephole %{ 17131 // // increment preceeded by register-register move 17132 // peepmatch ( incI_iReg movI ); 17133 // // require that the destination register of the increment 17134 // // match the destination register of the move 17135 // peepconstraint ( 0.dst == 1.dst ); 17136 // // construct a replacement instruction that sets 17137 // // the destination to ( move's source register + one ) 17138 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17139 // %} 17140 // 17141 17142 // Implementation no longer uses movX instructions since 17143 // machine-independent system no longer uses CopyX nodes. 17144 // 17145 // peephole 17146 // %{ 17147 // peepmatch (incI_iReg movI); 17148 // peepconstraint (0.dst == 1.dst); 17149 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17150 // %} 17151 17152 // peephole 17153 // %{ 17154 // peepmatch (decI_iReg movI); 17155 // peepconstraint (0.dst == 1.dst); 17156 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17157 // %} 17158 17159 // peephole 17160 // %{ 17161 // peepmatch (addI_iReg_imm movI); 17162 // peepconstraint (0.dst == 1.dst); 17163 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17164 // %} 17165 17166 // peephole 17167 // %{ 17168 // peepmatch (incL_iReg movL); 17169 // peepconstraint (0.dst == 1.dst); 17170 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17171 // %} 17172 17173 // peephole 17174 // %{ 17175 // peepmatch (decL_iReg movL); 17176 // peepconstraint (0.dst == 1.dst); 17177 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17178 // %} 17179 17180 // peephole 17181 // %{ 17182 // peepmatch (addL_iReg_imm movL); 17183 // peepconstraint (0.dst == 1.dst); 17184 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17185 // %} 17186 17187 // peephole 17188 // %{ 17189 // peepmatch (addP_iReg_imm movP); 17190 // peepconstraint (0.dst == 1.dst); 17191 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17192 // %} 17193 17194 // // Change load of spilled value to only a spill 17195 // instruct storeI(memory mem, iRegI src) 17196 // %{ 17197 // match(Set mem (StoreI mem src)); 17198 // %} 17199 // 17200 // instruct loadI(iRegINoSp dst, memory mem) 17201 // %{ 17202 // match(Set dst (LoadI mem)); 17203 // %} 17204 // 17205 17206 //----------SMARTSPILL RULES--------------------------------------------------- 17207 // These must follow all instruction definitions as they use the names 17208 // defined in the instructions definitions. 17209 17210 // Local Variables: 17211 // mode: c++ 17212 // End: