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 addressing modes 1196 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1197 %} 1198 1199 source %{ 1200 1201 // Optimizaton of volatile gets and puts 1202 // ------------------------------------- 1203 // 1204 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1205 // use to implement volatile reads and writes. For a volatile read 1206 // we simply need 1207 // 1208 // ldar<x> 1209 // 1210 // and for a volatile write we need 1211 // 1212 // stlr<x> 1213 // 1214 // Alternatively, we can implement them by pairing a normal 1215 // load/store with a memory barrier. For a volatile read we need 1216 // 1217 // ldr<x> 1218 // dmb ishld 1219 // 1220 // for a volatile write 1221 // 1222 // dmb ish 1223 // str<x> 1224 // dmb ish 1225 // 1226 // We can also use ldaxr and stlxr to implement compare and swap CAS 1227 // sequences. These are normally translated to an instruction 1228 // sequence like the following 1229 // 1230 // dmb ish 1231 // retry: 1232 // ldxr<x> rval raddr 1233 // cmp rval rold 1234 // b.ne done 1235 // stlxr<x> rval, rnew, rold 1236 // cbnz rval retry 1237 // done: 1238 // cset r0, eq 1239 // dmb ishld 1240 // 1241 // Note that the exclusive store is already using an stlxr 1242 // instruction. That is required to ensure visibility to other 1243 // threads of the exclusive write (assuming it succeeds) before that 1244 // of any subsequent writes. 1245 // 1246 // The following instruction sequence is an improvement on the above 1247 // 1248 // retry: 1249 // ldaxr<x> rval raddr 1250 // cmp rval rold 1251 // b.ne done 1252 // stlxr<x> rval, rnew, rold 1253 // cbnz rval retry 1254 // done: 1255 // cset r0, eq 1256 // 1257 // We don't need the leading dmb ish since the stlxr guarantees 1258 // visibility of prior writes in the case that the swap is 1259 // successful. Crucially we don't have to worry about the case where 1260 // the swap is not successful since no valid program should be 1261 // relying on visibility of prior changes by the attempting thread 1262 // in the case where the CAS fails. 1263 // 1264 // Similarly, we don't need the trailing dmb ishld if we substitute 1265 // an ldaxr instruction since that will provide all the guarantees we 1266 // require regarding observation of changes made by other threads 1267 // before any change to the CAS address observed by the load. 1268 // 1269 // In order to generate the desired instruction sequence we need to 1270 // be able to identify specific 'signature' ideal graph node 1271 // sequences which i) occur as a translation of a volatile reads or 1272 // writes or CAS operations and ii) do not occur through any other 1273 // translation or graph transformation. We can then provide 1274 // alternative aldc matching rules which translate these node 1275 // sequences to the desired machine code sequences. Selection of the 1276 // alternative rules can be implemented by predicates which identify 1277 // the relevant node sequences. 1278 // 1279 // The ideal graph generator translates a volatile read to the node 1280 // sequence 1281 // 1282 // LoadX[mo_acquire] 1283 // MemBarAcquire 1284 // 1285 // As a special case when using the compressed oops optimization we 1286 // may also see this variant 1287 // 1288 // LoadN[mo_acquire] 1289 // DecodeN 1290 // MemBarAcquire 1291 // 1292 // A volatile write is translated to the node sequence 1293 // 1294 // MemBarRelease 1295 // StoreX[mo_release] {CardMark}-optional 1296 // MemBarVolatile 1297 // 1298 // n.b. the above node patterns are generated with a strict 1299 // 'signature' configuration of input and output dependencies (see 1300 // the predicates below for exact details). The card mark may be as 1301 // simple as a few extra nodes or, in a few GC configurations, may 1302 // include more complex control flow between the leading and 1303 // trailing memory barriers. However, whatever the card mark 1304 // configuration these signatures are unique to translated volatile 1305 // reads/stores -- they will not appear as a result of any other 1306 // bytecode translation or inlining nor as a consequence of 1307 // optimizing transforms. 1308 // 1309 // We also want to catch inlined unsafe volatile gets and puts and 1310 // be able to implement them using either ldar<x>/stlr<x> or some 1311 // combination of ldr<x>/stlr<x> and dmb instructions. 1312 // 1313 // Inlined unsafe volatiles puts manifest as a minor variant of the 1314 // normal volatile put node sequence containing an extra cpuorder 1315 // membar 1316 // 1317 // MemBarRelease 1318 // MemBarCPUOrder 1319 // StoreX[mo_release] {CardMark}-optional 1320 // MemBarCPUOrder 1321 // MemBarVolatile 1322 // 1323 // n.b. as an aside, a cpuorder membar is not itself subject to 1324 // matching and translation by adlc rules. However, the rule 1325 // predicates need to detect its presence in order to correctly 1326 // select the desired adlc rules. 1327 // 1328 // Inlined unsafe volatile gets manifest as a slightly different 1329 // node sequence to a normal volatile get because of the 1330 // introduction of some CPUOrder memory barriers to bracket the 1331 // Load. However, but the same basic skeleton of a LoadX feeding a 1332 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1333 // present 1334 // 1335 // MemBarCPUOrder 1336 // || \\ 1337 // MemBarCPUOrder LoadX[mo_acquire] 1338 // || | 1339 // || {DecodeN} optional 1340 // || / 1341 // MemBarAcquire 1342 // 1343 // In this case the acquire membar does not directly depend on the 1344 // load. However, we can be sure that the load is generated from an 1345 // inlined unsafe volatile get if we see it dependent on this unique 1346 // sequence of membar nodes. Similarly, given an acquire membar we 1347 // can know that it was added because of an inlined unsafe volatile 1348 // get if it is fed and feeds a cpuorder membar and if its feed 1349 // membar also feeds an acquiring load. 1350 // 1351 // Finally an inlined (Unsafe) CAS operation is translated to the 1352 // following ideal graph 1353 // 1354 // MemBarRelease 1355 // MemBarCPUOrder 1356 // CompareAndSwapX {CardMark}-optional 1357 // MemBarCPUOrder 1358 // MemBarAcquire 1359 // 1360 // So, where we can identify these volatile read and write 1361 // signatures we can choose to plant either of the above two code 1362 // sequences. For a volatile read we can simply plant a normal 1363 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1364 // also choose to inhibit translation of the MemBarAcquire and 1365 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1366 // 1367 // When we recognise a volatile store signature we can choose to 1368 // plant at a dmb ish as a translation for the MemBarRelease, a 1369 // normal str<x> and then a dmb ish for the MemBarVolatile. 1370 // Alternatively, we can inhibit translation of the MemBarRelease 1371 // and MemBarVolatile and instead plant a simple stlr<x> 1372 // instruction. 1373 // 1374 // when we recognise a CAS signature we can choose to plant a dmb 1375 // ish as a translation for the MemBarRelease, the conventional 1376 // macro-instruction sequence for the CompareAndSwap node (which 1377 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1378 // Alternatively, we can elide generation of the dmb instructions 1379 // and plant the alternative CompareAndSwap macro-instruction 1380 // sequence (which uses ldaxr<x>). 1381 // 1382 // Of course, the above only applies when we see these signature 1383 // configurations. We still want to plant dmb instructions in any 1384 // other cases where we may see a MemBarAcquire, MemBarRelease or 1385 // MemBarVolatile. For example, at the end of a constructor which 1386 // writes final/volatile fields we will see a MemBarRelease 1387 // instruction and this needs a 'dmb ish' lest we risk the 1388 // constructed object being visible without making the 1389 // final/volatile field writes visible. 1390 // 1391 // n.b. the translation rules below which rely on detection of the 1392 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1393 // If we see anything other than the signature configurations we 1394 // always just translate the loads and stores to ldr<x> and str<x> 1395 // and translate acquire, release and volatile membars to the 1396 // relevant dmb instructions. 1397 // 1398 1399 // is_CAS(int opcode, bool maybe_volatile) 1400 // 1401 // return true if opcode is one of the possible CompareAndSwapX 1402 // values otherwise false. 1403 1404 bool is_CAS(int opcode, bool maybe_volatile) 1405 { 1406 switch(opcode) { 1407 // We handle these 1408 case Op_CompareAndSwapI: 1409 case Op_CompareAndSwapL: 1410 case Op_CompareAndSwapP: 1411 case Op_CompareAndSwapN: 1412 case Op_ShenandoahCompareAndSwapP: 1413 case Op_ShenandoahCompareAndSwapN: 1414 case Op_CompareAndSwapB: 1415 case Op_CompareAndSwapS: 1416 case Op_GetAndSetI: 1417 case Op_GetAndSetL: 1418 case Op_GetAndSetP: 1419 case Op_GetAndSetN: 1420 case Op_GetAndAddI: 1421 case Op_GetAndAddL: 1422 return true; 1423 case Op_CompareAndExchangeI: 1424 case Op_CompareAndExchangeN: 1425 case Op_CompareAndExchangeB: 1426 case Op_CompareAndExchangeS: 1427 case Op_CompareAndExchangeL: 1428 case Op_CompareAndExchangeP: 1429 case Op_WeakCompareAndSwapB: 1430 case Op_WeakCompareAndSwapS: 1431 case Op_WeakCompareAndSwapI: 1432 case Op_WeakCompareAndSwapL: 1433 case Op_WeakCompareAndSwapP: 1434 case Op_WeakCompareAndSwapN: 1435 case Op_ShenandoahWeakCompareAndSwapP: 1436 case Op_ShenandoahWeakCompareAndSwapN: 1437 case Op_ShenandoahCompareAndExchangeP: 1438 case Op_ShenandoahCompareAndExchangeN: 1439 return maybe_volatile; 1440 default: 1441 return false; 1442 } 1443 } 1444 1445 // helper to determine the maximum number of Phi nodes we may need to 1446 // traverse when searching from a card mark membar for the merge mem 1447 // feeding a trailing membar or vice versa 1448 1449 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1450 1451 bool unnecessary_acquire(const Node *barrier) 1452 { 1453 assert(barrier->is_MemBar(), "expecting a membar"); 1454 1455 if (UseBarriersForVolatile) { 1456 // we need to plant a dmb 1457 return false; 1458 } 1459 1460 MemBarNode* mb = barrier->as_MemBar(); 1461 1462 if (mb->trailing_load()) { 1463 return true; 1464 } 1465 1466 if (mb->trailing_load_store()) { 1467 Node* load_store = mb->in(MemBarNode::Precedent); 1468 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1469 return is_CAS(load_store->Opcode(), true); 1470 } 1471 1472 return false; 1473 } 1474 1475 bool needs_acquiring_load(const Node *n) 1476 { 1477 assert(n->is_Load(), "expecting a load"); 1478 if (UseBarriersForVolatile) { 1479 // we use a normal load and a dmb 1480 return false; 1481 } 1482 1483 LoadNode *ld = n->as_Load(); 1484 1485 return ld->is_acquire(); 1486 } 1487 1488 bool unnecessary_release(const Node *n) 1489 { 1490 assert((n->is_MemBar() && 1491 n->Opcode() == Op_MemBarRelease), 1492 "expecting a release membar"); 1493 1494 if (UseBarriersForVolatile) { 1495 // we need to plant a dmb 1496 return false; 1497 } 1498 1499 MemBarNode *barrier = n->as_MemBar(); 1500 if (!barrier->leading()) { 1501 return false; 1502 } else { 1503 Node* trailing = barrier->trailing_membar(); 1504 MemBarNode* trailing_mb = trailing->as_MemBar(); 1505 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1506 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1507 1508 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1509 if (mem->is_Store()) { 1510 assert(mem->as_Store()->is_release(), ""); 1511 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1512 return true; 1513 } else { 1514 assert(mem->is_LoadStore(), ""); 1515 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1516 return is_CAS(mem->Opcode(), true); 1517 } 1518 } 1519 return false; 1520 } 1521 1522 bool unnecessary_volatile(const Node *n) 1523 { 1524 // assert n->is_MemBar(); 1525 if (UseBarriersForVolatile) { 1526 // we need to plant a dmb 1527 return false; 1528 } 1529 1530 MemBarNode *mbvol = n->as_MemBar(); 1531 1532 bool release = mbvol->trailing_store(); 1533 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1534 #ifdef ASSERT 1535 if (release) { 1536 Node* leading = mbvol->leading_membar(); 1537 assert(leading->Opcode() == Op_MemBarRelease, ""); 1538 assert(leading->as_MemBar()->leading_store(), ""); 1539 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1540 } 1541 #endif 1542 1543 return release; 1544 } 1545 1546 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1547 1548 bool needs_releasing_store(const Node *n) 1549 { 1550 // assert n->is_Store(); 1551 if (UseBarriersForVolatile) { 1552 // we use a normal store and dmb combination 1553 return false; 1554 } 1555 1556 StoreNode *st = n->as_Store(); 1557 1558 return st->trailing_membar() != NULL; 1559 } 1560 1561 // predicate controlling translation of CAS 1562 // 1563 // returns true if CAS needs to use an acquiring load otherwise false 1564 1565 bool needs_acquiring_load_exclusive(const Node *n) 1566 { 1567 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1568 if (UseBarriersForVolatile) { 1569 return false; 1570 } 1571 1572 LoadStoreNode* ldst = n->as_LoadStore(); 1573 if (is_CAS(n->Opcode(), false)) { 1574 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1575 } else { 1576 return ldst->trailing_membar() != NULL; 1577 } 1578 1579 // so we can just return true here 1580 return true; 1581 } 1582 1583 #define __ _masm. 1584 1585 // advance declarations for helper functions to convert register 1586 // indices to register objects 1587 1588 // the ad file has to provide implementations of certain methods 1589 // expected by the generic code 1590 // 1591 // REQUIRED FUNCTIONALITY 1592 1593 //============================================================================= 1594 1595 // !!!!! Special hack to get all types of calls to specify the byte offset 1596 // from the start of the call to the point where the return address 1597 // will point. 1598 1599 int MachCallStaticJavaNode::ret_addr_offset() 1600 { 1601 // call should be a simple bl 1602 int off = 4; 1603 return off; 1604 } 1605 1606 int MachCallDynamicJavaNode::ret_addr_offset() 1607 { 1608 return 16; // movz, movk, movk, bl 1609 } 1610 1611 int MachCallRuntimeNode::ret_addr_offset() { 1612 // for generated stubs the call will be 1613 // far_call(addr) 1614 // for real runtime callouts it will be six instructions 1615 // see aarch64_enc_java_to_runtime 1616 // adr(rscratch2, retaddr) 1617 // lea(rscratch1, RuntimeAddress(addr) 1618 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1619 // blr(rscratch1) 1620 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1621 if (cb) { 1622 return MacroAssembler::far_branch_size(); 1623 } else { 1624 return 6 * NativeInstruction::instruction_size; 1625 } 1626 } 1627 1628 // Indicate if the safepoint node needs the polling page as an input 1629 1630 // the shared code plants the oop data at the start of the generated 1631 // code for the safepoint node and that needs ot be at the load 1632 // instruction itself. so we cannot plant a mov of the safepoint poll 1633 // address followed by a load. setting this to true means the mov is 1634 // scheduled as a prior instruction. that's better for scheduling 1635 // anyway. 1636 1637 bool SafePointNode::needs_polling_address_input() 1638 { 1639 return true; 1640 } 1641 1642 //============================================================================= 1643 1644 #ifndef PRODUCT 1645 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1646 st->print("BREAKPOINT"); 1647 } 1648 #endif 1649 1650 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1651 MacroAssembler _masm(&cbuf); 1652 __ brk(0); 1653 } 1654 1655 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1656 return MachNode::size(ra_); 1657 } 1658 1659 //============================================================================= 1660 1661 #ifndef PRODUCT 1662 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1663 st->print("nop \t# %d bytes pad for loops and calls", _count); 1664 } 1665 #endif 1666 1667 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1668 MacroAssembler _masm(&cbuf); 1669 for (int i = 0; i < _count; i++) { 1670 __ nop(); 1671 } 1672 } 1673 1674 uint MachNopNode::size(PhaseRegAlloc*) const { 1675 return _count * NativeInstruction::instruction_size; 1676 } 1677 1678 //============================================================================= 1679 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1680 1681 int Compile::ConstantTable::calculate_table_base_offset() const { 1682 return 0; // absolute addressing, no offset 1683 } 1684 1685 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1686 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1687 ShouldNotReachHere(); 1688 } 1689 1690 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1691 // Empty encoding 1692 } 1693 1694 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1695 return 0; 1696 } 1697 1698 #ifndef PRODUCT 1699 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1700 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1701 } 1702 #endif 1703 1704 #ifndef PRODUCT 1705 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1706 Compile* C = ra_->C; 1707 1708 int framesize = C->frame_slots() << LogBytesPerInt; 1709 1710 if (C->need_stack_bang(framesize)) 1711 st->print("# stack bang size=%d\n\t", framesize); 1712 1713 if (framesize < ((1 << 9) + 2 * wordSize)) { 1714 st->print("sub sp, sp, #%d\n\t", framesize); 1715 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1716 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1717 } else { 1718 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1719 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1720 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1721 st->print("sub sp, sp, rscratch1"); 1722 } 1723 } 1724 #endif 1725 1726 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1727 Compile* C = ra_->C; 1728 MacroAssembler _masm(&cbuf); 1729 1730 // n.b. frame size includes space for return pc and rfp 1731 const long framesize = C->frame_size_in_bytes(); 1732 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1733 1734 // insert a nop at the start of the prolog so we can patch in a 1735 // branch if we need to invalidate the method later 1736 __ nop(); 1737 1738 if (C->clinit_barrier_on_entry()) { 1739 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1740 1741 Label L_skip_barrier; 1742 1743 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1744 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1745 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1746 __ bind(L_skip_barrier); 1747 } 1748 1749 int bangsize = C->bang_size_in_bytes(); 1750 if (C->need_stack_bang(bangsize) && UseStackBanging) 1751 __ generate_stack_overflow_check(bangsize); 1752 1753 __ build_frame(framesize); 1754 1755 if (VerifyStackAtCalls) { 1756 Unimplemented(); 1757 } 1758 1759 C->set_frame_complete(cbuf.insts_size()); 1760 1761 if (C->has_mach_constant_base_node()) { 1762 // NOTE: We set the table base offset here because users might be 1763 // emitted before MachConstantBaseNode. 1764 Compile::ConstantTable& constant_table = C->constant_table(); 1765 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1766 } 1767 } 1768 1769 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1770 { 1771 return MachNode::size(ra_); // too many variables; just compute it 1772 // the hard way 1773 } 1774 1775 int MachPrologNode::reloc() const 1776 { 1777 return 0; 1778 } 1779 1780 //============================================================================= 1781 1782 #ifndef PRODUCT 1783 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1784 Compile* C = ra_->C; 1785 int framesize = C->frame_slots() << LogBytesPerInt; 1786 1787 st->print("# pop frame %d\n\t",framesize); 1788 1789 if (framesize == 0) { 1790 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1791 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1792 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1793 st->print("add sp, sp, #%d\n\t", framesize); 1794 } else { 1795 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1796 st->print("add sp, sp, rscratch1\n\t"); 1797 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1798 } 1799 1800 if (do_polling() && C->is_method_compilation()) { 1801 st->print("# touch polling page\n\t"); 1802 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1803 st->print("ldr zr, [rscratch1]"); 1804 } 1805 } 1806 #endif 1807 1808 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1809 Compile* C = ra_->C; 1810 MacroAssembler _masm(&cbuf); 1811 int framesize = C->frame_slots() << LogBytesPerInt; 1812 1813 __ remove_frame(framesize); 1814 1815 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1816 __ reserved_stack_check(); 1817 } 1818 1819 if (do_polling() && C->is_method_compilation()) { 1820 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1821 } 1822 } 1823 1824 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1825 // Variable size. Determine dynamically. 1826 return MachNode::size(ra_); 1827 } 1828 1829 int MachEpilogNode::reloc() const { 1830 // Return number of relocatable values contained in this instruction. 1831 return 1; // 1 for polling page. 1832 } 1833 1834 const Pipeline * MachEpilogNode::pipeline() const { 1835 return MachNode::pipeline_class(); 1836 } 1837 1838 // This method seems to be obsolete. It is declared in machnode.hpp 1839 // and defined in all *.ad files, but it is never called. Should we 1840 // get rid of it? 1841 int MachEpilogNode::safepoint_offset() const { 1842 assert(do_polling(), "no return for this epilog node"); 1843 return 4; 1844 } 1845 1846 //============================================================================= 1847 1848 // Figure out which register class each belongs in: rc_int, rc_float or 1849 // rc_stack. 1850 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1851 1852 static enum RC rc_class(OptoReg::Name reg) { 1853 1854 if (reg == OptoReg::Bad) { 1855 return rc_bad; 1856 } 1857 1858 // we have 30 int registers * 2 halves 1859 // (rscratch1 and rscratch2 are omitted) 1860 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1861 1862 if (reg < slots_of_int_registers) { 1863 return rc_int; 1864 } 1865 1866 // we have 32 float register * 4 halves 1867 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1868 return rc_float; 1869 } 1870 1871 // Between float regs & stack is the flags regs. 1872 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1873 1874 return rc_stack; 1875 } 1876 1877 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1878 Compile* C = ra_->C; 1879 1880 // Get registers to move. 1881 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1882 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1883 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1884 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1885 1886 enum RC src_hi_rc = rc_class(src_hi); 1887 enum RC src_lo_rc = rc_class(src_lo); 1888 enum RC dst_hi_rc = rc_class(dst_hi); 1889 enum RC dst_lo_rc = rc_class(dst_lo); 1890 1891 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1892 1893 if (src_hi != OptoReg::Bad) { 1894 assert((src_lo&1)==0 && src_lo+1==src_hi && 1895 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1896 "expected aligned-adjacent pairs"); 1897 } 1898 1899 if (src_lo == dst_lo && src_hi == dst_hi) { 1900 return 0; // Self copy, no move. 1901 } 1902 1903 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1904 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1905 int src_offset = ra_->reg2offset(src_lo); 1906 int dst_offset = ra_->reg2offset(dst_lo); 1907 1908 if (bottom_type()->isa_vect() != NULL) { 1909 uint ireg = ideal_reg(); 1910 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1911 if (cbuf) { 1912 MacroAssembler _masm(cbuf); 1913 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1914 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1915 // stack->stack 1916 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1917 if (ireg == Op_VecD) { 1918 __ unspill(rscratch1, true, src_offset); 1919 __ spill(rscratch1, true, dst_offset); 1920 } else { 1921 __ spill_copy128(src_offset, dst_offset); 1922 } 1923 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1924 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1925 ireg == Op_VecD ? __ T8B : __ T16B, 1926 as_FloatRegister(Matcher::_regEncode[src_lo])); 1927 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1928 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1929 ireg == Op_VecD ? __ D : __ Q, 1930 ra_->reg2offset(dst_lo)); 1931 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1932 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1933 ireg == Op_VecD ? __ D : __ Q, 1934 ra_->reg2offset(src_lo)); 1935 } else { 1936 ShouldNotReachHere(); 1937 } 1938 } 1939 } else if (cbuf) { 1940 MacroAssembler _masm(cbuf); 1941 switch (src_lo_rc) { 1942 case rc_int: 1943 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1944 if (is64) { 1945 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1946 as_Register(Matcher::_regEncode[src_lo])); 1947 } else { 1948 MacroAssembler _masm(cbuf); 1949 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1950 as_Register(Matcher::_regEncode[src_lo])); 1951 } 1952 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1953 if (is64) { 1954 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1955 as_Register(Matcher::_regEncode[src_lo])); 1956 } else { 1957 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1958 as_Register(Matcher::_regEncode[src_lo])); 1959 } 1960 } else { // gpr --> stack spill 1961 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1962 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1963 } 1964 break; 1965 case rc_float: 1966 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1967 if (is64) { 1968 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1969 as_FloatRegister(Matcher::_regEncode[src_lo])); 1970 } else { 1971 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1972 as_FloatRegister(Matcher::_regEncode[src_lo])); 1973 } 1974 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1975 if (cbuf) { 1976 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1977 as_FloatRegister(Matcher::_regEncode[src_lo])); 1978 } else { 1979 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1980 as_FloatRegister(Matcher::_regEncode[src_lo])); 1981 } 1982 } else { // fpr --> stack spill 1983 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1984 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1985 is64 ? __ D : __ S, dst_offset); 1986 } 1987 break; 1988 case rc_stack: 1989 if (dst_lo_rc == rc_int) { // stack --> gpr load 1990 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1991 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1992 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1993 is64 ? __ D : __ S, src_offset); 1994 } else { // stack --> stack copy 1995 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1996 __ unspill(rscratch1, is64, src_offset); 1997 __ spill(rscratch1, is64, dst_offset); 1998 } 1999 break; 2000 default: 2001 assert(false, "bad rc_class for spill"); 2002 ShouldNotReachHere(); 2003 } 2004 } 2005 2006 if (st) { 2007 st->print("spill "); 2008 if (src_lo_rc == rc_stack) { 2009 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2010 } else { 2011 st->print("%s -> ", Matcher::regName[src_lo]); 2012 } 2013 if (dst_lo_rc == rc_stack) { 2014 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2015 } else { 2016 st->print("%s", Matcher::regName[dst_lo]); 2017 } 2018 if (bottom_type()->isa_vect() != NULL) { 2019 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 2020 } else { 2021 st->print("\t# spill size = %d", is64 ? 64:32); 2022 } 2023 } 2024 2025 return 0; 2026 2027 } 2028 2029 #ifndef PRODUCT 2030 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2031 if (!ra_) 2032 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2033 else 2034 implementation(NULL, ra_, false, st); 2035 } 2036 #endif 2037 2038 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2039 implementation(&cbuf, ra_, false, NULL); 2040 } 2041 2042 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2043 return MachNode::size(ra_); 2044 } 2045 2046 //============================================================================= 2047 2048 #ifndef PRODUCT 2049 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2050 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2051 int reg = ra_->get_reg_first(this); 2052 st->print("add %s, rsp, #%d]\t# box lock", 2053 Matcher::regName[reg], offset); 2054 } 2055 #endif 2056 2057 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2058 MacroAssembler _masm(&cbuf); 2059 2060 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2061 int reg = ra_->get_encode(this); 2062 2063 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2064 __ add(as_Register(reg), sp, offset); 2065 } else { 2066 ShouldNotReachHere(); 2067 } 2068 } 2069 2070 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2071 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2072 return 4; 2073 } 2074 2075 //============================================================================= 2076 2077 #ifndef PRODUCT 2078 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2079 { 2080 st->print_cr("# MachUEPNode"); 2081 if (UseCompressedClassPointers) { 2082 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2083 if (CompressedKlassPointers::shift() != 0) { 2084 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2085 } 2086 } else { 2087 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2088 } 2089 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2090 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2091 } 2092 #endif 2093 2094 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2095 { 2096 // This is the unverified entry point. 2097 MacroAssembler _masm(&cbuf); 2098 2099 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2100 Label skip; 2101 // TODO 2102 // can we avoid this skip and still use a reloc? 2103 __ br(Assembler::EQ, skip); 2104 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2105 __ bind(skip); 2106 } 2107 2108 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2109 { 2110 return MachNode::size(ra_); 2111 } 2112 2113 // REQUIRED EMIT CODE 2114 2115 //============================================================================= 2116 2117 // Emit exception handler code. 2118 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2119 { 2120 // mov rscratch1 #exception_blob_entry_point 2121 // br rscratch1 2122 // Note that the code buffer's insts_mark is always relative to insts. 2123 // That's why we must use the macroassembler to generate a handler. 2124 MacroAssembler _masm(&cbuf); 2125 address base = __ start_a_stub(size_exception_handler()); 2126 if (base == NULL) { 2127 ciEnv::current()->record_failure("CodeCache is full"); 2128 return 0; // CodeBuffer::expand failed 2129 } 2130 int offset = __ offset(); 2131 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2132 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2133 __ end_a_stub(); 2134 return offset; 2135 } 2136 2137 // Emit deopt handler code. 2138 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2139 { 2140 // Note that the code buffer's insts_mark is always relative to insts. 2141 // That's why we must use the macroassembler to generate a handler. 2142 MacroAssembler _masm(&cbuf); 2143 address base = __ start_a_stub(size_deopt_handler()); 2144 if (base == NULL) { 2145 ciEnv::current()->record_failure("CodeCache is full"); 2146 return 0; // CodeBuffer::expand failed 2147 } 2148 int offset = __ offset(); 2149 2150 __ adr(lr, __ pc()); 2151 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2152 2153 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2154 __ end_a_stub(); 2155 return offset; 2156 } 2157 2158 // REQUIRED MATCHER CODE 2159 2160 //============================================================================= 2161 2162 const bool Matcher::match_rule_supported(int opcode) { 2163 if (!has_match_rule(opcode)) 2164 return false; 2165 2166 bool ret_value = true; 2167 switch (opcode) { 2168 case Op_CacheWB: 2169 case Op_CacheWBPreSync: 2170 case Op_CacheWBPostSync: 2171 if (!VM_Version::supports_data_cache_line_flush()) { 2172 ret_value = false; 2173 } 2174 break; 2175 } 2176 2177 return ret_value; // Per default match rules are supported. 2178 } 2179 2180 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2181 2182 // TODO 2183 // identify extra cases that we might want to provide match rules for 2184 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2185 bool ret_value = match_rule_supported(opcode); 2186 // Add rules here. 2187 2188 return ret_value; // Per default match rules are supported. 2189 } 2190 2191 const bool Matcher::has_predicated_vectors(void) { 2192 return false; 2193 } 2194 2195 const int Matcher::float_pressure(int default_pressure_threshold) { 2196 return default_pressure_threshold; 2197 } 2198 2199 int Matcher::regnum_to_fpu_offset(int regnum) 2200 { 2201 Unimplemented(); 2202 return 0; 2203 } 2204 2205 // Is this branch offset short enough that a short branch can be used? 2206 // 2207 // NOTE: If the platform does not provide any short branch variants, then 2208 // this method should return false for offset 0. 2209 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2210 // The passed offset is relative to address of the branch. 2211 2212 return (-32768 <= offset && offset < 32768); 2213 } 2214 2215 const bool Matcher::isSimpleConstant64(jlong value) { 2216 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2217 // Probably always true, even if a temp register is required. 2218 return true; 2219 } 2220 2221 // true just means we have fast l2f conversion 2222 const bool Matcher::convL2FSupported(void) { 2223 return true; 2224 } 2225 2226 // Vector width in bytes. 2227 const int Matcher::vector_width_in_bytes(BasicType bt) { 2228 int size = MIN2(16,(int)MaxVectorSize); 2229 // Minimum 2 values in vector 2230 if (size < 2*type2aelembytes(bt)) size = 0; 2231 // But never < 4 2232 if (size < 4) size = 0; 2233 return size; 2234 } 2235 2236 // Limits on vector size (number of elements) loaded into vector. 2237 const int Matcher::max_vector_size(const BasicType bt) { 2238 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2239 } 2240 const int Matcher::min_vector_size(const BasicType bt) { 2241 // For the moment limit the vector size to 8 bytes 2242 int size = 8 / type2aelembytes(bt); 2243 if (size < 2) size = 2; 2244 return size; 2245 } 2246 2247 // Vector ideal reg. 2248 const uint Matcher::vector_ideal_reg(int len) { 2249 switch(len) { 2250 case 8: return Op_VecD; 2251 case 16: return Op_VecX; 2252 } 2253 ShouldNotReachHere(); 2254 return 0; 2255 } 2256 2257 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2258 switch(size) { 2259 case 8: return Op_VecD; 2260 case 16: return Op_VecX; 2261 } 2262 ShouldNotReachHere(); 2263 return 0; 2264 } 2265 2266 // AES support not yet implemented 2267 const bool Matcher::pass_original_key_for_aes() { 2268 return false; 2269 } 2270 2271 // aarch64 supports misaligned vectors store/load. 2272 const bool Matcher::misaligned_vectors_ok() { 2273 return true; 2274 } 2275 2276 // false => size gets scaled to BytesPerLong, ok. 2277 const bool Matcher::init_array_count_is_in_bytes = false; 2278 2279 // Use conditional move (CMOVL) 2280 const int Matcher::long_cmove_cost() { 2281 // long cmoves are no more expensive than int cmoves 2282 return 0; 2283 } 2284 2285 const int Matcher::float_cmove_cost() { 2286 // float cmoves are no more expensive than int cmoves 2287 return 0; 2288 } 2289 2290 // Does the CPU require late expand (see block.cpp for description of late expand)? 2291 const bool Matcher::require_postalloc_expand = false; 2292 2293 // Do we need to mask the count passed to shift instructions or does 2294 // the cpu only look at the lower 5/6 bits anyway? 2295 const bool Matcher::need_masked_shift_count = false; 2296 2297 // No support for generic vector operands. 2298 const bool Matcher::supports_generic_vector_operands = false; 2299 2300 MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg) { 2301 ShouldNotReachHere(); // generic vector operands not supported 2302 return NULL; 2303 } 2304 2305 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2306 ShouldNotReachHere(); // generic vector operands not supported 2307 return false; 2308 } 2309 2310 bool Matcher::is_generic_vector(MachOper* opnd) { 2311 ShouldNotReachHere(); // generic vector operands not supported 2312 return false; 2313 } 2314 2315 // This affects two different things: 2316 // - how Decode nodes are matched 2317 // - how ImplicitNullCheck opportunities are recognized 2318 // If true, the matcher will try to remove all Decodes and match them 2319 // (as operands) into nodes. NullChecks are not prepared to deal with 2320 // Decodes by final_graph_reshaping(). 2321 // If false, final_graph_reshaping() forces the decode behind the Cmp 2322 // for a NullCheck. The matcher matches the Decode node into a register. 2323 // Implicit_null_check optimization moves the Decode along with the 2324 // memory operation back up before the NullCheck. 2325 bool Matcher::narrow_oop_use_complex_address() { 2326 return CompressedOops::shift() == 0; 2327 } 2328 2329 bool Matcher::narrow_klass_use_complex_address() { 2330 // TODO 2331 // decide whether we need to set this to true 2332 return false; 2333 } 2334 2335 bool Matcher::const_oop_prefer_decode() { 2336 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2337 return CompressedOops::base() == NULL; 2338 } 2339 2340 bool Matcher::const_klass_prefer_decode() { 2341 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2342 return CompressedKlassPointers::base() == NULL; 2343 } 2344 2345 // Is it better to copy float constants, or load them directly from 2346 // memory? Intel can load a float constant from a direct address, 2347 // requiring no extra registers. Most RISCs will have to materialize 2348 // an address into a register first, so they would do better to copy 2349 // the constant from stack. 2350 const bool Matcher::rematerialize_float_constants = false; 2351 2352 // If CPU can load and store mis-aligned doubles directly then no 2353 // fixup is needed. Else we split the double into 2 integer pieces 2354 // and move it piece-by-piece. Only happens when passing doubles into 2355 // C code as the Java calling convention forces doubles to be aligned. 2356 const bool Matcher::misaligned_doubles_ok = true; 2357 2358 // No-op on amd64 2359 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2360 Unimplemented(); 2361 } 2362 2363 // Advertise here if the CPU requires explicit rounding operations to 2364 // implement the UseStrictFP mode. 2365 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2366 2367 // Are floats converted to double when stored to stack during 2368 // deoptimization? 2369 bool Matcher::float_in_double() { return false; } 2370 2371 // Do ints take an entire long register or just half? 2372 // The relevant question is how the int is callee-saved: 2373 // the whole long is written but de-opt'ing will have to extract 2374 // the relevant 32 bits. 2375 const bool Matcher::int_in_long = true; 2376 2377 // Return whether or not this register is ever used as an argument. 2378 // This function is used on startup to build the trampoline stubs in 2379 // generateOptoStub. Registers not mentioned will be killed by the VM 2380 // call in the trampoline, and arguments in those registers not be 2381 // available to the callee. 2382 bool Matcher::can_be_java_arg(int reg) 2383 { 2384 return 2385 reg == R0_num || reg == R0_H_num || 2386 reg == R1_num || reg == R1_H_num || 2387 reg == R2_num || reg == R2_H_num || 2388 reg == R3_num || reg == R3_H_num || 2389 reg == R4_num || reg == R4_H_num || 2390 reg == R5_num || reg == R5_H_num || 2391 reg == R6_num || reg == R6_H_num || 2392 reg == R7_num || reg == R7_H_num || 2393 reg == V0_num || reg == V0_H_num || 2394 reg == V1_num || reg == V1_H_num || 2395 reg == V2_num || reg == V2_H_num || 2396 reg == V3_num || reg == V3_H_num || 2397 reg == V4_num || reg == V4_H_num || 2398 reg == V5_num || reg == V5_H_num || 2399 reg == V6_num || reg == V6_H_num || 2400 reg == V7_num || reg == V7_H_num; 2401 } 2402 2403 bool Matcher::is_spillable_arg(int reg) 2404 { 2405 return can_be_java_arg(reg); 2406 } 2407 2408 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2409 return false; 2410 } 2411 2412 RegMask Matcher::divI_proj_mask() { 2413 ShouldNotReachHere(); 2414 return RegMask(); 2415 } 2416 2417 // Register for MODI projection of divmodI. 2418 RegMask Matcher::modI_proj_mask() { 2419 ShouldNotReachHere(); 2420 return RegMask(); 2421 } 2422 2423 // Register for DIVL projection of divmodL. 2424 RegMask Matcher::divL_proj_mask() { 2425 ShouldNotReachHere(); 2426 return RegMask(); 2427 } 2428 2429 // Register for MODL projection of divmodL. 2430 RegMask Matcher::modL_proj_mask() { 2431 ShouldNotReachHere(); 2432 return RegMask(); 2433 } 2434 2435 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2436 return FP_REG_mask(); 2437 } 2438 2439 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2440 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2441 Node* u = addp->fast_out(i); 2442 if (u->is_Mem()) { 2443 int opsize = u->as_Mem()->memory_size(); 2444 assert(opsize > 0, "unexpected memory operand size"); 2445 if (u->as_Mem()->memory_size() != (1<<shift)) { 2446 return false; 2447 } 2448 } 2449 } 2450 return true; 2451 } 2452 2453 const bool Matcher::convi2l_type_required = false; 2454 2455 // Should the Matcher clone shifts on addressing modes, expecting them 2456 // to be subsumed into complex addressing expressions or compute them 2457 // into registers? 2458 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2459 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2460 return true; 2461 } 2462 2463 Node *off = m->in(AddPNode::Offset); 2464 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2465 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2466 // Are there other uses besides address expressions? 2467 !is_visited(off)) { 2468 address_visited.set(off->_idx); // Flag as address_visited 2469 mstack.push(off->in(2), Visit); 2470 Node *conv = off->in(1); 2471 if (conv->Opcode() == Op_ConvI2L && 2472 // Are there other uses besides address expressions? 2473 !is_visited(conv)) { 2474 address_visited.set(conv->_idx); // Flag as address_visited 2475 mstack.push(conv->in(1), Pre_Visit); 2476 } else { 2477 mstack.push(conv, Pre_Visit); 2478 } 2479 address_visited.test_set(m->_idx); // Flag as address_visited 2480 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2481 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2482 return true; 2483 } else if (off->Opcode() == Op_ConvI2L && 2484 // Are there other uses besides address expressions? 2485 !is_visited(off)) { 2486 address_visited.test_set(m->_idx); // Flag as address_visited 2487 address_visited.set(off->_idx); // Flag as address_visited 2488 mstack.push(off->in(1), Pre_Visit); 2489 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2490 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2491 return true; 2492 } 2493 return false; 2494 } 2495 2496 void Compile::reshape_address(AddPNode* addp) { 2497 } 2498 2499 2500 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2501 MacroAssembler _masm(&cbuf); \ 2502 { \ 2503 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2504 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2505 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2506 __ INSN(REG, as_Register(BASE)); \ 2507 } 2508 2509 2510 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2511 { 2512 Address::extend scale; 2513 2514 // Hooboy, this is fugly. We need a way to communicate to the 2515 // encoder that the index needs to be sign extended, so we have to 2516 // enumerate all the cases. 2517 switch (opcode) { 2518 case INDINDEXSCALEDI2L: 2519 case INDINDEXSCALEDI2LN: 2520 case INDINDEXI2L: 2521 case INDINDEXI2LN: 2522 scale = Address::sxtw(size); 2523 break; 2524 default: 2525 scale = Address::lsl(size); 2526 } 2527 2528 if (index == -1) { 2529 return Address(base, disp); 2530 } else { 2531 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2532 return Address(base, as_Register(index), scale); 2533 } 2534 } 2535 2536 2537 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2538 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2539 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2540 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2541 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2542 2543 // Used for all non-volatile memory accesses. The use of 2544 // $mem->opcode() to discover whether this pattern uses sign-extended 2545 // offsets is something of a kludge. 2546 static void loadStore(MacroAssembler masm, mem_insn insn, 2547 Register reg, int opcode, 2548 Register base, int index, int scale, int disp, 2549 int size_in_memory) 2550 { 2551 Address addr = mem2address(opcode, base, index, scale, disp); 2552 if (addr.getMode() == Address::base_plus_offset) { 2553 /* If we get an out-of-range offset it is a bug in the compiler, 2554 so we assert here. */ 2555 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2556 "c2 compiler bug"); 2557 /* Fix up any out-of-range offsets. */ 2558 assert_different_registers(rscratch1, base); 2559 assert_different_registers(rscratch1, reg); 2560 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2561 } 2562 (masm.*insn)(reg, addr); 2563 } 2564 2565 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2566 FloatRegister reg, int opcode, 2567 Register base, int index, int size, int disp, 2568 int size_in_memory) 2569 { 2570 Address::extend scale; 2571 2572 switch (opcode) { 2573 case INDINDEXSCALEDI2L: 2574 case INDINDEXSCALEDI2LN: 2575 scale = Address::sxtw(size); 2576 break; 2577 default: 2578 scale = Address::lsl(size); 2579 } 2580 2581 if (index == -1) { 2582 /* If we get an out-of-range offset it is a bug in the compiler, 2583 so we assert here. */ 2584 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2585 /* Fix up any out-of-range offsets. */ 2586 assert_different_registers(rscratch1, base); 2587 Address addr = Address(base, disp); 2588 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2589 (masm.*insn)(reg, addr); 2590 } else { 2591 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2592 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2593 } 2594 } 2595 2596 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2597 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2598 int opcode, Register base, int index, int size, int disp) 2599 { 2600 if (index == -1) { 2601 (masm.*insn)(reg, T, Address(base, disp)); 2602 } else { 2603 assert(disp == 0, "unsupported address mode"); 2604 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2605 } 2606 } 2607 2608 %} 2609 2610 2611 2612 //----------ENCODING BLOCK----------------------------------------------------- 2613 // This block specifies the encoding classes used by the compiler to 2614 // output byte streams. Encoding classes are parameterized macros 2615 // used by Machine Instruction Nodes in order to generate the bit 2616 // encoding of the instruction. Operands specify their base encoding 2617 // interface with the interface keyword. There are currently 2618 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2619 // COND_INTER. REG_INTER causes an operand to generate a function 2620 // which returns its register number when queried. CONST_INTER causes 2621 // an operand to generate a function which returns the value of the 2622 // constant when queried. MEMORY_INTER causes an operand to generate 2623 // four functions which return the Base Register, the Index Register, 2624 // the Scale Value, and the Offset Value of the operand when queried. 2625 // COND_INTER causes an operand to generate six functions which return 2626 // the encoding code (ie - encoding bits for the instruction) 2627 // associated with each basic boolean condition for a conditional 2628 // instruction. 2629 // 2630 // Instructions specify two basic values for encoding. Again, a 2631 // function is available to check if the constant displacement is an 2632 // oop. They use the ins_encode keyword to specify their encoding 2633 // classes (which must be a sequence of enc_class names, and their 2634 // parameters, specified in the encoding block), and they use the 2635 // opcode keyword to specify, in order, their primary, secondary, and 2636 // tertiary opcode. Only the opcode sections which a particular 2637 // instruction needs for encoding need to be specified. 2638 encode %{ 2639 // Build emit functions for each basic byte or larger field in the 2640 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2641 // from C++ code in the enc_class source block. Emit functions will 2642 // live in the main source block for now. In future, we can 2643 // generalize this by adding a syntax that specifies the sizes of 2644 // fields in an order, so that the adlc can build the emit functions 2645 // automagically 2646 2647 // catch all for unimplemented encodings 2648 enc_class enc_unimplemented %{ 2649 MacroAssembler _masm(&cbuf); 2650 __ unimplemented("C2 catch all"); 2651 %} 2652 2653 // BEGIN Non-volatile memory access 2654 2655 // This encoding class is generated automatically from ad_encode.m4. 2656 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2657 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2658 Register dst_reg = as_Register($dst$$reg); 2659 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2660 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2661 %} 2662 2663 // This encoding class is generated automatically from ad_encode.m4. 2664 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2665 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2666 Register dst_reg = as_Register($dst$$reg); 2667 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2668 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2669 %} 2670 2671 // This encoding class is generated automatically from ad_encode.m4. 2672 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2673 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2674 Register dst_reg = as_Register($dst$$reg); 2675 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2676 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2677 %} 2678 2679 // This encoding class is generated automatically from ad_encode.m4. 2680 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2681 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2682 Register dst_reg = as_Register($dst$$reg); 2683 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2684 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2685 %} 2686 2687 // This encoding class is generated automatically from ad_encode.m4. 2688 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2689 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2690 Register dst_reg = as_Register($dst$$reg); 2691 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2692 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2693 %} 2694 2695 // This encoding class is generated automatically from ad_encode.m4. 2696 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2697 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2698 Register dst_reg = as_Register($dst$$reg); 2699 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2700 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2701 %} 2702 2703 // This encoding class is generated automatically from ad_encode.m4. 2704 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2705 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2706 Register dst_reg = as_Register($dst$$reg); 2707 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2708 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2709 %} 2710 2711 // This encoding class is generated automatically from ad_encode.m4. 2712 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2713 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2714 Register dst_reg = as_Register($dst$$reg); 2715 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2716 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2717 %} 2718 2719 // This encoding class is generated automatically from ad_encode.m4. 2720 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2721 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2722 Register dst_reg = as_Register($dst$$reg); 2723 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2724 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2725 %} 2726 2727 // This encoding class is generated automatically from ad_encode.m4. 2728 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2729 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2730 Register dst_reg = as_Register($dst$$reg); 2731 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2732 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2733 %} 2734 2735 // This encoding class is generated automatically from ad_encode.m4. 2736 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2737 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2738 Register dst_reg = as_Register($dst$$reg); 2739 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2740 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2741 %} 2742 2743 // This encoding class is generated automatically from ad_encode.m4. 2744 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2745 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2746 Register dst_reg = as_Register($dst$$reg); 2747 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2748 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2749 %} 2750 2751 // This encoding class is generated automatically from ad_encode.m4. 2752 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2753 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2754 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2755 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2756 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2757 %} 2758 2759 // This encoding class is generated automatically from ad_encode.m4. 2760 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2761 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2762 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2763 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2764 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2765 %} 2766 2767 // This encoding class is generated automatically from ad_encode.m4. 2768 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2769 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2770 Register src_reg = as_Register($src$$reg); 2771 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2772 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2773 %} 2774 2775 // This encoding class is generated automatically from ad_encode.m4. 2776 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2777 enc_class aarch64_enc_strb0(memory1 mem) %{ 2778 MacroAssembler _masm(&cbuf); 2779 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2780 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2781 %} 2782 2783 // This encoding class is generated automatically from ad_encode.m4. 2784 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2785 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2786 Register src_reg = as_Register($src$$reg); 2787 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2788 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2789 %} 2790 2791 // This encoding class is generated automatically from ad_encode.m4. 2792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2793 enc_class aarch64_enc_strh0(memory2 mem) %{ 2794 MacroAssembler _masm(&cbuf); 2795 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2796 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2797 %} 2798 2799 // This encoding class is generated automatically from ad_encode.m4. 2800 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2801 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2802 Register src_reg = as_Register($src$$reg); 2803 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2804 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2805 %} 2806 2807 // This encoding class is generated automatically from ad_encode.m4. 2808 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2809 enc_class aarch64_enc_strw0(memory4 mem) %{ 2810 MacroAssembler _masm(&cbuf); 2811 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2812 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2813 %} 2814 2815 // This encoding class is generated automatically from ad_encode.m4. 2816 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2817 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2818 Register src_reg = as_Register($src$$reg); 2819 // we sometimes get asked to store the stack pointer into the 2820 // current thread -- we cannot do that directly on AArch64 2821 if (src_reg == r31_sp) { 2822 MacroAssembler _masm(&cbuf); 2823 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2824 __ mov(rscratch2, sp); 2825 src_reg = rscratch2; 2826 } 2827 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2828 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2829 %} 2830 2831 // This encoding class is generated automatically from ad_encode.m4. 2832 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2833 enc_class aarch64_enc_str0(memory8 mem) %{ 2834 MacroAssembler _masm(&cbuf); 2835 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2836 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2837 %} 2838 2839 // This encoding class is generated automatically from ad_encode.m4. 2840 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2841 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 2842 FloatRegister src_reg = as_FloatRegister($src$$reg); 2843 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2844 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2845 %} 2846 2847 // This encoding class is generated automatically from ad_encode.m4. 2848 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2849 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 2850 FloatRegister src_reg = as_FloatRegister($src$$reg); 2851 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2852 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2853 %} 2854 2855 // This encoding class is generated automatically from ad_encode.m4. 2856 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2857 enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{ 2858 MacroAssembler _masm(&cbuf); 2859 address con = (address)$src$$constant; 2860 // need to do this the hard way until we can manage relocs 2861 // for 32 bit constants 2862 __ movoop(rscratch2, (jobject)con); 2863 if (con) __ encode_heap_oop_not_null(rscratch2); 2864 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2865 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2866 %} 2867 2868 // This encoding class is generated automatically from ad_encode.m4. 2869 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2870 enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{ 2871 MacroAssembler _masm(&cbuf); 2872 address con = (address)$src$$constant; 2873 // need to do this the hard way until we can manage relocs 2874 // for 32 bit constants 2875 __ movoop(rscratch2, (jobject)con); 2876 __ encode_klass_not_null(rscratch2); 2877 loadStore(_masm, &MacroAssembler::strw, rscratch2, $mem->opcode(), 2878 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2879 %} 2880 2881 // This encoding class is generated automatically from ad_encode.m4. 2882 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2883 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 2884 MacroAssembler _masm(&cbuf); 2885 __ membar(Assembler::StoreStore); 2886 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2887 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2888 %} 2889 2890 // END Non-volatile memory access 2891 2892 // Vector loads and stores 2893 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2894 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2895 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2896 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2897 %} 2898 2899 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2900 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2901 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2902 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2903 %} 2904 2905 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2906 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2907 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2908 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2909 %} 2910 2911 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2912 FloatRegister src_reg = as_FloatRegister($src$$reg); 2913 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2914 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2915 %} 2916 2917 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2918 FloatRegister src_reg = as_FloatRegister($src$$reg); 2919 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2920 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2921 %} 2922 2923 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2924 FloatRegister src_reg = as_FloatRegister($src$$reg); 2925 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2926 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2927 %} 2928 2929 // volatile loads and stores 2930 2931 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2932 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2933 rscratch1, stlrb); 2934 %} 2935 2936 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2937 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2938 rscratch1, stlrh); 2939 %} 2940 2941 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2942 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2943 rscratch1, stlrw); 2944 %} 2945 2946 2947 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2948 Register dst_reg = as_Register($dst$$reg); 2949 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2950 rscratch1, ldarb); 2951 __ sxtbw(dst_reg, dst_reg); 2952 %} 2953 2954 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2955 Register dst_reg = as_Register($dst$$reg); 2956 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2957 rscratch1, ldarb); 2958 __ sxtb(dst_reg, dst_reg); 2959 %} 2960 2961 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2962 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2963 rscratch1, ldarb); 2964 %} 2965 2966 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2967 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2968 rscratch1, ldarb); 2969 %} 2970 2971 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2972 Register dst_reg = as_Register($dst$$reg); 2973 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2974 rscratch1, ldarh); 2975 __ sxthw(dst_reg, dst_reg); 2976 %} 2977 2978 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2979 Register dst_reg = as_Register($dst$$reg); 2980 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2981 rscratch1, ldarh); 2982 __ sxth(dst_reg, dst_reg); 2983 %} 2984 2985 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2986 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2987 rscratch1, ldarh); 2988 %} 2989 2990 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2991 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2992 rscratch1, ldarh); 2993 %} 2994 2995 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2996 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2997 rscratch1, ldarw); 2998 %} 2999 3000 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3001 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3002 rscratch1, ldarw); 3003 %} 3004 3005 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3006 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3007 rscratch1, ldar); 3008 %} 3009 3010 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3011 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3012 rscratch1, ldarw); 3013 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3014 %} 3015 3016 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3017 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3018 rscratch1, ldar); 3019 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3020 %} 3021 3022 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3023 Register src_reg = as_Register($src$$reg); 3024 // we sometimes get asked to store the stack pointer into the 3025 // current thread -- we cannot do that directly on AArch64 3026 if (src_reg == r31_sp) { 3027 MacroAssembler _masm(&cbuf); 3028 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3029 __ mov(rscratch2, sp); 3030 src_reg = rscratch2; 3031 } 3032 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3033 rscratch1, stlr); 3034 %} 3035 3036 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3037 { 3038 MacroAssembler _masm(&cbuf); 3039 FloatRegister src_reg = as_FloatRegister($src$$reg); 3040 __ fmovs(rscratch2, src_reg); 3041 } 3042 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3043 rscratch1, stlrw); 3044 %} 3045 3046 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3047 { 3048 MacroAssembler _masm(&cbuf); 3049 FloatRegister src_reg = as_FloatRegister($src$$reg); 3050 __ fmovd(rscratch2, src_reg); 3051 } 3052 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3053 rscratch1, stlr); 3054 %} 3055 3056 // synchronized read/update encodings 3057 3058 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3059 MacroAssembler _masm(&cbuf); 3060 Register dst_reg = as_Register($dst$$reg); 3061 Register base = as_Register($mem$$base); 3062 int index = $mem$$index; 3063 int scale = $mem$$scale; 3064 int disp = $mem$$disp; 3065 if (index == -1) { 3066 if (disp != 0) { 3067 __ lea(rscratch1, Address(base, disp)); 3068 __ ldaxr(dst_reg, rscratch1); 3069 } else { 3070 // TODO 3071 // should we ever get anything other than this case? 3072 __ ldaxr(dst_reg, base); 3073 } 3074 } else { 3075 Register index_reg = as_Register(index); 3076 if (disp == 0) { 3077 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3078 __ ldaxr(dst_reg, rscratch1); 3079 } else { 3080 __ lea(rscratch1, Address(base, disp)); 3081 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3082 __ ldaxr(dst_reg, rscratch1); 3083 } 3084 } 3085 %} 3086 3087 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3088 MacroAssembler _masm(&cbuf); 3089 Register src_reg = as_Register($src$$reg); 3090 Register base = as_Register($mem$$base); 3091 int index = $mem$$index; 3092 int scale = $mem$$scale; 3093 int disp = $mem$$disp; 3094 if (index == -1) { 3095 if (disp != 0) { 3096 __ lea(rscratch2, Address(base, disp)); 3097 __ stlxr(rscratch1, src_reg, rscratch2); 3098 } else { 3099 // TODO 3100 // should we ever get anything other than this case? 3101 __ stlxr(rscratch1, src_reg, base); 3102 } 3103 } else { 3104 Register index_reg = as_Register(index); 3105 if (disp == 0) { 3106 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3107 __ stlxr(rscratch1, src_reg, rscratch2); 3108 } else { 3109 __ lea(rscratch2, Address(base, disp)); 3110 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3111 __ stlxr(rscratch1, src_reg, rscratch2); 3112 } 3113 } 3114 __ cmpw(rscratch1, zr); 3115 %} 3116 3117 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3118 MacroAssembler _masm(&cbuf); 3119 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3120 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3121 Assembler::xword, /*acquire*/ false, /*release*/ true, 3122 /*weak*/ false, noreg); 3123 %} 3124 3125 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3126 MacroAssembler _masm(&cbuf); 3127 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3128 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3129 Assembler::word, /*acquire*/ false, /*release*/ true, 3130 /*weak*/ false, noreg); 3131 %} 3132 3133 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3134 MacroAssembler _masm(&cbuf); 3135 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3136 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3137 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3138 /*weak*/ false, noreg); 3139 %} 3140 3141 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3142 MacroAssembler _masm(&cbuf); 3143 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3144 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3145 Assembler::byte, /*acquire*/ false, /*release*/ true, 3146 /*weak*/ false, noreg); 3147 %} 3148 3149 3150 // The only difference between aarch64_enc_cmpxchg and 3151 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3152 // CompareAndSwap sequence to serve as a barrier on acquiring a 3153 // lock. 3154 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3155 MacroAssembler _masm(&cbuf); 3156 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3157 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3158 Assembler::xword, /*acquire*/ true, /*release*/ true, 3159 /*weak*/ false, noreg); 3160 %} 3161 3162 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3163 MacroAssembler _masm(&cbuf); 3164 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3165 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3166 Assembler::word, /*acquire*/ true, /*release*/ true, 3167 /*weak*/ false, noreg); 3168 %} 3169 3170 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3171 MacroAssembler _masm(&cbuf); 3172 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3173 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3174 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3175 /*weak*/ false, noreg); 3176 %} 3177 3178 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3179 MacroAssembler _masm(&cbuf); 3180 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3181 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3182 Assembler::byte, /*acquire*/ true, /*release*/ true, 3183 /*weak*/ false, noreg); 3184 %} 3185 3186 // auxiliary used for CompareAndSwapX to set result register 3187 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3188 MacroAssembler _masm(&cbuf); 3189 Register res_reg = as_Register($res$$reg); 3190 __ cset(res_reg, Assembler::EQ); 3191 %} 3192 3193 // prefetch encodings 3194 3195 enc_class aarch64_enc_prefetchw(memory mem) %{ 3196 MacroAssembler _masm(&cbuf); 3197 Register base = as_Register($mem$$base); 3198 int index = $mem$$index; 3199 int scale = $mem$$scale; 3200 int disp = $mem$$disp; 3201 if (index == -1) { 3202 __ prfm(Address(base, disp), PSTL1KEEP); 3203 } else { 3204 Register index_reg = as_Register(index); 3205 if (disp == 0) { 3206 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3207 } else { 3208 __ lea(rscratch1, Address(base, disp)); 3209 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3210 } 3211 } 3212 %} 3213 3214 /// mov envcodings 3215 3216 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3217 MacroAssembler _masm(&cbuf); 3218 u_int32_t con = (u_int32_t)$src$$constant; 3219 Register dst_reg = as_Register($dst$$reg); 3220 if (con == 0) { 3221 __ movw(dst_reg, zr); 3222 } else { 3223 __ movw(dst_reg, con); 3224 } 3225 %} 3226 3227 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3228 MacroAssembler _masm(&cbuf); 3229 Register dst_reg = as_Register($dst$$reg); 3230 u_int64_t con = (u_int64_t)$src$$constant; 3231 if (con == 0) { 3232 __ mov(dst_reg, zr); 3233 } else { 3234 __ mov(dst_reg, con); 3235 } 3236 %} 3237 3238 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3239 MacroAssembler _masm(&cbuf); 3240 Register dst_reg = as_Register($dst$$reg); 3241 address con = (address)$src$$constant; 3242 if (con == NULL || con == (address)1) { 3243 ShouldNotReachHere(); 3244 } else { 3245 relocInfo::relocType rtype = $src->constant_reloc(); 3246 if (rtype == relocInfo::oop_type) { 3247 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3248 } else if (rtype == relocInfo::metadata_type) { 3249 __ mov_metadata(dst_reg, (Metadata*)con); 3250 } else { 3251 assert(rtype == relocInfo::none, "unexpected reloc type"); 3252 if (con < (address)(uintptr_t)os::vm_page_size()) { 3253 __ mov(dst_reg, con); 3254 } else { 3255 unsigned long offset; 3256 __ adrp(dst_reg, con, offset); 3257 __ add(dst_reg, dst_reg, offset); 3258 } 3259 } 3260 } 3261 %} 3262 3263 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3264 MacroAssembler _masm(&cbuf); 3265 Register dst_reg = as_Register($dst$$reg); 3266 __ mov(dst_reg, zr); 3267 %} 3268 3269 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3270 MacroAssembler _masm(&cbuf); 3271 Register dst_reg = as_Register($dst$$reg); 3272 __ mov(dst_reg, (u_int64_t)1); 3273 %} 3274 3275 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3276 MacroAssembler _masm(&cbuf); 3277 address page = (address)$src$$constant; 3278 Register dst_reg = as_Register($dst$$reg); 3279 unsigned long off; 3280 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3281 assert(off == 0, "assumed offset == 0"); 3282 %} 3283 3284 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3285 MacroAssembler _masm(&cbuf); 3286 __ load_byte_map_base($dst$$Register); 3287 %} 3288 3289 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3290 MacroAssembler _masm(&cbuf); 3291 Register dst_reg = as_Register($dst$$reg); 3292 address con = (address)$src$$constant; 3293 if (con == NULL) { 3294 ShouldNotReachHere(); 3295 } else { 3296 relocInfo::relocType rtype = $src->constant_reloc(); 3297 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3298 __ set_narrow_oop(dst_reg, (jobject)con); 3299 } 3300 %} 3301 3302 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3303 MacroAssembler _masm(&cbuf); 3304 Register dst_reg = as_Register($dst$$reg); 3305 __ mov(dst_reg, zr); 3306 %} 3307 3308 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3309 MacroAssembler _masm(&cbuf); 3310 Register dst_reg = as_Register($dst$$reg); 3311 address con = (address)$src$$constant; 3312 if (con == NULL) { 3313 ShouldNotReachHere(); 3314 } else { 3315 relocInfo::relocType rtype = $src->constant_reloc(); 3316 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3317 __ set_narrow_klass(dst_reg, (Klass *)con); 3318 } 3319 %} 3320 3321 // arithmetic encodings 3322 3323 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3324 MacroAssembler _masm(&cbuf); 3325 Register dst_reg = as_Register($dst$$reg); 3326 Register src_reg = as_Register($src1$$reg); 3327 int32_t con = (int32_t)$src2$$constant; 3328 // add has primary == 0, subtract has primary == 1 3329 if ($primary) { con = -con; } 3330 if (con < 0) { 3331 __ subw(dst_reg, src_reg, -con); 3332 } else { 3333 __ addw(dst_reg, src_reg, con); 3334 } 3335 %} 3336 3337 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3338 MacroAssembler _masm(&cbuf); 3339 Register dst_reg = as_Register($dst$$reg); 3340 Register src_reg = as_Register($src1$$reg); 3341 int32_t con = (int32_t)$src2$$constant; 3342 // add has primary == 0, subtract has primary == 1 3343 if ($primary) { con = -con; } 3344 if (con < 0) { 3345 __ sub(dst_reg, src_reg, -con); 3346 } else { 3347 __ add(dst_reg, src_reg, con); 3348 } 3349 %} 3350 3351 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3352 MacroAssembler _masm(&cbuf); 3353 Register dst_reg = as_Register($dst$$reg); 3354 Register src1_reg = as_Register($src1$$reg); 3355 Register src2_reg = as_Register($src2$$reg); 3356 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3357 %} 3358 3359 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3360 MacroAssembler _masm(&cbuf); 3361 Register dst_reg = as_Register($dst$$reg); 3362 Register src1_reg = as_Register($src1$$reg); 3363 Register src2_reg = as_Register($src2$$reg); 3364 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3365 %} 3366 3367 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3368 MacroAssembler _masm(&cbuf); 3369 Register dst_reg = as_Register($dst$$reg); 3370 Register src1_reg = as_Register($src1$$reg); 3371 Register src2_reg = as_Register($src2$$reg); 3372 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3373 %} 3374 3375 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3376 MacroAssembler _masm(&cbuf); 3377 Register dst_reg = as_Register($dst$$reg); 3378 Register src1_reg = as_Register($src1$$reg); 3379 Register src2_reg = as_Register($src2$$reg); 3380 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3381 %} 3382 3383 // compare instruction encodings 3384 3385 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3386 MacroAssembler _masm(&cbuf); 3387 Register reg1 = as_Register($src1$$reg); 3388 Register reg2 = as_Register($src2$$reg); 3389 __ cmpw(reg1, reg2); 3390 %} 3391 3392 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3393 MacroAssembler _masm(&cbuf); 3394 Register reg = as_Register($src1$$reg); 3395 int32_t val = $src2$$constant; 3396 if (val >= 0) { 3397 __ subsw(zr, reg, val); 3398 } else { 3399 __ addsw(zr, reg, -val); 3400 } 3401 %} 3402 3403 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3404 MacroAssembler _masm(&cbuf); 3405 Register reg1 = as_Register($src1$$reg); 3406 u_int32_t val = (u_int32_t)$src2$$constant; 3407 __ movw(rscratch1, val); 3408 __ cmpw(reg1, rscratch1); 3409 %} 3410 3411 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3412 MacroAssembler _masm(&cbuf); 3413 Register reg1 = as_Register($src1$$reg); 3414 Register reg2 = as_Register($src2$$reg); 3415 __ cmp(reg1, reg2); 3416 %} 3417 3418 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3419 MacroAssembler _masm(&cbuf); 3420 Register reg = as_Register($src1$$reg); 3421 int64_t val = $src2$$constant; 3422 if (val >= 0) { 3423 __ subs(zr, reg, val); 3424 } else if (val != -val) { 3425 __ adds(zr, reg, -val); 3426 } else { 3427 // aargh, Long.MIN_VALUE is a special case 3428 __ orr(rscratch1, zr, (u_int64_t)val); 3429 __ subs(zr, reg, rscratch1); 3430 } 3431 %} 3432 3433 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3434 MacroAssembler _masm(&cbuf); 3435 Register reg1 = as_Register($src1$$reg); 3436 u_int64_t val = (u_int64_t)$src2$$constant; 3437 __ mov(rscratch1, val); 3438 __ cmp(reg1, rscratch1); 3439 %} 3440 3441 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3442 MacroAssembler _masm(&cbuf); 3443 Register reg1 = as_Register($src1$$reg); 3444 Register reg2 = as_Register($src2$$reg); 3445 __ cmp(reg1, reg2); 3446 %} 3447 3448 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3449 MacroAssembler _masm(&cbuf); 3450 Register reg1 = as_Register($src1$$reg); 3451 Register reg2 = as_Register($src2$$reg); 3452 __ cmpw(reg1, reg2); 3453 %} 3454 3455 enc_class aarch64_enc_testp(iRegP src) %{ 3456 MacroAssembler _masm(&cbuf); 3457 Register reg = as_Register($src$$reg); 3458 __ cmp(reg, zr); 3459 %} 3460 3461 enc_class aarch64_enc_testn(iRegN src) %{ 3462 MacroAssembler _masm(&cbuf); 3463 Register reg = as_Register($src$$reg); 3464 __ cmpw(reg, zr); 3465 %} 3466 3467 enc_class aarch64_enc_b(label lbl) %{ 3468 MacroAssembler _masm(&cbuf); 3469 Label *L = $lbl$$label; 3470 __ b(*L); 3471 %} 3472 3473 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3474 MacroAssembler _masm(&cbuf); 3475 Label *L = $lbl$$label; 3476 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3477 %} 3478 3479 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3480 MacroAssembler _masm(&cbuf); 3481 Label *L = $lbl$$label; 3482 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3483 %} 3484 3485 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3486 %{ 3487 Register sub_reg = as_Register($sub$$reg); 3488 Register super_reg = as_Register($super$$reg); 3489 Register temp_reg = as_Register($temp$$reg); 3490 Register result_reg = as_Register($result$$reg); 3491 3492 Label miss; 3493 MacroAssembler _masm(&cbuf); 3494 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3495 NULL, &miss, 3496 /*set_cond_codes:*/ true); 3497 if ($primary) { 3498 __ mov(result_reg, zr); 3499 } 3500 __ bind(miss); 3501 %} 3502 3503 enc_class aarch64_enc_java_static_call(method meth) %{ 3504 MacroAssembler _masm(&cbuf); 3505 3506 address addr = (address)$meth$$method; 3507 address call; 3508 if (!_method) { 3509 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3510 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3511 } else { 3512 int method_index = resolved_method_index(cbuf); 3513 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3514 : static_call_Relocation::spec(method_index); 3515 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3516 3517 // Emit stub for static call 3518 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3519 if (stub == NULL) { 3520 ciEnv::current()->record_failure("CodeCache is full"); 3521 return; 3522 } 3523 } 3524 if (call == NULL) { 3525 ciEnv::current()->record_failure("CodeCache is full"); 3526 return; 3527 } 3528 %} 3529 3530 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3531 MacroAssembler _masm(&cbuf); 3532 int method_index = resolved_method_index(cbuf); 3533 address call = __ ic_call((address)$meth$$method, method_index); 3534 if (call == NULL) { 3535 ciEnv::current()->record_failure("CodeCache is full"); 3536 return; 3537 } 3538 %} 3539 3540 enc_class aarch64_enc_call_epilog() %{ 3541 MacroAssembler _masm(&cbuf); 3542 if (VerifyStackAtCalls) { 3543 // Check that stack depth is unchanged: find majik cookie on stack 3544 __ call_Unimplemented(); 3545 } 3546 %} 3547 3548 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3549 MacroAssembler _masm(&cbuf); 3550 3551 // some calls to generated routines (arraycopy code) are scheduled 3552 // by C2 as runtime calls. if so we can call them using a br (they 3553 // will be in a reachable segment) otherwise we have to use a blr 3554 // which loads the absolute address into a register. 3555 address entry = (address)$meth$$method; 3556 CodeBlob *cb = CodeCache::find_blob(entry); 3557 if (cb) { 3558 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3559 if (call == NULL) { 3560 ciEnv::current()->record_failure("CodeCache is full"); 3561 return; 3562 } 3563 } else { 3564 Label retaddr; 3565 __ adr(rscratch2, retaddr); 3566 __ lea(rscratch1, RuntimeAddress(entry)); 3567 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3568 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3569 __ blr(rscratch1); 3570 __ bind(retaddr); 3571 __ add(sp, sp, 2 * wordSize); 3572 } 3573 %} 3574 3575 enc_class aarch64_enc_rethrow() %{ 3576 MacroAssembler _masm(&cbuf); 3577 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3578 %} 3579 3580 enc_class aarch64_enc_ret() %{ 3581 MacroAssembler _masm(&cbuf); 3582 __ ret(lr); 3583 %} 3584 3585 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3586 MacroAssembler _masm(&cbuf); 3587 Register target_reg = as_Register($jump_target$$reg); 3588 __ br(target_reg); 3589 %} 3590 3591 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3592 MacroAssembler _masm(&cbuf); 3593 Register target_reg = as_Register($jump_target$$reg); 3594 // exception oop should be in r0 3595 // ret addr has been popped into lr 3596 // callee expects it in r3 3597 __ mov(r3, lr); 3598 __ br(target_reg); 3599 %} 3600 3601 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3602 MacroAssembler _masm(&cbuf); 3603 Register oop = as_Register($object$$reg); 3604 Register box = as_Register($box$$reg); 3605 Register disp_hdr = as_Register($tmp$$reg); 3606 Register tmp = as_Register($tmp2$$reg); 3607 Label cont; 3608 Label object_has_monitor; 3609 Label cas_failed; 3610 3611 assert_different_registers(oop, box, tmp, disp_hdr); 3612 3613 // Load markWord from object into displaced_header. 3614 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3615 3616 if (UseBiasedLocking && !UseOptoBiasInlining) { 3617 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3618 } 3619 3620 // Check for existing monitor 3621 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3622 3623 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3624 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3625 3626 // Initialize the box. (Must happen before we update the object mark!) 3627 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3628 3629 // Compare object markWord with an unlocked value (tmp) and if 3630 // equal exchange the stack address of our box with object markWord. 3631 // On failure disp_hdr contains the possibly locked markWord. 3632 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3633 /*release*/ true, /*weak*/ false, disp_hdr); 3634 __ br(Assembler::EQ, cont); 3635 3636 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3637 3638 // If the compare-and-exchange succeeded, then we found an unlocked 3639 // object, will have now locked it will continue at label cont 3640 3641 __ bind(cas_failed); 3642 // We did not see an unlocked object so try the fast recursive case. 3643 3644 // Check if the owner is self by comparing the value in the 3645 // markWord of object (disp_hdr) with the stack pointer. 3646 __ mov(rscratch1, sp); 3647 __ sub(disp_hdr, disp_hdr, rscratch1); 3648 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3649 // If condition is true we are cont and hence we can store 0 as the 3650 // displaced header in the box, which indicates that it is a recursive lock. 3651 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3652 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3653 3654 __ b(cont); 3655 3656 // Handle existing monitor. 3657 __ bind(object_has_monitor); 3658 3659 // The object's monitor m is unlocked iff m->owner == NULL, 3660 // otherwise m->owner may contain a thread or a stack address. 3661 // 3662 // Try to CAS m->owner from NULL to current thread. 3663 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3664 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3665 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3666 3667 // Store a non-null value into the box to avoid looking like a re-entrant 3668 // lock. The fast-path monitor unlock code checks for 3669 // markWord::monitor_value so use markWord::unused_mark which has the 3670 // relevant bit set, and also matches ObjectSynchronizer::enter. 3671 __ mov(tmp, (address)markWord::unused_mark().value()); 3672 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3673 3674 __ bind(cont); 3675 // flag == EQ indicates success 3676 // flag == NE indicates failure 3677 %} 3678 3679 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3680 MacroAssembler _masm(&cbuf); 3681 Register oop = as_Register($object$$reg); 3682 Register box = as_Register($box$$reg); 3683 Register disp_hdr = as_Register($tmp$$reg); 3684 Register tmp = as_Register($tmp2$$reg); 3685 Label cont; 3686 Label object_has_monitor; 3687 3688 assert_different_registers(oop, box, tmp, disp_hdr); 3689 3690 if (UseBiasedLocking && !UseOptoBiasInlining) { 3691 __ biased_locking_exit(oop, tmp, cont); 3692 } 3693 3694 // Find the lock address and load the displaced header from the stack. 3695 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3696 3697 // If the displaced header is 0, we have a recursive unlock. 3698 __ cmp(disp_hdr, zr); 3699 __ br(Assembler::EQ, cont); 3700 3701 // Handle existing monitor. 3702 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3703 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3704 3705 // Check if it is still a light weight lock, this is is true if we 3706 // see the stack address of the basicLock in the markWord of the 3707 // object. 3708 3709 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3710 /*release*/ true, /*weak*/ false, tmp); 3711 __ b(cont); 3712 3713 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3714 3715 // Handle existing monitor. 3716 __ bind(object_has_monitor); 3717 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3718 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3719 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3720 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3721 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3722 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3723 __ cmp(rscratch1, zr); // Sets flags for result 3724 __ br(Assembler::NE, cont); 3725 3726 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3727 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3728 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3729 __ cmp(rscratch1, zr); // Sets flags for result 3730 __ cbnz(rscratch1, cont); 3731 // need a release store here 3732 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3733 __ stlr(zr, tmp); // set unowned 3734 3735 __ bind(cont); 3736 // flag == EQ indicates success 3737 // flag == NE indicates failure 3738 %} 3739 3740 %} 3741 3742 //----------FRAME-------------------------------------------------------------- 3743 // Definition of frame structure and management information. 3744 // 3745 // S T A C K L A Y O U T Allocators stack-slot number 3746 // | (to get allocators register number 3747 // G Owned by | | v add OptoReg::stack0()) 3748 // r CALLER | | 3749 // o | +--------+ pad to even-align allocators stack-slot 3750 // w V | pad0 | numbers; owned by CALLER 3751 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3752 // h ^ | in | 5 3753 // | | args | 4 Holes in incoming args owned by SELF 3754 // | | | | 3 3755 // | | +--------+ 3756 // V | | old out| Empty on Intel, window on Sparc 3757 // | old |preserve| Must be even aligned. 3758 // | SP-+--------+----> Matcher::_old_SP, even aligned 3759 // | | in | 3 area for Intel ret address 3760 // Owned by |preserve| Empty on Sparc. 3761 // SELF +--------+ 3762 // | | pad2 | 2 pad to align old SP 3763 // | +--------+ 1 3764 // | | locks | 0 3765 // | +--------+----> OptoReg::stack0(), even aligned 3766 // | | pad1 | 11 pad to align new SP 3767 // | +--------+ 3768 // | | | 10 3769 // | | spills | 9 spills 3770 // V | | 8 (pad0 slot for callee) 3771 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3772 // ^ | out | 7 3773 // | | args | 6 Holes in outgoing args owned by CALLEE 3774 // Owned by +--------+ 3775 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3776 // | new |preserve| Must be even-aligned. 3777 // | SP-+--------+----> Matcher::_new_SP, even aligned 3778 // | | | 3779 // 3780 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3781 // known from SELF's arguments and the Java calling convention. 3782 // Region 6-7 is determined per call site. 3783 // Note 2: If the calling convention leaves holes in the incoming argument 3784 // area, those holes are owned by SELF. Holes in the outgoing area 3785 // are owned by the CALLEE. Holes should not be nessecary in the 3786 // incoming area, as the Java calling convention is completely under 3787 // the control of the AD file. Doubles can be sorted and packed to 3788 // avoid holes. Holes in the outgoing arguments may be nessecary for 3789 // varargs C calling conventions. 3790 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3791 // even aligned with pad0 as needed. 3792 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3793 // (the latter is true on Intel but is it false on AArch64?) 3794 // region 6-11 is even aligned; it may be padded out more so that 3795 // the region from SP to FP meets the minimum stack alignment. 3796 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3797 // alignment. Region 11, pad1, may be dynamically extended so that 3798 // SP meets the minimum alignment. 3799 3800 frame %{ 3801 // What direction does stack grow in (assumed to be same for C & Java) 3802 stack_direction(TOWARDS_LOW); 3803 3804 // These three registers define part of the calling convention 3805 // between compiled code and the interpreter. 3806 3807 // Inline Cache Register or methodOop for I2C. 3808 inline_cache_reg(R12); 3809 3810 // Method Oop Register when calling interpreter. 3811 interpreter_method_oop_reg(R12); 3812 3813 // Number of stack slots consumed by locking an object 3814 sync_stack_slots(2); 3815 3816 // Compiled code's Frame Pointer 3817 frame_pointer(R31); 3818 3819 // Interpreter stores its frame pointer in a register which is 3820 // stored to the stack by I2CAdaptors. 3821 // I2CAdaptors convert from interpreted java to compiled java. 3822 interpreter_frame_pointer(R29); 3823 3824 // Stack alignment requirement 3825 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3826 3827 // Number of stack slots between incoming argument block and the start of 3828 // a new frame. The PROLOG must add this many slots to the stack. The 3829 // EPILOG must remove this many slots. aarch64 needs two slots for 3830 // return address and fp. 3831 // TODO think this is correct but check 3832 in_preserve_stack_slots(4); 3833 3834 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3835 // for calls to C. Supports the var-args backing area for register parms. 3836 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3837 3838 // The after-PROLOG location of the return address. Location of 3839 // return address specifies a type (REG or STACK) and a number 3840 // representing the register number (i.e. - use a register name) or 3841 // stack slot. 3842 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3843 // Otherwise, it is above the locks and verification slot and alignment word 3844 // TODO this may well be correct but need to check why that - 2 is there 3845 // ppc port uses 0 but we definitely need to allow for fixed_slots 3846 // which folds in the space used for monitors 3847 return_addr(STACK - 2 + 3848 align_up((Compile::current()->in_preserve_stack_slots() + 3849 Compile::current()->fixed_slots()), 3850 stack_alignment_in_slots())); 3851 3852 // Body of function which returns an integer array locating 3853 // arguments either in registers or in stack slots. Passed an array 3854 // of ideal registers called "sig" and a "length" count. Stack-slot 3855 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3856 // arguments for a CALLEE. Incoming stack arguments are 3857 // automatically biased by the preserve_stack_slots field above. 3858 3859 calling_convention 3860 %{ 3861 // No difference between ingoing/outgoing just pass false 3862 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3863 %} 3864 3865 c_calling_convention 3866 %{ 3867 // This is obviously always outgoing 3868 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3869 %} 3870 3871 // Location of compiled Java return values. Same as C for now. 3872 return_value 3873 %{ 3874 // TODO do we allow ideal_reg == Op_RegN??? 3875 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3876 "only return normal values"); 3877 3878 static const int lo[Op_RegL + 1] = { // enum name 3879 0, // Op_Node 3880 0, // Op_Set 3881 R0_num, // Op_RegN 3882 R0_num, // Op_RegI 3883 R0_num, // Op_RegP 3884 V0_num, // Op_RegF 3885 V0_num, // Op_RegD 3886 R0_num // Op_RegL 3887 }; 3888 3889 static const int hi[Op_RegL + 1] = { // enum name 3890 0, // Op_Node 3891 0, // Op_Set 3892 OptoReg::Bad, // Op_RegN 3893 OptoReg::Bad, // Op_RegI 3894 R0_H_num, // Op_RegP 3895 OptoReg::Bad, // Op_RegF 3896 V0_H_num, // Op_RegD 3897 R0_H_num // Op_RegL 3898 }; 3899 3900 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3901 %} 3902 %} 3903 3904 //----------ATTRIBUTES--------------------------------------------------------- 3905 //----------Operand Attributes------------------------------------------------- 3906 op_attrib op_cost(1); // Required cost attribute 3907 3908 //----------Instruction Attributes--------------------------------------------- 3909 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3910 ins_attrib ins_size(32); // Required size attribute (in bits) 3911 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3912 // a non-matching short branch variant 3913 // of some long branch? 3914 ins_attrib ins_alignment(4); // Required alignment attribute (must 3915 // be a power of 2) specifies the 3916 // alignment that some part of the 3917 // instruction (not necessarily the 3918 // start) requires. If > 1, a 3919 // compute_padding() function must be 3920 // provided for the instruction 3921 3922 //----------OPERANDS----------------------------------------------------------- 3923 // Operand definitions must precede instruction definitions for correct parsing 3924 // in the ADLC because operands constitute user defined types which are used in 3925 // instruction definitions. 3926 3927 //----------Simple Operands---------------------------------------------------- 3928 3929 // Integer operands 32 bit 3930 // 32 bit immediate 3931 operand immI() 3932 %{ 3933 match(ConI); 3934 3935 op_cost(0); 3936 format %{ %} 3937 interface(CONST_INTER); 3938 %} 3939 3940 // 32 bit zero 3941 operand immI0() 3942 %{ 3943 predicate(n->get_int() == 0); 3944 match(ConI); 3945 3946 op_cost(0); 3947 format %{ %} 3948 interface(CONST_INTER); 3949 %} 3950 3951 // 32 bit unit increment 3952 operand immI_1() 3953 %{ 3954 predicate(n->get_int() == 1); 3955 match(ConI); 3956 3957 op_cost(0); 3958 format %{ %} 3959 interface(CONST_INTER); 3960 %} 3961 3962 // 32 bit unit decrement 3963 operand immI_M1() 3964 %{ 3965 predicate(n->get_int() == -1); 3966 match(ConI); 3967 3968 op_cost(0); 3969 format %{ %} 3970 interface(CONST_INTER); 3971 %} 3972 3973 // Shift values for add/sub extension shift 3974 operand immIExt() 3975 %{ 3976 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3977 match(ConI); 3978 3979 op_cost(0); 3980 format %{ %} 3981 interface(CONST_INTER); 3982 %} 3983 3984 operand immI_le_4() 3985 %{ 3986 predicate(n->get_int() <= 4); 3987 match(ConI); 3988 3989 op_cost(0); 3990 format %{ %} 3991 interface(CONST_INTER); 3992 %} 3993 3994 operand immI_31() 3995 %{ 3996 predicate(n->get_int() == 31); 3997 match(ConI); 3998 3999 op_cost(0); 4000 format %{ %} 4001 interface(CONST_INTER); 4002 %} 4003 4004 operand immI_8() 4005 %{ 4006 predicate(n->get_int() == 8); 4007 match(ConI); 4008 4009 op_cost(0); 4010 format %{ %} 4011 interface(CONST_INTER); 4012 %} 4013 4014 operand immI_16() 4015 %{ 4016 predicate(n->get_int() == 16); 4017 match(ConI); 4018 4019 op_cost(0); 4020 format %{ %} 4021 interface(CONST_INTER); 4022 %} 4023 4024 operand immI_24() 4025 %{ 4026 predicate(n->get_int() == 24); 4027 match(ConI); 4028 4029 op_cost(0); 4030 format %{ %} 4031 interface(CONST_INTER); 4032 %} 4033 4034 operand immI_32() 4035 %{ 4036 predicate(n->get_int() == 32); 4037 match(ConI); 4038 4039 op_cost(0); 4040 format %{ %} 4041 interface(CONST_INTER); 4042 %} 4043 4044 operand immI_48() 4045 %{ 4046 predicate(n->get_int() == 48); 4047 match(ConI); 4048 4049 op_cost(0); 4050 format %{ %} 4051 interface(CONST_INTER); 4052 %} 4053 4054 operand immI_56() 4055 %{ 4056 predicate(n->get_int() == 56); 4057 match(ConI); 4058 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 operand immI_63() 4065 %{ 4066 predicate(n->get_int() == 63); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 operand immI_64() 4075 %{ 4076 predicate(n->get_int() == 64); 4077 match(ConI); 4078 4079 op_cost(0); 4080 format %{ %} 4081 interface(CONST_INTER); 4082 %} 4083 4084 operand immI_255() 4085 %{ 4086 predicate(n->get_int() == 255); 4087 match(ConI); 4088 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 operand immI_65535() 4095 %{ 4096 predicate(n->get_int() == 65535); 4097 match(ConI); 4098 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 operand immL_255() 4105 %{ 4106 predicate(n->get_long() == 255L); 4107 match(ConL); 4108 4109 op_cost(0); 4110 format %{ %} 4111 interface(CONST_INTER); 4112 %} 4113 4114 operand immL_65535() 4115 %{ 4116 predicate(n->get_long() == 65535L); 4117 match(ConL); 4118 4119 op_cost(0); 4120 format %{ %} 4121 interface(CONST_INTER); 4122 %} 4123 4124 operand immL_4294967295() 4125 %{ 4126 predicate(n->get_long() == 4294967295L); 4127 match(ConL); 4128 4129 op_cost(0); 4130 format %{ %} 4131 interface(CONST_INTER); 4132 %} 4133 4134 operand immL_bitmask() 4135 %{ 4136 predicate((n->get_long() != 0) 4137 && ((n->get_long() & 0xc000000000000000l) == 0) 4138 && is_power_of_2(n->get_long() + 1)); 4139 match(ConL); 4140 4141 op_cost(0); 4142 format %{ %} 4143 interface(CONST_INTER); 4144 %} 4145 4146 operand immI_bitmask() 4147 %{ 4148 predicate((n->get_int() != 0) 4149 && ((n->get_int() & 0xc0000000) == 0) 4150 && is_power_of_2(n->get_int() + 1)); 4151 match(ConI); 4152 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 // Scale values for scaled offset addressing modes (up to long but not quad) 4159 operand immIScale() 4160 %{ 4161 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4162 match(ConI); 4163 4164 op_cost(0); 4165 format %{ %} 4166 interface(CONST_INTER); 4167 %} 4168 4169 // 26 bit signed offset -- for pc-relative branches 4170 operand immI26() 4171 %{ 4172 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4173 match(ConI); 4174 4175 op_cost(0); 4176 format %{ %} 4177 interface(CONST_INTER); 4178 %} 4179 4180 // 19 bit signed offset -- for pc-relative loads 4181 operand immI19() 4182 %{ 4183 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4184 match(ConI); 4185 4186 op_cost(0); 4187 format %{ %} 4188 interface(CONST_INTER); 4189 %} 4190 4191 // 12 bit unsigned offset -- for base plus immediate loads 4192 operand immIU12() 4193 %{ 4194 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4195 match(ConI); 4196 4197 op_cost(0); 4198 format %{ %} 4199 interface(CONST_INTER); 4200 %} 4201 4202 operand immLU12() 4203 %{ 4204 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4205 match(ConL); 4206 4207 op_cost(0); 4208 format %{ %} 4209 interface(CONST_INTER); 4210 %} 4211 4212 // Offset for scaled or unscaled immediate loads and stores 4213 operand immIOffset() 4214 %{ 4215 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4216 match(ConI); 4217 4218 op_cost(0); 4219 format %{ %} 4220 interface(CONST_INTER); 4221 %} 4222 4223 operand immIOffset1() 4224 %{ 4225 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4226 match(ConI); 4227 4228 op_cost(0); 4229 format %{ %} 4230 interface(CONST_INTER); 4231 %} 4232 4233 operand immIOffset2() 4234 %{ 4235 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4236 match(ConI); 4237 4238 op_cost(0); 4239 format %{ %} 4240 interface(CONST_INTER); 4241 %} 4242 4243 operand immIOffset4() 4244 %{ 4245 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4246 match(ConI); 4247 4248 op_cost(0); 4249 format %{ %} 4250 interface(CONST_INTER); 4251 %} 4252 4253 operand immIOffset8() 4254 %{ 4255 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4256 match(ConI); 4257 4258 op_cost(0); 4259 format %{ %} 4260 interface(CONST_INTER); 4261 %} 4262 4263 operand immIOffset16() 4264 %{ 4265 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4266 match(ConI); 4267 4268 op_cost(0); 4269 format %{ %} 4270 interface(CONST_INTER); 4271 %} 4272 4273 operand immLoffset() 4274 %{ 4275 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4276 match(ConL); 4277 4278 op_cost(0); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 operand immLoffset1() 4284 %{ 4285 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4286 match(ConL); 4287 4288 op_cost(0); 4289 format %{ %} 4290 interface(CONST_INTER); 4291 %} 4292 4293 operand immLoffset2() 4294 %{ 4295 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4296 match(ConL); 4297 4298 op_cost(0); 4299 format %{ %} 4300 interface(CONST_INTER); 4301 %} 4302 4303 operand immLoffset4() 4304 %{ 4305 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4306 match(ConL); 4307 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 operand immLoffset8() 4314 %{ 4315 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4316 match(ConL); 4317 4318 op_cost(0); 4319 format %{ %} 4320 interface(CONST_INTER); 4321 %} 4322 4323 operand immLoffset16() 4324 %{ 4325 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4326 match(ConL); 4327 4328 op_cost(0); 4329 format %{ %} 4330 interface(CONST_INTER); 4331 %} 4332 4333 // 32 bit integer valid for add sub immediate 4334 operand immIAddSub() 4335 %{ 4336 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4337 match(ConI); 4338 op_cost(0); 4339 format %{ %} 4340 interface(CONST_INTER); 4341 %} 4342 4343 // 32 bit unsigned integer valid for logical immediate 4344 // TODO -- check this is right when e.g the mask is 0x80000000 4345 operand immILog() 4346 %{ 4347 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4348 match(ConI); 4349 4350 op_cost(0); 4351 format %{ %} 4352 interface(CONST_INTER); 4353 %} 4354 4355 // Integer operands 64 bit 4356 // 64 bit immediate 4357 operand immL() 4358 %{ 4359 match(ConL); 4360 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // 64 bit zero 4367 operand immL0() 4368 %{ 4369 predicate(n->get_long() == 0); 4370 match(ConL); 4371 4372 op_cost(0); 4373 format %{ %} 4374 interface(CONST_INTER); 4375 %} 4376 4377 // 64 bit unit increment 4378 operand immL_1() 4379 %{ 4380 predicate(n->get_long() == 1); 4381 match(ConL); 4382 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // 64 bit unit decrement 4389 operand immL_M1() 4390 %{ 4391 predicate(n->get_long() == -1); 4392 match(ConL); 4393 4394 op_cost(0); 4395 format %{ %} 4396 interface(CONST_INTER); 4397 %} 4398 4399 // 32 bit offset of pc in thread anchor 4400 4401 operand immL_pc_off() 4402 %{ 4403 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4404 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4405 match(ConL); 4406 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410 %} 4411 4412 // 64 bit integer valid for add sub immediate 4413 operand immLAddSub() 4414 %{ 4415 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4416 match(ConL); 4417 op_cost(0); 4418 format %{ %} 4419 interface(CONST_INTER); 4420 %} 4421 4422 // 64 bit integer valid for logical immediate 4423 operand immLLog() 4424 %{ 4425 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4426 match(ConL); 4427 op_cost(0); 4428 format %{ %} 4429 interface(CONST_INTER); 4430 %} 4431 4432 // Long Immediate: low 32-bit mask 4433 operand immL_32bits() 4434 %{ 4435 predicate(n->get_long() == 0xFFFFFFFFL); 4436 match(ConL); 4437 op_cost(0); 4438 format %{ %} 4439 interface(CONST_INTER); 4440 %} 4441 4442 // Pointer operands 4443 // Pointer Immediate 4444 operand immP() 4445 %{ 4446 match(ConP); 4447 4448 op_cost(0); 4449 format %{ %} 4450 interface(CONST_INTER); 4451 %} 4452 4453 // NULL Pointer Immediate 4454 operand immP0() 4455 %{ 4456 predicate(n->get_ptr() == 0); 4457 match(ConP); 4458 4459 op_cost(0); 4460 format %{ %} 4461 interface(CONST_INTER); 4462 %} 4463 4464 // Pointer Immediate One 4465 // this is used in object initialization (initial object header) 4466 operand immP_1() 4467 %{ 4468 predicate(n->get_ptr() == 1); 4469 match(ConP); 4470 4471 op_cost(0); 4472 format %{ %} 4473 interface(CONST_INTER); 4474 %} 4475 4476 // Polling Page Pointer Immediate 4477 operand immPollPage() 4478 %{ 4479 predicate((address)n->get_ptr() == os::get_polling_page()); 4480 match(ConP); 4481 4482 op_cost(0); 4483 format %{ %} 4484 interface(CONST_INTER); 4485 %} 4486 4487 // Card Table Byte Map Base 4488 operand immByteMapBase() 4489 %{ 4490 // Get base of card map 4491 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4492 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4493 match(ConP); 4494 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // Pointer Immediate Minus One 4501 // this is used when we want to write the current PC to the thread anchor 4502 operand immP_M1() 4503 %{ 4504 predicate(n->get_ptr() == -1); 4505 match(ConP); 4506 4507 op_cost(0); 4508 format %{ %} 4509 interface(CONST_INTER); 4510 %} 4511 4512 // Pointer Immediate Minus Two 4513 // this is used when we want to write the current PC to the thread anchor 4514 operand immP_M2() 4515 %{ 4516 predicate(n->get_ptr() == -2); 4517 match(ConP); 4518 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Float and Double operands 4525 // Double Immediate 4526 operand immD() 4527 %{ 4528 match(ConD); 4529 op_cost(0); 4530 format %{ %} 4531 interface(CONST_INTER); 4532 %} 4533 4534 // Double Immediate: +0.0d 4535 operand immD0() 4536 %{ 4537 predicate(jlong_cast(n->getd()) == 0); 4538 match(ConD); 4539 4540 op_cost(0); 4541 format %{ %} 4542 interface(CONST_INTER); 4543 %} 4544 4545 // constant 'double +0.0'. 4546 operand immDPacked() 4547 %{ 4548 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4549 match(ConD); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 // Float Immediate 4556 operand immF() 4557 %{ 4558 match(ConF); 4559 op_cost(0); 4560 format %{ %} 4561 interface(CONST_INTER); 4562 %} 4563 4564 // Float Immediate: +0.0f. 4565 operand immF0() 4566 %{ 4567 predicate(jint_cast(n->getf()) == 0); 4568 match(ConF); 4569 4570 op_cost(0); 4571 format %{ %} 4572 interface(CONST_INTER); 4573 %} 4574 4575 // 4576 operand immFPacked() 4577 %{ 4578 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4579 match(ConF); 4580 op_cost(0); 4581 format %{ %} 4582 interface(CONST_INTER); 4583 %} 4584 4585 // Narrow pointer operands 4586 // Narrow Pointer Immediate 4587 operand immN() 4588 %{ 4589 match(ConN); 4590 4591 op_cost(0); 4592 format %{ %} 4593 interface(CONST_INTER); 4594 %} 4595 4596 // Narrow NULL Pointer Immediate 4597 operand immN0() 4598 %{ 4599 predicate(n->get_narrowcon() == 0); 4600 match(ConN); 4601 4602 op_cost(0); 4603 format %{ %} 4604 interface(CONST_INTER); 4605 %} 4606 4607 operand immNKlass() 4608 %{ 4609 match(ConNKlass); 4610 4611 op_cost(0); 4612 format %{ %} 4613 interface(CONST_INTER); 4614 %} 4615 4616 // Integer 32 bit Register Operands 4617 // Integer 32 bitRegister (excludes SP) 4618 operand iRegI() 4619 %{ 4620 constraint(ALLOC_IN_RC(any_reg32)); 4621 match(RegI); 4622 match(iRegINoSp); 4623 op_cost(0); 4624 format %{ %} 4625 interface(REG_INTER); 4626 %} 4627 4628 // Integer 32 bit Register not Special 4629 operand iRegINoSp() 4630 %{ 4631 constraint(ALLOC_IN_RC(no_special_reg32)); 4632 match(RegI); 4633 op_cost(0); 4634 format %{ %} 4635 interface(REG_INTER); 4636 %} 4637 4638 // Integer 64 bit Register Operands 4639 // Integer 64 bit Register (includes SP) 4640 operand iRegL() 4641 %{ 4642 constraint(ALLOC_IN_RC(any_reg)); 4643 match(RegL); 4644 match(iRegLNoSp); 4645 op_cost(0); 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 // Integer 64 bit Register not Special 4651 operand iRegLNoSp() 4652 %{ 4653 constraint(ALLOC_IN_RC(no_special_reg)); 4654 match(RegL); 4655 match(iRegL_R0); 4656 format %{ %} 4657 interface(REG_INTER); 4658 %} 4659 4660 // Pointer Register Operands 4661 // Pointer Register 4662 operand iRegP() 4663 %{ 4664 constraint(ALLOC_IN_RC(ptr_reg)); 4665 match(RegP); 4666 match(iRegPNoSp); 4667 match(iRegP_R0); 4668 //match(iRegP_R2); 4669 //match(iRegP_R4); 4670 //match(iRegP_R5); 4671 match(thread_RegP); 4672 op_cost(0); 4673 format %{ %} 4674 interface(REG_INTER); 4675 %} 4676 4677 // Pointer 64 bit Register not Special 4678 operand iRegPNoSp() 4679 %{ 4680 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4681 match(RegP); 4682 // match(iRegP); 4683 // match(iRegP_R0); 4684 // match(iRegP_R2); 4685 // match(iRegP_R4); 4686 // match(iRegP_R5); 4687 // match(thread_RegP); 4688 op_cost(0); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 // Pointer 64 bit Register R0 only 4694 operand iRegP_R0() 4695 %{ 4696 constraint(ALLOC_IN_RC(r0_reg)); 4697 match(RegP); 4698 // match(iRegP); 4699 match(iRegPNoSp); 4700 op_cost(0); 4701 format %{ %} 4702 interface(REG_INTER); 4703 %} 4704 4705 // Pointer 64 bit Register R1 only 4706 operand iRegP_R1() 4707 %{ 4708 constraint(ALLOC_IN_RC(r1_reg)); 4709 match(RegP); 4710 // match(iRegP); 4711 match(iRegPNoSp); 4712 op_cost(0); 4713 format %{ %} 4714 interface(REG_INTER); 4715 %} 4716 4717 // Pointer 64 bit Register R2 only 4718 operand iRegP_R2() 4719 %{ 4720 constraint(ALLOC_IN_RC(r2_reg)); 4721 match(RegP); 4722 // match(iRegP); 4723 match(iRegPNoSp); 4724 op_cost(0); 4725 format %{ %} 4726 interface(REG_INTER); 4727 %} 4728 4729 // Pointer 64 bit Register R3 only 4730 operand iRegP_R3() 4731 %{ 4732 constraint(ALLOC_IN_RC(r3_reg)); 4733 match(RegP); 4734 // match(iRegP); 4735 match(iRegPNoSp); 4736 op_cost(0); 4737 format %{ %} 4738 interface(REG_INTER); 4739 %} 4740 4741 // Pointer 64 bit Register R4 only 4742 operand iRegP_R4() 4743 %{ 4744 constraint(ALLOC_IN_RC(r4_reg)); 4745 match(RegP); 4746 // match(iRegP); 4747 match(iRegPNoSp); 4748 op_cost(0); 4749 format %{ %} 4750 interface(REG_INTER); 4751 %} 4752 4753 // Pointer 64 bit Register R5 only 4754 operand iRegP_R5() 4755 %{ 4756 constraint(ALLOC_IN_RC(r5_reg)); 4757 match(RegP); 4758 // match(iRegP); 4759 match(iRegPNoSp); 4760 op_cost(0); 4761 format %{ %} 4762 interface(REG_INTER); 4763 %} 4764 4765 // Pointer 64 bit Register R10 only 4766 operand iRegP_R10() 4767 %{ 4768 constraint(ALLOC_IN_RC(r10_reg)); 4769 match(RegP); 4770 // match(iRegP); 4771 match(iRegPNoSp); 4772 op_cost(0); 4773 format %{ %} 4774 interface(REG_INTER); 4775 %} 4776 4777 // Long 64 bit Register R0 only 4778 operand iRegL_R0() 4779 %{ 4780 constraint(ALLOC_IN_RC(r0_reg)); 4781 match(RegL); 4782 match(iRegLNoSp); 4783 op_cost(0); 4784 format %{ %} 4785 interface(REG_INTER); 4786 %} 4787 4788 // Long 64 bit Register R2 only 4789 operand iRegL_R2() 4790 %{ 4791 constraint(ALLOC_IN_RC(r2_reg)); 4792 match(RegL); 4793 match(iRegLNoSp); 4794 op_cost(0); 4795 format %{ %} 4796 interface(REG_INTER); 4797 %} 4798 4799 // Long 64 bit Register R3 only 4800 operand iRegL_R3() 4801 %{ 4802 constraint(ALLOC_IN_RC(r3_reg)); 4803 match(RegL); 4804 match(iRegLNoSp); 4805 op_cost(0); 4806 format %{ %} 4807 interface(REG_INTER); 4808 %} 4809 4810 // Long 64 bit Register R11 only 4811 operand iRegL_R11() 4812 %{ 4813 constraint(ALLOC_IN_RC(r11_reg)); 4814 match(RegL); 4815 match(iRegLNoSp); 4816 op_cost(0); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 // Pointer 64 bit Register FP only 4822 operand iRegP_FP() 4823 %{ 4824 constraint(ALLOC_IN_RC(fp_reg)); 4825 match(RegP); 4826 // match(iRegP); 4827 op_cost(0); 4828 format %{ %} 4829 interface(REG_INTER); 4830 %} 4831 4832 // Register R0 only 4833 operand iRegI_R0() 4834 %{ 4835 constraint(ALLOC_IN_RC(int_r0_reg)); 4836 match(RegI); 4837 match(iRegINoSp); 4838 op_cost(0); 4839 format %{ %} 4840 interface(REG_INTER); 4841 %} 4842 4843 // Register R2 only 4844 operand iRegI_R2() 4845 %{ 4846 constraint(ALLOC_IN_RC(int_r2_reg)); 4847 match(RegI); 4848 match(iRegINoSp); 4849 op_cost(0); 4850 format %{ %} 4851 interface(REG_INTER); 4852 %} 4853 4854 // Register R3 only 4855 operand iRegI_R3() 4856 %{ 4857 constraint(ALLOC_IN_RC(int_r3_reg)); 4858 match(RegI); 4859 match(iRegINoSp); 4860 op_cost(0); 4861 format %{ %} 4862 interface(REG_INTER); 4863 %} 4864 4865 4866 // Register R4 only 4867 operand iRegI_R4() 4868 %{ 4869 constraint(ALLOC_IN_RC(int_r4_reg)); 4870 match(RegI); 4871 match(iRegINoSp); 4872 op_cost(0); 4873 format %{ %} 4874 interface(REG_INTER); 4875 %} 4876 4877 4878 // Pointer Register Operands 4879 // Narrow Pointer Register 4880 operand iRegN() 4881 %{ 4882 constraint(ALLOC_IN_RC(any_reg32)); 4883 match(RegN); 4884 match(iRegNNoSp); 4885 op_cost(0); 4886 format %{ %} 4887 interface(REG_INTER); 4888 %} 4889 4890 operand iRegN_R0() 4891 %{ 4892 constraint(ALLOC_IN_RC(r0_reg)); 4893 match(iRegN); 4894 op_cost(0); 4895 format %{ %} 4896 interface(REG_INTER); 4897 %} 4898 4899 operand iRegN_R2() 4900 %{ 4901 constraint(ALLOC_IN_RC(r2_reg)); 4902 match(iRegN); 4903 op_cost(0); 4904 format %{ %} 4905 interface(REG_INTER); 4906 %} 4907 4908 operand iRegN_R3() 4909 %{ 4910 constraint(ALLOC_IN_RC(r3_reg)); 4911 match(iRegN); 4912 op_cost(0); 4913 format %{ %} 4914 interface(REG_INTER); 4915 %} 4916 4917 // Integer 64 bit Register not Special 4918 operand iRegNNoSp() 4919 %{ 4920 constraint(ALLOC_IN_RC(no_special_reg32)); 4921 match(RegN); 4922 op_cost(0); 4923 format %{ %} 4924 interface(REG_INTER); 4925 %} 4926 4927 // heap base register -- used for encoding immN0 4928 4929 operand iRegIHeapbase() 4930 %{ 4931 constraint(ALLOC_IN_RC(heapbase_reg)); 4932 match(RegI); 4933 op_cost(0); 4934 format %{ %} 4935 interface(REG_INTER); 4936 %} 4937 4938 // Float Register 4939 // Float register operands 4940 operand vRegF() 4941 %{ 4942 constraint(ALLOC_IN_RC(float_reg)); 4943 match(RegF); 4944 4945 op_cost(0); 4946 format %{ %} 4947 interface(REG_INTER); 4948 %} 4949 4950 // Double Register 4951 // Double register operands 4952 operand vRegD() 4953 %{ 4954 constraint(ALLOC_IN_RC(double_reg)); 4955 match(RegD); 4956 4957 op_cost(0); 4958 format %{ %} 4959 interface(REG_INTER); 4960 %} 4961 4962 operand vecD() 4963 %{ 4964 constraint(ALLOC_IN_RC(vectord_reg)); 4965 match(VecD); 4966 4967 op_cost(0); 4968 format %{ %} 4969 interface(REG_INTER); 4970 %} 4971 4972 operand vecX() 4973 %{ 4974 constraint(ALLOC_IN_RC(vectorx_reg)); 4975 match(VecX); 4976 4977 op_cost(0); 4978 format %{ %} 4979 interface(REG_INTER); 4980 %} 4981 4982 operand vRegD_V0() 4983 %{ 4984 constraint(ALLOC_IN_RC(v0_reg)); 4985 match(RegD); 4986 op_cost(0); 4987 format %{ %} 4988 interface(REG_INTER); 4989 %} 4990 4991 operand vRegD_V1() 4992 %{ 4993 constraint(ALLOC_IN_RC(v1_reg)); 4994 match(RegD); 4995 op_cost(0); 4996 format %{ %} 4997 interface(REG_INTER); 4998 %} 4999 5000 operand vRegD_V2() 5001 %{ 5002 constraint(ALLOC_IN_RC(v2_reg)); 5003 match(RegD); 5004 op_cost(0); 5005 format %{ %} 5006 interface(REG_INTER); 5007 %} 5008 5009 operand vRegD_V3() 5010 %{ 5011 constraint(ALLOC_IN_RC(v3_reg)); 5012 match(RegD); 5013 op_cost(0); 5014 format %{ %} 5015 interface(REG_INTER); 5016 %} 5017 5018 operand vRegD_V4() 5019 %{ 5020 constraint(ALLOC_IN_RC(v4_reg)); 5021 match(RegD); 5022 op_cost(0); 5023 format %{ %} 5024 interface(REG_INTER); 5025 %} 5026 5027 operand vRegD_V5() 5028 %{ 5029 constraint(ALLOC_IN_RC(v5_reg)); 5030 match(RegD); 5031 op_cost(0); 5032 format %{ %} 5033 interface(REG_INTER); 5034 %} 5035 5036 operand vRegD_V6() 5037 %{ 5038 constraint(ALLOC_IN_RC(v6_reg)); 5039 match(RegD); 5040 op_cost(0); 5041 format %{ %} 5042 interface(REG_INTER); 5043 %} 5044 5045 operand vRegD_V7() 5046 %{ 5047 constraint(ALLOC_IN_RC(v7_reg)); 5048 match(RegD); 5049 op_cost(0); 5050 format %{ %} 5051 interface(REG_INTER); 5052 %} 5053 5054 operand vRegD_V8() 5055 %{ 5056 constraint(ALLOC_IN_RC(v8_reg)); 5057 match(RegD); 5058 op_cost(0); 5059 format %{ %} 5060 interface(REG_INTER); 5061 %} 5062 5063 operand vRegD_V9() 5064 %{ 5065 constraint(ALLOC_IN_RC(v9_reg)); 5066 match(RegD); 5067 op_cost(0); 5068 format %{ %} 5069 interface(REG_INTER); 5070 %} 5071 5072 operand vRegD_V10() 5073 %{ 5074 constraint(ALLOC_IN_RC(v10_reg)); 5075 match(RegD); 5076 op_cost(0); 5077 format %{ %} 5078 interface(REG_INTER); 5079 %} 5080 5081 operand vRegD_V11() 5082 %{ 5083 constraint(ALLOC_IN_RC(v11_reg)); 5084 match(RegD); 5085 op_cost(0); 5086 format %{ %} 5087 interface(REG_INTER); 5088 %} 5089 5090 operand vRegD_V12() 5091 %{ 5092 constraint(ALLOC_IN_RC(v12_reg)); 5093 match(RegD); 5094 op_cost(0); 5095 format %{ %} 5096 interface(REG_INTER); 5097 %} 5098 5099 operand vRegD_V13() 5100 %{ 5101 constraint(ALLOC_IN_RC(v13_reg)); 5102 match(RegD); 5103 op_cost(0); 5104 format %{ %} 5105 interface(REG_INTER); 5106 %} 5107 5108 operand vRegD_V14() 5109 %{ 5110 constraint(ALLOC_IN_RC(v14_reg)); 5111 match(RegD); 5112 op_cost(0); 5113 format %{ %} 5114 interface(REG_INTER); 5115 %} 5116 5117 operand vRegD_V15() 5118 %{ 5119 constraint(ALLOC_IN_RC(v15_reg)); 5120 match(RegD); 5121 op_cost(0); 5122 format %{ %} 5123 interface(REG_INTER); 5124 %} 5125 5126 operand vRegD_V16() 5127 %{ 5128 constraint(ALLOC_IN_RC(v16_reg)); 5129 match(RegD); 5130 op_cost(0); 5131 format %{ %} 5132 interface(REG_INTER); 5133 %} 5134 5135 operand vRegD_V17() 5136 %{ 5137 constraint(ALLOC_IN_RC(v17_reg)); 5138 match(RegD); 5139 op_cost(0); 5140 format %{ %} 5141 interface(REG_INTER); 5142 %} 5143 5144 operand vRegD_V18() 5145 %{ 5146 constraint(ALLOC_IN_RC(v18_reg)); 5147 match(RegD); 5148 op_cost(0); 5149 format %{ %} 5150 interface(REG_INTER); 5151 %} 5152 5153 operand vRegD_V19() 5154 %{ 5155 constraint(ALLOC_IN_RC(v19_reg)); 5156 match(RegD); 5157 op_cost(0); 5158 format %{ %} 5159 interface(REG_INTER); 5160 %} 5161 5162 operand vRegD_V20() 5163 %{ 5164 constraint(ALLOC_IN_RC(v20_reg)); 5165 match(RegD); 5166 op_cost(0); 5167 format %{ %} 5168 interface(REG_INTER); 5169 %} 5170 5171 operand vRegD_V21() 5172 %{ 5173 constraint(ALLOC_IN_RC(v21_reg)); 5174 match(RegD); 5175 op_cost(0); 5176 format %{ %} 5177 interface(REG_INTER); 5178 %} 5179 5180 operand vRegD_V22() 5181 %{ 5182 constraint(ALLOC_IN_RC(v22_reg)); 5183 match(RegD); 5184 op_cost(0); 5185 format %{ %} 5186 interface(REG_INTER); 5187 %} 5188 5189 operand vRegD_V23() 5190 %{ 5191 constraint(ALLOC_IN_RC(v23_reg)); 5192 match(RegD); 5193 op_cost(0); 5194 format %{ %} 5195 interface(REG_INTER); 5196 %} 5197 5198 operand vRegD_V24() 5199 %{ 5200 constraint(ALLOC_IN_RC(v24_reg)); 5201 match(RegD); 5202 op_cost(0); 5203 format %{ %} 5204 interface(REG_INTER); 5205 %} 5206 5207 operand vRegD_V25() 5208 %{ 5209 constraint(ALLOC_IN_RC(v25_reg)); 5210 match(RegD); 5211 op_cost(0); 5212 format %{ %} 5213 interface(REG_INTER); 5214 %} 5215 5216 operand vRegD_V26() 5217 %{ 5218 constraint(ALLOC_IN_RC(v26_reg)); 5219 match(RegD); 5220 op_cost(0); 5221 format %{ %} 5222 interface(REG_INTER); 5223 %} 5224 5225 operand vRegD_V27() 5226 %{ 5227 constraint(ALLOC_IN_RC(v27_reg)); 5228 match(RegD); 5229 op_cost(0); 5230 format %{ %} 5231 interface(REG_INTER); 5232 %} 5233 5234 operand vRegD_V28() 5235 %{ 5236 constraint(ALLOC_IN_RC(v28_reg)); 5237 match(RegD); 5238 op_cost(0); 5239 format %{ %} 5240 interface(REG_INTER); 5241 %} 5242 5243 operand vRegD_V29() 5244 %{ 5245 constraint(ALLOC_IN_RC(v29_reg)); 5246 match(RegD); 5247 op_cost(0); 5248 format %{ %} 5249 interface(REG_INTER); 5250 %} 5251 5252 operand vRegD_V30() 5253 %{ 5254 constraint(ALLOC_IN_RC(v30_reg)); 5255 match(RegD); 5256 op_cost(0); 5257 format %{ %} 5258 interface(REG_INTER); 5259 %} 5260 5261 operand vRegD_V31() 5262 %{ 5263 constraint(ALLOC_IN_RC(v31_reg)); 5264 match(RegD); 5265 op_cost(0); 5266 format %{ %} 5267 interface(REG_INTER); 5268 %} 5269 5270 // Flags register, used as output of signed compare instructions 5271 5272 // note that on AArch64 we also use this register as the output for 5273 // for floating point compare instructions (CmpF CmpD). this ensures 5274 // that ordered inequality tests use GT, GE, LT or LE none of which 5275 // pass through cases where the result is unordered i.e. one or both 5276 // inputs to the compare is a NaN. this means that the ideal code can 5277 // replace e.g. a GT with an LE and not end up capturing the NaN case 5278 // (where the comparison should always fail). EQ and NE tests are 5279 // always generated in ideal code so that unordered folds into the NE 5280 // case, matching the behaviour of AArch64 NE. 5281 // 5282 // This differs from x86 where the outputs of FP compares use a 5283 // special FP flags registers and where compares based on this 5284 // register are distinguished into ordered inequalities (cmpOpUCF) and 5285 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5286 // to explicitly handle the unordered case in branches. x86 also has 5287 // to include extra CMoveX rules to accept a cmpOpUCF input. 5288 5289 operand rFlagsReg() 5290 %{ 5291 constraint(ALLOC_IN_RC(int_flags)); 5292 match(RegFlags); 5293 5294 op_cost(0); 5295 format %{ "RFLAGS" %} 5296 interface(REG_INTER); 5297 %} 5298 5299 // Flags register, used as output of unsigned compare instructions 5300 operand rFlagsRegU() 5301 %{ 5302 constraint(ALLOC_IN_RC(int_flags)); 5303 match(RegFlags); 5304 5305 op_cost(0); 5306 format %{ "RFLAGSU" %} 5307 interface(REG_INTER); 5308 %} 5309 5310 // Special Registers 5311 5312 // Method Register 5313 operand inline_cache_RegP(iRegP reg) 5314 %{ 5315 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5316 match(reg); 5317 match(iRegPNoSp); 5318 op_cost(0); 5319 format %{ %} 5320 interface(REG_INTER); 5321 %} 5322 5323 operand interpreter_method_oop_RegP(iRegP reg) 5324 %{ 5325 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5326 match(reg); 5327 match(iRegPNoSp); 5328 op_cost(0); 5329 format %{ %} 5330 interface(REG_INTER); 5331 %} 5332 5333 // Thread Register 5334 operand thread_RegP(iRegP reg) 5335 %{ 5336 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5337 match(reg); 5338 op_cost(0); 5339 format %{ %} 5340 interface(REG_INTER); 5341 %} 5342 5343 operand lr_RegP(iRegP reg) 5344 %{ 5345 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5346 match(reg); 5347 op_cost(0); 5348 format %{ %} 5349 interface(REG_INTER); 5350 %} 5351 5352 //----------Memory Operands---------------------------------------------------- 5353 5354 operand indirect(iRegP reg) 5355 %{ 5356 constraint(ALLOC_IN_RC(ptr_reg)); 5357 match(reg); 5358 op_cost(0); 5359 format %{ "[$reg]" %} 5360 interface(MEMORY_INTER) %{ 5361 base($reg); 5362 index(0xffffffff); 5363 scale(0x0); 5364 disp(0x0); 5365 %} 5366 %} 5367 5368 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5369 %{ 5370 constraint(ALLOC_IN_RC(ptr_reg)); 5371 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5372 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5373 op_cost(0); 5374 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5375 interface(MEMORY_INTER) %{ 5376 base($reg); 5377 index($ireg); 5378 scale($scale); 5379 disp(0x0); 5380 %} 5381 %} 5382 5383 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5384 %{ 5385 constraint(ALLOC_IN_RC(ptr_reg)); 5386 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5387 match(AddP reg (LShiftL lreg scale)); 5388 op_cost(0); 5389 format %{ "$reg, $lreg lsl($scale)" %} 5390 interface(MEMORY_INTER) %{ 5391 base($reg); 5392 index($lreg); 5393 scale($scale); 5394 disp(0x0); 5395 %} 5396 %} 5397 5398 operand indIndexI2L(iRegP reg, iRegI ireg) 5399 %{ 5400 constraint(ALLOC_IN_RC(ptr_reg)); 5401 match(AddP reg (ConvI2L ireg)); 5402 op_cost(0); 5403 format %{ "$reg, $ireg, 0, I2L" %} 5404 interface(MEMORY_INTER) %{ 5405 base($reg); 5406 index($ireg); 5407 scale(0x0); 5408 disp(0x0); 5409 %} 5410 %} 5411 5412 operand indIndex(iRegP reg, iRegL lreg) 5413 %{ 5414 constraint(ALLOC_IN_RC(ptr_reg)); 5415 match(AddP reg lreg); 5416 op_cost(0); 5417 format %{ "$reg, $lreg" %} 5418 interface(MEMORY_INTER) %{ 5419 base($reg); 5420 index($lreg); 5421 scale(0x0); 5422 disp(0x0); 5423 %} 5424 %} 5425 5426 operand indOffI(iRegP reg, immIOffset off) 5427 %{ 5428 constraint(ALLOC_IN_RC(ptr_reg)); 5429 match(AddP reg off); 5430 op_cost(0); 5431 format %{ "[$reg, $off]" %} 5432 interface(MEMORY_INTER) %{ 5433 base($reg); 5434 index(0xffffffff); 5435 scale(0x0); 5436 disp($off); 5437 %} 5438 %} 5439 5440 operand indOffI1(iRegP reg, immIOffset1 off) 5441 %{ 5442 constraint(ALLOC_IN_RC(ptr_reg)); 5443 match(AddP reg off); 5444 op_cost(0); 5445 format %{ "[$reg, $off]" %} 5446 interface(MEMORY_INTER) %{ 5447 base($reg); 5448 index(0xffffffff); 5449 scale(0x0); 5450 disp($off); 5451 %} 5452 %} 5453 5454 operand indOffI2(iRegP reg, immIOffset2 off) 5455 %{ 5456 constraint(ALLOC_IN_RC(ptr_reg)); 5457 match(AddP reg off); 5458 op_cost(0); 5459 format %{ "[$reg, $off]" %} 5460 interface(MEMORY_INTER) %{ 5461 base($reg); 5462 index(0xffffffff); 5463 scale(0x0); 5464 disp($off); 5465 %} 5466 %} 5467 5468 operand indOffI4(iRegP reg, immIOffset4 off) 5469 %{ 5470 constraint(ALLOC_IN_RC(ptr_reg)); 5471 match(AddP reg off); 5472 op_cost(0); 5473 format %{ "[$reg, $off]" %} 5474 interface(MEMORY_INTER) %{ 5475 base($reg); 5476 index(0xffffffff); 5477 scale(0x0); 5478 disp($off); 5479 %} 5480 %} 5481 5482 operand indOffI8(iRegP reg, immIOffset8 off) 5483 %{ 5484 constraint(ALLOC_IN_RC(ptr_reg)); 5485 match(AddP reg off); 5486 op_cost(0); 5487 format %{ "[$reg, $off]" %} 5488 interface(MEMORY_INTER) %{ 5489 base($reg); 5490 index(0xffffffff); 5491 scale(0x0); 5492 disp($off); 5493 %} 5494 %} 5495 5496 operand indOffI16(iRegP reg, immIOffset16 off) 5497 %{ 5498 constraint(ALLOC_IN_RC(ptr_reg)); 5499 match(AddP reg off); 5500 op_cost(0); 5501 format %{ "[$reg, $off]" %} 5502 interface(MEMORY_INTER) %{ 5503 base($reg); 5504 index(0xffffffff); 5505 scale(0x0); 5506 disp($off); 5507 %} 5508 %} 5509 5510 operand indOffL(iRegP reg, immLoffset off) 5511 %{ 5512 constraint(ALLOC_IN_RC(ptr_reg)); 5513 match(AddP reg off); 5514 op_cost(0); 5515 format %{ "[$reg, $off]" %} 5516 interface(MEMORY_INTER) %{ 5517 base($reg); 5518 index(0xffffffff); 5519 scale(0x0); 5520 disp($off); 5521 %} 5522 %} 5523 5524 operand indOffL1(iRegP reg, immLoffset1 off) 5525 %{ 5526 constraint(ALLOC_IN_RC(ptr_reg)); 5527 match(AddP reg off); 5528 op_cost(0); 5529 format %{ "[$reg, $off]" %} 5530 interface(MEMORY_INTER) %{ 5531 base($reg); 5532 index(0xffffffff); 5533 scale(0x0); 5534 disp($off); 5535 %} 5536 %} 5537 5538 operand indOffL2(iRegP reg, immLoffset2 off) 5539 %{ 5540 constraint(ALLOC_IN_RC(ptr_reg)); 5541 match(AddP reg off); 5542 op_cost(0); 5543 format %{ "[$reg, $off]" %} 5544 interface(MEMORY_INTER) %{ 5545 base($reg); 5546 index(0xffffffff); 5547 scale(0x0); 5548 disp($off); 5549 %} 5550 %} 5551 5552 operand indOffL4(iRegP reg, immLoffset4 off) 5553 %{ 5554 constraint(ALLOC_IN_RC(ptr_reg)); 5555 match(AddP reg off); 5556 op_cost(0); 5557 format %{ "[$reg, $off]" %} 5558 interface(MEMORY_INTER) %{ 5559 base($reg); 5560 index(0xffffffff); 5561 scale(0x0); 5562 disp($off); 5563 %} 5564 %} 5565 5566 operand indOffL8(iRegP reg, immLoffset8 off) 5567 %{ 5568 constraint(ALLOC_IN_RC(ptr_reg)); 5569 match(AddP reg off); 5570 op_cost(0); 5571 format %{ "[$reg, $off]" %} 5572 interface(MEMORY_INTER) %{ 5573 base($reg); 5574 index(0xffffffff); 5575 scale(0x0); 5576 disp($off); 5577 %} 5578 %} 5579 5580 operand indOffL16(iRegP reg, immLoffset16 off) 5581 %{ 5582 constraint(ALLOC_IN_RC(ptr_reg)); 5583 match(AddP reg off); 5584 op_cost(0); 5585 format %{ "[$reg, $off]" %} 5586 interface(MEMORY_INTER) %{ 5587 base($reg); 5588 index(0xffffffff); 5589 scale(0x0); 5590 disp($off); 5591 %} 5592 %} 5593 5594 operand indirectN(iRegN reg) 5595 %{ 5596 predicate(CompressedOops::shift() == 0); 5597 constraint(ALLOC_IN_RC(ptr_reg)); 5598 match(DecodeN reg); 5599 op_cost(0); 5600 format %{ "[$reg]\t# narrow" %} 5601 interface(MEMORY_INTER) %{ 5602 base($reg); 5603 index(0xffffffff); 5604 scale(0x0); 5605 disp(0x0); 5606 %} 5607 %} 5608 5609 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5610 %{ 5611 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5612 constraint(ALLOC_IN_RC(ptr_reg)); 5613 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5614 op_cost(0); 5615 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5616 interface(MEMORY_INTER) %{ 5617 base($reg); 5618 index($ireg); 5619 scale($scale); 5620 disp(0x0); 5621 %} 5622 %} 5623 5624 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5625 %{ 5626 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5627 constraint(ALLOC_IN_RC(ptr_reg)); 5628 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5629 op_cost(0); 5630 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5631 interface(MEMORY_INTER) %{ 5632 base($reg); 5633 index($lreg); 5634 scale($scale); 5635 disp(0x0); 5636 %} 5637 %} 5638 5639 operand indIndexI2LN(iRegN reg, iRegI ireg) 5640 %{ 5641 predicate(CompressedOops::shift() == 0); 5642 constraint(ALLOC_IN_RC(ptr_reg)); 5643 match(AddP (DecodeN reg) (ConvI2L ireg)); 5644 op_cost(0); 5645 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5646 interface(MEMORY_INTER) %{ 5647 base($reg); 5648 index($ireg); 5649 scale(0x0); 5650 disp(0x0); 5651 %} 5652 %} 5653 5654 operand indIndexN(iRegN reg, iRegL lreg) 5655 %{ 5656 predicate(CompressedOops::shift() == 0); 5657 constraint(ALLOC_IN_RC(ptr_reg)); 5658 match(AddP (DecodeN reg) lreg); 5659 op_cost(0); 5660 format %{ "$reg, $lreg\t# narrow" %} 5661 interface(MEMORY_INTER) %{ 5662 base($reg); 5663 index($lreg); 5664 scale(0x0); 5665 disp(0x0); 5666 %} 5667 %} 5668 5669 operand indOffIN(iRegN reg, immIOffset off) 5670 %{ 5671 predicate(CompressedOops::shift() == 0); 5672 constraint(ALLOC_IN_RC(ptr_reg)); 5673 match(AddP (DecodeN reg) off); 5674 op_cost(0); 5675 format %{ "[$reg, $off]\t# narrow" %} 5676 interface(MEMORY_INTER) %{ 5677 base($reg); 5678 index(0xffffffff); 5679 scale(0x0); 5680 disp($off); 5681 %} 5682 %} 5683 5684 operand indOffLN(iRegN reg, immLoffset off) 5685 %{ 5686 predicate(CompressedOops::shift() == 0); 5687 constraint(ALLOC_IN_RC(ptr_reg)); 5688 match(AddP (DecodeN reg) off); 5689 op_cost(0); 5690 format %{ "[$reg, $off]\t# narrow" %} 5691 interface(MEMORY_INTER) %{ 5692 base($reg); 5693 index(0xffffffff); 5694 scale(0x0); 5695 disp($off); 5696 %} 5697 %} 5698 5699 5700 5701 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5702 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5703 %{ 5704 constraint(ALLOC_IN_RC(ptr_reg)); 5705 match(AddP reg off); 5706 op_cost(0); 5707 format %{ "[$reg, $off]" %} 5708 interface(MEMORY_INTER) %{ 5709 base($reg); 5710 index(0xffffffff); 5711 scale(0x0); 5712 disp($off); 5713 %} 5714 %} 5715 5716 //----------Special Memory Operands-------------------------------------------- 5717 // Stack Slot Operand - This operand is used for loading and storing temporary 5718 // values on the stack where a match requires a value to 5719 // flow through memory. 5720 operand stackSlotP(sRegP reg) 5721 %{ 5722 constraint(ALLOC_IN_RC(stack_slots)); 5723 op_cost(100); 5724 // No match rule because this operand is only generated in matching 5725 // match(RegP); 5726 format %{ "[$reg]" %} 5727 interface(MEMORY_INTER) %{ 5728 base(0x1e); // RSP 5729 index(0x0); // No Index 5730 scale(0x0); // No Scale 5731 disp($reg); // Stack Offset 5732 %} 5733 %} 5734 5735 operand stackSlotI(sRegI reg) 5736 %{ 5737 constraint(ALLOC_IN_RC(stack_slots)); 5738 // No match rule because this operand is only generated in matching 5739 // match(RegI); 5740 format %{ "[$reg]" %} 5741 interface(MEMORY_INTER) %{ 5742 base(0x1e); // RSP 5743 index(0x0); // No Index 5744 scale(0x0); // No Scale 5745 disp($reg); // Stack Offset 5746 %} 5747 %} 5748 5749 operand stackSlotF(sRegF reg) 5750 %{ 5751 constraint(ALLOC_IN_RC(stack_slots)); 5752 // No match rule because this operand is only generated in matching 5753 // match(RegF); 5754 format %{ "[$reg]" %} 5755 interface(MEMORY_INTER) %{ 5756 base(0x1e); // RSP 5757 index(0x0); // No Index 5758 scale(0x0); // No Scale 5759 disp($reg); // Stack Offset 5760 %} 5761 %} 5762 5763 operand stackSlotD(sRegD reg) 5764 %{ 5765 constraint(ALLOC_IN_RC(stack_slots)); 5766 // No match rule because this operand is only generated in matching 5767 // match(RegD); 5768 format %{ "[$reg]" %} 5769 interface(MEMORY_INTER) %{ 5770 base(0x1e); // RSP 5771 index(0x0); // No Index 5772 scale(0x0); // No Scale 5773 disp($reg); // Stack Offset 5774 %} 5775 %} 5776 5777 operand stackSlotL(sRegL reg) 5778 %{ 5779 constraint(ALLOC_IN_RC(stack_slots)); 5780 // No match rule because this operand is only generated in matching 5781 // match(RegL); 5782 format %{ "[$reg]" %} 5783 interface(MEMORY_INTER) %{ 5784 base(0x1e); // RSP 5785 index(0x0); // No Index 5786 scale(0x0); // No Scale 5787 disp($reg); // Stack Offset 5788 %} 5789 %} 5790 5791 // Operands for expressing Control Flow 5792 // NOTE: Label is a predefined operand which should not be redefined in 5793 // the AD file. It is generically handled within the ADLC. 5794 5795 //----------Conditional Branch Operands---------------------------------------- 5796 // Comparison Op - This is the operation of the comparison, and is limited to 5797 // the following set of codes: 5798 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5799 // 5800 // Other attributes of the comparison, such as unsignedness, are specified 5801 // by the comparison instruction that sets a condition code flags register. 5802 // That result is represented by a flags operand whose subtype is appropriate 5803 // to the unsignedness (etc.) of the comparison. 5804 // 5805 // Later, the instruction which matches both the Comparison Op (a Bool) and 5806 // the flags (produced by the Cmp) specifies the coding of the comparison op 5807 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5808 5809 // used for signed integral comparisons and fp comparisons 5810 5811 operand cmpOp() 5812 %{ 5813 match(Bool); 5814 5815 format %{ "" %} 5816 interface(COND_INTER) %{ 5817 equal(0x0, "eq"); 5818 not_equal(0x1, "ne"); 5819 less(0xb, "lt"); 5820 greater_equal(0xa, "ge"); 5821 less_equal(0xd, "le"); 5822 greater(0xc, "gt"); 5823 overflow(0x6, "vs"); 5824 no_overflow(0x7, "vc"); 5825 %} 5826 %} 5827 5828 // used for unsigned integral comparisons 5829 5830 operand cmpOpU() 5831 %{ 5832 match(Bool); 5833 5834 format %{ "" %} 5835 interface(COND_INTER) %{ 5836 equal(0x0, "eq"); 5837 not_equal(0x1, "ne"); 5838 less(0x3, "lo"); 5839 greater_equal(0x2, "hs"); 5840 less_equal(0x9, "ls"); 5841 greater(0x8, "hi"); 5842 overflow(0x6, "vs"); 5843 no_overflow(0x7, "vc"); 5844 %} 5845 %} 5846 5847 // used for certain integral comparisons which can be 5848 // converted to cbxx or tbxx instructions 5849 5850 operand cmpOpEqNe() 5851 %{ 5852 match(Bool); 5853 op_cost(0); 5854 predicate(n->as_Bool()->_test._test == BoolTest::ne 5855 || n->as_Bool()->_test._test == BoolTest::eq); 5856 5857 format %{ "" %} 5858 interface(COND_INTER) %{ 5859 equal(0x0, "eq"); 5860 not_equal(0x1, "ne"); 5861 less(0xb, "lt"); 5862 greater_equal(0xa, "ge"); 5863 less_equal(0xd, "le"); 5864 greater(0xc, "gt"); 5865 overflow(0x6, "vs"); 5866 no_overflow(0x7, "vc"); 5867 %} 5868 %} 5869 5870 // used for certain integral comparisons which can be 5871 // converted to cbxx or tbxx instructions 5872 5873 operand cmpOpLtGe() 5874 %{ 5875 match(Bool); 5876 op_cost(0); 5877 5878 predicate(n->as_Bool()->_test._test == BoolTest::lt 5879 || n->as_Bool()->_test._test == BoolTest::ge); 5880 5881 format %{ "" %} 5882 interface(COND_INTER) %{ 5883 equal(0x0, "eq"); 5884 not_equal(0x1, "ne"); 5885 less(0xb, "lt"); 5886 greater_equal(0xa, "ge"); 5887 less_equal(0xd, "le"); 5888 greater(0xc, "gt"); 5889 overflow(0x6, "vs"); 5890 no_overflow(0x7, "vc"); 5891 %} 5892 %} 5893 5894 // used for certain unsigned integral comparisons which can be 5895 // converted to cbxx or tbxx instructions 5896 5897 operand cmpOpUEqNeLtGe() 5898 %{ 5899 match(Bool); 5900 op_cost(0); 5901 5902 predicate(n->as_Bool()->_test._test == BoolTest::eq 5903 || n->as_Bool()->_test._test == BoolTest::ne 5904 || n->as_Bool()->_test._test == BoolTest::lt 5905 || n->as_Bool()->_test._test == BoolTest::ge); 5906 5907 format %{ "" %} 5908 interface(COND_INTER) %{ 5909 equal(0x0, "eq"); 5910 not_equal(0x1, "ne"); 5911 less(0xb, "lt"); 5912 greater_equal(0xa, "ge"); 5913 less_equal(0xd, "le"); 5914 greater(0xc, "gt"); 5915 overflow(0x6, "vs"); 5916 no_overflow(0x7, "vc"); 5917 %} 5918 %} 5919 5920 // Special operand allowing long args to int ops to be truncated for free 5921 5922 operand iRegL2I(iRegL reg) %{ 5923 5924 op_cost(0); 5925 5926 match(ConvL2I reg); 5927 5928 format %{ "l2i($reg)" %} 5929 5930 interface(REG_INTER) 5931 %} 5932 5933 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5934 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5935 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5936 5937 //----------OPERAND CLASSES---------------------------------------------------- 5938 // Operand Classes are groups of operands that are used as to simplify 5939 // instruction definitions by not requiring the AD writer to specify 5940 // separate instructions for every form of operand when the 5941 // instruction accepts multiple operand types with the same basic 5942 // encoding and format. The classic case of this is memory operands. 5943 5944 // memory is used to define read/write location for load/store 5945 // instruction defs. we can turn a memory op into an Address 5946 5947 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 5948 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5949 5950 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 5951 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 5952 5953 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 5954 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5955 5956 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 5957 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5958 5959 // All of the memory operands. For the pipeline description. 5960 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 5961 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 5962 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5963 5964 5965 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5966 // operations. it allows the src to be either an iRegI or a (ConvL2I 5967 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5968 // can be elided because the 32-bit instruction will just employ the 5969 // lower 32 bits anyway. 5970 // 5971 // n.b. this does not elide all L2I conversions. if the truncated 5972 // value is consumed by more than one operation then the ConvL2I 5973 // cannot be bundled into the consuming nodes so an l2i gets planted 5974 // (actually a movw $dst $src) and the downstream instructions consume 5975 // the result of the l2i as an iRegI input. That's a shame since the 5976 // movw is actually redundant but its not too costly. 5977 5978 opclass iRegIorL2I(iRegI, iRegL2I); 5979 5980 //----------PIPELINE----------------------------------------------------------- 5981 // Rules which define the behavior of the target architectures pipeline. 5982 5983 // For specific pipelines, eg A53, define the stages of that pipeline 5984 //pipe_desc(ISS, EX1, EX2, WR); 5985 #define ISS S0 5986 #define EX1 S1 5987 #define EX2 S2 5988 #define WR S3 5989 5990 // Integer ALU reg operation 5991 pipeline %{ 5992 5993 attributes %{ 5994 // ARM instructions are of fixed length 5995 fixed_size_instructions; // Fixed size instructions TODO does 5996 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5997 // ARM instructions come in 32-bit word units 5998 instruction_unit_size = 4; // An instruction is 4 bytes long 5999 instruction_fetch_unit_size = 64; // The processor fetches one line 6000 instruction_fetch_units = 1; // of 64 bytes 6001 6002 // List of nop instructions 6003 nops( MachNop ); 6004 %} 6005 6006 // We don't use an actual pipeline model so don't care about resources 6007 // or description. we do use pipeline classes to introduce fixed 6008 // latencies 6009 6010 //----------RESOURCES---------------------------------------------------------- 6011 // Resources are the functional units available to the machine 6012 6013 resources( INS0, INS1, INS01 = INS0 | INS1, 6014 ALU0, ALU1, ALU = ALU0 | ALU1, 6015 MAC, 6016 DIV, 6017 BRANCH, 6018 LDST, 6019 NEON_FP); 6020 6021 //----------PIPELINE DESCRIPTION----------------------------------------------- 6022 // Pipeline Description specifies the stages in the machine's pipeline 6023 6024 // Define the pipeline as a generic 6 stage pipeline 6025 pipe_desc(S0, S1, S2, S3, S4, S5); 6026 6027 //----------PIPELINE CLASSES--------------------------------------------------- 6028 // Pipeline Classes describe the stages in which input and output are 6029 // referenced by the hardware pipeline. 6030 6031 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 6032 %{ 6033 single_instruction; 6034 src1 : S1(read); 6035 src2 : S2(read); 6036 dst : S5(write); 6037 INS01 : ISS; 6038 NEON_FP : S5; 6039 %} 6040 6041 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 6042 %{ 6043 single_instruction; 6044 src1 : S1(read); 6045 src2 : S2(read); 6046 dst : S5(write); 6047 INS01 : ISS; 6048 NEON_FP : S5; 6049 %} 6050 6051 pipe_class fp_uop_s(vRegF dst, vRegF src) 6052 %{ 6053 single_instruction; 6054 src : S1(read); 6055 dst : S5(write); 6056 INS01 : ISS; 6057 NEON_FP : S5; 6058 %} 6059 6060 pipe_class fp_uop_d(vRegD dst, vRegD src) 6061 %{ 6062 single_instruction; 6063 src : S1(read); 6064 dst : S5(write); 6065 INS01 : ISS; 6066 NEON_FP : S5; 6067 %} 6068 6069 pipe_class fp_d2f(vRegF dst, vRegD src) 6070 %{ 6071 single_instruction; 6072 src : S1(read); 6073 dst : S5(write); 6074 INS01 : ISS; 6075 NEON_FP : S5; 6076 %} 6077 6078 pipe_class fp_f2d(vRegD dst, vRegF src) 6079 %{ 6080 single_instruction; 6081 src : S1(read); 6082 dst : S5(write); 6083 INS01 : ISS; 6084 NEON_FP : S5; 6085 %} 6086 6087 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 6088 %{ 6089 single_instruction; 6090 src : S1(read); 6091 dst : S5(write); 6092 INS01 : ISS; 6093 NEON_FP : S5; 6094 %} 6095 6096 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6097 %{ 6098 single_instruction; 6099 src : S1(read); 6100 dst : S5(write); 6101 INS01 : ISS; 6102 NEON_FP : S5; 6103 %} 6104 6105 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6106 %{ 6107 single_instruction; 6108 src : S1(read); 6109 dst : S5(write); 6110 INS01 : ISS; 6111 NEON_FP : S5; 6112 %} 6113 6114 pipe_class fp_l2f(vRegF dst, iRegL src) 6115 %{ 6116 single_instruction; 6117 src : S1(read); 6118 dst : S5(write); 6119 INS01 : ISS; 6120 NEON_FP : S5; 6121 %} 6122 6123 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6124 %{ 6125 single_instruction; 6126 src : S1(read); 6127 dst : S5(write); 6128 INS01 : ISS; 6129 NEON_FP : S5; 6130 %} 6131 6132 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6133 %{ 6134 single_instruction; 6135 src : S1(read); 6136 dst : S5(write); 6137 INS01 : ISS; 6138 NEON_FP : S5; 6139 %} 6140 6141 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6142 %{ 6143 single_instruction; 6144 src : S1(read); 6145 dst : S5(write); 6146 INS01 : ISS; 6147 NEON_FP : S5; 6148 %} 6149 6150 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6151 %{ 6152 single_instruction; 6153 src : S1(read); 6154 dst : S5(write); 6155 INS01 : ISS; 6156 NEON_FP : S5; 6157 %} 6158 6159 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6160 %{ 6161 single_instruction; 6162 src1 : S1(read); 6163 src2 : S2(read); 6164 dst : S5(write); 6165 INS0 : ISS; 6166 NEON_FP : S5; 6167 %} 6168 6169 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6170 %{ 6171 single_instruction; 6172 src1 : S1(read); 6173 src2 : S2(read); 6174 dst : S5(write); 6175 INS0 : ISS; 6176 NEON_FP : S5; 6177 %} 6178 6179 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6180 %{ 6181 single_instruction; 6182 cr : S1(read); 6183 src1 : S1(read); 6184 src2 : S1(read); 6185 dst : S3(write); 6186 INS01 : ISS; 6187 NEON_FP : S3; 6188 %} 6189 6190 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6191 %{ 6192 single_instruction; 6193 cr : S1(read); 6194 src1 : S1(read); 6195 src2 : S1(read); 6196 dst : S3(write); 6197 INS01 : ISS; 6198 NEON_FP : S3; 6199 %} 6200 6201 pipe_class fp_imm_s(vRegF dst) 6202 %{ 6203 single_instruction; 6204 dst : S3(write); 6205 INS01 : ISS; 6206 NEON_FP : S3; 6207 %} 6208 6209 pipe_class fp_imm_d(vRegD dst) 6210 %{ 6211 single_instruction; 6212 dst : S3(write); 6213 INS01 : ISS; 6214 NEON_FP : S3; 6215 %} 6216 6217 pipe_class fp_load_constant_s(vRegF dst) 6218 %{ 6219 single_instruction; 6220 dst : S4(write); 6221 INS01 : ISS; 6222 NEON_FP : S4; 6223 %} 6224 6225 pipe_class fp_load_constant_d(vRegD dst) 6226 %{ 6227 single_instruction; 6228 dst : S4(write); 6229 INS01 : ISS; 6230 NEON_FP : S4; 6231 %} 6232 6233 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6234 %{ 6235 single_instruction; 6236 dst : S5(write); 6237 src1 : S1(read); 6238 src2 : S1(read); 6239 INS01 : ISS; 6240 NEON_FP : S5; 6241 %} 6242 6243 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6244 %{ 6245 single_instruction; 6246 dst : S5(write); 6247 src1 : S1(read); 6248 src2 : S1(read); 6249 INS0 : ISS; 6250 NEON_FP : S5; 6251 %} 6252 6253 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6254 %{ 6255 single_instruction; 6256 dst : S5(write); 6257 src1 : S1(read); 6258 src2 : S1(read); 6259 dst : S1(read); 6260 INS01 : ISS; 6261 NEON_FP : S5; 6262 %} 6263 6264 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6265 %{ 6266 single_instruction; 6267 dst : S5(write); 6268 src1 : S1(read); 6269 src2 : S1(read); 6270 dst : S1(read); 6271 INS0 : ISS; 6272 NEON_FP : S5; 6273 %} 6274 6275 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6276 %{ 6277 single_instruction; 6278 dst : S4(write); 6279 src1 : S2(read); 6280 src2 : S2(read); 6281 INS01 : ISS; 6282 NEON_FP : S4; 6283 %} 6284 6285 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6286 %{ 6287 single_instruction; 6288 dst : S4(write); 6289 src1 : S2(read); 6290 src2 : S2(read); 6291 INS0 : ISS; 6292 NEON_FP : S4; 6293 %} 6294 6295 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6296 %{ 6297 single_instruction; 6298 dst : S3(write); 6299 src1 : S2(read); 6300 src2 : S2(read); 6301 INS01 : ISS; 6302 NEON_FP : S3; 6303 %} 6304 6305 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6306 %{ 6307 single_instruction; 6308 dst : S3(write); 6309 src1 : S2(read); 6310 src2 : S2(read); 6311 INS0 : ISS; 6312 NEON_FP : S3; 6313 %} 6314 6315 pipe_class vshift64(vecD dst, vecD src, vecX shift) 6316 %{ 6317 single_instruction; 6318 dst : S3(write); 6319 src : S1(read); 6320 shift : S1(read); 6321 INS01 : ISS; 6322 NEON_FP : S3; 6323 %} 6324 6325 pipe_class vshift128(vecX dst, vecX src, vecX shift) 6326 %{ 6327 single_instruction; 6328 dst : S3(write); 6329 src : S1(read); 6330 shift : S1(read); 6331 INS0 : ISS; 6332 NEON_FP : S3; 6333 %} 6334 6335 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6336 %{ 6337 single_instruction; 6338 dst : S3(write); 6339 src : S1(read); 6340 INS01 : ISS; 6341 NEON_FP : S3; 6342 %} 6343 6344 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6345 %{ 6346 single_instruction; 6347 dst : S3(write); 6348 src : S1(read); 6349 INS0 : ISS; 6350 NEON_FP : S3; 6351 %} 6352 6353 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6354 %{ 6355 single_instruction; 6356 dst : S5(write); 6357 src1 : S1(read); 6358 src2 : S1(read); 6359 INS01 : ISS; 6360 NEON_FP : S5; 6361 %} 6362 6363 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6364 %{ 6365 single_instruction; 6366 dst : S5(write); 6367 src1 : S1(read); 6368 src2 : S1(read); 6369 INS0 : ISS; 6370 NEON_FP : S5; 6371 %} 6372 6373 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6374 %{ 6375 single_instruction; 6376 dst : S5(write); 6377 src1 : S1(read); 6378 src2 : S1(read); 6379 INS0 : ISS; 6380 NEON_FP : S5; 6381 %} 6382 6383 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6384 %{ 6385 single_instruction; 6386 dst : S5(write); 6387 src1 : S1(read); 6388 src2 : S1(read); 6389 INS0 : ISS; 6390 NEON_FP : S5; 6391 %} 6392 6393 pipe_class vsqrt_fp128(vecX dst, vecX src) 6394 %{ 6395 single_instruction; 6396 dst : S5(write); 6397 src : S1(read); 6398 INS0 : ISS; 6399 NEON_FP : S5; 6400 %} 6401 6402 pipe_class vunop_fp64(vecD dst, vecD src) 6403 %{ 6404 single_instruction; 6405 dst : S5(write); 6406 src : S1(read); 6407 INS01 : ISS; 6408 NEON_FP : S5; 6409 %} 6410 6411 pipe_class vunop_fp128(vecX dst, vecX src) 6412 %{ 6413 single_instruction; 6414 dst : S5(write); 6415 src : S1(read); 6416 INS0 : ISS; 6417 NEON_FP : S5; 6418 %} 6419 6420 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6421 %{ 6422 single_instruction; 6423 dst : S3(write); 6424 src : S1(read); 6425 INS01 : ISS; 6426 NEON_FP : S3; 6427 %} 6428 6429 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6430 %{ 6431 single_instruction; 6432 dst : S3(write); 6433 src : S1(read); 6434 INS01 : ISS; 6435 NEON_FP : S3; 6436 %} 6437 6438 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6439 %{ 6440 single_instruction; 6441 dst : S3(write); 6442 src : S1(read); 6443 INS01 : ISS; 6444 NEON_FP : S3; 6445 %} 6446 6447 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6448 %{ 6449 single_instruction; 6450 dst : S3(write); 6451 src : S1(read); 6452 INS01 : ISS; 6453 NEON_FP : S3; 6454 %} 6455 6456 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6457 %{ 6458 single_instruction; 6459 dst : S3(write); 6460 src : S1(read); 6461 INS01 : ISS; 6462 NEON_FP : S3; 6463 %} 6464 6465 pipe_class vmovi_reg_imm64(vecD dst) 6466 %{ 6467 single_instruction; 6468 dst : S3(write); 6469 INS01 : ISS; 6470 NEON_FP : S3; 6471 %} 6472 6473 pipe_class vmovi_reg_imm128(vecX dst) 6474 %{ 6475 single_instruction; 6476 dst : S3(write); 6477 INS0 : ISS; 6478 NEON_FP : S3; 6479 %} 6480 6481 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6482 %{ 6483 single_instruction; 6484 dst : S5(write); 6485 mem : ISS(read); 6486 INS01 : ISS; 6487 NEON_FP : S3; 6488 %} 6489 6490 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6491 %{ 6492 single_instruction; 6493 dst : S5(write); 6494 mem : ISS(read); 6495 INS01 : ISS; 6496 NEON_FP : S3; 6497 %} 6498 6499 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6500 %{ 6501 single_instruction; 6502 mem : ISS(read); 6503 src : S2(read); 6504 INS01 : ISS; 6505 NEON_FP : S3; 6506 %} 6507 6508 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6509 %{ 6510 single_instruction; 6511 mem : ISS(read); 6512 src : S2(read); 6513 INS01 : ISS; 6514 NEON_FP : S3; 6515 %} 6516 6517 //------- Integer ALU operations -------------------------- 6518 6519 // Integer ALU reg-reg operation 6520 // Operands needed in EX1, result generated in EX2 6521 // Eg. ADD x0, x1, x2 6522 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6523 %{ 6524 single_instruction; 6525 dst : EX2(write); 6526 src1 : EX1(read); 6527 src2 : EX1(read); 6528 INS01 : ISS; // Dual issue as instruction 0 or 1 6529 ALU : EX2; 6530 %} 6531 6532 // Integer ALU reg-reg operation with constant shift 6533 // Shifted register must be available in LATE_ISS instead of EX1 6534 // Eg. ADD x0, x1, x2, LSL #2 6535 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6536 %{ 6537 single_instruction; 6538 dst : EX2(write); 6539 src1 : EX1(read); 6540 src2 : ISS(read); 6541 INS01 : ISS; 6542 ALU : EX2; 6543 %} 6544 6545 // Integer ALU reg operation with constant shift 6546 // Eg. LSL x0, x1, #shift 6547 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6548 %{ 6549 single_instruction; 6550 dst : EX2(write); 6551 src1 : ISS(read); 6552 INS01 : ISS; 6553 ALU : EX2; 6554 %} 6555 6556 // Integer ALU reg-reg operation with variable shift 6557 // Both operands must be available in LATE_ISS instead of EX1 6558 // Result is available in EX1 instead of EX2 6559 // Eg. LSLV x0, x1, x2 6560 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6561 %{ 6562 single_instruction; 6563 dst : EX1(write); 6564 src1 : ISS(read); 6565 src2 : ISS(read); 6566 INS01 : ISS; 6567 ALU : EX1; 6568 %} 6569 6570 // Integer ALU reg-reg operation with extract 6571 // As for _vshift above, but result generated in EX2 6572 // Eg. EXTR x0, x1, x2, #N 6573 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6574 %{ 6575 single_instruction; 6576 dst : EX2(write); 6577 src1 : ISS(read); 6578 src2 : ISS(read); 6579 INS1 : ISS; // Can only dual issue as Instruction 1 6580 ALU : EX1; 6581 %} 6582 6583 // Integer ALU reg operation 6584 // Eg. NEG x0, x1 6585 pipe_class ialu_reg(iRegI dst, iRegI src) 6586 %{ 6587 single_instruction; 6588 dst : EX2(write); 6589 src : EX1(read); 6590 INS01 : ISS; 6591 ALU : EX2; 6592 %} 6593 6594 // Integer ALU reg mmediate operation 6595 // Eg. ADD x0, x1, #N 6596 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6597 %{ 6598 single_instruction; 6599 dst : EX2(write); 6600 src1 : EX1(read); 6601 INS01 : ISS; 6602 ALU : EX2; 6603 %} 6604 6605 // Integer ALU immediate operation (no source operands) 6606 // Eg. MOV x0, #N 6607 pipe_class ialu_imm(iRegI dst) 6608 %{ 6609 single_instruction; 6610 dst : EX1(write); 6611 INS01 : ISS; 6612 ALU : EX1; 6613 %} 6614 6615 //------- Compare operation ------------------------------- 6616 6617 // Compare reg-reg 6618 // Eg. CMP x0, x1 6619 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6620 %{ 6621 single_instruction; 6622 // fixed_latency(16); 6623 cr : EX2(write); 6624 op1 : EX1(read); 6625 op2 : EX1(read); 6626 INS01 : ISS; 6627 ALU : EX2; 6628 %} 6629 6630 // Compare reg-reg 6631 // Eg. CMP x0, #N 6632 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6633 %{ 6634 single_instruction; 6635 // fixed_latency(16); 6636 cr : EX2(write); 6637 op1 : EX1(read); 6638 INS01 : ISS; 6639 ALU : EX2; 6640 %} 6641 6642 //------- Conditional instructions ------------------------ 6643 6644 // Conditional no operands 6645 // Eg. CSINC x0, zr, zr, <cond> 6646 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6647 %{ 6648 single_instruction; 6649 cr : EX1(read); 6650 dst : EX2(write); 6651 INS01 : ISS; 6652 ALU : EX2; 6653 %} 6654 6655 // Conditional 2 operand 6656 // EG. CSEL X0, X1, X2, <cond> 6657 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6658 %{ 6659 single_instruction; 6660 cr : EX1(read); 6661 src1 : EX1(read); 6662 src2 : EX1(read); 6663 dst : EX2(write); 6664 INS01 : ISS; 6665 ALU : EX2; 6666 %} 6667 6668 // Conditional 2 operand 6669 // EG. CSEL X0, X1, X2, <cond> 6670 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6671 %{ 6672 single_instruction; 6673 cr : EX1(read); 6674 src : EX1(read); 6675 dst : EX2(write); 6676 INS01 : ISS; 6677 ALU : EX2; 6678 %} 6679 6680 //------- Multiply pipeline operations -------------------- 6681 6682 // Multiply reg-reg 6683 // Eg. MUL w0, w1, w2 6684 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6685 %{ 6686 single_instruction; 6687 dst : WR(write); 6688 src1 : ISS(read); 6689 src2 : ISS(read); 6690 INS01 : ISS; 6691 MAC : WR; 6692 %} 6693 6694 // Multiply accumulate 6695 // Eg. MADD w0, w1, w2, w3 6696 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6697 %{ 6698 single_instruction; 6699 dst : WR(write); 6700 src1 : ISS(read); 6701 src2 : ISS(read); 6702 src3 : ISS(read); 6703 INS01 : ISS; 6704 MAC : WR; 6705 %} 6706 6707 // Eg. MUL w0, w1, w2 6708 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6709 %{ 6710 single_instruction; 6711 fixed_latency(3); // Maximum latency for 64 bit mul 6712 dst : WR(write); 6713 src1 : ISS(read); 6714 src2 : ISS(read); 6715 INS01 : ISS; 6716 MAC : WR; 6717 %} 6718 6719 // Multiply accumulate 6720 // Eg. MADD w0, w1, w2, w3 6721 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6722 %{ 6723 single_instruction; 6724 fixed_latency(3); // Maximum latency for 64 bit mul 6725 dst : WR(write); 6726 src1 : ISS(read); 6727 src2 : ISS(read); 6728 src3 : ISS(read); 6729 INS01 : ISS; 6730 MAC : WR; 6731 %} 6732 6733 //------- Divide pipeline operations -------------------- 6734 6735 // Eg. SDIV w0, w1, w2 6736 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6737 %{ 6738 single_instruction; 6739 fixed_latency(8); // Maximum latency for 32 bit divide 6740 dst : WR(write); 6741 src1 : ISS(read); 6742 src2 : ISS(read); 6743 INS0 : ISS; // Can only dual issue as instruction 0 6744 DIV : WR; 6745 %} 6746 6747 // Eg. SDIV x0, x1, x2 6748 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6749 %{ 6750 single_instruction; 6751 fixed_latency(16); // Maximum latency for 64 bit divide 6752 dst : WR(write); 6753 src1 : ISS(read); 6754 src2 : ISS(read); 6755 INS0 : ISS; // Can only dual issue as instruction 0 6756 DIV : WR; 6757 %} 6758 6759 //------- Load pipeline operations ------------------------ 6760 6761 // Load - prefetch 6762 // Eg. PFRM <mem> 6763 pipe_class iload_prefetch(memory mem) 6764 %{ 6765 single_instruction; 6766 mem : ISS(read); 6767 INS01 : ISS; 6768 LDST : WR; 6769 %} 6770 6771 // Load - reg, mem 6772 // Eg. LDR x0, <mem> 6773 pipe_class iload_reg_mem(iRegI dst, memory mem) 6774 %{ 6775 single_instruction; 6776 dst : WR(write); 6777 mem : ISS(read); 6778 INS01 : ISS; 6779 LDST : WR; 6780 %} 6781 6782 // Load - reg, reg 6783 // Eg. LDR x0, [sp, x1] 6784 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6785 %{ 6786 single_instruction; 6787 dst : WR(write); 6788 src : ISS(read); 6789 INS01 : ISS; 6790 LDST : WR; 6791 %} 6792 6793 //------- Store pipeline operations ----------------------- 6794 6795 // Store - zr, mem 6796 // Eg. STR zr, <mem> 6797 pipe_class istore_mem(memory mem) 6798 %{ 6799 single_instruction; 6800 mem : ISS(read); 6801 INS01 : ISS; 6802 LDST : WR; 6803 %} 6804 6805 // Store - reg, mem 6806 // Eg. STR x0, <mem> 6807 pipe_class istore_reg_mem(iRegI src, memory mem) 6808 %{ 6809 single_instruction; 6810 mem : ISS(read); 6811 src : EX2(read); 6812 INS01 : ISS; 6813 LDST : WR; 6814 %} 6815 6816 // Store - reg, reg 6817 // Eg. STR x0, [sp, x1] 6818 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6819 %{ 6820 single_instruction; 6821 dst : ISS(read); 6822 src : EX2(read); 6823 INS01 : ISS; 6824 LDST : WR; 6825 %} 6826 6827 //------- Store pipeline operations ----------------------- 6828 6829 // Branch 6830 pipe_class pipe_branch() 6831 %{ 6832 single_instruction; 6833 INS01 : ISS; 6834 BRANCH : EX1; 6835 %} 6836 6837 // Conditional branch 6838 pipe_class pipe_branch_cond(rFlagsReg cr) 6839 %{ 6840 single_instruction; 6841 cr : EX1(read); 6842 INS01 : ISS; 6843 BRANCH : EX1; 6844 %} 6845 6846 // Compare & Branch 6847 // EG. CBZ/CBNZ 6848 pipe_class pipe_cmp_branch(iRegI op1) 6849 %{ 6850 single_instruction; 6851 op1 : EX1(read); 6852 INS01 : ISS; 6853 BRANCH : EX1; 6854 %} 6855 6856 //------- Synchronisation operations ---------------------- 6857 6858 // Any operation requiring serialization. 6859 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6860 pipe_class pipe_serial() 6861 %{ 6862 single_instruction; 6863 force_serialization; 6864 fixed_latency(16); 6865 INS01 : ISS(2); // Cannot dual issue with any other instruction 6866 LDST : WR; 6867 %} 6868 6869 // Generic big/slow expanded idiom - also serialized 6870 pipe_class pipe_slow() 6871 %{ 6872 instruction_count(10); 6873 multiple_bundles; 6874 force_serialization; 6875 fixed_latency(16); 6876 INS01 : ISS(2); // Cannot dual issue with any other instruction 6877 LDST : WR; 6878 %} 6879 6880 // Empty pipeline class 6881 pipe_class pipe_class_empty() 6882 %{ 6883 single_instruction; 6884 fixed_latency(0); 6885 %} 6886 6887 // Default pipeline class. 6888 pipe_class pipe_class_default() 6889 %{ 6890 single_instruction; 6891 fixed_latency(2); 6892 %} 6893 6894 // Pipeline class for compares. 6895 pipe_class pipe_class_compare() 6896 %{ 6897 single_instruction; 6898 fixed_latency(16); 6899 %} 6900 6901 // Pipeline class for memory operations. 6902 pipe_class pipe_class_memory() 6903 %{ 6904 single_instruction; 6905 fixed_latency(16); 6906 %} 6907 6908 // Pipeline class for call. 6909 pipe_class pipe_class_call() 6910 %{ 6911 single_instruction; 6912 fixed_latency(100); 6913 %} 6914 6915 // Define the class for the Nop node. 6916 define %{ 6917 MachNop = pipe_class_empty; 6918 %} 6919 6920 %} 6921 //----------INSTRUCTIONS------------------------------------------------------- 6922 // 6923 // match -- States which machine-independent subtree may be replaced 6924 // by this instruction. 6925 // ins_cost -- The estimated cost of this instruction is used by instruction 6926 // selection to identify a minimum cost tree of machine 6927 // instructions that matches a tree of machine-independent 6928 // instructions. 6929 // format -- A string providing the disassembly for this instruction. 6930 // The value of an instruction's operand may be inserted 6931 // by referring to it with a '$' prefix. 6932 // opcode -- Three instruction opcodes may be provided. These are referred 6933 // to within an encode class as $primary, $secondary, and $tertiary 6934 // rrspectively. The primary opcode is commonly used to 6935 // indicate the type of machine instruction, while secondary 6936 // and tertiary are often used for prefix options or addressing 6937 // modes. 6938 // ins_encode -- A list of encode classes with parameters. The encode class 6939 // name must have been defined in an 'enc_class' specification 6940 // in the encode section of the architecture description. 6941 6942 // ============================================================================ 6943 // Memory (Load/Store) Instructions 6944 6945 // Load Instructions 6946 6947 // Load Byte (8 bit signed) 6948 instruct loadB(iRegINoSp dst, memory1 mem) 6949 %{ 6950 match(Set dst (LoadB mem)); 6951 predicate(!needs_acquiring_load(n)); 6952 6953 ins_cost(4 * INSN_COST); 6954 format %{ "ldrsbw $dst, $mem\t# byte" %} 6955 6956 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6957 6958 ins_pipe(iload_reg_mem); 6959 %} 6960 6961 // Load Byte (8 bit signed) into long 6962 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6963 %{ 6964 match(Set dst (ConvI2L (LoadB mem))); 6965 predicate(!needs_acquiring_load(n->in(1))); 6966 6967 ins_cost(4 * INSN_COST); 6968 format %{ "ldrsb $dst, $mem\t# byte" %} 6969 6970 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6971 6972 ins_pipe(iload_reg_mem); 6973 %} 6974 6975 // Load Byte (8 bit unsigned) 6976 instruct loadUB(iRegINoSp dst, memory1 mem) 6977 %{ 6978 match(Set dst (LoadUB mem)); 6979 predicate(!needs_acquiring_load(n)); 6980 6981 ins_cost(4 * INSN_COST); 6982 format %{ "ldrbw $dst, $mem\t# byte" %} 6983 6984 ins_encode(aarch64_enc_ldrb(dst, mem)); 6985 6986 ins_pipe(iload_reg_mem); 6987 %} 6988 6989 // Load Byte (8 bit unsigned) into long 6990 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6991 %{ 6992 match(Set dst (ConvI2L (LoadUB mem))); 6993 predicate(!needs_acquiring_load(n->in(1))); 6994 6995 ins_cost(4 * INSN_COST); 6996 format %{ "ldrb $dst, $mem\t# byte" %} 6997 6998 ins_encode(aarch64_enc_ldrb(dst, mem)); 6999 7000 ins_pipe(iload_reg_mem); 7001 %} 7002 7003 // Load Short (16 bit signed) 7004 instruct loadS(iRegINoSp dst, memory2 mem) 7005 %{ 7006 match(Set dst (LoadS mem)); 7007 predicate(!needs_acquiring_load(n)); 7008 7009 ins_cost(4 * INSN_COST); 7010 format %{ "ldrshw $dst, $mem\t# short" %} 7011 7012 ins_encode(aarch64_enc_ldrshw(dst, mem)); 7013 7014 ins_pipe(iload_reg_mem); 7015 %} 7016 7017 // Load Short (16 bit signed) into long 7018 instruct loadS2L(iRegLNoSp dst, memory2 mem) 7019 %{ 7020 match(Set dst (ConvI2L (LoadS mem))); 7021 predicate(!needs_acquiring_load(n->in(1))); 7022 7023 ins_cost(4 * INSN_COST); 7024 format %{ "ldrsh $dst, $mem\t# short" %} 7025 7026 ins_encode(aarch64_enc_ldrsh(dst, mem)); 7027 7028 ins_pipe(iload_reg_mem); 7029 %} 7030 7031 // Load Char (16 bit unsigned) 7032 instruct loadUS(iRegINoSp dst, memory2 mem) 7033 %{ 7034 match(Set dst (LoadUS mem)); 7035 predicate(!needs_acquiring_load(n)); 7036 7037 ins_cost(4 * INSN_COST); 7038 format %{ "ldrh $dst, $mem\t# short" %} 7039 7040 ins_encode(aarch64_enc_ldrh(dst, mem)); 7041 7042 ins_pipe(iload_reg_mem); 7043 %} 7044 7045 // Load Short/Char (16 bit unsigned) into long 7046 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 7047 %{ 7048 match(Set dst (ConvI2L (LoadUS mem))); 7049 predicate(!needs_acquiring_load(n->in(1))); 7050 7051 ins_cost(4 * INSN_COST); 7052 format %{ "ldrh $dst, $mem\t# short" %} 7053 7054 ins_encode(aarch64_enc_ldrh(dst, mem)); 7055 7056 ins_pipe(iload_reg_mem); 7057 %} 7058 7059 // Load Integer (32 bit signed) 7060 instruct loadI(iRegINoSp dst, memory4 mem) 7061 %{ 7062 match(Set dst (LoadI mem)); 7063 predicate(!needs_acquiring_load(n)); 7064 7065 ins_cost(4 * INSN_COST); 7066 format %{ "ldrw $dst, $mem\t# int" %} 7067 7068 ins_encode(aarch64_enc_ldrw(dst, mem)); 7069 7070 ins_pipe(iload_reg_mem); 7071 %} 7072 7073 // Load Integer (32 bit signed) into long 7074 instruct loadI2L(iRegLNoSp dst, memory4 mem) 7075 %{ 7076 match(Set dst (ConvI2L (LoadI mem))); 7077 predicate(!needs_acquiring_load(n->in(1))); 7078 7079 ins_cost(4 * INSN_COST); 7080 format %{ "ldrsw $dst, $mem\t# int" %} 7081 7082 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7083 7084 ins_pipe(iload_reg_mem); 7085 %} 7086 7087 // Load Integer (32 bit unsigned) into long 7088 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7089 %{ 7090 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7091 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7092 7093 ins_cost(4 * INSN_COST); 7094 format %{ "ldrw $dst, $mem\t# int" %} 7095 7096 ins_encode(aarch64_enc_ldrw(dst, mem)); 7097 7098 ins_pipe(iload_reg_mem); 7099 %} 7100 7101 // Load Long (64 bit signed) 7102 instruct loadL(iRegLNoSp dst, memory8 mem) 7103 %{ 7104 match(Set dst (LoadL mem)); 7105 predicate(!needs_acquiring_load(n)); 7106 7107 ins_cost(4 * INSN_COST); 7108 format %{ "ldr $dst, $mem\t# int" %} 7109 7110 ins_encode(aarch64_enc_ldr(dst, mem)); 7111 7112 ins_pipe(iload_reg_mem); 7113 %} 7114 7115 // Load Range 7116 instruct loadRange(iRegINoSp dst, memory8 mem) 7117 %{ 7118 match(Set dst (LoadRange mem)); 7119 7120 ins_cost(4 * INSN_COST); 7121 format %{ "ldrw $dst, $mem\t# range" %} 7122 7123 ins_encode(aarch64_enc_ldrw(dst, mem)); 7124 7125 ins_pipe(iload_reg_mem); 7126 %} 7127 7128 // Load Pointer 7129 instruct loadP(iRegPNoSp dst, memory8 mem) 7130 %{ 7131 match(Set dst (LoadP mem)); 7132 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7133 7134 ins_cost(4 * INSN_COST); 7135 format %{ "ldr $dst, $mem\t# ptr" %} 7136 7137 ins_encode(aarch64_enc_ldr(dst, mem)); 7138 7139 ins_pipe(iload_reg_mem); 7140 %} 7141 7142 // Load Compressed Pointer 7143 instruct loadN(iRegNNoSp dst, memory4 mem) 7144 %{ 7145 match(Set dst (LoadN mem)); 7146 predicate(!needs_acquiring_load(n)); 7147 7148 ins_cost(4 * INSN_COST); 7149 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7150 7151 ins_encode(aarch64_enc_ldrw(dst, mem)); 7152 7153 ins_pipe(iload_reg_mem); 7154 %} 7155 7156 // Load Klass Pointer 7157 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7158 %{ 7159 match(Set dst (LoadKlass mem)); 7160 predicate(!needs_acquiring_load(n)); 7161 7162 ins_cost(4 * INSN_COST); 7163 format %{ "ldr $dst, $mem\t# class" %} 7164 7165 ins_encode(aarch64_enc_ldr(dst, mem)); 7166 7167 ins_pipe(iload_reg_mem); 7168 %} 7169 7170 // Load Narrow Klass Pointer 7171 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7172 %{ 7173 match(Set dst (LoadNKlass mem)); 7174 predicate(!needs_acquiring_load(n)); 7175 7176 ins_cost(4 * INSN_COST); 7177 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7178 7179 ins_encode(aarch64_enc_ldrw(dst, mem)); 7180 7181 ins_pipe(iload_reg_mem); 7182 %} 7183 7184 // Load Float 7185 instruct loadF(vRegF dst, memory4 mem) 7186 %{ 7187 match(Set dst (LoadF mem)); 7188 predicate(!needs_acquiring_load(n)); 7189 7190 ins_cost(4 * INSN_COST); 7191 format %{ "ldrs $dst, $mem\t# float" %} 7192 7193 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7194 7195 ins_pipe(pipe_class_memory); 7196 %} 7197 7198 // Load Double 7199 instruct loadD(vRegD dst, memory8 mem) 7200 %{ 7201 match(Set dst (LoadD mem)); 7202 predicate(!needs_acquiring_load(n)); 7203 7204 ins_cost(4 * INSN_COST); 7205 format %{ "ldrd $dst, $mem\t# double" %} 7206 7207 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7208 7209 ins_pipe(pipe_class_memory); 7210 %} 7211 7212 7213 // Load Int Constant 7214 instruct loadConI(iRegINoSp dst, immI src) 7215 %{ 7216 match(Set dst src); 7217 7218 ins_cost(INSN_COST); 7219 format %{ "mov $dst, $src\t# int" %} 7220 7221 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7222 7223 ins_pipe(ialu_imm); 7224 %} 7225 7226 // Load Long Constant 7227 instruct loadConL(iRegLNoSp dst, immL src) 7228 %{ 7229 match(Set dst src); 7230 7231 ins_cost(INSN_COST); 7232 format %{ "mov $dst, $src\t# long" %} 7233 7234 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7235 7236 ins_pipe(ialu_imm); 7237 %} 7238 7239 // Load Pointer Constant 7240 7241 instruct loadConP(iRegPNoSp dst, immP con) 7242 %{ 7243 match(Set dst con); 7244 7245 ins_cost(INSN_COST * 4); 7246 format %{ 7247 "mov $dst, $con\t# ptr\n\t" 7248 %} 7249 7250 ins_encode(aarch64_enc_mov_p(dst, con)); 7251 7252 ins_pipe(ialu_imm); 7253 %} 7254 7255 // Load Null Pointer Constant 7256 7257 instruct loadConP0(iRegPNoSp dst, immP0 con) 7258 %{ 7259 match(Set dst con); 7260 7261 ins_cost(INSN_COST); 7262 format %{ "mov $dst, $con\t# NULL ptr" %} 7263 7264 ins_encode(aarch64_enc_mov_p0(dst, con)); 7265 7266 ins_pipe(ialu_imm); 7267 %} 7268 7269 // Load Pointer Constant One 7270 7271 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7272 %{ 7273 match(Set dst con); 7274 7275 ins_cost(INSN_COST); 7276 format %{ "mov $dst, $con\t# NULL ptr" %} 7277 7278 ins_encode(aarch64_enc_mov_p1(dst, con)); 7279 7280 ins_pipe(ialu_imm); 7281 %} 7282 7283 // Load Poll Page Constant 7284 7285 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 7286 %{ 7287 match(Set dst con); 7288 7289 ins_cost(INSN_COST); 7290 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 7291 7292 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 7293 7294 ins_pipe(ialu_imm); 7295 %} 7296 7297 // Load Byte Map Base Constant 7298 7299 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7300 %{ 7301 match(Set dst con); 7302 7303 ins_cost(INSN_COST); 7304 format %{ "adr $dst, $con\t# Byte Map Base" %} 7305 7306 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7307 7308 ins_pipe(ialu_imm); 7309 %} 7310 7311 // Load Narrow Pointer Constant 7312 7313 instruct loadConN(iRegNNoSp dst, immN con) 7314 %{ 7315 match(Set dst con); 7316 7317 ins_cost(INSN_COST * 4); 7318 format %{ "mov $dst, $con\t# compressed ptr" %} 7319 7320 ins_encode(aarch64_enc_mov_n(dst, con)); 7321 7322 ins_pipe(ialu_imm); 7323 %} 7324 7325 // Load Narrow Null Pointer Constant 7326 7327 instruct loadConN0(iRegNNoSp dst, immN0 con) 7328 %{ 7329 match(Set dst con); 7330 7331 ins_cost(INSN_COST); 7332 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7333 7334 ins_encode(aarch64_enc_mov_n0(dst, con)); 7335 7336 ins_pipe(ialu_imm); 7337 %} 7338 7339 // Load Narrow Klass Constant 7340 7341 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7342 %{ 7343 match(Set dst con); 7344 7345 ins_cost(INSN_COST); 7346 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7347 7348 ins_encode(aarch64_enc_mov_nk(dst, con)); 7349 7350 ins_pipe(ialu_imm); 7351 %} 7352 7353 // Load Packed Float Constant 7354 7355 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7356 match(Set dst con); 7357 ins_cost(INSN_COST * 4); 7358 format %{ "fmovs $dst, $con"%} 7359 ins_encode %{ 7360 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7361 %} 7362 7363 ins_pipe(fp_imm_s); 7364 %} 7365 7366 // Load Float Constant 7367 7368 instruct loadConF(vRegF dst, immF con) %{ 7369 match(Set dst con); 7370 7371 ins_cost(INSN_COST * 4); 7372 7373 format %{ 7374 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7375 %} 7376 7377 ins_encode %{ 7378 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7379 %} 7380 7381 ins_pipe(fp_load_constant_s); 7382 %} 7383 7384 // Load Packed Double Constant 7385 7386 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7387 match(Set dst con); 7388 ins_cost(INSN_COST); 7389 format %{ "fmovd $dst, $con"%} 7390 ins_encode %{ 7391 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7392 %} 7393 7394 ins_pipe(fp_imm_d); 7395 %} 7396 7397 // Load Double Constant 7398 7399 instruct loadConD(vRegD dst, immD con) %{ 7400 match(Set dst con); 7401 7402 ins_cost(INSN_COST * 5); 7403 format %{ 7404 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7405 %} 7406 7407 ins_encode %{ 7408 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7409 %} 7410 7411 ins_pipe(fp_load_constant_d); 7412 %} 7413 7414 // Store Instructions 7415 7416 // Store CMS card-mark Immediate 7417 instruct storeimmCM0(immI0 zero, memory1 mem) 7418 %{ 7419 match(Set mem (StoreCM mem zero)); 7420 7421 ins_cost(INSN_COST); 7422 format %{ "storestore (elided)\n\t" 7423 "strb zr, $mem\t# byte" %} 7424 7425 ins_encode(aarch64_enc_strb0(mem)); 7426 7427 ins_pipe(istore_mem); 7428 %} 7429 7430 // Store CMS card-mark Immediate with intervening StoreStore 7431 // needed when using CMS with no conditional card marking 7432 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7433 %{ 7434 match(Set mem (StoreCM mem zero)); 7435 7436 ins_cost(INSN_COST * 2); 7437 format %{ "storestore\n\t" 7438 "dmb ishst" 7439 "\n\tstrb zr, $mem\t# byte" %} 7440 7441 ins_encode(aarch64_enc_strb0_ordered(mem)); 7442 7443 ins_pipe(istore_mem); 7444 %} 7445 7446 // Store Byte 7447 instruct storeB(iRegIorL2I src, memory1 mem) 7448 %{ 7449 match(Set mem (StoreB mem src)); 7450 predicate(!needs_releasing_store(n)); 7451 7452 ins_cost(INSN_COST); 7453 format %{ "strb $src, $mem\t# byte" %} 7454 7455 ins_encode(aarch64_enc_strb(src, mem)); 7456 7457 ins_pipe(istore_reg_mem); 7458 %} 7459 7460 7461 instruct storeimmB0(immI0 zero, memory1 mem) 7462 %{ 7463 match(Set mem (StoreB mem zero)); 7464 predicate(!needs_releasing_store(n)); 7465 7466 ins_cost(INSN_COST); 7467 format %{ "strb rscractch2, $mem\t# byte" %} 7468 7469 ins_encode(aarch64_enc_strb0(mem)); 7470 7471 ins_pipe(istore_mem); 7472 %} 7473 7474 // Store Char/Short 7475 instruct storeC(iRegIorL2I src, memory2 mem) 7476 %{ 7477 match(Set mem (StoreC mem src)); 7478 predicate(!needs_releasing_store(n)); 7479 7480 ins_cost(INSN_COST); 7481 format %{ "strh $src, $mem\t# short" %} 7482 7483 ins_encode(aarch64_enc_strh(src, mem)); 7484 7485 ins_pipe(istore_reg_mem); 7486 %} 7487 7488 instruct storeimmC0(immI0 zero, memory2 mem) 7489 %{ 7490 match(Set mem (StoreC mem zero)); 7491 predicate(!needs_releasing_store(n)); 7492 7493 ins_cost(INSN_COST); 7494 format %{ "strh zr, $mem\t# short" %} 7495 7496 ins_encode(aarch64_enc_strh0(mem)); 7497 7498 ins_pipe(istore_mem); 7499 %} 7500 7501 // Store Integer 7502 7503 instruct storeI(iRegIorL2I src, memory4 mem) 7504 %{ 7505 match(Set mem(StoreI mem src)); 7506 predicate(!needs_releasing_store(n)); 7507 7508 ins_cost(INSN_COST); 7509 format %{ "strw $src, $mem\t# int" %} 7510 7511 ins_encode(aarch64_enc_strw(src, mem)); 7512 7513 ins_pipe(istore_reg_mem); 7514 %} 7515 7516 instruct storeimmI0(immI0 zero, memory4 mem) 7517 %{ 7518 match(Set mem(StoreI mem zero)); 7519 predicate(!needs_releasing_store(n)); 7520 7521 ins_cost(INSN_COST); 7522 format %{ "strw zr, $mem\t# int" %} 7523 7524 ins_encode(aarch64_enc_strw0(mem)); 7525 7526 ins_pipe(istore_mem); 7527 %} 7528 7529 // Store Long (64 bit signed) 7530 instruct storeL(iRegL src, memory8 mem) 7531 %{ 7532 match(Set mem (StoreL mem src)); 7533 predicate(!needs_releasing_store(n)); 7534 7535 ins_cost(INSN_COST); 7536 format %{ "str $src, $mem\t# int" %} 7537 7538 ins_encode(aarch64_enc_str(src, mem)); 7539 7540 ins_pipe(istore_reg_mem); 7541 %} 7542 7543 // Store Long (64 bit signed) 7544 instruct storeimmL0(immL0 zero, memory8 mem) 7545 %{ 7546 match(Set mem (StoreL mem zero)); 7547 predicate(!needs_releasing_store(n)); 7548 7549 ins_cost(INSN_COST); 7550 format %{ "str zr, $mem\t# int" %} 7551 7552 ins_encode(aarch64_enc_str0(mem)); 7553 7554 ins_pipe(istore_mem); 7555 %} 7556 7557 // Store Pointer 7558 instruct storeP(iRegP src, memory8 mem) 7559 %{ 7560 match(Set mem (StoreP mem src)); 7561 predicate(!needs_releasing_store(n)); 7562 7563 ins_cost(INSN_COST); 7564 format %{ "str $src, $mem\t# ptr" %} 7565 7566 ins_encode(aarch64_enc_str(src, mem)); 7567 7568 ins_pipe(istore_reg_mem); 7569 %} 7570 7571 // Store Pointer 7572 instruct storeimmP0(immP0 zero, memory8 mem) 7573 %{ 7574 match(Set mem (StoreP mem zero)); 7575 predicate(!needs_releasing_store(n)); 7576 7577 ins_cost(INSN_COST); 7578 format %{ "str zr, $mem\t# ptr" %} 7579 7580 ins_encode(aarch64_enc_str0(mem)); 7581 7582 ins_pipe(istore_mem); 7583 %} 7584 7585 // Store Compressed Pointer 7586 instruct storeN(iRegN src, memory4 mem) 7587 %{ 7588 match(Set mem (StoreN mem src)); 7589 predicate(!needs_releasing_store(n)); 7590 7591 ins_cost(INSN_COST); 7592 format %{ "strw $src, $mem\t# compressed ptr" %} 7593 7594 ins_encode(aarch64_enc_strw(src, mem)); 7595 7596 ins_pipe(istore_reg_mem); 7597 %} 7598 7599 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory4 mem) 7600 %{ 7601 match(Set mem (StoreN mem zero)); 7602 predicate(CompressedOops::base() == NULL && 7603 CompressedKlassPointers::base() == NULL && 7604 (!needs_releasing_store(n))); 7605 7606 ins_cost(INSN_COST); 7607 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7608 7609 ins_encode(aarch64_enc_strw(heapbase, mem)); 7610 7611 ins_pipe(istore_reg_mem); 7612 %} 7613 7614 // Store Float 7615 instruct storeF(vRegF src, memory4 mem) 7616 %{ 7617 match(Set mem (StoreF mem src)); 7618 predicate(!needs_releasing_store(n)); 7619 7620 ins_cost(INSN_COST); 7621 format %{ "strs $src, $mem\t# float" %} 7622 7623 ins_encode( aarch64_enc_strs(src, mem) ); 7624 7625 ins_pipe(pipe_class_memory); 7626 %} 7627 7628 // TODO 7629 // implement storeImmF0 and storeFImmPacked 7630 7631 // Store Double 7632 instruct storeD(vRegD src, memory8 mem) 7633 %{ 7634 match(Set mem (StoreD mem src)); 7635 predicate(!needs_releasing_store(n)); 7636 7637 ins_cost(INSN_COST); 7638 format %{ "strd $src, $mem\t# double" %} 7639 7640 ins_encode( aarch64_enc_strd(src, mem) ); 7641 7642 ins_pipe(pipe_class_memory); 7643 %} 7644 7645 // Store Compressed Klass Pointer 7646 instruct storeNKlass(iRegN src, memory4 mem) 7647 %{ 7648 predicate(!needs_releasing_store(n)); 7649 match(Set mem (StoreNKlass mem src)); 7650 7651 ins_cost(INSN_COST); 7652 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7653 7654 ins_encode(aarch64_enc_strw(src, mem)); 7655 7656 ins_pipe(istore_reg_mem); 7657 %} 7658 7659 // TODO 7660 // implement storeImmD0 and storeDImmPacked 7661 7662 // prefetch instructions 7663 // Must be safe to execute with invalid address (cannot fault). 7664 7665 instruct prefetchalloc( memory8 mem ) %{ 7666 match(PrefetchAllocation mem); 7667 7668 ins_cost(INSN_COST); 7669 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7670 7671 ins_encode( aarch64_enc_prefetchw(mem) ); 7672 7673 ins_pipe(iload_prefetch); 7674 %} 7675 7676 // ---------------- volatile loads and stores ---------------- 7677 7678 // Load Byte (8 bit signed) 7679 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7680 %{ 7681 match(Set dst (LoadB mem)); 7682 7683 ins_cost(VOLATILE_REF_COST); 7684 format %{ "ldarsb $dst, $mem\t# byte" %} 7685 7686 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7687 7688 ins_pipe(pipe_serial); 7689 %} 7690 7691 // Load Byte (8 bit signed) into long 7692 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7693 %{ 7694 match(Set dst (ConvI2L (LoadB mem))); 7695 7696 ins_cost(VOLATILE_REF_COST); 7697 format %{ "ldarsb $dst, $mem\t# byte" %} 7698 7699 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7700 7701 ins_pipe(pipe_serial); 7702 %} 7703 7704 // Load Byte (8 bit unsigned) 7705 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7706 %{ 7707 match(Set dst (LoadUB mem)); 7708 7709 ins_cost(VOLATILE_REF_COST); 7710 format %{ "ldarb $dst, $mem\t# byte" %} 7711 7712 ins_encode(aarch64_enc_ldarb(dst, mem)); 7713 7714 ins_pipe(pipe_serial); 7715 %} 7716 7717 // Load Byte (8 bit unsigned) into long 7718 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7719 %{ 7720 match(Set dst (ConvI2L (LoadUB mem))); 7721 7722 ins_cost(VOLATILE_REF_COST); 7723 format %{ "ldarb $dst, $mem\t# byte" %} 7724 7725 ins_encode(aarch64_enc_ldarb(dst, mem)); 7726 7727 ins_pipe(pipe_serial); 7728 %} 7729 7730 // Load Short (16 bit signed) 7731 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7732 %{ 7733 match(Set dst (LoadS mem)); 7734 7735 ins_cost(VOLATILE_REF_COST); 7736 format %{ "ldarshw $dst, $mem\t# short" %} 7737 7738 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7739 7740 ins_pipe(pipe_serial); 7741 %} 7742 7743 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7744 %{ 7745 match(Set dst (LoadUS mem)); 7746 7747 ins_cost(VOLATILE_REF_COST); 7748 format %{ "ldarhw $dst, $mem\t# short" %} 7749 7750 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7751 7752 ins_pipe(pipe_serial); 7753 %} 7754 7755 // Load Short/Char (16 bit unsigned) into long 7756 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7757 %{ 7758 match(Set dst (ConvI2L (LoadUS mem))); 7759 7760 ins_cost(VOLATILE_REF_COST); 7761 format %{ "ldarh $dst, $mem\t# short" %} 7762 7763 ins_encode(aarch64_enc_ldarh(dst, mem)); 7764 7765 ins_pipe(pipe_serial); 7766 %} 7767 7768 // Load Short/Char (16 bit signed) into long 7769 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7770 %{ 7771 match(Set dst (ConvI2L (LoadS mem))); 7772 7773 ins_cost(VOLATILE_REF_COST); 7774 format %{ "ldarh $dst, $mem\t# short" %} 7775 7776 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7777 7778 ins_pipe(pipe_serial); 7779 %} 7780 7781 // Load Integer (32 bit signed) 7782 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7783 %{ 7784 match(Set dst (LoadI mem)); 7785 7786 ins_cost(VOLATILE_REF_COST); 7787 format %{ "ldarw $dst, $mem\t# int" %} 7788 7789 ins_encode(aarch64_enc_ldarw(dst, mem)); 7790 7791 ins_pipe(pipe_serial); 7792 %} 7793 7794 // Load Integer (32 bit unsigned) into long 7795 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7796 %{ 7797 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7798 7799 ins_cost(VOLATILE_REF_COST); 7800 format %{ "ldarw $dst, $mem\t# int" %} 7801 7802 ins_encode(aarch64_enc_ldarw(dst, mem)); 7803 7804 ins_pipe(pipe_serial); 7805 %} 7806 7807 // Load Long (64 bit signed) 7808 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7809 %{ 7810 match(Set dst (LoadL mem)); 7811 7812 ins_cost(VOLATILE_REF_COST); 7813 format %{ "ldar $dst, $mem\t# int" %} 7814 7815 ins_encode(aarch64_enc_ldar(dst, mem)); 7816 7817 ins_pipe(pipe_serial); 7818 %} 7819 7820 // Load Pointer 7821 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7822 %{ 7823 match(Set dst (LoadP mem)); 7824 predicate(n->as_Load()->barrier_data() == 0); 7825 7826 ins_cost(VOLATILE_REF_COST); 7827 format %{ "ldar $dst, $mem\t# ptr" %} 7828 7829 ins_encode(aarch64_enc_ldar(dst, mem)); 7830 7831 ins_pipe(pipe_serial); 7832 %} 7833 7834 // Load Compressed Pointer 7835 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7836 %{ 7837 match(Set dst (LoadN mem)); 7838 7839 ins_cost(VOLATILE_REF_COST); 7840 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7841 7842 ins_encode(aarch64_enc_ldarw(dst, mem)); 7843 7844 ins_pipe(pipe_serial); 7845 %} 7846 7847 // Load Float 7848 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7849 %{ 7850 match(Set dst (LoadF mem)); 7851 7852 ins_cost(VOLATILE_REF_COST); 7853 format %{ "ldars $dst, $mem\t# float" %} 7854 7855 ins_encode( aarch64_enc_fldars(dst, mem) ); 7856 7857 ins_pipe(pipe_serial); 7858 %} 7859 7860 // Load Double 7861 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7862 %{ 7863 match(Set dst (LoadD mem)); 7864 7865 ins_cost(VOLATILE_REF_COST); 7866 format %{ "ldard $dst, $mem\t# double" %} 7867 7868 ins_encode( aarch64_enc_fldard(dst, mem) ); 7869 7870 ins_pipe(pipe_serial); 7871 %} 7872 7873 // Store Byte 7874 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7875 %{ 7876 match(Set mem (StoreB mem src)); 7877 7878 ins_cost(VOLATILE_REF_COST); 7879 format %{ "stlrb $src, $mem\t# byte" %} 7880 7881 ins_encode(aarch64_enc_stlrb(src, mem)); 7882 7883 ins_pipe(pipe_class_memory); 7884 %} 7885 7886 // Store Char/Short 7887 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7888 %{ 7889 match(Set mem (StoreC mem src)); 7890 7891 ins_cost(VOLATILE_REF_COST); 7892 format %{ "stlrh $src, $mem\t# short" %} 7893 7894 ins_encode(aarch64_enc_stlrh(src, mem)); 7895 7896 ins_pipe(pipe_class_memory); 7897 %} 7898 7899 // Store Integer 7900 7901 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7902 %{ 7903 match(Set mem(StoreI mem src)); 7904 7905 ins_cost(VOLATILE_REF_COST); 7906 format %{ "stlrw $src, $mem\t# int" %} 7907 7908 ins_encode(aarch64_enc_stlrw(src, mem)); 7909 7910 ins_pipe(pipe_class_memory); 7911 %} 7912 7913 // Store Long (64 bit signed) 7914 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7915 %{ 7916 match(Set mem (StoreL mem src)); 7917 7918 ins_cost(VOLATILE_REF_COST); 7919 format %{ "stlr $src, $mem\t# int" %} 7920 7921 ins_encode(aarch64_enc_stlr(src, mem)); 7922 7923 ins_pipe(pipe_class_memory); 7924 %} 7925 7926 // Store Pointer 7927 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7928 %{ 7929 match(Set mem (StoreP mem src)); 7930 7931 ins_cost(VOLATILE_REF_COST); 7932 format %{ "stlr $src, $mem\t# ptr" %} 7933 7934 ins_encode(aarch64_enc_stlr(src, mem)); 7935 7936 ins_pipe(pipe_class_memory); 7937 %} 7938 7939 // Store Compressed Pointer 7940 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7941 %{ 7942 match(Set mem (StoreN mem src)); 7943 7944 ins_cost(VOLATILE_REF_COST); 7945 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7946 7947 ins_encode(aarch64_enc_stlrw(src, mem)); 7948 7949 ins_pipe(pipe_class_memory); 7950 %} 7951 7952 // Store Float 7953 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7954 %{ 7955 match(Set mem (StoreF mem src)); 7956 7957 ins_cost(VOLATILE_REF_COST); 7958 format %{ "stlrs $src, $mem\t# float" %} 7959 7960 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7961 7962 ins_pipe(pipe_class_memory); 7963 %} 7964 7965 // TODO 7966 // implement storeImmF0 and storeFImmPacked 7967 7968 // Store Double 7969 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7970 %{ 7971 match(Set mem (StoreD mem src)); 7972 7973 ins_cost(VOLATILE_REF_COST); 7974 format %{ "stlrd $src, $mem\t# double" %} 7975 7976 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7977 7978 ins_pipe(pipe_class_memory); 7979 %} 7980 7981 // ---------------- end of volatile loads and stores ---------------- 7982 7983 instruct cacheWB(indirect addr) 7984 %{ 7985 predicate(VM_Version::supports_data_cache_line_flush()); 7986 match(CacheWB addr); 7987 7988 ins_cost(100); 7989 format %{"cache wb $addr" %} 7990 ins_encode %{ 7991 assert($addr->index_position() < 0, "should be"); 7992 assert($addr$$disp == 0, "should be"); 7993 __ cache_wb(Address($addr$$base$$Register, 0)); 7994 %} 7995 ins_pipe(pipe_slow); // XXX 7996 %} 7997 7998 instruct cacheWBPreSync() 7999 %{ 8000 predicate(VM_Version::supports_data_cache_line_flush()); 8001 match(CacheWBPreSync); 8002 8003 ins_cost(100); 8004 format %{"cache wb presync" %} 8005 ins_encode %{ 8006 __ cache_wbsync(true); 8007 %} 8008 ins_pipe(pipe_slow); // XXX 8009 %} 8010 8011 instruct cacheWBPostSync() 8012 %{ 8013 predicate(VM_Version::supports_data_cache_line_flush()); 8014 match(CacheWBPostSync); 8015 8016 ins_cost(100); 8017 format %{"cache wb postsync" %} 8018 ins_encode %{ 8019 __ cache_wbsync(false); 8020 %} 8021 ins_pipe(pipe_slow); // XXX 8022 %} 8023 8024 // ============================================================================ 8025 // BSWAP Instructions 8026 8027 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 8028 match(Set dst (ReverseBytesI src)); 8029 8030 ins_cost(INSN_COST); 8031 format %{ "revw $dst, $src" %} 8032 8033 ins_encode %{ 8034 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 8035 %} 8036 8037 ins_pipe(ialu_reg); 8038 %} 8039 8040 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 8041 match(Set dst (ReverseBytesL src)); 8042 8043 ins_cost(INSN_COST); 8044 format %{ "rev $dst, $src" %} 8045 8046 ins_encode %{ 8047 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 8048 %} 8049 8050 ins_pipe(ialu_reg); 8051 %} 8052 8053 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 8054 match(Set dst (ReverseBytesUS src)); 8055 8056 ins_cost(INSN_COST); 8057 format %{ "rev16w $dst, $src" %} 8058 8059 ins_encode %{ 8060 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8061 %} 8062 8063 ins_pipe(ialu_reg); 8064 %} 8065 8066 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 8067 match(Set dst (ReverseBytesS src)); 8068 8069 ins_cost(INSN_COST); 8070 format %{ "rev16w $dst, $src\n\t" 8071 "sbfmw $dst, $dst, #0, #15" %} 8072 8073 ins_encode %{ 8074 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8075 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 8076 %} 8077 8078 ins_pipe(ialu_reg); 8079 %} 8080 8081 // ============================================================================ 8082 // Zero Count Instructions 8083 8084 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8085 match(Set dst (CountLeadingZerosI src)); 8086 8087 ins_cost(INSN_COST); 8088 format %{ "clzw $dst, $src" %} 8089 ins_encode %{ 8090 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8091 %} 8092 8093 ins_pipe(ialu_reg); 8094 %} 8095 8096 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8097 match(Set dst (CountLeadingZerosL src)); 8098 8099 ins_cost(INSN_COST); 8100 format %{ "clz $dst, $src" %} 8101 ins_encode %{ 8102 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8103 %} 8104 8105 ins_pipe(ialu_reg); 8106 %} 8107 8108 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8109 match(Set dst (CountTrailingZerosI src)); 8110 8111 ins_cost(INSN_COST * 2); 8112 format %{ "rbitw $dst, $src\n\t" 8113 "clzw $dst, $dst" %} 8114 ins_encode %{ 8115 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8116 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8117 %} 8118 8119 ins_pipe(ialu_reg); 8120 %} 8121 8122 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8123 match(Set dst (CountTrailingZerosL src)); 8124 8125 ins_cost(INSN_COST * 2); 8126 format %{ "rbit $dst, $src\n\t" 8127 "clz $dst, $dst" %} 8128 ins_encode %{ 8129 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8130 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8131 %} 8132 8133 ins_pipe(ialu_reg); 8134 %} 8135 8136 //---------- Population Count Instructions ------------------------------------- 8137 // 8138 8139 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8140 predicate(UsePopCountInstruction); 8141 match(Set dst (PopCountI src)); 8142 effect(TEMP tmp); 8143 ins_cost(INSN_COST * 13); 8144 8145 format %{ "movw $src, $src\n\t" 8146 "mov $tmp, $src\t# vector (1D)\n\t" 8147 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8148 "addv $tmp, $tmp\t# vector (8B)\n\t" 8149 "mov $dst, $tmp\t# vector (1D)" %} 8150 ins_encode %{ 8151 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8152 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8153 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8154 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8155 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8156 %} 8157 8158 ins_pipe(pipe_class_default); 8159 %} 8160 8161 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8162 predicate(UsePopCountInstruction); 8163 match(Set dst (PopCountI (LoadI mem))); 8164 effect(TEMP tmp); 8165 ins_cost(INSN_COST * 13); 8166 8167 format %{ "ldrs $tmp, $mem\n\t" 8168 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8169 "addv $tmp, $tmp\t# vector (8B)\n\t" 8170 "mov $dst, $tmp\t# vector (1D)" %} 8171 ins_encode %{ 8172 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8173 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8174 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, sizeof (jfloat)); 8175 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8176 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8177 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8178 %} 8179 8180 ins_pipe(pipe_class_default); 8181 %} 8182 8183 // Note: Long.bitCount(long) returns an int. 8184 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8185 predicate(UsePopCountInstruction); 8186 match(Set dst (PopCountL src)); 8187 effect(TEMP tmp); 8188 ins_cost(INSN_COST * 13); 8189 8190 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8191 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8192 "addv $tmp, $tmp\t# vector (8B)\n\t" 8193 "mov $dst, $tmp\t# vector (1D)" %} 8194 ins_encode %{ 8195 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8196 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8197 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8198 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8199 %} 8200 8201 ins_pipe(pipe_class_default); 8202 %} 8203 8204 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8205 predicate(UsePopCountInstruction); 8206 match(Set dst (PopCountL (LoadL mem))); 8207 effect(TEMP tmp); 8208 ins_cost(INSN_COST * 13); 8209 8210 format %{ "ldrd $tmp, $mem\n\t" 8211 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8212 "addv $tmp, $tmp\t# vector (8B)\n\t" 8213 "mov $dst, $tmp\t# vector (1D)" %} 8214 ins_encode %{ 8215 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8216 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8217 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, sizeof (jdouble)); 8218 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8219 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8220 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8221 %} 8222 8223 ins_pipe(pipe_class_default); 8224 %} 8225 8226 // ============================================================================ 8227 // MemBar Instruction 8228 8229 instruct load_fence() %{ 8230 match(LoadFence); 8231 ins_cost(VOLATILE_REF_COST); 8232 8233 format %{ "load_fence" %} 8234 8235 ins_encode %{ 8236 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8237 %} 8238 ins_pipe(pipe_serial); 8239 %} 8240 8241 instruct unnecessary_membar_acquire() %{ 8242 predicate(unnecessary_acquire(n)); 8243 match(MemBarAcquire); 8244 ins_cost(0); 8245 8246 format %{ "membar_acquire (elided)" %} 8247 8248 ins_encode %{ 8249 __ block_comment("membar_acquire (elided)"); 8250 %} 8251 8252 ins_pipe(pipe_class_empty); 8253 %} 8254 8255 instruct membar_acquire() %{ 8256 match(MemBarAcquire); 8257 ins_cost(VOLATILE_REF_COST); 8258 8259 format %{ "membar_acquire\n\t" 8260 "dmb ish" %} 8261 8262 ins_encode %{ 8263 __ block_comment("membar_acquire"); 8264 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8265 %} 8266 8267 ins_pipe(pipe_serial); 8268 %} 8269 8270 8271 instruct membar_acquire_lock() %{ 8272 match(MemBarAcquireLock); 8273 ins_cost(VOLATILE_REF_COST); 8274 8275 format %{ "membar_acquire_lock (elided)" %} 8276 8277 ins_encode %{ 8278 __ block_comment("membar_acquire_lock (elided)"); 8279 %} 8280 8281 ins_pipe(pipe_serial); 8282 %} 8283 8284 instruct store_fence() %{ 8285 match(StoreFence); 8286 ins_cost(VOLATILE_REF_COST); 8287 8288 format %{ "store_fence" %} 8289 8290 ins_encode %{ 8291 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8292 %} 8293 ins_pipe(pipe_serial); 8294 %} 8295 8296 instruct unnecessary_membar_release() %{ 8297 predicate(unnecessary_release(n)); 8298 match(MemBarRelease); 8299 ins_cost(0); 8300 8301 format %{ "membar_release (elided)" %} 8302 8303 ins_encode %{ 8304 __ block_comment("membar_release (elided)"); 8305 %} 8306 ins_pipe(pipe_serial); 8307 %} 8308 8309 instruct membar_release() %{ 8310 match(MemBarRelease); 8311 ins_cost(VOLATILE_REF_COST); 8312 8313 format %{ "membar_release\n\t" 8314 "dmb ish" %} 8315 8316 ins_encode %{ 8317 __ block_comment("membar_release"); 8318 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8319 %} 8320 ins_pipe(pipe_serial); 8321 %} 8322 8323 instruct membar_storestore() %{ 8324 match(MemBarStoreStore); 8325 ins_cost(VOLATILE_REF_COST); 8326 8327 format %{ "MEMBAR-store-store" %} 8328 8329 ins_encode %{ 8330 __ membar(Assembler::StoreStore); 8331 %} 8332 ins_pipe(pipe_serial); 8333 %} 8334 8335 instruct membar_release_lock() %{ 8336 match(MemBarReleaseLock); 8337 ins_cost(VOLATILE_REF_COST); 8338 8339 format %{ "membar_release_lock (elided)" %} 8340 8341 ins_encode %{ 8342 __ block_comment("membar_release_lock (elided)"); 8343 %} 8344 8345 ins_pipe(pipe_serial); 8346 %} 8347 8348 instruct unnecessary_membar_volatile() %{ 8349 predicate(unnecessary_volatile(n)); 8350 match(MemBarVolatile); 8351 ins_cost(0); 8352 8353 format %{ "membar_volatile (elided)" %} 8354 8355 ins_encode %{ 8356 __ block_comment("membar_volatile (elided)"); 8357 %} 8358 8359 ins_pipe(pipe_serial); 8360 %} 8361 8362 instruct membar_volatile() %{ 8363 match(MemBarVolatile); 8364 ins_cost(VOLATILE_REF_COST*100); 8365 8366 format %{ "membar_volatile\n\t" 8367 "dmb ish"%} 8368 8369 ins_encode %{ 8370 __ block_comment("membar_volatile"); 8371 __ membar(Assembler::StoreLoad); 8372 %} 8373 8374 ins_pipe(pipe_serial); 8375 %} 8376 8377 // ============================================================================ 8378 // Cast/Convert Instructions 8379 8380 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8381 match(Set dst (CastX2P src)); 8382 8383 ins_cost(INSN_COST); 8384 format %{ "mov $dst, $src\t# long -> ptr" %} 8385 8386 ins_encode %{ 8387 if ($dst$$reg != $src$$reg) { 8388 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8389 } 8390 %} 8391 8392 ins_pipe(ialu_reg); 8393 %} 8394 8395 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8396 match(Set dst (CastP2X src)); 8397 8398 ins_cost(INSN_COST); 8399 format %{ "mov $dst, $src\t# ptr -> long" %} 8400 8401 ins_encode %{ 8402 if ($dst$$reg != $src$$reg) { 8403 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8404 } 8405 %} 8406 8407 ins_pipe(ialu_reg); 8408 %} 8409 8410 // Convert oop into int for vectors alignment masking 8411 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8412 match(Set dst (ConvL2I (CastP2X src))); 8413 8414 ins_cost(INSN_COST); 8415 format %{ "movw $dst, $src\t# ptr -> int" %} 8416 ins_encode %{ 8417 __ movw($dst$$Register, $src$$Register); 8418 %} 8419 8420 ins_pipe(ialu_reg); 8421 %} 8422 8423 // Convert compressed oop into int for vectors alignment masking 8424 // in case of 32bit oops (heap < 4Gb). 8425 instruct convN2I(iRegINoSp dst, iRegN src) 8426 %{ 8427 predicate(CompressedOops::shift() == 0); 8428 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8429 8430 ins_cost(INSN_COST); 8431 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8432 ins_encode %{ 8433 __ movw($dst$$Register, $src$$Register); 8434 %} 8435 8436 ins_pipe(ialu_reg); 8437 %} 8438 8439 8440 // Convert oop pointer into compressed form 8441 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8442 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8443 match(Set dst (EncodeP src)); 8444 effect(KILL cr); 8445 ins_cost(INSN_COST * 3); 8446 format %{ "encode_heap_oop $dst, $src" %} 8447 ins_encode %{ 8448 Register s = $src$$Register; 8449 Register d = $dst$$Register; 8450 __ encode_heap_oop(d, s); 8451 %} 8452 ins_pipe(ialu_reg); 8453 %} 8454 8455 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8456 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8457 match(Set dst (EncodeP src)); 8458 ins_cost(INSN_COST * 3); 8459 format %{ "encode_heap_oop_not_null $dst, $src" %} 8460 ins_encode %{ 8461 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8462 %} 8463 ins_pipe(ialu_reg); 8464 %} 8465 8466 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8467 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8468 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8469 match(Set dst (DecodeN src)); 8470 ins_cost(INSN_COST * 3); 8471 format %{ "decode_heap_oop $dst, $src" %} 8472 ins_encode %{ 8473 Register s = $src$$Register; 8474 Register d = $dst$$Register; 8475 __ decode_heap_oop(d, s); 8476 %} 8477 ins_pipe(ialu_reg); 8478 %} 8479 8480 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8481 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8482 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8483 match(Set dst (DecodeN src)); 8484 ins_cost(INSN_COST * 3); 8485 format %{ "decode_heap_oop_not_null $dst, $src" %} 8486 ins_encode %{ 8487 Register s = $src$$Register; 8488 Register d = $dst$$Register; 8489 __ decode_heap_oop_not_null(d, s); 8490 %} 8491 ins_pipe(ialu_reg); 8492 %} 8493 8494 // n.b. AArch64 implementations of encode_klass_not_null and 8495 // decode_klass_not_null do not modify the flags register so, unlike 8496 // Intel, we don't kill CR as a side effect here 8497 8498 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8499 match(Set dst (EncodePKlass src)); 8500 8501 ins_cost(INSN_COST * 3); 8502 format %{ "encode_klass_not_null $dst,$src" %} 8503 8504 ins_encode %{ 8505 Register src_reg = as_Register($src$$reg); 8506 Register dst_reg = as_Register($dst$$reg); 8507 __ encode_klass_not_null(dst_reg, src_reg); 8508 %} 8509 8510 ins_pipe(ialu_reg); 8511 %} 8512 8513 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8514 match(Set dst (DecodeNKlass src)); 8515 8516 ins_cost(INSN_COST * 3); 8517 format %{ "decode_klass_not_null $dst,$src" %} 8518 8519 ins_encode %{ 8520 Register src_reg = as_Register($src$$reg); 8521 Register dst_reg = as_Register($dst$$reg); 8522 if (dst_reg != src_reg) { 8523 __ decode_klass_not_null(dst_reg, src_reg); 8524 } else { 8525 __ decode_klass_not_null(dst_reg); 8526 } 8527 %} 8528 8529 ins_pipe(ialu_reg); 8530 %} 8531 8532 instruct checkCastPP(iRegPNoSp dst) 8533 %{ 8534 match(Set dst (CheckCastPP dst)); 8535 8536 size(0); 8537 format %{ "# checkcastPP of $dst" %} 8538 ins_encode(/* empty encoding */); 8539 ins_pipe(pipe_class_empty); 8540 %} 8541 8542 instruct castPP(iRegPNoSp dst) 8543 %{ 8544 match(Set dst (CastPP dst)); 8545 8546 size(0); 8547 format %{ "# castPP of $dst" %} 8548 ins_encode(/* empty encoding */); 8549 ins_pipe(pipe_class_empty); 8550 %} 8551 8552 instruct castII(iRegI dst) 8553 %{ 8554 match(Set dst (CastII dst)); 8555 8556 size(0); 8557 format %{ "# castII of $dst" %} 8558 ins_encode(/* empty encoding */); 8559 ins_cost(0); 8560 ins_pipe(pipe_class_empty); 8561 %} 8562 8563 instruct castLL(iRegL dst) 8564 %{ 8565 match(Set dst (CastLL dst)); 8566 8567 size(0); 8568 format %{ "# castLL of $dst" %} 8569 ins_encode(/* empty encoding */); 8570 ins_cost(0); 8571 ins_pipe(pipe_class_empty); 8572 %} 8573 8574 // ============================================================================ 8575 // Atomic operation instructions 8576 // 8577 // Intel and SPARC both implement Ideal Node LoadPLocked and 8578 // Store{PIL}Conditional instructions using a normal load for the 8579 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8580 // 8581 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8582 // pair to lock object allocations from Eden space when not using 8583 // TLABs. 8584 // 8585 // There does not appear to be a Load{IL}Locked Ideal Node and the 8586 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8587 // and to use StoreIConditional only for 32-bit and StoreLConditional 8588 // only for 64-bit. 8589 // 8590 // We implement LoadPLocked and StorePLocked instructions using, 8591 // respectively the AArch64 hw load-exclusive and store-conditional 8592 // instructions. Whereas we must implement each of 8593 // Store{IL}Conditional using a CAS which employs a pair of 8594 // instructions comprising a load-exclusive followed by a 8595 // store-conditional. 8596 8597 8598 // Locked-load (linked load) of the current heap-top 8599 // used when updating the eden heap top 8600 // implemented using ldaxr on AArch64 8601 8602 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8603 %{ 8604 match(Set dst (LoadPLocked mem)); 8605 8606 ins_cost(VOLATILE_REF_COST); 8607 8608 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8609 8610 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8611 8612 ins_pipe(pipe_serial); 8613 %} 8614 8615 // Conditional-store of the updated heap-top. 8616 // Used during allocation of the shared heap. 8617 // Sets flag (EQ) on success. 8618 // implemented using stlxr on AArch64. 8619 8620 instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8621 %{ 8622 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8623 8624 ins_cost(VOLATILE_REF_COST); 8625 8626 // TODO 8627 // do we need to do a store-conditional release or can we just use a 8628 // plain store-conditional? 8629 8630 format %{ 8631 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8632 "cmpw rscratch1, zr\t# EQ on successful write" 8633 %} 8634 8635 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8636 8637 ins_pipe(pipe_serial); 8638 %} 8639 8640 8641 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8642 // when attempting to rebias a lock towards the current thread. We 8643 // must use the acquire form of cmpxchg in order to guarantee acquire 8644 // semantics in this case. 8645 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8646 %{ 8647 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8648 8649 ins_cost(VOLATILE_REF_COST); 8650 8651 format %{ 8652 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8653 "cmpw rscratch1, zr\t# EQ on successful write" 8654 %} 8655 8656 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8657 8658 ins_pipe(pipe_slow); 8659 %} 8660 8661 // storeIConditional also has acquire semantics, for no better reason 8662 // than matching storeLConditional. At the time of writing this 8663 // comment storeIConditional was not used anywhere by AArch64. 8664 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8665 %{ 8666 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8667 8668 ins_cost(VOLATILE_REF_COST); 8669 8670 format %{ 8671 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8672 "cmpw rscratch1, zr\t# EQ on successful write" 8673 %} 8674 8675 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8676 8677 ins_pipe(pipe_slow); 8678 %} 8679 8680 // standard CompareAndSwapX when we are using barriers 8681 // these have higher priority than the rules selected by a predicate 8682 8683 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8684 // can't match them 8685 8686 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8687 8688 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8689 ins_cost(2 * VOLATILE_REF_COST); 8690 8691 effect(KILL cr); 8692 8693 format %{ 8694 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8695 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8696 %} 8697 8698 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8699 aarch64_enc_cset_eq(res)); 8700 8701 ins_pipe(pipe_slow); 8702 %} 8703 8704 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8705 8706 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8707 ins_cost(2 * VOLATILE_REF_COST); 8708 8709 effect(KILL cr); 8710 8711 format %{ 8712 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8713 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8714 %} 8715 8716 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8717 aarch64_enc_cset_eq(res)); 8718 8719 ins_pipe(pipe_slow); 8720 %} 8721 8722 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8723 8724 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8725 ins_cost(2 * VOLATILE_REF_COST); 8726 8727 effect(KILL cr); 8728 8729 format %{ 8730 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8731 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8732 %} 8733 8734 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8735 aarch64_enc_cset_eq(res)); 8736 8737 ins_pipe(pipe_slow); 8738 %} 8739 8740 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8741 8742 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8743 ins_cost(2 * VOLATILE_REF_COST); 8744 8745 effect(KILL cr); 8746 8747 format %{ 8748 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8749 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8750 %} 8751 8752 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8753 aarch64_enc_cset_eq(res)); 8754 8755 ins_pipe(pipe_slow); 8756 %} 8757 8758 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8759 8760 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8761 predicate(n->as_LoadStore()->barrier_data() == 0); 8762 ins_cost(2 * VOLATILE_REF_COST); 8763 8764 effect(KILL cr); 8765 8766 format %{ 8767 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8768 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8769 %} 8770 8771 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8772 aarch64_enc_cset_eq(res)); 8773 8774 ins_pipe(pipe_slow); 8775 %} 8776 8777 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8778 8779 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8780 ins_cost(2 * VOLATILE_REF_COST); 8781 8782 effect(KILL cr); 8783 8784 format %{ 8785 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8786 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8787 %} 8788 8789 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8790 aarch64_enc_cset_eq(res)); 8791 8792 ins_pipe(pipe_slow); 8793 %} 8794 8795 // alternative CompareAndSwapX when we are eliding barriers 8796 8797 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8798 8799 predicate(needs_acquiring_load_exclusive(n)); 8800 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8801 ins_cost(VOLATILE_REF_COST); 8802 8803 effect(KILL cr); 8804 8805 format %{ 8806 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8807 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8808 %} 8809 8810 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8811 aarch64_enc_cset_eq(res)); 8812 8813 ins_pipe(pipe_slow); 8814 %} 8815 8816 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8817 8818 predicate(needs_acquiring_load_exclusive(n)); 8819 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8820 ins_cost(VOLATILE_REF_COST); 8821 8822 effect(KILL cr); 8823 8824 format %{ 8825 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8826 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8827 %} 8828 8829 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8830 aarch64_enc_cset_eq(res)); 8831 8832 ins_pipe(pipe_slow); 8833 %} 8834 8835 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8836 8837 predicate(needs_acquiring_load_exclusive(n)); 8838 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8839 ins_cost(VOLATILE_REF_COST); 8840 8841 effect(KILL cr); 8842 8843 format %{ 8844 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8845 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8846 %} 8847 8848 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8849 aarch64_enc_cset_eq(res)); 8850 8851 ins_pipe(pipe_slow); 8852 %} 8853 8854 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8855 8856 predicate(needs_acquiring_load_exclusive(n)); 8857 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8858 ins_cost(VOLATILE_REF_COST); 8859 8860 effect(KILL cr); 8861 8862 format %{ 8863 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8864 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8865 %} 8866 8867 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8868 aarch64_enc_cset_eq(res)); 8869 8870 ins_pipe(pipe_slow); 8871 %} 8872 8873 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8874 8875 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8876 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8877 ins_cost(VOLATILE_REF_COST); 8878 8879 effect(KILL cr); 8880 8881 format %{ 8882 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8883 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8884 %} 8885 8886 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8887 aarch64_enc_cset_eq(res)); 8888 8889 ins_pipe(pipe_slow); 8890 %} 8891 8892 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8893 8894 predicate(needs_acquiring_load_exclusive(n)); 8895 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8896 ins_cost(VOLATILE_REF_COST); 8897 8898 effect(KILL cr); 8899 8900 format %{ 8901 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8902 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8903 %} 8904 8905 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8906 aarch64_enc_cset_eq(res)); 8907 8908 ins_pipe(pipe_slow); 8909 %} 8910 8911 8912 // --------------------------------------------------------------------- 8913 8914 8915 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8916 8917 // Sundry CAS operations. Note that release is always true, 8918 // regardless of the memory ordering of the CAS. This is because we 8919 // need the volatile case to be sequentially consistent but there is 8920 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8921 // can't check the type of memory ordering here, so we always emit a 8922 // STLXR. 8923 8924 // This section is generated from aarch64_ad_cas.m4 8925 8926 8927 8928 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8929 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8930 ins_cost(2 * VOLATILE_REF_COST); 8931 effect(TEMP_DEF res, KILL cr); 8932 format %{ 8933 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8934 %} 8935 ins_encode %{ 8936 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8937 Assembler::byte, /*acquire*/ false, /*release*/ true, 8938 /*weak*/ false, $res$$Register); 8939 __ sxtbw($res$$Register, $res$$Register); 8940 %} 8941 ins_pipe(pipe_slow); 8942 %} 8943 8944 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8945 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8946 ins_cost(2 * VOLATILE_REF_COST); 8947 effect(TEMP_DEF res, KILL cr); 8948 format %{ 8949 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8950 %} 8951 ins_encode %{ 8952 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8953 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8954 /*weak*/ false, $res$$Register); 8955 __ sxthw($res$$Register, $res$$Register); 8956 %} 8957 ins_pipe(pipe_slow); 8958 %} 8959 8960 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8961 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8962 ins_cost(2 * VOLATILE_REF_COST); 8963 effect(TEMP_DEF res, KILL cr); 8964 format %{ 8965 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8966 %} 8967 ins_encode %{ 8968 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8969 Assembler::word, /*acquire*/ false, /*release*/ true, 8970 /*weak*/ false, $res$$Register); 8971 %} 8972 ins_pipe(pipe_slow); 8973 %} 8974 8975 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8976 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8977 ins_cost(2 * VOLATILE_REF_COST); 8978 effect(TEMP_DEF res, KILL cr); 8979 format %{ 8980 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8981 %} 8982 ins_encode %{ 8983 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8984 Assembler::xword, /*acquire*/ false, /*release*/ true, 8985 /*weak*/ false, $res$$Register); 8986 %} 8987 ins_pipe(pipe_slow); 8988 %} 8989 8990 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8991 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8992 ins_cost(2 * VOLATILE_REF_COST); 8993 effect(TEMP_DEF res, KILL cr); 8994 format %{ 8995 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8996 %} 8997 ins_encode %{ 8998 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8999 Assembler::word, /*acquire*/ false, /*release*/ true, 9000 /*weak*/ false, $res$$Register); 9001 %} 9002 ins_pipe(pipe_slow); 9003 %} 9004 9005 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9006 predicate(n->as_LoadStore()->barrier_data() == 0); 9007 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9008 ins_cost(2 * VOLATILE_REF_COST); 9009 effect(TEMP_DEF res, KILL cr); 9010 format %{ 9011 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9012 %} 9013 ins_encode %{ 9014 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9015 Assembler::xword, /*acquire*/ false, /*release*/ true, 9016 /*weak*/ false, $res$$Register); 9017 %} 9018 ins_pipe(pipe_slow); 9019 %} 9020 9021 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9022 predicate(needs_acquiring_load_exclusive(n)); 9023 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 9024 ins_cost(VOLATILE_REF_COST); 9025 effect(TEMP_DEF res, KILL cr); 9026 format %{ 9027 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9028 %} 9029 ins_encode %{ 9030 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9031 Assembler::byte, /*acquire*/ true, /*release*/ true, 9032 /*weak*/ false, $res$$Register); 9033 __ sxtbw($res$$Register, $res$$Register); 9034 %} 9035 ins_pipe(pipe_slow); 9036 %} 9037 9038 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9039 predicate(needs_acquiring_load_exclusive(n)); 9040 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9041 ins_cost(VOLATILE_REF_COST); 9042 effect(TEMP_DEF res, KILL cr); 9043 format %{ 9044 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9045 %} 9046 ins_encode %{ 9047 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9048 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9049 /*weak*/ false, $res$$Register); 9050 __ sxthw($res$$Register, $res$$Register); 9051 %} 9052 ins_pipe(pipe_slow); 9053 %} 9054 9055 9056 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9057 predicate(needs_acquiring_load_exclusive(n)); 9058 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9059 ins_cost(VOLATILE_REF_COST); 9060 effect(TEMP_DEF res, KILL cr); 9061 format %{ 9062 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9063 %} 9064 ins_encode %{ 9065 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9066 Assembler::word, /*acquire*/ true, /*release*/ true, 9067 /*weak*/ false, $res$$Register); 9068 %} 9069 ins_pipe(pipe_slow); 9070 %} 9071 9072 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9073 predicate(needs_acquiring_load_exclusive(n)); 9074 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9075 ins_cost(VOLATILE_REF_COST); 9076 effect(TEMP_DEF res, KILL cr); 9077 format %{ 9078 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9079 %} 9080 ins_encode %{ 9081 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9082 Assembler::xword, /*acquire*/ true, /*release*/ true, 9083 /*weak*/ false, $res$$Register); 9084 %} 9085 ins_pipe(pipe_slow); 9086 %} 9087 9088 9089 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9090 predicate(needs_acquiring_load_exclusive(n)); 9091 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9092 ins_cost(VOLATILE_REF_COST); 9093 effect(TEMP_DEF res, KILL cr); 9094 format %{ 9095 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9096 %} 9097 ins_encode %{ 9098 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9099 Assembler::word, /*acquire*/ true, /*release*/ true, 9100 /*weak*/ false, $res$$Register); 9101 %} 9102 ins_pipe(pipe_slow); 9103 %} 9104 9105 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9106 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9107 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9108 ins_cost(VOLATILE_REF_COST); 9109 effect(TEMP_DEF res, KILL cr); 9110 format %{ 9111 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9112 %} 9113 ins_encode %{ 9114 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9115 Assembler::xword, /*acquire*/ true, /*release*/ true, 9116 /*weak*/ false, $res$$Register); 9117 %} 9118 ins_pipe(pipe_slow); 9119 %} 9120 9121 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9122 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9123 ins_cost(2 * VOLATILE_REF_COST); 9124 effect(KILL cr); 9125 format %{ 9126 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9127 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9128 %} 9129 ins_encode %{ 9130 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9131 Assembler::byte, /*acquire*/ false, /*release*/ true, 9132 /*weak*/ true, noreg); 9133 __ csetw($res$$Register, Assembler::EQ); 9134 %} 9135 ins_pipe(pipe_slow); 9136 %} 9137 9138 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9139 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9140 ins_cost(2 * VOLATILE_REF_COST); 9141 effect(KILL cr); 9142 format %{ 9143 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9144 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9145 %} 9146 ins_encode %{ 9147 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9148 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9149 /*weak*/ true, noreg); 9150 __ csetw($res$$Register, Assembler::EQ); 9151 %} 9152 ins_pipe(pipe_slow); 9153 %} 9154 9155 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9156 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9157 ins_cost(2 * VOLATILE_REF_COST); 9158 effect(KILL cr); 9159 format %{ 9160 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9161 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9162 %} 9163 ins_encode %{ 9164 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9165 Assembler::word, /*acquire*/ false, /*release*/ true, 9166 /*weak*/ true, noreg); 9167 __ csetw($res$$Register, Assembler::EQ); 9168 %} 9169 ins_pipe(pipe_slow); 9170 %} 9171 9172 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9173 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9174 ins_cost(2 * VOLATILE_REF_COST); 9175 effect(KILL cr); 9176 format %{ 9177 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9178 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9179 %} 9180 ins_encode %{ 9181 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9182 Assembler::xword, /*acquire*/ false, /*release*/ true, 9183 /*weak*/ true, noreg); 9184 __ csetw($res$$Register, Assembler::EQ); 9185 %} 9186 ins_pipe(pipe_slow); 9187 %} 9188 9189 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9190 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9191 ins_cost(2 * VOLATILE_REF_COST); 9192 effect(KILL cr); 9193 format %{ 9194 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9195 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9196 %} 9197 ins_encode %{ 9198 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9199 Assembler::word, /*acquire*/ false, /*release*/ true, 9200 /*weak*/ true, noreg); 9201 __ csetw($res$$Register, Assembler::EQ); 9202 %} 9203 ins_pipe(pipe_slow); 9204 %} 9205 9206 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9207 predicate(n->as_LoadStore()->barrier_data() == 0); 9208 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9209 ins_cost(2 * VOLATILE_REF_COST); 9210 effect(KILL cr); 9211 format %{ 9212 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9213 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9214 %} 9215 ins_encode %{ 9216 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9217 Assembler::xword, /*acquire*/ false, /*release*/ true, 9218 /*weak*/ true, noreg); 9219 __ csetw($res$$Register, Assembler::EQ); 9220 %} 9221 ins_pipe(pipe_slow); 9222 %} 9223 9224 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9225 predicate(needs_acquiring_load_exclusive(n)); 9226 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9227 ins_cost(VOLATILE_REF_COST); 9228 effect(KILL cr); 9229 format %{ 9230 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9231 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9232 %} 9233 ins_encode %{ 9234 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9235 Assembler::byte, /*acquire*/ true, /*release*/ true, 9236 /*weak*/ true, noreg); 9237 __ csetw($res$$Register, Assembler::EQ); 9238 %} 9239 ins_pipe(pipe_slow); 9240 %} 9241 9242 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9243 predicate(needs_acquiring_load_exclusive(n)); 9244 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9245 ins_cost(VOLATILE_REF_COST); 9246 effect(KILL cr); 9247 format %{ 9248 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9249 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9250 %} 9251 ins_encode %{ 9252 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9253 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9254 /*weak*/ true, noreg); 9255 __ csetw($res$$Register, Assembler::EQ); 9256 %} 9257 ins_pipe(pipe_slow); 9258 %} 9259 9260 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9261 predicate(needs_acquiring_load_exclusive(n)); 9262 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9263 ins_cost(VOLATILE_REF_COST); 9264 effect(KILL cr); 9265 format %{ 9266 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9267 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9268 %} 9269 ins_encode %{ 9270 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9271 Assembler::word, /*acquire*/ true, /*release*/ true, 9272 /*weak*/ true, noreg); 9273 __ csetw($res$$Register, Assembler::EQ); 9274 %} 9275 ins_pipe(pipe_slow); 9276 %} 9277 9278 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9279 predicate(needs_acquiring_load_exclusive(n)); 9280 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9281 ins_cost(VOLATILE_REF_COST); 9282 effect(KILL cr); 9283 format %{ 9284 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9285 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9286 %} 9287 ins_encode %{ 9288 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9289 Assembler::xword, /*acquire*/ true, /*release*/ true, 9290 /*weak*/ true, noreg); 9291 __ csetw($res$$Register, Assembler::EQ); 9292 %} 9293 ins_pipe(pipe_slow); 9294 %} 9295 9296 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9297 predicate(needs_acquiring_load_exclusive(n)); 9298 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9299 ins_cost(VOLATILE_REF_COST); 9300 effect(KILL cr); 9301 format %{ 9302 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9303 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9304 %} 9305 ins_encode %{ 9306 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9307 Assembler::word, /*acquire*/ true, /*release*/ true, 9308 /*weak*/ true, noreg); 9309 __ csetw($res$$Register, Assembler::EQ); 9310 %} 9311 ins_pipe(pipe_slow); 9312 %} 9313 9314 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9315 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9316 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9317 ins_cost(VOLATILE_REF_COST); 9318 effect(KILL cr); 9319 format %{ 9320 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9321 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9322 %} 9323 ins_encode %{ 9324 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9325 Assembler::xword, /*acquire*/ true, /*release*/ true, 9326 /*weak*/ true, noreg); 9327 __ csetw($res$$Register, Assembler::EQ); 9328 %} 9329 ins_pipe(pipe_slow); 9330 %} 9331 9332 // END This section of the file is automatically generated. Do not edit -------------- 9333 // --------------------------------------------------------------------- 9334 9335 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9336 match(Set prev (GetAndSetI mem newv)); 9337 ins_cost(2 * VOLATILE_REF_COST); 9338 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9339 ins_encode %{ 9340 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9341 %} 9342 ins_pipe(pipe_serial); 9343 %} 9344 9345 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9346 match(Set prev (GetAndSetL mem newv)); 9347 ins_cost(2 * VOLATILE_REF_COST); 9348 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9349 ins_encode %{ 9350 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9351 %} 9352 ins_pipe(pipe_serial); 9353 %} 9354 9355 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9356 match(Set prev (GetAndSetN mem newv)); 9357 ins_cost(2 * VOLATILE_REF_COST); 9358 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9359 ins_encode %{ 9360 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9361 %} 9362 ins_pipe(pipe_serial); 9363 %} 9364 9365 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9366 predicate(n->as_LoadStore()->barrier_data() == 0); 9367 match(Set prev (GetAndSetP mem newv)); 9368 ins_cost(2 * VOLATILE_REF_COST); 9369 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9370 ins_encode %{ 9371 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9372 %} 9373 ins_pipe(pipe_serial); 9374 %} 9375 9376 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9377 predicate(needs_acquiring_load_exclusive(n)); 9378 match(Set prev (GetAndSetI mem newv)); 9379 ins_cost(VOLATILE_REF_COST); 9380 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9381 ins_encode %{ 9382 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9383 %} 9384 ins_pipe(pipe_serial); 9385 %} 9386 9387 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9388 predicate(needs_acquiring_load_exclusive(n)); 9389 match(Set prev (GetAndSetL mem newv)); 9390 ins_cost(VOLATILE_REF_COST); 9391 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9392 ins_encode %{ 9393 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9394 %} 9395 ins_pipe(pipe_serial); 9396 %} 9397 9398 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9399 predicate(needs_acquiring_load_exclusive(n)); 9400 match(Set prev (GetAndSetN mem newv)); 9401 ins_cost(VOLATILE_REF_COST); 9402 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9403 ins_encode %{ 9404 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9405 %} 9406 ins_pipe(pipe_serial); 9407 %} 9408 9409 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9410 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9411 match(Set prev (GetAndSetP mem newv)); 9412 ins_cost(VOLATILE_REF_COST); 9413 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9414 ins_encode %{ 9415 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9416 %} 9417 ins_pipe(pipe_serial); 9418 %} 9419 9420 9421 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9422 match(Set newval (GetAndAddL mem incr)); 9423 ins_cost(2 * VOLATILE_REF_COST + 1); 9424 format %{ "get_and_addL $newval, [$mem], $incr" %} 9425 ins_encode %{ 9426 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9427 %} 9428 ins_pipe(pipe_serial); 9429 %} 9430 9431 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9432 predicate(n->as_LoadStore()->result_not_used()); 9433 match(Set dummy (GetAndAddL mem incr)); 9434 ins_cost(2 * VOLATILE_REF_COST); 9435 format %{ "get_and_addL [$mem], $incr" %} 9436 ins_encode %{ 9437 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9438 %} 9439 ins_pipe(pipe_serial); 9440 %} 9441 9442 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9443 match(Set newval (GetAndAddL mem incr)); 9444 ins_cost(2 * VOLATILE_REF_COST + 1); 9445 format %{ "get_and_addL $newval, [$mem], $incr" %} 9446 ins_encode %{ 9447 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9448 %} 9449 ins_pipe(pipe_serial); 9450 %} 9451 9452 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9453 predicate(n->as_LoadStore()->result_not_used()); 9454 match(Set dummy (GetAndAddL mem incr)); 9455 ins_cost(2 * VOLATILE_REF_COST); 9456 format %{ "get_and_addL [$mem], $incr" %} 9457 ins_encode %{ 9458 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9459 %} 9460 ins_pipe(pipe_serial); 9461 %} 9462 9463 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9464 match(Set newval (GetAndAddI mem incr)); 9465 ins_cost(2 * VOLATILE_REF_COST + 1); 9466 format %{ "get_and_addI $newval, [$mem], $incr" %} 9467 ins_encode %{ 9468 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9469 %} 9470 ins_pipe(pipe_serial); 9471 %} 9472 9473 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9474 predicate(n->as_LoadStore()->result_not_used()); 9475 match(Set dummy (GetAndAddI mem incr)); 9476 ins_cost(2 * VOLATILE_REF_COST); 9477 format %{ "get_and_addI [$mem], $incr" %} 9478 ins_encode %{ 9479 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9480 %} 9481 ins_pipe(pipe_serial); 9482 %} 9483 9484 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9485 match(Set newval (GetAndAddI mem incr)); 9486 ins_cost(2 * VOLATILE_REF_COST + 1); 9487 format %{ "get_and_addI $newval, [$mem], $incr" %} 9488 ins_encode %{ 9489 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9490 %} 9491 ins_pipe(pipe_serial); 9492 %} 9493 9494 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9495 predicate(n->as_LoadStore()->result_not_used()); 9496 match(Set dummy (GetAndAddI mem incr)); 9497 ins_cost(2 * VOLATILE_REF_COST); 9498 format %{ "get_and_addI [$mem], $incr" %} 9499 ins_encode %{ 9500 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9501 %} 9502 ins_pipe(pipe_serial); 9503 %} 9504 9505 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9506 predicate(needs_acquiring_load_exclusive(n)); 9507 match(Set newval (GetAndAddL mem incr)); 9508 ins_cost(VOLATILE_REF_COST + 1); 9509 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9510 ins_encode %{ 9511 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9512 %} 9513 ins_pipe(pipe_serial); 9514 %} 9515 9516 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9517 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9518 match(Set dummy (GetAndAddL mem incr)); 9519 ins_cost(VOLATILE_REF_COST); 9520 format %{ "get_and_addL_acq [$mem], $incr" %} 9521 ins_encode %{ 9522 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9523 %} 9524 ins_pipe(pipe_serial); 9525 %} 9526 9527 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9528 predicate(needs_acquiring_load_exclusive(n)); 9529 match(Set newval (GetAndAddL mem incr)); 9530 ins_cost(VOLATILE_REF_COST + 1); 9531 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9532 ins_encode %{ 9533 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9534 %} 9535 ins_pipe(pipe_serial); 9536 %} 9537 9538 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9539 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9540 match(Set dummy (GetAndAddL mem incr)); 9541 ins_cost(VOLATILE_REF_COST); 9542 format %{ "get_and_addL_acq [$mem], $incr" %} 9543 ins_encode %{ 9544 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9545 %} 9546 ins_pipe(pipe_serial); 9547 %} 9548 9549 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9550 predicate(needs_acquiring_load_exclusive(n)); 9551 match(Set newval (GetAndAddI mem incr)); 9552 ins_cost(VOLATILE_REF_COST + 1); 9553 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9554 ins_encode %{ 9555 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9556 %} 9557 ins_pipe(pipe_serial); 9558 %} 9559 9560 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9561 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9562 match(Set dummy (GetAndAddI mem incr)); 9563 ins_cost(VOLATILE_REF_COST); 9564 format %{ "get_and_addI_acq [$mem], $incr" %} 9565 ins_encode %{ 9566 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9567 %} 9568 ins_pipe(pipe_serial); 9569 %} 9570 9571 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9572 predicate(needs_acquiring_load_exclusive(n)); 9573 match(Set newval (GetAndAddI mem incr)); 9574 ins_cost(VOLATILE_REF_COST + 1); 9575 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9576 ins_encode %{ 9577 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9578 %} 9579 ins_pipe(pipe_serial); 9580 %} 9581 9582 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9583 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9584 match(Set dummy (GetAndAddI mem incr)); 9585 ins_cost(VOLATILE_REF_COST); 9586 format %{ "get_and_addI_acq [$mem], $incr" %} 9587 ins_encode %{ 9588 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9589 %} 9590 ins_pipe(pipe_serial); 9591 %} 9592 9593 // Manifest a CmpL result in an integer register. 9594 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9595 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9596 %{ 9597 match(Set dst (CmpL3 src1 src2)); 9598 effect(KILL flags); 9599 9600 ins_cost(INSN_COST * 6); 9601 format %{ 9602 "cmp $src1, $src2" 9603 "csetw $dst, ne" 9604 "cnegw $dst, lt" 9605 %} 9606 // format %{ "CmpL3 $dst, $src1, $src2" %} 9607 ins_encode %{ 9608 __ cmp($src1$$Register, $src2$$Register); 9609 __ csetw($dst$$Register, Assembler::NE); 9610 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9611 %} 9612 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9617 %{ 9618 match(Set dst (CmpL3 src1 src2)); 9619 effect(KILL flags); 9620 9621 ins_cost(INSN_COST * 6); 9622 format %{ 9623 "cmp $src1, $src2" 9624 "csetw $dst, ne" 9625 "cnegw $dst, lt" 9626 %} 9627 ins_encode %{ 9628 int32_t con = (int32_t)$src2$$constant; 9629 if (con < 0) { 9630 __ adds(zr, $src1$$Register, -con); 9631 } else { 9632 __ subs(zr, $src1$$Register, con); 9633 } 9634 __ csetw($dst$$Register, Assembler::NE); 9635 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9636 %} 9637 9638 ins_pipe(pipe_class_default); 9639 %} 9640 9641 // ============================================================================ 9642 // Conditional Move Instructions 9643 9644 // n.b. we have identical rules for both a signed compare op (cmpOp) 9645 // and an unsigned compare op (cmpOpU). it would be nice if we could 9646 // define an op class which merged both inputs and use it to type the 9647 // argument to a single rule. unfortunatelyt his fails because the 9648 // opclass does not live up to the COND_INTER interface of its 9649 // component operands. When the generic code tries to negate the 9650 // operand it ends up running the generci Machoper::negate method 9651 // which throws a ShouldNotHappen. So, we have to provide two flavours 9652 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9653 9654 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9655 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9656 9657 ins_cost(INSN_COST * 2); 9658 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9659 9660 ins_encode %{ 9661 __ cselw(as_Register($dst$$reg), 9662 as_Register($src2$$reg), 9663 as_Register($src1$$reg), 9664 (Assembler::Condition)$cmp$$cmpcode); 9665 %} 9666 9667 ins_pipe(icond_reg_reg); 9668 %} 9669 9670 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9671 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9672 9673 ins_cost(INSN_COST * 2); 9674 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9675 9676 ins_encode %{ 9677 __ cselw(as_Register($dst$$reg), 9678 as_Register($src2$$reg), 9679 as_Register($src1$$reg), 9680 (Assembler::Condition)$cmp$$cmpcode); 9681 %} 9682 9683 ins_pipe(icond_reg_reg); 9684 %} 9685 9686 // special cases where one arg is zero 9687 9688 // n.b. this is selected in preference to the rule above because it 9689 // avoids loading constant 0 into a source register 9690 9691 // TODO 9692 // we ought only to be able to cull one of these variants as the ideal 9693 // transforms ought always to order the zero consistently (to left/right?) 9694 9695 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9696 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9697 9698 ins_cost(INSN_COST * 2); 9699 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9700 9701 ins_encode %{ 9702 __ cselw(as_Register($dst$$reg), 9703 as_Register($src$$reg), 9704 zr, 9705 (Assembler::Condition)$cmp$$cmpcode); 9706 %} 9707 9708 ins_pipe(icond_reg); 9709 %} 9710 9711 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9712 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9713 9714 ins_cost(INSN_COST * 2); 9715 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9716 9717 ins_encode %{ 9718 __ cselw(as_Register($dst$$reg), 9719 as_Register($src$$reg), 9720 zr, 9721 (Assembler::Condition)$cmp$$cmpcode); 9722 %} 9723 9724 ins_pipe(icond_reg); 9725 %} 9726 9727 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9728 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9729 9730 ins_cost(INSN_COST * 2); 9731 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9732 9733 ins_encode %{ 9734 __ cselw(as_Register($dst$$reg), 9735 zr, 9736 as_Register($src$$reg), 9737 (Assembler::Condition)$cmp$$cmpcode); 9738 %} 9739 9740 ins_pipe(icond_reg); 9741 %} 9742 9743 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9744 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9745 9746 ins_cost(INSN_COST * 2); 9747 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9748 9749 ins_encode %{ 9750 __ cselw(as_Register($dst$$reg), 9751 zr, 9752 as_Register($src$$reg), 9753 (Assembler::Condition)$cmp$$cmpcode); 9754 %} 9755 9756 ins_pipe(icond_reg); 9757 %} 9758 9759 // special case for creating a boolean 0 or 1 9760 9761 // n.b. this is selected in preference to the rule above because it 9762 // avoids loading constants 0 and 1 into a source register 9763 9764 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9765 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9766 9767 ins_cost(INSN_COST * 2); 9768 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9769 9770 ins_encode %{ 9771 // equivalently 9772 // cset(as_Register($dst$$reg), 9773 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9774 __ csincw(as_Register($dst$$reg), 9775 zr, 9776 zr, 9777 (Assembler::Condition)$cmp$$cmpcode); 9778 %} 9779 9780 ins_pipe(icond_none); 9781 %} 9782 9783 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9784 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9785 9786 ins_cost(INSN_COST * 2); 9787 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9788 9789 ins_encode %{ 9790 // equivalently 9791 // cset(as_Register($dst$$reg), 9792 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9793 __ csincw(as_Register($dst$$reg), 9794 zr, 9795 zr, 9796 (Assembler::Condition)$cmp$$cmpcode); 9797 %} 9798 9799 ins_pipe(icond_none); 9800 %} 9801 9802 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9803 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9804 9805 ins_cost(INSN_COST * 2); 9806 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9807 9808 ins_encode %{ 9809 __ csel(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 cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9819 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9820 9821 ins_cost(INSN_COST * 2); 9822 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9823 9824 ins_encode %{ 9825 __ csel(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 cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9837 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9838 9839 ins_cost(INSN_COST * 2); 9840 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9841 9842 ins_encode %{ 9843 __ csel(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 cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9853 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9854 9855 ins_cost(INSN_COST * 2); 9856 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9857 9858 ins_encode %{ 9859 __ csel(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 cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9869 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9870 9871 ins_cost(INSN_COST * 2); 9872 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9873 9874 ins_encode %{ 9875 __ csel(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 cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9885 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9886 9887 ins_cost(INSN_COST * 2); 9888 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9889 9890 ins_encode %{ 9891 __ csel(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 cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9901 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9902 9903 ins_cost(INSN_COST * 2); 9904 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9905 9906 ins_encode %{ 9907 __ csel(as_Register($dst$$reg), 9908 as_Register($src2$$reg), 9909 as_Register($src1$$reg), 9910 (Assembler::Condition)$cmp$$cmpcode); 9911 %} 9912 9913 ins_pipe(icond_reg_reg); 9914 %} 9915 9916 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9917 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9918 9919 ins_cost(INSN_COST * 2); 9920 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9921 9922 ins_encode %{ 9923 __ csel(as_Register($dst$$reg), 9924 as_Register($src2$$reg), 9925 as_Register($src1$$reg), 9926 (Assembler::Condition)$cmp$$cmpcode); 9927 %} 9928 9929 ins_pipe(icond_reg_reg); 9930 %} 9931 9932 // special cases where one arg is zero 9933 9934 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9935 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9936 9937 ins_cost(INSN_COST * 2); 9938 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9939 9940 ins_encode %{ 9941 __ csel(as_Register($dst$$reg), 9942 zr, 9943 as_Register($src$$reg), 9944 (Assembler::Condition)$cmp$$cmpcode); 9945 %} 9946 9947 ins_pipe(icond_reg); 9948 %} 9949 9950 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9951 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9952 9953 ins_cost(INSN_COST * 2); 9954 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9955 9956 ins_encode %{ 9957 __ csel(as_Register($dst$$reg), 9958 zr, 9959 as_Register($src$$reg), 9960 (Assembler::Condition)$cmp$$cmpcode); 9961 %} 9962 9963 ins_pipe(icond_reg); 9964 %} 9965 9966 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9967 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9968 9969 ins_cost(INSN_COST * 2); 9970 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9971 9972 ins_encode %{ 9973 __ csel(as_Register($dst$$reg), 9974 as_Register($src$$reg), 9975 zr, 9976 (Assembler::Condition)$cmp$$cmpcode); 9977 %} 9978 9979 ins_pipe(icond_reg); 9980 %} 9981 9982 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9983 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9984 9985 ins_cost(INSN_COST * 2); 9986 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9987 9988 ins_encode %{ 9989 __ csel(as_Register($dst$$reg), 9990 as_Register($src$$reg), 9991 zr, 9992 (Assembler::Condition)$cmp$$cmpcode); 9993 %} 9994 9995 ins_pipe(icond_reg); 9996 %} 9997 9998 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9999 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10000 10001 ins_cost(INSN_COST * 2); 10002 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10003 10004 ins_encode %{ 10005 __ cselw(as_Register($dst$$reg), 10006 as_Register($src2$$reg), 10007 as_Register($src1$$reg), 10008 (Assembler::Condition)$cmp$$cmpcode); 10009 %} 10010 10011 ins_pipe(icond_reg_reg); 10012 %} 10013 10014 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10015 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10016 10017 ins_cost(INSN_COST * 2); 10018 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10019 10020 ins_encode %{ 10021 __ cselw(as_Register($dst$$reg), 10022 as_Register($src2$$reg), 10023 as_Register($src1$$reg), 10024 (Assembler::Condition)$cmp$$cmpcode); 10025 %} 10026 10027 ins_pipe(icond_reg_reg); 10028 %} 10029 10030 // special cases where one arg is zero 10031 10032 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10033 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10034 10035 ins_cost(INSN_COST * 2); 10036 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 10037 10038 ins_encode %{ 10039 __ cselw(as_Register($dst$$reg), 10040 zr, 10041 as_Register($src$$reg), 10042 (Assembler::Condition)$cmp$$cmpcode); 10043 %} 10044 10045 ins_pipe(icond_reg); 10046 %} 10047 10048 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10049 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10050 10051 ins_cost(INSN_COST * 2); 10052 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 10053 10054 ins_encode %{ 10055 __ cselw(as_Register($dst$$reg), 10056 zr, 10057 as_Register($src$$reg), 10058 (Assembler::Condition)$cmp$$cmpcode); 10059 %} 10060 10061 ins_pipe(icond_reg); 10062 %} 10063 10064 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10065 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10066 10067 ins_cost(INSN_COST * 2); 10068 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 10069 10070 ins_encode %{ 10071 __ cselw(as_Register($dst$$reg), 10072 as_Register($src$$reg), 10073 zr, 10074 (Assembler::Condition)$cmp$$cmpcode); 10075 %} 10076 10077 ins_pipe(icond_reg); 10078 %} 10079 10080 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10081 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10082 10083 ins_cost(INSN_COST * 2); 10084 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 10085 10086 ins_encode %{ 10087 __ cselw(as_Register($dst$$reg), 10088 as_Register($src$$reg), 10089 zr, 10090 (Assembler::Condition)$cmp$$cmpcode); 10091 %} 10092 10093 ins_pipe(icond_reg); 10094 %} 10095 10096 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10097 %{ 10098 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10099 10100 ins_cost(INSN_COST * 3); 10101 10102 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10103 ins_encode %{ 10104 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10105 __ fcsels(as_FloatRegister($dst$$reg), 10106 as_FloatRegister($src2$$reg), 10107 as_FloatRegister($src1$$reg), 10108 cond); 10109 %} 10110 10111 ins_pipe(fp_cond_reg_reg_s); 10112 %} 10113 10114 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10115 %{ 10116 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10117 10118 ins_cost(INSN_COST * 3); 10119 10120 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10121 ins_encode %{ 10122 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10123 __ fcsels(as_FloatRegister($dst$$reg), 10124 as_FloatRegister($src2$$reg), 10125 as_FloatRegister($src1$$reg), 10126 cond); 10127 %} 10128 10129 ins_pipe(fp_cond_reg_reg_s); 10130 %} 10131 10132 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10133 %{ 10134 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10135 10136 ins_cost(INSN_COST * 3); 10137 10138 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10139 ins_encode %{ 10140 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10141 __ fcseld(as_FloatRegister($dst$$reg), 10142 as_FloatRegister($src2$$reg), 10143 as_FloatRegister($src1$$reg), 10144 cond); 10145 %} 10146 10147 ins_pipe(fp_cond_reg_reg_d); 10148 %} 10149 10150 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10151 %{ 10152 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10153 10154 ins_cost(INSN_COST * 3); 10155 10156 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10157 ins_encode %{ 10158 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10159 __ fcseld(as_FloatRegister($dst$$reg), 10160 as_FloatRegister($src2$$reg), 10161 as_FloatRegister($src1$$reg), 10162 cond); 10163 %} 10164 10165 ins_pipe(fp_cond_reg_reg_d); 10166 %} 10167 10168 // ============================================================================ 10169 // Arithmetic Instructions 10170 // 10171 10172 // Integer Addition 10173 10174 // TODO 10175 // these currently employ operations which do not set CR and hence are 10176 // not flagged as killing CR but we would like to isolate the cases 10177 // where we want to set flags from those where we don't. need to work 10178 // out how to do that. 10179 10180 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10181 match(Set dst (AddI src1 src2)); 10182 10183 ins_cost(INSN_COST); 10184 format %{ "addw $dst, $src1, $src2" %} 10185 10186 ins_encode %{ 10187 __ addw(as_Register($dst$$reg), 10188 as_Register($src1$$reg), 10189 as_Register($src2$$reg)); 10190 %} 10191 10192 ins_pipe(ialu_reg_reg); 10193 %} 10194 10195 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10196 match(Set dst (AddI src1 src2)); 10197 10198 ins_cost(INSN_COST); 10199 format %{ "addw $dst, $src1, $src2" %} 10200 10201 // use opcode to indicate that this is an add not a sub 10202 opcode(0x0); 10203 10204 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10205 10206 ins_pipe(ialu_reg_imm); 10207 %} 10208 10209 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10210 match(Set dst (AddI (ConvL2I src1) src2)); 10211 10212 ins_cost(INSN_COST); 10213 format %{ "addw $dst, $src1, $src2" %} 10214 10215 // use opcode to indicate that this is an add not a sub 10216 opcode(0x0); 10217 10218 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10219 10220 ins_pipe(ialu_reg_imm); 10221 %} 10222 10223 // Pointer Addition 10224 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10225 match(Set dst (AddP src1 src2)); 10226 10227 ins_cost(INSN_COST); 10228 format %{ "add $dst, $src1, $src2\t# ptr" %} 10229 10230 ins_encode %{ 10231 __ add(as_Register($dst$$reg), 10232 as_Register($src1$$reg), 10233 as_Register($src2$$reg)); 10234 %} 10235 10236 ins_pipe(ialu_reg_reg); 10237 %} 10238 10239 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10240 match(Set dst (AddP src1 (ConvI2L src2))); 10241 10242 ins_cost(1.9 * INSN_COST); 10243 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10244 10245 ins_encode %{ 10246 __ add(as_Register($dst$$reg), 10247 as_Register($src1$$reg), 10248 as_Register($src2$$reg), ext::sxtw); 10249 %} 10250 10251 ins_pipe(ialu_reg_reg); 10252 %} 10253 10254 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10255 match(Set dst (AddP src1 (LShiftL src2 scale))); 10256 10257 ins_cost(1.9 * INSN_COST); 10258 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10259 10260 ins_encode %{ 10261 __ lea(as_Register($dst$$reg), 10262 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10263 Address::lsl($scale$$constant))); 10264 %} 10265 10266 ins_pipe(ialu_reg_reg_shift); 10267 %} 10268 10269 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10270 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10271 10272 ins_cost(1.9 * INSN_COST); 10273 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10274 10275 ins_encode %{ 10276 __ lea(as_Register($dst$$reg), 10277 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10278 Address::sxtw($scale$$constant))); 10279 %} 10280 10281 ins_pipe(ialu_reg_reg_shift); 10282 %} 10283 10284 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10285 match(Set dst (LShiftL (ConvI2L src) scale)); 10286 10287 ins_cost(INSN_COST); 10288 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10289 10290 ins_encode %{ 10291 __ sbfiz(as_Register($dst$$reg), 10292 as_Register($src$$reg), 10293 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 10294 %} 10295 10296 ins_pipe(ialu_reg_shift); 10297 %} 10298 10299 // Pointer Immediate Addition 10300 // n.b. this needs to be more expensive than using an indirect memory 10301 // operand 10302 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10303 match(Set dst (AddP src1 src2)); 10304 10305 ins_cost(INSN_COST); 10306 format %{ "add $dst, $src1, $src2\t# ptr" %} 10307 10308 // use opcode to indicate that this is an add not a sub 10309 opcode(0x0); 10310 10311 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10312 10313 ins_pipe(ialu_reg_imm); 10314 %} 10315 10316 // Long Addition 10317 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10318 10319 match(Set dst (AddL src1 src2)); 10320 10321 ins_cost(INSN_COST); 10322 format %{ "add $dst, $src1, $src2" %} 10323 10324 ins_encode %{ 10325 __ add(as_Register($dst$$reg), 10326 as_Register($src1$$reg), 10327 as_Register($src2$$reg)); 10328 %} 10329 10330 ins_pipe(ialu_reg_reg); 10331 %} 10332 10333 // No constant pool entries requiredLong Immediate Addition. 10334 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10335 match(Set dst (AddL src1 src2)); 10336 10337 ins_cost(INSN_COST); 10338 format %{ "add $dst, $src1, $src2" %} 10339 10340 // use opcode to indicate that this is an add not a sub 10341 opcode(0x0); 10342 10343 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10344 10345 ins_pipe(ialu_reg_imm); 10346 %} 10347 10348 // Integer Subtraction 10349 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10350 match(Set dst (SubI src1 src2)); 10351 10352 ins_cost(INSN_COST); 10353 format %{ "subw $dst, $src1, $src2" %} 10354 10355 ins_encode %{ 10356 __ subw(as_Register($dst$$reg), 10357 as_Register($src1$$reg), 10358 as_Register($src2$$reg)); 10359 %} 10360 10361 ins_pipe(ialu_reg_reg); 10362 %} 10363 10364 // Immediate Subtraction 10365 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10366 match(Set dst (SubI src1 src2)); 10367 10368 ins_cost(INSN_COST); 10369 format %{ "subw $dst, $src1, $src2" %} 10370 10371 // use opcode to indicate that this is a sub not an add 10372 opcode(0x1); 10373 10374 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10375 10376 ins_pipe(ialu_reg_imm); 10377 %} 10378 10379 // Long Subtraction 10380 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10381 10382 match(Set dst (SubL src1 src2)); 10383 10384 ins_cost(INSN_COST); 10385 format %{ "sub $dst, $src1, $src2" %} 10386 10387 ins_encode %{ 10388 __ sub(as_Register($dst$$reg), 10389 as_Register($src1$$reg), 10390 as_Register($src2$$reg)); 10391 %} 10392 10393 ins_pipe(ialu_reg_reg); 10394 %} 10395 10396 // No constant pool entries requiredLong Immediate Subtraction. 10397 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10398 match(Set dst (SubL src1 src2)); 10399 10400 ins_cost(INSN_COST); 10401 format %{ "sub$dst, $src1, $src2" %} 10402 10403 // use opcode to indicate that this is a sub not an add 10404 opcode(0x1); 10405 10406 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10407 10408 ins_pipe(ialu_reg_imm); 10409 %} 10410 10411 // Integer Negation (special case for sub) 10412 10413 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10414 match(Set dst (SubI zero src)); 10415 10416 ins_cost(INSN_COST); 10417 format %{ "negw $dst, $src\t# int" %} 10418 10419 ins_encode %{ 10420 __ negw(as_Register($dst$$reg), 10421 as_Register($src$$reg)); 10422 %} 10423 10424 ins_pipe(ialu_reg); 10425 %} 10426 10427 // Long Negation 10428 10429 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10430 match(Set dst (SubL zero src)); 10431 10432 ins_cost(INSN_COST); 10433 format %{ "neg $dst, $src\t# long" %} 10434 10435 ins_encode %{ 10436 __ neg(as_Register($dst$$reg), 10437 as_Register($src$$reg)); 10438 %} 10439 10440 ins_pipe(ialu_reg); 10441 %} 10442 10443 // Integer Multiply 10444 10445 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10446 match(Set dst (MulI src1 src2)); 10447 10448 ins_cost(INSN_COST * 3); 10449 format %{ "mulw $dst, $src1, $src2" %} 10450 10451 ins_encode %{ 10452 __ mulw(as_Register($dst$$reg), 10453 as_Register($src1$$reg), 10454 as_Register($src2$$reg)); 10455 %} 10456 10457 ins_pipe(imul_reg_reg); 10458 %} 10459 10460 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10461 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10462 10463 ins_cost(INSN_COST * 3); 10464 format %{ "smull $dst, $src1, $src2" %} 10465 10466 ins_encode %{ 10467 __ smull(as_Register($dst$$reg), 10468 as_Register($src1$$reg), 10469 as_Register($src2$$reg)); 10470 %} 10471 10472 ins_pipe(imul_reg_reg); 10473 %} 10474 10475 // Long Multiply 10476 10477 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10478 match(Set dst (MulL src1 src2)); 10479 10480 ins_cost(INSN_COST * 5); 10481 format %{ "mul $dst, $src1, $src2" %} 10482 10483 ins_encode %{ 10484 __ mul(as_Register($dst$$reg), 10485 as_Register($src1$$reg), 10486 as_Register($src2$$reg)); 10487 %} 10488 10489 ins_pipe(lmul_reg_reg); 10490 %} 10491 10492 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10493 %{ 10494 match(Set dst (MulHiL src1 src2)); 10495 10496 ins_cost(INSN_COST * 7); 10497 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10498 10499 ins_encode %{ 10500 __ smulh(as_Register($dst$$reg), 10501 as_Register($src1$$reg), 10502 as_Register($src2$$reg)); 10503 %} 10504 10505 ins_pipe(lmul_reg_reg); 10506 %} 10507 10508 // Combined Integer Multiply & Add/Sub 10509 10510 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10511 match(Set dst (AddI src3 (MulI src1 src2))); 10512 10513 ins_cost(INSN_COST * 3); 10514 format %{ "madd $dst, $src1, $src2, $src3" %} 10515 10516 ins_encode %{ 10517 __ maddw(as_Register($dst$$reg), 10518 as_Register($src1$$reg), 10519 as_Register($src2$$reg), 10520 as_Register($src3$$reg)); 10521 %} 10522 10523 ins_pipe(imac_reg_reg); 10524 %} 10525 10526 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10527 match(Set dst (SubI src3 (MulI src1 src2))); 10528 10529 ins_cost(INSN_COST * 3); 10530 format %{ "msub $dst, $src1, $src2, $src3" %} 10531 10532 ins_encode %{ 10533 __ msubw(as_Register($dst$$reg), 10534 as_Register($src1$$reg), 10535 as_Register($src2$$reg), 10536 as_Register($src3$$reg)); 10537 %} 10538 10539 ins_pipe(imac_reg_reg); 10540 %} 10541 10542 // Combined Integer Multiply & Neg 10543 10544 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10545 match(Set dst (MulI (SubI zero src1) src2)); 10546 match(Set dst (MulI src1 (SubI zero src2))); 10547 10548 ins_cost(INSN_COST * 3); 10549 format %{ "mneg $dst, $src1, $src2" %} 10550 10551 ins_encode %{ 10552 __ mnegw(as_Register($dst$$reg), 10553 as_Register($src1$$reg), 10554 as_Register($src2$$reg)); 10555 %} 10556 10557 ins_pipe(imac_reg_reg); 10558 %} 10559 10560 // Combined Long Multiply & Add/Sub 10561 10562 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10563 match(Set dst (AddL src3 (MulL src1 src2))); 10564 10565 ins_cost(INSN_COST * 5); 10566 format %{ "madd $dst, $src1, $src2, $src3" %} 10567 10568 ins_encode %{ 10569 __ madd(as_Register($dst$$reg), 10570 as_Register($src1$$reg), 10571 as_Register($src2$$reg), 10572 as_Register($src3$$reg)); 10573 %} 10574 10575 ins_pipe(lmac_reg_reg); 10576 %} 10577 10578 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10579 match(Set dst (SubL src3 (MulL src1 src2))); 10580 10581 ins_cost(INSN_COST * 5); 10582 format %{ "msub $dst, $src1, $src2, $src3" %} 10583 10584 ins_encode %{ 10585 __ msub(as_Register($dst$$reg), 10586 as_Register($src1$$reg), 10587 as_Register($src2$$reg), 10588 as_Register($src3$$reg)); 10589 %} 10590 10591 ins_pipe(lmac_reg_reg); 10592 %} 10593 10594 // Combined Long Multiply & Neg 10595 10596 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10597 match(Set dst (MulL (SubL zero src1) src2)); 10598 match(Set dst (MulL src1 (SubL zero src2))); 10599 10600 ins_cost(INSN_COST * 5); 10601 format %{ "mneg $dst, $src1, $src2" %} 10602 10603 ins_encode %{ 10604 __ mneg(as_Register($dst$$reg), 10605 as_Register($src1$$reg), 10606 as_Register($src2$$reg)); 10607 %} 10608 10609 ins_pipe(lmac_reg_reg); 10610 %} 10611 10612 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10613 10614 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10615 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10616 10617 ins_cost(INSN_COST * 3); 10618 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10619 10620 ins_encode %{ 10621 __ smaddl(as_Register($dst$$reg), 10622 as_Register($src1$$reg), 10623 as_Register($src2$$reg), 10624 as_Register($src3$$reg)); 10625 %} 10626 10627 ins_pipe(imac_reg_reg); 10628 %} 10629 10630 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10631 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10632 10633 ins_cost(INSN_COST * 3); 10634 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10635 10636 ins_encode %{ 10637 __ smsubl(as_Register($dst$$reg), 10638 as_Register($src1$$reg), 10639 as_Register($src2$$reg), 10640 as_Register($src3$$reg)); 10641 %} 10642 10643 ins_pipe(imac_reg_reg); 10644 %} 10645 10646 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10647 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10648 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10649 10650 ins_cost(INSN_COST * 3); 10651 format %{ "smnegl $dst, $src1, $src2" %} 10652 10653 ins_encode %{ 10654 __ smnegl(as_Register($dst$$reg), 10655 as_Register($src1$$reg), 10656 as_Register($src2$$reg)); 10657 %} 10658 10659 ins_pipe(imac_reg_reg); 10660 %} 10661 10662 // Integer Divide 10663 10664 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10665 match(Set dst (DivI src1 src2)); 10666 10667 ins_cost(INSN_COST * 19); 10668 format %{ "sdivw $dst, $src1, $src2" %} 10669 10670 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10671 ins_pipe(idiv_reg_reg); 10672 %} 10673 10674 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 10675 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 10676 ins_cost(INSN_COST); 10677 format %{ "lsrw $dst, $src1, $div1" %} 10678 ins_encode %{ 10679 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 10680 %} 10681 ins_pipe(ialu_reg_shift); 10682 %} 10683 10684 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 10685 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 10686 ins_cost(INSN_COST); 10687 format %{ "addw $dst, $src, LSR $div1" %} 10688 10689 ins_encode %{ 10690 __ addw(as_Register($dst$$reg), 10691 as_Register($src$$reg), 10692 as_Register($src$$reg), 10693 Assembler::LSR, 31); 10694 %} 10695 ins_pipe(ialu_reg); 10696 %} 10697 10698 // Long Divide 10699 10700 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10701 match(Set dst (DivL src1 src2)); 10702 10703 ins_cost(INSN_COST * 35); 10704 format %{ "sdiv $dst, $src1, $src2" %} 10705 10706 ins_encode(aarch64_enc_div(dst, src1, src2)); 10707 ins_pipe(ldiv_reg_reg); 10708 %} 10709 10710 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 10711 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 10712 ins_cost(INSN_COST); 10713 format %{ "lsr $dst, $src1, $div1" %} 10714 ins_encode %{ 10715 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 10716 %} 10717 ins_pipe(ialu_reg_shift); 10718 %} 10719 10720 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 10721 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 10722 ins_cost(INSN_COST); 10723 format %{ "add $dst, $src, $div1" %} 10724 10725 ins_encode %{ 10726 __ add(as_Register($dst$$reg), 10727 as_Register($src$$reg), 10728 as_Register($src$$reg), 10729 Assembler::LSR, 63); 10730 %} 10731 ins_pipe(ialu_reg); 10732 %} 10733 10734 // Integer Remainder 10735 10736 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10737 match(Set dst (ModI src1 src2)); 10738 10739 ins_cost(INSN_COST * 22); 10740 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10741 "msubw($dst, rscratch1, $src2, $src1" %} 10742 10743 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10744 ins_pipe(idiv_reg_reg); 10745 %} 10746 10747 // Long Remainder 10748 10749 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10750 match(Set dst (ModL src1 src2)); 10751 10752 ins_cost(INSN_COST * 38); 10753 format %{ "sdiv rscratch1, $src1, $src2\n" 10754 "msub($dst, rscratch1, $src2, $src1" %} 10755 10756 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10757 ins_pipe(ldiv_reg_reg); 10758 %} 10759 10760 // Integer Shifts 10761 10762 // Shift Left Register 10763 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10764 match(Set dst (LShiftI src1 src2)); 10765 10766 ins_cost(INSN_COST * 2); 10767 format %{ "lslvw $dst, $src1, $src2" %} 10768 10769 ins_encode %{ 10770 __ lslvw(as_Register($dst$$reg), 10771 as_Register($src1$$reg), 10772 as_Register($src2$$reg)); 10773 %} 10774 10775 ins_pipe(ialu_reg_reg_vshift); 10776 %} 10777 10778 // Shift Left Immediate 10779 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10780 match(Set dst (LShiftI src1 src2)); 10781 10782 ins_cost(INSN_COST); 10783 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10784 10785 ins_encode %{ 10786 __ lslw(as_Register($dst$$reg), 10787 as_Register($src1$$reg), 10788 $src2$$constant & 0x1f); 10789 %} 10790 10791 ins_pipe(ialu_reg_shift); 10792 %} 10793 10794 // Shift Right Logical Register 10795 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10796 match(Set dst (URShiftI src1 src2)); 10797 10798 ins_cost(INSN_COST * 2); 10799 format %{ "lsrvw $dst, $src1, $src2" %} 10800 10801 ins_encode %{ 10802 __ lsrvw(as_Register($dst$$reg), 10803 as_Register($src1$$reg), 10804 as_Register($src2$$reg)); 10805 %} 10806 10807 ins_pipe(ialu_reg_reg_vshift); 10808 %} 10809 10810 // Shift Right Logical Immediate 10811 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10812 match(Set dst (URShiftI src1 src2)); 10813 10814 ins_cost(INSN_COST); 10815 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10816 10817 ins_encode %{ 10818 __ lsrw(as_Register($dst$$reg), 10819 as_Register($src1$$reg), 10820 $src2$$constant & 0x1f); 10821 %} 10822 10823 ins_pipe(ialu_reg_shift); 10824 %} 10825 10826 // Shift Right Arithmetic Register 10827 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10828 match(Set dst (RShiftI src1 src2)); 10829 10830 ins_cost(INSN_COST * 2); 10831 format %{ "asrvw $dst, $src1, $src2" %} 10832 10833 ins_encode %{ 10834 __ asrvw(as_Register($dst$$reg), 10835 as_Register($src1$$reg), 10836 as_Register($src2$$reg)); 10837 %} 10838 10839 ins_pipe(ialu_reg_reg_vshift); 10840 %} 10841 10842 // Shift Right Arithmetic Immediate 10843 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10844 match(Set dst (RShiftI src1 src2)); 10845 10846 ins_cost(INSN_COST); 10847 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10848 10849 ins_encode %{ 10850 __ asrw(as_Register($dst$$reg), 10851 as_Register($src1$$reg), 10852 $src2$$constant & 0x1f); 10853 %} 10854 10855 ins_pipe(ialu_reg_shift); 10856 %} 10857 10858 // Combined Int Mask and Right Shift (using UBFM) 10859 // TODO 10860 10861 // Long Shifts 10862 10863 // Shift Left Register 10864 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10865 match(Set dst (LShiftL src1 src2)); 10866 10867 ins_cost(INSN_COST * 2); 10868 format %{ "lslv $dst, $src1, $src2" %} 10869 10870 ins_encode %{ 10871 __ lslv(as_Register($dst$$reg), 10872 as_Register($src1$$reg), 10873 as_Register($src2$$reg)); 10874 %} 10875 10876 ins_pipe(ialu_reg_reg_vshift); 10877 %} 10878 10879 // Shift Left Immediate 10880 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10881 match(Set dst (LShiftL src1 src2)); 10882 10883 ins_cost(INSN_COST); 10884 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10885 10886 ins_encode %{ 10887 __ lsl(as_Register($dst$$reg), 10888 as_Register($src1$$reg), 10889 $src2$$constant & 0x3f); 10890 %} 10891 10892 ins_pipe(ialu_reg_shift); 10893 %} 10894 10895 // Shift Right Logical Register 10896 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10897 match(Set dst (URShiftL src1 src2)); 10898 10899 ins_cost(INSN_COST * 2); 10900 format %{ "lsrv $dst, $src1, $src2" %} 10901 10902 ins_encode %{ 10903 __ lsrv(as_Register($dst$$reg), 10904 as_Register($src1$$reg), 10905 as_Register($src2$$reg)); 10906 %} 10907 10908 ins_pipe(ialu_reg_reg_vshift); 10909 %} 10910 10911 // Shift Right Logical Immediate 10912 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10913 match(Set dst (URShiftL src1 src2)); 10914 10915 ins_cost(INSN_COST); 10916 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10917 10918 ins_encode %{ 10919 __ lsr(as_Register($dst$$reg), 10920 as_Register($src1$$reg), 10921 $src2$$constant & 0x3f); 10922 %} 10923 10924 ins_pipe(ialu_reg_shift); 10925 %} 10926 10927 // A special-case pattern for card table stores. 10928 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10929 match(Set dst (URShiftL (CastP2X src1) src2)); 10930 10931 ins_cost(INSN_COST); 10932 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10933 10934 ins_encode %{ 10935 __ lsr(as_Register($dst$$reg), 10936 as_Register($src1$$reg), 10937 $src2$$constant & 0x3f); 10938 %} 10939 10940 ins_pipe(ialu_reg_shift); 10941 %} 10942 10943 // Shift Right Arithmetic Register 10944 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10945 match(Set dst (RShiftL src1 src2)); 10946 10947 ins_cost(INSN_COST * 2); 10948 format %{ "asrv $dst, $src1, $src2" %} 10949 10950 ins_encode %{ 10951 __ asrv(as_Register($dst$$reg), 10952 as_Register($src1$$reg), 10953 as_Register($src2$$reg)); 10954 %} 10955 10956 ins_pipe(ialu_reg_reg_vshift); 10957 %} 10958 10959 // Shift Right Arithmetic Immediate 10960 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10961 match(Set dst (RShiftL src1 src2)); 10962 10963 ins_cost(INSN_COST); 10964 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10965 10966 ins_encode %{ 10967 __ asr(as_Register($dst$$reg), 10968 as_Register($src1$$reg), 10969 $src2$$constant & 0x3f); 10970 %} 10971 10972 ins_pipe(ialu_reg_shift); 10973 %} 10974 10975 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10976 10977 instruct regL_not_reg(iRegLNoSp dst, 10978 iRegL src1, immL_M1 m1, 10979 rFlagsReg cr) %{ 10980 match(Set dst (XorL src1 m1)); 10981 ins_cost(INSN_COST); 10982 format %{ "eon $dst, $src1, zr" %} 10983 10984 ins_encode %{ 10985 __ eon(as_Register($dst$$reg), 10986 as_Register($src1$$reg), 10987 zr, 10988 Assembler::LSL, 0); 10989 %} 10990 10991 ins_pipe(ialu_reg); 10992 %} 10993 instruct regI_not_reg(iRegINoSp dst, 10994 iRegIorL2I src1, immI_M1 m1, 10995 rFlagsReg cr) %{ 10996 match(Set dst (XorI src1 m1)); 10997 ins_cost(INSN_COST); 10998 format %{ "eonw $dst, $src1, zr" %} 10999 11000 ins_encode %{ 11001 __ eonw(as_Register($dst$$reg), 11002 as_Register($src1$$reg), 11003 zr, 11004 Assembler::LSL, 0); 11005 %} 11006 11007 ins_pipe(ialu_reg); 11008 %} 11009 11010 instruct AndI_reg_not_reg(iRegINoSp dst, 11011 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 11012 rFlagsReg cr) %{ 11013 match(Set dst (AndI src1 (XorI src2 m1))); 11014 ins_cost(INSN_COST); 11015 format %{ "bicw $dst, $src1, $src2" %} 11016 11017 ins_encode %{ 11018 __ bicw(as_Register($dst$$reg), 11019 as_Register($src1$$reg), 11020 as_Register($src2$$reg), 11021 Assembler::LSL, 0); 11022 %} 11023 11024 ins_pipe(ialu_reg_reg); 11025 %} 11026 11027 instruct AndL_reg_not_reg(iRegLNoSp dst, 11028 iRegL src1, iRegL src2, immL_M1 m1, 11029 rFlagsReg cr) %{ 11030 match(Set dst (AndL src1 (XorL src2 m1))); 11031 ins_cost(INSN_COST); 11032 format %{ "bic $dst, $src1, $src2" %} 11033 11034 ins_encode %{ 11035 __ bic(as_Register($dst$$reg), 11036 as_Register($src1$$reg), 11037 as_Register($src2$$reg), 11038 Assembler::LSL, 0); 11039 %} 11040 11041 ins_pipe(ialu_reg_reg); 11042 %} 11043 11044 instruct OrI_reg_not_reg(iRegINoSp dst, 11045 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 11046 rFlagsReg cr) %{ 11047 match(Set dst (OrI src1 (XorI src2 m1))); 11048 ins_cost(INSN_COST); 11049 format %{ "ornw $dst, $src1, $src2" %} 11050 11051 ins_encode %{ 11052 __ ornw(as_Register($dst$$reg), 11053 as_Register($src1$$reg), 11054 as_Register($src2$$reg), 11055 Assembler::LSL, 0); 11056 %} 11057 11058 ins_pipe(ialu_reg_reg); 11059 %} 11060 11061 instruct OrL_reg_not_reg(iRegLNoSp dst, 11062 iRegL src1, iRegL src2, immL_M1 m1, 11063 rFlagsReg cr) %{ 11064 match(Set dst (OrL src1 (XorL src2 m1))); 11065 ins_cost(INSN_COST); 11066 format %{ "orn $dst, $src1, $src2" %} 11067 11068 ins_encode %{ 11069 __ orn(as_Register($dst$$reg), 11070 as_Register($src1$$reg), 11071 as_Register($src2$$reg), 11072 Assembler::LSL, 0); 11073 %} 11074 11075 ins_pipe(ialu_reg_reg); 11076 %} 11077 11078 instruct XorI_reg_not_reg(iRegINoSp dst, 11079 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 11080 rFlagsReg cr) %{ 11081 match(Set dst (XorI m1 (XorI src2 src1))); 11082 ins_cost(INSN_COST); 11083 format %{ "eonw $dst, $src1, $src2" %} 11084 11085 ins_encode %{ 11086 __ eonw(as_Register($dst$$reg), 11087 as_Register($src1$$reg), 11088 as_Register($src2$$reg), 11089 Assembler::LSL, 0); 11090 %} 11091 11092 ins_pipe(ialu_reg_reg); 11093 %} 11094 11095 instruct XorL_reg_not_reg(iRegLNoSp dst, 11096 iRegL src1, iRegL src2, immL_M1 m1, 11097 rFlagsReg cr) %{ 11098 match(Set dst (XorL m1 (XorL src2 src1))); 11099 ins_cost(INSN_COST); 11100 format %{ "eon $dst, $src1, $src2" %} 11101 11102 ins_encode %{ 11103 __ eon(as_Register($dst$$reg), 11104 as_Register($src1$$reg), 11105 as_Register($src2$$reg), 11106 Assembler::LSL, 0); 11107 %} 11108 11109 ins_pipe(ialu_reg_reg); 11110 %} 11111 11112 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11113 iRegIorL2I src1, iRegIorL2I src2, 11114 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11115 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11116 ins_cost(1.9 * INSN_COST); 11117 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11118 11119 ins_encode %{ 11120 __ bicw(as_Register($dst$$reg), 11121 as_Register($src1$$reg), 11122 as_Register($src2$$reg), 11123 Assembler::LSR, 11124 $src3$$constant & 0x1f); 11125 %} 11126 11127 ins_pipe(ialu_reg_reg_shift); 11128 %} 11129 11130 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11131 iRegL src1, iRegL src2, 11132 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11133 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11134 ins_cost(1.9 * INSN_COST); 11135 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11136 11137 ins_encode %{ 11138 __ bic(as_Register($dst$$reg), 11139 as_Register($src1$$reg), 11140 as_Register($src2$$reg), 11141 Assembler::LSR, 11142 $src3$$constant & 0x3f); 11143 %} 11144 11145 ins_pipe(ialu_reg_reg_shift); 11146 %} 11147 11148 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11149 iRegIorL2I src1, iRegIorL2I src2, 11150 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11151 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11152 ins_cost(1.9 * INSN_COST); 11153 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11154 11155 ins_encode %{ 11156 __ bicw(as_Register($dst$$reg), 11157 as_Register($src1$$reg), 11158 as_Register($src2$$reg), 11159 Assembler::ASR, 11160 $src3$$constant & 0x1f); 11161 %} 11162 11163 ins_pipe(ialu_reg_reg_shift); 11164 %} 11165 11166 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11167 iRegL src1, iRegL src2, 11168 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11169 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11170 ins_cost(1.9 * INSN_COST); 11171 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11172 11173 ins_encode %{ 11174 __ bic(as_Register($dst$$reg), 11175 as_Register($src1$$reg), 11176 as_Register($src2$$reg), 11177 Assembler::ASR, 11178 $src3$$constant & 0x3f); 11179 %} 11180 11181 ins_pipe(ialu_reg_reg_shift); 11182 %} 11183 11184 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11185 iRegIorL2I src1, iRegIorL2I src2, 11186 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11187 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11188 ins_cost(1.9 * INSN_COST); 11189 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11190 11191 ins_encode %{ 11192 __ bicw(as_Register($dst$$reg), 11193 as_Register($src1$$reg), 11194 as_Register($src2$$reg), 11195 Assembler::LSL, 11196 $src3$$constant & 0x1f); 11197 %} 11198 11199 ins_pipe(ialu_reg_reg_shift); 11200 %} 11201 11202 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11203 iRegL src1, iRegL src2, 11204 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11205 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11206 ins_cost(1.9 * INSN_COST); 11207 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11208 11209 ins_encode %{ 11210 __ bic(as_Register($dst$$reg), 11211 as_Register($src1$$reg), 11212 as_Register($src2$$reg), 11213 Assembler::LSL, 11214 $src3$$constant & 0x3f); 11215 %} 11216 11217 ins_pipe(ialu_reg_reg_shift); 11218 %} 11219 11220 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11221 iRegIorL2I src1, iRegIorL2I src2, 11222 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11223 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11224 ins_cost(1.9 * INSN_COST); 11225 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11226 11227 ins_encode %{ 11228 __ eonw(as_Register($dst$$reg), 11229 as_Register($src1$$reg), 11230 as_Register($src2$$reg), 11231 Assembler::LSR, 11232 $src3$$constant & 0x1f); 11233 %} 11234 11235 ins_pipe(ialu_reg_reg_shift); 11236 %} 11237 11238 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11239 iRegL src1, iRegL src2, 11240 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11241 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11242 ins_cost(1.9 * INSN_COST); 11243 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11244 11245 ins_encode %{ 11246 __ eon(as_Register($dst$$reg), 11247 as_Register($src1$$reg), 11248 as_Register($src2$$reg), 11249 Assembler::LSR, 11250 $src3$$constant & 0x3f); 11251 %} 11252 11253 ins_pipe(ialu_reg_reg_shift); 11254 %} 11255 11256 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11257 iRegIorL2I src1, iRegIorL2I src2, 11258 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11259 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11260 ins_cost(1.9 * INSN_COST); 11261 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11262 11263 ins_encode %{ 11264 __ eonw(as_Register($dst$$reg), 11265 as_Register($src1$$reg), 11266 as_Register($src2$$reg), 11267 Assembler::ASR, 11268 $src3$$constant & 0x1f); 11269 %} 11270 11271 ins_pipe(ialu_reg_reg_shift); 11272 %} 11273 11274 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11275 iRegL src1, iRegL src2, 11276 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11277 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11278 ins_cost(1.9 * INSN_COST); 11279 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11280 11281 ins_encode %{ 11282 __ eon(as_Register($dst$$reg), 11283 as_Register($src1$$reg), 11284 as_Register($src2$$reg), 11285 Assembler::ASR, 11286 $src3$$constant & 0x3f); 11287 %} 11288 11289 ins_pipe(ialu_reg_reg_shift); 11290 %} 11291 11292 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11293 iRegIorL2I src1, iRegIorL2I src2, 11294 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11295 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11296 ins_cost(1.9 * INSN_COST); 11297 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11298 11299 ins_encode %{ 11300 __ eonw(as_Register($dst$$reg), 11301 as_Register($src1$$reg), 11302 as_Register($src2$$reg), 11303 Assembler::LSL, 11304 $src3$$constant & 0x1f); 11305 %} 11306 11307 ins_pipe(ialu_reg_reg_shift); 11308 %} 11309 11310 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11311 iRegL src1, iRegL src2, 11312 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11313 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11314 ins_cost(1.9 * INSN_COST); 11315 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11316 11317 ins_encode %{ 11318 __ eon(as_Register($dst$$reg), 11319 as_Register($src1$$reg), 11320 as_Register($src2$$reg), 11321 Assembler::LSL, 11322 $src3$$constant & 0x3f); 11323 %} 11324 11325 ins_pipe(ialu_reg_reg_shift); 11326 %} 11327 11328 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11329 iRegIorL2I src1, iRegIorL2I src2, 11330 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11331 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11332 ins_cost(1.9 * INSN_COST); 11333 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11334 11335 ins_encode %{ 11336 __ ornw(as_Register($dst$$reg), 11337 as_Register($src1$$reg), 11338 as_Register($src2$$reg), 11339 Assembler::LSR, 11340 $src3$$constant & 0x1f); 11341 %} 11342 11343 ins_pipe(ialu_reg_reg_shift); 11344 %} 11345 11346 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11347 iRegL src1, iRegL src2, 11348 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11349 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11350 ins_cost(1.9 * INSN_COST); 11351 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11352 11353 ins_encode %{ 11354 __ orn(as_Register($dst$$reg), 11355 as_Register($src1$$reg), 11356 as_Register($src2$$reg), 11357 Assembler::LSR, 11358 $src3$$constant & 0x3f); 11359 %} 11360 11361 ins_pipe(ialu_reg_reg_shift); 11362 %} 11363 11364 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11365 iRegIorL2I src1, iRegIorL2I src2, 11366 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11367 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11368 ins_cost(1.9 * INSN_COST); 11369 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11370 11371 ins_encode %{ 11372 __ ornw(as_Register($dst$$reg), 11373 as_Register($src1$$reg), 11374 as_Register($src2$$reg), 11375 Assembler::ASR, 11376 $src3$$constant & 0x1f); 11377 %} 11378 11379 ins_pipe(ialu_reg_reg_shift); 11380 %} 11381 11382 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11383 iRegL src1, iRegL src2, 11384 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11385 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11386 ins_cost(1.9 * INSN_COST); 11387 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11388 11389 ins_encode %{ 11390 __ orn(as_Register($dst$$reg), 11391 as_Register($src1$$reg), 11392 as_Register($src2$$reg), 11393 Assembler::ASR, 11394 $src3$$constant & 0x3f); 11395 %} 11396 11397 ins_pipe(ialu_reg_reg_shift); 11398 %} 11399 11400 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11401 iRegIorL2I src1, iRegIorL2I src2, 11402 immI src3, immI_M1 src4, rFlagsReg cr) %{ 11403 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11404 ins_cost(1.9 * INSN_COST); 11405 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11406 11407 ins_encode %{ 11408 __ ornw(as_Register($dst$$reg), 11409 as_Register($src1$$reg), 11410 as_Register($src2$$reg), 11411 Assembler::LSL, 11412 $src3$$constant & 0x1f); 11413 %} 11414 11415 ins_pipe(ialu_reg_reg_shift); 11416 %} 11417 11418 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11419 iRegL src1, iRegL src2, 11420 immI src3, immL_M1 src4, rFlagsReg cr) %{ 11421 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11422 ins_cost(1.9 * INSN_COST); 11423 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11424 11425 ins_encode %{ 11426 __ orn(as_Register($dst$$reg), 11427 as_Register($src1$$reg), 11428 as_Register($src2$$reg), 11429 Assembler::LSL, 11430 $src3$$constant & 0x3f); 11431 %} 11432 11433 ins_pipe(ialu_reg_reg_shift); 11434 %} 11435 11436 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11437 iRegIorL2I src1, iRegIorL2I src2, 11438 immI src3, rFlagsReg cr) %{ 11439 match(Set dst (AndI src1 (URShiftI src2 src3))); 11440 11441 ins_cost(1.9 * INSN_COST); 11442 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11443 11444 ins_encode %{ 11445 __ andw(as_Register($dst$$reg), 11446 as_Register($src1$$reg), 11447 as_Register($src2$$reg), 11448 Assembler::LSR, 11449 $src3$$constant & 0x1f); 11450 %} 11451 11452 ins_pipe(ialu_reg_reg_shift); 11453 %} 11454 11455 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11456 iRegL src1, iRegL src2, 11457 immI src3, rFlagsReg cr) %{ 11458 match(Set dst (AndL src1 (URShiftL src2 src3))); 11459 11460 ins_cost(1.9 * INSN_COST); 11461 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11462 11463 ins_encode %{ 11464 __ andr(as_Register($dst$$reg), 11465 as_Register($src1$$reg), 11466 as_Register($src2$$reg), 11467 Assembler::LSR, 11468 $src3$$constant & 0x3f); 11469 %} 11470 11471 ins_pipe(ialu_reg_reg_shift); 11472 %} 11473 11474 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11475 iRegIorL2I src1, iRegIorL2I src2, 11476 immI src3, rFlagsReg cr) %{ 11477 match(Set dst (AndI src1 (RShiftI src2 src3))); 11478 11479 ins_cost(1.9 * INSN_COST); 11480 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11481 11482 ins_encode %{ 11483 __ andw(as_Register($dst$$reg), 11484 as_Register($src1$$reg), 11485 as_Register($src2$$reg), 11486 Assembler::ASR, 11487 $src3$$constant & 0x1f); 11488 %} 11489 11490 ins_pipe(ialu_reg_reg_shift); 11491 %} 11492 11493 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11494 iRegL src1, iRegL src2, 11495 immI src3, rFlagsReg cr) %{ 11496 match(Set dst (AndL src1 (RShiftL src2 src3))); 11497 11498 ins_cost(1.9 * INSN_COST); 11499 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11500 11501 ins_encode %{ 11502 __ andr(as_Register($dst$$reg), 11503 as_Register($src1$$reg), 11504 as_Register($src2$$reg), 11505 Assembler::ASR, 11506 $src3$$constant & 0x3f); 11507 %} 11508 11509 ins_pipe(ialu_reg_reg_shift); 11510 %} 11511 11512 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11513 iRegIorL2I src1, iRegIorL2I src2, 11514 immI src3, rFlagsReg cr) %{ 11515 match(Set dst (AndI src1 (LShiftI src2 src3))); 11516 11517 ins_cost(1.9 * INSN_COST); 11518 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11519 11520 ins_encode %{ 11521 __ andw(as_Register($dst$$reg), 11522 as_Register($src1$$reg), 11523 as_Register($src2$$reg), 11524 Assembler::LSL, 11525 $src3$$constant & 0x1f); 11526 %} 11527 11528 ins_pipe(ialu_reg_reg_shift); 11529 %} 11530 11531 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 11532 iRegL src1, iRegL src2, 11533 immI src3, rFlagsReg cr) %{ 11534 match(Set dst (AndL src1 (LShiftL src2 src3))); 11535 11536 ins_cost(1.9 * INSN_COST); 11537 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 11538 11539 ins_encode %{ 11540 __ andr(as_Register($dst$$reg), 11541 as_Register($src1$$reg), 11542 as_Register($src2$$reg), 11543 Assembler::LSL, 11544 $src3$$constant & 0x3f); 11545 %} 11546 11547 ins_pipe(ialu_reg_reg_shift); 11548 %} 11549 11550 instruct XorI_reg_URShift_reg(iRegINoSp dst, 11551 iRegIorL2I src1, iRegIorL2I src2, 11552 immI src3, rFlagsReg cr) %{ 11553 match(Set dst (XorI src1 (URShiftI src2 src3))); 11554 11555 ins_cost(1.9 * INSN_COST); 11556 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 11557 11558 ins_encode %{ 11559 __ eorw(as_Register($dst$$reg), 11560 as_Register($src1$$reg), 11561 as_Register($src2$$reg), 11562 Assembler::LSR, 11563 $src3$$constant & 0x1f); 11564 %} 11565 11566 ins_pipe(ialu_reg_reg_shift); 11567 %} 11568 11569 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 11570 iRegL src1, iRegL src2, 11571 immI src3, rFlagsReg cr) %{ 11572 match(Set dst (XorL src1 (URShiftL src2 src3))); 11573 11574 ins_cost(1.9 * INSN_COST); 11575 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 11576 11577 ins_encode %{ 11578 __ eor(as_Register($dst$$reg), 11579 as_Register($src1$$reg), 11580 as_Register($src2$$reg), 11581 Assembler::LSR, 11582 $src3$$constant & 0x3f); 11583 %} 11584 11585 ins_pipe(ialu_reg_reg_shift); 11586 %} 11587 11588 instruct XorI_reg_RShift_reg(iRegINoSp dst, 11589 iRegIorL2I src1, iRegIorL2I src2, 11590 immI src3, rFlagsReg cr) %{ 11591 match(Set dst (XorI src1 (RShiftI src2 src3))); 11592 11593 ins_cost(1.9 * INSN_COST); 11594 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 11595 11596 ins_encode %{ 11597 __ eorw(as_Register($dst$$reg), 11598 as_Register($src1$$reg), 11599 as_Register($src2$$reg), 11600 Assembler::ASR, 11601 $src3$$constant & 0x1f); 11602 %} 11603 11604 ins_pipe(ialu_reg_reg_shift); 11605 %} 11606 11607 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 11608 iRegL src1, iRegL src2, 11609 immI src3, rFlagsReg cr) %{ 11610 match(Set dst (XorL src1 (RShiftL src2 src3))); 11611 11612 ins_cost(1.9 * INSN_COST); 11613 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 11614 11615 ins_encode %{ 11616 __ eor(as_Register($dst$$reg), 11617 as_Register($src1$$reg), 11618 as_Register($src2$$reg), 11619 Assembler::ASR, 11620 $src3$$constant & 0x3f); 11621 %} 11622 11623 ins_pipe(ialu_reg_reg_shift); 11624 %} 11625 11626 instruct XorI_reg_LShift_reg(iRegINoSp dst, 11627 iRegIorL2I src1, iRegIorL2I src2, 11628 immI src3, rFlagsReg cr) %{ 11629 match(Set dst (XorI src1 (LShiftI src2 src3))); 11630 11631 ins_cost(1.9 * INSN_COST); 11632 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 11633 11634 ins_encode %{ 11635 __ eorw(as_Register($dst$$reg), 11636 as_Register($src1$$reg), 11637 as_Register($src2$$reg), 11638 Assembler::LSL, 11639 $src3$$constant & 0x1f); 11640 %} 11641 11642 ins_pipe(ialu_reg_reg_shift); 11643 %} 11644 11645 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11646 iRegL src1, iRegL src2, 11647 immI src3, rFlagsReg cr) %{ 11648 match(Set dst (XorL src1 (LShiftL src2 src3))); 11649 11650 ins_cost(1.9 * INSN_COST); 11651 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11652 11653 ins_encode %{ 11654 __ eor(as_Register($dst$$reg), 11655 as_Register($src1$$reg), 11656 as_Register($src2$$reg), 11657 Assembler::LSL, 11658 $src3$$constant & 0x3f); 11659 %} 11660 11661 ins_pipe(ialu_reg_reg_shift); 11662 %} 11663 11664 instruct OrI_reg_URShift_reg(iRegINoSp dst, 11665 iRegIorL2I src1, iRegIorL2I src2, 11666 immI src3, rFlagsReg cr) %{ 11667 match(Set dst (OrI src1 (URShiftI src2 src3))); 11668 11669 ins_cost(1.9 * INSN_COST); 11670 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11671 11672 ins_encode %{ 11673 __ orrw(as_Register($dst$$reg), 11674 as_Register($src1$$reg), 11675 as_Register($src2$$reg), 11676 Assembler::LSR, 11677 $src3$$constant & 0x1f); 11678 %} 11679 11680 ins_pipe(ialu_reg_reg_shift); 11681 %} 11682 11683 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11684 iRegL src1, iRegL src2, 11685 immI src3, rFlagsReg cr) %{ 11686 match(Set dst (OrL src1 (URShiftL src2 src3))); 11687 11688 ins_cost(1.9 * INSN_COST); 11689 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11690 11691 ins_encode %{ 11692 __ orr(as_Register($dst$$reg), 11693 as_Register($src1$$reg), 11694 as_Register($src2$$reg), 11695 Assembler::LSR, 11696 $src3$$constant & 0x3f); 11697 %} 11698 11699 ins_pipe(ialu_reg_reg_shift); 11700 %} 11701 11702 instruct OrI_reg_RShift_reg(iRegINoSp dst, 11703 iRegIorL2I src1, iRegIorL2I src2, 11704 immI src3, rFlagsReg cr) %{ 11705 match(Set dst (OrI src1 (RShiftI src2 src3))); 11706 11707 ins_cost(1.9 * INSN_COST); 11708 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11709 11710 ins_encode %{ 11711 __ orrw(as_Register($dst$$reg), 11712 as_Register($src1$$reg), 11713 as_Register($src2$$reg), 11714 Assembler::ASR, 11715 $src3$$constant & 0x1f); 11716 %} 11717 11718 ins_pipe(ialu_reg_reg_shift); 11719 %} 11720 11721 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11722 iRegL src1, iRegL src2, 11723 immI src3, rFlagsReg cr) %{ 11724 match(Set dst (OrL src1 (RShiftL src2 src3))); 11725 11726 ins_cost(1.9 * INSN_COST); 11727 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11728 11729 ins_encode %{ 11730 __ orr(as_Register($dst$$reg), 11731 as_Register($src1$$reg), 11732 as_Register($src2$$reg), 11733 Assembler::ASR, 11734 $src3$$constant & 0x3f); 11735 %} 11736 11737 ins_pipe(ialu_reg_reg_shift); 11738 %} 11739 11740 instruct OrI_reg_LShift_reg(iRegINoSp dst, 11741 iRegIorL2I src1, iRegIorL2I src2, 11742 immI src3, rFlagsReg cr) %{ 11743 match(Set dst (OrI src1 (LShiftI src2 src3))); 11744 11745 ins_cost(1.9 * INSN_COST); 11746 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11747 11748 ins_encode %{ 11749 __ orrw(as_Register($dst$$reg), 11750 as_Register($src1$$reg), 11751 as_Register($src2$$reg), 11752 Assembler::LSL, 11753 $src3$$constant & 0x1f); 11754 %} 11755 11756 ins_pipe(ialu_reg_reg_shift); 11757 %} 11758 11759 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11760 iRegL src1, iRegL src2, 11761 immI src3, rFlagsReg cr) %{ 11762 match(Set dst (OrL src1 (LShiftL src2 src3))); 11763 11764 ins_cost(1.9 * INSN_COST); 11765 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11766 11767 ins_encode %{ 11768 __ orr(as_Register($dst$$reg), 11769 as_Register($src1$$reg), 11770 as_Register($src2$$reg), 11771 Assembler::LSL, 11772 $src3$$constant & 0x3f); 11773 %} 11774 11775 ins_pipe(ialu_reg_reg_shift); 11776 %} 11777 11778 instruct AddI_reg_URShift_reg(iRegINoSp dst, 11779 iRegIorL2I src1, iRegIorL2I src2, 11780 immI src3, rFlagsReg cr) %{ 11781 match(Set dst (AddI src1 (URShiftI src2 src3))); 11782 11783 ins_cost(1.9 * INSN_COST); 11784 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11785 11786 ins_encode %{ 11787 __ addw(as_Register($dst$$reg), 11788 as_Register($src1$$reg), 11789 as_Register($src2$$reg), 11790 Assembler::LSR, 11791 $src3$$constant & 0x1f); 11792 %} 11793 11794 ins_pipe(ialu_reg_reg_shift); 11795 %} 11796 11797 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11798 iRegL src1, iRegL src2, 11799 immI src3, rFlagsReg cr) %{ 11800 match(Set dst (AddL src1 (URShiftL src2 src3))); 11801 11802 ins_cost(1.9 * INSN_COST); 11803 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11804 11805 ins_encode %{ 11806 __ add(as_Register($dst$$reg), 11807 as_Register($src1$$reg), 11808 as_Register($src2$$reg), 11809 Assembler::LSR, 11810 $src3$$constant & 0x3f); 11811 %} 11812 11813 ins_pipe(ialu_reg_reg_shift); 11814 %} 11815 11816 instruct AddI_reg_RShift_reg(iRegINoSp dst, 11817 iRegIorL2I src1, iRegIorL2I src2, 11818 immI src3, rFlagsReg cr) %{ 11819 match(Set dst (AddI src1 (RShiftI src2 src3))); 11820 11821 ins_cost(1.9 * INSN_COST); 11822 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11823 11824 ins_encode %{ 11825 __ addw(as_Register($dst$$reg), 11826 as_Register($src1$$reg), 11827 as_Register($src2$$reg), 11828 Assembler::ASR, 11829 $src3$$constant & 0x1f); 11830 %} 11831 11832 ins_pipe(ialu_reg_reg_shift); 11833 %} 11834 11835 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11836 iRegL src1, iRegL src2, 11837 immI src3, rFlagsReg cr) %{ 11838 match(Set dst (AddL src1 (RShiftL src2 src3))); 11839 11840 ins_cost(1.9 * INSN_COST); 11841 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11842 11843 ins_encode %{ 11844 __ add(as_Register($dst$$reg), 11845 as_Register($src1$$reg), 11846 as_Register($src2$$reg), 11847 Assembler::ASR, 11848 $src3$$constant & 0x3f); 11849 %} 11850 11851 ins_pipe(ialu_reg_reg_shift); 11852 %} 11853 11854 instruct AddI_reg_LShift_reg(iRegINoSp dst, 11855 iRegIorL2I src1, iRegIorL2I src2, 11856 immI src3, rFlagsReg cr) %{ 11857 match(Set dst (AddI src1 (LShiftI src2 src3))); 11858 11859 ins_cost(1.9 * INSN_COST); 11860 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11861 11862 ins_encode %{ 11863 __ addw(as_Register($dst$$reg), 11864 as_Register($src1$$reg), 11865 as_Register($src2$$reg), 11866 Assembler::LSL, 11867 $src3$$constant & 0x1f); 11868 %} 11869 11870 ins_pipe(ialu_reg_reg_shift); 11871 %} 11872 11873 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11874 iRegL src1, iRegL src2, 11875 immI src3, rFlagsReg cr) %{ 11876 match(Set dst (AddL src1 (LShiftL src2 src3))); 11877 11878 ins_cost(1.9 * INSN_COST); 11879 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11880 11881 ins_encode %{ 11882 __ add(as_Register($dst$$reg), 11883 as_Register($src1$$reg), 11884 as_Register($src2$$reg), 11885 Assembler::LSL, 11886 $src3$$constant & 0x3f); 11887 %} 11888 11889 ins_pipe(ialu_reg_reg_shift); 11890 %} 11891 11892 instruct SubI_reg_URShift_reg(iRegINoSp dst, 11893 iRegIorL2I src1, iRegIorL2I src2, 11894 immI src3, rFlagsReg cr) %{ 11895 match(Set dst (SubI src1 (URShiftI src2 src3))); 11896 11897 ins_cost(1.9 * INSN_COST); 11898 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11899 11900 ins_encode %{ 11901 __ subw(as_Register($dst$$reg), 11902 as_Register($src1$$reg), 11903 as_Register($src2$$reg), 11904 Assembler::LSR, 11905 $src3$$constant & 0x1f); 11906 %} 11907 11908 ins_pipe(ialu_reg_reg_shift); 11909 %} 11910 11911 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11912 iRegL src1, iRegL src2, 11913 immI src3, rFlagsReg cr) %{ 11914 match(Set dst (SubL src1 (URShiftL src2 src3))); 11915 11916 ins_cost(1.9 * INSN_COST); 11917 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11918 11919 ins_encode %{ 11920 __ sub(as_Register($dst$$reg), 11921 as_Register($src1$$reg), 11922 as_Register($src2$$reg), 11923 Assembler::LSR, 11924 $src3$$constant & 0x3f); 11925 %} 11926 11927 ins_pipe(ialu_reg_reg_shift); 11928 %} 11929 11930 instruct SubI_reg_RShift_reg(iRegINoSp dst, 11931 iRegIorL2I src1, iRegIorL2I src2, 11932 immI src3, rFlagsReg cr) %{ 11933 match(Set dst (SubI src1 (RShiftI src2 src3))); 11934 11935 ins_cost(1.9 * INSN_COST); 11936 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11937 11938 ins_encode %{ 11939 __ subw(as_Register($dst$$reg), 11940 as_Register($src1$$reg), 11941 as_Register($src2$$reg), 11942 Assembler::ASR, 11943 $src3$$constant & 0x1f); 11944 %} 11945 11946 ins_pipe(ialu_reg_reg_shift); 11947 %} 11948 11949 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11950 iRegL src1, iRegL src2, 11951 immI src3, rFlagsReg cr) %{ 11952 match(Set dst (SubL src1 (RShiftL src2 src3))); 11953 11954 ins_cost(1.9 * INSN_COST); 11955 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11956 11957 ins_encode %{ 11958 __ sub(as_Register($dst$$reg), 11959 as_Register($src1$$reg), 11960 as_Register($src2$$reg), 11961 Assembler::ASR, 11962 $src3$$constant & 0x3f); 11963 %} 11964 11965 ins_pipe(ialu_reg_reg_shift); 11966 %} 11967 11968 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11969 iRegIorL2I src1, iRegIorL2I src2, 11970 immI src3, rFlagsReg cr) %{ 11971 match(Set dst (SubI src1 (LShiftI src2 src3))); 11972 11973 ins_cost(1.9 * INSN_COST); 11974 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11975 11976 ins_encode %{ 11977 __ subw(as_Register($dst$$reg), 11978 as_Register($src1$$reg), 11979 as_Register($src2$$reg), 11980 Assembler::LSL, 11981 $src3$$constant & 0x1f); 11982 %} 11983 11984 ins_pipe(ialu_reg_reg_shift); 11985 %} 11986 11987 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11988 iRegL src1, iRegL src2, 11989 immI src3, rFlagsReg cr) %{ 11990 match(Set dst (SubL src1 (LShiftL src2 src3))); 11991 11992 ins_cost(1.9 * INSN_COST); 11993 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11994 11995 ins_encode %{ 11996 __ sub(as_Register($dst$$reg), 11997 as_Register($src1$$reg), 11998 as_Register($src2$$reg), 11999 Assembler::LSL, 12000 $src3$$constant & 0x3f); 12001 %} 12002 12003 ins_pipe(ialu_reg_reg_shift); 12004 %} 12005 12006 12007 12008 // Shift Left followed by Shift Right. 12009 // This idiom is used by the compiler for the i2b bytecode etc. 12010 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12011 %{ 12012 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12013 ins_cost(INSN_COST * 2); 12014 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12015 ins_encode %{ 12016 int lshift = $lshift_count$$constant & 63; 12017 int rshift = $rshift_count$$constant & 63; 12018 int s = 63 - lshift; 12019 int r = (rshift - lshift) & 63; 12020 __ sbfm(as_Register($dst$$reg), 12021 as_Register($src$$reg), 12022 r, s); 12023 %} 12024 12025 ins_pipe(ialu_reg_shift); 12026 %} 12027 12028 // Shift Left followed by Shift Right. 12029 // This idiom is used by the compiler for the i2b bytecode etc. 12030 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12031 %{ 12032 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12033 ins_cost(INSN_COST * 2); 12034 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12035 ins_encode %{ 12036 int lshift = $lshift_count$$constant & 31; 12037 int rshift = $rshift_count$$constant & 31; 12038 int s = 31 - lshift; 12039 int r = (rshift - lshift) & 31; 12040 __ sbfmw(as_Register($dst$$reg), 12041 as_Register($src$$reg), 12042 r, s); 12043 %} 12044 12045 ins_pipe(ialu_reg_shift); 12046 %} 12047 12048 // Shift Left followed by Shift Right. 12049 // This idiom is used by the compiler for the i2b bytecode etc. 12050 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12051 %{ 12052 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12053 ins_cost(INSN_COST * 2); 12054 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12055 ins_encode %{ 12056 int lshift = $lshift_count$$constant & 63; 12057 int rshift = $rshift_count$$constant & 63; 12058 int s = 63 - lshift; 12059 int r = (rshift - lshift) & 63; 12060 __ ubfm(as_Register($dst$$reg), 12061 as_Register($src$$reg), 12062 r, s); 12063 %} 12064 12065 ins_pipe(ialu_reg_shift); 12066 %} 12067 12068 // Shift Left followed by Shift Right. 12069 // This idiom is used by the compiler for the i2b bytecode etc. 12070 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12071 %{ 12072 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12073 ins_cost(INSN_COST * 2); 12074 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12075 ins_encode %{ 12076 int lshift = $lshift_count$$constant & 31; 12077 int rshift = $rshift_count$$constant & 31; 12078 int s = 31 - lshift; 12079 int r = (rshift - lshift) & 31; 12080 __ ubfmw(as_Register($dst$$reg), 12081 as_Register($src$$reg), 12082 r, s); 12083 %} 12084 12085 ins_pipe(ialu_reg_shift); 12086 %} 12087 // Bitfield extract with shift & mask 12088 12089 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12090 %{ 12091 match(Set dst (AndI (URShiftI src rshift) mask)); 12092 // Make sure we are not going to exceed what ubfxw can do. 12093 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12094 12095 ins_cost(INSN_COST); 12096 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12097 ins_encode %{ 12098 int rshift = $rshift$$constant & 31; 12099 long mask = $mask$$constant; 12100 int width = exact_log2(mask+1); 12101 __ ubfxw(as_Register($dst$$reg), 12102 as_Register($src$$reg), rshift, width); 12103 %} 12104 ins_pipe(ialu_reg_shift); 12105 %} 12106 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12107 %{ 12108 match(Set dst (AndL (URShiftL src rshift) mask)); 12109 // Make sure we are not going to exceed what ubfx can do. 12110 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12111 12112 ins_cost(INSN_COST); 12113 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12114 ins_encode %{ 12115 int rshift = $rshift$$constant & 63; 12116 long mask = $mask$$constant; 12117 int width = exact_log2_long(mask+1); 12118 __ ubfx(as_Register($dst$$reg), 12119 as_Register($src$$reg), rshift, width); 12120 %} 12121 ins_pipe(ialu_reg_shift); 12122 %} 12123 12124 // We can use ubfx when extending an And with a mask when we know mask 12125 // is positive. We know that because immI_bitmask guarantees it. 12126 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12127 %{ 12128 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12129 // Make sure we are not going to exceed what ubfxw can do. 12130 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12131 12132 ins_cost(INSN_COST * 2); 12133 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12134 ins_encode %{ 12135 int rshift = $rshift$$constant & 31; 12136 long mask = $mask$$constant; 12137 int width = exact_log2(mask+1); 12138 __ ubfx(as_Register($dst$$reg), 12139 as_Register($src$$reg), rshift, width); 12140 %} 12141 ins_pipe(ialu_reg_shift); 12142 %} 12143 12144 // We can use ubfiz when masking by a positive number and then left shifting the result. 12145 // We know that the mask is positive because immI_bitmask guarantees it. 12146 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12147 %{ 12148 match(Set dst (LShiftI (AndI src mask) lshift)); 12149 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12150 12151 ins_cost(INSN_COST); 12152 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12153 ins_encode %{ 12154 int lshift = $lshift$$constant & 31; 12155 long mask = $mask$$constant; 12156 int width = exact_log2(mask+1); 12157 __ ubfizw(as_Register($dst$$reg), 12158 as_Register($src$$reg), lshift, width); 12159 %} 12160 ins_pipe(ialu_reg_shift); 12161 %} 12162 // We can use ubfiz when masking by a positive number and then left shifting the result. 12163 // We know that the mask is positive because immL_bitmask guarantees it. 12164 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12165 %{ 12166 match(Set dst (LShiftL (AndL src mask) lshift)); 12167 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12168 12169 ins_cost(INSN_COST); 12170 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12171 ins_encode %{ 12172 int lshift = $lshift$$constant & 63; 12173 long mask = $mask$$constant; 12174 int width = exact_log2_long(mask+1); 12175 __ ubfiz(as_Register($dst$$reg), 12176 as_Register($src$$reg), lshift, width); 12177 %} 12178 ins_pipe(ialu_reg_shift); 12179 %} 12180 12181 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12182 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12183 %{ 12184 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12185 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12186 12187 ins_cost(INSN_COST); 12188 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12189 ins_encode %{ 12190 int lshift = $lshift$$constant & 63; 12191 long mask = $mask$$constant; 12192 int width = exact_log2(mask+1); 12193 __ ubfiz(as_Register($dst$$reg), 12194 as_Register($src$$reg), lshift, width); 12195 %} 12196 ins_pipe(ialu_reg_shift); 12197 %} 12198 12199 // Rotations 12200 12201 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12202 %{ 12203 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12204 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12205 12206 ins_cost(INSN_COST); 12207 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12208 12209 ins_encode %{ 12210 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12211 $rshift$$constant & 63); 12212 %} 12213 ins_pipe(ialu_reg_reg_extr); 12214 %} 12215 12216 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12217 %{ 12218 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12219 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12220 12221 ins_cost(INSN_COST); 12222 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12223 12224 ins_encode %{ 12225 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12226 $rshift$$constant & 31); 12227 %} 12228 ins_pipe(ialu_reg_reg_extr); 12229 %} 12230 12231 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12232 %{ 12233 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12234 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12235 12236 ins_cost(INSN_COST); 12237 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12238 12239 ins_encode %{ 12240 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12241 $rshift$$constant & 63); 12242 %} 12243 ins_pipe(ialu_reg_reg_extr); 12244 %} 12245 12246 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12247 %{ 12248 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12249 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12250 12251 ins_cost(INSN_COST); 12252 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12253 12254 ins_encode %{ 12255 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12256 $rshift$$constant & 31); 12257 %} 12258 ins_pipe(ialu_reg_reg_extr); 12259 %} 12260 12261 12262 // rol expander 12263 12264 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12265 %{ 12266 effect(DEF dst, USE src, USE shift); 12267 12268 format %{ "rol $dst, $src, $shift" %} 12269 ins_cost(INSN_COST * 3); 12270 ins_encode %{ 12271 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12272 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12273 rscratch1); 12274 %} 12275 ins_pipe(ialu_reg_reg_vshift); 12276 %} 12277 12278 // rol expander 12279 12280 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12281 %{ 12282 effect(DEF dst, USE src, USE shift); 12283 12284 format %{ "rol $dst, $src, $shift" %} 12285 ins_cost(INSN_COST * 3); 12286 ins_encode %{ 12287 __ subw(rscratch1, zr, as_Register($shift$$reg)); 12288 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12289 rscratch1); 12290 %} 12291 ins_pipe(ialu_reg_reg_vshift); 12292 %} 12293 12294 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12295 %{ 12296 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 12297 12298 expand %{ 12299 rolL_rReg(dst, src, shift, cr); 12300 %} 12301 %} 12302 12303 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12304 %{ 12305 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 12306 12307 expand %{ 12308 rolL_rReg(dst, src, shift, cr); 12309 %} 12310 %} 12311 12312 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12313 %{ 12314 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 12315 12316 expand %{ 12317 rolI_rReg(dst, src, shift, cr); 12318 %} 12319 %} 12320 12321 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12322 %{ 12323 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 12324 12325 expand %{ 12326 rolI_rReg(dst, src, shift, cr); 12327 %} 12328 %} 12329 12330 // ror expander 12331 12332 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 12333 %{ 12334 effect(DEF dst, USE src, USE shift); 12335 12336 format %{ "ror $dst, $src, $shift" %} 12337 ins_cost(INSN_COST); 12338 ins_encode %{ 12339 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 12340 as_Register($shift$$reg)); 12341 %} 12342 ins_pipe(ialu_reg_reg_vshift); 12343 %} 12344 12345 // ror expander 12346 12347 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 12348 %{ 12349 effect(DEF dst, USE src, USE shift); 12350 12351 format %{ "ror $dst, $src, $shift" %} 12352 ins_cost(INSN_COST); 12353 ins_encode %{ 12354 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 12355 as_Register($shift$$reg)); 12356 %} 12357 ins_pipe(ialu_reg_reg_vshift); 12358 %} 12359 12360 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 12361 %{ 12362 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 12363 12364 expand %{ 12365 rorL_rReg(dst, src, shift, cr); 12366 %} 12367 %} 12368 12369 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 12370 %{ 12371 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 12372 12373 expand %{ 12374 rorL_rReg(dst, src, shift, cr); 12375 %} 12376 %} 12377 12378 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 12379 %{ 12380 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 12381 12382 expand %{ 12383 rorI_rReg(dst, src, shift, cr); 12384 %} 12385 %} 12386 12387 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 12388 %{ 12389 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 12390 12391 expand %{ 12392 rorI_rReg(dst, src, shift, cr); 12393 %} 12394 %} 12395 12396 // Add/subtract (extended) 12397 12398 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12399 %{ 12400 match(Set dst (AddL src1 (ConvI2L src2))); 12401 ins_cost(INSN_COST); 12402 format %{ "add $dst, $src1, $src2, sxtw" %} 12403 12404 ins_encode %{ 12405 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12406 as_Register($src2$$reg), ext::sxtw); 12407 %} 12408 ins_pipe(ialu_reg_reg); 12409 %}; 12410 12411 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 12412 %{ 12413 match(Set dst (SubL src1 (ConvI2L src2))); 12414 ins_cost(INSN_COST); 12415 format %{ "sub $dst, $src1, $src2, sxtw" %} 12416 12417 ins_encode %{ 12418 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12419 as_Register($src2$$reg), ext::sxtw); 12420 %} 12421 ins_pipe(ialu_reg_reg); 12422 %}; 12423 12424 12425 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 12426 %{ 12427 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12428 ins_cost(INSN_COST); 12429 format %{ "add $dst, $src1, $src2, sxth" %} 12430 12431 ins_encode %{ 12432 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12433 as_Register($src2$$reg), ext::sxth); 12434 %} 12435 ins_pipe(ialu_reg_reg); 12436 %} 12437 12438 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12439 %{ 12440 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 12441 ins_cost(INSN_COST); 12442 format %{ "add $dst, $src1, $src2, sxtb" %} 12443 12444 ins_encode %{ 12445 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12446 as_Register($src2$$reg), ext::sxtb); 12447 %} 12448 ins_pipe(ialu_reg_reg); 12449 %} 12450 12451 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12452 %{ 12453 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12454 ins_cost(INSN_COST); 12455 format %{ "add $dst, $src1, $src2, uxtb" %} 12456 12457 ins_encode %{ 12458 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12459 as_Register($src2$$reg), ext::uxtb); 12460 %} 12461 ins_pipe(ialu_reg_reg); 12462 %} 12463 12464 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12465 %{ 12466 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12467 ins_cost(INSN_COST); 12468 format %{ "add $dst, $src1, $src2, sxth" %} 12469 12470 ins_encode %{ 12471 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12472 as_Register($src2$$reg), ext::sxth); 12473 %} 12474 ins_pipe(ialu_reg_reg); 12475 %} 12476 12477 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12478 %{ 12479 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12480 ins_cost(INSN_COST); 12481 format %{ "add $dst, $src1, $src2, sxtw" %} 12482 12483 ins_encode %{ 12484 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12485 as_Register($src2$$reg), ext::sxtw); 12486 %} 12487 ins_pipe(ialu_reg_reg); 12488 %} 12489 12490 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12491 %{ 12492 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12493 ins_cost(INSN_COST); 12494 format %{ "add $dst, $src1, $src2, sxtb" %} 12495 12496 ins_encode %{ 12497 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12498 as_Register($src2$$reg), ext::sxtb); 12499 %} 12500 ins_pipe(ialu_reg_reg); 12501 %} 12502 12503 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12504 %{ 12505 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12506 ins_cost(INSN_COST); 12507 format %{ "add $dst, $src1, $src2, uxtb" %} 12508 12509 ins_encode %{ 12510 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12511 as_Register($src2$$reg), ext::uxtb); 12512 %} 12513 ins_pipe(ialu_reg_reg); 12514 %} 12515 12516 12517 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12518 %{ 12519 match(Set dst (AddI src1 (AndI src2 mask))); 12520 ins_cost(INSN_COST); 12521 format %{ "addw $dst, $src1, $src2, uxtb" %} 12522 12523 ins_encode %{ 12524 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12525 as_Register($src2$$reg), ext::uxtb); 12526 %} 12527 ins_pipe(ialu_reg_reg); 12528 %} 12529 12530 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12531 %{ 12532 match(Set dst (AddI src1 (AndI src2 mask))); 12533 ins_cost(INSN_COST); 12534 format %{ "addw $dst, $src1, $src2, uxth" %} 12535 12536 ins_encode %{ 12537 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12538 as_Register($src2$$reg), ext::uxth); 12539 %} 12540 ins_pipe(ialu_reg_reg); 12541 %} 12542 12543 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12544 %{ 12545 match(Set dst (AddL src1 (AndL src2 mask))); 12546 ins_cost(INSN_COST); 12547 format %{ "add $dst, $src1, $src2, uxtb" %} 12548 12549 ins_encode %{ 12550 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12551 as_Register($src2$$reg), ext::uxtb); 12552 %} 12553 ins_pipe(ialu_reg_reg); 12554 %} 12555 12556 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12557 %{ 12558 match(Set dst (AddL src1 (AndL src2 mask))); 12559 ins_cost(INSN_COST); 12560 format %{ "add $dst, $src1, $src2, uxth" %} 12561 12562 ins_encode %{ 12563 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12564 as_Register($src2$$reg), ext::uxth); 12565 %} 12566 ins_pipe(ialu_reg_reg); 12567 %} 12568 12569 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12570 %{ 12571 match(Set dst (AddL src1 (AndL src2 mask))); 12572 ins_cost(INSN_COST); 12573 format %{ "add $dst, $src1, $src2, uxtw" %} 12574 12575 ins_encode %{ 12576 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12577 as_Register($src2$$reg), ext::uxtw); 12578 %} 12579 ins_pipe(ialu_reg_reg); 12580 %} 12581 12582 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12583 %{ 12584 match(Set dst (SubI src1 (AndI src2 mask))); 12585 ins_cost(INSN_COST); 12586 format %{ "subw $dst, $src1, $src2, uxtb" %} 12587 12588 ins_encode %{ 12589 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12590 as_Register($src2$$reg), ext::uxtb); 12591 %} 12592 ins_pipe(ialu_reg_reg); 12593 %} 12594 12595 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12596 %{ 12597 match(Set dst (SubI src1 (AndI src2 mask))); 12598 ins_cost(INSN_COST); 12599 format %{ "subw $dst, $src1, $src2, uxth" %} 12600 12601 ins_encode %{ 12602 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12603 as_Register($src2$$reg), ext::uxth); 12604 %} 12605 ins_pipe(ialu_reg_reg); 12606 %} 12607 12608 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12609 %{ 12610 match(Set dst (SubL src1 (AndL src2 mask))); 12611 ins_cost(INSN_COST); 12612 format %{ "sub $dst, $src1, $src2, uxtb" %} 12613 12614 ins_encode %{ 12615 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12616 as_Register($src2$$reg), ext::uxtb); 12617 %} 12618 ins_pipe(ialu_reg_reg); 12619 %} 12620 12621 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12622 %{ 12623 match(Set dst (SubL src1 (AndL src2 mask))); 12624 ins_cost(INSN_COST); 12625 format %{ "sub $dst, $src1, $src2, uxth" %} 12626 12627 ins_encode %{ 12628 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12629 as_Register($src2$$reg), ext::uxth); 12630 %} 12631 ins_pipe(ialu_reg_reg); 12632 %} 12633 12634 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12635 %{ 12636 match(Set dst (SubL src1 (AndL src2 mask))); 12637 ins_cost(INSN_COST); 12638 format %{ "sub $dst, $src1, $src2, uxtw" %} 12639 12640 ins_encode %{ 12641 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12642 as_Register($src2$$reg), ext::uxtw); 12643 %} 12644 ins_pipe(ialu_reg_reg); 12645 %} 12646 12647 12648 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12649 %{ 12650 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12651 ins_cost(1.9 * INSN_COST); 12652 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12653 12654 ins_encode %{ 12655 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12656 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12657 %} 12658 ins_pipe(ialu_reg_reg_shift); 12659 %} 12660 12661 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12662 %{ 12663 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12664 ins_cost(1.9 * INSN_COST); 12665 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12666 12667 ins_encode %{ 12668 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12669 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12670 %} 12671 ins_pipe(ialu_reg_reg_shift); 12672 %} 12673 12674 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12675 %{ 12676 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12677 ins_cost(1.9 * INSN_COST); 12678 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12679 12680 ins_encode %{ 12681 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12682 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12683 %} 12684 ins_pipe(ialu_reg_reg_shift); 12685 %} 12686 12687 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12688 %{ 12689 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12690 ins_cost(1.9 * INSN_COST); 12691 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12692 12693 ins_encode %{ 12694 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12695 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12696 %} 12697 ins_pipe(ialu_reg_reg_shift); 12698 %} 12699 12700 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12701 %{ 12702 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12703 ins_cost(1.9 * INSN_COST); 12704 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12705 12706 ins_encode %{ 12707 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12708 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12709 %} 12710 ins_pipe(ialu_reg_reg_shift); 12711 %} 12712 12713 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12714 %{ 12715 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12716 ins_cost(1.9 * INSN_COST); 12717 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12718 12719 ins_encode %{ 12720 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12721 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12722 %} 12723 ins_pipe(ialu_reg_reg_shift); 12724 %} 12725 12726 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12727 %{ 12728 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12729 ins_cost(1.9 * INSN_COST); 12730 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12731 12732 ins_encode %{ 12733 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12734 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12735 %} 12736 ins_pipe(ialu_reg_reg_shift); 12737 %} 12738 12739 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12740 %{ 12741 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12742 ins_cost(1.9 * INSN_COST); 12743 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12744 12745 ins_encode %{ 12746 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12747 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12748 %} 12749 ins_pipe(ialu_reg_reg_shift); 12750 %} 12751 12752 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12753 %{ 12754 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12755 ins_cost(1.9 * INSN_COST); 12756 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12757 12758 ins_encode %{ 12759 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12760 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12761 %} 12762 ins_pipe(ialu_reg_reg_shift); 12763 %} 12764 12765 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12766 %{ 12767 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12768 ins_cost(1.9 * INSN_COST); 12769 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12770 12771 ins_encode %{ 12772 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12773 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12774 %} 12775 ins_pipe(ialu_reg_reg_shift); 12776 %} 12777 12778 12779 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12780 %{ 12781 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12782 ins_cost(1.9 * INSN_COST); 12783 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12784 12785 ins_encode %{ 12786 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12787 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12788 %} 12789 ins_pipe(ialu_reg_reg_shift); 12790 %}; 12791 12792 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12793 %{ 12794 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12795 ins_cost(1.9 * INSN_COST); 12796 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12797 12798 ins_encode %{ 12799 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12800 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12801 %} 12802 ins_pipe(ialu_reg_reg_shift); 12803 %}; 12804 12805 12806 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12807 %{ 12808 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12809 ins_cost(1.9 * INSN_COST); 12810 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12811 12812 ins_encode %{ 12813 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12814 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12815 %} 12816 ins_pipe(ialu_reg_reg_shift); 12817 %} 12818 12819 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12820 %{ 12821 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12822 ins_cost(1.9 * INSN_COST); 12823 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12824 12825 ins_encode %{ 12826 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12827 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12828 %} 12829 ins_pipe(ialu_reg_reg_shift); 12830 %} 12831 12832 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12833 %{ 12834 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12835 ins_cost(1.9 * INSN_COST); 12836 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12837 12838 ins_encode %{ 12839 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12840 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12841 %} 12842 ins_pipe(ialu_reg_reg_shift); 12843 %} 12844 12845 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12846 %{ 12847 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12848 ins_cost(1.9 * INSN_COST); 12849 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12850 12851 ins_encode %{ 12852 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12853 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12854 %} 12855 ins_pipe(ialu_reg_reg_shift); 12856 %} 12857 12858 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12859 %{ 12860 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12861 ins_cost(1.9 * INSN_COST); 12862 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12863 12864 ins_encode %{ 12865 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12866 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12867 %} 12868 ins_pipe(ialu_reg_reg_shift); 12869 %} 12870 12871 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12872 %{ 12873 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12874 ins_cost(1.9 * INSN_COST); 12875 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12876 12877 ins_encode %{ 12878 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12879 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12880 %} 12881 ins_pipe(ialu_reg_reg_shift); 12882 %} 12883 12884 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12885 %{ 12886 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12887 ins_cost(1.9 * INSN_COST); 12888 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12889 12890 ins_encode %{ 12891 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12892 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12893 %} 12894 ins_pipe(ialu_reg_reg_shift); 12895 %} 12896 12897 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12898 %{ 12899 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12900 ins_cost(1.9 * INSN_COST); 12901 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12902 12903 ins_encode %{ 12904 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12905 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12906 %} 12907 ins_pipe(ialu_reg_reg_shift); 12908 %} 12909 12910 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12911 %{ 12912 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12913 ins_cost(1.9 * INSN_COST); 12914 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12915 12916 ins_encode %{ 12917 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12918 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12919 %} 12920 ins_pipe(ialu_reg_reg_shift); 12921 %} 12922 12923 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12924 %{ 12925 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12926 ins_cost(1.9 * INSN_COST); 12927 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12928 12929 ins_encode %{ 12930 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12931 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12932 %} 12933 ins_pipe(ialu_reg_reg_shift); 12934 %} 12935 // END This section of the file is automatically generated. Do not edit -------------- 12936 12937 // ============================================================================ 12938 // Floating Point Arithmetic Instructions 12939 12940 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12941 match(Set dst (AddF src1 src2)); 12942 12943 ins_cost(INSN_COST * 5); 12944 format %{ "fadds $dst, $src1, $src2" %} 12945 12946 ins_encode %{ 12947 __ fadds(as_FloatRegister($dst$$reg), 12948 as_FloatRegister($src1$$reg), 12949 as_FloatRegister($src2$$reg)); 12950 %} 12951 12952 ins_pipe(fp_dop_reg_reg_s); 12953 %} 12954 12955 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12956 match(Set dst (AddD src1 src2)); 12957 12958 ins_cost(INSN_COST * 5); 12959 format %{ "faddd $dst, $src1, $src2" %} 12960 12961 ins_encode %{ 12962 __ faddd(as_FloatRegister($dst$$reg), 12963 as_FloatRegister($src1$$reg), 12964 as_FloatRegister($src2$$reg)); 12965 %} 12966 12967 ins_pipe(fp_dop_reg_reg_d); 12968 %} 12969 12970 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12971 match(Set dst (SubF src1 src2)); 12972 12973 ins_cost(INSN_COST * 5); 12974 format %{ "fsubs $dst, $src1, $src2" %} 12975 12976 ins_encode %{ 12977 __ fsubs(as_FloatRegister($dst$$reg), 12978 as_FloatRegister($src1$$reg), 12979 as_FloatRegister($src2$$reg)); 12980 %} 12981 12982 ins_pipe(fp_dop_reg_reg_s); 12983 %} 12984 12985 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12986 match(Set dst (SubD src1 src2)); 12987 12988 ins_cost(INSN_COST * 5); 12989 format %{ "fsubd $dst, $src1, $src2" %} 12990 12991 ins_encode %{ 12992 __ fsubd(as_FloatRegister($dst$$reg), 12993 as_FloatRegister($src1$$reg), 12994 as_FloatRegister($src2$$reg)); 12995 %} 12996 12997 ins_pipe(fp_dop_reg_reg_d); 12998 %} 12999 13000 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13001 match(Set dst (MulF src1 src2)); 13002 13003 ins_cost(INSN_COST * 6); 13004 format %{ "fmuls $dst, $src1, $src2" %} 13005 13006 ins_encode %{ 13007 __ fmuls(as_FloatRegister($dst$$reg), 13008 as_FloatRegister($src1$$reg), 13009 as_FloatRegister($src2$$reg)); 13010 %} 13011 13012 ins_pipe(fp_dop_reg_reg_s); 13013 %} 13014 13015 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13016 match(Set dst (MulD src1 src2)); 13017 13018 ins_cost(INSN_COST * 6); 13019 format %{ "fmuld $dst, $src1, $src2" %} 13020 13021 ins_encode %{ 13022 __ fmuld(as_FloatRegister($dst$$reg), 13023 as_FloatRegister($src1$$reg), 13024 as_FloatRegister($src2$$reg)); 13025 %} 13026 13027 ins_pipe(fp_dop_reg_reg_d); 13028 %} 13029 13030 // src1 * src2 + src3 13031 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13032 predicate(UseFMA); 13033 match(Set dst (FmaF src3 (Binary src1 src2))); 13034 13035 format %{ "fmadds $dst, $src1, $src2, $src3" %} 13036 13037 ins_encode %{ 13038 __ fmadds(as_FloatRegister($dst$$reg), 13039 as_FloatRegister($src1$$reg), 13040 as_FloatRegister($src2$$reg), 13041 as_FloatRegister($src3$$reg)); 13042 %} 13043 13044 ins_pipe(pipe_class_default); 13045 %} 13046 13047 // src1 * src2 + src3 13048 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13049 predicate(UseFMA); 13050 match(Set dst (FmaD src3 (Binary src1 src2))); 13051 13052 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 13053 13054 ins_encode %{ 13055 __ fmaddd(as_FloatRegister($dst$$reg), 13056 as_FloatRegister($src1$$reg), 13057 as_FloatRegister($src2$$reg), 13058 as_FloatRegister($src3$$reg)); 13059 %} 13060 13061 ins_pipe(pipe_class_default); 13062 %} 13063 13064 // -src1 * src2 + src3 13065 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13066 predicate(UseFMA); 13067 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 13068 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 13069 13070 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 13071 13072 ins_encode %{ 13073 __ fmsubs(as_FloatRegister($dst$$reg), 13074 as_FloatRegister($src1$$reg), 13075 as_FloatRegister($src2$$reg), 13076 as_FloatRegister($src3$$reg)); 13077 %} 13078 13079 ins_pipe(pipe_class_default); 13080 %} 13081 13082 // -src1 * src2 + src3 13083 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13084 predicate(UseFMA); 13085 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 13086 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 13087 13088 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 13089 13090 ins_encode %{ 13091 __ fmsubd(as_FloatRegister($dst$$reg), 13092 as_FloatRegister($src1$$reg), 13093 as_FloatRegister($src2$$reg), 13094 as_FloatRegister($src3$$reg)); 13095 %} 13096 13097 ins_pipe(pipe_class_default); 13098 %} 13099 13100 // -src1 * src2 - src3 13101 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13102 predicate(UseFMA); 13103 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 13104 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13105 13106 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13107 13108 ins_encode %{ 13109 __ fnmadds(as_FloatRegister($dst$$reg), 13110 as_FloatRegister($src1$$reg), 13111 as_FloatRegister($src2$$reg), 13112 as_FloatRegister($src3$$reg)); 13113 %} 13114 13115 ins_pipe(pipe_class_default); 13116 %} 13117 13118 // -src1 * src2 - src3 13119 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13120 predicate(UseFMA); 13121 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13122 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13123 13124 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13125 13126 ins_encode %{ 13127 __ fnmaddd(as_FloatRegister($dst$$reg), 13128 as_FloatRegister($src1$$reg), 13129 as_FloatRegister($src2$$reg), 13130 as_FloatRegister($src3$$reg)); 13131 %} 13132 13133 ins_pipe(pipe_class_default); 13134 %} 13135 13136 // src1 * src2 - src3 13137 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13138 predicate(UseFMA); 13139 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13140 13141 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13142 13143 ins_encode %{ 13144 __ fnmsubs(as_FloatRegister($dst$$reg), 13145 as_FloatRegister($src1$$reg), 13146 as_FloatRegister($src2$$reg), 13147 as_FloatRegister($src3$$reg)); 13148 %} 13149 13150 ins_pipe(pipe_class_default); 13151 %} 13152 13153 // src1 * src2 - src3 13154 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13155 predicate(UseFMA); 13156 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13157 13158 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13159 13160 ins_encode %{ 13161 // n.b. insn name should be fnmsubd 13162 __ fnmsub(as_FloatRegister($dst$$reg), 13163 as_FloatRegister($src1$$reg), 13164 as_FloatRegister($src2$$reg), 13165 as_FloatRegister($src3$$reg)); 13166 %} 13167 13168 ins_pipe(pipe_class_default); 13169 %} 13170 13171 13172 // Math.max(FF)F 13173 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13174 match(Set dst (MaxF src1 src2)); 13175 13176 format %{ "fmaxs $dst, $src1, $src2" %} 13177 ins_encode %{ 13178 __ fmaxs(as_FloatRegister($dst$$reg), 13179 as_FloatRegister($src1$$reg), 13180 as_FloatRegister($src2$$reg)); 13181 %} 13182 13183 ins_pipe(fp_dop_reg_reg_s); 13184 %} 13185 13186 // Math.min(FF)F 13187 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13188 match(Set dst (MinF src1 src2)); 13189 13190 format %{ "fmins $dst, $src1, $src2" %} 13191 ins_encode %{ 13192 __ fmins(as_FloatRegister($dst$$reg), 13193 as_FloatRegister($src1$$reg), 13194 as_FloatRegister($src2$$reg)); 13195 %} 13196 13197 ins_pipe(fp_dop_reg_reg_s); 13198 %} 13199 13200 // Math.max(DD)D 13201 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13202 match(Set dst (MaxD src1 src2)); 13203 13204 format %{ "fmaxd $dst, $src1, $src2" %} 13205 ins_encode %{ 13206 __ fmaxd(as_FloatRegister($dst$$reg), 13207 as_FloatRegister($src1$$reg), 13208 as_FloatRegister($src2$$reg)); 13209 %} 13210 13211 ins_pipe(fp_dop_reg_reg_d); 13212 %} 13213 13214 // Math.min(DD)D 13215 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13216 match(Set dst (MinD src1 src2)); 13217 13218 format %{ "fmind $dst, $src1, $src2" %} 13219 ins_encode %{ 13220 __ fmind(as_FloatRegister($dst$$reg), 13221 as_FloatRegister($src1$$reg), 13222 as_FloatRegister($src2$$reg)); 13223 %} 13224 13225 ins_pipe(fp_dop_reg_reg_d); 13226 %} 13227 13228 13229 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13230 match(Set dst (DivF src1 src2)); 13231 13232 ins_cost(INSN_COST * 18); 13233 format %{ "fdivs $dst, $src1, $src2" %} 13234 13235 ins_encode %{ 13236 __ fdivs(as_FloatRegister($dst$$reg), 13237 as_FloatRegister($src1$$reg), 13238 as_FloatRegister($src2$$reg)); 13239 %} 13240 13241 ins_pipe(fp_div_s); 13242 %} 13243 13244 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13245 match(Set dst (DivD src1 src2)); 13246 13247 ins_cost(INSN_COST * 32); 13248 format %{ "fdivd $dst, $src1, $src2" %} 13249 13250 ins_encode %{ 13251 __ fdivd(as_FloatRegister($dst$$reg), 13252 as_FloatRegister($src1$$reg), 13253 as_FloatRegister($src2$$reg)); 13254 %} 13255 13256 ins_pipe(fp_div_d); 13257 %} 13258 13259 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 13260 match(Set dst (NegF src)); 13261 13262 ins_cost(INSN_COST * 3); 13263 format %{ "fneg $dst, $src" %} 13264 13265 ins_encode %{ 13266 __ fnegs(as_FloatRegister($dst$$reg), 13267 as_FloatRegister($src$$reg)); 13268 %} 13269 13270 ins_pipe(fp_uop_s); 13271 %} 13272 13273 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 13274 match(Set dst (NegD src)); 13275 13276 ins_cost(INSN_COST * 3); 13277 format %{ "fnegd $dst, $src" %} 13278 13279 ins_encode %{ 13280 __ fnegd(as_FloatRegister($dst$$reg), 13281 as_FloatRegister($src$$reg)); 13282 %} 13283 13284 ins_pipe(fp_uop_d); 13285 %} 13286 13287 instruct absF_reg(vRegF dst, vRegF src) %{ 13288 match(Set dst (AbsF src)); 13289 13290 ins_cost(INSN_COST * 3); 13291 format %{ "fabss $dst, $src" %} 13292 ins_encode %{ 13293 __ fabss(as_FloatRegister($dst$$reg), 13294 as_FloatRegister($src$$reg)); 13295 %} 13296 13297 ins_pipe(fp_uop_s); 13298 %} 13299 13300 instruct absD_reg(vRegD dst, vRegD src) %{ 13301 match(Set dst (AbsD src)); 13302 13303 ins_cost(INSN_COST * 3); 13304 format %{ "fabsd $dst, $src" %} 13305 ins_encode %{ 13306 __ fabsd(as_FloatRegister($dst$$reg), 13307 as_FloatRegister($src$$reg)); 13308 %} 13309 13310 ins_pipe(fp_uop_d); 13311 %} 13312 13313 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 13314 match(Set dst (SqrtD src)); 13315 13316 ins_cost(INSN_COST * 50); 13317 format %{ "fsqrtd $dst, $src" %} 13318 ins_encode %{ 13319 __ fsqrtd(as_FloatRegister($dst$$reg), 13320 as_FloatRegister($src$$reg)); 13321 %} 13322 13323 ins_pipe(fp_div_s); 13324 %} 13325 13326 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 13327 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 13328 13329 ins_cost(INSN_COST * 50); 13330 format %{ "fsqrts $dst, $src" %} 13331 ins_encode %{ 13332 __ fsqrts(as_FloatRegister($dst$$reg), 13333 as_FloatRegister($src$$reg)); 13334 %} 13335 13336 ins_pipe(fp_div_d); 13337 %} 13338 13339 // ============================================================================ 13340 // Logical Instructions 13341 13342 // Integer Logical Instructions 13343 13344 // And Instructions 13345 13346 13347 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13348 match(Set dst (AndI src1 src2)); 13349 13350 format %{ "andw $dst, $src1, $src2\t# int" %} 13351 13352 ins_cost(INSN_COST); 13353 ins_encode %{ 13354 __ andw(as_Register($dst$$reg), 13355 as_Register($src1$$reg), 13356 as_Register($src2$$reg)); 13357 %} 13358 13359 ins_pipe(ialu_reg_reg); 13360 %} 13361 13362 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13363 match(Set dst (AndI src1 src2)); 13364 13365 format %{ "andsw $dst, $src1, $src2\t# int" %} 13366 13367 ins_cost(INSN_COST); 13368 ins_encode %{ 13369 __ andw(as_Register($dst$$reg), 13370 as_Register($src1$$reg), 13371 (unsigned long)($src2$$constant)); 13372 %} 13373 13374 ins_pipe(ialu_reg_imm); 13375 %} 13376 13377 // Or Instructions 13378 13379 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13380 match(Set dst (OrI src1 src2)); 13381 13382 format %{ "orrw $dst, $src1, $src2\t# int" %} 13383 13384 ins_cost(INSN_COST); 13385 ins_encode %{ 13386 __ orrw(as_Register($dst$$reg), 13387 as_Register($src1$$reg), 13388 as_Register($src2$$reg)); 13389 %} 13390 13391 ins_pipe(ialu_reg_reg); 13392 %} 13393 13394 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13395 match(Set dst (OrI src1 src2)); 13396 13397 format %{ "orrw $dst, $src1, $src2\t# int" %} 13398 13399 ins_cost(INSN_COST); 13400 ins_encode %{ 13401 __ orrw(as_Register($dst$$reg), 13402 as_Register($src1$$reg), 13403 (unsigned long)($src2$$constant)); 13404 %} 13405 13406 ins_pipe(ialu_reg_imm); 13407 %} 13408 13409 // Xor Instructions 13410 13411 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13412 match(Set dst (XorI src1 src2)); 13413 13414 format %{ "eorw $dst, $src1, $src2\t# int" %} 13415 13416 ins_cost(INSN_COST); 13417 ins_encode %{ 13418 __ eorw(as_Register($dst$$reg), 13419 as_Register($src1$$reg), 13420 as_Register($src2$$reg)); 13421 %} 13422 13423 ins_pipe(ialu_reg_reg); 13424 %} 13425 13426 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13427 match(Set dst (XorI src1 src2)); 13428 13429 format %{ "eorw $dst, $src1, $src2\t# int" %} 13430 13431 ins_cost(INSN_COST); 13432 ins_encode %{ 13433 __ eorw(as_Register($dst$$reg), 13434 as_Register($src1$$reg), 13435 (unsigned long)($src2$$constant)); 13436 %} 13437 13438 ins_pipe(ialu_reg_imm); 13439 %} 13440 13441 // Long Logical Instructions 13442 // TODO 13443 13444 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13445 match(Set dst (AndL src1 src2)); 13446 13447 format %{ "and $dst, $src1, $src2\t# int" %} 13448 13449 ins_cost(INSN_COST); 13450 ins_encode %{ 13451 __ andr(as_Register($dst$$reg), 13452 as_Register($src1$$reg), 13453 as_Register($src2$$reg)); 13454 %} 13455 13456 ins_pipe(ialu_reg_reg); 13457 %} 13458 13459 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13460 match(Set dst (AndL src1 src2)); 13461 13462 format %{ "and $dst, $src1, $src2\t# int" %} 13463 13464 ins_cost(INSN_COST); 13465 ins_encode %{ 13466 __ andr(as_Register($dst$$reg), 13467 as_Register($src1$$reg), 13468 (unsigned long)($src2$$constant)); 13469 %} 13470 13471 ins_pipe(ialu_reg_imm); 13472 %} 13473 13474 // Or Instructions 13475 13476 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13477 match(Set dst (OrL src1 src2)); 13478 13479 format %{ "orr $dst, $src1, $src2\t# int" %} 13480 13481 ins_cost(INSN_COST); 13482 ins_encode %{ 13483 __ orr(as_Register($dst$$reg), 13484 as_Register($src1$$reg), 13485 as_Register($src2$$reg)); 13486 %} 13487 13488 ins_pipe(ialu_reg_reg); 13489 %} 13490 13491 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13492 match(Set dst (OrL src1 src2)); 13493 13494 format %{ "orr $dst, $src1, $src2\t# int" %} 13495 13496 ins_cost(INSN_COST); 13497 ins_encode %{ 13498 __ orr(as_Register($dst$$reg), 13499 as_Register($src1$$reg), 13500 (unsigned long)($src2$$constant)); 13501 %} 13502 13503 ins_pipe(ialu_reg_imm); 13504 %} 13505 13506 // Xor Instructions 13507 13508 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13509 match(Set dst (XorL src1 src2)); 13510 13511 format %{ "eor $dst, $src1, $src2\t# int" %} 13512 13513 ins_cost(INSN_COST); 13514 ins_encode %{ 13515 __ eor(as_Register($dst$$reg), 13516 as_Register($src1$$reg), 13517 as_Register($src2$$reg)); 13518 %} 13519 13520 ins_pipe(ialu_reg_reg); 13521 %} 13522 13523 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13524 match(Set dst (XorL src1 src2)); 13525 13526 ins_cost(INSN_COST); 13527 format %{ "eor $dst, $src1, $src2\t# int" %} 13528 13529 ins_encode %{ 13530 __ eor(as_Register($dst$$reg), 13531 as_Register($src1$$reg), 13532 (unsigned long)($src2$$constant)); 13533 %} 13534 13535 ins_pipe(ialu_reg_imm); 13536 %} 13537 13538 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13539 %{ 13540 match(Set dst (ConvI2L src)); 13541 13542 ins_cost(INSN_COST); 13543 format %{ "sxtw $dst, $src\t# i2l" %} 13544 ins_encode %{ 13545 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13546 %} 13547 ins_pipe(ialu_reg_shift); 13548 %} 13549 13550 // this pattern occurs in bigmath arithmetic 13551 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13552 %{ 13553 match(Set dst (AndL (ConvI2L src) mask)); 13554 13555 ins_cost(INSN_COST); 13556 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13557 ins_encode %{ 13558 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13559 %} 13560 13561 ins_pipe(ialu_reg_shift); 13562 %} 13563 13564 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13565 match(Set dst (ConvL2I src)); 13566 13567 ins_cost(INSN_COST); 13568 format %{ "movw $dst, $src \t// l2i" %} 13569 13570 ins_encode %{ 13571 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13572 %} 13573 13574 ins_pipe(ialu_reg); 13575 %} 13576 13577 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13578 %{ 13579 match(Set dst (Conv2B src)); 13580 effect(KILL cr); 13581 13582 format %{ 13583 "cmpw $src, zr\n\t" 13584 "cset $dst, ne" 13585 %} 13586 13587 ins_encode %{ 13588 __ cmpw(as_Register($src$$reg), zr); 13589 __ cset(as_Register($dst$$reg), Assembler::NE); 13590 %} 13591 13592 ins_pipe(ialu_reg); 13593 %} 13594 13595 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13596 %{ 13597 match(Set dst (Conv2B src)); 13598 effect(KILL cr); 13599 13600 format %{ 13601 "cmp $src, zr\n\t" 13602 "cset $dst, ne" 13603 %} 13604 13605 ins_encode %{ 13606 __ cmp(as_Register($src$$reg), zr); 13607 __ cset(as_Register($dst$$reg), Assembler::NE); 13608 %} 13609 13610 ins_pipe(ialu_reg); 13611 %} 13612 13613 instruct convD2F_reg(vRegF dst, vRegD src) %{ 13614 match(Set dst (ConvD2F src)); 13615 13616 ins_cost(INSN_COST * 5); 13617 format %{ "fcvtd $dst, $src \t// d2f" %} 13618 13619 ins_encode %{ 13620 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13621 %} 13622 13623 ins_pipe(fp_d2f); 13624 %} 13625 13626 instruct convF2D_reg(vRegD dst, vRegF src) %{ 13627 match(Set dst (ConvF2D src)); 13628 13629 ins_cost(INSN_COST * 5); 13630 format %{ "fcvts $dst, $src \t// f2d" %} 13631 13632 ins_encode %{ 13633 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13634 %} 13635 13636 ins_pipe(fp_f2d); 13637 %} 13638 13639 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13640 match(Set dst (ConvF2I src)); 13641 13642 ins_cost(INSN_COST * 5); 13643 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13644 13645 ins_encode %{ 13646 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13647 %} 13648 13649 ins_pipe(fp_f2i); 13650 %} 13651 13652 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13653 match(Set dst (ConvF2L src)); 13654 13655 ins_cost(INSN_COST * 5); 13656 format %{ "fcvtzs $dst, $src \t// f2l" %} 13657 13658 ins_encode %{ 13659 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13660 %} 13661 13662 ins_pipe(fp_f2l); 13663 %} 13664 13665 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13666 match(Set dst (ConvI2F src)); 13667 13668 ins_cost(INSN_COST * 5); 13669 format %{ "scvtfws $dst, $src \t// i2f" %} 13670 13671 ins_encode %{ 13672 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13673 %} 13674 13675 ins_pipe(fp_i2f); 13676 %} 13677 13678 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13679 match(Set dst (ConvL2F src)); 13680 13681 ins_cost(INSN_COST * 5); 13682 format %{ "scvtfs $dst, $src \t// l2f" %} 13683 13684 ins_encode %{ 13685 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13686 %} 13687 13688 ins_pipe(fp_l2f); 13689 %} 13690 13691 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13692 match(Set dst (ConvD2I src)); 13693 13694 ins_cost(INSN_COST * 5); 13695 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13696 13697 ins_encode %{ 13698 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13699 %} 13700 13701 ins_pipe(fp_d2i); 13702 %} 13703 13704 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13705 match(Set dst (ConvD2L src)); 13706 13707 ins_cost(INSN_COST * 5); 13708 format %{ "fcvtzd $dst, $src \t// d2l" %} 13709 13710 ins_encode %{ 13711 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13712 %} 13713 13714 ins_pipe(fp_d2l); 13715 %} 13716 13717 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13718 match(Set dst (ConvI2D src)); 13719 13720 ins_cost(INSN_COST * 5); 13721 format %{ "scvtfwd $dst, $src \t// i2d" %} 13722 13723 ins_encode %{ 13724 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13725 %} 13726 13727 ins_pipe(fp_i2d); 13728 %} 13729 13730 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13731 match(Set dst (ConvL2D src)); 13732 13733 ins_cost(INSN_COST * 5); 13734 format %{ "scvtfd $dst, $src \t// l2d" %} 13735 13736 ins_encode %{ 13737 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13738 %} 13739 13740 ins_pipe(fp_l2d); 13741 %} 13742 13743 // stack <-> reg and reg <-> reg shuffles with no conversion 13744 13745 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13746 13747 match(Set dst (MoveF2I src)); 13748 13749 effect(DEF dst, USE src); 13750 13751 ins_cost(4 * INSN_COST); 13752 13753 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13754 13755 ins_encode %{ 13756 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13757 %} 13758 13759 ins_pipe(iload_reg_reg); 13760 13761 %} 13762 13763 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13764 13765 match(Set dst (MoveI2F src)); 13766 13767 effect(DEF dst, USE src); 13768 13769 ins_cost(4 * INSN_COST); 13770 13771 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13772 13773 ins_encode %{ 13774 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13775 %} 13776 13777 ins_pipe(pipe_class_memory); 13778 13779 %} 13780 13781 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13782 13783 match(Set dst (MoveD2L src)); 13784 13785 effect(DEF dst, USE src); 13786 13787 ins_cost(4 * INSN_COST); 13788 13789 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13790 13791 ins_encode %{ 13792 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13793 %} 13794 13795 ins_pipe(iload_reg_reg); 13796 13797 %} 13798 13799 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13800 13801 match(Set dst (MoveL2D src)); 13802 13803 effect(DEF dst, USE src); 13804 13805 ins_cost(4 * INSN_COST); 13806 13807 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13808 13809 ins_encode %{ 13810 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13811 %} 13812 13813 ins_pipe(pipe_class_memory); 13814 13815 %} 13816 13817 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13818 13819 match(Set dst (MoveF2I src)); 13820 13821 effect(DEF dst, USE src); 13822 13823 ins_cost(INSN_COST); 13824 13825 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13826 13827 ins_encode %{ 13828 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13829 %} 13830 13831 ins_pipe(pipe_class_memory); 13832 13833 %} 13834 13835 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13836 13837 match(Set dst (MoveI2F src)); 13838 13839 effect(DEF dst, USE src); 13840 13841 ins_cost(INSN_COST); 13842 13843 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13844 13845 ins_encode %{ 13846 __ strw($src$$Register, Address(sp, $dst$$disp)); 13847 %} 13848 13849 ins_pipe(istore_reg_reg); 13850 13851 %} 13852 13853 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13854 13855 match(Set dst (MoveD2L src)); 13856 13857 effect(DEF dst, USE src); 13858 13859 ins_cost(INSN_COST); 13860 13861 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13862 13863 ins_encode %{ 13864 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13865 %} 13866 13867 ins_pipe(pipe_class_memory); 13868 13869 %} 13870 13871 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13872 13873 match(Set dst (MoveL2D src)); 13874 13875 effect(DEF dst, USE src); 13876 13877 ins_cost(INSN_COST); 13878 13879 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13880 13881 ins_encode %{ 13882 __ str($src$$Register, Address(sp, $dst$$disp)); 13883 %} 13884 13885 ins_pipe(istore_reg_reg); 13886 13887 %} 13888 13889 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13890 13891 match(Set dst (MoveF2I src)); 13892 13893 effect(DEF dst, USE src); 13894 13895 ins_cost(INSN_COST); 13896 13897 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13898 13899 ins_encode %{ 13900 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13901 %} 13902 13903 ins_pipe(fp_f2i); 13904 13905 %} 13906 13907 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13908 13909 match(Set dst (MoveI2F src)); 13910 13911 effect(DEF dst, USE src); 13912 13913 ins_cost(INSN_COST); 13914 13915 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13916 13917 ins_encode %{ 13918 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13919 %} 13920 13921 ins_pipe(fp_i2f); 13922 13923 %} 13924 13925 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13926 13927 match(Set dst (MoveD2L src)); 13928 13929 effect(DEF dst, USE src); 13930 13931 ins_cost(INSN_COST); 13932 13933 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13934 13935 ins_encode %{ 13936 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13937 %} 13938 13939 ins_pipe(fp_d2l); 13940 13941 %} 13942 13943 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13944 13945 match(Set dst (MoveL2D src)); 13946 13947 effect(DEF dst, USE src); 13948 13949 ins_cost(INSN_COST); 13950 13951 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13952 13953 ins_encode %{ 13954 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13955 %} 13956 13957 ins_pipe(fp_l2d); 13958 13959 %} 13960 13961 // ============================================================================ 13962 // clearing of an array 13963 13964 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13965 %{ 13966 match(Set dummy (ClearArray cnt base)); 13967 effect(USE_KILL cnt, USE_KILL base); 13968 13969 ins_cost(4 * INSN_COST); 13970 format %{ "ClearArray $cnt, $base" %} 13971 13972 ins_encode %{ 13973 __ zero_words($base$$Register, $cnt$$Register); 13974 %} 13975 13976 ins_pipe(pipe_class_memory); 13977 %} 13978 13979 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13980 %{ 13981 predicate((u_int64_t)n->in(2)->get_long() 13982 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13983 match(Set dummy (ClearArray cnt base)); 13984 effect(USE_KILL base); 13985 13986 ins_cost(4 * INSN_COST); 13987 format %{ "ClearArray $cnt, $base" %} 13988 13989 ins_encode %{ 13990 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 13991 %} 13992 13993 ins_pipe(pipe_class_memory); 13994 %} 13995 13996 // ============================================================================ 13997 // Overflow Math Instructions 13998 13999 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14000 %{ 14001 match(Set cr (OverflowAddI op1 op2)); 14002 14003 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14004 ins_cost(INSN_COST); 14005 ins_encode %{ 14006 __ cmnw($op1$$Register, $op2$$Register); 14007 %} 14008 14009 ins_pipe(icmp_reg_reg); 14010 %} 14011 14012 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14013 %{ 14014 match(Set cr (OverflowAddI op1 op2)); 14015 14016 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14017 ins_cost(INSN_COST); 14018 ins_encode %{ 14019 __ cmnw($op1$$Register, $op2$$constant); 14020 %} 14021 14022 ins_pipe(icmp_reg_imm); 14023 %} 14024 14025 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14026 %{ 14027 match(Set cr (OverflowAddL op1 op2)); 14028 14029 format %{ "cmn $op1, $op2\t# overflow check long" %} 14030 ins_cost(INSN_COST); 14031 ins_encode %{ 14032 __ cmn($op1$$Register, $op2$$Register); 14033 %} 14034 14035 ins_pipe(icmp_reg_reg); 14036 %} 14037 14038 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14039 %{ 14040 match(Set cr (OverflowAddL op1 op2)); 14041 14042 format %{ "cmn $op1, $op2\t# overflow check long" %} 14043 ins_cost(INSN_COST); 14044 ins_encode %{ 14045 __ cmn($op1$$Register, $op2$$constant); 14046 %} 14047 14048 ins_pipe(icmp_reg_imm); 14049 %} 14050 14051 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14052 %{ 14053 match(Set cr (OverflowSubI op1 op2)); 14054 14055 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14056 ins_cost(INSN_COST); 14057 ins_encode %{ 14058 __ cmpw($op1$$Register, $op2$$Register); 14059 %} 14060 14061 ins_pipe(icmp_reg_reg); 14062 %} 14063 14064 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14065 %{ 14066 match(Set cr (OverflowSubI op1 op2)); 14067 14068 format %{ "cmpw $op1, $op2\t# overflow check int" %} 14069 ins_cost(INSN_COST); 14070 ins_encode %{ 14071 __ cmpw($op1$$Register, $op2$$constant); 14072 %} 14073 14074 ins_pipe(icmp_reg_imm); 14075 %} 14076 14077 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14078 %{ 14079 match(Set cr (OverflowSubL op1 op2)); 14080 14081 format %{ "cmp $op1, $op2\t# overflow check long" %} 14082 ins_cost(INSN_COST); 14083 ins_encode %{ 14084 __ cmp($op1$$Register, $op2$$Register); 14085 %} 14086 14087 ins_pipe(icmp_reg_reg); 14088 %} 14089 14090 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 14091 %{ 14092 match(Set cr (OverflowSubL op1 op2)); 14093 14094 format %{ "cmp $op1, $op2\t# overflow check long" %} 14095 ins_cost(INSN_COST); 14096 ins_encode %{ 14097 __ subs(zr, $op1$$Register, $op2$$constant); 14098 %} 14099 14100 ins_pipe(icmp_reg_imm); 14101 %} 14102 14103 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 14104 %{ 14105 match(Set cr (OverflowSubI zero op1)); 14106 14107 format %{ "cmpw zr, $op1\t# overflow check int" %} 14108 ins_cost(INSN_COST); 14109 ins_encode %{ 14110 __ cmpw(zr, $op1$$Register); 14111 %} 14112 14113 ins_pipe(icmp_reg_imm); 14114 %} 14115 14116 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 14117 %{ 14118 match(Set cr (OverflowSubL zero op1)); 14119 14120 format %{ "cmp zr, $op1\t# overflow check long" %} 14121 ins_cost(INSN_COST); 14122 ins_encode %{ 14123 __ cmp(zr, $op1$$Register); 14124 %} 14125 14126 ins_pipe(icmp_reg_imm); 14127 %} 14128 14129 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14130 %{ 14131 match(Set cr (OverflowMulI op1 op2)); 14132 14133 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14134 "cmp rscratch1, rscratch1, sxtw\n\t" 14135 "movw rscratch1, #0x80000000\n\t" 14136 "cselw rscratch1, rscratch1, zr, NE\n\t" 14137 "cmpw rscratch1, #1" %} 14138 ins_cost(5 * INSN_COST); 14139 ins_encode %{ 14140 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14141 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14142 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14143 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14144 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14145 %} 14146 14147 ins_pipe(pipe_slow); 14148 %} 14149 14150 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 14151 %{ 14152 match(If cmp (OverflowMulI op1 op2)); 14153 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14154 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14155 effect(USE labl, KILL cr); 14156 14157 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 14158 "cmp rscratch1, rscratch1, sxtw\n\t" 14159 "b$cmp $labl" %} 14160 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 14161 ins_encode %{ 14162 Label* L = $labl$$label; 14163 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14164 __ smull(rscratch1, $op1$$Register, $op2$$Register); 14165 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 14166 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14167 %} 14168 14169 ins_pipe(pipe_serial); 14170 %} 14171 14172 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14173 %{ 14174 match(Set cr (OverflowMulL op1 op2)); 14175 14176 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14177 "smulh rscratch2, $op1, $op2\n\t" 14178 "cmp rscratch2, rscratch1, ASR #63\n\t" 14179 "movw rscratch1, #0x80000000\n\t" 14180 "cselw rscratch1, rscratch1, zr, NE\n\t" 14181 "cmpw rscratch1, #1" %} 14182 ins_cost(6 * INSN_COST); 14183 ins_encode %{ 14184 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14185 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14186 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14187 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 14188 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 14189 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 14190 %} 14191 14192 ins_pipe(pipe_slow); 14193 %} 14194 14195 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 14196 %{ 14197 match(If cmp (OverflowMulL op1 op2)); 14198 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 14199 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 14200 effect(USE labl, KILL cr); 14201 14202 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 14203 "smulh rscratch2, $op1, $op2\n\t" 14204 "cmp rscratch2, rscratch1, ASR #63\n\t" 14205 "b$cmp $labl" %} 14206 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 14207 ins_encode %{ 14208 Label* L = $labl$$label; 14209 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14210 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 14211 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 14212 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 14213 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 14214 %} 14215 14216 ins_pipe(pipe_serial); 14217 %} 14218 14219 // ============================================================================ 14220 // Compare Instructions 14221 14222 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 14223 %{ 14224 match(Set cr (CmpI op1 op2)); 14225 14226 effect(DEF cr, USE op1, USE op2); 14227 14228 ins_cost(INSN_COST); 14229 format %{ "cmpw $op1, $op2" %} 14230 14231 ins_encode(aarch64_enc_cmpw(op1, op2)); 14232 14233 ins_pipe(icmp_reg_reg); 14234 %} 14235 14236 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 14237 %{ 14238 match(Set cr (CmpI op1 zero)); 14239 14240 effect(DEF cr, USE op1); 14241 14242 ins_cost(INSN_COST); 14243 format %{ "cmpw $op1, 0" %} 14244 14245 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14246 14247 ins_pipe(icmp_reg_imm); 14248 %} 14249 14250 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 14251 %{ 14252 match(Set cr (CmpI op1 op2)); 14253 14254 effect(DEF cr, USE op1); 14255 14256 ins_cost(INSN_COST); 14257 format %{ "cmpw $op1, $op2" %} 14258 14259 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14260 14261 ins_pipe(icmp_reg_imm); 14262 %} 14263 14264 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14265 %{ 14266 match(Set cr (CmpI op1 op2)); 14267 14268 effect(DEF cr, USE op1); 14269 14270 ins_cost(INSN_COST * 2); 14271 format %{ "cmpw $op1, $op2" %} 14272 14273 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14274 14275 ins_pipe(icmp_reg_imm); 14276 %} 14277 14278 // Unsigned compare Instructions; really, same as signed compare 14279 // except it should only be used to feed an If or a CMovI which takes a 14280 // cmpOpU. 14281 14282 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14283 %{ 14284 match(Set cr (CmpU op1 op2)); 14285 14286 effect(DEF cr, USE op1, USE op2); 14287 14288 ins_cost(INSN_COST); 14289 format %{ "cmpw $op1, $op2\t# unsigned" %} 14290 14291 ins_encode(aarch64_enc_cmpw(op1, op2)); 14292 14293 ins_pipe(icmp_reg_reg); 14294 %} 14295 14296 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14297 %{ 14298 match(Set cr (CmpU op1 zero)); 14299 14300 effect(DEF cr, USE op1); 14301 14302 ins_cost(INSN_COST); 14303 format %{ "cmpw $op1, #0\t# unsigned" %} 14304 14305 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14306 14307 ins_pipe(icmp_reg_imm); 14308 %} 14309 14310 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14311 %{ 14312 match(Set cr (CmpU op1 op2)); 14313 14314 effect(DEF cr, USE op1); 14315 14316 ins_cost(INSN_COST); 14317 format %{ "cmpw $op1, $op2\t# unsigned" %} 14318 14319 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14320 14321 ins_pipe(icmp_reg_imm); 14322 %} 14323 14324 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14325 %{ 14326 match(Set cr (CmpU op1 op2)); 14327 14328 effect(DEF cr, USE op1); 14329 14330 ins_cost(INSN_COST * 2); 14331 format %{ "cmpw $op1, $op2\t# unsigned" %} 14332 14333 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14334 14335 ins_pipe(icmp_reg_imm); 14336 %} 14337 14338 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14339 %{ 14340 match(Set cr (CmpL op1 op2)); 14341 14342 effect(DEF cr, USE op1, USE op2); 14343 14344 ins_cost(INSN_COST); 14345 format %{ "cmp $op1, $op2" %} 14346 14347 ins_encode(aarch64_enc_cmp(op1, op2)); 14348 14349 ins_pipe(icmp_reg_reg); 14350 %} 14351 14352 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14353 %{ 14354 match(Set cr (CmpL op1 zero)); 14355 14356 effect(DEF cr, USE op1); 14357 14358 ins_cost(INSN_COST); 14359 format %{ "tst $op1" %} 14360 14361 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14362 14363 ins_pipe(icmp_reg_imm); 14364 %} 14365 14366 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14367 %{ 14368 match(Set cr (CmpL op1 op2)); 14369 14370 effect(DEF cr, USE op1); 14371 14372 ins_cost(INSN_COST); 14373 format %{ "cmp $op1, $op2" %} 14374 14375 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14376 14377 ins_pipe(icmp_reg_imm); 14378 %} 14379 14380 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14381 %{ 14382 match(Set cr (CmpL op1 op2)); 14383 14384 effect(DEF cr, USE op1); 14385 14386 ins_cost(INSN_COST * 2); 14387 format %{ "cmp $op1, $op2" %} 14388 14389 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14390 14391 ins_pipe(icmp_reg_imm); 14392 %} 14393 14394 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14395 %{ 14396 match(Set cr (CmpUL op1 op2)); 14397 14398 effect(DEF cr, USE op1, USE op2); 14399 14400 ins_cost(INSN_COST); 14401 format %{ "cmp $op1, $op2" %} 14402 14403 ins_encode(aarch64_enc_cmp(op1, op2)); 14404 14405 ins_pipe(icmp_reg_reg); 14406 %} 14407 14408 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14409 %{ 14410 match(Set cr (CmpUL op1 zero)); 14411 14412 effect(DEF cr, USE op1); 14413 14414 ins_cost(INSN_COST); 14415 format %{ "tst $op1" %} 14416 14417 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14418 14419 ins_pipe(icmp_reg_imm); 14420 %} 14421 14422 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14423 %{ 14424 match(Set cr (CmpUL op1 op2)); 14425 14426 effect(DEF cr, USE op1); 14427 14428 ins_cost(INSN_COST); 14429 format %{ "cmp $op1, $op2" %} 14430 14431 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14432 14433 ins_pipe(icmp_reg_imm); 14434 %} 14435 14436 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14437 %{ 14438 match(Set cr (CmpUL op1 op2)); 14439 14440 effect(DEF cr, USE op1); 14441 14442 ins_cost(INSN_COST * 2); 14443 format %{ "cmp $op1, $op2" %} 14444 14445 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14446 14447 ins_pipe(icmp_reg_imm); 14448 %} 14449 14450 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14451 %{ 14452 match(Set cr (CmpP op1 op2)); 14453 14454 effect(DEF cr, USE op1, USE op2); 14455 14456 ins_cost(INSN_COST); 14457 format %{ "cmp $op1, $op2\t // ptr" %} 14458 14459 ins_encode(aarch64_enc_cmpp(op1, op2)); 14460 14461 ins_pipe(icmp_reg_reg); 14462 %} 14463 14464 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14465 %{ 14466 match(Set cr (CmpN op1 op2)); 14467 14468 effect(DEF cr, USE op1, USE op2); 14469 14470 ins_cost(INSN_COST); 14471 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14472 14473 ins_encode(aarch64_enc_cmpn(op1, op2)); 14474 14475 ins_pipe(icmp_reg_reg); 14476 %} 14477 14478 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14479 %{ 14480 match(Set cr (CmpP op1 zero)); 14481 14482 effect(DEF cr, USE op1, USE zero); 14483 14484 ins_cost(INSN_COST); 14485 format %{ "cmp $op1, 0\t // ptr" %} 14486 14487 ins_encode(aarch64_enc_testp(op1)); 14488 14489 ins_pipe(icmp_reg_imm); 14490 %} 14491 14492 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14493 %{ 14494 match(Set cr (CmpN op1 zero)); 14495 14496 effect(DEF cr, USE op1, USE zero); 14497 14498 ins_cost(INSN_COST); 14499 format %{ "cmp $op1, 0\t // compressed ptr" %} 14500 14501 ins_encode(aarch64_enc_testn(op1)); 14502 14503 ins_pipe(icmp_reg_imm); 14504 %} 14505 14506 // FP comparisons 14507 // 14508 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 14509 // using normal cmpOp. See declaration of rFlagsReg for details. 14510 14511 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14512 %{ 14513 match(Set cr (CmpF src1 src2)); 14514 14515 ins_cost(3 * INSN_COST); 14516 format %{ "fcmps $src1, $src2" %} 14517 14518 ins_encode %{ 14519 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14520 %} 14521 14522 ins_pipe(pipe_class_compare); 14523 %} 14524 14525 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14526 %{ 14527 match(Set cr (CmpF src1 src2)); 14528 14529 ins_cost(3 * INSN_COST); 14530 format %{ "fcmps $src1, 0.0" %} 14531 14532 ins_encode %{ 14533 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14534 %} 14535 14536 ins_pipe(pipe_class_compare); 14537 %} 14538 // FROM HERE 14539 14540 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14541 %{ 14542 match(Set cr (CmpD src1 src2)); 14543 14544 ins_cost(3 * INSN_COST); 14545 format %{ "fcmpd $src1, $src2" %} 14546 14547 ins_encode %{ 14548 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14549 %} 14550 14551 ins_pipe(pipe_class_compare); 14552 %} 14553 14554 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14555 %{ 14556 match(Set cr (CmpD src1 src2)); 14557 14558 ins_cost(3 * INSN_COST); 14559 format %{ "fcmpd $src1, 0.0" %} 14560 14561 ins_encode %{ 14562 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14563 %} 14564 14565 ins_pipe(pipe_class_compare); 14566 %} 14567 14568 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14569 %{ 14570 match(Set dst (CmpF3 src1 src2)); 14571 effect(KILL cr); 14572 14573 ins_cost(5 * INSN_COST); 14574 format %{ "fcmps $src1, $src2\n\t" 14575 "csinvw($dst, zr, zr, eq\n\t" 14576 "csnegw($dst, $dst, $dst, lt)" 14577 %} 14578 14579 ins_encode %{ 14580 Label done; 14581 FloatRegister s1 = as_FloatRegister($src1$$reg); 14582 FloatRegister s2 = as_FloatRegister($src2$$reg); 14583 Register d = as_Register($dst$$reg); 14584 __ fcmps(s1, s2); 14585 // installs 0 if EQ else -1 14586 __ csinvw(d, zr, zr, Assembler::EQ); 14587 // keeps -1 if less or unordered else installs 1 14588 __ csnegw(d, d, d, Assembler::LT); 14589 __ bind(done); 14590 %} 14591 14592 ins_pipe(pipe_class_default); 14593 14594 %} 14595 14596 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14597 %{ 14598 match(Set dst (CmpD3 src1 src2)); 14599 effect(KILL cr); 14600 14601 ins_cost(5 * INSN_COST); 14602 format %{ "fcmpd $src1, $src2\n\t" 14603 "csinvw($dst, zr, zr, eq\n\t" 14604 "csnegw($dst, $dst, $dst, lt)" 14605 %} 14606 14607 ins_encode %{ 14608 Label done; 14609 FloatRegister s1 = as_FloatRegister($src1$$reg); 14610 FloatRegister s2 = as_FloatRegister($src2$$reg); 14611 Register d = as_Register($dst$$reg); 14612 __ fcmpd(s1, s2); 14613 // installs 0 if EQ else -1 14614 __ csinvw(d, zr, zr, Assembler::EQ); 14615 // keeps -1 if less or unordered else installs 1 14616 __ csnegw(d, d, d, Assembler::LT); 14617 __ bind(done); 14618 %} 14619 ins_pipe(pipe_class_default); 14620 14621 %} 14622 14623 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14624 %{ 14625 match(Set dst (CmpF3 src1 zero)); 14626 effect(KILL cr); 14627 14628 ins_cost(5 * INSN_COST); 14629 format %{ "fcmps $src1, 0.0\n\t" 14630 "csinvw($dst, zr, zr, eq\n\t" 14631 "csnegw($dst, $dst, $dst, lt)" 14632 %} 14633 14634 ins_encode %{ 14635 Label done; 14636 FloatRegister s1 = as_FloatRegister($src1$$reg); 14637 Register d = as_Register($dst$$reg); 14638 __ fcmps(s1, 0.0); 14639 // installs 0 if EQ else -1 14640 __ csinvw(d, zr, zr, Assembler::EQ); 14641 // keeps -1 if less or unordered else installs 1 14642 __ csnegw(d, d, d, Assembler::LT); 14643 __ bind(done); 14644 %} 14645 14646 ins_pipe(pipe_class_default); 14647 14648 %} 14649 14650 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14651 %{ 14652 match(Set dst (CmpD3 src1 zero)); 14653 effect(KILL cr); 14654 14655 ins_cost(5 * INSN_COST); 14656 format %{ "fcmpd $src1, 0.0\n\t" 14657 "csinvw($dst, zr, zr, eq\n\t" 14658 "csnegw($dst, $dst, $dst, lt)" 14659 %} 14660 14661 ins_encode %{ 14662 Label done; 14663 FloatRegister s1 = as_FloatRegister($src1$$reg); 14664 Register d = as_Register($dst$$reg); 14665 __ fcmpd(s1, 0.0); 14666 // installs 0 if EQ else -1 14667 __ csinvw(d, zr, zr, Assembler::EQ); 14668 // keeps -1 if less or unordered else installs 1 14669 __ csnegw(d, d, d, Assembler::LT); 14670 __ bind(done); 14671 %} 14672 ins_pipe(pipe_class_default); 14673 14674 %} 14675 14676 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14677 %{ 14678 match(Set dst (CmpLTMask p q)); 14679 effect(KILL cr); 14680 14681 ins_cost(3 * INSN_COST); 14682 14683 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14684 "csetw $dst, lt\n\t" 14685 "subw $dst, zr, $dst" 14686 %} 14687 14688 ins_encode %{ 14689 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14690 __ csetw(as_Register($dst$$reg), Assembler::LT); 14691 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14692 %} 14693 14694 ins_pipe(ialu_reg_reg); 14695 %} 14696 14697 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14698 %{ 14699 match(Set dst (CmpLTMask src zero)); 14700 effect(KILL cr); 14701 14702 ins_cost(INSN_COST); 14703 14704 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14705 14706 ins_encode %{ 14707 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14708 %} 14709 14710 ins_pipe(ialu_reg_shift); 14711 %} 14712 14713 // ============================================================================ 14714 // Max and Min 14715 14716 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14717 %{ 14718 effect( DEF dst, USE src1, USE src2, USE cr ); 14719 14720 ins_cost(INSN_COST * 2); 14721 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14722 14723 ins_encode %{ 14724 __ cselw(as_Register($dst$$reg), 14725 as_Register($src1$$reg), 14726 as_Register($src2$$reg), 14727 Assembler::LT); 14728 %} 14729 14730 ins_pipe(icond_reg_reg); 14731 %} 14732 14733 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14734 %{ 14735 match(Set dst (MinI src1 src2)); 14736 ins_cost(INSN_COST * 3); 14737 14738 expand %{ 14739 rFlagsReg cr; 14740 compI_reg_reg(cr, src1, src2); 14741 cmovI_reg_reg_lt(dst, src1, src2, cr); 14742 %} 14743 14744 %} 14745 // FROM HERE 14746 14747 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14748 %{ 14749 effect( DEF dst, USE src1, USE src2, USE cr ); 14750 14751 ins_cost(INSN_COST * 2); 14752 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14753 14754 ins_encode %{ 14755 __ cselw(as_Register($dst$$reg), 14756 as_Register($src1$$reg), 14757 as_Register($src2$$reg), 14758 Assembler::GT); 14759 %} 14760 14761 ins_pipe(icond_reg_reg); 14762 %} 14763 14764 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14765 %{ 14766 match(Set dst (MaxI src1 src2)); 14767 ins_cost(INSN_COST * 3); 14768 expand %{ 14769 rFlagsReg cr; 14770 compI_reg_reg(cr, src1, src2); 14771 cmovI_reg_reg_gt(dst, src1, src2, cr); 14772 %} 14773 %} 14774 14775 // ============================================================================ 14776 // Branch Instructions 14777 14778 // Direct Branch. 14779 instruct branch(label lbl) 14780 %{ 14781 match(Goto); 14782 14783 effect(USE lbl); 14784 14785 ins_cost(BRANCH_COST); 14786 format %{ "b $lbl" %} 14787 14788 ins_encode(aarch64_enc_b(lbl)); 14789 14790 ins_pipe(pipe_branch); 14791 %} 14792 14793 // Conditional Near Branch 14794 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14795 %{ 14796 // Same match rule as `branchConFar'. 14797 match(If cmp cr); 14798 14799 effect(USE lbl); 14800 14801 ins_cost(BRANCH_COST); 14802 // If set to 1 this indicates that the current instruction is a 14803 // short variant of a long branch. This avoids using this 14804 // instruction in first-pass matching. It will then only be used in 14805 // the `Shorten_branches' pass. 14806 // ins_short_branch(1); 14807 format %{ "b$cmp $lbl" %} 14808 14809 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14810 14811 ins_pipe(pipe_branch_cond); 14812 %} 14813 14814 // Conditional Near Branch Unsigned 14815 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14816 %{ 14817 // Same match rule as `branchConFar'. 14818 match(If cmp cr); 14819 14820 effect(USE lbl); 14821 14822 ins_cost(BRANCH_COST); 14823 // If set to 1 this indicates that the current instruction is a 14824 // short variant of a long branch. This avoids using this 14825 // instruction in first-pass matching. It will then only be used in 14826 // the `Shorten_branches' pass. 14827 // ins_short_branch(1); 14828 format %{ "b$cmp $lbl\t# unsigned" %} 14829 14830 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14831 14832 ins_pipe(pipe_branch_cond); 14833 %} 14834 14835 // Make use of CBZ and CBNZ. These instructions, as well as being 14836 // shorter than (cmp; branch), have the additional benefit of not 14837 // killing the flags. 14838 14839 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14840 match(If cmp (CmpI op1 op2)); 14841 effect(USE labl); 14842 14843 ins_cost(BRANCH_COST); 14844 format %{ "cbw$cmp $op1, $labl" %} 14845 ins_encode %{ 14846 Label* L = $labl$$label; 14847 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14848 if (cond == Assembler::EQ) 14849 __ cbzw($op1$$Register, *L); 14850 else 14851 __ cbnzw($op1$$Register, *L); 14852 %} 14853 ins_pipe(pipe_cmp_branch); 14854 %} 14855 14856 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14857 match(If cmp (CmpL op1 op2)); 14858 effect(USE labl); 14859 14860 ins_cost(BRANCH_COST); 14861 format %{ "cb$cmp $op1, $labl" %} 14862 ins_encode %{ 14863 Label* L = $labl$$label; 14864 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14865 if (cond == Assembler::EQ) 14866 __ cbz($op1$$Register, *L); 14867 else 14868 __ cbnz($op1$$Register, *L); 14869 %} 14870 ins_pipe(pipe_cmp_branch); 14871 %} 14872 14873 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14874 match(If cmp (CmpP op1 op2)); 14875 effect(USE labl); 14876 14877 ins_cost(BRANCH_COST); 14878 format %{ "cb$cmp $op1, $labl" %} 14879 ins_encode %{ 14880 Label* L = $labl$$label; 14881 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14882 if (cond == Assembler::EQ) 14883 __ cbz($op1$$Register, *L); 14884 else 14885 __ cbnz($op1$$Register, *L); 14886 %} 14887 ins_pipe(pipe_cmp_branch); 14888 %} 14889 14890 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14891 match(If cmp (CmpN op1 op2)); 14892 effect(USE labl); 14893 14894 ins_cost(BRANCH_COST); 14895 format %{ "cbw$cmp $op1, $labl" %} 14896 ins_encode %{ 14897 Label* L = $labl$$label; 14898 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14899 if (cond == Assembler::EQ) 14900 __ cbzw($op1$$Register, *L); 14901 else 14902 __ cbnzw($op1$$Register, *L); 14903 %} 14904 ins_pipe(pipe_cmp_branch); 14905 %} 14906 14907 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14908 match(If cmp (CmpP (DecodeN oop) zero)); 14909 effect(USE labl); 14910 14911 ins_cost(BRANCH_COST); 14912 format %{ "cb$cmp $oop, $labl" %} 14913 ins_encode %{ 14914 Label* L = $labl$$label; 14915 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14916 if (cond == Assembler::EQ) 14917 __ cbzw($oop$$Register, *L); 14918 else 14919 __ cbnzw($oop$$Register, *L); 14920 %} 14921 ins_pipe(pipe_cmp_branch); 14922 %} 14923 14924 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14925 match(If cmp (CmpU op1 op2)); 14926 effect(USE labl); 14927 14928 ins_cost(BRANCH_COST); 14929 format %{ "cbw$cmp $op1, $labl" %} 14930 ins_encode %{ 14931 Label* L = $labl$$label; 14932 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14933 if (cond == Assembler::EQ || cond == Assembler::LS) 14934 __ cbzw($op1$$Register, *L); 14935 else 14936 __ cbnzw($op1$$Register, *L); 14937 %} 14938 ins_pipe(pipe_cmp_branch); 14939 %} 14940 14941 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14942 match(If cmp (CmpUL op1 op2)); 14943 effect(USE labl); 14944 14945 ins_cost(BRANCH_COST); 14946 format %{ "cb$cmp $op1, $labl" %} 14947 ins_encode %{ 14948 Label* L = $labl$$label; 14949 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14950 if (cond == Assembler::EQ || cond == Assembler::LS) 14951 __ cbz($op1$$Register, *L); 14952 else 14953 __ cbnz($op1$$Register, *L); 14954 %} 14955 ins_pipe(pipe_cmp_branch); 14956 %} 14957 14958 // Test bit and Branch 14959 14960 // Patterns for short (< 32KiB) variants 14961 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14962 match(If cmp (CmpL op1 op2)); 14963 effect(USE labl); 14964 14965 ins_cost(BRANCH_COST); 14966 format %{ "cb$cmp $op1, $labl # long" %} 14967 ins_encode %{ 14968 Label* L = $labl$$label; 14969 Assembler::Condition cond = 14970 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14971 __ tbr(cond, $op1$$Register, 63, *L); 14972 %} 14973 ins_pipe(pipe_cmp_branch); 14974 ins_short_branch(1); 14975 %} 14976 14977 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14978 match(If cmp (CmpI op1 op2)); 14979 effect(USE labl); 14980 14981 ins_cost(BRANCH_COST); 14982 format %{ "cb$cmp $op1, $labl # int" %} 14983 ins_encode %{ 14984 Label* L = $labl$$label; 14985 Assembler::Condition cond = 14986 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14987 __ tbr(cond, $op1$$Register, 31, *L); 14988 %} 14989 ins_pipe(pipe_cmp_branch); 14990 ins_short_branch(1); 14991 %} 14992 14993 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14994 match(If cmp (CmpL (AndL op1 op2) op3)); 14995 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14996 effect(USE labl); 14997 14998 ins_cost(BRANCH_COST); 14999 format %{ "tb$cmp $op1, $op2, $labl" %} 15000 ins_encode %{ 15001 Label* L = $labl$$label; 15002 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15003 int bit = exact_log2($op2$$constant); 15004 __ tbr(cond, $op1$$Register, bit, *L); 15005 %} 15006 ins_pipe(pipe_cmp_branch); 15007 ins_short_branch(1); 15008 %} 15009 15010 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15011 match(If cmp (CmpI (AndI op1 op2) op3)); 15012 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 15013 effect(USE labl); 15014 15015 ins_cost(BRANCH_COST); 15016 format %{ "tb$cmp $op1, $op2, $labl" %} 15017 ins_encode %{ 15018 Label* L = $labl$$label; 15019 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15020 int bit = exact_log2($op2$$constant); 15021 __ tbr(cond, $op1$$Register, bit, *L); 15022 %} 15023 ins_pipe(pipe_cmp_branch); 15024 ins_short_branch(1); 15025 %} 15026 15027 // And far variants 15028 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15029 match(If cmp (CmpL op1 op2)); 15030 effect(USE labl); 15031 15032 ins_cost(BRANCH_COST); 15033 format %{ "cb$cmp $op1, $labl # long" %} 15034 ins_encode %{ 15035 Label* L = $labl$$label; 15036 Assembler::Condition cond = 15037 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15038 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 15039 %} 15040 ins_pipe(pipe_cmp_branch); 15041 %} 15042 15043 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15044 match(If cmp (CmpI op1 op2)); 15045 effect(USE labl); 15046 15047 ins_cost(BRANCH_COST); 15048 format %{ "cb$cmp $op1, $labl # int" %} 15049 ins_encode %{ 15050 Label* L = $labl$$label; 15051 Assembler::Condition cond = 15052 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15053 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 15054 %} 15055 ins_pipe(pipe_cmp_branch); 15056 %} 15057 15058 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15059 match(If cmp (CmpL (AndL op1 op2) op3)); 15060 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 15061 effect(USE labl); 15062 15063 ins_cost(BRANCH_COST); 15064 format %{ "tb$cmp $op1, $op2, $labl" %} 15065 ins_encode %{ 15066 Label* L = $labl$$label; 15067 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15068 int bit = exact_log2($op2$$constant); 15069 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15070 %} 15071 ins_pipe(pipe_cmp_branch); 15072 %} 15073 15074 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15075 match(If cmp (CmpI (AndI op1 op2) op3)); 15076 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 15077 effect(USE labl); 15078 15079 ins_cost(BRANCH_COST); 15080 format %{ "tb$cmp $op1, $op2, $labl" %} 15081 ins_encode %{ 15082 Label* L = $labl$$label; 15083 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15084 int bit = exact_log2($op2$$constant); 15085 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 15086 %} 15087 ins_pipe(pipe_cmp_branch); 15088 %} 15089 15090 // Test bits 15091 15092 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 15093 match(Set cr (CmpL (AndL op1 op2) op3)); 15094 predicate(Assembler::operand_valid_for_logical_immediate 15095 (/*is_32*/false, n->in(1)->in(2)->get_long())); 15096 15097 ins_cost(INSN_COST); 15098 format %{ "tst $op1, $op2 # long" %} 15099 ins_encode %{ 15100 __ tst($op1$$Register, $op2$$constant); 15101 %} 15102 ins_pipe(ialu_reg_reg); 15103 %} 15104 15105 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 15106 match(Set cr (CmpI (AndI op1 op2) op3)); 15107 predicate(Assembler::operand_valid_for_logical_immediate 15108 (/*is_32*/true, n->in(1)->in(2)->get_int())); 15109 15110 ins_cost(INSN_COST); 15111 format %{ "tst $op1, $op2 # int" %} 15112 ins_encode %{ 15113 __ tstw($op1$$Register, $op2$$constant); 15114 %} 15115 ins_pipe(ialu_reg_reg); 15116 %} 15117 15118 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 15119 match(Set cr (CmpL (AndL op1 op2) op3)); 15120 15121 ins_cost(INSN_COST); 15122 format %{ "tst $op1, $op2 # long" %} 15123 ins_encode %{ 15124 __ tst($op1$$Register, $op2$$Register); 15125 %} 15126 ins_pipe(ialu_reg_reg); 15127 %} 15128 15129 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 15130 match(Set cr (CmpI (AndI op1 op2) op3)); 15131 15132 ins_cost(INSN_COST); 15133 format %{ "tstw $op1, $op2 # int" %} 15134 ins_encode %{ 15135 __ tstw($op1$$Register, $op2$$Register); 15136 %} 15137 ins_pipe(ialu_reg_reg); 15138 %} 15139 15140 15141 // Conditional Far Branch 15142 // Conditional Far Branch Unsigned 15143 // TODO: fixme 15144 15145 // counted loop end branch near 15146 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 15147 %{ 15148 match(CountedLoopEnd cmp cr); 15149 15150 effect(USE lbl); 15151 15152 ins_cost(BRANCH_COST); 15153 // short variant. 15154 // ins_short_branch(1); 15155 format %{ "b$cmp $lbl \t// counted loop end" %} 15156 15157 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15158 15159 ins_pipe(pipe_branch); 15160 %} 15161 15162 // counted loop end branch near Unsigned 15163 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15164 %{ 15165 match(CountedLoopEnd cmp cr); 15166 15167 effect(USE lbl); 15168 15169 ins_cost(BRANCH_COST); 15170 // short variant. 15171 // ins_short_branch(1); 15172 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 15173 15174 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15175 15176 ins_pipe(pipe_branch); 15177 %} 15178 15179 // counted loop end branch far 15180 // counted loop end branch far unsigned 15181 // TODO: fixme 15182 15183 // ============================================================================ 15184 // inlined locking and unlocking 15185 15186 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15187 %{ 15188 match(Set cr (FastLock object box)); 15189 effect(TEMP tmp, TEMP tmp2); 15190 15191 // TODO 15192 // identify correct cost 15193 ins_cost(5 * INSN_COST); 15194 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 15195 15196 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 15197 15198 ins_pipe(pipe_serial); 15199 %} 15200 15201 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 15202 %{ 15203 match(Set cr (FastUnlock object box)); 15204 effect(TEMP tmp, TEMP tmp2); 15205 15206 ins_cost(5 * INSN_COST); 15207 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 15208 15209 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 15210 15211 ins_pipe(pipe_serial); 15212 %} 15213 15214 15215 // ============================================================================ 15216 // Safepoint Instructions 15217 15218 // TODO 15219 // provide a near and far version of this code 15220 15221 instruct safePoint(rFlagsReg cr, iRegP poll) 15222 %{ 15223 match(SafePoint poll); 15224 effect(KILL cr); 15225 15226 format %{ 15227 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 15228 %} 15229 ins_encode %{ 15230 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 15231 %} 15232 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 15233 %} 15234 15235 15236 // ============================================================================ 15237 // Procedure Call/Return Instructions 15238 15239 // Call Java Static Instruction 15240 15241 instruct CallStaticJavaDirect(method meth) 15242 %{ 15243 match(CallStaticJava); 15244 15245 effect(USE meth); 15246 15247 ins_cost(CALL_COST); 15248 15249 format %{ "call,static $meth \t// ==> " %} 15250 15251 ins_encode( aarch64_enc_java_static_call(meth), 15252 aarch64_enc_call_epilog ); 15253 15254 ins_pipe(pipe_class_call); 15255 %} 15256 15257 // TO HERE 15258 15259 // Call Java Dynamic Instruction 15260 instruct CallDynamicJavaDirect(method meth) 15261 %{ 15262 match(CallDynamicJava); 15263 15264 effect(USE meth); 15265 15266 ins_cost(CALL_COST); 15267 15268 format %{ "CALL,dynamic $meth \t// ==> " %} 15269 15270 ins_encode( aarch64_enc_java_dynamic_call(meth), 15271 aarch64_enc_call_epilog ); 15272 15273 ins_pipe(pipe_class_call); 15274 %} 15275 15276 // Call Runtime Instruction 15277 15278 instruct CallRuntimeDirect(method meth) 15279 %{ 15280 match(CallRuntime); 15281 15282 effect(USE meth); 15283 15284 ins_cost(CALL_COST); 15285 15286 format %{ "CALL, runtime $meth" %} 15287 15288 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15289 15290 ins_pipe(pipe_class_call); 15291 %} 15292 15293 // Call Runtime Instruction 15294 15295 instruct CallLeafDirect(method meth) 15296 %{ 15297 match(CallLeaf); 15298 15299 effect(USE meth); 15300 15301 ins_cost(CALL_COST); 15302 15303 format %{ "CALL, runtime leaf $meth" %} 15304 15305 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15306 15307 ins_pipe(pipe_class_call); 15308 %} 15309 15310 // Call Runtime Instruction 15311 15312 instruct CallLeafNoFPDirect(method meth) 15313 %{ 15314 match(CallLeafNoFP); 15315 15316 effect(USE meth); 15317 15318 ins_cost(CALL_COST); 15319 15320 format %{ "CALL, runtime leaf nofp $meth" %} 15321 15322 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15323 15324 ins_pipe(pipe_class_call); 15325 %} 15326 15327 // Tail Call; Jump from runtime stub to Java code. 15328 // Also known as an 'interprocedural jump'. 15329 // Target of jump will eventually return to caller. 15330 // TailJump below removes the return address. 15331 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15332 %{ 15333 match(TailCall jump_target method_oop); 15334 15335 ins_cost(CALL_COST); 15336 15337 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15338 15339 ins_encode(aarch64_enc_tail_call(jump_target)); 15340 15341 ins_pipe(pipe_class_call); 15342 %} 15343 15344 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15345 %{ 15346 match(TailJump jump_target ex_oop); 15347 15348 ins_cost(CALL_COST); 15349 15350 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15351 15352 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15353 15354 ins_pipe(pipe_class_call); 15355 %} 15356 15357 // Create exception oop: created by stack-crawling runtime code. 15358 // Created exception is now available to this handler, and is setup 15359 // just prior to jumping to this handler. No code emitted. 15360 // TODO check 15361 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15362 instruct CreateException(iRegP_R0 ex_oop) 15363 %{ 15364 match(Set ex_oop (CreateEx)); 15365 15366 format %{ " -- \t// exception oop; no code emitted" %} 15367 15368 size(0); 15369 15370 ins_encode( /*empty*/ ); 15371 15372 ins_pipe(pipe_class_empty); 15373 %} 15374 15375 // Rethrow exception: The exception oop will come in the first 15376 // argument position. Then JUMP (not call) to the rethrow stub code. 15377 instruct RethrowException() %{ 15378 match(Rethrow); 15379 ins_cost(CALL_COST); 15380 15381 format %{ "b rethrow_stub" %} 15382 15383 ins_encode( aarch64_enc_rethrow() ); 15384 15385 ins_pipe(pipe_class_call); 15386 %} 15387 15388 15389 // Return Instruction 15390 // epilog node loads ret address into lr as part of frame pop 15391 instruct Ret() 15392 %{ 15393 match(Return); 15394 15395 format %{ "ret\t// return register" %} 15396 15397 ins_encode( aarch64_enc_ret() ); 15398 15399 ins_pipe(pipe_branch); 15400 %} 15401 15402 // Die now. 15403 instruct ShouldNotReachHere() %{ 15404 match(Halt); 15405 15406 ins_cost(CALL_COST); 15407 format %{ "ShouldNotReachHere" %} 15408 15409 ins_encode %{ 15410 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 15411 // return true 15412 __ dpcs1(0xdead + 1); 15413 %} 15414 15415 ins_pipe(pipe_class_default); 15416 %} 15417 15418 // ============================================================================ 15419 // Partial Subtype Check 15420 // 15421 // superklass array for an instance of the superklass. Set a hidden 15422 // internal cache on a hit (cache is checked with exposed code in 15423 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15424 // encoding ALSO sets flags. 15425 15426 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15427 %{ 15428 match(Set result (PartialSubtypeCheck sub super)); 15429 effect(KILL cr, KILL temp); 15430 15431 ins_cost(1100); // slightly larger than the next version 15432 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15433 15434 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15435 15436 opcode(0x1); // Force zero of result reg on hit 15437 15438 ins_pipe(pipe_class_memory); 15439 %} 15440 15441 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15442 %{ 15443 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15444 effect(KILL temp, KILL result); 15445 15446 ins_cost(1100); // slightly larger than the next version 15447 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15448 15449 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15450 15451 opcode(0x0); // Don't zero result reg on hit 15452 15453 ins_pipe(pipe_class_memory); 15454 %} 15455 15456 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15457 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15458 %{ 15459 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15460 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15461 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15462 15463 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15464 ins_encode %{ 15465 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15466 __ string_compare($str1$$Register, $str2$$Register, 15467 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15468 $tmp1$$Register, $tmp2$$Register, 15469 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15470 %} 15471 ins_pipe(pipe_class_memory); 15472 %} 15473 15474 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15475 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15476 %{ 15477 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15478 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15479 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15480 15481 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15482 ins_encode %{ 15483 __ string_compare($str1$$Register, $str2$$Register, 15484 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15485 $tmp1$$Register, $tmp2$$Register, 15486 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15487 %} 15488 ins_pipe(pipe_class_memory); 15489 %} 15490 15491 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15492 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15493 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15494 %{ 15495 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15496 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15497 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15498 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15499 15500 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15501 ins_encode %{ 15502 __ string_compare($str1$$Register, $str2$$Register, 15503 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15504 $tmp1$$Register, $tmp2$$Register, 15505 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15506 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15507 %} 15508 ins_pipe(pipe_class_memory); 15509 %} 15510 15511 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15512 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15513 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15514 %{ 15515 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15516 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15517 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15518 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15519 15520 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15521 ins_encode %{ 15522 __ string_compare($str1$$Register, $str2$$Register, 15523 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15524 $tmp1$$Register, $tmp2$$Register, 15525 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15526 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15527 %} 15528 ins_pipe(pipe_class_memory); 15529 %} 15530 15531 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15532 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15533 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15534 %{ 15535 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15536 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15537 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15538 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15539 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15540 15541 ins_encode %{ 15542 __ string_indexof($str1$$Register, $str2$$Register, 15543 $cnt1$$Register, $cnt2$$Register, 15544 $tmp1$$Register, $tmp2$$Register, 15545 $tmp3$$Register, $tmp4$$Register, 15546 $tmp5$$Register, $tmp6$$Register, 15547 -1, $result$$Register, StrIntrinsicNode::UU); 15548 %} 15549 ins_pipe(pipe_class_memory); 15550 %} 15551 15552 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15553 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15554 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15555 %{ 15556 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15557 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15558 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15559 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15560 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15561 15562 ins_encode %{ 15563 __ string_indexof($str1$$Register, $str2$$Register, 15564 $cnt1$$Register, $cnt2$$Register, 15565 $tmp1$$Register, $tmp2$$Register, 15566 $tmp3$$Register, $tmp4$$Register, 15567 $tmp5$$Register, $tmp6$$Register, 15568 -1, $result$$Register, StrIntrinsicNode::LL); 15569 %} 15570 ins_pipe(pipe_class_memory); 15571 %} 15572 15573 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15574 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15575 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15576 %{ 15577 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15578 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15579 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15580 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15581 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15582 15583 ins_encode %{ 15584 __ string_indexof($str1$$Register, $str2$$Register, 15585 $cnt1$$Register, $cnt2$$Register, 15586 $tmp1$$Register, $tmp2$$Register, 15587 $tmp3$$Register, $tmp4$$Register, 15588 $tmp5$$Register, $tmp6$$Register, 15589 -1, $result$$Register, StrIntrinsicNode::UL); 15590 %} 15591 ins_pipe(pipe_class_memory); 15592 %} 15593 15594 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15595 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15596 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15597 %{ 15598 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15599 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15600 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15601 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15602 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15603 15604 ins_encode %{ 15605 int icnt2 = (int)$int_cnt2$$constant; 15606 __ string_indexof($str1$$Register, $str2$$Register, 15607 $cnt1$$Register, zr, 15608 $tmp1$$Register, $tmp2$$Register, 15609 $tmp3$$Register, $tmp4$$Register, zr, zr, 15610 icnt2, $result$$Register, StrIntrinsicNode::UU); 15611 %} 15612 ins_pipe(pipe_class_memory); 15613 %} 15614 15615 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15616 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15617 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15618 %{ 15619 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15620 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15621 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15622 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15623 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15624 15625 ins_encode %{ 15626 int icnt2 = (int)$int_cnt2$$constant; 15627 __ string_indexof($str1$$Register, $str2$$Register, 15628 $cnt1$$Register, zr, 15629 $tmp1$$Register, $tmp2$$Register, 15630 $tmp3$$Register, $tmp4$$Register, zr, zr, 15631 icnt2, $result$$Register, StrIntrinsicNode::LL); 15632 %} 15633 ins_pipe(pipe_class_memory); 15634 %} 15635 15636 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15637 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15638 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15639 %{ 15640 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15641 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15642 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15643 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15644 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15645 15646 ins_encode %{ 15647 int icnt2 = (int)$int_cnt2$$constant; 15648 __ string_indexof($str1$$Register, $str2$$Register, 15649 $cnt1$$Register, zr, 15650 $tmp1$$Register, $tmp2$$Register, 15651 $tmp3$$Register, $tmp4$$Register, zr, zr, 15652 icnt2, $result$$Register, StrIntrinsicNode::UL); 15653 %} 15654 ins_pipe(pipe_class_memory); 15655 %} 15656 15657 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15658 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15659 iRegINoSp tmp3, rFlagsReg cr) 15660 %{ 15661 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15662 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15663 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15664 15665 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15666 15667 ins_encode %{ 15668 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15669 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15670 $tmp3$$Register); 15671 %} 15672 ins_pipe(pipe_class_memory); 15673 %} 15674 15675 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15676 iRegI_R0 result, rFlagsReg cr) 15677 %{ 15678 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15679 match(Set result (StrEquals (Binary str1 str2) cnt)); 15680 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15681 15682 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15683 ins_encode %{ 15684 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15685 __ string_equals($str1$$Register, $str2$$Register, 15686 $result$$Register, $cnt$$Register, 1); 15687 %} 15688 ins_pipe(pipe_class_memory); 15689 %} 15690 15691 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15692 iRegI_R0 result, rFlagsReg cr) 15693 %{ 15694 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15695 match(Set result (StrEquals (Binary str1 str2) cnt)); 15696 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15697 15698 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15699 ins_encode %{ 15700 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15701 __ string_equals($str1$$Register, $str2$$Register, 15702 $result$$Register, $cnt$$Register, 2); 15703 %} 15704 ins_pipe(pipe_class_memory); 15705 %} 15706 15707 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15708 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15709 iRegP_R10 tmp, rFlagsReg cr) 15710 %{ 15711 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15712 match(Set result (AryEq ary1 ary2)); 15713 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15714 15715 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15716 ins_encode %{ 15717 __ arrays_equals($ary1$$Register, $ary2$$Register, 15718 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15719 $result$$Register, $tmp$$Register, 1); 15720 %} 15721 ins_pipe(pipe_class_memory); 15722 %} 15723 15724 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15725 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15726 iRegP_R10 tmp, rFlagsReg cr) 15727 %{ 15728 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15729 match(Set result (AryEq ary1 ary2)); 15730 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15731 15732 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15733 ins_encode %{ 15734 __ arrays_equals($ary1$$Register, $ary2$$Register, 15735 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15736 $result$$Register, $tmp$$Register, 2); 15737 %} 15738 ins_pipe(pipe_class_memory); 15739 %} 15740 15741 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15742 %{ 15743 match(Set result (HasNegatives ary1 len)); 15744 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15745 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15746 ins_encode %{ 15747 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15748 %} 15749 ins_pipe( pipe_slow ); 15750 %} 15751 15752 // fast char[] to byte[] compression 15753 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15754 vRegD_V0 tmp1, vRegD_V1 tmp2, 15755 vRegD_V2 tmp3, vRegD_V3 tmp4, 15756 iRegI_R0 result, rFlagsReg cr) 15757 %{ 15758 match(Set result (StrCompressedCopy src (Binary dst len))); 15759 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15760 15761 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15762 ins_encode %{ 15763 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15764 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15765 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15766 $result$$Register); 15767 %} 15768 ins_pipe( pipe_slow ); 15769 %} 15770 15771 // fast byte[] to char[] inflation 15772 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15773 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15774 %{ 15775 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15776 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15777 15778 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15779 ins_encode %{ 15780 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15781 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 15782 %} 15783 ins_pipe(pipe_class_memory); 15784 %} 15785 15786 // encode char[] to byte[] in ISO_8859_1 15787 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15788 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15789 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15790 iRegI_R0 result, rFlagsReg cr) 15791 %{ 15792 match(Set result (EncodeISOArray src (Binary dst len))); 15793 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15794 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15795 15796 format %{ "Encode array $src,$dst,$len -> $result" %} 15797 ins_encode %{ 15798 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15799 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15800 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15801 %} 15802 ins_pipe( pipe_class_memory ); 15803 %} 15804 15805 // ============================================================================ 15806 // This name is KNOWN by the ADLC and cannot be changed. 15807 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15808 // for this guy. 15809 instruct tlsLoadP(thread_RegP dst) 15810 %{ 15811 match(Set dst (ThreadLocal)); 15812 15813 ins_cost(0); 15814 15815 format %{ " -- \t// $dst=Thread::current(), empty" %} 15816 15817 size(0); 15818 15819 ins_encode( /*empty*/ ); 15820 15821 ins_pipe(pipe_class_empty); 15822 %} 15823 15824 // ====================VECTOR INSTRUCTIONS===================================== 15825 15826 // Load vector (32 bits) 15827 instruct loadV4(vecD dst, vmem4 mem) 15828 %{ 15829 predicate(n->as_LoadVector()->memory_size() == 4); 15830 match(Set dst (LoadVector mem)); 15831 ins_cost(4 * INSN_COST); 15832 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15833 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15834 ins_pipe(vload_reg_mem64); 15835 %} 15836 15837 // Load vector (64 bits) 15838 instruct loadV8(vecD dst, vmem8 mem) 15839 %{ 15840 predicate(n->as_LoadVector()->memory_size() == 8); 15841 match(Set dst (LoadVector mem)); 15842 ins_cost(4 * INSN_COST); 15843 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15844 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15845 ins_pipe(vload_reg_mem64); 15846 %} 15847 15848 // Load Vector (128 bits) 15849 instruct loadV16(vecX dst, vmem16 mem) 15850 %{ 15851 predicate(n->as_LoadVector()->memory_size() == 16); 15852 match(Set dst (LoadVector mem)); 15853 ins_cost(4 * INSN_COST); 15854 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15855 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15856 ins_pipe(vload_reg_mem128); 15857 %} 15858 15859 // Store Vector (32 bits) 15860 instruct storeV4(vecD src, vmem4 mem) 15861 %{ 15862 predicate(n->as_StoreVector()->memory_size() == 4); 15863 match(Set mem (StoreVector mem src)); 15864 ins_cost(4 * INSN_COST); 15865 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15866 ins_encode( aarch64_enc_strvS(src, mem) ); 15867 ins_pipe(vstore_reg_mem64); 15868 %} 15869 15870 // Store Vector (64 bits) 15871 instruct storeV8(vecD src, vmem8 mem) 15872 %{ 15873 predicate(n->as_StoreVector()->memory_size() == 8); 15874 match(Set mem (StoreVector mem src)); 15875 ins_cost(4 * INSN_COST); 15876 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15877 ins_encode( aarch64_enc_strvD(src, mem) ); 15878 ins_pipe(vstore_reg_mem64); 15879 %} 15880 15881 // Store Vector (128 bits) 15882 instruct storeV16(vecX src, vmem16 mem) 15883 %{ 15884 predicate(n->as_StoreVector()->memory_size() == 16); 15885 match(Set mem (StoreVector mem src)); 15886 ins_cost(4 * INSN_COST); 15887 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15888 ins_encode( aarch64_enc_strvQ(src, mem) ); 15889 ins_pipe(vstore_reg_mem128); 15890 %} 15891 15892 instruct replicate8B(vecD dst, iRegIorL2I src) 15893 %{ 15894 predicate(n->as_Vector()->length() == 4 || 15895 n->as_Vector()->length() == 8); 15896 match(Set dst (ReplicateB src)); 15897 ins_cost(INSN_COST); 15898 format %{ "dup $dst, $src\t# vector (8B)" %} 15899 ins_encode %{ 15900 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15901 %} 15902 ins_pipe(vdup_reg_reg64); 15903 %} 15904 15905 instruct replicate16B(vecX dst, iRegIorL2I src) 15906 %{ 15907 predicate(n->as_Vector()->length() == 16); 15908 match(Set dst (ReplicateB src)); 15909 ins_cost(INSN_COST); 15910 format %{ "dup $dst, $src\t# vector (16B)" %} 15911 ins_encode %{ 15912 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15913 %} 15914 ins_pipe(vdup_reg_reg128); 15915 %} 15916 15917 instruct replicate8B_imm(vecD dst, immI con) 15918 %{ 15919 predicate(n->as_Vector()->length() == 4 || 15920 n->as_Vector()->length() == 8); 15921 match(Set dst (ReplicateB con)); 15922 ins_cost(INSN_COST); 15923 format %{ "movi $dst, $con\t# vector(8B)" %} 15924 ins_encode %{ 15925 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15926 %} 15927 ins_pipe(vmovi_reg_imm64); 15928 %} 15929 15930 instruct replicate16B_imm(vecX dst, immI con) 15931 %{ 15932 predicate(n->as_Vector()->length() == 16); 15933 match(Set dst (ReplicateB con)); 15934 ins_cost(INSN_COST); 15935 format %{ "movi $dst, $con\t# vector(16B)" %} 15936 ins_encode %{ 15937 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15938 %} 15939 ins_pipe(vmovi_reg_imm128); 15940 %} 15941 15942 instruct replicate4S(vecD dst, iRegIorL2I src) 15943 %{ 15944 predicate(n->as_Vector()->length() == 2 || 15945 n->as_Vector()->length() == 4); 15946 match(Set dst (ReplicateS src)); 15947 ins_cost(INSN_COST); 15948 format %{ "dup $dst, $src\t# vector (4S)" %} 15949 ins_encode %{ 15950 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15951 %} 15952 ins_pipe(vdup_reg_reg64); 15953 %} 15954 15955 instruct replicate8S(vecX dst, iRegIorL2I src) 15956 %{ 15957 predicate(n->as_Vector()->length() == 8); 15958 match(Set dst (ReplicateS src)); 15959 ins_cost(INSN_COST); 15960 format %{ "dup $dst, $src\t# vector (8S)" %} 15961 ins_encode %{ 15962 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15963 %} 15964 ins_pipe(vdup_reg_reg128); 15965 %} 15966 15967 instruct replicate4S_imm(vecD dst, immI con) 15968 %{ 15969 predicate(n->as_Vector()->length() == 2 || 15970 n->as_Vector()->length() == 4); 15971 match(Set dst (ReplicateS con)); 15972 ins_cost(INSN_COST); 15973 format %{ "movi $dst, $con\t# vector(4H)" %} 15974 ins_encode %{ 15975 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15976 %} 15977 ins_pipe(vmovi_reg_imm64); 15978 %} 15979 15980 instruct replicate8S_imm(vecX dst, immI con) 15981 %{ 15982 predicate(n->as_Vector()->length() == 8); 15983 match(Set dst (ReplicateS con)); 15984 ins_cost(INSN_COST); 15985 format %{ "movi $dst, $con\t# vector(8H)" %} 15986 ins_encode %{ 15987 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15988 %} 15989 ins_pipe(vmovi_reg_imm128); 15990 %} 15991 15992 instruct replicate2I(vecD dst, iRegIorL2I src) 15993 %{ 15994 predicate(n->as_Vector()->length() == 2); 15995 match(Set dst (ReplicateI src)); 15996 ins_cost(INSN_COST); 15997 format %{ "dup $dst, $src\t# vector (2I)" %} 15998 ins_encode %{ 15999 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 16000 %} 16001 ins_pipe(vdup_reg_reg64); 16002 %} 16003 16004 instruct replicate4I(vecX dst, iRegIorL2I src) 16005 %{ 16006 predicate(n->as_Vector()->length() == 4); 16007 match(Set dst (ReplicateI src)); 16008 ins_cost(INSN_COST); 16009 format %{ "dup $dst, $src\t# vector (4I)" %} 16010 ins_encode %{ 16011 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 16012 %} 16013 ins_pipe(vdup_reg_reg128); 16014 %} 16015 16016 instruct replicate2I_imm(vecD dst, immI con) 16017 %{ 16018 predicate(n->as_Vector()->length() == 2); 16019 match(Set dst (ReplicateI con)); 16020 ins_cost(INSN_COST); 16021 format %{ "movi $dst, $con\t# vector(2I)" %} 16022 ins_encode %{ 16023 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 16024 %} 16025 ins_pipe(vmovi_reg_imm64); 16026 %} 16027 16028 instruct replicate4I_imm(vecX dst, immI con) 16029 %{ 16030 predicate(n->as_Vector()->length() == 4); 16031 match(Set dst (ReplicateI con)); 16032 ins_cost(INSN_COST); 16033 format %{ "movi $dst, $con\t# vector(4I)" %} 16034 ins_encode %{ 16035 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 16036 %} 16037 ins_pipe(vmovi_reg_imm128); 16038 %} 16039 16040 instruct replicate2L(vecX dst, iRegL src) 16041 %{ 16042 predicate(n->as_Vector()->length() == 2); 16043 match(Set dst (ReplicateL src)); 16044 ins_cost(INSN_COST); 16045 format %{ "dup $dst, $src\t# vector (2L)" %} 16046 ins_encode %{ 16047 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 16048 %} 16049 ins_pipe(vdup_reg_reg128); 16050 %} 16051 16052 instruct replicate2L_zero(vecX dst, immI0 zero) 16053 %{ 16054 predicate(n->as_Vector()->length() == 2); 16055 match(Set dst (ReplicateI zero)); 16056 ins_cost(INSN_COST); 16057 format %{ "movi $dst, $zero\t# vector(4I)" %} 16058 ins_encode %{ 16059 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16060 as_FloatRegister($dst$$reg), 16061 as_FloatRegister($dst$$reg)); 16062 %} 16063 ins_pipe(vmovi_reg_imm128); 16064 %} 16065 16066 instruct replicate2F(vecD dst, vRegF src) 16067 %{ 16068 predicate(n->as_Vector()->length() == 2); 16069 match(Set dst (ReplicateF src)); 16070 ins_cost(INSN_COST); 16071 format %{ "dup $dst, $src\t# vector (2F)" %} 16072 ins_encode %{ 16073 __ dup(as_FloatRegister($dst$$reg), __ T2S, 16074 as_FloatRegister($src$$reg)); 16075 %} 16076 ins_pipe(vdup_reg_freg64); 16077 %} 16078 16079 instruct replicate4F(vecX dst, vRegF src) 16080 %{ 16081 predicate(n->as_Vector()->length() == 4); 16082 match(Set dst (ReplicateF src)); 16083 ins_cost(INSN_COST); 16084 format %{ "dup $dst, $src\t# vector (4F)" %} 16085 ins_encode %{ 16086 __ dup(as_FloatRegister($dst$$reg), __ T4S, 16087 as_FloatRegister($src$$reg)); 16088 %} 16089 ins_pipe(vdup_reg_freg128); 16090 %} 16091 16092 instruct replicate2D(vecX dst, vRegD src) 16093 %{ 16094 predicate(n->as_Vector()->length() == 2); 16095 match(Set dst (ReplicateD src)); 16096 ins_cost(INSN_COST); 16097 format %{ "dup $dst, $src\t# vector (2D)" %} 16098 ins_encode %{ 16099 __ dup(as_FloatRegister($dst$$reg), __ T2D, 16100 as_FloatRegister($src$$reg)); 16101 %} 16102 ins_pipe(vdup_reg_dreg128); 16103 %} 16104 16105 // ====================REDUCTION ARITHMETIC==================================== 16106 16107 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 16108 %{ 16109 match(Set dst (AddReductionVI src1 src2)); 16110 ins_cost(INSN_COST); 16111 effect(TEMP tmp, TEMP tmp2); 16112 format %{ "umov $tmp, $src2, S, 0\n\t" 16113 "umov $tmp2, $src2, S, 1\n\t" 16114 "addw $dst, $src1, $tmp\n\t" 16115 "addw $dst, $dst, $tmp2\t add reduction2i" 16116 %} 16117 ins_encode %{ 16118 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16119 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16120 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 16121 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 16122 %} 16123 ins_pipe(pipe_class_default); 16124 %} 16125 16126 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16127 %{ 16128 match(Set dst (AddReductionVI src1 src2)); 16129 ins_cost(INSN_COST); 16130 effect(TEMP tmp, TEMP tmp2); 16131 format %{ "addv $tmp, T4S, $src2\n\t" 16132 "umov $tmp2, $tmp, S, 0\n\t" 16133 "addw $dst, $tmp2, $src1\t add reduction4i" 16134 %} 16135 ins_encode %{ 16136 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 16137 as_FloatRegister($src2$$reg)); 16138 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16139 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 16140 %} 16141 ins_pipe(pipe_class_default); 16142 %} 16143 16144 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 16145 %{ 16146 match(Set dst (MulReductionVI src1 src2)); 16147 ins_cost(INSN_COST); 16148 effect(TEMP tmp, TEMP dst); 16149 format %{ "umov $tmp, $src2, S, 0\n\t" 16150 "mul $dst, $tmp, $src1\n\t" 16151 "umov $tmp, $src2, S, 1\n\t" 16152 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 16153 %} 16154 ins_encode %{ 16155 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 16156 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 16157 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 16158 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 16159 %} 16160 ins_pipe(pipe_class_default); 16161 %} 16162 16163 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 16164 %{ 16165 match(Set dst (MulReductionVI src1 src2)); 16166 ins_cost(INSN_COST); 16167 effect(TEMP tmp, TEMP tmp2, TEMP dst); 16168 format %{ "ins $tmp, $src2, 0, 1\n\t" 16169 "mul $tmp, $tmp, $src2\n\t" 16170 "umov $tmp2, $tmp, S, 0\n\t" 16171 "mul $dst, $tmp2, $src1\n\t" 16172 "umov $tmp2, $tmp, S, 1\n\t" 16173 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 16174 %} 16175 ins_encode %{ 16176 __ ins(as_FloatRegister($tmp$$reg), __ D, 16177 as_FloatRegister($src2$$reg), 0, 1); 16178 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 16179 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 16180 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 16181 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 16182 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 16183 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 16184 %} 16185 ins_pipe(pipe_class_default); 16186 %} 16187 16188 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16189 %{ 16190 match(Set dst (AddReductionVF src1 src2)); 16191 ins_cost(INSN_COST); 16192 effect(TEMP tmp, TEMP dst); 16193 format %{ "fadds $dst, $src1, $src2\n\t" 16194 "ins $tmp, S, $src2, 0, 1\n\t" 16195 "fadds $dst, $dst, $tmp\t add reduction2f" 16196 %} 16197 ins_encode %{ 16198 __ fadds(as_FloatRegister($dst$$reg), 16199 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16200 __ ins(as_FloatRegister($tmp$$reg), __ S, 16201 as_FloatRegister($src2$$reg), 0, 1); 16202 __ fadds(as_FloatRegister($dst$$reg), 16203 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16204 %} 16205 ins_pipe(pipe_class_default); 16206 %} 16207 16208 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16209 %{ 16210 match(Set dst (AddReductionVF src1 src2)); 16211 ins_cost(INSN_COST); 16212 effect(TEMP tmp, TEMP dst); 16213 format %{ "fadds $dst, $src1, $src2\n\t" 16214 "ins $tmp, S, $src2, 0, 1\n\t" 16215 "fadds $dst, $dst, $tmp\n\t" 16216 "ins $tmp, S, $src2, 0, 2\n\t" 16217 "fadds $dst, $dst, $tmp\n\t" 16218 "ins $tmp, S, $src2, 0, 3\n\t" 16219 "fadds $dst, $dst, $tmp\t add reduction4f" 16220 %} 16221 ins_encode %{ 16222 __ fadds(as_FloatRegister($dst$$reg), 16223 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16224 __ ins(as_FloatRegister($tmp$$reg), __ S, 16225 as_FloatRegister($src2$$reg), 0, 1); 16226 __ fadds(as_FloatRegister($dst$$reg), 16227 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16228 __ ins(as_FloatRegister($tmp$$reg), __ S, 16229 as_FloatRegister($src2$$reg), 0, 2); 16230 __ fadds(as_FloatRegister($dst$$reg), 16231 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16232 __ ins(as_FloatRegister($tmp$$reg), __ S, 16233 as_FloatRegister($src2$$reg), 0, 3); 16234 __ fadds(as_FloatRegister($dst$$reg), 16235 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16236 %} 16237 ins_pipe(pipe_class_default); 16238 %} 16239 16240 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 16241 %{ 16242 match(Set dst (MulReductionVF src1 src2)); 16243 ins_cost(INSN_COST); 16244 effect(TEMP tmp, TEMP dst); 16245 format %{ "fmuls $dst, $src1, $src2\n\t" 16246 "ins $tmp, S, $src2, 0, 1\n\t" 16247 "fmuls $dst, $dst, $tmp\t add reduction4f" 16248 %} 16249 ins_encode %{ 16250 __ fmuls(as_FloatRegister($dst$$reg), 16251 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16252 __ ins(as_FloatRegister($tmp$$reg), __ S, 16253 as_FloatRegister($src2$$reg), 0, 1); 16254 __ fmuls(as_FloatRegister($dst$$reg), 16255 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16256 %} 16257 ins_pipe(pipe_class_default); 16258 %} 16259 16260 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16261 %{ 16262 match(Set dst (MulReductionVF src1 src2)); 16263 ins_cost(INSN_COST); 16264 effect(TEMP tmp, TEMP dst); 16265 format %{ "fmuls $dst, $src1, $src2\n\t" 16266 "ins $tmp, S, $src2, 0, 1\n\t" 16267 "fmuls $dst, $dst, $tmp\n\t" 16268 "ins $tmp, S, $src2, 0, 2\n\t" 16269 "fmuls $dst, $dst, $tmp\n\t" 16270 "ins $tmp, S, $src2, 0, 3\n\t" 16271 "fmuls $dst, $dst, $tmp\t add reduction4f" 16272 %} 16273 ins_encode %{ 16274 __ fmuls(as_FloatRegister($dst$$reg), 16275 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16276 __ ins(as_FloatRegister($tmp$$reg), __ S, 16277 as_FloatRegister($src2$$reg), 0, 1); 16278 __ fmuls(as_FloatRegister($dst$$reg), 16279 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16280 __ ins(as_FloatRegister($tmp$$reg), __ S, 16281 as_FloatRegister($src2$$reg), 0, 2); 16282 __ fmuls(as_FloatRegister($dst$$reg), 16283 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16284 __ ins(as_FloatRegister($tmp$$reg), __ S, 16285 as_FloatRegister($src2$$reg), 0, 3); 16286 __ fmuls(as_FloatRegister($dst$$reg), 16287 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16288 %} 16289 ins_pipe(pipe_class_default); 16290 %} 16291 16292 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16293 %{ 16294 match(Set dst (AddReductionVD src1 src2)); 16295 ins_cost(INSN_COST); 16296 effect(TEMP tmp, TEMP dst); 16297 format %{ "faddd $dst, $src1, $src2\n\t" 16298 "ins $tmp, D, $src2, 0, 1\n\t" 16299 "faddd $dst, $dst, $tmp\t add reduction2d" 16300 %} 16301 ins_encode %{ 16302 __ faddd(as_FloatRegister($dst$$reg), 16303 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16304 __ ins(as_FloatRegister($tmp$$reg), __ D, 16305 as_FloatRegister($src2$$reg), 0, 1); 16306 __ faddd(as_FloatRegister($dst$$reg), 16307 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16308 %} 16309 ins_pipe(pipe_class_default); 16310 %} 16311 16312 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16313 %{ 16314 match(Set dst (MulReductionVD src1 src2)); 16315 ins_cost(INSN_COST); 16316 effect(TEMP tmp, TEMP dst); 16317 format %{ "fmuld $dst, $src1, $src2\n\t" 16318 "ins $tmp, D, $src2, 0, 1\n\t" 16319 "fmuld $dst, $dst, $tmp\t add reduction2d" 16320 %} 16321 ins_encode %{ 16322 __ fmuld(as_FloatRegister($dst$$reg), 16323 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16324 __ ins(as_FloatRegister($tmp$$reg), __ D, 16325 as_FloatRegister($src2$$reg), 0, 1); 16326 __ fmuld(as_FloatRegister($dst$$reg), 16327 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16328 %} 16329 ins_pipe(pipe_class_default); 16330 %} 16331 16332 instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16333 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16334 match(Set dst (MaxReductionV src1 src2)); 16335 ins_cost(INSN_COST); 16336 effect(TEMP_DEF dst, TEMP tmp); 16337 format %{ "fmaxs $dst, $src1, $src2\n\t" 16338 "ins $tmp, S, $src2, 0, 1\n\t" 16339 "fmaxs $dst, $dst, $tmp\t max reduction2F" %} 16340 ins_encode %{ 16341 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16342 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16343 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16344 %} 16345 ins_pipe(pipe_class_default); 16346 %} 16347 16348 instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ 16349 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16350 match(Set dst (MaxReductionV src1 src2)); 16351 ins_cost(INSN_COST); 16352 effect(TEMP_DEF dst); 16353 format %{ "fmaxv $dst, T4S, $src2\n\t" 16354 "fmaxs $dst, $dst, $src1\t max reduction4F" %} 16355 ins_encode %{ 16356 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16357 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16358 %} 16359 ins_pipe(pipe_class_default); 16360 %} 16361 16362 instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16363 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16364 match(Set dst (MaxReductionV src1 src2)); 16365 ins_cost(INSN_COST); 16366 effect(TEMP_DEF dst, TEMP tmp); 16367 format %{ "fmaxd $dst, $src1, $src2\n\t" 16368 "ins $tmp, D, $src2, 0, 1\n\t" 16369 "fmaxd $dst, $dst, $tmp\t max reduction2D" %} 16370 ins_encode %{ 16371 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16372 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16373 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16374 %} 16375 ins_pipe(pipe_class_default); 16376 %} 16377 16378 instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16379 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16380 match(Set dst (MinReductionV src1 src2)); 16381 ins_cost(INSN_COST); 16382 effect(TEMP_DEF dst, TEMP tmp); 16383 format %{ "fmins $dst, $src1, $src2\n\t" 16384 "ins $tmp, S, $src2, 0, 1\n\t" 16385 "fmins $dst, $dst, $tmp\t min reduction2F" %} 16386 ins_encode %{ 16387 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16388 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16389 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16390 %} 16391 ins_pipe(pipe_class_default); 16392 %} 16393 16394 instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ 16395 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16396 match(Set dst (MinReductionV src1 src2)); 16397 ins_cost(INSN_COST); 16398 effect(TEMP_DEF dst); 16399 format %{ "fminv $dst, T4S, $src2\n\t" 16400 "fmins $dst, $dst, $src1\t min reduction4F" %} 16401 ins_encode %{ 16402 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16403 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16404 %} 16405 ins_pipe(pipe_class_default); 16406 %} 16407 16408 instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16409 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16410 match(Set dst (MinReductionV src1 src2)); 16411 ins_cost(INSN_COST); 16412 effect(TEMP_DEF dst, TEMP tmp); 16413 format %{ "fmind $dst, $src1, $src2\n\t" 16414 "ins $tmp, D, $src2, 0, 1\n\t" 16415 "fmind $dst, $dst, $tmp\t min reduction2D" %} 16416 ins_encode %{ 16417 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16418 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16419 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16420 %} 16421 ins_pipe(pipe_class_default); 16422 %} 16423 16424 // ====================VECTOR ARITHMETIC======================================= 16425 16426 // --------------------------------- ADD -------------------------------------- 16427 16428 instruct vadd8B(vecD dst, vecD src1, vecD src2) 16429 %{ 16430 predicate(n->as_Vector()->length() == 4 || 16431 n->as_Vector()->length() == 8); 16432 match(Set dst (AddVB src1 src2)); 16433 ins_cost(INSN_COST); 16434 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16435 ins_encode %{ 16436 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16437 as_FloatRegister($src1$$reg), 16438 as_FloatRegister($src2$$reg)); 16439 %} 16440 ins_pipe(vdop64); 16441 %} 16442 16443 instruct vadd16B(vecX dst, vecX src1, vecX src2) 16444 %{ 16445 predicate(n->as_Vector()->length() == 16); 16446 match(Set dst (AddVB src1 src2)); 16447 ins_cost(INSN_COST); 16448 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16449 ins_encode %{ 16450 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16451 as_FloatRegister($src1$$reg), 16452 as_FloatRegister($src2$$reg)); 16453 %} 16454 ins_pipe(vdop128); 16455 %} 16456 16457 instruct vadd4S(vecD dst, vecD src1, vecD src2) 16458 %{ 16459 predicate(n->as_Vector()->length() == 2 || 16460 n->as_Vector()->length() == 4); 16461 match(Set dst (AddVS src1 src2)); 16462 ins_cost(INSN_COST); 16463 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16464 ins_encode %{ 16465 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16466 as_FloatRegister($src1$$reg), 16467 as_FloatRegister($src2$$reg)); 16468 %} 16469 ins_pipe(vdop64); 16470 %} 16471 16472 instruct vadd8S(vecX dst, vecX src1, vecX src2) 16473 %{ 16474 predicate(n->as_Vector()->length() == 8); 16475 match(Set dst (AddVS src1 src2)); 16476 ins_cost(INSN_COST); 16477 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16478 ins_encode %{ 16479 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16480 as_FloatRegister($src1$$reg), 16481 as_FloatRegister($src2$$reg)); 16482 %} 16483 ins_pipe(vdop128); 16484 %} 16485 16486 instruct vadd2I(vecD dst, vecD src1, vecD src2) 16487 %{ 16488 predicate(n->as_Vector()->length() == 2); 16489 match(Set dst (AddVI src1 src2)); 16490 ins_cost(INSN_COST); 16491 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16492 ins_encode %{ 16493 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16494 as_FloatRegister($src1$$reg), 16495 as_FloatRegister($src2$$reg)); 16496 %} 16497 ins_pipe(vdop64); 16498 %} 16499 16500 instruct vadd4I(vecX dst, vecX src1, vecX src2) 16501 %{ 16502 predicate(n->as_Vector()->length() == 4); 16503 match(Set dst (AddVI src1 src2)); 16504 ins_cost(INSN_COST); 16505 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16506 ins_encode %{ 16507 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16508 as_FloatRegister($src1$$reg), 16509 as_FloatRegister($src2$$reg)); 16510 %} 16511 ins_pipe(vdop128); 16512 %} 16513 16514 instruct vadd2L(vecX dst, vecX src1, vecX src2) 16515 %{ 16516 predicate(n->as_Vector()->length() == 2); 16517 match(Set dst (AddVL src1 src2)); 16518 ins_cost(INSN_COST); 16519 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16520 ins_encode %{ 16521 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16522 as_FloatRegister($src1$$reg), 16523 as_FloatRegister($src2$$reg)); 16524 %} 16525 ins_pipe(vdop128); 16526 %} 16527 16528 instruct vadd2F(vecD dst, vecD src1, vecD src2) 16529 %{ 16530 predicate(n->as_Vector()->length() == 2); 16531 match(Set dst (AddVF src1 src2)); 16532 ins_cost(INSN_COST); 16533 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16534 ins_encode %{ 16535 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16536 as_FloatRegister($src1$$reg), 16537 as_FloatRegister($src2$$reg)); 16538 %} 16539 ins_pipe(vdop_fp64); 16540 %} 16541 16542 instruct vadd4F(vecX dst, vecX src1, vecX src2) 16543 %{ 16544 predicate(n->as_Vector()->length() == 4); 16545 match(Set dst (AddVF src1 src2)); 16546 ins_cost(INSN_COST); 16547 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16548 ins_encode %{ 16549 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16550 as_FloatRegister($src1$$reg), 16551 as_FloatRegister($src2$$reg)); 16552 %} 16553 ins_pipe(vdop_fp128); 16554 %} 16555 16556 instruct vadd2D(vecX dst, vecX src1, vecX src2) 16557 %{ 16558 match(Set dst (AddVD src1 src2)); 16559 ins_cost(INSN_COST); 16560 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16561 ins_encode %{ 16562 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16563 as_FloatRegister($src1$$reg), 16564 as_FloatRegister($src2$$reg)); 16565 %} 16566 ins_pipe(vdop_fp128); 16567 %} 16568 16569 // --------------------------------- SUB -------------------------------------- 16570 16571 instruct vsub8B(vecD dst, vecD src1, vecD src2) 16572 %{ 16573 predicate(n->as_Vector()->length() == 4 || 16574 n->as_Vector()->length() == 8); 16575 match(Set dst (SubVB src1 src2)); 16576 ins_cost(INSN_COST); 16577 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16578 ins_encode %{ 16579 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16580 as_FloatRegister($src1$$reg), 16581 as_FloatRegister($src2$$reg)); 16582 %} 16583 ins_pipe(vdop64); 16584 %} 16585 16586 instruct vsub16B(vecX dst, vecX src1, vecX src2) 16587 %{ 16588 predicate(n->as_Vector()->length() == 16); 16589 match(Set dst (SubVB src1 src2)); 16590 ins_cost(INSN_COST); 16591 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16592 ins_encode %{ 16593 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16594 as_FloatRegister($src1$$reg), 16595 as_FloatRegister($src2$$reg)); 16596 %} 16597 ins_pipe(vdop128); 16598 %} 16599 16600 instruct vsub4S(vecD dst, vecD src1, vecD src2) 16601 %{ 16602 predicate(n->as_Vector()->length() == 2 || 16603 n->as_Vector()->length() == 4); 16604 match(Set dst (SubVS src1 src2)); 16605 ins_cost(INSN_COST); 16606 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16607 ins_encode %{ 16608 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16609 as_FloatRegister($src1$$reg), 16610 as_FloatRegister($src2$$reg)); 16611 %} 16612 ins_pipe(vdop64); 16613 %} 16614 16615 instruct vsub8S(vecX dst, vecX src1, vecX src2) 16616 %{ 16617 predicate(n->as_Vector()->length() == 8); 16618 match(Set dst (SubVS src1 src2)); 16619 ins_cost(INSN_COST); 16620 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16621 ins_encode %{ 16622 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16623 as_FloatRegister($src1$$reg), 16624 as_FloatRegister($src2$$reg)); 16625 %} 16626 ins_pipe(vdop128); 16627 %} 16628 16629 instruct vsub2I(vecD dst, vecD src1, vecD src2) 16630 %{ 16631 predicate(n->as_Vector()->length() == 2); 16632 match(Set dst (SubVI src1 src2)); 16633 ins_cost(INSN_COST); 16634 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16635 ins_encode %{ 16636 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16637 as_FloatRegister($src1$$reg), 16638 as_FloatRegister($src2$$reg)); 16639 %} 16640 ins_pipe(vdop64); 16641 %} 16642 16643 instruct vsub4I(vecX dst, vecX src1, vecX src2) 16644 %{ 16645 predicate(n->as_Vector()->length() == 4); 16646 match(Set dst (SubVI src1 src2)); 16647 ins_cost(INSN_COST); 16648 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16649 ins_encode %{ 16650 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16651 as_FloatRegister($src1$$reg), 16652 as_FloatRegister($src2$$reg)); 16653 %} 16654 ins_pipe(vdop128); 16655 %} 16656 16657 instruct vsub2L(vecX dst, vecX src1, vecX src2) 16658 %{ 16659 predicate(n->as_Vector()->length() == 2); 16660 match(Set dst (SubVL src1 src2)); 16661 ins_cost(INSN_COST); 16662 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16663 ins_encode %{ 16664 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16665 as_FloatRegister($src1$$reg), 16666 as_FloatRegister($src2$$reg)); 16667 %} 16668 ins_pipe(vdop128); 16669 %} 16670 16671 instruct vsub2F(vecD dst, vecD src1, vecD src2) 16672 %{ 16673 predicate(n->as_Vector()->length() == 2); 16674 match(Set dst (SubVF src1 src2)); 16675 ins_cost(INSN_COST); 16676 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16677 ins_encode %{ 16678 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16679 as_FloatRegister($src1$$reg), 16680 as_FloatRegister($src2$$reg)); 16681 %} 16682 ins_pipe(vdop_fp64); 16683 %} 16684 16685 instruct vsub4F(vecX dst, vecX src1, vecX src2) 16686 %{ 16687 predicate(n->as_Vector()->length() == 4); 16688 match(Set dst (SubVF src1 src2)); 16689 ins_cost(INSN_COST); 16690 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16691 ins_encode %{ 16692 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16693 as_FloatRegister($src1$$reg), 16694 as_FloatRegister($src2$$reg)); 16695 %} 16696 ins_pipe(vdop_fp128); 16697 %} 16698 16699 instruct vsub2D(vecX dst, vecX src1, vecX src2) 16700 %{ 16701 predicate(n->as_Vector()->length() == 2); 16702 match(Set dst (SubVD src1 src2)); 16703 ins_cost(INSN_COST); 16704 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16705 ins_encode %{ 16706 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16707 as_FloatRegister($src1$$reg), 16708 as_FloatRegister($src2$$reg)); 16709 %} 16710 ins_pipe(vdop_fp128); 16711 %} 16712 16713 // --------------------------------- MUL -------------------------------------- 16714 16715 instruct vmul4S(vecD dst, vecD src1, vecD src2) 16716 %{ 16717 predicate(n->as_Vector()->length() == 2 || 16718 n->as_Vector()->length() == 4); 16719 match(Set dst (MulVS src1 src2)); 16720 ins_cost(INSN_COST); 16721 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16722 ins_encode %{ 16723 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16724 as_FloatRegister($src1$$reg), 16725 as_FloatRegister($src2$$reg)); 16726 %} 16727 ins_pipe(vmul64); 16728 %} 16729 16730 instruct vmul8S(vecX dst, vecX src1, vecX src2) 16731 %{ 16732 predicate(n->as_Vector()->length() == 8); 16733 match(Set dst (MulVS src1 src2)); 16734 ins_cost(INSN_COST); 16735 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16736 ins_encode %{ 16737 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16738 as_FloatRegister($src1$$reg), 16739 as_FloatRegister($src2$$reg)); 16740 %} 16741 ins_pipe(vmul128); 16742 %} 16743 16744 instruct vmul2I(vecD dst, vecD src1, vecD src2) 16745 %{ 16746 predicate(n->as_Vector()->length() == 2); 16747 match(Set dst (MulVI src1 src2)); 16748 ins_cost(INSN_COST); 16749 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16750 ins_encode %{ 16751 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16752 as_FloatRegister($src1$$reg), 16753 as_FloatRegister($src2$$reg)); 16754 %} 16755 ins_pipe(vmul64); 16756 %} 16757 16758 instruct vmul4I(vecX dst, vecX src1, vecX src2) 16759 %{ 16760 predicate(n->as_Vector()->length() == 4); 16761 match(Set dst (MulVI src1 src2)); 16762 ins_cost(INSN_COST); 16763 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16764 ins_encode %{ 16765 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16766 as_FloatRegister($src1$$reg), 16767 as_FloatRegister($src2$$reg)); 16768 %} 16769 ins_pipe(vmul128); 16770 %} 16771 16772 instruct vmul2F(vecD dst, vecD src1, vecD src2) 16773 %{ 16774 predicate(n->as_Vector()->length() == 2); 16775 match(Set dst (MulVF src1 src2)); 16776 ins_cost(INSN_COST); 16777 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16778 ins_encode %{ 16779 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16780 as_FloatRegister($src1$$reg), 16781 as_FloatRegister($src2$$reg)); 16782 %} 16783 ins_pipe(vmuldiv_fp64); 16784 %} 16785 16786 instruct vmul4F(vecX dst, vecX src1, vecX src2) 16787 %{ 16788 predicate(n->as_Vector()->length() == 4); 16789 match(Set dst (MulVF src1 src2)); 16790 ins_cost(INSN_COST); 16791 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16792 ins_encode %{ 16793 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16794 as_FloatRegister($src1$$reg), 16795 as_FloatRegister($src2$$reg)); 16796 %} 16797 ins_pipe(vmuldiv_fp128); 16798 %} 16799 16800 instruct vmul2D(vecX dst, vecX src1, vecX src2) 16801 %{ 16802 predicate(n->as_Vector()->length() == 2); 16803 match(Set dst (MulVD src1 src2)); 16804 ins_cost(INSN_COST); 16805 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16806 ins_encode %{ 16807 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16808 as_FloatRegister($src1$$reg), 16809 as_FloatRegister($src2$$reg)); 16810 %} 16811 ins_pipe(vmuldiv_fp128); 16812 %} 16813 16814 // --------------------------------- MLA -------------------------------------- 16815 16816 instruct vmla4S(vecD dst, vecD src1, vecD src2) 16817 %{ 16818 predicate(n->as_Vector()->length() == 2 || 16819 n->as_Vector()->length() == 4); 16820 match(Set dst (AddVS dst (MulVS src1 src2))); 16821 ins_cost(INSN_COST); 16822 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16823 ins_encode %{ 16824 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16825 as_FloatRegister($src1$$reg), 16826 as_FloatRegister($src2$$reg)); 16827 %} 16828 ins_pipe(vmla64); 16829 %} 16830 16831 instruct vmla8S(vecX dst, vecX src1, vecX src2) 16832 %{ 16833 predicate(n->as_Vector()->length() == 8); 16834 match(Set dst (AddVS dst (MulVS src1 src2))); 16835 ins_cost(INSN_COST); 16836 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16837 ins_encode %{ 16838 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16839 as_FloatRegister($src1$$reg), 16840 as_FloatRegister($src2$$reg)); 16841 %} 16842 ins_pipe(vmla128); 16843 %} 16844 16845 instruct vmla2I(vecD dst, vecD src1, vecD src2) 16846 %{ 16847 predicate(n->as_Vector()->length() == 2); 16848 match(Set dst (AddVI dst (MulVI src1 src2))); 16849 ins_cost(INSN_COST); 16850 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16851 ins_encode %{ 16852 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16853 as_FloatRegister($src1$$reg), 16854 as_FloatRegister($src2$$reg)); 16855 %} 16856 ins_pipe(vmla64); 16857 %} 16858 16859 instruct vmla4I(vecX dst, vecX src1, vecX src2) 16860 %{ 16861 predicate(n->as_Vector()->length() == 4); 16862 match(Set dst (AddVI dst (MulVI src1 src2))); 16863 ins_cost(INSN_COST); 16864 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16865 ins_encode %{ 16866 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16867 as_FloatRegister($src1$$reg), 16868 as_FloatRegister($src2$$reg)); 16869 %} 16870 ins_pipe(vmla128); 16871 %} 16872 16873 // dst + src1 * src2 16874 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16875 predicate(UseFMA && n->as_Vector()->length() == 2); 16876 match(Set dst (FmaVF dst (Binary src1 src2))); 16877 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16878 ins_cost(INSN_COST); 16879 ins_encode %{ 16880 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16881 as_FloatRegister($src1$$reg), 16882 as_FloatRegister($src2$$reg)); 16883 %} 16884 ins_pipe(vmuldiv_fp64); 16885 %} 16886 16887 // dst + src1 * src2 16888 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16889 predicate(UseFMA && n->as_Vector()->length() == 4); 16890 match(Set dst (FmaVF dst (Binary src1 src2))); 16891 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16892 ins_cost(INSN_COST); 16893 ins_encode %{ 16894 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16895 as_FloatRegister($src1$$reg), 16896 as_FloatRegister($src2$$reg)); 16897 %} 16898 ins_pipe(vmuldiv_fp128); 16899 %} 16900 16901 // dst + src1 * src2 16902 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16903 predicate(UseFMA && n->as_Vector()->length() == 2); 16904 match(Set dst (FmaVD dst (Binary src1 src2))); 16905 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16906 ins_cost(INSN_COST); 16907 ins_encode %{ 16908 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16909 as_FloatRegister($src1$$reg), 16910 as_FloatRegister($src2$$reg)); 16911 %} 16912 ins_pipe(vmuldiv_fp128); 16913 %} 16914 16915 // --------------------------------- MLS -------------------------------------- 16916 16917 instruct vmls4S(vecD dst, vecD src1, vecD src2) 16918 %{ 16919 predicate(n->as_Vector()->length() == 2 || 16920 n->as_Vector()->length() == 4); 16921 match(Set dst (SubVS dst (MulVS src1 src2))); 16922 ins_cost(INSN_COST); 16923 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16924 ins_encode %{ 16925 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16926 as_FloatRegister($src1$$reg), 16927 as_FloatRegister($src2$$reg)); 16928 %} 16929 ins_pipe(vmla64); 16930 %} 16931 16932 instruct vmls8S(vecX dst, vecX src1, vecX src2) 16933 %{ 16934 predicate(n->as_Vector()->length() == 8); 16935 match(Set dst (SubVS dst (MulVS src1 src2))); 16936 ins_cost(INSN_COST); 16937 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16938 ins_encode %{ 16939 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16940 as_FloatRegister($src1$$reg), 16941 as_FloatRegister($src2$$reg)); 16942 %} 16943 ins_pipe(vmla128); 16944 %} 16945 16946 instruct vmls2I(vecD dst, vecD src1, vecD src2) 16947 %{ 16948 predicate(n->as_Vector()->length() == 2); 16949 match(Set dst (SubVI dst (MulVI src1 src2))); 16950 ins_cost(INSN_COST); 16951 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16952 ins_encode %{ 16953 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16954 as_FloatRegister($src1$$reg), 16955 as_FloatRegister($src2$$reg)); 16956 %} 16957 ins_pipe(vmla64); 16958 %} 16959 16960 instruct vmls4I(vecX dst, vecX src1, vecX src2) 16961 %{ 16962 predicate(n->as_Vector()->length() == 4); 16963 match(Set dst (SubVI dst (MulVI src1 src2))); 16964 ins_cost(INSN_COST); 16965 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16966 ins_encode %{ 16967 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16968 as_FloatRegister($src1$$reg), 16969 as_FloatRegister($src2$$reg)); 16970 %} 16971 ins_pipe(vmla128); 16972 %} 16973 16974 // dst - src1 * src2 16975 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16976 predicate(UseFMA && n->as_Vector()->length() == 2); 16977 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16978 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16979 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16980 ins_cost(INSN_COST); 16981 ins_encode %{ 16982 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16983 as_FloatRegister($src1$$reg), 16984 as_FloatRegister($src2$$reg)); 16985 %} 16986 ins_pipe(vmuldiv_fp64); 16987 %} 16988 16989 // dst - src1 * src2 16990 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16991 predicate(UseFMA && n->as_Vector()->length() == 4); 16992 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16993 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16994 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16995 ins_cost(INSN_COST); 16996 ins_encode %{ 16997 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16998 as_FloatRegister($src1$$reg), 16999 as_FloatRegister($src2$$reg)); 17000 %} 17001 ins_pipe(vmuldiv_fp128); 17002 %} 17003 17004 // dst - src1 * src2 17005 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 17006 predicate(UseFMA && n->as_Vector()->length() == 2); 17007 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 17008 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 17009 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 17010 ins_cost(INSN_COST); 17011 ins_encode %{ 17012 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 17013 as_FloatRegister($src1$$reg), 17014 as_FloatRegister($src2$$reg)); 17015 %} 17016 ins_pipe(vmuldiv_fp128); 17017 %} 17018 17019 // --------------------------------- DIV -------------------------------------- 17020 17021 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 17022 %{ 17023 predicate(n->as_Vector()->length() == 2); 17024 match(Set dst (DivVF src1 src2)); 17025 ins_cost(INSN_COST); 17026 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 17027 ins_encode %{ 17028 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 17029 as_FloatRegister($src1$$reg), 17030 as_FloatRegister($src2$$reg)); 17031 %} 17032 ins_pipe(vmuldiv_fp64); 17033 %} 17034 17035 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 17036 %{ 17037 predicate(n->as_Vector()->length() == 4); 17038 match(Set dst (DivVF src1 src2)); 17039 ins_cost(INSN_COST); 17040 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 17041 ins_encode %{ 17042 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 17043 as_FloatRegister($src1$$reg), 17044 as_FloatRegister($src2$$reg)); 17045 %} 17046 ins_pipe(vmuldiv_fp128); 17047 %} 17048 17049 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 17050 %{ 17051 predicate(n->as_Vector()->length() == 2); 17052 match(Set dst (DivVD src1 src2)); 17053 ins_cost(INSN_COST); 17054 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 17055 ins_encode %{ 17056 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 17057 as_FloatRegister($src1$$reg), 17058 as_FloatRegister($src2$$reg)); 17059 %} 17060 ins_pipe(vmuldiv_fp128); 17061 %} 17062 17063 // --------------------------------- SQRT ------------------------------------- 17064 17065 instruct vsqrt2D(vecX dst, vecX src) 17066 %{ 17067 predicate(n->as_Vector()->length() == 2); 17068 match(Set dst (SqrtVD src)); 17069 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 17070 ins_encode %{ 17071 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 17072 as_FloatRegister($src$$reg)); 17073 %} 17074 ins_pipe(vsqrt_fp128); 17075 %} 17076 17077 // --------------------------------- ABS -------------------------------------- 17078 17079 instruct vabs2F(vecD dst, vecD src) 17080 %{ 17081 predicate(n->as_Vector()->length() == 2); 17082 match(Set dst (AbsVF src)); 17083 ins_cost(INSN_COST * 3); 17084 format %{ "fabs $dst,$src\t# vector (2S)" %} 17085 ins_encode %{ 17086 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 17087 as_FloatRegister($src$$reg)); 17088 %} 17089 ins_pipe(vunop_fp64); 17090 %} 17091 17092 instruct vabs4F(vecX dst, vecX src) 17093 %{ 17094 predicate(n->as_Vector()->length() == 4); 17095 match(Set dst (AbsVF src)); 17096 ins_cost(INSN_COST * 3); 17097 format %{ "fabs $dst,$src\t# vector (4S)" %} 17098 ins_encode %{ 17099 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 17100 as_FloatRegister($src$$reg)); 17101 %} 17102 ins_pipe(vunop_fp128); 17103 %} 17104 17105 instruct vabs2D(vecX dst, vecX src) 17106 %{ 17107 predicate(n->as_Vector()->length() == 2); 17108 match(Set dst (AbsVD src)); 17109 ins_cost(INSN_COST * 3); 17110 format %{ "fabs $dst,$src\t# vector (2D)" %} 17111 ins_encode %{ 17112 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17113 as_FloatRegister($src$$reg)); 17114 %} 17115 ins_pipe(vunop_fp128); 17116 %} 17117 17118 // --------------------------------- NEG -------------------------------------- 17119 17120 instruct vneg2F(vecD dst, vecD src) 17121 %{ 17122 predicate(n->as_Vector()->length() == 2); 17123 match(Set dst (NegVF src)); 17124 ins_cost(INSN_COST * 3); 17125 format %{ "fneg $dst,$src\t# vector (2S)" %} 17126 ins_encode %{ 17127 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17128 as_FloatRegister($src$$reg)); 17129 %} 17130 ins_pipe(vunop_fp64); 17131 %} 17132 17133 instruct vneg4F(vecX dst, vecX src) 17134 %{ 17135 predicate(n->as_Vector()->length() == 4); 17136 match(Set dst (NegVF src)); 17137 ins_cost(INSN_COST * 3); 17138 format %{ "fneg $dst,$src\t# vector (4S)" %} 17139 ins_encode %{ 17140 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17141 as_FloatRegister($src$$reg)); 17142 %} 17143 ins_pipe(vunop_fp128); 17144 %} 17145 17146 instruct vneg2D(vecX dst, vecX src) 17147 %{ 17148 predicate(n->as_Vector()->length() == 2); 17149 match(Set dst (NegVD src)); 17150 ins_cost(INSN_COST * 3); 17151 format %{ "fneg $dst,$src\t# vector (2D)" %} 17152 ins_encode %{ 17153 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17154 as_FloatRegister($src$$reg)); 17155 %} 17156 ins_pipe(vunop_fp128); 17157 %} 17158 17159 // --------------------------------- AND -------------------------------------- 17160 17161 instruct vand8B(vecD dst, vecD src1, vecD src2) 17162 %{ 17163 predicate(n->as_Vector()->length_in_bytes() == 4 || 17164 n->as_Vector()->length_in_bytes() == 8); 17165 match(Set dst (AndV src1 src2)); 17166 ins_cost(INSN_COST); 17167 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17168 ins_encode %{ 17169 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17170 as_FloatRegister($src1$$reg), 17171 as_FloatRegister($src2$$reg)); 17172 %} 17173 ins_pipe(vlogical64); 17174 %} 17175 17176 instruct vand16B(vecX dst, vecX src1, vecX src2) 17177 %{ 17178 predicate(n->as_Vector()->length_in_bytes() == 16); 17179 match(Set dst (AndV src1 src2)); 17180 ins_cost(INSN_COST); 17181 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17182 ins_encode %{ 17183 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17184 as_FloatRegister($src1$$reg), 17185 as_FloatRegister($src2$$reg)); 17186 %} 17187 ins_pipe(vlogical128); 17188 %} 17189 17190 // --------------------------------- OR --------------------------------------- 17191 17192 instruct vor8B(vecD dst, vecD src1, vecD src2) 17193 %{ 17194 predicate(n->as_Vector()->length_in_bytes() == 4 || 17195 n->as_Vector()->length_in_bytes() == 8); 17196 match(Set dst (OrV src1 src2)); 17197 ins_cost(INSN_COST); 17198 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17199 ins_encode %{ 17200 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17201 as_FloatRegister($src1$$reg), 17202 as_FloatRegister($src2$$reg)); 17203 %} 17204 ins_pipe(vlogical64); 17205 %} 17206 17207 instruct vor16B(vecX dst, vecX src1, vecX src2) 17208 %{ 17209 predicate(n->as_Vector()->length_in_bytes() == 16); 17210 match(Set dst (OrV src1 src2)); 17211 ins_cost(INSN_COST); 17212 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17213 ins_encode %{ 17214 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17215 as_FloatRegister($src1$$reg), 17216 as_FloatRegister($src2$$reg)); 17217 %} 17218 ins_pipe(vlogical128); 17219 %} 17220 17221 // --------------------------------- XOR -------------------------------------- 17222 17223 instruct vxor8B(vecD dst, vecD src1, vecD src2) 17224 %{ 17225 predicate(n->as_Vector()->length_in_bytes() == 4 || 17226 n->as_Vector()->length_in_bytes() == 8); 17227 match(Set dst (XorV src1 src2)); 17228 ins_cost(INSN_COST); 17229 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17230 ins_encode %{ 17231 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17232 as_FloatRegister($src1$$reg), 17233 as_FloatRegister($src2$$reg)); 17234 %} 17235 ins_pipe(vlogical64); 17236 %} 17237 17238 instruct vxor16B(vecX dst, vecX src1, vecX src2) 17239 %{ 17240 predicate(n->as_Vector()->length_in_bytes() == 16); 17241 match(Set dst (XorV src1 src2)); 17242 ins_cost(INSN_COST); 17243 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17244 ins_encode %{ 17245 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17246 as_FloatRegister($src1$$reg), 17247 as_FloatRegister($src2$$reg)); 17248 %} 17249 ins_pipe(vlogical128); 17250 %} 17251 17252 // ------------------------------ Shift --------------------------------------- 17253 instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17254 predicate(n->as_Vector()->length_in_bytes() == 8); 17255 match(Set dst (LShiftCntV cnt)); 17256 match(Set dst (RShiftCntV cnt)); 17257 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17258 ins_encode %{ 17259 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17260 %} 17261 ins_pipe(vdup_reg_reg64); 17262 %} 17263 17264 instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17265 predicate(n->as_Vector()->length_in_bytes() == 16); 17266 match(Set dst (LShiftCntV cnt)); 17267 match(Set dst (RShiftCntV cnt)); 17268 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17269 ins_encode %{ 17270 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17271 %} 17272 ins_pipe(vdup_reg_reg128); 17273 %} 17274 17275 instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17276 predicate(n->as_Vector()->length() == 4 || 17277 n->as_Vector()->length() == 8); 17278 match(Set dst (LShiftVB src shift)); 17279 ins_cost(INSN_COST); 17280 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17281 ins_encode %{ 17282 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17283 as_FloatRegister($src$$reg), 17284 as_FloatRegister($shift$$reg)); 17285 %} 17286 ins_pipe(vshift64); 17287 %} 17288 17289 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17290 predicate(n->as_Vector()->length() == 16); 17291 match(Set dst (LShiftVB src shift)); 17292 ins_cost(INSN_COST); 17293 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17294 ins_encode %{ 17295 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17296 as_FloatRegister($src$$reg), 17297 as_FloatRegister($shift$$reg)); 17298 %} 17299 ins_pipe(vshift128); 17300 %} 17301 17302 // Right shifts with vector shift count on aarch64 SIMD are implemented 17303 // as left shift by negative shift count. 17304 // There are two cases for vector shift count. 17305 // 17306 // Case 1: The vector shift count is from replication. 17307 // | | 17308 // LoadVector RShiftCntV 17309 // | / 17310 // RShiftVI 17311 // Note: In inner loop, multiple neg instructions are used, which can be 17312 // moved to outer loop and merge into one neg instruction. 17313 // 17314 // Case 2: The vector shift count is from loading. 17315 // This case isn't supported by middle-end now. But it's supported by 17316 // panama/vectorIntrinsics(JEP 338: Vector API). 17317 // | | 17318 // LoadVector LoadVector 17319 // | / 17320 // RShiftVI 17321 // 17322 17323 instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17324 predicate(n->as_Vector()->length() == 4 || 17325 n->as_Vector()->length() == 8); 17326 match(Set dst (RShiftVB src shift)); 17327 ins_cost(INSN_COST); 17328 effect(TEMP tmp); 17329 format %{ "negr $tmp,$shift\t" 17330 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17331 ins_encode %{ 17332 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17333 as_FloatRegister($shift$$reg)); 17334 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17335 as_FloatRegister($src$$reg), 17336 as_FloatRegister($tmp$$reg)); 17337 %} 17338 ins_pipe(vshift64); 17339 %} 17340 17341 instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17342 predicate(n->as_Vector()->length() == 16); 17343 match(Set dst (RShiftVB src shift)); 17344 ins_cost(INSN_COST); 17345 effect(TEMP tmp); 17346 format %{ "negr $tmp,$shift\t" 17347 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17348 ins_encode %{ 17349 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17350 as_FloatRegister($shift$$reg)); 17351 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17352 as_FloatRegister($src$$reg), 17353 as_FloatRegister($tmp$$reg)); 17354 %} 17355 ins_pipe(vshift128); 17356 %} 17357 17358 instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17359 predicate(n->as_Vector()->length() == 4 || 17360 n->as_Vector()->length() == 8); 17361 match(Set dst (URShiftVB src shift)); 17362 ins_cost(INSN_COST); 17363 effect(TEMP tmp); 17364 format %{ "negr $tmp,$shift\t" 17365 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17366 ins_encode %{ 17367 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17368 as_FloatRegister($shift$$reg)); 17369 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17370 as_FloatRegister($src$$reg), 17371 as_FloatRegister($tmp$$reg)); 17372 %} 17373 ins_pipe(vshift64); 17374 %} 17375 17376 instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17377 predicate(n->as_Vector()->length() == 16); 17378 match(Set dst (URShiftVB src shift)); 17379 ins_cost(INSN_COST); 17380 effect(TEMP tmp); 17381 format %{ "negr $tmp,$shift\t" 17382 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17383 ins_encode %{ 17384 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17385 as_FloatRegister($shift$$reg)); 17386 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17387 as_FloatRegister($src$$reg), 17388 as_FloatRegister($tmp$$reg)); 17389 %} 17390 ins_pipe(vshift128); 17391 %} 17392 17393 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17394 predicate(n->as_Vector()->length() == 4 || 17395 n->as_Vector()->length() == 8); 17396 match(Set dst (LShiftVB src shift)); 17397 ins_cost(INSN_COST); 17398 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17399 ins_encode %{ 17400 int sh = (int)$shift$$constant; 17401 if (sh >= 8) { 17402 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17403 as_FloatRegister($src$$reg), 17404 as_FloatRegister($src$$reg)); 17405 } else { 17406 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17407 as_FloatRegister($src$$reg), sh); 17408 } 17409 %} 17410 ins_pipe(vshift64_imm); 17411 %} 17412 17413 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17414 predicate(n->as_Vector()->length() == 16); 17415 match(Set dst (LShiftVB src shift)); 17416 ins_cost(INSN_COST); 17417 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17418 ins_encode %{ 17419 int sh = (int)$shift$$constant; 17420 if (sh >= 8) { 17421 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17422 as_FloatRegister($src$$reg), 17423 as_FloatRegister($src$$reg)); 17424 } else { 17425 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17426 as_FloatRegister($src$$reg), sh); 17427 } 17428 %} 17429 ins_pipe(vshift128_imm); 17430 %} 17431 17432 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17433 predicate(n->as_Vector()->length() == 4 || 17434 n->as_Vector()->length() == 8); 17435 match(Set dst (RShiftVB src shift)); 17436 ins_cost(INSN_COST); 17437 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17438 ins_encode %{ 17439 int sh = (int)$shift$$constant; 17440 if (sh >= 8) sh = 7; 17441 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17442 as_FloatRegister($src$$reg), sh); 17443 %} 17444 ins_pipe(vshift64_imm); 17445 %} 17446 17447 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17448 predicate(n->as_Vector()->length() == 16); 17449 match(Set dst (RShiftVB src shift)); 17450 ins_cost(INSN_COST); 17451 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17452 ins_encode %{ 17453 int sh = (int)$shift$$constant; 17454 if (sh >= 8) sh = 7; 17455 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17456 as_FloatRegister($src$$reg), sh); 17457 %} 17458 ins_pipe(vshift128_imm); 17459 %} 17460 17461 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17462 predicate(n->as_Vector()->length() == 4 || 17463 n->as_Vector()->length() == 8); 17464 match(Set dst (URShiftVB src shift)); 17465 ins_cost(INSN_COST); 17466 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17467 ins_encode %{ 17468 int sh = (int)$shift$$constant; 17469 if (sh >= 8) { 17470 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17471 as_FloatRegister($src$$reg), 17472 as_FloatRegister($src$$reg)); 17473 } else { 17474 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17475 as_FloatRegister($src$$reg), sh); 17476 } 17477 %} 17478 ins_pipe(vshift64_imm); 17479 %} 17480 17481 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17482 predicate(n->as_Vector()->length() == 16); 17483 match(Set dst (URShiftVB src shift)); 17484 ins_cost(INSN_COST); 17485 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17486 ins_encode %{ 17487 int sh = (int)$shift$$constant; 17488 if (sh >= 8) { 17489 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17490 as_FloatRegister($src$$reg), 17491 as_FloatRegister($src$$reg)); 17492 } else { 17493 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17494 as_FloatRegister($src$$reg), sh); 17495 } 17496 %} 17497 ins_pipe(vshift128_imm); 17498 %} 17499 17500 instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17501 predicate(n->as_Vector()->length() == 2 || 17502 n->as_Vector()->length() == 4); 17503 match(Set dst (LShiftVS src shift)); 17504 ins_cost(INSN_COST); 17505 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17506 ins_encode %{ 17507 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17508 as_FloatRegister($src$$reg), 17509 as_FloatRegister($shift$$reg)); 17510 %} 17511 ins_pipe(vshift64); 17512 %} 17513 17514 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17515 predicate(n->as_Vector()->length() == 8); 17516 match(Set dst (LShiftVS src shift)); 17517 ins_cost(INSN_COST); 17518 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17519 ins_encode %{ 17520 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17521 as_FloatRegister($src$$reg), 17522 as_FloatRegister($shift$$reg)); 17523 %} 17524 ins_pipe(vshift128); 17525 %} 17526 17527 instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17528 predicate(n->as_Vector()->length() == 2 || 17529 n->as_Vector()->length() == 4); 17530 match(Set dst (RShiftVS src shift)); 17531 ins_cost(INSN_COST); 17532 effect(TEMP tmp); 17533 format %{ "negr $tmp,$shift\t" 17534 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17535 ins_encode %{ 17536 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17537 as_FloatRegister($shift$$reg)); 17538 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17539 as_FloatRegister($src$$reg), 17540 as_FloatRegister($tmp$$reg)); 17541 %} 17542 ins_pipe(vshift64); 17543 %} 17544 17545 instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17546 predicate(n->as_Vector()->length() == 8); 17547 match(Set dst (RShiftVS src shift)); 17548 ins_cost(INSN_COST); 17549 effect(TEMP tmp); 17550 format %{ "negr $tmp,$shift\t" 17551 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17552 ins_encode %{ 17553 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17554 as_FloatRegister($shift$$reg)); 17555 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17556 as_FloatRegister($src$$reg), 17557 as_FloatRegister($tmp$$reg)); 17558 %} 17559 ins_pipe(vshift128); 17560 %} 17561 17562 instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17563 predicate(n->as_Vector()->length() == 2 || 17564 n->as_Vector()->length() == 4); 17565 match(Set dst (URShiftVS src shift)); 17566 ins_cost(INSN_COST); 17567 effect(TEMP tmp); 17568 format %{ "negr $tmp,$shift\t" 17569 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17570 ins_encode %{ 17571 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17572 as_FloatRegister($shift$$reg)); 17573 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17574 as_FloatRegister($src$$reg), 17575 as_FloatRegister($tmp$$reg)); 17576 %} 17577 ins_pipe(vshift64); 17578 %} 17579 17580 instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17581 predicate(n->as_Vector()->length() == 8); 17582 match(Set dst (URShiftVS src shift)); 17583 ins_cost(INSN_COST); 17584 effect(TEMP tmp); 17585 format %{ "negr $tmp,$shift\t" 17586 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17587 ins_encode %{ 17588 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17589 as_FloatRegister($shift$$reg)); 17590 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17591 as_FloatRegister($src$$reg), 17592 as_FloatRegister($tmp$$reg)); 17593 %} 17594 ins_pipe(vshift128); 17595 %} 17596 17597 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17598 predicate(n->as_Vector()->length() == 2 || 17599 n->as_Vector()->length() == 4); 17600 match(Set dst (LShiftVS src shift)); 17601 ins_cost(INSN_COST); 17602 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17603 ins_encode %{ 17604 int sh = (int)$shift$$constant; 17605 if (sh >= 16) { 17606 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17607 as_FloatRegister($src$$reg), 17608 as_FloatRegister($src$$reg)); 17609 } else { 17610 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17611 as_FloatRegister($src$$reg), sh); 17612 } 17613 %} 17614 ins_pipe(vshift64_imm); 17615 %} 17616 17617 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17618 predicate(n->as_Vector()->length() == 8); 17619 match(Set dst (LShiftVS src shift)); 17620 ins_cost(INSN_COST); 17621 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17622 ins_encode %{ 17623 int sh = (int)$shift$$constant; 17624 if (sh >= 16) { 17625 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17626 as_FloatRegister($src$$reg), 17627 as_FloatRegister($src$$reg)); 17628 } else { 17629 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17630 as_FloatRegister($src$$reg), sh); 17631 } 17632 %} 17633 ins_pipe(vshift128_imm); 17634 %} 17635 17636 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17637 predicate(n->as_Vector()->length() == 2 || 17638 n->as_Vector()->length() == 4); 17639 match(Set dst (RShiftVS src shift)); 17640 ins_cost(INSN_COST); 17641 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17642 ins_encode %{ 17643 int sh = (int)$shift$$constant; 17644 if (sh >= 16) sh = 15; 17645 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17646 as_FloatRegister($src$$reg), sh); 17647 %} 17648 ins_pipe(vshift64_imm); 17649 %} 17650 17651 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17652 predicate(n->as_Vector()->length() == 8); 17653 match(Set dst (RShiftVS src shift)); 17654 ins_cost(INSN_COST); 17655 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17656 ins_encode %{ 17657 int sh = (int)$shift$$constant; 17658 if (sh >= 16) sh = 15; 17659 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17660 as_FloatRegister($src$$reg), sh); 17661 %} 17662 ins_pipe(vshift128_imm); 17663 %} 17664 17665 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17666 predicate(n->as_Vector()->length() == 2 || 17667 n->as_Vector()->length() == 4); 17668 match(Set dst (URShiftVS src shift)); 17669 ins_cost(INSN_COST); 17670 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17671 ins_encode %{ 17672 int sh = (int)$shift$$constant; 17673 if (sh >= 16) { 17674 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17675 as_FloatRegister($src$$reg), 17676 as_FloatRegister($src$$reg)); 17677 } else { 17678 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17679 as_FloatRegister($src$$reg), sh); 17680 } 17681 %} 17682 ins_pipe(vshift64_imm); 17683 %} 17684 17685 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17686 predicate(n->as_Vector()->length() == 8); 17687 match(Set dst (URShiftVS src shift)); 17688 ins_cost(INSN_COST); 17689 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17690 ins_encode %{ 17691 int sh = (int)$shift$$constant; 17692 if (sh >= 16) { 17693 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17694 as_FloatRegister($src$$reg), 17695 as_FloatRegister($src$$reg)); 17696 } else { 17697 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17698 as_FloatRegister($src$$reg), sh); 17699 } 17700 %} 17701 ins_pipe(vshift128_imm); 17702 %} 17703 17704 instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17705 predicate(n->as_Vector()->length() == 2); 17706 match(Set dst (LShiftVI src shift)); 17707 ins_cost(INSN_COST); 17708 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17709 ins_encode %{ 17710 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17711 as_FloatRegister($src$$reg), 17712 as_FloatRegister($shift$$reg)); 17713 %} 17714 ins_pipe(vshift64); 17715 %} 17716 17717 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17718 predicate(n->as_Vector()->length() == 4); 17719 match(Set dst (LShiftVI src shift)); 17720 ins_cost(INSN_COST); 17721 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17722 ins_encode %{ 17723 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17724 as_FloatRegister($src$$reg), 17725 as_FloatRegister($shift$$reg)); 17726 %} 17727 ins_pipe(vshift128); 17728 %} 17729 17730 instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17731 predicate(n->as_Vector()->length() == 2); 17732 match(Set dst (RShiftVI src shift)); 17733 ins_cost(INSN_COST); 17734 effect(TEMP tmp); 17735 format %{ "negr $tmp,$shift\t" 17736 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17737 ins_encode %{ 17738 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17739 as_FloatRegister($shift$$reg)); 17740 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17741 as_FloatRegister($src$$reg), 17742 as_FloatRegister($tmp$$reg)); 17743 %} 17744 ins_pipe(vshift64); 17745 %} 17746 17747 instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17748 predicate(n->as_Vector()->length() == 4); 17749 match(Set dst (RShiftVI src shift)); 17750 ins_cost(INSN_COST); 17751 effect(TEMP tmp); 17752 format %{ "negr $tmp,$shift\t" 17753 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17754 ins_encode %{ 17755 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17756 as_FloatRegister($shift$$reg)); 17757 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17758 as_FloatRegister($src$$reg), 17759 as_FloatRegister($tmp$$reg)); 17760 %} 17761 ins_pipe(vshift128); 17762 %} 17763 17764 instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17765 predicate(n->as_Vector()->length() == 2); 17766 match(Set dst (URShiftVI src shift)); 17767 ins_cost(INSN_COST); 17768 effect(TEMP tmp); 17769 format %{ "negr $tmp,$shift\t" 17770 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17771 ins_encode %{ 17772 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17773 as_FloatRegister($shift$$reg)); 17774 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17775 as_FloatRegister($src$$reg), 17776 as_FloatRegister($tmp$$reg)); 17777 %} 17778 ins_pipe(vshift64); 17779 %} 17780 17781 instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17782 predicate(n->as_Vector()->length() == 4); 17783 match(Set dst (URShiftVI src shift)); 17784 ins_cost(INSN_COST); 17785 effect(TEMP tmp); 17786 format %{ "negr $tmp,$shift\t" 17787 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17788 ins_encode %{ 17789 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17790 as_FloatRegister($shift$$reg)); 17791 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17792 as_FloatRegister($src$$reg), 17793 as_FloatRegister($tmp$$reg)); 17794 %} 17795 ins_pipe(vshift128); 17796 %} 17797 17798 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17799 predicate(n->as_Vector()->length() == 2); 17800 match(Set dst (LShiftVI src shift)); 17801 ins_cost(INSN_COST); 17802 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17803 ins_encode %{ 17804 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17805 as_FloatRegister($src$$reg), 17806 (int)$shift$$constant); 17807 %} 17808 ins_pipe(vshift64_imm); 17809 %} 17810 17811 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17812 predicate(n->as_Vector()->length() == 4); 17813 match(Set dst (LShiftVI src shift)); 17814 ins_cost(INSN_COST); 17815 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17816 ins_encode %{ 17817 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17818 as_FloatRegister($src$$reg), 17819 (int)$shift$$constant); 17820 %} 17821 ins_pipe(vshift128_imm); 17822 %} 17823 17824 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17825 predicate(n->as_Vector()->length() == 2); 17826 match(Set dst (RShiftVI src shift)); 17827 ins_cost(INSN_COST); 17828 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17829 ins_encode %{ 17830 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17831 as_FloatRegister($src$$reg), 17832 (int)$shift$$constant); 17833 %} 17834 ins_pipe(vshift64_imm); 17835 %} 17836 17837 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17838 predicate(n->as_Vector()->length() == 4); 17839 match(Set dst (RShiftVI src shift)); 17840 ins_cost(INSN_COST); 17841 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17842 ins_encode %{ 17843 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17844 as_FloatRegister($src$$reg), 17845 (int)$shift$$constant); 17846 %} 17847 ins_pipe(vshift128_imm); 17848 %} 17849 17850 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17851 predicate(n->as_Vector()->length() == 2); 17852 match(Set dst (URShiftVI src shift)); 17853 ins_cost(INSN_COST); 17854 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17855 ins_encode %{ 17856 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17857 as_FloatRegister($src$$reg), 17858 (int)$shift$$constant); 17859 %} 17860 ins_pipe(vshift64_imm); 17861 %} 17862 17863 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17864 predicate(n->as_Vector()->length() == 4); 17865 match(Set dst (URShiftVI src shift)); 17866 ins_cost(INSN_COST); 17867 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17868 ins_encode %{ 17869 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17870 as_FloatRegister($src$$reg), 17871 (int)$shift$$constant); 17872 %} 17873 ins_pipe(vshift128_imm); 17874 %} 17875 17876 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17877 predicate(n->as_Vector()->length() == 2); 17878 match(Set dst (LShiftVL src shift)); 17879 ins_cost(INSN_COST); 17880 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17881 ins_encode %{ 17882 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17883 as_FloatRegister($src$$reg), 17884 as_FloatRegister($shift$$reg)); 17885 %} 17886 ins_pipe(vshift128); 17887 %} 17888 17889 instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17890 predicate(n->as_Vector()->length() == 2); 17891 match(Set dst (RShiftVL src shift)); 17892 ins_cost(INSN_COST); 17893 effect(TEMP tmp); 17894 format %{ "negr $tmp,$shift\t" 17895 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17896 ins_encode %{ 17897 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17898 as_FloatRegister($shift$$reg)); 17899 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17900 as_FloatRegister($src$$reg), 17901 as_FloatRegister($tmp$$reg)); 17902 %} 17903 ins_pipe(vshift128); 17904 %} 17905 17906 instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17907 predicate(n->as_Vector()->length() == 2); 17908 match(Set dst (URShiftVL src shift)); 17909 ins_cost(INSN_COST); 17910 effect(TEMP tmp); 17911 format %{ "negr $tmp,$shift\t" 17912 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17913 ins_encode %{ 17914 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17915 as_FloatRegister($shift$$reg)); 17916 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17917 as_FloatRegister($src$$reg), 17918 as_FloatRegister($tmp$$reg)); 17919 %} 17920 ins_pipe(vshift128); 17921 %} 17922 17923 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17924 predicate(n->as_Vector()->length() == 2); 17925 match(Set dst (LShiftVL src shift)); 17926 ins_cost(INSN_COST); 17927 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17928 ins_encode %{ 17929 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17930 as_FloatRegister($src$$reg), 17931 (int)$shift$$constant); 17932 %} 17933 ins_pipe(vshift128_imm); 17934 %} 17935 17936 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17937 predicate(n->as_Vector()->length() == 2); 17938 match(Set dst (RShiftVL src shift)); 17939 ins_cost(INSN_COST); 17940 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17941 ins_encode %{ 17942 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17943 as_FloatRegister($src$$reg), 17944 (int)$shift$$constant); 17945 %} 17946 ins_pipe(vshift128_imm); 17947 %} 17948 17949 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17950 predicate(n->as_Vector()->length() == 2); 17951 match(Set dst (URShiftVL src shift)); 17952 ins_cost(INSN_COST); 17953 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17954 ins_encode %{ 17955 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17956 as_FloatRegister($src$$reg), 17957 (int)$shift$$constant); 17958 %} 17959 ins_pipe(vshift128_imm); 17960 %} 17961 17962 instruct vmax2F(vecD dst, vecD src1, vecD src2) 17963 %{ 17964 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17965 match(Set dst (MaxV src1 src2)); 17966 ins_cost(INSN_COST); 17967 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 17968 ins_encode %{ 17969 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 17970 as_FloatRegister($src1$$reg), 17971 as_FloatRegister($src2$$reg)); 17972 %} 17973 ins_pipe(vdop_fp64); 17974 %} 17975 17976 instruct vmax4F(vecX dst, vecX src1, vecX src2) 17977 %{ 17978 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17979 match(Set dst (MaxV src1 src2)); 17980 ins_cost(INSN_COST); 17981 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 17982 ins_encode %{ 17983 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 17984 as_FloatRegister($src1$$reg), 17985 as_FloatRegister($src2$$reg)); 17986 %} 17987 ins_pipe(vdop_fp128); 17988 %} 17989 17990 instruct vmax2D(vecX dst, vecX src1, vecX src2) 17991 %{ 17992 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17993 match(Set dst (MaxV src1 src2)); 17994 ins_cost(INSN_COST); 17995 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 17996 ins_encode %{ 17997 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 17998 as_FloatRegister($src1$$reg), 17999 as_FloatRegister($src2$$reg)); 18000 %} 18001 ins_pipe(vdop_fp128); 18002 %} 18003 18004 instruct vmin2F(vecD dst, vecD src1, vecD src2) 18005 %{ 18006 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18007 match(Set dst (MinV src1 src2)); 18008 ins_cost(INSN_COST); 18009 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 18010 ins_encode %{ 18011 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 18012 as_FloatRegister($src1$$reg), 18013 as_FloatRegister($src2$$reg)); 18014 %} 18015 ins_pipe(vdop_fp64); 18016 %} 18017 18018 instruct vmin4F(vecX dst, vecX src1, vecX src2) 18019 %{ 18020 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 18021 match(Set dst (MinV src1 src2)); 18022 ins_cost(INSN_COST); 18023 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 18024 ins_encode %{ 18025 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 18026 as_FloatRegister($src1$$reg), 18027 as_FloatRegister($src2$$reg)); 18028 %} 18029 ins_pipe(vdop_fp128); 18030 %} 18031 18032 instruct vmin2D(vecX dst, vecX src1, vecX src2) 18033 %{ 18034 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 18035 match(Set dst (MinV src1 src2)); 18036 ins_cost(INSN_COST); 18037 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 18038 ins_encode %{ 18039 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 18040 as_FloatRegister($src1$$reg), 18041 as_FloatRegister($src2$$reg)); 18042 %} 18043 ins_pipe(vdop_fp128); 18044 %} 18045 18046 //----------PEEPHOLE RULES----------------------------------------------------- 18047 // These must follow all instruction definitions as they use the names 18048 // defined in the instructions definitions. 18049 // 18050 // peepmatch ( root_instr_name [preceding_instruction]* ); 18051 // 18052 // peepconstraint %{ 18053 // (instruction_number.operand_name relational_op instruction_number.operand_name 18054 // [, ...] ); 18055 // // instruction numbers are zero-based using left to right order in peepmatch 18056 // 18057 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 18058 // // provide an instruction_number.operand_name for each operand that appears 18059 // // in the replacement instruction's match rule 18060 // 18061 // ---------VM FLAGS--------------------------------------------------------- 18062 // 18063 // All peephole optimizations can be turned off using -XX:-OptoPeephole 18064 // 18065 // Each peephole rule is given an identifying number starting with zero and 18066 // increasing by one in the order seen by the parser. An individual peephole 18067 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 18068 // on the command-line. 18069 // 18070 // ---------CURRENT LIMITATIONS---------------------------------------------- 18071 // 18072 // Only match adjacent instructions in same basic block 18073 // Only equality constraints 18074 // Only constraints between operands, not (0.dest_reg == RAX_enc) 18075 // Only one replacement instruction 18076 // 18077 // ---------EXAMPLE---------------------------------------------------------- 18078 // 18079 // // pertinent parts of existing instructions in architecture description 18080 // instruct movI(iRegINoSp dst, iRegI src) 18081 // %{ 18082 // match(Set dst (CopyI src)); 18083 // %} 18084 // 18085 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18086 // %{ 18087 // match(Set dst (AddI dst src)); 18088 // effect(KILL cr); 18089 // %} 18090 // 18091 // // Change (inc mov) to lea 18092 // peephole %{ 18093 // // increment preceeded by register-register move 18094 // peepmatch ( incI_iReg movI ); 18095 // // require that the destination register of the increment 18096 // // match the destination register of the move 18097 // peepconstraint ( 0.dst == 1.dst ); 18098 // // construct a replacement instruction that sets 18099 // // the destination to ( move's source register + one ) 18100 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18101 // %} 18102 // 18103 18104 // Implementation no longer uses movX instructions since 18105 // machine-independent system no longer uses CopyX nodes. 18106 // 18107 // peephole 18108 // %{ 18109 // peepmatch (incI_iReg movI); 18110 // peepconstraint (0.dst == 1.dst); 18111 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18112 // %} 18113 18114 // peephole 18115 // %{ 18116 // peepmatch (decI_iReg movI); 18117 // peepconstraint (0.dst == 1.dst); 18118 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18119 // %} 18120 18121 // peephole 18122 // %{ 18123 // peepmatch (addI_iReg_imm movI); 18124 // peepconstraint (0.dst == 1.dst); 18125 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18126 // %} 18127 18128 // peephole 18129 // %{ 18130 // peepmatch (incL_iReg movL); 18131 // peepconstraint (0.dst == 1.dst); 18132 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18133 // %} 18134 18135 // peephole 18136 // %{ 18137 // peepmatch (decL_iReg movL); 18138 // peepconstraint (0.dst == 1.dst); 18139 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18140 // %} 18141 18142 // peephole 18143 // %{ 18144 // peepmatch (addL_iReg_imm movL); 18145 // peepconstraint (0.dst == 1.dst); 18146 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18147 // %} 18148 18149 // peephole 18150 // %{ 18151 // peepmatch (addP_iReg_imm movP); 18152 // peepconstraint (0.dst == 1.dst); 18153 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18154 // %} 18155 18156 // // Change load of spilled value to only a spill 18157 // instruct storeI(memory mem, iRegI src) 18158 // %{ 18159 // match(Set mem (StoreI mem src)); 18160 // %} 18161 // 18162 // instruct loadI(iRegINoSp dst, memory mem) 18163 // %{ 18164 // match(Set dst (LoadI mem)); 18165 // %} 18166 // 18167 18168 //----------SMARTSPILL RULES--------------------------------------------------- 18169 // These must follow all instruction definitions as they use the names 18170 // defined in the instructions definitions. 18171 18172 // Local Variables: 18173 // mode: c++ 18174 // End: