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 // Class for 128 bit register v4 961 reg_class v4_reg( 962 V4, V4_H 963 ); 964 965 // Class for 128 bit register v5 966 reg_class v5_reg( 967 V5, V5_H 968 ); 969 970 // Class for 128 bit register v6 971 reg_class v6_reg( 972 V6, V6_H 973 ); 974 975 // Class for 128 bit register v7 976 reg_class v7_reg( 977 V7, V7_H 978 ); 979 980 // Class for 128 bit register v8 981 reg_class v8_reg( 982 V8, V8_H 983 ); 984 985 // Class for 128 bit register v9 986 reg_class v9_reg( 987 V9, V9_H 988 ); 989 990 // Class for 128 bit register v10 991 reg_class v10_reg( 992 V10, V10_H 993 ); 994 995 // Class for 128 bit register v11 996 reg_class v11_reg( 997 V11, V11_H 998 ); 999 1000 // Class for 128 bit register v12 1001 reg_class v12_reg( 1002 V12, V12_H 1003 ); 1004 1005 // Class for 128 bit register v13 1006 reg_class v13_reg( 1007 V13, V13_H 1008 ); 1009 1010 // Class for 128 bit register v14 1011 reg_class v14_reg( 1012 V14, V14_H 1013 ); 1014 1015 // Class for 128 bit register v15 1016 reg_class v15_reg( 1017 V15, V15_H 1018 ); 1019 1020 // Class for 128 bit register v16 1021 reg_class v16_reg( 1022 V16, V16_H 1023 ); 1024 1025 // Class for 128 bit register v17 1026 reg_class v17_reg( 1027 V17, V17_H 1028 ); 1029 1030 // Class for 128 bit register v18 1031 reg_class v18_reg( 1032 V18, V18_H 1033 ); 1034 1035 // Class for 128 bit register v19 1036 reg_class v19_reg( 1037 V19, V19_H 1038 ); 1039 1040 // Class for 128 bit register v20 1041 reg_class v20_reg( 1042 V20, V20_H 1043 ); 1044 1045 // Class for 128 bit register v21 1046 reg_class v21_reg( 1047 V21, V21_H 1048 ); 1049 1050 // Class for 128 bit register v22 1051 reg_class v22_reg( 1052 V22, V22_H 1053 ); 1054 1055 // Class for 128 bit register v23 1056 reg_class v23_reg( 1057 V23, V23_H 1058 ); 1059 1060 // Class for 128 bit register v24 1061 reg_class v24_reg( 1062 V24, V24_H 1063 ); 1064 1065 // Class for 128 bit register v25 1066 reg_class v25_reg( 1067 V25, V25_H 1068 ); 1069 1070 // Class for 128 bit register v26 1071 reg_class v26_reg( 1072 V26, V26_H 1073 ); 1074 1075 // Class for 128 bit register v27 1076 reg_class v27_reg( 1077 V27, V27_H 1078 ); 1079 1080 // Class for 128 bit register v28 1081 reg_class v28_reg( 1082 V28, V28_H 1083 ); 1084 1085 // Class for 128 bit register v29 1086 reg_class v29_reg( 1087 V29, V29_H 1088 ); 1089 1090 // Class for 128 bit register v30 1091 reg_class v30_reg( 1092 V30, V30_H 1093 ); 1094 1095 // Class for 128 bit register v31 1096 reg_class v31_reg( 1097 V31, V31_H 1098 ); 1099 1100 // Singleton class for condition codes 1101 reg_class int_flags(RFLAGS); 1102 1103 %} 1104 1105 //----------DEFINITION BLOCK--------------------------------------------------- 1106 // Define name --> value mappings to inform the ADLC of an integer valued name 1107 // Current support includes integer values in the range [0, 0x7FFFFFFF] 1108 // Format: 1109 // int_def <name> ( <int_value>, <expression>); 1110 // Generated Code in ad_<arch>.hpp 1111 // #define <name> (<expression>) 1112 // // value == <int_value> 1113 // Generated code in ad_<arch>.cpp adlc_verification() 1114 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 1115 // 1116 1117 // we follow the ppc-aix port in using a simple cost model which ranks 1118 // register operations as cheap, memory ops as more expensive and 1119 // branches as most expensive. the first two have a low as well as a 1120 // normal cost. huge cost appears to be a way of saying don't do 1121 // something 1122 1123 definitions %{ 1124 // The default cost (of a register move instruction). 1125 int_def INSN_COST ( 100, 100); 1126 int_def BRANCH_COST ( 200, 2 * INSN_COST); 1127 int_def CALL_COST ( 200, 2 * INSN_COST); 1128 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 1129 %} 1130 1131 1132 //----------SOURCE BLOCK------------------------------------------------------- 1133 // This is a block of C++ code which provides values, functions, and 1134 // definitions necessary in the rest of the architecture description 1135 1136 source_hpp %{ 1137 1138 #include "asm/macroAssembler.hpp" 1139 #include "gc/shared/cardTable.hpp" 1140 #include "gc/shared/cardTableBarrierSet.hpp" 1141 #include "gc/shared/collectedHeap.hpp" 1142 #include "opto/addnode.hpp" 1143 1144 class CallStubImpl { 1145 1146 //-------------------------------------------------------------- 1147 //---< Used for optimization in Compile::shorten_branches >--- 1148 //-------------------------------------------------------------- 1149 1150 public: 1151 // Size of call trampoline stub. 1152 static uint size_call_trampoline() { 1153 return 0; // no call trampolines on this platform 1154 } 1155 1156 // number of relocations needed by a call trampoline stub 1157 static uint reloc_call_trampoline() { 1158 return 0; // no call trampolines on this platform 1159 } 1160 }; 1161 1162 class HandlerImpl { 1163 1164 public: 1165 1166 static int emit_exception_handler(CodeBuffer &cbuf); 1167 static int emit_deopt_handler(CodeBuffer& cbuf); 1168 1169 static uint size_exception_handler() { 1170 return MacroAssembler::far_branch_size(); 1171 } 1172 1173 static uint size_deopt_handler() { 1174 // count one adr and one far branch instruction 1175 return 4 * NativeInstruction::instruction_size; 1176 } 1177 }; 1178 1179 bool is_CAS(int opcode, bool maybe_volatile); 1180 1181 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1182 1183 bool unnecessary_acquire(const Node *barrier); 1184 bool needs_acquiring_load(const Node *load); 1185 1186 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1187 1188 bool unnecessary_release(const Node *barrier); 1189 bool unnecessary_volatile(const Node *barrier); 1190 bool needs_releasing_store(const Node *store); 1191 1192 // predicate controlling translation of CompareAndSwapX 1193 bool needs_acquiring_load_exclusive(const Node *load); 1194 1195 // predicate controlling translation of StoreCM 1196 bool unnecessary_storestore(const Node *storecm); 1197 1198 // predicate controlling addressing modes 1199 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1200 %} 1201 1202 source %{ 1203 1204 // Optimizaton of volatile gets and puts 1205 // ------------------------------------- 1206 // 1207 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1208 // use to implement volatile reads and writes. For a volatile read 1209 // we simply need 1210 // 1211 // ldar<x> 1212 // 1213 // and for a volatile write we need 1214 // 1215 // stlr<x> 1216 // 1217 // Alternatively, we can implement them by pairing a normal 1218 // load/store with a memory barrier. For a volatile read we need 1219 // 1220 // ldr<x> 1221 // dmb ishld 1222 // 1223 // for a volatile write 1224 // 1225 // dmb ish 1226 // str<x> 1227 // dmb ish 1228 // 1229 // We can also use ldaxr and stlxr to implement compare and swap CAS 1230 // sequences. These are normally translated to an instruction 1231 // sequence like the following 1232 // 1233 // dmb ish 1234 // retry: 1235 // ldxr<x> rval raddr 1236 // cmp rval rold 1237 // b.ne done 1238 // stlxr<x> rval, rnew, rold 1239 // cbnz rval retry 1240 // done: 1241 // cset r0, eq 1242 // dmb ishld 1243 // 1244 // Note that the exclusive store is already using an stlxr 1245 // instruction. That is required to ensure visibility to other 1246 // threads of the exclusive write (assuming it succeeds) before that 1247 // of any subsequent writes. 1248 // 1249 // The following instruction sequence is an improvement on the above 1250 // 1251 // retry: 1252 // ldaxr<x> rval raddr 1253 // cmp rval rold 1254 // b.ne done 1255 // stlxr<x> rval, rnew, rold 1256 // cbnz rval retry 1257 // done: 1258 // cset r0, eq 1259 // 1260 // We don't need the leading dmb ish since the stlxr guarantees 1261 // visibility of prior writes in the case that the swap is 1262 // successful. Crucially we don't have to worry about the case where 1263 // the swap is not successful since no valid program should be 1264 // relying on visibility of prior changes by the attempting thread 1265 // in the case where the CAS fails. 1266 // 1267 // Similarly, we don't need the trailing dmb ishld if we substitute 1268 // an ldaxr instruction since that will provide all the guarantees we 1269 // require regarding observation of changes made by other threads 1270 // before any change to the CAS address observed by the load. 1271 // 1272 // In order to generate the desired instruction sequence we need to 1273 // be able to identify specific 'signature' ideal graph node 1274 // sequences which i) occur as a translation of a volatile reads or 1275 // writes or CAS operations and ii) do not occur through any other 1276 // translation or graph transformation. We can then provide 1277 // alternative aldc matching rules which translate these node 1278 // sequences to the desired machine code sequences. Selection of the 1279 // alternative rules can be implemented by predicates which identify 1280 // the relevant node sequences. 1281 // 1282 // The ideal graph generator translates a volatile read to the node 1283 // sequence 1284 // 1285 // LoadX[mo_acquire] 1286 // MemBarAcquire 1287 // 1288 // As a special case when using the compressed oops optimization we 1289 // may also see this variant 1290 // 1291 // LoadN[mo_acquire] 1292 // DecodeN 1293 // MemBarAcquire 1294 // 1295 // A volatile write is translated to the node sequence 1296 // 1297 // MemBarRelease 1298 // StoreX[mo_release] {CardMark}-optional 1299 // MemBarVolatile 1300 // 1301 // n.b. the above node patterns are generated with a strict 1302 // 'signature' configuration of input and output dependencies (see 1303 // the predicates below for exact details). The card mark may be as 1304 // simple as a few extra nodes or, in a few GC configurations, may 1305 // include more complex control flow between the leading and 1306 // trailing memory barriers. However, whatever the card mark 1307 // configuration these signatures are unique to translated volatile 1308 // reads/stores -- they will not appear as a result of any other 1309 // bytecode translation or inlining nor as a consequence of 1310 // optimizing transforms. 1311 // 1312 // We also want to catch inlined unsafe volatile gets and puts and 1313 // be able to implement them using either ldar<x>/stlr<x> or some 1314 // combination of ldr<x>/stlr<x> and dmb instructions. 1315 // 1316 // Inlined unsafe volatiles puts manifest as a minor variant of the 1317 // normal volatile put node sequence containing an extra cpuorder 1318 // membar 1319 // 1320 // MemBarRelease 1321 // MemBarCPUOrder 1322 // StoreX[mo_release] {CardMark}-optional 1323 // MemBarCPUOrder 1324 // MemBarVolatile 1325 // 1326 // n.b. as an aside, a cpuorder membar is not itself subject to 1327 // matching and translation by adlc rules. However, the rule 1328 // predicates need to detect its presence in order to correctly 1329 // select the desired adlc rules. 1330 // 1331 // Inlined unsafe volatile gets manifest as a slightly different 1332 // node sequence to a normal volatile get because of the 1333 // introduction of some CPUOrder memory barriers to bracket the 1334 // Load. However, but the same basic skeleton of a LoadX feeding a 1335 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1336 // present 1337 // 1338 // MemBarCPUOrder 1339 // || \\ 1340 // MemBarCPUOrder LoadX[mo_acquire] 1341 // || | 1342 // || {DecodeN} optional 1343 // || / 1344 // MemBarAcquire 1345 // 1346 // In this case the acquire membar does not directly depend on the 1347 // load. However, we can be sure that the load is generated from an 1348 // inlined unsafe volatile get if we see it dependent on this unique 1349 // sequence of membar nodes. Similarly, given an acquire membar we 1350 // can know that it was added because of an inlined unsafe volatile 1351 // get if it is fed and feeds a cpuorder membar and if its feed 1352 // membar also feeds an acquiring load. 1353 // 1354 // Finally an inlined (Unsafe) CAS operation is translated to the 1355 // following ideal graph 1356 // 1357 // MemBarRelease 1358 // MemBarCPUOrder 1359 // CompareAndSwapX {CardMark}-optional 1360 // MemBarCPUOrder 1361 // MemBarAcquire 1362 // 1363 // So, where we can identify these volatile read and write 1364 // signatures we can choose to plant either of the above two code 1365 // sequences. For a volatile read we can simply plant a normal 1366 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1367 // also choose to inhibit translation of the MemBarAcquire and 1368 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1369 // 1370 // When we recognise a volatile store signature we can choose to 1371 // plant at a dmb ish as a translation for the MemBarRelease, a 1372 // normal str<x> and then a dmb ish for the MemBarVolatile. 1373 // Alternatively, we can inhibit translation of the MemBarRelease 1374 // and MemBarVolatile and instead plant a simple stlr<x> 1375 // instruction. 1376 // 1377 // when we recognise a CAS signature we can choose to plant a dmb 1378 // ish as a translation for the MemBarRelease, the conventional 1379 // macro-instruction sequence for the CompareAndSwap node (which 1380 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1381 // Alternatively, we can elide generation of the dmb instructions 1382 // and plant the alternative CompareAndSwap macro-instruction 1383 // sequence (which uses ldaxr<x>). 1384 // 1385 // Of course, the above only applies when we see these signature 1386 // configurations. We still want to plant dmb instructions in any 1387 // other cases where we may see a MemBarAcquire, MemBarRelease or 1388 // MemBarVolatile. For example, at the end of a constructor which 1389 // writes final/volatile fields we will see a MemBarRelease 1390 // instruction and this needs a 'dmb ish' lest we risk the 1391 // constructed object being visible without making the 1392 // final/volatile field writes visible. 1393 // 1394 // n.b. the translation rules below which rely on detection of the 1395 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1396 // If we see anything other than the signature configurations we 1397 // always just translate the loads and stores to ldr<x> and str<x> 1398 // and translate acquire, release and volatile membars to the 1399 // relevant dmb instructions. 1400 // 1401 1402 // is_CAS(int opcode, bool maybe_volatile) 1403 // 1404 // return true if opcode is one of the possible CompareAndSwapX 1405 // values otherwise false. 1406 1407 bool is_CAS(int opcode, bool maybe_volatile) 1408 { 1409 switch(opcode) { 1410 // We handle these 1411 case Op_CompareAndSwapI: 1412 case Op_CompareAndSwapL: 1413 case Op_CompareAndSwapP: 1414 case Op_CompareAndSwapN: 1415 case Op_ShenandoahCompareAndSwapP: 1416 case Op_ShenandoahCompareAndSwapN: 1417 case Op_CompareAndSwapB: 1418 case Op_CompareAndSwapS: 1419 case Op_GetAndSetI: 1420 case Op_GetAndSetL: 1421 case Op_GetAndSetP: 1422 case Op_GetAndSetN: 1423 case Op_GetAndAddI: 1424 case Op_GetAndAddL: 1425 return true; 1426 case Op_CompareAndExchangeI: 1427 case Op_CompareAndExchangeN: 1428 case Op_CompareAndExchangeB: 1429 case Op_CompareAndExchangeS: 1430 case Op_CompareAndExchangeL: 1431 case Op_CompareAndExchangeP: 1432 case Op_WeakCompareAndSwapB: 1433 case Op_WeakCompareAndSwapS: 1434 case Op_WeakCompareAndSwapI: 1435 case Op_WeakCompareAndSwapL: 1436 case Op_WeakCompareAndSwapP: 1437 case Op_WeakCompareAndSwapN: 1438 case Op_ShenandoahWeakCompareAndSwapP: 1439 case Op_ShenandoahWeakCompareAndSwapN: 1440 case Op_ShenandoahCompareAndExchangeP: 1441 case Op_ShenandoahCompareAndExchangeN: 1442 return maybe_volatile; 1443 default: 1444 return false; 1445 } 1446 } 1447 1448 // helper to determine the maximum number of Phi nodes we may need to 1449 // traverse when searching from a card mark membar for the merge mem 1450 // feeding a trailing membar or vice versa 1451 1452 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1453 1454 bool unnecessary_acquire(const Node *barrier) 1455 { 1456 assert(barrier->is_MemBar(), "expecting a membar"); 1457 1458 if (UseBarriersForVolatile) { 1459 // we need to plant a dmb 1460 return false; 1461 } 1462 1463 MemBarNode* mb = barrier->as_MemBar(); 1464 1465 if (mb->trailing_load()) { 1466 return true; 1467 } 1468 1469 if (mb->trailing_load_store()) { 1470 Node* load_store = mb->in(MemBarNode::Precedent); 1471 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1472 return is_CAS(load_store->Opcode(), true); 1473 } 1474 1475 return false; 1476 } 1477 1478 bool needs_acquiring_load(const Node *n) 1479 { 1480 assert(n->is_Load(), "expecting a load"); 1481 if (UseBarriersForVolatile) { 1482 // we use a normal load and a dmb 1483 return false; 1484 } 1485 1486 LoadNode *ld = n->as_Load(); 1487 1488 return ld->is_acquire(); 1489 } 1490 1491 bool unnecessary_release(const Node *n) 1492 { 1493 assert((n->is_MemBar() && 1494 n->Opcode() == Op_MemBarRelease), 1495 "expecting a release membar"); 1496 1497 if (UseBarriersForVolatile) { 1498 // we need to plant a dmb 1499 return false; 1500 } 1501 1502 MemBarNode *barrier = n->as_MemBar(); 1503 if (!barrier->leading()) { 1504 return false; 1505 } else { 1506 Node* trailing = barrier->trailing_membar(); 1507 MemBarNode* trailing_mb = trailing->as_MemBar(); 1508 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1509 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1510 1511 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1512 if (mem->is_Store()) { 1513 assert(mem->as_Store()->is_release(), ""); 1514 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1515 return true; 1516 } else { 1517 assert(mem->is_LoadStore(), ""); 1518 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1519 return is_CAS(mem->Opcode(), true); 1520 } 1521 } 1522 return false; 1523 } 1524 1525 bool unnecessary_volatile(const Node *n) 1526 { 1527 // assert n->is_MemBar(); 1528 if (UseBarriersForVolatile) { 1529 // we need to plant a dmb 1530 return false; 1531 } 1532 1533 MemBarNode *mbvol = n->as_MemBar(); 1534 1535 bool release = mbvol->trailing_store(); 1536 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1537 #ifdef ASSERT 1538 if (release) { 1539 Node* leading = mbvol->leading_membar(); 1540 assert(leading->Opcode() == Op_MemBarRelease, ""); 1541 assert(leading->as_MemBar()->leading_store(), ""); 1542 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1543 } 1544 #endif 1545 1546 return release; 1547 } 1548 1549 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1550 1551 bool needs_releasing_store(const Node *n) 1552 { 1553 // assert n->is_Store(); 1554 if (UseBarriersForVolatile) { 1555 // we use a normal store and dmb combination 1556 return false; 1557 } 1558 1559 StoreNode *st = n->as_Store(); 1560 1561 return st->trailing_membar() != NULL; 1562 } 1563 1564 // predicate controlling translation of CAS 1565 // 1566 // returns true if CAS needs to use an acquiring load otherwise false 1567 1568 bool needs_acquiring_load_exclusive(const Node *n) 1569 { 1570 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1571 if (UseBarriersForVolatile) { 1572 return false; 1573 } 1574 1575 LoadStoreNode* ldst = n->as_LoadStore(); 1576 if (is_CAS(n->Opcode(), false)) { 1577 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1578 } else { 1579 return ldst->trailing_membar() != NULL; 1580 } 1581 1582 // so we can just return true here 1583 return true; 1584 } 1585 1586 // predicate controlling translation of StoreCM 1587 // 1588 // returns true if a StoreStore must precede the card write otherwise 1589 // false 1590 1591 bool unnecessary_storestore(const Node *storecm) 1592 { 1593 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1594 1595 // we need to generate a dmb ishst between an object put and the 1596 // associated card mark when we are using CMS without conditional 1597 // card marking 1598 1599 if (UseConcMarkSweepGC && !UseCondCardMark) { 1600 return false; 1601 } 1602 1603 // a storestore is unnecesary in all other cases 1604 1605 return true; 1606 } 1607 1608 1609 #define __ _masm. 1610 1611 // advance declarations for helper functions to convert register 1612 // indices to register objects 1613 1614 // the ad file has to provide implementations of certain methods 1615 // expected by the generic code 1616 // 1617 // REQUIRED FUNCTIONALITY 1618 1619 //============================================================================= 1620 1621 // !!!!! Special hack to get all types of calls to specify the byte offset 1622 // from the start of the call to the point where the return address 1623 // will point. 1624 1625 int MachCallStaticJavaNode::ret_addr_offset() 1626 { 1627 // call should be a simple bl 1628 int off = 4; 1629 return off; 1630 } 1631 1632 int MachCallDynamicJavaNode::ret_addr_offset() 1633 { 1634 return 16; // movz, movk, movk, bl 1635 } 1636 1637 int MachCallRuntimeNode::ret_addr_offset() { 1638 // for generated stubs the call will be 1639 // far_call(addr) 1640 // for real runtime callouts it will be six instructions 1641 // see aarch64_enc_java_to_runtime 1642 // adr(rscratch2, retaddr) 1643 // lea(rscratch1, RuntimeAddress(addr) 1644 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1645 // blr(rscratch1) 1646 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1647 if (cb) { 1648 return MacroAssembler::far_branch_size(); 1649 } else { 1650 return 6 * NativeInstruction::instruction_size; 1651 } 1652 } 1653 1654 // Indicate if the safepoint node needs the polling page as an input 1655 1656 // the shared code plants the oop data at the start of the generated 1657 // code for the safepoint node and that needs ot be at the load 1658 // instruction itself. so we cannot plant a mov of the safepoint poll 1659 // address followed by a load. setting this to true means the mov is 1660 // scheduled as a prior instruction. that's better for scheduling 1661 // anyway. 1662 1663 bool SafePointNode::needs_polling_address_input() 1664 { 1665 return true; 1666 } 1667 1668 //============================================================================= 1669 1670 #ifndef PRODUCT 1671 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1672 st->print("BREAKPOINT"); 1673 } 1674 #endif 1675 1676 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1677 MacroAssembler _masm(&cbuf); 1678 __ brk(0); 1679 } 1680 1681 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1682 return MachNode::size(ra_); 1683 } 1684 1685 //============================================================================= 1686 1687 #ifndef PRODUCT 1688 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1689 st->print("nop \t# %d bytes pad for loops and calls", _count); 1690 } 1691 #endif 1692 1693 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1694 MacroAssembler _masm(&cbuf); 1695 for (int i = 0; i < _count; i++) { 1696 __ nop(); 1697 } 1698 } 1699 1700 uint MachNopNode::size(PhaseRegAlloc*) const { 1701 return _count * NativeInstruction::instruction_size; 1702 } 1703 1704 //============================================================================= 1705 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1706 1707 int Compile::ConstantTable::calculate_table_base_offset() const { 1708 return 0; // absolute addressing, no offset 1709 } 1710 1711 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1712 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1713 ShouldNotReachHere(); 1714 } 1715 1716 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1717 // Empty encoding 1718 } 1719 1720 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1721 return 0; 1722 } 1723 1724 #ifndef PRODUCT 1725 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1726 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1727 } 1728 #endif 1729 1730 #ifndef PRODUCT 1731 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1732 Compile* C = ra_->C; 1733 1734 int framesize = C->frame_slots() << LogBytesPerInt; 1735 1736 if (C->need_stack_bang(framesize)) 1737 st->print("# stack bang size=%d\n\t", framesize); 1738 1739 if (framesize < ((1 << 9) + 2 * wordSize)) { 1740 st->print("sub sp, sp, #%d\n\t", framesize); 1741 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1742 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1743 } else { 1744 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1745 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1746 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1747 st->print("sub sp, sp, rscratch1"); 1748 } 1749 } 1750 #endif 1751 1752 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1753 Compile* C = ra_->C; 1754 MacroAssembler _masm(&cbuf); 1755 1756 // n.b. frame size includes space for return pc and rfp 1757 const long framesize = C->frame_size_in_bytes(); 1758 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1759 1760 // insert a nop at the start of the prolog so we can patch in a 1761 // branch if we need to invalidate the method later 1762 __ nop(); 1763 1764 if (C->clinit_barrier_on_entry()) { 1765 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1766 1767 Label L_skip_barrier; 1768 1769 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1770 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1771 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1772 __ bind(L_skip_barrier); 1773 } 1774 1775 int bangsize = C->bang_size_in_bytes(); 1776 if (C->need_stack_bang(bangsize) && UseStackBanging) 1777 __ generate_stack_overflow_check(bangsize); 1778 1779 __ build_frame(framesize); 1780 1781 if (VerifyStackAtCalls) { 1782 Unimplemented(); 1783 } 1784 1785 C->set_frame_complete(cbuf.insts_size()); 1786 1787 if (C->has_mach_constant_base_node()) { 1788 // NOTE: We set the table base offset here because users might be 1789 // emitted before MachConstantBaseNode. 1790 Compile::ConstantTable& constant_table = C->constant_table(); 1791 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1792 } 1793 } 1794 1795 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1796 { 1797 return MachNode::size(ra_); // too many variables; just compute it 1798 // the hard way 1799 } 1800 1801 int MachPrologNode::reloc() const 1802 { 1803 return 0; 1804 } 1805 1806 //============================================================================= 1807 1808 #ifndef PRODUCT 1809 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1810 Compile* C = ra_->C; 1811 int framesize = C->frame_slots() << LogBytesPerInt; 1812 1813 st->print("# pop frame %d\n\t",framesize); 1814 1815 if (framesize == 0) { 1816 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1817 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1818 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1819 st->print("add sp, sp, #%d\n\t", framesize); 1820 } else { 1821 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1822 st->print("add sp, sp, rscratch1\n\t"); 1823 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1824 } 1825 1826 if (do_polling() && C->is_method_compilation()) { 1827 st->print("# touch polling page\n\t"); 1828 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1829 st->print("ldr zr, [rscratch1]"); 1830 } 1831 } 1832 #endif 1833 1834 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1835 Compile* C = ra_->C; 1836 MacroAssembler _masm(&cbuf); 1837 int framesize = C->frame_slots() << LogBytesPerInt; 1838 1839 __ remove_frame(framesize); 1840 1841 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1842 __ reserved_stack_check(); 1843 } 1844 1845 if (do_polling() && C->is_method_compilation()) { 1846 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1847 } 1848 } 1849 1850 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1851 // Variable size. Determine dynamically. 1852 return MachNode::size(ra_); 1853 } 1854 1855 int MachEpilogNode::reloc() const { 1856 // Return number of relocatable values contained in this instruction. 1857 return 1; // 1 for polling page. 1858 } 1859 1860 const Pipeline * MachEpilogNode::pipeline() const { 1861 return MachNode::pipeline_class(); 1862 } 1863 1864 // This method seems to be obsolete. It is declared in machnode.hpp 1865 // and defined in all *.ad files, but it is never called. Should we 1866 // get rid of it? 1867 int MachEpilogNode::safepoint_offset() const { 1868 assert(do_polling(), "no return for this epilog node"); 1869 return 4; 1870 } 1871 1872 //============================================================================= 1873 1874 // Figure out which register class each belongs in: rc_int, rc_float or 1875 // rc_stack. 1876 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1877 1878 static enum RC rc_class(OptoReg::Name reg) { 1879 1880 if (reg == OptoReg::Bad) { 1881 return rc_bad; 1882 } 1883 1884 // we have 30 int registers * 2 halves 1885 // (rscratch1 and rscratch2 are omitted) 1886 1887 if (reg < 60) { 1888 return rc_int; 1889 } 1890 1891 // we have 32 float register * 4 halves 1892 if (reg < 60 + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1893 return rc_float; 1894 } 1895 1896 // Between float regs & stack is the flags regs. 1897 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1898 1899 return rc_stack; 1900 } 1901 1902 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1903 Compile* C = ra_->C; 1904 1905 // Get registers to move. 1906 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1907 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1908 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1909 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1910 1911 enum RC src_hi_rc = rc_class(src_hi); 1912 enum RC src_lo_rc = rc_class(src_lo); 1913 enum RC dst_hi_rc = rc_class(dst_hi); 1914 enum RC dst_lo_rc = rc_class(dst_lo); 1915 1916 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1917 1918 if (src_hi != OptoReg::Bad) { 1919 assert((src_lo&1)==0 && src_lo+1==src_hi && 1920 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1921 "expected aligned-adjacent pairs"); 1922 } 1923 1924 if (src_lo == dst_lo && src_hi == dst_hi) { 1925 return 0; // Self copy, no move. 1926 } 1927 1928 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1929 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1930 int src_offset = ra_->reg2offset(src_lo); 1931 int dst_offset = ra_->reg2offset(dst_lo); 1932 1933 if (bottom_type()->isa_vect() != NULL) { 1934 uint ireg = ideal_reg(); 1935 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1936 if (cbuf) { 1937 MacroAssembler _masm(cbuf); 1938 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1939 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1940 // stack->stack 1941 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1942 if (ireg == Op_VecD) { 1943 __ unspill(rscratch1, true, src_offset); 1944 __ spill(rscratch1, true, dst_offset); 1945 } else { 1946 __ spill_copy128(src_offset, dst_offset); 1947 } 1948 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1949 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1950 ireg == Op_VecD ? __ T8B : __ T16B, 1951 as_FloatRegister(Matcher::_regEncode[src_lo])); 1952 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1953 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1954 ireg == Op_VecD ? __ D : __ Q, 1955 ra_->reg2offset(dst_lo)); 1956 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1957 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1958 ireg == Op_VecD ? __ D : __ Q, 1959 ra_->reg2offset(src_lo)); 1960 } else { 1961 ShouldNotReachHere(); 1962 } 1963 } 1964 } else if (cbuf) { 1965 MacroAssembler _masm(cbuf); 1966 switch (src_lo_rc) { 1967 case rc_int: 1968 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1969 if (is64) { 1970 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1971 as_Register(Matcher::_regEncode[src_lo])); 1972 } else { 1973 MacroAssembler _masm(cbuf); 1974 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1975 as_Register(Matcher::_regEncode[src_lo])); 1976 } 1977 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1978 if (is64) { 1979 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1980 as_Register(Matcher::_regEncode[src_lo])); 1981 } else { 1982 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1983 as_Register(Matcher::_regEncode[src_lo])); 1984 } 1985 } else { // gpr --> stack spill 1986 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1987 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1988 } 1989 break; 1990 case rc_float: 1991 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1992 if (is64) { 1993 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1994 as_FloatRegister(Matcher::_regEncode[src_lo])); 1995 } else { 1996 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1997 as_FloatRegister(Matcher::_regEncode[src_lo])); 1998 } 1999 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2000 if (cbuf) { 2001 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2002 as_FloatRegister(Matcher::_regEncode[src_lo])); 2003 } else { 2004 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2005 as_FloatRegister(Matcher::_regEncode[src_lo])); 2006 } 2007 } else { // fpr --> stack spill 2008 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2009 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2010 is64 ? __ D : __ S, dst_offset); 2011 } 2012 break; 2013 case rc_stack: 2014 if (dst_lo_rc == rc_int) { // stack --> gpr load 2015 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 2016 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2017 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2018 is64 ? __ D : __ S, src_offset); 2019 } else { // stack --> stack copy 2020 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2021 __ unspill(rscratch1, is64, src_offset); 2022 __ spill(rscratch1, is64, dst_offset); 2023 } 2024 break; 2025 default: 2026 assert(false, "bad rc_class for spill"); 2027 ShouldNotReachHere(); 2028 } 2029 } 2030 2031 if (st) { 2032 st->print("spill "); 2033 if (src_lo_rc == rc_stack) { 2034 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2035 } else { 2036 st->print("%s -> ", Matcher::regName[src_lo]); 2037 } 2038 if (dst_lo_rc == rc_stack) { 2039 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2040 } else { 2041 st->print("%s", Matcher::regName[dst_lo]); 2042 } 2043 if (bottom_type()->isa_vect() != NULL) { 2044 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 2045 } else { 2046 st->print("\t# spill size = %d", is64 ? 64:32); 2047 } 2048 } 2049 2050 return 0; 2051 2052 } 2053 2054 #ifndef PRODUCT 2055 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2056 if (!ra_) 2057 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2058 else 2059 implementation(NULL, ra_, false, st); 2060 } 2061 #endif 2062 2063 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2064 implementation(&cbuf, ra_, false, NULL); 2065 } 2066 2067 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2068 return MachNode::size(ra_); 2069 } 2070 2071 //============================================================================= 2072 2073 #ifndef PRODUCT 2074 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2075 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2076 int reg = ra_->get_reg_first(this); 2077 st->print("add %s, rsp, #%d]\t# box lock", 2078 Matcher::regName[reg], offset); 2079 } 2080 #endif 2081 2082 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2083 MacroAssembler _masm(&cbuf); 2084 2085 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2086 int reg = ra_->get_encode(this); 2087 2088 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2089 __ add(as_Register(reg), sp, offset); 2090 } else { 2091 ShouldNotReachHere(); 2092 } 2093 } 2094 2095 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2096 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2097 return 4; 2098 } 2099 2100 //============================================================================= 2101 2102 #ifndef PRODUCT 2103 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2104 { 2105 st->print_cr("# MachUEPNode"); 2106 if (UseCompressedClassPointers) { 2107 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2108 if (CompressedKlassPointers::shift() != 0) { 2109 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2110 } 2111 } else { 2112 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2113 } 2114 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2115 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2116 } 2117 #endif 2118 2119 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2120 { 2121 // This is the unverified entry point. 2122 MacroAssembler _masm(&cbuf); 2123 2124 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2125 Label skip; 2126 // TODO 2127 // can we avoid this skip and still use a reloc? 2128 __ br(Assembler::EQ, skip); 2129 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2130 __ bind(skip); 2131 } 2132 2133 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2134 { 2135 return MachNode::size(ra_); 2136 } 2137 2138 // REQUIRED EMIT CODE 2139 2140 //============================================================================= 2141 2142 // Emit exception handler code. 2143 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2144 { 2145 // mov rscratch1 #exception_blob_entry_point 2146 // br rscratch1 2147 // Note that the code buffer's insts_mark is always relative to insts. 2148 // That's why we must use the macroassembler to generate a handler. 2149 MacroAssembler _masm(&cbuf); 2150 address base = __ start_a_stub(size_exception_handler()); 2151 if (base == NULL) { 2152 ciEnv::current()->record_failure("CodeCache is full"); 2153 return 0; // CodeBuffer::expand failed 2154 } 2155 int offset = __ offset(); 2156 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2157 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2158 __ end_a_stub(); 2159 return offset; 2160 } 2161 2162 // Emit deopt handler code. 2163 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2164 { 2165 // Note that the code buffer's insts_mark is always relative to insts. 2166 // That's why we must use the macroassembler to generate a handler. 2167 MacroAssembler _masm(&cbuf); 2168 address base = __ start_a_stub(size_deopt_handler()); 2169 if (base == NULL) { 2170 ciEnv::current()->record_failure("CodeCache is full"); 2171 return 0; // CodeBuffer::expand failed 2172 } 2173 int offset = __ offset(); 2174 2175 __ adr(lr, __ pc()); 2176 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2177 2178 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2179 __ end_a_stub(); 2180 return offset; 2181 } 2182 2183 // REQUIRED MATCHER CODE 2184 2185 //============================================================================= 2186 2187 const bool Matcher::match_rule_supported(int opcode) { 2188 if (!has_match_rule(opcode)) 2189 return false; 2190 2191 bool ret_value = true; 2192 switch (opcode) { 2193 case Op_CacheWB: 2194 case Op_CacheWBPreSync: 2195 case Op_CacheWBPostSync: 2196 if (!VM_Version::supports_data_cache_line_flush()) { 2197 ret_value = false; 2198 } 2199 break; 2200 } 2201 2202 return ret_value; // Per default match rules are supported. 2203 } 2204 2205 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2206 2207 // TODO 2208 // identify extra cases that we might want to provide match rules for 2209 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2210 bool ret_value = match_rule_supported(opcode); 2211 // Add rules here. 2212 2213 return ret_value; // Per default match rules are supported. 2214 } 2215 2216 const bool Matcher::has_predicated_vectors(void) { 2217 return false; 2218 } 2219 2220 const int Matcher::float_pressure(int default_pressure_threshold) { 2221 return default_pressure_threshold; 2222 } 2223 2224 int Matcher::regnum_to_fpu_offset(int regnum) 2225 { 2226 Unimplemented(); 2227 return 0; 2228 } 2229 2230 // Is this branch offset short enough that a short branch can be used? 2231 // 2232 // NOTE: If the platform does not provide any short branch variants, then 2233 // this method should return false for offset 0. 2234 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2235 // The passed offset is relative to address of the branch. 2236 2237 return (-32768 <= offset && offset < 32768); 2238 } 2239 2240 const bool Matcher::isSimpleConstant64(jlong value) { 2241 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2242 // Probably always true, even if a temp register is required. 2243 return true; 2244 } 2245 2246 // true just means we have fast l2f conversion 2247 const bool Matcher::convL2FSupported(void) { 2248 return true; 2249 } 2250 2251 // Vector width in bytes. 2252 const int Matcher::vector_width_in_bytes(BasicType bt) { 2253 int size = MIN2(16,(int)MaxVectorSize); 2254 // Minimum 2 values in vector 2255 if (size < 2*type2aelembytes(bt)) size = 0; 2256 // But never < 4 2257 if (size < 4) size = 0; 2258 return size; 2259 } 2260 2261 // Limits on vector size (number of elements) loaded into vector. 2262 const int Matcher::max_vector_size(const BasicType bt) { 2263 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2264 } 2265 const int Matcher::min_vector_size(const BasicType bt) { 2266 // For the moment limit the vector size to 8 bytes 2267 int size = 8 / type2aelembytes(bt); 2268 if (size < 2) size = 2; 2269 return size; 2270 } 2271 2272 // Vector ideal reg. 2273 const uint Matcher::vector_ideal_reg(int len) { 2274 switch(len) { 2275 case 8: return Op_VecD; 2276 case 16: return Op_VecX; 2277 } 2278 ShouldNotReachHere(); 2279 return 0; 2280 } 2281 2282 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2283 switch(size) { 2284 case 8: return Op_VecD; 2285 case 16: return Op_VecX; 2286 } 2287 ShouldNotReachHere(); 2288 return 0; 2289 } 2290 2291 // AES support not yet implemented 2292 const bool Matcher::pass_original_key_for_aes() { 2293 return false; 2294 } 2295 2296 // aarch64 supports misaligned vectors store/load. 2297 const bool Matcher::misaligned_vectors_ok() { 2298 return true; 2299 } 2300 2301 // false => size gets scaled to BytesPerLong, ok. 2302 const bool Matcher::init_array_count_is_in_bytes = false; 2303 2304 // Use conditional move (CMOVL) 2305 const int Matcher::long_cmove_cost() { 2306 // long cmoves are no more expensive than int cmoves 2307 return 0; 2308 } 2309 2310 const int Matcher::float_cmove_cost() { 2311 // float cmoves are no more expensive than int cmoves 2312 return 0; 2313 } 2314 2315 // Does the CPU require late expand (see block.cpp for description of late expand)? 2316 const bool Matcher::require_postalloc_expand = false; 2317 2318 // Do we need to mask the count passed to shift instructions or does 2319 // the cpu only look at the lower 5/6 bits anyway? 2320 const bool Matcher::need_masked_shift_count = false; 2321 2322 // This affects two different things: 2323 // - how Decode nodes are matched 2324 // - how ImplicitNullCheck opportunities are recognized 2325 // If true, the matcher will try to remove all Decodes and match them 2326 // (as operands) into nodes. NullChecks are not prepared to deal with 2327 // Decodes by final_graph_reshaping(). 2328 // If false, final_graph_reshaping() forces the decode behind the Cmp 2329 // for a NullCheck. The matcher matches the Decode node into a register. 2330 // Implicit_null_check optimization moves the Decode along with the 2331 // memory operation back up before the NullCheck. 2332 bool Matcher::narrow_oop_use_complex_address() { 2333 return CompressedOops::shift() == 0; 2334 } 2335 2336 bool Matcher::narrow_klass_use_complex_address() { 2337 // TODO 2338 // decide whether we need to set this to true 2339 return false; 2340 } 2341 2342 bool Matcher::const_oop_prefer_decode() { 2343 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2344 return CompressedOops::base() == NULL; 2345 } 2346 2347 bool Matcher::const_klass_prefer_decode() { 2348 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2349 return CompressedKlassPointers::base() == NULL; 2350 } 2351 2352 // Is it better to copy float constants, or load them directly from 2353 // memory? Intel can load a float constant from a direct address, 2354 // requiring no extra registers. Most RISCs will have to materialize 2355 // an address into a register first, so they would do better to copy 2356 // the constant from stack. 2357 const bool Matcher::rematerialize_float_constants = false; 2358 2359 // If CPU can load and store mis-aligned doubles directly then no 2360 // fixup is needed. Else we split the double into 2 integer pieces 2361 // and move it piece-by-piece. Only happens when passing doubles into 2362 // C code as the Java calling convention forces doubles to be aligned. 2363 const bool Matcher::misaligned_doubles_ok = true; 2364 2365 // No-op on amd64 2366 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2367 Unimplemented(); 2368 } 2369 2370 // Advertise here if the CPU requires explicit rounding operations to 2371 // implement the UseStrictFP mode. 2372 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2373 2374 // Are floats converted to double when stored to stack during 2375 // deoptimization? 2376 bool Matcher::float_in_double() { return false; } 2377 2378 // Do ints take an entire long register or just half? 2379 // The relevant question is how the int is callee-saved: 2380 // the whole long is written but de-opt'ing will have to extract 2381 // the relevant 32 bits. 2382 const bool Matcher::int_in_long = true; 2383 2384 // Return whether or not this register is ever used as an argument. 2385 // This function is used on startup to build the trampoline stubs in 2386 // generateOptoStub. Registers not mentioned will be killed by the VM 2387 // call in the trampoline, and arguments in those registers not be 2388 // available to the callee. 2389 bool Matcher::can_be_java_arg(int reg) 2390 { 2391 return 2392 reg == R0_num || reg == R0_H_num || 2393 reg == R1_num || reg == R1_H_num || 2394 reg == R2_num || reg == R2_H_num || 2395 reg == R3_num || reg == R3_H_num || 2396 reg == R4_num || reg == R4_H_num || 2397 reg == R5_num || reg == R5_H_num || 2398 reg == R6_num || reg == R6_H_num || 2399 reg == R7_num || reg == R7_H_num || 2400 reg == V0_num || reg == V0_H_num || 2401 reg == V1_num || reg == V1_H_num || 2402 reg == V2_num || reg == V2_H_num || 2403 reg == V3_num || reg == V3_H_num || 2404 reg == V4_num || reg == V4_H_num || 2405 reg == V5_num || reg == V5_H_num || 2406 reg == V6_num || reg == V6_H_num || 2407 reg == V7_num || reg == V7_H_num; 2408 } 2409 2410 bool Matcher::is_spillable_arg(int reg) 2411 { 2412 return can_be_java_arg(reg); 2413 } 2414 2415 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2416 return false; 2417 } 2418 2419 RegMask Matcher::divI_proj_mask() { 2420 ShouldNotReachHere(); 2421 return RegMask(); 2422 } 2423 2424 // Register for MODI projection of divmodI. 2425 RegMask Matcher::modI_proj_mask() { 2426 ShouldNotReachHere(); 2427 return RegMask(); 2428 } 2429 2430 // Register for DIVL projection of divmodL. 2431 RegMask Matcher::divL_proj_mask() { 2432 ShouldNotReachHere(); 2433 return RegMask(); 2434 } 2435 2436 // Register for MODL projection of divmodL. 2437 RegMask Matcher::modL_proj_mask() { 2438 ShouldNotReachHere(); 2439 return RegMask(); 2440 } 2441 2442 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2443 return FP_REG_mask(); 2444 } 2445 2446 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2447 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2448 Node* u = addp->fast_out(i); 2449 if (u->is_Mem()) { 2450 int opsize = u->as_Mem()->memory_size(); 2451 assert(opsize > 0, "unexpected memory operand size"); 2452 if (u->as_Mem()->memory_size() != (1<<shift)) { 2453 return false; 2454 } 2455 } 2456 } 2457 return true; 2458 } 2459 2460 const bool Matcher::convi2l_type_required = false; 2461 2462 // Should the Matcher clone shifts on addressing modes, expecting them 2463 // to be subsumed into complex addressing expressions or compute them 2464 // into registers? 2465 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2466 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2467 return true; 2468 } 2469 2470 Node *off = m->in(AddPNode::Offset); 2471 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2472 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2473 // Are there other uses besides address expressions? 2474 !is_visited(off)) { 2475 address_visited.set(off->_idx); // Flag as address_visited 2476 mstack.push(off->in(2), Visit); 2477 Node *conv = off->in(1); 2478 if (conv->Opcode() == Op_ConvI2L && 2479 // Are there other uses besides address expressions? 2480 !is_visited(conv)) { 2481 address_visited.set(conv->_idx); // Flag as address_visited 2482 mstack.push(conv->in(1), Pre_Visit); 2483 } else { 2484 mstack.push(conv, Pre_Visit); 2485 } 2486 address_visited.test_set(m->_idx); // Flag as address_visited 2487 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2488 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2489 return true; 2490 } else if (off->Opcode() == Op_ConvI2L && 2491 // Are there other uses besides address expressions? 2492 !is_visited(off)) { 2493 address_visited.test_set(m->_idx); // Flag as address_visited 2494 address_visited.set(off->_idx); // Flag as address_visited 2495 mstack.push(off->in(1), Pre_Visit); 2496 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2497 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2498 return true; 2499 } 2500 return false; 2501 } 2502 2503 void Compile::reshape_address(AddPNode* addp) { 2504 } 2505 2506 2507 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2508 MacroAssembler _masm(&cbuf); \ 2509 { \ 2510 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2511 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2512 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2513 __ INSN(REG, as_Register(BASE)); \ 2514 } 2515 2516 2517 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2518 { 2519 Address::extend scale; 2520 2521 // Hooboy, this is fugly. We need a way to communicate to the 2522 // encoder that the index needs to be sign extended, so we have to 2523 // enumerate all the cases. 2524 switch (opcode) { 2525 case INDINDEXSCALEDI2L: 2526 case INDINDEXSCALEDI2LN: 2527 case INDINDEXI2L: 2528 case INDINDEXI2LN: 2529 scale = Address::sxtw(size); 2530 break; 2531 default: 2532 scale = Address::lsl(size); 2533 } 2534 2535 if (index == -1) { 2536 return Address(base, disp); 2537 } else { 2538 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2539 return Address(base, as_Register(index), scale); 2540 } 2541 } 2542 2543 2544 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2545 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2546 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2547 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2548 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2549 2550 // Used for all non-volatile memory accesses. The use of 2551 // $mem->opcode() to discover whether this pattern uses sign-extended 2552 // offsets is something of a kludge. 2553 static void loadStore(MacroAssembler masm, mem_insn insn, 2554 Register reg, int opcode, 2555 Register base, int index, int size, int disp) 2556 { 2557 Address addr = mem2address(opcode, base, index, size, disp); 2558 (masm.*insn)(reg, addr); 2559 } 2560 2561 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2562 FloatRegister reg, int opcode, 2563 Register base, int index, int size, int disp) 2564 { 2565 Address::extend scale; 2566 2567 switch (opcode) { 2568 case INDINDEXSCALEDI2L: 2569 case INDINDEXSCALEDI2LN: 2570 scale = Address::sxtw(size); 2571 break; 2572 default: 2573 scale = Address::lsl(size); 2574 } 2575 2576 if (index == -1) { 2577 (masm.*insn)(reg, Address(base, disp)); 2578 } else { 2579 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2580 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2581 } 2582 } 2583 2584 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2585 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2586 int opcode, Register base, int index, int size, int disp) 2587 { 2588 if (index == -1) { 2589 (masm.*insn)(reg, T, Address(base, disp)); 2590 } else { 2591 assert(disp == 0, "unsupported address mode"); 2592 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2593 } 2594 } 2595 2596 %} 2597 2598 2599 2600 //----------ENCODING BLOCK----------------------------------------------------- 2601 // This block specifies the encoding classes used by the compiler to 2602 // output byte streams. Encoding classes are parameterized macros 2603 // used by Machine Instruction Nodes in order to generate the bit 2604 // encoding of the instruction. Operands specify their base encoding 2605 // interface with the interface keyword. There are currently 2606 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2607 // COND_INTER. REG_INTER causes an operand to generate a function 2608 // which returns its register number when queried. CONST_INTER causes 2609 // an operand to generate a function which returns the value of the 2610 // constant when queried. MEMORY_INTER causes an operand to generate 2611 // four functions which return the Base Register, the Index Register, 2612 // the Scale Value, and the Offset Value of the operand when queried. 2613 // COND_INTER causes an operand to generate six functions which return 2614 // the encoding code (ie - encoding bits for the instruction) 2615 // associated with each basic boolean condition for a conditional 2616 // instruction. 2617 // 2618 // Instructions specify two basic values for encoding. Again, a 2619 // function is available to check if the constant displacement is an 2620 // oop. They use the ins_encode keyword to specify their encoding 2621 // classes (which must be a sequence of enc_class names, and their 2622 // parameters, specified in the encoding block), and they use the 2623 // opcode keyword to specify, in order, their primary, secondary, and 2624 // tertiary opcode. Only the opcode sections which a particular 2625 // instruction needs for encoding need to be specified. 2626 encode %{ 2627 // Build emit functions for each basic byte or larger field in the 2628 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2629 // from C++ code in the enc_class source block. Emit functions will 2630 // live in the main source block for now. In future, we can 2631 // generalize this by adding a syntax that specifies the sizes of 2632 // fields in an order, so that the adlc can build the emit functions 2633 // automagically 2634 2635 // catch all for unimplemented encodings 2636 enc_class enc_unimplemented %{ 2637 MacroAssembler _masm(&cbuf); 2638 __ unimplemented("C2 catch all"); 2639 %} 2640 2641 // BEGIN Non-volatile memory access 2642 2643 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2644 Register dst_reg = as_Register($dst$$reg); 2645 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2646 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2647 %} 2648 2649 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2650 Register dst_reg = as_Register($dst$$reg); 2651 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2652 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2653 %} 2654 2655 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2656 Register dst_reg = as_Register($dst$$reg); 2657 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2658 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2659 %} 2660 2661 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2662 Register dst_reg = as_Register($dst$$reg); 2663 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2664 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2665 %} 2666 2667 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2668 Register dst_reg = as_Register($dst$$reg); 2669 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2670 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2671 %} 2672 2673 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2674 Register dst_reg = as_Register($dst$$reg); 2675 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2676 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2677 %} 2678 2679 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2680 Register dst_reg = as_Register($dst$$reg); 2681 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2682 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2683 %} 2684 2685 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2686 Register dst_reg = as_Register($dst$$reg); 2687 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2688 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2689 %} 2690 2691 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2692 Register dst_reg = as_Register($dst$$reg); 2693 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2694 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2695 %} 2696 2697 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2698 Register dst_reg = as_Register($dst$$reg); 2699 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2700 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2701 %} 2702 2703 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2704 Register dst_reg = as_Register($dst$$reg); 2705 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2706 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2707 %} 2708 2709 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2710 Register dst_reg = as_Register($dst$$reg); 2711 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2712 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2713 %} 2714 2715 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2716 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2717 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2718 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2719 %} 2720 2721 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2722 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2723 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2724 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2725 %} 2726 2727 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2728 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2729 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2730 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2731 %} 2732 2733 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2734 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2735 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2736 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2737 %} 2738 2739 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2740 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2741 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2742 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2743 %} 2744 2745 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2746 Register src_reg = as_Register($src$$reg); 2747 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2748 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2749 %} 2750 2751 enc_class aarch64_enc_strb0(memory mem) %{ 2752 MacroAssembler _masm(&cbuf); 2753 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2754 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2755 %} 2756 2757 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2758 MacroAssembler _masm(&cbuf); 2759 __ membar(Assembler::StoreStore); 2760 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2761 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2762 %} 2763 2764 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2765 Register src_reg = as_Register($src$$reg); 2766 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2767 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2768 %} 2769 2770 enc_class aarch64_enc_strh0(memory mem) %{ 2771 MacroAssembler _masm(&cbuf); 2772 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2773 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2774 %} 2775 2776 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2777 Register src_reg = as_Register($src$$reg); 2778 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2779 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2780 %} 2781 2782 enc_class aarch64_enc_strw0(memory mem) %{ 2783 MacroAssembler _masm(&cbuf); 2784 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2785 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2786 %} 2787 2788 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2789 Register src_reg = as_Register($src$$reg); 2790 // we sometimes get asked to store the stack pointer into the 2791 // current thread -- we cannot do that directly on AArch64 2792 if (src_reg == r31_sp) { 2793 MacroAssembler _masm(&cbuf); 2794 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2795 __ mov(rscratch2, sp); 2796 src_reg = rscratch2; 2797 } 2798 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2799 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2800 %} 2801 2802 enc_class aarch64_enc_str0(memory mem) %{ 2803 MacroAssembler _masm(&cbuf); 2804 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2805 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2806 %} 2807 2808 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2809 FloatRegister src_reg = as_FloatRegister($src$$reg); 2810 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2811 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2812 %} 2813 2814 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2815 FloatRegister src_reg = as_FloatRegister($src$$reg); 2816 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2817 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2818 %} 2819 2820 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2821 FloatRegister src_reg = as_FloatRegister($src$$reg); 2822 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2823 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2824 %} 2825 2826 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2827 FloatRegister src_reg = as_FloatRegister($src$$reg); 2828 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2829 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2830 %} 2831 2832 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2833 FloatRegister src_reg = as_FloatRegister($src$$reg); 2834 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2835 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2836 %} 2837 2838 // END Non-volatile memory access 2839 2840 // volatile loads and stores 2841 2842 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2843 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2844 rscratch1, stlrb); 2845 %} 2846 2847 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2848 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2849 rscratch1, stlrh); 2850 %} 2851 2852 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2853 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2854 rscratch1, stlrw); 2855 %} 2856 2857 2858 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2859 Register dst_reg = as_Register($dst$$reg); 2860 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2861 rscratch1, ldarb); 2862 __ sxtbw(dst_reg, dst_reg); 2863 %} 2864 2865 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2866 Register dst_reg = as_Register($dst$$reg); 2867 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2868 rscratch1, ldarb); 2869 __ sxtb(dst_reg, dst_reg); 2870 %} 2871 2872 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2873 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2874 rscratch1, ldarb); 2875 %} 2876 2877 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2878 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2879 rscratch1, ldarb); 2880 %} 2881 2882 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2883 Register dst_reg = as_Register($dst$$reg); 2884 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2885 rscratch1, ldarh); 2886 __ sxthw(dst_reg, dst_reg); 2887 %} 2888 2889 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2890 Register dst_reg = as_Register($dst$$reg); 2891 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2892 rscratch1, ldarh); 2893 __ sxth(dst_reg, dst_reg); 2894 %} 2895 2896 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2897 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2898 rscratch1, ldarh); 2899 %} 2900 2901 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2902 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2903 rscratch1, ldarh); 2904 %} 2905 2906 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2907 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2908 rscratch1, ldarw); 2909 %} 2910 2911 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2912 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2913 rscratch1, ldarw); 2914 %} 2915 2916 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2917 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2918 rscratch1, ldar); 2919 %} 2920 2921 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2922 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2923 rscratch1, ldarw); 2924 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2925 %} 2926 2927 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2928 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2929 rscratch1, ldar); 2930 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2931 %} 2932 2933 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2934 Register src_reg = as_Register($src$$reg); 2935 // we sometimes get asked to store the stack pointer into the 2936 // current thread -- we cannot do that directly on AArch64 2937 if (src_reg == r31_sp) { 2938 MacroAssembler _masm(&cbuf); 2939 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2940 __ mov(rscratch2, sp); 2941 src_reg = rscratch2; 2942 } 2943 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2944 rscratch1, stlr); 2945 %} 2946 2947 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2948 { 2949 MacroAssembler _masm(&cbuf); 2950 FloatRegister src_reg = as_FloatRegister($src$$reg); 2951 __ fmovs(rscratch2, src_reg); 2952 } 2953 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2954 rscratch1, stlrw); 2955 %} 2956 2957 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2958 { 2959 MacroAssembler _masm(&cbuf); 2960 FloatRegister src_reg = as_FloatRegister($src$$reg); 2961 __ fmovd(rscratch2, src_reg); 2962 } 2963 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2964 rscratch1, stlr); 2965 %} 2966 2967 // synchronized read/update encodings 2968 2969 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2970 MacroAssembler _masm(&cbuf); 2971 Register dst_reg = as_Register($dst$$reg); 2972 Register base = as_Register($mem$$base); 2973 int index = $mem$$index; 2974 int scale = $mem$$scale; 2975 int disp = $mem$$disp; 2976 if (index == -1) { 2977 if (disp != 0) { 2978 __ lea(rscratch1, Address(base, disp)); 2979 __ ldaxr(dst_reg, rscratch1); 2980 } else { 2981 // TODO 2982 // should we ever get anything other than this case? 2983 __ ldaxr(dst_reg, base); 2984 } 2985 } else { 2986 Register index_reg = as_Register(index); 2987 if (disp == 0) { 2988 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2989 __ ldaxr(dst_reg, rscratch1); 2990 } else { 2991 __ lea(rscratch1, Address(base, disp)); 2992 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2993 __ ldaxr(dst_reg, rscratch1); 2994 } 2995 } 2996 %} 2997 2998 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2999 MacroAssembler _masm(&cbuf); 3000 Register src_reg = as_Register($src$$reg); 3001 Register base = as_Register($mem$$base); 3002 int index = $mem$$index; 3003 int scale = $mem$$scale; 3004 int disp = $mem$$disp; 3005 if (index == -1) { 3006 if (disp != 0) { 3007 __ lea(rscratch2, Address(base, disp)); 3008 __ stlxr(rscratch1, src_reg, rscratch2); 3009 } else { 3010 // TODO 3011 // should we ever get anything other than this case? 3012 __ stlxr(rscratch1, src_reg, base); 3013 } 3014 } else { 3015 Register index_reg = as_Register(index); 3016 if (disp == 0) { 3017 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3018 __ stlxr(rscratch1, src_reg, rscratch2); 3019 } else { 3020 __ lea(rscratch2, Address(base, disp)); 3021 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3022 __ stlxr(rscratch1, src_reg, rscratch2); 3023 } 3024 } 3025 __ cmpw(rscratch1, zr); 3026 %} 3027 3028 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3029 MacroAssembler _masm(&cbuf); 3030 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3031 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3032 Assembler::xword, /*acquire*/ false, /*release*/ true, 3033 /*weak*/ false, noreg); 3034 %} 3035 3036 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3037 MacroAssembler _masm(&cbuf); 3038 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3039 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3040 Assembler::word, /*acquire*/ false, /*release*/ true, 3041 /*weak*/ false, noreg); 3042 %} 3043 3044 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3045 MacroAssembler _masm(&cbuf); 3046 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3047 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3048 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3049 /*weak*/ false, noreg); 3050 %} 3051 3052 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3053 MacroAssembler _masm(&cbuf); 3054 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3055 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3056 Assembler::byte, /*acquire*/ false, /*release*/ true, 3057 /*weak*/ false, noreg); 3058 %} 3059 3060 3061 // The only difference between aarch64_enc_cmpxchg and 3062 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3063 // CompareAndSwap sequence to serve as a barrier on acquiring a 3064 // lock. 3065 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3066 MacroAssembler _masm(&cbuf); 3067 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3068 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3069 Assembler::xword, /*acquire*/ true, /*release*/ true, 3070 /*weak*/ false, noreg); 3071 %} 3072 3073 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3074 MacroAssembler _masm(&cbuf); 3075 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3076 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3077 Assembler::word, /*acquire*/ true, /*release*/ true, 3078 /*weak*/ false, noreg); 3079 %} 3080 3081 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3082 MacroAssembler _masm(&cbuf); 3083 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3084 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3085 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3086 /*weak*/ false, noreg); 3087 %} 3088 3089 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3090 MacroAssembler _masm(&cbuf); 3091 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3092 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3093 Assembler::byte, /*acquire*/ true, /*release*/ true, 3094 /*weak*/ false, noreg); 3095 %} 3096 3097 // auxiliary used for CompareAndSwapX to set result register 3098 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3099 MacroAssembler _masm(&cbuf); 3100 Register res_reg = as_Register($res$$reg); 3101 __ cset(res_reg, Assembler::EQ); 3102 %} 3103 3104 // prefetch encodings 3105 3106 enc_class aarch64_enc_prefetchw(memory mem) %{ 3107 MacroAssembler _masm(&cbuf); 3108 Register base = as_Register($mem$$base); 3109 int index = $mem$$index; 3110 int scale = $mem$$scale; 3111 int disp = $mem$$disp; 3112 if (index == -1) { 3113 __ prfm(Address(base, disp), PSTL1KEEP); 3114 } else { 3115 Register index_reg = as_Register(index); 3116 if (disp == 0) { 3117 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3118 } else { 3119 __ lea(rscratch1, Address(base, disp)); 3120 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3121 } 3122 } 3123 %} 3124 3125 /// mov envcodings 3126 3127 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3128 MacroAssembler _masm(&cbuf); 3129 u_int32_t con = (u_int32_t)$src$$constant; 3130 Register dst_reg = as_Register($dst$$reg); 3131 if (con == 0) { 3132 __ movw(dst_reg, zr); 3133 } else { 3134 __ movw(dst_reg, con); 3135 } 3136 %} 3137 3138 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3139 MacroAssembler _masm(&cbuf); 3140 Register dst_reg = as_Register($dst$$reg); 3141 u_int64_t con = (u_int64_t)$src$$constant; 3142 if (con == 0) { 3143 __ mov(dst_reg, zr); 3144 } else { 3145 __ mov(dst_reg, con); 3146 } 3147 %} 3148 3149 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3150 MacroAssembler _masm(&cbuf); 3151 Register dst_reg = as_Register($dst$$reg); 3152 address con = (address)$src$$constant; 3153 if (con == NULL || con == (address)1) { 3154 ShouldNotReachHere(); 3155 } else { 3156 relocInfo::relocType rtype = $src->constant_reloc(); 3157 if (rtype == relocInfo::oop_type) { 3158 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3159 } else if (rtype == relocInfo::metadata_type) { 3160 __ mov_metadata(dst_reg, (Metadata*)con); 3161 } else { 3162 assert(rtype == relocInfo::none, "unexpected reloc type"); 3163 if (con < (address)(uintptr_t)os::vm_page_size()) { 3164 __ mov(dst_reg, con); 3165 } else { 3166 unsigned long offset; 3167 __ adrp(dst_reg, con, offset); 3168 __ add(dst_reg, dst_reg, offset); 3169 } 3170 } 3171 } 3172 %} 3173 3174 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3175 MacroAssembler _masm(&cbuf); 3176 Register dst_reg = as_Register($dst$$reg); 3177 __ mov(dst_reg, zr); 3178 %} 3179 3180 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3181 MacroAssembler _masm(&cbuf); 3182 Register dst_reg = as_Register($dst$$reg); 3183 __ mov(dst_reg, (u_int64_t)1); 3184 %} 3185 3186 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3187 MacroAssembler _masm(&cbuf); 3188 address page = (address)$src$$constant; 3189 Register dst_reg = as_Register($dst$$reg); 3190 unsigned long off; 3191 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3192 assert(off == 0, "assumed offset == 0"); 3193 %} 3194 3195 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3196 MacroAssembler _masm(&cbuf); 3197 __ load_byte_map_base($dst$$Register); 3198 %} 3199 3200 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3201 MacroAssembler _masm(&cbuf); 3202 Register dst_reg = as_Register($dst$$reg); 3203 address con = (address)$src$$constant; 3204 if (con == NULL) { 3205 ShouldNotReachHere(); 3206 } else { 3207 relocInfo::relocType rtype = $src->constant_reloc(); 3208 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3209 __ set_narrow_oop(dst_reg, (jobject)con); 3210 } 3211 %} 3212 3213 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3214 MacroAssembler _masm(&cbuf); 3215 Register dst_reg = as_Register($dst$$reg); 3216 __ mov(dst_reg, zr); 3217 %} 3218 3219 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3220 MacroAssembler _masm(&cbuf); 3221 Register dst_reg = as_Register($dst$$reg); 3222 address con = (address)$src$$constant; 3223 if (con == NULL) { 3224 ShouldNotReachHere(); 3225 } else { 3226 relocInfo::relocType rtype = $src->constant_reloc(); 3227 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3228 __ set_narrow_klass(dst_reg, (Klass *)con); 3229 } 3230 %} 3231 3232 // arithmetic encodings 3233 3234 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3235 MacroAssembler _masm(&cbuf); 3236 Register dst_reg = as_Register($dst$$reg); 3237 Register src_reg = as_Register($src1$$reg); 3238 int32_t con = (int32_t)$src2$$constant; 3239 // add has primary == 0, subtract has primary == 1 3240 if ($primary) { con = -con; } 3241 if (con < 0) { 3242 __ subw(dst_reg, src_reg, -con); 3243 } else { 3244 __ addw(dst_reg, src_reg, con); 3245 } 3246 %} 3247 3248 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3249 MacroAssembler _masm(&cbuf); 3250 Register dst_reg = as_Register($dst$$reg); 3251 Register src_reg = as_Register($src1$$reg); 3252 int32_t con = (int32_t)$src2$$constant; 3253 // add has primary == 0, subtract has primary == 1 3254 if ($primary) { con = -con; } 3255 if (con < 0) { 3256 __ sub(dst_reg, src_reg, -con); 3257 } else { 3258 __ add(dst_reg, src_reg, con); 3259 } 3260 %} 3261 3262 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3263 MacroAssembler _masm(&cbuf); 3264 Register dst_reg = as_Register($dst$$reg); 3265 Register src1_reg = as_Register($src1$$reg); 3266 Register src2_reg = as_Register($src2$$reg); 3267 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3268 %} 3269 3270 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3271 MacroAssembler _masm(&cbuf); 3272 Register dst_reg = as_Register($dst$$reg); 3273 Register src1_reg = as_Register($src1$$reg); 3274 Register src2_reg = as_Register($src2$$reg); 3275 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3276 %} 3277 3278 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3279 MacroAssembler _masm(&cbuf); 3280 Register dst_reg = as_Register($dst$$reg); 3281 Register src1_reg = as_Register($src1$$reg); 3282 Register src2_reg = as_Register($src2$$reg); 3283 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3284 %} 3285 3286 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3287 MacroAssembler _masm(&cbuf); 3288 Register dst_reg = as_Register($dst$$reg); 3289 Register src1_reg = as_Register($src1$$reg); 3290 Register src2_reg = as_Register($src2$$reg); 3291 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3292 %} 3293 3294 // compare instruction encodings 3295 3296 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3297 MacroAssembler _masm(&cbuf); 3298 Register reg1 = as_Register($src1$$reg); 3299 Register reg2 = as_Register($src2$$reg); 3300 __ cmpw(reg1, reg2); 3301 %} 3302 3303 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3304 MacroAssembler _masm(&cbuf); 3305 Register reg = as_Register($src1$$reg); 3306 int32_t val = $src2$$constant; 3307 if (val >= 0) { 3308 __ subsw(zr, reg, val); 3309 } else { 3310 __ addsw(zr, reg, -val); 3311 } 3312 %} 3313 3314 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3315 MacroAssembler _masm(&cbuf); 3316 Register reg1 = as_Register($src1$$reg); 3317 u_int32_t val = (u_int32_t)$src2$$constant; 3318 __ movw(rscratch1, val); 3319 __ cmpw(reg1, rscratch1); 3320 %} 3321 3322 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3323 MacroAssembler _masm(&cbuf); 3324 Register reg1 = as_Register($src1$$reg); 3325 Register reg2 = as_Register($src2$$reg); 3326 __ cmp(reg1, reg2); 3327 %} 3328 3329 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3330 MacroAssembler _masm(&cbuf); 3331 Register reg = as_Register($src1$$reg); 3332 int64_t val = $src2$$constant; 3333 if (val >= 0) { 3334 __ subs(zr, reg, val); 3335 } else if (val != -val) { 3336 __ adds(zr, reg, -val); 3337 } else { 3338 // aargh, Long.MIN_VALUE is a special case 3339 __ orr(rscratch1, zr, (u_int64_t)val); 3340 __ subs(zr, reg, rscratch1); 3341 } 3342 %} 3343 3344 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3345 MacroAssembler _masm(&cbuf); 3346 Register reg1 = as_Register($src1$$reg); 3347 u_int64_t val = (u_int64_t)$src2$$constant; 3348 __ mov(rscratch1, val); 3349 __ cmp(reg1, rscratch1); 3350 %} 3351 3352 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3353 MacroAssembler _masm(&cbuf); 3354 Register reg1 = as_Register($src1$$reg); 3355 Register reg2 = as_Register($src2$$reg); 3356 __ cmp(reg1, reg2); 3357 %} 3358 3359 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3360 MacroAssembler _masm(&cbuf); 3361 Register reg1 = as_Register($src1$$reg); 3362 Register reg2 = as_Register($src2$$reg); 3363 __ cmpw(reg1, reg2); 3364 %} 3365 3366 enc_class aarch64_enc_testp(iRegP src) %{ 3367 MacroAssembler _masm(&cbuf); 3368 Register reg = as_Register($src$$reg); 3369 __ cmp(reg, zr); 3370 %} 3371 3372 enc_class aarch64_enc_testn(iRegN src) %{ 3373 MacroAssembler _masm(&cbuf); 3374 Register reg = as_Register($src$$reg); 3375 __ cmpw(reg, zr); 3376 %} 3377 3378 enc_class aarch64_enc_b(label lbl) %{ 3379 MacroAssembler _masm(&cbuf); 3380 Label *L = $lbl$$label; 3381 __ b(*L); 3382 %} 3383 3384 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3385 MacroAssembler _masm(&cbuf); 3386 Label *L = $lbl$$label; 3387 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3388 %} 3389 3390 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3391 MacroAssembler _masm(&cbuf); 3392 Label *L = $lbl$$label; 3393 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3394 %} 3395 3396 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3397 %{ 3398 Register sub_reg = as_Register($sub$$reg); 3399 Register super_reg = as_Register($super$$reg); 3400 Register temp_reg = as_Register($temp$$reg); 3401 Register result_reg = as_Register($result$$reg); 3402 3403 Label miss; 3404 MacroAssembler _masm(&cbuf); 3405 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3406 NULL, &miss, 3407 /*set_cond_codes:*/ true); 3408 if ($primary) { 3409 __ mov(result_reg, zr); 3410 } 3411 __ bind(miss); 3412 %} 3413 3414 enc_class aarch64_enc_java_static_call(method meth) %{ 3415 MacroAssembler _masm(&cbuf); 3416 3417 address addr = (address)$meth$$method; 3418 address call; 3419 if (!_method) { 3420 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3421 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3422 } else { 3423 int method_index = resolved_method_index(cbuf); 3424 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3425 : static_call_Relocation::spec(method_index); 3426 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3427 3428 // Emit stub for static call 3429 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3430 if (stub == NULL) { 3431 ciEnv::current()->record_failure("CodeCache is full"); 3432 return; 3433 } 3434 } 3435 if (call == NULL) { 3436 ciEnv::current()->record_failure("CodeCache is full"); 3437 return; 3438 } 3439 %} 3440 3441 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3442 MacroAssembler _masm(&cbuf); 3443 int method_index = resolved_method_index(cbuf); 3444 address call = __ ic_call((address)$meth$$method, method_index); 3445 if (call == NULL) { 3446 ciEnv::current()->record_failure("CodeCache is full"); 3447 return; 3448 } 3449 %} 3450 3451 enc_class aarch64_enc_call_epilog() %{ 3452 MacroAssembler _masm(&cbuf); 3453 if (VerifyStackAtCalls) { 3454 // Check that stack depth is unchanged: find majik cookie on stack 3455 __ call_Unimplemented(); 3456 } 3457 %} 3458 3459 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3460 MacroAssembler _masm(&cbuf); 3461 3462 // some calls to generated routines (arraycopy code) are scheduled 3463 // by C2 as runtime calls. if so we can call them using a br (they 3464 // will be in a reachable segment) otherwise we have to use a blr 3465 // which loads the absolute address into a register. 3466 address entry = (address)$meth$$method; 3467 CodeBlob *cb = CodeCache::find_blob(entry); 3468 if (cb) { 3469 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3470 if (call == NULL) { 3471 ciEnv::current()->record_failure("CodeCache is full"); 3472 return; 3473 } 3474 } else { 3475 Label retaddr; 3476 __ adr(rscratch2, retaddr); 3477 __ lea(rscratch1, RuntimeAddress(entry)); 3478 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3479 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3480 __ blr(rscratch1); 3481 __ bind(retaddr); 3482 __ add(sp, sp, 2 * wordSize); 3483 } 3484 %} 3485 3486 enc_class aarch64_enc_rethrow() %{ 3487 MacroAssembler _masm(&cbuf); 3488 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3489 %} 3490 3491 enc_class aarch64_enc_ret() %{ 3492 MacroAssembler _masm(&cbuf); 3493 __ ret(lr); 3494 %} 3495 3496 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3497 MacroAssembler _masm(&cbuf); 3498 Register target_reg = as_Register($jump_target$$reg); 3499 __ br(target_reg); 3500 %} 3501 3502 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3503 MacroAssembler _masm(&cbuf); 3504 Register target_reg = as_Register($jump_target$$reg); 3505 // exception oop should be in r0 3506 // ret addr has been popped into lr 3507 // callee expects it in r3 3508 __ mov(r3, lr); 3509 __ br(target_reg); 3510 %} 3511 3512 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3513 MacroAssembler _masm(&cbuf); 3514 Register oop = as_Register($object$$reg); 3515 Register box = as_Register($box$$reg); 3516 Register disp_hdr = as_Register($tmp$$reg); 3517 Register tmp = as_Register($tmp2$$reg); 3518 Label cont; 3519 Label object_has_monitor; 3520 Label cas_failed; 3521 3522 assert_different_registers(oop, box, tmp, disp_hdr); 3523 3524 // Load markWord from object into displaced_header. 3525 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3526 3527 if (UseBiasedLocking && !UseOptoBiasInlining) { 3528 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3529 } 3530 3531 // Check for existing monitor 3532 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3533 3534 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3535 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3536 3537 // Initialize the box. (Must happen before we update the object mark!) 3538 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3539 3540 // Compare object markWord with an unlocked value (tmp) and if 3541 // equal exchange the stack address of our box with object markWord. 3542 // On failure disp_hdr contains the possibly locked markWord. 3543 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3544 /*release*/ true, /*weak*/ false, disp_hdr); 3545 __ br(Assembler::EQ, cont); 3546 3547 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3548 3549 // If the compare-and-exchange succeeded, then we found an unlocked 3550 // object, will have now locked it will continue at label cont 3551 3552 __ bind(cas_failed); 3553 // We did not see an unlocked object so try the fast recursive case. 3554 3555 // Check if the owner is self by comparing the value in the 3556 // markWord of object (disp_hdr) with the stack pointer. 3557 __ mov(rscratch1, sp); 3558 __ sub(disp_hdr, disp_hdr, rscratch1); 3559 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3560 // If condition is true we are cont and hence we can store 0 as the 3561 // displaced header in the box, which indicates that it is a recursive lock. 3562 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3563 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3564 3565 __ b(cont); 3566 3567 // Handle existing monitor. 3568 __ bind(object_has_monitor); 3569 3570 // The object's monitor m is unlocked iff m->owner == NULL, 3571 // otherwise m->owner may contain a thread or a stack address. 3572 // 3573 // Try to CAS m->owner from NULL to current thread. 3574 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3575 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3576 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3577 3578 // Store a non-null value into the box to avoid looking like a re-entrant 3579 // lock. The fast-path monitor unlock code checks for 3580 // markWord::monitor_value so use markWord::unused_mark which has the 3581 // relevant bit set, and also matches ObjectSynchronizer::enter. 3582 __ mov(tmp, (address)markWord::unused_mark().value()); 3583 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3584 3585 __ bind(cont); 3586 // flag == EQ indicates success 3587 // flag == NE indicates failure 3588 %} 3589 3590 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3591 MacroAssembler _masm(&cbuf); 3592 Register oop = as_Register($object$$reg); 3593 Register box = as_Register($box$$reg); 3594 Register disp_hdr = as_Register($tmp$$reg); 3595 Register tmp = as_Register($tmp2$$reg); 3596 Label cont; 3597 Label object_has_monitor; 3598 3599 assert_different_registers(oop, box, tmp, disp_hdr); 3600 3601 if (UseBiasedLocking && !UseOptoBiasInlining) { 3602 __ biased_locking_exit(oop, tmp, cont); 3603 } 3604 3605 // Find the lock address and load the displaced header from the stack. 3606 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3607 3608 // If the displaced header is 0, we have a recursive unlock. 3609 __ cmp(disp_hdr, zr); 3610 __ br(Assembler::EQ, cont); 3611 3612 // Handle existing monitor. 3613 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3614 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3615 3616 // Check if it is still a light weight lock, this is is true if we 3617 // see the stack address of the basicLock in the markWord of the 3618 // object. 3619 3620 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3621 /*release*/ true, /*weak*/ false, tmp); 3622 __ b(cont); 3623 3624 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3625 3626 // Handle existing monitor. 3627 __ bind(object_has_monitor); 3628 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3629 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3630 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3631 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3632 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3633 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3634 __ cmp(rscratch1, zr); // Sets flags for result 3635 __ br(Assembler::NE, cont); 3636 3637 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3638 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3639 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3640 __ cmp(rscratch1, zr); // Sets flags for result 3641 __ cbnz(rscratch1, cont); 3642 // need a release store here 3643 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3644 __ stlr(zr, tmp); // set unowned 3645 3646 __ bind(cont); 3647 // flag == EQ indicates success 3648 // flag == NE indicates failure 3649 %} 3650 3651 %} 3652 3653 //----------FRAME-------------------------------------------------------------- 3654 // Definition of frame structure and management information. 3655 // 3656 // S T A C K L A Y O U T Allocators stack-slot number 3657 // | (to get allocators register number 3658 // G Owned by | | v add OptoReg::stack0()) 3659 // r CALLER | | 3660 // o | +--------+ pad to even-align allocators stack-slot 3661 // w V | pad0 | numbers; owned by CALLER 3662 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3663 // h ^ | in | 5 3664 // | | args | 4 Holes in incoming args owned by SELF 3665 // | | | | 3 3666 // | | +--------+ 3667 // V | | old out| Empty on Intel, window on Sparc 3668 // | old |preserve| Must be even aligned. 3669 // | SP-+--------+----> Matcher::_old_SP, even aligned 3670 // | | in | 3 area for Intel ret address 3671 // Owned by |preserve| Empty on Sparc. 3672 // SELF +--------+ 3673 // | | pad2 | 2 pad to align old SP 3674 // | +--------+ 1 3675 // | | locks | 0 3676 // | +--------+----> OptoReg::stack0(), even aligned 3677 // | | pad1 | 11 pad to align new SP 3678 // | +--------+ 3679 // | | | 10 3680 // | | spills | 9 spills 3681 // V | | 8 (pad0 slot for callee) 3682 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3683 // ^ | out | 7 3684 // | | args | 6 Holes in outgoing args owned by CALLEE 3685 // Owned by +--------+ 3686 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3687 // | new |preserve| Must be even-aligned. 3688 // | SP-+--------+----> Matcher::_new_SP, even aligned 3689 // | | | 3690 // 3691 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3692 // known from SELF's arguments and the Java calling convention. 3693 // Region 6-7 is determined per call site. 3694 // Note 2: If the calling convention leaves holes in the incoming argument 3695 // area, those holes are owned by SELF. Holes in the outgoing area 3696 // are owned by the CALLEE. Holes should not be nessecary in the 3697 // incoming area, as the Java calling convention is completely under 3698 // the control of the AD file. Doubles can be sorted and packed to 3699 // avoid holes. Holes in the outgoing arguments may be nessecary for 3700 // varargs C calling conventions. 3701 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3702 // even aligned with pad0 as needed. 3703 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3704 // (the latter is true on Intel but is it false on AArch64?) 3705 // region 6-11 is even aligned; it may be padded out more so that 3706 // the region from SP to FP meets the minimum stack alignment. 3707 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3708 // alignment. Region 11, pad1, may be dynamically extended so that 3709 // SP meets the minimum alignment. 3710 3711 frame %{ 3712 // What direction does stack grow in (assumed to be same for C & Java) 3713 stack_direction(TOWARDS_LOW); 3714 3715 // These three registers define part of the calling convention 3716 // between compiled code and the interpreter. 3717 3718 // Inline Cache Register or methodOop for I2C. 3719 inline_cache_reg(R12); 3720 3721 // Method Oop Register when calling interpreter. 3722 interpreter_method_oop_reg(R12); 3723 3724 // Number of stack slots consumed by locking an object 3725 sync_stack_slots(2); 3726 3727 // Compiled code's Frame Pointer 3728 frame_pointer(R31); 3729 3730 // Interpreter stores its frame pointer in a register which is 3731 // stored to the stack by I2CAdaptors. 3732 // I2CAdaptors convert from interpreted java to compiled java. 3733 interpreter_frame_pointer(R29); 3734 3735 // Stack alignment requirement 3736 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3737 3738 // Number of stack slots between incoming argument block and the start of 3739 // a new frame. The PROLOG must add this many slots to the stack. The 3740 // EPILOG must remove this many slots. aarch64 needs two slots for 3741 // return address and fp. 3742 // TODO think this is correct but check 3743 in_preserve_stack_slots(4); 3744 3745 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3746 // for calls to C. Supports the var-args backing area for register parms. 3747 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3748 3749 // The after-PROLOG location of the return address. Location of 3750 // return address specifies a type (REG or STACK) and a number 3751 // representing the register number (i.e. - use a register name) or 3752 // stack slot. 3753 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3754 // Otherwise, it is above the locks and verification slot and alignment word 3755 // TODO this may well be correct but need to check why that - 2 is there 3756 // ppc port uses 0 but we definitely need to allow for fixed_slots 3757 // which folds in the space used for monitors 3758 return_addr(STACK - 2 + 3759 align_up((Compile::current()->in_preserve_stack_slots() + 3760 Compile::current()->fixed_slots()), 3761 stack_alignment_in_slots())); 3762 3763 // Body of function which returns an integer array locating 3764 // arguments either in registers or in stack slots. Passed an array 3765 // of ideal registers called "sig" and a "length" count. Stack-slot 3766 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3767 // arguments for a CALLEE. Incoming stack arguments are 3768 // automatically biased by the preserve_stack_slots field above. 3769 3770 calling_convention 3771 %{ 3772 // No difference between ingoing/outgoing just pass false 3773 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3774 %} 3775 3776 c_calling_convention 3777 %{ 3778 // This is obviously always outgoing 3779 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3780 %} 3781 3782 // Location of compiled Java return values. Same as C for now. 3783 return_value 3784 %{ 3785 // TODO do we allow ideal_reg == Op_RegN??? 3786 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3787 "only return normal values"); 3788 3789 static const int lo[Op_RegL + 1] = { // enum name 3790 0, // Op_Node 3791 0, // Op_Set 3792 R0_num, // Op_RegN 3793 R0_num, // Op_RegI 3794 R0_num, // Op_RegP 3795 V0_num, // Op_RegF 3796 V0_num, // Op_RegD 3797 R0_num // Op_RegL 3798 }; 3799 3800 static const int hi[Op_RegL + 1] = { // enum name 3801 0, // Op_Node 3802 0, // Op_Set 3803 OptoReg::Bad, // Op_RegN 3804 OptoReg::Bad, // Op_RegI 3805 R0_H_num, // Op_RegP 3806 OptoReg::Bad, // Op_RegF 3807 V0_H_num, // Op_RegD 3808 R0_H_num // Op_RegL 3809 }; 3810 3811 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3812 %} 3813 %} 3814 3815 //----------ATTRIBUTES--------------------------------------------------------- 3816 //----------Operand Attributes------------------------------------------------- 3817 op_attrib op_cost(1); // Required cost attribute 3818 3819 //----------Instruction Attributes--------------------------------------------- 3820 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3821 ins_attrib ins_size(32); // Required size attribute (in bits) 3822 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3823 // a non-matching short branch variant 3824 // of some long branch? 3825 ins_attrib ins_alignment(4); // Required alignment attribute (must 3826 // be a power of 2) specifies the 3827 // alignment that some part of the 3828 // instruction (not necessarily the 3829 // start) requires. If > 1, a 3830 // compute_padding() function must be 3831 // provided for the instruction 3832 3833 //----------OPERANDS----------------------------------------------------------- 3834 // Operand definitions must precede instruction definitions for correct parsing 3835 // in the ADLC because operands constitute user defined types which are used in 3836 // instruction definitions. 3837 3838 //----------Simple Operands---------------------------------------------------- 3839 3840 // Integer operands 32 bit 3841 // 32 bit immediate 3842 operand immI() 3843 %{ 3844 match(ConI); 3845 3846 op_cost(0); 3847 format %{ %} 3848 interface(CONST_INTER); 3849 %} 3850 3851 // 32 bit zero 3852 operand immI0() 3853 %{ 3854 predicate(n->get_int() == 0); 3855 match(ConI); 3856 3857 op_cost(0); 3858 format %{ %} 3859 interface(CONST_INTER); 3860 %} 3861 3862 // 32 bit unit increment 3863 operand immI_1() 3864 %{ 3865 predicate(n->get_int() == 1); 3866 match(ConI); 3867 3868 op_cost(0); 3869 format %{ %} 3870 interface(CONST_INTER); 3871 %} 3872 3873 // 32 bit unit decrement 3874 operand immI_M1() 3875 %{ 3876 predicate(n->get_int() == -1); 3877 match(ConI); 3878 3879 op_cost(0); 3880 format %{ %} 3881 interface(CONST_INTER); 3882 %} 3883 3884 // Shift values for add/sub extension shift 3885 operand immIExt() 3886 %{ 3887 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3888 match(ConI); 3889 3890 op_cost(0); 3891 format %{ %} 3892 interface(CONST_INTER); 3893 %} 3894 3895 operand immI_le_4() 3896 %{ 3897 predicate(n->get_int() <= 4); 3898 match(ConI); 3899 3900 op_cost(0); 3901 format %{ %} 3902 interface(CONST_INTER); 3903 %} 3904 3905 operand immI_31() 3906 %{ 3907 predicate(n->get_int() == 31); 3908 match(ConI); 3909 3910 op_cost(0); 3911 format %{ %} 3912 interface(CONST_INTER); 3913 %} 3914 3915 operand immI_8() 3916 %{ 3917 predicate(n->get_int() == 8); 3918 match(ConI); 3919 3920 op_cost(0); 3921 format %{ %} 3922 interface(CONST_INTER); 3923 %} 3924 3925 operand immI_16() 3926 %{ 3927 predicate(n->get_int() == 16); 3928 match(ConI); 3929 3930 op_cost(0); 3931 format %{ %} 3932 interface(CONST_INTER); 3933 %} 3934 3935 operand immI_24() 3936 %{ 3937 predicate(n->get_int() == 24); 3938 match(ConI); 3939 3940 op_cost(0); 3941 format %{ %} 3942 interface(CONST_INTER); 3943 %} 3944 3945 operand immI_32() 3946 %{ 3947 predicate(n->get_int() == 32); 3948 match(ConI); 3949 3950 op_cost(0); 3951 format %{ %} 3952 interface(CONST_INTER); 3953 %} 3954 3955 operand immI_48() 3956 %{ 3957 predicate(n->get_int() == 48); 3958 match(ConI); 3959 3960 op_cost(0); 3961 format %{ %} 3962 interface(CONST_INTER); 3963 %} 3964 3965 operand immI_56() 3966 %{ 3967 predicate(n->get_int() == 56); 3968 match(ConI); 3969 3970 op_cost(0); 3971 format %{ %} 3972 interface(CONST_INTER); 3973 %} 3974 3975 operand immI_63() 3976 %{ 3977 predicate(n->get_int() == 63); 3978 match(ConI); 3979 3980 op_cost(0); 3981 format %{ %} 3982 interface(CONST_INTER); 3983 %} 3984 3985 operand immI_64() 3986 %{ 3987 predicate(n->get_int() == 64); 3988 match(ConI); 3989 3990 op_cost(0); 3991 format %{ %} 3992 interface(CONST_INTER); 3993 %} 3994 3995 operand immI_255() 3996 %{ 3997 predicate(n->get_int() == 255); 3998 match(ConI); 3999 4000 op_cost(0); 4001 format %{ %} 4002 interface(CONST_INTER); 4003 %} 4004 4005 operand immI_65535() 4006 %{ 4007 predicate(n->get_int() == 65535); 4008 match(ConI); 4009 4010 op_cost(0); 4011 format %{ %} 4012 interface(CONST_INTER); 4013 %} 4014 4015 operand immL_255() 4016 %{ 4017 predicate(n->get_long() == 255L); 4018 match(ConL); 4019 4020 op_cost(0); 4021 format %{ %} 4022 interface(CONST_INTER); 4023 %} 4024 4025 operand immL_65535() 4026 %{ 4027 predicate(n->get_long() == 65535L); 4028 match(ConL); 4029 4030 op_cost(0); 4031 format %{ %} 4032 interface(CONST_INTER); 4033 %} 4034 4035 operand immL_4294967295() 4036 %{ 4037 predicate(n->get_long() == 4294967295L); 4038 match(ConL); 4039 4040 op_cost(0); 4041 format %{ %} 4042 interface(CONST_INTER); 4043 %} 4044 4045 operand immL_bitmask() 4046 %{ 4047 predicate((n->get_long() != 0) 4048 && ((n->get_long() & 0xc000000000000000l) == 0) 4049 && is_power_of_2(n->get_long() + 1)); 4050 match(ConL); 4051 4052 op_cost(0); 4053 format %{ %} 4054 interface(CONST_INTER); 4055 %} 4056 4057 operand immI_bitmask() 4058 %{ 4059 predicate((n->get_int() != 0) 4060 && ((n->get_int() & 0xc0000000) == 0) 4061 && is_power_of_2(n->get_int() + 1)); 4062 match(ConI); 4063 4064 op_cost(0); 4065 format %{ %} 4066 interface(CONST_INTER); 4067 %} 4068 4069 // Scale values for scaled offset addressing modes (up to long but not quad) 4070 operand immIScale() 4071 %{ 4072 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4073 match(ConI); 4074 4075 op_cost(0); 4076 format %{ %} 4077 interface(CONST_INTER); 4078 %} 4079 4080 // 26 bit signed offset -- for pc-relative branches 4081 operand immI26() 4082 %{ 4083 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4084 match(ConI); 4085 4086 op_cost(0); 4087 format %{ %} 4088 interface(CONST_INTER); 4089 %} 4090 4091 // 19 bit signed offset -- for pc-relative loads 4092 operand immI19() 4093 %{ 4094 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4095 match(ConI); 4096 4097 op_cost(0); 4098 format %{ %} 4099 interface(CONST_INTER); 4100 %} 4101 4102 // 12 bit unsigned offset -- for base plus immediate loads 4103 operand immIU12() 4104 %{ 4105 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4106 match(ConI); 4107 4108 op_cost(0); 4109 format %{ %} 4110 interface(CONST_INTER); 4111 %} 4112 4113 operand immLU12() 4114 %{ 4115 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4116 match(ConL); 4117 4118 op_cost(0); 4119 format %{ %} 4120 interface(CONST_INTER); 4121 %} 4122 4123 // Offset for scaled or unscaled immediate loads and stores 4124 operand immIOffset() 4125 %{ 4126 predicate(Address::offset_ok_for_immed(n->get_int())); 4127 match(ConI); 4128 4129 op_cost(0); 4130 format %{ %} 4131 interface(CONST_INTER); 4132 %} 4133 4134 operand immIOffset4() 4135 %{ 4136 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4137 match(ConI); 4138 4139 op_cost(0); 4140 format %{ %} 4141 interface(CONST_INTER); 4142 %} 4143 4144 operand immIOffset8() 4145 %{ 4146 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4147 match(ConI); 4148 4149 op_cost(0); 4150 format %{ %} 4151 interface(CONST_INTER); 4152 %} 4153 4154 operand immIOffset16() 4155 %{ 4156 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4157 match(ConI); 4158 4159 op_cost(0); 4160 format %{ %} 4161 interface(CONST_INTER); 4162 %} 4163 4164 operand immLoffset() 4165 %{ 4166 predicate(Address::offset_ok_for_immed(n->get_long())); 4167 match(ConL); 4168 4169 op_cost(0); 4170 format %{ %} 4171 interface(CONST_INTER); 4172 %} 4173 4174 operand immLoffset4() 4175 %{ 4176 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4177 match(ConL); 4178 4179 op_cost(0); 4180 format %{ %} 4181 interface(CONST_INTER); 4182 %} 4183 4184 operand immLoffset8() 4185 %{ 4186 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4187 match(ConL); 4188 4189 op_cost(0); 4190 format %{ %} 4191 interface(CONST_INTER); 4192 %} 4193 4194 operand immLoffset16() 4195 %{ 4196 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4197 match(ConL); 4198 4199 op_cost(0); 4200 format %{ %} 4201 interface(CONST_INTER); 4202 %} 4203 4204 // 32 bit integer valid for add sub immediate 4205 operand immIAddSub() 4206 %{ 4207 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4208 match(ConI); 4209 op_cost(0); 4210 format %{ %} 4211 interface(CONST_INTER); 4212 %} 4213 4214 // 32 bit unsigned integer valid for logical immediate 4215 // TODO -- check this is right when e.g the mask is 0x80000000 4216 operand immILog() 4217 %{ 4218 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4219 match(ConI); 4220 4221 op_cost(0); 4222 format %{ %} 4223 interface(CONST_INTER); 4224 %} 4225 4226 // Integer operands 64 bit 4227 // 64 bit immediate 4228 operand immL() 4229 %{ 4230 match(ConL); 4231 4232 op_cost(0); 4233 format %{ %} 4234 interface(CONST_INTER); 4235 %} 4236 4237 // 64 bit zero 4238 operand immL0() 4239 %{ 4240 predicate(n->get_long() == 0); 4241 match(ConL); 4242 4243 op_cost(0); 4244 format %{ %} 4245 interface(CONST_INTER); 4246 %} 4247 4248 // 64 bit unit increment 4249 operand immL_1() 4250 %{ 4251 predicate(n->get_long() == 1); 4252 match(ConL); 4253 4254 op_cost(0); 4255 format %{ %} 4256 interface(CONST_INTER); 4257 %} 4258 4259 // 64 bit unit decrement 4260 operand immL_M1() 4261 %{ 4262 predicate(n->get_long() == -1); 4263 match(ConL); 4264 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 // 32 bit offset of pc in thread anchor 4271 4272 operand immL_pc_off() 4273 %{ 4274 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4275 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4276 match(ConL); 4277 4278 op_cost(0); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // 64 bit integer valid for add sub immediate 4284 operand immLAddSub() 4285 %{ 4286 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4287 match(ConL); 4288 op_cost(0); 4289 format %{ %} 4290 interface(CONST_INTER); 4291 %} 4292 4293 // 64 bit integer valid for logical immediate 4294 operand immLLog() 4295 %{ 4296 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4297 match(ConL); 4298 op_cost(0); 4299 format %{ %} 4300 interface(CONST_INTER); 4301 %} 4302 4303 // Long Immediate: low 32-bit mask 4304 operand immL_32bits() 4305 %{ 4306 predicate(n->get_long() == 0xFFFFFFFFL); 4307 match(ConL); 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 // Pointer operands 4314 // Pointer Immediate 4315 operand immP() 4316 %{ 4317 match(ConP); 4318 4319 op_cost(0); 4320 format %{ %} 4321 interface(CONST_INTER); 4322 %} 4323 4324 // NULL Pointer Immediate 4325 operand immP0() 4326 %{ 4327 predicate(n->get_ptr() == 0); 4328 match(ConP); 4329 4330 op_cost(0); 4331 format %{ %} 4332 interface(CONST_INTER); 4333 %} 4334 4335 // Pointer Immediate One 4336 // this is used in object initialization (initial object header) 4337 operand immP_1() 4338 %{ 4339 predicate(n->get_ptr() == 1); 4340 match(ConP); 4341 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Polling Page Pointer Immediate 4348 operand immPollPage() 4349 %{ 4350 predicate((address)n->get_ptr() == os::get_polling_page()); 4351 match(ConP); 4352 4353 op_cost(0); 4354 format %{ %} 4355 interface(CONST_INTER); 4356 %} 4357 4358 // Card Table Byte Map Base 4359 operand immByteMapBase() 4360 %{ 4361 // Get base of card map 4362 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4363 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4364 match(ConP); 4365 4366 op_cost(0); 4367 format %{ %} 4368 interface(CONST_INTER); 4369 %} 4370 4371 // Pointer Immediate Minus One 4372 // this is used when we want to write the current PC to the thread anchor 4373 operand immP_M1() 4374 %{ 4375 predicate(n->get_ptr() == -1); 4376 match(ConP); 4377 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // Pointer Immediate Minus Two 4384 // this is used when we want to write the current PC to the thread anchor 4385 operand immP_M2() 4386 %{ 4387 predicate(n->get_ptr() == -2); 4388 match(ConP); 4389 4390 op_cost(0); 4391 format %{ %} 4392 interface(CONST_INTER); 4393 %} 4394 4395 // Float and Double operands 4396 // Double Immediate 4397 operand immD() 4398 %{ 4399 match(ConD); 4400 op_cost(0); 4401 format %{ %} 4402 interface(CONST_INTER); 4403 %} 4404 4405 // Double Immediate: +0.0d 4406 operand immD0() 4407 %{ 4408 predicate(jlong_cast(n->getd()) == 0); 4409 match(ConD); 4410 4411 op_cost(0); 4412 format %{ %} 4413 interface(CONST_INTER); 4414 %} 4415 4416 // constant 'double +0.0'. 4417 operand immDPacked() 4418 %{ 4419 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4420 match(ConD); 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 // Float Immediate 4427 operand immF() 4428 %{ 4429 match(ConF); 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 // Float Immediate: +0.0f. 4436 operand immF0() 4437 %{ 4438 predicate(jint_cast(n->getf()) == 0); 4439 match(ConF); 4440 4441 op_cost(0); 4442 format %{ %} 4443 interface(CONST_INTER); 4444 %} 4445 4446 // 4447 operand immFPacked() 4448 %{ 4449 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4450 match(ConF); 4451 op_cost(0); 4452 format %{ %} 4453 interface(CONST_INTER); 4454 %} 4455 4456 // Narrow pointer operands 4457 // Narrow Pointer Immediate 4458 operand immN() 4459 %{ 4460 match(ConN); 4461 4462 op_cost(0); 4463 format %{ %} 4464 interface(CONST_INTER); 4465 %} 4466 4467 // Narrow NULL Pointer Immediate 4468 operand immN0() 4469 %{ 4470 predicate(n->get_narrowcon() == 0); 4471 match(ConN); 4472 4473 op_cost(0); 4474 format %{ %} 4475 interface(CONST_INTER); 4476 %} 4477 4478 operand immNKlass() 4479 %{ 4480 match(ConNKlass); 4481 4482 op_cost(0); 4483 format %{ %} 4484 interface(CONST_INTER); 4485 %} 4486 4487 // Integer 32 bit Register Operands 4488 // Integer 32 bitRegister (excludes SP) 4489 operand iRegI() 4490 %{ 4491 constraint(ALLOC_IN_RC(any_reg32)); 4492 match(RegI); 4493 match(iRegINoSp); 4494 op_cost(0); 4495 format %{ %} 4496 interface(REG_INTER); 4497 %} 4498 4499 // Integer 32 bit Register not Special 4500 operand iRegINoSp() 4501 %{ 4502 constraint(ALLOC_IN_RC(no_special_reg32)); 4503 match(RegI); 4504 op_cost(0); 4505 format %{ %} 4506 interface(REG_INTER); 4507 %} 4508 4509 // Integer 64 bit Register Operands 4510 // Integer 64 bit Register (includes SP) 4511 operand iRegL() 4512 %{ 4513 constraint(ALLOC_IN_RC(any_reg)); 4514 match(RegL); 4515 match(iRegLNoSp); 4516 op_cost(0); 4517 format %{ %} 4518 interface(REG_INTER); 4519 %} 4520 4521 // Integer 64 bit Register not Special 4522 operand iRegLNoSp() 4523 %{ 4524 constraint(ALLOC_IN_RC(no_special_reg)); 4525 match(RegL); 4526 match(iRegL_R0); 4527 format %{ %} 4528 interface(REG_INTER); 4529 %} 4530 4531 // Pointer Register Operands 4532 // Pointer Register 4533 operand iRegP() 4534 %{ 4535 constraint(ALLOC_IN_RC(ptr_reg)); 4536 match(RegP); 4537 match(iRegPNoSp); 4538 match(iRegP_R0); 4539 //match(iRegP_R2); 4540 //match(iRegP_R4); 4541 //match(iRegP_R5); 4542 match(thread_RegP); 4543 op_cost(0); 4544 format %{ %} 4545 interface(REG_INTER); 4546 %} 4547 4548 // Pointer 64 bit Register not Special 4549 operand iRegPNoSp() 4550 %{ 4551 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4552 match(RegP); 4553 // match(iRegP); 4554 // match(iRegP_R0); 4555 // match(iRegP_R2); 4556 // match(iRegP_R4); 4557 // match(iRegP_R5); 4558 // match(thread_RegP); 4559 op_cost(0); 4560 format %{ %} 4561 interface(REG_INTER); 4562 %} 4563 4564 // Pointer 64 bit Register R0 only 4565 operand iRegP_R0() 4566 %{ 4567 constraint(ALLOC_IN_RC(r0_reg)); 4568 match(RegP); 4569 // match(iRegP); 4570 match(iRegPNoSp); 4571 op_cost(0); 4572 format %{ %} 4573 interface(REG_INTER); 4574 %} 4575 4576 // Pointer 64 bit Register R1 only 4577 operand iRegP_R1() 4578 %{ 4579 constraint(ALLOC_IN_RC(r1_reg)); 4580 match(RegP); 4581 // match(iRegP); 4582 match(iRegPNoSp); 4583 op_cost(0); 4584 format %{ %} 4585 interface(REG_INTER); 4586 %} 4587 4588 // Pointer 64 bit Register R2 only 4589 operand iRegP_R2() 4590 %{ 4591 constraint(ALLOC_IN_RC(r2_reg)); 4592 match(RegP); 4593 // match(iRegP); 4594 match(iRegPNoSp); 4595 op_cost(0); 4596 format %{ %} 4597 interface(REG_INTER); 4598 %} 4599 4600 // Pointer 64 bit Register R3 only 4601 operand iRegP_R3() 4602 %{ 4603 constraint(ALLOC_IN_RC(r3_reg)); 4604 match(RegP); 4605 // match(iRegP); 4606 match(iRegPNoSp); 4607 op_cost(0); 4608 format %{ %} 4609 interface(REG_INTER); 4610 %} 4611 4612 // Pointer 64 bit Register R4 only 4613 operand iRegP_R4() 4614 %{ 4615 constraint(ALLOC_IN_RC(r4_reg)); 4616 match(RegP); 4617 // match(iRegP); 4618 match(iRegPNoSp); 4619 op_cost(0); 4620 format %{ %} 4621 interface(REG_INTER); 4622 %} 4623 4624 // Pointer 64 bit Register R5 only 4625 operand iRegP_R5() 4626 %{ 4627 constraint(ALLOC_IN_RC(r5_reg)); 4628 match(RegP); 4629 // match(iRegP); 4630 match(iRegPNoSp); 4631 op_cost(0); 4632 format %{ %} 4633 interface(REG_INTER); 4634 %} 4635 4636 // Pointer 64 bit Register R10 only 4637 operand iRegP_R10() 4638 %{ 4639 constraint(ALLOC_IN_RC(r10_reg)); 4640 match(RegP); 4641 // match(iRegP); 4642 match(iRegPNoSp); 4643 op_cost(0); 4644 format %{ %} 4645 interface(REG_INTER); 4646 %} 4647 4648 // Long 64 bit Register R0 only 4649 operand iRegL_R0() 4650 %{ 4651 constraint(ALLOC_IN_RC(r0_reg)); 4652 match(RegL); 4653 match(iRegLNoSp); 4654 op_cost(0); 4655 format %{ %} 4656 interface(REG_INTER); 4657 %} 4658 4659 // Long 64 bit Register R2 only 4660 operand iRegL_R2() 4661 %{ 4662 constraint(ALLOC_IN_RC(r2_reg)); 4663 match(RegL); 4664 match(iRegLNoSp); 4665 op_cost(0); 4666 format %{ %} 4667 interface(REG_INTER); 4668 %} 4669 4670 // Long 64 bit Register R3 only 4671 operand iRegL_R3() 4672 %{ 4673 constraint(ALLOC_IN_RC(r3_reg)); 4674 match(RegL); 4675 match(iRegLNoSp); 4676 op_cost(0); 4677 format %{ %} 4678 interface(REG_INTER); 4679 %} 4680 4681 // Long 64 bit Register R11 only 4682 operand iRegL_R11() 4683 %{ 4684 constraint(ALLOC_IN_RC(r11_reg)); 4685 match(RegL); 4686 match(iRegLNoSp); 4687 op_cost(0); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 // Pointer 64 bit Register FP only 4693 operand iRegP_FP() 4694 %{ 4695 constraint(ALLOC_IN_RC(fp_reg)); 4696 match(RegP); 4697 // match(iRegP); 4698 op_cost(0); 4699 format %{ %} 4700 interface(REG_INTER); 4701 %} 4702 4703 // Register R0 only 4704 operand iRegI_R0() 4705 %{ 4706 constraint(ALLOC_IN_RC(int_r0_reg)); 4707 match(RegI); 4708 match(iRegINoSp); 4709 op_cost(0); 4710 format %{ %} 4711 interface(REG_INTER); 4712 %} 4713 4714 // Register R2 only 4715 operand iRegI_R2() 4716 %{ 4717 constraint(ALLOC_IN_RC(int_r2_reg)); 4718 match(RegI); 4719 match(iRegINoSp); 4720 op_cost(0); 4721 format %{ %} 4722 interface(REG_INTER); 4723 %} 4724 4725 // Register R3 only 4726 operand iRegI_R3() 4727 %{ 4728 constraint(ALLOC_IN_RC(int_r3_reg)); 4729 match(RegI); 4730 match(iRegINoSp); 4731 op_cost(0); 4732 format %{ %} 4733 interface(REG_INTER); 4734 %} 4735 4736 4737 // Register R4 only 4738 operand iRegI_R4() 4739 %{ 4740 constraint(ALLOC_IN_RC(int_r4_reg)); 4741 match(RegI); 4742 match(iRegINoSp); 4743 op_cost(0); 4744 format %{ %} 4745 interface(REG_INTER); 4746 %} 4747 4748 4749 // Pointer Register Operands 4750 // Narrow Pointer Register 4751 operand iRegN() 4752 %{ 4753 constraint(ALLOC_IN_RC(any_reg32)); 4754 match(RegN); 4755 match(iRegNNoSp); 4756 op_cost(0); 4757 format %{ %} 4758 interface(REG_INTER); 4759 %} 4760 4761 operand iRegN_R0() 4762 %{ 4763 constraint(ALLOC_IN_RC(r0_reg)); 4764 match(iRegN); 4765 op_cost(0); 4766 format %{ %} 4767 interface(REG_INTER); 4768 %} 4769 4770 operand iRegN_R2() 4771 %{ 4772 constraint(ALLOC_IN_RC(r2_reg)); 4773 match(iRegN); 4774 op_cost(0); 4775 format %{ %} 4776 interface(REG_INTER); 4777 %} 4778 4779 operand iRegN_R3() 4780 %{ 4781 constraint(ALLOC_IN_RC(r3_reg)); 4782 match(iRegN); 4783 op_cost(0); 4784 format %{ %} 4785 interface(REG_INTER); 4786 %} 4787 4788 // Integer 64 bit Register not Special 4789 operand iRegNNoSp() 4790 %{ 4791 constraint(ALLOC_IN_RC(no_special_reg32)); 4792 match(RegN); 4793 op_cost(0); 4794 format %{ %} 4795 interface(REG_INTER); 4796 %} 4797 4798 // heap base register -- used for encoding immN0 4799 4800 operand iRegIHeapbase() 4801 %{ 4802 constraint(ALLOC_IN_RC(heapbase_reg)); 4803 match(RegI); 4804 op_cost(0); 4805 format %{ %} 4806 interface(REG_INTER); 4807 %} 4808 4809 // Float Register 4810 // Float register operands 4811 operand vRegF() 4812 %{ 4813 constraint(ALLOC_IN_RC(float_reg)); 4814 match(RegF); 4815 4816 op_cost(0); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 // Double Register 4822 // Double register operands 4823 operand vRegD() 4824 %{ 4825 constraint(ALLOC_IN_RC(double_reg)); 4826 match(RegD); 4827 4828 op_cost(0); 4829 format %{ %} 4830 interface(REG_INTER); 4831 %} 4832 4833 operand vecD() 4834 %{ 4835 constraint(ALLOC_IN_RC(vectord_reg)); 4836 match(VecD); 4837 4838 op_cost(0); 4839 format %{ %} 4840 interface(REG_INTER); 4841 %} 4842 4843 operand vecX() 4844 %{ 4845 constraint(ALLOC_IN_RC(vectorx_reg)); 4846 match(VecX); 4847 4848 op_cost(0); 4849 format %{ %} 4850 interface(REG_INTER); 4851 %} 4852 4853 operand vRegD_V0() 4854 %{ 4855 constraint(ALLOC_IN_RC(v0_reg)); 4856 match(RegD); 4857 op_cost(0); 4858 format %{ %} 4859 interface(REG_INTER); 4860 %} 4861 4862 operand vRegD_V1() 4863 %{ 4864 constraint(ALLOC_IN_RC(v1_reg)); 4865 match(RegD); 4866 op_cost(0); 4867 format %{ %} 4868 interface(REG_INTER); 4869 %} 4870 4871 operand vRegD_V2() 4872 %{ 4873 constraint(ALLOC_IN_RC(v2_reg)); 4874 match(RegD); 4875 op_cost(0); 4876 format %{ %} 4877 interface(REG_INTER); 4878 %} 4879 4880 operand vRegD_V3() 4881 %{ 4882 constraint(ALLOC_IN_RC(v3_reg)); 4883 match(RegD); 4884 op_cost(0); 4885 format %{ %} 4886 interface(REG_INTER); 4887 %} 4888 4889 operand vRegD_V4() 4890 %{ 4891 constraint(ALLOC_IN_RC(v4_reg)); 4892 match(RegD); 4893 op_cost(0); 4894 format %{ %} 4895 interface(REG_INTER); 4896 %} 4897 4898 operand vRegD_V5() 4899 %{ 4900 constraint(ALLOC_IN_RC(v5_reg)); 4901 match(RegD); 4902 op_cost(0); 4903 format %{ %} 4904 interface(REG_INTER); 4905 %} 4906 4907 operand vRegD_V6() 4908 %{ 4909 constraint(ALLOC_IN_RC(v6_reg)); 4910 match(RegD); 4911 op_cost(0); 4912 format %{ %} 4913 interface(REG_INTER); 4914 %} 4915 4916 operand vRegD_V7() 4917 %{ 4918 constraint(ALLOC_IN_RC(v7_reg)); 4919 match(RegD); 4920 op_cost(0); 4921 format %{ %} 4922 interface(REG_INTER); 4923 %} 4924 4925 operand vRegD_V8() 4926 %{ 4927 constraint(ALLOC_IN_RC(v8_reg)); 4928 match(RegD); 4929 op_cost(0); 4930 format %{ %} 4931 interface(REG_INTER); 4932 %} 4933 4934 operand vRegD_V9() 4935 %{ 4936 constraint(ALLOC_IN_RC(v9_reg)); 4937 match(RegD); 4938 op_cost(0); 4939 format %{ %} 4940 interface(REG_INTER); 4941 %} 4942 4943 operand vRegD_V10() 4944 %{ 4945 constraint(ALLOC_IN_RC(v10_reg)); 4946 match(RegD); 4947 op_cost(0); 4948 format %{ %} 4949 interface(REG_INTER); 4950 %} 4951 4952 operand vRegD_V11() 4953 %{ 4954 constraint(ALLOC_IN_RC(v11_reg)); 4955 match(RegD); 4956 op_cost(0); 4957 format %{ %} 4958 interface(REG_INTER); 4959 %} 4960 4961 operand vRegD_V12() 4962 %{ 4963 constraint(ALLOC_IN_RC(v12_reg)); 4964 match(RegD); 4965 op_cost(0); 4966 format %{ %} 4967 interface(REG_INTER); 4968 %} 4969 4970 operand vRegD_V13() 4971 %{ 4972 constraint(ALLOC_IN_RC(v13_reg)); 4973 match(RegD); 4974 op_cost(0); 4975 format %{ %} 4976 interface(REG_INTER); 4977 %} 4978 4979 operand vRegD_V14() 4980 %{ 4981 constraint(ALLOC_IN_RC(v14_reg)); 4982 match(RegD); 4983 op_cost(0); 4984 format %{ %} 4985 interface(REG_INTER); 4986 %} 4987 4988 operand vRegD_V15() 4989 %{ 4990 constraint(ALLOC_IN_RC(v15_reg)); 4991 match(RegD); 4992 op_cost(0); 4993 format %{ %} 4994 interface(REG_INTER); 4995 %} 4996 4997 operand vRegD_V16() 4998 %{ 4999 constraint(ALLOC_IN_RC(v16_reg)); 5000 match(RegD); 5001 op_cost(0); 5002 format %{ %} 5003 interface(REG_INTER); 5004 %} 5005 5006 operand vRegD_V17() 5007 %{ 5008 constraint(ALLOC_IN_RC(v17_reg)); 5009 match(RegD); 5010 op_cost(0); 5011 format %{ %} 5012 interface(REG_INTER); 5013 %} 5014 5015 operand vRegD_V18() 5016 %{ 5017 constraint(ALLOC_IN_RC(v18_reg)); 5018 match(RegD); 5019 op_cost(0); 5020 format %{ %} 5021 interface(REG_INTER); 5022 %} 5023 5024 operand vRegD_V19() 5025 %{ 5026 constraint(ALLOC_IN_RC(v19_reg)); 5027 match(RegD); 5028 op_cost(0); 5029 format %{ %} 5030 interface(REG_INTER); 5031 %} 5032 5033 operand vRegD_V20() 5034 %{ 5035 constraint(ALLOC_IN_RC(v20_reg)); 5036 match(RegD); 5037 op_cost(0); 5038 format %{ %} 5039 interface(REG_INTER); 5040 %} 5041 5042 operand vRegD_V21() 5043 %{ 5044 constraint(ALLOC_IN_RC(v21_reg)); 5045 match(RegD); 5046 op_cost(0); 5047 format %{ %} 5048 interface(REG_INTER); 5049 %} 5050 5051 operand vRegD_V22() 5052 %{ 5053 constraint(ALLOC_IN_RC(v22_reg)); 5054 match(RegD); 5055 op_cost(0); 5056 format %{ %} 5057 interface(REG_INTER); 5058 %} 5059 5060 operand vRegD_V23() 5061 %{ 5062 constraint(ALLOC_IN_RC(v23_reg)); 5063 match(RegD); 5064 op_cost(0); 5065 format %{ %} 5066 interface(REG_INTER); 5067 %} 5068 5069 operand vRegD_V24() 5070 %{ 5071 constraint(ALLOC_IN_RC(v24_reg)); 5072 match(RegD); 5073 op_cost(0); 5074 format %{ %} 5075 interface(REG_INTER); 5076 %} 5077 5078 operand vRegD_V25() 5079 %{ 5080 constraint(ALLOC_IN_RC(v25_reg)); 5081 match(RegD); 5082 op_cost(0); 5083 format %{ %} 5084 interface(REG_INTER); 5085 %} 5086 5087 operand vRegD_V26() 5088 %{ 5089 constraint(ALLOC_IN_RC(v26_reg)); 5090 match(RegD); 5091 op_cost(0); 5092 format %{ %} 5093 interface(REG_INTER); 5094 %} 5095 5096 operand vRegD_V27() 5097 %{ 5098 constraint(ALLOC_IN_RC(v27_reg)); 5099 match(RegD); 5100 op_cost(0); 5101 format %{ %} 5102 interface(REG_INTER); 5103 %} 5104 5105 operand vRegD_V28() 5106 %{ 5107 constraint(ALLOC_IN_RC(v28_reg)); 5108 match(RegD); 5109 op_cost(0); 5110 format %{ %} 5111 interface(REG_INTER); 5112 %} 5113 5114 operand vRegD_V29() 5115 %{ 5116 constraint(ALLOC_IN_RC(v29_reg)); 5117 match(RegD); 5118 op_cost(0); 5119 format %{ %} 5120 interface(REG_INTER); 5121 %} 5122 5123 operand vRegD_V30() 5124 %{ 5125 constraint(ALLOC_IN_RC(v30_reg)); 5126 match(RegD); 5127 op_cost(0); 5128 format %{ %} 5129 interface(REG_INTER); 5130 %} 5131 5132 operand vRegD_V31() 5133 %{ 5134 constraint(ALLOC_IN_RC(v31_reg)); 5135 match(RegD); 5136 op_cost(0); 5137 format %{ %} 5138 interface(REG_INTER); 5139 %} 5140 5141 // Flags register, used as output of signed compare instructions 5142 5143 // note that on AArch64 we also use this register as the output for 5144 // for floating point compare instructions (CmpF CmpD). this ensures 5145 // that ordered inequality tests use GT, GE, LT or LE none of which 5146 // pass through cases where the result is unordered i.e. one or both 5147 // inputs to the compare is a NaN. this means that the ideal code can 5148 // replace e.g. a GT with an LE and not end up capturing the NaN case 5149 // (where the comparison should always fail). EQ and NE tests are 5150 // always generated in ideal code so that unordered folds into the NE 5151 // case, matching the behaviour of AArch64 NE. 5152 // 5153 // This differs from x86 where the outputs of FP compares use a 5154 // special FP flags registers and where compares based on this 5155 // register are distinguished into ordered inequalities (cmpOpUCF) and 5156 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5157 // to explicitly handle the unordered case in branches. x86 also has 5158 // to include extra CMoveX rules to accept a cmpOpUCF input. 5159 5160 operand rFlagsReg() 5161 %{ 5162 constraint(ALLOC_IN_RC(int_flags)); 5163 match(RegFlags); 5164 5165 op_cost(0); 5166 format %{ "RFLAGS" %} 5167 interface(REG_INTER); 5168 %} 5169 5170 // Flags register, used as output of unsigned compare instructions 5171 operand rFlagsRegU() 5172 %{ 5173 constraint(ALLOC_IN_RC(int_flags)); 5174 match(RegFlags); 5175 5176 op_cost(0); 5177 format %{ "RFLAGSU" %} 5178 interface(REG_INTER); 5179 %} 5180 5181 // Special Registers 5182 5183 // Method Register 5184 operand inline_cache_RegP(iRegP reg) 5185 %{ 5186 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5187 match(reg); 5188 match(iRegPNoSp); 5189 op_cost(0); 5190 format %{ %} 5191 interface(REG_INTER); 5192 %} 5193 5194 operand interpreter_method_oop_RegP(iRegP reg) 5195 %{ 5196 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5197 match(reg); 5198 match(iRegPNoSp); 5199 op_cost(0); 5200 format %{ %} 5201 interface(REG_INTER); 5202 %} 5203 5204 // Thread Register 5205 operand thread_RegP(iRegP reg) 5206 %{ 5207 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5208 match(reg); 5209 op_cost(0); 5210 format %{ %} 5211 interface(REG_INTER); 5212 %} 5213 5214 operand lr_RegP(iRegP reg) 5215 %{ 5216 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5217 match(reg); 5218 op_cost(0); 5219 format %{ %} 5220 interface(REG_INTER); 5221 %} 5222 5223 //----------Memory Operands---------------------------------------------------- 5224 5225 operand indirect(iRegP reg) 5226 %{ 5227 constraint(ALLOC_IN_RC(ptr_reg)); 5228 match(reg); 5229 op_cost(0); 5230 format %{ "[$reg]" %} 5231 interface(MEMORY_INTER) %{ 5232 base($reg); 5233 index(0xffffffff); 5234 scale(0x0); 5235 disp(0x0); 5236 %} 5237 %} 5238 5239 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5240 %{ 5241 constraint(ALLOC_IN_RC(ptr_reg)); 5242 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5243 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5244 op_cost(0); 5245 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5246 interface(MEMORY_INTER) %{ 5247 base($reg); 5248 index($ireg); 5249 scale($scale); 5250 disp(0x0); 5251 %} 5252 %} 5253 5254 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5255 %{ 5256 constraint(ALLOC_IN_RC(ptr_reg)); 5257 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5258 match(AddP reg (LShiftL lreg scale)); 5259 op_cost(0); 5260 format %{ "$reg, $lreg lsl($scale)" %} 5261 interface(MEMORY_INTER) %{ 5262 base($reg); 5263 index($lreg); 5264 scale($scale); 5265 disp(0x0); 5266 %} 5267 %} 5268 5269 operand indIndexI2L(iRegP reg, iRegI ireg) 5270 %{ 5271 constraint(ALLOC_IN_RC(ptr_reg)); 5272 match(AddP reg (ConvI2L ireg)); 5273 op_cost(0); 5274 format %{ "$reg, $ireg, 0, I2L" %} 5275 interface(MEMORY_INTER) %{ 5276 base($reg); 5277 index($ireg); 5278 scale(0x0); 5279 disp(0x0); 5280 %} 5281 %} 5282 5283 operand indIndex(iRegP reg, iRegL lreg) 5284 %{ 5285 constraint(ALLOC_IN_RC(ptr_reg)); 5286 match(AddP reg lreg); 5287 op_cost(0); 5288 format %{ "$reg, $lreg" %} 5289 interface(MEMORY_INTER) %{ 5290 base($reg); 5291 index($lreg); 5292 scale(0x0); 5293 disp(0x0); 5294 %} 5295 %} 5296 5297 operand indOffI(iRegP reg, immIOffset off) 5298 %{ 5299 constraint(ALLOC_IN_RC(ptr_reg)); 5300 match(AddP reg off); 5301 op_cost(0); 5302 format %{ "[$reg, $off]" %} 5303 interface(MEMORY_INTER) %{ 5304 base($reg); 5305 index(0xffffffff); 5306 scale(0x0); 5307 disp($off); 5308 %} 5309 %} 5310 5311 operand indOffI4(iRegP reg, immIOffset4 off) 5312 %{ 5313 constraint(ALLOC_IN_RC(ptr_reg)); 5314 match(AddP reg off); 5315 op_cost(0); 5316 format %{ "[$reg, $off]" %} 5317 interface(MEMORY_INTER) %{ 5318 base($reg); 5319 index(0xffffffff); 5320 scale(0x0); 5321 disp($off); 5322 %} 5323 %} 5324 5325 operand indOffI8(iRegP reg, immIOffset8 off) 5326 %{ 5327 constraint(ALLOC_IN_RC(ptr_reg)); 5328 match(AddP reg off); 5329 op_cost(0); 5330 format %{ "[$reg, $off]" %} 5331 interface(MEMORY_INTER) %{ 5332 base($reg); 5333 index(0xffffffff); 5334 scale(0x0); 5335 disp($off); 5336 %} 5337 %} 5338 5339 operand indOffI16(iRegP reg, immIOffset16 off) 5340 %{ 5341 constraint(ALLOC_IN_RC(ptr_reg)); 5342 match(AddP reg off); 5343 op_cost(0); 5344 format %{ "[$reg, $off]" %} 5345 interface(MEMORY_INTER) %{ 5346 base($reg); 5347 index(0xffffffff); 5348 scale(0x0); 5349 disp($off); 5350 %} 5351 %} 5352 5353 operand indOffL(iRegP reg, immLoffset off) 5354 %{ 5355 constraint(ALLOC_IN_RC(ptr_reg)); 5356 match(AddP reg off); 5357 op_cost(0); 5358 format %{ "[$reg, $off]" %} 5359 interface(MEMORY_INTER) %{ 5360 base($reg); 5361 index(0xffffffff); 5362 scale(0x0); 5363 disp($off); 5364 %} 5365 %} 5366 5367 operand indOffL4(iRegP reg, immLoffset4 off) 5368 %{ 5369 constraint(ALLOC_IN_RC(ptr_reg)); 5370 match(AddP reg off); 5371 op_cost(0); 5372 format %{ "[$reg, $off]" %} 5373 interface(MEMORY_INTER) %{ 5374 base($reg); 5375 index(0xffffffff); 5376 scale(0x0); 5377 disp($off); 5378 %} 5379 %} 5380 5381 operand indOffL8(iRegP reg, immLoffset8 off) 5382 %{ 5383 constraint(ALLOC_IN_RC(ptr_reg)); 5384 match(AddP reg off); 5385 op_cost(0); 5386 format %{ "[$reg, $off]" %} 5387 interface(MEMORY_INTER) %{ 5388 base($reg); 5389 index(0xffffffff); 5390 scale(0x0); 5391 disp($off); 5392 %} 5393 %} 5394 5395 operand indOffL16(iRegP reg, immLoffset16 off) 5396 %{ 5397 constraint(ALLOC_IN_RC(ptr_reg)); 5398 match(AddP reg off); 5399 op_cost(0); 5400 format %{ "[$reg, $off]" %} 5401 interface(MEMORY_INTER) %{ 5402 base($reg); 5403 index(0xffffffff); 5404 scale(0x0); 5405 disp($off); 5406 %} 5407 %} 5408 5409 operand indirectN(iRegN reg) 5410 %{ 5411 predicate(CompressedOops::shift() == 0); 5412 constraint(ALLOC_IN_RC(ptr_reg)); 5413 match(DecodeN reg); 5414 op_cost(0); 5415 format %{ "[$reg]\t# narrow" %} 5416 interface(MEMORY_INTER) %{ 5417 base($reg); 5418 index(0xffffffff); 5419 scale(0x0); 5420 disp(0x0); 5421 %} 5422 %} 5423 5424 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5425 %{ 5426 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5427 constraint(ALLOC_IN_RC(ptr_reg)); 5428 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5429 op_cost(0); 5430 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5431 interface(MEMORY_INTER) %{ 5432 base($reg); 5433 index($ireg); 5434 scale($scale); 5435 disp(0x0); 5436 %} 5437 %} 5438 5439 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5440 %{ 5441 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5442 constraint(ALLOC_IN_RC(ptr_reg)); 5443 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5444 op_cost(0); 5445 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5446 interface(MEMORY_INTER) %{ 5447 base($reg); 5448 index($lreg); 5449 scale($scale); 5450 disp(0x0); 5451 %} 5452 %} 5453 5454 operand indIndexI2LN(iRegN reg, iRegI ireg) 5455 %{ 5456 predicate(CompressedOops::shift() == 0); 5457 constraint(ALLOC_IN_RC(ptr_reg)); 5458 match(AddP (DecodeN reg) (ConvI2L ireg)); 5459 op_cost(0); 5460 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5461 interface(MEMORY_INTER) %{ 5462 base($reg); 5463 index($ireg); 5464 scale(0x0); 5465 disp(0x0); 5466 %} 5467 %} 5468 5469 operand indIndexN(iRegN reg, iRegL lreg) 5470 %{ 5471 predicate(CompressedOops::shift() == 0); 5472 constraint(ALLOC_IN_RC(ptr_reg)); 5473 match(AddP (DecodeN reg) lreg); 5474 op_cost(0); 5475 format %{ "$reg, $lreg\t# narrow" %} 5476 interface(MEMORY_INTER) %{ 5477 base($reg); 5478 index($lreg); 5479 scale(0x0); 5480 disp(0x0); 5481 %} 5482 %} 5483 5484 operand indOffIN(iRegN reg, immIOffset off) 5485 %{ 5486 predicate(CompressedOops::shift() == 0); 5487 constraint(ALLOC_IN_RC(ptr_reg)); 5488 match(AddP (DecodeN reg) off); 5489 op_cost(0); 5490 format %{ "[$reg, $off]\t# narrow" %} 5491 interface(MEMORY_INTER) %{ 5492 base($reg); 5493 index(0xffffffff); 5494 scale(0x0); 5495 disp($off); 5496 %} 5497 %} 5498 5499 operand indOffLN(iRegN reg, immLoffset off) 5500 %{ 5501 predicate(CompressedOops::shift() == 0); 5502 constraint(ALLOC_IN_RC(ptr_reg)); 5503 match(AddP (DecodeN reg) off); 5504 op_cost(0); 5505 format %{ "[$reg, $off]\t# narrow" %} 5506 interface(MEMORY_INTER) %{ 5507 base($reg); 5508 index(0xffffffff); 5509 scale(0x0); 5510 disp($off); 5511 %} 5512 %} 5513 5514 5515 5516 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5517 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5518 %{ 5519 constraint(ALLOC_IN_RC(ptr_reg)); 5520 match(AddP reg off); 5521 op_cost(0); 5522 format %{ "[$reg, $off]" %} 5523 interface(MEMORY_INTER) %{ 5524 base($reg); 5525 index(0xffffffff); 5526 scale(0x0); 5527 disp($off); 5528 %} 5529 %} 5530 5531 //----------Special Memory Operands-------------------------------------------- 5532 // Stack Slot Operand - This operand is used for loading and storing temporary 5533 // values on the stack where a match requires a value to 5534 // flow through memory. 5535 operand stackSlotP(sRegP reg) 5536 %{ 5537 constraint(ALLOC_IN_RC(stack_slots)); 5538 op_cost(100); 5539 // No match rule because this operand is only generated in matching 5540 // match(RegP); 5541 format %{ "[$reg]" %} 5542 interface(MEMORY_INTER) %{ 5543 base(0x1e); // RSP 5544 index(0x0); // No Index 5545 scale(0x0); // No Scale 5546 disp($reg); // Stack Offset 5547 %} 5548 %} 5549 5550 operand stackSlotI(sRegI reg) 5551 %{ 5552 constraint(ALLOC_IN_RC(stack_slots)); 5553 // No match rule because this operand is only generated in matching 5554 // match(RegI); 5555 format %{ "[$reg]" %} 5556 interface(MEMORY_INTER) %{ 5557 base(0x1e); // RSP 5558 index(0x0); // No Index 5559 scale(0x0); // No Scale 5560 disp($reg); // Stack Offset 5561 %} 5562 %} 5563 5564 operand stackSlotF(sRegF reg) 5565 %{ 5566 constraint(ALLOC_IN_RC(stack_slots)); 5567 // No match rule because this operand is only generated in matching 5568 // match(RegF); 5569 format %{ "[$reg]" %} 5570 interface(MEMORY_INTER) %{ 5571 base(0x1e); // RSP 5572 index(0x0); // No Index 5573 scale(0x0); // No Scale 5574 disp($reg); // Stack Offset 5575 %} 5576 %} 5577 5578 operand stackSlotD(sRegD reg) 5579 %{ 5580 constraint(ALLOC_IN_RC(stack_slots)); 5581 // No match rule because this operand is only generated in matching 5582 // match(RegD); 5583 format %{ "[$reg]" %} 5584 interface(MEMORY_INTER) %{ 5585 base(0x1e); // RSP 5586 index(0x0); // No Index 5587 scale(0x0); // No Scale 5588 disp($reg); // Stack Offset 5589 %} 5590 %} 5591 5592 operand stackSlotL(sRegL reg) 5593 %{ 5594 constraint(ALLOC_IN_RC(stack_slots)); 5595 // No match rule because this operand is only generated in matching 5596 // match(RegL); 5597 format %{ "[$reg]" %} 5598 interface(MEMORY_INTER) %{ 5599 base(0x1e); // RSP 5600 index(0x0); // No Index 5601 scale(0x0); // No Scale 5602 disp($reg); // Stack Offset 5603 %} 5604 %} 5605 5606 // Operands for expressing Control Flow 5607 // NOTE: Label is a predefined operand which should not be redefined in 5608 // the AD file. It is generically handled within the ADLC. 5609 5610 //----------Conditional Branch Operands---------------------------------------- 5611 // Comparison Op - This is the operation of the comparison, and is limited to 5612 // the following set of codes: 5613 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5614 // 5615 // Other attributes of the comparison, such as unsignedness, are specified 5616 // by the comparison instruction that sets a condition code flags register. 5617 // That result is represented by a flags operand whose subtype is appropriate 5618 // to the unsignedness (etc.) of the comparison. 5619 // 5620 // Later, the instruction which matches both the Comparison Op (a Bool) and 5621 // the flags (produced by the Cmp) specifies the coding of the comparison op 5622 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5623 5624 // used for signed integral comparisons and fp comparisons 5625 5626 operand cmpOp() 5627 %{ 5628 match(Bool); 5629 5630 format %{ "" %} 5631 interface(COND_INTER) %{ 5632 equal(0x0, "eq"); 5633 not_equal(0x1, "ne"); 5634 less(0xb, "lt"); 5635 greater_equal(0xa, "ge"); 5636 less_equal(0xd, "le"); 5637 greater(0xc, "gt"); 5638 overflow(0x6, "vs"); 5639 no_overflow(0x7, "vc"); 5640 %} 5641 %} 5642 5643 // used for unsigned integral comparisons 5644 5645 operand cmpOpU() 5646 %{ 5647 match(Bool); 5648 5649 format %{ "" %} 5650 interface(COND_INTER) %{ 5651 equal(0x0, "eq"); 5652 not_equal(0x1, "ne"); 5653 less(0x3, "lo"); 5654 greater_equal(0x2, "hs"); 5655 less_equal(0x9, "ls"); 5656 greater(0x8, "hi"); 5657 overflow(0x6, "vs"); 5658 no_overflow(0x7, "vc"); 5659 %} 5660 %} 5661 5662 // used for certain integral comparisons which can be 5663 // converted to cbxx or tbxx instructions 5664 5665 operand cmpOpEqNe() 5666 %{ 5667 match(Bool); 5668 match(CmpOp); 5669 op_cost(0); 5670 predicate(n->as_Bool()->_test._test == BoolTest::ne 5671 || n->as_Bool()->_test._test == BoolTest::eq); 5672 5673 format %{ "" %} 5674 interface(COND_INTER) %{ 5675 equal(0x0, "eq"); 5676 not_equal(0x1, "ne"); 5677 less(0xb, "lt"); 5678 greater_equal(0xa, "ge"); 5679 less_equal(0xd, "le"); 5680 greater(0xc, "gt"); 5681 overflow(0x6, "vs"); 5682 no_overflow(0x7, "vc"); 5683 %} 5684 %} 5685 5686 // used for certain integral comparisons which can be 5687 // converted to cbxx or tbxx instructions 5688 5689 operand cmpOpLtGe() 5690 %{ 5691 match(Bool); 5692 match(CmpOp); 5693 op_cost(0); 5694 5695 predicate(n->as_Bool()->_test._test == BoolTest::lt 5696 || n->as_Bool()->_test._test == BoolTest::ge); 5697 5698 format %{ "" %} 5699 interface(COND_INTER) %{ 5700 equal(0x0, "eq"); 5701 not_equal(0x1, "ne"); 5702 less(0xb, "lt"); 5703 greater_equal(0xa, "ge"); 5704 less_equal(0xd, "le"); 5705 greater(0xc, "gt"); 5706 overflow(0x6, "vs"); 5707 no_overflow(0x7, "vc"); 5708 %} 5709 %} 5710 5711 // used for certain unsigned integral comparisons which can be 5712 // converted to cbxx or tbxx instructions 5713 5714 operand cmpOpUEqNeLtGe() 5715 %{ 5716 match(Bool); 5717 match(CmpOp); 5718 op_cost(0); 5719 5720 predicate(n->as_Bool()->_test._test == BoolTest::eq 5721 || n->as_Bool()->_test._test == BoolTest::ne 5722 || n->as_Bool()->_test._test == BoolTest::lt 5723 || n->as_Bool()->_test._test == BoolTest::ge); 5724 5725 format %{ "" %} 5726 interface(COND_INTER) %{ 5727 equal(0x0, "eq"); 5728 not_equal(0x1, "ne"); 5729 less(0xb, "lt"); 5730 greater_equal(0xa, "ge"); 5731 less_equal(0xd, "le"); 5732 greater(0xc, "gt"); 5733 overflow(0x6, "vs"); 5734 no_overflow(0x7, "vc"); 5735 %} 5736 %} 5737 5738 // Special operand allowing long args to int ops to be truncated for free 5739 5740 operand iRegL2I(iRegL reg) %{ 5741 5742 op_cost(0); 5743 5744 match(ConvL2I reg); 5745 5746 format %{ "l2i($reg)" %} 5747 5748 interface(REG_INTER) 5749 %} 5750 5751 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5752 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5753 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5754 5755 //----------OPERAND CLASSES---------------------------------------------------- 5756 // Operand Classes are groups of operands that are used as to simplify 5757 // instruction definitions by not requiring the AD writer to specify 5758 // separate instructions for every form of operand when the 5759 // instruction accepts multiple operand types with the same basic 5760 // encoding and format. The classic case of this is memory operands. 5761 5762 // memory is used to define read/write location for load/store 5763 // instruction defs. we can turn a memory op into an Address 5764 5765 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5766 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5767 5768 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5769 // operations. it allows the src to be either an iRegI or a (ConvL2I 5770 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5771 // can be elided because the 32-bit instruction will just employ the 5772 // lower 32 bits anyway. 5773 // 5774 // n.b. this does not elide all L2I conversions. if the truncated 5775 // value is consumed by more than one operation then the ConvL2I 5776 // cannot be bundled into the consuming nodes so an l2i gets planted 5777 // (actually a movw $dst $src) and the downstream instructions consume 5778 // the result of the l2i as an iRegI input. That's a shame since the 5779 // movw is actually redundant but its not too costly. 5780 5781 opclass iRegIorL2I(iRegI, iRegL2I); 5782 5783 //----------PIPELINE----------------------------------------------------------- 5784 // Rules which define the behavior of the target architectures pipeline. 5785 5786 // For specific pipelines, eg A53, define the stages of that pipeline 5787 //pipe_desc(ISS, EX1, EX2, WR); 5788 #define ISS S0 5789 #define EX1 S1 5790 #define EX2 S2 5791 #define WR S3 5792 5793 // Integer ALU reg operation 5794 pipeline %{ 5795 5796 attributes %{ 5797 // ARM instructions are of fixed length 5798 fixed_size_instructions; // Fixed size instructions TODO does 5799 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5800 // ARM instructions come in 32-bit word units 5801 instruction_unit_size = 4; // An instruction is 4 bytes long 5802 instruction_fetch_unit_size = 64; // The processor fetches one line 5803 instruction_fetch_units = 1; // of 64 bytes 5804 5805 // List of nop instructions 5806 nops( MachNop ); 5807 %} 5808 5809 // We don't use an actual pipeline model so don't care about resources 5810 // or description. we do use pipeline classes to introduce fixed 5811 // latencies 5812 5813 //----------RESOURCES---------------------------------------------------------- 5814 // Resources are the functional units available to the machine 5815 5816 resources( INS0, INS1, INS01 = INS0 | INS1, 5817 ALU0, ALU1, ALU = ALU0 | ALU1, 5818 MAC, 5819 DIV, 5820 BRANCH, 5821 LDST, 5822 NEON_FP); 5823 5824 //----------PIPELINE DESCRIPTION----------------------------------------------- 5825 // Pipeline Description specifies the stages in the machine's pipeline 5826 5827 // Define the pipeline as a generic 6 stage pipeline 5828 pipe_desc(S0, S1, S2, S3, S4, S5); 5829 5830 //----------PIPELINE CLASSES--------------------------------------------------- 5831 // Pipeline Classes describe the stages in which input and output are 5832 // referenced by the hardware pipeline. 5833 5834 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5835 %{ 5836 single_instruction; 5837 src1 : S1(read); 5838 src2 : S2(read); 5839 dst : S5(write); 5840 INS01 : ISS; 5841 NEON_FP : S5; 5842 %} 5843 5844 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5845 %{ 5846 single_instruction; 5847 src1 : S1(read); 5848 src2 : S2(read); 5849 dst : S5(write); 5850 INS01 : ISS; 5851 NEON_FP : S5; 5852 %} 5853 5854 pipe_class fp_uop_s(vRegF dst, vRegF src) 5855 %{ 5856 single_instruction; 5857 src : S1(read); 5858 dst : S5(write); 5859 INS01 : ISS; 5860 NEON_FP : S5; 5861 %} 5862 5863 pipe_class fp_uop_d(vRegD dst, vRegD src) 5864 %{ 5865 single_instruction; 5866 src : S1(read); 5867 dst : S5(write); 5868 INS01 : ISS; 5869 NEON_FP : S5; 5870 %} 5871 5872 pipe_class fp_d2f(vRegF dst, vRegD src) 5873 %{ 5874 single_instruction; 5875 src : S1(read); 5876 dst : S5(write); 5877 INS01 : ISS; 5878 NEON_FP : S5; 5879 %} 5880 5881 pipe_class fp_f2d(vRegD dst, vRegF src) 5882 %{ 5883 single_instruction; 5884 src : S1(read); 5885 dst : S5(write); 5886 INS01 : ISS; 5887 NEON_FP : S5; 5888 %} 5889 5890 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5891 %{ 5892 single_instruction; 5893 src : S1(read); 5894 dst : S5(write); 5895 INS01 : ISS; 5896 NEON_FP : S5; 5897 %} 5898 5899 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5900 %{ 5901 single_instruction; 5902 src : S1(read); 5903 dst : S5(write); 5904 INS01 : ISS; 5905 NEON_FP : S5; 5906 %} 5907 5908 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5909 %{ 5910 single_instruction; 5911 src : S1(read); 5912 dst : S5(write); 5913 INS01 : ISS; 5914 NEON_FP : S5; 5915 %} 5916 5917 pipe_class fp_l2f(vRegF dst, iRegL src) 5918 %{ 5919 single_instruction; 5920 src : S1(read); 5921 dst : S5(write); 5922 INS01 : ISS; 5923 NEON_FP : S5; 5924 %} 5925 5926 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5927 %{ 5928 single_instruction; 5929 src : S1(read); 5930 dst : S5(write); 5931 INS01 : ISS; 5932 NEON_FP : S5; 5933 %} 5934 5935 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5936 %{ 5937 single_instruction; 5938 src : S1(read); 5939 dst : S5(write); 5940 INS01 : ISS; 5941 NEON_FP : S5; 5942 %} 5943 5944 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5945 %{ 5946 single_instruction; 5947 src : S1(read); 5948 dst : S5(write); 5949 INS01 : ISS; 5950 NEON_FP : S5; 5951 %} 5952 5953 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5954 %{ 5955 single_instruction; 5956 src : S1(read); 5957 dst : S5(write); 5958 INS01 : ISS; 5959 NEON_FP : S5; 5960 %} 5961 5962 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5963 %{ 5964 single_instruction; 5965 src1 : S1(read); 5966 src2 : S2(read); 5967 dst : S5(write); 5968 INS0 : ISS; 5969 NEON_FP : S5; 5970 %} 5971 5972 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5973 %{ 5974 single_instruction; 5975 src1 : S1(read); 5976 src2 : S2(read); 5977 dst : S5(write); 5978 INS0 : ISS; 5979 NEON_FP : S5; 5980 %} 5981 5982 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5983 %{ 5984 single_instruction; 5985 cr : S1(read); 5986 src1 : S1(read); 5987 src2 : S1(read); 5988 dst : S3(write); 5989 INS01 : ISS; 5990 NEON_FP : S3; 5991 %} 5992 5993 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5994 %{ 5995 single_instruction; 5996 cr : S1(read); 5997 src1 : S1(read); 5998 src2 : S1(read); 5999 dst : S3(write); 6000 INS01 : ISS; 6001 NEON_FP : S3; 6002 %} 6003 6004 pipe_class fp_imm_s(vRegF dst) 6005 %{ 6006 single_instruction; 6007 dst : S3(write); 6008 INS01 : ISS; 6009 NEON_FP : S3; 6010 %} 6011 6012 pipe_class fp_imm_d(vRegD dst) 6013 %{ 6014 single_instruction; 6015 dst : S3(write); 6016 INS01 : ISS; 6017 NEON_FP : S3; 6018 %} 6019 6020 pipe_class fp_load_constant_s(vRegF dst) 6021 %{ 6022 single_instruction; 6023 dst : S4(write); 6024 INS01 : ISS; 6025 NEON_FP : S4; 6026 %} 6027 6028 pipe_class fp_load_constant_d(vRegD dst) 6029 %{ 6030 single_instruction; 6031 dst : S4(write); 6032 INS01 : ISS; 6033 NEON_FP : S4; 6034 %} 6035 6036 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6037 %{ 6038 single_instruction; 6039 dst : S5(write); 6040 src1 : S1(read); 6041 src2 : S1(read); 6042 INS01 : ISS; 6043 NEON_FP : S5; 6044 %} 6045 6046 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6047 %{ 6048 single_instruction; 6049 dst : S5(write); 6050 src1 : S1(read); 6051 src2 : S1(read); 6052 INS0 : ISS; 6053 NEON_FP : S5; 6054 %} 6055 6056 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6057 %{ 6058 single_instruction; 6059 dst : S5(write); 6060 src1 : S1(read); 6061 src2 : S1(read); 6062 dst : S1(read); 6063 INS01 : ISS; 6064 NEON_FP : S5; 6065 %} 6066 6067 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6068 %{ 6069 single_instruction; 6070 dst : S5(write); 6071 src1 : S1(read); 6072 src2 : S1(read); 6073 dst : S1(read); 6074 INS0 : ISS; 6075 NEON_FP : S5; 6076 %} 6077 6078 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6079 %{ 6080 single_instruction; 6081 dst : S4(write); 6082 src1 : S2(read); 6083 src2 : S2(read); 6084 INS01 : ISS; 6085 NEON_FP : S4; 6086 %} 6087 6088 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6089 %{ 6090 single_instruction; 6091 dst : S4(write); 6092 src1 : S2(read); 6093 src2 : S2(read); 6094 INS0 : ISS; 6095 NEON_FP : S4; 6096 %} 6097 6098 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6099 %{ 6100 single_instruction; 6101 dst : S3(write); 6102 src1 : S2(read); 6103 src2 : S2(read); 6104 INS01 : ISS; 6105 NEON_FP : S3; 6106 %} 6107 6108 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6109 %{ 6110 single_instruction; 6111 dst : S3(write); 6112 src1 : S2(read); 6113 src2 : S2(read); 6114 INS0 : ISS; 6115 NEON_FP : S3; 6116 %} 6117 6118 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6119 %{ 6120 single_instruction; 6121 dst : S3(write); 6122 src : S1(read); 6123 shift : S1(read); 6124 INS01 : ISS; 6125 NEON_FP : S3; 6126 %} 6127 6128 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6129 %{ 6130 single_instruction; 6131 dst : S3(write); 6132 src : S1(read); 6133 shift : S1(read); 6134 INS0 : ISS; 6135 NEON_FP : S3; 6136 %} 6137 6138 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6139 %{ 6140 single_instruction; 6141 dst : S3(write); 6142 src : S1(read); 6143 INS01 : ISS; 6144 NEON_FP : S3; 6145 %} 6146 6147 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6148 %{ 6149 single_instruction; 6150 dst : S3(write); 6151 src : S1(read); 6152 INS0 : ISS; 6153 NEON_FP : S3; 6154 %} 6155 6156 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6157 %{ 6158 single_instruction; 6159 dst : S5(write); 6160 src1 : S1(read); 6161 src2 : S1(read); 6162 INS01 : ISS; 6163 NEON_FP : S5; 6164 %} 6165 6166 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6167 %{ 6168 single_instruction; 6169 dst : S5(write); 6170 src1 : S1(read); 6171 src2 : S1(read); 6172 INS0 : ISS; 6173 NEON_FP : S5; 6174 %} 6175 6176 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6177 %{ 6178 single_instruction; 6179 dst : S5(write); 6180 src1 : S1(read); 6181 src2 : S1(read); 6182 INS0 : ISS; 6183 NEON_FP : S5; 6184 %} 6185 6186 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6187 %{ 6188 single_instruction; 6189 dst : S5(write); 6190 src1 : S1(read); 6191 src2 : S1(read); 6192 INS0 : ISS; 6193 NEON_FP : S5; 6194 %} 6195 6196 pipe_class vsqrt_fp128(vecX dst, vecX src) 6197 %{ 6198 single_instruction; 6199 dst : S5(write); 6200 src : S1(read); 6201 INS0 : ISS; 6202 NEON_FP : S5; 6203 %} 6204 6205 pipe_class vunop_fp64(vecD dst, vecD src) 6206 %{ 6207 single_instruction; 6208 dst : S5(write); 6209 src : S1(read); 6210 INS01 : ISS; 6211 NEON_FP : S5; 6212 %} 6213 6214 pipe_class vunop_fp128(vecX dst, vecX src) 6215 %{ 6216 single_instruction; 6217 dst : S5(write); 6218 src : S1(read); 6219 INS0 : ISS; 6220 NEON_FP : S5; 6221 %} 6222 6223 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6224 %{ 6225 single_instruction; 6226 dst : S3(write); 6227 src : S1(read); 6228 INS01 : ISS; 6229 NEON_FP : S3; 6230 %} 6231 6232 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6233 %{ 6234 single_instruction; 6235 dst : S3(write); 6236 src : S1(read); 6237 INS01 : ISS; 6238 NEON_FP : S3; 6239 %} 6240 6241 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6242 %{ 6243 single_instruction; 6244 dst : S3(write); 6245 src : S1(read); 6246 INS01 : ISS; 6247 NEON_FP : S3; 6248 %} 6249 6250 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6251 %{ 6252 single_instruction; 6253 dst : S3(write); 6254 src : S1(read); 6255 INS01 : ISS; 6256 NEON_FP : S3; 6257 %} 6258 6259 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6260 %{ 6261 single_instruction; 6262 dst : S3(write); 6263 src : S1(read); 6264 INS01 : ISS; 6265 NEON_FP : S3; 6266 %} 6267 6268 pipe_class vmovi_reg_imm64(vecD dst) 6269 %{ 6270 single_instruction; 6271 dst : S3(write); 6272 INS01 : ISS; 6273 NEON_FP : S3; 6274 %} 6275 6276 pipe_class vmovi_reg_imm128(vecX dst) 6277 %{ 6278 single_instruction; 6279 dst : S3(write); 6280 INS0 : ISS; 6281 NEON_FP : S3; 6282 %} 6283 6284 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6285 %{ 6286 single_instruction; 6287 dst : S5(write); 6288 mem : ISS(read); 6289 INS01 : ISS; 6290 NEON_FP : S3; 6291 %} 6292 6293 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6294 %{ 6295 single_instruction; 6296 dst : S5(write); 6297 mem : ISS(read); 6298 INS01 : ISS; 6299 NEON_FP : S3; 6300 %} 6301 6302 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6303 %{ 6304 single_instruction; 6305 mem : ISS(read); 6306 src : S2(read); 6307 INS01 : ISS; 6308 NEON_FP : S3; 6309 %} 6310 6311 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6312 %{ 6313 single_instruction; 6314 mem : ISS(read); 6315 src : S2(read); 6316 INS01 : ISS; 6317 NEON_FP : S3; 6318 %} 6319 6320 //------- Integer ALU operations -------------------------- 6321 6322 // Integer ALU reg-reg operation 6323 // Operands needed in EX1, result generated in EX2 6324 // Eg. ADD x0, x1, x2 6325 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6326 %{ 6327 single_instruction; 6328 dst : EX2(write); 6329 src1 : EX1(read); 6330 src2 : EX1(read); 6331 INS01 : ISS; // Dual issue as instruction 0 or 1 6332 ALU : EX2; 6333 %} 6334 6335 // Integer ALU reg-reg operation with constant shift 6336 // Shifted register must be available in LATE_ISS instead of EX1 6337 // Eg. ADD x0, x1, x2, LSL #2 6338 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6339 %{ 6340 single_instruction; 6341 dst : EX2(write); 6342 src1 : EX1(read); 6343 src2 : ISS(read); 6344 INS01 : ISS; 6345 ALU : EX2; 6346 %} 6347 6348 // Integer ALU reg operation with constant shift 6349 // Eg. LSL x0, x1, #shift 6350 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6351 %{ 6352 single_instruction; 6353 dst : EX2(write); 6354 src1 : ISS(read); 6355 INS01 : ISS; 6356 ALU : EX2; 6357 %} 6358 6359 // Integer ALU reg-reg operation with variable shift 6360 // Both operands must be available in LATE_ISS instead of EX1 6361 // Result is available in EX1 instead of EX2 6362 // Eg. LSLV x0, x1, x2 6363 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6364 %{ 6365 single_instruction; 6366 dst : EX1(write); 6367 src1 : ISS(read); 6368 src2 : ISS(read); 6369 INS01 : ISS; 6370 ALU : EX1; 6371 %} 6372 6373 // Integer ALU reg-reg operation with extract 6374 // As for _vshift above, but result generated in EX2 6375 // Eg. EXTR x0, x1, x2, #N 6376 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6377 %{ 6378 single_instruction; 6379 dst : EX2(write); 6380 src1 : ISS(read); 6381 src2 : ISS(read); 6382 INS1 : ISS; // Can only dual issue as Instruction 1 6383 ALU : EX1; 6384 %} 6385 6386 // Integer ALU reg operation 6387 // Eg. NEG x0, x1 6388 pipe_class ialu_reg(iRegI dst, iRegI src) 6389 %{ 6390 single_instruction; 6391 dst : EX2(write); 6392 src : EX1(read); 6393 INS01 : ISS; 6394 ALU : EX2; 6395 %} 6396 6397 // Integer ALU reg mmediate operation 6398 // Eg. ADD x0, x1, #N 6399 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6400 %{ 6401 single_instruction; 6402 dst : EX2(write); 6403 src1 : EX1(read); 6404 INS01 : ISS; 6405 ALU : EX2; 6406 %} 6407 6408 // Integer ALU immediate operation (no source operands) 6409 // Eg. MOV x0, #N 6410 pipe_class ialu_imm(iRegI dst) 6411 %{ 6412 single_instruction; 6413 dst : EX1(write); 6414 INS01 : ISS; 6415 ALU : EX1; 6416 %} 6417 6418 //------- Compare operation ------------------------------- 6419 6420 // Compare reg-reg 6421 // Eg. CMP x0, x1 6422 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6423 %{ 6424 single_instruction; 6425 // fixed_latency(16); 6426 cr : EX2(write); 6427 op1 : EX1(read); 6428 op2 : EX1(read); 6429 INS01 : ISS; 6430 ALU : EX2; 6431 %} 6432 6433 // Compare reg-reg 6434 // Eg. CMP x0, #N 6435 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6436 %{ 6437 single_instruction; 6438 // fixed_latency(16); 6439 cr : EX2(write); 6440 op1 : EX1(read); 6441 INS01 : ISS; 6442 ALU : EX2; 6443 %} 6444 6445 //------- Conditional instructions ------------------------ 6446 6447 // Conditional no operands 6448 // Eg. CSINC x0, zr, zr, <cond> 6449 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6450 %{ 6451 single_instruction; 6452 cr : EX1(read); 6453 dst : EX2(write); 6454 INS01 : ISS; 6455 ALU : EX2; 6456 %} 6457 6458 // Conditional 2 operand 6459 // EG. CSEL X0, X1, X2, <cond> 6460 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6461 %{ 6462 single_instruction; 6463 cr : EX1(read); 6464 src1 : EX1(read); 6465 src2 : EX1(read); 6466 dst : EX2(write); 6467 INS01 : ISS; 6468 ALU : EX2; 6469 %} 6470 6471 // Conditional 2 operand 6472 // EG. CSEL X0, X1, X2, <cond> 6473 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6474 %{ 6475 single_instruction; 6476 cr : EX1(read); 6477 src : EX1(read); 6478 dst : EX2(write); 6479 INS01 : ISS; 6480 ALU : EX2; 6481 %} 6482 6483 //------- Multiply pipeline operations -------------------- 6484 6485 // Multiply reg-reg 6486 // Eg. MUL w0, w1, w2 6487 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6488 %{ 6489 single_instruction; 6490 dst : WR(write); 6491 src1 : ISS(read); 6492 src2 : ISS(read); 6493 INS01 : ISS; 6494 MAC : WR; 6495 %} 6496 6497 // Multiply accumulate 6498 // Eg. MADD w0, w1, w2, w3 6499 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6500 %{ 6501 single_instruction; 6502 dst : WR(write); 6503 src1 : ISS(read); 6504 src2 : ISS(read); 6505 src3 : ISS(read); 6506 INS01 : ISS; 6507 MAC : WR; 6508 %} 6509 6510 // Eg. MUL w0, w1, w2 6511 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6512 %{ 6513 single_instruction; 6514 fixed_latency(3); // Maximum latency for 64 bit mul 6515 dst : WR(write); 6516 src1 : ISS(read); 6517 src2 : ISS(read); 6518 INS01 : ISS; 6519 MAC : WR; 6520 %} 6521 6522 // Multiply accumulate 6523 // Eg. MADD w0, w1, w2, w3 6524 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6525 %{ 6526 single_instruction; 6527 fixed_latency(3); // Maximum latency for 64 bit mul 6528 dst : WR(write); 6529 src1 : ISS(read); 6530 src2 : ISS(read); 6531 src3 : ISS(read); 6532 INS01 : ISS; 6533 MAC : WR; 6534 %} 6535 6536 //------- Divide pipeline operations -------------------- 6537 6538 // Eg. SDIV w0, w1, w2 6539 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6540 %{ 6541 single_instruction; 6542 fixed_latency(8); // Maximum latency for 32 bit divide 6543 dst : WR(write); 6544 src1 : ISS(read); 6545 src2 : ISS(read); 6546 INS0 : ISS; // Can only dual issue as instruction 0 6547 DIV : WR; 6548 %} 6549 6550 // Eg. SDIV x0, x1, x2 6551 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6552 %{ 6553 single_instruction; 6554 fixed_latency(16); // Maximum latency for 64 bit divide 6555 dst : WR(write); 6556 src1 : ISS(read); 6557 src2 : ISS(read); 6558 INS0 : ISS; // Can only dual issue as instruction 0 6559 DIV : WR; 6560 %} 6561 6562 //------- Load pipeline operations ------------------------ 6563 6564 // Load - prefetch 6565 // Eg. PFRM <mem> 6566 pipe_class iload_prefetch(memory mem) 6567 %{ 6568 single_instruction; 6569 mem : ISS(read); 6570 INS01 : ISS; 6571 LDST : WR; 6572 %} 6573 6574 // Load - reg, mem 6575 // Eg. LDR x0, <mem> 6576 pipe_class iload_reg_mem(iRegI dst, memory mem) 6577 %{ 6578 single_instruction; 6579 dst : WR(write); 6580 mem : ISS(read); 6581 INS01 : ISS; 6582 LDST : WR; 6583 %} 6584 6585 // Load - reg, reg 6586 // Eg. LDR x0, [sp, x1] 6587 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6588 %{ 6589 single_instruction; 6590 dst : WR(write); 6591 src : ISS(read); 6592 INS01 : ISS; 6593 LDST : WR; 6594 %} 6595 6596 //------- Store pipeline operations ----------------------- 6597 6598 // Store - zr, mem 6599 // Eg. STR zr, <mem> 6600 pipe_class istore_mem(memory mem) 6601 %{ 6602 single_instruction; 6603 mem : ISS(read); 6604 INS01 : ISS; 6605 LDST : WR; 6606 %} 6607 6608 // Store - reg, mem 6609 // Eg. STR x0, <mem> 6610 pipe_class istore_reg_mem(iRegI src, memory mem) 6611 %{ 6612 single_instruction; 6613 mem : ISS(read); 6614 src : EX2(read); 6615 INS01 : ISS; 6616 LDST : WR; 6617 %} 6618 6619 // Store - reg, reg 6620 // Eg. STR x0, [sp, x1] 6621 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6622 %{ 6623 single_instruction; 6624 dst : ISS(read); 6625 src : EX2(read); 6626 INS01 : ISS; 6627 LDST : WR; 6628 %} 6629 6630 //------- Store pipeline operations ----------------------- 6631 6632 // Branch 6633 pipe_class pipe_branch() 6634 %{ 6635 single_instruction; 6636 INS01 : ISS; 6637 BRANCH : EX1; 6638 %} 6639 6640 // Conditional branch 6641 pipe_class pipe_branch_cond(rFlagsReg cr) 6642 %{ 6643 single_instruction; 6644 cr : EX1(read); 6645 INS01 : ISS; 6646 BRANCH : EX1; 6647 %} 6648 6649 // Compare & Branch 6650 // EG. CBZ/CBNZ 6651 pipe_class pipe_cmp_branch(iRegI op1) 6652 %{ 6653 single_instruction; 6654 op1 : EX1(read); 6655 INS01 : ISS; 6656 BRANCH : EX1; 6657 %} 6658 6659 //------- Synchronisation operations ---------------------- 6660 6661 // Any operation requiring serialization. 6662 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6663 pipe_class pipe_serial() 6664 %{ 6665 single_instruction; 6666 force_serialization; 6667 fixed_latency(16); 6668 INS01 : ISS(2); // Cannot dual issue with any other instruction 6669 LDST : WR; 6670 %} 6671 6672 // Generic big/slow expanded idiom - also serialized 6673 pipe_class pipe_slow() 6674 %{ 6675 instruction_count(10); 6676 multiple_bundles; 6677 force_serialization; 6678 fixed_latency(16); 6679 INS01 : ISS(2); // Cannot dual issue with any other instruction 6680 LDST : WR; 6681 %} 6682 6683 // Empty pipeline class 6684 pipe_class pipe_class_empty() 6685 %{ 6686 single_instruction; 6687 fixed_latency(0); 6688 %} 6689 6690 // Default pipeline class. 6691 pipe_class pipe_class_default() 6692 %{ 6693 single_instruction; 6694 fixed_latency(2); 6695 %} 6696 6697 // Pipeline class for compares. 6698 pipe_class pipe_class_compare() 6699 %{ 6700 single_instruction; 6701 fixed_latency(16); 6702 %} 6703 6704 // Pipeline class for memory operations. 6705 pipe_class pipe_class_memory() 6706 %{ 6707 single_instruction; 6708 fixed_latency(16); 6709 %} 6710 6711 // Pipeline class for call. 6712 pipe_class pipe_class_call() 6713 %{ 6714 single_instruction; 6715 fixed_latency(100); 6716 %} 6717 6718 // Define the class for the Nop node. 6719 define %{ 6720 MachNop = pipe_class_empty; 6721 %} 6722 6723 %} 6724 //----------INSTRUCTIONS------------------------------------------------------- 6725 // 6726 // match -- States which machine-independent subtree may be replaced 6727 // by this instruction. 6728 // ins_cost -- The estimated cost of this instruction is used by instruction 6729 // selection to identify a minimum cost tree of machine 6730 // instructions that matches a tree of machine-independent 6731 // instructions. 6732 // format -- A string providing the disassembly for this instruction. 6733 // The value of an instruction's operand may be inserted 6734 // by referring to it with a '$' prefix. 6735 // opcode -- Three instruction opcodes may be provided. These are referred 6736 // to within an encode class as $primary, $secondary, and $tertiary 6737 // rrspectively. The primary opcode is commonly used to 6738 // indicate the type of machine instruction, while secondary 6739 // and tertiary are often used for prefix options or addressing 6740 // modes. 6741 // ins_encode -- A list of encode classes with parameters. The encode class 6742 // name must have been defined in an 'enc_class' specification 6743 // in the encode section of the architecture description. 6744 6745 // ============================================================================ 6746 // Memory (Load/Store) Instructions 6747 6748 // Load Instructions 6749 6750 // Load Byte (8 bit signed) 6751 instruct loadB(iRegINoSp dst, memory mem) 6752 %{ 6753 match(Set dst (LoadB mem)); 6754 predicate(!needs_acquiring_load(n)); 6755 6756 ins_cost(4 * INSN_COST); 6757 format %{ "ldrsbw $dst, $mem\t# byte" %} 6758 6759 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6760 6761 ins_pipe(iload_reg_mem); 6762 %} 6763 6764 // Load Byte (8 bit signed) into long 6765 instruct loadB2L(iRegLNoSp dst, memory mem) 6766 %{ 6767 match(Set dst (ConvI2L (LoadB mem))); 6768 predicate(!needs_acquiring_load(n->in(1))); 6769 6770 ins_cost(4 * INSN_COST); 6771 format %{ "ldrsb $dst, $mem\t# byte" %} 6772 6773 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6774 6775 ins_pipe(iload_reg_mem); 6776 %} 6777 6778 // Load Byte (8 bit unsigned) 6779 instruct loadUB(iRegINoSp dst, memory mem) 6780 %{ 6781 match(Set dst (LoadUB mem)); 6782 predicate(!needs_acquiring_load(n)); 6783 6784 ins_cost(4 * INSN_COST); 6785 format %{ "ldrbw $dst, $mem\t# byte" %} 6786 6787 ins_encode(aarch64_enc_ldrb(dst, mem)); 6788 6789 ins_pipe(iload_reg_mem); 6790 %} 6791 6792 // Load Byte (8 bit unsigned) into long 6793 instruct loadUB2L(iRegLNoSp dst, memory mem) 6794 %{ 6795 match(Set dst (ConvI2L (LoadUB mem))); 6796 predicate(!needs_acquiring_load(n->in(1))); 6797 6798 ins_cost(4 * INSN_COST); 6799 format %{ "ldrb $dst, $mem\t# byte" %} 6800 6801 ins_encode(aarch64_enc_ldrb(dst, mem)); 6802 6803 ins_pipe(iload_reg_mem); 6804 %} 6805 6806 // Load Short (16 bit signed) 6807 instruct loadS(iRegINoSp dst, memory mem) 6808 %{ 6809 match(Set dst (LoadS mem)); 6810 predicate(!needs_acquiring_load(n)); 6811 6812 ins_cost(4 * INSN_COST); 6813 format %{ "ldrshw $dst, $mem\t# short" %} 6814 6815 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6816 6817 ins_pipe(iload_reg_mem); 6818 %} 6819 6820 // Load Short (16 bit signed) into long 6821 instruct loadS2L(iRegLNoSp dst, memory mem) 6822 %{ 6823 match(Set dst (ConvI2L (LoadS mem))); 6824 predicate(!needs_acquiring_load(n->in(1))); 6825 6826 ins_cost(4 * INSN_COST); 6827 format %{ "ldrsh $dst, $mem\t# short" %} 6828 6829 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6830 6831 ins_pipe(iload_reg_mem); 6832 %} 6833 6834 // Load Char (16 bit unsigned) 6835 instruct loadUS(iRegINoSp dst, memory mem) 6836 %{ 6837 match(Set dst (LoadUS mem)); 6838 predicate(!needs_acquiring_load(n)); 6839 6840 ins_cost(4 * INSN_COST); 6841 format %{ "ldrh $dst, $mem\t# short" %} 6842 6843 ins_encode(aarch64_enc_ldrh(dst, mem)); 6844 6845 ins_pipe(iload_reg_mem); 6846 %} 6847 6848 // Load Short/Char (16 bit unsigned) into long 6849 instruct loadUS2L(iRegLNoSp dst, memory mem) 6850 %{ 6851 match(Set dst (ConvI2L (LoadUS mem))); 6852 predicate(!needs_acquiring_load(n->in(1))); 6853 6854 ins_cost(4 * INSN_COST); 6855 format %{ "ldrh $dst, $mem\t# short" %} 6856 6857 ins_encode(aarch64_enc_ldrh(dst, mem)); 6858 6859 ins_pipe(iload_reg_mem); 6860 %} 6861 6862 // Load Integer (32 bit signed) 6863 instruct loadI(iRegINoSp dst, memory mem) 6864 %{ 6865 match(Set dst (LoadI mem)); 6866 predicate(!needs_acquiring_load(n)); 6867 6868 ins_cost(4 * INSN_COST); 6869 format %{ "ldrw $dst, $mem\t# int" %} 6870 6871 ins_encode(aarch64_enc_ldrw(dst, mem)); 6872 6873 ins_pipe(iload_reg_mem); 6874 %} 6875 6876 // Load Integer (32 bit signed) into long 6877 instruct loadI2L(iRegLNoSp dst, memory mem) 6878 %{ 6879 match(Set dst (ConvI2L (LoadI mem))); 6880 predicate(!needs_acquiring_load(n->in(1))); 6881 6882 ins_cost(4 * INSN_COST); 6883 format %{ "ldrsw $dst, $mem\t# int" %} 6884 6885 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6886 6887 ins_pipe(iload_reg_mem); 6888 %} 6889 6890 // Load Integer (32 bit unsigned) into long 6891 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6892 %{ 6893 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6894 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6895 6896 ins_cost(4 * INSN_COST); 6897 format %{ "ldrw $dst, $mem\t# int" %} 6898 6899 ins_encode(aarch64_enc_ldrw(dst, mem)); 6900 6901 ins_pipe(iload_reg_mem); 6902 %} 6903 6904 // Load Long (64 bit signed) 6905 instruct loadL(iRegLNoSp dst, memory mem) 6906 %{ 6907 match(Set dst (LoadL mem)); 6908 predicate(!needs_acquiring_load(n)); 6909 6910 ins_cost(4 * INSN_COST); 6911 format %{ "ldr $dst, $mem\t# int" %} 6912 6913 ins_encode(aarch64_enc_ldr(dst, mem)); 6914 6915 ins_pipe(iload_reg_mem); 6916 %} 6917 6918 // Load Range 6919 instruct loadRange(iRegINoSp dst, memory mem) 6920 %{ 6921 match(Set dst (LoadRange mem)); 6922 6923 ins_cost(4 * INSN_COST); 6924 format %{ "ldrw $dst, $mem\t# range" %} 6925 6926 ins_encode(aarch64_enc_ldrw(dst, mem)); 6927 6928 ins_pipe(iload_reg_mem); 6929 %} 6930 6931 // Load Pointer 6932 instruct loadP(iRegPNoSp dst, memory mem) 6933 %{ 6934 match(Set dst (LoadP mem)); 6935 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 6936 6937 ins_cost(4 * INSN_COST); 6938 format %{ "ldr $dst, $mem\t# ptr" %} 6939 6940 ins_encode(aarch64_enc_ldr(dst, mem)); 6941 6942 ins_pipe(iload_reg_mem); 6943 %} 6944 6945 // Load Compressed Pointer 6946 instruct loadN(iRegNNoSp dst, memory mem) 6947 %{ 6948 match(Set dst (LoadN mem)); 6949 predicate(!needs_acquiring_load(n)); 6950 6951 ins_cost(4 * INSN_COST); 6952 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6953 6954 ins_encode(aarch64_enc_ldrw(dst, mem)); 6955 6956 ins_pipe(iload_reg_mem); 6957 %} 6958 6959 // Load Klass Pointer 6960 instruct loadKlass(iRegPNoSp dst, memory mem) 6961 %{ 6962 match(Set dst (LoadKlass mem)); 6963 predicate(!needs_acquiring_load(n)); 6964 6965 ins_cost(4 * INSN_COST); 6966 format %{ "ldr $dst, $mem\t# class" %} 6967 6968 ins_encode(aarch64_enc_ldr(dst, mem)); 6969 6970 ins_pipe(iload_reg_mem); 6971 %} 6972 6973 // Load Narrow Klass Pointer 6974 instruct loadNKlass(iRegNNoSp dst, memory mem) 6975 %{ 6976 match(Set dst (LoadNKlass mem)); 6977 predicate(!needs_acquiring_load(n)); 6978 6979 ins_cost(4 * INSN_COST); 6980 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6981 6982 ins_encode(aarch64_enc_ldrw(dst, mem)); 6983 6984 ins_pipe(iload_reg_mem); 6985 %} 6986 6987 // Load Float 6988 instruct loadF(vRegF dst, memory mem) 6989 %{ 6990 match(Set dst (LoadF mem)); 6991 predicate(!needs_acquiring_load(n)); 6992 6993 ins_cost(4 * INSN_COST); 6994 format %{ "ldrs $dst, $mem\t# float" %} 6995 6996 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6997 6998 ins_pipe(pipe_class_memory); 6999 %} 7000 7001 // Load Double 7002 instruct loadD(vRegD dst, memory mem) 7003 %{ 7004 match(Set dst (LoadD mem)); 7005 predicate(!needs_acquiring_load(n)); 7006 7007 ins_cost(4 * INSN_COST); 7008 format %{ "ldrd $dst, $mem\t# double" %} 7009 7010 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7011 7012 ins_pipe(pipe_class_memory); 7013 %} 7014 7015 7016 // Load Int Constant 7017 instruct loadConI(iRegINoSp dst, immI src) 7018 %{ 7019 match(Set dst src); 7020 7021 ins_cost(INSN_COST); 7022 format %{ "mov $dst, $src\t# int" %} 7023 7024 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7025 7026 ins_pipe(ialu_imm); 7027 %} 7028 7029 // Load Long Constant 7030 instruct loadConL(iRegLNoSp dst, immL src) 7031 %{ 7032 match(Set dst src); 7033 7034 ins_cost(INSN_COST); 7035 format %{ "mov $dst, $src\t# long" %} 7036 7037 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7038 7039 ins_pipe(ialu_imm); 7040 %} 7041 7042 // Load Pointer Constant 7043 7044 instruct loadConP(iRegPNoSp dst, immP con) 7045 %{ 7046 match(Set dst con); 7047 7048 ins_cost(INSN_COST * 4); 7049 format %{ 7050 "mov $dst, $con\t# ptr\n\t" 7051 %} 7052 7053 ins_encode(aarch64_enc_mov_p(dst, con)); 7054 7055 ins_pipe(ialu_imm); 7056 %} 7057 7058 // Load Null Pointer Constant 7059 7060 instruct loadConP0(iRegPNoSp dst, immP0 con) 7061 %{ 7062 match(Set dst con); 7063 7064 ins_cost(INSN_COST); 7065 format %{ "mov $dst, $con\t# NULL ptr" %} 7066 7067 ins_encode(aarch64_enc_mov_p0(dst, con)); 7068 7069 ins_pipe(ialu_imm); 7070 %} 7071 7072 // Load Pointer Constant One 7073 7074 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7075 %{ 7076 match(Set dst con); 7077 7078 ins_cost(INSN_COST); 7079 format %{ "mov $dst, $con\t# NULL ptr" %} 7080 7081 ins_encode(aarch64_enc_mov_p1(dst, con)); 7082 7083 ins_pipe(ialu_imm); 7084 %} 7085 7086 // Load Poll Page Constant 7087 7088 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 7089 %{ 7090 match(Set dst con); 7091 7092 ins_cost(INSN_COST); 7093 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 7094 7095 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 7096 7097 ins_pipe(ialu_imm); 7098 %} 7099 7100 // Load Byte Map Base Constant 7101 7102 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7103 %{ 7104 match(Set dst con); 7105 7106 ins_cost(INSN_COST); 7107 format %{ "adr $dst, $con\t# Byte Map Base" %} 7108 7109 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7110 7111 ins_pipe(ialu_imm); 7112 %} 7113 7114 // Load Narrow Pointer Constant 7115 7116 instruct loadConN(iRegNNoSp dst, immN con) 7117 %{ 7118 match(Set dst con); 7119 7120 ins_cost(INSN_COST * 4); 7121 format %{ "mov $dst, $con\t# compressed ptr" %} 7122 7123 ins_encode(aarch64_enc_mov_n(dst, con)); 7124 7125 ins_pipe(ialu_imm); 7126 %} 7127 7128 // Load Narrow Null Pointer Constant 7129 7130 instruct loadConN0(iRegNNoSp dst, immN0 con) 7131 %{ 7132 match(Set dst con); 7133 7134 ins_cost(INSN_COST); 7135 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7136 7137 ins_encode(aarch64_enc_mov_n0(dst, con)); 7138 7139 ins_pipe(ialu_imm); 7140 %} 7141 7142 // Load Narrow Klass Constant 7143 7144 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7145 %{ 7146 match(Set dst con); 7147 7148 ins_cost(INSN_COST); 7149 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7150 7151 ins_encode(aarch64_enc_mov_nk(dst, con)); 7152 7153 ins_pipe(ialu_imm); 7154 %} 7155 7156 // Load Packed Float Constant 7157 7158 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7159 match(Set dst con); 7160 ins_cost(INSN_COST * 4); 7161 format %{ "fmovs $dst, $con"%} 7162 ins_encode %{ 7163 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7164 %} 7165 7166 ins_pipe(fp_imm_s); 7167 %} 7168 7169 // Load Float Constant 7170 7171 instruct loadConF(vRegF dst, immF con) %{ 7172 match(Set dst con); 7173 7174 ins_cost(INSN_COST * 4); 7175 7176 format %{ 7177 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7178 %} 7179 7180 ins_encode %{ 7181 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7182 %} 7183 7184 ins_pipe(fp_load_constant_s); 7185 %} 7186 7187 // Load Packed Double Constant 7188 7189 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7190 match(Set dst con); 7191 ins_cost(INSN_COST); 7192 format %{ "fmovd $dst, $con"%} 7193 ins_encode %{ 7194 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7195 %} 7196 7197 ins_pipe(fp_imm_d); 7198 %} 7199 7200 // Load Double Constant 7201 7202 instruct loadConD(vRegD dst, immD con) %{ 7203 match(Set dst con); 7204 7205 ins_cost(INSN_COST * 5); 7206 format %{ 7207 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7208 %} 7209 7210 ins_encode %{ 7211 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7212 %} 7213 7214 ins_pipe(fp_load_constant_d); 7215 %} 7216 7217 // Store Instructions 7218 7219 // Store CMS card-mark Immediate 7220 instruct storeimmCM0(immI0 zero, memory mem) 7221 %{ 7222 match(Set mem (StoreCM mem zero)); 7223 predicate(unnecessary_storestore(n)); 7224 7225 ins_cost(INSN_COST); 7226 format %{ "storestore (elided)\n\t" 7227 "strb zr, $mem\t# byte" %} 7228 7229 ins_encode(aarch64_enc_strb0(mem)); 7230 7231 ins_pipe(istore_mem); 7232 %} 7233 7234 // Store CMS card-mark Immediate with intervening StoreStore 7235 // needed when using CMS with no conditional card marking 7236 instruct storeimmCM0_ordered(immI0 zero, memory mem) 7237 %{ 7238 match(Set mem (StoreCM mem zero)); 7239 7240 ins_cost(INSN_COST * 2); 7241 format %{ "storestore\n\t" 7242 "dmb ishst" 7243 "\n\tstrb zr, $mem\t# byte" %} 7244 7245 ins_encode(aarch64_enc_strb0_ordered(mem)); 7246 7247 ins_pipe(istore_mem); 7248 %} 7249 7250 // Store Byte 7251 instruct storeB(iRegIorL2I src, memory mem) 7252 %{ 7253 match(Set mem (StoreB mem src)); 7254 predicate(!needs_releasing_store(n)); 7255 7256 ins_cost(INSN_COST); 7257 format %{ "strb $src, $mem\t# byte" %} 7258 7259 ins_encode(aarch64_enc_strb(src, mem)); 7260 7261 ins_pipe(istore_reg_mem); 7262 %} 7263 7264 7265 instruct storeimmB0(immI0 zero, memory mem) 7266 %{ 7267 match(Set mem (StoreB mem zero)); 7268 predicate(!needs_releasing_store(n)); 7269 7270 ins_cost(INSN_COST); 7271 format %{ "strb rscractch2, $mem\t# byte" %} 7272 7273 ins_encode(aarch64_enc_strb0(mem)); 7274 7275 ins_pipe(istore_mem); 7276 %} 7277 7278 // Store Char/Short 7279 instruct storeC(iRegIorL2I src, memory mem) 7280 %{ 7281 match(Set mem (StoreC mem src)); 7282 predicate(!needs_releasing_store(n)); 7283 7284 ins_cost(INSN_COST); 7285 format %{ "strh $src, $mem\t# short" %} 7286 7287 ins_encode(aarch64_enc_strh(src, mem)); 7288 7289 ins_pipe(istore_reg_mem); 7290 %} 7291 7292 instruct storeimmC0(immI0 zero, memory mem) 7293 %{ 7294 match(Set mem (StoreC mem zero)); 7295 predicate(!needs_releasing_store(n)); 7296 7297 ins_cost(INSN_COST); 7298 format %{ "strh zr, $mem\t# short" %} 7299 7300 ins_encode(aarch64_enc_strh0(mem)); 7301 7302 ins_pipe(istore_mem); 7303 %} 7304 7305 // Store Integer 7306 7307 instruct storeI(iRegIorL2I src, memory mem) 7308 %{ 7309 match(Set mem(StoreI mem src)); 7310 predicate(!needs_releasing_store(n)); 7311 7312 ins_cost(INSN_COST); 7313 format %{ "strw $src, $mem\t# int" %} 7314 7315 ins_encode(aarch64_enc_strw(src, mem)); 7316 7317 ins_pipe(istore_reg_mem); 7318 %} 7319 7320 instruct storeimmI0(immI0 zero, memory mem) 7321 %{ 7322 match(Set mem(StoreI mem zero)); 7323 predicate(!needs_releasing_store(n)); 7324 7325 ins_cost(INSN_COST); 7326 format %{ "strw zr, $mem\t# int" %} 7327 7328 ins_encode(aarch64_enc_strw0(mem)); 7329 7330 ins_pipe(istore_mem); 7331 %} 7332 7333 // Store Long (64 bit signed) 7334 instruct storeL(iRegL src, memory mem) 7335 %{ 7336 match(Set mem (StoreL mem src)); 7337 predicate(!needs_releasing_store(n)); 7338 7339 ins_cost(INSN_COST); 7340 format %{ "str $src, $mem\t# int" %} 7341 7342 ins_encode(aarch64_enc_str(src, mem)); 7343 7344 ins_pipe(istore_reg_mem); 7345 %} 7346 7347 // Store Long (64 bit signed) 7348 instruct storeimmL0(immL0 zero, memory mem) 7349 %{ 7350 match(Set mem (StoreL mem zero)); 7351 predicate(!needs_releasing_store(n)); 7352 7353 ins_cost(INSN_COST); 7354 format %{ "str zr, $mem\t# int" %} 7355 7356 ins_encode(aarch64_enc_str0(mem)); 7357 7358 ins_pipe(istore_mem); 7359 %} 7360 7361 // Store Pointer 7362 instruct storeP(iRegP src, memory mem) 7363 %{ 7364 match(Set mem (StoreP mem src)); 7365 predicate(!needs_releasing_store(n)); 7366 7367 ins_cost(INSN_COST); 7368 format %{ "str $src, $mem\t# ptr" %} 7369 7370 ins_encode(aarch64_enc_str(src, mem)); 7371 7372 ins_pipe(istore_reg_mem); 7373 %} 7374 7375 // Store Pointer 7376 instruct storeimmP0(immP0 zero, memory mem) 7377 %{ 7378 match(Set mem (StoreP mem zero)); 7379 predicate(!needs_releasing_store(n)); 7380 7381 ins_cost(INSN_COST); 7382 format %{ "str zr, $mem\t# ptr" %} 7383 7384 ins_encode(aarch64_enc_str0(mem)); 7385 7386 ins_pipe(istore_mem); 7387 %} 7388 7389 // Store Compressed Pointer 7390 instruct storeN(iRegN src, memory mem) 7391 %{ 7392 match(Set mem (StoreN mem src)); 7393 predicate(!needs_releasing_store(n)); 7394 7395 ins_cost(INSN_COST); 7396 format %{ "strw $src, $mem\t# compressed ptr" %} 7397 7398 ins_encode(aarch64_enc_strw(src, mem)); 7399 7400 ins_pipe(istore_reg_mem); 7401 %} 7402 7403 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7404 %{ 7405 match(Set mem (StoreN mem zero)); 7406 predicate(CompressedOops::base() == NULL && 7407 CompressedKlassPointers::base() == NULL && 7408 (!needs_releasing_store(n))); 7409 7410 ins_cost(INSN_COST); 7411 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7412 7413 ins_encode(aarch64_enc_strw(heapbase, mem)); 7414 7415 ins_pipe(istore_reg_mem); 7416 %} 7417 7418 // Store Float 7419 instruct storeF(vRegF src, memory mem) 7420 %{ 7421 match(Set mem (StoreF mem src)); 7422 predicate(!needs_releasing_store(n)); 7423 7424 ins_cost(INSN_COST); 7425 format %{ "strs $src, $mem\t# float" %} 7426 7427 ins_encode( aarch64_enc_strs(src, mem) ); 7428 7429 ins_pipe(pipe_class_memory); 7430 %} 7431 7432 // TODO 7433 // implement storeImmF0 and storeFImmPacked 7434 7435 // Store Double 7436 instruct storeD(vRegD src, memory mem) 7437 %{ 7438 match(Set mem (StoreD mem src)); 7439 predicate(!needs_releasing_store(n)); 7440 7441 ins_cost(INSN_COST); 7442 format %{ "strd $src, $mem\t# double" %} 7443 7444 ins_encode( aarch64_enc_strd(src, mem) ); 7445 7446 ins_pipe(pipe_class_memory); 7447 %} 7448 7449 // Store Compressed Klass Pointer 7450 instruct storeNKlass(iRegN src, memory mem) 7451 %{ 7452 predicate(!needs_releasing_store(n)); 7453 match(Set mem (StoreNKlass mem src)); 7454 7455 ins_cost(INSN_COST); 7456 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7457 7458 ins_encode(aarch64_enc_strw(src, mem)); 7459 7460 ins_pipe(istore_reg_mem); 7461 %} 7462 7463 // TODO 7464 // implement storeImmD0 and storeDImmPacked 7465 7466 // prefetch instructions 7467 // Must be safe to execute with invalid address (cannot fault). 7468 7469 instruct prefetchalloc( memory mem ) %{ 7470 match(PrefetchAllocation mem); 7471 7472 ins_cost(INSN_COST); 7473 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7474 7475 ins_encode( aarch64_enc_prefetchw(mem) ); 7476 7477 ins_pipe(iload_prefetch); 7478 %} 7479 7480 // ---------------- volatile loads and stores ---------------- 7481 7482 // Load Byte (8 bit signed) 7483 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7484 %{ 7485 match(Set dst (LoadB mem)); 7486 7487 ins_cost(VOLATILE_REF_COST); 7488 format %{ "ldarsb $dst, $mem\t# byte" %} 7489 7490 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7491 7492 ins_pipe(pipe_serial); 7493 %} 7494 7495 // Load Byte (8 bit signed) into long 7496 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7497 %{ 7498 match(Set dst (ConvI2L (LoadB mem))); 7499 7500 ins_cost(VOLATILE_REF_COST); 7501 format %{ "ldarsb $dst, $mem\t# byte" %} 7502 7503 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7504 7505 ins_pipe(pipe_serial); 7506 %} 7507 7508 // Load Byte (8 bit unsigned) 7509 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7510 %{ 7511 match(Set dst (LoadUB mem)); 7512 7513 ins_cost(VOLATILE_REF_COST); 7514 format %{ "ldarb $dst, $mem\t# byte" %} 7515 7516 ins_encode(aarch64_enc_ldarb(dst, mem)); 7517 7518 ins_pipe(pipe_serial); 7519 %} 7520 7521 // Load Byte (8 bit unsigned) into long 7522 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7523 %{ 7524 match(Set dst (ConvI2L (LoadUB mem))); 7525 7526 ins_cost(VOLATILE_REF_COST); 7527 format %{ "ldarb $dst, $mem\t# byte" %} 7528 7529 ins_encode(aarch64_enc_ldarb(dst, mem)); 7530 7531 ins_pipe(pipe_serial); 7532 %} 7533 7534 // Load Short (16 bit signed) 7535 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7536 %{ 7537 match(Set dst (LoadS mem)); 7538 7539 ins_cost(VOLATILE_REF_COST); 7540 format %{ "ldarshw $dst, $mem\t# short" %} 7541 7542 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7543 7544 ins_pipe(pipe_serial); 7545 %} 7546 7547 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7548 %{ 7549 match(Set dst (LoadUS mem)); 7550 7551 ins_cost(VOLATILE_REF_COST); 7552 format %{ "ldarhw $dst, $mem\t# short" %} 7553 7554 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7555 7556 ins_pipe(pipe_serial); 7557 %} 7558 7559 // Load Short/Char (16 bit unsigned) into long 7560 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7561 %{ 7562 match(Set dst (ConvI2L (LoadUS mem))); 7563 7564 ins_cost(VOLATILE_REF_COST); 7565 format %{ "ldarh $dst, $mem\t# short" %} 7566 7567 ins_encode(aarch64_enc_ldarh(dst, mem)); 7568 7569 ins_pipe(pipe_serial); 7570 %} 7571 7572 // Load Short/Char (16 bit signed) into long 7573 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7574 %{ 7575 match(Set dst (ConvI2L (LoadS mem))); 7576 7577 ins_cost(VOLATILE_REF_COST); 7578 format %{ "ldarh $dst, $mem\t# short" %} 7579 7580 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7581 7582 ins_pipe(pipe_serial); 7583 %} 7584 7585 // Load Integer (32 bit signed) 7586 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7587 %{ 7588 match(Set dst (LoadI mem)); 7589 7590 ins_cost(VOLATILE_REF_COST); 7591 format %{ "ldarw $dst, $mem\t# int" %} 7592 7593 ins_encode(aarch64_enc_ldarw(dst, mem)); 7594 7595 ins_pipe(pipe_serial); 7596 %} 7597 7598 // Load Integer (32 bit unsigned) into long 7599 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7600 %{ 7601 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7602 7603 ins_cost(VOLATILE_REF_COST); 7604 format %{ "ldarw $dst, $mem\t# int" %} 7605 7606 ins_encode(aarch64_enc_ldarw(dst, mem)); 7607 7608 ins_pipe(pipe_serial); 7609 %} 7610 7611 // Load Long (64 bit signed) 7612 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7613 %{ 7614 match(Set dst (LoadL mem)); 7615 7616 ins_cost(VOLATILE_REF_COST); 7617 format %{ "ldar $dst, $mem\t# int" %} 7618 7619 ins_encode(aarch64_enc_ldar(dst, mem)); 7620 7621 ins_pipe(pipe_serial); 7622 %} 7623 7624 // Load Pointer 7625 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7626 %{ 7627 match(Set dst (LoadP mem)); 7628 predicate(n->as_Load()->barrier_data() == 0); 7629 7630 ins_cost(VOLATILE_REF_COST); 7631 format %{ "ldar $dst, $mem\t# ptr" %} 7632 7633 ins_encode(aarch64_enc_ldar(dst, mem)); 7634 7635 ins_pipe(pipe_serial); 7636 %} 7637 7638 // Load Compressed Pointer 7639 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7640 %{ 7641 match(Set dst (LoadN mem)); 7642 7643 ins_cost(VOLATILE_REF_COST); 7644 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7645 7646 ins_encode(aarch64_enc_ldarw(dst, mem)); 7647 7648 ins_pipe(pipe_serial); 7649 %} 7650 7651 // Load Float 7652 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7653 %{ 7654 match(Set dst (LoadF mem)); 7655 7656 ins_cost(VOLATILE_REF_COST); 7657 format %{ "ldars $dst, $mem\t# float" %} 7658 7659 ins_encode( aarch64_enc_fldars(dst, mem) ); 7660 7661 ins_pipe(pipe_serial); 7662 %} 7663 7664 // Load Double 7665 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7666 %{ 7667 match(Set dst (LoadD mem)); 7668 7669 ins_cost(VOLATILE_REF_COST); 7670 format %{ "ldard $dst, $mem\t# double" %} 7671 7672 ins_encode( aarch64_enc_fldard(dst, mem) ); 7673 7674 ins_pipe(pipe_serial); 7675 %} 7676 7677 // Store Byte 7678 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7679 %{ 7680 match(Set mem (StoreB mem src)); 7681 7682 ins_cost(VOLATILE_REF_COST); 7683 format %{ "stlrb $src, $mem\t# byte" %} 7684 7685 ins_encode(aarch64_enc_stlrb(src, mem)); 7686 7687 ins_pipe(pipe_class_memory); 7688 %} 7689 7690 // Store Char/Short 7691 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7692 %{ 7693 match(Set mem (StoreC mem src)); 7694 7695 ins_cost(VOLATILE_REF_COST); 7696 format %{ "stlrh $src, $mem\t# short" %} 7697 7698 ins_encode(aarch64_enc_stlrh(src, mem)); 7699 7700 ins_pipe(pipe_class_memory); 7701 %} 7702 7703 // Store Integer 7704 7705 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7706 %{ 7707 match(Set mem(StoreI mem src)); 7708 7709 ins_cost(VOLATILE_REF_COST); 7710 format %{ "stlrw $src, $mem\t# int" %} 7711 7712 ins_encode(aarch64_enc_stlrw(src, mem)); 7713 7714 ins_pipe(pipe_class_memory); 7715 %} 7716 7717 // Store Long (64 bit signed) 7718 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7719 %{ 7720 match(Set mem (StoreL mem src)); 7721 7722 ins_cost(VOLATILE_REF_COST); 7723 format %{ "stlr $src, $mem\t# int" %} 7724 7725 ins_encode(aarch64_enc_stlr(src, mem)); 7726 7727 ins_pipe(pipe_class_memory); 7728 %} 7729 7730 // Store Pointer 7731 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7732 %{ 7733 match(Set mem (StoreP mem src)); 7734 7735 ins_cost(VOLATILE_REF_COST); 7736 format %{ "stlr $src, $mem\t# ptr" %} 7737 7738 ins_encode(aarch64_enc_stlr(src, mem)); 7739 7740 ins_pipe(pipe_class_memory); 7741 %} 7742 7743 // Store Compressed Pointer 7744 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7745 %{ 7746 match(Set mem (StoreN mem src)); 7747 7748 ins_cost(VOLATILE_REF_COST); 7749 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7750 7751 ins_encode(aarch64_enc_stlrw(src, mem)); 7752 7753 ins_pipe(pipe_class_memory); 7754 %} 7755 7756 // Store Float 7757 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7758 %{ 7759 match(Set mem (StoreF mem src)); 7760 7761 ins_cost(VOLATILE_REF_COST); 7762 format %{ "stlrs $src, $mem\t# float" %} 7763 7764 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7765 7766 ins_pipe(pipe_class_memory); 7767 %} 7768 7769 // TODO 7770 // implement storeImmF0 and storeFImmPacked 7771 7772 // Store Double 7773 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7774 %{ 7775 match(Set mem (StoreD mem src)); 7776 7777 ins_cost(VOLATILE_REF_COST); 7778 format %{ "stlrd $src, $mem\t# double" %} 7779 7780 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7781 7782 ins_pipe(pipe_class_memory); 7783 %} 7784 7785 // ---------------- end of volatile loads and stores ---------------- 7786 7787 instruct cacheWB(indirect addr) 7788 %{ 7789 predicate(VM_Version::supports_data_cache_line_flush()); 7790 match(CacheWB addr); 7791 7792 ins_cost(100); 7793 format %{"cache wb $addr" %} 7794 ins_encode %{ 7795 assert($addr->index_position() < 0, "should be"); 7796 assert($addr$$disp == 0, "should be"); 7797 __ cache_wb(Address($addr$$base$$Register, 0)); 7798 %} 7799 ins_pipe(pipe_slow); // XXX 7800 %} 7801 7802 instruct cacheWBPreSync() 7803 %{ 7804 predicate(VM_Version::supports_data_cache_line_flush()); 7805 match(CacheWBPreSync); 7806 7807 ins_cost(100); 7808 format %{"cache wb presync" %} 7809 ins_encode %{ 7810 __ cache_wbsync(true); 7811 %} 7812 ins_pipe(pipe_slow); // XXX 7813 %} 7814 7815 instruct cacheWBPostSync() 7816 %{ 7817 predicate(VM_Version::supports_data_cache_line_flush()); 7818 match(CacheWBPostSync); 7819 7820 ins_cost(100); 7821 format %{"cache wb postsync" %} 7822 ins_encode %{ 7823 __ cache_wbsync(false); 7824 %} 7825 ins_pipe(pipe_slow); // XXX 7826 %} 7827 7828 // ============================================================================ 7829 // BSWAP Instructions 7830 7831 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7832 match(Set dst (ReverseBytesI src)); 7833 7834 ins_cost(INSN_COST); 7835 format %{ "revw $dst, $src" %} 7836 7837 ins_encode %{ 7838 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7839 %} 7840 7841 ins_pipe(ialu_reg); 7842 %} 7843 7844 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7845 match(Set dst (ReverseBytesL src)); 7846 7847 ins_cost(INSN_COST); 7848 format %{ "rev $dst, $src" %} 7849 7850 ins_encode %{ 7851 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7852 %} 7853 7854 ins_pipe(ialu_reg); 7855 %} 7856 7857 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7858 match(Set dst (ReverseBytesUS src)); 7859 7860 ins_cost(INSN_COST); 7861 format %{ "rev16w $dst, $src" %} 7862 7863 ins_encode %{ 7864 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7865 %} 7866 7867 ins_pipe(ialu_reg); 7868 %} 7869 7870 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7871 match(Set dst (ReverseBytesS src)); 7872 7873 ins_cost(INSN_COST); 7874 format %{ "rev16w $dst, $src\n\t" 7875 "sbfmw $dst, $dst, #0, #15" %} 7876 7877 ins_encode %{ 7878 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7879 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7880 %} 7881 7882 ins_pipe(ialu_reg); 7883 %} 7884 7885 // ============================================================================ 7886 // Zero Count Instructions 7887 7888 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7889 match(Set dst (CountLeadingZerosI src)); 7890 7891 ins_cost(INSN_COST); 7892 format %{ "clzw $dst, $src" %} 7893 ins_encode %{ 7894 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7895 %} 7896 7897 ins_pipe(ialu_reg); 7898 %} 7899 7900 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7901 match(Set dst (CountLeadingZerosL src)); 7902 7903 ins_cost(INSN_COST); 7904 format %{ "clz $dst, $src" %} 7905 ins_encode %{ 7906 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7907 %} 7908 7909 ins_pipe(ialu_reg); 7910 %} 7911 7912 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7913 match(Set dst (CountTrailingZerosI src)); 7914 7915 ins_cost(INSN_COST * 2); 7916 format %{ "rbitw $dst, $src\n\t" 7917 "clzw $dst, $dst" %} 7918 ins_encode %{ 7919 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7920 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7921 %} 7922 7923 ins_pipe(ialu_reg); 7924 %} 7925 7926 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7927 match(Set dst (CountTrailingZerosL src)); 7928 7929 ins_cost(INSN_COST * 2); 7930 format %{ "rbit $dst, $src\n\t" 7931 "clz $dst, $dst" %} 7932 ins_encode %{ 7933 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7934 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7935 %} 7936 7937 ins_pipe(ialu_reg); 7938 %} 7939 7940 //---------- Population Count Instructions ------------------------------------- 7941 // 7942 7943 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7944 predicate(UsePopCountInstruction); 7945 match(Set dst (PopCountI src)); 7946 effect(TEMP tmp); 7947 ins_cost(INSN_COST * 13); 7948 7949 format %{ "movw $src, $src\n\t" 7950 "mov $tmp, $src\t# vector (1D)\n\t" 7951 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7952 "addv $tmp, $tmp\t# vector (8B)\n\t" 7953 "mov $dst, $tmp\t# vector (1D)" %} 7954 ins_encode %{ 7955 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7956 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7957 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7958 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7959 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7960 %} 7961 7962 ins_pipe(pipe_class_default); 7963 %} 7964 7965 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7966 predicate(UsePopCountInstruction); 7967 match(Set dst (PopCountI (LoadI mem))); 7968 effect(TEMP tmp); 7969 ins_cost(INSN_COST * 13); 7970 7971 format %{ "ldrs $tmp, $mem\n\t" 7972 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7973 "addv $tmp, $tmp\t# vector (8B)\n\t" 7974 "mov $dst, $tmp\t# vector (1D)" %} 7975 ins_encode %{ 7976 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7977 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7978 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7979 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7980 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7981 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7982 %} 7983 7984 ins_pipe(pipe_class_default); 7985 %} 7986 7987 // Note: Long.bitCount(long) returns an int. 7988 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7989 predicate(UsePopCountInstruction); 7990 match(Set dst (PopCountL src)); 7991 effect(TEMP tmp); 7992 ins_cost(INSN_COST * 13); 7993 7994 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7995 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7996 "addv $tmp, $tmp\t# vector (8B)\n\t" 7997 "mov $dst, $tmp\t# vector (1D)" %} 7998 ins_encode %{ 7999 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8000 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8001 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8002 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8003 %} 8004 8005 ins_pipe(pipe_class_default); 8006 %} 8007 8008 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 8009 predicate(UsePopCountInstruction); 8010 match(Set dst (PopCountL (LoadL mem))); 8011 effect(TEMP tmp); 8012 ins_cost(INSN_COST * 13); 8013 8014 format %{ "ldrd $tmp, $mem\n\t" 8015 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8016 "addv $tmp, $tmp\t# vector (8B)\n\t" 8017 "mov $dst, $tmp\t# vector (1D)" %} 8018 ins_encode %{ 8019 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8020 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8021 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 8022 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8023 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8024 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8025 %} 8026 8027 ins_pipe(pipe_class_default); 8028 %} 8029 8030 // ============================================================================ 8031 // MemBar Instruction 8032 8033 instruct load_fence() %{ 8034 match(LoadFence); 8035 ins_cost(VOLATILE_REF_COST); 8036 8037 format %{ "load_fence" %} 8038 8039 ins_encode %{ 8040 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8041 %} 8042 ins_pipe(pipe_serial); 8043 %} 8044 8045 instruct unnecessary_membar_acquire() %{ 8046 predicate(unnecessary_acquire(n)); 8047 match(MemBarAcquire); 8048 ins_cost(0); 8049 8050 format %{ "membar_acquire (elided)" %} 8051 8052 ins_encode %{ 8053 __ block_comment("membar_acquire (elided)"); 8054 %} 8055 8056 ins_pipe(pipe_class_empty); 8057 %} 8058 8059 instruct membar_acquire() %{ 8060 match(MemBarAcquire); 8061 ins_cost(VOLATILE_REF_COST); 8062 8063 format %{ "membar_acquire\n\t" 8064 "dmb ish" %} 8065 8066 ins_encode %{ 8067 __ block_comment("membar_acquire"); 8068 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8069 %} 8070 8071 ins_pipe(pipe_serial); 8072 %} 8073 8074 8075 instruct membar_acquire_lock() %{ 8076 match(MemBarAcquireLock); 8077 ins_cost(VOLATILE_REF_COST); 8078 8079 format %{ "membar_acquire_lock (elided)" %} 8080 8081 ins_encode %{ 8082 __ block_comment("membar_acquire_lock (elided)"); 8083 %} 8084 8085 ins_pipe(pipe_serial); 8086 %} 8087 8088 instruct store_fence() %{ 8089 match(StoreFence); 8090 ins_cost(VOLATILE_REF_COST); 8091 8092 format %{ "store_fence" %} 8093 8094 ins_encode %{ 8095 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8096 %} 8097 ins_pipe(pipe_serial); 8098 %} 8099 8100 instruct unnecessary_membar_release() %{ 8101 predicate(unnecessary_release(n)); 8102 match(MemBarRelease); 8103 ins_cost(0); 8104 8105 format %{ "membar_release (elided)" %} 8106 8107 ins_encode %{ 8108 __ block_comment("membar_release (elided)"); 8109 %} 8110 ins_pipe(pipe_serial); 8111 %} 8112 8113 instruct membar_release() %{ 8114 match(MemBarRelease); 8115 ins_cost(VOLATILE_REF_COST); 8116 8117 format %{ "membar_release\n\t" 8118 "dmb ish" %} 8119 8120 ins_encode %{ 8121 __ block_comment("membar_release"); 8122 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8123 %} 8124 ins_pipe(pipe_serial); 8125 %} 8126 8127 instruct membar_storestore() %{ 8128 match(MemBarStoreStore); 8129 ins_cost(VOLATILE_REF_COST); 8130 8131 format %{ "MEMBAR-store-store" %} 8132 8133 ins_encode %{ 8134 __ membar(Assembler::StoreStore); 8135 %} 8136 ins_pipe(pipe_serial); 8137 %} 8138 8139 instruct membar_release_lock() %{ 8140 match(MemBarReleaseLock); 8141 ins_cost(VOLATILE_REF_COST); 8142 8143 format %{ "membar_release_lock (elided)" %} 8144 8145 ins_encode %{ 8146 __ block_comment("membar_release_lock (elided)"); 8147 %} 8148 8149 ins_pipe(pipe_serial); 8150 %} 8151 8152 instruct unnecessary_membar_volatile() %{ 8153 predicate(unnecessary_volatile(n)); 8154 match(MemBarVolatile); 8155 ins_cost(0); 8156 8157 format %{ "membar_volatile (elided)" %} 8158 8159 ins_encode %{ 8160 __ block_comment("membar_volatile (elided)"); 8161 %} 8162 8163 ins_pipe(pipe_serial); 8164 %} 8165 8166 instruct membar_volatile() %{ 8167 match(MemBarVolatile); 8168 ins_cost(VOLATILE_REF_COST*100); 8169 8170 format %{ "membar_volatile\n\t" 8171 "dmb ish"%} 8172 8173 ins_encode %{ 8174 __ block_comment("membar_volatile"); 8175 __ membar(Assembler::StoreLoad); 8176 %} 8177 8178 ins_pipe(pipe_serial); 8179 %} 8180 8181 // ============================================================================ 8182 // Cast/Convert Instructions 8183 8184 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8185 match(Set dst (CastX2P src)); 8186 8187 ins_cost(INSN_COST); 8188 format %{ "mov $dst, $src\t# long -> ptr" %} 8189 8190 ins_encode %{ 8191 if ($dst$$reg != $src$$reg) { 8192 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8193 } 8194 %} 8195 8196 ins_pipe(ialu_reg); 8197 %} 8198 8199 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8200 match(Set dst (CastP2X src)); 8201 8202 ins_cost(INSN_COST); 8203 format %{ "mov $dst, $src\t# ptr -> long" %} 8204 8205 ins_encode %{ 8206 if ($dst$$reg != $src$$reg) { 8207 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8208 } 8209 %} 8210 8211 ins_pipe(ialu_reg); 8212 %} 8213 8214 // Convert oop into int for vectors alignment masking 8215 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8216 match(Set dst (ConvL2I (CastP2X src))); 8217 8218 ins_cost(INSN_COST); 8219 format %{ "movw $dst, $src\t# ptr -> int" %} 8220 ins_encode %{ 8221 __ movw($dst$$Register, $src$$Register); 8222 %} 8223 8224 ins_pipe(ialu_reg); 8225 %} 8226 8227 // Convert compressed oop into int for vectors alignment masking 8228 // in case of 32bit oops (heap < 4Gb). 8229 instruct convN2I(iRegINoSp dst, iRegN src) 8230 %{ 8231 predicate(CompressedOops::shift() == 0); 8232 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8233 8234 ins_cost(INSN_COST); 8235 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8236 ins_encode %{ 8237 __ movw($dst$$Register, $src$$Register); 8238 %} 8239 8240 ins_pipe(ialu_reg); 8241 %} 8242 8243 8244 // Convert oop pointer into compressed form 8245 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8246 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8247 match(Set dst (EncodeP src)); 8248 effect(KILL cr); 8249 ins_cost(INSN_COST * 3); 8250 format %{ "encode_heap_oop $dst, $src" %} 8251 ins_encode %{ 8252 Register s = $src$$Register; 8253 Register d = $dst$$Register; 8254 __ encode_heap_oop(d, s); 8255 %} 8256 ins_pipe(ialu_reg); 8257 %} 8258 8259 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8260 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8261 match(Set dst (EncodeP src)); 8262 ins_cost(INSN_COST * 3); 8263 format %{ "encode_heap_oop_not_null $dst, $src" %} 8264 ins_encode %{ 8265 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8266 %} 8267 ins_pipe(ialu_reg); 8268 %} 8269 8270 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8271 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8272 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8273 match(Set dst (DecodeN src)); 8274 ins_cost(INSN_COST * 3); 8275 format %{ "decode_heap_oop $dst, $src" %} 8276 ins_encode %{ 8277 Register s = $src$$Register; 8278 Register d = $dst$$Register; 8279 __ decode_heap_oop(d, s); 8280 %} 8281 ins_pipe(ialu_reg); 8282 %} 8283 8284 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8285 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8286 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8287 match(Set dst (DecodeN src)); 8288 ins_cost(INSN_COST * 3); 8289 format %{ "decode_heap_oop_not_null $dst, $src" %} 8290 ins_encode %{ 8291 Register s = $src$$Register; 8292 Register d = $dst$$Register; 8293 __ decode_heap_oop_not_null(d, s); 8294 %} 8295 ins_pipe(ialu_reg); 8296 %} 8297 8298 // n.b. AArch64 implementations of encode_klass_not_null and 8299 // decode_klass_not_null do not modify the flags register so, unlike 8300 // Intel, we don't kill CR as a side effect here 8301 8302 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8303 match(Set dst (EncodePKlass src)); 8304 8305 ins_cost(INSN_COST * 3); 8306 format %{ "encode_klass_not_null $dst,$src" %} 8307 8308 ins_encode %{ 8309 Register src_reg = as_Register($src$$reg); 8310 Register dst_reg = as_Register($dst$$reg); 8311 __ encode_klass_not_null(dst_reg, src_reg); 8312 %} 8313 8314 ins_pipe(ialu_reg); 8315 %} 8316 8317 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8318 match(Set dst (DecodeNKlass src)); 8319 8320 ins_cost(INSN_COST * 3); 8321 format %{ "decode_klass_not_null $dst,$src" %} 8322 8323 ins_encode %{ 8324 Register src_reg = as_Register($src$$reg); 8325 Register dst_reg = as_Register($dst$$reg); 8326 if (dst_reg != src_reg) { 8327 __ decode_klass_not_null(dst_reg, src_reg); 8328 } else { 8329 __ decode_klass_not_null(dst_reg); 8330 } 8331 %} 8332 8333 ins_pipe(ialu_reg); 8334 %} 8335 8336 instruct checkCastPP(iRegPNoSp dst) 8337 %{ 8338 match(Set dst (CheckCastPP dst)); 8339 8340 size(0); 8341 format %{ "# checkcastPP of $dst" %} 8342 ins_encode(/* empty encoding */); 8343 ins_pipe(pipe_class_empty); 8344 %} 8345 8346 instruct castPP(iRegPNoSp dst) 8347 %{ 8348 match(Set dst (CastPP dst)); 8349 8350 size(0); 8351 format %{ "# castPP of $dst" %} 8352 ins_encode(/* empty encoding */); 8353 ins_pipe(pipe_class_empty); 8354 %} 8355 8356 instruct castII(iRegI dst) 8357 %{ 8358 match(Set dst (CastII dst)); 8359 8360 size(0); 8361 format %{ "# castII of $dst" %} 8362 ins_encode(/* empty encoding */); 8363 ins_cost(0); 8364 ins_pipe(pipe_class_empty); 8365 %} 8366 8367 instruct castLL(iRegL dst) 8368 %{ 8369 match(Set dst (CastLL dst)); 8370 8371 size(0); 8372 format %{ "# castLL of $dst" %} 8373 ins_encode(/* empty encoding */); 8374 ins_cost(0); 8375 ins_pipe(pipe_class_empty); 8376 %} 8377 8378 // ============================================================================ 8379 // Atomic operation instructions 8380 // 8381 // Intel and SPARC both implement Ideal Node LoadPLocked and 8382 // Store{PIL}Conditional instructions using a normal load for the 8383 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8384 // 8385 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8386 // pair to lock object allocations from Eden space when not using 8387 // TLABs. 8388 // 8389 // There does not appear to be a Load{IL}Locked Ideal Node and the 8390 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8391 // and to use StoreIConditional only for 32-bit and StoreLConditional 8392 // only for 64-bit. 8393 // 8394 // We implement LoadPLocked and StorePLocked instructions using, 8395 // respectively the AArch64 hw load-exclusive and store-conditional 8396 // instructions. Whereas we must implement each of 8397 // Store{IL}Conditional using a CAS which employs a pair of 8398 // instructions comprising a load-exclusive followed by a 8399 // store-conditional. 8400 8401 8402 // Locked-load (linked load) of the current heap-top 8403 // used when updating the eden heap top 8404 // implemented using ldaxr on AArch64 8405 8406 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8407 %{ 8408 match(Set dst (LoadPLocked mem)); 8409 8410 ins_cost(VOLATILE_REF_COST); 8411 8412 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8413 8414 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8415 8416 ins_pipe(pipe_serial); 8417 %} 8418 8419 // Conditional-store of the updated heap-top. 8420 // Used during allocation of the shared heap. 8421 // Sets flag (EQ) on success. 8422 // implemented using stlxr on AArch64. 8423 8424 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8425 %{ 8426 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8427 8428 ins_cost(VOLATILE_REF_COST); 8429 8430 // TODO 8431 // do we need to do a store-conditional release or can we just use a 8432 // plain store-conditional? 8433 8434 format %{ 8435 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8436 "cmpw rscratch1, zr\t# EQ on successful write" 8437 %} 8438 8439 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8440 8441 ins_pipe(pipe_serial); 8442 %} 8443 8444 8445 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8446 // when attempting to rebias a lock towards the current thread. We 8447 // must use the acquire form of cmpxchg in order to guarantee acquire 8448 // semantics in this case. 8449 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8450 %{ 8451 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8452 8453 ins_cost(VOLATILE_REF_COST); 8454 8455 format %{ 8456 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8457 "cmpw rscratch1, zr\t# EQ on successful write" 8458 %} 8459 8460 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8461 8462 ins_pipe(pipe_slow); 8463 %} 8464 8465 // storeIConditional also has acquire semantics, for no better reason 8466 // than matching storeLConditional. At the time of writing this 8467 // comment storeIConditional was not used anywhere by AArch64. 8468 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8469 %{ 8470 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8471 8472 ins_cost(VOLATILE_REF_COST); 8473 8474 format %{ 8475 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8476 "cmpw rscratch1, zr\t# EQ on successful write" 8477 %} 8478 8479 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8480 8481 ins_pipe(pipe_slow); 8482 %} 8483 8484 // standard CompareAndSwapX when we are using barriers 8485 // these have higher priority than the rules selected by a predicate 8486 8487 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8488 // can't match them 8489 8490 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8491 8492 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8493 ins_cost(2 * VOLATILE_REF_COST); 8494 8495 effect(KILL cr); 8496 8497 format %{ 8498 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8499 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8500 %} 8501 8502 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8503 aarch64_enc_cset_eq(res)); 8504 8505 ins_pipe(pipe_slow); 8506 %} 8507 8508 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8509 8510 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8511 ins_cost(2 * VOLATILE_REF_COST); 8512 8513 effect(KILL cr); 8514 8515 format %{ 8516 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8517 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8518 %} 8519 8520 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8521 aarch64_enc_cset_eq(res)); 8522 8523 ins_pipe(pipe_slow); 8524 %} 8525 8526 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8527 8528 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8529 ins_cost(2 * VOLATILE_REF_COST); 8530 8531 effect(KILL cr); 8532 8533 format %{ 8534 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8535 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8536 %} 8537 8538 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8539 aarch64_enc_cset_eq(res)); 8540 8541 ins_pipe(pipe_slow); 8542 %} 8543 8544 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8545 8546 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8547 ins_cost(2 * VOLATILE_REF_COST); 8548 8549 effect(KILL cr); 8550 8551 format %{ 8552 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8553 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8554 %} 8555 8556 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8557 aarch64_enc_cset_eq(res)); 8558 8559 ins_pipe(pipe_slow); 8560 %} 8561 8562 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8563 8564 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8565 predicate(n->as_LoadStore()->barrier_data() == 0); 8566 ins_cost(2 * VOLATILE_REF_COST); 8567 8568 effect(KILL cr); 8569 8570 format %{ 8571 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8572 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8573 %} 8574 8575 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8576 aarch64_enc_cset_eq(res)); 8577 8578 ins_pipe(pipe_slow); 8579 %} 8580 8581 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8582 8583 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8584 ins_cost(2 * VOLATILE_REF_COST); 8585 8586 effect(KILL cr); 8587 8588 format %{ 8589 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8590 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8591 %} 8592 8593 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8594 aarch64_enc_cset_eq(res)); 8595 8596 ins_pipe(pipe_slow); 8597 %} 8598 8599 // alternative CompareAndSwapX when we are eliding barriers 8600 8601 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8602 8603 predicate(needs_acquiring_load_exclusive(n)); 8604 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8605 ins_cost(VOLATILE_REF_COST); 8606 8607 effect(KILL cr); 8608 8609 format %{ 8610 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8611 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8612 %} 8613 8614 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8615 aarch64_enc_cset_eq(res)); 8616 8617 ins_pipe(pipe_slow); 8618 %} 8619 8620 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8621 8622 predicate(needs_acquiring_load_exclusive(n)); 8623 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8624 ins_cost(VOLATILE_REF_COST); 8625 8626 effect(KILL cr); 8627 8628 format %{ 8629 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8630 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8631 %} 8632 8633 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8634 aarch64_enc_cset_eq(res)); 8635 8636 ins_pipe(pipe_slow); 8637 %} 8638 8639 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8640 8641 predicate(needs_acquiring_load_exclusive(n)); 8642 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8643 ins_cost(VOLATILE_REF_COST); 8644 8645 effect(KILL cr); 8646 8647 format %{ 8648 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8649 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8650 %} 8651 8652 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8653 aarch64_enc_cset_eq(res)); 8654 8655 ins_pipe(pipe_slow); 8656 %} 8657 8658 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8659 8660 predicate(needs_acquiring_load_exclusive(n)); 8661 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8662 ins_cost(VOLATILE_REF_COST); 8663 8664 effect(KILL cr); 8665 8666 format %{ 8667 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8668 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8669 %} 8670 8671 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8672 aarch64_enc_cset_eq(res)); 8673 8674 ins_pipe(pipe_slow); 8675 %} 8676 8677 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8678 8679 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8680 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8681 ins_cost(VOLATILE_REF_COST); 8682 8683 effect(KILL cr); 8684 8685 format %{ 8686 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8687 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8688 %} 8689 8690 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8691 aarch64_enc_cset_eq(res)); 8692 8693 ins_pipe(pipe_slow); 8694 %} 8695 8696 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8697 8698 predicate(needs_acquiring_load_exclusive(n)); 8699 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8700 ins_cost(VOLATILE_REF_COST); 8701 8702 effect(KILL cr); 8703 8704 format %{ 8705 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8706 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8707 %} 8708 8709 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8710 aarch64_enc_cset_eq(res)); 8711 8712 ins_pipe(pipe_slow); 8713 %} 8714 8715 8716 // --------------------------------------------------------------------- 8717 8718 8719 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8720 8721 // Sundry CAS operations. Note that release is always true, 8722 // regardless of the memory ordering of the CAS. This is because we 8723 // need the volatile case to be sequentially consistent but there is 8724 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8725 // can't check the type of memory ordering here, so we always emit a 8726 // STLXR. 8727 8728 // This section is generated from aarch64_ad_cas.m4 8729 8730 8731 8732 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8733 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8734 ins_cost(2 * VOLATILE_REF_COST); 8735 effect(TEMP_DEF res, KILL cr); 8736 format %{ 8737 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8738 %} 8739 ins_encode %{ 8740 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8741 Assembler::byte, /*acquire*/ false, /*release*/ true, 8742 /*weak*/ false, $res$$Register); 8743 __ sxtbw($res$$Register, $res$$Register); 8744 %} 8745 ins_pipe(pipe_slow); 8746 %} 8747 8748 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8749 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8750 ins_cost(2 * VOLATILE_REF_COST); 8751 effect(TEMP_DEF res, KILL cr); 8752 format %{ 8753 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8754 %} 8755 ins_encode %{ 8756 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8757 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8758 /*weak*/ false, $res$$Register); 8759 __ sxthw($res$$Register, $res$$Register); 8760 %} 8761 ins_pipe(pipe_slow); 8762 %} 8763 8764 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8765 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8766 ins_cost(2 * VOLATILE_REF_COST); 8767 effect(TEMP_DEF res, KILL cr); 8768 format %{ 8769 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8770 %} 8771 ins_encode %{ 8772 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8773 Assembler::word, /*acquire*/ false, /*release*/ true, 8774 /*weak*/ false, $res$$Register); 8775 %} 8776 ins_pipe(pipe_slow); 8777 %} 8778 8779 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8780 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8781 ins_cost(2 * VOLATILE_REF_COST); 8782 effect(TEMP_DEF res, KILL cr); 8783 format %{ 8784 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8785 %} 8786 ins_encode %{ 8787 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8788 Assembler::xword, /*acquire*/ false, /*release*/ true, 8789 /*weak*/ false, $res$$Register); 8790 %} 8791 ins_pipe(pipe_slow); 8792 %} 8793 8794 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8795 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8796 ins_cost(2 * VOLATILE_REF_COST); 8797 effect(TEMP_DEF res, KILL cr); 8798 format %{ 8799 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8800 %} 8801 ins_encode %{ 8802 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8803 Assembler::word, /*acquire*/ false, /*release*/ true, 8804 /*weak*/ false, $res$$Register); 8805 %} 8806 ins_pipe(pipe_slow); 8807 %} 8808 8809 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8810 predicate(n->as_LoadStore()->barrier_data() == 0); 8811 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8812 ins_cost(2 * VOLATILE_REF_COST); 8813 effect(TEMP_DEF res, KILL cr); 8814 format %{ 8815 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8816 %} 8817 ins_encode %{ 8818 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8819 Assembler::xword, /*acquire*/ false, /*release*/ true, 8820 /*weak*/ false, $res$$Register); 8821 %} 8822 ins_pipe(pipe_slow); 8823 %} 8824 8825 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8826 predicate(needs_acquiring_load_exclusive(n)); 8827 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8828 ins_cost(VOLATILE_REF_COST); 8829 effect(TEMP_DEF res, KILL cr); 8830 format %{ 8831 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8832 %} 8833 ins_encode %{ 8834 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8835 Assembler::byte, /*acquire*/ true, /*release*/ true, 8836 /*weak*/ false, $res$$Register); 8837 __ sxtbw($res$$Register, $res$$Register); 8838 %} 8839 ins_pipe(pipe_slow); 8840 %} 8841 8842 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8843 predicate(needs_acquiring_load_exclusive(n)); 8844 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8845 ins_cost(VOLATILE_REF_COST); 8846 effect(TEMP_DEF res, KILL cr); 8847 format %{ 8848 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8849 %} 8850 ins_encode %{ 8851 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8852 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8853 /*weak*/ false, $res$$Register); 8854 __ sxthw($res$$Register, $res$$Register); 8855 %} 8856 ins_pipe(pipe_slow); 8857 %} 8858 8859 8860 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8861 predicate(needs_acquiring_load_exclusive(n)); 8862 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8863 ins_cost(VOLATILE_REF_COST); 8864 effect(TEMP_DEF res, KILL cr); 8865 format %{ 8866 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8867 %} 8868 ins_encode %{ 8869 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8870 Assembler::word, /*acquire*/ true, /*release*/ true, 8871 /*weak*/ false, $res$$Register); 8872 %} 8873 ins_pipe(pipe_slow); 8874 %} 8875 8876 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8877 predicate(needs_acquiring_load_exclusive(n)); 8878 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8879 ins_cost(VOLATILE_REF_COST); 8880 effect(TEMP_DEF res, KILL cr); 8881 format %{ 8882 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8883 %} 8884 ins_encode %{ 8885 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8886 Assembler::xword, /*acquire*/ true, /*release*/ true, 8887 /*weak*/ false, $res$$Register); 8888 %} 8889 ins_pipe(pipe_slow); 8890 %} 8891 8892 8893 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8894 predicate(needs_acquiring_load_exclusive(n)); 8895 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8896 ins_cost(VOLATILE_REF_COST); 8897 effect(TEMP_DEF res, KILL cr); 8898 format %{ 8899 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8900 %} 8901 ins_encode %{ 8902 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8903 Assembler::word, /*acquire*/ true, /*release*/ true, 8904 /*weak*/ false, $res$$Register); 8905 %} 8906 ins_pipe(pipe_slow); 8907 %} 8908 8909 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8910 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8911 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8912 ins_cost(VOLATILE_REF_COST); 8913 effect(TEMP_DEF res, KILL cr); 8914 format %{ 8915 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8916 %} 8917 ins_encode %{ 8918 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8919 Assembler::xword, /*acquire*/ true, /*release*/ true, 8920 /*weak*/ false, $res$$Register); 8921 %} 8922 ins_pipe(pipe_slow); 8923 %} 8924 8925 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8926 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8927 ins_cost(2 * VOLATILE_REF_COST); 8928 effect(KILL cr); 8929 format %{ 8930 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8931 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8932 %} 8933 ins_encode %{ 8934 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8935 Assembler::byte, /*acquire*/ false, /*release*/ true, 8936 /*weak*/ true, noreg); 8937 __ csetw($res$$Register, Assembler::EQ); 8938 %} 8939 ins_pipe(pipe_slow); 8940 %} 8941 8942 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8943 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8944 ins_cost(2 * VOLATILE_REF_COST); 8945 effect(KILL cr); 8946 format %{ 8947 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8948 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8949 %} 8950 ins_encode %{ 8951 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8952 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8953 /*weak*/ true, noreg); 8954 __ csetw($res$$Register, Assembler::EQ); 8955 %} 8956 ins_pipe(pipe_slow); 8957 %} 8958 8959 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8960 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8961 ins_cost(2 * VOLATILE_REF_COST); 8962 effect(KILL cr); 8963 format %{ 8964 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8965 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8966 %} 8967 ins_encode %{ 8968 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8969 Assembler::word, /*acquire*/ false, /*release*/ true, 8970 /*weak*/ true, noreg); 8971 __ csetw($res$$Register, Assembler::EQ); 8972 %} 8973 ins_pipe(pipe_slow); 8974 %} 8975 8976 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8977 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8978 ins_cost(2 * VOLATILE_REF_COST); 8979 effect(KILL cr); 8980 format %{ 8981 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8982 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8983 %} 8984 ins_encode %{ 8985 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8986 Assembler::xword, /*acquire*/ false, /*release*/ true, 8987 /*weak*/ true, noreg); 8988 __ csetw($res$$Register, Assembler::EQ); 8989 %} 8990 ins_pipe(pipe_slow); 8991 %} 8992 8993 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8994 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8995 ins_cost(2 * VOLATILE_REF_COST); 8996 effect(KILL cr); 8997 format %{ 8998 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8999 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9000 %} 9001 ins_encode %{ 9002 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9003 Assembler::word, /*acquire*/ false, /*release*/ true, 9004 /*weak*/ true, noreg); 9005 __ csetw($res$$Register, Assembler::EQ); 9006 %} 9007 ins_pipe(pipe_slow); 9008 %} 9009 9010 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9011 predicate(n->as_LoadStore()->barrier_data() == 0); 9012 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9013 ins_cost(2 * VOLATILE_REF_COST); 9014 effect(KILL cr); 9015 format %{ 9016 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9017 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9018 %} 9019 ins_encode %{ 9020 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9021 Assembler::xword, /*acquire*/ false, /*release*/ true, 9022 /*weak*/ true, noreg); 9023 __ csetw($res$$Register, Assembler::EQ); 9024 %} 9025 ins_pipe(pipe_slow); 9026 %} 9027 9028 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9029 predicate(needs_acquiring_load_exclusive(n)); 9030 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9031 ins_cost(VOLATILE_REF_COST); 9032 effect(KILL cr); 9033 format %{ 9034 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9035 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9036 %} 9037 ins_encode %{ 9038 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9039 Assembler::byte, /*acquire*/ true, /*release*/ true, 9040 /*weak*/ true, noreg); 9041 __ csetw($res$$Register, Assembler::EQ); 9042 %} 9043 ins_pipe(pipe_slow); 9044 %} 9045 9046 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9047 predicate(needs_acquiring_load_exclusive(n)); 9048 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9049 ins_cost(VOLATILE_REF_COST); 9050 effect(KILL cr); 9051 format %{ 9052 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9053 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9054 %} 9055 ins_encode %{ 9056 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9057 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9058 /*weak*/ true, noreg); 9059 __ csetw($res$$Register, Assembler::EQ); 9060 %} 9061 ins_pipe(pipe_slow); 9062 %} 9063 9064 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9065 predicate(needs_acquiring_load_exclusive(n)); 9066 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9067 ins_cost(VOLATILE_REF_COST); 9068 effect(KILL cr); 9069 format %{ 9070 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9071 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9072 %} 9073 ins_encode %{ 9074 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9075 Assembler::word, /*acquire*/ true, /*release*/ true, 9076 /*weak*/ true, noreg); 9077 __ csetw($res$$Register, Assembler::EQ); 9078 %} 9079 ins_pipe(pipe_slow); 9080 %} 9081 9082 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9083 predicate(needs_acquiring_load_exclusive(n)); 9084 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9085 ins_cost(VOLATILE_REF_COST); 9086 effect(KILL cr); 9087 format %{ 9088 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9089 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9090 %} 9091 ins_encode %{ 9092 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9093 Assembler::xword, /*acquire*/ true, /*release*/ true, 9094 /*weak*/ true, noreg); 9095 __ csetw($res$$Register, Assembler::EQ); 9096 %} 9097 ins_pipe(pipe_slow); 9098 %} 9099 9100 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9101 predicate(needs_acquiring_load_exclusive(n)); 9102 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9103 ins_cost(VOLATILE_REF_COST); 9104 effect(KILL cr); 9105 format %{ 9106 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9107 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9108 %} 9109 ins_encode %{ 9110 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9111 Assembler::word, /*acquire*/ true, /*release*/ true, 9112 /*weak*/ true, noreg); 9113 __ csetw($res$$Register, Assembler::EQ); 9114 %} 9115 ins_pipe(pipe_slow); 9116 %} 9117 9118 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9119 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9120 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9121 ins_cost(VOLATILE_REF_COST); 9122 effect(KILL cr); 9123 format %{ 9124 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9125 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9126 %} 9127 ins_encode %{ 9128 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9129 Assembler::xword, /*acquire*/ true, /*release*/ true, 9130 /*weak*/ true, noreg); 9131 __ csetw($res$$Register, Assembler::EQ); 9132 %} 9133 ins_pipe(pipe_slow); 9134 %} 9135 9136 // END This section of the file is automatically generated. Do not edit -------------- 9137 // --------------------------------------------------------------------- 9138 9139 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9140 match(Set prev (GetAndSetI mem newv)); 9141 ins_cost(2 * VOLATILE_REF_COST); 9142 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9143 ins_encode %{ 9144 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9145 %} 9146 ins_pipe(pipe_serial); 9147 %} 9148 9149 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9150 match(Set prev (GetAndSetL mem newv)); 9151 ins_cost(2 * VOLATILE_REF_COST); 9152 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9153 ins_encode %{ 9154 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9155 %} 9156 ins_pipe(pipe_serial); 9157 %} 9158 9159 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9160 match(Set prev (GetAndSetN mem newv)); 9161 ins_cost(2 * VOLATILE_REF_COST); 9162 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9163 ins_encode %{ 9164 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9165 %} 9166 ins_pipe(pipe_serial); 9167 %} 9168 9169 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9170 predicate(n->as_LoadStore()->barrier_data() == 0); 9171 match(Set prev (GetAndSetP mem newv)); 9172 ins_cost(2 * VOLATILE_REF_COST); 9173 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9174 ins_encode %{ 9175 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9176 %} 9177 ins_pipe(pipe_serial); 9178 %} 9179 9180 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9181 predicate(needs_acquiring_load_exclusive(n)); 9182 match(Set prev (GetAndSetI mem newv)); 9183 ins_cost(VOLATILE_REF_COST); 9184 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9185 ins_encode %{ 9186 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9187 %} 9188 ins_pipe(pipe_serial); 9189 %} 9190 9191 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9192 predicate(needs_acquiring_load_exclusive(n)); 9193 match(Set prev (GetAndSetL mem newv)); 9194 ins_cost(VOLATILE_REF_COST); 9195 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9196 ins_encode %{ 9197 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9198 %} 9199 ins_pipe(pipe_serial); 9200 %} 9201 9202 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9203 predicate(needs_acquiring_load_exclusive(n)); 9204 match(Set prev (GetAndSetN mem newv)); 9205 ins_cost(VOLATILE_REF_COST); 9206 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9207 ins_encode %{ 9208 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9209 %} 9210 ins_pipe(pipe_serial); 9211 %} 9212 9213 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9214 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9215 match(Set prev (GetAndSetP mem newv)); 9216 ins_cost(VOLATILE_REF_COST); 9217 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9218 ins_encode %{ 9219 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9220 %} 9221 ins_pipe(pipe_serial); 9222 %} 9223 9224 9225 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9226 match(Set newval (GetAndAddL mem incr)); 9227 ins_cost(2 * VOLATILE_REF_COST + 1); 9228 format %{ "get_and_addL $newval, [$mem], $incr" %} 9229 ins_encode %{ 9230 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9231 %} 9232 ins_pipe(pipe_serial); 9233 %} 9234 9235 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9236 predicate(n->as_LoadStore()->result_not_used()); 9237 match(Set dummy (GetAndAddL mem incr)); 9238 ins_cost(2 * VOLATILE_REF_COST); 9239 format %{ "get_and_addL [$mem], $incr" %} 9240 ins_encode %{ 9241 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9242 %} 9243 ins_pipe(pipe_serial); 9244 %} 9245 9246 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9247 match(Set newval (GetAndAddL mem incr)); 9248 ins_cost(2 * VOLATILE_REF_COST + 1); 9249 format %{ "get_and_addL $newval, [$mem], $incr" %} 9250 ins_encode %{ 9251 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9252 %} 9253 ins_pipe(pipe_serial); 9254 %} 9255 9256 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9257 predicate(n->as_LoadStore()->result_not_used()); 9258 match(Set dummy (GetAndAddL mem incr)); 9259 ins_cost(2 * VOLATILE_REF_COST); 9260 format %{ "get_and_addL [$mem], $incr" %} 9261 ins_encode %{ 9262 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9263 %} 9264 ins_pipe(pipe_serial); 9265 %} 9266 9267 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9268 match(Set newval (GetAndAddI mem incr)); 9269 ins_cost(2 * VOLATILE_REF_COST + 1); 9270 format %{ "get_and_addI $newval, [$mem], $incr" %} 9271 ins_encode %{ 9272 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9273 %} 9274 ins_pipe(pipe_serial); 9275 %} 9276 9277 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9278 predicate(n->as_LoadStore()->result_not_used()); 9279 match(Set dummy (GetAndAddI mem incr)); 9280 ins_cost(2 * VOLATILE_REF_COST); 9281 format %{ "get_and_addI [$mem], $incr" %} 9282 ins_encode %{ 9283 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9284 %} 9285 ins_pipe(pipe_serial); 9286 %} 9287 9288 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9289 match(Set newval (GetAndAddI mem incr)); 9290 ins_cost(2 * VOLATILE_REF_COST + 1); 9291 format %{ "get_and_addI $newval, [$mem], $incr" %} 9292 ins_encode %{ 9293 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9294 %} 9295 ins_pipe(pipe_serial); 9296 %} 9297 9298 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9299 predicate(n->as_LoadStore()->result_not_used()); 9300 match(Set dummy (GetAndAddI mem incr)); 9301 ins_cost(2 * VOLATILE_REF_COST); 9302 format %{ "get_and_addI [$mem], $incr" %} 9303 ins_encode %{ 9304 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9305 %} 9306 ins_pipe(pipe_serial); 9307 %} 9308 9309 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9310 predicate(needs_acquiring_load_exclusive(n)); 9311 match(Set newval (GetAndAddL mem incr)); 9312 ins_cost(VOLATILE_REF_COST + 1); 9313 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9314 ins_encode %{ 9315 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9316 %} 9317 ins_pipe(pipe_serial); 9318 %} 9319 9320 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9321 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9322 match(Set dummy (GetAndAddL mem incr)); 9323 ins_cost(VOLATILE_REF_COST); 9324 format %{ "get_and_addL_acq [$mem], $incr" %} 9325 ins_encode %{ 9326 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9327 %} 9328 ins_pipe(pipe_serial); 9329 %} 9330 9331 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9332 predicate(needs_acquiring_load_exclusive(n)); 9333 match(Set newval (GetAndAddL mem incr)); 9334 ins_cost(VOLATILE_REF_COST + 1); 9335 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9336 ins_encode %{ 9337 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9338 %} 9339 ins_pipe(pipe_serial); 9340 %} 9341 9342 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9343 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9344 match(Set dummy (GetAndAddL mem incr)); 9345 ins_cost(VOLATILE_REF_COST); 9346 format %{ "get_and_addL_acq [$mem], $incr" %} 9347 ins_encode %{ 9348 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9349 %} 9350 ins_pipe(pipe_serial); 9351 %} 9352 9353 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9354 predicate(needs_acquiring_load_exclusive(n)); 9355 match(Set newval (GetAndAddI mem incr)); 9356 ins_cost(VOLATILE_REF_COST + 1); 9357 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9358 ins_encode %{ 9359 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9360 %} 9361 ins_pipe(pipe_serial); 9362 %} 9363 9364 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9365 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9366 match(Set dummy (GetAndAddI mem incr)); 9367 ins_cost(VOLATILE_REF_COST); 9368 format %{ "get_and_addI_acq [$mem], $incr" %} 9369 ins_encode %{ 9370 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9371 %} 9372 ins_pipe(pipe_serial); 9373 %} 9374 9375 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9376 predicate(needs_acquiring_load_exclusive(n)); 9377 match(Set newval (GetAndAddI mem incr)); 9378 ins_cost(VOLATILE_REF_COST + 1); 9379 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9380 ins_encode %{ 9381 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9382 %} 9383 ins_pipe(pipe_serial); 9384 %} 9385 9386 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9387 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9388 match(Set dummy (GetAndAddI mem incr)); 9389 ins_cost(VOLATILE_REF_COST); 9390 format %{ "get_and_addI_acq [$mem], $incr" %} 9391 ins_encode %{ 9392 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9393 %} 9394 ins_pipe(pipe_serial); 9395 %} 9396 9397 // Manifest a CmpL result in an integer register. 9398 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9399 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9400 %{ 9401 match(Set dst (CmpL3 src1 src2)); 9402 effect(KILL flags); 9403 9404 ins_cost(INSN_COST * 6); 9405 format %{ 9406 "cmp $src1, $src2" 9407 "csetw $dst, ne" 9408 "cnegw $dst, lt" 9409 %} 9410 // format %{ "CmpL3 $dst, $src1, $src2" %} 9411 ins_encode %{ 9412 __ cmp($src1$$Register, $src2$$Register); 9413 __ csetw($dst$$Register, Assembler::NE); 9414 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9415 %} 9416 9417 ins_pipe(pipe_class_default); 9418 %} 9419 9420 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9421 %{ 9422 match(Set dst (CmpL3 src1 src2)); 9423 effect(KILL flags); 9424 9425 ins_cost(INSN_COST * 6); 9426 format %{ 9427 "cmp $src1, $src2" 9428 "csetw $dst, ne" 9429 "cnegw $dst, lt" 9430 %} 9431 ins_encode %{ 9432 int32_t con = (int32_t)$src2$$constant; 9433 if (con < 0) { 9434 __ adds(zr, $src1$$Register, -con); 9435 } else { 9436 __ subs(zr, $src1$$Register, con); 9437 } 9438 __ csetw($dst$$Register, Assembler::NE); 9439 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9440 %} 9441 9442 ins_pipe(pipe_class_default); 9443 %} 9444 9445 // ============================================================================ 9446 // Conditional Move Instructions 9447 9448 // n.b. we have identical rules for both a signed compare op (cmpOp) 9449 // and an unsigned compare op (cmpOpU). it would be nice if we could 9450 // define an op class which merged both inputs and use it to type the 9451 // argument to a single rule. unfortunatelyt his fails because the 9452 // opclass does not live up to the COND_INTER interface of its 9453 // component operands. When the generic code tries to negate the 9454 // operand it ends up running the generci Machoper::negate method 9455 // which throws a ShouldNotHappen. So, we have to provide two flavours 9456 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9457 9458 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9459 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9460 9461 ins_cost(INSN_COST * 2); 9462 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9463 9464 ins_encode %{ 9465 __ cselw(as_Register($dst$$reg), 9466 as_Register($src2$$reg), 9467 as_Register($src1$$reg), 9468 (Assembler::Condition)$cmp$$cmpcode); 9469 %} 9470 9471 ins_pipe(icond_reg_reg); 9472 %} 9473 9474 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9475 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9476 9477 ins_cost(INSN_COST * 2); 9478 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9479 9480 ins_encode %{ 9481 __ cselw(as_Register($dst$$reg), 9482 as_Register($src2$$reg), 9483 as_Register($src1$$reg), 9484 (Assembler::Condition)$cmp$$cmpcode); 9485 %} 9486 9487 ins_pipe(icond_reg_reg); 9488 %} 9489 9490 // special cases where one arg is zero 9491 9492 // n.b. this is selected in preference to the rule above because it 9493 // avoids loading constant 0 into a source register 9494 9495 // TODO 9496 // we ought only to be able to cull one of these variants as the ideal 9497 // transforms ought always to order the zero consistently (to left/right?) 9498 9499 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9500 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9501 9502 ins_cost(INSN_COST * 2); 9503 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9504 9505 ins_encode %{ 9506 __ cselw(as_Register($dst$$reg), 9507 as_Register($src$$reg), 9508 zr, 9509 (Assembler::Condition)$cmp$$cmpcode); 9510 %} 9511 9512 ins_pipe(icond_reg); 9513 %} 9514 9515 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9516 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9517 9518 ins_cost(INSN_COST * 2); 9519 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9520 9521 ins_encode %{ 9522 __ cselw(as_Register($dst$$reg), 9523 as_Register($src$$reg), 9524 zr, 9525 (Assembler::Condition)$cmp$$cmpcode); 9526 %} 9527 9528 ins_pipe(icond_reg); 9529 %} 9530 9531 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9532 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9533 9534 ins_cost(INSN_COST * 2); 9535 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9536 9537 ins_encode %{ 9538 __ cselw(as_Register($dst$$reg), 9539 zr, 9540 as_Register($src$$reg), 9541 (Assembler::Condition)$cmp$$cmpcode); 9542 %} 9543 9544 ins_pipe(icond_reg); 9545 %} 9546 9547 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9548 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9549 9550 ins_cost(INSN_COST * 2); 9551 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9552 9553 ins_encode %{ 9554 __ cselw(as_Register($dst$$reg), 9555 zr, 9556 as_Register($src$$reg), 9557 (Assembler::Condition)$cmp$$cmpcode); 9558 %} 9559 9560 ins_pipe(icond_reg); 9561 %} 9562 9563 // special case for creating a boolean 0 or 1 9564 9565 // n.b. this is selected in preference to the rule above because it 9566 // avoids loading constants 0 and 1 into a source register 9567 9568 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9569 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9570 9571 ins_cost(INSN_COST * 2); 9572 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9573 9574 ins_encode %{ 9575 // equivalently 9576 // cset(as_Register($dst$$reg), 9577 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9578 __ csincw(as_Register($dst$$reg), 9579 zr, 9580 zr, 9581 (Assembler::Condition)$cmp$$cmpcode); 9582 %} 9583 9584 ins_pipe(icond_none); 9585 %} 9586 9587 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9588 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9589 9590 ins_cost(INSN_COST * 2); 9591 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9592 9593 ins_encode %{ 9594 // equivalently 9595 // cset(as_Register($dst$$reg), 9596 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9597 __ csincw(as_Register($dst$$reg), 9598 zr, 9599 zr, 9600 (Assembler::Condition)$cmp$$cmpcode); 9601 %} 9602 9603 ins_pipe(icond_none); 9604 %} 9605 9606 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9607 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9608 9609 ins_cost(INSN_COST * 2); 9610 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9611 9612 ins_encode %{ 9613 __ csel(as_Register($dst$$reg), 9614 as_Register($src2$$reg), 9615 as_Register($src1$$reg), 9616 (Assembler::Condition)$cmp$$cmpcode); 9617 %} 9618 9619 ins_pipe(icond_reg_reg); 9620 %} 9621 9622 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9623 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9624 9625 ins_cost(INSN_COST * 2); 9626 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9627 9628 ins_encode %{ 9629 __ csel(as_Register($dst$$reg), 9630 as_Register($src2$$reg), 9631 as_Register($src1$$reg), 9632 (Assembler::Condition)$cmp$$cmpcode); 9633 %} 9634 9635 ins_pipe(icond_reg_reg); 9636 %} 9637 9638 // special cases where one arg is zero 9639 9640 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9641 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9642 9643 ins_cost(INSN_COST * 2); 9644 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9645 9646 ins_encode %{ 9647 __ csel(as_Register($dst$$reg), 9648 zr, 9649 as_Register($src$$reg), 9650 (Assembler::Condition)$cmp$$cmpcode); 9651 %} 9652 9653 ins_pipe(icond_reg); 9654 %} 9655 9656 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9657 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9658 9659 ins_cost(INSN_COST * 2); 9660 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9661 9662 ins_encode %{ 9663 __ csel(as_Register($dst$$reg), 9664 zr, 9665 as_Register($src$$reg), 9666 (Assembler::Condition)$cmp$$cmpcode); 9667 %} 9668 9669 ins_pipe(icond_reg); 9670 %} 9671 9672 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9673 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9674 9675 ins_cost(INSN_COST * 2); 9676 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9677 9678 ins_encode %{ 9679 __ csel(as_Register($dst$$reg), 9680 as_Register($src$$reg), 9681 zr, 9682 (Assembler::Condition)$cmp$$cmpcode); 9683 %} 9684 9685 ins_pipe(icond_reg); 9686 %} 9687 9688 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9689 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9690 9691 ins_cost(INSN_COST * 2); 9692 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9693 9694 ins_encode %{ 9695 __ csel(as_Register($dst$$reg), 9696 as_Register($src$$reg), 9697 zr, 9698 (Assembler::Condition)$cmp$$cmpcode); 9699 %} 9700 9701 ins_pipe(icond_reg); 9702 %} 9703 9704 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9705 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9706 9707 ins_cost(INSN_COST * 2); 9708 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9709 9710 ins_encode %{ 9711 __ csel(as_Register($dst$$reg), 9712 as_Register($src2$$reg), 9713 as_Register($src1$$reg), 9714 (Assembler::Condition)$cmp$$cmpcode); 9715 %} 9716 9717 ins_pipe(icond_reg_reg); 9718 %} 9719 9720 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9721 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9722 9723 ins_cost(INSN_COST * 2); 9724 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9725 9726 ins_encode %{ 9727 __ csel(as_Register($dst$$reg), 9728 as_Register($src2$$reg), 9729 as_Register($src1$$reg), 9730 (Assembler::Condition)$cmp$$cmpcode); 9731 %} 9732 9733 ins_pipe(icond_reg_reg); 9734 %} 9735 9736 // special cases where one arg is zero 9737 9738 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9739 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9740 9741 ins_cost(INSN_COST * 2); 9742 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9743 9744 ins_encode %{ 9745 __ csel(as_Register($dst$$reg), 9746 zr, 9747 as_Register($src$$reg), 9748 (Assembler::Condition)$cmp$$cmpcode); 9749 %} 9750 9751 ins_pipe(icond_reg); 9752 %} 9753 9754 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9755 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9756 9757 ins_cost(INSN_COST * 2); 9758 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9759 9760 ins_encode %{ 9761 __ csel(as_Register($dst$$reg), 9762 zr, 9763 as_Register($src$$reg), 9764 (Assembler::Condition)$cmp$$cmpcode); 9765 %} 9766 9767 ins_pipe(icond_reg); 9768 %} 9769 9770 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9771 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9772 9773 ins_cost(INSN_COST * 2); 9774 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9775 9776 ins_encode %{ 9777 __ csel(as_Register($dst$$reg), 9778 as_Register($src$$reg), 9779 zr, 9780 (Assembler::Condition)$cmp$$cmpcode); 9781 %} 9782 9783 ins_pipe(icond_reg); 9784 %} 9785 9786 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9787 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9788 9789 ins_cost(INSN_COST * 2); 9790 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9791 9792 ins_encode %{ 9793 __ csel(as_Register($dst$$reg), 9794 as_Register($src$$reg), 9795 zr, 9796 (Assembler::Condition)$cmp$$cmpcode); 9797 %} 9798 9799 ins_pipe(icond_reg); 9800 %} 9801 9802 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9803 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9804 9805 ins_cost(INSN_COST * 2); 9806 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9807 9808 ins_encode %{ 9809 __ cselw(as_Register($dst$$reg), 9810 as_Register($src2$$reg), 9811 as_Register($src1$$reg), 9812 (Assembler::Condition)$cmp$$cmpcode); 9813 %} 9814 9815 ins_pipe(icond_reg_reg); 9816 %} 9817 9818 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9819 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9820 9821 ins_cost(INSN_COST * 2); 9822 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9823 9824 ins_encode %{ 9825 __ cselw(as_Register($dst$$reg), 9826 as_Register($src2$$reg), 9827 as_Register($src1$$reg), 9828 (Assembler::Condition)$cmp$$cmpcode); 9829 %} 9830 9831 ins_pipe(icond_reg_reg); 9832 %} 9833 9834 // special cases where one arg is zero 9835 9836 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9837 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9838 9839 ins_cost(INSN_COST * 2); 9840 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9841 9842 ins_encode %{ 9843 __ cselw(as_Register($dst$$reg), 9844 zr, 9845 as_Register($src$$reg), 9846 (Assembler::Condition)$cmp$$cmpcode); 9847 %} 9848 9849 ins_pipe(icond_reg); 9850 %} 9851 9852 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9853 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9854 9855 ins_cost(INSN_COST * 2); 9856 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9857 9858 ins_encode %{ 9859 __ cselw(as_Register($dst$$reg), 9860 zr, 9861 as_Register($src$$reg), 9862 (Assembler::Condition)$cmp$$cmpcode); 9863 %} 9864 9865 ins_pipe(icond_reg); 9866 %} 9867 9868 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9869 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9870 9871 ins_cost(INSN_COST * 2); 9872 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9873 9874 ins_encode %{ 9875 __ cselw(as_Register($dst$$reg), 9876 as_Register($src$$reg), 9877 zr, 9878 (Assembler::Condition)$cmp$$cmpcode); 9879 %} 9880 9881 ins_pipe(icond_reg); 9882 %} 9883 9884 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9885 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9886 9887 ins_cost(INSN_COST * 2); 9888 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9889 9890 ins_encode %{ 9891 __ cselw(as_Register($dst$$reg), 9892 as_Register($src$$reg), 9893 zr, 9894 (Assembler::Condition)$cmp$$cmpcode); 9895 %} 9896 9897 ins_pipe(icond_reg); 9898 %} 9899 9900 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9901 %{ 9902 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9903 9904 ins_cost(INSN_COST * 3); 9905 9906 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9907 ins_encode %{ 9908 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9909 __ fcsels(as_FloatRegister($dst$$reg), 9910 as_FloatRegister($src2$$reg), 9911 as_FloatRegister($src1$$reg), 9912 cond); 9913 %} 9914 9915 ins_pipe(fp_cond_reg_reg_s); 9916 %} 9917 9918 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9919 %{ 9920 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9921 9922 ins_cost(INSN_COST * 3); 9923 9924 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9925 ins_encode %{ 9926 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9927 __ fcsels(as_FloatRegister($dst$$reg), 9928 as_FloatRegister($src2$$reg), 9929 as_FloatRegister($src1$$reg), 9930 cond); 9931 %} 9932 9933 ins_pipe(fp_cond_reg_reg_s); 9934 %} 9935 9936 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9937 %{ 9938 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9939 9940 ins_cost(INSN_COST * 3); 9941 9942 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9943 ins_encode %{ 9944 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9945 __ fcseld(as_FloatRegister($dst$$reg), 9946 as_FloatRegister($src2$$reg), 9947 as_FloatRegister($src1$$reg), 9948 cond); 9949 %} 9950 9951 ins_pipe(fp_cond_reg_reg_d); 9952 %} 9953 9954 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9955 %{ 9956 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9957 9958 ins_cost(INSN_COST * 3); 9959 9960 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9961 ins_encode %{ 9962 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9963 __ fcseld(as_FloatRegister($dst$$reg), 9964 as_FloatRegister($src2$$reg), 9965 as_FloatRegister($src1$$reg), 9966 cond); 9967 %} 9968 9969 ins_pipe(fp_cond_reg_reg_d); 9970 %} 9971 9972 // ============================================================================ 9973 // Arithmetic Instructions 9974 // 9975 9976 // Integer Addition 9977 9978 // TODO 9979 // these currently employ operations which do not set CR and hence are 9980 // not flagged as killing CR but we would like to isolate the cases 9981 // where we want to set flags from those where we don't. need to work 9982 // out how to do that. 9983 9984 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9985 match(Set dst (AddI src1 src2)); 9986 9987 ins_cost(INSN_COST); 9988 format %{ "addw $dst, $src1, $src2" %} 9989 9990 ins_encode %{ 9991 __ addw(as_Register($dst$$reg), 9992 as_Register($src1$$reg), 9993 as_Register($src2$$reg)); 9994 %} 9995 9996 ins_pipe(ialu_reg_reg); 9997 %} 9998 9999 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10000 match(Set dst (AddI src1 src2)); 10001 10002 ins_cost(INSN_COST); 10003 format %{ "addw $dst, $src1, $src2" %} 10004 10005 // use opcode to indicate that this is an add not a sub 10006 opcode(0x0); 10007 10008 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10009 10010 ins_pipe(ialu_reg_imm); 10011 %} 10012 10013 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10014 match(Set dst (AddI (ConvL2I src1) src2)); 10015 10016 ins_cost(INSN_COST); 10017 format %{ "addw $dst, $src1, $src2" %} 10018 10019 // use opcode to indicate that this is an add not a sub 10020 opcode(0x0); 10021 10022 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10023 10024 ins_pipe(ialu_reg_imm); 10025 %} 10026 10027 // Pointer Addition 10028 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10029 match(Set dst (AddP src1 src2)); 10030 10031 ins_cost(INSN_COST); 10032 format %{ "add $dst, $src1, $src2\t# ptr" %} 10033 10034 ins_encode %{ 10035 __ add(as_Register($dst$$reg), 10036 as_Register($src1$$reg), 10037 as_Register($src2$$reg)); 10038 %} 10039 10040 ins_pipe(ialu_reg_reg); 10041 %} 10042 10043 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10044 match(Set dst (AddP src1 (ConvI2L src2))); 10045 10046 ins_cost(1.9 * INSN_COST); 10047 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10048 10049 ins_encode %{ 10050 __ add(as_Register($dst$$reg), 10051 as_Register($src1$$reg), 10052 as_Register($src2$$reg), ext::sxtw); 10053 %} 10054 10055 ins_pipe(ialu_reg_reg); 10056 %} 10057 10058 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10059 match(Set dst (AddP src1 (LShiftL src2 scale))); 10060 10061 ins_cost(1.9 * INSN_COST); 10062 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10063 10064 ins_encode %{ 10065 __ lea(as_Register($dst$$reg), 10066 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10067 Address::lsl($scale$$constant))); 10068 %} 10069 10070 ins_pipe(ialu_reg_reg_shift); 10071 %} 10072 10073 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10074 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10075 10076 ins_cost(1.9 * INSN_COST); 10077 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10078 10079 ins_encode %{ 10080 __ lea(as_Register($dst$$reg), 10081 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10082 Address::sxtw($scale$$constant))); 10083 %} 10084 10085 ins_pipe(ialu_reg_reg_shift); 10086 %} 10087 10088 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10089 match(Set dst (LShiftL (ConvI2L src) scale)); 10090 10091 ins_cost(INSN_COST); 10092 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10093 10094 ins_encode %{ 10095 __ sbfiz(as_Register($dst$$reg), 10096 as_Register($src$$reg), 10097 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 10098 %} 10099 10100 ins_pipe(ialu_reg_shift); 10101 %} 10102 10103 // Pointer Immediate Addition 10104 // n.b. this needs to be more expensive than using an indirect memory 10105 // operand 10106 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10107 match(Set dst (AddP src1 src2)); 10108 10109 ins_cost(INSN_COST); 10110 format %{ "add $dst, $src1, $src2\t# ptr" %} 10111 10112 // use opcode to indicate that this is an add not a sub 10113 opcode(0x0); 10114 10115 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10116 10117 ins_pipe(ialu_reg_imm); 10118 %} 10119 10120 // Long Addition 10121 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10122 10123 match(Set dst (AddL src1 src2)); 10124 10125 ins_cost(INSN_COST); 10126 format %{ "add $dst, $src1, $src2" %} 10127 10128 ins_encode %{ 10129 __ add(as_Register($dst$$reg), 10130 as_Register($src1$$reg), 10131 as_Register($src2$$reg)); 10132 %} 10133 10134 ins_pipe(ialu_reg_reg); 10135 %} 10136 10137 // No constant pool entries requiredLong Immediate Addition. 10138 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10139 match(Set dst (AddL src1 src2)); 10140 10141 ins_cost(INSN_COST); 10142 format %{ "add $dst, $src1, $src2" %} 10143 10144 // use opcode to indicate that this is an add not a sub 10145 opcode(0x0); 10146 10147 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10148 10149 ins_pipe(ialu_reg_imm); 10150 %} 10151 10152 // Integer Subtraction 10153 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10154 match(Set dst (SubI src1 src2)); 10155 10156 ins_cost(INSN_COST); 10157 format %{ "subw $dst, $src1, $src2" %} 10158 10159 ins_encode %{ 10160 __ subw(as_Register($dst$$reg), 10161 as_Register($src1$$reg), 10162 as_Register($src2$$reg)); 10163 %} 10164 10165 ins_pipe(ialu_reg_reg); 10166 %} 10167 10168 // Immediate Subtraction 10169 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10170 match(Set dst (SubI src1 src2)); 10171 10172 ins_cost(INSN_COST); 10173 format %{ "subw $dst, $src1, $src2" %} 10174 10175 // use opcode to indicate that this is a sub not an add 10176 opcode(0x1); 10177 10178 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10179 10180 ins_pipe(ialu_reg_imm); 10181 %} 10182 10183 // Long Subtraction 10184 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10185 10186 match(Set dst (SubL src1 src2)); 10187 10188 ins_cost(INSN_COST); 10189 format %{ "sub $dst, $src1, $src2" %} 10190 10191 ins_encode %{ 10192 __ sub(as_Register($dst$$reg), 10193 as_Register($src1$$reg), 10194 as_Register($src2$$reg)); 10195 %} 10196 10197 ins_pipe(ialu_reg_reg); 10198 %} 10199 10200 // No constant pool entries requiredLong Immediate Subtraction. 10201 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10202 match(Set dst (SubL src1 src2)); 10203 10204 ins_cost(INSN_COST); 10205 format %{ "sub$dst, $src1, $src2" %} 10206 10207 // use opcode to indicate that this is a sub not an add 10208 opcode(0x1); 10209 10210 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10211 10212 ins_pipe(ialu_reg_imm); 10213 %} 10214 10215 // Integer Negation (special case for sub) 10216 10217 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10218 match(Set dst (SubI zero src)); 10219 10220 ins_cost(INSN_COST); 10221 format %{ "negw $dst, $src\t# int" %} 10222 10223 ins_encode %{ 10224 __ negw(as_Register($dst$$reg), 10225 as_Register($src$$reg)); 10226 %} 10227 10228 ins_pipe(ialu_reg); 10229 %} 10230 10231 // Long Negation 10232 10233 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10234 match(Set dst (SubL zero src)); 10235 10236 ins_cost(INSN_COST); 10237 format %{ "neg $dst, $src\t# long" %} 10238 10239 ins_encode %{ 10240 __ neg(as_Register($dst$$reg), 10241 as_Register($src$$reg)); 10242 %} 10243 10244 ins_pipe(ialu_reg); 10245 %} 10246 10247 // Integer Multiply 10248 10249 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10250 match(Set dst (MulI src1 src2)); 10251 10252 ins_cost(INSN_COST * 3); 10253 format %{ "mulw $dst, $src1, $src2" %} 10254 10255 ins_encode %{ 10256 __ mulw(as_Register($dst$$reg), 10257 as_Register($src1$$reg), 10258 as_Register($src2$$reg)); 10259 %} 10260 10261 ins_pipe(imul_reg_reg); 10262 %} 10263 10264 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10265 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10266 10267 ins_cost(INSN_COST * 3); 10268 format %{ "smull $dst, $src1, $src2" %} 10269 10270 ins_encode %{ 10271 __ smull(as_Register($dst$$reg), 10272 as_Register($src1$$reg), 10273 as_Register($src2$$reg)); 10274 %} 10275 10276 ins_pipe(imul_reg_reg); 10277 %} 10278 10279 // Long Multiply 10280 10281 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10282 match(Set dst (MulL src1 src2)); 10283 10284 ins_cost(INSN_COST * 5); 10285 format %{ "mul $dst, $src1, $src2" %} 10286 10287 ins_encode %{ 10288 __ mul(as_Register($dst$$reg), 10289 as_Register($src1$$reg), 10290 as_Register($src2$$reg)); 10291 %} 10292 10293 ins_pipe(lmul_reg_reg); 10294 %} 10295 10296 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10297 %{ 10298 match(Set dst (MulHiL src1 src2)); 10299 10300 ins_cost(INSN_COST * 7); 10301 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10302 10303 ins_encode %{ 10304 __ smulh(as_Register($dst$$reg), 10305 as_Register($src1$$reg), 10306 as_Register($src2$$reg)); 10307 %} 10308 10309 ins_pipe(lmul_reg_reg); 10310 %} 10311 10312 // Combined Integer Multiply & Add/Sub 10313 10314 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10315 match(Set dst (AddI src3 (MulI src1 src2))); 10316 10317 ins_cost(INSN_COST * 3); 10318 format %{ "madd $dst, $src1, $src2, $src3" %} 10319 10320 ins_encode %{ 10321 __ maddw(as_Register($dst$$reg), 10322 as_Register($src1$$reg), 10323 as_Register($src2$$reg), 10324 as_Register($src3$$reg)); 10325 %} 10326 10327 ins_pipe(imac_reg_reg); 10328 %} 10329 10330 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10331 match(Set dst (SubI src3 (MulI src1 src2))); 10332 10333 ins_cost(INSN_COST * 3); 10334 format %{ "msub $dst, $src1, $src2, $src3" %} 10335 10336 ins_encode %{ 10337 __ msubw(as_Register($dst$$reg), 10338 as_Register($src1$$reg), 10339 as_Register($src2$$reg), 10340 as_Register($src3$$reg)); 10341 %} 10342 10343 ins_pipe(imac_reg_reg); 10344 %} 10345 10346 // Combined Integer Multiply & Neg 10347 10348 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10349 match(Set dst (MulI (SubI zero src1) src2)); 10350 match(Set dst (MulI src1 (SubI zero src2))); 10351 10352 ins_cost(INSN_COST * 3); 10353 format %{ "mneg $dst, $src1, $src2" %} 10354 10355 ins_encode %{ 10356 __ mnegw(as_Register($dst$$reg), 10357 as_Register($src1$$reg), 10358 as_Register($src2$$reg)); 10359 %} 10360 10361 ins_pipe(imac_reg_reg); 10362 %} 10363 10364 // Combined Long Multiply & Add/Sub 10365 10366 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10367 match(Set dst (AddL src3 (MulL src1 src2))); 10368 10369 ins_cost(INSN_COST * 5); 10370 format %{ "madd $dst, $src1, $src2, $src3" %} 10371 10372 ins_encode %{ 10373 __ madd(as_Register($dst$$reg), 10374 as_Register($src1$$reg), 10375 as_Register($src2$$reg), 10376 as_Register($src3$$reg)); 10377 %} 10378 10379 ins_pipe(lmac_reg_reg); 10380 %} 10381 10382 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10383 match(Set dst (SubL src3 (MulL src1 src2))); 10384 10385 ins_cost(INSN_COST * 5); 10386 format %{ "msub $dst, $src1, $src2, $src3" %} 10387 10388 ins_encode %{ 10389 __ msub(as_Register($dst$$reg), 10390 as_Register($src1$$reg), 10391 as_Register($src2$$reg), 10392 as_Register($src3$$reg)); 10393 %} 10394 10395 ins_pipe(lmac_reg_reg); 10396 %} 10397 10398 // Combined Long Multiply & Neg 10399 10400 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10401 match(Set dst (MulL (SubL zero src1) src2)); 10402 match(Set dst (MulL src1 (SubL zero src2))); 10403 10404 ins_cost(INSN_COST * 5); 10405 format %{ "mneg $dst, $src1, $src2" %} 10406 10407 ins_encode %{ 10408 __ mneg(as_Register($dst$$reg), 10409 as_Register($src1$$reg), 10410 as_Register($src2$$reg)); 10411 %} 10412 10413 ins_pipe(lmac_reg_reg); 10414 %} 10415 10416 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10417 10418 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10419 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10420 10421 ins_cost(INSN_COST * 3); 10422 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10423 10424 ins_encode %{ 10425 __ smaddl(as_Register($dst$$reg), 10426 as_Register($src1$$reg), 10427 as_Register($src2$$reg), 10428 as_Register($src3$$reg)); 10429 %} 10430 10431 ins_pipe(imac_reg_reg); 10432 %} 10433 10434 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10435 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10436 10437 ins_cost(INSN_COST * 3); 10438 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10439 10440 ins_encode %{ 10441 __ smsubl(as_Register($dst$$reg), 10442 as_Register($src1$$reg), 10443 as_Register($src2$$reg), 10444 as_Register($src3$$reg)); 10445 %} 10446 10447 ins_pipe(imac_reg_reg); 10448 %} 10449 10450 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10451 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10452 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10453 10454 ins_cost(INSN_COST * 3); 10455 format %{ "smnegl $dst, $src1, $src2" %} 10456 10457 ins_encode %{ 10458 __ smnegl(as_Register($dst$$reg), 10459 as_Register($src1$$reg), 10460 as_Register($src2$$reg)); 10461 %} 10462 10463 ins_pipe(imac_reg_reg); 10464 %} 10465 10466 // Integer Divide 10467 10468 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10469 match(Set dst (DivI src1 src2)); 10470 10471 ins_cost(INSN_COST * 19); 10472 format %{ "sdivw $dst, $src1, $src2" %} 10473 10474 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10475 ins_pipe(idiv_reg_reg); 10476 %} 10477 10478 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 10479 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 10480 ins_cost(INSN_COST); 10481 format %{ "lsrw $dst, $src1, $div1" %} 10482 ins_encode %{ 10483 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 10484 %} 10485 ins_pipe(ialu_reg_shift); 10486 %} 10487 10488 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 10489 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 10490 ins_cost(INSN_COST); 10491 format %{ "addw $dst, $src, LSR $div1" %} 10492 10493 ins_encode %{ 10494 __ addw(as_Register($dst$$reg), 10495 as_Register($src$$reg), 10496 as_Register($src$$reg), 10497 Assembler::LSR, 31); 10498 %} 10499 ins_pipe(ialu_reg); 10500 %} 10501 10502 // Long Divide 10503 10504 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10505 match(Set dst (DivL src1 src2)); 10506 10507 ins_cost(INSN_COST * 35); 10508 format %{ "sdiv $dst, $src1, $src2" %} 10509 10510 ins_encode(aarch64_enc_div(dst, src1, src2)); 10511 ins_pipe(ldiv_reg_reg); 10512 %} 10513 10514 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 10515 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 10516 ins_cost(INSN_COST); 10517 format %{ "lsr $dst, $src1, $div1" %} 10518 ins_encode %{ 10519 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 10520 %} 10521 ins_pipe(ialu_reg_shift); 10522 %} 10523 10524 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 10525 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 10526 ins_cost(INSN_COST); 10527 format %{ "add $dst, $src, $div1" %} 10528 10529 ins_encode %{ 10530 __ add(as_Register($dst$$reg), 10531 as_Register($src$$reg), 10532 as_Register($src$$reg), 10533 Assembler::LSR, 63); 10534 %} 10535 ins_pipe(ialu_reg); 10536 %} 10537 10538 // Integer Remainder 10539 10540 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10541 match(Set dst (ModI src1 src2)); 10542 10543 ins_cost(INSN_COST * 22); 10544 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10545 "msubw($dst, rscratch1, $src2, $src1" %} 10546 10547 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10548 ins_pipe(idiv_reg_reg); 10549 %} 10550 10551 // Long Remainder 10552 10553 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10554 match(Set dst (ModL src1 src2)); 10555 10556 ins_cost(INSN_COST * 38); 10557 format %{ "sdiv rscratch1, $src1, $src2\n" 10558 "msub($dst, rscratch1, $src2, $src1" %} 10559 10560 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10561 ins_pipe(ldiv_reg_reg); 10562 %} 10563 10564 // Integer Shifts 10565 10566 // Shift Left Register 10567 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10568 match(Set dst (LShiftI src1 src2)); 10569 10570 ins_cost(INSN_COST * 2); 10571 format %{ "lslvw $dst, $src1, $src2" %} 10572 10573 ins_encode %{ 10574 __ lslvw(as_Register($dst$$reg), 10575 as_Register($src1$$reg), 10576 as_Register($src2$$reg)); 10577 %} 10578 10579 ins_pipe(ialu_reg_reg_vshift); 10580 %} 10581 10582 // Shift Left Immediate 10583 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10584 match(Set dst (LShiftI src1 src2)); 10585 10586 ins_cost(INSN_COST); 10587 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10588 10589 ins_encode %{ 10590 __ lslw(as_Register($dst$$reg), 10591 as_Register($src1$$reg), 10592 $src2$$constant & 0x1f); 10593 %} 10594 10595 ins_pipe(ialu_reg_shift); 10596 %} 10597 10598 // Shift Right Logical Register 10599 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10600 match(Set dst (URShiftI src1 src2)); 10601 10602 ins_cost(INSN_COST * 2); 10603 format %{ "lsrvw $dst, $src1, $src2" %} 10604 10605 ins_encode %{ 10606 __ lsrvw(as_Register($dst$$reg), 10607 as_Register($src1$$reg), 10608 as_Register($src2$$reg)); 10609 %} 10610 10611 ins_pipe(ialu_reg_reg_vshift); 10612 %} 10613 10614 // Shift Right Logical Immediate 10615 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10616 match(Set dst (URShiftI src1 src2)); 10617 10618 ins_cost(INSN_COST); 10619 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10620 10621 ins_encode %{ 10622 __ lsrw(as_Register($dst$$reg), 10623 as_Register($src1$$reg), 10624 $src2$$constant & 0x1f); 10625 %} 10626 10627 ins_pipe(ialu_reg_shift); 10628 %} 10629 10630 // Shift Right Arithmetic Register 10631 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10632 match(Set dst (RShiftI src1 src2)); 10633 10634 ins_cost(INSN_COST * 2); 10635 format %{ "asrvw $dst, $src1, $src2" %} 10636 10637 ins_encode %{ 10638 __ asrvw(as_Register($dst$$reg), 10639 as_Register($src1$$reg), 10640 as_Register($src2$$reg)); 10641 %} 10642 10643 ins_pipe(ialu_reg_reg_vshift); 10644 %} 10645 10646 // Shift Right Arithmetic Immediate 10647 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10648 match(Set dst (RShiftI src1 src2)); 10649 10650 ins_cost(INSN_COST); 10651 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10652 10653 ins_encode %{ 10654 __ asrw(as_Register($dst$$reg), 10655 as_Register($src1$$reg), 10656 $src2$$constant & 0x1f); 10657 %} 10658 10659 ins_pipe(ialu_reg_shift); 10660 %} 10661 10662 // Combined Int Mask and Right Shift (using UBFM) 10663 // TODO 10664 10665 // Long Shifts 10666 10667 // Shift Left Register 10668 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10669 match(Set dst (LShiftL src1 src2)); 10670 10671 ins_cost(INSN_COST * 2); 10672 format %{ "lslv $dst, $src1, $src2" %} 10673 10674 ins_encode %{ 10675 __ lslv(as_Register($dst$$reg), 10676 as_Register($src1$$reg), 10677 as_Register($src2$$reg)); 10678 %} 10679 10680 ins_pipe(ialu_reg_reg_vshift); 10681 %} 10682 10683 // Shift Left Immediate 10684 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10685 match(Set dst (LShiftL src1 src2)); 10686 10687 ins_cost(INSN_COST); 10688 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10689 10690 ins_encode %{ 10691 __ lsl(as_Register($dst$$reg), 10692 as_Register($src1$$reg), 10693 $src2$$constant & 0x3f); 10694 %} 10695 10696 ins_pipe(ialu_reg_shift); 10697 %} 10698 10699 // Shift Right Logical Register 10700 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10701 match(Set dst (URShiftL src1 src2)); 10702 10703 ins_cost(INSN_COST * 2); 10704 format %{ "lsrv $dst, $src1, $src2" %} 10705 10706 ins_encode %{ 10707 __ lsrv(as_Register($dst$$reg), 10708 as_Register($src1$$reg), 10709 as_Register($src2$$reg)); 10710 %} 10711 10712 ins_pipe(ialu_reg_reg_vshift); 10713 %} 10714 10715 // Shift Right Logical Immediate 10716 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10717 match(Set dst (URShiftL src1 src2)); 10718 10719 ins_cost(INSN_COST); 10720 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10721 10722 ins_encode %{ 10723 __ lsr(as_Register($dst$$reg), 10724 as_Register($src1$$reg), 10725 $src2$$constant & 0x3f); 10726 %} 10727 10728 ins_pipe(ialu_reg_shift); 10729 %} 10730 10731 // A special-case pattern for card table stores. 10732 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10733 match(Set dst (URShiftL (CastP2X src1) src2)); 10734 10735 ins_cost(INSN_COST); 10736 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10737 10738 ins_encode %{ 10739 __ lsr(as_Register($dst$$reg), 10740 as_Register($src1$$reg), 10741 $src2$$constant & 0x3f); 10742 %} 10743 10744 ins_pipe(ialu_reg_shift); 10745 %} 10746 10747 // Shift Right Arithmetic Register 10748 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10749 match(Set dst (RShiftL src1 src2)); 10750 10751 ins_cost(INSN_COST * 2); 10752 format %{ "asrv $dst, $src1, $src2" %} 10753 10754 ins_encode %{ 10755 __ asrv(as_Register($dst$$reg), 10756 as_Register($src1$$reg), 10757 as_Register($src2$$reg)); 10758 %} 10759 10760 ins_pipe(ialu_reg_reg_vshift); 10761 %} 10762 10763 // Shift Right Arithmetic Immediate 10764 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10765 match(Set dst (RShiftL src1 src2)); 10766 10767 ins_cost(INSN_COST); 10768 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10769 10770 ins_encode %{ 10771 __ asr(as_Register($dst$$reg), 10772 as_Register($src1$$reg), 10773 $src2$$constant & 0x3f); 10774 %} 10775 10776 ins_pipe(ialu_reg_shift); 10777 %} 10778 10779 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10780 10781 instruct regL_not_reg(iRegLNoSp dst, 10782 iRegL src1, immL_M1 m1, 10783 rFlagsReg cr) %{ 10784 match(Set dst (XorL src1 m1)); 10785 ins_cost(INSN_COST); 10786 format %{ "eon $dst, $src1, zr" %} 10787 10788 ins_encode %{ 10789 __ eon(as_Register($dst$$reg), 10790 as_Register($src1$$reg), 10791 zr, 10792 Assembler::LSL, 0); 10793 %} 10794 10795 ins_pipe(ialu_reg); 10796 %} 10797 instruct regI_not_reg(iRegINoSp dst, 10798 iRegIorL2I src1, immI_M1 m1, 10799 rFlagsReg cr) %{ 10800 match(Set dst (XorI src1 m1)); 10801 ins_cost(INSN_COST); 10802 format %{ "eonw $dst, $src1, zr" %} 10803 10804 ins_encode %{ 10805 __ eonw(as_Register($dst$$reg), 10806 as_Register($src1$$reg), 10807 zr, 10808 Assembler::LSL, 0); 10809 %} 10810 10811 ins_pipe(ialu_reg); 10812 %} 10813 10814 instruct AndI_reg_not_reg(iRegINoSp dst, 10815 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10816 rFlagsReg cr) %{ 10817 match(Set dst (AndI src1 (XorI src2 m1))); 10818 ins_cost(INSN_COST); 10819 format %{ "bicw $dst, $src1, $src2" %} 10820 10821 ins_encode %{ 10822 __ bicw(as_Register($dst$$reg), 10823 as_Register($src1$$reg), 10824 as_Register($src2$$reg), 10825 Assembler::LSL, 0); 10826 %} 10827 10828 ins_pipe(ialu_reg_reg); 10829 %} 10830 10831 instruct AndL_reg_not_reg(iRegLNoSp dst, 10832 iRegL src1, iRegL src2, immL_M1 m1, 10833 rFlagsReg cr) %{ 10834 match(Set dst (AndL src1 (XorL src2 m1))); 10835 ins_cost(INSN_COST); 10836 format %{ "bic $dst, $src1, $src2" %} 10837 10838 ins_encode %{ 10839 __ bic(as_Register($dst$$reg), 10840 as_Register($src1$$reg), 10841 as_Register($src2$$reg), 10842 Assembler::LSL, 0); 10843 %} 10844 10845 ins_pipe(ialu_reg_reg); 10846 %} 10847 10848 instruct OrI_reg_not_reg(iRegINoSp dst, 10849 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10850 rFlagsReg cr) %{ 10851 match(Set dst (OrI src1 (XorI src2 m1))); 10852 ins_cost(INSN_COST); 10853 format %{ "ornw $dst, $src1, $src2" %} 10854 10855 ins_encode %{ 10856 __ ornw(as_Register($dst$$reg), 10857 as_Register($src1$$reg), 10858 as_Register($src2$$reg), 10859 Assembler::LSL, 0); 10860 %} 10861 10862 ins_pipe(ialu_reg_reg); 10863 %} 10864 10865 instruct OrL_reg_not_reg(iRegLNoSp dst, 10866 iRegL src1, iRegL src2, immL_M1 m1, 10867 rFlagsReg cr) %{ 10868 match(Set dst (OrL src1 (XorL src2 m1))); 10869 ins_cost(INSN_COST); 10870 format %{ "orn $dst, $src1, $src2" %} 10871 10872 ins_encode %{ 10873 __ orn(as_Register($dst$$reg), 10874 as_Register($src1$$reg), 10875 as_Register($src2$$reg), 10876 Assembler::LSL, 0); 10877 %} 10878 10879 ins_pipe(ialu_reg_reg); 10880 %} 10881 10882 instruct XorI_reg_not_reg(iRegINoSp dst, 10883 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10884 rFlagsReg cr) %{ 10885 match(Set dst (XorI m1 (XorI src2 src1))); 10886 ins_cost(INSN_COST); 10887 format %{ "eonw $dst, $src1, $src2" %} 10888 10889 ins_encode %{ 10890 __ eonw(as_Register($dst$$reg), 10891 as_Register($src1$$reg), 10892 as_Register($src2$$reg), 10893 Assembler::LSL, 0); 10894 %} 10895 10896 ins_pipe(ialu_reg_reg); 10897 %} 10898 10899 instruct XorL_reg_not_reg(iRegLNoSp dst, 10900 iRegL src1, iRegL src2, immL_M1 m1, 10901 rFlagsReg cr) %{ 10902 match(Set dst (XorL m1 (XorL src2 src1))); 10903 ins_cost(INSN_COST); 10904 format %{ "eon $dst, $src1, $src2" %} 10905 10906 ins_encode %{ 10907 __ eon(as_Register($dst$$reg), 10908 as_Register($src1$$reg), 10909 as_Register($src2$$reg), 10910 Assembler::LSL, 0); 10911 %} 10912 10913 ins_pipe(ialu_reg_reg); 10914 %} 10915 10916 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10917 iRegIorL2I src1, iRegIorL2I src2, 10918 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10919 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10920 ins_cost(1.9 * INSN_COST); 10921 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10922 10923 ins_encode %{ 10924 __ bicw(as_Register($dst$$reg), 10925 as_Register($src1$$reg), 10926 as_Register($src2$$reg), 10927 Assembler::LSR, 10928 $src3$$constant & 0x1f); 10929 %} 10930 10931 ins_pipe(ialu_reg_reg_shift); 10932 %} 10933 10934 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10935 iRegL src1, iRegL src2, 10936 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10937 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10938 ins_cost(1.9 * INSN_COST); 10939 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10940 10941 ins_encode %{ 10942 __ bic(as_Register($dst$$reg), 10943 as_Register($src1$$reg), 10944 as_Register($src2$$reg), 10945 Assembler::LSR, 10946 $src3$$constant & 0x3f); 10947 %} 10948 10949 ins_pipe(ialu_reg_reg_shift); 10950 %} 10951 10952 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10953 iRegIorL2I src1, iRegIorL2I src2, 10954 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10955 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10956 ins_cost(1.9 * INSN_COST); 10957 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10958 10959 ins_encode %{ 10960 __ bicw(as_Register($dst$$reg), 10961 as_Register($src1$$reg), 10962 as_Register($src2$$reg), 10963 Assembler::ASR, 10964 $src3$$constant & 0x1f); 10965 %} 10966 10967 ins_pipe(ialu_reg_reg_shift); 10968 %} 10969 10970 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10971 iRegL src1, iRegL src2, 10972 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10973 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10974 ins_cost(1.9 * INSN_COST); 10975 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10976 10977 ins_encode %{ 10978 __ bic(as_Register($dst$$reg), 10979 as_Register($src1$$reg), 10980 as_Register($src2$$reg), 10981 Assembler::ASR, 10982 $src3$$constant & 0x3f); 10983 %} 10984 10985 ins_pipe(ialu_reg_reg_shift); 10986 %} 10987 10988 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10989 iRegIorL2I src1, iRegIorL2I src2, 10990 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10991 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10992 ins_cost(1.9 * INSN_COST); 10993 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10994 10995 ins_encode %{ 10996 __ bicw(as_Register($dst$$reg), 10997 as_Register($src1$$reg), 10998 as_Register($src2$$reg), 10999 Assembler::LSL, 11000 $src3$$constant & 0x1f); 11001 %} 11002 11003 ins_pipe(ialu_reg_reg_shift); 11004 %} 11005 11006 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11007 iRegL src1, iRegL src2, 11008 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11009 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11010 ins_cost(1.9 * INSN_COST); 11011 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11012 11013 ins_encode %{ 11014 __ bic(as_Register($dst$$reg), 11015 as_Register($src1$$reg), 11016 as_Register($src2$$reg), 11017 Assembler::LSL, 11018 $src3$$constant & 0x3f); 11019 %} 11020 11021 ins_pipe(ialu_reg_reg_shift); 11022 %} 11023 11024 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11025 iRegIorL2I src1, iRegIorL2I src2, 11026 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11027 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11028 ins_cost(1.9 * INSN_COST); 11029 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11030 11031 ins_encode %{ 11032 __ eonw(as_Register($dst$$reg), 11033 as_Register($src1$$reg), 11034 as_Register($src2$$reg), 11035 Assembler::LSR, 11036 $src3$$constant & 0x1f); 11037 %} 11038 11039 ins_pipe(ialu_reg_reg_shift); 11040 %} 11041 11042 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11043 iRegL src1, iRegL src2, 11044 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11045 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11046 ins_cost(1.9 * INSN_COST); 11047 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11048 11049 ins_encode %{ 11050 __ eon(as_Register($dst$$reg), 11051 as_Register($src1$$reg), 11052 as_Register($src2$$reg), 11053 Assembler::LSR, 11054 $src3$$constant & 0x3f); 11055 %} 11056 11057 ins_pipe(ialu_reg_reg_shift); 11058 %} 11059 11060 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11061 iRegIorL2I src1, iRegIorL2I src2, 11062 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11063 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11064 ins_cost(1.9 * INSN_COST); 11065 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11066 11067 ins_encode %{ 11068 __ eonw(as_Register($dst$$reg), 11069 as_Register($src1$$reg), 11070 as_Register($src2$$reg), 11071 Assembler::ASR, 11072 $src3$$constant & 0x1f); 11073 %} 11074 11075 ins_pipe(ialu_reg_reg_shift); 11076 %} 11077 11078 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11079 iRegL src1, iRegL src2, 11080 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11081 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11082 ins_cost(1.9 * INSN_COST); 11083 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11084 11085 ins_encode %{ 11086 __ eon(as_Register($dst$$reg), 11087 as_Register($src1$$reg), 11088 as_Register($src2$$reg), 11089 Assembler::ASR, 11090 $src3$$constant & 0x3f); 11091 %} 11092 11093 ins_pipe(ialu_reg_reg_shift); 11094 %} 11095 11096 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11097 iRegIorL2I src1, iRegIorL2I src2, 11098 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11099 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11100 ins_cost(1.9 * INSN_COST); 11101 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11102 11103 ins_encode %{ 11104 __ eonw(as_Register($dst$$reg), 11105 as_Register($src1$$reg), 11106 as_Register($src2$$reg), 11107 Assembler::LSL, 11108 $src3$$constant & 0x1f); 11109 %} 11110 11111 ins_pipe(ialu_reg_reg_shift); 11112 %} 11113 11114 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11115 iRegL src1, iRegL src2, 11116 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11117 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11118 ins_cost(1.9 * INSN_COST); 11119 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11120 11121 ins_encode %{ 11122 __ eon(as_Register($dst$$reg), 11123 as_Register($src1$$reg), 11124 as_Register($src2$$reg), 11125 Assembler::LSL, 11126 $src3$$constant & 0x3f); 11127 %} 11128 11129 ins_pipe(ialu_reg_reg_shift); 11130 %} 11131 11132 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11133 iRegIorL2I src1, iRegIorL2I src2, 11134 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11135 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11136 ins_cost(1.9 * INSN_COST); 11137 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11138 11139 ins_encode %{ 11140 __ ornw(as_Register($dst$$reg), 11141 as_Register($src1$$reg), 11142 as_Register($src2$$reg), 11143 Assembler::LSR, 11144 $src3$$constant & 0x1f); 11145 %} 11146 11147 ins_pipe(ialu_reg_reg_shift); 11148 %} 11149 11150 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11151 iRegL src1, iRegL src2, 11152 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11153 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11154 ins_cost(1.9 * INSN_COST); 11155 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11156 11157 ins_encode %{ 11158 __ orn(as_Register($dst$$reg), 11159 as_Register($src1$$reg), 11160 as_Register($src2$$reg), 11161 Assembler::LSR, 11162 $src3$$constant & 0x3f); 11163 %} 11164 11165 ins_pipe(ialu_reg_reg_shift); 11166 %} 11167 11168 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11169 iRegIorL2I src1, iRegIorL2I src2, 11170 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11171 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11172 ins_cost(1.9 * INSN_COST); 11173 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11174 11175 ins_encode %{ 11176 __ ornw(as_Register($dst$$reg), 11177 as_Register($src1$$reg), 11178 as_Register($src2$$reg), 11179 Assembler::ASR, 11180 $src3$$constant & 0x1f); 11181 %} 11182 11183 ins_pipe(ialu_reg_reg_shift); 11184 %} 11185 11186 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11187 iRegL src1, iRegL src2, 11188 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11189 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11190 ins_cost(1.9 * INSN_COST); 11191 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11192 11193 ins_encode %{ 11194 __ orn(as_Register($dst$$reg), 11195 as_Register($src1$$reg), 11196 as_Register($src2$$reg), 11197 Assembler::ASR, 11198 $src3$$constant & 0x3f); 11199 %} 11200 11201 ins_pipe(ialu_reg_reg_shift); 11202 %} 11203 11204 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11205 iRegIorL2I src1, iRegIorL2I src2, 11206 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11207 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11208 ins_cost(1.9 * INSN_COST); 11209 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11210 11211 ins_encode %{ 11212 __ ornw(as_Register($dst$$reg), 11213 as_Register($src1$$reg), 11214 as_Register($src2$$reg), 11215 Assembler::LSL, 11216 $src3$$constant & 0x1f); 11217 %} 11218 11219 ins_pipe(ialu_reg_reg_shift); 11220 %} 11221 11222 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11223 iRegL src1, iRegL src2, 11224 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11225 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11226 ins_cost(1.9 * INSN_COST); 11227 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11228 11229 ins_encode %{ 11230 __ orn(as_Register($dst$$reg), 11231 as_Register($src1$$reg), 11232 as_Register($src2$$reg), 11233 Assembler::LSL, 11234 $src3$$constant & 0x3f); 11235 %} 11236 11237 ins_pipe(ialu_reg_reg_shift); 11238 %} 11239 11240 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11241 iRegIorL2I src1, iRegIorL2I src2, 11242 immI src3, rFlagsReg cr) %{ 11243 match(Set dst (AndI src1 (URShiftI src2 src3))); 11244 11245 ins_cost(1.9 * INSN_COST); 11246 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11247 11248 ins_encode %{ 11249 __ andw(as_Register($dst$$reg), 11250 as_Register($src1$$reg), 11251 as_Register($src2$$reg), 11252 Assembler::LSR, 11253 $src3$$constant & 0x1f); 11254 %} 11255 11256 ins_pipe(ialu_reg_reg_shift); 11257 %} 11258 11259 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11260 iRegL src1, iRegL src2, 11261 immI src3, rFlagsReg cr) %{ 11262 match(Set dst (AndL src1 (URShiftL src2 src3))); 11263 11264 ins_cost(1.9 * INSN_COST); 11265 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11266 11267 ins_encode %{ 11268 __ andr(as_Register($dst$$reg), 11269 as_Register($src1$$reg), 11270 as_Register($src2$$reg), 11271 Assembler::LSR, 11272 $src3$$constant & 0x3f); 11273 %} 11274 11275 ins_pipe(ialu_reg_reg_shift); 11276 %} 11277 11278 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11279 iRegIorL2I src1, iRegIorL2I src2, 11280 immI src3, rFlagsReg cr) %{ 11281 match(Set dst (AndI src1 (RShiftI src2 src3))); 11282 11283 ins_cost(1.9 * INSN_COST); 11284 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11285 11286 ins_encode %{ 11287 __ andw(as_Register($dst$$reg), 11288 as_Register($src1$$reg), 11289 as_Register($src2$$reg), 11290 Assembler::ASR, 11291 $src3$$constant & 0x1f); 11292 %} 11293 11294 ins_pipe(ialu_reg_reg_shift); 11295 %} 11296 11297 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11298 iRegL src1, iRegL src2, 11299 immI src3, rFlagsReg cr) %{ 11300 match(Set dst (AndL src1 (RShiftL src2 src3))); 11301 11302 ins_cost(1.9 * INSN_COST); 11303 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11304 11305 ins_encode %{ 11306 __ andr(as_Register($dst$$reg), 11307 as_Register($src1$$reg), 11308 as_Register($src2$$reg), 11309 Assembler::ASR, 11310 $src3$$constant & 0x3f); 11311 %} 11312 11313 ins_pipe(ialu_reg_reg_shift); 11314 %} 11315 11316 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11317 iRegIorL2I src1, iRegIorL2I src2, 11318 immI src3, rFlagsReg cr) %{ 11319 match(Set dst (AndI src1 (LShiftI src2 src3))); 11320 11321 ins_cost(1.9 * INSN_COST); 11322 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11323 11324 ins_encode %{ 11325 __ andw(as_Register($dst$$reg), 11326 as_Register($src1$$reg), 11327 as_Register($src2$$reg), 11328 Assembler::LSL, 11329 $src3$$constant & 0x1f); 11330 %} 11331 11332 ins_pipe(ialu_reg_reg_shift); 11333 %} 11334 11335 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11336 iRegL src1, iRegL src2, 11337 immI src3, rFlagsReg cr) %{ 11338 match(Set dst (AndL src1 (LShiftL src2 src3))); 11339 11340 ins_cost(1.9 * INSN_COST); 11341 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11342 11343 ins_encode %{ 11344 __ andr(as_Register($dst$$reg), 11345 as_Register($src1$$reg), 11346 as_Register($src2$$reg), 11347 Assembler::LSL, 11348 $src3$$constant & 0x3f); 11349 %} 11350 11351 ins_pipe(ialu_reg_reg_shift); 11352 %} 11353 11354 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11355 iRegIorL2I src1, iRegIorL2I src2, 11356 immI src3, rFlagsReg cr) %{ 11357 match(Set dst (XorI src1 (URShiftI src2 src3))); 11358 11359 ins_cost(1.9 * INSN_COST); 11360 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11361 11362 ins_encode %{ 11363 __ eorw(as_Register($dst$$reg), 11364 as_Register($src1$$reg), 11365 as_Register($src2$$reg), 11366 Assembler::LSR, 11367 $src3$$constant & 0x1f); 11368 %} 11369 11370 ins_pipe(ialu_reg_reg_shift); 11371 %} 11372 11373 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11374 iRegL src1, iRegL src2, 11375 immI src3, rFlagsReg cr) %{ 11376 match(Set dst (XorL src1 (URShiftL src2 src3))); 11377 11378 ins_cost(1.9 * INSN_COST); 11379 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11380 11381 ins_encode %{ 11382 __ eor(as_Register($dst$$reg), 11383 as_Register($src1$$reg), 11384 as_Register($src2$$reg), 11385 Assembler::LSR, 11386 $src3$$constant & 0x3f); 11387 %} 11388 11389 ins_pipe(ialu_reg_reg_shift); 11390 %} 11391 11392 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11393 iRegIorL2I src1, iRegIorL2I src2, 11394 immI src3, rFlagsReg cr) %{ 11395 match(Set dst (XorI src1 (RShiftI src2 src3))); 11396 11397 ins_cost(1.9 * INSN_COST); 11398 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11399 11400 ins_encode %{ 11401 __ eorw(as_Register($dst$$reg), 11402 as_Register($src1$$reg), 11403 as_Register($src2$$reg), 11404 Assembler::ASR, 11405 $src3$$constant & 0x1f); 11406 %} 11407 11408 ins_pipe(ialu_reg_reg_shift); 11409 %} 11410 11411 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11412 iRegL src1, iRegL src2, 11413 immI src3, rFlagsReg cr) %{ 11414 match(Set dst (XorL src1 (RShiftL src2 src3))); 11415 11416 ins_cost(1.9 * INSN_COST); 11417 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11418 11419 ins_encode %{ 11420 __ eor(as_Register($dst$$reg), 11421 as_Register($src1$$reg), 11422 as_Register($src2$$reg), 11423 Assembler::ASR, 11424 $src3$$constant & 0x3f); 11425 %} 11426 11427 ins_pipe(ialu_reg_reg_shift); 11428 %} 11429 11430 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11431 iRegIorL2I src1, iRegIorL2I src2, 11432 immI src3, rFlagsReg cr) %{ 11433 match(Set dst (XorI src1 (LShiftI src2 src3))); 11434 11435 ins_cost(1.9 * INSN_COST); 11436 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11437 11438 ins_encode %{ 11439 __ eorw(as_Register($dst$$reg), 11440 as_Register($src1$$reg), 11441 as_Register($src2$$reg), 11442 Assembler::LSL, 11443 $src3$$constant & 0x1f); 11444 %} 11445 11446 ins_pipe(ialu_reg_reg_shift); 11447 %} 11448 11449 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11450 iRegL src1, iRegL src2, 11451 immI src3, rFlagsReg cr) %{ 11452 match(Set dst (XorL src1 (LShiftL src2 src3))); 11453 11454 ins_cost(1.9 * INSN_COST); 11455 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11456 11457 ins_encode %{ 11458 __ eor(as_Register($dst$$reg), 11459 as_Register($src1$$reg), 11460 as_Register($src2$$reg), 11461 Assembler::LSL, 11462 $src3$$constant & 0x3f); 11463 %} 11464 11465 ins_pipe(ialu_reg_reg_shift); 11466 %} 11467 11468 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11469 iRegIorL2I src1, iRegIorL2I src2, 11470 immI src3, rFlagsReg cr) %{ 11471 match(Set dst (OrI src1 (URShiftI src2 src3))); 11472 11473 ins_cost(1.9 * INSN_COST); 11474 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11475 11476 ins_encode %{ 11477 __ orrw(as_Register($dst$$reg), 11478 as_Register($src1$$reg), 11479 as_Register($src2$$reg), 11480 Assembler::LSR, 11481 $src3$$constant & 0x1f); 11482 %} 11483 11484 ins_pipe(ialu_reg_reg_shift); 11485 %} 11486 11487 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11488 iRegL src1, iRegL src2, 11489 immI src3, rFlagsReg cr) %{ 11490 match(Set dst (OrL src1 (URShiftL src2 src3))); 11491 11492 ins_cost(1.9 * INSN_COST); 11493 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11494 11495 ins_encode %{ 11496 __ orr(as_Register($dst$$reg), 11497 as_Register($src1$$reg), 11498 as_Register($src2$$reg), 11499 Assembler::LSR, 11500 $src3$$constant & 0x3f); 11501 %} 11502 11503 ins_pipe(ialu_reg_reg_shift); 11504 %} 11505 11506 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11507 iRegIorL2I src1, iRegIorL2I src2, 11508 immI src3, rFlagsReg cr) %{ 11509 match(Set dst (OrI src1 (RShiftI src2 src3))); 11510 11511 ins_cost(1.9 * INSN_COST); 11512 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11513 11514 ins_encode %{ 11515 __ orrw(as_Register($dst$$reg), 11516 as_Register($src1$$reg), 11517 as_Register($src2$$reg), 11518 Assembler::ASR, 11519 $src3$$constant & 0x1f); 11520 %} 11521 11522 ins_pipe(ialu_reg_reg_shift); 11523 %} 11524 11525 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11526 iRegL src1, iRegL src2, 11527 immI src3, rFlagsReg cr) %{ 11528 match(Set dst (OrL src1 (RShiftL src2 src3))); 11529 11530 ins_cost(1.9 * INSN_COST); 11531 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11532 11533 ins_encode %{ 11534 __ orr(as_Register($dst$$reg), 11535 as_Register($src1$$reg), 11536 as_Register($src2$$reg), 11537 Assembler::ASR, 11538 $src3$$constant & 0x3f); 11539 %} 11540 11541 ins_pipe(ialu_reg_reg_shift); 11542 %} 11543 11544 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11545 iRegIorL2I src1, iRegIorL2I src2, 11546 immI src3, rFlagsReg cr) %{ 11547 match(Set dst (OrI src1 (LShiftI src2 src3))); 11548 11549 ins_cost(1.9 * INSN_COST); 11550 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11551 11552 ins_encode %{ 11553 __ orrw(as_Register($dst$$reg), 11554 as_Register($src1$$reg), 11555 as_Register($src2$$reg), 11556 Assembler::LSL, 11557 $src3$$constant & 0x1f); 11558 %} 11559 11560 ins_pipe(ialu_reg_reg_shift); 11561 %} 11562 11563 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11564 iRegL src1, iRegL src2, 11565 immI src3, rFlagsReg cr) %{ 11566 match(Set dst (OrL src1 (LShiftL src2 src3))); 11567 11568 ins_cost(1.9 * INSN_COST); 11569 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11570 11571 ins_encode %{ 11572 __ orr(as_Register($dst$$reg), 11573 as_Register($src1$$reg), 11574 as_Register($src2$$reg), 11575 Assembler::LSL, 11576 $src3$$constant & 0x3f); 11577 %} 11578 11579 ins_pipe(ialu_reg_reg_shift); 11580 %} 11581 11582 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11583 iRegIorL2I src1, iRegIorL2I src2, 11584 immI src3, rFlagsReg cr) %{ 11585 match(Set dst (AddI src1 (URShiftI src2 src3))); 11586 11587 ins_cost(1.9 * INSN_COST); 11588 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11589 11590 ins_encode %{ 11591 __ addw(as_Register($dst$$reg), 11592 as_Register($src1$$reg), 11593 as_Register($src2$$reg), 11594 Assembler::LSR, 11595 $src3$$constant & 0x1f); 11596 %} 11597 11598 ins_pipe(ialu_reg_reg_shift); 11599 %} 11600 11601 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11602 iRegL src1, iRegL src2, 11603 immI src3, rFlagsReg cr) %{ 11604 match(Set dst (AddL src1 (URShiftL src2 src3))); 11605 11606 ins_cost(1.9 * INSN_COST); 11607 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11608 11609 ins_encode %{ 11610 __ add(as_Register($dst$$reg), 11611 as_Register($src1$$reg), 11612 as_Register($src2$$reg), 11613 Assembler::LSR, 11614 $src3$$constant & 0x3f); 11615 %} 11616 11617 ins_pipe(ialu_reg_reg_shift); 11618 %} 11619 11620 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11621 iRegIorL2I src1, iRegIorL2I src2, 11622 immI src3, rFlagsReg cr) %{ 11623 match(Set dst (AddI src1 (RShiftI src2 src3))); 11624 11625 ins_cost(1.9 * INSN_COST); 11626 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11627 11628 ins_encode %{ 11629 __ addw(as_Register($dst$$reg), 11630 as_Register($src1$$reg), 11631 as_Register($src2$$reg), 11632 Assembler::ASR, 11633 $src3$$constant & 0x1f); 11634 %} 11635 11636 ins_pipe(ialu_reg_reg_shift); 11637 %} 11638 11639 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11640 iRegL src1, iRegL src2, 11641 immI src3, rFlagsReg cr) %{ 11642 match(Set dst (AddL src1 (RShiftL src2 src3))); 11643 11644 ins_cost(1.9 * INSN_COST); 11645 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11646 11647 ins_encode %{ 11648 __ add(as_Register($dst$$reg), 11649 as_Register($src1$$reg), 11650 as_Register($src2$$reg), 11651 Assembler::ASR, 11652 $src3$$constant & 0x3f); 11653 %} 11654 11655 ins_pipe(ialu_reg_reg_shift); 11656 %} 11657 11658 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11659 iRegIorL2I src1, iRegIorL2I src2, 11660 immI src3, rFlagsReg cr) %{ 11661 match(Set dst (AddI src1 (LShiftI src2 src3))); 11662 11663 ins_cost(1.9 * INSN_COST); 11664 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11665 11666 ins_encode %{ 11667 __ addw(as_Register($dst$$reg), 11668 as_Register($src1$$reg), 11669 as_Register($src2$$reg), 11670 Assembler::LSL, 11671 $src3$$constant & 0x1f); 11672 %} 11673 11674 ins_pipe(ialu_reg_reg_shift); 11675 %} 11676 11677 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11678 iRegL src1, iRegL src2, 11679 immI src3, rFlagsReg cr) %{ 11680 match(Set dst (AddL src1 (LShiftL src2 src3))); 11681 11682 ins_cost(1.9 * INSN_COST); 11683 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11684 11685 ins_encode %{ 11686 __ add(as_Register($dst$$reg), 11687 as_Register($src1$$reg), 11688 as_Register($src2$$reg), 11689 Assembler::LSL, 11690 $src3$$constant & 0x3f); 11691 %} 11692 11693 ins_pipe(ialu_reg_reg_shift); 11694 %} 11695 11696 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11697 iRegIorL2I src1, iRegIorL2I src2, 11698 immI src3, rFlagsReg cr) %{ 11699 match(Set dst (SubI src1 (URShiftI src2 src3))); 11700 11701 ins_cost(1.9 * INSN_COST); 11702 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11703 11704 ins_encode %{ 11705 __ subw(as_Register($dst$$reg), 11706 as_Register($src1$$reg), 11707 as_Register($src2$$reg), 11708 Assembler::LSR, 11709 $src3$$constant & 0x1f); 11710 %} 11711 11712 ins_pipe(ialu_reg_reg_shift); 11713 %} 11714 11715 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11716 iRegL src1, iRegL src2, 11717 immI src3, rFlagsReg cr) %{ 11718 match(Set dst (SubL src1 (URShiftL src2 src3))); 11719 11720 ins_cost(1.9 * INSN_COST); 11721 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11722 11723 ins_encode %{ 11724 __ sub(as_Register($dst$$reg), 11725 as_Register($src1$$reg), 11726 as_Register($src2$$reg), 11727 Assembler::LSR, 11728 $src3$$constant & 0x3f); 11729 %} 11730 11731 ins_pipe(ialu_reg_reg_shift); 11732 %} 11733 11734 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11735 iRegIorL2I src1, iRegIorL2I src2, 11736 immI src3, rFlagsReg cr) %{ 11737 match(Set dst (SubI src1 (RShiftI src2 src3))); 11738 11739 ins_cost(1.9 * INSN_COST); 11740 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11741 11742 ins_encode %{ 11743 __ subw(as_Register($dst$$reg), 11744 as_Register($src1$$reg), 11745 as_Register($src2$$reg), 11746 Assembler::ASR, 11747 $src3$$constant & 0x1f); 11748 %} 11749 11750 ins_pipe(ialu_reg_reg_shift); 11751 %} 11752 11753 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11754 iRegL src1, iRegL src2, 11755 immI src3, rFlagsReg cr) %{ 11756 match(Set dst (SubL src1 (RShiftL src2 src3))); 11757 11758 ins_cost(1.9 * INSN_COST); 11759 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11760 11761 ins_encode %{ 11762 __ sub(as_Register($dst$$reg), 11763 as_Register($src1$$reg), 11764 as_Register($src2$$reg), 11765 Assembler::ASR, 11766 $src3$$constant & 0x3f); 11767 %} 11768 11769 ins_pipe(ialu_reg_reg_shift); 11770 %} 11771 11772 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11773 iRegIorL2I src1, iRegIorL2I src2, 11774 immI src3, rFlagsReg cr) %{ 11775 match(Set dst (SubI src1 (LShiftI src2 src3))); 11776 11777 ins_cost(1.9 * INSN_COST); 11778 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11779 11780 ins_encode %{ 11781 __ subw(as_Register($dst$$reg), 11782 as_Register($src1$$reg), 11783 as_Register($src2$$reg), 11784 Assembler::LSL, 11785 $src3$$constant & 0x1f); 11786 %} 11787 11788 ins_pipe(ialu_reg_reg_shift); 11789 %} 11790 11791 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11792 iRegL src1, iRegL src2, 11793 immI src3, rFlagsReg cr) %{ 11794 match(Set dst (SubL src1 (LShiftL src2 src3))); 11795 11796 ins_cost(1.9 * INSN_COST); 11797 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11798 11799 ins_encode %{ 11800 __ sub(as_Register($dst$$reg), 11801 as_Register($src1$$reg), 11802 as_Register($src2$$reg), 11803 Assembler::LSL, 11804 $src3$$constant & 0x3f); 11805 %} 11806 11807 ins_pipe(ialu_reg_reg_shift); 11808 %} 11809 11810 11811 11812 // Shift Left followed by Shift Right. 11813 // This idiom is used by the compiler for the i2b bytecode etc. 11814 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11815 %{ 11816 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11817 ins_cost(INSN_COST * 2); 11818 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11819 ins_encode %{ 11820 int lshift = $lshift_count$$constant & 63; 11821 int rshift = $rshift_count$$constant & 63; 11822 int s = 63 - lshift; 11823 int r = (rshift - lshift) & 63; 11824 __ sbfm(as_Register($dst$$reg), 11825 as_Register($src$$reg), 11826 r, s); 11827 %} 11828 11829 ins_pipe(ialu_reg_shift); 11830 %} 11831 11832 // Shift Left followed by Shift Right. 11833 // This idiom is used by the compiler for the i2b bytecode etc. 11834 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11835 %{ 11836 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11837 ins_cost(INSN_COST * 2); 11838 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11839 ins_encode %{ 11840 int lshift = $lshift_count$$constant & 31; 11841 int rshift = $rshift_count$$constant & 31; 11842 int s = 31 - lshift; 11843 int r = (rshift - lshift) & 31; 11844 __ sbfmw(as_Register($dst$$reg), 11845 as_Register($src$$reg), 11846 r, s); 11847 %} 11848 11849 ins_pipe(ialu_reg_shift); 11850 %} 11851 11852 // Shift Left followed by Shift Right. 11853 // This idiom is used by the compiler for the i2b bytecode etc. 11854 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11855 %{ 11856 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11857 ins_cost(INSN_COST * 2); 11858 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11859 ins_encode %{ 11860 int lshift = $lshift_count$$constant & 63; 11861 int rshift = $rshift_count$$constant & 63; 11862 int s = 63 - lshift; 11863 int r = (rshift - lshift) & 63; 11864 __ ubfm(as_Register($dst$$reg), 11865 as_Register($src$$reg), 11866 r, s); 11867 %} 11868 11869 ins_pipe(ialu_reg_shift); 11870 %} 11871 11872 // Shift Left followed by Shift Right. 11873 // This idiom is used by the compiler for the i2b bytecode etc. 11874 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11875 %{ 11876 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11877 ins_cost(INSN_COST * 2); 11878 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11879 ins_encode %{ 11880 int lshift = $lshift_count$$constant & 31; 11881 int rshift = $rshift_count$$constant & 31; 11882 int s = 31 - lshift; 11883 int r = (rshift - lshift) & 31; 11884 __ ubfmw(as_Register($dst$$reg), 11885 as_Register($src$$reg), 11886 r, s); 11887 %} 11888 11889 ins_pipe(ialu_reg_shift); 11890 %} 11891 // Bitfield extract with shift & mask 11892 11893 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11894 %{ 11895 match(Set dst (AndI (URShiftI src rshift) mask)); 11896 // Make sure we are not going to exceed what ubfxw can do. 11897 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11898 11899 ins_cost(INSN_COST); 11900 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11901 ins_encode %{ 11902 int rshift = $rshift$$constant & 31; 11903 long mask = $mask$$constant; 11904 int width = exact_log2(mask+1); 11905 __ ubfxw(as_Register($dst$$reg), 11906 as_Register($src$$reg), rshift, width); 11907 %} 11908 ins_pipe(ialu_reg_shift); 11909 %} 11910 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11911 %{ 11912 match(Set dst (AndL (URShiftL src rshift) mask)); 11913 // Make sure we are not going to exceed what ubfx can do. 11914 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 11915 11916 ins_cost(INSN_COST); 11917 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11918 ins_encode %{ 11919 int rshift = $rshift$$constant & 63; 11920 long mask = $mask$$constant; 11921 int width = exact_log2_long(mask+1); 11922 __ ubfx(as_Register($dst$$reg), 11923 as_Register($src$$reg), rshift, width); 11924 %} 11925 ins_pipe(ialu_reg_shift); 11926 %} 11927 11928 // We can use ubfx when extending an And with a mask when we know mask 11929 // is positive. We know that because immI_bitmask guarantees it. 11930 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11931 %{ 11932 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11933 // Make sure we are not going to exceed what ubfxw can do. 11934 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11935 11936 ins_cost(INSN_COST * 2); 11937 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11938 ins_encode %{ 11939 int rshift = $rshift$$constant & 31; 11940 long mask = $mask$$constant; 11941 int width = exact_log2(mask+1); 11942 __ ubfx(as_Register($dst$$reg), 11943 as_Register($src$$reg), rshift, width); 11944 %} 11945 ins_pipe(ialu_reg_shift); 11946 %} 11947 11948 // We can use ubfiz when masking by a positive number and then left shifting the result. 11949 // We know that the mask is positive because immI_bitmask guarantees it. 11950 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11951 %{ 11952 match(Set dst (LShiftI (AndI src mask) lshift)); 11953 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 11954 11955 ins_cost(INSN_COST); 11956 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11957 ins_encode %{ 11958 int lshift = $lshift$$constant & 31; 11959 long mask = $mask$$constant; 11960 int width = exact_log2(mask+1); 11961 __ ubfizw(as_Register($dst$$reg), 11962 as_Register($src$$reg), lshift, width); 11963 %} 11964 ins_pipe(ialu_reg_shift); 11965 %} 11966 // We can use ubfiz when masking by a positive number and then left shifting the result. 11967 // We know that the mask is positive because immL_bitmask guarantees it. 11968 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11969 %{ 11970 match(Set dst (LShiftL (AndL src mask) lshift)); 11971 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 11972 11973 ins_cost(INSN_COST); 11974 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11975 ins_encode %{ 11976 int lshift = $lshift$$constant & 63; 11977 long mask = $mask$$constant; 11978 int width = exact_log2_long(mask+1); 11979 __ ubfiz(as_Register($dst$$reg), 11980 as_Register($src$$reg), lshift, width); 11981 %} 11982 ins_pipe(ialu_reg_shift); 11983 %} 11984 11985 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11986 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11987 %{ 11988 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 11989 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 11990 11991 ins_cost(INSN_COST); 11992 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11993 ins_encode %{ 11994 int lshift = $lshift$$constant & 63; 11995 long mask = $mask$$constant; 11996 int width = exact_log2(mask+1); 11997 __ ubfiz(as_Register($dst$$reg), 11998 as_Register($src$$reg), lshift, width); 11999 %} 12000 ins_pipe(ialu_reg_shift); 12001 %} 12002 12003 // Rotations 12004 12005 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12006 %{ 12007 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12008 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12009 12010 ins_cost(INSN_COST); 12011 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12012 12013 ins_encode %{ 12014 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12015 $rshift$$constant & 63); 12016 %} 12017 ins_pipe(ialu_reg_reg_extr); 12018 %} 12019 12020 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12021 %{ 12022 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12023 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12024 12025 ins_cost(INSN_COST); 12026 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12027 12028 ins_encode %{ 12029 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12030 $rshift$$constant & 31); 12031 %} 12032 ins_pipe(ialu_reg_reg_extr); 12033 %} 12034 12035 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12036 %{ 12037 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12038 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12039 12040 ins_cost(INSN_COST); 12041 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12042 12043 ins_encode %{ 12044 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12045 $rshift$$constant & 63); 12046 %} 12047 ins_pipe(ialu_reg_reg_extr); 12048 %} 12049 12050 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12051 %{ 12052 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12053 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12054 12055 ins_cost(INSN_COST); 12056 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12057 12058 ins_encode %{ 12059 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12060 $rshift$$constant & 31); 12061 %} 12062 ins_pipe(ialu_reg_reg_extr); 12063 %} 12064 12065 12066 // rol expander 12067 12068 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12069 %{ 12070 effect(DEF dst, USE src, USE shift); 12071 12072 format %{ "rol $dst, $src, $shift" %} 12073 ins_cost(INSN_COST * 3); 12074 ins_encode %{ 12075 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12076 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12077 rscratch1); 12078 %} 12079 ins_pipe(ialu_reg_reg_vshift); 12080 %} 12081 12082 // rol expander 12083 12084 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12085 %{ 12086 effect(DEF dst, USE src, USE shift); 12087 12088 format %{ "rol $dst, $src, $shift" %} 12089 ins_cost(INSN_COST * 3); 12090 ins_encode %{ 12091 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12092 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12093 rscratch1); 12094 %} 12095 ins_pipe(ialu_reg_reg_vshift); 12096 %} 12097 12098 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12099 %{ 12100 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12101 12102 expand %{ 12103 rolL_rReg(dst, src, shift, cr); 12104 %} 12105 %} 12106 12107 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12108 %{ 12109 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12110 12111 expand %{ 12112 rolL_rReg(dst, src, shift, cr); 12113 %} 12114 %} 12115 12116 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12117 %{ 12118 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12119 12120 expand %{ 12121 rolI_rReg(dst, src, shift, cr); 12122 %} 12123 %} 12124 12125 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12126 %{ 12127 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12128 12129 expand %{ 12130 rolI_rReg(dst, src, shift, cr); 12131 %} 12132 %} 12133 12134 // ror expander 12135 12136 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12137 %{ 12138 effect(DEF dst, USE src, USE shift); 12139 12140 format %{ "ror $dst, $src, $shift" %} 12141 ins_cost(INSN_COST); 12142 ins_encode %{ 12143 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12144 as_Register($shift$$reg)); 12145 %} 12146 ins_pipe(ialu_reg_reg_vshift); 12147 %} 12148 12149 // ror expander 12150 12151 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12152 %{ 12153 effect(DEF dst, USE src, USE shift); 12154 12155 format %{ "ror $dst, $src, $shift" %} 12156 ins_cost(INSN_COST); 12157 ins_encode %{ 12158 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12159 as_Register($shift$$reg)); 12160 %} 12161 ins_pipe(ialu_reg_reg_vshift); 12162 %} 12163 12164 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12165 %{ 12166 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12167 12168 expand %{ 12169 rorL_rReg(dst, src, shift, cr); 12170 %} 12171 %} 12172 12173 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12174 %{ 12175 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12176 12177 expand %{ 12178 rorL_rReg(dst, src, shift, cr); 12179 %} 12180 %} 12181 12182 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12183 %{ 12184 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12185 12186 expand %{ 12187 rorI_rReg(dst, src, shift, cr); 12188 %} 12189 %} 12190 12191 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12192 %{ 12193 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12194 12195 expand %{ 12196 rorI_rReg(dst, src, shift, cr); 12197 %} 12198 %} 12199 12200 // Add/subtract (extended) 12201 12202 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12203 %{ 12204 match(Set dst (AddL src1 (ConvI2L src2))); 12205 ins_cost(INSN_COST); 12206 format %{ "add $dst, $src1, $src2, sxtw" %} 12207 12208 ins_encode %{ 12209 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12210 as_Register($src2$$reg), ext::sxtw); 12211 %} 12212 ins_pipe(ialu_reg_reg); 12213 %}; 12214 12215 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12216 %{ 12217 match(Set dst (SubL src1 (ConvI2L src2))); 12218 ins_cost(INSN_COST); 12219 format %{ "sub $dst, $src1, $src2, sxtw" %} 12220 12221 ins_encode %{ 12222 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12223 as_Register($src2$$reg), ext::sxtw); 12224 %} 12225 ins_pipe(ialu_reg_reg); 12226 %}; 12227 12228 12229 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12230 %{ 12231 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12232 ins_cost(INSN_COST); 12233 format %{ "add $dst, $src1, $src2, sxth" %} 12234 12235 ins_encode %{ 12236 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12237 as_Register($src2$$reg), ext::sxth); 12238 %} 12239 ins_pipe(ialu_reg_reg); 12240 %} 12241 12242 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12243 %{ 12244 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12245 ins_cost(INSN_COST); 12246 format %{ "add $dst, $src1, $src2, sxtb" %} 12247 12248 ins_encode %{ 12249 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12250 as_Register($src2$$reg), ext::sxtb); 12251 %} 12252 ins_pipe(ialu_reg_reg); 12253 %} 12254 12255 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12256 %{ 12257 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12258 ins_cost(INSN_COST); 12259 format %{ "add $dst, $src1, $src2, uxtb" %} 12260 12261 ins_encode %{ 12262 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12263 as_Register($src2$$reg), ext::uxtb); 12264 %} 12265 ins_pipe(ialu_reg_reg); 12266 %} 12267 12268 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12269 %{ 12270 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12271 ins_cost(INSN_COST); 12272 format %{ "add $dst, $src1, $src2, sxth" %} 12273 12274 ins_encode %{ 12275 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12276 as_Register($src2$$reg), ext::sxth); 12277 %} 12278 ins_pipe(ialu_reg_reg); 12279 %} 12280 12281 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12282 %{ 12283 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12284 ins_cost(INSN_COST); 12285 format %{ "add $dst, $src1, $src2, sxtw" %} 12286 12287 ins_encode %{ 12288 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12289 as_Register($src2$$reg), ext::sxtw); 12290 %} 12291 ins_pipe(ialu_reg_reg); 12292 %} 12293 12294 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12295 %{ 12296 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12297 ins_cost(INSN_COST); 12298 format %{ "add $dst, $src1, $src2, sxtb" %} 12299 12300 ins_encode %{ 12301 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12302 as_Register($src2$$reg), ext::sxtb); 12303 %} 12304 ins_pipe(ialu_reg_reg); 12305 %} 12306 12307 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12308 %{ 12309 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12310 ins_cost(INSN_COST); 12311 format %{ "add $dst, $src1, $src2, uxtb" %} 12312 12313 ins_encode %{ 12314 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12315 as_Register($src2$$reg), ext::uxtb); 12316 %} 12317 ins_pipe(ialu_reg_reg); 12318 %} 12319 12320 12321 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12322 %{ 12323 match(Set dst (AddI src1 (AndI src2 mask))); 12324 ins_cost(INSN_COST); 12325 format %{ "addw $dst, $src1, $src2, uxtb" %} 12326 12327 ins_encode %{ 12328 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12329 as_Register($src2$$reg), ext::uxtb); 12330 %} 12331 ins_pipe(ialu_reg_reg); 12332 %} 12333 12334 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12335 %{ 12336 match(Set dst (AddI src1 (AndI src2 mask))); 12337 ins_cost(INSN_COST); 12338 format %{ "addw $dst, $src1, $src2, uxth" %} 12339 12340 ins_encode %{ 12341 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12342 as_Register($src2$$reg), ext::uxth); 12343 %} 12344 ins_pipe(ialu_reg_reg); 12345 %} 12346 12347 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12348 %{ 12349 match(Set dst (AddL src1 (AndL src2 mask))); 12350 ins_cost(INSN_COST); 12351 format %{ "add $dst, $src1, $src2, uxtb" %} 12352 12353 ins_encode %{ 12354 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12355 as_Register($src2$$reg), ext::uxtb); 12356 %} 12357 ins_pipe(ialu_reg_reg); 12358 %} 12359 12360 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12361 %{ 12362 match(Set dst (AddL src1 (AndL src2 mask))); 12363 ins_cost(INSN_COST); 12364 format %{ "add $dst, $src1, $src2, uxth" %} 12365 12366 ins_encode %{ 12367 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12368 as_Register($src2$$reg), ext::uxth); 12369 %} 12370 ins_pipe(ialu_reg_reg); 12371 %} 12372 12373 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12374 %{ 12375 match(Set dst (AddL src1 (AndL src2 mask))); 12376 ins_cost(INSN_COST); 12377 format %{ "add $dst, $src1, $src2, uxtw" %} 12378 12379 ins_encode %{ 12380 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12381 as_Register($src2$$reg), ext::uxtw); 12382 %} 12383 ins_pipe(ialu_reg_reg); 12384 %} 12385 12386 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12387 %{ 12388 match(Set dst (SubI src1 (AndI src2 mask))); 12389 ins_cost(INSN_COST); 12390 format %{ "subw $dst, $src1, $src2, uxtb" %} 12391 12392 ins_encode %{ 12393 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12394 as_Register($src2$$reg), ext::uxtb); 12395 %} 12396 ins_pipe(ialu_reg_reg); 12397 %} 12398 12399 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12400 %{ 12401 match(Set dst (SubI src1 (AndI src2 mask))); 12402 ins_cost(INSN_COST); 12403 format %{ "subw $dst, $src1, $src2, uxth" %} 12404 12405 ins_encode %{ 12406 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12407 as_Register($src2$$reg), ext::uxth); 12408 %} 12409 ins_pipe(ialu_reg_reg); 12410 %} 12411 12412 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12413 %{ 12414 match(Set dst (SubL src1 (AndL src2 mask))); 12415 ins_cost(INSN_COST); 12416 format %{ "sub $dst, $src1, $src2, uxtb" %} 12417 12418 ins_encode %{ 12419 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12420 as_Register($src2$$reg), ext::uxtb); 12421 %} 12422 ins_pipe(ialu_reg_reg); 12423 %} 12424 12425 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12426 %{ 12427 match(Set dst (SubL src1 (AndL src2 mask))); 12428 ins_cost(INSN_COST); 12429 format %{ "sub $dst, $src1, $src2, uxth" %} 12430 12431 ins_encode %{ 12432 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12433 as_Register($src2$$reg), ext::uxth); 12434 %} 12435 ins_pipe(ialu_reg_reg); 12436 %} 12437 12438 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12439 %{ 12440 match(Set dst (SubL src1 (AndL src2 mask))); 12441 ins_cost(INSN_COST); 12442 format %{ "sub $dst, $src1, $src2, uxtw" %} 12443 12444 ins_encode %{ 12445 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12446 as_Register($src2$$reg), ext::uxtw); 12447 %} 12448 ins_pipe(ialu_reg_reg); 12449 %} 12450 12451 12452 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12453 %{ 12454 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12455 ins_cost(1.9 * INSN_COST); 12456 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12457 12458 ins_encode %{ 12459 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12460 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12461 %} 12462 ins_pipe(ialu_reg_reg_shift); 12463 %} 12464 12465 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12466 %{ 12467 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12468 ins_cost(1.9 * INSN_COST); 12469 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12470 12471 ins_encode %{ 12472 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12473 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12474 %} 12475 ins_pipe(ialu_reg_reg_shift); 12476 %} 12477 12478 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12479 %{ 12480 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12481 ins_cost(1.9 * INSN_COST); 12482 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12483 12484 ins_encode %{ 12485 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12486 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12487 %} 12488 ins_pipe(ialu_reg_reg_shift); 12489 %} 12490 12491 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12492 %{ 12493 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12494 ins_cost(1.9 * INSN_COST); 12495 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12496 12497 ins_encode %{ 12498 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12499 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12500 %} 12501 ins_pipe(ialu_reg_reg_shift); 12502 %} 12503 12504 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12505 %{ 12506 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12507 ins_cost(1.9 * INSN_COST); 12508 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12509 12510 ins_encode %{ 12511 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12512 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12513 %} 12514 ins_pipe(ialu_reg_reg_shift); 12515 %} 12516 12517 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12518 %{ 12519 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12520 ins_cost(1.9 * INSN_COST); 12521 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12522 12523 ins_encode %{ 12524 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12525 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12526 %} 12527 ins_pipe(ialu_reg_reg_shift); 12528 %} 12529 12530 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12531 %{ 12532 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12533 ins_cost(1.9 * INSN_COST); 12534 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12535 12536 ins_encode %{ 12537 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12538 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12539 %} 12540 ins_pipe(ialu_reg_reg_shift); 12541 %} 12542 12543 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12544 %{ 12545 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12546 ins_cost(1.9 * INSN_COST); 12547 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12548 12549 ins_encode %{ 12550 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12551 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12552 %} 12553 ins_pipe(ialu_reg_reg_shift); 12554 %} 12555 12556 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12557 %{ 12558 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12559 ins_cost(1.9 * INSN_COST); 12560 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12561 12562 ins_encode %{ 12563 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12564 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12565 %} 12566 ins_pipe(ialu_reg_reg_shift); 12567 %} 12568 12569 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12570 %{ 12571 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12572 ins_cost(1.9 * INSN_COST); 12573 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12574 12575 ins_encode %{ 12576 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12577 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12578 %} 12579 ins_pipe(ialu_reg_reg_shift); 12580 %} 12581 12582 12583 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12584 %{ 12585 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12586 ins_cost(1.9 * INSN_COST); 12587 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12588 12589 ins_encode %{ 12590 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12591 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12592 %} 12593 ins_pipe(ialu_reg_reg_shift); 12594 %}; 12595 12596 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12597 %{ 12598 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12599 ins_cost(1.9 * INSN_COST); 12600 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12601 12602 ins_encode %{ 12603 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12604 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12605 %} 12606 ins_pipe(ialu_reg_reg_shift); 12607 %}; 12608 12609 12610 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12611 %{ 12612 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12613 ins_cost(1.9 * INSN_COST); 12614 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12615 12616 ins_encode %{ 12617 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12618 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12619 %} 12620 ins_pipe(ialu_reg_reg_shift); 12621 %} 12622 12623 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12624 %{ 12625 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12626 ins_cost(1.9 * INSN_COST); 12627 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12628 12629 ins_encode %{ 12630 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12631 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12632 %} 12633 ins_pipe(ialu_reg_reg_shift); 12634 %} 12635 12636 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12637 %{ 12638 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12639 ins_cost(1.9 * INSN_COST); 12640 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12641 12642 ins_encode %{ 12643 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12644 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12645 %} 12646 ins_pipe(ialu_reg_reg_shift); 12647 %} 12648 12649 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12650 %{ 12651 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12652 ins_cost(1.9 * INSN_COST); 12653 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12654 12655 ins_encode %{ 12656 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12657 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12658 %} 12659 ins_pipe(ialu_reg_reg_shift); 12660 %} 12661 12662 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12663 %{ 12664 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12665 ins_cost(1.9 * INSN_COST); 12666 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12667 12668 ins_encode %{ 12669 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12670 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12671 %} 12672 ins_pipe(ialu_reg_reg_shift); 12673 %} 12674 12675 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12676 %{ 12677 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12678 ins_cost(1.9 * INSN_COST); 12679 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12680 12681 ins_encode %{ 12682 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12683 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12684 %} 12685 ins_pipe(ialu_reg_reg_shift); 12686 %} 12687 12688 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12689 %{ 12690 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12691 ins_cost(1.9 * INSN_COST); 12692 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12693 12694 ins_encode %{ 12695 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12696 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12697 %} 12698 ins_pipe(ialu_reg_reg_shift); 12699 %} 12700 12701 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12702 %{ 12703 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12704 ins_cost(1.9 * INSN_COST); 12705 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12706 12707 ins_encode %{ 12708 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12709 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12710 %} 12711 ins_pipe(ialu_reg_reg_shift); 12712 %} 12713 12714 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12715 %{ 12716 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12717 ins_cost(1.9 * INSN_COST); 12718 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12719 12720 ins_encode %{ 12721 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12722 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12723 %} 12724 ins_pipe(ialu_reg_reg_shift); 12725 %} 12726 12727 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12728 %{ 12729 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12730 ins_cost(1.9 * INSN_COST); 12731 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12732 12733 ins_encode %{ 12734 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12735 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12736 %} 12737 ins_pipe(ialu_reg_reg_shift); 12738 %} 12739 // END This section of the file is automatically generated. Do not edit -------------- 12740 12741 // ============================================================================ 12742 // Floating Point Arithmetic Instructions 12743 12744 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12745 match(Set dst (AddF src1 src2)); 12746 12747 ins_cost(INSN_COST * 5); 12748 format %{ "fadds $dst, $src1, $src2" %} 12749 12750 ins_encode %{ 12751 __ fadds(as_FloatRegister($dst$$reg), 12752 as_FloatRegister($src1$$reg), 12753 as_FloatRegister($src2$$reg)); 12754 %} 12755 12756 ins_pipe(fp_dop_reg_reg_s); 12757 %} 12758 12759 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12760 match(Set dst (AddD src1 src2)); 12761 12762 ins_cost(INSN_COST * 5); 12763 format %{ "faddd $dst, $src1, $src2" %} 12764 12765 ins_encode %{ 12766 __ faddd(as_FloatRegister($dst$$reg), 12767 as_FloatRegister($src1$$reg), 12768 as_FloatRegister($src2$$reg)); 12769 %} 12770 12771 ins_pipe(fp_dop_reg_reg_d); 12772 %} 12773 12774 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12775 match(Set dst (SubF src1 src2)); 12776 12777 ins_cost(INSN_COST * 5); 12778 format %{ "fsubs $dst, $src1, $src2" %} 12779 12780 ins_encode %{ 12781 __ fsubs(as_FloatRegister($dst$$reg), 12782 as_FloatRegister($src1$$reg), 12783 as_FloatRegister($src2$$reg)); 12784 %} 12785 12786 ins_pipe(fp_dop_reg_reg_s); 12787 %} 12788 12789 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12790 match(Set dst (SubD src1 src2)); 12791 12792 ins_cost(INSN_COST * 5); 12793 format %{ "fsubd $dst, $src1, $src2" %} 12794 12795 ins_encode %{ 12796 __ fsubd(as_FloatRegister($dst$$reg), 12797 as_FloatRegister($src1$$reg), 12798 as_FloatRegister($src2$$reg)); 12799 %} 12800 12801 ins_pipe(fp_dop_reg_reg_d); 12802 %} 12803 12804 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12805 match(Set dst (MulF src1 src2)); 12806 12807 ins_cost(INSN_COST * 6); 12808 format %{ "fmuls $dst, $src1, $src2" %} 12809 12810 ins_encode %{ 12811 __ fmuls(as_FloatRegister($dst$$reg), 12812 as_FloatRegister($src1$$reg), 12813 as_FloatRegister($src2$$reg)); 12814 %} 12815 12816 ins_pipe(fp_dop_reg_reg_s); 12817 %} 12818 12819 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12820 match(Set dst (MulD src1 src2)); 12821 12822 ins_cost(INSN_COST * 6); 12823 format %{ "fmuld $dst, $src1, $src2" %} 12824 12825 ins_encode %{ 12826 __ fmuld(as_FloatRegister($dst$$reg), 12827 as_FloatRegister($src1$$reg), 12828 as_FloatRegister($src2$$reg)); 12829 %} 12830 12831 ins_pipe(fp_dop_reg_reg_d); 12832 %} 12833 12834 // src1 * src2 + src3 12835 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12836 predicate(UseFMA); 12837 match(Set dst (FmaF src3 (Binary src1 src2))); 12838 12839 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12840 12841 ins_encode %{ 12842 __ fmadds(as_FloatRegister($dst$$reg), 12843 as_FloatRegister($src1$$reg), 12844 as_FloatRegister($src2$$reg), 12845 as_FloatRegister($src3$$reg)); 12846 %} 12847 12848 ins_pipe(pipe_class_default); 12849 %} 12850 12851 // src1 * src2 + src3 12852 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12853 predicate(UseFMA); 12854 match(Set dst (FmaD src3 (Binary src1 src2))); 12855 12856 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12857 12858 ins_encode %{ 12859 __ fmaddd(as_FloatRegister($dst$$reg), 12860 as_FloatRegister($src1$$reg), 12861 as_FloatRegister($src2$$reg), 12862 as_FloatRegister($src3$$reg)); 12863 %} 12864 12865 ins_pipe(pipe_class_default); 12866 %} 12867 12868 // -src1 * src2 + src3 12869 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12870 predicate(UseFMA); 12871 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12872 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12873 12874 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12875 12876 ins_encode %{ 12877 __ fmsubs(as_FloatRegister($dst$$reg), 12878 as_FloatRegister($src1$$reg), 12879 as_FloatRegister($src2$$reg), 12880 as_FloatRegister($src3$$reg)); 12881 %} 12882 12883 ins_pipe(pipe_class_default); 12884 %} 12885 12886 // -src1 * src2 + src3 12887 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12888 predicate(UseFMA); 12889 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12890 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12891 12892 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12893 12894 ins_encode %{ 12895 __ fmsubd(as_FloatRegister($dst$$reg), 12896 as_FloatRegister($src1$$reg), 12897 as_FloatRegister($src2$$reg), 12898 as_FloatRegister($src3$$reg)); 12899 %} 12900 12901 ins_pipe(pipe_class_default); 12902 %} 12903 12904 // -src1 * src2 - src3 12905 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12906 predicate(UseFMA); 12907 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12908 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12909 12910 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12911 12912 ins_encode %{ 12913 __ fnmadds(as_FloatRegister($dst$$reg), 12914 as_FloatRegister($src1$$reg), 12915 as_FloatRegister($src2$$reg), 12916 as_FloatRegister($src3$$reg)); 12917 %} 12918 12919 ins_pipe(pipe_class_default); 12920 %} 12921 12922 // -src1 * src2 - src3 12923 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12924 predicate(UseFMA); 12925 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12926 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12927 12928 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12929 12930 ins_encode %{ 12931 __ fnmaddd(as_FloatRegister($dst$$reg), 12932 as_FloatRegister($src1$$reg), 12933 as_FloatRegister($src2$$reg), 12934 as_FloatRegister($src3$$reg)); 12935 %} 12936 12937 ins_pipe(pipe_class_default); 12938 %} 12939 12940 // src1 * src2 - src3 12941 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12942 predicate(UseFMA); 12943 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12944 12945 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12946 12947 ins_encode %{ 12948 __ fnmsubs(as_FloatRegister($dst$$reg), 12949 as_FloatRegister($src1$$reg), 12950 as_FloatRegister($src2$$reg), 12951 as_FloatRegister($src3$$reg)); 12952 %} 12953 12954 ins_pipe(pipe_class_default); 12955 %} 12956 12957 // src1 * src2 - src3 12958 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12959 predicate(UseFMA); 12960 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12961 12962 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12963 12964 ins_encode %{ 12965 // n.b. insn name should be fnmsubd 12966 __ fnmsub(as_FloatRegister($dst$$reg), 12967 as_FloatRegister($src1$$reg), 12968 as_FloatRegister($src2$$reg), 12969 as_FloatRegister($src3$$reg)); 12970 %} 12971 12972 ins_pipe(pipe_class_default); 12973 %} 12974 12975 12976 // Math.max(FF)F 12977 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12978 match(Set dst (MaxF src1 src2)); 12979 12980 format %{ "fmaxs $dst, $src1, $src2" %} 12981 ins_encode %{ 12982 __ fmaxs(as_FloatRegister($dst$$reg), 12983 as_FloatRegister($src1$$reg), 12984 as_FloatRegister($src2$$reg)); 12985 %} 12986 12987 ins_pipe(fp_dop_reg_reg_s); 12988 %} 12989 12990 // Math.min(FF)F 12991 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12992 match(Set dst (MinF src1 src2)); 12993 12994 format %{ "fmins $dst, $src1, $src2" %} 12995 ins_encode %{ 12996 __ fmins(as_FloatRegister($dst$$reg), 12997 as_FloatRegister($src1$$reg), 12998 as_FloatRegister($src2$$reg)); 12999 %} 13000 13001 ins_pipe(fp_dop_reg_reg_s); 13002 %} 13003 13004 // Math.max(DD)D 13005 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13006 match(Set dst (MaxD src1 src2)); 13007 13008 format %{ "fmaxd $dst, $src1, $src2" %} 13009 ins_encode %{ 13010 __ fmaxd(as_FloatRegister($dst$$reg), 13011 as_FloatRegister($src1$$reg), 13012 as_FloatRegister($src2$$reg)); 13013 %} 13014 13015 ins_pipe(fp_dop_reg_reg_d); 13016 %} 13017 13018 // Math.min(DD)D 13019 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13020 match(Set dst (MinD src1 src2)); 13021 13022 format %{ "fmind $dst, $src1, $src2" %} 13023 ins_encode %{ 13024 __ fmind(as_FloatRegister($dst$$reg), 13025 as_FloatRegister($src1$$reg), 13026 as_FloatRegister($src2$$reg)); 13027 %} 13028 13029 ins_pipe(fp_dop_reg_reg_d); 13030 %} 13031 13032 13033 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13034 match(Set dst (DivF src1 src2)); 13035 13036 ins_cost(INSN_COST * 18); 13037 format %{ "fdivs $dst, $src1, $src2" %} 13038 13039 ins_encode %{ 13040 __ fdivs(as_FloatRegister($dst$$reg), 13041 as_FloatRegister($src1$$reg), 13042 as_FloatRegister($src2$$reg)); 13043 %} 13044 13045 ins_pipe(fp_div_s); 13046 %} 13047 13048 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13049 match(Set dst (DivD src1 src2)); 13050 13051 ins_cost(INSN_COST * 32); 13052 format %{ "fdivd $dst, $src1, $src2" %} 13053 13054 ins_encode %{ 13055 __ fdivd(as_FloatRegister($dst$$reg), 13056 as_FloatRegister($src1$$reg), 13057 as_FloatRegister($src2$$reg)); 13058 %} 13059 13060 ins_pipe(fp_div_d); 13061 %} 13062 13063 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13064 match(Set dst (NegF src)); 13065 13066 ins_cost(INSN_COST * 3); 13067 format %{ "fneg $dst, $src" %} 13068 13069 ins_encode %{ 13070 __ fnegs(as_FloatRegister($dst$$reg), 13071 as_FloatRegister($src$$reg)); 13072 %} 13073 13074 ins_pipe(fp_uop_s); 13075 %} 13076 13077 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13078 match(Set dst (NegD src)); 13079 13080 ins_cost(INSN_COST * 3); 13081 format %{ "fnegd $dst, $src" %} 13082 13083 ins_encode %{ 13084 __ fnegd(as_FloatRegister($dst$$reg), 13085 as_FloatRegister($src$$reg)); 13086 %} 13087 13088 ins_pipe(fp_uop_d); 13089 %} 13090 13091 instruct absF_reg(vRegF dst, vRegF src) %{ 13092 match(Set dst (AbsF src)); 13093 13094 ins_cost(INSN_COST * 3); 13095 format %{ "fabss $dst, $src" %} 13096 ins_encode %{ 13097 __ fabss(as_FloatRegister($dst$$reg), 13098 as_FloatRegister($src$$reg)); 13099 %} 13100 13101 ins_pipe(fp_uop_s); 13102 %} 13103 13104 instruct absD_reg(vRegD dst, vRegD src) %{ 13105 match(Set dst (AbsD src)); 13106 13107 ins_cost(INSN_COST * 3); 13108 format %{ "fabsd $dst, $src" %} 13109 ins_encode %{ 13110 __ fabsd(as_FloatRegister($dst$$reg), 13111 as_FloatRegister($src$$reg)); 13112 %} 13113 13114 ins_pipe(fp_uop_d); 13115 %} 13116 13117 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13118 match(Set dst (SqrtD src)); 13119 13120 ins_cost(INSN_COST * 50); 13121 format %{ "fsqrtd $dst, $src" %} 13122 ins_encode %{ 13123 __ fsqrtd(as_FloatRegister($dst$$reg), 13124 as_FloatRegister($src$$reg)); 13125 %} 13126 13127 ins_pipe(fp_div_s); 13128 %} 13129 13130 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13131 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 13132 13133 ins_cost(INSN_COST * 50); 13134 format %{ "fsqrts $dst, $src" %} 13135 ins_encode %{ 13136 __ fsqrts(as_FloatRegister($dst$$reg), 13137 as_FloatRegister($src$$reg)); 13138 %} 13139 13140 ins_pipe(fp_div_d); 13141 %} 13142 13143 // ============================================================================ 13144 // Logical Instructions 13145 13146 // Integer Logical Instructions 13147 13148 // And Instructions 13149 13150 13151 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13152 match(Set dst (AndI src1 src2)); 13153 13154 format %{ "andw $dst, $src1, $src2\t# int" %} 13155 13156 ins_cost(INSN_COST); 13157 ins_encode %{ 13158 __ andw(as_Register($dst$$reg), 13159 as_Register($src1$$reg), 13160 as_Register($src2$$reg)); 13161 %} 13162 13163 ins_pipe(ialu_reg_reg); 13164 %} 13165 13166 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13167 match(Set dst (AndI src1 src2)); 13168 13169 format %{ "andsw $dst, $src1, $src2\t# int" %} 13170 13171 ins_cost(INSN_COST); 13172 ins_encode %{ 13173 __ andw(as_Register($dst$$reg), 13174 as_Register($src1$$reg), 13175 (unsigned long)($src2$$constant)); 13176 %} 13177 13178 ins_pipe(ialu_reg_imm); 13179 %} 13180 13181 // Or Instructions 13182 13183 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13184 match(Set dst (OrI src1 src2)); 13185 13186 format %{ "orrw $dst, $src1, $src2\t# int" %} 13187 13188 ins_cost(INSN_COST); 13189 ins_encode %{ 13190 __ orrw(as_Register($dst$$reg), 13191 as_Register($src1$$reg), 13192 as_Register($src2$$reg)); 13193 %} 13194 13195 ins_pipe(ialu_reg_reg); 13196 %} 13197 13198 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13199 match(Set dst (OrI src1 src2)); 13200 13201 format %{ "orrw $dst, $src1, $src2\t# int" %} 13202 13203 ins_cost(INSN_COST); 13204 ins_encode %{ 13205 __ orrw(as_Register($dst$$reg), 13206 as_Register($src1$$reg), 13207 (unsigned long)($src2$$constant)); 13208 %} 13209 13210 ins_pipe(ialu_reg_imm); 13211 %} 13212 13213 // Xor Instructions 13214 13215 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13216 match(Set dst (XorI src1 src2)); 13217 13218 format %{ "eorw $dst, $src1, $src2\t# int" %} 13219 13220 ins_cost(INSN_COST); 13221 ins_encode %{ 13222 __ eorw(as_Register($dst$$reg), 13223 as_Register($src1$$reg), 13224 as_Register($src2$$reg)); 13225 %} 13226 13227 ins_pipe(ialu_reg_reg); 13228 %} 13229 13230 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13231 match(Set dst (XorI src1 src2)); 13232 13233 format %{ "eorw $dst, $src1, $src2\t# int" %} 13234 13235 ins_cost(INSN_COST); 13236 ins_encode %{ 13237 __ eorw(as_Register($dst$$reg), 13238 as_Register($src1$$reg), 13239 (unsigned long)($src2$$constant)); 13240 %} 13241 13242 ins_pipe(ialu_reg_imm); 13243 %} 13244 13245 // Long Logical Instructions 13246 // TODO 13247 13248 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13249 match(Set dst (AndL src1 src2)); 13250 13251 format %{ "and $dst, $src1, $src2\t# int" %} 13252 13253 ins_cost(INSN_COST); 13254 ins_encode %{ 13255 __ andr(as_Register($dst$$reg), 13256 as_Register($src1$$reg), 13257 as_Register($src2$$reg)); 13258 %} 13259 13260 ins_pipe(ialu_reg_reg); 13261 %} 13262 13263 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13264 match(Set dst (AndL src1 src2)); 13265 13266 format %{ "and $dst, $src1, $src2\t# int" %} 13267 13268 ins_cost(INSN_COST); 13269 ins_encode %{ 13270 __ andr(as_Register($dst$$reg), 13271 as_Register($src1$$reg), 13272 (unsigned long)($src2$$constant)); 13273 %} 13274 13275 ins_pipe(ialu_reg_imm); 13276 %} 13277 13278 // Or Instructions 13279 13280 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13281 match(Set dst (OrL src1 src2)); 13282 13283 format %{ "orr $dst, $src1, $src2\t# int" %} 13284 13285 ins_cost(INSN_COST); 13286 ins_encode %{ 13287 __ orr(as_Register($dst$$reg), 13288 as_Register($src1$$reg), 13289 as_Register($src2$$reg)); 13290 %} 13291 13292 ins_pipe(ialu_reg_reg); 13293 %} 13294 13295 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13296 match(Set dst (OrL src1 src2)); 13297 13298 format %{ "orr $dst, $src1, $src2\t# int" %} 13299 13300 ins_cost(INSN_COST); 13301 ins_encode %{ 13302 __ orr(as_Register($dst$$reg), 13303 as_Register($src1$$reg), 13304 (unsigned long)($src2$$constant)); 13305 %} 13306 13307 ins_pipe(ialu_reg_imm); 13308 %} 13309 13310 // Xor Instructions 13311 13312 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13313 match(Set dst (XorL src1 src2)); 13314 13315 format %{ "eor $dst, $src1, $src2\t# int" %} 13316 13317 ins_cost(INSN_COST); 13318 ins_encode %{ 13319 __ eor(as_Register($dst$$reg), 13320 as_Register($src1$$reg), 13321 as_Register($src2$$reg)); 13322 %} 13323 13324 ins_pipe(ialu_reg_reg); 13325 %} 13326 13327 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13328 match(Set dst (XorL src1 src2)); 13329 13330 ins_cost(INSN_COST); 13331 format %{ "eor $dst, $src1, $src2\t# int" %} 13332 13333 ins_encode %{ 13334 __ eor(as_Register($dst$$reg), 13335 as_Register($src1$$reg), 13336 (unsigned long)($src2$$constant)); 13337 %} 13338 13339 ins_pipe(ialu_reg_imm); 13340 %} 13341 13342 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13343 %{ 13344 match(Set dst (ConvI2L src)); 13345 13346 ins_cost(INSN_COST); 13347 format %{ "sxtw $dst, $src\t# i2l" %} 13348 ins_encode %{ 13349 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13350 %} 13351 ins_pipe(ialu_reg_shift); 13352 %} 13353 13354 // this pattern occurs in bigmath arithmetic 13355 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13356 %{ 13357 match(Set dst (AndL (ConvI2L src) mask)); 13358 13359 ins_cost(INSN_COST); 13360 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13361 ins_encode %{ 13362 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13363 %} 13364 13365 ins_pipe(ialu_reg_shift); 13366 %} 13367 13368 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13369 match(Set dst (ConvL2I src)); 13370 13371 ins_cost(INSN_COST); 13372 format %{ "movw $dst, $src \t// l2i" %} 13373 13374 ins_encode %{ 13375 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13376 %} 13377 13378 ins_pipe(ialu_reg); 13379 %} 13380 13381 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13382 %{ 13383 match(Set dst (Conv2B src)); 13384 effect(KILL cr); 13385 13386 format %{ 13387 "cmpw $src, zr\n\t" 13388 "cset $dst, ne" 13389 %} 13390 13391 ins_encode %{ 13392 __ cmpw(as_Register($src$$reg), zr); 13393 __ cset(as_Register($dst$$reg), Assembler::NE); 13394 %} 13395 13396 ins_pipe(ialu_reg); 13397 %} 13398 13399 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13400 %{ 13401 match(Set dst (Conv2B src)); 13402 effect(KILL cr); 13403 13404 format %{ 13405 "cmp $src, zr\n\t" 13406 "cset $dst, ne" 13407 %} 13408 13409 ins_encode %{ 13410 __ cmp(as_Register($src$$reg), zr); 13411 __ cset(as_Register($dst$$reg), Assembler::NE); 13412 %} 13413 13414 ins_pipe(ialu_reg); 13415 %} 13416 13417 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13418 match(Set dst (ConvD2F src)); 13419 13420 ins_cost(INSN_COST * 5); 13421 format %{ "fcvtd $dst, $src \t// d2f" %} 13422 13423 ins_encode %{ 13424 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13425 %} 13426 13427 ins_pipe(fp_d2f); 13428 %} 13429 13430 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13431 match(Set dst (ConvF2D src)); 13432 13433 ins_cost(INSN_COST * 5); 13434 format %{ "fcvts $dst, $src \t// f2d" %} 13435 13436 ins_encode %{ 13437 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13438 %} 13439 13440 ins_pipe(fp_f2d); 13441 %} 13442 13443 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13444 match(Set dst (ConvF2I src)); 13445 13446 ins_cost(INSN_COST * 5); 13447 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13448 13449 ins_encode %{ 13450 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13451 %} 13452 13453 ins_pipe(fp_f2i); 13454 %} 13455 13456 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13457 match(Set dst (ConvF2L src)); 13458 13459 ins_cost(INSN_COST * 5); 13460 format %{ "fcvtzs $dst, $src \t// f2l" %} 13461 13462 ins_encode %{ 13463 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13464 %} 13465 13466 ins_pipe(fp_f2l); 13467 %} 13468 13469 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13470 match(Set dst (ConvI2F src)); 13471 13472 ins_cost(INSN_COST * 5); 13473 format %{ "scvtfws $dst, $src \t// i2f" %} 13474 13475 ins_encode %{ 13476 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13477 %} 13478 13479 ins_pipe(fp_i2f); 13480 %} 13481 13482 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13483 match(Set dst (ConvL2F src)); 13484 13485 ins_cost(INSN_COST * 5); 13486 format %{ "scvtfs $dst, $src \t// l2f" %} 13487 13488 ins_encode %{ 13489 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13490 %} 13491 13492 ins_pipe(fp_l2f); 13493 %} 13494 13495 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13496 match(Set dst (ConvD2I src)); 13497 13498 ins_cost(INSN_COST * 5); 13499 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13500 13501 ins_encode %{ 13502 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13503 %} 13504 13505 ins_pipe(fp_d2i); 13506 %} 13507 13508 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13509 match(Set dst (ConvD2L src)); 13510 13511 ins_cost(INSN_COST * 5); 13512 format %{ "fcvtzd $dst, $src \t// d2l" %} 13513 13514 ins_encode %{ 13515 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13516 %} 13517 13518 ins_pipe(fp_d2l); 13519 %} 13520 13521 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13522 match(Set dst (ConvI2D src)); 13523 13524 ins_cost(INSN_COST * 5); 13525 format %{ "scvtfwd $dst, $src \t// i2d" %} 13526 13527 ins_encode %{ 13528 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13529 %} 13530 13531 ins_pipe(fp_i2d); 13532 %} 13533 13534 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13535 match(Set dst (ConvL2D src)); 13536 13537 ins_cost(INSN_COST * 5); 13538 format %{ "scvtfd $dst, $src \t// l2d" %} 13539 13540 ins_encode %{ 13541 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13542 %} 13543 13544 ins_pipe(fp_l2d); 13545 %} 13546 13547 // stack <-> reg and reg <-> reg shuffles with no conversion 13548 13549 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13550 13551 match(Set dst (MoveF2I src)); 13552 13553 effect(DEF dst, USE src); 13554 13555 ins_cost(4 * INSN_COST); 13556 13557 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13558 13559 ins_encode %{ 13560 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13561 %} 13562 13563 ins_pipe(iload_reg_reg); 13564 13565 %} 13566 13567 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13568 13569 match(Set dst (MoveI2F src)); 13570 13571 effect(DEF dst, USE src); 13572 13573 ins_cost(4 * INSN_COST); 13574 13575 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13576 13577 ins_encode %{ 13578 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13579 %} 13580 13581 ins_pipe(pipe_class_memory); 13582 13583 %} 13584 13585 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13586 13587 match(Set dst (MoveD2L src)); 13588 13589 effect(DEF dst, USE src); 13590 13591 ins_cost(4 * INSN_COST); 13592 13593 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13594 13595 ins_encode %{ 13596 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13597 %} 13598 13599 ins_pipe(iload_reg_reg); 13600 13601 %} 13602 13603 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13604 13605 match(Set dst (MoveL2D src)); 13606 13607 effect(DEF dst, USE src); 13608 13609 ins_cost(4 * INSN_COST); 13610 13611 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13612 13613 ins_encode %{ 13614 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13615 %} 13616 13617 ins_pipe(pipe_class_memory); 13618 13619 %} 13620 13621 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13622 13623 match(Set dst (MoveF2I src)); 13624 13625 effect(DEF dst, USE src); 13626 13627 ins_cost(INSN_COST); 13628 13629 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13630 13631 ins_encode %{ 13632 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13633 %} 13634 13635 ins_pipe(pipe_class_memory); 13636 13637 %} 13638 13639 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13640 13641 match(Set dst (MoveI2F src)); 13642 13643 effect(DEF dst, USE src); 13644 13645 ins_cost(INSN_COST); 13646 13647 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13648 13649 ins_encode %{ 13650 __ strw($src$$Register, Address(sp, $dst$$disp)); 13651 %} 13652 13653 ins_pipe(istore_reg_reg); 13654 13655 %} 13656 13657 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13658 13659 match(Set dst (MoveD2L src)); 13660 13661 effect(DEF dst, USE src); 13662 13663 ins_cost(INSN_COST); 13664 13665 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13666 13667 ins_encode %{ 13668 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13669 %} 13670 13671 ins_pipe(pipe_class_memory); 13672 13673 %} 13674 13675 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13676 13677 match(Set dst (MoveL2D src)); 13678 13679 effect(DEF dst, USE src); 13680 13681 ins_cost(INSN_COST); 13682 13683 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13684 13685 ins_encode %{ 13686 __ str($src$$Register, Address(sp, $dst$$disp)); 13687 %} 13688 13689 ins_pipe(istore_reg_reg); 13690 13691 %} 13692 13693 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13694 13695 match(Set dst (MoveF2I src)); 13696 13697 effect(DEF dst, USE src); 13698 13699 ins_cost(INSN_COST); 13700 13701 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13702 13703 ins_encode %{ 13704 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13705 %} 13706 13707 ins_pipe(fp_f2i); 13708 13709 %} 13710 13711 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13712 13713 match(Set dst (MoveI2F src)); 13714 13715 effect(DEF dst, USE src); 13716 13717 ins_cost(INSN_COST); 13718 13719 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13720 13721 ins_encode %{ 13722 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13723 %} 13724 13725 ins_pipe(fp_i2f); 13726 13727 %} 13728 13729 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13730 13731 match(Set dst (MoveD2L src)); 13732 13733 effect(DEF dst, USE src); 13734 13735 ins_cost(INSN_COST); 13736 13737 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13738 13739 ins_encode %{ 13740 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13741 %} 13742 13743 ins_pipe(fp_d2l); 13744 13745 %} 13746 13747 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13748 13749 match(Set dst (MoveL2D src)); 13750 13751 effect(DEF dst, USE src); 13752 13753 ins_cost(INSN_COST); 13754 13755 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13756 13757 ins_encode %{ 13758 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13759 %} 13760 13761 ins_pipe(fp_l2d); 13762 13763 %} 13764 13765 // ============================================================================ 13766 // clearing of an array 13767 13768 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13769 %{ 13770 match(Set dummy (ClearArray cnt base)); 13771 effect(USE_KILL cnt, USE_KILL base); 13772 13773 ins_cost(4 * INSN_COST); 13774 format %{ "ClearArray $cnt, $base" %} 13775 13776 ins_encode %{ 13777 __ zero_words($base$$Register, $cnt$$Register); 13778 %} 13779 13780 ins_pipe(pipe_class_memory); 13781 %} 13782 13783 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13784 %{ 13785 predicate((u_int64_t)n->in(2)->get_long() 13786 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13787 match(Set dummy (ClearArray cnt base)); 13788 effect(USE_KILL base); 13789 13790 ins_cost(4 * INSN_COST); 13791 format %{ "ClearArray $cnt, $base" %} 13792 13793 ins_encode %{ 13794 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13795 %} 13796 13797 ins_pipe(pipe_class_memory); 13798 %} 13799 13800 // ============================================================================ 13801 // Overflow Math Instructions 13802 13803 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13804 %{ 13805 match(Set cr (OverflowAddI op1 op2)); 13806 13807 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13808 ins_cost(INSN_COST); 13809 ins_encode %{ 13810 __ cmnw($op1$$Register, $op2$$Register); 13811 %} 13812 13813 ins_pipe(icmp_reg_reg); 13814 %} 13815 13816 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13817 %{ 13818 match(Set cr (OverflowAddI op1 op2)); 13819 13820 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13821 ins_cost(INSN_COST); 13822 ins_encode %{ 13823 __ cmnw($op1$$Register, $op2$$constant); 13824 %} 13825 13826 ins_pipe(icmp_reg_imm); 13827 %} 13828 13829 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13830 %{ 13831 match(Set cr (OverflowAddL op1 op2)); 13832 13833 format %{ "cmn $op1, $op2\t# overflow check long" %} 13834 ins_cost(INSN_COST); 13835 ins_encode %{ 13836 __ cmn($op1$$Register, $op2$$Register); 13837 %} 13838 13839 ins_pipe(icmp_reg_reg); 13840 %} 13841 13842 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13843 %{ 13844 match(Set cr (OverflowAddL op1 op2)); 13845 13846 format %{ "cmn $op1, $op2\t# overflow check long" %} 13847 ins_cost(INSN_COST); 13848 ins_encode %{ 13849 __ cmn($op1$$Register, $op2$$constant); 13850 %} 13851 13852 ins_pipe(icmp_reg_imm); 13853 %} 13854 13855 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13856 %{ 13857 match(Set cr (OverflowSubI op1 op2)); 13858 13859 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13860 ins_cost(INSN_COST); 13861 ins_encode %{ 13862 __ cmpw($op1$$Register, $op2$$Register); 13863 %} 13864 13865 ins_pipe(icmp_reg_reg); 13866 %} 13867 13868 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13869 %{ 13870 match(Set cr (OverflowSubI op1 op2)); 13871 13872 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13873 ins_cost(INSN_COST); 13874 ins_encode %{ 13875 __ cmpw($op1$$Register, $op2$$constant); 13876 %} 13877 13878 ins_pipe(icmp_reg_imm); 13879 %} 13880 13881 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13882 %{ 13883 match(Set cr (OverflowSubL op1 op2)); 13884 13885 format %{ "cmp $op1, $op2\t# overflow check long" %} 13886 ins_cost(INSN_COST); 13887 ins_encode %{ 13888 __ cmp($op1$$Register, $op2$$Register); 13889 %} 13890 13891 ins_pipe(icmp_reg_reg); 13892 %} 13893 13894 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13895 %{ 13896 match(Set cr (OverflowSubL op1 op2)); 13897 13898 format %{ "cmp $op1, $op2\t# overflow check long" %} 13899 ins_cost(INSN_COST); 13900 ins_encode %{ 13901 __ subs(zr, $op1$$Register, $op2$$constant); 13902 %} 13903 13904 ins_pipe(icmp_reg_imm); 13905 %} 13906 13907 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13908 %{ 13909 match(Set cr (OverflowSubI zero op1)); 13910 13911 format %{ "cmpw zr, $op1\t# overflow check int" %} 13912 ins_cost(INSN_COST); 13913 ins_encode %{ 13914 __ cmpw(zr, $op1$$Register); 13915 %} 13916 13917 ins_pipe(icmp_reg_imm); 13918 %} 13919 13920 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13921 %{ 13922 match(Set cr (OverflowSubL zero op1)); 13923 13924 format %{ "cmp zr, $op1\t# overflow check long" %} 13925 ins_cost(INSN_COST); 13926 ins_encode %{ 13927 __ cmp(zr, $op1$$Register); 13928 %} 13929 13930 ins_pipe(icmp_reg_imm); 13931 %} 13932 13933 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13934 %{ 13935 match(Set cr (OverflowMulI op1 op2)); 13936 13937 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13938 "cmp rscratch1, rscratch1, sxtw\n\t" 13939 "movw rscratch1, #0x80000000\n\t" 13940 "cselw rscratch1, rscratch1, zr, NE\n\t" 13941 "cmpw rscratch1, #1" %} 13942 ins_cost(5 * INSN_COST); 13943 ins_encode %{ 13944 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13945 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13946 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13947 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13948 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13949 %} 13950 13951 ins_pipe(pipe_slow); 13952 %} 13953 13954 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13955 %{ 13956 match(If cmp (OverflowMulI op1 op2)); 13957 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13958 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13959 effect(USE labl, KILL cr); 13960 13961 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13962 "cmp rscratch1, rscratch1, sxtw\n\t" 13963 "b$cmp $labl" %} 13964 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13965 ins_encode %{ 13966 Label* L = $labl$$label; 13967 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13968 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13969 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13970 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13971 %} 13972 13973 ins_pipe(pipe_serial); 13974 %} 13975 13976 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13977 %{ 13978 match(Set cr (OverflowMulL op1 op2)); 13979 13980 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13981 "smulh rscratch2, $op1, $op2\n\t" 13982 "cmp rscratch2, rscratch1, ASR #63\n\t" 13983 "movw rscratch1, #0x80000000\n\t" 13984 "cselw rscratch1, rscratch1, zr, NE\n\t" 13985 "cmpw rscratch1, #1" %} 13986 ins_cost(6 * INSN_COST); 13987 ins_encode %{ 13988 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13989 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13990 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13991 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13992 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13993 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13994 %} 13995 13996 ins_pipe(pipe_slow); 13997 %} 13998 13999 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14000 %{ 14001 match(If cmp (OverflowMulL op1 op2)); 14002 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14003 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14004 effect(USE labl, KILL cr); 14005 14006 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14007 "smulh rscratch2, $op1, $op2\n\t" 14008 "cmp rscratch2, rscratch1, ASR #63\n\t" 14009 "b$cmp $labl" %} 14010 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14011 ins_encode %{ 14012 Label* L = $labl$$label; 14013 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14014 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14015 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14016 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14017 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14018 %} 14019 14020 ins_pipe(pipe_serial); 14021 %} 14022 14023 // ============================================================================ 14024 // Compare Instructions 14025 14026 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14027 %{ 14028 match(Set cr (CmpI op1 op2)); 14029 14030 effect(DEF cr, USE op1, USE op2); 14031 14032 ins_cost(INSN_COST); 14033 format %{ "cmpw $op1, $op2" %} 14034 14035 ins_encode(aarch64_enc_cmpw(op1, op2)); 14036 14037 ins_pipe(icmp_reg_reg); 14038 %} 14039 14040 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14041 %{ 14042 match(Set cr (CmpI op1 zero)); 14043 14044 effect(DEF cr, USE op1); 14045 14046 ins_cost(INSN_COST); 14047 format %{ "cmpw $op1, 0" %} 14048 14049 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14050 14051 ins_pipe(icmp_reg_imm); 14052 %} 14053 14054 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14055 %{ 14056 match(Set cr (CmpI op1 op2)); 14057 14058 effect(DEF cr, USE op1); 14059 14060 ins_cost(INSN_COST); 14061 format %{ "cmpw $op1, $op2" %} 14062 14063 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14064 14065 ins_pipe(icmp_reg_imm); 14066 %} 14067 14068 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14069 %{ 14070 match(Set cr (CmpI op1 op2)); 14071 14072 effect(DEF cr, USE op1); 14073 14074 ins_cost(INSN_COST * 2); 14075 format %{ "cmpw $op1, $op2" %} 14076 14077 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14078 14079 ins_pipe(icmp_reg_imm); 14080 %} 14081 14082 // Unsigned compare Instructions; really, same as signed compare 14083 // except it should only be used to feed an If or a CMovI which takes a 14084 // cmpOpU. 14085 14086 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14087 %{ 14088 match(Set cr (CmpU op1 op2)); 14089 14090 effect(DEF cr, USE op1, USE op2); 14091 14092 ins_cost(INSN_COST); 14093 format %{ "cmpw $op1, $op2\t# unsigned" %} 14094 14095 ins_encode(aarch64_enc_cmpw(op1, op2)); 14096 14097 ins_pipe(icmp_reg_reg); 14098 %} 14099 14100 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14101 %{ 14102 match(Set cr (CmpU op1 zero)); 14103 14104 effect(DEF cr, USE op1); 14105 14106 ins_cost(INSN_COST); 14107 format %{ "cmpw $op1, #0\t# unsigned" %} 14108 14109 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14110 14111 ins_pipe(icmp_reg_imm); 14112 %} 14113 14114 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14115 %{ 14116 match(Set cr (CmpU op1 op2)); 14117 14118 effect(DEF cr, USE op1); 14119 14120 ins_cost(INSN_COST); 14121 format %{ "cmpw $op1, $op2\t# unsigned" %} 14122 14123 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14124 14125 ins_pipe(icmp_reg_imm); 14126 %} 14127 14128 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14129 %{ 14130 match(Set cr (CmpU op1 op2)); 14131 14132 effect(DEF cr, USE op1); 14133 14134 ins_cost(INSN_COST * 2); 14135 format %{ "cmpw $op1, $op2\t# unsigned" %} 14136 14137 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14138 14139 ins_pipe(icmp_reg_imm); 14140 %} 14141 14142 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14143 %{ 14144 match(Set cr (CmpL op1 op2)); 14145 14146 effect(DEF cr, USE op1, USE op2); 14147 14148 ins_cost(INSN_COST); 14149 format %{ "cmp $op1, $op2" %} 14150 14151 ins_encode(aarch64_enc_cmp(op1, op2)); 14152 14153 ins_pipe(icmp_reg_reg); 14154 %} 14155 14156 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14157 %{ 14158 match(Set cr (CmpL op1 zero)); 14159 14160 effect(DEF cr, USE op1); 14161 14162 ins_cost(INSN_COST); 14163 format %{ "tst $op1" %} 14164 14165 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14166 14167 ins_pipe(icmp_reg_imm); 14168 %} 14169 14170 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14171 %{ 14172 match(Set cr (CmpL op1 op2)); 14173 14174 effect(DEF cr, USE op1); 14175 14176 ins_cost(INSN_COST); 14177 format %{ "cmp $op1, $op2" %} 14178 14179 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14180 14181 ins_pipe(icmp_reg_imm); 14182 %} 14183 14184 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14185 %{ 14186 match(Set cr (CmpL op1 op2)); 14187 14188 effect(DEF cr, USE op1); 14189 14190 ins_cost(INSN_COST * 2); 14191 format %{ "cmp $op1, $op2" %} 14192 14193 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14194 14195 ins_pipe(icmp_reg_imm); 14196 %} 14197 14198 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14199 %{ 14200 match(Set cr (CmpUL op1 op2)); 14201 14202 effect(DEF cr, USE op1, USE op2); 14203 14204 ins_cost(INSN_COST); 14205 format %{ "cmp $op1, $op2" %} 14206 14207 ins_encode(aarch64_enc_cmp(op1, op2)); 14208 14209 ins_pipe(icmp_reg_reg); 14210 %} 14211 14212 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14213 %{ 14214 match(Set cr (CmpUL op1 zero)); 14215 14216 effect(DEF cr, USE op1); 14217 14218 ins_cost(INSN_COST); 14219 format %{ "tst $op1" %} 14220 14221 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14222 14223 ins_pipe(icmp_reg_imm); 14224 %} 14225 14226 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14227 %{ 14228 match(Set cr (CmpUL op1 op2)); 14229 14230 effect(DEF cr, USE op1); 14231 14232 ins_cost(INSN_COST); 14233 format %{ "cmp $op1, $op2" %} 14234 14235 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14236 14237 ins_pipe(icmp_reg_imm); 14238 %} 14239 14240 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14241 %{ 14242 match(Set cr (CmpUL op1 op2)); 14243 14244 effect(DEF cr, USE op1); 14245 14246 ins_cost(INSN_COST * 2); 14247 format %{ "cmp $op1, $op2" %} 14248 14249 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14250 14251 ins_pipe(icmp_reg_imm); 14252 %} 14253 14254 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14255 %{ 14256 match(Set cr (CmpP op1 op2)); 14257 14258 effect(DEF cr, USE op1, USE op2); 14259 14260 ins_cost(INSN_COST); 14261 format %{ "cmp $op1, $op2\t // ptr" %} 14262 14263 ins_encode(aarch64_enc_cmpp(op1, op2)); 14264 14265 ins_pipe(icmp_reg_reg); 14266 %} 14267 14268 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14269 %{ 14270 match(Set cr (CmpN op1 op2)); 14271 14272 effect(DEF cr, USE op1, USE op2); 14273 14274 ins_cost(INSN_COST); 14275 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14276 14277 ins_encode(aarch64_enc_cmpn(op1, op2)); 14278 14279 ins_pipe(icmp_reg_reg); 14280 %} 14281 14282 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14283 %{ 14284 match(Set cr (CmpP op1 zero)); 14285 14286 effect(DEF cr, USE op1, USE zero); 14287 14288 ins_cost(INSN_COST); 14289 format %{ "cmp $op1, 0\t // ptr" %} 14290 14291 ins_encode(aarch64_enc_testp(op1)); 14292 14293 ins_pipe(icmp_reg_imm); 14294 %} 14295 14296 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14297 %{ 14298 match(Set cr (CmpN op1 zero)); 14299 14300 effect(DEF cr, USE op1, USE zero); 14301 14302 ins_cost(INSN_COST); 14303 format %{ "cmp $op1, 0\t // compressed ptr" %} 14304 14305 ins_encode(aarch64_enc_testn(op1)); 14306 14307 ins_pipe(icmp_reg_imm); 14308 %} 14309 14310 // FP comparisons 14311 // 14312 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14313 // using normal cmpOp. See declaration of rFlagsReg for details. 14314 14315 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14316 %{ 14317 match(Set cr (CmpF src1 src2)); 14318 14319 ins_cost(3 * INSN_COST); 14320 format %{ "fcmps $src1, $src2" %} 14321 14322 ins_encode %{ 14323 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14324 %} 14325 14326 ins_pipe(pipe_class_compare); 14327 %} 14328 14329 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14330 %{ 14331 match(Set cr (CmpF src1 src2)); 14332 14333 ins_cost(3 * INSN_COST); 14334 format %{ "fcmps $src1, 0.0" %} 14335 14336 ins_encode %{ 14337 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14338 %} 14339 14340 ins_pipe(pipe_class_compare); 14341 %} 14342 // FROM HERE 14343 14344 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14345 %{ 14346 match(Set cr (CmpD src1 src2)); 14347 14348 ins_cost(3 * INSN_COST); 14349 format %{ "fcmpd $src1, $src2" %} 14350 14351 ins_encode %{ 14352 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14353 %} 14354 14355 ins_pipe(pipe_class_compare); 14356 %} 14357 14358 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14359 %{ 14360 match(Set cr (CmpD src1 src2)); 14361 14362 ins_cost(3 * INSN_COST); 14363 format %{ "fcmpd $src1, 0.0" %} 14364 14365 ins_encode %{ 14366 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14367 %} 14368 14369 ins_pipe(pipe_class_compare); 14370 %} 14371 14372 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14373 %{ 14374 match(Set dst (CmpF3 src1 src2)); 14375 effect(KILL cr); 14376 14377 ins_cost(5 * INSN_COST); 14378 format %{ "fcmps $src1, $src2\n\t" 14379 "csinvw($dst, zr, zr, eq\n\t" 14380 "csnegw($dst, $dst, $dst, lt)" 14381 %} 14382 14383 ins_encode %{ 14384 Label done; 14385 FloatRegister s1 = as_FloatRegister($src1$$reg); 14386 FloatRegister s2 = as_FloatRegister($src2$$reg); 14387 Register d = as_Register($dst$$reg); 14388 __ fcmps(s1, s2); 14389 // installs 0 if EQ else -1 14390 __ csinvw(d, zr, zr, Assembler::EQ); 14391 // keeps -1 if less or unordered else installs 1 14392 __ csnegw(d, d, d, Assembler::LT); 14393 __ bind(done); 14394 %} 14395 14396 ins_pipe(pipe_class_default); 14397 14398 %} 14399 14400 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14401 %{ 14402 match(Set dst (CmpD3 src1 src2)); 14403 effect(KILL cr); 14404 14405 ins_cost(5 * INSN_COST); 14406 format %{ "fcmpd $src1, $src2\n\t" 14407 "csinvw($dst, zr, zr, eq\n\t" 14408 "csnegw($dst, $dst, $dst, lt)" 14409 %} 14410 14411 ins_encode %{ 14412 Label done; 14413 FloatRegister s1 = as_FloatRegister($src1$$reg); 14414 FloatRegister s2 = as_FloatRegister($src2$$reg); 14415 Register d = as_Register($dst$$reg); 14416 __ fcmpd(s1, s2); 14417 // installs 0 if EQ else -1 14418 __ csinvw(d, zr, zr, Assembler::EQ); 14419 // keeps -1 if less or unordered else installs 1 14420 __ csnegw(d, d, d, Assembler::LT); 14421 __ bind(done); 14422 %} 14423 ins_pipe(pipe_class_default); 14424 14425 %} 14426 14427 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14428 %{ 14429 match(Set dst (CmpF3 src1 zero)); 14430 effect(KILL cr); 14431 14432 ins_cost(5 * INSN_COST); 14433 format %{ "fcmps $src1, 0.0\n\t" 14434 "csinvw($dst, zr, zr, eq\n\t" 14435 "csnegw($dst, $dst, $dst, lt)" 14436 %} 14437 14438 ins_encode %{ 14439 Label done; 14440 FloatRegister s1 = as_FloatRegister($src1$$reg); 14441 Register d = as_Register($dst$$reg); 14442 __ fcmps(s1, 0.0); 14443 // installs 0 if EQ else -1 14444 __ csinvw(d, zr, zr, Assembler::EQ); 14445 // keeps -1 if less or unordered else installs 1 14446 __ csnegw(d, d, d, Assembler::LT); 14447 __ bind(done); 14448 %} 14449 14450 ins_pipe(pipe_class_default); 14451 14452 %} 14453 14454 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14455 %{ 14456 match(Set dst (CmpD3 src1 zero)); 14457 effect(KILL cr); 14458 14459 ins_cost(5 * INSN_COST); 14460 format %{ "fcmpd $src1, 0.0\n\t" 14461 "csinvw($dst, zr, zr, eq\n\t" 14462 "csnegw($dst, $dst, $dst, lt)" 14463 %} 14464 14465 ins_encode %{ 14466 Label done; 14467 FloatRegister s1 = as_FloatRegister($src1$$reg); 14468 Register d = as_Register($dst$$reg); 14469 __ fcmpd(s1, 0.0); 14470 // installs 0 if EQ else -1 14471 __ csinvw(d, zr, zr, Assembler::EQ); 14472 // keeps -1 if less or unordered else installs 1 14473 __ csnegw(d, d, d, Assembler::LT); 14474 __ bind(done); 14475 %} 14476 ins_pipe(pipe_class_default); 14477 14478 %} 14479 14480 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14481 %{ 14482 match(Set dst (CmpLTMask p q)); 14483 effect(KILL cr); 14484 14485 ins_cost(3 * INSN_COST); 14486 14487 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14488 "csetw $dst, lt\n\t" 14489 "subw $dst, zr, $dst" 14490 %} 14491 14492 ins_encode %{ 14493 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14494 __ csetw(as_Register($dst$$reg), Assembler::LT); 14495 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14496 %} 14497 14498 ins_pipe(ialu_reg_reg); 14499 %} 14500 14501 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14502 %{ 14503 match(Set dst (CmpLTMask src zero)); 14504 effect(KILL cr); 14505 14506 ins_cost(INSN_COST); 14507 14508 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14509 14510 ins_encode %{ 14511 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14512 %} 14513 14514 ins_pipe(ialu_reg_shift); 14515 %} 14516 14517 // ============================================================================ 14518 // Max and Min 14519 14520 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14521 %{ 14522 effect( DEF dst, USE src1, USE src2, USE cr ); 14523 14524 ins_cost(INSN_COST * 2); 14525 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14526 14527 ins_encode %{ 14528 __ cselw(as_Register($dst$$reg), 14529 as_Register($src1$$reg), 14530 as_Register($src2$$reg), 14531 Assembler::LT); 14532 %} 14533 14534 ins_pipe(icond_reg_reg); 14535 %} 14536 14537 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14538 %{ 14539 match(Set dst (MinI src1 src2)); 14540 ins_cost(INSN_COST * 3); 14541 14542 expand %{ 14543 rFlagsReg cr; 14544 compI_reg_reg(cr, src1, src2); 14545 cmovI_reg_reg_lt(dst, src1, src2, cr); 14546 %} 14547 14548 %} 14549 // FROM HERE 14550 14551 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14552 %{ 14553 effect( DEF dst, USE src1, USE src2, USE cr ); 14554 14555 ins_cost(INSN_COST * 2); 14556 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14557 14558 ins_encode %{ 14559 __ cselw(as_Register($dst$$reg), 14560 as_Register($src1$$reg), 14561 as_Register($src2$$reg), 14562 Assembler::GT); 14563 %} 14564 14565 ins_pipe(icond_reg_reg); 14566 %} 14567 14568 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14569 %{ 14570 match(Set dst (MaxI src1 src2)); 14571 ins_cost(INSN_COST * 3); 14572 expand %{ 14573 rFlagsReg cr; 14574 compI_reg_reg(cr, src1, src2); 14575 cmovI_reg_reg_gt(dst, src1, src2, cr); 14576 %} 14577 %} 14578 14579 // ============================================================================ 14580 // Branch Instructions 14581 14582 // Direct Branch. 14583 instruct branch(label lbl) 14584 %{ 14585 match(Goto); 14586 14587 effect(USE lbl); 14588 14589 ins_cost(BRANCH_COST); 14590 format %{ "b $lbl" %} 14591 14592 ins_encode(aarch64_enc_b(lbl)); 14593 14594 ins_pipe(pipe_branch); 14595 %} 14596 14597 // Conditional Near Branch 14598 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14599 %{ 14600 // Same match rule as `branchConFar'. 14601 match(If cmp cr); 14602 14603 effect(USE lbl); 14604 14605 ins_cost(BRANCH_COST); 14606 // If set to 1 this indicates that the current instruction is a 14607 // short variant of a long branch. This avoids using this 14608 // instruction in first-pass matching. It will then only be used in 14609 // the `Shorten_branches' pass. 14610 // ins_short_branch(1); 14611 format %{ "b$cmp $lbl" %} 14612 14613 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14614 14615 ins_pipe(pipe_branch_cond); 14616 %} 14617 14618 // Conditional Near Branch Unsigned 14619 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14620 %{ 14621 // Same match rule as `branchConFar'. 14622 match(If cmp cr); 14623 14624 effect(USE lbl); 14625 14626 ins_cost(BRANCH_COST); 14627 // If set to 1 this indicates that the current instruction is a 14628 // short variant of a long branch. This avoids using this 14629 // instruction in first-pass matching. It will then only be used in 14630 // the `Shorten_branches' pass. 14631 // ins_short_branch(1); 14632 format %{ "b$cmp $lbl\t# unsigned" %} 14633 14634 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14635 14636 ins_pipe(pipe_branch_cond); 14637 %} 14638 14639 // Make use of CBZ and CBNZ. These instructions, as well as being 14640 // shorter than (cmp; branch), have the additional benefit of not 14641 // killing the flags. 14642 14643 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14644 match(If cmp (CmpI op1 op2)); 14645 effect(USE labl); 14646 14647 ins_cost(BRANCH_COST); 14648 format %{ "cbw$cmp $op1, $labl" %} 14649 ins_encode %{ 14650 Label* L = $labl$$label; 14651 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14652 if (cond == Assembler::EQ) 14653 __ cbzw($op1$$Register, *L); 14654 else 14655 __ cbnzw($op1$$Register, *L); 14656 %} 14657 ins_pipe(pipe_cmp_branch); 14658 %} 14659 14660 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14661 match(If cmp (CmpL op1 op2)); 14662 effect(USE labl); 14663 14664 ins_cost(BRANCH_COST); 14665 format %{ "cb$cmp $op1, $labl" %} 14666 ins_encode %{ 14667 Label* L = $labl$$label; 14668 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14669 if (cond == Assembler::EQ) 14670 __ cbz($op1$$Register, *L); 14671 else 14672 __ cbnz($op1$$Register, *L); 14673 %} 14674 ins_pipe(pipe_cmp_branch); 14675 %} 14676 14677 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14678 match(If cmp (CmpP op1 op2)); 14679 effect(USE labl); 14680 14681 ins_cost(BRANCH_COST); 14682 format %{ "cb$cmp $op1, $labl" %} 14683 ins_encode %{ 14684 Label* L = $labl$$label; 14685 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14686 if (cond == Assembler::EQ) 14687 __ cbz($op1$$Register, *L); 14688 else 14689 __ cbnz($op1$$Register, *L); 14690 %} 14691 ins_pipe(pipe_cmp_branch); 14692 %} 14693 14694 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14695 match(If cmp (CmpN op1 op2)); 14696 effect(USE labl); 14697 14698 ins_cost(BRANCH_COST); 14699 format %{ "cbw$cmp $op1, $labl" %} 14700 ins_encode %{ 14701 Label* L = $labl$$label; 14702 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14703 if (cond == Assembler::EQ) 14704 __ cbzw($op1$$Register, *L); 14705 else 14706 __ cbnzw($op1$$Register, *L); 14707 %} 14708 ins_pipe(pipe_cmp_branch); 14709 %} 14710 14711 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14712 match(If cmp (CmpP (DecodeN oop) zero)); 14713 effect(USE labl); 14714 14715 ins_cost(BRANCH_COST); 14716 format %{ "cb$cmp $oop, $labl" %} 14717 ins_encode %{ 14718 Label* L = $labl$$label; 14719 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14720 if (cond == Assembler::EQ) 14721 __ cbzw($oop$$Register, *L); 14722 else 14723 __ cbnzw($oop$$Register, *L); 14724 %} 14725 ins_pipe(pipe_cmp_branch); 14726 %} 14727 14728 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14729 match(If cmp (CmpU op1 op2)); 14730 effect(USE labl); 14731 14732 ins_cost(BRANCH_COST); 14733 format %{ "cbw$cmp $op1, $labl" %} 14734 ins_encode %{ 14735 Label* L = $labl$$label; 14736 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14737 if (cond == Assembler::EQ || cond == Assembler::LS) 14738 __ cbzw($op1$$Register, *L); 14739 else 14740 __ cbnzw($op1$$Register, *L); 14741 %} 14742 ins_pipe(pipe_cmp_branch); 14743 %} 14744 14745 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14746 match(If cmp (CmpUL op1 op2)); 14747 effect(USE labl); 14748 14749 ins_cost(BRANCH_COST); 14750 format %{ "cb$cmp $op1, $labl" %} 14751 ins_encode %{ 14752 Label* L = $labl$$label; 14753 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14754 if (cond == Assembler::EQ || cond == Assembler::LS) 14755 __ cbz($op1$$Register, *L); 14756 else 14757 __ cbnz($op1$$Register, *L); 14758 %} 14759 ins_pipe(pipe_cmp_branch); 14760 %} 14761 14762 // Test bit and Branch 14763 14764 // Patterns for short (< 32KiB) variants 14765 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14766 match(If cmp (CmpL op1 op2)); 14767 effect(USE labl); 14768 14769 ins_cost(BRANCH_COST); 14770 format %{ "cb$cmp $op1, $labl # long" %} 14771 ins_encode %{ 14772 Label* L = $labl$$label; 14773 Assembler::Condition cond = 14774 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14775 __ tbr(cond, $op1$$Register, 63, *L); 14776 %} 14777 ins_pipe(pipe_cmp_branch); 14778 ins_short_branch(1); 14779 %} 14780 14781 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14782 match(If cmp (CmpI op1 op2)); 14783 effect(USE labl); 14784 14785 ins_cost(BRANCH_COST); 14786 format %{ "cb$cmp $op1, $labl # int" %} 14787 ins_encode %{ 14788 Label* L = $labl$$label; 14789 Assembler::Condition cond = 14790 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14791 __ tbr(cond, $op1$$Register, 31, *L); 14792 %} 14793 ins_pipe(pipe_cmp_branch); 14794 ins_short_branch(1); 14795 %} 14796 14797 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14798 match(If cmp (CmpL (AndL op1 op2) op3)); 14799 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14800 effect(USE labl); 14801 14802 ins_cost(BRANCH_COST); 14803 format %{ "tb$cmp $op1, $op2, $labl" %} 14804 ins_encode %{ 14805 Label* L = $labl$$label; 14806 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14807 int bit = exact_log2($op2$$constant); 14808 __ tbr(cond, $op1$$Register, bit, *L); 14809 %} 14810 ins_pipe(pipe_cmp_branch); 14811 ins_short_branch(1); 14812 %} 14813 14814 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14815 match(If cmp (CmpI (AndI op1 op2) op3)); 14816 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14817 effect(USE labl); 14818 14819 ins_cost(BRANCH_COST); 14820 format %{ "tb$cmp $op1, $op2, $labl" %} 14821 ins_encode %{ 14822 Label* L = $labl$$label; 14823 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14824 int bit = exact_log2($op2$$constant); 14825 __ tbr(cond, $op1$$Register, bit, *L); 14826 %} 14827 ins_pipe(pipe_cmp_branch); 14828 ins_short_branch(1); 14829 %} 14830 14831 // And far variants 14832 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14833 match(If cmp (CmpL op1 op2)); 14834 effect(USE labl); 14835 14836 ins_cost(BRANCH_COST); 14837 format %{ "cb$cmp $op1, $labl # long" %} 14838 ins_encode %{ 14839 Label* L = $labl$$label; 14840 Assembler::Condition cond = 14841 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14842 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14843 %} 14844 ins_pipe(pipe_cmp_branch); 14845 %} 14846 14847 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14848 match(If cmp (CmpI op1 op2)); 14849 effect(USE labl); 14850 14851 ins_cost(BRANCH_COST); 14852 format %{ "cb$cmp $op1, $labl # int" %} 14853 ins_encode %{ 14854 Label* L = $labl$$label; 14855 Assembler::Condition cond = 14856 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14857 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14858 %} 14859 ins_pipe(pipe_cmp_branch); 14860 %} 14861 14862 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14863 match(If cmp (CmpL (AndL op1 op2) op3)); 14864 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14865 effect(USE labl); 14866 14867 ins_cost(BRANCH_COST); 14868 format %{ "tb$cmp $op1, $op2, $labl" %} 14869 ins_encode %{ 14870 Label* L = $labl$$label; 14871 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14872 int bit = exact_log2($op2$$constant); 14873 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14874 %} 14875 ins_pipe(pipe_cmp_branch); 14876 %} 14877 14878 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14879 match(If cmp (CmpI (AndI op1 op2) op3)); 14880 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14881 effect(USE labl); 14882 14883 ins_cost(BRANCH_COST); 14884 format %{ "tb$cmp $op1, $op2, $labl" %} 14885 ins_encode %{ 14886 Label* L = $labl$$label; 14887 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14888 int bit = exact_log2($op2$$constant); 14889 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14890 %} 14891 ins_pipe(pipe_cmp_branch); 14892 %} 14893 14894 // Test bits 14895 14896 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14897 match(Set cr (CmpL (AndL op1 op2) op3)); 14898 predicate(Assembler::operand_valid_for_logical_immediate 14899 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14900 14901 ins_cost(INSN_COST); 14902 format %{ "tst $op1, $op2 # long" %} 14903 ins_encode %{ 14904 __ tst($op1$$Register, $op2$$constant); 14905 %} 14906 ins_pipe(ialu_reg_reg); 14907 %} 14908 14909 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14910 match(Set cr (CmpI (AndI op1 op2) op3)); 14911 predicate(Assembler::operand_valid_for_logical_immediate 14912 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14913 14914 ins_cost(INSN_COST); 14915 format %{ "tst $op1, $op2 # int" %} 14916 ins_encode %{ 14917 __ tstw($op1$$Register, $op2$$constant); 14918 %} 14919 ins_pipe(ialu_reg_reg); 14920 %} 14921 14922 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14923 match(Set cr (CmpL (AndL op1 op2) op3)); 14924 14925 ins_cost(INSN_COST); 14926 format %{ "tst $op1, $op2 # long" %} 14927 ins_encode %{ 14928 __ tst($op1$$Register, $op2$$Register); 14929 %} 14930 ins_pipe(ialu_reg_reg); 14931 %} 14932 14933 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14934 match(Set cr (CmpI (AndI op1 op2) op3)); 14935 14936 ins_cost(INSN_COST); 14937 format %{ "tstw $op1, $op2 # int" %} 14938 ins_encode %{ 14939 __ tstw($op1$$Register, $op2$$Register); 14940 %} 14941 ins_pipe(ialu_reg_reg); 14942 %} 14943 14944 14945 // Conditional Far Branch 14946 // Conditional Far Branch Unsigned 14947 // TODO: fixme 14948 14949 // counted loop end branch near 14950 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14951 %{ 14952 match(CountedLoopEnd cmp cr); 14953 14954 effect(USE lbl); 14955 14956 ins_cost(BRANCH_COST); 14957 // short variant. 14958 // ins_short_branch(1); 14959 format %{ "b$cmp $lbl \t// counted loop end" %} 14960 14961 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14962 14963 ins_pipe(pipe_branch); 14964 %} 14965 14966 // counted loop end branch near Unsigned 14967 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14968 %{ 14969 match(CountedLoopEnd cmp cr); 14970 14971 effect(USE lbl); 14972 14973 ins_cost(BRANCH_COST); 14974 // short variant. 14975 // ins_short_branch(1); 14976 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14977 14978 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14979 14980 ins_pipe(pipe_branch); 14981 %} 14982 14983 // counted loop end branch far 14984 // counted loop end branch far unsigned 14985 // TODO: fixme 14986 14987 // ============================================================================ 14988 // inlined locking and unlocking 14989 14990 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14991 %{ 14992 match(Set cr (FastLock object box)); 14993 effect(TEMP tmp, TEMP tmp2); 14994 14995 // TODO 14996 // identify correct cost 14997 ins_cost(5 * INSN_COST); 14998 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14999 15000 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15001 15002 ins_pipe(pipe_serial); 15003 %} 15004 15005 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15006 %{ 15007 match(Set cr (FastUnlock object box)); 15008 effect(TEMP tmp, TEMP tmp2); 15009 15010 ins_cost(5 * INSN_COST); 15011 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15012 15013 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15014 15015 ins_pipe(pipe_serial); 15016 %} 15017 15018 15019 // ============================================================================ 15020 // Safepoint Instructions 15021 15022 // TODO 15023 // provide a near and far version of this code 15024 15025 instruct safePoint(rFlagsReg cr, iRegP poll) 15026 %{ 15027 match(SafePoint poll); 15028 effect(KILL cr); 15029 15030 format %{ 15031 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15032 %} 15033 ins_encode %{ 15034 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15035 %} 15036 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15037 %} 15038 15039 15040 // ============================================================================ 15041 // Procedure Call/Return Instructions 15042 15043 // Call Java Static Instruction 15044 15045 instruct CallStaticJavaDirect(method meth) 15046 %{ 15047 match(CallStaticJava); 15048 15049 effect(USE meth); 15050 15051 ins_cost(CALL_COST); 15052 15053 format %{ "call,static $meth \t// ==> " %} 15054 15055 ins_encode( aarch64_enc_java_static_call(meth), 15056 aarch64_enc_call_epilog ); 15057 15058 ins_pipe(pipe_class_call); 15059 %} 15060 15061 // TO HERE 15062 15063 // Call Java Dynamic Instruction 15064 instruct CallDynamicJavaDirect(method meth) 15065 %{ 15066 match(CallDynamicJava); 15067 15068 effect(USE meth); 15069 15070 ins_cost(CALL_COST); 15071 15072 format %{ "CALL,dynamic $meth \t// ==> " %} 15073 15074 ins_encode( aarch64_enc_java_dynamic_call(meth), 15075 aarch64_enc_call_epilog ); 15076 15077 ins_pipe(pipe_class_call); 15078 %} 15079 15080 // Call Runtime Instruction 15081 15082 instruct CallRuntimeDirect(method meth) 15083 %{ 15084 match(CallRuntime); 15085 15086 effect(USE meth); 15087 15088 ins_cost(CALL_COST); 15089 15090 format %{ "CALL, runtime $meth" %} 15091 15092 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15093 15094 ins_pipe(pipe_class_call); 15095 %} 15096 15097 // Call Runtime Instruction 15098 15099 instruct CallLeafDirect(method meth) 15100 %{ 15101 match(CallLeaf); 15102 15103 effect(USE meth); 15104 15105 ins_cost(CALL_COST); 15106 15107 format %{ "CALL, runtime leaf $meth" %} 15108 15109 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15110 15111 ins_pipe(pipe_class_call); 15112 %} 15113 15114 // Call Runtime Instruction 15115 15116 instruct CallLeafNoFPDirect(method meth) 15117 %{ 15118 match(CallLeafNoFP); 15119 15120 effect(USE meth); 15121 15122 ins_cost(CALL_COST); 15123 15124 format %{ "CALL, runtime leaf nofp $meth" %} 15125 15126 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15127 15128 ins_pipe(pipe_class_call); 15129 %} 15130 15131 // Tail Call; Jump from runtime stub to Java code. 15132 // Also known as an 'interprocedural jump'. 15133 // Target of jump will eventually return to caller. 15134 // TailJump below removes the return address. 15135 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15136 %{ 15137 match(TailCall jump_target method_oop); 15138 15139 ins_cost(CALL_COST); 15140 15141 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15142 15143 ins_encode(aarch64_enc_tail_call(jump_target)); 15144 15145 ins_pipe(pipe_class_call); 15146 %} 15147 15148 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15149 %{ 15150 match(TailJump jump_target ex_oop); 15151 15152 ins_cost(CALL_COST); 15153 15154 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15155 15156 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15157 15158 ins_pipe(pipe_class_call); 15159 %} 15160 15161 // Create exception oop: created by stack-crawling runtime code. 15162 // Created exception is now available to this handler, and is setup 15163 // just prior to jumping to this handler. No code emitted. 15164 // TODO check 15165 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15166 instruct CreateException(iRegP_R0 ex_oop) 15167 %{ 15168 match(Set ex_oop (CreateEx)); 15169 15170 format %{ " -- \t// exception oop; no code emitted" %} 15171 15172 size(0); 15173 15174 ins_encode( /*empty*/ ); 15175 15176 ins_pipe(pipe_class_empty); 15177 %} 15178 15179 // Rethrow exception: The exception oop will come in the first 15180 // argument position. Then JUMP (not call) to the rethrow stub code. 15181 instruct RethrowException() %{ 15182 match(Rethrow); 15183 ins_cost(CALL_COST); 15184 15185 format %{ "b rethrow_stub" %} 15186 15187 ins_encode( aarch64_enc_rethrow() ); 15188 15189 ins_pipe(pipe_class_call); 15190 %} 15191 15192 15193 // Return Instruction 15194 // epilog node loads ret address into lr as part of frame pop 15195 instruct Ret() 15196 %{ 15197 match(Return); 15198 15199 format %{ "ret\t// return register" %} 15200 15201 ins_encode( aarch64_enc_ret() ); 15202 15203 ins_pipe(pipe_branch); 15204 %} 15205 15206 // Die now. 15207 instruct ShouldNotReachHere() %{ 15208 match(Halt); 15209 15210 ins_cost(CALL_COST); 15211 format %{ "ShouldNotReachHere" %} 15212 15213 ins_encode %{ 15214 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 15215 // return true 15216 __ dpcs1(0xdead + 1); 15217 %} 15218 15219 ins_pipe(pipe_class_default); 15220 %} 15221 15222 // ============================================================================ 15223 // Partial Subtype Check 15224 // 15225 // superklass array for an instance of the superklass. Set a hidden 15226 // internal cache on a hit (cache is checked with exposed code in 15227 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15228 // encoding ALSO sets flags. 15229 15230 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15231 %{ 15232 match(Set result (PartialSubtypeCheck sub super)); 15233 effect(KILL cr, KILL temp); 15234 15235 ins_cost(1100); // slightly larger than the next version 15236 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15237 15238 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15239 15240 opcode(0x1); // Force zero of result reg on hit 15241 15242 ins_pipe(pipe_class_memory); 15243 %} 15244 15245 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15246 %{ 15247 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15248 effect(KILL temp, KILL result); 15249 15250 ins_cost(1100); // slightly larger than the next version 15251 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15252 15253 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15254 15255 opcode(0x0); // Don't zero result reg on hit 15256 15257 ins_pipe(pipe_class_memory); 15258 %} 15259 15260 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15261 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15262 %{ 15263 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15264 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15265 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15266 15267 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15268 ins_encode %{ 15269 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15270 __ string_compare($str1$$Register, $str2$$Register, 15271 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15272 $tmp1$$Register, $tmp2$$Register, 15273 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15274 %} 15275 ins_pipe(pipe_class_memory); 15276 %} 15277 15278 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15279 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15280 %{ 15281 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15282 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15283 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15284 15285 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15286 ins_encode %{ 15287 __ string_compare($str1$$Register, $str2$$Register, 15288 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15289 $tmp1$$Register, $tmp2$$Register, 15290 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15291 %} 15292 ins_pipe(pipe_class_memory); 15293 %} 15294 15295 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15296 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15297 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15298 %{ 15299 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15300 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15301 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15302 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15303 15304 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15305 ins_encode %{ 15306 __ string_compare($str1$$Register, $str2$$Register, 15307 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15308 $tmp1$$Register, $tmp2$$Register, 15309 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15310 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15311 %} 15312 ins_pipe(pipe_class_memory); 15313 %} 15314 15315 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15316 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15317 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15318 %{ 15319 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15320 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15321 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15322 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15323 15324 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15325 ins_encode %{ 15326 __ string_compare($str1$$Register, $str2$$Register, 15327 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15328 $tmp1$$Register, $tmp2$$Register, 15329 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15330 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15331 %} 15332 ins_pipe(pipe_class_memory); 15333 %} 15334 15335 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15336 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15337 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15338 %{ 15339 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15340 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15341 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15342 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15343 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15344 15345 ins_encode %{ 15346 __ string_indexof($str1$$Register, $str2$$Register, 15347 $cnt1$$Register, $cnt2$$Register, 15348 $tmp1$$Register, $tmp2$$Register, 15349 $tmp3$$Register, $tmp4$$Register, 15350 $tmp5$$Register, $tmp6$$Register, 15351 -1, $result$$Register, StrIntrinsicNode::UU); 15352 %} 15353 ins_pipe(pipe_class_memory); 15354 %} 15355 15356 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15357 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15358 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15359 %{ 15360 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15361 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15362 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15363 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15364 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15365 15366 ins_encode %{ 15367 __ string_indexof($str1$$Register, $str2$$Register, 15368 $cnt1$$Register, $cnt2$$Register, 15369 $tmp1$$Register, $tmp2$$Register, 15370 $tmp3$$Register, $tmp4$$Register, 15371 $tmp5$$Register, $tmp6$$Register, 15372 -1, $result$$Register, StrIntrinsicNode::LL); 15373 %} 15374 ins_pipe(pipe_class_memory); 15375 %} 15376 15377 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15378 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15379 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15380 %{ 15381 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15382 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15383 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15384 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15385 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15386 15387 ins_encode %{ 15388 __ string_indexof($str1$$Register, $str2$$Register, 15389 $cnt1$$Register, $cnt2$$Register, 15390 $tmp1$$Register, $tmp2$$Register, 15391 $tmp3$$Register, $tmp4$$Register, 15392 $tmp5$$Register, $tmp6$$Register, 15393 -1, $result$$Register, StrIntrinsicNode::UL); 15394 %} 15395 ins_pipe(pipe_class_memory); 15396 %} 15397 15398 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15399 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15400 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15401 %{ 15402 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15403 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15404 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15405 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15406 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15407 15408 ins_encode %{ 15409 int icnt2 = (int)$int_cnt2$$constant; 15410 __ string_indexof($str1$$Register, $str2$$Register, 15411 $cnt1$$Register, zr, 15412 $tmp1$$Register, $tmp2$$Register, 15413 $tmp3$$Register, $tmp4$$Register, zr, zr, 15414 icnt2, $result$$Register, StrIntrinsicNode::UU); 15415 %} 15416 ins_pipe(pipe_class_memory); 15417 %} 15418 15419 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15420 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15421 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15422 %{ 15423 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15424 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15425 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15426 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15427 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15428 15429 ins_encode %{ 15430 int icnt2 = (int)$int_cnt2$$constant; 15431 __ string_indexof($str1$$Register, $str2$$Register, 15432 $cnt1$$Register, zr, 15433 $tmp1$$Register, $tmp2$$Register, 15434 $tmp3$$Register, $tmp4$$Register, zr, zr, 15435 icnt2, $result$$Register, StrIntrinsicNode::LL); 15436 %} 15437 ins_pipe(pipe_class_memory); 15438 %} 15439 15440 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15441 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15442 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15443 %{ 15444 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15445 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15446 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15447 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15448 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15449 15450 ins_encode %{ 15451 int icnt2 = (int)$int_cnt2$$constant; 15452 __ string_indexof($str1$$Register, $str2$$Register, 15453 $cnt1$$Register, zr, 15454 $tmp1$$Register, $tmp2$$Register, 15455 $tmp3$$Register, $tmp4$$Register, zr, zr, 15456 icnt2, $result$$Register, StrIntrinsicNode::UL); 15457 %} 15458 ins_pipe(pipe_class_memory); 15459 %} 15460 15461 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15462 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15463 iRegINoSp tmp3, rFlagsReg cr) 15464 %{ 15465 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15466 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15467 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15468 15469 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15470 15471 ins_encode %{ 15472 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15473 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15474 $tmp3$$Register); 15475 %} 15476 ins_pipe(pipe_class_memory); 15477 %} 15478 15479 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15480 iRegI_R0 result, rFlagsReg cr) 15481 %{ 15482 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15483 match(Set result (StrEquals (Binary str1 str2) cnt)); 15484 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15485 15486 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15487 ins_encode %{ 15488 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15489 __ string_equals($str1$$Register, $str2$$Register, 15490 $result$$Register, $cnt$$Register, 1); 15491 %} 15492 ins_pipe(pipe_class_memory); 15493 %} 15494 15495 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15496 iRegI_R0 result, rFlagsReg cr) 15497 %{ 15498 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15499 match(Set result (StrEquals (Binary str1 str2) cnt)); 15500 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15501 15502 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15503 ins_encode %{ 15504 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15505 __ string_equals($str1$$Register, $str2$$Register, 15506 $result$$Register, $cnt$$Register, 2); 15507 %} 15508 ins_pipe(pipe_class_memory); 15509 %} 15510 15511 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15512 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15513 iRegP_R10 tmp, rFlagsReg cr) 15514 %{ 15515 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15516 match(Set result (AryEq ary1 ary2)); 15517 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15518 15519 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15520 ins_encode %{ 15521 __ arrays_equals($ary1$$Register, $ary2$$Register, 15522 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15523 $result$$Register, $tmp$$Register, 1); 15524 %} 15525 ins_pipe(pipe_class_memory); 15526 %} 15527 15528 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15529 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15530 iRegP_R10 tmp, rFlagsReg cr) 15531 %{ 15532 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15533 match(Set result (AryEq ary1 ary2)); 15534 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15535 15536 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15537 ins_encode %{ 15538 __ arrays_equals($ary1$$Register, $ary2$$Register, 15539 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15540 $result$$Register, $tmp$$Register, 2); 15541 %} 15542 ins_pipe(pipe_class_memory); 15543 %} 15544 15545 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15546 %{ 15547 match(Set result (HasNegatives ary1 len)); 15548 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15549 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15550 ins_encode %{ 15551 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15552 %} 15553 ins_pipe( pipe_slow ); 15554 %} 15555 15556 // fast char[] to byte[] compression 15557 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15558 vRegD_V0 tmp1, vRegD_V1 tmp2, 15559 vRegD_V2 tmp3, vRegD_V3 tmp4, 15560 iRegI_R0 result, rFlagsReg cr) 15561 %{ 15562 match(Set result (StrCompressedCopy src (Binary dst len))); 15563 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15564 15565 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15566 ins_encode %{ 15567 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15568 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15569 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15570 $result$$Register); 15571 %} 15572 ins_pipe( pipe_slow ); 15573 %} 15574 15575 // fast byte[] to char[] inflation 15576 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15577 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15578 %{ 15579 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15580 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15581 15582 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15583 ins_encode %{ 15584 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15585 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15586 %} 15587 ins_pipe(pipe_class_memory); 15588 %} 15589 15590 // encode char[] to byte[] in ISO_8859_1 15591 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15592 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15593 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15594 iRegI_R0 result, rFlagsReg cr) 15595 %{ 15596 match(Set result (EncodeISOArray src (Binary dst len))); 15597 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15598 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15599 15600 format %{ "Encode array $src,$dst,$len -> $result" %} 15601 ins_encode %{ 15602 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15603 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15604 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15605 %} 15606 ins_pipe( pipe_class_memory ); 15607 %} 15608 15609 // ============================================================================ 15610 // This name is KNOWN by the ADLC and cannot be changed. 15611 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15612 // for this guy. 15613 instruct tlsLoadP(thread_RegP dst) 15614 %{ 15615 match(Set dst (ThreadLocal)); 15616 15617 ins_cost(0); 15618 15619 format %{ " -- \t// $dst=Thread::current(), empty" %} 15620 15621 size(0); 15622 15623 ins_encode( /*empty*/ ); 15624 15625 ins_pipe(pipe_class_empty); 15626 %} 15627 15628 // ====================VECTOR INSTRUCTIONS===================================== 15629 15630 // Load vector (32 bits) 15631 instruct loadV4(vecD dst, vmem4 mem) 15632 %{ 15633 predicate(n->as_LoadVector()->memory_size() == 4); 15634 match(Set dst (LoadVector mem)); 15635 ins_cost(4 * INSN_COST); 15636 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15637 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15638 ins_pipe(vload_reg_mem64); 15639 %} 15640 15641 // Load vector (64 bits) 15642 instruct loadV8(vecD dst, vmem8 mem) 15643 %{ 15644 predicate(n->as_LoadVector()->memory_size() == 8); 15645 match(Set dst (LoadVector mem)); 15646 ins_cost(4 * INSN_COST); 15647 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15648 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15649 ins_pipe(vload_reg_mem64); 15650 %} 15651 15652 // Load Vector (128 bits) 15653 instruct loadV16(vecX dst, vmem16 mem) 15654 %{ 15655 predicate(n->as_LoadVector()->memory_size() == 16); 15656 match(Set dst (LoadVector mem)); 15657 ins_cost(4 * INSN_COST); 15658 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15659 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15660 ins_pipe(vload_reg_mem128); 15661 %} 15662 15663 // Store Vector (32 bits) 15664 instruct storeV4(vecD src, vmem4 mem) 15665 %{ 15666 predicate(n->as_StoreVector()->memory_size() == 4); 15667 match(Set mem (StoreVector mem src)); 15668 ins_cost(4 * INSN_COST); 15669 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15670 ins_encode( aarch64_enc_strvS(src, mem) ); 15671 ins_pipe(vstore_reg_mem64); 15672 %} 15673 15674 // Store Vector (64 bits) 15675 instruct storeV8(vecD src, vmem8 mem) 15676 %{ 15677 predicate(n->as_StoreVector()->memory_size() == 8); 15678 match(Set mem (StoreVector mem src)); 15679 ins_cost(4 * INSN_COST); 15680 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15681 ins_encode( aarch64_enc_strvD(src, mem) ); 15682 ins_pipe(vstore_reg_mem64); 15683 %} 15684 15685 // Store Vector (128 bits) 15686 instruct storeV16(vecX src, vmem16 mem) 15687 %{ 15688 predicate(n->as_StoreVector()->memory_size() == 16); 15689 match(Set mem (StoreVector mem src)); 15690 ins_cost(4 * INSN_COST); 15691 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15692 ins_encode( aarch64_enc_strvQ(src, mem) ); 15693 ins_pipe(vstore_reg_mem128); 15694 %} 15695 15696 instruct replicate8B(vecD dst, iRegIorL2I src) 15697 %{ 15698 predicate(n->as_Vector()->length() == 4 || 15699 n->as_Vector()->length() == 8); 15700 match(Set dst (ReplicateB src)); 15701 ins_cost(INSN_COST); 15702 format %{ "dup $dst, $src\t# vector (8B)" %} 15703 ins_encode %{ 15704 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15705 %} 15706 ins_pipe(vdup_reg_reg64); 15707 %} 15708 15709 instruct replicate16B(vecX dst, iRegIorL2I src) 15710 %{ 15711 predicate(n->as_Vector()->length() == 16); 15712 match(Set dst (ReplicateB src)); 15713 ins_cost(INSN_COST); 15714 format %{ "dup $dst, $src\t# vector (16B)" %} 15715 ins_encode %{ 15716 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15717 %} 15718 ins_pipe(vdup_reg_reg128); 15719 %} 15720 15721 instruct replicate8B_imm(vecD dst, immI con) 15722 %{ 15723 predicate(n->as_Vector()->length() == 4 || 15724 n->as_Vector()->length() == 8); 15725 match(Set dst (ReplicateB con)); 15726 ins_cost(INSN_COST); 15727 format %{ "movi $dst, $con\t# vector(8B)" %} 15728 ins_encode %{ 15729 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15730 %} 15731 ins_pipe(vmovi_reg_imm64); 15732 %} 15733 15734 instruct replicate16B_imm(vecX dst, immI con) 15735 %{ 15736 predicate(n->as_Vector()->length() == 16); 15737 match(Set dst (ReplicateB con)); 15738 ins_cost(INSN_COST); 15739 format %{ "movi $dst, $con\t# vector(16B)" %} 15740 ins_encode %{ 15741 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15742 %} 15743 ins_pipe(vmovi_reg_imm128); 15744 %} 15745 15746 instruct replicate4S(vecD dst, iRegIorL2I src) 15747 %{ 15748 predicate(n->as_Vector()->length() == 2 || 15749 n->as_Vector()->length() == 4); 15750 match(Set dst (ReplicateS src)); 15751 ins_cost(INSN_COST); 15752 format %{ "dup $dst, $src\t# vector (4S)" %} 15753 ins_encode %{ 15754 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15755 %} 15756 ins_pipe(vdup_reg_reg64); 15757 %} 15758 15759 instruct replicate8S(vecX dst, iRegIorL2I src) 15760 %{ 15761 predicate(n->as_Vector()->length() == 8); 15762 match(Set dst (ReplicateS src)); 15763 ins_cost(INSN_COST); 15764 format %{ "dup $dst, $src\t# vector (8S)" %} 15765 ins_encode %{ 15766 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15767 %} 15768 ins_pipe(vdup_reg_reg128); 15769 %} 15770 15771 instruct replicate4S_imm(vecD dst, immI con) 15772 %{ 15773 predicate(n->as_Vector()->length() == 2 || 15774 n->as_Vector()->length() == 4); 15775 match(Set dst (ReplicateS con)); 15776 ins_cost(INSN_COST); 15777 format %{ "movi $dst, $con\t# vector(4H)" %} 15778 ins_encode %{ 15779 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15780 %} 15781 ins_pipe(vmovi_reg_imm64); 15782 %} 15783 15784 instruct replicate8S_imm(vecX dst, immI con) 15785 %{ 15786 predicate(n->as_Vector()->length() == 8); 15787 match(Set dst (ReplicateS con)); 15788 ins_cost(INSN_COST); 15789 format %{ "movi $dst, $con\t# vector(8H)" %} 15790 ins_encode %{ 15791 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15792 %} 15793 ins_pipe(vmovi_reg_imm128); 15794 %} 15795 15796 instruct replicate2I(vecD dst, iRegIorL2I src) 15797 %{ 15798 predicate(n->as_Vector()->length() == 2); 15799 match(Set dst (ReplicateI src)); 15800 ins_cost(INSN_COST); 15801 format %{ "dup $dst, $src\t# vector (2I)" %} 15802 ins_encode %{ 15803 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15804 %} 15805 ins_pipe(vdup_reg_reg64); 15806 %} 15807 15808 instruct replicate4I(vecX dst, iRegIorL2I src) 15809 %{ 15810 predicate(n->as_Vector()->length() == 4); 15811 match(Set dst (ReplicateI src)); 15812 ins_cost(INSN_COST); 15813 format %{ "dup $dst, $src\t# vector (4I)" %} 15814 ins_encode %{ 15815 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15816 %} 15817 ins_pipe(vdup_reg_reg128); 15818 %} 15819 15820 instruct replicate2I_imm(vecD dst, immI con) 15821 %{ 15822 predicate(n->as_Vector()->length() == 2); 15823 match(Set dst (ReplicateI con)); 15824 ins_cost(INSN_COST); 15825 format %{ "movi $dst, $con\t# vector(2I)" %} 15826 ins_encode %{ 15827 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15828 %} 15829 ins_pipe(vmovi_reg_imm64); 15830 %} 15831 15832 instruct replicate4I_imm(vecX dst, immI con) 15833 %{ 15834 predicate(n->as_Vector()->length() == 4); 15835 match(Set dst (ReplicateI con)); 15836 ins_cost(INSN_COST); 15837 format %{ "movi $dst, $con\t# vector(4I)" %} 15838 ins_encode %{ 15839 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15840 %} 15841 ins_pipe(vmovi_reg_imm128); 15842 %} 15843 15844 instruct replicate2L(vecX dst, iRegL src) 15845 %{ 15846 predicate(n->as_Vector()->length() == 2); 15847 match(Set dst (ReplicateL src)); 15848 ins_cost(INSN_COST); 15849 format %{ "dup $dst, $src\t# vector (2L)" %} 15850 ins_encode %{ 15851 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15852 %} 15853 ins_pipe(vdup_reg_reg128); 15854 %} 15855 15856 instruct replicate2L_zero(vecX dst, immI0 zero) 15857 %{ 15858 predicate(n->as_Vector()->length() == 2); 15859 match(Set dst (ReplicateI zero)); 15860 ins_cost(INSN_COST); 15861 format %{ "movi $dst, $zero\t# vector(4I)" %} 15862 ins_encode %{ 15863 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15864 as_FloatRegister($dst$$reg), 15865 as_FloatRegister($dst$$reg)); 15866 %} 15867 ins_pipe(vmovi_reg_imm128); 15868 %} 15869 15870 instruct replicate2F(vecD dst, vRegF src) 15871 %{ 15872 predicate(n->as_Vector()->length() == 2); 15873 match(Set dst (ReplicateF src)); 15874 ins_cost(INSN_COST); 15875 format %{ "dup $dst, $src\t# vector (2F)" %} 15876 ins_encode %{ 15877 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15878 as_FloatRegister($src$$reg)); 15879 %} 15880 ins_pipe(vdup_reg_freg64); 15881 %} 15882 15883 instruct replicate4F(vecX dst, vRegF src) 15884 %{ 15885 predicate(n->as_Vector()->length() == 4); 15886 match(Set dst (ReplicateF src)); 15887 ins_cost(INSN_COST); 15888 format %{ "dup $dst, $src\t# vector (4F)" %} 15889 ins_encode %{ 15890 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15891 as_FloatRegister($src$$reg)); 15892 %} 15893 ins_pipe(vdup_reg_freg128); 15894 %} 15895 15896 instruct replicate2D(vecX dst, vRegD src) 15897 %{ 15898 predicate(n->as_Vector()->length() == 2); 15899 match(Set dst (ReplicateD src)); 15900 ins_cost(INSN_COST); 15901 format %{ "dup $dst, $src\t# vector (2D)" %} 15902 ins_encode %{ 15903 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15904 as_FloatRegister($src$$reg)); 15905 %} 15906 ins_pipe(vdup_reg_dreg128); 15907 %} 15908 15909 // ====================REDUCTION ARITHMETIC==================================== 15910 15911 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15912 %{ 15913 match(Set dst (AddReductionVI src1 src2)); 15914 ins_cost(INSN_COST); 15915 effect(TEMP tmp, TEMP tmp2); 15916 format %{ "umov $tmp, $src2, S, 0\n\t" 15917 "umov $tmp2, $src2, S, 1\n\t" 15918 "addw $dst, $src1, $tmp\n\t" 15919 "addw $dst, $dst, $tmp2\t add reduction2i" 15920 %} 15921 ins_encode %{ 15922 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15923 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15924 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15925 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15926 %} 15927 ins_pipe(pipe_class_default); 15928 %} 15929 15930 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15931 %{ 15932 match(Set dst (AddReductionVI src1 src2)); 15933 ins_cost(INSN_COST); 15934 effect(TEMP tmp, TEMP tmp2); 15935 format %{ "addv $tmp, T4S, $src2\n\t" 15936 "umov $tmp2, $tmp, S, 0\n\t" 15937 "addw $dst, $tmp2, $src1\t add reduction4i" 15938 %} 15939 ins_encode %{ 15940 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15941 as_FloatRegister($src2$$reg)); 15942 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15943 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15944 %} 15945 ins_pipe(pipe_class_default); 15946 %} 15947 15948 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15949 %{ 15950 match(Set dst (MulReductionVI src1 src2)); 15951 ins_cost(INSN_COST); 15952 effect(TEMP tmp, TEMP dst); 15953 format %{ "umov $tmp, $src2, S, 0\n\t" 15954 "mul $dst, $tmp, $src1\n\t" 15955 "umov $tmp, $src2, S, 1\n\t" 15956 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15957 %} 15958 ins_encode %{ 15959 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15960 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15961 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15962 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15963 %} 15964 ins_pipe(pipe_class_default); 15965 %} 15966 15967 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15968 %{ 15969 match(Set dst (MulReductionVI src1 src2)); 15970 ins_cost(INSN_COST); 15971 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15972 format %{ "ins $tmp, $src2, 0, 1\n\t" 15973 "mul $tmp, $tmp, $src2\n\t" 15974 "umov $tmp2, $tmp, S, 0\n\t" 15975 "mul $dst, $tmp2, $src1\n\t" 15976 "umov $tmp2, $tmp, S, 1\n\t" 15977 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15978 %} 15979 ins_encode %{ 15980 __ ins(as_FloatRegister($tmp$$reg), __ D, 15981 as_FloatRegister($src2$$reg), 0, 1); 15982 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15983 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15984 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15985 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15986 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15987 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15988 %} 15989 ins_pipe(pipe_class_default); 15990 %} 15991 15992 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15993 %{ 15994 match(Set dst (AddReductionVF src1 src2)); 15995 ins_cost(INSN_COST); 15996 effect(TEMP tmp, TEMP dst); 15997 format %{ "fadds $dst, $src1, $src2\n\t" 15998 "ins $tmp, S, $src2, 0, 1\n\t" 15999 "fadds $dst, $dst, $tmp\t add reduction2f" 16000 %} 16001 ins_encode %{ 16002 __ fadds(as_FloatRegister($dst$$reg), 16003 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16004 __ ins(as_FloatRegister($tmp$$reg), __ S, 16005 as_FloatRegister($src2$$reg), 0, 1); 16006 __ fadds(as_FloatRegister($dst$$reg), 16007 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16008 %} 16009 ins_pipe(pipe_class_default); 16010 %} 16011 16012 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16013 %{ 16014 match(Set dst (AddReductionVF src1 src2)); 16015 ins_cost(INSN_COST); 16016 effect(TEMP tmp, TEMP dst); 16017 format %{ "fadds $dst, $src1, $src2\n\t" 16018 "ins $tmp, S, $src2, 0, 1\n\t" 16019 "fadds $dst, $dst, $tmp\n\t" 16020 "ins $tmp, S, $src2, 0, 2\n\t" 16021 "fadds $dst, $dst, $tmp\n\t" 16022 "ins $tmp, S, $src2, 0, 3\n\t" 16023 "fadds $dst, $dst, $tmp\t add reduction4f" 16024 %} 16025 ins_encode %{ 16026 __ fadds(as_FloatRegister($dst$$reg), 16027 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16028 __ ins(as_FloatRegister($tmp$$reg), __ S, 16029 as_FloatRegister($src2$$reg), 0, 1); 16030 __ fadds(as_FloatRegister($dst$$reg), 16031 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16032 __ ins(as_FloatRegister($tmp$$reg), __ S, 16033 as_FloatRegister($src2$$reg), 0, 2); 16034 __ fadds(as_FloatRegister($dst$$reg), 16035 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16036 __ ins(as_FloatRegister($tmp$$reg), __ S, 16037 as_FloatRegister($src2$$reg), 0, 3); 16038 __ fadds(as_FloatRegister($dst$$reg), 16039 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16040 %} 16041 ins_pipe(pipe_class_default); 16042 %} 16043 16044 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16045 %{ 16046 match(Set dst (MulReductionVF src1 src2)); 16047 ins_cost(INSN_COST); 16048 effect(TEMP tmp, TEMP dst); 16049 format %{ "fmuls $dst, $src1, $src2\n\t" 16050 "ins $tmp, S, $src2, 0, 1\n\t" 16051 "fmuls $dst, $dst, $tmp\t add reduction4f" 16052 %} 16053 ins_encode %{ 16054 __ fmuls(as_FloatRegister($dst$$reg), 16055 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16056 __ ins(as_FloatRegister($tmp$$reg), __ S, 16057 as_FloatRegister($src2$$reg), 0, 1); 16058 __ fmuls(as_FloatRegister($dst$$reg), 16059 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16060 %} 16061 ins_pipe(pipe_class_default); 16062 %} 16063 16064 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16065 %{ 16066 match(Set dst (MulReductionVF src1 src2)); 16067 ins_cost(INSN_COST); 16068 effect(TEMP tmp, TEMP dst); 16069 format %{ "fmuls $dst, $src1, $src2\n\t" 16070 "ins $tmp, S, $src2, 0, 1\n\t" 16071 "fmuls $dst, $dst, $tmp\n\t" 16072 "ins $tmp, S, $src2, 0, 2\n\t" 16073 "fmuls $dst, $dst, $tmp\n\t" 16074 "ins $tmp, S, $src2, 0, 3\n\t" 16075 "fmuls $dst, $dst, $tmp\t add reduction4f" 16076 %} 16077 ins_encode %{ 16078 __ fmuls(as_FloatRegister($dst$$reg), 16079 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16080 __ ins(as_FloatRegister($tmp$$reg), __ S, 16081 as_FloatRegister($src2$$reg), 0, 1); 16082 __ fmuls(as_FloatRegister($dst$$reg), 16083 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16084 __ ins(as_FloatRegister($tmp$$reg), __ S, 16085 as_FloatRegister($src2$$reg), 0, 2); 16086 __ fmuls(as_FloatRegister($dst$$reg), 16087 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16088 __ ins(as_FloatRegister($tmp$$reg), __ S, 16089 as_FloatRegister($src2$$reg), 0, 3); 16090 __ fmuls(as_FloatRegister($dst$$reg), 16091 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16092 %} 16093 ins_pipe(pipe_class_default); 16094 %} 16095 16096 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16097 %{ 16098 match(Set dst (AddReductionVD src1 src2)); 16099 ins_cost(INSN_COST); 16100 effect(TEMP tmp, TEMP dst); 16101 format %{ "faddd $dst, $src1, $src2\n\t" 16102 "ins $tmp, D, $src2, 0, 1\n\t" 16103 "faddd $dst, $dst, $tmp\t add reduction2d" 16104 %} 16105 ins_encode %{ 16106 __ faddd(as_FloatRegister($dst$$reg), 16107 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16108 __ ins(as_FloatRegister($tmp$$reg), __ D, 16109 as_FloatRegister($src2$$reg), 0, 1); 16110 __ faddd(as_FloatRegister($dst$$reg), 16111 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16112 %} 16113 ins_pipe(pipe_class_default); 16114 %} 16115 16116 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16117 %{ 16118 match(Set dst (MulReductionVD src1 src2)); 16119 ins_cost(INSN_COST); 16120 effect(TEMP tmp, TEMP dst); 16121 format %{ "fmuld $dst, $src1, $src2\n\t" 16122 "ins $tmp, D, $src2, 0, 1\n\t" 16123 "fmuld $dst, $dst, $tmp\t add reduction2d" 16124 %} 16125 ins_encode %{ 16126 __ fmuld(as_FloatRegister($dst$$reg), 16127 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16128 __ ins(as_FloatRegister($tmp$$reg), __ D, 16129 as_FloatRegister($src2$$reg), 0, 1); 16130 __ fmuld(as_FloatRegister($dst$$reg), 16131 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16132 %} 16133 ins_pipe(pipe_class_default); 16134 %} 16135 16136 instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16137 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16138 match(Set dst (MaxReductionV src1 src2)); 16139 ins_cost(INSN_COST); 16140 effect(TEMP_DEF dst, TEMP tmp); 16141 format %{ "fmaxs $dst, $src1, $src2\n\t" 16142 "ins $tmp, S, $src2, 0, 1\n\t" 16143 "fmaxs $dst, $dst, $tmp\t max reduction2F" %} 16144 ins_encode %{ 16145 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16146 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16147 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16148 %} 16149 ins_pipe(pipe_class_default); 16150 %} 16151 16152 instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ 16153 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16154 match(Set dst (MaxReductionV src1 src2)); 16155 ins_cost(INSN_COST); 16156 effect(TEMP_DEF dst); 16157 format %{ "fmaxv $dst, T4S, $src2\n\t" 16158 "fmaxs $dst, $dst, $src1\t max reduction4F" %} 16159 ins_encode %{ 16160 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16161 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16162 %} 16163 ins_pipe(pipe_class_default); 16164 %} 16165 16166 instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16167 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16168 match(Set dst (MaxReductionV src1 src2)); 16169 ins_cost(INSN_COST); 16170 effect(TEMP_DEF dst, TEMP tmp); 16171 format %{ "fmaxd $dst, $src1, $src2\n\t" 16172 "ins $tmp, D, $src2, 0, 1\n\t" 16173 "fmaxd $dst, $dst, $tmp\t max reduction2D" %} 16174 ins_encode %{ 16175 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16176 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16177 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16178 %} 16179 ins_pipe(pipe_class_default); 16180 %} 16181 16182 instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16183 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16184 match(Set dst (MinReductionV src1 src2)); 16185 ins_cost(INSN_COST); 16186 effect(TEMP_DEF dst, TEMP tmp); 16187 format %{ "fmins $dst, $src1, $src2\n\t" 16188 "ins $tmp, S, $src2, 0, 1\n\t" 16189 "fmins $dst, $dst, $tmp\t min reduction2F" %} 16190 ins_encode %{ 16191 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16192 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16193 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16194 %} 16195 ins_pipe(pipe_class_default); 16196 %} 16197 16198 instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ 16199 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16200 match(Set dst (MinReductionV src1 src2)); 16201 ins_cost(INSN_COST); 16202 effect(TEMP_DEF dst); 16203 format %{ "fminv $dst, T4S, $src2\n\t" 16204 "fmins $dst, $dst, $src1\t min reduction4F" %} 16205 ins_encode %{ 16206 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16207 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16208 %} 16209 ins_pipe(pipe_class_default); 16210 %} 16211 16212 instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16213 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16214 match(Set dst (MinReductionV src1 src2)); 16215 ins_cost(INSN_COST); 16216 effect(TEMP_DEF dst, TEMP tmp); 16217 format %{ "fmind $dst, $src1, $src2\n\t" 16218 "ins $tmp, D, $src2, 0, 1\n\t" 16219 "fmind $dst, $dst, $tmp\t min reduction2D" %} 16220 ins_encode %{ 16221 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16222 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16223 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16224 %} 16225 ins_pipe(pipe_class_default); 16226 %} 16227 16228 // ====================VECTOR ARITHMETIC======================================= 16229 16230 // --------------------------------- ADD -------------------------------------- 16231 16232 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16233 %{ 16234 predicate(n->as_Vector()->length() == 4 || 16235 n->as_Vector()->length() == 8); 16236 match(Set dst (AddVB src1 src2)); 16237 ins_cost(INSN_COST); 16238 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16239 ins_encode %{ 16240 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16241 as_FloatRegister($src1$$reg), 16242 as_FloatRegister($src2$$reg)); 16243 %} 16244 ins_pipe(vdop64); 16245 %} 16246 16247 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16248 %{ 16249 predicate(n->as_Vector()->length() == 16); 16250 match(Set dst (AddVB src1 src2)); 16251 ins_cost(INSN_COST); 16252 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16253 ins_encode %{ 16254 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16255 as_FloatRegister($src1$$reg), 16256 as_FloatRegister($src2$$reg)); 16257 %} 16258 ins_pipe(vdop128); 16259 %} 16260 16261 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16262 %{ 16263 predicate(n->as_Vector()->length() == 2 || 16264 n->as_Vector()->length() == 4); 16265 match(Set dst (AddVS src1 src2)); 16266 ins_cost(INSN_COST); 16267 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16268 ins_encode %{ 16269 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16270 as_FloatRegister($src1$$reg), 16271 as_FloatRegister($src2$$reg)); 16272 %} 16273 ins_pipe(vdop64); 16274 %} 16275 16276 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16277 %{ 16278 predicate(n->as_Vector()->length() == 8); 16279 match(Set dst (AddVS src1 src2)); 16280 ins_cost(INSN_COST); 16281 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16282 ins_encode %{ 16283 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16284 as_FloatRegister($src1$$reg), 16285 as_FloatRegister($src2$$reg)); 16286 %} 16287 ins_pipe(vdop128); 16288 %} 16289 16290 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16291 %{ 16292 predicate(n->as_Vector()->length() == 2); 16293 match(Set dst (AddVI src1 src2)); 16294 ins_cost(INSN_COST); 16295 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16296 ins_encode %{ 16297 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16298 as_FloatRegister($src1$$reg), 16299 as_FloatRegister($src2$$reg)); 16300 %} 16301 ins_pipe(vdop64); 16302 %} 16303 16304 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16305 %{ 16306 predicate(n->as_Vector()->length() == 4); 16307 match(Set dst (AddVI src1 src2)); 16308 ins_cost(INSN_COST); 16309 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16310 ins_encode %{ 16311 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16312 as_FloatRegister($src1$$reg), 16313 as_FloatRegister($src2$$reg)); 16314 %} 16315 ins_pipe(vdop128); 16316 %} 16317 16318 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16319 %{ 16320 predicate(n->as_Vector()->length() == 2); 16321 match(Set dst (AddVL src1 src2)); 16322 ins_cost(INSN_COST); 16323 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16324 ins_encode %{ 16325 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16326 as_FloatRegister($src1$$reg), 16327 as_FloatRegister($src2$$reg)); 16328 %} 16329 ins_pipe(vdop128); 16330 %} 16331 16332 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16333 %{ 16334 predicate(n->as_Vector()->length() == 2); 16335 match(Set dst (AddVF src1 src2)); 16336 ins_cost(INSN_COST); 16337 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16338 ins_encode %{ 16339 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16340 as_FloatRegister($src1$$reg), 16341 as_FloatRegister($src2$$reg)); 16342 %} 16343 ins_pipe(vdop_fp64); 16344 %} 16345 16346 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16347 %{ 16348 predicate(n->as_Vector()->length() == 4); 16349 match(Set dst (AddVF src1 src2)); 16350 ins_cost(INSN_COST); 16351 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16352 ins_encode %{ 16353 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16354 as_FloatRegister($src1$$reg), 16355 as_FloatRegister($src2$$reg)); 16356 %} 16357 ins_pipe(vdop_fp128); 16358 %} 16359 16360 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16361 %{ 16362 match(Set dst (AddVD src1 src2)); 16363 ins_cost(INSN_COST); 16364 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16365 ins_encode %{ 16366 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16367 as_FloatRegister($src1$$reg), 16368 as_FloatRegister($src2$$reg)); 16369 %} 16370 ins_pipe(vdop_fp128); 16371 %} 16372 16373 // --------------------------------- SUB -------------------------------------- 16374 16375 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16376 %{ 16377 predicate(n->as_Vector()->length() == 4 || 16378 n->as_Vector()->length() == 8); 16379 match(Set dst (SubVB src1 src2)); 16380 ins_cost(INSN_COST); 16381 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16382 ins_encode %{ 16383 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16384 as_FloatRegister($src1$$reg), 16385 as_FloatRegister($src2$$reg)); 16386 %} 16387 ins_pipe(vdop64); 16388 %} 16389 16390 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16391 %{ 16392 predicate(n->as_Vector()->length() == 16); 16393 match(Set dst (SubVB src1 src2)); 16394 ins_cost(INSN_COST); 16395 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16396 ins_encode %{ 16397 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16398 as_FloatRegister($src1$$reg), 16399 as_FloatRegister($src2$$reg)); 16400 %} 16401 ins_pipe(vdop128); 16402 %} 16403 16404 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16405 %{ 16406 predicate(n->as_Vector()->length() == 2 || 16407 n->as_Vector()->length() == 4); 16408 match(Set dst (SubVS src1 src2)); 16409 ins_cost(INSN_COST); 16410 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16411 ins_encode %{ 16412 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16413 as_FloatRegister($src1$$reg), 16414 as_FloatRegister($src2$$reg)); 16415 %} 16416 ins_pipe(vdop64); 16417 %} 16418 16419 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16420 %{ 16421 predicate(n->as_Vector()->length() == 8); 16422 match(Set dst (SubVS src1 src2)); 16423 ins_cost(INSN_COST); 16424 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16425 ins_encode %{ 16426 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16427 as_FloatRegister($src1$$reg), 16428 as_FloatRegister($src2$$reg)); 16429 %} 16430 ins_pipe(vdop128); 16431 %} 16432 16433 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16434 %{ 16435 predicate(n->as_Vector()->length() == 2); 16436 match(Set dst (SubVI src1 src2)); 16437 ins_cost(INSN_COST); 16438 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16439 ins_encode %{ 16440 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16441 as_FloatRegister($src1$$reg), 16442 as_FloatRegister($src2$$reg)); 16443 %} 16444 ins_pipe(vdop64); 16445 %} 16446 16447 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16448 %{ 16449 predicate(n->as_Vector()->length() == 4); 16450 match(Set dst (SubVI src1 src2)); 16451 ins_cost(INSN_COST); 16452 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16453 ins_encode %{ 16454 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16455 as_FloatRegister($src1$$reg), 16456 as_FloatRegister($src2$$reg)); 16457 %} 16458 ins_pipe(vdop128); 16459 %} 16460 16461 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16462 %{ 16463 predicate(n->as_Vector()->length() == 2); 16464 match(Set dst (SubVL src1 src2)); 16465 ins_cost(INSN_COST); 16466 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16467 ins_encode %{ 16468 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16469 as_FloatRegister($src1$$reg), 16470 as_FloatRegister($src2$$reg)); 16471 %} 16472 ins_pipe(vdop128); 16473 %} 16474 16475 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16476 %{ 16477 predicate(n->as_Vector()->length() == 2); 16478 match(Set dst (SubVF src1 src2)); 16479 ins_cost(INSN_COST); 16480 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16481 ins_encode %{ 16482 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16483 as_FloatRegister($src1$$reg), 16484 as_FloatRegister($src2$$reg)); 16485 %} 16486 ins_pipe(vdop_fp64); 16487 %} 16488 16489 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16490 %{ 16491 predicate(n->as_Vector()->length() == 4); 16492 match(Set dst (SubVF src1 src2)); 16493 ins_cost(INSN_COST); 16494 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16495 ins_encode %{ 16496 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16497 as_FloatRegister($src1$$reg), 16498 as_FloatRegister($src2$$reg)); 16499 %} 16500 ins_pipe(vdop_fp128); 16501 %} 16502 16503 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16504 %{ 16505 predicate(n->as_Vector()->length() == 2); 16506 match(Set dst (SubVD src1 src2)); 16507 ins_cost(INSN_COST); 16508 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16509 ins_encode %{ 16510 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16511 as_FloatRegister($src1$$reg), 16512 as_FloatRegister($src2$$reg)); 16513 %} 16514 ins_pipe(vdop_fp128); 16515 %} 16516 16517 // --------------------------------- MUL -------------------------------------- 16518 16519 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16520 %{ 16521 predicate(n->as_Vector()->length() == 2 || 16522 n->as_Vector()->length() == 4); 16523 match(Set dst (MulVS src1 src2)); 16524 ins_cost(INSN_COST); 16525 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16526 ins_encode %{ 16527 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16528 as_FloatRegister($src1$$reg), 16529 as_FloatRegister($src2$$reg)); 16530 %} 16531 ins_pipe(vmul64); 16532 %} 16533 16534 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16535 %{ 16536 predicate(n->as_Vector()->length() == 8); 16537 match(Set dst (MulVS src1 src2)); 16538 ins_cost(INSN_COST); 16539 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16540 ins_encode %{ 16541 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16542 as_FloatRegister($src1$$reg), 16543 as_FloatRegister($src2$$reg)); 16544 %} 16545 ins_pipe(vmul128); 16546 %} 16547 16548 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16549 %{ 16550 predicate(n->as_Vector()->length() == 2); 16551 match(Set dst (MulVI src1 src2)); 16552 ins_cost(INSN_COST); 16553 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16554 ins_encode %{ 16555 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16556 as_FloatRegister($src1$$reg), 16557 as_FloatRegister($src2$$reg)); 16558 %} 16559 ins_pipe(vmul64); 16560 %} 16561 16562 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16563 %{ 16564 predicate(n->as_Vector()->length() == 4); 16565 match(Set dst (MulVI src1 src2)); 16566 ins_cost(INSN_COST); 16567 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16568 ins_encode %{ 16569 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16570 as_FloatRegister($src1$$reg), 16571 as_FloatRegister($src2$$reg)); 16572 %} 16573 ins_pipe(vmul128); 16574 %} 16575 16576 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16577 %{ 16578 predicate(n->as_Vector()->length() == 2); 16579 match(Set dst (MulVF src1 src2)); 16580 ins_cost(INSN_COST); 16581 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16582 ins_encode %{ 16583 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16584 as_FloatRegister($src1$$reg), 16585 as_FloatRegister($src2$$reg)); 16586 %} 16587 ins_pipe(vmuldiv_fp64); 16588 %} 16589 16590 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16591 %{ 16592 predicate(n->as_Vector()->length() == 4); 16593 match(Set dst (MulVF src1 src2)); 16594 ins_cost(INSN_COST); 16595 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16596 ins_encode %{ 16597 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16598 as_FloatRegister($src1$$reg), 16599 as_FloatRegister($src2$$reg)); 16600 %} 16601 ins_pipe(vmuldiv_fp128); 16602 %} 16603 16604 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16605 %{ 16606 predicate(n->as_Vector()->length() == 2); 16607 match(Set dst (MulVD src1 src2)); 16608 ins_cost(INSN_COST); 16609 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16610 ins_encode %{ 16611 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16612 as_FloatRegister($src1$$reg), 16613 as_FloatRegister($src2$$reg)); 16614 %} 16615 ins_pipe(vmuldiv_fp128); 16616 %} 16617 16618 // --------------------------------- MLA -------------------------------------- 16619 16620 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16621 %{ 16622 predicate(n->as_Vector()->length() == 2 || 16623 n->as_Vector()->length() == 4); 16624 match(Set dst (AddVS dst (MulVS src1 src2))); 16625 ins_cost(INSN_COST); 16626 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16627 ins_encode %{ 16628 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16629 as_FloatRegister($src1$$reg), 16630 as_FloatRegister($src2$$reg)); 16631 %} 16632 ins_pipe(vmla64); 16633 %} 16634 16635 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16636 %{ 16637 predicate(n->as_Vector()->length() == 8); 16638 match(Set dst (AddVS dst (MulVS src1 src2))); 16639 ins_cost(INSN_COST); 16640 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16641 ins_encode %{ 16642 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16643 as_FloatRegister($src1$$reg), 16644 as_FloatRegister($src2$$reg)); 16645 %} 16646 ins_pipe(vmla128); 16647 %} 16648 16649 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16650 %{ 16651 predicate(n->as_Vector()->length() == 2); 16652 match(Set dst (AddVI dst (MulVI src1 src2))); 16653 ins_cost(INSN_COST); 16654 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16655 ins_encode %{ 16656 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16657 as_FloatRegister($src1$$reg), 16658 as_FloatRegister($src2$$reg)); 16659 %} 16660 ins_pipe(vmla64); 16661 %} 16662 16663 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16664 %{ 16665 predicate(n->as_Vector()->length() == 4); 16666 match(Set dst (AddVI dst (MulVI src1 src2))); 16667 ins_cost(INSN_COST); 16668 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16669 ins_encode %{ 16670 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16671 as_FloatRegister($src1$$reg), 16672 as_FloatRegister($src2$$reg)); 16673 %} 16674 ins_pipe(vmla128); 16675 %} 16676 16677 // dst + src1 * src2 16678 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16679 predicate(UseFMA && n->as_Vector()->length() == 2); 16680 match(Set dst (FmaVF dst (Binary src1 src2))); 16681 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16682 ins_cost(INSN_COST); 16683 ins_encode %{ 16684 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16685 as_FloatRegister($src1$$reg), 16686 as_FloatRegister($src2$$reg)); 16687 %} 16688 ins_pipe(vmuldiv_fp64); 16689 %} 16690 16691 // dst + src1 * src2 16692 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16693 predicate(UseFMA && n->as_Vector()->length() == 4); 16694 match(Set dst (FmaVF dst (Binary src1 src2))); 16695 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16696 ins_cost(INSN_COST); 16697 ins_encode %{ 16698 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16699 as_FloatRegister($src1$$reg), 16700 as_FloatRegister($src2$$reg)); 16701 %} 16702 ins_pipe(vmuldiv_fp128); 16703 %} 16704 16705 // dst + src1 * src2 16706 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16707 predicate(UseFMA && n->as_Vector()->length() == 2); 16708 match(Set dst (FmaVD dst (Binary src1 src2))); 16709 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16710 ins_cost(INSN_COST); 16711 ins_encode %{ 16712 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16713 as_FloatRegister($src1$$reg), 16714 as_FloatRegister($src2$$reg)); 16715 %} 16716 ins_pipe(vmuldiv_fp128); 16717 %} 16718 16719 // --------------------------------- MLS -------------------------------------- 16720 16721 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16722 %{ 16723 predicate(n->as_Vector()->length() == 2 || 16724 n->as_Vector()->length() == 4); 16725 match(Set dst (SubVS dst (MulVS src1 src2))); 16726 ins_cost(INSN_COST); 16727 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16728 ins_encode %{ 16729 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16730 as_FloatRegister($src1$$reg), 16731 as_FloatRegister($src2$$reg)); 16732 %} 16733 ins_pipe(vmla64); 16734 %} 16735 16736 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16737 %{ 16738 predicate(n->as_Vector()->length() == 8); 16739 match(Set dst (SubVS dst (MulVS src1 src2))); 16740 ins_cost(INSN_COST); 16741 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16742 ins_encode %{ 16743 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16744 as_FloatRegister($src1$$reg), 16745 as_FloatRegister($src2$$reg)); 16746 %} 16747 ins_pipe(vmla128); 16748 %} 16749 16750 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16751 %{ 16752 predicate(n->as_Vector()->length() == 2); 16753 match(Set dst (SubVI dst (MulVI src1 src2))); 16754 ins_cost(INSN_COST); 16755 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16756 ins_encode %{ 16757 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16758 as_FloatRegister($src1$$reg), 16759 as_FloatRegister($src2$$reg)); 16760 %} 16761 ins_pipe(vmla64); 16762 %} 16763 16764 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16765 %{ 16766 predicate(n->as_Vector()->length() == 4); 16767 match(Set dst (SubVI dst (MulVI src1 src2))); 16768 ins_cost(INSN_COST); 16769 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16770 ins_encode %{ 16771 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16772 as_FloatRegister($src1$$reg), 16773 as_FloatRegister($src2$$reg)); 16774 %} 16775 ins_pipe(vmla128); 16776 %} 16777 16778 // dst - src1 * src2 16779 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16780 predicate(UseFMA && n->as_Vector()->length() == 2); 16781 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16782 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16783 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16784 ins_cost(INSN_COST); 16785 ins_encode %{ 16786 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16787 as_FloatRegister($src1$$reg), 16788 as_FloatRegister($src2$$reg)); 16789 %} 16790 ins_pipe(vmuldiv_fp64); 16791 %} 16792 16793 // dst - src1 * src2 16794 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16795 predicate(UseFMA && n->as_Vector()->length() == 4); 16796 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16797 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16798 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16799 ins_cost(INSN_COST); 16800 ins_encode %{ 16801 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16802 as_FloatRegister($src1$$reg), 16803 as_FloatRegister($src2$$reg)); 16804 %} 16805 ins_pipe(vmuldiv_fp128); 16806 %} 16807 16808 // dst - src1 * src2 16809 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16810 predicate(UseFMA && n->as_Vector()->length() == 2); 16811 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16812 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16813 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16814 ins_cost(INSN_COST); 16815 ins_encode %{ 16816 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16817 as_FloatRegister($src1$$reg), 16818 as_FloatRegister($src2$$reg)); 16819 %} 16820 ins_pipe(vmuldiv_fp128); 16821 %} 16822 16823 // --------------------------------- DIV -------------------------------------- 16824 16825 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16826 %{ 16827 predicate(n->as_Vector()->length() == 2); 16828 match(Set dst (DivVF src1 src2)); 16829 ins_cost(INSN_COST); 16830 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16831 ins_encode %{ 16832 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16833 as_FloatRegister($src1$$reg), 16834 as_FloatRegister($src2$$reg)); 16835 %} 16836 ins_pipe(vmuldiv_fp64); 16837 %} 16838 16839 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16840 %{ 16841 predicate(n->as_Vector()->length() == 4); 16842 match(Set dst (DivVF src1 src2)); 16843 ins_cost(INSN_COST); 16844 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16845 ins_encode %{ 16846 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16847 as_FloatRegister($src1$$reg), 16848 as_FloatRegister($src2$$reg)); 16849 %} 16850 ins_pipe(vmuldiv_fp128); 16851 %} 16852 16853 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 16854 %{ 16855 predicate(n->as_Vector()->length() == 2); 16856 match(Set dst (DivVD src1 src2)); 16857 ins_cost(INSN_COST); 16858 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 16859 ins_encode %{ 16860 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 16861 as_FloatRegister($src1$$reg), 16862 as_FloatRegister($src2$$reg)); 16863 %} 16864 ins_pipe(vmuldiv_fp128); 16865 %} 16866 16867 // --------------------------------- SQRT ------------------------------------- 16868 16869 instruct vsqrt2D(vecX dst, vecX src) 16870 %{ 16871 predicate(n->as_Vector()->length() == 2); 16872 match(Set dst (SqrtVD src)); 16873 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 16874 ins_encode %{ 16875 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 16876 as_FloatRegister($src$$reg)); 16877 %} 16878 ins_pipe(vsqrt_fp128); 16879 %} 16880 16881 // --------------------------------- ABS -------------------------------------- 16882 16883 instruct vabs2F(vecD dst, vecD src) 16884 %{ 16885 predicate(n->as_Vector()->length() == 2); 16886 match(Set dst (AbsVF src)); 16887 ins_cost(INSN_COST * 3); 16888 format %{ "fabs $dst,$src\t# vector (2S)" %} 16889 ins_encode %{ 16890 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 16891 as_FloatRegister($src$$reg)); 16892 %} 16893 ins_pipe(vunop_fp64); 16894 %} 16895 16896 instruct vabs4F(vecX dst, vecX src) 16897 %{ 16898 predicate(n->as_Vector()->length() == 4); 16899 match(Set dst (AbsVF src)); 16900 ins_cost(INSN_COST * 3); 16901 format %{ "fabs $dst,$src\t# vector (4S)" %} 16902 ins_encode %{ 16903 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16904 as_FloatRegister($src$$reg)); 16905 %} 16906 ins_pipe(vunop_fp128); 16907 %} 16908 16909 instruct vabs2D(vecX dst, vecX src) 16910 %{ 16911 predicate(n->as_Vector()->length() == 2); 16912 match(Set dst (AbsVD src)); 16913 ins_cost(INSN_COST * 3); 16914 format %{ "fabs $dst,$src\t# vector (2D)" %} 16915 ins_encode %{ 16916 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 16917 as_FloatRegister($src$$reg)); 16918 %} 16919 ins_pipe(vunop_fp128); 16920 %} 16921 16922 // --------------------------------- NEG -------------------------------------- 16923 16924 instruct vneg2F(vecD dst, vecD src) 16925 %{ 16926 predicate(n->as_Vector()->length() == 2); 16927 match(Set dst (NegVF src)); 16928 ins_cost(INSN_COST * 3); 16929 format %{ "fneg $dst,$src\t# vector (2S)" %} 16930 ins_encode %{ 16931 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 16932 as_FloatRegister($src$$reg)); 16933 %} 16934 ins_pipe(vunop_fp64); 16935 %} 16936 16937 instruct vneg4F(vecX dst, vecX src) 16938 %{ 16939 predicate(n->as_Vector()->length() == 4); 16940 match(Set dst (NegVF src)); 16941 ins_cost(INSN_COST * 3); 16942 format %{ "fneg $dst,$src\t# vector (4S)" %} 16943 ins_encode %{ 16944 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16945 as_FloatRegister($src$$reg)); 16946 %} 16947 ins_pipe(vunop_fp128); 16948 %} 16949 16950 instruct vneg2D(vecX dst, vecX src) 16951 %{ 16952 predicate(n->as_Vector()->length() == 2); 16953 match(Set dst (NegVD src)); 16954 ins_cost(INSN_COST * 3); 16955 format %{ "fneg $dst,$src\t# vector (2D)" %} 16956 ins_encode %{ 16957 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16958 as_FloatRegister($src$$reg)); 16959 %} 16960 ins_pipe(vunop_fp128); 16961 %} 16962 16963 // --------------------------------- AND -------------------------------------- 16964 16965 instruct vand8B(vecD dst, vecD src1, vecD src2) 16966 %{ 16967 predicate(n->as_Vector()->length_in_bytes() == 4 || 16968 n->as_Vector()->length_in_bytes() == 8); 16969 match(Set dst (AndV src1 src2)); 16970 ins_cost(INSN_COST); 16971 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16972 ins_encode %{ 16973 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16974 as_FloatRegister($src1$$reg), 16975 as_FloatRegister($src2$$reg)); 16976 %} 16977 ins_pipe(vlogical64); 16978 %} 16979 16980 instruct vand16B(vecX dst, vecX src1, vecX src2) 16981 %{ 16982 predicate(n->as_Vector()->length_in_bytes() == 16); 16983 match(Set dst (AndV src1 src2)); 16984 ins_cost(INSN_COST); 16985 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16986 ins_encode %{ 16987 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16988 as_FloatRegister($src1$$reg), 16989 as_FloatRegister($src2$$reg)); 16990 %} 16991 ins_pipe(vlogical128); 16992 %} 16993 16994 // --------------------------------- OR --------------------------------------- 16995 16996 instruct vor8B(vecD dst, vecD src1, vecD src2) 16997 %{ 16998 predicate(n->as_Vector()->length_in_bytes() == 4 || 16999 n->as_Vector()->length_in_bytes() == 8); 17000 match(Set dst (OrV src1 src2)); 17001 ins_cost(INSN_COST); 17002 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17003 ins_encode %{ 17004 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17005 as_FloatRegister($src1$$reg), 17006 as_FloatRegister($src2$$reg)); 17007 %} 17008 ins_pipe(vlogical64); 17009 %} 17010 17011 instruct vor16B(vecX dst, vecX src1, vecX src2) 17012 %{ 17013 predicate(n->as_Vector()->length_in_bytes() == 16); 17014 match(Set dst (OrV src1 src2)); 17015 ins_cost(INSN_COST); 17016 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17017 ins_encode %{ 17018 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17019 as_FloatRegister($src1$$reg), 17020 as_FloatRegister($src2$$reg)); 17021 %} 17022 ins_pipe(vlogical128); 17023 %} 17024 17025 // --------------------------------- XOR -------------------------------------- 17026 17027 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17028 %{ 17029 predicate(n->as_Vector()->length_in_bytes() == 4 || 17030 n->as_Vector()->length_in_bytes() == 8); 17031 match(Set dst (XorV src1 src2)); 17032 ins_cost(INSN_COST); 17033 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17034 ins_encode %{ 17035 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17036 as_FloatRegister($src1$$reg), 17037 as_FloatRegister($src2$$reg)); 17038 %} 17039 ins_pipe(vlogical64); 17040 %} 17041 17042 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17043 %{ 17044 predicate(n->as_Vector()->length_in_bytes() == 16); 17045 match(Set dst (XorV src1 src2)); 17046 ins_cost(INSN_COST); 17047 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17048 ins_encode %{ 17049 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17050 as_FloatRegister($src1$$reg), 17051 as_FloatRegister($src2$$reg)); 17052 %} 17053 ins_pipe(vlogical128); 17054 %} 17055 17056 // ------------------------------ Shift --------------------------------------- 17057 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17058 predicate(n->as_Vector()->length_in_bytes() == 8); 17059 match(Set dst (LShiftCntV cnt)); 17060 match(Set dst (RShiftCntV cnt)); 17061 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17062 ins_encode %{ 17063 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17064 %} 17065 ins_pipe(vdup_reg_reg64); 17066 %} 17067 17068 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17069 predicate(n->as_Vector()->length_in_bytes() == 16); 17070 match(Set dst (LShiftCntV cnt)); 17071 match(Set dst (RShiftCntV cnt)); 17072 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17073 ins_encode %{ 17074 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17075 %} 17076 ins_pipe(vdup_reg_reg128); 17077 %} 17078 17079 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17080 predicate(n->as_Vector()->length() == 4 || 17081 n->as_Vector()->length() == 8); 17082 match(Set dst (LShiftVB src shift)); 17083 ins_cost(INSN_COST); 17084 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17085 ins_encode %{ 17086 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17087 as_FloatRegister($src$$reg), 17088 as_FloatRegister($shift$$reg)); 17089 %} 17090 ins_pipe(vshift64); 17091 %} 17092 17093 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17094 predicate(n->as_Vector()->length() == 16); 17095 match(Set dst (LShiftVB src shift)); 17096 ins_cost(INSN_COST); 17097 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17098 ins_encode %{ 17099 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17100 as_FloatRegister($src$$reg), 17101 as_FloatRegister($shift$$reg)); 17102 %} 17103 ins_pipe(vshift128); 17104 %} 17105 17106 // Right shifts with vector shift count on aarch64 SIMD are implemented 17107 // as left shift by negative shift count. 17108 // There are two cases for vector shift count. 17109 // 17110 // Case 1: The vector shift count is from replication. 17111 // | | 17112 // LoadVector RShiftCntV 17113 // | / 17114 // RShiftVI 17115 // Note: In inner loop, multiple neg instructions are used, which can be 17116 // moved to outer loop and merge into one neg instruction. 17117 // 17118 // Case 2: The vector shift count is from loading. 17119 // This case isn't supported by middle-end now. But it's supported by 17120 // panama/vectorIntrinsics(JEP 338: Vector API). 17121 // | | 17122 // LoadVector LoadVector 17123 // | / 17124 // RShiftVI 17125 // 17126 17127 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17128 predicate(n->as_Vector()->length() == 4 || 17129 n->as_Vector()->length() == 8); 17130 match(Set dst (RShiftVB src shift)); 17131 ins_cost(INSN_COST); 17132 effect(TEMP tmp); 17133 format %{ "negr $tmp,$shift\t" 17134 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17135 ins_encode %{ 17136 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17137 as_FloatRegister($shift$$reg)); 17138 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17139 as_FloatRegister($src$$reg), 17140 as_FloatRegister($tmp$$reg)); 17141 %} 17142 ins_pipe(vshift64); 17143 %} 17144 17145 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17146 predicate(n->as_Vector()->length() == 16); 17147 match(Set dst (RShiftVB src shift)); 17148 ins_cost(INSN_COST); 17149 effect(TEMP tmp); 17150 format %{ "negr $tmp,$shift\t" 17151 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17152 ins_encode %{ 17153 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17154 as_FloatRegister($shift$$reg)); 17155 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17156 as_FloatRegister($src$$reg), 17157 as_FloatRegister($tmp$$reg)); 17158 %} 17159 ins_pipe(vshift128); 17160 %} 17161 17162 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17163 predicate(n->as_Vector()->length() == 4 || 17164 n->as_Vector()->length() == 8); 17165 match(Set dst (URShiftVB src shift)); 17166 ins_cost(INSN_COST); 17167 effect(TEMP tmp); 17168 format %{ "negr $tmp,$shift\t" 17169 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17170 ins_encode %{ 17171 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17172 as_FloatRegister($shift$$reg)); 17173 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17174 as_FloatRegister($src$$reg), 17175 as_FloatRegister($tmp$$reg)); 17176 %} 17177 ins_pipe(vshift64); 17178 %} 17179 17180 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17181 predicate(n->as_Vector()->length() == 16); 17182 match(Set dst (URShiftVB src shift)); 17183 ins_cost(INSN_COST); 17184 effect(TEMP tmp); 17185 format %{ "negr $tmp,$shift\t" 17186 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17187 ins_encode %{ 17188 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17189 as_FloatRegister($shift$$reg)); 17190 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17191 as_FloatRegister($src$$reg), 17192 as_FloatRegister($tmp$$reg)); 17193 %} 17194 ins_pipe(vshift128); 17195 %} 17196 17197 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17198 predicate(n->as_Vector()->length() == 4 || 17199 n->as_Vector()->length() == 8); 17200 match(Set dst (LShiftVB src shift)); 17201 ins_cost(INSN_COST); 17202 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17203 ins_encode %{ 17204 int sh = (int)$shift$$constant; 17205 if (sh >= 8) { 17206 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17207 as_FloatRegister($src$$reg), 17208 as_FloatRegister($src$$reg)); 17209 } else { 17210 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17211 as_FloatRegister($src$$reg), sh); 17212 } 17213 %} 17214 ins_pipe(vshift64_imm); 17215 %} 17216 17217 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17218 predicate(n->as_Vector()->length() == 16); 17219 match(Set dst (LShiftVB src shift)); 17220 ins_cost(INSN_COST); 17221 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17222 ins_encode %{ 17223 int sh = (int)$shift$$constant; 17224 if (sh >= 8) { 17225 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17226 as_FloatRegister($src$$reg), 17227 as_FloatRegister($src$$reg)); 17228 } else { 17229 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17230 as_FloatRegister($src$$reg), sh); 17231 } 17232 %} 17233 ins_pipe(vshift128_imm); 17234 %} 17235 17236 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17237 predicate(n->as_Vector()->length() == 4 || 17238 n->as_Vector()->length() == 8); 17239 match(Set dst (RShiftVB src shift)); 17240 ins_cost(INSN_COST); 17241 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17242 ins_encode %{ 17243 int sh = (int)$shift$$constant; 17244 if (sh >= 8) sh = 7; 17245 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17246 as_FloatRegister($src$$reg), sh); 17247 %} 17248 ins_pipe(vshift64_imm); 17249 %} 17250 17251 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17252 predicate(n->as_Vector()->length() == 16); 17253 match(Set dst (RShiftVB src shift)); 17254 ins_cost(INSN_COST); 17255 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17256 ins_encode %{ 17257 int sh = (int)$shift$$constant; 17258 if (sh >= 8) sh = 7; 17259 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17260 as_FloatRegister($src$$reg), sh); 17261 %} 17262 ins_pipe(vshift128_imm); 17263 %} 17264 17265 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17266 predicate(n->as_Vector()->length() == 4 || 17267 n->as_Vector()->length() == 8); 17268 match(Set dst (URShiftVB src shift)); 17269 ins_cost(INSN_COST); 17270 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17271 ins_encode %{ 17272 int sh = (int)$shift$$constant; 17273 if (sh >= 8) { 17274 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17275 as_FloatRegister($src$$reg), 17276 as_FloatRegister($src$$reg)); 17277 } else { 17278 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17279 as_FloatRegister($src$$reg), sh); 17280 } 17281 %} 17282 ins_pipe(vshift64_imm); 17283 %} 17284 17285 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17286 predicate(n->as_Vector()->length() == 16); 17287 match(Set dst (URShiftVB src shift)); 17288 ins_cost(INSN_COST); 17289 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17290 ins_encode %{ 17291 int sh = (int)$shift$$constant; 17292 if (sh >= 8) { 17293 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17294 as_FloatRegister($src$$reg), 17295 as_FloatRegister($src$$reg)); 17296 } else { 17297 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17298 as_FloatRegister($src$$reg), sh); 17299 } 17300 %} 17301 ins_pipe(vshift128_imm); 17302 %} 17303 17304 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17305 predicate(n->as_Vector()->length() == 2 || 17306 n->as_Vector()->length() == 4); 17307 match(Set dst (LShiftVS src shift)); 17308 ins_cost(INSN_COST); 17309 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17310 ins_encode %{ 17311 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17312 as_FloatRegister($src$$reg), 17313 as_FloatRegister($shift$$reg)); 17314 %} 17315 ins_pipe(vshift64); 17316 %} 17317 17318 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17319 predicate(n->as_Vector()->length() == 8); 17320 match(Set dst (LShiftVS src shift)); 17321 ins_cost(INSN_COST); 17322 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17323 ins_encode %{ 17324 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17325 as_FloatRegister($src$$reg), 17326 as_FloatRegister($shift$$reg)); 17327 %} 17328 ins_pipe(vshift128); 17329 %} 17330 17331 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17332 predicate(n->as_Vector()->length() == 2 || 17333 n->as_Vector()->length() == 4); 17334 match(Set dst (RShiftVS src shift)); 17335 ins_cost(INSN_COST); 17336 effect(TEMP tmp); 17337 format %{ "negr $tmp,$shift\t" 17338 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17339 ins_encode %{ 17340 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17341 as_FloatRegister($shift$$reg)); 17342 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17343 as_FloatRegister($src$$reg), 17344 as_FloatRegister($tmp$$reg)); 17345 %} 17346 ins_pipe(vshift64); 17347 %} 17348 17349 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17350 predicate(n->as_Vector()->length() == 8); 17351 match(Set dst (RShiftVS src shift)); 17352 ins_cost(INSN_COST); 17353 effect(TEMP tmp); 17354 format %{ "negr $tmp,$shift\t" 17355 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17356 ins_encode %{ 17357 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17358 as_FloatRegister($shift$$reg)); 17359 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17360 as_FloatRegister($src$$reg), 17361 as_FloatRegister($tmp$$reg)); 17362 %} 17363 ins_pipe(vshift128); 17364 %} 17365 17366 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17367 predicate(n->as_Vector()->length() == 2 || 17368 n->as_Vector()->length() == 4); 17369 match(Set dst (URShiftVS src shift)); 17370 ins_cost(INSN_COST); 17371 effect(TEMP tmp); 17372 format %{ "negr $tmp,$shift\t" 17373 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17374 ins_encode %{ 17375 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17376 as_FloatRegister($shift$$reg)); 17377 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17378 as_FloatRegister($src$$reg), 17379 as_FloatRegister($tmp$$reg)); 17380 %} 17381 ins_pipe(vshift64); 17382 %} 17383 17384 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17385 predicate(n->as_Vector()->length() == 8); 17386 match(Set dst (URShiftVS src shift)); 17387 ins_cost(INSN_COST); 17388 effect(TEMP tmp); 17389 format %{ "negr $tmp,$shift\t" 17390 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17391 ins_encode %{ 17392 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17393 as_FloatRegister($shift$$reg)); 17394 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17395 as_FloatRegister($src$$reg), 17396 as_FloatRegister($tmp$$reg)); 17397 %} 17398 ins_pipe(vshift128); 17399 %} 17400 17401 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17402 predicate(n->as_Vector()->length() == 2 || 17403 n->as_Vector()->length() == 4); 17404 match(Set dst (LShiftVS src shift)); 17405 ins_cost(INSN_COST); 17406 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17407 ins_encode %{ 17408 int sh = (int)$shift$$constant; 17409 if (sh >= 16) { 17410 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17411 as_FloatRegister($src$$reg), 17412 as_FloatRegister($src$$reg)); 17413 } else { 17414 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17415 as_FloatRegister($src$$reg), sh); 17416 } 17417 %} 17418 ins_pipe(vshift64_imm); 17419 %} 17420 17421 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17422 predicate(n->as_Vector()->length() == 8); 17423 match(Set dst (LShiftVS src shift)); 17424 ins_cost(INSN_COST); 17425 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17426 ins_encode %{ 17427 int sh = (int)$shift$$constant; 17428 if (sh >= 16) { 17429 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17430 as_FloatRegister($src$$reg), 17431 as_FloatRegister($src$$reg)); 17432 } else { 17433 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17434 as_FloatRegister($src$$reg), sh); 17435 } 17436 %} 17437 ins_pipe(vshift128_imm); 17438 %} 17439 17440 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17441 predicate(n->as_Vector()->length() == 2 || 17442 n->as_Vector()->length() == 4); 17443 match(Set dst (RShiftVS src shift)); 17444 ins_cost(INSN_COST); 17445 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17446 ins_encode %{ 17447 int sh = (int)$shift$$constant; 17448 if (sh >= 16) sh = 15; 17449 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17450 as_FloatRegister($src$$reg), sh); 17451 %} 17452 ins_pipe(vshift64_imm); 17453 %} 17454 17455 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17456 predicate(n->as_Vector()->length() == 8); 17457 match(Set dst (RShiftVS src shift)); 17458 ins_cost(INSN_COST); 17459 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17460 ins_encode %{ 17461 int sh = (int)$shift$$constant; 17462 if (sh >= 16) sh = 15; 17463 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17464 as_FloatRegister($src$$reg), sh); 17465 %} 17466 ins_pipe(vshift128_imm); 17467 %} 17468 17469 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17470 predicate(n->as_Vector()->length() == 2 || 17471 n->as_Vector()->length() == 4); 17472 match(Set dst (URShiftVS src shift)); 17473 ins_cost(INSN_COST); 17474 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17475 ins_encode %{ 17476 int sh = (int)$shift$$constant; 17477 if (sh >= 16) { 17478 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17479 as_FloatRegister($src$$reg), 17480 as_FloatRegister($src$$reg)); 17481 } else { 17482 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17483 as_FloatRegister($src$$reg), sh); 17484 } 17485 %} 17486 ins_pipe(vshift64_imm); 17487 %} 17488 17489 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17490 predicate(n->as_Vector()->length() == 8); 17491 match(Set dst (URShiftVS src shift)); 17492 ins_cost(INSN_COST); 17493 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17494 ins_encode %{ 17495 int sh = (int)$shift$$constant; 17496 if (sh >= 16) { 17497 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17498 as_FloatRegister($src$$reg), 17499 as_FloatRegister($src$$reg)); 17500 } else { 17501 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17502 as_FloatRegister($src$$reg), sh); 17503 } 17504 %} 17505 ins_pipe(vshift128_imm); 17506 %} 17507 17508 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17509 predicate(n->as_Vector()->length() == 2); 17510 match(Set dst (LShiftVI src shift)); 17511 ins_cost(INSN_COST); 17512 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17513 ins_encode %{ 17514 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17515 as_FloatRegister($src$$reg), 17516 as_FloatRegister($shift$$reg)); 17517 %} 17518 ins_pipe(vshift64); 17519 %} 17520 17521 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17522 predicate(n->as_Vector()->length() == 4); 17523 match(Set dst (LShiftVI src shift)); 17524 ins_cost(INSN_COST); 17525 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17526 ins_encode %{ 17527 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17528 as_FloatRegister($src$$reg), 17529 as_FloatRegister($shift$$reg)); 17530 %} 17531 ins_pipe(vshift128); 17532 %} 17533 17534 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17535 predicate(n->as_Vector()->length() == 2); 17536 match(Set dst (RShiftVI src shift)); 17537 ins_cost(INSN_COST); 17538 effect(TEMP tmp); 17539 format %{ "negr $tmp,$shift\t" 17540 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17541 ins_encode %{ 17542 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17543 as_FloatRegister($shift$$reg)); 17544 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17545 as_FloatRegister($src$$reg), 17546 as_FloatRegister($tmp$$reg)); 17547 %} 17548 ins_pipe(vshift64); 17549 %} 17550 17551 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17552 predicate(n->as_Vector()->length() == 4); 17553 match(Set dst (RShiftVI src shift)); 17554 ins_cost(INSN_COST); 17555 effect(TEMP tmp); 17556 format %{ "negr $tmp,$shift\t" 17557 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17558 ins_encode %{ 17559 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17560 as_FloatRegister($shift$$reg)); 17561 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17562 as_FloatRegister($src$$reg), 17563 as_FloatRegister($tmp$$reg)); 17564 %} 17565 ins_pipe(vshift128); 17566 %} 17567 17568 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17569 predicate(n->as_Vector()->length() == 2); 17570 match(Set dst (URShiftVI src shift)); 17571 ins_cost(INSN_COST); 17572 effect(TEMP tmp); 17573 format %{ "negr $tmp,$shift\t" 17574 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17575 ins_encode %{ 17576 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17577 as_FloatRegister($shift$$reg)); 17578 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17579 as_FloatRegister($src$$reg), 17580 as_FloatRegister($tmp$$reg)); 17581 %} 17582 ins_pipe(vshift64); 17583 %} 17584 17585 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17586 predicate(n->as_Vector()->length() == 4); 17587 match(Set dst (URShiftVI src shift)); 17588 ins_cost(INSN_COST); 17589 effect(TEMP tmp); 17590 format %{ "negr $tmp,$shift\t" 17591 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17592 ins_encode %{ 17593 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17594 as_FloatRegister($shift$$reg)); 17595 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17596 as_FloatRegister($src$$reg), 17597 as_FloatRegister($tmp$$reg)); 17598 %} 17599 ins_pipe(vshift128); 17600 %} 17601 17602 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17603 predicate(n->as_Vector()->length() == 2); 17604 match(Set dst (LShiftVI src shift)); 17605 ins_cost(INSN_COST); 17606 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17607 ins_encode %{ 17608 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17609 as_FloatRegister($src$$reg), 17610 (int)$shift$$constant); 17611 %} 17612 ins_pipe(vshift64_imm); 17613 %} 17614 17615 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17616 predicate(n->as_Vector()->length() == 4); 17617 match(Set dst (LShiftVI src shift)); 17618 ins_cost(INSN_COST); 17619 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17620 ins_encode %{ 17621 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17622 as_FloatRegister($src$$reg), 17623 (int)$shift$$constant); 17624 %} 17625 ins_pipe(vshift128_imm); 17626 %} 17627 17628 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17629 predicate(n->as_Vector()->length() == 2); 17630 match(Set dst (RShiftVI src shift)); 17631 ins_cost(INSN_COST); 17632 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17633 ins_encode %{ 17634 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17635 as_FloatRegister($src$$reg), 17636 (int)$shift$$constant); 17637 %} 17638 ins_pipe(vshift64_imm); 17639 %} 17640 17641 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17642 predicate(n->as_Vector()->length() == 4); 17643 match(Set dst (RShiftVI src shift)); 17644 ins_cost(INSN_COST); 17645 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17646 ins_encode %{ 17647 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17648 as_FloatRegister($src$$reg), 17649 (int)$shift$$constant); 17650 %} 17651 ins_pipe(vshift128_imm); 17652 %} 17653 17654 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17655 predicate(n->as_Vector()->length() == 2); 17656 match(Set dst (URShiftVI src shift)); 17657 ins_cost(INSN_COST); 17658 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17659 ins_encode %{ 17660 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17661 as_FloatRegister($src$$reg), 17662 (int)$shift$$constant); 17663 %} 17664 ins_pipe(vshift64_imm); 17665 %} 17666 17667 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17668 predicate(n->as_Vector()->length() == 4); 17669 match(Set dst (URShiftVI src shift)); 17670 ins_cost(INSN_COST); 17671 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17672 ins_encode %{ 17673 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17674 as_FloatRegister($src$$reg), 17675 (int)$shift$$constant); 17676 %} 17677 ins_pipe(vshift128_imm); 17678 %} 17679 17680 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17681 predicate(n->as_Vector()->length() == 2); 17682 match(Set dst (LShiftVL src shift)); 17683 ins_cost(INSN_COST); 17684 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17685 ins_encode %{ 17686 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17687 as_FloatRegister($src$$reg), 17688 as_FloatRegister($shift$$reg)); 17689 %} 17690 ins_pipe(vshift128); 17691 %} 17692 17693 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17694 predicate(n->as_Vector()->length() == 2); 17695 match(Set dst (RShiftVL src shift)); 17696 ins_cost(INSN_COST); 17697 effect(TEMP tmp); 17698 format %{ "negr $tmp,$shift\t" 17699 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17700 ins_encode %{ 17701 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17702 as_FloatRegister($shift$$reg)); 17703 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17704 as_FloatRegister($src$$reg), 17705 as_FloatRegister($tmp$$reg)); 17706 %} 17707 ins_pipe(vshift128); 17708 %} 17709 17710 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17711 predicate(n->as_Vector()->length() == 2); 17712 match(Set dst (URShiftVL src shift)); 17713 ins_cost(INSN_COST); 17714 effect(TEMP tmp); 17715 format %{ "negr $tmp,$shift\t" 17716 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17717 ins_encode %{ 17718 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17719 as_FloatRegister($shift$$reg)); 17720 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17721 as_FloatRegister($src$$reg), 17722 as_FloatRegister($tmp$$reg)); 17723 %} 17724 ins_pipe(vshift128); 17725 %} 17726 17727 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17728 predicate(n->as_Vector()->length() == 2); 17729 match(Set dst (LShiftVL src shift)); 17730 ins_cost(INSN_COST); 17731 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17732 ins_encode %{ 17733 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17734 as_FloatRegister($src$$reg), 17735 (int)$shift$$constant); 17736 %} 17737 ins_pipe(vshift128_imm); 17738 %} 17739 17740 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17741 predicate(n->as_Vector()->length() == 2); 17742 match(Set dst (RShiftVL src shift)); 17743 ins_cost(INSN_COST); 17744 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17745 ins_encode %{ 17746 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17747 as_FloatRegister($src$$reg), 17748 (int)$shift$$constant); 17749 %} 17750 ins_pipe(vshift128_imm); 17751 %} 17752 17753 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17754 predicate(n->as_Vector()->length() == 2); 17755 match(Set dst (URShiftVL src shift)); 17756 ins_cost(INSN_COST); 17757 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17758 ins_encode %{ 17759 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17760 as_FloatRegister($src$$reg), 17761 (int)$shift$$constant); 17762 %} 17763 ins_pipe(vshift128_imm); 17764 %} 17765 17766 instruct vmax2F(vecD dst, vecD src1, vecD src2) 17767 %{ 17768 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17769 match(Set dst (MaxV src1 src2)); 17770 ins_cost(INSN_COST); 17771 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 17772 ins_encode %{ 17773 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 17774 as_FloatRegister($src1$$reg), 17775 as_FloatRegister($src2$$reg)); 17776 %} 17777 ins_pipe(vdop_fp64); 17778 %} 17779 17780 instruct vmax4F(vecX dst, vecX src1, vecX src2) 17781 %{ 17782 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17783 match(Set dst (MaxV src1 src2)); 17784 ins_cost(INSN_COST); 17785 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 17786 ins_encode %{ 17787 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 17788 as_FloatRegister($src1$$reg), 17789 as_FloatRegister($src2$$reg)); 17790 %} 17791 ins_pipe(vdop_fp128); 17792 %} 17793 17794 instruct vmax2D(vecX dst, vecX src1, vecX src2) 17795 %{ 17796 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17797 match(Set dst (MaxV src1 src2)); 17798 ins_cost(INSN_COST); 17799 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 17800 ins_encode %{ 17801 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 17802 as_FloatRegister($src1$$reg), 17803 as_FloatRegister($src2$$reg)); 17804 %} 17805 ins_pipe(vdop_fp128); 17806 %} 17807 17808 instruct vmin2F(vecD dst, vecD src1, vecD src2) 17809 %{ 17810 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17811 match(Set dst (MinV src1 src2)); 17812 ins_cost(INSN_COST); 17813 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 17814 ins_encode %{ 17815 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 17816 as_FloatRegister($src1$$reg), 17817 as_FloatRegister($src2$$reg)); 17818 %} 17819 ins_pipe(vdop_fp64); 17820 %} 17821 17822 instruct vmin4F(vecX dst, vecX src1, vecX src2) 17823 %{ 17824 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17825 match(Set dst (MinV src1 src2)); 17826 ins_cost(INSN_COST); 17827 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 17828 ins_encode %{ 17829 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 17830 as_FloatRegister($src1$$reg), 17831 as_FloatRegister($src2$$reg)); 17832 %} 17833 ins_pipe(vdop_fp128); 17834 %} 17835 17836 instruct vmin2D(vecX dst, vecX src1, vecX src2) 17837 %{ 17838 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17839 match(Set dst (MinV src1 src2)); 17840 ins_cost(INSN_COST); 17841 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 17842 ins_encode %{ 17843 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 17844 as_FloatRegister($src1$$reg), 17845 as_FloatRegister($src2$$reg)); 17846 %} 17847 ins_pipe(vdop_fp128); 17848 %} 17849 17850 //----------PEEPHOLE RULES----------------------------------------------------- 17851 // These must follow all instruction definitions as they use the names 17852 // defined in the instructions definitions. 17853 // 17854 // peepmatch ( root_instr_name [preceding_instruction]* ); 17855 // 17856 // peepconstraint %{ 17857 // (instruction_number.operand_name relational_op instruction_number.operand_name 17858 // [, ...] ); 17859 // // instruction numbers are zero-based using left to right order in peepmatch 17860 // 17861 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17862 // // provide an instruction_number.operand_name for each operand that appears 17863 // // in the replacement instruction's match rule 17864 // 17865 // ---------VM FLAGS--------------------------------------------------------- 17866 // 17867 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17868 // 17869 // Each peephole rule is given an identifying number starting with zero and 17870 // increasing by one in the order seen by the parser. An individual peephole 17871 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17872 // on the command-line. 17873 // 17874 // ---------CURRENT LIMITATIONS---------------------------------------------- 17875 // 17876 // Only match adjacent instructions in same basic block 17877 // Only equality constraints 17878 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17879 // Only one replacement instruction 17880 // 17881 // ---------EXAMPLE---------------------------------------------------------- 17882 // 17883 // // pertinent parts of existing instructions in architecture description 17884 // instruct movI(iRegINoSp dst, iRegI src) 17885 // %{ 17886 // match(Set dst (CopyI src)); 17887 // %} 17888 // 17889 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17890 // %{ 17891 // match(Set dst (AddI dst src)); 17892 // effect(KILL cr); 17893 // %} 17894 // 17895 // // Change (inc mov) to lea 17896 // peephole %{ 17897 // // increment preceeded by register-register move 17898 // peepmatch ( incI_iReg movI ); 17899 // // require that the destination register of the increment 17900 // // match the destination register of the move 17901 // peepconstraint ( 0.dst == 1.dst ); 17902 // // construct a replacement instruction that sets 17903 // // the destination to ( move's source register + one ) 17904 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17905 // %} 17906 // 17907 17908 // Implementation no longer uses movX instructions since 17909 // machine-independent system no longer uses CopyX nodes. 17910 // 17911 // peephole 17912 // %{ 17913 // peepmatch (incI_iReg movI); 17914 // peepconstraint (0.dst == 1.dst); 17915 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17916 // %} 17917 17918 // peephole 17919 // %{ 17920 // peepmatch (decI_iReg movI); 17921 // peepconstraint (0.dst == 1.dst); 17922 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17923 // %} 17924 17925 // peephole 17926 // %{ 17927 // peepmatch (addI_iReg_imm movI); 17928 // peepconstraint (0.dst == 1.dst); 17929 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17930 // %} 17931 17932 // peephole 17933 // %{ 17934 // peepmatch (incL_iReg movL); 17935 // peepconstraint (0.dst == 1.dst); 17936 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17937 // %} 17938 17939 // peephole 17940 // %{ 17941 // peepmatch (decL_iReg movL); 17942 // peepconstraint (0.dst == 1.dst); 17943 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17944 // %} 17945 17946 // peephole 17947 // %{ 17948 // peepmatch (addL_iReg_imm movL); 17949 // peepconstraint (0.dst == 1.dst); 17950 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17951 // %} 17952 17953 // peephole 17954 // %{ 17955 // peepmatch (addP_iReg_imm movP); 17956 // peepconstraint (0.dst == 1.dst); 17957 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17958 // %} 17959 17960 // // Change load of spilled value to only a spill 17961 // instruct storeI(memory mem, iRegI src) 17962 // %{ 17963 // match(Set mem (StoreI mem src)); 17964 // %} 17965 // 17966 // instruct loadI(iRegINoSp dst, memory mem) 17967 // %{ 17968 // match(Set dst (LoadI mem)); 17969 // %} 17970 // 17971 17972 //----------SMARTSPILL RULES--------------------------------------------------- 17973 // These must follow all instruction definitions as they use the names 17974 // defined in the instructions definitions. 17975 17976 // Local Variables: 17977 // mode: c++ 17978 // End: