1 // 2 // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, Red Hat Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 167 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 168 169 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 170 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 171 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 172 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 173 174 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 175 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 176 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 177 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 178 179 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 180 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 181 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 182 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 183 184 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 185 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 186 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 187 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 188 189 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 190 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 191 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 192 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 193 194 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 195 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 196 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 197 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 198 199 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 200 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 201 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 202 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 203 204 reg_def V8 ( SOC, SOC, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next() ); 206 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 207 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 208 209 reg_def V9 ( SOC, SOC, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next() ); 211 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 212 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 213 214 reg_def V10 ( SOC, SOC, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next() ); 216 reg_def V10_J( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2)); 217 reg_def V10_K( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3)); 218 219 reg_def V11 ( SOC, SOC, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next() ); 221 reg_def V11_J( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2)); 222 reg_def V11_K( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3)); 223 224 reg_def V12 ( SOC, SOC, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next() ); 226 reg_def V12_J( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2)); 227 reg_def V12_K( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3)); 228 229 reg_def V13 ( SOC, SOC, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next() ); 231 reg_def V13_J( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2)); 232 reg_def V13_K( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3)); 233 234 reg_def V14 ( SOC, SOC, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next() ); 236 reg_def V14_J( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2)); 237 reg_def V14_K( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3)); 238 239 reg_def V15 ( SOC, SOC, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next() ); 241 reg_def V15_J( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2)); 242 reg_def V15_K( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3)); 243 244 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 245 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 246 reg_def V16_J( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2)); 247 reg_def V16_K( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3)); 248 249 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 250 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 251 reg_def V17_J( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2)); 252 reg_def V17_K( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3)); 253 254 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 255 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 256 reg_def V18_J( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2)); 257 reg_def V18_K( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3)); 258 259 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 260 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 261 reg_def V19_J( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2)); 262 reg_def V19_K( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3)); 263 264 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 265 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 266 reg_def V20_J( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2)); 267 reg_def V20_K( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3)); 268 269 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 270 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 271 reg_def V21_J( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2)); 272 reg_def V21_K( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3)); 273 274 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 275 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 276 reg_def V22_J( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2)); 277 reg_def V22_K( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3)); 278 279 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 280 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 281 reg_def V23_J( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2)); 282 reg_def V23_K( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3)); 283 284 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 285 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 286 reg_def V24_J( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2)); 287 reg_def V24_K( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3)); 288 289 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 290 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 291 reg_def V25_J( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2)); 292 reg_def V25_K( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3)); 293 294 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 295 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 296 reg_def V26_J( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2)); 297 reg_def V26_K( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3)); 298 299 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 300 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 301 reg_def V27_J( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2)); 302 reg_def V27_K( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3)); 303 304 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 305 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 306 reg_def V28_J( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2)); 307 reg_def V28_K( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3)); 308 309 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 310 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 311 reg_def V29_J( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2)); 312 reg_def V29_K( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3)); 313 314 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 315 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 316 reg_def V30_J( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2)); 317 reg_def V30_K( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3)); 318 319 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 320 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 321 reg_def V31_J( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2)); 322 reg_def V31_K( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3)); 323 324 // ---------------------------- 325 // Special Registers 326 // ---------------------------- 327 328 // the AArch64 CSPR status flag register is not directly acessible as 329 // instruction operand. the FPSR status flag register is a system 330 // register which can be written/read using MSR/MRS but again does not 331 // appear as an operand (a code identifying the FSPR occurs as an 332 // immediate value in the instruction). 333 334 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 335 336 337 // Specify priority of register selection within phases of register 338 // allocation. Highest priority is first. A useful heuristic is to 339 // give registers a low priority when they are required by machine 340 // instructions, like EAX and EDX on I486, and choose no-save registers 341 // before save-on-call, & save-on-call before save-on-entry. Registers 342 // which participate in fixed calling sequences should come last. 343 // Registers which are used as pairs must fall on an even boundary. 344 345 alloc_class chunk0( 346 // volatiles 347 R10, R10_H, 348 R11, R11_H, 349 R12, R12_H, 350 R13, R13_H, 351 R14, R14_H, 352 R15, R15_H, 353 R16, R16_H, 354 R17, R17_H, 355 R18, R18_H, 356 357 // arg registers 358 R0, R0_H, 359 R1, R1_H, 360 R2, R2_H, 361 R3, R3_H, 362 R4, R4_H, 363 R5, R5_H, 364 R6, R6_H, 365 R7, R7_H, 366 367 // non-volatiles 368 R19, R19_H, 369 R20, R20_H, 370 R21, R21_H, 371 R22, R22_H, 372 R23, R23_H, 373 R24, R24_H, 374 R25, R25_H, 375 R26, R26_H, 376 377 // non-allocatable registers 378 379 R27, R27_H, // heapbase 380 R28, R28_H, // thread 381 R29, R29_H, // fp 382 R30, R30_H, // lr 383 R31, R31_H, // sp 384 ); 385 386 alloc_class chunk1( 387 388 // no save 389 V16, V16_H, V16_J, V16_K, 390 V17, V17_H, V17_J, V17_K, 391 V18, V18_H, V18_J, V18_K, 392 V19, V19_H, V19_J, V19_K, 393 V20, V20_H, V20_J, V20_K, 394 V21, V21_H, V21_J, V21_K, 395 V22, V22_H, V22_J, V22_K, 396 V23, V23_H, V23_J, V23_K, 397 V24, V24_H, V24_J, V24_K, 398 V25, V25_H, V25_J, V25_K, 399 V26, V26_H, V26_J, V26_K, 400 V27, V27_H, V27_J, V27_K, 401 V28, V28_H, V28_J, V28_K, 402 V29, V29_H, V29_J, V29_K, 403 V30, V30_H, V30_J, V30_K, 404 V31, V31_H, V31_J, V31_K, 405 406 // arg registers 407 V0, V0_H, V0_J, V0_K, 408 V1, V1_H, V1_J, V1_K, 409 V2, V2_H, V2_J, V2_K, 410 V3, V3_H, V3_J, V3_K, 411 V4, V4_H, V4_J, V4_K, 412 V5, V5_H, V5_J, V5_K, 413 V6, V6_H, V6_J, V6_K, 414 V7, V7_H, V7_J, V7_K, 415 416 // non-volatiles 417 V8, V8_H, V8_J, V8_K, 418 V9, V9_H, V9_J, V9_K, 419 V10, V10_H, V10_J, V10_K, 420 V11, V11_H, V11_J, V11_K, 421 V12, V12_H, V12_J, V12_K, 422 V13, V13_H, V13_J, V13_K, 423 V14, V14_H, V14_J, V14_K, 424 V15, V15_H, V15_J, V15_K, 425 ); 426 427 alloc_class chunk2(RFLAGS); 428 429 //----------Architecture Description Register Classes-------------------------- 430 // Several register classes are automatically defined based upon information in 431 // this architecture description. 432 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 433 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 434 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 435 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 436 // 437 438 // Class for all 32 bit integer registers -- excludes SP which will 439 // never be used as an integer register 440 reg_class any_reg32( 441 R0, 442 R1, 443 R2, 444 R3, 445 R4, 446 R5, 447 R6, 448 R7, 449 R10, 450 R11, 451 R12, 452 R13, 453 R14, 454 R15, 455 R16, 456 R17, 457 R18, 458 R19, 459 R20, 460 R21, 461 R22, 462 R23, 463 R24, 464 R25, 465 R26, 466 R27, 467 R28, 468 R29, 469 R30 470 ); 471 472 // Singleton class for R0 int register 473 reg_class int_r0_reg(R0); 474 475 // Singleton class for R2 int register 476 reg_class int_r2_reg(R2); 477 478 // Singleton class for R3 int register 479 reg_class int_r3_reg(R3); 480 481 // Singleton class for R4 int register 482 reg_class int_r4_reg(R4); 483 484 // Class for all long integer registers (including RSP) 485 reg_class any_reg( 486 R0, R0_H, 487 R1, R1_H, 488 R2, R2_H, 489 R3, R3_H, 490 R4, R4_H, 491 R5, R5_H, 492 R6, R6_H, 493 R7, R7_H, 494 R10, R10_H, 495 R11, R11_H, 496 R12, R12_H, 497 R13, R13_H, 498 R14, R14_H, 499 R15, R15_H, 500 R16, R16_H, 501 R17, R17_H, 502 R18, R18_H, 503 R19, R19_H, 504 R20, R20_H, 505 R21, R21_H, 506 R22, R22_H, 507 R23, R23_H, 508 R24, R24_H, 509 R25, R25_H, 510 R26, R26_H, 511 R27, R27_H, 512 R28, R28_H, 513 R29, R29_H, 514 R30, R30_H, 515 R31, R31_H 516 ); 517 518 // Class for all non-special integer registers 519 reg_class no_special_reg32_no_fp( 520 R0, 521 R1, 522 R2, 523 R3, 524 R4, 525 R5, 526 R6, 527 R7, 528 R10, 529 R11, 530 R12, // rmethod 531 R13, 532 R14, 533 R15, 534 R16, 535 R17, 536 R18, 537 R19, 538 R20, 539 R21, 540 R22, 541 R23, 542 R24, 543 R25, 544 R26 545 /* R27, */ // heapbase 546 /* R28, */ // thread 547 /* R29, */ // fp 548 /* R30, */ // lr 549 /* R31 */ // sp 550 ); 551 552 reg_class no_special_reg32_with_fp( 553 R0, 554 R1, 555 R2, 556 R3, 557 R4, 558 R5, 559 R6, 560 R7, 561 R10, 562 R11, 563 R12, // rmethod 564 R13, 565 R14, 566 R15, 567 R16, 568 R17, 569 R18, 570 R19, 571 R20, 572 R21, 573 R22, 574 R23, 575 R24, 576 R25, 577 R26 578 /* R27, */ // heapbase 579 /* R28, */ // thread 580 R29, // fp 581 /* R30, */ // lr 582 /* R31 */ // sp 583 ); 584 585 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); 586 587 // Class for all non-special long integer registers 588 reg_class no_special_reg_no_fp( 589 R0, R0_H, 590 R1, R1_H, 591 R2, R2_H, 592 R3, R3_H, 593 R4, R4_H, 594 R5, R5_H, 595 R6, R6_H, 596 R7, R7_H, 597 R10, R10_H, 598 R11, R11_H, 599 R12, R12_H, // rmethod 600 R13, R13_H, 601 R14, R14_H, 602 R15, R15_H, 603 R16, R16_H, 604 R17, R17_H, 605 R18, R18_H, 606 R19, R19_H, 607 R20, R20_H, 608 R21, R21_H, 609 R22, R22_H, 610 R23, R23_H, 611 R24, R24_H, 612 R25, R25_H, 613 R26, R26_H, 614 /* R27, R27_H, */ // heapbase 615 /* R28, R28_H, */ // thread 616 /* R29, R29_H, */ // fp 617 /* R30, R30_H, */ // lr 618 /* R31, R31_H */ // sp 619 ); 620 621 reg_class no_special_reg_with_fp( 622 R0, R0_H, 623 R1, R1_H, 624 R2, R2_H, 625 R3, R3_H, 626 R4, R4_H, 627 R5, R5_H, 628 R6, R6_H, 629 R7, R7_H, 630 R10, R10_H, 631 R11, R11_H, 632 R12, R12_H, // rmethod 633 R13, R13_H, 634 R14, R14_H, 635 R15, R15_H, 636 R16, R16_H, 637 R17, R17_H, 638 R18, R18_H, 639 R19, R19_H, 640 R20, R20_H, 641 R21, R21_H, 642 R22, R22_H, 643 R23, R23_H, 644 R24, R24_H, 645 R25, R25_H, 646 R26, R26_H, 647 /* R27, R27_H, */ // heapbase 648 /* R28, R28_H, */ // thread 649 R29, R29_H, // fp 650 /* R30, R30_H, */ // lr 651 /* R31, R31_H */ // sp 652 ); 653 654 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 655 656 // Class for 64 bit register r0 657 reg_class r0_reg( 658 R0, R0_H 659 ); 660 661 // Class for 64 bit register r1 662 reg_class r1_reg( 663 R1, R1_H 664 ); 665 666 // Class for 64 bit register r2 667 reg_class r2_reg( 668 R2, R2_H 669 ); 670 671 // Class for 64 bit register r3 672 reg_class r3_reg( 673 R3, R3_H 674 ); 675 676 // Class for 64 bit register r4 677 reg_class r4_reg( 678 R4, R4_H 679 ); 680 681 // Class for 64 bit register r5 682 reg_class r5_reg( 683 R5, R5_H 684 ); 685 686 // Class for 64 bit register r10 687 reg_class r10_reg( 688 R10, R10_H 689 ); 690 691 // Class for 64 bit register r11 692 reg_class r11_reg( 693 R11, R11_H 694 ); 695 696 // Class for method register 697 reg_class method_reg( 698 R12, R12_H 699 ); 700 701 // Class for heapbase register 702 reg_class heapbase_reg( 703 R27, R27_H 704 ); 705 706 // Class for thread register 707 reg_class thread_reg( 708 R28, R28_H 709 ); 710 711 // Class for frame pointer register 712 reg_class fp_reg( 713 R29, R29_H 714 ); 715 716 // Class for link register 717 reg_class lr_reg( 718 R30, R30_H 719 ); 720 721 // Class for long sp register 722 reg_class sp_reg( 723 R31, R31_H 724 ); 725 726 // Class for all pointer registers 727 reg_class ptr_reg( 728 R0, R0_H, 729 R1, R1_H, 730 R2, R2_H, 731 R3, R3_H, 732 R4, R4_H, 733 R5, R5_H, 734 R6, R6_H, 735 R7, R7_H, 736 R10, R10_H, 737 R11, R11_H, 738 R12, R12_H, 739 R13, R13_H, 740 R14, R14_H, 741 R15, R15_H, 742 R16, R16_H, 743 R17, R17_H, 744 R18, R18_H, 745 R19, R19_H, 746 R20, R20_H, 747 R21, R21_H, 748 R22, R22_H, 749 R23, R23_H, 750 R24, R24_H, 751 R25, R25_H, 752 R26, R26_H, 753 R27, R27_H, 754 R28, R28_H, 755 R29, R29_H, 756 R30, R30_H, 757 R31, R31_H 758 ); 759 760 // Class for all non_special pointer registers 761 reg_class no_special_ptr_reg( 762 R0, R0_H, 763 R1, R1_H, 764 R2, R2_H, 765 R3, R3_H, 766 R4, R4_H, 767 R5, R5_H, 768 R6, R6_H, 769 R7, R7_H, 770 R10, R10_H, 771 R11, R11_H, 772 R12, R12_H, 773 R13, R13_H, 774 R14, R14_H, 775 R15, R15_H, 776 R16, R16_H, 777 R17, R17_H, 778 R18, R18_H, 779 R19, R19_H, 780 R20, R20_H, 781 R21, R21_H, 782 R22, R22_H, 783 R23, R23_H, 784 R24, R24_H, 785 R25, R25_H, 786 R26, R26_H, 787 /* R27, R27_H, */ // heapbase 788 /* R28, R28_H, */ // thread 789 /* R29, R29_H, */ // fp 790 /* R30, R30_H, */ // lr 791 /* R31, R31_H */ // sp 792 ); 793 794 // Class for all float registers 795 reg_class float_reg( 796 V0, 797 V1, 798 V2, 799 V3, 800 V4, 801 V5, 802 V6, 803 V7, 804 V8, 805 V9, 806 V10, 807 V11, 808 V12, 809 V13, 810 V14, 811 V15, 812 V16, 813 V17, 814 V18, 815 V19, 816 V20, 817 V21, 818 V22, 819 V23, 820 V24, 821 V25, 822 V26, 823 V27, 824 V28, 825 V29, 826 V30, 827 V31 828 ); 829 830 // Double precision float registers have virtual `high halves' that 831 // are needed by the allocator. 832 // Class for all double registers 833 reg_class double_reg( 834 V0, V0_H, 835 V1, V1_H, 836 V2, V2_H, 837 V3, V3_H, 838 V4, V4_H, 839 V5, V5_H, 840 V6, V6_H, 841 V7, V7_H, 842 V8, V8_H, 843 V9, V9_H, 844 V10, V10_H, 845 V11, V11_H, 846 V12, V12_H, 847 V13, V13_H, 848 V14, V14_H, 849 V15, V15_H, 850 V16, V16_H, 851 V17, V17_H, 852 V18, V18_H, 853 V19, V19_H, 854 V20, V20_H, 855 V21, V21_H, 856 V22, V22_H, 857 V23, V23_H, 858 V24, V24_H, 859 V25, V25_H, 860 V26, V26_H, 861 V27, V27_H, 862 V28, V28_H, 863 V29, V29_H, 864 V30, V30_H, 865 V31, V31_H 866 ); 867 868 // Class for all 64bit vector registers 869 reg_class vectord_reg( 870 V0, V0_H, 871 V1, V1_H, 872 V2, V2_H, 873 V3, V3_H, 874 V4, V4_H, 875 V5, V5_H, 876 V6, V6_H, 877 V7, V7_H, 878 V8, V8_H, 879 V9, V9_H, 880 V10, V10_H, 881 V11, V11_H, 882 V12, V12_H, 883 V13, V13_H, 884 V14, V14_H, 885 V15, V15_H, 886 V16, V16_H, 887 V17, V17_H, 888 V18, V18_H, 889 V19, V19_H, 890 V20, V20_H, 891 V21, V21_H, 892 V22, V22_H, 893 V23, V23_H, 894 V24, V24_H, 895 V25, V25_H, 896 V26, V26_H, 897 V27, V27_H, 898 V28, V28_H, 899 V29, V29_H, 900 V30, V30_H, 901 V31, V31_H 902 ); 903 904 // Class for all 128bit vector registers 905 reg_class vectorx_reg( 906 V0, V0_H, V0_J, V0_K, 907 V1, V1_H, V1_J, V1_K, 908 V2, V2_H, V2_J, V2_K, 909 V3, V3_H, V3_J, V3_K, 910 V4, V4_H, V4_J, V4_K, 911 V5, V5_H, V5_J, V5_K, 912 V6, V6_H, V6_J, V6_K, 913 V7, V7_H, V7_J, V7_K, 914 V8, V8_H, V8_J, V8_K, 915 V9, V9_H, V9_J, V9_K, 916 V10, V10_H, V10_J, V10_K, 917 V11, V11_H, V11_J, V11_K, 918 V12, V12_H, V12_J, V12_K, 919 V13, V13_H, V13_J, V13_K, 920 V14, V14_H, V14_J, V14_K, 921 V15, V15_H, V15_J, V15_K, 922 V16, V16_H, V16_J, V16_K, 923 V17, V17_H, V17_J, V17_K, 924 V18, V18_H, V18_J, V18_K, 925 V19, V19_H, V19_J, V19_K, 926 V20, V20_H, V20_J, V20_K, 927 V21, V21_H, V21_J, V21_K, 928 V22, V22_H, V22_J, V22_K, 929 V23, V23_H, V23_J, V23_K, 930 V24, V24_H, V24_J, V24_K, 931 V25, V25_H, V25_J, V25_K, 932 V26, V26_H, V26_J, V26_K, 933 V27, V27_H, V27_J, V27_K, 934 V28, V28_H, V28_J, V28_K, 935 V29, V29_H, V29_J, V29_K, 936 V30, V30_H, V30_J, V30_K, 937 V31, V31_H, V31_J, V31_K 938 ); 939 940 // Class for 128 bit register v0 941 reg_class v0_reg( 942 V0, V0_H 943 ); 944 945 // Class for 128 bit register v1 946 reg_class v1_reg( 947 V1, V1_H 948 ); 949 950 // Class for 128 bit register v2 951 reg_class v2_reg( 952 V2, V2_H 953 ); 954 955 // Class for 128 bit register v3 956 reg_class v3_reg( 957 V3, V3_H 958 ); 959 960 // Singleton class for condition codes 961 reg_class int_flags(RFLAGS); 962 963 %} 964 965 //----------DEFINITION BLOCK--------------------------------------------------- 966 // Define name --> value mappings to inform the ADLC of an integer valued name 967 // Current support includes integer values in the range [0, 0x7FFFFFFF] 968 // Format: 969 // int_def <name> ( <int_value>, <expression>); 970 // Generated Code in ad_<arch>.hpp 971 // #define <name> (<expression>) 972 // // value == <int_value> 973 // Generated code in ad_<arch>.cpp adlc_verification() 974 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 975 // 976 977 // we follow the ppc-aix port in using a simple cost model which ranks 978 // register operations as cheap, memory ops as more expensive and 979 // branches as most expensive. the first two have a low as well as a 980 // normal cost. huge cost appears to be a way of saying don't do 981 // something 982 983 definitions %{ 984 // The default cost (of a register move instruction). 985 int_def INSN_COST ( 100, 100); 986 int_def BRANCH_COST ( 200, 2 * INSN_COST); 987 int_def CALL_COST ( 200, 2 * INSN_COST); 988 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 989 %} 990 991 992 //----------SOURCE BLOCK------------------------------------------------------- 993 // This is a block of C++ code which provides values, functions, and 994 // definitions necessary in the rest of the architecture description 995 996 source_hpp %{ 997 998 #include "asm/macroAssembler.hpp" 999 #include "gc/shared/cardTable.hpp" 1000 #include "gc/shared/cardTableBarrierSet.hpp" 1001 #include "gc/shared/collectedHeap.hpp" 1002 #include "opto/addnode.hpp" 1003 1004 class CallStubImpl { 1005 1006 //-------------------------------------------------------------- 1007 //---< Used for optimization in Compile::shorten_branches >--- 1008 //-------------------------------------------------------------- 1009 1010 public: 1011 // Size of call trampoline stub. 1012 static uint size_call_trampoline() { 1013 return 0; // no call trampolines on this platform 1014 } 1015 1016 // number of relocations needed by a call trampoline stub 1017 static uint reloc_call_trampoline() { 1018 return 0; // no call trampolines on this platform 1019 } 1020 }; 1021 1022 class HandlerImpl { 1023 1024 public: 1025 1026 static int emit_exception_handler(CodeBuffer &cbuf); 1027 static int emit_deopt_handler(CodeBuffer& cbuf); 1028 1029 static uint size_exception_handler() { 1030 return MacroAssembler::far_branch_size(); 1031 } 1032 1033 static uint size_deopt_handler() { 1034 // count one adr and one far branch instruction 1035 return 4 * NativeInstruction::instruction_size; 1036 } 1037 }; 1038 1039 bool is_CAS(int opcode); 1040 1041 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1042 1043 bool unnecessary_acquire(const Node *barrier); 1044 bool needs_acquiring_load(const Node *load); 1045 1046 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1047 1048 bool unnecessary_release(const Node *barrier); 1049 bool unnecessary_volatile(const Node *barrier); 1050 bool needs_releasing_store(const Node *store); 1051 1052 // predicate controlling translation of CompareAndSwapX 1053 bool needs_acquiring_load_exclusive(const Node *load); 1054 1055 // predicate controlling translation of StoreCM 1056 bool unnecessary_storestore(const Node *storecm); 1057 1058 // predicate controlling addressing modes 1059 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1060 %} 1061 1062 source %{ 1063 1064 // Optimizaton of volatile gets and puts 1065 // ------------------------------------- 1066 // 1067 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1068 // use to implement volatile reads and writes. For a volatile read 1069 // we simply need 1070 // 1071 // ldar<x> 1072 // 1073 // and for a volatile write we need 1074 // 1075 // stlr<x> 1076 // 1077 // Alternatively, we can implement them by pairing a normal 1078 // load/store with a memory barrier. For a volatile read we need 1079 // 1080 // ldr<x> 1081 // dmb ishld 1082 // 1083 // for a volatile write 1084 // 1085 // dmb ish 1086 // str<x> 1087 // dmb ish 1088 // 1089 // We can also use ldaxr and stlxr to implement compare and swap CAS 1090 // sequences. These are normally translated to an instruction 1091 // sequence like the following 1092 // 1093 // dmb ish 1094 // retry: 1095 // ldxr<x> rval raddr 1096 // cmp rval rold 1097 // b.ne done 1098 // stlxr<x> rval, rnew, rold 1099 // cbnz rval retry 1100 // done: 1101 // cset r0, eq 1102 // dmb ishld 1103 // 1104 // Note that the exclusive store is already using an stlxr 1105 // instruction. That is required to ensure visibility to other 1106 // threads of the exclusive write (assuming it succeeds) before that 1107 // of any subsequent writes. 1108 // 1109 // The following instruction sequence is an improvement on the above 1110 // 1111 // retry: 1112 // ldaxr<x> rval raddr 1113 // cmp rval rold 1114 // b.ne done 1115 // stlxr<x> rval, rnew, rold 1116 // cbnz rval retry 1117 // done: 1118 // cset r0, eq 1119 // 1120 // We don't need the leading dmb ish since the stlxr guarantees 1121 // visibility of prior writes in the case that the swap is 1122 // successful. Crucially we don't have to worry about the case where 1123 // the swap is not successful since no valid program should be 1124 // relying on visibility of prior changes by the attempting thread 1125 // in the case where the CAS fails. 1126 // 1127 // Similarly, we don't need the trailing dmb ishld if we substitute 1128 // an ldaxr instruction since that will provide all the guarantees we 1129 // require regarding observation of changes made by other threads 1130 // before any change to the CAS address observed by the load. 1131 // 1132 // In order to generate the desired instruction sequence we need to 1133 // be able to identify specific 'signature' ideal graph node 1134 // sequences which i) occur as a translation of a volatile reads or 1135 // writes or CAS operations and ii) do not occur through any other 1136 // translation or graph transformation. We can then provide 1137 // alternative aldc matching rules which translate these node 1138 // sequences to the desired machine code sequences. Selection of the 1139 // alternative rules can be implemented by predicates which identify 1140 // the relevant node sequences. 1141 // 1142 // The ideal graph generator translates a volatile read to the node 1143 // sequence 1144 // 1145 // LoadX[mo_acquire] 1146 // MemBarAcquire 1147 // 1148 // As a special case when using the compressed oops optimization we 1149 // may also see this variant 1150 // 1151 // LoadN[mo_acquire] 1152 // DecodeN 1153 // MemBarAcquire 1154 // 1155 // A volatile write is translated to the node sequence 1156 // 1157 // MemBarRelease 1158 // StoreX[mo_release] {CardMark}-optional 1159 // MemBarVolatile 1160 // 1161 // n.b. the above node patterns are generated with a strict 1162 // 'signature' configuration of input and output dependencies (see 1163 // the predicates below for exact details). The card mark may be as 1164 // simple as a few extra nodes or, in a few GC configurations, may 1165 // include more complex control flow between the leading and 1166 // trailing memory barriers. However, whatever the card mark 1167 // configuration these signatures are unique to translated volatile 1168 // reads/stores -- they will not appear as a result of any other 1169 // bytecode translation or inlining nor as a consequence of 1170 // optimizing transforms. 1171 // 1172 // We also want to catch inlined unsafe volatile gets and puts and 1173 // be able to implement them using either ldar<x>/stlr<x> or some 1174 // combination of ldr<x>/stlr<x> and dmb instructions. 1175 // 1176 // Inlined unsafe volatiles puts manifest as a minor variant of the 1177 // normal volatile put node sequence containing an extra cpuorder 1178 // membar 1179 // 1180 // MemBarRelease 1181 // MemBarCPUOrder 1182 // StoreX[mo_release] {CardMark}-optional 1183 // MemBarCPUOrder 1184 // MemBarVolatile 1185 // 1186 // n.b. as an aside, a cpuorder membar is not itself subject to 1187 // matching and translation by adlc rules. However, the rule 1188 // predicates need to detect its presence in order to correctly 1189 // select the desired adlc rules. 1190 // 1191 // Inlined unsafe volatile gets manifest as a slightly different 1192 // node sequence to a normal volatile get because of the 1193 // introduction of some CPUOrder memory barriers to bracket the 1194 // Load. However, but the same basic skeleton of a LoadX feeding a 1195 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1196 // present 1197 // 1198 // MemBarCPUOrder 1199 // || \\ 1200 // MemBarCPUOrder LoadX[mo_acquire] 1201 // || | 1202 // || {DecodeN} optional 1203 // || / 1204 // MemBarAcquire 1205 // 1206 // In this case the acquire membar does not directly depend on the 1207 // load. However, we can be sure that the load is generated from an 1208 // inlined unsafe volatile get if we see it dependent on this unique 1209 // sequence of membar nodes. Similarly, given an acquire membar we 1210 // can know that it was added because of an inlined unsafe volatile 1211 // get if it is fed and feeds a cpuorder membar and if its feed 1212 // membar also feeds an acquiring load. 1213 // 1214 // Finally an inlined (Unsafe) CAS operation is translated to the 1215 // following ideal graph 1216 // 1217 // MemBarRelease 1218 // MemBarCPUOrder 1219 // CompareAndSwapX {CardMark}-optional 1220 // MemBarCPUOrder 1221 // MemBarAcquire 1222 // 1223 // So, where we can identify these volatile read and write 1224 // signatures we can choose to plant either of the above two code 1225 // sequences. For a volatile read we can simply plant a normal 1226 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1227 // also choose to inhibit translation of the MemBarAcquire and 1228 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1229 // 1230 // When we recognise a volatile store signature we can choose to 1231 // plant at a dmb ish as a translation for the MemBarRelease, a 1232 // normal str<x> and then a dmb ish for the MemBarVolatile. 1233 // Alternatively, we can inhibit translation of the MemBarRelease 1234 // and MemBarVolatile and instead plant a simple stlr<x> 1235 // instruction. 1236 // 1237 // when we recognise a CAS signature we can choose to plant a dmb 1238 // ish as a translation for the MemBarRelease, the conventional 1239 // macro-instruction sequence for the CompareAndSwap node (which 1240 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1241 // Alternatively, we can elide generation of the dmb instructions 1242 // and plant the alternative CompareAndSwap macro-instruction 1243 // sequence (which uses ldaxr<x>). 1244 // 1245 // Of course, the above only applies when we see these signature 1246 // configurations. We still want to plant dmb instructions in any 1247 // other cases where we may see a MemBarAcquire, MemBarRelease or 1248 // MemBarVolatile. For example, at the end of a constructor which 1249 // writes final/volatile fields we will see a MemBarRelease 1250 // instruction and this needs a 'dmb ish' lest we risk the 1251 // constructed object being visible without making the 1252 // final/volatile field writes visible. 1253 // 1254 // n.b. the translation rules below which rely on detection of the 1255 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1256 // If we see anything other than the signature configurations we 1257 // always just translate the loads and stores to ldr<x> and str<x> 1258 // and translate acquire, release and volatile membars to the 1259 // relevant dmb instructions. 1260 // 1261 1262 // is_CAS(int opcode) 1263 // 1264 // return true if opcode is one of the possible CompareAndSwapX 1265 // values otherwise false. 1266 1267 bool is_CAS(int opcode) 1268 { 1269 switch(opcode) { 1270 // We handle these 1271 case Op_CompareAndSwapI: 1272 case Op_CompareAndSwapL: 1273 case Op_CompareAndSwapP: 1274 case Op_CompareAndSwapN: 1275 // case Op_CompareAndSwapB: 1276 // case Op_CompareAndSwapS: 1277 return true; 1278 // These are TBD 1279 case Op_WeakCompareAndSwapB: 1280 case Op_WeakCompareAndSwapS: 1281 case Op_WeakCompareAndSwapI: 1282 case Op_WeakCompareAndSwapL: 1283 case Op_WeakCompareAndSwapP: 1284 case Op_WeakCompareAndSwapN: 1285 case Op_CompareAndExchangeB: 1286 case Op_CompareAndExchangeS: 1287 case Op_CompareAndExchangeI: 1288 case Op_CompareAndExchangeL: 1289 case Op_CompareAndExchangeP: 1290 case Op_CompareAndExchangeN: 1291 return false; 1292 default: 1293 return false; 1294 } 1295 } 1296 1297 // helper to determine the maximum number of Phi nodes we may need to 1298 // traverse when searching from a card mark membar for the merge mem 1299 // feeding a trailing membar or vice versa 1300 1301 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1302 1303 bool unnecessary_acquire(const Node *barrier) 1304 { 1305 assert(barrier->is_MemBar(), "expecting a membar"); 1306 1307 if (UseBarriersForVolatile) { 1308 // we need to plant a dmb 1309 return false; 1310 } 1311 1312 MemBarNode* mb = barrier->as_MemBar(); 1313 1314 if (mb->trailing_load()) { 1315 return true; 1316 } 1317 1318 if (mb->trailing_load_store()) { 1319 Node* load_store = mb->in(MemBarNode::Precedent); 1320 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1321 return is_CAS(load_store->Opcode()); 1322 } 1323 1324 return false; 1325 } 1326 1327 bool needs_acquiring_load(const Node *n) 1328 { 1329 assert(n->is_Load(), "expecting a load"); 1330 if (UseBarriersForVolatile) { 1331 // we use a normal load and a dmb 1332 return false; 1333 } 1334 1335 LoadNode *ld = n->as_Load(); 1336 1337 return ld->is_acquire(); 1338 } 1339 1340 bool unnecessary_release(const Node *n) 1341 { 1342 assert((n->is_MemBar() && 1343 n->Opcode() == Op_MemBarRelease), 1344 "expecting a release membar"); 1345 1346 if (UseBarriersForVolatile) { 1347 // we need to plant a dmb 1348 return false; 1349 } 1350 1351 MemBarNode *barrier = n->as_MemBar(); 1352 if (!barrier->leading()) { 1353 return false; 1354 } else { 1355 Node* trailing = barrier->trailing_membar(); 1356 MemBarNode* trailing_mb = trailing->as_MemBar(); 1357 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1358 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1359 1360 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1361 if (mem->is_Store()) { 1362 assert(mem->as_Store()->is_release(), ""); 1363 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1364 return true; 1365 } else { 1366 assert(mem->is_LoadStore(), ""); 1367 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1368 return is_CAS(mem->Opcode()); 1369 } 1370 } 1371 return false; 1372 } 1373 1374 bool unnecessary_volatile(const Node *n) 1375 { 1376 // assert n->is_MemBar(); 1377 if (UseBarriersForVolatile) { 1378 // we need to plant a dmb 1379 return false; 1380 } 1381 1382 MemBarNode *mbvol = n->as_MemBar(); 1383 1384 bool release = mbvol->trailing_store(); 1385 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1386 #ifdef ASSERT 1387 if (release) { 1388 Node* leading = mbvol->leading_membar(); 1389 assert(leading->Opcode() == Op_MemBarRelease, ""); 1390 assert(leading->as_MemBar()->leading_store(), ""); 1391 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1392 } 1393 #endif 1394 1395 return release; 1396 } 1397 1398 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1399 1400 bool needs_releasing_store(const Node *n) 1401 { 1402 // assert n->is_Store(); 1403 if (UseBarriersForVolatile) { 1404 // we use a normal store and dmb combination 1405 return false; 1406 } 1407 1408 StoreNode *st = n->as_Store(); 1409 1410 return st->trailing_membar() != NULL; 1411 } 1412 1413 // predicate controlling translation of CAS 1414 // 1415 // returns true if CAS needs to use an acquiring load otherwise false 1416 1417 bool needs_acquiring_load_exclusive(const Node *n) 1418 { 1419 assert(is_CAS(n->Opcode()), "expecting a compare and swap"); 1420 if (UseBarriersForVolatile) { 1421 return false; 1422 } 1423 1424 LoadStoreNode* ldst = n->as_LoadStore(); 1425 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1426 1427 // so we can just return true here 1428 return true; 1429 } 1430 1431 // predicate controlling translation of StoreCM 1432 // 1433 // returns true if a StoreStore must precede the card write otherwise 1434 // false 1435 1436 bool unnecessary_storestore(const Node *storecm) 1437 { 1438 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1439 1440 // we need to generate a dmb ishst between an object put and the 1441 // associated card mark when we are using CMS without conditional 1442 // card marking 1443 1444 if (UseConcMarkSweepGC && !UseCondCardMark) { 1445 return false; 1446 } 1447 1448 // a storestore is unnecesary in all other cases 1449 1450 return true; 1451 } 1452 1453 1454 #define __ _masm. 1455 1456 // advance declarations for helper functions to convert register 1457 // indices to register objects 1458 1459 // the ad file has to provide implementations of certain methods 1460 // expected by the generic code 1461 // 1462 // REQUIRED FUNCTIONALITY 1463 1464 //============================================================================= 1465 1466 // !!!!! Special hack to get all types of calls to specify the byte offset 1467 // from the start of the call to the point where the return address 1468 // will point. 1469 1470 int MachCallStaticJavaNode::ret_addr_offset() 1471 { 1472 // call should be a simple bl 1473 int off = 4; 1474 return off; 1475 } 1476 1477 int MachCallDynamicJavaNode::ret_addr_offset() 1478 { 1479 return 16; // movz, movk, movk, bl 1480 } 1481 1482 int MachCallRuntimeNode::ret_addr_offset() { 1483 // for generated stubs the call will be 1484 // far_call(addr) 1485 // for real runtime callouts it will be six instructions 1486 // see aarch64_enc_java_to_runtime 1487 // adr(rscratch2, retaddr) 1488 // lea(rscratch1, RuntimeAddress(addr) 1489 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1490 // blrt rscratch1 1491 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1492 if (cb) { 1493 return MacroAssembler::far_branch_size(); 1494 } else { 1495 return 6 * NativeInstruction::instruction_size; 1496 } 1497 } 1498 1499 // Indicate if the safepoint node needs the polling page as an input 1500 1501 // the shared code plants the oop data at the start of the generated 1502 // code for the safepoint node and that needs ot be at the load 1503 // instruction itself. so we cannot plant a mov of the safepoint poll 1504 // address followed by a load. setting this to true means the mov is 1505 // scheduled as a prior instruction. that's better for scheduling 1506 // anyway. 1507 1508 bool SafePointNode::needs_polling_address_input() 1509 { 1510 return true; 1511 } 1512 1513 //============================================================================= 1514 1515 #ifndef PRODUCT 1516 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1517 st->print("BREAKPOINT"); 1518 } 1519 #endif 1520 1521 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1522 MacroAssembler _masm(&cbuf); 1523 __ brk(0); 1524 } 1525 1526 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1527 return MachNode::size(ra_); 1528 } 1529 1530 //============================================================================= 1531 1532 #ifndef PRODUCT 1533 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1534 st->print("nop \t# %d bytes pad for loops and calls", _count); 1535 } 1536 #endif 1537 1538 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1539 MacroAssembler _masm(&cbuf); 1540 for (int i = 0; i < _count; i++) { 1541 __ nop(); 1542 } 1543 } 1544 1545 uint MachNopNode::size(PhaseRegAlloc*) const { 1546 return _count * NativeInstruction::instruction_size; 1547 } 1548 1549 //============================================================================= 1550 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1551 1552 int Compile::ConstantTable::calculate_table_base_offset() const { 1553 return 0; // absolute addressing, no offset 1554 } 1555 1556 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1557 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1558 ShouldNotReachHere(); 1559 } 1560 1561 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1562 // Empty encoding 1563 } 1564 1565 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1566 return 0; 1567 } 1568 1569 #ifndef PRODUCT 1570 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1571 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1572 } 1573 #endif 1574 1575 #ifndef PRODUCT 1576 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1577 Compile* C = ra_->C; 1578 1579 int framesize = C->frame_slots() << LogBytesPerInt; 1580 1581 if (C->need_stack_bang(framesize)) 1582 st->print("# stack bang size=%d\n\t", framesize); 1583 1584 if (framesize < ((1 << 9) + 2 * wordSize)) { 1585 st->print("sub sp, sp, #%d\n\t", framesize); 1586 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1587 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1588 } else { 1589 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1590 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1591 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1592 st->print("sub sp, sp, rscratch1"); 1593 } 1594 } 1595 #endif 1596 1597 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1598 Compile* C = ra_->C; 1599 MacroAssembler _masm(&cbuf); 1600 1601 // n.b. frame size includes space for return pc and rfp 1602 const long framesize = C->frame_size_in_bytes(); 1603 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1604 1605 // insert a nop at the start of the prolog so we can patch in a 1606 // branch if we need to invalidate the method later 1607 __ nop(); 1608 1609 int bangsize = C->bang_size_in_bytes(); 1610 if (C->need_stack_bang(bangsize) && UseStackBanging) 1611 __ generate_stack_overflow_check(bangsize); 1612 1613 __ build_frame(framesize); 1614 1615 if (NotifySimulator) { 1616 __ notify(Assembler::method_entry); 1617 } 1618 1619 if (VerifyStackAtCalls) { 1620 Unimplemented(); 1621 } 1622 1623 C->set_frame_complete(cbuf.insts_size()); 1624 1625 if (C->has_mach_constant_base_node()) { 1626 // NOTE: We set the table base offset here because users might be 1627 // emitted before MachConstantBaseNode. 1628 Compile::ConstantTable& constant_table = C->constant_table(); 1629 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1630 } 1631 } 1632 1633 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1634 { 1635 return MachNode::size(ra_); // too many variables; just compute it 1636 // the hard way 1637 } 1638 1639 int MachPrologNode::reloc() const 1640 { 1641 return 0; 1642 } 1643 1644 //============================================================================= 1645 1646 #ifndef PRODUCT 1647 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1648 Compile* C = ra_->C; 1649 int framesize = C->frame_slots() << LogBytesPerInt; 1650 1651 st->print("# pop frame %d\n\t",framesize); 1652 1653 if (framesize == 0) { 1654 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1655 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1656 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1657 st->print("add sp, sp, #%d\n\t", framesize); 1658 } else { 1659 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1660 st->print("add sp, sp, rscratch1\n\t"); 1661 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1662 } 1663 1664 if (do_polling() && C->is_method_compilation()) { 1665 st->print("# touch polling page\n\t"); 1666 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1667 st->print("ldr zr, [rscratch1]"); 1668 } 1669 } 1670 #endif 1671 1672 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1673 Compile* C = ra_->C; 1674 MacroAssembler _masm(&cbuf); 1675 int framesize = C->frame_slots() << LogBytesPerInt; 1676 1677 __ remove_frame(framesize); 1678 1679 if (NotifySimulator) { 1680 __ notify(Assembler::method_reentry); 1681 } 1682 1683 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1684 __ reserved_stack_check(); 1685 } 1686 1687 if (do_polling() && C->is_method_compilation()) { 1688 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1689 } 1690 } 1691 1692 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1693 // Variable size. Determine dynamically. 1694 return MachNode::size(ra_); 1695 } 1696 1697 int MachEpilogNode::reloc() const { 1698 // Return number of relocatable values contained in this instruction. 1699 return 1; // 1 for polling page. 1700 } 1701 1702 const Pipeline * MachEpilogNode::pipeline() const { 1703 return MachNode::pipeline_class(); 1704 } 1705 1706 // This method seems to be obsolete. It is declared in machnode.hpp 1707 // and defined in all *.ad files, but it is never called. Should we 1708 // get rid of it? 1709 int MachEpilogNode::safepoint_offset() const { 1710 assert(do_polling(), "no return for this epilog node"); 1711 return 4; 1712 } 1713 1714 //============================================================================= 1715 1716 // Figure out which register class each belongs in: rc_int, rc_float or 1717 // rc_stack. 1718 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1719 1720 static enum RC rc_class(OptoReg::Name reg) { 1721 1722 if (reg == OptoReg::Bad) { 1723 return rc_bad; 1724 } 1725 1726 // we have 30 int registers * 2 halves 1727 // (rscratch1 and rscratch2 are omitted) 1728 1729 if (reg < 60) { 1730 return rc_int; 1731 } 1732 1733 // we have 32 float register * 2 halves 1734 if (reg < 60 + 128) { 1735 return rc_float; 1736 } 1737 1738 // Between float regs & stack is the flags regs. 1739 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1740 1741 return rc_stack; 1742 } 1743 1744 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1745 Compile* C = ra_->C; 1746 1747 // Get registers to move. 1748 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1749 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1750 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1751 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1752 1753 enum RC src_hi_rc = rc_class(src_hi); 1754 enum RC src_lo_rc = rc_class(src_lo); 1755 enum RC dst_hi_rc = rc_class(dst_hi); 1756 enum RC dst_lo_rc = rc_class(dst_lo); 1757 1758 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1759 1760 if (src_hi != OptoReg::Bad) { 1761 assert((src_lo&1)==0 && src_lo+1==src_hi && 1762 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1763 "expected aligned-adjacent pairs"); 1764 } 1765 1766 if (src_lo == dst_lo && src_hi == dst_hi) { 1767 return 0; // Self copy, no move. 1768 } 1769 1770 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1771 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1772 int src_offset = ra_->reg2offset(src_lo); 1773 int dst_offset = ra_->reg2offset(dst_lo); 1774 1775 if (bottom_type()->isa_vect() != NULL) { 1776 uint ireg = ideal_reg(); 1777 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1778 if (cbuf) { 1779 MacroAssembler _masm(cbuf); 1780 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1781 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1782 // stack->stack 1783 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1784 if (ireg == Op_VecD) { 1785 __ unspill(rscratch1, true, src_offset); 1786 __ spill(rscratch1, true, dst_offset); 1787 } else { 1788 __ spill_copy128(src_offset, dst_offset); 1789 } 1790 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1791 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1792 ireg == Op_VecD ? __ T8B : __ T16B, 1793 as_FloatRegister(Matcher::_regEncode[src_lo])); 1794 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1795 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1796 ireg == Op_VecD ? __ D : __ Q, 1797 ra_->reg2offset(dst_lo)); 1798 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1799 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1800 ireg == Op_VecD ? __ D : __ Q, 1801 ra_->reg2offset(src_lo)); 1802 } else { 1803 ShouldNotReachHere(); 1804 } 1805 } 1806 } else if (cbuf) { 1807 MacroAssembler _masm(cbuf); 1808 switch (src_lo_rc) { 1809 case rc_int: 1810 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1811 if (is64) { 1812 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1813 as_Register(Matcher::_regEncode[src_lo])); 1814 } else { 1815 MacroAssembler _masm(cbuf); 1816 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1817 as_Register(Matcher::_regEncode[src_lo])); 1818 } 1819 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1820 if (is64) { 1821 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1822 as_Register(Matcher::_regEncode[src_lo])); 1823 } else { 1824 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1825 as_Register(Matcher::_regEncode[src_lo])); 1826 } 1827 } else { // gpr --> stack spill 1828 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1829 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1830 } 1831 break; 1832 case rc_float: 1833 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1834 if (is64) { 1835 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1836 as_FloatRegister(Matcher::_regEncode[src_lo])); 1837 } else { 1838 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1839 as_FloatRegister(Matcher::_regEncode[src_lo])); 1840 } 1841 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1842 if (cbuf) { 1843 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1844 as_FloatRegister(Matcher::_regEncode[src_lo])); 1845 } else { 1846 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1847 as_FloatRegister(Matcher::_regEncode[src_lo])); 1848 } 1849 } else { // fpr --> stack spill 1850 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1851 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1852 is64 ? __ D : __ S, dst_offset); 1853 } 1854 break; 1855 case rc_stack: 1856 if (dst_lo_rc == rc_int) { // stack --> gpr load 1857 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1858 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1859 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1860 is64 ? __ D : __ S, src_offset); 1861 } else { // stack --> stack copy 1862 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1863 __ unspill(rscratch1, is64, src_offset); 1864 __ spill(rscratch1, is64, dst_offset); 1865 } 1866 break; 1867 default: 1868 assert(false, "bad rc_class for spill"); 1869 ShouldNotReachHere(); 1870 } 1871 } 1872 1873 if (st) { 1874 st->print("spill "); 1875 if (src_lo_rc == rc_stack) { 1876 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1877 } else { 1878 st->print("%s -> ", Matcher::regName[src_lo]); 1879 } 1880 if (dst_lo_rc == rc_stack) { 1881 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1882 } else { 1883 st->print("%s", Matcher::regName[dst_lo]); 1884 } 1885 if (bottom_type()->isa_vect() != NULL) { 1886 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1887 } else { 1888 st->print("\t# spill size = %d", is64 ? 64:32); 1889 } 1890 } 1891 1892 return 0; 1893 1894 } 1895 1896 #ifndef PRODUCT 1897 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1898 if (!ra_) 1899 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1900 else 1901 implementation(NULL, ra_, false, st); 1902 } 1903 #endif 1904 1905 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1906 implementation(&cbuf, ra_, false, NULL); 1907 } 1908 1909 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1910 return MachNode::size(ra_); 1911 } 1912 1913 //============================================================================= 1914 1915 #ifndef PRODUCT 1916 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1917 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1918 int reg = ra_->get_reg_first(this); 1919 st->print("add %s, rsp, #%d]\t# box lock", 1920 Matcher::regName[reg], offset); 1921 } 1922 #endif 1923 1924 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1925 MacroAssembler _masm(&cbuf); 1926 1927 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1928 int reg = ra_->get_encode(this); 1929 1930 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1931 __ add(as_Register(reg), sp, offset); 1932 } else { 1933 ShouldNotReachHere(); 1934 } 1935 } 1936 1937 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1938 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1939 return 4; 1940 } 1941 1942 //============================================================================= 1943 1944 #ifndef PRODUCT 1945 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1946 { 1947 st->print_cr("# MachUEPNode"); 1948 if (UseCompressedClassPointers) { 1949 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1950 if (Universe::narrow_klass_shift() != 0) { 1951 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1952 } 1953 } else { 1954 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1955 } 1956 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1957 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1958 } 1959 #endif 1960 1961 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1962 { 1963 // This is the unverified entry point. 1964 MacroAssembler _masm(&cbuf); 1965 1966 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1967 Label skip; 1968 // TODO 1969 // can we avoid this skip and still use a reloc? 1970 __ br(Assembler::EQ, skip); 1971 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1972 __ bind(skip); 1973 } 1974 1975 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1976 { 1977 return MachNode::size(ra_); 1978 } 1979 1980 // REQUIRED EMIT CODE 1981 1982 //============================================================================= 1983 1984 // Emit exception handler code. 1985 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1986 { 1987 // mov rscratch1 #exception_blob_entry_point 1988 // br rscratch1 1989 // Note that the code buffer's insts_mark is always relative to insts. 1990 // That's why we must use the macroassembler to generate a handler. 1991 MacroAssembler _masm(&cbuf); 1992 address base = __ start_a_stub(size_exception_handler()); 1993 if (base == NULL) { 1994 ciEnv::current()->record_failure("CodeCache is full"); 1995 return 0; // CodeBuffer::expand failed 1996 } 1997 int offset = __ offset(); 1998 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1999 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2000 __ end_a_stub(); 2001 return offset; 2002 } 2003 2004 // Emit deopt handler code. 2005 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2006 { 2007 // Note that the code buffer's insts_mark is always relative to insts. 2008 // That's why we must use the macroassembler to generate a handler. 2009 MacroAssembler _masm(&cbuf); 2010 address base = __ start_a_stub(size_deopt_handler()); 2011 if (base == NULL) { 2012 ciEnv::current()->record_failure("CodeCache is full"); 2013 return 0; // CodeBuffer::expand failed 2014 } 2015 int offset = __ offset(); 2016 2017 __ adr(lr, __ pc()); 2018 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2019 2020 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2021 __ end_a_stub(); 2022 return offset; 2023 } 2024 2025 // REQUIRED MATCHER CODE 2026 2027 //============================================================================= 2028 2029 const bool Matcher::match_rule_supported(int opcode) { 2030 2031 switch (opcode) { 2032 default: 2033 break; 2034 } 2035 2036 if (!has_match_rule(opcode)) { 2037 return false; 2038 } 2039 2040 return true; // Per default match rules are supported. 2041 } 2042 2043 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt, int op_arity) { 2044 int bit_size = vlen * type2aelembytes(bt) * 8; 2045 if (bit_size > 128) { 2046 return false; 2047 } 2048 // identify extra cases that we might want to provide match rules for 2049 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2050 bool ret_value = match_rule_supported(opcode); 2051 // Add rules here. 2052 2053 return ret_value; // Per default match rules are supported. 2054 } 2055 2056 const bool Matcher::has_predicated_vectors(void) { 2057 return false; 2058 } 2059 2060 // Vector calling convention not yet implemented. 2061 const bool Matcher::supports_vector_calling_convention() { 2062 return false; 2063 } 2064 2065 void Matcher::vector_calling_convention(VMRegPair *regs, uint num_bits, uint total_args_passed) { 2066 (void) SharedRuntime::vector_calling_convention(regs, num_bits, total_args_passed); 2067 } 2068 2069 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2070 Unimplemented(); 2071 return OptoRegPair(0, 0); 2072 } 2073 2074 const int Matcher::float_pressure(int default_pressure_threshold) { 2075 return default_pressure_threshold; 2076 } 2077 2078 int Matcher::regnum_to_fpu_offset(int regnum) 2079 { 2080 Unimplemented(); 2081 return 0; 2082 } 2083 2084 // Is this branch offset short enough that a short branch can be used? 2085 // 2086 // NOTE: If the platform does not provide any short branch variants, then 2087 // this method should return false for offset 0. 2088 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2089 // The passed offset is relative to address of the branch. 2090 2091 return (-32768 <= offset && offset < 32768); 2092 } 2093 2094 const bool Matcher::isSimpleConstant64(jlong value) { 2095 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2096 // Probably always true, even if a temp register is required. 2097 return true; 2098 } 2099 2100 // true just means we have fast l2f conversion 2101 const bool Matcher::convL2FSupported(void) { 2102 return true; 2103 } 2104 2105 // Vector width in bytes. 2106 const int Matcher::vector_width_in_bytes(BasicType bt) { 2107 int size = MIN2(UseSVE ? 256: 16, (int)MaxVectorSize); 2108 // Minimum 2 values in vector 2109 if (size < 2*type2aelembytes(bt)) size = 0; 2110 // But never < 4 2111 if (size < 4) size = 0; 2112 return size; 2113 } 2114 2115 // Limits on vector size (number of elements) loaded into vector. 2116 const int Matcher::max_vector_size(const BasicType bt) { 2117 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2118 } 2119 const int Matcher::min_vector_size(const BasicType bt) { 2120 // For the moment limit the vector size to 8 bytes 2121 int size = 8 / type2aelembytes(bt); 2122 if (size < 2) size = 2; 2123 return size; 2124 } 2125 2126 // Vector ideal reg. 2127 const uint Matcher::vector_ideal_reg(int len) { 2128 switch(len) { 2129 case 8: return Op_VecD; 2130 case 16: return Op_VecX; 2131 } 2132 ShouldNotReachHere(); 2133 return 0; 2134 } 2135 2136 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2137 return Op_VecX; 2138 } 2139 2140 // AES support not yet implemented 2141 const bool Matcher::pass_original_key_for_aes() { 2142 return false; 2143 } 2144 2145 // x86 supports misaligned vectors store/load. 2146 const bool Matcher::misaligned_vectors_ok() { 2147 return !AlignVector; // can be changed by flag 2148 } 2149 2150 // false => size gets scaled to BytesPerLong, ok. 2151 const bool Matcher::init_array_count_is_in_bytes = false; 2152 2153 // Use conditional move (CMOVL) 2154 const int Matcher::long_cmove_cost() { 2155 // long cmoves are no more expensive than int cmoves 2156 return 0; 2157 } 2158 2159 const int Matcher::float_cmove_cost() { 2160 // float cmoves are no more expensive than int cmoves 2161 return 0; 2162 } 2163 2164 // Does the CPU require late expand (see block.cpp for description of late expand)? 2165 const bool Matcher::require_postalloc_expand = false; 2166 2167 // Do we need to mask the count passed to shift instructions or does 2168 // the cpu only look at the lower 5/6 bits anyway? 2169 const bool Matcher::need_masked_shift_count = false; 2170 2171 // This affects two different things: 2172 // - how Decode nodes are matched 2173 // - how ImplicitNullCheck opportunities are recognized 2174 // If true, the matcher will try to remove all Decodes and match them 2175 // (as operands) into nodes. NullChecks are not prepared to deal with 2176 // Decodes by final_graph_reshaping(). 2177 // If false, final_graph_reshaping() forces the decode behind the Cmp 2178 // for a NullCheck. The matcher matches the Decode node into a register. 2179 // Implicit_null_check optimization moves the Decode along with the 2180 // memory operation back up before the NullCheck. 2181 bool Matcher::narrow_oop_use_complex_address() { 2182 return Universe::narrow_oop_shift() == 0; 2183 } 2184 2185 bool Matcher::narrow_klass_use_complex_address() { 2186 // TODO 2187 // decide whether we need to set this to true 2188 return false; 2189 } 2190 2191 bool Matcher::const_oop_prefer_decode() { 2192 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2193 return Universe::narrow_oop_base() == NULL; 2194 } 2195 2196 bool Matcher::const_klass_prefer_decode() { 2197 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2198 return Universe::narrow_klass_base() == NULL; 2199 } 2200 2201 // Is it better to copy float constants, or load them directly from 2202 // memory? Intel can load a float constant from a direct address, 2203 // requiring no extra registers. Most RISCs will have to materialize 2204 // an address into a register first, so they would do better to copy 2205 // the constant from stack. 2206 const bool Matcher::rematerialize_float_constants = false; 2207 2208 // If CPU can load and store mis-aligned doubles directly then no 2209 // fixup is needed. Else we split the double into 2 integer pieces 2210 // and move it piece-by-piece. Only happens when passing doubles into 2211 // C code as the Java calling convention forces doubles to be aligned. 2212 const bool Matcher::misaligned_doubles_ok = true; 2213 2214 // No-op on amd64 2215 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2216 Unimplemented(); 2217 } 2218 2219 // Advertise here if the CPU requires explicit rounding operations to 2220 // implement the UseStrictFP mode. 2221 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2222 2223 // Are floats converted to double when stored to stack during 2224 // deoptimization? 2225 bool Matcher::float_in_double() { return false; } 2226 2227 // Do ints take an entire long register or just half? 2228 // The relevant question is how the int is callee-saved: 2229 // the whole long is written but de-opt'ing will have to extract 2230 // the relevant 32 bits. 2231 const bool Matcher::int_in_long = true; 2232 2233 // Return whether or not this register is ever used as an argument. 2234 // This function is used on startup to build the trampoline stubs in 2235 // generateOptoStub. Registers not mentioned will be killed by the VM 2236 // call in the trampoline, and arguments in those registers not be 2237 // available to the callee. 2238 bool Matcher::can_be_java_arg(int reg) 2239 { 2240 return 2241 reg == R0_num || reg == R0_H_num || 2242 reg == R1_num || reg == R1_H_num || 2243 reg == R2_num || reg == R2_H_num || 2244 reg == R3_num || reg == R3_H_num || 2245 reg == R4_num || reg == R4_H_num || 2246 reg == R5_num || reg == R5_H_num || 2247 reg == R6_num || reg == R6_H_num || 2248 reg == R7_num || reg == R7_H_num || 2249 reg == V0_num || reg == V0_H_num || 2250 reg == V1_num || reg == V1_H_num || 2251 reg == V2_num || reg == V2_H_num || 2252 reg == V3_num || reg == V3_H_num || 2253 reg == V4_num || reg == V4_H_num || 2254 reg == V5_num || reg == V5_H_num || 2255 reg == V6_num || reg == V6_H_num || 2256 reg == V7_num || reg == V7_H_num; 2257 } 2258 2259 bool Matcher::is_spillable_arg(int reg) 2260 { 2261 return can_be_java_arg(reg); 2262 } 2263 2264 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2265 return false; 2266 } 2267 2268 RegMask Matcher::divI_proj_mask() { 2269 ShouldNotReachHere(); 2270 return RegMask(); 2271 } 2272 2273 // Register for MODI projection of divmodI. 2274 RegMask Matcher::modI_proj_mask() { 2275 ShouldNotReachHere(); 2276 return RegMask(); 2277 } 2278 2279 // Register for DIVL projection of divmodL. 2280 RegMask Matcher::divL_proj_mask() { 2281 ShouldNotReachHere(); 2282 return RegMask(); 2283 } 2284 2285 // Register for MODL projection of divmodL. 2286 RegMask Matcher::modL_proj_mask() { 2287 ShouldNotReachHere(); 2288 return RegMask(); 2289 } 2290 2291 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2292 return FP_REG_mask(); 2293 } 2294 2295 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2296 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2297 Node* u = addp->fast_out(i); 2298 if (u->is_Mem()) { 2299 int opsize = u->as_Mem()->memory_size(); 2300 assert(opsize > 0, "unexpected memory operand size"); 2301 if (u->as_Mem()->memory_size() != (1<<shift)) { 2302 return false; 2303 } 2304 } 2305 } 2306 return true; 2307 } 2308 2309 const bool Matcher::convi2l_type_required = false; 2310 2311 // Should the Matcher clone shifts on addressing modes, expecting them 2312 // to be subsumed into complex addressing expressions or compute them 2313 // into registers? 2314 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2315 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2316 return true; 2317 } 2318 2319 Node *off = m->in(AddPNode::Offset); 2320 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2321 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2322 // Are there other uses besides address expressions? 2323 !is_visited(off)) { 2324 address_visited.set(off->_idx); // Flag as address_visited 2325 mstack.push(off->in(2), Visit); 2326 Node *conv = off->in(1); 2327 if (conv->Opcode() == Op_ConvI2L && 2328 // Are there other uses besides address expressions? 2329 !is_visited(conv)) { 2330 address_visited.set(conv->_idx); // Flag as address_visited 2331 mstack.push(conv->in(1), Pre_Visit); 2332 } else { 2333 mstack.push(conv, Pre_Visit); 2334 } 2335 address_visited.test_set(m->_idx); // Flag as address_visited 2336 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2337 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2338 return true; 2339 } else if (off->Opcode() == Op_ConvI2L && 2340 // Are there other uses besides address expressions? 2341 !is_visited(off)) { 2342 address_visited.test_set(m->_idx); // Flag as address_visited 2343 address_visited.set(off->_idx); // Flag as address_visited 2344 mstack.push(off->in(1), Pre_Visit); 2345 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2346 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2347 return true; 2348 } 2349 return false; 2350 } 2351 2352 void Compile::reshape_address(AddPNode* addp) { 2353 } 2354 2355 // helper for encoding java_to_runtime calls on sim 2356 // 2357 // this is needed to compute the extra arguments required when 2358 // planting a call to the simulator blrt instruction. the TypeFunc 2359 // can be queried to identify the counts for integral, and floating 2360 // arguments and the return type 2361 2362 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2363 { 2364 int gps = 0; 2365 int fps = 0; 2366 const TypeTuple *domain = tf->domain(); 2367 int max = domain->cnt(); 2368 for (int i = TypeFunc::Parms; i < max; i++) { 2369 const Type *t = domain->field_at(i); 2370 switch(t->basic_type()) { 2371 case T_FLOAT: 2372 case T_DOUBLE: 2373 fps++; 2374 default: 2375 gps++; 2376 } 2377 } 2378 gpcnt = gps; 2379 fpcnt = fps; 2380 BasicType rt = tf->return_type(); 2381 switch (rt) { 2382 case T_VOID: 2383 rtype = MacroAssembler::ret_type_void; 2384 break; 2385 default: 2386 rtype = MacroAssembler::ret_type_integral; 2387 break; 2388 case T_FLOAT: 2389 rtype = MacroAssembler::ret_type_float; 2390 break; 2391 case T_DOUBLE: 2392 rtype = MacroAssembler::ret_type_double; 2393 break; 2394 } 2395 } 2396 2397 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2398 MacroAssembler _masm(&cbuf); \ 2399 { \ 2400 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2401 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2402 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2403 __ INSN(REG, as_Register(BASE)); \ 2404 } 2405 2406 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2407 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2408 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2409 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2410 2411 // Used for all non-volatile memory accesses. The use of 2412 // $mem->opcode() to discover whether this pattern uses sign-extended 2413 // offsets is something of a kludge. 2414 static void loadStore(MacroAssembler masm, mem_insn insn, 2415 Register reg, int opcode, 2416 Register base, int index, int size, int disp) 2417 { 2418 Address::extend scale; 2419 2420 // Hooboy, this is fugly. We need a way to communicate to the 2421 // encoder that the index needs to be sign extended, so we have to 2422 // enumerate all the cases. 2423 switch (opcode) { 2424 case INDINDEXSCALEDI2L: 2425 case INDINDEXSCALEDI2LN: 2426 case INDINDEXI2L: 2427 case INDINDEXI2LN: 2428 scale = Address::sxtw(size); 2429 break; 2430 default: 2431 scale = Address::lsl(size); 2432 } 2433 2434 if (index == -1) { 2435 (masm.*insn)(reg, Address(base, disp)); 2436 } else { 2437 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2438 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2439 } 2440 } 2441 2442 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2443 FloatRegister reg, int opcode, 2444 Register base, int index, int size, int disp) 2445 { 2446 Address::extend scale; 2447 2448 switch (opcode) { 2449 case INDINDEXSCALEDI2L: 2450 case INDINDEXSCALEDI2LN: 2451 scale = Address::sxtw(size); 2452 break; 2453 default: 2454 scale = Address::lsl(size); 2455 } 2456 2457 if (index == -1) { 2458 (masm.*insn)(reg, Address(base, disp)); 2459 } else { 2460 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2461 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2462 } 2463 } 2464 2465 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2466 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2467 int opcode, Register base, int index, int size, int disp) 2468 { 2469 if (index == -1) { 2470 (masm.*insn)(reg, T, Address(base, disp)); 2471 } else { 2472 assert(disp == 0, "unsupported address mode"); 2473 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2474 } 2475 } 2476 2477 %} 2478 2479 2480 2481 //----------ENCODING BLOCK----------------------------------------------------- 2482 // This block specifies the encoding classes used by the compiler to 2483 // output byte streams. Encoding classes are parameterized macros 2484 // used by Machine Instruction Nodes in order to generate the bit 2485 // encoding of the instruction. Operands specify their base encoding 2486 // interface with the interface keyword. There are currently 2487 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2488 // COND_INTER. REG_INTER causes an operand to generate a function 2489 // which returns its register number when queried. CONST_INTER causes 2490 // an operand to generate a function which returns the value of the 2491 // constant when queried. MEMORY_INTER causes an operand to generate 2492 // four functions which return the Base Register, the Index Register, 2493 // the Scale Value, and the Offset Value of the operand when queried. 2494 // COND_INTER causes an operand to generate six functions which return 2495 // the encoding code (ie - encoding bits for the instruction) 2496 // associated with each basic boolean condition for a conditional 2497 // instruction. 2498 // 2499 // Instructions specify two basic values for encoding. Again, a 2500 // function is available to check if the constant displacement is an 2501 // oop. They use the ins_encode keyword to specify their encoding 2502 // classes (which must be a sequence of enc_class names, and their 2503 // parameters, specified in the encoding block), and they use the 2504 // opcode keyword to specify, in order, their primary, secondary, and 2505 // tertiary opcode. Only the opcode sections which a particular 2506 // instruction needs for encoding need to be specified. 2507 encode %{ 2508 // Build emit functions for each basic byte or larger field in the 2509 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2510 // from C++ code in the enc_class source block. Emit functions will 2511 // live in the main source block for now. In future, we can 2512 // generalize this by adding a syntax that specifies the sizes of 2513 // fields in an order, so that the adlc can build the emit functions 2514 // automagically 2515 2516 // catch all for unimplemented encodings 2517 enc_class enc_unimplemented %{ 2518 MacroAssembler _masm(&cbuf); 2519 __ unimplemented("C2 catch all"); 2520 %} 2521 2522 // BEGIN Non-volatile memory access 2523 2524 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2525 Register dst_reg = as_Register($dst$$reg); 2526 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2527 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2528 %} 2529 2530 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2531 Register dst_reg = as_Register($dst$$reg); 2532 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2533 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2534 %} 2535 2536 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2537 Register dst_reg = as_Register($dst$$reg); 2538 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2539 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2540 %} 2541 2542 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2543 Register dst_reg = as_Register($dst$$reg); 2544 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2545 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2546 %} 2547 2548 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2549 Register dst_reg = as_Register($dst$$reg); 2550 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2551 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2552 %} 2553 2554 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2555 Register dst_reg = as_Register($dst$$reg); 2556 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2557 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2558 %} 2559 2560 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2561 Register dst_reg = as_Register($dst$$reg); 2562 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2563 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2564 %} 2565 2566 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2567 Register dst_reg = as_Register($dst$$reg); 2568 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2569 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2570 %} 2571 2572 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2573 Register dst_reg = as_Register($dst$$reg); 2574 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2575 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2576 %} 2577 2578 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2579 Register dst_reg = as_Register($dst$$reg); 2580 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2581 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2582 %} 2583 2584 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2585 Register dst_reg = as_Register($dst$$reg); 2586 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2587 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2588 %} 2589 2590 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2591 Register dst_reg = as_Register($dst$$reg); 2592 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2593 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2594 %} 2595 2596 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2597 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2598 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2599 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2600 %} 2601 2602 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2603 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2604 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2605 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2606 %} 2607 2608 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2609 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2610 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2611 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2612 %} 2613 2614 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2615 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2616 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2617 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2618 %} 2619 2620 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2621 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2622 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2623 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2624 %} 2625 2626 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2627 Register src_reg = as_Register($src$$reg); 2628 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2629 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2630 %} 2631 2632 enc_class aarch64_enc_strb0(memory mem) %{ 2633 MacroAssembler _masm(&cbuf); 2634 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2635 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2636 %} 2637 2638 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2639 MacroAssembler _masm(&cbuf); 2640 __ membar(Assembler::StoreStore); 2641 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2642 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2643 %} 2644 2645 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2646 Register src_reg = as_Register($src$$reg); 2647 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2648 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2649 %} 2650 2651 enc_class aarch64_enc_strh0(memory mem) %{ 2652 MacroAssembler _masm(&cbuf); 2653 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2654 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2655 %} 2656 2657 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2658 Register src_reg = as_Register($src$$reg); 2659 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2660 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2661 %} 2662 2663 enc_class aarch64_enc_strw0(memory mem) %{ 2664 MacroAssembler _masm(&cbuf); 2665 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2666 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2667 %} 2668 2669 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2670 Register src_reg = as_Register($src$$reg); 2671 // we sometimes get asked to store the stack pointer into the 2672 // current thread -- we cannot do that directly on AArch64 2673 if (src_reg == r31_sp) { 2674 MacroAssembler _masm(&cbuf); 2675 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2676 __ mov(rscratch2, sp); 2677 src_reg = rscratch2; 2678 } 2679 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2680 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2681 %} 2682 2683 enc_class aarch64_enc_str0(memory mem) %{ 2684 MacroAssembler _masm(&cbuf); 2685 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2686 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2687 %} 2688 2689 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2690 FloatRegister src_reg = as_FloatRegister($src$$reg); 2691 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2692 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2693 %} 2694 2695 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2696 FloatRegister src_reg = as_FloatRegister($src$$reg); 2697 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2698 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2699 %} 2700 2701 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2702 FloatRegister src_reg = as_FloatRegister($src$$reg); 2703 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2704 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2705 %} 2706 2707 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2708 FloatRegister src_reg = as_FloatRegister($src$$reg); 2709 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2710 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2711 %} 2712 2713 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2714 FloatRegister src_reg = as_FloatRegister($src$$reg); 2715 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2716 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2717 %} 2718 2719 // END Non-volatile memory access 2720 2721 // volatile loads and stores 2722 2723 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2724 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2725 rscratch1, stlrb); 2726 %} 2727 2728 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2729 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2730 rscratch1, stlrh); 2731 %} 2732 2733 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2734 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2735 rscratch1, stlrw); 2736 %} 2737 2738 2739 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2740 Register dst_reg = as_Register($dst$$reg); 2741 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2742 rscratch1, ldarb); 2743 __ sxtbw(dst_reg, dst_reg); 2744 %} 2745 2746 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2747 Register dst_reg = as_Register($dst$$reg); 2748 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2749 rscratch1, ldarb); 2750 __ sxtb(dst_reg, dst_reg); 2751 %} 2752 2753 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2754 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2755 rscratch1, ldarb); 2756 %} 2757 2758 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2759 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2760 rscratch1, ldarb); 2761 %} 2762 2763 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2764 Register dst_reg = as_Register($dst$$reg); 2765 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2766 rscratch1, ldarh); 2767 __ sxthw(dst_reg, dst_reg); 2768 %} 2769 2770 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2771 Register dst_reg = as_Register($dst$$reg); 2772 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2773 rscratch1, ldarh); 2774 __ sxth(dst_reg, dst_reg); 2775 %} 2776 2777 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2778 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2779 rscratch1, ldarh); 2780 %} 2781 2782 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2783 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2784 rscratch1, ldarh); 2785 %} 2786 2787 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2788 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2789 rscratch1, ldarw); 2790 %} 2791 2792 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2793 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2794 rscratch1, ldarw); 2795 %} 2796 2797 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2798 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2799 rscratch1, ldar); 2800 %} 2801 2802 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2803 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2804 rscratch1, ldarw); 2805 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2806 %} 2807 2808 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2809 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2810 rscratch1, ldar); 2811 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2812 %} 2813 2814 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2815 Register src_reg = as_Register($src$$reg); 2816 // we sometimes get asked to store the stack pointer into the 2817 // current thread -- we cannot do that directly on AArch64 2818 if (src_reg == r31_sp) { 2819 MacroAssembler _masm(&cbuf); 2820 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2821 __ mov(rscratch2, sp); 2822 src_reg = rscratch2; 2823 } 2824 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2825 rscratch1, stlr); 2826 %} 2827 2828 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2829 { 2830 MacroAssembler _masm(&cbuf); 2831 FloatRegister src_reg = as_FloatRegister($src$$reg); 2832 __ fmovs(rscratch2, src_reg); 2833 } 2834 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2835 rscratch1, stlrw); 2836 %} 2837 2838 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2839 { 2840 MacroAssembler _masm(&cbuf); 2841 FloatRegister src_reg = as_FloatRegister($src$$reg); 2842 __ fmovd(rscratch2, src_reg); 2843 } 2844 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2845 rscratch1, stlr); 2846 %} 2847 2848 // synchronized read/update encodings 2849 2850 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2851 MacroAssembler _masm(&cbuf); 2852 Register dst_reg = as_Register($dst$$reg); 2853 Register base = as_Register($mem$$base); 2854 int index = $mem$$index; 2855 int scale = $mem$$scale; 2856 int disp = $mem$$disp; 2857 if (index == -1) { 2858 if (disp != 0) { 2859 __ lea(rscratch1, Address(base, disp)); 2860 __ ldaxr(dst_reg, rscratch1); 2861 } else { 2862 // TODO 2863 // should we ever get anything other than this case? 2864 __ ldaxr(dst_reg, base); 2865 } 2866 } else { 2867 Register index_reg = as_Register(index); 2868 if (disp == 0) { 2869 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2870 __ ldaxr(dst_reg, rscratch1); 2871 } else { 2872 __ lea(rscratch1, Address(base, disp)); 2873 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2874 __ ldaxr(dst_reg, rscratch1); 2875 } 2876 } 2877 %} 2878 2879 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2880 MacroAssembler _masm(&cbuf); 2881 Register src_reg = as_Register($src$$reg); 2882 Register base = as_Register($mem$$base); 2883 int index = $mem$$index; 2884 int scale = $mem$$scale; 2885 int disp = $mem$$disp; 2886 if (index == -1) { 2887 if (disp != 0) { 2888 __ lea(rscratch2, Address(base, disp)); 2889 __ stlxr(rscratch1, src_reg, rscratch2); 2890 } else { 2891 // TODO 2892 // should we ever get anything other than this case? 2893 __ stlxr(rscratch1, src_reg, base); 2894 } 2895 } else { 2896 Register index_reg = as_Register(index); 2897 if (disp == 0) { 2898 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2899 __ stlxr(rscratch1, src_reg, rscratch2); 2900 } else { 2901 __ lea(rscratch2, Address(base, disp)); 2902 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2903 __ stlxr(rscratch1, src_reg, rscratch2); 2904 } 2905 } 2906 __ cmpw(rscratch1, zr); 2907 %} 2908 2909 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2910 MacroAssembler _masm(&cbuf); 2911 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2912 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2913 Assembler::xword, /*acquire*/ false, /*release*/ true, 2914 /*weak*/ false, noreg); 2915 %} 2916 2917 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2918 MacroAssembler _masm(&cbuf); 2919 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2920 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2921 Assembler::word, /*acquire*/ false, /*release*/ true, 2922 /*weak*/ false, noreg); 2923 %} 2924 2925 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2926 MacroAssembler _masm(&cbuf); 2927 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2928 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2929 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2930 /*weak*/ false, noreg); 2931 %} 2932 2933 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2934 MacroAssembler _masm(&cbuf); 2935 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2936 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2937 Assembler::byte, /*acquire*/ false, /*release*/ true, 2938 /*weak*/ false, noreg); 2939 %} 2940 2941 2942 // The only difference between aarch64_enc_cmpxchg and 2943 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2944 // CompareAndSwap sequence to serve as a barrier on acquiring a 2945 // lock. 2946 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2947 MacroAssembler _masm(&cbuf); 2948 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2949 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2950 Assembler::xword, /*acquire*/ true, /*release*/ true, 2951 /*weak*/ false, noreg); 2952 %} 2953 2954 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2955 MacroAssembler _masm(&cbuf); 2956 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2957 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2958 Assembler::word, /*acquire*/ true, /*release*/ true, 2959 /*weak*/ false, noreg); 2960 %} 2961 2962 2963 // auxiliary used for CompareAndSwapX to set result register 2964 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2965 MacroAssembler _masm(&cbuf); 2966 Register res_reg = as_Register($res$$reg); 2967 __ cset(res_reg, Assembler::EQ); 2968 %} 2969 2970 // prefetch encodings 2971 2972 enc_class aarch64_enc_prefetchw(memory mem) %{ 2973 MacroAssembler _masm(&cbuf); 2974 Register base = as_Register($mem$$base); 2975 int index = $mem$$index; 2976 int scale = $mem$$scale; 2977 int disp = $mem$$disp; 2978 if (index == -1) { 2979 __ prfm(Address(base, disp), PSTL1KEEP); 2980 } else { 2981 Register index_reg = as_Register(index); 2982 if (disp == 0) { 2983 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2984 } else { 2985 __ lea(rscratch1, Address(base, disp)); 2986 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2987 } 2988 } 2989 %} 2990 2991 /// mov envcodings 2992 2993 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2994 MacroAssembler _masm(&cbuf); 2995 u_int32_t con = (u_int32_t)$src$$constant; 2996 Register dst_reg = as_Register($dst$$reg); 2997 if (con == 0) { 2998 __ movw(dst_reg, zr); 2999 } else { 3000 __ movw(dst_reg, con); 3001 } 3002 %} 3003 3004 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3005 MacroAssembler _masm(&cbuf); 3006 Register dst_reg = as_Register($dst$$reg); 3007 u_int64_t con = (u_int64_t)$src$$constant; 3008 if (con == 0) { 3009 __ mov(dst_reg, zr); 3010 } else { 3011 __ mov(dst_reg, con); 3012 } 3013 %} 3014 3015 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3016 MacroAssembler _masm(&cbuf); 3017 Register dst_reg = as_Register($dst$$reg); 3018 address con = (address)$src$$constant; 3019 if (con == NULL || con == (address)1) { 3020 ShouldNotReachHere(); 3021 } else { 3022 relocInfo::relocType rtype = $src->constant_reloc(); 3023 if (rtype == relocInfo::oop_type) { 3024 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3025 } else if (rtype == relocInfo::metadata_type) { 3026 __ mov_metadata(dst_reg, (Metadata*)con); 3027 } else { 3028 assert(rtype == relocInfo::none, "unexpected reloc type"); 3029 if (con < (address)(uintptr_t)os::vm_page_size()) { 3030 __ mov(dst_reg, con); 3031 } else { 3032 unsigned long offset; 3033 __ adrp(dst_reg, con, offset); 3034 __ add(dst_reg, dst_reg, offset); 3035 } 3036 } 3037 } 3038 %} 3039 3040 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3041 MacroAssembler _masm(&cbuf); 3042 Register dst_reg = as_Register($dst$$reg); 3043 __ mov(dst_reg, zr); 3044 %} 3045 3046 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3047 MacroAssembler _masm(&cbuf); 3048 Register dst_reg = as_Register($dst$$reg); 3049 __ mov(dst_reg, (u_int64_t)1); 3050 %} 3051 3052 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3053 MacroAssembler _masm(&cbuf); 3054 address page = (address)$src$$constant; 3055 Register dst_reg = as_Register($dst$$reg); 3056 unsigned long off; 3057 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3058 assert(off == 0, "assumed offset == 0"); 3059 %} 3060 3061 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3062 MacroAssembler _masm(&cbuf); 3063 __ load_byte_map_base($dst$$Register); 3064 %} 3065 3066 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3067 MacroAssembler _masm(&cbuf); 3068 Register dst_reg = as_Register($dst$$reg); 3069 address con = (address)$src$$constant; 3070 if (con == NULL) { 3071 ShouldNotReachHere(); 3072 } else { 3073 relocInfo::relocType rtype = $src->constant_reloc(); 3074 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3075 __ set_narrow_oop(dst_reg, (jobject)con); 3076 } 3077 %} 3078 3079 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3080 MacroAssembler _masm(&cbuf); 3081 Register dst_reg = as_Register($dst$$reg); 3082 __ mov(dst_reg, zr); 3083 %} 3084 3085 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3086 MacroAssembler _masm(&cbuf); 3087 Register dst_reg = as_Register($dst$$reg); 3088 address con = (address)$src$$constant; 3089 if (con == NULL) { 3090 ShouldNotReachHere(); 3091 } else { 3092 relocInfo::relocType rtype = $src->constant_reloc(); 3093 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3094 __ set_narrow_klass(dst_reg, (Klass *)con); 3095 } 3096 %} 3097 3098 // arithmetic encodings 3099 3100 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3101 MacroAssembler _masm(&cbuf); 3102 Register dst_reg = as_Register($dst$$reg); 3103 Register src_reg = as_Register($src1$$reg); 3104 int32_t con = (int32_t)$src2$$constant; 3105 // add has primary == 0, subtract has primary == 1 3106 if ($primary) { con = -con; } 3107 if (con < 0) { 3108 __ subw(dst_reg, src_reg, -con); 3109 } else { 3110 __ addw(dst_reg, src_reg, con); 3111 } 3112 %} 3113 3114 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3115 MacroAssembler _masm(&cbuf); 3116 Register dst_reg = as_Register($dst$$reg); 3117 Register src_reg = as_Register($src1$$reg); 3118 int32_t con = (int32_t)$src2$$constant; 3119 // add has primary == 0, subtract has primary == 1 3120 if ($primary) { con = -con; } 3121 if (con < 0) { 3122 __ sub(dst_reg, src_reg, -con); 3123 } else { 3124 __ add(dst_reg, src_reg, con); 3125 } 3126 %} 3127 3128 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3129 MacroAssembler _masm(&cbuf); 3130 Register dst_reg = as_Register($dst$$reg); 3131 Register src1_reg = as_Register($src1$$reg); 3132 Register src2_reg = as_Register($src2$$reg); 3133 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3134 %} 3135 3136 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3137 MacroAssembler _masm(&cbuf); 3138 Register dst_reg = as_Register($dst$$reg); 3139 Register src1_reg = as_Register($src1$$reg); 3140 Register src2_reg = as_Register($src2$$reg); 3141 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3142 %} 3143 3144 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3145 MacroAssembler _masm(&cbuf); 3146 Register dst_reg = as_Register($dst$$reg); 3147 Register src1_reg = as_Register($src1$$reg); 3148 Register src2_reg = as_Register($src2$$reg); 3149 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3150 %} 3151 3152 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3153 MacroAssembler _masm(&cbuf); 3154 Register dst_reg = as_Register($dst$$reg); 3155 Register src1_reg = as_Register($src1$$reg); 3156 Register src2_reg = as_Register($src2$$reg); 3157 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3158 %} 3159 3160 // compare instruction encodings 3161 3162 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3163 MacroAssembler _masm(&cbuf); 3164 Register reg1 = as_Register($src1$$reg); 3165 Register reg2 = as_Register($src2$$reg); 3166 __ cmpw(reg1, reg2); 3167 %} 3168 3169 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3170 MacroAssembler _masm(&cbuf); 3171 Register reg = as_Register($src1$$reg); 3172 int32_t val = $src2$$constant; 3173 if (val >= 0) { 3174 __ subsw(zr, reg, val); 3175 } else { 3176 __ addsw(zr, reg, -val); 3177 } 3178 %} 3179 3180 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3181 MacroAssembler _masm(&cbuf); 3182 Register reg1 = as_Register($src1$$reg); 3183 u_int32_t val = (u_int32_t)$src2$$constant; 3184 __ movw(rscratch1, val); 3185 __ cmpw(reg1, rscratch1); 3186 %} 3187 3188 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3189 MacroAssembler _masm(&cbuf); 3190 Register reg1 = as_Register($src1$$reg); 3191 Register reg2 = as_Register($src2$$reg); 3192 __ cmp(reg1, reg2); 3193 %} 3194 3195 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3196 MacroAssembler _masm(&cbuf); 3197 Register reg = as_Register($src1$$reg); 3198 int64_t val = $src2$$constant; 3199 if (val >= 0) { 3200 __ subs(zr, reg, val); 3201 } else if (val != -val) { 3202 __ adds(zr, reg, -val); 3203 } else { 3204 // aargh, Long.MIN_VALUE is a special case 3205 __ orr(rscratch1, zr, (u_int64_t)val); 3206 __ subs(zr, reg, rscratch1); 3207 } 3208 %} 3209 3210 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3211 MacroAssembler _masm(&cbuf); 3212 Register reg1 = as_Register($src1$$reg); 3213 u_int64_t val = (u_int64_t)$src2$$constant; 3214 __ mov(rscratch1, val); 3215 __ cmp(reg1, rscratch1); 3216 %} 3217 3218 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3219 MacroAssembler _masm(&cbuf); 3220 Register reg1 = as_Register($src1$$reg); 3221 Register reg2 = as_Register($src2$$reg); 3222 __ cmp(reg1, reg2); 3223 %} 3224 3225 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3226 MacroAssembler _masm(&cbuf); 3227 Register reg1 = as_Register($src1$$reg); 3228 Register reg2 = as_Register($src2$$reg); 3229 __ cmpw(reg1, reg2); 3230 %} 3231 3232 enc_class aarch64_enc_testp(iRegP src) %{ 3233 MacroAssembler _masm(&cbuf); 3234 Register reg = as_Register($src$$reg); 3235 __ cmp(reg, zr); 3236 %} 3237 3238 enc_class aarch64_enc_testn(iRegN src) %{ 3239 MacroAssembler _masm(&cbuf); 3240 Register reg = as_Register($src$$reg); 3241 __ cmpw(reg, zr); 3242 %} 3243 3244 enc_class aarch64_enc_b(label lbl) %{ 3245 MacroAssembler _masm(&cbuf); 3246 Label *L = $lbl$$label; 3247 __ b(*L); 3248 %} 3249 3250 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3251 MacroAssembler _masm(&cbuf); 3252 Label *L = $lbl$$label; 3253 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3254 %} 3255 3256 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3257 MacroAssembler _masm(&cbuf); 3258 Label *L = $lbl$$label; 3259 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3260 %} 3261 3262 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3263 %{ 3264 Register sub_reg = as_Register($sub$$reg); 3265 Register super_reg = as_Register($super$$reg); 3266 Register temp_reg = as_Register($temp$$reg); 3267 Register result_reg = as_Register($result$$reg); 3268 3269 Label miss; 3270 MacroAssembler _masm(&cbuf); 3271 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3272 NULL, &miss, 3273 /*set_cond_codes:*/ true); 3274 if ($primary) { 3275 __ mov(result_reg, zr); 3276 } 3277 __ bind(miss); 3278 %} 3279 3280 enc_class aarch64_enc_java_static_call(method meth) %{ 3281 MacroAssembler _masm(&cbuf); 3282 3283 address addr = (address)$meth$$method; 3284 address call; 3285 if (!_method) { 3286 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3287 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3288 } else { 3289 int method_index = resolved_method_index(cbuf); 3290 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3291 : static_call_Relocation::spec(method_index); 3292 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3293 3294 // Emit stub for static call 3295 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3296 if (stub == NULL) { 3297 ciEnv::current()->record_failure("CodeCache is full"); 3298 return; 3299 } 3300 } 3301 if (call == NULL) { 3302 ciEnv::current()->record_failure("CodeCache is full"); 3303 return; 3304 } 3305 %} 3306 3307 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3308 MacroAssembler _masm(&cbuf); 3309 int method_index = resolved_method_index(cbuf); 3310 address call = __ ic_call((address)$meth$$method, method_index); 3311 if (call == NULL) { 3312 ciEnv::current()->record_failure("CodeCache is full"); 3313 return; 3314 } 3315 %} 3316 3317 enc_class aarch64_enc_call_epilog() %{ 3318 MacroAssembler _masm(&cbuf); 3319 if (VerifyStackAtCalls) { 3320 // Check that stack depth is unchanged: find majik cookie on stack 3321 __ call_Unimplemented(); 3322 } 3323 %} 3324 3325 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3326 MacroAssembler _masm(&cbuf); 3327 3328 // some calls to generated routines (arraycopy code) are scheduled 3329 // by C2 as runtime calls. if so we can call them using a br (they 3330 // will be in a reachable segment) otherwise we have to use a blrt 3331 // which loads the absolute address into a register. 3332 address entry = (address)$meth$$method; 3333 CodeBlob *cb = CodeCache::find_blob(entry); 3334 if (cb) { 3335 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3336 if (call == NULL) { 3337 ciEnv::current()->record_failure("CodeCache is full"); 3338 return; 3339 } 3340 } else { 3341 int gpcnt; 3342 int fpcnt; 3343 int rtype; 3344 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3345 Label retaddr; 3346 __ adr(rscratch2, retaddr); 3347 __ lea(rscratch1, RuntimeAddress(entry)); 3348 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3349 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3350 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3351 __ bind(retaddr); 3352 __ add(sp, sp, 2 * wordSize); 3353 } 3354 %} 3355 3356 enc_class aarch64_enc_rethrow() %{ 3357 MacroAssembler _masm(&cbuf); 3358 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3359 %} 3360 3361 enc_class aarch64_enc_ret() %{ 3362 MacroAssembler _masm(&cbuf); 3363 __ ret(lr); 3364 %} 3365 3366 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3367 MacroAssembler _masm(&cbuf); 3368 Register target_reg = as_Register($jump_target$$reg); 3369 __ br(target_reg); 3370 %} 3371 3372 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3373 MacroAssembler _masm(&cbuf); 3374 Register target_reg = as_Register($jump_target$$reg); 3375 // exception oop should be in r0 3376 // ret addr has been popped into lr 3377 // callee expects it in r3 3378 __ mov(r3, lr); 3379 __ br(target_reg); 3380 %} 3381 3382 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3383 MacroAssembler _masm(&cbuf); 3384 Register oop = as_Register($object$$reg); 3385 Register box = as_Register($box$$reg); 3386 Register disp_hdr = as_Register($tmp$$reg); 3387 Register tmp = as_Register($tmp2$$reg); 3388 Label cont; 3389 Label object_has_monitor; 3390 Label cas_failed; 3391 3392 assert_different_registers(oop, box, tmp, disp_hdr); 3393 3394 // Load markOop from object into displaced_header. 3395 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3396 3397 // Always do locking in runtime. 3398 if (EmitSync & 0x01) { 3399 __ cmp(oop, zr); 3400 return; 3401 } 3402 3403 if (UseBiasedLocking && !UseOptoBiasInlining) { 3404 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3405 } 3406 3407 // Handle existing monitor 3408 if ((EmitSync & 0x02) == 0) { 3409 // we can use AArch64's bit test and branch here but 3410 // markoopDesc does not define a bit index just the bit value 3411 // so assert in case the bit pos changes 3412 # define __monitor_value_log2 1 3413 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 3414 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 3415 # undef __monitor_value_log2 3416 } 3417 3418 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3419 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3420 3421 // Load Compare Value application register. 3422 3423 // Initialize the box. (Must happen before we update the object mark!) 3424 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3425 3426 // Compare object markOop with mark and if equal exchange scratch1 3427 // with object markOop. 3428 if (UseLSE) { 3429 __ mov(tmp, disp_hdr); 3430 __ casal(Assembler::xword, tmp, box, oop); 3431 __ cmp(tmp, disp_hdr); 3432 __ br(Assembler::EQ, cont); 3433 } else { 3434 Label retry_load; 3435 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3436 __ prfm(Address(oop), PSTL1STRM); 3437 __ bind(retry_load); 3438 __ ldaxr(tmp, oop); 3439 __ cmp(tmp, disp_hdr); 3440 __ br(Assembler::NE, cas_failed); 3441 // use stlxr to ensure update is immediately visible 3442 __ stlxr(tmp, box, oop); 3443 __ cbzw(tmp, cont); 3444 __ b(retry_load); 3445 } 3446 3447 // Formerly: 3448 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3449 // /*newv=*/box, 3450 // /*addr=*/oop, 3451 // /*tmp=*/tmp, 3452 // cont, 3453 // /*fail*/NULL); 3454 3455 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3456 3457 // If the compare-and-exchange succeeded, then we found an unlocked 3458 // object, will have now locked it will continue at label cont 3459 3460 __ bind(cas_failed); 3461 // We did not see an unlocked object so try the fast recursive case. 3462 3463 // Check if the owner is self by comparing the value in the 3464 // markOop of object (disp_hdr) with the stack pointer. 3465 __ mov(rscratch1, sp); 3466 __ sub(disp_hdr, disp_hdr, rscratch1); 3467 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3468 // If condition is true we are cont and hence we can store 0 as the 3469 // displaced header in the box, which indicates that it is a recursive lock. 3470 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3471 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3472 3473 // Handle existing monitor. 3474 if ((EmitSync & 0x02) == 0) { 3475 __ b(cont); 3476 3477 __ bind(object_has_monitor); 3478 // The object's monitor m is unlocked iff m->owner == NULL, 3479 // otherwise m->owner may contain a thread or a stack address. 3480 // 3481 // Try to CAS m->owner from NULL to current thread. 3482 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3483 __ mov(disp_hdr, zr); 3484 3485 if (UseLSE) { 3486 __ mov(rscratch1, disp_hdr); 3487 __ casal(Assembler::xword, rscratch1, rthread, tmp); 3488 __ cmp(rscratch1, disp_hdr); 3489 } else { 3490 Label retry_load, fail; 3491 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3492 __ prfm(Address(tmp), PSTL1STRM); 3493 __ bind(retry_load); 3494 __ ldaxr(rscratch1, tmp); 3495 __ cmp(disp_hdr, rscratch1); 3496 __ br(Assembler::NE, fail); 3497 // use stlxr to ensure update is immediately visible 3498 __ stlxr(rscratch1, rthread, tmp); 3499 __ cbnzw(rscratch1, retry_load); 3500 __ bind(fail); 3501 } 3502 3503 // Label next; 3504 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3505 // /*newv=*/rthread, 3506 // /*addr=*/tmp, 3507 // /*tmp=*/rscratch1, 3508 // /*succeed*/next, 3509 // /*fail*/NULL); 3510 // __ bind(next); 3511 3512 // store a non-null value into the box. 3513 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3514 3515 // PPC port checks the following invariants 3516 // #ifdef ASSERT 3517 // bne(flag, cont); 3518 // We have acquired the monitor, check some invariants. 3519 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 3520 // Invariant 1: _recursions should be 0. 3521 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 3522 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 3523 // "monitor->_recursions should be 0", -1); 3524 // Invariant 2: OwnerIsThread shouldn't be 0. 3525 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 3526 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 3527 // "monitor->OwnerIsThread shouldn't be 0", -1); 3528 // #endif 3529 } 3530 3531 __ bind(cont); 3532 // flag == EQ indicates success 3533 // flag == NE indicates failure 3534 3535 %} 3536 3537 // TODO 3538 // reimplement this with custom cmpxchgptr code 3539 // which avoids some of the unnecessary branching 3540 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3541 MacroAssembler _masm(&cbuf); 3542 Register oop = as_Register($object$$reg); 3543 Register box = as_Register($box$$reg); 3544 Register disp_hdr = as_Register($tmp$$reg); 3545 Register tmp = as_Register($tmp2$$reg); 3546 Label cont; 3547 Label object_has_monitor; 3548 Label cas_failed; 3549 3550 assert_different_registers(oop, box, tmp, disp_hdr); 3551 3552 // Always do locking in runtime. 3553 if (EmitSync & 0x01) { 3554 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3555 return; 3556 } 3557 3558 if (UseBiasedLocking && !UseOptoBiasInlining) { 3559 __ biased_locking_exit(oop, tmp, cont); 3560 } 3561 3562 // Find the lock address and load the displaced header from the stack. 3563 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3564 3565 // If the displaced header is 0, we have a recursive unlock. 3566 __ cmp(disp_hdr, zr); 3567 __ br(Assembler::EQ, cont); 3568 3569 3570 // Handle existing monitor. 3571 if ((EmitSync & 0x02) == 0) { 3572 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3573 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3574 } 3575 3576 // Check if it is still a light weight lock, this is is true if we 3577 // see the stack address of the basicLock in the markOop of the 3578 // object. 3579 3580 if (UseLSE) { 3581 __ mov(tmp, box); 3582 __ casl(Assembler::xword, tmp, disp_hdr, oop); 3583 __ cmp(tmp, box); 3584 } else { 3585 Label retry_load; 3586 if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) 3587 __ prfm(Address(oop), PSTL1STRM); 3588 __ bind(retry_load); 3589 __ ldxr(tmp, oop); 3590 __ cmp(box, tmp); 3591 __ br(Assembler::NE, cas_failed); 3592 // use stlxr to ensure update is immediately visible 3593 __ stlxr(tmp, disp_hdr, oop); 3594 __ cbzw(tmp, cont); 3595 __ b(retry_load); 3596 } 3597 3598 // __ cmpxchgptr(/*compare_value=*/box, 3599 // /*exchange_value=*/disp_hdr, 3600 // /*where=*/oop, 3601 // /*result=*/tmp, 3602 // cont, 3603 // /*cas_failed*/NULL); 3604 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3605 3606 __ bind(cas_failed); 3607 3608 // Handle existing monitor. 3609 if ((EmitSync & 0x02) == 0) { 3610 __ b(cont); 3611 3612 __ bind(object_has_monitor); 3613 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3614 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3615 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3616 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3617 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3618 __ cmp(rscratch1, zr); 3619 __ br(Assembler::NE, cont); 3620 3621 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3622 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3623 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3624 __ cmp(rscratch1, zr); 3625 __ cbnz(rscratch1, cont); 3626 // need a release store here 3627 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3628 __ stlr(rscratch1, tmp); // rscratch1 is zero 3629 } 3630 3631 __ bind(cont); 3632 // flag == EQ indicates success 3633 // flag == NE indicates failure 3634 %} 3635 3636 %} 3637 3638 //----------FRAME-------------------------------------------------------------- 3639 // Definition of frame structure and management information. 3640 // 3641 // S T A C K L A Y O U T Allocators stack-slot number 3642 // | (to get allocators register number 3643 // G Owned by | | v add OptoReg::stack0()) 3644 // r CALLER | | 3645 // o | +--------+ pad to even-align allocators stack-slot 3646 // w V | pad0 | numbers; owned by CALLER 3647 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3648 // h ^ | in | 5 3649 // | | args | 4 Holes in incoming args owned by SELF 3650 // | | | | 3 3651 // | | +--------+ 3652 // V | | old out| Empty on Intel, window on Sparc 3653 // | old |preserve| Must be even aligned. 3654 // | SP-+--------+----> Matcher::_old_SP, even aligned 3655 // | | in | 3 area for Intel ret address 3656 // Owned by |preserve| Empty on Sparc. 3657 // SELF +--------+ 3658 // | | pad2 | 2 pad to align old SP 3659 // | +--------+ 1 3660 // | | locks | 0 3661 // | +--------+----> OptoReg::stack0(), even aligned 3662 // | | pad1 | 11 pad to align new SP 3663 // | +--------+ 3664 // | | | 10 3665 // | | spills | 9 spills 3666 // V | | 8 (pad0 slot for callee) 3667 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3668 // ^ | out | 7 3669 // | | args | 6 Holes in outgoing args owned by CALLEE 3670 // Owned by +--------+ 3671 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3672 // | new |preserve| Must be even-aligned. 3673 // | SP-+--------+----> Matcher::_new_SP, even aligned 3674 // | | | 3675 // 3676 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3677 // known from SELF's arguments and the Java calling convention. 3678 // Region 6-7 is determined per call site. 3679 // Note 2: If the calling convention leaves holes in the incoming argument 3680 // area, those holes are owned by SELF. Holes in the outgoing area 3681 // are owned by the CALLEE. Holes should not be nessecary in the 3682 // incoming area, as the Java calling convention is completely under 3683 // the control of the AD file. Doubles can be sorted and packed to 3684 // avoid holes. Holes in the outgoing arguments may be nessecary for 3685 // varargs C calling conventions. 3686 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3687 // even aligned with pad0 as needed. 3688 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3689 // (the latter is true on Intel but is it false on AArch64?) 3690 // region 6-11 is even aligned; it may be padded out more so that 3691 // the region from SP to FP meets the minimum stack alignment. 3692 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3693 // alignment. Region 11, pad1, may be dynamically extended so that 3694 // SP meets the minimum alignment. 3695 3696 frame %{ 3697 // What direction does stack grow in (assumed to be same for C & Java) 3698 stack_direction(TOWARDS_LOW); 3699 3700 // These three registers define part of the calling convention 3701 // between compiled code and the interpreter. 3702 3703 // Inline Cache Register or methodOop for I2C. 3704 inline_cache_reg(R12); 3705 3706 // Method Oop Register when calling interpreter. 3707 interpreter_method_oop_reg(R12); 3708 3709 // Number of stack slots consumed by locking an object 3710 sync_stack_slots(2); 3711 3712 // Compiled code's Frame Pointer 3713 frame_pointer(R31); 3714 3715 // Interpreter stores its frame pointer in a register which is 3716 // stored to the stack by I2CAdaptors. 3717 // I2CAdaptors convert from interpreted java to compiled java. 3718 interpreter_frame_pointer(R29); 3719 3720 // Stack alignment requirement 3721 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3722 3723 // Number of stack slots between incoming argument block and the start of 3724 // a new frame. The PROLOG must add this many slots to the stack. The 3725 // EPILOG must remove this many slots. aarch64 needs two slots for 3726 // return address and fp. 3727 // TODO think this is correct but check 3728 in_preserve_stack_slots(4); 3729 3730 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3731 // for calls to C. Supports the var-args backing area for register parms. 3732 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3733 3734 // The after-PROLOG location of the return address. Location of 3735 // return address specifies a type (REG or STACK) and a number 3736 // representing the register number (i.e. - use a register name) or 3737 // stack slot. 3738 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3739 // Otherwise, it is above the locks and verification slot and alignment word 3740 // TODO this may well be correct but need to check why that - 2 is there 3741 // ppc port uses 0 but we definitely need to allow for fixed_slots 3742 // which folds in the space used for monitors 3743 return_addr(STACK - 2 + 3744 align_up((Compile::current()->in_preserve_stack_slots() + 3745 Compile::current()->fixed_slots()), 3746 stack_alignment_in_slots())); 3747 3748 // Body of function which returns an integer array locating 3749 // arguments either in registers or in stack slots. Passed an array 3750 // of ideal registers called "sig" and a "length" count. Stack-slot 3751 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3752 // arguments for a CALLEE. Incoming stack arguments are 3753 // automatically biased by the preserve_stack_slots field above. 3754 3755 calling_convention 3756 %{ 3757 // No difference between ingoing/outgoing just pass false 3758 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3759 %} 3760 3761 c_calling_convention 3762 %{ 3763 // This is obviously always outgoing 3764 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3765 %} 3766 3767 // Location of compiled Java return values. Same as C for now. 3768 return_value 3769 %{ 3770 // TODO do we allow ideal_reg == Op_RegN??? 3771 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3772 "only return normal values"); 3773 3774 static const int lo[Op_RegL + 1] = { // enum name 3775 0, // Op_Node 3776 0, // Op_Set 3777 R0_num, // Op_RegN 3778 R0_num, // Op_RegI 3779 R0_num, // Op_RegP 3780 V0_num, // Op_RegF 3781 V0_num, // Op_RegD 3782 R0_num // Op_RegL 3783 }; 3784 3785 static const int hi[Op_RegL + 1] = { // enum name 3786 0, // Op_Node 3787 0, // Op_Set 3788 OptoReg::Bad, // Op_RegN 3789 OptoReg::Bad, // Op_RegI 3790 R0_H_num, // Op_RegP 3791 OptoReg::Bad, // Op_RegF 3792 V0_H_num, // Op_RegD 3793 R0_H_num // Op_RegL 3794 }; 3795 3796 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3797 %} 3798 %} 3799 3800 //----------ATTRIBUTES--------------------------------------------------------- 3801 //----------Operand Attributes------------------------------------------------- 3802 op_attrib op_cost(1); // Required cost attribute 3803 3804 //----------Instruction Attributes--------------------------------------------- 3805 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3806 ins_attrib ins_size(32); // Required size attribute (in bits) 3807 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3808 // a non-matching short branch variant 3809 // of some long branch? 3810 ins_attrib ins_alignment(4); // Required alignment attribute (must 3811 // be a power of 2) specifies the 3812 // alignment that some part of the 3813 // instruction (not necessarily the 3814 // start) requires. If > 1, a 3815 // compute_padding() function must be 3816 // provided for the instruction 3817 3818 //----------OPERANDS----------------------------------------------------------- 3819 // Operand definitions must precede instruction definitions for correct parsing 3820 // in the ADLC because operands constitute user defined types which are used in 3821 // instruction definitions. 3822 3823 //----------Simple Operands---------------------------------------------------- 3824 3825 // Integer operands 32 bit 3826 // 32 bit immediate 3827 operand immI() 3828 %{ 3829 match(ConI); 3830 3831 op_cost(0); 3832 format %{ %} 3833 interface(CONST_INTER); 3834 %} 3835 3836 // 32 bit zero 3837 operand immI0() 3838 %{ 3839 predicate(n->get_int() == 0); 3840 match(ConI); 3841 3842 op_cost(0); 3843 format %{ %} 3844 interface(CONST_INTER); 3845 %} 3846 3847 // 32 bit unit increment 3848 operand immI_1() 3849 %{ 3850 predicate(n->get_int() == 1); 3851 match(ConI); 3852 3853 op_cost(0); 3854 format %{ %} 3855 interface(CONST_INTER); 3856 %} 3857 3858 // 32 bit unit decrement 3859 operand immI_M1() 3860 %{ 3861 predicate(n->get_int() == -1); 3862 match(ConI); 3863 3864 op_cost(0); 3865 format %{ %} 3866 interface(CONST_INTER); 3867 %} 3868 3869 // Shift values for add/sub extension shift 3870 operand immIExt() 3871 %{ 3872 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3873 match(ConI); 3874 3875 op_cost(0); 3876 format %{ %} 3877 interface(CONST_INTER); 3878 %} 3879 3880 operand immI_le_4() 3881 %{ 3882 predicate(n->get_int() <= 4); 3883 match(ConI); 3884 3885 op_cost(0); 3886 format %{ %} 3887 interface(CONST_INTER); 3888 %} 3889 3890 operand immI_31() 3891 %{ 3892 predicate(n->get_int() == 31); 3893 match(ConI); 3894 3895 op_cost(0); 3896 format %{ %} 3897 interface(CONST_INTER); 3898 %} 3899 3900 operand immI_8() 3901 %{ 3902 predicate(n->get_int() == 8); 3903 match(ConI); 3904 3905 op_cost(0); 3906 format %{ %} 3907 interface(CONST_INTER); 3908 %} 3909 3910 operand immI_16() 3911 %{ 3912 predicate(n->get_int() == 16); 3913 match(ConI); 3914 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918 %} 3919 3920 operand immI_24() 3921 %{ 3922 predicate(n->get_int() == 24); 3923 match(ConI); 3924 3925 op_cost(0); 3926 format %{ %} 3927 interface(CONST_INTER); 3928 %} 3929 3930 operand immI_32() 3931 %{ 3932 predicate(n->get_int() == 32); 3933 match(ConI); 3934 3935 op_cost(0); 3936 format %{ %} 3937 interface(CONST_INTER); 3938 %} 3939 3940 operand immI_48() 3941 %{ 3942 predicate(n->get_int() == 48); 3943 match(ConI); 3944 3945 op_cost(0); 3946 format %{ %} 3947 interface(CONST_INTER); 3948 %} 3949 3950 operand immI_56() 3951 %{ 3952 predicate(n->get_int() == 56); 3953 match(ConI); 3954 3955 op_cost(0); 3956 format %{ %} 3957 interface(CONST_INTER); 3958 %} 3959 3960 operand immI_63() 3961 %{ 3962 predicate(n->get_int() == 63); 3963 match(ConI); 3964 3965 op_cost(0); 3966 format %{ %} 3967 interface(CONST_INTER); 3968 %} 3969 3970 operand immI_64() 3971 %{ 3972 predicate(n->get_int() == 64); 3973 match(ConI); 3974 3975 op_cost(0); 3976 format %{ %} 3977 interface(CONST_INTER); 3978 %} 3979 3980 operand immI_255() 3981 %{ 3982 predicate(n->get_int() == 255); 3983 match(ConI); 3984 3985 op_cost(0); 3986 format %{ %} 3987 interface(CONST_INTER); 3988 %} 3989 3990 operand immI_65535() 3991 %{ 3992 predicate(n->get_int() == 65535); 3993 match(ConI); 3994 3995 op_cost(0); 3996 format %{ %} 3997 interface(CONST_INTER); 3998 %} 3999 4000 operand immL_255() 4001 %{ 4002 predicate(n->get_long() == 255L); 4003 match(ConL); 4004 4005 op_cost(0); 4006 format %{ %} 4007 interface(CONST_INTER); 4008 %} 4009 4010 operand immL_65535() 4011 %{ 4012 predicate(n->get_long() == 65535L); 4013 match(ConL); 4014 4015 op_cost(0); 4016 format %{ %} 4017 interface(CONST_INTER); 4018 %} 4019 4020 operand immL_4294967295() 4021 %{ 4022 predicate(n->get_long() == 4294967295L); 4023 match(ConL); 4024 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 operand immL_bitmask() 4031 %{ 4032 predicate(((n->get_long() & 0xc000000000000000l) == 0) 4033 && is_power_of_2(n->get_long() + 1)); 4034 match(ConL); 4035 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 operand immI_bitmask() 4042 %{ 4043 predicate(((n->get_int() & 0xc0000000) == 0) 4044 && is_power_of_2(n->get_int() + 1)); 4045 match(ConI); 4046 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // Scale values for scaled offset addressing modes (up to long but not quad) 4053 operand immIScale() 4054 %{ 4055 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 // 26 bit signed offset -- for pc-relative branches 4064 operand immI26() 4065 %{ 4066 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 // 19 bit signed offset -- for pc-relative loads 4075 operand immI19() 4076 %{ 4077 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4078 match(ConI); 4079 4080 op_cost(0); 4081 format %{ %} 4082 interface(CONST_INTER); 4083 %} 4084 4085 // 12 bit unsigned offset -- for base plus immediate loads 4086 operand immIU12() 4087 %{ 4088 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4089 match(ConI); 4090 4091 op_cost(0); 4092 format %{ %} 4093 interface(CONST_INTER); 4094 %} 4095 4096 operand immLU12() 4097 %{ 4098 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4099 match(ConL); 4100 4101 op_cost(0); 4102 format %{ %} 4103 interface(CONST_INTER); 4104 %} 4105 4106 // Offset for scaled or unscaled immediate loads and stores 4107 operand immIOffset() 4108 %{ 4109 predicate(Address::offset_ok_for_immed(n->get_int())); 4110 match(ConI); 4111 4112 op_cost(0); 4113 format %{ %} 4114 interface(CONST_INTER); 4115 %} 4116 4117 operand immIOffset4() 4118 %{ 4119 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4120 match(ConI); 4121 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125 %} 4126 4127 operand immIOffset8() 4128 %{ 4129 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4130 match(ConI); 4131 4132 op_cost(0); 4133 format %{ %} 4134 interface(CONST_INTER); 4135 %} 4136 4137 operand immIOffset16() 4138 %{ 4139 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4140 match(ConI); 4141 4142 op_cost(0); 4143 format %{ %} 4144 interface(CONST_INTER); 4145 %} 4146 4147 operand immLoffset() 4148 %{ 4149 predicate(Address::offset_ok_for_immed(n->get_long())); 4150 match(ConL); 4151 4152 op_cost(0); 4153 format %{ %} 4154 interface(CONST_INTER); 4155 %} 4156 4157 operand immLoffset4() 4158 %{ 4159 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4160 match(ConL); 4161 4162 op_cost(0); 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 operand immLoffset8() 4168 %{ 4169 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4170 match(ConL); 4171 4172 op_cost(0); 4173 format %{ %} 4174 interface(CONST_INTER); 4175 %} 4176 4177 operand immLoffset16() 4178 %{ 4179 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4180 match(ConL); 4181 4182 op_cost(0); 4183 format %{ %} 4184 interface(CONST_INTER); 4185 %} 4186 4187 // 32 bit integer valid for add sub immediate 4188 operand immIAddSub() 4189 %{ 4190 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4191 match(ConI); 4192 op_cost(0); 4193 format %{ %} 4194 interface(CONST_INTER); 4195 %} 4196 4197 // 32 bit unsigned integer valid for logical immediate 4198 // TODO -- check this is right when e.g the mask is 0x80000000 4199 operand immILog() 4200 %{ 4201 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4202 match(ConI); 4203 4204 op_cost(0); 4205 format %{ %} 4206 interface(CONST_INTER); 4207 %} 4208 4209 // Integer operands 64 bit 4210 // 64 bit immediate 4211 operand immL() 4212 %{ 4213 match(ConL); 4214 4215 op_cost(0); 4216 format %{ %} 4217 interface(CONST_INTER); 4218 %} 4219 4220 // 64 bit zero 4221 operand immL0() 4222 %{ 4223 predicate(n->get_long() == 0); 4224 match(ConL); 4225 4226 op_cost(0); 4227 format %{ %} 4228 interface(CONST_INTER); 4229 %} 4230 4231 // 64 bit unit increment 4232 operand immL_1() 4233 %{ 4234 predicate(n->get_long() == 1); 4235 match(ConL); 4236 4237 op_cost(0); 4238 format %{ %} 4239 interface(CONST_INTER); 4240 %} 4241 4242 // 64 bit unit decrement 4243 operand immL_M1() 4244 %{ 4245 predicate(n->get_long() == -1); 4246 match(ConL); 4247 4248 op_cost(0); 4249 format %{ %} 4250 interface(CONST_INTER); 4251 %} 4252 4253 // 32 bit offset of pc in thread anchor 4254 4255 operand immL_pc_off() 4256 %{ 4257 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4258 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4259 match(ConL); 4260 4261 op_cost(0); 4262 format %{ %} 4263 interface(CONST_INTER); 4264 %} 4265 4266 // 64 bit integer valid for add sub immediate 4267 operand immLAddSub() 4268 %{ 4269 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4270 match(ConL); 4271 op_cost(0); 4272 format %{ %} 4273 interface(CONST_INTER); 4274 %} 4275 4276 // 64 bit integer valid for logical immediate 4277 operand immLLog() 4278 %{ 4279 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4280 match(ConL); 4281 op_cost(0); 4282 format %{ %} 4283 interface(CONST_INTER); 4284 %} 4285 4286 // Long Immediate: low 32-bit mask 4287 operand immL_32bits() 4288 %{ 4289 predicate(n->get_long() == 0xFFFFFFFFL); 4290 match(ConL); 4291 op_cost(0); 4292 format %{ %} 4293 interface(CONST_INTER); 4294 %} 4295 4296 // Pointer operands 4297 // Pointer Immediate 4298 operand immP() 4299 %{ 4300 match(ConP); 4301 4302 op_cost(0); 4303 format %{ %} 4304 interface(CONST_INTER); 4305 %} 4306 4307 // NULL Pointer Immediate 4308 operand immP0() 4309 %{ 4310 predicate(n->get_ptr() == 0); 4311 match(ConP); 4312 4313 op_cost(0); 4314 format %{ %} 4315 interface(CONST_INTER); 4316 %} 4317 4318 // Pointer Immediate One 4319 // this is used in object initialization (initial object header) 4320 operand immP_1() 4321 %{ 4322 predicate(n->get_ptr() == 1); 4323 match(ConP); 4324 4325 op_cost(0); 4326 format %{ %} 4327 interface(CONST_INTER); 4328 %} 4329 4330 // Polling Page Pointer Immediate 4331 operand immPollPage() 4332 %{ 4333 predicate((address)n->get_ptr() == os::get_polling_page()); 4334 match(ConP); 4335 4336 op_cost(0); 4337 format %{ %} 4338 interface(CONST_INTER); 4339 %} 4340 4341 // Card Table Byte Map Base 4342 operand immByteMapBase() 4343 %{ 4344 // Get base of card map 4345 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4346 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4347 match(ConP); 4348 4349 op_cost(0); 4350 format %{ %} 4351 interface(CONST_INTER); 4352 %} 4353 4354 // Pointer Immediate Minus One 4355 // this is used when we want to write the current PC to the thread anchor 4356 operand immP_M1() 4357 %{ 4358 predicate(n->get_ptr() == -1); 4359 match(ConP); 4360 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // Pointer Immediate Minus Two 4367 // this is used when we want to write the current PC to the thread anchor 4368 operand immP_M2() 4369 %{ 4370 predicate(n->get_ptr() == -2); 4371 match(ConP); 4372 4373 op_cost(0); 4374 format %{ %} 4375 interface(CONST_INTER); 4376 %} 4377 4378 // Float and Double operands 4379 // Double Immediate 4380 operand immD() 4381 %{ 4382 match(ConD); 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // Double Immediate: +0.0d 4389 operand immD0() 4390 %{ 4391 predicate(jlong_cast(n->getd()) == 0); 4392 match(ConD); 4393 4394 op_cost(0); 4395 format %{ %} 4396 interface(CONST_INTER); 4397 %} 4398 4399 // constant 'double +0.0'. 4400 operand immDPacked() 4401 %{ 4402 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4403 match(ConD); 4404 op_cost(0); 4405 format %{ %} 4406 interface(CONST_INTER); 4407 %} 4408 4409 // Float Immediate 4410 operand immF() 4411 %{ 4412 match(ConF); 4413 op_cost(0); 4414 format %{ %} 4415 interface(CONST_INTER); 4416 %} 4417 4418 // Float Immediate: +0.0f. 4419 operand immF0() 4420 %{ 4421 predicate(jint_cast(n->getf()) == 0); 4422 match(ConF); 4423 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // 4430 operand immFPacked() 4431 %{ 4432 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4433 match(ConF); 4434 op_cost(0); 4435 format %{ %} 4436 interface(CONST_INTER); 4437 %} 4438 4439 // Narrow pointer operands 4440 // Narrow Pointer Immediate 4441 operand immN() 4442 %{ 4443 match(ConN); 4444 4445 op_cost(0); 4446 format %{ %} 4447 interface(CONST_INTER); 4448 %} 4449 4450 // Narrow NULL Pointer Immediate 4451 operand immN0() 4452 %{ 4453 predicate(n->get_narrowcon() == 0); 4454 match(ConN); 4455 4456 op_cost(0); 4457 format %{ %} 4458 interface(CONST_INTER); 4459 %} 4460 4461 operand immNKlass() 4462 %{ 4463 match(ConNKlass); 4464 4465 op_cost(0); 4466 format %{ %} 4467 interface(CONST_INTER); 4468 %} 4469 4470 // Integer 32 bit Register Operands 4471 // Integer 32 bitRegister (excludes SP) 4472 operand iRegI() 4473 %{ 4474 constraint(ALLOC_IN_RC(any_reg32)); 4475 match(RegI); 4476 match(iRegINoSp); 4477 op_cost(0); 4478 format %{ %} 4479 interface(REG_INTER); 4480 %} 4481 4482 // Integer 32 bit Register not Special 4483 operand iRegINoSp() 4484 %{ 4485 constraint(ALLOC_IN_RC(no_special_reg32)); 4486 match(RegI); 4487 op_cost(0); 4488 format %{ %} 4489 interface(REG_INTER); 4490 %} 4491 4492 // Integer 64 bit Register Operands 4493 // Integer 64 bit Register (includes SP) 4494 operand iRegL() 4495 %{ 4496 constraint(ALLOC_IN_RC(any_reg)); 4497 match(RegL); 4498 match(iRegLNoSp); 4499 op_cost(0); 4500 format %{ %} 4501 interface(REG_INTER); 4502 %} 4503 4504 // Integer 64 bit Register not Special 4505 operand iRegLNoSp() 4506 %{ 4507 constraint(ALLOC_IN_RC(no_special_reg)); 4508 match(RegL); 4509 match(iRegL_R0); 4510 format %{ %} 4511 interface(REG_INTER); 4512 %} 4513 4514 // Pointer Register Operands 4515 // Pointer Register 4516 operand iRegP() 4517 %{ 4518 constraint(ALLOC_IN_RC(ptr_reg)); 4519 match(RegP); 4520 match(iRegPNoSp); 4521 match(iRegP_R0); 4522 //match(iRegP_R2); 4523 //match(iRegP_R4); 4524 //match(iRegP_R5); 4525 match(thread_RegP); 4526 op_cost(0); 4527 format %{ %} 4528 interface(REG_INTER); 4529 %} 4530 4531 // Pointer 64 bit Register not Special 4532 operand iRegPNoSp() 4533 %{ 4534 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4535 match(RegP); 4536 // match(iRegP); 4537 // match(iRegP_R0); 4538 // match(iRegP_R2); 4539 // match(iRegP_R4); 4540 // match(iRegP_R5); 4541 // match(thread_RegP); 4542 op_cost(0); 4543 format %{ %} 4544 interface(REG_INTER); 4545 %} 4546 4547 // Pointer 64 bit Register R0 only 4548 operand iRegP_R0() 4549 %{ 4550 constraint(ALLOC_IN_RC(r0_reg)); 4551 match(RegP); 4552 // match(iRegP); 4553 match(iRegPNoSp); 4554 op_cost(0); 4555 format %{ %} 4556 interface(REG_INTER); 4557 %} 4558 4559 // Pointer 64 bit Register R1 only 4560 operand iRegP_R1() 4561 %{ 4562 constraint(ALLOC_IN_RC(r1_reg)); 4563 match(RegP); 4564 // match(iRegP); 4565 match(iRegPNoSp); 4566 op_cost(0); 4567 format %{ %} 4568 interface(REG_INTER); 4569 %} 4570 4571 // Pointer 64 bit Register R2 only 4572 operand iRegP_R2() 4573 %{ 4574 constraint(ALLOC_IN_RC(r2_reg)); 4575 match(RegP); 4576 // match(iRegP); 4577 match(iRegPNoSp); 4578 op_cost(0); 4579 format %{ %} 4580 interface(REG_INTER); 4581 %} 4582 4583 // Pointer 64 bit Register R3 only 4584 operand iRegP_R3() 4585 %{ 4586 constraint(ALLOC_IN_RC(r3_reg)); 4587 match(RegP); 4588 // match(iRegP); 4589 match(iRegPNoSp); 4590 op_cost(0); 4591 format %{ %} 4592 interface(REG_INTER); 4593 %} 4594 4595 // Pointer 64 bit Register R4 only 4596 operand iRegP_R4() 4597 %{ 4598 constraint(ALLOC_IN_RC(r4_reg)); 4599 match(RegP); 4600 // match(iRegP); 4601 match(iRegPNoSp); 4602 op_cost(0); 4603 format %{ %} 4604 interface(REG_INTER); 4605 %} 4606 4607 // Pointer 64 bit Register R5 only 4608 operand iRegP_R5() 4609 %{ 4610 constraint(ALLOC_IN_RC(r5_reg)); 4611 match(RegP); 4612 // match(iRegP); 4613 match(iRegPNoSp); 4614 op_cost(0); 4615 format %{ %} 4616 interface(REG_INTER); 4617 %} 4618 4619 // Pointer 64 bit Register R10 only 4620 operand iRegP_R10() 4621 %{ 4622 constraint(ALLOC_IN_RC(r10_reg)); 4623 match(RegP); 4624 // match(iRegP); 4625 match(iRegPNoSp); 4626 op_cost(0); 4627 format %{ %} 4628 interface(REG_INTER); 4629 %} 4630 4631 // Long 64 bit Register R0 only 4632 operand iRegL_R0() 4633 %{ 4634 constraint(ALLOC_IN_RC(r0_reg)); 4635 match(RegL); 4636 match(iRegLNoSp); 4637 op_cost(0); 4638 format %{ %} 4639 interface(REG_INTER); 4640 %} 4641 4642 // Long 64 bit Register R2 only 4643 operand iRegL_R2() 4644 %{ 4645 constraint(ALLOC_IN_RC(r2_reg)); 4646 match(RegL); 4647 match(iRegLNoSp); 4648 op_cost(0); 4649 format %{ %} 4650 interface(REG_INTER); 4651 %} 4652 4653 // Long 64 bit Register R3 only 4654 operand iRegL_R3() 4655 %{ 4656 constraint(ALLOC_IN_RC(r3_reg)); 4657 match(RegL); 4658 match(iRegLNoSp); 4659 op_cost(0); 4660 format %{ %} 4661 interface(REG_INTER); 4662 %} 4663 4664 // Long 64 bit Register R11 only 4665 operand iRegL_R11() 4666 %{ 4667 constraint(ALLOC_IN_RC(r11_reg)); 4668 match(RegL); 4669 match(iRegLNoSp); 4670 op_cost(0); 4671 format %{ %} 4672 interface(REG_INTER); 4673 %} 4674 4675 // Pointer 64 bit Register FP only 4676 operand iRegP_FP() 4677 %{ 4678 constraint(ALLOC_IN_RC(fp_reg)); 4679 match(RegP); 4680 // match(iRegP); 4681 op_cost(0); 4682 format %{ %} 4683 interface(REG_INTER); 4684 %} 4685 4686 // Register R0 only 4687 operand iRegI_R0() 4688 %{ 4689 constraint(ALLOC_IN_RC(int_r0_reg)); 4690 match(RegI); 4691 match(iRegINoSp); 4692 op_cost(0); 4693 format %{ %} 4694 interface(REG_INTER); 4695 %} 4696 4697 // Register R2 only 4698 operand iRegI_R2() 4699 %{ 4700 constraint(ALLOC_IN_RC(int_r2_reg)); 4701 match(RegI); 4702 match(iRegINoSp); 4703 op_cost(0); 4704 format %{ %} 4705 interface(REG_INTER); 4706 %} 4707 4708 // Register R3 only 4709 operand iRegI_R3() 4710 %{ 4711 constraint(ALLOC_IN_RC(int_r3_reg)); 4712 match(RegI); 4713 match(iRegINoSp); 4714 op_cost(0); 4715 format %{ %} 4716 interface(REG_INTER); 4717 %} 4718 4719 4720 // Register R4 only 4721 operand iRegI_R4() 4722 %{ 4723 constraint(ALLOC_IN_RC(int_r4_reg)); 4724 match(RegI); 4725 match(iRegINoSp); 4726 op_cost(0); 4727 format %{ %} 4728 interface(REG_INTER); 4729 %} 4730 4731 4732 // Pointer Register Operands 4733 // Narrow Pointer Register 4734 operand iRegN() 4735 %{ 4736 constraint(ALLOC_IN_RC(any_reg32)); 4737 match(RegN); 4738 match(iRegNNoSp); 4739 op_cost(0); 4740 format %{ %} 4741 interface(REG_INTER); 4742 %} 4743 4744 operand iRegN_R0() 4745 %{ 4746 constraint(ALLOC_IN_RC(r0_reg)); 4747 match(iRegN); 4748 op_cost(0); 4749 format %{ %} 4750 interface(REG_INTER); 4751 %} 4752 4753 operand iRegN_R2() 4754 %{ 4755 constraint(ALLOC_IN_RC(r2_reg)); 4756 match(iRegN); 4757 op_cost(0); 4758 format %{ %} 4759 interface(REG_INTER); 4760 %} 4761 4762 operand iRegN_R3() 4763 %{ 4764 constraint(ALLOC_IN_RC(r3_reg)); 4765 match(iRegN); 4766 op_cost(0); 4767 format %{ %} 4768 interface(REG_INTER); 4769 %} 4770 4771 // Integer 64 bit Register not Special 4772 operand iRegNNoSp() 4773 %{ 4774 constraint(ALLOC_IN_RC(no_special_reg32)); 4775 match(RegN); 4776 op_cost(0); 4777 format %{ %} 4778 interface(REG_INTER); 4779 %} 4780 4781 // heap base register -- used for encoding immN0 4782 4783 operand iRegIHeapbase() 4784 %{ 4785 constraint(ALLOC_IN_RC(heapbase_reg)); 4786 match(RegI); 4787 op_cost(0); 4788 format %{ %} 4789 interface(REG_INTER); 4790 %} 4791 4792 // Float Register 4793 // Float register operands 4794 operand vRegF() 4795 %{ 4796 constraint(ALLOC_IN_RC(float_reg)); 4797 match(RegF); 4798 4799 op_cost(0); 4800 format %{ %} 4801 interface(REG_INTER); 4802 %} 4803 4804 // Double Register 4805 // Double register operands 4806 operand vRegD() 4807 %{ 4808 constraint(ALLOC_IN_RC(double_reg)); 4809 match(RegD); 4810 4811 op_cost(0); 4812 format %{ %} 4813 interface(REG_INTER); 4814 %} 4815 4816 operand vecD() 4817 %{ 4818 constraint(ALLOC_IN_RC(vectord_reg)); 4819 match(VecD); 4820 4821 op_cost(0); 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 operand vecX() 4827 %{ 4828 constraint(ALLOC_IN_RC(vectorx_reg)); 4829 match(VecX); 4830 4831 op_cost(0); 4832 format %{ %} 4833 interface(REG_INTER); 4834 %} 4835 4836 operand vRegD_V0() 4837 %{ 4838 constraint(ALLOC_IN_RC(v0_reg)); 4839 match(RegD); 4840 op_cost(0); 4841 format %{ %} 4842 interface(REG_INTER); 4843 %} 4844 4845 operand vRegD_V1() 4846 %{ 4847 constraint(ALLOC_IN_RC(v1_reg)); 4848 match(RegD); 4849 op_cost(0); 4850 format %{ %} 4851 interface(REG_INTER); 4852 %} 4853 4854 operand vRegD_V2() 4855 %{ 4856 constraint(ALLOC_IN_RC(v2_reg)); 4857 match(RegD); 4858 op_cost(0); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 operand vRegD_V3() 4864 %{ 4865 constraint(ALLOC_IN_RC(v3_reg)); 4866 match(RegD); 4867 op_cost(0); 4868 format %{ %} 4869 interface(REG_INTER); 4870 %} 4871 4872 // Flags register, used as output of signed compare instructions 4873 4874 // note that on AArch64 we also use this register as the output for 4875 // for floating point compare instructions (CmpF CmpD). this ensures 4876 // that ordered inequality tests use GT, GE, LT or LE none of which 4877 // pass through cases where the result is unordered i.e. one or both 4878 // inputs to the compare is a NaN. this means that the ideal code can 4879 // replace e.g. a GT with an LE and not end up capturing the NaN case 4880 // (where the comparison should always fail). EQ and NE tests are 4881 // always generated in ideal code so that unordered folds into the NE 4882 // case, matching the behaviour of AArch64 NE. 4883 // 4884 // This differs from x86 where the outputs of FP compares use a 4885 // special FP flags registers and where compares based on this 4886 // register are distinguished into ordered inequalities (cmpOpUCF) and 4887 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4888 // to explicitly handle the unordered case in branches. x86 also has 4889 // to include extra CMoveX rules to accept a cmpOpUCF input. 4890 4891 operand rFlagsReg() 4892 %{ 4893 constraint(ALLOC_IN_RC(int_flags)); 4894 match(RegFlags); 4895 4896 op_cost(0); 4897 format %{ "RFLAGS" %} 4898 interface(REG_INTER); 4899 %} 4900 4901 // Flags register, used as output of unsigned compare instructions 4902 operand rFlagsRegU() 4903 %{ 4904 constraint(ALLOC_IN_RC(int_flags)); 4905 match(RegFlags); 4906 4907 op_cost(0); 4908 format %{ "RFLAGSU" %} 4909 interface(REG_INTER); 4910 %} 4911 4912 // Special Registers 4913 4914 // Method Register 4915 operand inline_cache_RegP(iRegP reg) 4916 %{ 4917 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4918 match(reg); 4919 match(iRegPNoSp); 4920 op_cost(0); 4921 format %{ %} 4922 interface(REG_INTER); 4923 %} 4924 4925 operand interpreter_method_oop_RegP(iRegP reg) 4926 %{ 4927 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4928 match(reg); 4929 match(iRegPNoSp); 4930 op_cost(0); 4931 format %{ %} 4932 interface(REG_INTER); 4933 %} 4934 4935 // Thread Register 4936 operand thread_RegP(iRegP reg) 4937 %{ 4938 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4939 match(reg); 4940 op_cost(0); 4941 format %{ %} 4942 interface(REG_INTER); 4943 %} 4944 4945 operand lr_RegP(iRegP reg) 4946 %{ 4947 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4948 match(reg); 4949 op_cost(0); 4950 format %{ %} 4951 interface(REG_INTER); 4952 %} 4953 4954 //----------Memory Operands---------------------------------------------------- 4955 4956 operand indirect(iRegP reg) 4957 %{ 4958 constraint(ALLOC_IN_RC(ptr_reg)); 4959 match(reg); 4960 op_cost(0); 4961 format %{ "[$reg]" %} 4962 interface(MEMORY_INTER) %{ 4963 base($reg); 4964 index(0xffffffff); 4965 scale(0x0); 4966 disp(0x0); 4967 %} 4968 %} 4969 4970 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4971 %{ 4972 constraint(ALLOC_IN_RC(ptr_reg)); 4973 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4974 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4975 op_cost(0); 4976 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4977 interface(MEMORY_INTER) %{ 4978 base($reg); 4979 index($ireg); 4980 scale($scale); 4981 disp(0x0); 4982 %} 4983 %} 4984 4985 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4986 %{ 4987 constraint(ALLOC_IN_RC(ptr_reg)); 4988 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4989 match(AddP reg (LShiftL lreg scale)); 4990 op_cost(0); 4991 format %{ "$reg, $lreg lsl($scale)" %} 4992 interface(MEMORY_INTER) %{ 4993 base($reg); 4994 index($lreg); 4995 scale($scale); 4996 disp(0x0); 4997 %} 4998 %} 4999 5000 operand indIndexI2L(iRegP reg, iRegI ireg) 5001 %{ 5002 constraint(ALLOC_IN_RC(ptr_reg)); 5003 match(AddP reg (ConvI2L ireg)); 5004 op_cost(0); 5005 format %{ "$reg, $ireg, 0, I2L" %} 5006 interface(MEMORY_INTER) %{ 5007 base($reg); 5008 index($ireg); 5009 scale(0x0); 5010 disp(0x0); 5011 %} 5012 %} 5013 5014 operand indIndex(iRegP reg, iRegL lreg) 5015 %{ 5016 constraint(ALLOC_IN_RC(ptr_reg)); 5017 match(AddP reg lreg); 5018 op_cost(0); 5019 format %{ "$reg, $lreg" %} 5020 interface(MEMORY_INTER) %{ 5021 base($reg); 5022 index($lreg); 5023 scale(0x0); 5024 disp(0x0); 5025 %} 5026 %} 5027 5028 operand indOffI(iRegP reg, immIOffset off) 5029 %{ 5030 constraint(ALLOC_IN_RC(ptr_reg)); 5031 match(AddP reg off); 5032 op_cost(0); 5033 format %{ "[$reg, $off]" %} 5034 interface(MEMORY_INTER) %{ 5035 base($reg); 5036 index(0xffffffff); 5037 scale(0x0); 5038 disp($off); 5039 %} 5040 %} 5041 5042 operand indOffI4(iRegP reg, immIOffset4 off) 5043 %{ 5044 constraint(ALLOC_IN_RC(ptr_reg)); 5045 match(AddP reg off); 5046 op_cost(0); 5047 format %{ "[$reg, $off]" %} 5048 interface(MEMORY_INTER) %{ 5049 base($reg); 5050 index(0xffffffff); 5051 scale(0x0); 5052 disp($off); 5053 %} 5054 %} 5055 5056 operand indOffI8(iRegP reg, immIOffset8 off) 5057 %{ 5058 constraint(ALLOC_IN_RC(ptr_reg)); 5059 match(AddP reg off); 5060 op_cost(0); 5061 format %{ "[$reg, $off]" %} 5062 interface(MEMORY_INTER) %{ 5063 base($reg); 5064 index(0xffffffff); 5065 scale(0x0); 5066 disp($off); 5067 %} 5068 %} 5069 5070 operand indOffI16(iRegP reg, immIOffset16 off) 5071 %{ 5072 constraint(ALLOC_IN_RC(ptr_reg)); 5073 match(AddP reg off); 5074 op_cost(0); 5075 format %{ "[$reg, $off]" %} 5076 interface(MEMORY_INTER) %{ 5077 base($reg); 5078 index(0xffffffff); 5079 scale(0x0); 5080 disp($off); 5081 %} 5082 %} 5083 5084 operand indOffL(iRegP reg, immLoffset off) 5085 %{ 5086 constraint(ALLOC_IN_RC(ptr_reg)); 5087 match(AddP reg off); 5088 op_cost(0); 5089 format %{ "[$reg, $off]" %} 5090 interface(MEMORY_INTER) %{ 5091 base($reg); 5092 index(0xffffffff); 5093 scale(0x0); 5094 disp($off); 5095 %} 5096 %} 5097 5098 operand indOffL4(iRegP reg, immLoffset4 off) 5099 %{ 5100 constraint(ALLOC_IN_RC(ptr_reg)); 5101 match(AddP reg off); 5102 op_cost(0); 5103 format %{ "[$reg, $off]" %} 5104 interface(MEMORY_INTER) %{ 5105 base($reg); 5106 index(0xffffffff); 5107 scale(0x0); 5108 disp($off); 5109 %} 5110 %} 5111 5112 operand indOffL8(iRegP reg, immLoffset8 off) 5113 %{ 5114 constraint(ALLOC_IN_RC(ptr_reg)); 5115 match(AddP reg off); 5116 op_cost(0); 5117 format %{ "[$reg, $off]" %} 5118 interface(MEMORY_INTER) %{ 5119 base($reg); 5120 index(0xffffffff); 5121 scale(0x0); 5122 disp($off); 5123 %} 5124 %} 5125 5126 operand indOffL16(iRegP reg, immLoffset16 off) 5127 %{ 5128 constraint(ALLOC_IN_RC(ptr_reg)); 5129 match(AddP reg off); 5130 op_cost(0); 5131 format %{ "[$reg, $off]" %} 5132 interface(MEMORY_INTER) %{ 5133 base($reg); 5134 index(0xffffffff); 5135 scale(0x0); 5136 disp($off); 5137 %} 5138 %} 5139 5140 operand indirectN(iRegN reg) 5141 %{ 5142 predicate(Universe::narrow_oop_shift() == 0); 5143 constraint(ALLOC_IN_RC(ptr_reg)); 5144 match(DecodeN reg); 5145 op_cost(0); 5146 format %{ "[$reg]\t# narrow" %} 5147 interface(MEMORY_INTER) %{ 5148 base($reg); 5149 index(0xffffffff); 5150 scale(0x0); 5151 disp(0x0); 5152 %} 5153 %} 5154 5155 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5156 %{ 5157 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5158 constraint(ALLOC_IN_RC(ptr_reg)); 5159 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5160 op_cost(0); 5161 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5162 interface(MEMORY_INTER) %{ 5163 base($reg); 5164 index($ireg); 5165 scale($scale); 5166 disp(0x0); 5167 %} 5168 %} 5169 5170 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5171 %{ 5172 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5173 constraint(ALLOC_IN_RC(ptr_reg)); 5174 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5175 op_cost(0); 5176 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5177 interface(MEMORY_INTER) %{ 5178 base($reg); 5179 index($lreg); 5180 scale($scale); 5181 disp(0x0); 5182 %} 5183 %} 5184 5185 operand indIndexI2LN(iRegN reg, iRegI ireg) 5186 %{ 5187 predicate(Universe::narrow_oop_shift() == 0); 5188 constraint(ALLOC_IN_RC(ptr_reg)); 5189 match(AddP (DecodeN reg) (ConvI2L ireg)); 5190 op_cost(0); 5191 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5192 interface(MEMORY_INTER) %{ 5193 base($reg); 5194 index($ireg); 5195 scale(0x0); 5196 disp(0x0); 5197 %} 5198 %} 5199 5200 operand indIndexN(iRegN reg, iRegL lreg) 5201 %{ 5202 predicate(Universe::narrow_oop_shift() == 0); 5203 constraint(ALLOC_IN_RC(ptr_reg)); 5204 match(AddP (DecodeN reg) lreg); 5205 op_cost(0); 5206 format %{ "$reg, $lreg\t# narrow" %} 5207 interface(MEMORY_INTER) %{ 5208 base($reg); 5209 index($lreg); 5210 scale(0x0); 5211 disp(0x0); 5212 %} 5213 %} 5214 5215 operand indOffIN(iRegN reg, immIOffset off) 5216 %{ 5217 predicate(Universe::narrow_oop_shift() == 0); 5218 constraint(ALLOC_IN_RC(ptr_reg)); 5219 match(AddP (DecodeN reg) off); 5220 op_cost(0); 5221 format %{ "[$reg, $off]\t# narrow" %} 5222 interface(MEMORY_INTER) %{ 5223 base($reg); 5224 index(0xffffffff); 5225 scale(0x0); 5226 disp($off); 5227 %} 5228 %} 5229 5230 operand indOffLN(iRegN reg, immLoffset off) 5231 %{ 5232 predicate(Universe::narrow_oop_shift() == 0); 5233 constraint(ALLOC_IN_RC(ptr_reg)); 5234 match(AddP (DecodeN reg) off); 5235 op_cost(0); 5236 format %{ "[$reg, $off]\t# narrow" %} 5237 interface(MEMORY_INTER) %{ 5238 base($reg); 5239 index(0xffffffff); 5240 scale(0x0); 5241 disp($off); 5242 %} 5243 %} 5244 5245 5246 5247 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5248 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5249 %{ 5250 constraint(ALLOC_IN_RC(ptr_reg)); 5251 match(AddP reg off); 5252 op_cost(0); 5253 format %{ "[$reg, $off]" %} 5254 interface(MEMORY_INTER) %{ 5255 base($reg); 5256 index(0xffffffff); 5257 scale(0x0); 5258 disp($off); 5259 %} 5260 %} 5261 5262 //----------Special Memory Operands-------------------------------------------- 5263 // Stack Slot Operand - This operand is used for loading and storing temporary 5264 // values on the stack where a match requires a value to 5265 // flow through memory. 5266 operand stackSlotP(sRegP reg) 5267 %{ 5268 constraint(ALLOC_IN_RC(stack_slots)); 5269 op_cost(100); 5270 // No match rule because this operand is only generated in matching 5271 // match(RegP); 5272 format %{ "[$reg]" %} 5273 interface(MEMORY_INTER) %{ 5274 base(0x1e); // RSP 5275 index(0x0); // No Index 5276 scale(0x0); // No Scale 5277 disp($reg); // Stack Offset 5278 %} 5279 %} 5280 5281 operand stackSlotI(sRegI reg) 5282 %{ 5283 constraint(ALLOC_IN_RC(stack_slots)); 5284 // No match rule because this operand is only generated in matching 5285 // match(RegI); 5286 format %{ "[$reg]" %} 5287 interface(MEMORY_INTER) %{ 5288 base(0x1e); // RSP 5289 index(0x0); // No Index 5290 scale(0x0); // No Scale 5291 disp($reg); // Stack Offset 5292 %} 5293 %} 5294 5295 operand stackSlotF(sRegF reg) 5296 %{ 5297 constraint(ALLOC_IN_RC(stack_slots)); 5298 // No match rule because this operand is only generated in matching 5299 // match(RegF); 5300 format %{ "[$reg]" %} 5301 interface(MEMORY_INTER) %{ 5302 base(0x1e); // RSP 5303 index(0x0); // No Index 5304 scale(0x0); // No Scale 5305 disp($reg); // Stack Offset 5306 %} 5307 %} 5308 5309 operand stackSlotD(sRegD reg) 5310 %{ 5311 constraint(ALLOC_IN_RC(stack_slots)); 5312 // No match rule because this operand is only generated in matching 5313 // match(RegD); 5314 format %{ "[$reg]" %} 5315 interface(MEMORY_INTER) %{ 5316 base(0x1e); // RSP 5317 index(0x0); // No Index 5318 scale(0x0); // No Scale 5319 disp($reg); // Stack Offset 5320 %} 5321 %} 5322 5323 operand stackSlotL(sRegL reg) 5324 %{ 5325 constraint(ALLOC_IN_RC(stack_slots)); 5326 // No match rule because this operand is only generated in matching 5327 // match(RegL); 5328 format %{ "[$reg]" %} 5329 interface(MEMORY_INTER) %{ 5330 base(0x1e); // RSP 5331 index(0x0); // No Index 5332 scale(0x0); // No Scale 5333 disp($reg); // Stack Offset 5334 %} 5335 %} 5336 5337 // Operands for expressing Control Flow 5338 // NOTE: Label is a predefined operand which should not be redefined in 5339 // the AD file. It is generically handled within the ADLC. 5340 5341 //----------Conditional Branch Operands---------------------------------------- 5342 // Comparison Op - This is the operation of the comparison, and is limited to 5343 // the following set of codes: 5344 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5345 // 5346 // Other attributes of the comparison, such as unsignedness, are specified 5347 // by the comparison instruction that sets a condition code flags register. 5348 // That result is represented by a flags operand whose subtype is appropriate 5349 // to the unsignedness (etc.) of the comparison. 5350 // 5351 // Later, the instruction which matches both the Comparison Op (a Bool) and 5352 // the flags (produced by the Cmp) specifies the coding of the comparison op 5353 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5354 5355 // used for signed integral comparisons and fp comparisons 5356 5357 operand cmpOp() 5358 %{ 5359 match(Bool); 5360 5361 format %{ "" %} 5362 interface(COND_INTER) %{ 5363 equal(0x0, "eq"); 5364 not_equal(0x1, "ne"); 5365 less(0xb, "lt"); 5366 greater_equal(0xa, "ge"); 5367 less_equal(0xd, "le"); 5368 greater(0xc, "gt"); 5369 overflow(0x6, "vs"); 5370 no_overflow(0x7, "vc"); 5371 %} 5372 %} 5373 5374 // used for unsigned integral comparisons 5375 5376 operand cmpOpU() 5377 %{ 5378 match(Bool); 5379 5380 format %{ "" %} 5381 interface(COND_INTER) %{ 5382 equal(0x0, "eq"); 5383 not_equal(0x1, "ne"); 5384 less(0x3, "lo"); 5385 greater_equal(0x2, "hs"); 5386 less_equal(0x9, "ls"); 5387 greater(0x8, "hi"); 5388 overflow(0x6, "vs"); 5389 no_overflow(0x7, "vc"); 5390 %} 5391 %} 5392 5393 // used for certain integral comparisons which can be 5394 // converted to cbxx or tbxx instructions 5395 5396 operand cmpOpEqNe() 5397 %{ 5398 match(Bool); 5399 match(CmpOp); 5400 op_cost(0); 5401 predicate(n->as_Bool()->_test._test == BoolTest::ne 5402 || n->as_Bool()->_test._test == BoolTest::eq); 5403 5404 format %{ "" %} 5405 interface(COND_INTER) %{ 5406 equal(0x0, "eq"); 5407 not_equal(0x1, "ne"); 5408 less(0xb, "lt"); 5409 greater_equal(0xa, "ge"); 5410 less_equal(0xd, "le"); 5411 greater(0xc, "gt"); 5412 overflow(0x6, "vs"); 5413 no_overflow(0x7, "vc"); 5414 %} 5415 %} 5416 5417 // used for certain integral comparisons which can be 5418 // converted to cbxx or tbxx instructions 5419 5420 operand cmpOpLtGe() 5421 %{ 5422 match(Bool); 5423 match(CmpOp); 5424 op_cost(0); 5425 5426 predicate(n->as_Bool()->_test._test == BoolTest::lt 5427 || n->as_Bool()->_test._test == BoolTest::ge); 5428 5429 format %{ "" %} 5430 interface(COND_INTER) %{ 5431 equal(0x0, "eq"); 5432 not_equal(0x1, "ne"); 5433 less(0xb, "lt"); 5434 greater_equal(0xa, "ge"); 5435 less_equal(0xd, "le"); 5436 greater(0xc, "gt"); 5437 overflow(0x6, "vs"); 5438 no_overflow(0x7, "vc"); 5439 %} 5440 %} 5441 5442 // used for certain unsigned integral comparisons which can be 5443 // converted to cbxx or tbxx instructions 5444 5445 operand cmpOpUEqNeLtGe() 5446 %{ 5447 match(Bool); 5448 match(CmpOp); 5449 op_cost(0); 5450 5451 predicate(n->as_Bool()->_test._test == BoolTest::eq 5452 || n->as_Bool()->_test._test == BoolTest::ne 5453 || n->as_Bool()->_test._test == BoolTest::lt 5454 || n->as_Bool()->_test._test == BoolTest::ge); 5455 5456 format %{ "" %} 5457 interface(COND_INTER) %{ 5458 equal(0x0, "eq"); 5459 not_equal(0x1, "ne"); 5460 less(0xb, "lt"); 5461 greater_equal(0xa, "ge"); 5462 less_equal(0xd, "le"); 5463 greater(0xc, "gt"); 5464 overflow(0x6, "vs"); 5465 no_overflow(0x7, "vc"); 5466 %} 5467 %} 5468 5469 // Special operand allowing long args to int ops to be truncated for free 5470 5471 operand iRegL2I(iRegL reg) %{ 5472 5473 op_cost(0); 5474 5475 match(ConvL2I reg); 5476 5477 format %{ "l2i($reg)" %} 5478 5479 interface(REG_INTER) 5480 %} 5481 5482 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5483 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5484 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5485 5486 //----------OPERAND CLASSES---------------------------------------------------- 5487 // Operand Classes are groups of operands that are used as to simplify 5488 // instruction definitions by not requiring the AD writer to specify 5489 // separate instructions for every form of operand when the 5490 // instruction accepts multiple operand types with the same basic 5491 // encoding and format. The classic case of this is memory operands. 5492 5493 // memory is used to define read/write location for load/store 5494 // instruction defs. we can turn a memory op into an Address 5495 5496 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5497 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5498 5499 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5500 // operations. it allows the src to be either an iRegI or a (ConvL2I 5501 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5502 // can be elided because the 32-bit instruction will just employ the 5503 // lower 32 bits anyway. 5504 // 5505 // n.b. this does not elide all L2I conversions. if the truncated 5506 // value is consumed by more than one operation then the ConvL2I 5507 // cannot be bundled into the consuming nodes so an l2i gets planted 5508 // (actually a movw $dst $src) and the downstream instructions consume 5509 // the result of the l2i as an iRegI input. That's a shame since the 5510 // movw is actually redundant but its not too costly. 5511 5512 opclass iRegIorL2I(iRegI, iRegL2I); 5513 5514 //----------PIPELINE----------------------------------------------------------- 5515 // Rules which define the behavior of the target architectures pipeline. 5516 5517 // For specific pipelines, eg A53, define the stages of that pipeline 5518 //pipe_desc(ISS, EX1, EX2, WR); 5519 #define ISS S0 5520 #define EX1 S1 5521 #define EX2 S2 5522 #define WR S3 5523 5524 // Integer ALU reg operation 5525 pipeline %{ 5526 5527 attributes %{ 5528 // ARM instructions are of fixed length 5529 fixed_size_instructions; // Fixed size instructions TODO does 5530 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5531 // ARM instructions come in 32-bit word units 5532 instruction_unit_size = 4; // An instruction is 4 bytes long 5533 instruction_fetch_unit_size = 64; // The processor fetches one line 5534 instruction_fetch_units = 1; // of 64 bytes 5535 5536 // List of nop instructions 5537 nops( MachNop ); 5538 %} 5539 5540 // We don't use an actual pipeline model so don't care about resources 5541 // or description. we do use pipeline classes to introduce fixed 5542 // latencies 5543 5544 //----------RESOURCES---------------------------------------------------------- 5545 // Resources are the functional units available to the machine 5546 5547 resources( INS0, INS1, INS01 = INS0 | INS1, 5548 ALU0, ALU1, ALU = ALU0 | ALU1, 5549 MAC, 5550 DIV, 5551 BRANCH, 5552 LDST, 5553 NEON_FP); 5554 5555 //----------PIPELINE DESCRIPTION----------------------------------------------- 5556 // Pipeline Description specifies the stages in the machine's pipeline 5557 5558 // Define the pipeline as a generic 6 stage pipeline 5559 pipe_desc(S0, S1, S2, S3, S4, S5); 5560 5561 //----------PIPELINE CLASSES--------------------------------------------------- 5562 // Pipeline Classes describe the stages in which input and output are 5563 // referenced by the hardware pipeline. 5564 5565 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5566 %{ 5567 single_instruction; 5568 src1 : S1(read); 5569 src2 : S2(read); 5570 dst : S5(write); 5571 INS01 : ISS; 5572 NEON_FP : S5; 5573 %} 5574 5575 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5576 %{ 5577 single_instruction; 5578 src1 : S1(read); 5579 src2 : S2(read); 5580 dst : S5(write); 5581 INS01 : ISS; 5582 NEON_FP : S5; 5583 %} 5584 5585 pipe_class fp_uop_s(vRegF dst, vRegF src) 5586 %{ 5587 single_instruction; 5588 src : S1(read); 5589 dst : S5(write); 5590 INS01 : ISS; 5591 NEON_FP : S5; 5592 %} 5593 5594 pipe_class fp_uop_d(vRegD dst, vRegD src) 5595 %{ 5596 single_instruction; 5597 src : S1(read); 5598 dst : S5(write); 5599 INS01 : ISS; 5600 NEON_FP : S5; 5601 %} 5602 5603 pipe_class fp_d2f(vRegF dst, vRegD src) 5604 %{ 5605 single_instruction; 5606 src : S1(read); 5607 dst : S5(write); 5608 INS01 : ISS; 5609 NEON_FP : S5; 5610 %} 5611 5612 pipe_class fp_f2d(vRegD dst, vRegF src) 5613 %{ 5614 single_instruction; 5615 src : S1(read); 5616 dst : S5(write); 5617 INS01 : ISS; 5618 NEON_FP : S5; 5619 %} 5620 5621 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5622 %{ 5623 single_instruction; 5624 src : S1(read); 5625 dst : S5(write); 5626 INS01 : ISS; 5627 NEON_FP : S5; 5628 %} 5629 5630 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5631 %{ 5632 single_instruction; 5633 src : S1(read); 5634 dst : S5(write); 5635 INS01 : ISS; 5636 NEON_FP : S5; 5637 %} 5638 5639 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5640 %{ 5641 single_instruction; 5642 src : S1(read); 5643 dst : S5(write); 5644 INS01 : ISS; 5645 NEON_FP : S5; 5646 %} 5647 5648 pipe_class fp_l2f(vRegF dst, iRegL src) 5649 %{ 5650 single_instruction; 5651 src : S1(read); 5652 dst : S5(write); 5653 INS01 : ISS; 5654 NEON_FP : S5; 5655 %} 5656 5657 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5658 %{ 5659 single_instruction; 5660 src : S1(read); 5661 dst : S5(write); 5662 INS01 : ISS; 5663 NEON_FP : S5; 5664 %} 5665 5666 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5667 %{ 5668 single_instruction; 5669 src : S1(read); 5670 dst : S5(write); 5671 INS01 : ISS; 5672 NEON_FP : S5; 5673 %} 5674 5675 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5676 %{ 5677 single_instruction; 5678 src : S1(read); 5679 dst : S5(write); 5680 INS01 : ISS; 5681 NEON_FP : S5; 5682 %} 5683 5684 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5685 %{ 5686 single_instruction; 5687 src : S1(read); 5688 dst : S5(write); 5689 INS01 : ISS; 5690 NEON_FP : S5; 5691 %} 5692 5693 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5694 %{ 5695 single_instruction; 5696 src1 : S1(read); 5697 src2 : S2(read); 5698 dst : S5(write); 5699 INS0 : ISS; 5700 NEON_FP : S5; 5701 %} 5702 5703 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5704 %{ 5705 single_instruction; 5706 src1 : S1(read); 5707 src2 : S2(read); 5708 dst : S5(write); 5709 INS0 : ISS; 5710 NEON_FP : S5; 5711 %} 5712 5713 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5714 %{ 5715 single_instruction; 5716 cr : S1(read); 5717 src1 : S1(read); 5718 src2 : S1(read); 5719 dst : S3(write); 5720 INS01 : ISS; 5721 NEON_FP : S3; 5722 %} 5723 5724 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5725 %{ 5726 single_instruction; 5727 cr : S1(read); 5728 src1 : S1(read); 5729 src2 : S1(read); 5730 dst : S3(write); 5731 INS01 : ISS; 5732 NEON_FP : S3; 5733 %} 5734 5735 pipe_class fp_imm_s(vRegF dst) 5736 %{ 5737 single_instruction; 5738 dst : S3(write); 5739 INS01 : ISS; 5740 NEON_FP : S3; 5741 %} 5742 5743 pipe_class fp_imm_d(vRegD dst) 5744 %{ 5745 single_instruction; 5746 dst : S3(write); 5747 INS01 : ISS; 5748 NEON_FP : S3; 5749 %} 5750 5751 pipe_class fp_load_constant_s(vRegF dst) 5752 %{ 5753 single_instruction; 5754 dst : S4(write); 5755 INS01 : ISS; 5756 NEON_FP : S4; 5757 %} 5758 5759 pipe_class fp_load_constant_d(vRegD dst) 5760 %{ 5761 single_instruction; 5762 dst : S4(write); 5763 INS01 : ISS; 5764 NEON_FP : S4; 5765 %} 5766 5767 pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5768 %{ 5769 single_instruction; 5770 dst : S5(write); 5771 src1 : S1(read); 5772 src2 : S1(read); 5773 INS01 : ISS; 5774 NEON_FP : S5; 5775 %} 5776 5777 pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5778 %{ 5779 single_instruction; 5780 dst : S5(write); 5781 src1 : S1(read); 5782 src2 : S1(read); 5783 INS0 : ISS; 5784 NEON_FP : S5; 5785 %} 5786 5787 pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5788 %{ 5789 single_instruction; 5790 dst : S5(write); 5791 src1 : S1(read); 5792 src2 : S1(read); 5793 dst : S1(read); 5794 INS01 : ISS; 5795 NEON_FP : S5; 5796 %} 5797 5798 pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5799 %{ 5800 single_instruction; 5801 dst : S5(write); 5802 src1 : S1(read); 5803 src2 : S1(read); 5804 dst : S1(read); 5805 INS0 : ISS; 5806 NEON_FP : S5; 5807 %} 5808 5809 pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5810 %{ 5811 single_instruction; 5812 dst : S4(write); 5813 src1 : S2(read); 5814 src2 : S2(read); 5815 INS01 : ISS; 5816 NEON_FP : S4; 5817 %} 5818 5819 pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5820 %{ 5821 single_instruction; 5822 dst : S4(write); 5823 src1 : S2(read); 5824 src2 : S2(read); 5825 INS0 : ISS; 5826 NEON_FP : S4; 5827 %} 5828 5829 pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5830 %{ 5831 single_instruction; 5832 dst : S3(write); 5833 src1 : S2(read); 5834 src2 : S2(read); 5835 INS01 : ISS; 5836 NEON_FP : S3; 5837 %} 5838 5839 pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5840 %{ 5841 single_instruction; 5842 dst : S3(write); 5843 src1 : S2(read); 5844 src2 : S2(read); 5845 INS0 : ISS; 5846 NEON_FP : S3; 5847 %} 5848 5849 pipe_class vshift64(vecD dst, vecD src, vecX shift) 5850 %{ 5851 single_instruction; 5852 dst : S3(write); 5853 src : S1(read); 5854 shift : S1(read); 5855 INS01 : ISS; 5856 NEON_FP : S3; 5857 %} 5858 5859 pipe_class vshift128(vecX dst, vecX src, vecX shift) 5860 %{ 5861 single_instruction; 5862 dst : S3(write); 5863 src : S1(read); 5864 shift : S1(read); 5865 INS0 : ISS; 5866 NEON_FP : S3; 5867 %} 5868 5869 pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5870 %{ 5871 single_instruction; 5872 dst : S3(write); 5873 src : S1(read); 5874 INS01 : ISS; 5875 NEON_FP : S3; 5876 %} 5877 5878 pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5879 %{ 5880 single_instruction; 5881 dst : S3(write); 5882 src : S1(read); 5883 INS0 : ISS; 5884 NEON_FP : S3; 5885 %} 5886 5887 pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5888 %{ 5889 single_instruction; 5890 dst : S5(write); 5891 src1 : S1(read); 5892 src2 : S1(read); 5893 INS01 : ISS; 5894 NEON_FP : S5; 5895 %} 5896 5897 pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5898 %{ 5899 single_instruction; 5900 dst : S5(write); 5901 src1 : S1(read); 5902 src2 : S1(read); 5903 INS0 : ISS; 5904 NEON_FP : S5; 5905 %} 5906 5907 pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5908 %{ 5909 single_instruction; 5910 dst : S5(write); 5911 src1 : S1(read); 5912 src2 : S1(read); 5913 INS0 : ISS; 5914 NEON_FP : S5; 5915 %} 5916 5917 pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5918 %{ 5919 single_instruction; 5920 dst : S5(write); 5921 src1 : S1(read); 5922 src2 : S1(read); 5923 INS0 : ISS; 5924 NEON_FP : S5; 5925 %} 5926 5927 pipe_class vsqrt_fp128(vecX dst, vecX src) 5928 %{ 5929 single_instruction; 5930 dst : S5(write); 5931 src : S1(read); 5932 INS0 : ISS; 5933 NEON_FP : S5; 5934 %} 5935 5936 pipe_class vunop_fp64(vecD dst, vecD src) 5937 %{ 5938 single_instruction; 5939 dst : S5(write); 5940 src : S1(read); 5941 INS01 : ISS; 5942 NEON_FP : S5; 5943 %} 5944 5945 pipe_class vunop_fp128(vecX dst, vecX src) 5946 %{ 5947 single_instruction; 5948 dst : S5(write); 5949 src : S1(read); 5950 INS0 : ISS; 5951 NEON_FP : S5; 5952 %} 5953 5954 pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5955 %{ 5956 single_instruction; 5957 dst : S3(write); 5958 src : S1(read); 5959 INS01 : ISS; 5960 NEON_FP : S3; 5961 %} 5962 5963 pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5964 %{ 5965 single_instruction; 5966 dst : S3(write); 5967 src : S1(read); 5968 INS01 : ISS; 5969 NEON_FP : S3; 5970 %} 5971 5972 pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5973 %{ 5974 single_instruction; 5975 dst : S3(write); 5976 src : S1(read); 5977 INS01 : ISS; 5978 NEON_FP : S3; 5979 %} 5980 5981 pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5982 %{ 5983 single_instruction; 5984 dst : S3(write); 5985 src : S1(read); 5986 INS01 : ISS; 5987 NEON_FP : S3; 5988 %} 5989 5990 pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5991 %{ 5992 single_instruction; 5993 dst : S3(write); 5994 src : S1(read); 5995 INS01 : ISS; 5996 NEON_FP : S3; 5997 %} 5998 5999 pipe_class vmovi_reg_imm64(vecD dst) 6000 %{ 6001 single_instruction; 6002 dst : S3(write); 6003 INS01 : ISS; 6004 NEON_FP : S3; 6005 %} 6006 6007 pipe_class vmovi_reg_imm128(vecX dst) 6008 %{ 6009 single_instruction; 6010 dst : S3(write); 6011 INS0 : ISS; 6012 NEON_FP : S3; 6013 %} 6014 6015 pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6016 %{ 6017 single_instruction; 6018 dst : S5(write); 6019 mem : ISS(read); 6020 INS01 : ISS; 6021 NEON_FP : S3; 6022 %} 6023 6024 pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6025 %{ 6026 single_instruction; 6027 dst : S5(write); 6028 mem : ISS(read); 6029 INS01 : ISS; 6030 NEON_FP : S3; 6031 %} 6032 6033 pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6034 %{ 6035 single_instruction; 6036 mem : ISS(read); 6037 src : S2(read); 6038 INS01 : ISS; 6039 NEON_FP : S3; 6040 %} 6041 6042 pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6043 %{ 6044 single_instruction; 6045 mem : ISS(read); 6046 src : S2(read); 6047 INS01 : ISS; 6048 NEON_FP : S3; 6049 %} 6050 6051 //------- Integer ALU operations -------------------------- 6052 6053 // Integer ALU reg-reg operation 6054 // Operands needed in EX1, result generated in EX2 6055 // Eg. ADD x0, x1, x2 6056 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6057 %{ 6058 single_instruction; 6059 dst : EX2(write); 6060 src1 : EX1(read); 6061 src2 : EX1(read); 6062 INS01 : ISS; // Dual issue as instruction 0 or 1 6063 ALU : EX2; 6064 %} 6065 6066 // Integer ALU reg-reg operation with constant shift 6067 // Shifted register must be available in LATE_ISS instead of EX1 6068 // Eg. ADD x0, x1, x2, LSL #2 6069 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6070 %{ 6071 single_instruction; 6072 dst : EX2(write); 6073 src1 : EX1(read); 6074 src2 : ISS(read); 6075 INS01 : ISS; 6076 ALU : EX2; 6077 %} 6078 6079 // Integer ALU reg operation with constant shift 6080 // Eg. LSL x0, x1, #shift 6081 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6082 %{ 6083 single_instruction; 6084 dst : EX2(write); 6085 src1 : ISS(read); 6086 INS01 : ISS; 6087 ALU : EX2; 6088 %} 6089 6090 // Integer ALU reg-reg operation with variable shift 6091 // Both operands must be available in LATE_ISS instead of EX1 6092 // Result is available in EX1 instead of EX2 6093 // Eg. LSLV x0, x1, x2 6094 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6095 %{ 6096 single_instruction; 6097 dst : EX1(write); 6098 src1 : ISS(read); 6099 src2 : ISS(read); 6100 INS01 : ISS; 6101 ALU : EX1; 6102 %} 6103 6104 // Integer ALU reg-reg operation with extract 6105 // As for _vshift above, but result generated in EX2 6106 // Eg. EXTR x0, x1, x2, #N 6107 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6108 %{ 6109 single_instruction; 6110 dst : EX2(write); 6111 src1 : ISS(read); 6112 src2 : ISS(read); 6113 INS1 : ISS; // Can only dual issue as Instruction 1 6114 ALU : EX1; 6115 %} 6116 6117 // Integer ALU reg operation 6118 // Eg. NEG x0, x1 6119 pipe_class ialu_reg(iRegI dst, iRegI src) 6120 %{ 6121 single_instruction; 6122 dst : EX2(write); 6123 src : EX1(read); 6124 INS01 : ISS; 6125 ALU : EX2; 6126 %} 6127 6128 // Integer ALU reg mmediate operation 6129 // Eg. ADD x0, x1, #N 6130 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6131 %{ 6132 single_instruction; 6133 dst : EX2(write); 6134 src1 : EX1(read); 6135 INS01 : ISS; 6136 ALU : EX2; 6137 %} 6138 6139 // Integer ALU immediate operation (no source operands) 6140 // Eg. MOV x0, #N 6141 pipe_class ialu_imm(iRegI dst) 6142 %{ 6143 single_instruction; 6144 dst : EX1(write); 6145 INS01 : ISS; 6146 ALU : EX1; 6147 %} 6148 6149 //------- Compare operation ------------------------------- 6150 6151 // Compare reg-reg 6152 // Eg. CMP x0, x1 6153 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6154 %{ 6155 single_instruction; 6156 // fixed_latency(16); 6157 cr : EX2(write); 6158 op1 : EX1(read); 6159 op2 : EX1(read); 6160 INS01 : ISS; 6161 ALU : EX2; 6162 %} 6163 6164 // Compare reg-reg 6165 // Eg. CMP x0, #N 6166 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6167 %{ 6168 single_instruction; 6169 // fixed_latency(16); 6170 cr : EX2(write); 6171 op1 : EX1(read); 6172 INS01 : ISS; 6173 ALU : EX2; 6174 %} 6175 6176 //------- Conditional instructions ------------------------ 6177 6178 // Conditional no operands 6179 // Eg. CSINC x0, zr, zr, <cond> 6180 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6181 %{ 6182 single_instruction; 6183 cr : EX1(read); 6184 dst : EX2(write); 6185 INS01 : ISS; 6186 ALU : EX2; 6187 %} 6188 6189 // Conditional 2 operand 6190 // EG. CSEL X0, X1, X2, <cond> 6191 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6192 %{ 6193 single_instruction; 6194 cr : EX1(read); 6195 src1 : EX1(read); 6196 src2 : EX1(read); 6197 dst : EX2(write); 6198 INS01 : ISS; 6199 ALU : EX2; 6200 %} 6201 6202 // Conditional 2 operand 6203 // EG. CSEL X0, X1, X2, <cond> 6204 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6205 %{ 6206 single_instruction; 6207 cr : EX1(read); 6208 src : EX1(read); 6209 dst : EX2(write); 6210 INS01 : ISS; 6211 ALU : EX2; 6212 %} 6213 6214 //------- Multiply pipeline operations -------------------- 6215 6216 // Multiply reg-reg 6217 // Eg. MUL w0, w1, w2 6218 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6219 %{ 6220 single_instruction; 6221 dst : WR(write); 6222 src1 : ISS(read); 6223 src2 : ISS(read); 6224 INS01 : ISS; 6225 MAC : WR; 6226 %} 6227 6228 // Multiply accumulate 6229 // Eg. MADD w0, w1, w2, w3 6230 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6231 %{ 6232 single_instruction; 6233 dst : WR(write); 6234 src1 : ISS(read); 6235 src2 : ISS(read); 6236 src3 : ISS(read); 6237 INS01 : ISS; 6238 MAC : WR; 6239 %} 6240 6241 // Eg. MUL w0, w1, w2 6242 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6243 %{ 6244 single_instruction; 6245 fixed_latency(3); // Maximum latency for 64 bit mul 6246 dst : WR(write); 6247 src1 : ISS(read); 6248 src2 : ISS(read); 6249 INS01 : ISS; 6250 MAC : WR; 6251 %} 6252 6253 // Multiply accumulate 6254 // Eg. MADD w0, w1, w2, w3 6255 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6256 %{ 6257 single_instruction; 6258 fixed_latency(3); // Maximum latency for 64 bit mul 6259 dst : WR(write); 6260 src1 : ISS(read); 6261 src2 : ISS(read); 6262 src3 : ISS(read); 6263 INS01 : ISS; 6264 MAC : WR; 6265 %} 6266 6267 //------- Divide pipeline operations -------------------- 6268 6269 // Eg. SDIV w0, w1, w2 6270 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6271 %{ 6272 single_instruction; 6273 fixed_latency(8); // Maximum latency for 32 bit divide 6274 dst : WR(write); 6275 src1 : ISS(read); 6276 src2 : ISS(read); 6277 INS0 : ISS; // Can only dual issue as instruction 0 6278 DIV : WR; 6279 %} 6280 6281 // Eg. SDIV x0, x1, x2 6282 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6283 %{ 6284 single_instruction; 6285 fixed_latency(16); // Maximum latency for 64 bit divide 6286 dst : WR(write); 6287 src1 : ISS(read); 6288 src2 : ISS(read); 6289 INS0 : ISS; // Can only dual issue as instruction 0 6290 DIV : WR; 6291 %} 6292 6293 //------- Load pipeline operations ------------------------ 6294 6295 // Load - prefetch 6296 // Eg. PFRM <mem> 6297 pipe_class iload_prefetch(memory mem) 6298 %{ 6299 single_instruction; 6300 mem : ISS(read); 6301 INS01 : ISS; 6302 LDST : WR; 6303 %} 6304 6305 // Load - reg, mem 6306 // Eg. LDR x0, <mem> 6307 pipe_class iload_reg_mem(iRegI dst, memory mem) 6308 %{ 6309 single_instruction; 6310 dst : WR(write); 6311 mem : ISS(read); 6312 INS01 : ISS; 6313 LDST : WR; 6314 %} 6315 6316 // Load - reg, reg 6317 // Eg. LDR x0, [sp, x1] 6318 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6319 %{ 6320 single_instruction; 6321 dst : WR(write); 6322 src : ISS(read); 6323 INS01 : ISS; 6324 LDST : WR; 6325 %} 6326 6327 //------- Store pipeline operations ----------------------- 6328 6329 // Store - zr, mem 6330 // Eg. STR zr, <mem> 6331 pipe_class istore_mem(memory mem) 6332 %{ 6333 single_instruction; 6334 mem : ISS(read); 6335 INS01 : ISS; 6336 LDST : WR; 6337 %} 6338 6339 // Store - reg, mem 6340 // Eg. STR x0, <mem> 6341 pipe_class istore_reg_mem(iRegI src, memory mem) 6342 %{ 6343 single_instruction; 6344 mem : ISS(read); 6345 src : EX2(read); 6346 INS01 : ISS; 6347 LDST : WR; 6348 %} 6349 6350 // Store - reg, reg 6351 // Eg. STR x0, [sp, x1] 6352 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6353 %{ 6354 single_instruction; 6355 dst : ISS(read); 6356 src : EX2(read); 6357 INS01 : ISS; 6358 LDST : WR; 6359 %} 6360 6361 //------- Store pipeline operations ----------------------- 6362 6363 // Branch 6364 pipe_class pipe_branch() 6365 %{ 6366 single_instruction; 6367 INS01 : ISS; 6368 BRANCH : EX1; 6369 %} 6370 6371 // Conditional branch 6372 pipe_class pipe_branch_cond(rFlagsReg cr) 6373 %{ 6374 single_instruction; 6375 cr : EX1(read); 6376 INS01 : ISS; 6377 BRANCH : EX1; 6378 %} 6379 6380 // Compare & Branch 6381 // EG. CBZ/CBNZ 6382 pipe_class pipe_cmp_branch(iRegI op1) 6383 %{ 6384 single_instruction; 6385 op1 : EX1(read); 6386 INS01 : ISS; 6387 BRANCH : EX1; 6388 %} 6389 6390 //------- Synchronisation operations ---------------------- 6391 6392 // Any operation requiring serialization. 6393 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6394 pipe_class pipe_serial() 6395 %{ 6396 single_instruction; 6397 force_serialization; 6398 fixed_latency(16); 6399 INS01 : ISS(2); // Cannot dual issue with any other instruction 6400 LDST : WR; 6401 %} 6402 6403 // Generic big/slow expanded idiom - also serialized 6404 pipe_class pipe_slow() 6405 %{ 6406 instruction_count(10); 6407 multiple_bundles; 6408 force_serialization; 6409 fixed_latency(16); 6410 INS01 : ISS(2); // Cannot dual issue with any other instruction 6411 LDST : WR; 6412 %} 6413 6414 // Empty pipeline class 6415 pipe_class pipe_class_empty() 6416 %{ 6417 single_instruction; 6418 fixed_latency(0); 6419 %} 6420 6421 // Default pipeline class. 6422 pipe_class pipe_class_default() 6423 %{ 6424 single_instruction; 6425 fixed_latency(2); 6426 %} 6427 6428 // Pipeline class for compares. 6429 pipe_class pipe_class_compare() 6430 %{ 6431 single_instruction; 6432 fixed_latency(16); 6433 %} 6434 6435 // Pipeline class for memory operations. 6436 pipe_class pipe_class_memory() 6437 %{ 6438 single_instruction; 6439 fixed_latency(16); 6440 %} 6441 6442 // Pipeline class for call. 6443 pipe_class pipe_class_call() 6444 %{ 6445 single_instruction; 6446 fixed_latency(100); 6447 %} 6448 6449 // Define the class for the Nop node. 6450 define %{ 6451 MachNop = pipe_class_empty; 6452 %} 6453 6454 %} 6455 //----------INSTRUCTIONS------------------------------------------------------- 6456 // 6457 // match -- States which machine-independent subtree may be replaced 6458 // by this instruction. 6459 // ins_cost -- The estimated cost of this instruction is used by instruction 6460 // selection to identify a minimum cost tree of machine 6461 // instructions that matches a tree of machine-independent 6462 // instructions. 6463 // format -- A string providing the disassembly for this instruction. 6464 // The value of an instruction's operand may be inserted 6465 // by referring to it with a '$' prefix. 6466 // opcode -- Three instruction opcodes may be provided. These are referred 6467 // to within an encode class as $primary, $secondary, and $tertiary 6468 // rrspectively. The primary opcode is commonly used to 6469 // indicate the type of machine instruction, while secondary 6470 // and tertiary are often used for prefix options or addressing 6471 // modes. 6472 // ins_encode -- A list of encode classes with parameters. The encode class 6473 // name must have been defined in an 'enc_class' specification 6474 // in the encode section of the architecture description. 6475 6476 // ============================================================================ 6477 // Memory (Load/Store) Instructions 6478 6479 // Load Instructions 6480 6481 // Load Byte (8 bit signed) 6482 instruct loadB(iRegINoSp dst, memory mem) 6483 %{ 6484 match(Set dst (LoadB mem)); 6485 predicate(!needs_acquiring_load(n)); 6486 6487 ins_cost(4 * INSN_COST); 6488 format %{ "ldrsbw $dst, $mem\t# byte" %} 6489 6490 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6491 6492 ins_pipe(iload_reg_mem); 6493 %} 6494 6495 // Load Byte (8 bit signed) into long 6496 instruct loadB2L(iRegLNoSp dst, memory mem) 6497 %{ 6498 match(Set dst (ConvI2L (LoadB mem))); 6499 predicate(!needs_acquiring_load(n->in(1))); 6500 6501 ins_cost(4 * INSN_COST); 6502 format %{ "ldrsb $dst, $mem\t# byte" %} 6503 6504 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6505 6506 ins_pipe(iload_reg_mem); 6507 %} 6508 6509 // Load Byte (8 bit unsigned) 6510 instruct loadUB(iRegINoSp dst, memory mem) 6511 %{ 6512 match(Set dst (LoadUB mem)); 6513 predicate(!needs_acquiring_load(n)); 6514 6515 ins_cost(4 * INSN_COST); 6516 format %{ "ldrbw $dst, $mem\t# byte" %} 6517 6518 ins_encode(aarch64_enc_ldrb(dst, mem)); 6519 6520 ins_pipe(iload_reg_mem); 6521 %} 6522 6523 // Load Byte (8 bit unsigned) into long 6524 instruct loadUB2L(iRegLNoSp dst, memory mem) 6525 %{ 6526 match(Set dst (ConvI2L (LoadUB mem))); 6527 predicate(!needs_acquiring_load(n->in(1))); 6528 6529 ins_cost(4 * INSN_COST); 6530 format %{ "ldrb $dst, $mem\t# byte" %} 6531 6532 ins_encode(aarch64_enc_ldrb(dst, mem)); 6533 6534 ins_pipe(iload_reg_mem); 6535 %} 6536 6537 // Load Short (16 bit signed) 6538 instruct loadS(iRegINoSp dst, memory mem) 6539 %{ 6540 match(Set dst (LoadS mem)); 6541 predicate(!needs_acquiring_load(n)); 6542 6543 ins_cost(4 * INSN_COST); 6544 format %{ "ldrshw $dst, $mem\t# short" %} 6545 6546 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6547 6548 ins_pipe(iload_reg_mem); 6549 %} 6550 6551 // Load Short (16 bit signed) into long 6552 instruct loadS2L(iRegLNoSp dst, memory mem) 6553 %{ 6554 match(Set dst (ConvI2L (LoadS mem))); 6555 predicate(!needs_acquiring_load(n->in(1))); 6556 6557 ins_cost(4 * INSN_COST); 6558 format %{ "ldrsh $dst, $mem\t# short" %} 6559 6560 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6561 6562 ins_pipe(iload_reg_mem); 6563 %} 6564 6565 // Load Char (16 bit unsigned) 6566 instruct loadUS(iRegINoSp dst, memory mem) 6567 %{ 6568 match(Set dst (LoadUS mem)); 6569 predicate(!needs_acquiring_load(n)); 6570 6571 ins_cost(4 * INSN_COST); 6572 format %{ "ldrh $dst, $mem\t# short" %} 6573 6574 ins_encode(aarch64_enc_ldrh(dst, mem)); 6575 6576 ins_pipe(iload_reg_mem); 6577 %} 6578 6579 // Load Short/Char (16 bit unsigned) into long 6580 instruct loadUS2L(iRegLNoSp dst, memory mem) 6581 %{ 6582 match(Set dst (ConvI2L (LoadUS mem))); 6583 predicate(!needs_acquiring_load(n->in(1))); 6584 6585 ins_cost(4 * INSN_COST); 6586 format %{ "ldrh $dst, $mem\t# short" %} 6587 6588 ins_encode(aarch64_enc_ldrh(dst, mem)); 6589 6590 ins_pipe(iload_reg_mem); 6591 %} 6592 6593 // Load Integer (32 bit signed) 6594 instruct loadI(iRegINoSp dst, memory mem) 6595 %{ 6596 match(Set dst (LoadI mem)); 6597 predicate(!needs_acquiring_load(n)); 6598 6599 ins_cost(4 * INSN_COST); 6600 format %{ "ldrw $dst, $mem\t# int" %} 6601 6602 ins_encode(aarch64_enc_ldrw(dst, mem)); 6603 6604 ins_pipe(iload_reg_mem); 6605 %} 6606 6607 // Load Integer (32 bit signed) into long 6608 instruct loadI2L(iRegLNoSp dst, memory mem) 6609 %{ 6610 match(Set dst (ConvI2L (LoadI mem))); 6611 predicate(!needs_acquiring_load(n->in(1))); 6612 6613 ins_cost(4 * INSN_COST); 6614 format %{ "ldrsw $dst, $mem\t# int" %} 6615 6616 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6617 6618 ins_pipe(iload_reg_mem); 6619 %} 6620 6621 // Load Integer (32 bit unsigned) into long 6622 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6623 %{ 6624 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6625 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6626 6627 ins_cost(4 * INSN_COST); 6628 format %{ "ldrw $dst, $mem\t# int" %} 6629 6630 ins_encode(aarch64_enc_ldrw(dst, mem)); 6631 6632 ins_pipe(iload_reg_mem); 6633 %} 6634 6635 // Load Long (64 bit signed) 6636 instruct loadL(iRegLNoSp dst, memory mem) 6637 %{ 6638 match(Set dst (LoadL mem)); 6639 predicate(!needs_acquiring_load(n)); 6640 6641 ins_cost(4 * INSN_COST); 6642 format %{ "ldr $dst, $mem\t# int" %} 6643 6644 ins_encode(aarch64_enc_ldr(dst, mem)); 6645 6646 ins_pipe(iload_reg_mem); 6647 %} 6648 6649 // Load Range 6650 instruct loadRange(iRegINoSp dst, memory mem) 6651 %{ 6652 match(Set dst (LoadRange mem)); 6653 6654 ins_cost(4 * INSN_COST); 6655 format %{ "ldrw $dst, $mem\t# range" %} 6656 6657 ins_encode(aarch64_enc_ldrw(dst, mem)); 6658 6659 ins_pipe(iload_reg_mem); 6660 %} 6661 6662 // Load Pointer 6663 instruct loadP(iRegPNoSp dst, memory mem) 6664 %{ 6665 match(Set dst (LoadP mem)); 6666 predicate(!needs_acquiring_load(n)); 6667 6668 ins_cost(4 * INSN_COST); 6669 format %{ "ldr $dst, $mem\t# ptr" %} 6670 6671 ins_encode(aarch64_enc_ldr(dst, mem)); 6672 6673 ins_pipe(iload_reg_mem); 6674 %} 6675 6676 // Load Compressed Pointer 6677 instruct loadN(iRegNNoSp dst, memory mem) 6678 %{ 6679 match(Set dst (LoadN mem)); 6680 predicate(!needs_acquiring_load(n)); 6681 6682 ins_cost(4 * INSN_COST); 6683 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6684 6685 ins_encode(aarch64_enc_ldrw(dst, mem)); 6686 6687 ins_pipe(iload_reg_mem); 6688 %} 6689 6690 // Load Klass Pointer 6691 instruct loadKlass(iRegPNoSp dst, memory mem) 6692 %{ 6693 match(Set dst (LoadKlass mem)); 6694 predicate(!needs_acquiring_load(n)); 6695 6696 ins_cost(4 * INSN_COST); 6697 format %{ "ldr $dst, $mem\t# class" %} 6698 6699 ins_encode(aarch64_enc_ldr(dst, mem)); 6700 6701 ins_pipe(iload_reg_mem); 6702 %} 6703 6704 // Load Narrow Klass Pointer 6705 instruct loadNKlass(iRegNNoSp dst, memory mem) 6706 %{ 6707 match(Set dst (LoadNKlass mem)); 6708 predicate(!needs_acquiring_load(n)); 6709 6710 ins_cost(4 * INSN_COST); 6711 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6712 6713 ins_encode(aarch64_enc_ldrw(dst, mem)); 6714 6715 ins_pipe(iload_reg_mem); 6716 %} 6717 6718 // Load Float 6719 instruct loadF(vRegF dst, memory mem) 6720 %{ 6721 match(Set dst (LoadF mem)); 6722 predicate(!needs_acquiring_load(n)); 6723 6724 ins_cost(4 * INSN_COST); 6725 format %{ "ldrs $dst, $mem\t# float" %} 6726 6727 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6728 6729 ins_pipe(pipe_class_memory); 6730 %} 6731 6732 // Load Double 6733 instruct loadD(vRegD dst, memory mem) 6734 %{ 6735 match(Set dst (LoadD mem)); 6736 predicate(!needs_acquiring_load(n)); 6737 6738 ins_cost(4 * INSN_COST); 6739 format %{ "ldrd $dst, $mem\t# double" %} 6740 6741 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6742 6743 ins_pipe(pipe_class_memory); 6744 %} 6745 6746 6747 // Load Int Constant 6748 instruct loadConI(iRegINoSp dst, immI src) 6749 %{ 6750 match(Set dst src); 6751 6752 ins_cost(INSN_COST); 6753 format %{ "mov $dst, $src\t# int" %} 6754 6755 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6756 6757 ins_pipe(ialu_imm); 6758 %} 6759 6760 // Load Long Constant 6761 instruct loadConL(iRegLNoSp dst, immL src) 6762 %{ 6763 match(Set dst src); 6764 6765 ins_cost(INSN_COST); 6766 format %{ "mov $dst, $src\t# long" %} 6767 6768 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6769 6770 ins_pipe(ialu_imm); 6771 %} 6772 6773 // Load Pointer Constant 6774 6775 instruct loadConP(iRegPNoSp dst, immP con) 6776 %{ 6777 match(Set dst con); 6778 6779 ins_cost(INSN_COST * 4); 6780 format %{ 6781 "mov $dst, $con\t# ptr\n\t" 6782 %} 6783 6784 ins_encode(aarch64_enc_mov_p(dst, con)); 6785 6786 ins_pipe(ialu_imm); 6787 %} 6788 6789 // Load Null Pointer Constant 6790 6791 instruct loadConP0(iRegPNoSp dst, immP0 con) 6792 %{ 6793 match(Set dst con); 6794 6795 ins_cost(INSN_COST); 6796 format %{ "mov $dst, $con\t# NULL ptr" %} 6797 6798 ins_encode(aarch64_enc_mov_p0(dst, con)); 6799 6800 ins_pipe(ialu_imm); 6801 %} 6802 6803 // Load Pointer Constant One 6804 6805 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6806 %{ 6807 match(Set dst con); 6808 6809 ins_cost(INSN_COST); 6810 format %{ "mov $dst, $con\t# NULL ptr" %} 6811 6812 ins_encode(aarch64_enc_mov_p1(dst, con)); 6813 6814 ins_pipe(ialu_imm); 6815 %} 6816 6817 // Load Poll Page Constant 6818 6819 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6820 %{ 6821 match(Set dst con); 6822 6823 ins_cost(INSN_COST); 6824 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6825 6826 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6827 6828 ins_pipe(ialu_imm); 6829 %} 6830 6831 // Load Byte Map Base Constant 6832 6833 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6834 %{ 6835 match(Set dst con); 6836 6837 ins_cost(INSN_COST); 6838 format %{ "adr $dst, $con\t# Byte Map Base" %} 6839 6840 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6841 6842 ins_pipe(ialu_imm); 6843 %} 6844 6845 // Load Narrow Pointer Constant 6846 6847 instruct loadConN(iRegNNoSp dst, immN con) 6848 %{ 6849 match(Set dst con); 6850 6851 ins_cost(INSN_COST * 4); 6852 format %{ "mov $dst, $con\t# compressed ptr" %} 6853 6854 ins_encode(aarch64_enc_mov_n(dst, con)); 6855 6856 ins_pipe(ialu_imm); 6857 %} 6858 6859 // Load Narrow Null Pointer Constant 6860 6861 instruct loadConN0(iRegNNoSp dst, immN0 con) 6862 %{ 6863 match(Set dst con); 6864 6865 ins_cost(INSN_COST); 6866 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6867 6868 ins_encode(aarch64_enc_mov_n0(dst, con)); 6869 6870 ins_pipe(ialu_imm); 6871 %} 6872 6873 // Load Narrow Klass Constant 6874 6875 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6876 %{ 6877 match(Set dst con); 6878 6879 ins_cost(INSN_COST); 6880 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6881 6882 ins_encode(aarch64_enc_mov_nk(dst, con)); 6883 6884 ins_pipe(ialu_imm); 6885 %} 6886 6887 // Load Packed Float Constant 6888 6889 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6890 match(Set dst con); 6891 ins_cost(INSN_COST * 4); 6892 format %{ "fmovs $dst, $con"%} 6893 ins_encode %{ 6894 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6895 %} 6896 6897 ins_pipe(fp_imm_s); 6898 %} 6899 6900 // Load Float Constant 6901 6902 instruct loadConF(vRegF dst, immF con) %{ 6903 match(Set dst con); 6904 6905 ins_cost(INSN_COST * 4); 6906 6907 format %{ 6908 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6909 %} 6910 6911 ins_encode %{ 6912 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6913 %} 6914 6915 ins_pipe(fp_load_constant_s); 6916 %} 6917 6918 // Load Packed Double Constant 6919 6920 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6921 match(Set dst con); 6922 ins_cost(INSN_COST); 6923 format %{ "fmovd $dst, $con"%} 6924 ins_encode %{ 6925 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6926 %} 6927 6928 ins_pipe(fp_imm_d); 6929 %} 6930 6931 // Load Double Constant 6932 6933 instruct loadConD(vRegD dst, immD con) %{ 6934 match(Set dst con); 6935 6936 ins_cost(INSN_COST * 5); 6937 format %{ 6938 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6939 %} 6940 6941 ins_encode %{ 6942 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6943 %} 6944 6945 ins_pipe(fp_load_constant_d); 6946 %} 6947 6948 // Store Instructions 6949 6950 // Store CMS card-mark Immediate 6951 instruct storeimmCM0(immI0 zero, memory mem) 6952 %{ 6953 match(Set mem (StoreCM mem zero)); 6954 predicate(unnecessary_storestore(n)); 6955 6956 ins_cost(INSN_COST); 6957 format %{ "storestore (elided)\n\t" 6958 "strb zr, $mem\t# byte" %} 6959 6960 ins_encode(aarch64_enc_strb0(mem)); 6961 6962 ins_pipe(istore_mem); 6963 %} 6964 6965 // Store CMS card-mark Immediate with intervening StoreStore 6966 // needed when using CMS with no conditional card marking 6967 instruct storeimmCM0_ordered(immI0 zero, memory mem) 6968 %{ 6969 match(Set mem (StoreCM mem zero)); 6970 6971 ins_cost(INSN_COST * 2); 6972 format %{ "storestore\n\t" 6973 "dmb ishst" 6974 "\n\tstrb zr, $mem\t# byte" %} 6975 6976 ins_encode(aarch64_enc_strb0_ordered(mem)); 6977 6978 ins_pipe(istore_mem); 6979 %} 6980 6981 // Store Byte 6982 instruct storeB(iRegIorL2I src, memory mem) 6983 %{ 6984 match(Set mem (StoreB mem src)); 6985 predicate(!needs_releasing_store(n)); 6986 6987 ins_cost(INSN_COST); 6988 format %{ "strb $src, $mem\t# byte" %} 6989 6990 ins_encode(aarch64_enc_strb(src, mem)); 6991 6992 ins_pipe(istore_reg_mem); 6993 %} 6994 6995 6996 instruct storeimmB0(immI0 zero, memory mem) 6997 %{ 6998 match(Set mem (StoreB mem zero)); 6999 predicate(!needs_releasing_store(n)); 7000 7001 ins_cost(INSN_COST); 7002 format %{ "strb rscractch2, $mem\t# byte" %} 7003 7004 ins_encode(aarch64_enc_strb0(mem)); 7005 7006 ins_pipe(istore_mem); 7007 %} 7008 7009 // Store Char/Short 7010 instruct storeC(iRegIorL2I src, memory mem) 7011 %{ 7012 match(Set mem (StoreC mem src)); 7013 predicate(!needs_releasing_store(n)); 7014 7015 ins_cost(INSN_COST); 7016 format %{ "strh $src, $mem\t# short" %} 7017 7018 ins_encode(aarch64_enc_strh(src, mem)); 7019 7020 ins_pipe(istore_reg_mem); 7021 %} 7022 7023 instruct storeimmC0(immI0 zero, memory mem) 7024 %{ 7025 match(Set mem (StoreC mem zero)); 7026 predicate(!needs_releasing_store(n)); 7027 7028 ins_cost(INSN_COST); 7029 format %{ "strh zr, $mem\t# short" %} 7030 7031 ins_encode(aarch64_enc_strh0(mem)); 7032 7033 ins_pipe(istore_mem); 7034 %} 7035 7036 // Store Integer 7037 7038 instruct storeI(iRegIorL2I src, memory mem) 7039 %{ 7040 match(Set mem(StoreI mem src)); 7041 predicate(!needs_releasing_store(n)); 7042 7043 ins_cost(INSN_COST); 7044 format %{ "strw $src, $mem\t# int" %} 7045 7046 ins_encode(aarch64_enc_strw(src, mem)); 7047 7048 ins_pipe(istore_reg_mem); 7049 %} 7050 7051 instruct storeimmI0(immI0 zero, memory mem) 7052 %{ 7053 match(Set mem(StoreI mem zero)); 7054 predicate(!needs_releasing_store(n)); 7055 7056 ins_cost(INSN_COST); 7057 format %{ "strw zr, $mem\t# int" %} 7058 7059 ins_encode(aarch64_enc_strw0(mem)); 7060 7061 ins_pipe(istore_mem); 7062 %} 7063 7064 // Store Long (64 bit signed) 7065 instruct storeL(iRegL src, memory mem) 7066 %{ 7067 match(Set mem (StoreL mem src)); 7068 predicate(!needs_releasing_store(n)); 7069 7070 ins_cost(INSN_COST); 7071 format %{ "str $src, $mem\t# int" %} 7072 7073 ins_encode(aarch64_enc_str(src, mem)); 7074 7075 ins_pipe(istore_reg_mem); 7076 %} 7077 7078 // Store Long (64 bit signed) 7079 instruct storeimmL0(immL0 zero, memory mem) 7080 %{ 7081 match(Set mem (StoreL mem zero)); 7082 predicate(!needs_releasing_store(n)); 7083 7084 ins_cost(INSN_COST); 7085 format %{ "str zr, $mem\t# int" %} 7086 7087 ins_encode(aarch64_enc_str0(mem)); 7088 7089 ins_pipe(istore_mem); 7090 %} 7091 7092 // Store Pointer 7093 instruct storeP(iRegP src, memory mem) 7094 %{ 7095 match(Set mem (StoreP mem src)); 7096 predicate(!needs_releasing_store(n)); 7097 7098 ins_cost(INSN_COST); 7099 format %{ "str $src, $mem\t# ptr" %} 7100 7101 ins_encode(aarch64_enc_str(src, mem)); 7102 7103 ins_pipe(istore_reg_mem); 7104 %} 7105 7106 // Store Pointer 7107 instruct storeimmP0(immP0 zero, memory mem) 7108 %{ 7109 match(Set mem (StoreP mem zero)); 7110 predicate(!needs_releasing_store(n)); 7111 7112 ins_cost(INSN_COST); 7113 format %{ "str zr, $mem\t# ptr" %} 7114 7115 ins_encode(aarch64_enc_str0(mem)); 7116 7117 ins_pipe(istore_mem); 7118 %} 7119 7120 // Store Compressed Pointer 7121 instruct storeN(iRegN src, memory mem) 7122 %{ 7123 match(Set mem (StoreN mem src)); 7124 predicate(!needs_releasing_store(n)); 7125 7126 ins_cost(INSN_COST); 7127 format %{ "strw $src, $mem\t# compressed ptr" %} 7128 7129 ins_encode(aarch64_enc_strw(src, mem)); 7130 7131 ins_pipe(istore_reg_mem); 7132 %} 7133 7134 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7135 %{ 7136 match(Set mem (StoreN mem zero)); 7137 predicate(Universe::narrow_oop_base() == NULL && 7138 Universe::narrow_klass_base() == NULL && 7139 (!needs_releasing_store(n))); 7140 7141 ins_cost(INSN_COST); 7142 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7143 7144 ins_encode(aarch64_enc_strw(heapbase, mem)); 7145 7146 ins_pipe(istore_reg_mem); 7147 %} 7148 7149 // Store Float 7150 instruct storeF(vRegF src, memory mem) 7151 %{ 7152 match(Set mem (StoreF mem src)); 7153 predicate(!needs_releasing_store(n)); 7154 7155 ins_cost(INSN_COST); 7156 format %{ "strs $src, $mem\t# float" %} 7157 7158 ins_encode( aarch64_enc_strs(src, mem) ); 7159 7160 ins_pipe(pipe_class_memory); 7161 %} 7162 7163 // TODO 7164 // implement storeImmF0 and storeFImmPacked 7165 7166 // Store Double 7167 instruct storeD(vRegD src, memory mem) 7168 %{ 7169 match(Set mem (StoreD mem src)); 7170 predicate(!needs_releasing_store(n)); 7171 7172 ins_cost(INSN_COST); 7173 format %{ "strd $src, $mem\t# double" %} 7174 7175 ins_encode( aarch64_enc_strd(src, mem) ); 7176 7177 ins_pipe(pipe_class_memory); 7178 %} 7179 7180 // Store Compressed Klass Pointer 7181 instruct storeNKlass(iRegN src, memory mem) 7182 %{ 7183 predicate(!needs_releasing_store(n)); 7184 match(Set mem (StoreNKlass mem src)); 7185 7186 ins_cost(INSN_COST); 7187 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7188 7189 ins_encode(aarch64_enc_strw(src, mem)); 7190 7191 ins_pipe(istore_reg_mem); 7192 %} 7193 7194 // TODO 7195 // implement storeImmD0 and storeDImmPacked 7196 7197 // prefetch instructions 7198 // Must be safe to execute with invalid address (cannot fault). 7199 7200 instruct prefetchalloc( memory mem ) %{ 7201 match(PrefetchAllocation mem); 7202 7203 ins_cost(INSN_COST); 7204 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7205 7206 ins_encode( aarch64_enc_prefetchw(mem) ); 7207 7208 ins_pipe(iload_prefetch); 7209 %} 7210 7211 // ---------------- volatile loads and stores ---------------- 7212 7213 // Load Byte (8 bit signed) 7214 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7215 %{ 7216 match(Set dst (LoadB mem)); 7217 7218 ins_cost(VOLATILE_REF_COST); 7219 format %{ "ldarsb $dst, $mem\t# byte" %} 7220 7221 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7222 7223 ins_pipe(pipe_serial); 7224 %} 7225 7226 // Load Byte (8 bit signed) into long 7227 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7228 %{ 7229 match(Set dst (ConvI2L (LoadB mem))); 7230 7231 ins_cost(VOLATILE_REF_COST); 7232 format %{ "ldarsb $dst, $mem\t# byte" %} 7233 7234 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7235 7236 ins_pipe(pipe_serial); 7237 %} 7238 7239 // Load Byte (8 bit unsigned) 7240 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7241 %{ 7242 match(Set dst (LoadUB mem)); 7243 7244 ins_cost(VOLATILE_REF_COST); 7245 format %{ "ldarb $dst, $mem\t# byte" %} 7246 7247 ins_encode(aarch64_enc_ldarb(dst, mem)); 7248 7249 ins_pipe(pipe_serial); 7250 %} 7251 7252 // Load Byte (8 bit unsigned) into long 7253 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7254 %{ 7255 match(Set dst (ConvI2L (LoadUB mem))); 7256 7257 ins_cost(VOLATILE_REF_COST); 7258 format %{ "ldarb $dst, $mem\t# byte" %} 7259 7260 ins_encode(aarch64_enc_ldarb(dst, mem)); 7261 7262 ins_pipe(pipe_serial); 7263 %} 7264 7265 // Load Short (16 bit signed) 7266 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7267 %{ 7268 match(Set dst (LoadS mem)); 7269 7270 ins_cost(VOLATILE_REF_COST); 7271 format %{ "ldarshw $dst, $mem\t# short" %} 7272 7273 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7274 7275 ins_pipe(pipe_serial); 7276 %} 7277 7278 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7279 %{ 7280 match(Set dst (LoadUS mem)); 7281 7282 ins_cost(VOLATILE_REF_COST); 7283 format %{ "ldarhw $dst, $mem\t# short" %} 7284 7285 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7286 7287 ins_pipe(pipe_serial); 7288 %} 7289 7290 // Load Short/Char (16 bit unsigned) into long 7291 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7292 %{ 7293 match(Set dst (ConvI2L (LoadUS mem))); 7294 7295 ins_cost(VOLATILE_REF_COST); 7296 format %{ "ldarh $dst, $mem\t# short" %} 7297 7298 ins_encode(aarch64_enc_ldarh(dst, mem)); 7299 7300 ins_pipe(pipe_serial); 7301 %} 7302 7303 // Load Short/Char (16 bit signed) into long 7304 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7305 %{ 7306 match(Set dst (ConvI2L (LoadS mem))); 7307 7308 ins_cost(VOLATILE_REF_COST); 7309 format %{ "ldarh $dst, $mem\t# short" %} 7310 7311 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7312 7313 ins_pipe(pipe_serial); 7314 %} 7315 7316 // Load Integer (32 bit signed) 7317 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7318 %{ 7319 match(Set dst (LoadI mem)); 7320 7321 ins_cost(VOLATILE_REF_COST); 7322 format %{ "ldarw $dst, $mem\t# int" %} 7323 7324 ins_encode(aarch64_enc_ldarw(dst, mem)); 7325 7326 ins_pipe(pipe_serial); 7327 %} 7328 7329 // Load Integer (32 bit unsigned) into long 7330 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7331 %{ 7332 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7333 7334 ins_cost(VOLATILE_REF_COST); 7335 format %{ "ldarw $dst, $mem\t# int" %} 7336 7337 ins_encode(aarch64_enc_ldarw(dst, mem)); 7338 7339 ins_pipe(pipe_serial); 7340 %} 7341 7342 // Load Long (64 bit signed) 7343 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7344 %{ 7345 match(Set dst (LoadL mem)); 7346 7347 ins_cost(VOLATILE_REF_COST); 7348 format %{ "ldar $dst, $mem\t# int" %} 7349 7350 ins_encode(aarch64_enc_ldar(dst, mem)); 7351 7352 ins_pipe(pipe_serial); 7353 %} 7354 7355 // Load Pointer 7356 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7357 %{ 7358 match(Set dst (LoadP mem)); 7359 7360 ins_cost(VOLATILE_REF_COST); 7361 format %{ "ldar $dst, $mem\t# ptr" %} 7362 7363 ins_encode(aarch64_enc_ldar(dst, mem)); 7364 7365 ins_pipe(pipe_serial); 7366 %} 7367 7368 // Load Compressed Pointer 7369 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7370 %{ 7371 match(Set dst (LoadN mem)); 7372 7373 ins_cost(VOLATILE_REF_COST); 7374 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7375 7376 ins_encode(aarch64_enc_ldarw(dst, mem)); 7377 7378 ins_pipe(pipe_serial); 7379 %} 7380 7381 // Load Float 7382 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7383 %{ 7384 match(Set dst (LoadF mem)); 7385 7386 ins_cost(VOLATILE_REF_COST); 7387 format %{ "ldars $dst, $mem\t# float" %} 7388 7389 ins_encode( aarch64_enc_fldars(dst, mem) ); 7390 7391 ins_pipe(pipe_serial); 7392 %} 7393 7394 // Load Double 7395 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7396 %{ 7397 match(Set dst (LoadD mem)); 7398 7399 ins_cost(VOLATILE_REF_COST); 7400 format %{ "ldard $dst, $mem\t# double" %} 7401 7402 ins_encode( aarch64_enc_fldard(dst, mem) ); 7403 7404 ins_pipe(pipe_serial); 7405 %} 7406 7407 // Store Byte 7408 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7409 %{ 7410 match(Set mem (StoreB mem src)); 7411 7412 ins_cost(VOLATILE_REF_COST); 7413 format %{ "stlrb $src, $mem\t# byte" %} 7414 7415 ins_encode(aarch64_enc_stlrb(src, mem)); 7416 7417 ins_pipe(pipe_class_memory); 7418 %} 7419 7420 // Store Char/Short 7421 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7422 %{ 7423 match(Set mem (StoreC mem src)); 7424 7425 ins_cost(VOLATILE_REF_COST); 7426 format %{ "stlrh $src, $mem\t# short" %} 7427 7428 ins_encode(aarch64_enc_stlrh(src, mem)); 7429 7430 ins_pipe(pipe_class_memory); 7431 %} 7432 7433 // Store Integer 7434 7435 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7436 %{ 7437 match(Set mem(StoreI mem src)); 7438 7439 ins_cost(VOLATILE_REF_COST); 7440 format %{ "stlrw $src, $mem\t# int" %} 7441 7442 ins_encode(aarch64_enc_stlrw(src, mem)); 7443 7444 ins_pipe(pipe_class_memory); 7445 %} 7446 7447 // Store Long (64 bit signed) 7448 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7449 %{ 7450 match(Set mem (StoreL mem src)); 7451 7452 ins_cost(VOLATILE_REF_COST); 7453 format %{ "stlr $src, $mem\t# int" %} 7454 7455 ins_encode(aarch64_enc_stlr(src, mem)); 7456 7457 ins_pipe(pipe_class_memory); 7458 %} 7459 7460 // Store Pointer 7461 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7462 %{ 7463 match(Set mem (StoreP mem src)); 7464 7465 ins_cost(VOLATILE_REF_COST); 7466 format %{ "stlr $src, $mem\t# ptr" %} 7467 7468 ins_encode(aarch64_enc_stlr(src, mem)); 7469 7470 ins_pipe(pipe_class_memory); 7471 %} 7472 7473 // Store Compressed Pointer 7474 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7475 %{ 7476 match(Set mem (StoreN mem src)); 7477 7478 ins_cost(VOLATILE_REF_COST); 7479 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7480 7481 ins_encode(aarch64_enc_stlrw(src, mem)); 7482 7483 ins_pipe(pipe_class_memory); 7484 %} 7485 7486 // Store Float 7487 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7488 %{ 7489 match(Set mem (StoreF mem src)); 7490 7491 ins_cost(VOLATILE_REF_COST); 7492 format %{ "stlrs $src, $mem\t# float" %} 7493 7494 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7495 7496 ins_pipe(pipe_class_memory); 7497 %} 7498 7499 // TODO 7500 // implement storeImmF0 and storeFImmPacked 7501 7502 // Store Double 7503 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7504 %{ 7505 match(Set mem (StoreD mem src)); 7506 7507 ins_cost(VOLATILE_REF_COST); 7508 format %{ "stlrd $src, $mem\t# double" %} 7509 7510 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7511 7512 ins_pipe(pipe_class_memory); 7513 %} 7514 7515 // ---------------- end of volatile loads and stores ---------------- 7516 7517 // ============================================================================ 7518 // BSWAP Instructions 7519 7520 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7521 match(Set dst (ReverseBytesI src)); 7522 7523 ins_cost(INSN_COST); 7524 format %{ "revw $dst, $src" %} 7525 7526 ins_encode %{ 7527 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7528 %} 7529 7530 ins_pipe(ialu_reg); 7531 %} 7532 7533 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7534 match(Set dst (ReverseBytesL src)); 7535 7536 ins_cost(INSN_COST); 7537 format %{ "rev $dst, $src" %} 7538 7539 ins_encode %{ 7540 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7541 %} 7542 7543 ins_pipe(ialu_reg); 7544 %} 7545 7546 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7547 match(Set dst (ReverseBytesUS src)); 7548 7549 ins_cost(INSN_COST); 7550 format %{ "rev16w $dst, $src" %} 7551 7552 ins_encode %{ 7553 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7554 %} 7555 7556 ins_pipe(ialu_reg); 7557 %} 7558 7559 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7560 match(Set dst (ReverseBytesS src)); 7561 7562 ins_cost(INSN_COST); 7563 format %{ "rev16w $dst, $src\n\t" 7564 "sbfmw $dst, $dst, #0, #15" %} 7565 7566 ins_encode %{ 7567 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7568 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7569 %} 7570 7571 ins_pipe(ialu_reg); 7572 %} 7573 7574 // ============================================================================ 7575 // Zero Count Instructions 7576 7577 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7578 match(Set dst (CountLeadingZerosI src)); 7579 7580 ins_cost(INSN_COST); 7581 format %{ "clzw $dst, $src" %} 7582 ins_encode %{ 7583 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7584 %} 7585 7586 ins_pipe(ialu_reg); 7587 %} 7588 7589 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7590 match(Set dst (CountLeadingZerosL src)); 7591 7592 ins_cost(INSN_COST); 7593 format %{ "clz $dst, $src" %} 7594 ins_encode %{ 7595 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7596 %} 7597 7598 ins_pipe(ialu_reg); 7599 %} 7600 7601 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7602 match(Set dst (CountTrailingZerosI src)); 7603 7604 ins_cost(INSN_COST * 2); 7605 format %{ "rbitw $dst, $src\n\t" 7606 "clzw $dst, $dst" %} 7607 ins_encode %{ 7608 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7609 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7610 %} 7611 7612 ins_pipe(ialu_reg); 7613 %} 7614 7615 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7616 match(Set dst (CountTrailingZerosL src)); 7617 7618 ins_cost(INSN_COST * 2); 7619 format %{ "rbit $dst, $src\n\t" 7620 "clz $dst, $dst" %} 7621 ins_encode %{ 7622 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7623 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7624 %} 7625 7626 ins_pipe(ialu_reg); 7627 %} 7628 7629 //---------- Population Count Instructions ------------------------------------- 7630 // 7631 7632 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7633 predicate(UsePopCountInstruction); 7634 match(Set dst (PopCountI src)); 7635 effect(TEMP tmp); 7636 ins_cost(INSN_COST * 13); 7637 7638 format %{ "movw $src, $src\n\t" 7639 "mov $tmp, $src\t# vector (1D)\n\t" 7640 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7641 "addv $tmp, $tmp\t# vector (8B)\n\t" 7642 "mov $dst, $tmp\t# vector (1D)" %} 7643 ins_encode %{ 7644 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7645 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7646 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7647 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7648 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7649 %} 7650 7651 ins_pipe(pipe_class_default); 7652 %} 7653 7654 instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7655 predicate(UsePopCountInstruction); 7656 match(Set dst (PopCountI (LoadI mem))); 7657 effect(TEMP tmp); 7658 ins_cost(INSN_COST * 13); 7659 7660 format %{ "ldrs $tmp, $mem\n\t" 7661 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7662 "addv $tmp, $tmp\t# vector (8B)\n\t" 7663 "mov $dst, $tmp\t# vector (1D)" %} 7664 ins_encode %{ 7665 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7666 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7667 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7668 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7669 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7670 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7671 %} 7672 7673 ins_pipe(pipe_class_default); 7674 %} 7675 7676 // Note: Long.bitCount(long) returns an int. 7677 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7678 predicate(UsePopCountInstruction); 7679 match(Set dst (PopCountL src)); 7680 effect(TEMP tmp); 7681 ins_cost(INSN_COST * 13); 7682 7683 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7684 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7685 "addv $tmp, $tmp\t# vector (8B)\n\t" 7686 "mov $dst, $tmp\t# vector (1D)" %} 7687 ins_encode %{ 7688 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7689 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7690 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7691 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7692 %} 7693 7694 ins_pipe(pipe_class_default); 7695 %} 7696 7697 instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7698 predicate(UsePopCountInstruction); 7699 match(Set dst (PopCountL (LoadL mem))); 7700 effect(TEMP tmp); 7701 ins_cost(INSN_COST * 13); 7702 7703 format %{ "ldrd $tmp, $mem\n\t" 7704 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7705 "addv $tmp, $tmp\t# vector (8B)\n\t" 7706 "mov $dst, $tmp\t# vector (1D)" %} 7707 ins_encode %{ 7708 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7709 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7710 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7711 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7712 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7713 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7714 %} 7715 7716 ins_pipe(pipe_class_default); 7717 %} 7718 7719 // ============================================================================ 7720 // MemBar Instruction 7721 7722 instruct load_fence() %{ 7723 match(LoadFence); 7724 ins_cost(VOLATILE_REF_COST); 7725 7726 format %{ "load_fence" %} 7727 7728 ins_encode %{ 7729 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7730 %} 7731 ins_pipe(pipe_serial); 7732 %} 7733 7734 instruct unnecessary_membar_acquire() %{ 7735 predicate(unnecessary_acquire(n)); 7736 match(MemBarAcquire); 7737 ins_cost(0); 7738 7739 format %{ "membar_acquire (elided)" %} 7740 7741 ins_encode %{ 7742 __ block_comment("membar_acquire (elided)"); 7743 %} 7744 7745 ins_pipe(pipe_class_empty); 7746 %} 7747 7748 instruct membar_acquire() %{ 7749 match(MemBarAcquire); 7750 ins_cost(VOLATILE_REF_COST); 7751 7752 format %{ "membar_acquire\n\t" 7753 "dmb ish" %} 7754 7755 ins_encode %{ 7756 __ block_comment("membar_acquire"); 7757 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7758 %} 7759 7760 ins_pipe(pipe_serial); 7761 %} 7762 7763 7764 instruct membar_acquire_lock() %{ 7765 match(MemBarAcquireLock); 7766 ins_cost(VOLATILE_REF_COST); 7767 7768 format %{ "membar_acquire_lock (elided)" %} 7769 7770 ins_encode %{ 7771 __ block_comment("membar_acquire_lock (elided)"); 7772 %} 7773 7774 ins_pipe(pipe_serial); 7775 %} 7776 7777 instruct store_fence() %{ 7778 match(StoreFence); 7779 ins_cost(VOLATILE_REF_COST); 7780 7781 format %{ "store_fence" %} 7782 7783 ins_encode %{ 7784 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7785 %} 7786 ins_pipe(pipe_serial); 7787 %} 7788 7789 instruct unnecessary_membar_release() %{ 7790 predicate(unnecessary_release(n)); 7791 match(MemBarRelease); 7792 ins_cost(0); 7793 7794 format %{ "membar_release (elided)" %} 7795 7796 ins_encode %{ 7797 __ block_comment("membar_release (elided)"); 7798 %} 7799 ins_pipe(pipe_serial); 7800 %} 7801 7802 instruct membar_release() %{ 7803 match(MemBarRelease); 7804 ins_cost(VOLATILE_REF_COST); 7805 7806 format %{ "membar_release\n\t" 7807 "dmb ish" %} 7808 7809 ins_encode %{ 7810 __ block_comment("membar_release"); 7811 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7812 %} 7813 ins_pipe(pipe_serial); 7814 %} 7815 7816 instruct membar_storestore() %{ 7817 match(MemBarStoreStore); 7818 ins_cost(VOLATILE_REF_COST); 7819 7820 format %{ "MEMBAR-store-store" %} 7821 7822 ins_encode %{ 7823 __ membar(Assembler::StoreStore); 7824 %} 7825 ins_pipe(pipe_serial); 7826 %} 7827 7828 instruct membar_release_lock() %{ 7829 match(MemBarReleaseLock); 7830 ins_cost(VOLATILE_REF_COST); 7831 7832 format %{ "membar_release_lock (elided)" %} 7833 7834 ins_encode %{ 7835 __ block_comment("membar_release_lock (elided)"); 7836 %} 7837 7838 ins_pipe(pipe_serial); 7839 %} 7840 7841 instruct unnecessary_membar_volatile() %{ 7842 predicate(unnecessary_volatile(n)); 7843 match(MemBarVolatile); 7844 ins_cost(0); 7845 7846 format %{ "membar_volatile (elided)" %} 7847 7848 ins_encode %{ 7849 __ block_comment("membar_volatile (elided)"); 7850 %} 7851 7852 ins_pipe(pipe_serial); 7853 %} 7854 7855 instruct membar_volatile() %{ 7856 match(MemBarVolatile); 7857 ins_cost(VOLATILE_REF_COST*100); 7858 7859 format %{ "membar_volatile\n\t" 7860 "dmb ish"%} 7861 7862 ins_encode %{ 7863 __ block_comment("membar_volatile"); 7864 __ membar(Assembler::StoreLoad); 7865 %} 7866 7867 ins_pipe(pipe_serial); 7868 %} 7869 7870 // ============================================================================ 7871 // Cast/Convert Instructions 7872 7873 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7874 match(Set dst (CastX2P src)); 7875 7876 ins_cost(INSN_COST); 7877 format %{ "mov $dst, $src\t# long -> ptr" %} 7878 7879 ins_encode %{ 7880 if ($dst$$reg != $src$$reg) { 7881 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7882 } 7883 %} 7884 7885 ins_pipe(ialu_reg); 7886 %} 7887 7888 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7889 match(Set dst (CastP2X src)); 7890 7891 ins_cost(INSN_COST); 7892 format %{ "mov $dst, $src\t# ptr -> long" %} 7893 7894 ins_encode %{ 7895 if ($dst$$reg != $src$$reg) { 7896 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7897 } 7898 %} 7899 7900 ins_pipe(ialu_reg); 7901 %} 7902 7903 // Convert oop into int for vectors alignment masking 7904 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7905 match(Set dst (ConvL2I (CastP2X src))); 7906 7907 ins_cost(INSN_COST); 7908 format %{ "movw $dst, $src\t# ptr -> int" %} 7909 ins_encode %{ 7910 __ movw($dst$$Register, $src$$Register); 7911 %} 7912 7913 ins_pipe(ialu_reg); 7914 %} 7915 7916 // Convert compressed oop into int for vectors alignment masking 7917 // in case of 32bit oops (heap < 4Gb). 7918 instruct convN2I(iRegINoSp dst, iRegN src) 7919 %{ 7920 predicate(Universe::narrow_oop_shift() == 0); 7921 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7922 7923 ins_cost(INSN_COST); 7924 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7925 ins_encode %{ 7926 __ movw($dst$$Register, $src$$Register); 7927 %} 7928 7929 ins_pipe(ialu_reg); 7930 %} 7931 7932 7933 // Convert oop pointer into compressed form 7934 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7935 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7936 match(Set dst (EncodeP src)); 7937 effect(KILL cr); 7938 ins_cost(INSN_COST * 3); 7939 format %{ "encode_heap_oop $dst, $src" %} 7940 ins_encode %{ 7941 Register s = $src$$Register; 7942 Register d = $dst$$Register; 7943 __ encode_heap_oop(d, s); 7944 %} 7945 ins_pipe(ialu_reg); 7946 %} 7947 7948 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7949 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7950 match(Set dst (EncodeP src)); 7951 ins_cost(INSN_COST * 3); 7952 format %{ "encode_heap_oop_not_null $dst, $src" %} 7953 ins_encode %{ 7954 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7955 %} 7956 ins_pipe(ialu_reg); 7957 %} 7958 7959 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7960 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7961 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7962 match(Set dst (DecodeN src)); 7963 ins_cost(INSN_COST * 3); 7964 format %{ "decode_heap_oop $dst, $src" %} 7965 ins_encode %{ 7966 Register s = $src$$Register; 7967 Register d = $dst$$Register; 7968 __ decode_heap_oop(d, s); 7969 %} 7970 ins_pipe(ialu_reg); 7971 %} 7972 7973 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7974 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7975 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7976 match(Set dst (DecodeN src)); 7977 ins_cost(INSN_COST * 3); 7978 format %{ "decode_heap_oop_not_null $dst, $src" %} 7979 ins_encode %{ 7980 Register s = $src$$Register; 7981 Register d = $dst$$Register; 7982 __ decode_heap_oop_not_null(d, s); 7983 %} 7984 ins_pipe(ialu_reg); 7985 %} 7986 7987 // n.b. AArch64 implementations of encode_klass_not_null and 7988 // decode_klass_not_null do not modify the flags register so, unlike 7989 // Intel, we don't kill CR as a side effect here 7990 7991 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7992 match(Set dst (EncodePKlass src)); 7993 7994 ins_cost(INSN_COST * 3); 7995 format %{ "encode_klass_not_null $dst,$src" %} 7996 7997 ins_encode %{ 7998 Register src_reg = as_Register($src$$reg); 7999 Register dst_reg = as_Register($dst$$reg); 8000 __ encode_klass_not_null(dst_reg, src_reg); 8001 %} 8002 8003 ins_pipe(ialu_reg); 8004 %} 8005 8006 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8007 match(Set dst (DecodeNKlass src)); 8008 8009 ins_cost(INSN_COST * 3); 8010 format %{ "decode_klass_not_null $dst,$src" %} 8011 8012 ins_encode %{ 8013 Register src_reg = as_Register($src$$reg); 8014 Register dst_reg = as_Register($dst$$reg); 8015 if (dst_reg != src_reg) { 8016 __ decode_klass_not_null(dst_reg, src_reg); 8017 } else { 8018 __ decode_klass_not_null(dst_reg); 8019 } 8020 %} 8021 8022 ins_pipe(ialu_reg); 8023 %} 8024 8025 instruct checkCastPP(iRegPNoSp dst) 8026 %{ 8027 match(Set dst (CheckCastPP dst)); 8028 8029 size(0); 8030 format %{ "# checkcastPP of $dst" %} 8031 ins_encode(/* empty encoding */); 8032 ins_pipe(pipe_class_empty); 8033 %} 8034 8035 instruct castPP(iRegPNoSp dst) 8036 %{ 8037 match(Set dst (CastPP dst)); 8038 8039 size(0); 8040 format %{ "# castPP of $dst" %} 8041 ins_encode(/* empty encoding */); 8042 ins_pipe(pipe_class_empty); 8043 %} 8044 8045 instruct castII(iRegI dst) 8046 %{ 8047 match(Set dst (CastII dst)); 8048 8049 size(0); 8050 format %{ "# castII of $dst" %} 8051 ins_encode(/* empty encoding */); 8052 ins_cost(0); 8053 ins_pipe(pipe_class_empty); 8054 %} 8055 8056 // ============================================================================ 8057 // Atomic operation instructions 8058 // 8059 // Intel and SPARC both implement Ideal Node LoadPLocked and 8060 // Store{PIL}Conditional instructions using a normal load for the 8061 // LoadPLocked and a CAS for the Store{PIL}Conditional. 8062 // 8063 // The ideal code appears only to use LoadPLocked/StorePLocked as a 8064 // pair to lock object allocations from Eden space when not using 8065 // TLABs. 8066 // 8067 // There does not appear to be a Load{IL}Locked Ideal Node and the 8068 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 8069 // and to use StoreIConditional only for 32-bit and StoreLConditional 8070 // only for 64-bit. 8071 // 8072 // We implement LoadPLocked and StorePLocked instructions using, 8073 // respectively the AArch64 hw load-exclusive and store-conditional 8074 // instructions. Whereas we must implement each of 8075 // Store{IL}Conditional using a CAS which employs a pair of 8076 // instructions comprising a load-exclusive followed by a 8077 // store-conditional. 8078 8079 8080 // Locked-load (linked load) of the current heap-top 8081 // used when updating the eden heap top 8082 // implemented using ldaxr on AArch64 8083 8084 instruct loadPLocked(iRegPNoSp dst, indirect mem) 8085 %{ 8086 match(Set dst (LoadPLocked mem)); 8087 8088 ins_cost(VOLATILE_REF_COST); 8089 8090 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8091 8092 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8093 8094 ins_pipe(pipe_serial); 8095 %} 8096 8097 // Conditional-store of the updated heap-top. 8098 // Used during allocation of the shared heap. 8099 // Sets flag (EQ) on success. 8100 // implemented using stlxr on AArch64. 8101 8102 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8103 %{ 8104 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8105 8106 ins_cost(VOLATILE_REF_COST); 8107 8108 // TODO 8109 // do we need to do a store-conditional release or can we just use a 8110 // plain store-conditional? 8111 8112 format %{ 8113 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8114 "cmpw rscratch1, zr\t# EQ on successful write" 8115 %} 8116 8117 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8118 8119 ins_pipe(pipe_serial); 8120 %} 8121 8122 8123 // storeLConditional is used by PhaseMacroExpand::expand_lock_node 8124 // when attempting to rebias a lock towards the current thread. We 8125 // must use the acquire form of cmpxchg in order to guarantee acquire 8126 // semantics in this case. 8127 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8128 %{ 8129 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8130 8131 ins_cost(VOLATILE_REF_COST); 8132 8133 format %{ 8134 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8135 "cmpw rscratch1, zr\t# EQ on successful write" 8136 %} 8137 8138 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8139 8140 ins_pipe(pipe_slow); 8141 %} 8142 8143 // storeIConditional also has acquire semantics, for no better reason 8144 // than matching storeLConditional. At the time of writing this 8145 // comment storeIConditional was not used anywhere by AArch64. 8146 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8147 %{ 8148 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8149 8150 ins_cost(VOLATILE_REF_COST); 8151 8152 format %{ 8153 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8154 "cmpw rscratch1, zr\t# EQ on successful write" 8155 %} 8156 8157 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8158 8159 ins_pipe(pipe_slow); 8160 %} 8161 8162 // standard CompareAndSwapX when we are using barriers 8163 // these have higher priority than the rules selected by a predicate 8164 8165 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8166 // can't match them 8167 8168 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8169 8170 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8171 ins_cost(2 * VOLATILE_REF_COST); 8172 8173 effect(KILL cr); 8174 8175 format %{ 8176 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8177 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8178 %} 8179 8180 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8181 aarch64_enc_cset_eq(res)); 8182 8183 ins_pipe(pipe_slow); 8184 %} 8185 8186 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8187 8188 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8189 ins_cost(2 * VOLATILE_REF_COST); 8190 8191 effect(KILL cr); 8192 8193 format %{ 8194 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8195 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8196 %} 8197 8198 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8199 aarch64_enc_cset_eq(res)); 8200 8201 ins_pipe(pipe_slow); 8202 %} 8203 8204 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8205 8206 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8207 ins_cost(2 * VOLATILE_REF_COST); 8208 8209 effect(KILL cr); 8210 8211 format %{ 8212 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8213 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8214 %} 8215 8216 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8217 aarch64_enc_cset_eq(res)); 8218 8219 ins_pipe(pipe_slow); 8220 %} 8221 8222 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8223 8224 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8225 ins_cost(2 * VOLATILE_REF_COST); 8226 8227 effect(KILL cr); 8228 8229 format %{ 8230 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8231 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8232 %} 8233 8234 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8235 aarch64_enc_cset_eq(res)); 8236 8237 ins_pipe(pipe_slow); 8238 %} 8239 8240 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8241 8242 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8243 ins_cost(2 * VOLATILE_REF_COST); 8244 8245 effect(KILL cr); 8246 8247 format %{ 8248 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8249 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8250 %} 8251 8252 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8253 aarch64_enc_cset_eq(res)); 8254 8255 ins_pipe(pipe_slow); 8256 %} 8257 8258 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8259 8260 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8261 ins_cost(2 * VOLATILE_REF_COST); 8262 8263 effect(KILL cr); 8264 8265 format %{ 8266 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8267 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8268 %} 8269 8270 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8271 aarch64_enc_cset_eq(res)); 8272 8273 ins_pipe(pipe_slow); 8274 %} 8275 8276 // alternative CompareAndSwapX when we are eliding barriers 8277 8278 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8279 8280 predicate(needs_acquiring_load_exclusive(n)); 8281 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8282 ins_cost(VOLATILE_REF_COST); 8283 8284 effect(KILL cr); 8285 8286 format %{ 8287 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8288 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8289 %} 8290 8291 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8292 aarch64_enc_cset_eq(res)); 8293 8294 ins_pipe(pipe_slow); 8295 %} 8296 8297 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8298 8299 predicate(needs_acquiring_load_exclusive(n)); 8300 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8301 ins_cost(VOLATILE_REF_COST); 8302 8303 effect(KILL cr); 8304 8305 format %{ 8306 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8307 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8308 %} 8309 8310 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8311 aarch64_enc_cset_eq(res)); 8312 8313 ins_pipe(pipe_slow); 8314 %} 8315 8316 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8317 8318 predicate(needs_acquiring_load_exclusive(n)); 8319 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8320 ins_cost(VOLATILE_REF_COST); 8321 8322 effect(KILL cr); 8323 8324 format %{ 8325 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8326 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8327 %} 8328 8329 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8330 aarch64_enc_cset_eq(res)); 8331 8332 ins_pipe(pipe_slow); 8333 %} 8334 8335 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8336 8337 predicate(needs_acquiring_load_exclusive(n)); 8338 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8339 ins_cost(VOLATILE_REF_COST); 8340 8341 effect(KILL cr); 8342 8343 format %{ 8344 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8345 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8346 %} 8347 8348 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8349 aarch64_enc_cset_eq(res)); 8350 8351 ins_pipe(pipe_slow); 8352 %} 8353 8354 8355 // --------------------------------------------------------------------- 8356 8357 8358 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8359 8360 // Sundry CAS operations. Note that release is always true, 8361 // regardless of the memory ordering of the CAS. This is because we 8362 // need the volatile case to be sequentially consistent but there is 8363 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8364 // can't check the type of memory ordering here, so we always emit a 8365 // STLXR. 8366 8367 // This section is generated from aarch64_ad_cas.m4 8368 8369 8370 8371 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8372 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8373 ins_cost(2 * VOLATILE_REF_COST); 8374 effect(TEMP_DEF res, KILL cr); 8375 format %{ 8376 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8377 %} 8378 ins_encode %{ 8379 __ uxtbw(rscratch2, $oldval$$Register); 8380 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8381 Assembler::byte, /*acquire*/ false, /*release*/ true, 8382 /*weak*/ false, $res$$Register); 8383 __ sxtbw($res$$Register, $res$$Register); 8384 %} 8385 ins_pipe(pipe_slow); 8386 %} 8387 8388 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8389 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8390 ins_cost(2 * VOLATILE_REF_COST); 8391 effect(TEMP_DEF res, KILL cr); 8392 format %{ 8393 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8394 %} 8395 ins_encode %{ 8396 __ uxthw(rscratch2, $oldval$$Register); 8397 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8398 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8399 /*weak*/ false, $res$$Register); 8400 __ sxthw($res$$Register, $res$$Register); 8401 %} 8402 ins_pipe(pipe_slow); 8403 %} 8404 8405 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8406 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8407 ins_cost(2 * VOLATILE_REF_COST); 8408 effect(TEMP_DEF res, KILL cr); 8409 format %{ 8410 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8411 %} 8412 ins_encode %{ 8413 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8414 Assembler::word, /*acquire*/ false, /*release*/ true, 8415 /*weak*/ false, $res$$Register); 8416 %} 8417 ins_pipe(pipe_slow); 8418 %} 8419 8420 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8421 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8422 ins_cost(2 * VOLATILE_REF_COST); 8423 effect(TEMP_DEF res, KILL cr); 8424 format %{ 8425 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8426 %} 8427 ins_encode %{ 8428 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8429 Assembler::xword, /*acquire*/ false, /*release*/ true, 8430 /*weak*/ false, $res$$Register); 8431 %} 8432 ins_pipe(pipe_slow); 8433 %} 8434 8435 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8436 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8437 ins_cost(2 * VOLATILE_REF_COST); 8438 effect(TEMP_DEF res, KILL cr); 8439 format %{ 8440 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8441 %} 8442 ins_encode %{ 8443 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8444 Assembler::word, /*acquire*/ false, /*release*/ true, 8445 /*weak*/ false, $res$$Register); 8446 %} 8447 ins_pipe(pipe_slow); 8448 %} 8449 8450 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8451 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8452 ins_cost(2 * VOLATILE_REF_COST); 8453 effect(TEMP_DEF res, KILL cr); 8454 format %{ 8455 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8456 %} 8457 ins_encode %{ 8458 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8459 Assembler::xword, /*acquire*/ false, /*release*/ true, 8460 /*weak*/ false, $res$$Register); 8461 %} 8462 ins_pipe(pipe_slow); 8463 %} 8464 8465 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8466 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8467 ins_cost(2 * VOLATILE_REF_COST); 8468 effect(KILL cr); 8469 format %{ 8470 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8471 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8472 %} 8473 ins_encode %{ 8474 __ uxtbw(rscratch2, $oldval$$Register); 8475 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8476 Assembler::byte, /*acquire*/ false, /*release*/ true, 8477 /*weak*/ true, noreg); 8478 __ csetw($res$$Register, Assembler::EQ); 8479 %} 8480 ins_pipe(pipe_slow); 8481 %} 8482 8483 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8484 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8485 ins_cost(2 * VOLATILE_REF_COST); 8486 effect(KILL cr); 8487 format %{ 8488 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8489 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8490 %} 8491 ins_encode %{ 8492 __ uxthw(rscratch2, $oldval$$Register); 8493 __ cmpxchg($mem$$Register, rscratch2, $newval$$Register, 8494 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8495 /*weak*/ true, noreg); 8496 __ csetw($res$$Register, Assembler::EQ); 8497 %} 8498 ins_pipe(pipe_slow); 8499 %} 8500 8501 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8502 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8503 ins_cost(2 * VOLATILE_REF_COST); 8504 effect(KILL cr); 8505 format %{ 8506 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8507 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8508 %} 8509 ins_encode %{ 8510 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8511 Assembler::word, /*acquire*/ false, /*release*/ true, 8512 /*weak*/ true, noreg); 8513 __ csetw($res$$Register, Assembler::EQ); 8514 %} 8515 ins_pipe(pipe_slow); 8516 %} 8517 8518 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8519 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8520 ins_cost(2 * VOLATILE_REF_COST); 8521 effect(KILL cr); 8522 format %{ 8523 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8524 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8525 %} 8526 ins_encode %{ 8527 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8528 Assembler::xword, /*acquire*/ false, /*release*/ true, 8529 /*weak*/ true, noreg); 8530 __ csetw($res$$Register, Assembler::EQ); 8531 %} 8532 ins_pipe(pipe_slow); 8533 %} 8534 8535 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8536 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8537 ins_cost(2 * VOLATILE_REF_COST); 8538 effect(KILL cr); 8539 format %{ 8540 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8541 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8542 %} 8543 ins_encode %{ 8544 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8545 Assembler::word, /*acquire*/ false, /*release*/ true, 8546 /*weak*/ true, noreg); 8547 __ csetw($res$$Register, Assembler::EQ); 8548 %} 8549 ins_pipe(pipe_slow); 8550 %} 8551 8552 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8553 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8554 ins_cost(2 * VOLATILE_REF_COST); 8555 effect(KILL cr); 8556 format %{ 8557 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8558 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8559 %} 8560 ins_encode %{ 8561 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8562 Assembler::xword, /*acquire*/ false, /*release*/ true, 8563 /*weak*/ true, noreg); 8564 __ csetw($res$$Register, Assembler::EQ); 8565 %} 8566 ins_pipe(pipe_slow); 8567 %} 8568 8569 // END This section of the file is automatically generated. Do not edit -------------- 8570 // --------------------------------------------------------------------- 8571 8572 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8573 match(Set prev (GetAndSetI mem newv)); 8574 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8575 ins_encode %{ 8576 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8577 %} 8578 ins_pipe(pipe_serial); 8579 %} 8580 8581 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8582 match(Set prev (GetAndSetL mem newv)); 8583 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8584 ins_encode %{ 8585 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8586 %} 8587 ins_pipe(pipe_serial); 8588 %} 8589 8590 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8591 match(Set prev (GetAndSetN mem newv)); 8592 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8593 ins_encode %{ 8594 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8595 %} 8596 ins_pipe(pipe_serial); 8597 %} 8598 8599 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8600 match(Set prev (GetAndSetP mem newv)); 8601 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8602 ins_encode %{ 8603 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8604 %} 8605 ins_pipe(pipe_serial); 8606 %} 8607 8608 8609 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8610 match(Set newval (GetAndAddL mem incr)); 8611 ins_cost(INSN_COST * 10); 8612 format %{ "get_and_addL $newval, [$mem], $incr" %} 8613 ins_encode %{ 8614 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8615 %} 8616 ins_pipe(pipe_serial); 8617 %} 8618 8619 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8620 predicate(n->as_LoadStore()->result_not_used()); 8621 match(Set dummy (GetAndAddL mem incr)); 8622 ins_cost(INSN_COST * 9); 8623 format %{ "get_and_addL [$mem], $incr" %} 8624 ins_encode %{ 8625 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8626 %} 8627 ins_pipe(pipe_serial); 8628 %} 8629 8630 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8631 match(Set newval (GetAndAddL mem incr)); 8632 ins_cost(INSN_COST * 10); 8633 format %{ "get_and_addL $newval, [$mem], $incr" %} 8634 ins_encode %{ 8635 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8636 %} 8637 ins_pipe(pipe_serial); 8638 %} 8639 8640 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8641 predicate(n->as_LoadStore()->result_not_used()); 8642 match(Set dummy (GetAndAddL mem incr)); 8643 ins_cost(INSN_COST * 9); 8644 format %{ "get_and_addL [$mem], $incr" %} 8645 ins_encode %{ 8646 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8647 %} 8648 ins_pipe(pipe_serial); 8649 %} 8650 8651 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8652 match(Set newval (GetAndAddI mem incr)); 8653 ins_cost(INSN_COST * 10); 8654 format %{ "get_and_addI $newval, [$mem], $incr" %} 8655 ins_encode %{ 8656 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8657 %} 8658 ins_pipe(pipe_serial); 8659 %} 8660 8661 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8662 predicate(n->as_LoadStore()->result_not_used()); 8663 match(Set dummy (GetAndAddI mem incr)); 8664 ins_cost(INSN_COST * 9); 8665 format %{ "get_and_addI [$mem], $incr" %} 8666 ins_encode %{ 8667 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8668 %} 8669 ins_pipe(pipe_serial); 8670 %} 8671 8672 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8673 match(Set newval (GetAndAddI mem incr)); 8674 ins_cost(INSN_COST * 10); 8675 format %{ "get_and_addI $newval, [$mem], $incr" %} 8676 ins_encode %{ 8677 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8678 %} 8679 ins_pipe(pipe_serial); 8680 %} 8681 8682 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8683 predicate(n->as_LoadStore()->result_not_used()); 8684 match(Set dummy (GetAndAddI mem incr)); 8685 ins_cost(INSN_COST * 9); 8686 format %{ "get_and_addI [$mem], $incr" %} 8687 ins_encode %{ 8688 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8689 %} 8690 ins_pipe(pipe_serial); 8691 %} 8692 8693 // Manifest a CmpL result in an integer register. 8694 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8695 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8696 %{ 8697 match(Set dst (CmpL3 src1 src2)); 8698 effect(KILL flags); 8699 8700 ins_cost(INSN_COST * 6); 8701 format %{ 8702 "cmp $src1, $src2" 8703 "csetw $dst, ne" 8704 "cnegw $dst, lt" 8705 %} 8706 // format %{ "CmpL3 $dst, $src1, $src2" %} 8707 ins_encode %{ 8708 __ cmp($src1$$Register, $src2$$Register); 8709 __ csetw($dst$$Register, Assembler::NE); 8710 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8711 %} 8712 8713 ins_pipe(pipe_class_default); 8714 %} 8715 8716 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8717 %{ 8718 match(Set dst (CmpL3 src1 src2)); 8719 effect(KILL flags); 8720 8721 ins_cost(INSN_COST * 6); 8722 format %{ 8723 "cmp $src1, $src2" 8724 "csetw $dst, ne" 8725 "cnegw $dst, lt" 8726 %} 8727 ins_encode %{ 8728 int32_t con = (int32_t)$src2$$constant; 8729 if (con < 0) { 8730 __ adds(zr, $src1$$Register, -con); 8731 } else { 8732 __ subs(zr, $src1$$Register, con); 8733 } 8734 __ csetw($dst$$Register, Assembler::NE); 8735 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8736 %} 8737 8738 ins_pipe(pipe_class_default); 8739 %} 8740 8741 // ============================================================================ 8742 // Conditional Move Instructions 8743 8744 // n.b. we have identical rules for both a signed compare op (cmpOp) 8745 // and an unsigned compare op (cmpOpU). it would be nice if we could 8746 // define an op class which merged both inputs and use it to type the 8747 // argument to a single rule. unfortunatelyt his fails because the 8748 // opclass does not live up to the COND_INTER interface of its 8749 // component operands. When the generic code tries to negate the 8750 // operand it ends up running the generci Machoper::negate method 8751 // which throws a ShouldNotHappen. So, we have to provide two flavours 8752 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 8753 8754 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8755 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8756 8757 ins_cost(INSN_COST * 2); 8758 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 8759 8760 ins_encode %{ 8761 __ cselw(as_Register($dst$$reg), 8762 as_Register($src2$$reg), 8763 as_Register($src1$$reg), 8764 (Assembler::Condition)$cmp$$cmpcode); 8765 %} 8766 8767 ins_pipe(icond_reg_reg); 8768 %} 8769 8770 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8771 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8772 8773 ins_cost(INSN_COST * 2); 8774 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 8775 8776 ins_encode %{ 8777 __ cselw(as_Register($dst$$reg), 8778 as_Register($src2$$reg), 8779 as_Register($src1$$reg), 8780 (Assembler::Condition)$cmp$$cmpcode); 8781 %} 8782 8783 ins_pipe(icond_reg_reg); 8784 %} 8785 8786 // special cases where one arg is zero 8787 8788 // n.b. this is selected in preference to the rule above because it 8789 // avoids loading constant 0 into a source register 8790 8791 // TODO 8792 // we ought only to be able to cull one of these variants as the ideal 8793 // transforms ought always to order the zero consistently (to left/right?) 8794 8795 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8796 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8797 8798 ins_cost(INSN_COST * 2); 8799 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 8800 8801 ins_encode %{ 8802 __ cselw(as_Register($dst$$reg), 8803 as_Register($src$$reg), 8804 zr, 8805 (Assembler::Condition)$cmp$$cmpcode); 8806 %} 8807 8808 ins_pipe(icond_reg); 8809 %} 8810 8811 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8812 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8813 8814 ins_cost(INSN_COST * 2); 8815 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 8816 8817 ins_encode %{ 8818 __ cselw(as_Register($dst$$reg), 8819 as_Register($src$$reg), 8820 zr, 8821 (Assembler::Condition)$cmp$$cmpcode); 8822 %} 8823 8824 ins_pipe(icond_reg); 8825 %} 8826 8827 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8828 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8829 8830 ins_cost(INSN_COST * 2); 8831 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 8832 8833 ins_encode %{ 8834 __ cselw(as_Register($dst$$reg), 8835 zr, 8836 as_Register($src$$reg), 8837 (Assembler::Condition)$cmp$$cmpcode); 8838 %} 8839 8840 ins_pipe(icond_reg); 8841 %} 8842 8843 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8844 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8845 8846 ins_cost(INSN_COST * 2); 8847 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 8848 8849 ins_encode %{ 8850 __ cselw(as_Register($dst$$reg), 8851 zr, 8852 as_Register($src$$reg), 8853 (Assembler::Condition)$cmp$$cmpcode); 8854 %} 8855 8856 ins_pipe(icond_reg); 8857 %} 8858 8859 // special case for creating a boolean 0 or 1 8860 8861 // n.b. this is selected in preference to the rule above because it 8862 // avoids loading constants 0 and 1 into a source register 8863 8864 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8865 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8866 8867 ins_cost(INSN_COST * 2); 8868 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 8869 8870 ins_encode %{ 8871 // equivalently 8872 // cset(as_Register($dst$$reg), 8873 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8874 __ csincw(as_Register($dst$$reg), 8875 zr, 8876 zr, 8877 (Assembler::Condition)$cmp$$cmpcode); 8878 %} 8879 8880 ins_pipe(icond_none); 8881 %} 8882 8883 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8884 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8885 8886 ins_cost(INSN_COST * 2); 8887 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 8888 8889 ins_encode %{ 8890 // equivalently 8891 // cset(as_Register($dst$$reg), 8892 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8893 __ csincw(as_Register($dst$$reg), 8894 zr, 8895 zr, 8896 (Assembler::Condition)$cmp$$cmpcode); 8897 %} 8898 8899 ins_pipe(icond_none); 8900 %} 8901 8902 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8903 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8904 8905 ins_cost(INSN_COST * 2); 8906 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 8907 8908 ins_encode %{ 8909 __ csel(as_Register($dst$$reg), 8910 as_Register($src2$$reg), 8911 as_Register($src1$$reg), 8912 (Assembler::Condition)$cmp$$cmpcode); 8913 %} 8914 8915 ins_pipe(icond_reg_reg); 8916 %} 8917 8918 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8919 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8920 8921 ins_cost(INSN_COST * 2); 8922 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 8923 8924 ins_encode %{ 8925 __ csel(as_Register($dst$$reg), 8926 as_Register($src2$$reg), 8927 as_Register($src1$$reg), 8928 (Assembler::Condition)$cmp$$cmpcode); 8929 %} 8930 8931 ins_pipe(icond_reg_reg); 8932 %} 8933 8934 // special cases where one arg is zero 8935 8936 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8937 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8938 8939 ins_cost(INSN_COST * 2); 8940 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 8941 8942 ins_encode %{ 8943 __ csel(as_Register($dst$$reg), 8944 zr, 8945 as_Register($src$$reg), 8946 (Assembler::Condition)$cmp$$cmpcode); 8947 %} 8948 8949 ins_pipe(icond_reg); 8950 %} 8951 8952 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8953 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8954 8955 ins_cost(INSN_COST * 2); 8956 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 8957 8958 ins_encode %{ 8959 __ csel(as_Register($dst$$reg), 8960 zr, 8961 as_Register($src$$reg), 8962 (Assembler::Condition)$cmp$$cmpcode); 8963 %} 8964 8965 ins_pipe(icond_reg); 8966 %} 8967 8968 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8969 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8970 8971 ins_cost(INSN_COST * 2); 8972 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 8973 8974 ins_encode %{ 8975 __ csel(as_Register($dst$$reg), 8976 as_Register($src$$reg), 8977 zr, 8978 (Assembler::Condition)$cmp$$cmpcode); 8979 %} 8980 8981 ins_pipe(icond_reg); 8982 %} 8983 8984 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8985 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8986 8987 ins_cost(INSN_COST * 2); 8988 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 8989 8990 ins_encode %{ 8991 __ csel(as_Register($dst$$reg), 8992 as_Register($src$$reg), 8993 zr, 8994 (Assembler::Condition)$cmp$$cmpcode); 8995 %} 8996 8997 ins_pipe(icond_reg); 8998 %} 8999 9000 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9001 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9002 9003 ins_cost(INSN_COST * 2); 9004 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9005 9006 ins_encode %{ 9007 __ csel(as_Register($dst$$reg), 9008 as_Register($src2$$reg), 9009 as_Register($src1$$reg), 9010 (Assembler::Condition)$cmp$$cmpcode); 9011 %} 9012 9013 ins_pipe(icond_reg_reg); 9014 %} 9015 9016 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9017 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9018 9019 ins_cost(INSN_COST * 2); 9020 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9021 9022 ins_encode %{ 9023 __ csel(as_Register($dst$$reg), 9024 as_Register($src2$$reg), 9025 as_Register($src1$$reg), 9026 (Assembler::Condition)$cmp$$cmpcode); 9027 %} 9028 9029 ins_pipe(icond_reg_reg); 9030 %} 9031 9032 // special cases where one arg is zero 9033 9034 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9035 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9036 9037 ins_cost(INSN_COST * 2); 9038 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9039 9040 ins_encode %{ 9041 __ csel(as_Register($dst$$reg), 9042 zr, 9043 as_Register($src$$reg), 9044 (Assembler::Condition)$cmp$$cmpcode); 9045 %} 9046 9047 ins_pipe(icond_reg); 9048 %} 9049 9050 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9051 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9052 9053 ins_cost(INSN_COST * 2); 9054 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9055 9056 ins_encode %{ 9057 __ csel(as_Register($dst$$reg), 9058 zr, 9059 as_Register($src$$reg), 9060 (Assembler::Condition)$cmp$$cmpcode); 9061 %} 9062 9063 ins_pipe(icond_reg); 9064 %} 9065 9066 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9067 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9068 9069 ins_cost(INSN_COST * 2); 9070 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9071 9072 ins_encode %{ 9073 __ csel(as_Register($dst$$reg), 9074 as_Register($src$$reg), 9075 zr, 9076 (Assembler::Condition)$cmp$$cmpcode); 9077 %} 9078 9079 ins_pipe(icond_reg); 9080 %} 9081 9082 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9083 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9084 9085 ins_cost(INSN_COST * 2); 9086 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9087 9088 ins_encode %{ 9089 __ csel(as_Register($dst$$reg), 9090 as_Register($src$$reg), 9091 zr, 9092 (Assembler::Condition)$cmp$$cmpcode); 9093 %} 9094 9095 ins_pipe(icond_reg); 9096 %} 9097 9098 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9099 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9100 9101 ins_cost(INSN_COST * 2); 9102 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9103 9104 ins_encode %{ 9105 __ cselw(as_Register($dst$$reg), 9106 as_Register($src2$$reg), 9107 as_Register($src1$$reg), 9108 (Assembler::Condition)$cmp$$cmpcode); 9109 %} 9110 9111 ins_pipe(icond_reg_reg); 9112 %} 9113 9114 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9115 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9116 9117 ins_cost(INSN_COST * 2); 9118 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9119 9120 ins_encode %{ 9121 __ cselw(as_Register($dst$$reg), 9122 as_Register($src2$$reg), 9123 as_Register($src1$$reg), 9124 (Assembler::Condition)$cmp$$cmpcode); 9125 %} 9126 9127 ins_pipe(icond_reg_reg); 9128 %} 9129 9130 // special cases where one arg is zero 9131 9132 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9133 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9134 9135 ins_cost(INSN_COST * 2); 9136 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9137 9138 ins_encode %{ 9139 __ cselw(as_Register($dst$$reg), 9140 zr, 9141 as_Register($src$$reg), 9142 (Assembler::Condition)$cmp$$cmpcode); 9143 %} 9144 9145 ins_pipe(icond_reg); 9146 %} 9147 9148 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9149 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9150 9151 ins_cost(INSN_COST * 2); 9152 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9153 9154 ins_encode %{ 9155 __ cselw(as_Register($dst$$reg), 9156 zr, 9157 as_Register($src$$reg), 9158 (Assembler::Condition)$cmp$$cmpcode); 9159 %} 9160 9161 ins_pipe(icond_reg); 9162 %} 9163 9164 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9165 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9166 9167 ins_cost(INSN_COST * 2); 9168 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9169 9170 ins_encode %{ 9171 __ cselw(as_Register($dst$$reg), 9172 as_Register($src$$reg), 9173 zr, 9174 (Assembler::Condition)$cmp$$cmpcode); 9175 %} 9176 9177 ins_pipe(icond_reg); 9178 %} 9179 9180 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9181 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9182 9183 ins_cost(INSN_COST * 2); 9184 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9185 9186 ins_encode %{ 9187 __ cselw(as_Register($dst$$reg), 9188 as_Register($src$$reg), 9189 zr, 9190 (Assembler::Condition)$cmp$$cmpcode); 9191 %} 9192 9193 ins_pipe(icond_reg); 9194 %} 9195 9196 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9197 %{ 9198 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9199 9200 ins_cost(INSN_COST * 3); 9201 9202 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9203 ins_encode %{ 9204 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9205 __ fcsels(as_FloatRegister($dst$$reg), 9206 as_FloatRegister($src2$$reg), 9207 as_FloatRegister($src1$$reg), 9208 cond); 9209 %} 9210 9211 ins_pipe(fp_cond_reg_reg_s); 9212 %} 9213 9214 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9215 %{ 9216 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9217 9218 ins_cost(INSN_COST * 3); 9219 9220 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9221 ins_encode %{ 9222 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9223 __ fcsels(as_FloatRegister($dst$$reg), 9224 as_FloatRegister($src2$$reg), 9225 as_FloatRegister($src1$$reg), 9226 cond); 9227 %} 9228 9229 ins_pipe(fp_cond_reg_reg_s); 9230 %} 9231 9232 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9233 %{ 9234 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9235 9236 ins_cost(INSN_COST * 3); 9237 9238 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9239 ins_encode %{ 9240 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9241 __ fcseld(as_FloatRegister($dst$$reg), 9242 as_FloatRegister($src2$$reg), 9243 as_FloatRegister($src1$$reg), 9244 cond); 9245 %} 9246 9247 ins_pipe(fp_cond_reg_reg_d); 9248 %} 9249 9250 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9251 %{ 9252 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9253 9254 ins_cost(INSN_COST * 3); 9255 9256 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9257 ins_encode %{ 9258 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9259 __ fcseld(as_FloatRegister($dst$$reg), 9260 as_FloatRegister($src2$$reg), 9261 as_FloatRegister($src1$$reg), 9262 cond); 9263 %} 9264 9265 ins_pipe(fp_cond_reg_reg_d); 9266 %} 9267 9268 // ============================================================================ 9269 // Arithmetic Instructions 9270 // 9271 9272 // Integer Addition 9273 9274 // TODO 9275 // these currently employ operations which do not set CR and hence are 9276 // not flagged as killing CR but we would like to isolate the cases 9277 // where we want to set flags from those where we don't. need to work 9278 // out how to do that. 9279 9280 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9281 match(Set dst (AddI src1 src2)); 9282 9283 ins_cost(INSN_COST); 9284 format %{ "addw $dst, $src1, $src2" %} 9285 9286 ins_encode %{ 9287 __ addw(as_Register($dst$$reg), 9288 as_Register($src1$$reg), 9289 as_Register($src2$$reg)); 9290 %} 9291 9292 ins_pipe(ialu_reg_reg); 9293 %} 9294 9295 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9296 match(Set dst (AddI src1 src2)); 9297 9298 ins_cost(INSN_COST); 9299 format %{ "addw $dst, $src1, $src2" %} 9300 9301 // use opcode to indicate that this is an add not a sub 9302 opcode(0x0); 9303 9304 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9305 9306 ins_pipe(ialu_reg_imm); 9307 %} 9308 9309 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9310 match(Set dst (AddI (ConvL2I src1) src2)); 9311 9312 ins_cost(INSN_COST); 9313 format %{ "addw $dst, $src1, $src2" %} 9314 9315 // use opcode to indicate that this is an add not a sub 9316 opcode(0x0); 9317 9318 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9319 9320 ins_pipe(ialu_reg_imm); 9321 %} 9322 9323 // Pointer Addition 9324 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9325 match(Set dst (AddP src1 src2)); 9326 9327 ins_cost(INSN_COST); 9328 format %{ "add $dst, $src1, $src2\t# ptr" %} 9329 9330 ins_encode %{ 9331 __ add(as_Register($dst$$reg), 9332 as_Register($src1$$reg), 9333 as_Register($src2$$reg)); 9334 %} 9335 9336 ins_pipe(ialu_reg_reg); 9337 %} 9338 9339 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9340 match(Set dst (AddP src1 (ConvI2L src2))); 9341 9342 ins_cost(1.9 * INSN_COST); 9343 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9344 9345 ins_encode %{ 9346 __ add(as_Register($dst$$reg), 9347 as_Register($src1$$reg), 9348 as_Register($src2$$reg), ext::sxtw); 9349 %} 9350 9351 ins_pipe(ialu_reg_reg); 9352 %} 9353 9354 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9355 match(Set dst (AddP src1 (LShiftL src2 scale))); 9356 9357 ins_cost(1.9 * INSN_COST); 9358 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9359 9360 ins_encode %{ 9361 __ lea(as_Register($dst$$reg), 9362 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9363 Address::lsl($scale$$constant))); 9364 %} 9365 9366 ins_pipe(ialu_reg_reg_shift); 9367 %} 9368 9369 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9370 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9371 9372 ins_cost(1.9 * INSN_COST); 9373 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9374 9375 ins_encode %{ 9376 __ lea(as_Register($dst$$reg), 9377 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9378 Address::sxtw($scale$$constant))); 9379 %} 9380 9381 ins_pipe(ialu_reg_reg_shift); 9382 %} 9383 9384 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9385 match(Set dst (LShiftL (ConvI2L src) scale)); 9386 9387 ins_cost(INSN_COST); 9388 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9389 9390 ins_encode %{ 9391 __ sbfiz(as_Register($dst$$reg), 9392 as_Register($src$$reg), 9393 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 9394 %} 9395 9396 ins_pipe(ialu_reg_shift); 9397 %} 9398 9399 // Pointer Immediate Addition 9400 // n.b. this needs to be more expensive than using an indirect memory 9401 // operand 9402 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9403 match(Set dst (AddP src1 src2)); 9404 9405 ins_cost(INSN_COST); 9406 format %{ "add $dst, $src1, $src2\t# ptr" %} 9407 9408 // use opcode to indicate that this is an add not a sub 9409 opcode(0x0); 9410 9411 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9412 9413 ins_pipe(ialu_reg_imm); 9414 %} 9415 9416 // Long Addition 9417 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9418 9419 match(Set dst (AddL src1 src2)); 9420 9421 ins_cost(INSN_COST); 9422 format %{ "add $dst, $src1, $src2" %} 9423 9424 ins_encode %{ 9425 __ add(as_Register($dst$$reg), 9426 as_Register($src1$$reg), 9427 as_Register($src2$$reg)); 9428 %} 9429 9430 ins_pipe(ialu_reg_reg); 9431 %} 9432 9433 // No constant pool entries requiredLong Immediate Addition. 9434 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9435 match(Set dst (AddL src1 src2)); 9436 9437 ins_cost(INSN_COST); 9438 format %{ "add $dst, $src1, $src2" %} 9439 9440 // use opcode to indicate that this is an add not a sub 9441 opcode(0x0); 9442 9443 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9444 9445 ins_pipe(ialu_reg_imm); 9446 %} 9447 9448 // Integer Subtraction 9449 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9450 match(Set dst (SubI src1 src2)); 9451 9452 ins_cost(INSN_COST); 9453 format %{ "subw $dst, $src1, $src2" %} 9454 9455 ins_encode %{ 9456 __ subw(as_Register($dst$$reg), 9457 as_Register($src1$$reg), 9458 as_Register($src2$$reg)); 9459 %} 9460 9461 ins_pipe(ialu_reg_reg); 9462 %} 9463 9464 // Immediate Subtraction 9465 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9466 match(Set dst (SubI src1 src2)); 9467 9468 ins_cost(INSN_COST); 9469 format %{ "subw $dst, $src1, $src2" %} 9470 9471 // use opcode to indicate that this is a sub not an add 9472 opcode(0x1); 9473 9474 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9475 9476 ins_pipe(ialu_reg_imm); 9477 %} 9478 9479 // Long Subtraction 9480 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9481 9482 match(Set dst (SubL src1 src2)); 9483 9484 ins_cost(INSN_COST); 9485 format %{ "sub $dst, $src1, $src2" %} 9486 9487 ins_encode %{ 9488 __ sub(as_Register($dst$$reg), 9489 as_Register($src1$$reg), 9490 as_Register($src2$$reg)); 9491 %} 9492 9493 ins_pipe(ialu_reg_reg); 9494 %} 9495 9496 // No constant pool entries requiredLong Immediate Subtraction. 9497 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9498 match(Set dst (SubL src1 src2)); 9499 9500 ins_cost(INSN_COST); 9501 format %{ "sub$dst, $src1, $src2" %} 9502 9503 // use opcode to indicate that this is a sub not an add 9504 opcode(0x1); 9505 9506 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9507 9508 ins_pipe(ialu_reg_imm); 9509 %} 9510 9511 // Integer Negation (special case for sub) 9512 9513 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9514 match(Set dst (SubI zero src)); 9515 9516 ins_cost(INSN_COST); 9517 format %{ "negw $dst, $src\t# int" %} 9518 9519 ins_encode %{ 9520 __ negw(as_Register($dst$$reg), 9521 as_Register($src$$reg)); 9522 %} 9523 9524 ins_pipe(ialu_reg); 9525 %} 9526 9527 // Long Negation 9528 9529 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9530 match(Set dst (SubL zero src)); 9531 9532 ins_cost(INSN_COST); 9533 format %{ "neg $dst, $src\t# long" %} 9534 9535 ins_encode %{ 9536 __ neg(as_Register($dst$$reg), 9537 as_Register($src$$reg)); 9538 %} 9539 9540 ins_pipe(ialu_reg); 9541 %} 9542 9543 // Integer Multiply 9544 9545 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9546 match(Set dst (MulI src1 src2)); 9547 9548 ins_cost(INSN_COST * 3); 9549 format %{ "mulw $dst, $src1, $src2" %} 9550 9551 ins_encode %{ 9552 __ mulw(as_Register($dst$$reg), 9553 as_Register($src1$$reg), 9554 as_Register($src2$$reg)); 9555 %} 9556 9557 ins_pipe(imul_reg_reg); 9558 %} 9559 9560 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9561 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9562 9563 ins_cost(INSN_COST * 3); 9564 format %{ "smull $dst, $src1, $src2" %} 9565 9566 ins_encode %{ 9567 __ smull(as_Register($dst$$reg), 9568 as_Register($src1$$reg), 9569 as_Register($src2$$reg)); 9570 %} 9571 9572 ins_pipe(imul_reg_reg); 9573 %} 9574 9575 // Long Multiply 9576 9577 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9578 match(Set dst (MulL src1 src2)); 9579 9580 ins_cost(INSN_COST * 5); 9581 format %{ "mul $dst, $src1, $src2" %} 9582 9583 ins_encode %{ 9584 __ mul(as_Register($dst$$reg), 9585 as_Register($src1$$reg), 9586 as_Register($src2$$reg)); 9587 %} 9588 9589 ins_pipe(lmul_reg_reg); 9590 %} 9591 9592 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9593 %{ 9594 match(Set dst (MulHiL src1 src2)); 9595 9596 ins_cost(INSN_COST * 7); 9597 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9598 9599 ins_encode %{ 9600 __ smulh(as_Register($dst$$reg), 9601 as_Register($src1$$reg), 9602 as_Register($src2$$reg)); 9603 %} 9604 9605 ins_pipe(lmul_reg_reg); 9606 %} 9607 9608 // Combined Integer Multiply & Add/Sub 9609 9610 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9611 match(Set dst (AddI src3 (MulI src1 src2))); 9612 9613 ins_cost(INSN_COST * 3); 9614 format %{ "madd $dst, $src1, $src2, $src3" %} 9615 9616 ins_encode %{ 9617 __ maddw(as_Register($dst$$reg), 9618 as_Register($src1$$reg), 9619 as_Register($src2$$reg), 9620 as_Register($src3$$reg)); 9621 %} 9622 9623 ins_pipe(imac_reg_reg); 9624 %} 9625 9626 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9627 match(Set dst (SubI src3 (MulI src1 src2))); 9628 9629 ins_cost(INSN_COST * 3); 9630 format %{ "msub $dst, $src1, $src2, $src3" %} 9631 9632 ins_encode %{ 9633 __ msubw(as_Register($dst$$reg), 9634 as_Register($src1$$reg), 9635 as_Register($src2$$reg), 9636 as_Register($src3$$reg)); 9637 %} 9638 9639 ins_pipe(imac_reg_reg); 9640 %} 9641 9642 // Combined Integer Multiply & Neg 9643 9644 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 9645 match(Set dst (MulI (SubI zero src1) src2)); 9646 match(Set dst (MulI src1 (SubI zero src2))); 9647 9648 ins_cost(INSN_COST * 3); 9649 format %{ "mneg $dst, $src1, $src2" %} 9650 9651 ins_encode %{ 9652 __ mnegw(as_Register($dst$$reg), 9653 as_Register($src1$$reg), 9654 as_Register($src2$$reg)); 9655 %} 9656 9657 ins_pipe(imac_reg_reg); 9658 %} 9659 9660 // Combined Long Multiply & Add/Sub 9661 9662 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9663 match(Set dst (AddL src3 (MulL src1 src2))); 9664 9665 ins_cost(INSN_COST * 5); 9666 format %{ "madd $dst, $src1, $src2, $src3" %} 9667 9668 ins_encode %{ 9669 __ madd(as_Register($dst$$reg), 9670 as_Register($src1$$reg), 9671 as_Register($src2$$reg), 9672 as_Register($src3$$reg)); 9673 %} 9674 9675 ins_pipe(lmac_reg_reg); 9676 %} 9677 9678 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9679 match(Set dst (SubL src3 (MulL src1 src2))); 9680 9681 ins_cost(INSN_COST * 5); 9682 format %{ "msub $dst, $src1, $src2, $src3" %} 9683 9684 ins_encode %{ 9685 __ msub(as_Register($dst$$reg), 9686 as_Register($src1$$reg), 9687 as_Register($src2$$reg), 9688 as_Register($src3$$reg)); 9689 %} 9690 9691 ins_pipe(lmac_reg_reg); 9692 %} 9693 9694 // Combined Long Multiply & Neg 9695 9696 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 9697 match(Set dst (MulL (SubL zero src1) src2)); 9698 match(Set dst (MulL src1 (SubL zero src2))); 9699 9700 ins_cost(INSN_COST * 5); 9701 format %{ "mneg $dst, $src1, $src2" %} 9702 9703 ins_encode %{ 9704 __ mneg(as_Register($dst$$reg), 9705 as_Register($src1$$reg), 9706 as_Register($src2$$reg)); 9707 %} 9708 9709 ins_pipe(lmac_reg_reg); 9710 %} 9711 9712 // Integer Divide 9713 9714 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9715 match(Set dst (DivI src1 src2)); 9716 9717 ins_cost(INSN_COST * 19); 9718 format %{ "sdivw $dst, $src1, $src2" %} 9719 9720 ins_encode(aarch64_enc_divw(dst, src1, src2)); 9721 ins_pipe(idiv_reg_reg); 9722 %} 9723 9724 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 9725 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 9726 ins_cost(INSN_COST); 9727 format %{ "lsrw $dst, $src1, $div1" %} 9728 ins_encode %{ 9729 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 9730 %} 9731 ins_pipe(ialu_reg_shift); 9732 %} 9733 9734 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 9735 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 9736 ins_cost(INSN_COST); 9737 format %{ "addw $dst, $src, LSR $div1" %} 9738 9739 ins_encode %{ 9740 __ addw(as_Register($dst$$reg), 9741 as_Register($src$$reg), 9742 as_Register($src$$reg), 9743 Assembler::LSR, 31); 9744 %} 9745 ins_pipe(ialu_reg); 9746 %} 9747 9748 // Long Divide 9749 9750 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9751 match(Set dst (DivL src1 src2)); 9752 9753 ins_cost(INSN_COST * 35); 9754 format %{ "sdiv $dst, $src1, $src2" %} 9755 9756 ins_encode(aarch64_enc_div(dst, src1, src2)); 9757 ins_pipe(ldiv_reg_reg); 9758 %} 9759 9760 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 9761 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 9762 ins_cost(INSN_COST); 9763 format %{ "lsr $dst, $src1, $div1" %} 9764 ins_encode %{ 9765 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 9766 %} 9767 ins_pipe(ialu_reg_shift); 9768 %} 9769 9770 instruct div2RoundL(iRegLNoSp dst, iRegL src, immI_63 div1, immI_63 div2) %{ 9771 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 9772 ins_cost(INSN_COST); 9773 format %{ "add $dst, $src, $div1" %} 9774 9775 ins_encode %{ 9776 __ add(as_Register($dst$$reg), 9777 as_Register($src$$reg), 9778 as_Register($src$$reg), 9779 Assembler::LSR, 63); 9780 %} 9781 ins_pipe(ialu_reg); 9782 %} 9783 9784 // Integer Remainder 9785 9786 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9787 match(Set dst (ModI src1 src2)); 9788 9789 ins_cost(INSN_COST * 22); 9790 format %{ "sdivw rscratch1, $src1, $src2\n\t" 9791 "msubw($dst, rscratch1, $src2, $src1" %} 9792 9793 ins_encode(aarch64_enc_modw(dst, src1, src2)); 9794 ins_pipe(idiv_reg_reg); 9795 %} 9796 9797 // Long Remainder 9798 9799 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9800 match(Set dst (ModL src1 src2)); 9801 9802 ins_cost(INSN_COST * 38); 9803 format %{ "sdiv rscratch1, $src1, $src2\n" 9804 "msub($dst, rscratch1, $src2, $src1" %} 9805 9806 ins_encode(aarch64_enc_mod(dst, src1, src2)); 9807 ins_pipe(ldiv_reg_reg); 9808 %} 9809 9810 // Integer Shifts 9811 9812 // Shift Left Register 9813 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9814 match(Set dst (LShiftI src1 src2)); 9815 9816 ins_cost(INSN_COST * 2); 9817 format %{ "lslvw $dst, $src1, $src2" %} 9818 9819 ins_encode %{ 9820 __ lslvw(as_Register($dst$$reg), 9821 as_Register($src1$$reg), 9822 as_Register($src2$$reg)); 9823 %} 9824 9825 ins_pipe(ialu_reg_reg_vshift); 9826 %} 9827 9828 // Shift Left Immediate 9829 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9830 match(Set dst (LShiftI src1 src2)); 9831 9832 ins_cost(INSN_COST); 9833 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 9834 9835 ins_encode %{ 9836 __ lslw(as_Register($dst$$reg), 9837 as_Register($src1$$reg), 9838 $src2$$constant & 0x1f); 9839 %} 9840 9841 ins_pipe(ialu_reg_shift); 9842 %} 9843 9844 // Shift Right Logical Register 9845 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9846 match(Set dst (URShiftI src1 src2)); 9847 9848 ins_cost(INSN_COST * 2); 9849 format %{ "lsrvw $dst, $src1, $src2" %} 9850 9851 ins_encode %{ 9852 __ lsrvw(as_Register($dst$$reg), 9853 as_Register($src1$$reg), 9854 as_Register($src2$$reg)); 9855 %} 9856 9857 ins_pipe(ialu_reg_reg_vshift); 9858 %} 9859 9860 // Shift Right Logical Immediate 9861 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9862 match(Set dst (URShiftI src1 src2)); 9863 9864 ins_cost(INSN_COST); 9865 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 9866 9867 ins_encode %{ 9868 __ lsrw(as_Register($dst$$reg), 9869 as_Register($src1$$reg), 9870 $src2$$constant & 0x1f); 9871 %} 9872 9873 ins_pipe(ialu_reg_shift); 9874 %} 9875 9876 // Shift Right Arithmetic Register 9877 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9878 match(Set dst (RShiftI src1 src2)); 9879 9880 ins_cost(INSN_COST * 2); 9881 format %{ "asrvw $dst, $src1, $src2" %} 9882 9883 ins_encode %{ 9884 __ asrvw(as_Register($dst$$reg), 9885 as_Register($src1$$reg), 9886 as_Register($src2$$reg)); 9887 %} 9888 9889 ins_pipe(ialu_reg_reg_vshift); 9890 %} 9891 9892 // Shift Right Arithmetic Immediate 9893 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9894 match(Set dst (RShiftI src1 src2)); 9895 9896 ins_cost(INSN_COST); 9897 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 9898 9899 ins_encode %{ 9900 __ asrw(as_Register($dst$$reg), 9901 as_Register($src1$$reg), 9902 $src2$$constant & 0x1f); 9903 %} 9904 9905 ins_pipe(ialu_reg_shift); 9906 %} 9907 9908 // Combined Int Mask and Right Shift (using UBFM) 9909 // TODO 9910 9911 // Long Shifts 9912 9913 // Shift Left Register 9914 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9915 match(Set dst (LShiftL src1 src2)); 9916 9917 ins_cost(INSN_COST * 2); 9918 format %{ "lslv $dst, $src1, $src2" %} 9919 9920 ins_encode %{ 9921 __ lslv(as_Register($dst$$reg), 9922 as_Register($src1$$reg), 9923 as_Register($src2$$reg)); 9924 %} 9925 9926 ins_pipe(ialu_reg_reg_vshift); 9927 %} 9928 9929 // Shift Left Immediate 9930 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9931 match(Set dst (LShiftL src1 src2)); 9932 9933 ins_cost(INSN_COST); 9934 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 9935 9936 ins_encode %{ 9937 __ lsl(as_Register($dst$$reg), 9938 as_Register($src1$$reg), 9939 $src2$$constant & 0x3f); 9940 %} 9941 9942 ins_pipe(ialu_reg_shift); 9943 %} 9944 9945 // Shift Right Logical Register 9946 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9947 match(Set dst (URShiftL src1 src2)); 9948 9949 ins_cost(INSN_COST * 2); 9950 format %{ "lsrv $dst, $src1, $src2" %} 9951 9952 ins_encode %{ 9953 __ lsrv(as_Register($dst$$reg), 9954 as_Register($src1$$reg), 9955 as_Register($src2$$reg)); 9956 %} 9957 9958 ins_pipe(ialu_reg_reg_vshift); 9959 %} 9960 9961 // Shift Right Logical Immediate 9962 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9963 match(Set dst (URShiftL src1 src2)); 9964 9965 ins_cost(INSN_COST); 9966 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 9967 9968 ins_encode %{ 9969 __ lsr(as_Register($dst$$reg), 9970 as_Register($src1$$reg), 9971 $src2$$constant & 0x3f); 9972 %} 9973 9974 ins_pipe(ialu_reg_shift); 9975 %} 9976 9977 // A special-case pattern for card table stores. 9978 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 9979 match(Set dst (URShiftL (CastP2X src1) src2)); 9980 9981 ins_cost(INSN_COST); 9982 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 9983 9984 ins_encode %{ 9985 __ lsr(as_Register($dst$$reg), 9986 as_Register($src1$$reg), 9987 $src2$$constant & 0x3f); 9988 %} 9989 9990 ins_pipe(ialu_reg_shift); 9991 %} 9992 9993 // Shift Right Arithmetic Register 9994 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9995 match(Set dst (RShiftL src1 src2)); 9996 9997 ins_cost(INSN_COST * 2); 9998 format %{ "asrv $dst, $src1, $src2" %} 9999 10000 ins_encode %{ 10001 __ asrv(as_Register($dst$$reg), 10002 as_Register($src1$$reg), 10003 as_Register($src2$$reg)); 10004 %} 10005 10006 ins_pipe(ialu_reg_reg_vshift); 10007 %} 10008 10009 // Shift Right Arithmetic Immediate 10010 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10011 match(Set dst (RShiftL src1 src2)); 10012 10013 ins_cost(INSN_COST); 10014 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10015 10016 ins_encode %{ 10017 __ asr(as_Register($dst$$reg), 10018 as_Register($src1$$reg), 10019 $src2$$constant & 0x3f); 10020 %} 10021 10022 ins_pipe(ialu_reg_shift); 10023 %} 10024 10025 // BEGIN This section of the file is automatically generated. Do not edit -------------- 10026 10027 instruct regL_not_reg(iRegLNoSp dst, 10028 iRegL src1, immL_M1 m1, 10029 rFlagsReg cr) %{ 10030 match(Set dst (XorL src1 m1)); 10031 ins_cost(INSN_COST); 10032 format %{ "eon $dst, $src1, zr" %} 10033 10034 ins_encode %{ 10035 __ eon(as_Register($dst$$reg), 10036 as_Register($src1$$reg), 10037 zr, 10038 Assembler::LSL, 0); 10039 %} 10040 10041 ins_pipe(ialu_reg); 10042 %} 10043 instruct regI_not_reg(iRegINoSp dst, 10044 iRegIorL2I src1, immI_M1 m1, 10045 rFlagsReg cr) %{ 10046 match(Set dst (XorI src1 m1)); 10047 ins_cost(INSN_COST); 10048 format %{ "eonw $dst, $src1, zr" %} 10049 10050 ins_encode %{ 10051 __ eonw(as_Register($dst$$reg), 10052 as_Register($src1$$reg), 10053 zr, 10054 Assembler::LSL, 0); 10055 %} 10056 10057 ins_pipe(ialu_reg); 10058 %} 10059 10060 instruct AndI_reg_not_reg(iRegINoSp dst, 10061 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10062 rFlagsReg cr) %{ 10063 match(Set dst (AndI src1 (XorI src2 m1))); 10064 ins_cost(INSN_COST); 10065 format %{ "bicw $dst, $src1, $src2" %} 10066 10067 ins_encode %{ 10068 __ bicw(as_Register($dst$$reg), 10069 as_Register($src1$$reg), 10070 as_Register($src2$$reg), 10071 Assembler::LSL, 0); 10072 %} 10073 10074 ins_pipe(ialu_reg_reg); 10075 %} 10076 10077 instruct AndL_reg_not_reg(iRegLNoSp dst, 10078 iRegL src1, iRegL src2, immL_M1 m1, 10079 rFlagsReg cr) %{ 10080 match(Set dst (AndL src1 (XorL src2 m1))); 10081 ins_cost(INSN_COST); 10082 format %{ "bic $dst, $src1, $src2" %} 10083 10084 ins_encode %{ 10085 __ bic(as_Register($dst$$reg), 10086 as_Register($src1$$reg), 10087 as_Register($src2$$reg), 10088 Assembler::LSL, 0); 10089 %} 10090 10091 ins_pipe(ialu_reg_reg); 10092 %} 10093 10094 instruct OrI_reg_not_reg(iRegINoSp dst, 10095 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10096 rFlagsReg cr) %{ 10097 match(Set dst (OrI src1 (XorI src2 m1))); 10098 ins_cost(INSN_COST); 10099 format %{ "ornw $dst, $src1, $src2" %} 10100 10101 ins_encode %{ 10102 __ ornw(as_Register($dst$$reg), 10103 as_Register($src1$$reg), 10104 as_Register($src2$$reg), 10105 Assembler::LSL, 0); 10106 %} 10107 10108 ins_pipe(ialu_reg_reg); 10109 %} 10110 10111 instruct OrL_reg_not_reg(iRegLNoSp dst, 10112 iRegL src1, iRegL src2, immL_M1 m1, 10113 rFlagsReg cr) %{ 10114 match(Set dst (OrL src1 (XorL src2 m1))); 10115 ins_cost(INSN_COST); 10116 format %{ "orn $dst, $src1, $src2" %} 10117 10118 ins_encode %{ 10119 __ orn(as_Register($dst$$reg), 10120 as_Register($src1$$reg), 10121 as_Register($src2$$reg), 10122 Assembler::LSL, 0); 10123 %} 10124 10125 ins_pipe(ialu_reg_reg); 10126 %} 10127 10128 instruct XorI_reg_not_reg(iRegINoSp dst, 10129 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10130 rFlagsReg cr) %{ 10131 match(Set dst (XorI m1 (XorI src2 src1))); 10132 ins_cost(INSN_COST); 10133 format %{ "eonw $dst, $src1, $src2" %} 10134 10135 ins_encode %{ 10136 __ eonw(as_Register($dst$$reg), 10137 as_Register($src1$$reg), 10138 as_Register($src2$$reg), 10139 Assembler::LSL, 0); 10140 %} 10141 10142 ins_pipe(ialu_reg_reg); 10143 %} 10144 10145 instruct XorL_reg_not_reg(iRegLNoSp dst, 10146 iRegL src1, iRegL src2, immL_M1 m1, 10147 rFlagsReg cr) %{ 10148 match(Set dst (XorL m1 (XorL src2 src1))); 10149 ins_cost(INSN_COST); 10150 format %{ "eon $dst, $src1, $src2" %} 10151 10152 ins_encode %{ 10153 __ eon(as_Register($dst$$reg), 10154 as_Register($src1$$reg), 10155 as_Register($src2$$reg), 10156 Assembler::LSL, 0); 10157 %} 10158 10159 ins_pipe(ialu_reg_reg); 10160 %} 10161 10162 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10163 iRegIorL2I src1, iRegIorL2I src2, 10164 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10165 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10166 ins_cost(1.9 * INSN_COST); 10167 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10168 10169 ins_encode %{ 10170 __ bicw(as_Register($dst$$reg), 10171 as_Register($src1$$reg), 10172 as_Register($src2$$reg), 10173 Assembler::LSR, 10174 $src3$$constant & 0x1f); 10175 %} 10176 10177 ins_pipe(ialu_reg_reg_shift); 10178 %} 10179 10180 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10181 iRegL src1, iRegL src2, 10182 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10183 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10184 ins_cost(1.9 * INSN_COST); 10185 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10186 10187 ins_encode %{ 10188 __ bic(as_Register($dst$$reg), 10189 as_Register($src1$$reg), 10190 as_Register($src2$$reg), 10191 Assembler::LSR, 10192 $src3$$constant & 0x3f); 10193 %} 10194 10195 ins_pipe(ialu_reg_reg_shift); 10196 %} 10197 10198 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10199 iRegIorL2I src1, iRegIorL2I src2, 10200 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10201 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10202 ins_cost(1.9 * INSN_COST); 10203 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10204 10205 ins_encode %{ 10206 __ bicw(as_Register($dst$$reg), 10207 as_Register($src1$$reg), 10208 as_Register($src2$$reg), 10209 Assembler::ASR, 10210 $src3$$constant & 0x1f); 10211 %} 10212 10213 ins_pipe(ialu_reg_reg_shift); 10214 %} 10215 10216 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10217 iRegL src1, iRegL src2, 10218 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10219 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10220 ins_cost(1.9 * INSN_COST); 10221 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10222 10223 ins_encode %{ 10224 __ bic(as_Register($dst$$reg), 10225 as_Register($src1$$reg), 10226 as_Register($src2$$reg), 10227 Assembler::ASR, 10228 $src3$$constant & 0x3f); 10229 %} 10230 10231 ins_pipe(ialu_reg_reg_shift); 10232 %} 10233 10234 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10235 iRegIorL2I src1, iRegIorL2I src2, 10236 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10237 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10238 ins_cost(1.9 * INSN_COST); 10239 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10240 10241 ins_encode %{ 10242 __ bicw(as_Register($dst$$reg), 10243 as_Register($src1$$reg), 10244 as_Register($src2$$reg), 10245 Assembler::LSL, 10246 $src3$$constant & 0x1f); 10247 %} 10248 10249 ins_pipe(ialu_reg_reg_shift); 10250 %} 10251 10252 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10253 iRegL src1, iRegL src2, 10254 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10255 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10256 ins_cost(1.9 * INSN_COST); 10257 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10258 10259 ins_encode %{ 10260 __ bic(as_Register($dst$$reg), 10261 as_Register($src1$$reg), 10262 as_Register($src2$$reg), 10263 Assembler::LSL, 10264 $src3$$constant & 0x3f); 10265 %} 10266 10267 ins_pipe(ialu_reg_reg_shift); 10268 %} 10269 10270 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10271 iRegIorL2I src1, iRegIorL2I src2, 10272 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10273 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10274 ins_cost(1.9 * INSN_COST); 10275 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10276 10277 ins_encode %{ 10278 __ eonw(as_Register($dst$$reg), 10279 as_Register($src1$$reg), 10280 as_Register($src2$$reg), 10281 Assembler::LSR, 10282 $src3$$constant & 0x1f); 10283 %} 10284 10285 ins_pipe(ialu_reg_reg_shift); 10286 %} 10287 10288 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10289 iRegL src1, iRegL src2, 10290 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10291 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10292 ins_cost(1.9 * INSN_COST); 10293 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10294 10295 ins_encode %{ 10296 __ eon(as_Register($dst$$reg), 10297 as_Register($src1$$reg), 10298 as_Register($src2$$reg), 10299 Assembler::LSR, 10300 $src3$$constant & 0x3f); 10301 %} 10302 10303 ins_pipe(ialu_reg_reg_shift); 10304 %} 10305 10306 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10307 iRegIorL2I src1, iRegIorL2I src2, 10308 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10309 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10310 ins_cost(1.9 * INSN_COST); 10311 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10312 10313 ins_encode %{ 10314 __ eonw(as_Register($dst$$reg), 10315 as_Register($src1$$reg), 10316 as_Register($src2$$reg), 10317 Assembler::ASR, 10318 $src3$$constant & 0x1f); 10319 %} 10320 10321 ins_pipe(ialu_reg_reg_shift); 10322 %} 10323 10324 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10325 iRegL src1, iRegL src2, 10326 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10327 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10328 ins_cost(1.9 * INSN_COST); 10329 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10330 10331 ins_encode %{ 10332 __ eon(as_Register($dst$$reg), 10333 as_Register($src1$$reg), 10334 as_Register($src2$$reg), 10335 Assembler::ASR, 10336 $src3$$constant & 0x3f); 10337 %} 10338 10339 ins_pipe(ialu_reg_reg_shift); 10340 %} 10341 10342 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10343 iRegIorL2I src1, iRegIorL2I src2, 10344 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10345 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10346 ins_cost(1.9 * INSN_COST); 10347 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10348 10349 ins_encode %{ 10350 __ eonw(as_Register($dst$$reg), 10351 as_Register($src1$$reg), 10352 as_Register($src2$$reg), 10353 Assembler::LSL, 10354 $src3$$constant & 0x1f); 10355 %} 10356 10357 ins_pipe(ialu_reg_reg_shift); 10358 %} 10359 10360 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10361 iRegL src1, iRegL src2, 10362 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10363 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10364 ins_cost(1.9 * INSN_COST); 10365 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10366 10367 ins_encode %{ 10368 __ eon(as_Register($dst$$reg), 10369 as_Register($src1$$reg), 10370 as_Register($src2$$reg), 10371 Assembler::LSL, 10372 $src3$$constant & 0x3f); 10373 %} 10374 10375 ins_pipe(ialu_reg_reg_shift); 10376 %} 10377 10378 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10379 iRegIorL2I src1, iRegIorL2I src2, 10380 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10381 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10382 ins_cost(1.9 * INSN_COST); 10383 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10384 10385 ins_encode %{ 10386 __ ornw(as_Register($dst$$reg), 10387 as_Register($src1$$reg), 10388 as_Register($src2$$reg), 10389 Assembler::LSR, 10390 $src3$$constant & 0x1f); 10391 %} 10392 10393 ins_pipe(ialu_reg_reg_shift); 10394 %} 10395 10396 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10397 iRegL src1, iRegL src2, 10398 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10399 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10400 ins_cost(1.9 * INSN_COST); 10401 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10402 10403 ins_encode %{ 10404 __ orn(as_Register($dst$$reg), 10405 as_Register($src1$$reg), 10406 as_Register($src2$$reg), 10407 Assembler::LSR, 10408 $src3$$constant & 0x3f); 10409 %} 10410 10411 ins_pipe(ialu_reg_reg_shift); 10412 %} 10413 10414 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10415 iRegIorL2I src1, iRegIorL2I src2, 10416 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10417 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10418 ins_cost(1.9 * INSN_COST); 10419 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10420 10421 ins_encode %{ 10422 __ ornw(as_Register($dst$$reg), 10423 as_Register($src1$$reg), 10424 as_Register($src2$$reg), 10425 Assembler::ASR, 10426 $src3$$constant & 0x1f); 10427 %} 10428 10429 ins_pipe(ialu_reg_reg_shift); 10430 %} 10431 10432 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10433 iRegL src1, iRegL src2, 10434 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10435 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10436 ins_cost(1.9 * INSN_COST); 10437 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10438 10439 ins_encode %{ 10440 __ orn(as_Register($dst$$reg), 10441 as_Register($src1$$reg), 10442 as_Register($src2$$reg), 10443 Assembler::ASR, 10444 $src3$$constant & 0x3f); 10445 %} 10446 10447 ins_pipe(ialu_reg_reg_shift); 10448 %} 10449 10450 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10451 iRegIorL2I src1, iRegIorL2I src2, 10452 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10453 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10454 ins_cost(1.9 * INSN_COST); 10455 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10456 10457 ins_encode %{ 10458 __ ornw(as_Register($dst$$reg), 10459 as_Register($src1$$reg), 10460 as_Register($src2$$reg), 10461 Assembler::LSL, 10462 $src3$$constant & 0x1f); 10463 %} 10464 10465 ins_pipe(ialu_reg_reg_shift); 10466 %} 10467 10468 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10469 iRegL src1, iRegL src2, 10470 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10471 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10472 ins_cost(1.9 * INSN_COST); 10473 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10474 10475 ins_encode %{ 10476 __ orn(as_Register($dst$$reg), 10477 as_Register($src1$$reg), 10478 as_Register($src2$$reg), 10479 Assembler::LSL, 10480 $src3$$constant & 0x3f); 10481 %} 10482 10483 ins_pipe(ialu_reg_reg_shift); 10484 %} 10485 10486 instruct AndI_reg_URShift_reg(iRegINoSp dst, 10487 iRegIorL2I src1, iRegIorL2I src2, 10488 immI src3, rFlagsReg cr) %{ 10489 match(Set dst (AndI src1 (URShiftI src2 src3))); 10490 10491 ins_cost(1.9 * INSN_COST); 10492 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10493 10494 ins_encode %{ 10495 __ andw(as_Register($dst$$reg), 10496 as_Register($src1$$reg), 10497 as_Register($src2$$reg), 10498 Assembler::LSR, 10499 $src3$$constant & 0x1f); 10500 %} 10501 10502 ins_pipe(ialu_reg_reg_shift); 10503 %} 10504 10505 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 10506 iRegL src1, iRegL src2, 10507 immI src3, rFlagsReg cr) %{ 10508 match(Set dst (AndL src1 (URShiftL src2 src3))); 10509 10510 ins_cost(1.9 * INSN_COST); 10511 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10512 10513 ins_encode %{ 10514 __ andr(as_Register($dst$$reg), 10515 as_Register($src1$$reg), 10516 as_Register($src2$$reg), 10517 Assembler::LSR, 10518 $src3$$constant & 0x3f); 10519 %} 10520 10521 ins_pipe(ialu_reg_reg_shift); 10522 %} 10523 10524 instruct AndI_reg_RShift_reg(iRegINoSp dst, 10525 iRegIorL2I src1, iRegIorL2I src2, 10526 immI src3, rFlagsReg cr) %{ 10527 match(Set dst (AndI src1 (RShiftI src2 src3))); 10528 10529 ins_cost(1.9 * INSN_COST); 10530 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10531 10532 ins_encode %{ 10533 __ andw(as_Register($dst$$reg), 10534 as_Register($src1$$reg), 10535 as_Register($src2$$reg), 10536 Assembler::ASR, 10537 $src3$$constant & 0x1f); 10538 %} 10539 10540 ins_pipe(ialu_reg_reg_shift); 10541 %} 10542 10543 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10544 iRegL src1, iRegL src2, 10545 immI src3, rFlagsReg cr) %{ 10546 match(Set dst (AndL src1 (RShiftL src2 src3))); 10547 10548 ins_cost(1.9 * INSN_COST); 10549 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10550 10551 ins_encode %{ 10552 __ andr(as_Register($dst$$reg), 10553 as_Register($src1$$reg), 10554 as_Register($src2$$reg), 10555 Assembler::ASR, 10556 $src3$$constant & 0x3f); 10557 %} 10558 10559 ins_pipe(ialu_reg_reg_shift); 10560 %} 10561 10562 instruct AndI_reg_LShift_reg(iRegINoSp dst, 10563 iRegIorL2I src1, iRegIorL2I src2, 10564 immI src3, rFlagsReg cr) %{ 10565 match(Set dst (AndI src1 (LShiftI src2 src3))); 10566 10567 ins_cost(1.9 * INSN_COST); 10568 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10569 10570 ins_encode %{ 10571 __ andw(as_Register($dst$$reg), 10572 as_Register($src1$$reg), 10573 as_Register($src2$$reg), 10574 Assembler::LSL, 10575 $src3$$constant & 0x1f); 10576 %} 10577 10578 ins_pipe(ialu_reg_reg_shift); 10579 %} 10580 10581 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10582 iRegL src1, iRegL src2, 10583 immI src3, rFlagsReg cr) %{ 10584 match(Set dst (AndL src1 (LShiftL src2 src3))); 10585 10586 ins_cost(1.9 * INSN_COST); 10587 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10588 10589 ins_encode %{ 10590 __ andr(as_Register($dst$$reg), 10591 as_Register($src1$$reg), 10592 as_Register($src2$$reg), 10593 Assembler::LSL, 10594 $src3$$constant & 0x3f); 10595 %} 10596 10597 ins_pipe(ialu_reg_reg_shift); 10598 %} 10599 10600 instruct XorI_reg_URShift_reg(iRegINoSp dst, 10601 iRegIorL2I src1, iRegIorL2I src2, 10602 immI src3, rFlagsReg cr) %{ 10603 match(Set dst (XorI src1 (URShiftI src2 src3))); 10604 10605 ins_cost(1.9 * INSN_COST); 10606 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10607 10608 ins_encode %{ 10609 __ eorw(as_Register($dst$$reg), 10610 as_Register($src1$$reg), 10611 as_Register($src2$$reg), 10612 Assembler::LSR, 10613 $src3$$constant & 0x1f); 10614 %} 10615 10616 ins_pipe(ialu_reg_reg_shift); 10617 %} 10618 10619 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10620 iRegL src1, iRegL src2, 10621 immI src3, rFlagsReg cr) %{ 10622 match(Set dst (XorL src1 (URShiftL src2 src3))); 10623 10624 ins_cost(1.9 * INSN_COST); 10625 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10626 10627 ins_encode %{ 10628 __ eor(as_Register($dst$$reg), 10629 as_Register($src1$$reg), 10630 as_Register($src2$$reg), 10631 Assembler::LSR, 10632 $src3$$constant & 0x3f); 10633 %} 10634 10635 ins_pipe(ialu_reg_reg_shift); 10636 %} 10637 10638 instruct XorI_reg_RShift_reg(iRegINoSp dst, 10639 iRegIorL2I src1, iRegIorL2I src2, 10640 immI src3, rFlagsReg cr) %{ 10641 match(Set dst (XorI src1 (RShiftI src2 src3))); 10642 10643 ins_cost(1.9 * INSN_COST); 10644 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10645 10646 ins_encode %{ 10647 __ eorw(as_Register($dst$$reg), 10648 as_Register($src1$$reg), 10649 as_Register($src2$$reg), 10650 Assembler::ASR, 10651 $src3$$constant & 0x1f); 10652 %} 10653 10654 ins_pipe(ialu_reg_reg_shift); 10655 %} 10656 10657 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10658 iRegL src1, iRegL src2, 10659 immI src3, rFlagsReg cr) %{ 10660 match(Set dst (XorL src1 (RShiftL src2 src3))); 10661 10662 ins_cost(1.9 * INSN_COST); 10663 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10664 10665 ins_encode %{ 10666 __ eor(as_Register($dst$$reg), 10667 as_Register($src1$$reg), 10668 as_Register($src2$$reg), 10669 Assembler::ASR, 10670 $src3$$constant & 0x3f); 10671 %} 10672 10673 ins_pipe(ialu_reg_reg_shift); 10674 %} 10675 10676 instruct XorI_reg_LShift_reg(iRegINoSp dst, 10677 iRegIorL2I src1, iRegIorL2I src2, 10678 immI src3, rFlagsReg cr) %{ 10679 match(Set dst (XorI src1 (LShiftI src2 src3))); 10680 10681 ins_cost(1.9 * INSN_COST); 10682 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10683 10684 ins_encode %{ 10685 __ eorw(as_Register($dst$$reg), 10686 as_Register($src1$$reg), 10687 as_Register($src2$$reg), 10688 Assembler::LSL, 10689 $src3$$constant & 0x1f); 10690 %} 10691 10692 ins_pipe(ialu_reg_reg_shift); 10693 %} 10694 10695 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 10696 iRegL src1, iRegL src2, 10697 immI src3, rFlagsReg cr) %{ 10698 match(Set dst (XorL src1 (LShiftL src2 src3))); 10699 10700 ins_cost(1.9 * INSN_COST); 10701 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 10702 10703 ins_encode %{ 10704 __ eor(as_Register($dst$$reg), 10705 as_Register($src1$$reg), 10706 as_Register($src2$$reg), 10707 Assembler::LSL, 10708 $src3$$constant & 0x3f); 10709 %} 10710 10711 ins_pipe(ialu_reg_reg_shift); 10712 %} 10713 10714 instruct OrI_reg_URShift_reg(iRegINoSp dst, 10715 iRegIorL2I src1, iRegIorL2I src2, 10716 immI src3, rFlagsReg cr) %{ 10717 match(Set dst (OrI src1 (URShiftI src2 src3))); 10718 10719 ins_cost(1.9 * INSN_COST); 10720 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 10721 10722 ins_encode %{ 10723 __ orrw(as_Register($dst$$reg), 10724 as_Register($src1$$reg), 10725 as_Register($src2$$reg), 10726 Assembler::LSR, 10727 $src3$$constant & 0x1f); 10728 %} 10729 10730 ins_pipe(ialu_reg_reg_shift); 10731 %} 10732 10733 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 10734 iRegL src1, iRegL src2, 10735 immI src3, rFlagsReg cr) %{ 10736 match(Set dst (OrL src1 (URShiftL src2 src3))); 10737 10738 ins_cost(1.9 * INSN_COST); 10739 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 10740 10741 ins_encode %{ 10742 __ orr(as_Register($dst$$reg), 10743 as_Register($src1$$reg), 10744 as_Register($src2$$reg), 10745 Assembler::LSR, 10746 $src3$$constant & 0x3f); 10747 %} 10748 10749 ins_pipe(ialu_reg_reg_shift); 10750 %} 10751 10752 instruct OrI_reg_RShift_reg(iRegINoSp dst, 10753 iRegIorL2I src1, iRegIorL2I src2, 10754 immI src3, rFlagsReg cr) %{ 10755 match(Set dst (OrI src1 (RShiftI src2 src3))); 10756 10757 ins_cost(1.9 * INSN_COST); 10758 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 10759 10760 ins_encode %{ 10761 __ orrw(as_Register($dst$$reg), 10762 as_Register($src1$$reg), 10763 as_Register($src2$$reg), 10764 Assembler::ASR, 10765 $src3$$constant & 0x1f); 10766 %} 10767 10768 ins_pipe(ialu_reg_reg_shift); 10769 %} 10770 10771 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 10772 iRegL src1, iRegL src2, 10773 immI src3, rFlagsReg cr) %{ 10774 match(Set dst (OrL src1 (RShiftL src2 src3))); 10775 10776 ins_cost(1.9 * INSN_COST); 10777 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 10778 10779 ins_encode %{ 10780 __ orr(as_Register($dst$$reg), 10781 as_Register($src1$$reg), 10782 as_Register($src2$$reg), 10783 Assembler::ASR, 10784 $src3$$constant & 0x3f); 10785 %} 10786 10787 ins_pipe(ialu_reg_reg_shift); 10788 %} 10789 10790 instruct OrI_reg_LShift_reg(iRegINoSp dst, 10791 iRegIorL2I src1, iRegIorL2I src2, 10792 immI src3, rFlagsReg cr) %{ 10793 match(Set dst (OrI src1 (LShiftI src2 src3))); 10794 10795 ins_cost(1.9 * INSN_COST); 10796 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 10797 10798 ins_encode %{ 10799 __ orrw(as_Register($dst$$reg), 10800 as_Register($src1$$reg), 10801 as_Register($src2$$reg), 10802 Assembler::LSL, 10803 $src3$$constant & 0x1f); 10804 %} 10805 10806 ins_pipe(ialu_reg_reg_shift); 10807 %} 10808 10809 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 10810 iRegL src1, iRegL src2, 10811 immI src3, rFlagsReg cr) %{ 10812 match(Set dst (OrL src1 (LShiftL src2 src3))); 10813 10814 ins_cost(1.9 * INSN_COST); 10815 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 10816 10817 ins_encode %{ 10818 __ orr(as_Register($dst$$reg), 10819 as_Register($src1$$reg), 10820 as_Register($src2$$reg), 10821 Assembler::LSL, 10822 $src3$$constant & 0x3f); 10823 %} 10824 10825 ins_pipe(ialu_reg_reg_shift); 10826 %} 10827 10828 instruct AddI_reg_URShift_reg(iRegINoSp dst, 10829 iRegIorL2I src1, iRegIorL2I src2, 10830 immI src3, rFlagsReg cr) %{ 10831 match(Set dst (AddI src1 (URShiftI src2 src3))); 10832 10833 ins_cost(1.9 * INSN_COST); 10834 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 10835 10836 ins_encode %{ 10837 __ addw(as_Register($dst$$reg), 10838 as_Register($src1$$reg), 10839 as_Register($src2$$reg), 10840 Assembler::LSR, 10841 $src3$$constant & 0x1f); 10842 %} 10843 10844 ins_pipe(ialu_reg_reg_shift); 10845 %} 10846 10847 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 10848 iRegL src1, iRegL src2, 10849 immI src3, rFlagsReg cr) %{ 10850 match(Set dst (AddL src1 (URShiftL src2 src3))); 10851 10852 ins_cost(1.9 * INSN_COST); 10853 format %{ "add $dst, $src1, $src2, LSR $src3" %} 10854 10855 ins_encode %{ 10856 __ add(as_Register($dst$$reg), 10857 as_Register($src1$$reg), 10858 as_Register($src2$$reg), 10859 Assembler::LSR, 10860 $src3$$constant & 0x3f); 10861 %} 10862 10863 ins_pipe(ialu_reg_reg_shift); 10864 %} 10865 10866 instruct AddI_reg_RShift_reg(iRegINoSp dst, 10867 iRegIorL2I src1, iRegIorL2I src2, 10868 immI src3, rFlagsReg cr) %{ 10869 match(Set dst (AddI src1 (RShiftI src2 src3))); 10870 10871 ins_cost(1.9 * INSN_COST); 10872 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 10873 10874 ins_encode %{ 10875 __ addw(as_Register($dst$$reg), 10876 as_Register($src1$$reg), 10877 as_Register($src2$$reg), 10878 Assembler::ASR, 10879 $src3$$constant & 0x1f); 10880 %} 10881 10882 ins_pipe(ialu_reg_reg_shift); 10883 %} 10884 10885 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 10886 iRegL src1, iRegL src2, 10887 immI src3, rFlagsReg cr) %{ 10888 match(Set dst (AddL src1 (RShiftL src2 src3))); 10889 10890 ins_cost(1.9 * INSN_COST); 10891 format %{ "add $dst, $src1, $src2, ASR $src3" %} 10892 10893 ins_encode %{ 10894 __ add(as_Register($dst$$reg), 10895 as_Register($src1$$reg), 10896 as_Register($src2$$reg), 10897 Assembler::ASR, 10898 $src3$$constant & 0x3f); 10899 %} 10900 10901 ins_pipe(ialu_reg_reg_shift); 10902 %} 10903 10904 instruct AddI_reg_LShift_reg(iRegINoSp dst, 10905 iRegIorL2I src1, iRegIorL2I src2, 10906 immI src3, rFlagsReg cr) %{ 10907 match(Set dst (AddI src1 (LShiftI src2 src3))); 10908 10909 ins_cost(1.9 * INSN_COST); 10910 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 10911 10912 ins_encode %{ 10913 __ addw(as_Register($dst$$reg), 10914 as_Register($src1$$reg), 10915 as_Register($src2$$reg), 10916 Assembler::LSL, 10917 $src3$$constant & 0x1f); 10918 %} 10919 10920 ins_pipe(ialu_reg_reg_shift); 10921 %} 10922 10923 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 10924 iRegL src1, iRegL src2, 10925 immI src3, rFlagsReg cr) %{ 10926 match(Set dst (AddL src1 (LShiftL src2 src3))); 10927 10928 ins_cost(1.9 * INSN_COST); 10929 format %{ "add $dst, $src1, $src2, LSL $src3" %} 10930 10931 ins_encode %{ 10932 __ add(as_Register($dst$$reg), 10933 as_Register($src1$$reg), 10934 as_Register($src2$$reg), 10935 Assembler::LSL, 10936 $src3$$constant & 0x3f); 10937 %} 10938 10939 ins_pipe(ialu_reg_reg_shift); 10940 %} 10941 10942 instruct SubI_reg_URShift_reg(iRegINoSp dst, 10943 iRegIorL2I src1, iRegIorL2I src2, 10944 immI src3, rFlagsReg cr) %{ 10945 match(Set dst (SubI src1 (URShiftI src2 src3))); 10946 10947 ins_cost(1.9 * INSN_COST); 10948 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 10949 10950 ins_encode %{ 10951 __ subw(as_Register($dst$$reg), 10952 as_Register($src1$$reg), 10953 as_Register($src2$$reg), 10954 Assembler::LSR, 10955 $src3$$constant & 0x1f); 10956 %} 10957 10958 ins_pipe(ialu_reg_reg_shift); 10959 %} 10960 10961 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 10962 iRegL src1, iRegL src2, 10963 immI src3, rFlagsReg cr) %{ 10964 match(Set dst (SubL src1 (URShiftL src2 src3))); 10965 10966 ins_cost(1.9 * INSN_COST); 10967 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 10968 10969 ins_encode %{ 10970 __ sub(as_Register($dst$$reg), 10971 as_Register($src1$$reg), 10972 as_Register($src2$$reg), 10973 Assembler::LSR, 10974 $src3$$constant & 0x3f); 10975 %} 10976 10977 ins_pipe(ialu_reg_reg_shift); 10978 %} 10979 10980 instruct SubI_reg_RShift_reg(iRegINoSp dst, 10981 iRegIorL2I src1, iRegIorL2I src2, 10982 immI src3, rFlagsReg cr) %{ 10983 match(Set dst (SubI src1 (RShiftI src2 src3))); 10984 10985 ins_cost(1.9 * INSN_COST); 10986 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 10987 10988 ins_encode %{ 10989 __ subw(as_Register($dst$$reg), 10990 as_Register($src1$$reg), 10991 as_Register($src2$$reg), 10992 Assembler::ASR, 10993 $src3$$constant & 0x1f); 10994 %} 10995 10996 ins_pipe(ialu_reg_reg_shift); 10997 %} 10998 10999 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11000 iRegL src1, iRegL src2, 11001 immI src3, rFlagsReg cr) %{ 11002 match(Set dst (SubL src1 (RShiftL src2 src3))); 11003 11004 ins_cost(1.9 * INSN_COST); 11005 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11006 11007 ins_encode %{ 11008 __ sub(as_Register($dst$$reg), 11009 as_Register($src1$$reg), 11010 as_Register($src2$$reg), 11011 Assembler::ASR, 11012 $src3$$constant & 0x3f); 11013 %} 11014 11015 ins_pipe(ialu_reg_reg_shift); 11016 %} 11017 11018 instruct SubI_reg_LShift_reg(iRegINoSp dst, 11019 iRegIorL2I src1, iRegIorL2I src2, 11020 immI src3, rFlagsReg cr) %{ 11021 match(Set dst (SubI src1 (LShiftI src2 src3))); 11022 11023 ins_cost(1.9 * INSN_COST); 11024 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11025 11026 ins_encode %{ 11027 __ subw(as_Register($dst$$reg), 11028 as_Register($src1$$reg), 11029 as_Register($src2$$reg), 11030 Assembler::LSL, 11031 $src3$$constant & 0x1f); 11032 %} 11033 11034 ins_pipe(ialu_reg_reg_shift); 11035 %} 11036 11037 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11038 iRegL src1, iRegL src2, 11039 immI src3, rFlagsReg cr) %{ 11040 match(Set dst (SubL src1 (LShiftL src2 src3))); 11041 11042 ins_cost(1.9 * INSN_COST); 11043 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11044 11045 ins_encode %{ 11046 __ sub(as_Register($dst$$reg), 11047 as_Register($src1$$reg), 11048 as_Register($src2$$reg), 11049 Assembler::LSL, 11050 $src3$$constant & 0x3f); 11051 %} 11052 11053 ins_pipe(ialu_reg_reg_shift); 11054 %} 11055 11056 11057 11058 // Shift Left followed by Shift Right. 11059 // This idiom is used by the compiler for the i2b bytecode etc. 11060 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11061 %{ 11062 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11063 // Make sure we are not going to exceed what sbfm can do. 11064 predicate((unsigned int)n->in(2)->get_int() <= 63 11065 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11066 11067 ins_cost(INSN_COST * 2); 11068 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11069 ins_encode %{ 11070 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11071 int s = 63 - lshift; 11072 int r = (rshift - lshift) & 63; 11073 __ sbfm(as_Register($dst$$reg), 11074 as_Register($src$$reg), 11075 r, s); 11076 %} 11077 11078 ins_pipe(ialu_reg_shift); 11079 %} 11080 11081 // Shift Left followed by Shift Right. 11082 // This idiom is used by the compiler for the i2b bytecode etc. 11083 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11084 %{ 11085 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11086 // Make sure we are not going to exceed what sbfmw can do. 11087 predicate((unsigned int)n->in(2)->get_int() <= 31 11088 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11089 11090 ins_cost(INSN_COST * 2); 11091 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11092 ins_encode %{ 11093 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11094 int s = 31 - lshift; 11095 int r = (rshift - lshift) & 31; 11096 __ sbfmw(as_Register($dst$$reg), 11097 as_Register($src$$reg), 11098 r, s); 11099 %} 11100 11101 ins_pipe(ialu_reg_shift); 11102 %} 11103 11104 // Shift Left followed by Shift Right. 11105 // This idiom is used by the compiler for the i2b bytecode etc. 11106 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11107 %{ 11108 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11109 // Make sure we are not going to exceed what ubfm can do. 11110 predicate((unsigned int)n->in(2)->get_int() <= 63 11111 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 11112 11113 ins_cost(INSN_COST * 2); 11114 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11115 ins_encode %{ 11116 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11117 int s = 63 - lshift; 11118 int r = (rshift - lshift) & 63; 11119 __ ubfm(as_Register($dst$$reg), 11120 as_Register($src$$reg), 11121 r, s); 11122 %} 11123 11124 ins_pipe(ialu_reg_shift); 11125 %} 11126 11127 // Shift Left followed by Shift Right. 11128 // This idiom is used by the compiler for the i2b bytecode etc. 11129 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11130 %{ 11131 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11132 // Make sure we are not going to exceed what ubfmw can do. 11133 predicate((unsigned int)n->in(2)->get_int() <= 31 11134 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 11135 11136 ins_cost(INSN_COST * 2); 11137 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11138 ins_encode %{ 11139 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 11140 int s = 31 - lshift; 11141 int r = (rshift - lshift) & 31; 11142 __ ubfmw(as_Register($dst$$reg), 11143 as_Register($src$$reg), 11144 r, s); 11145 %} 11146 11147 ins_pipe(ialu_reg_shift); 11148 %} 11149 // Bitfield extract with shift & mask 11150 11151 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11152 %{ 11153 match(Set dst (AndI (URShiftI src rshift) mask)); 11154 11155 ins_cost(INSN_COST); 11156 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11157 ins_encode %{ 11158 int rshift = $rshift$$constant; 11159 long mask = $mask$$constant; 11160 int width = exact_log2(mask+1); 11161 __ ubfxw(as_Register($dst$$reg), 11162 as_Register($src$$reg), rshift, width); 11163 %} 11164 ins_pipe(ialu_reg_shift); 11165 %} 11166 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11167 %{ 11168 match(Set dst (AndL (URShiftL src rshift) mask)); 11169 11170 ins_cost(INSN_COST); 11171 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11172 ins_encode %{ 11173 int rshift = $rshift$$constant; 11174 long mask = $mask$$constant; 11175 int width = exact_log2(mask+1); 11176 __ ubfx(as_Register($dst$$reg), 11177 as_Register($src$$reg), rshift, width); 11178 %} 11179 ins_pipe(ialu_reg_shift); 11180 %} 11181 11182 // We can use ubfx when extending an And with a mask when we know mask 11183 // is positive. We know that because immI_bitmask guarantees it. 11184 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11185 %{ 11186 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11187 11188 ins_cost(INSN_COST * 2); 11189 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11190 ins_encode %{ 11191 int rshift = $rshift$$constant; 11192 long mask = $mask$$constant; 11193 int width = exact_log2(mask+1); 11194 __ ubfx(as_Register($dst$$reg), 11195 as_Register($src$$reg), rshift, width); 11196 %} 11197 ins_pipe(ialu_reg_shift); 11198 %} 11199 11200 // We can use ubfiz when masking by a positive number and then left shifting the result. 11201 // We know that the mask is positive because immI_bitmask guarantees it. 11202 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11203 %{ 11204 match(Set dst (LShiftI (AndI src mask) lshift)); 11205 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11206 (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1)); 11207 11208 ins_cost(INSN_COST); 11209 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11210 ins_encode %{ 11211 int lshift = $lshift$$constant; 11212 long mask = $mask$$constant; 11213 int width = exact_log2(mask+1); 11214 __ ubfizw(as_Register($dst$$reg), 11215 as_Register($src$$reg), lshift, width); 11216 %} 11217 ins_pipe(ialu_reg_shift); 11218 %} 11219 // We can use ubfiz when masking by a positive number and then left shifting the result. 11220 // We know that the mask is positive because immL_bitmask guarantees it. 11221 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11222 %{ 11223 match(Set dst (LShiftL (AndL src mask) lshift)); 11224 predicate((unsigned int)n->in(2)->get_int() <= 63 && 11225 (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1)); 11226 11227 ins_cost(INSN_COST); 11228 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11229 ins_encode %{ 11230 int lshift = $lshift$$constant; 11231 long mask = $mask$$constant; 11232 int width = exact_log2(mask+1); 11233 __ ubfiz(as_Register($dst$$reg), 11234 as_Register($src$$reg), lshift, width); 11235 %} 11236 ins_pipe(ialu_reg_shift); 11237 %} 11238 11239 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11240 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11241 %{ 11242 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); 11243 predicate((unsigned int)n->in(2)->get_int() <= 31 && 11244 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); 11245 11246 ins_cost(INSN_COST); 11247 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11248 ins_encode %{ 11249 int lshift = $lshift$$constant; 11250 long mask = $mask$$constant; 11251 int width = exact_log2(mask+1); 11252 __ ubfiz(as_Register($dst$$reg), 11253 as_Register($src$$reg), lshift, width); 11254 %} 11255 ins_pipe(ialu_reg_shift); 11256 %} 11257 11258 // Rotations 11259 11260 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11261 %{ 11262 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11263 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11264 11265 ins_cost(INSN_COST); 11266 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11267 11268 ins_encode %{ 11269 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11270 $rshift$$constant & 63); 11271 %} 11272 ins_pipe(ialu_reg_reg_extr); 11273 %} 11274 11275 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11276 %{ 11277 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11278 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11279 11280 ins_cost(INSN_COST); 11281 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11282 11283 ins_encode %{ 11284 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11285 $rshift$$constant & 31); 11286 %} 11287 ins_pipe(ialu_reg_reg_extr); 11288 %} 11289 11290 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11291 %{ 11292 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11293 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 11294 11295 ins_cost(INSN_COST); 11296 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11297 11298 ins_encode %{ 11299 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11300 $rshift$$constant & 63); 11301 %} 11302 ins_pipe(ialu_reg_reg_extr); 11303 %} 11304 11305 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11306 %{ 11307 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11308 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 11309 11310 ins_cost(INSN_COST); 11311 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11312 11313 ins_encode %{ 11314 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11315 $rshift$$constant & 31); 11316 %} 11317 ins_pipe(ialu_reg_reg_extr); 11318 %} 11319 11320 11321 // rol expander 11322 11323 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11324 %{ 11325 effect(DEF dst, USE src, USE shift); 11326 11327 format %{ "rol $dst, $src, $shift" %} 11328 ins_cost(INSN_COST * 3); 11329 ins_encode %{ 11330 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11331 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11332 rscratch1); 11333 %} 11334 ins_pipe(ialu_reg_reg_vshift); 11335 %} 11336 11337 // rol expander 11338 11339 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11340 %{ 11341 effect(DEF dst, USE src, USE shift); 11342 11343 format %{ "rol $dst, $src, $shift" %} 11344 ins_cost(INSN_COST * 3); 11345 ins_encode %{ 11346 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11347 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11348 rscratch1); 11349 %} 11350 ins_pipe(ialu_reg_reg_vshift); 11351 %} 11352 11353 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11354 %{ 11355 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11356 11357 expand %{ 11358 rolL_rReg(dst, src, shift, cr); 11359 %} 11360 %} 11361 11362 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11363 %{ 11364 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11365 11366 expand %{ 11367 rolL_rReg(dst, src, shift, cr); 11368 %} 11369 %} 11370 11371 instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11372 %{ 11373 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11374 11375 expand %{ 11376 rolI_rReg(dst, src, shift, cr); 11377 %} 11378 %} 11379 11380 instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11381 %{ 11382 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11383 11384 expand %{ 11385 rolI_rReg(dst, src, shift, cr); 11386 %} 11387 %} 11388 11389 // ror expander 11390 11391 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11392 %{ 11393 effect(DEF dst, USE src, USE shift); 11394 11395 format %{ "ror $dst, $src, $shift" %} 11396 ins_cost(INSN_COST); 11397 ins_encode %{ 11398 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11399 as_Register($shift$$reg)); 11400 %} 11401 ins_pipe(ialu_reg_reg_vshift); 11402 %} 11403 11404 // ror expander 11405 11406 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11407 %{ 11408 effect(DEF dst, USE src, USE shift); 11409 11410 format %{ "ror $dst, $src, $shift" %} 11411 ins_cost(INSN_COST); 11412 ins_encode %{ 11413 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11414 as_Register($shift$$reg)); 11415 %} 11416 ins_pipe(ialu_reg_reg_vshift); 11417 %} 11418 11419 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11420 %{ 11421 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11422 11423 expand %{ 11424 rorL_rReg(dst, src, shift, cr); 11425 %} 11426 %} 11427 11428 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11429 %{ 11430 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11431 11432 expand %{ 11433 rorL_rReg(dst, src, shift, cr); 11434 %} 11435 %} 11436 11437 instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11438 %{ 11439 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11440 11441 expand %{ 11442 rorI_rReg(dst, src, shift, cr); 11443 %} 11444 %} 11445 11446 instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11447 %{ 11448 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11449 11450 expand %{ 11451 rorI_rReg(dst, src, shift, cr); 11452 %} 11453 %} 11454 11455 // Add/subtract (extended) 11456 11457 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11458 %{ 11459 match(Set dst (AddL src1 (ConvI2L src2))); 11460 ins_cost(INSN_COST); 11461 format %{ "add $dst, $src1, $src2, sxtw" %} 11462 11463 ins_encode %{ 11464 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11465 as_Register($src2$$reg), ext::sxtw); 11466 %} 11467 ins_pipe(ialu_reg_reg); 11468 %}; 11469 11470 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11471 %{ 11472 match(Set dst (SubL src1 (ConvI2L src2))); 11473 ins_cost(INSN_COST); 11474 format %{ "sub $dst, $src1, $src2, sxtw" %} 11475 11476 ins_encode %{ 11477 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11478 as_Register($src2$$reg), ext::sxtw); 11479 %} 11480 ins_pipe(ialu_reg_reg); 11481 %}; 11482 11483 11484 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11485 %{ 11486 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11487 ins_cost(INSN_COST); 11488 format %{ "add $dst, $src1, $src2, sxth" %} 11489 11490 ins_encode %{ 11491 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11492 as_Register($src2$$reg), ext::sxth); 11493 %} 11494 ins_pipe(ialu_reg_reg); 11495 %} 11496 11497 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11498 %{ 11499 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11500 ins_cost(INSN_COST); 11501 format %{ "add $dst, $src1, $src2, sxtb" %} 11502 11503 ins_encode %{ 11504 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11505 as_Register($src2$$reg), ext::sxtb); 11506 %} 11507 ins_pipe(ialu_reg_reg); 11508 %} 11509 11510 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11511 %{ 11512 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 11513 ins_cost(INSN_COST); 11514 format %{ "add $dst, $src1, $src2, uxtb" %} 11515 11516 ins_encode %{ 11517 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11518 as_Register($src2$$reg), ext::uxtb); 11519 %} 11520 ins_pipe(ialu_reg_reg); 11521 %} 11522 11523 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 11524 %{ 11525 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11526 ins_cost(INSN_COST); 11527 format %{ "add $dst, $src1, $src2, sxth" %} 11528 11529 ins_encode %{ 11530 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11531 as_Register($src2$$reg), ext::sxth); 11532 %} 11533 ins_pipe(ialu_reg_reg); 11534 %} 11535 11536 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 11537 %{ 11538 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11539 ins_cost(INSN_COST); 11540 format %{ "add $dst, $src1, $src2, sxtw" %} 11541 11542 ins_encode %{ 11543 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11544 as_Register($src2$$reg), ext::sxtw); 11545 %} 11546 ins_pipe(ialu_reg_reg); 11547 %} 11548 11549 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11550 %{ 11551 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 11552 ins_cost(INSN_COST); 11553 format %{ "add $dst, $src1, $src2, sxtb" %} 11554 11555 ins_encode %{ 11556 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11557 as_Register($src2$$reg), ext::sxtb); 11558 %} 11559 ins_pipe(ialu_reg_reg); 11560 %} 11561 11562 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 11563 %{ 11564 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 11565 ins_cost(INSN_COST); 11566 format %{ "add $dst, $src1, $src2, uxtb" %} 11567 11568 ins_encode %{ 11569 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11570 as_Register($src2$$reg), ext::uxtb); 11571 %} 11572 ins_pipe(ialu_reg_reg); 11573 %} 11574 11575 11576 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11577 %{ 11578 match(Set dst (AddI src1 (AndI src2 mask))); 11579 ins_cost(INSN_COST); 11580 format %{ "addw $dst, $src1, $src2, uxtb" %} 11581 11582 ins_encode %{ 11583 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11584 as_Register($src2$$reg), ext::uxtb); 11585 %} 11586 ins_pipe(ialu_reg_reg); 11587 %} 11588 11589 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11590 %{ 11591 match(Set dst (AddI src1 (AndI src2 mask))); 11592 ins_cost(INSN_COST); 11593 format %{ "addw $dst, $src1, $src2, uxth" %} 11594 11595 ins_encode %{ 11596 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11597 as_Register($src2$$reg), ext::uxth); 11598 %} 11599 ins_pipe(ialu_reg_reg); 11600 %} 11601 11602 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11603 %{ 11604 match(Set dst (AddL src1 (AndL src2 mask))); 11605 ins_cost(INSN_COST); 11606 format %{ "add $dst, $src1, $src2, uxtb" %} 11607 11608 ins_encode %{ 11609 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11610 as_Register($src2$$reg), ext::uxtb); 11611 %} 11612 ins_pipe(ialu_reg_reg); 11613 %} 11614 11615 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11616 %{ 11617 match(Set dst (AddL src1 (AndL src2 mask))); 11618 ins_cost(INSN_COST); 11619 format %{ "add $dst, $src1, $src2, uxth" %} 11620 11621 ins_encode %{ 11622 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11623 as_Register($src2$$reg), ext::uxth); 11624 %} 11625 ins_pipe(ialu_reg_reg); 11626 %} 11627 11628 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11629 %{ 11630 match(Set dst (AddL src1 (AndL src2 mask))); 11631 ins_cost(INSN_COST); 11632 format %{ "add $dst, $src1, $src2, uxtw" %} 11633 11634 ins_encode %{ 11635 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11636 as_Register($src2$$reg), ext::uxtw); 11637 %} 11638 ins_pipe(ialu_reg_reg); 11639 %} 11640 11641 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 11642 %{ 11643 match(Set dst (SubI src1 (AndI src2 mask))); 11644 ins_cost(INSN_COST); 11645 format %{ "subw $dst, $src1, $src2, uxtb" %} 11646 11647 ins_encode %{ 11648 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11649 as_Register($src2$$reg), ext::uxtb); 11650 %} 11651 ins_pipe(ialu_reg_reg); 11652 %} 11653 11654 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 11655 %{ 11656 match(Set dst (SubI src1 (AndI src2 mask))); 11657 ins_cost(INSN_COST); 11658 format %{ "subw $dst, $src1, $src2, uxth" %} 11659 11660 ins_encode %{ 11661 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11662 as_Register($src2$$reg), ext::uxth); 11663 %} 11664 ins_pipe(ialu_reg_reg); 11665 %} 11666 11667 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 11668 %{ 11669 match(Set dst (SubL src1 (AndL src2 mask))); 11670 ins_cost(INSN_COST); 11671 format %{ "sub $dst, $src1, $src2, uxtb" %} 11672 11673 ins_encode %{ 11674 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11675 as_Register($src2$$reg), ext::uxtb); 11676 %} 11677 ins_pipe(ialu_reg_reg); 11678 %} 11679 11680 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 11681 %{ 11682 match(Set dst (SubL src1 (AndL src2 mask))); 11683 ins_cost(INSN_COST); 11684 format %{ "sub $dst, $src1, $src2, uxth" %} 11685 11686 ins_encode %{ 11687 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11688 as_Register($src2$$reg), ext::uxth); 11689 %} 11690 ins_pipe(ialu_reg_reg); 11691 %} 11692 11693 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 11694 %{ 11695 match(Set dst (SubL src1 (AndL src2 mask))); 11696 ins_cost(INSN_COST); 11697 format %{ "sub $dst, $src1, $src2, uxtw" %} 11698 11699 ins_encode %{ 11700 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11701 as_Register($src2$$reg), ext::uxtw); 11702 %} 11703 ins_pipe(ialu_reg_reg); 11704 %} 11705 11706 11707 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11708 %{ 11709 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11710 ins_cost(1.9 * INSN_COST); 11711 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 11712 11713 ins_encode %{ 11714 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11715 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11716 %} 11717 ins_pipe(ialu_reg_reg_shift); 11718 %} 11719 11720 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11721 %{ 11722 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11723 ins_cost(1.9 * INSN_COST); 11724 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 11725 11726 ins_encode %{ 11727 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11728 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11729 %} 11730 ins_pipe(ialu_reg_reg_shift); 11731 %} 11732 11733 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11734 %{ 11735 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11736 ins_cost(1.9 * INSN_COST); 11737 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 11738 11739 ins_encode %{ 11740 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11741 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11742 %} 11743 ins_pipe(ialu_reg_reg_shift); 11744 %} 11745 11746 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 11747 %{ 11748 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11749 ins_cost(1.9 * INSN_COST); 11750 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 11751 11752 ins_encode %{ 11753 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11754 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11755 %} 11756 ins_pipe(ialu_reg_reg_shift); 11757 %} 11758 11759 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 11760 %{ 11761 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11762 ins_cost(1.9 * INSN_COST); 11763 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 11764 11765 ins_encode %{ 11766 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11767 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11768 %} 11769 ins_pipe(ialu_reg_reg_shift); 11770 %} 11771 11772 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 11773 %{ 11774 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 11775 ins_cost(1.9 * INSN_COST); 11776 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 11777 11778 ins_encode %{ 11779 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11780 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 11781 %} 11782 ins_pipe(ialu_reg_reg_shift); 11783 %} 11784 11785 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 11786 %{ 11787 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11788 ins_cost(1.9 * INSN_COST); 11789 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 11790 11791 ins_encode %{ 11792 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11793 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11794 %} 11795 ins_pipe(ialu_reg_reg_shift); 11796 %} 11797 11798 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 11799 %{ 11800 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11801 ins_cost(1.9 * INSN_COST); 11802 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 11803 11804 ins_encode %{ 11805 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11806 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11807 %} 11808 ins_pipe(ialu_reg_reg_shift); 11809 %} 11810 11811 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 11812 %{ 11813 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11814 ins_cost(1.9 * INSN_COST); 11815 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 11816 11817 ins_encode %{ 11818 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11819 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 11820 %} 11821 ins_pipe(ialu_reg_reg_shift); 11822 %} 11823 11824 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 11825 %{ 11826 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 11827 ins_cost(1.9 * INSN_COST); 11828 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 11829 11830 ins_encode %{ 11831 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11832 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 11833 %} 11834 ins_pipe(ialu_reg_reg_shift); 11835 %} 11836 11837 11838 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 11839 %{ 11840 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 11841 ins_cost(1.9 * INSN_COST); 11842 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 11843 11844 ins_encode %{ 11845 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11846 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 11847 %} 11848 ins_pipe(ialu_reg_reg_shift); 11849 %}; 11850 11851 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 11852 %{ 11853 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 11854 ins_cost(1.9 * INSN_COST); 11855 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 11856 11857 ins_encode %{ 11858 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11859 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 11860 %} 11861 ins_pipe(ialu_reg_reg_shift); 11862 %}; 11863 11864 11865 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 11866 %{ 11867 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11868 ins_cost(1.9 * INSN_COST); 11869 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 11870 11871 ins_encode %{ 11872 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11873 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11874 %} 11875 ins_pipe(ialu_reg_reg_shift); 11876 %} 11877 11878 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 11879 %{ 11880 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11881 ins_cost(1.9 * INSN_COST); 11882 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 11883 11884 ins_encode %{ 11885 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11886 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11887 %} 11888 ins_pipe(ialu_reg_reg_shift); 11889 %} 11890 11891 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 11892 %{ 11893 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 11894 ins_cost(1.9 * INSN_COST); 11895 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 11896 11897 ins_encode %{ 11898 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11899 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 11900 %} 11901 ins_pipe(ialu_reg_reg_shift); 11902 %} 11903 11904 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 11905 %{ 11906 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11907 ins_cost(1.9 * INSN_COST); 11908 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 11909 11910 ins_encode %{ 11911 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11912 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11913 %} 11914 ins_pipe(ialu_reg_reg_shift); 11915 %} 11916 11917 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 11918 %{ 11919 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11920 ins_cost(1.9 * INSN_COST); 11921 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 11922 11923 ins_encode %{ 11924 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11925 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11926 %} 11927 ins_pipe(ialu_reg_reg_shift); 11928 %} 11929 11930 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 11931 %{ 11932 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 11933 ins_cost(1.9 * INSN_COST); 11934 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 11935 11936 ins_encode %{ 11937 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11938 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 11939 %} 11940 ins_pipe(ialu_reg_reg_shift); 11941 %} 11942 11943 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 11944 %{ 11945 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 11946 ins_cost(1.9 * INSN_COST); 11947 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 11948 11949 ins_encode %{ 11950 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11951 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11952 %} 11953 ins_pipe(ialu_reg_reg_shift); 11954 %} 11955 11956 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 11957 %{ 11958 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 11959 ins_cost(1.9 * INSN_COST); 11960 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 11961 11962 ins_encode %{ 11963 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 11964 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11965 %} 11966 ins_pipe(ialu_reg_reg_shift); 11967 %} 11968 11969 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 11970 %{ 11971 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 11972 ins_cost(1.9 * INSN_COST); 11973 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 11974 11975 ins_encode %{ 11976 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11977 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 11978 %} 11979 ins_pipe(ialu_reg_reg_shift); 11980 %} 11981 11982 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 11983 %{ 11984 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 11985 ins_cost(1.9 * INSN_COST); 11986 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 11987 11988 ins_encode %{ 11989 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 11990 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 11991 %} 11992 ins_pipe(ialu_reg_reg_shift); 11993 %} 11994 // END This section of the file is automatically generated. Do not edit -------------- 11995 11996 // ============================================================================ 11997 // Floating Point Arithmetic Instructions 11998 11999 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12000 match(Set dst (AddF src1 src2)); 12001 12002 ins_cost(INSN_COST * 5); 12003 format %{ "fadds $dst, $src1, $src2" %} 12004 12005 ins_encode %{ 12006 __ fadds(as_FloatRegister($dst$$reg), 12007 as_FloatRegister($src1$$reg), 12008 as_FloatRegister($src2$$reg)); 12009 %} 12010 12011 ins_pipe(fp_dop_reg_reg_s); 12012 %} 12013 12014 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12015 match(Set dst (AddD src1 src2)); 12016 12017 ins_cost(INSN_COST * 5); 12018 format %{ "faddd $dst, $src1, $src2" %} 12019 12020 ins_encode %{ 12021 __ faddd(as_FloatRegister($dst$$reg), 12022 as_FloatRegister($src1$$reg), 12023 as_FloatRegister($src2$$reg)); 12024 %} 12025 12026 ins_pipe(fp_dop_reg_reg_d); 12027 %} 12028 12029 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12030 match(Set dst (SubF src1 src2)); 12031 12032 ins_cost(INSN_COST * 5); 12033 format %{ "fsubs $dst, $src1, $src2" %} 12034 12035 ins_encode %{ 12036 __ fsubs(as_FloatRegister($dst$$reg), 12037 as_FloatRegister($src1$$reg), 12038 as_FloatRegister($src2$$reg)); 12039 %} 12040 12041 ins_pipe(fp_dop_reg_reg_s); 12042 %} 12043 12044 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12045 match(Set dst (SubD src1 src2)); 12046 12047 ins_cost(INSN_COST * 5); 12048 format %{ "fsubd $dst, $src1, $src2" %} 12049 12050 ins_encode %{ 12051 __ fsubd(as_FloatRegister($dst$$reg), 12052 as_FloatRegister($src1$$reg), 12053 as_FloatRegister($src2$$reg)); 12054 %} 12055 12056 ins_pipe(fp_dop_reg_reg_d); 12057 %} 12058 12059 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12060 match(Set dst (MulF src1 src2)); 12061 12062 ins_cost(INSN_COST * 6); 12063 format %{ "fmuls $dst, $src1, $src2" %} 12064 12065 ins_encode %{ 12066 __ fmuls(as_FloatRegister($dst$$reg), 12067 as_FloatRegister($src1$$reg), 12068 as_FloatRegister($src2$$reg)); 12069 %} 12070 12071 ins_pipe(fp_dop_reg_reg_s); 12072 %} 12073 12074 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12075 match(Set dst (MulD src1 src2)); 12076 12077 ins_cost(INSN_COST * 6); 12078 format %{ "fmuld $dst, $src1, $src2" %} 12079 12080 ins_encode %{ 12081 __ fmuld(as_FloatRegister($dst$$reg), 12082 as_FloatRegister($src1$$reg), 12083 as_FloatRegister($src2$$reg)); 12084 %} 12085 12086 ins_pipe(fp_dop_reg_reg_d); 12087 %} 12088 12089 // src1 * src2 + src3 12090 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12091 predicate(UseFMA); 12092 match(Set dst (FmaF src3 (Binary src1 src2))); 12093 12094 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12095 12096 ins_encode %{ 12097 __ fmadds(as_FloatRegister($dst$$reg), 12098 as_FloatRegister($src1$$reg), 12099 as_FloatRegister($src2$$reg), 12100 as_FloatRegister($src3$$reg)); 12101 %} 12102 12103 ins_pipe(pipe_class_default); 12104 %} 12105 12106 // src1 * src2 + src3 12107 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12108 predicate(UseFMA); 12109 match(Set dst (FmaD src3 (Binary src1 src2))); 12110 12111 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12112 12113 ins_encode %{ 12114 __ fmaddd(as_FloatRegister($dst$$reg), 12115 as_FloatRegister($src1$$reg), 12116 as_FloatRegister($src2$$reg), 12117 as_FloatRegister($src3$$reg)); 12118 %} 12119 12120 ins_pipe(pipe_class_default); 12121 %} 12122 12123 // -src1 * src2 + src3 12124 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12125 predicate(UseFMA); 12126 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12127 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12128 12129 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12130 12131 ins_encode %{ 12132 __ fmsubs(as_FloatRegister($dst$$reg), 12133 as_FloatRegister($src1$$reg), 12134 as_FloatRegister($src2$$reg), 12135 as_FloatRegister($src3$$reg)); 12136 %} 12137 12138 ins_pipe(pipe_class_default); 12139 %} 12140 12141 // -src1 * src2 + src3 12142 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12143 predicate(UseFMA); 12144 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12145 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12146 12147 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12148 12149 ins_encode %{ 12150 __ fmsubd(as_FloatRegister($dst$$reg), 12151 as_FloatRegister($src1$$reg), 12152 as_FloatRegister($src2$$reg), 12153 as_FloatRegister($src3$$reg)); 12154 %} 12155 12156 ins_pipe(pipe_class_default); 12157 %} 12158 12159 // -src1 * src2 - src3 12160 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12161 predicate(UseFMA); 12162 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12163 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12164 12165 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12166 12167 ins_encode %{ 12168 __ fnmadds(as_FloatRegister($dst$$reg), 12169 as_FloatRegister($src1$$reg), 12170 as_FloatRegister($src2$$reg), 12171 as_FloatRegister($src3$$reg)); 12172 %} 12173 12174 ins_pipe(pipe_class_default); 12175 %} 12176 12177 // -src1 * src2 - src3 12178 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12179 predicate(UseFMA); 12180 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12181 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12182 12183 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12184 12185 ins_encode %{ 12186 __ fnmaddd(as_FloatRegister($dst$$reg), 12187 as_FloatRegister($src1$$reg), 12188 as_FloatRegister($src2$$reg), 12189 as_FloatRegister($src3$$reg)); 12190 %} 12191 12192 ins_pipe(pipe_class_default); 12193 %} 12194 12195 // src1 * src2 - src3 12196 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12197 predicate(UseFMA); 12198 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12199 12200 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12201 12202 ins_encode %{ 12203 __ fnmsubs(as_FloatRegister($dst$$reg), 12204 as_FloatRegister($src1$$reg), 12205 as_FloatRegister($src2$$reg), 12206 as_FloatRegister($src3$$reg)); 12207 %} 12208 12209 ins_pipe(pipe_class_default); 12210 %} 12211 12212 // src1 * src2 - src3 12213 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12214 predicate(UseFMA); 12215 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12216 12217 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12218 12219 ins_encode %{ 12220 // n.b. insn name should be fnmsubd 12221 __ fnmsub(as_FloatRegister($dst$$reg), 12222 as_FloatRegister($src1$$reg), 12223 as_FloatRegister($src2$$reg), 12224 as_FloatRegister($src3$$reg)); 12225 %} 12226 12227 ins_pipe(pipe_class_default); 12228 %} 12229 12230 12231 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12232 match(Set dst (DivF src1 src2)); 12233 12234 ins_cost(INSN_COST * 18); 12235 format %{ "fdivs $dst, $src1, $src2" %} 12236 12237 ins_encode %{ 12238 __ fdivs(as_FloatRegister($dst$$reg), 12239 as_FloatRegister($src1$$reg), 12240 as_FloatRegister($src2$$reg)); 12241 %} 12242 12243 ins_pipe(fp_div_s); 12244 %} 12245 12246 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12247 match(Set dst (DivD src1 src2)); 12248 12249 ins_cost(INSN_COST * 32); 12250 format %{ "fdivd $dst, $src1, $src2" %} 12251 12252 ins_encode %{ 12253 __ fdivd(as_FloatRegister($dst$$reg), 12254 as_FloatRegister($src1$$reg), 12255 as_FloatRegister($src2$$reg)); 12256 %} 12257 12258 ins_pipe(fp_div_d); 12259 %} 12260 12261 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12262 match(Set dst (NegF src)); 12263 12264 ins_cost(INSN_COST * 3); 12265 format %{ "fneg $dst, $src" %} 12266 12267 ins_encode %{ 12268 __ fnegs(as_FloatRegister($dst$$reg), 12269 as_FloatRegister($src$$reg)); 12270 %} 12271 12272 ins_pipe(fp_uop_s); 12273 %} 12274 12275 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12276 match(Set dst (NegD src)); 12277 12278 ins_cost(INSN_COST * 3); 12279 format %{ "fnegd $dst, $src" %} 12280 12281 ins_encode %{ 12282 __ fnegd(as_FloatRegister($dst$$reg), 12283 as_FloatRegister($src$$reg)); 12284 %} 12285 12286 ins_pipe(fp_uop_d); 12287 %} 12288 12289 instruct absF_reg(vRegF dst, vRegF src) %{ 12290 match(Set dst (AbsF src)); 12291 12292 ins_cost(INSN_COST * 3); 12293 format %{ "fabss $dst, $src" %} 12294 ins_encode %{ 12295 __ fabss(as_FloatRegister($dst$$reg), 12296 as_FloatRegister($src$$reg)); 12297 %} 12298 12299 ins_pipe(fp_uop_s); 12300 %} 12301 12302 instruct absD_reg(vRegD dst, vRegD src) %{ 12303 match(Set dst (AbsD src)); 12304 12305 ins_cost(INSN_COST * 3); 12306 format %{ "fabsd $dst, $src" %} 12307 ins_encode %{ 12308 __ fabsd(as_FloatRegister($dst$$reg), 12309 as_FloatRegister($src$$reg)); 12310 %} 12311 12312 ins_pipe(fp_uop_d); 12313 %} 12314 12315 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12316 match(Set dst (SqrtD src)); 12317 12318 ins_cost(INSN_COST * 50); 12319 format %{ "fsqrtd $dst, $src" %} 12320 ins_encode %{ 12321 __ fsqrtd(as_FloatRegister($dst$$reg), 12322 as_FloatRegister($src$$reg)); 12323 %} 12324 12325 ins_pipe(fp_div_s); 12326 %} 12327 12328 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12329 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 12330 12331 ins_cost(INSN_COST * 50); 12332 format %{ "fsqrts $dst, $src" %} 12333 ins_encode %{ 12334 __ fsqrts(as_FloatRegister($dst$$reg), 12335 as_FloatRegister($src$$reg)); 12336 %} 12337 12338 ins_pipe(fp_div_d); 12339 %} 12340 12341 // ============================================================================ 12342 // Logical Instructions 12343 12344 // Integer Logical Instructions 12345 12346 // And Instructions 12347 12348 12349 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 12350 match(Set dst (AndI src1 src2)); 12351 12352 format %{ "andw $dst, $src1, $src2\t# int" %} 12353 12354 ins_cost(INSN_COST); 12355 ins_encode %{ 12356 __ andw(as_Register($dst$$reg), 12357 as_Register($src1$$reg), 12358 as_Register($src2$$reg)); 12359 %} 12360 12361 ins_pipe(ialu_reg_reg); 12362 %} 12363 12364 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 12365 match(Set dst (AndI src1 src2)); 12366 12367 format %{ "andsw $dst, $src1, $src2\t# int" %} 12368 12369 ins_cost(INSN_COST); 12370 ins_encode %{ 12371 __ andw(as_Register($dst$$reg), 12372 as_Register($src1$$reg), 12373 (unsigned long)($src2$$constant)); 12374 %} 12375 12376 ins_pipe(ialu_reg_imm); 12377 %} 12378 12379 // Or Instructions 12380 12381 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12382 match(Set dst (OrI src1 src2)); 12383 12384 format %{ "orrw $dst, $src1, $src2\t# int" %} 12385 12386 ins_cost(INSN_COST); 12387 ins_encode %{ 12388 __ orrw(as_Register($dst$$reg), 12389 as_Register($src1$$reg), 12390 as_Register($src2$$reg)); 12391 %} 12392 12393 ins_pipe(ialu_reg_reg); 12394 %} 12395 12396 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12397 match(Set dst (OrI src1 src2)); 12398 12399 format %{ "orrw $dst, $src1, $src2\t# int" %} 12400 12401 ins_cost(INSN_COST); 12402 ins_encode %{ 12403 __ orrw(as_Register($dst$$reg), 12404 as_Register($src1$$reg), 12405 (unsigned long)($src2$$constant)); 12406 %} 12407 12408 ins_pipe(ialu_reg_imm); 12409 %} 12410 12411 // Xor Instructions 12412 12413 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 12414 match(Set dst (XorI src1 src2)); 12415 12416 format %{ "eorw $dst, $src1, $src2\t# int" %} 12417 12418 ins_cost(INSN_COST); 12419 ins_encode %{ 12420 __ eorw(as_Register($dst$$reg), 12421 as_Register($src1$$reg), 12422 as_Register($src2$$reg)); 12423 %} 12424 12425 ins_pipe(ialu_reg_reg); 12426 %} 12427 12428 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 12429 match(Set dst (XorI src1 src2)); 12430 12431 format %{ "eorw $dst, $src1, $src2\t# int" %} 12432 12433 ins_cost(INSN_COST); 12434 ins_encode %{ 12435 __ eorw(as_Register($dst$$reg), 12436 as_Register($src1$$reg), 12437 (unsigned long)($src2$$constant)); 12438 %} 12439 12440 ins_pipe(ialu_reg_imm); 12441 %} 12442 12443 // Long Logical Instructions 12444 // TODO 12445 12446 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 12447 match(Set dst (AndL src1 src2)); 12448 12449 format %{ "and $dst, $src1, $src2\t# int" %} 12450 12451 ins_cost(INSN_COST); 12452 ins_encode %{ 12453 __ andr(as_Register($dst$$reg), 12454 as_Register($src1$$reg), 12455 as_Register($src2$$reg)); 12456 %} 12457 12458 ins_pipe(ialu_reg_reg); 12459 %} 12460 12461 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 12462 match(Set dst (AndL src1 src2)); 12463 12464 format %{ "and $dst, $src1, $src2\t# int" %} 12465 12466 ins_cost(INSN_COST); 12467 ins_encode %{ 12468 __ andr(as_Register($dst$$reg), 12469 as_Register($src1$$reg), 12470 (unsigned long)($src2$$constant)); 12471 %} 12472 12473 ins_pipe(ialu_reg_imm); 12474 %} 12475 12476 // Or Instructions 12477 12478 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12479 match(Set dst (OrL src1 src2)); 12480 12481 format %{ "orr $dst, $src1, $src2\t# int" %} 12482 12483 ins_cost(INSN_COST); 12484 ins_encode %{ 12485 __ orr(as_Register($dst$$reg), 12486 as_Register($src1$$reg), 12487 as_Register($src2$$reg)); 12488 %} 12489 12490 ins_pipe(ialu_reg_reg); 12491 %} 12492 12493 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12494 match(Set dst (OrL src1 src2)); 12495 12496 format %{ "orr $dst, $src1, $src2\t# int" %} 12497 12498 ins_cost(INSN_COST); 12499 ins_encode %{ 12500 __ orr(as_Register($dst$$reg), 12501 as_Register($src1$$reg), 12502 (unsigned long)($src2$$constant)); 12503 %} 12504 12505 ins_pipe(ialu_reg_imm); 12506 %} 12507 12508 // Xor Instructions 12509 12510 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 12511 match(Set dst (XorL src1 src2)); 12512 12513 format %{ "eor $dst, $src1, $src2\t# int" %} 12514 12515 ins_cost(INSN_COST); 12516 ins_encode %{ 12517 __ eor(as_Register($dst$$reg), 12518 as_Register($src1$$reg), 12519 as_Register($src2$$reg)); 12520 %} 12521 12522 ins_pipe(ialu_reg_reg); 12523 %} 12524 12525 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 12526 match(Set dst (XorL src1 src2)); 12527 12528 ins_cost(INSN_COST); 12529 format %{ "eor $dst, $src1, $src2\t# int" %} 12530 12531 ins_encode %{ 12532 __ eor(as_Register($dst$$reg), 12533 as_Register($src1$$reg), 12534 (unsigned long)($src2$$constant)); 12535 %} 12536 12537 ins_pipe(ialu_reg_imm); 12538 %} 12539 12540 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 12541 %{ 12542 match(Set dst (ConvI2L src)); 12543 12544 ins_cost(INSN_COST); 12545 format %{ "sxtw $dst, $src\t# i2l" %} 12546 ins_encode %{ 12547 __ sbfm($dst$$Register, $src$$Register, 0, 31); 12548 %} 12549 ins_pipe(ialu_reg_shift); 12550 %} 12551 12552 // this pattern occurs in bigmath arithmetic 12553 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 12554 %{ 12555 match(Set dst (AndL (ConvI2L src) mask)); 12556 12557 ins_cost(INSN_COST); 12558 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 12559 ins_encode %{ 12560 __ ubfm($dst$$Register, $src$$Register, 0, 31); 12561 %} 12562 12563 ins_pipe(ialu_reg_shift); 12564 %} 12565 12566 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 12567 match(Set dst (ConvL2I src)); 12568 12569 ins_cost(INSN_COST); 12570 format %{ "movw $dst, $src \t// l2i" %} 12571 12572 ins_encode %{ 12573 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 12574 %} 12575 12576 ins_pipe(ialu_reg); 12577 %} 12578 12579 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12580 %{ 12581 match(Set dst (Conv2B src)); 12582 effect(KILL cr); 12583 12584 format %{ 12585 "cmpw $src, zr\n\t" 12586 "cset $dst, ne" 12587 %} 12588 12589 ins_encode %{ 12590 __ cmpw(as_Register($src$$reg), zr); 12591 __ cset(as_Register($dst$$reg), Assembler::NE); 12592 %} 12593 12594 ins_pipe(ialu_reg); 12595 %} 12596 12597 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 12598 %{ 12599 match(Set dst (Conv2B src)); 12600 effect(KILL cr); 12601 12602 format %{ 12603 "cmp $src, zr\n\t" 12604 "cset $dst, ne" 12605 %} 12606 12607 ins_encode %{ 12608 __ cmp(as_Register($src$$reg), zr); 12609 __ cset(as_Register($dst$$reg), Assembler::NE); 12610 %} 12611 12612 ins_pipe(ialu_reg); 12613 %} 12614 12615 instruct convD2F_reg(vRegF dst, vRegD src) %{ 12616 match(Set dst (ConvD2F src)); 12617 12618 ins_cost(INSN_COST * 5); 12619 format %{ "fcvtd $dst, $src \t// d2f" %} 12620 12621 ins_encode %{ 12622 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12623 %} 12624 12625 ins_pipe(fp_d2f); 12626 %} 12627 12628 instruct convF2D_reg(vRegD dst, vRegF src) %{ 12629 match(Set dst (ConvF2D src)); 12630 12631 ins_cost(INSN_COST * 5); 12632 format %{ "fcvts $dst, $src \t// f2d" %} 12633 12634 ins_encode %{ 12635 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 12636 %} 12637 12638 ins_pipe(fp_f2d); 12639 %} 12640 12641 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12642 match(Set dst (ConvF2I src)); 12643 12644 ins_cost(INSN_COST * 5); 12645 format %{ "fcvtzsw $dst, $src \t// f2i" %} 12646 12647 ins_encode %{ 12648 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12649 %} 12650 12651 ins_pipe(fp_f2i); 12652 %} 12653 12654 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 12655 match(Set dst (ConvF2L src)); 12656 12657 ins_cost(INSN_COST * 5); 12658 format %{ "fcvtzs $dst, $src \t// f2l" %} 12659 12660 ins_encode %{ 12661 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12662 %} 12663 12664 ins_pipe(fp_f2l); 12665 %} 12666 12667 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 12668 match(Set dst (ConvI2F src)); 12669 12670 ins_cost(INSN_COST * 5); 12671 format %{ "scvtfws $dst, $src \t// i2f" %} 12672 12673 ins_encode %{ 12674 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12675 %} 12676 12677 ins_pipe(fp_i2f); 12678 %} 12679 12680 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 12681 match(Set dst (ConvL2F src)); 12682 12683 ins_cost(INSN_COST * 5); 12684 format %{ "scvtfs $dst, $src \t// l2f" %} 12685 12686 ins_encode %{ 12687 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12688 %} 12689 12690 ins_pipe(fp_l2f); 12691 %} 12692 12693 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 12694 match(Set dst (ConvD2I src)); 12695 12696 ins_cost(INSN_COST * 5); 12697 format %{ "fcvtzdw $dst, $src \t// d2i" %} 12698 12699 ins_encode %{ 12700 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12701 %} 12702 12703 ins_pipe(fp_d2i); 12704 %} 12705 12706 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12707 match(Set dst (ConvD2L src)); 12708 12709 ins_cost(INSN_COST * 5); 12710 format %{ "fcvtzd $dst, $src \t// d2l" %} 12711 12712 ins_encode %{ 12713 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 12714 %} 12715 12716 ins_pipe(fp_d2l); 12717 %} 12718 12719 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 12720 match(Set dst (ConvI2D src)); 12721 12722 ins_cost(INSN_COST * 5); 12723 format %{ "scvtfwd $dst, $src \t// i2d" %} 12724 12725 ins_encode %{ 12726 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12727 %} 12728 12729 ins_pipe(fp_i2d); 12730 %} 12731 12732 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 12733 match(Set dst (ConvL2D src)); 12734 12735 ins_cost(INSN_COST * 5); 12736 format %{ "scvtfd $dst, $src \t// l2d" %} 12737 12738 ins_encode %{ 12739 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 12740 %} 12741 12742 ins_pipe(fp_l2d); 12743 %} 12744 12745 // stack <-> reg and reg <-> reg shuffles with no conversion 12746 12747 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 12748 12749 match(Set dst (MoveF2I src)); 12750 12751 effect(DEF dst, USE src); 12752 12753 ins_cost(4 * INSN_COST); 12754 12755 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 12756 12757 ins_encode %{ 12758 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 12759 %} 12760 12761 ins_pipe(iload_reg_reg); 12762 12763 %} 12764 12765 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 12766 12767 match(Set dst (MoveI2F src)); 12768 12769 effect(DEF dst, USE src); 12770 12771 ins_cost(4 * INSN_COST); 12772 12773 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 12774 12775 ins_encode %{ 12776 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12777 %} 12778 12779 ins_pipe(pipe_class_memory); 12780 12781 %} 12782 12783 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 12784 12785 match(Set dst (MoveD2L src)); 12786 12787 effect(DEF dst, USE src); 12788 12789 ins_cost(4 * INSN_COST); 12790 12791 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 12792 12793 ins_encode %{ 12794 __ ldr($dst$$Register, Address(sp, $src$$disp)); 12795 %} 12796 12797 ins_pipe(iload_reg_reg); 12798 12799 %} 12800 12801 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 12802 12803 match(Set dst (MoveL2D src)); 12804 12805 effect(DEF dst, USE src); 12806 12807 ins_cost(4 * INSN_COST); 12808 12809 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 12810 12811 ins_encode %{ 12812 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 12813 %} 12814 12815 ins_pipe(pipe_class_memory); 12816 12817 %} 12818 12819 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 12820 12821 match(Set dst (MoveF2I src)); 12822 12823 effect(DEF dst, USE src); 12824 12825 ins_cost(INSN_COST); 12826 12827 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 12828 12829 ins_encode %{ 12830 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 12831 %} 12832 12833 ins_pipe(pipe_class_memory); 12834 12835 %} 12836 12837 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 12838 12839 match(Set dst (MoveI2F src)); 12840 12841 effect(DEF dst, USE src); 12842 12843 ins_cost(INSN_COST); 12844 12845 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 12846 12847 ins_encode %{ 12848 __ strw($src$$Register, Address(sp, $dst$$disp)); 12849 %} 12850 12851 ins_pipe(istore_reg_reg); 12852 12853 %} 12854 12855 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 12856 12857 match(Set dst (MoveD2L src)); 12858 12859 effect(DEF dst, USE src); 12860 12861 ins_cost(INSN_COST); 12862 12863 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 12864 12865 ins_encode %{ 12866 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 12867 %} 12868 12869 ins_pipe(pipe_class_memory); 12870 12871 %} 12872 12873 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 12874 12875 match(Set dst (MoveL2D src)); 12876 12877 effect(DEF dst, USE src); 12878 12879 ins_cost(INSN_COST); 12880 12881 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 12882 12883 ins_encode %{ 12884 __ str($src$$Register, Address(sp, $dst$$disp)); 12885 %} 12886 12887 ins_pipe(istore_reg_reg); 12888 12889 %} 12890 12891 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 12892 12893 match(Set dst (MoveF2I src)); 12894 12895 effect(DEF dst, USE src); 12896 12897 ins_cost(INSN_COST); 12898 12899 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 12900 12901 ins_encode %{ 12902 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 12903 %} 12904 12905 ins_pipe(fp_f2i); 12906 12907 %} 12908 12909 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 12910 12911 match(Set dst (MoveI2F src)); 12912 12913 effect(DEF dst, USE src); 12914 12915 ins_cost(INSN_COST); 12916 12917 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 12918 12919 ins_encode %{ 12920 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 12921 %} 12922 12923 ins_pipe(fp_i2f); 12924 12925 %} 12926 12927 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 12928 12929 match(Set dst (MoveD2L src)); 12930 12931 effect(DEF dst, USE src); 12932 12933 ins_cost(INSN_COST); 12934 12935 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 12936 12937 ins_encode %{ 12938 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 12939 %} 12940 12941 ins_pipe(fp_d2l); 12942 12943 %} 12944 12945 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 12946 12947 match(Set dst (MoveL2D src)); 12948 12949 effect(DEF dst, USE src); 12950 12951 ins_cost(INSN_COST); 12952 12953 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 12954 12955 ins_encode %{ 12956 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 12957 %} 12958 12959 ins_pipe(fp_l2d); 12960 12961 %} 12962 12963 // ============================================================================ 12964 // clearing of an array 12965 12966 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 12967 %{ 12968 match(Set dummy (ClearArray cnt base)); 12969 effect(USE_KILL cnt, USE_KILL base); 12970 12971 ins_cost(4 * INSN_COST); 12972 format %{ "ClearArray $cnt, $base" %} 12973 12974 ins_encode %{ 12975 __ zero_words($base$$Register, $cnt$$Register); 12976 %} 12977 12978 ins_pipe(pipe_class_memory); 12979 %} 12980 12981 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 12982 %{ 12983 predicate((u_int64_t)n->in(2)->get_long() 12984 < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 12985 match(Set dummy (ClearArray cnt base)); 12986 effect(USE_KILL base); 12987 12988 ins_cost(4 * INSN_COST); 12989 format %{ "ClearArray $cnt, $base" %} 12990 12991 ins_encode %{ 12992 __ zero_words($base$$Register, (u_int64_t)$cnt$$constant); 12993 %} 12994 12995 ins_pipe(pipe_class_memory); 12996 %} 12997 12998 // ============================================================================ 12999 // Overflow Math Instructions 13000 13001 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13002 %{ 13003 match(Set cr (OverflowAddI op1 op2)); 13004 13005 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13006 ins_cost(INSN_COST); 13007 ins_encode %{ 13008 __ cmnw($op1$$Register, $op2$$Register); 13009 %} 13010 13011 ins_pipe(icmp_reg_reg); 13012 %} 13013 13014 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13015 %{ 13016 match(Set cr (OverflowAddI op1 op2)); 13017 13018 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13019 ins_cost(INSN_COST); 13020 ins_encode %{ 13021 __ cmnw($op1$$Register, $op2$$constant); 13022 %} 13023 13024 ins_pipe(icmp_reg_imm); 13025 %} 13026 13027 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13028 %{ 13029 match(Set cr (OverflowAddL op1 op2)); 13030 13031 format %{ "cmn $op1, $op2\t# overflow check long" %} 13032 ins_cost(INSN_COST); 13033 ins_encode %{ 13034 __ cmn($op1$$Register, $op2$$Register); 13035 %} 13036 13037 ins_pipe(icmp_reg_reg); 13038 %} 13039 13040 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13041 %{ 13042 match(Set cr (OverflowAddL op1 op2)); 13043 13044 format %{ "cmn $op1, $op2\t# overflow check long" %} 13045 ins_cost(INSN_COST); 13046 ins_encode %{ 13047 __ cmn($op1$$Register, $op2$$constant); 13048 %} 13049 13050 ins_pipe(icmp_reg_imm); 13051 %} 13052 13053 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13054 %{ 13055 match(Set cr (OverflowSubI op1 op2)); 13056 13057 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13058 ins_cost(INSN_COST); 13059 ins_encode %{ 13060 __ cmpw($op1$$Register, $op2$$Register); 13061 %} 13062 13063 ins_pipe(icmp_reg_reg); 13064 %} 13065 13066 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13067 %{ 13068 match(Set cr (OverflowSubI op1 op2)); 13069 13070 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13071 ins_cost(INSN_COST); 13072 ins_encode %{ 13073 __ cmpw($op1$$Register, $op2$$constant); 13074 %} 13075 13076 ins_pipe(icmp_reg_imm); 13077 %} 13078 13079 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13080 %{ 13081 match(Set cr (OverflowSubL op1 op2)); 13082 13083 format %{ "cmp $op1, $op2\t# overflow check long" %} 13084 ins_cost(INSN_COST); 13085 ins_encode %{ 13086 __ cmp($op1$$Register, $op2$$Register); 13087 %} 13088 13089 ins_pipe(icmp_reg_reg); 13090 %} 13091 13092 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13093 %{ 13094 match(Set cr (OverflowSubL op1 op2)); 13095 13096 format %{ "cmp $op1, $op2\t# overflow check long" %} 13097 ins_cost(INSN_COST); 13098 ins_encode %{ 13099 __ subs(zr, $op1$$Register, $op2$$constant); 13100 %} 13101 13102 ins_pipe(icmp_reg_imm); 13103 %} 13104 13105 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13106 %{ 13107 match(Set cr (OverflowSubI zero op1)); 13108 13109 format %{ "cmpw zr, $op1\t# overflow check int" %} 13110 ins_cost(INSN_COST); 13111 ins_encode %{ 13112 __ cmpw(zr, $op1$$Register); 13113 %} 13114 13115 ins_pipe(icmp_reg_imm); 13116 %} 13117 13118 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13119 %{ 13120 match(Set cr (OverflowSubL zero op1)); 13121 13122 format %{ "cmp zr, $op1\t# overflow check long" %} 13123 ins_cost(INSN_COST); 13124 ins_encode %{ 13125 __ cmp(zr, $op1$$Register); 13126 %} 13127 13128 ins_pipe(icmp_reg_imm); 13129 %} 13130 13131 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13132 %{ 13133 match(Set cr (OverflowMulI op1 op2)); 13134 13135 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13136 "cmp rscratch1, rscratch1, sxtw\n\t" 13137 "movw rscratch1, #0x80000000\n\t" 13138 "cselw rscratch1, rscratch1, zr, NE\n\t" 13139 "cmpw rscratch1, #1" %} 13140 ins_cost(5 * INSN_COST); 13141 ins_encode %{ 13142 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13143 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13144 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13145 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13146 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13147 %} 13148 13149 ins_pipe(pipe_slow); 13150 %} 13151 13152 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13153 %{ 13154 match(If cmp (OverflowMulI op1 op2)); 13155 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13156 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13157 effect(USE labl, KILL cr); 13158 13159 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13160 "cmp rscratch1, rscratch1, sxtw\n\t" 13161 "b$cmp $labl" %} 13162 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13163 ins_encode %{ 13164 Label* L = $labl$$label; 13165 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13166 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13167 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13168 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13169 %} 13170 13171 ins_pipe(pipe_serial); 13172 %} 13173 13174 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13175 %{ 13176 match(Set cr (OverflowMulL op1 op2)); 13177 13178 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13179 "smulh rscratch2, $op1, $op2\n\t" 13180 "cmp rscratch2, rscratch1, ASR #63\n\t" 13181 "movw rscratch1, #0x80000000\n\t" 13182 "cselw rscratch1, rscratch1, zr, NE\n\t" 13183 "cmpw rscratch1, #1" %} 13184 ins_cost(6 * INSN_COST); 13185 ins_encode %{ 13186 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13187 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13188 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13189 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13190 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13191 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13192 %} 13193 13194 ins_pipe(pipe_slow); 13195 %} 13196 13197 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13198 %{ 13199 match(If cmp (OverflowMulL op1 op2)); 13200 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13201 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13202 effect(USE labl, KILL cr); 13203 13204 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13205 "smulh rscratch2, $op1, $op2\n\t" 13206 "cmp rscratch2, rscratch1, ASR #63\n\t" 13207 "b$cmp $labl" %} 13208 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13209 ins_encode %{ 13210 Label* L = $labl$$label; 13211 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13212 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13213 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13214 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13215 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13216 %} 13217 13218 ins_pipe(pipe_serial); 13219 %} 13220 13221 // ============================================================================ 13222 // Compare Instructions 13223 13224 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13225 %{ 13226 match(Set cr (CmpI op1 op2)); 13227 13228 effect(DEF cr, USE op1, USE op2); 13229 13230 ins_cost(INSN_COST); 13231 format %{ "cmpw $op1, $op2" %} 13232 13233 ins_encode(aarch64_enc_cmpw(op1, op2)); 13234 13235 ins_pipe(icmp_reg_reg); 13236 %} 13237 13238 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13239 %{ 13240 match(Set cr (CmpI op1 zero)); 13241 13242 effect(DEF cr, USE op1); 13243 13244 ins_cost(INSN_COST); 13245 format %{ "cmpw $op1, 0" %} 13246 13247 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13248 13249 ins_pipe(icmp_reg_imm); 13250 %} 13251 13252 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13253 %{ 13254 match(Set cr (CmpI op1 op2)); 13255 13256 effect(DEF cr, USE op1); 13257 13258 ins_cost(INSN_COST); 13259 format %{ "cmpw $op1, $op2" %} 13260 13261 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13262 13263 ins_pipe(icmp_reg_imm); 13264 %} 13265 13266 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 13267 %{ 13268 match(Set cr (CmpI op1 op2)); 13269 13270 effect(DEF cr, USE op1); 13271 13272 ins_cost(INSN_COST * 2); 13273 format %{ "cmpw $op1, $op2" %} 13274 13275 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13276 13277 ins_pipe(icmp_reg_imm); 13278 %} 13279 13280 // Unsigned compare Instructions; really, same as signed compare 13281 // except it should only be used to feed an If or a CMovI which takes a 13282 // cmpOpU. 13283 13284 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 13285 %{ 13286 match(Set cr (CmpU op1 op2)); 13287 13288 effect(DEF cr, USE op1, USE op2); 13289 13290 ins_cost(INSN_COST); 13291 format %{ "cmpw $op1, $op2\t# unsigned" %} 13292 13293 ins_encode(aarch64_enc_cmpw(op1, op2)); 13294 13295 ins_pipe(icmp_reg_reg); 13296 %} 13297 13298 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 13299 %{ 13300 match(Set cr (CmpU op1 zero)); 13301 13302 effect(DEF cr, USE op1); 13303 13304 ins_cost(INSN_COST); 13305 format %{ "cmpw $op1, #0\t# unsigned" %} 13306 13307 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13308 13309 ins_pipe(icmp_reg_imm); 13310 %} 13311 13312 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 13313 %{ 13314 match(Set cr (CmpU op1 op2)); 13315 13316 effect(DEF cr, USE op1); 13317 13318 ins_cost(INSN_COST); 13319 format %{ "cmpw $op1, $op2\t# unsigned" %} 13320 13321 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13322 13323 ins_pipe(icmp_reg_imm); 13324 %} 13325 13326 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 13327 %{ 13328 match(Set cr (CmpU op1 op2)); 13329 13330 effect(DEF cr, USE op1); 13331 13332 ins_cost(INSN_COST * 2); 13333 format %{ "cmpw $op1, $op2\t# unsigned" %} 13334 13335 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 13336 13337 ins_pipe(icmp_reg_imm); 13338 %} 13339 13340 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13341 %{ 13342 match(Set cr (CmpL op1 op2)); 13343 13344 effect(DEF cr, USE op1, USE op2); 13345 13346 ins_cost(INSN_COST); 13347 format %{ "cmp $op1, $op2" %} 13348 13349 ins_encode(aarch64_enc_cmp(op1, op2)); 13350 13351 ins_pipe(icmp_reg_reg); 13352 %} 13353 13354 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 13355 %{ 13356 match(Set cr (CmpL op1 zero)); 13357 13358 effect(DEF cr, USE op1); 13359 13360 ins_cost(INSN_COST); 13361 format %{ "tst $op1" %} 13362 13363 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13364 13365 ins_pipe(icmp_reg_imm); 13366 %} 13367 13368 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 13369 %{ 13370 match(Set cr (CmpL op1 op2)); 13371 13372 effect(DEF cr, USE op1); 13373 13374 ins_cost(INSN_COST); 13375 format %{ "cmp $op1, $op2" %} 13376 13377 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13378 13379 ins_pipe(icmp_reg_imm); 13380 %} 13381 13382 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 13383 %{ 13384 match(Set cr (CmpL op1 op2)); 13385 13386 effect(DEF cr, USE op1); 13387 13388 ins_cost(INSN_COST * 2); 13389 format %{ "cmp $op1, $op2" %} 13390 13391 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13392 13393 ins_pipe(icmp_reg_imm); 13394 %} 13395 13396 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 13397 %{ 13398 match(Set cr (CmpUL op1 op2)); 13399 13400 effect(DEF cr, USE op1, USE op2); 13401 13402 ins_cost(INSN_COST); 13403 format %{ "cmp $op1, $op2" %} 13404 13405 ins_encode(aarch64_enc_cmp(op1, op2)); 13406 13407 ins_pipe(icmp_reg_reg); 13408 %} 13409 13410 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 13411 %{ 13412 match(Set cr (CmpUL op1 zero)); 13413 13414 effect(DEF cr, USE op1); 13415 13416 ins_cost(INSN_COST); 13417 format %{ "tst $op1" %} 13418 13419 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 13420 13421 ins_pipe(icmp_reg_imm); 13422 %} 13423 13424 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 13425 %{ 13426 match(Set cr (CmpUL op1 op2)); 13427 13428 effect(DEF cr, USE op1); 13429 13430 ins_cost(INSN_COST); 13431 format %{ "cmp $op1, $op2" %} 13432 13433 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 13434 13435 ins_pipe(icmp_reg_imm); 13436 %} 13437 13438 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 13439 %{ 13440 match(Set cr (CmpUL op1 op2)); 13441 13442 effect(DEF cr, USE op1); 13443 13444 ins_cost(INSN_COST * 2); 13445 format %{ "cmp $op1, $op2" %} 13446 13447 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 13448 13449 ins_pipe(icmp_reg_imm); 13450 %} 13451 13452 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 13453 %{ 13454 match(Set cr (CmpP op1 op2)); 13455 13456 effect(DEF cr, USE op1, USE op2); 13457 13458 ins_cost(INSN_COST); 13459 format %{ "cmp $op1, $op2\t // ptr" %} 13460 13461 ins_encode(aarch64_enc_cmpp(op1, op2)); 13462 13463 ins_pipe(icmp_reg_reg); 13464 %} 13465 13466 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 13467 %{ 13468 match(Set cr (CmpN op1 op2)); 13469 13470 effect(DEF cr, USE op1, USE op2); 13471 13472 ins_cost(INSN_COST); 13473 format %{ "cmp $op1, $op2\t // compressed ptr" %} 13474 13475 ins_encode(aarch64_enc_cmpn(op1, op2)); 13476 13477 ins_pipe(icmp_reg_reg); 13478 %} 13479 13480 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 13481 %{ 13482 match(Set cr (CmpP op1 zero)); 13483 13484 effect(DEF cr, USE op1, USE zero); 13485 13486 ins_cost(INSN_COST); 13487 format %{ "cmp $op1, 0\t // ptr" %} 13488 13489 ins_encode(aarch64_enc_testp(op1)); 13490 13491 ins_pipe(icmp_reg_imm); 13492 %} 13493 13494 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 13495 %{ 13496 match(Set cr (CmpN op1 zero)); 13497 13498 effect(DEF cr, USE op1, USE zero); 13499 13500 ins_cost(INSN_COST); 13501 format %{ "cmp $op1, 0\t // compressed ptr" %} 13502 13503 ins_encode(aarch64_enc_testn(op1)); 13504 13505 ins_pipe(icmp_reg_imm); 13506 %} 13507 13508 // FP comparisons 13509 // 13510 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 13511 // using normal cmpOp. See declaration of rFlagsReg for details. 13512 13513 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 13514 %{ 13515 match(Set cr (CmpF src1 src2)); 13516 13517 ins_cost(3 * INSN_COST); 13518 format %{ "fcmps $src1, $src2" %} 13519 13520 ins_encode %{ 13521 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13522 %} 13523 13524 ins_pipe(pipe_class_compare); 13525 %} 13526 13527 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 13528 %{ 13529 match(Set cr (CmpF src1 src2)); 13530 13531 ins_cost(3 * INSN_COST); 13532 format %{ "fcmps $src1, 0.0" %} 13533 13534 ins_encode %{ 13535 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 13536 %} 13537 13538 ins_pipe(pipe_class_compare); 13539 %} 13540 // FROM HERE 13541 13542 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 13543 %{ 13544 match(Set cr (CmpD src1 src2)); 13545 13546 ins_cost(3 * INSN_COST); 13547 format %{ "fcmpd $src1, $src2" %} 13548 13549 ins_encode %{ 13550 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13551 %} 13552 13553 ins_pipe(pipe_class_compare); 13554 %} 13555 13556 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 13557 %{ 13558 match(Set cr (CmpD src1 src2)); 13559 13560 ins_cost(3 * INSN_COST); 13561 format %{ "fcmpd $src1, 0.0" %} 13562 13563 ins_encode %{ 13564 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 13565 %} 13566 13567 ins_pipe(pipe_class_compare); 13568 %} 13569 13570 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 13571 %{ 13572 match(Set dst (CmpF3 src1 src2)); 13573 effect(KILL cr); 13574 13575 ins_cost(5 * INSN_COST); 13576 format %{ "fcmps $src1, $src2\n\t" 13577 "csinvw($dst, zr, zr, eq\n\t" 13578 "csnegw($dst, $dst, $dst, lt)" 13579 %} 13580 13581 ins_encode %{ 13582 Label done; 13583 FloatRegister s1 = as_FloatRegister($src1$$reg); 13584 FloatRegister s2 = as_FloatRegister($src2$$reg); 13585 Register d = as_Register($dst$$reg); 13586 __ fcmps(s1, s2); 13587 // installs 0 if EQ else -1 13588 __ csinvw(d, zr, zr, Assembler::EQ); 13589 // keeps -1 if less or unordered else installs 1 13590 __ csnegw(d, d, d, Assembler::LT); 13591 __ bind(done); 13592 %} 13593 13594 ins_pipe(pipe_class_default); 13595 13596 %} 13597 13598 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 13599 %{ 13600 match(Set dst (CmpD3 src1 src2)); 13601 effect(KILL cr); 13602 13603 ins_cost(5 * INSN_COST); 13604 format %{ "fcmpd $src1, $src2\n\t" 13605 "csinvw($dst, zr, zr, eq\n\t" 13606 "csnegw($dst, $dst, $dst, lt)" 13607 %} 13608 13609 ins_encode %{ 13610 Label done; 13611 FloatRegister s1 = as_FloatRegister($src1$$reg); 13612 FloatRegister s2 = as_FloatRegister($src2$$reg); 13613 Register d = as_Register($dst$$reg); 13614 __ fcmpd(s1, s2); 13615 // installs 0 if EQ else -1 13616 __ csinvw(d, zr, zr, Assembler::EQ); 13617 // keeps -1 if less or unordered else installs 1 13618 __ csnegw(d, d, d, Assembler::LT); 13619 __ bind(done); 13620 %} 13621 ins_pipe(pipe_class_default); 13622 13623 %} 13624 13625 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 13626 %{ 13627 match(Set dst (CmpF3 src1 zero)); 13628 effect(KILL cr); 13629 13630 ins_cost(5 * INSN_COST); 13631 format %{ "fcmps $src1, 0.0\n\t" 13632 "csinvw($dst, zr, zr, eq\n\t" 13633 "csnegw($dst, $dst, $dst, lt)" 13634 %} 13635 13636 ins_encode %{ 13637 Label done; 13638 FloatRegister s1 = as_FloatRegister($src1$$reg); 13639 Register d = as_Register($dst$$reg); 13640 __ fcmps(s1, 0.0D); 13641 // installs 0 if EQ else -1 13642 __ csinvw(d, zr, zr, Assembler::EQ); 13643 // keeps -1 if less or unordered else installs 1 13644 __ csnegw(d, d, d, Assembler::LT); 13645 __ bind(done); 13646 %} 13647 13648 ins_pipe(pipe_class_default); 13649 13650 %} 13651 13652 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 13653 %{ 13654 match(Set dst (CmpD3 src1 zero)); 13655 effect(KILL cr); 13656 13657 ins_cost(5 * INSN_COST); 13658 format %{ "fcmpd $src1, 0.0\n\t" 13659 "csinvw($dst, zr, zr, eq\n\t" 13660 "csnegw($dst, $dst, $dst, lt)" 13661 %} 13662 13663 ins_encode %{ 13664 Label done; 13665 FloatRegister s1 = as_FloatRegister($src1$$reg); 13666 Register d = as_Register($dst$$reg); 13667 __ fcmpd(s1, 0.0D); 13668 // installs 0 if EQ else -1 13669 __ csinvw(d, zr, zr, Assembler::EQ); 13670 // keeps -1 if less or unordered else installs 1 13671 __ csnegw(d, d, d, Assembler::LT); 13672 __ bind(done); 13673 %} 13674 ins_pipe(pipe_class_default); 13675 13676 %} 13677 13678 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 13679 %{ 13680 match(Set dst (CmpLTMask p q)); 13681 effect(KILL cr); 13682 13683 ins_cost(3 * INSN_COST); 13684 13685 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 13686 "csetw $dst, lt\n\t" 13687 "subw $dst, zr, $dst" 13688 %} 13689 13690 ins_encode %{ 13691 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 13692 __ csetw(as_Register($dst$$reg), Assembler::LT); 13693 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 13694 %} 13695 13696 ins_pipe(ialu_reg_reg); 13697 %} 13698 13699 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 13700 %{ 13701 match(Set dst (CmpLTMask src zero)); 13702 effect(KILL cr); 13703 13704 ins_cost(INSN_COST); 13705 13706 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 13707 13708 ins_encode %{ 13709 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 13710 %} 13711 13712 ins_pipe(ialu_reg_shift); 13713 %} 13714 13715 // ============================================================================ 13716 // Max and Min 13717 13718 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13719 %{ 13720 match(Set dst (MinI src1 src2)); 13721 13722 effect(DEF dst, USE src1, USE src2, KILL cr); 13723 size(8); 13724 13725 ins_cost(INSN_COST * 3); 13726 format %{ 13727 "cmpw $src1 $src2\t signed int\n\t" 13728 "cselw $dst, $src1, $src2 lt\t" 13729 %} 13730 13731 ins_encode %{ 13732 __ cmpw(as_Register($src1$$reg), 13733 as_Register($src2$$reg)); 13734 __ cselw(as_Register($dst$$reg), 13735 as_Register($src1$$reg), 13736 as_Register($src2$$reg), 13737 Assembler::LT); 13738 %} 13739 13740 ins_pipe(ialu_reg_reg); 13741 %} 13742 // FROM HERE 13743 13744 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13745 %{ 13746 match(Set dst (MaxI src1 src2)); 13747 13748 effect(DEF dst, USE src1, USE src2, KILL cr); 13749 size(8); 13750 13751 ins_cost(INSN_COST * 3); 13752 format %{ 13753 "cmpw $src1 $src2\t signed int\n\t" 13754 "cselw $dst, $src1, $src2 gt\t" 13755 %} 13756 13757 ins_encode %{ 13758 __ cmpw(as_Register($src1$$reg), 13759 as_Register($src2$$reg)); 13760 __ cselw(as_Register($dst$$reg), 13761 as_Register($src1$$reg), 13762 as_Register($src2$$reg), 13763 Assembler::GT); 13764 %} 13765 13766 ins_pipe(ialu_reg_reg); 13767 %} 13768 13769 // ============================================================================ 13770 // Branch Instructions 13771 13772 // Direct Branch. 13773 instruct branch(label lbl) 13774 %{ 13775 match(Goto); 13776 13777 effect(USE lbl); 13778 13779 ins_cost(BRANCH_COST); 13780 format %{ "b $lbl" %} 13781 13782 ins_encode(aarch64_enc_b(lbl)); 13783 13784 ins_pipe(pipe_branch); 13785 %} 13786 13787 // Conditional Near Branch 13788 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 13789 %{ 13790 // Same match rule as `branchConFar'. 13791 match(If cmp cr); 13792 13793 effect(USE lbl); 13794 13795 ins_cost(BRANCH_COST); 13796 // If set to 1 this indicates that the current instruction is a 13797 // short variant of a long branch. This avoids using this 13798 // instruction in first-pass matching. It will then only be used in 13799 // the `Shorten_branches' pass. 13800 // ins_short_branch(1); 13801 format %{ "b$cmp $lbl" %} 13802 13803 ins_encode(aarch64_enc_br_con(cmp, lbl)); 13804 13805 ins_pipe(pipe_branch_cond); 13806 %} 13807 13808 // Conditional Near Branch Unsigned 13809 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 13810 %{ 13811 // Same match rule as `branchConFar'. 13812 match(If cmp cr); 13813 13814 effect(USE lbl); 13815 13816 ins_cost(BRANCH_COST); 13817 // If set to 1 this indicates that the current instruction is a 13818 // short variant of a long branch. This avoids using this 13819 // instruction in first-pass matching. It will then only be used in 13820 // the `Shorten_branches' pass. 13821 // ins_short_branch(1); 13822 format %{ "b$cmp $lbl\t# unsigned" %} 13823 13824 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 13825 13826 ins_pipe(pipe_branch_cond); 13827 %} 13828 13829 // Make use of CBZ and CBNZ. These instructions, as well as being 13830 // shorter than (cmp; branch), have the additional benefit of not 13831 // killing the flags. 13832 13833 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 13834 match(If cmp (CmpI op1 op2)); 13835 effect(USE labl); 13836 13837 ins_cost(BRANCH_COST); 13838 format %{ "cbw$cmp $op1, $labl" %} 13839 ins_encode %{ 13840 Label* L = $labl$$label; 13841 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13842 if (cond == Assembler::EQ) 13843 __ cbzw($op1$$Register, *L); 13844 else 13845 __ cbnzw($op1$$Register, *L); 13846 %} 13847 ins_pipe(pipe_cmp_branch); 13848 %} 13849 13850 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 13851 match(If cmp (CmpL op1 op2)); 13852 effect(USE labl); 13853 13854 ins_cost(BRANCH_COST); 13855 format %{ "cb$cmp $op1, $labl" %} 13856 ins_encode %{ 13857 Label* L = $labl$$label; 13858 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13859 if (cond == Assembler::EQ) 13860 __ cbz($op1$$Register, *L); 13861 else 13862 __ cbnz($op1$$Register, *L); 13863 %} 13864 ins_pipe(pipe_cmp_branch); 13865 %} 13866 13867 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 13868 match(If cmp (CmpP op1 op2)); 13869 effect(USE labl); 13870 13871 ins_cost(BRANCH_COST); 13872 format %{ "cb$cmp $op1, $labl" %} 13873 ins_encode %{ 13874 Label* L = $labl$$label; 13875 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13876 if (cond == Assembler::EQ) 13877 __ cbz($op1$$Register, *L); 13878 else 13879 __ cbnz($op1$$Register, *L); 13880 %} 13881 ins_pipe(pipe_cmp_branch); 13882 %} 13883 13884 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 13885 match(If cmp (CmpN op1 op2)); 13886 effect(USE labl); 13887 13888 ins_cost(BRANCH_COST); 13889 format %{ "cbw$cmp $op1, $labl" %} 13890 ins_encode %{ 13891 Label* L = $labl$$label; 13892 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13893 if (cond == Assembler::EQ) 13894 __ cbzw($op1$$Register, *L); 13895 else 13896 __ cbnzw($op1$$Register, *L); 13897 %} 13898 ins_pipe(pipe_cmp_branch); 13899 %} 13900 13901 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 13902 match(If cmp (CmpP (DecodeN oop) zero)); 13903 effect(USE labl); 13904 13905 ins_cost(BRANCH_COST); 13906 format %{ "cb$cmp $oop, $labl" %} 13907 ins_encode %{ 13908 Label* L = $labl$$label; 13909 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13910 if (cond == Assembler::EQ) 13911 __ cbzw($oop$$Register, *L); 13912 else 13913 __ cbnzw($oop$$Register, *L); 13914 %} 13915 ins_pipe(pipe_cmp_branch); 13916 %} 13917 13918 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 13919 match(If cmp (CmpU op1 op2)); 13920 effect(USE labl); 13921 13922 ins_cost(BRANCH_COST); 13923 format %{ "cbw$cmp $op1, $labl" %} 13924 ins_encode %{ 13925 Label* L = $labl$$label; 13926 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13927 if (cond == Assembler::EQ || cond == Assembler::LS) 13928 __ cbzw($op1$$Register, *L); 13929 else 13930 __ cbnzw($op1$$Register, *L); 13931 %} 13932 ins_pipe(pipe_cmp_branch); 13933 %} 13934 13935 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 13936 match(If cmp (CmpUL op1 op2)); 13937 effect(USE labl); 13938 13939 ins_cost(BRANCH_COST); 13940 format %{ "cb$cmp $op1, $labl" %} 13941 ins_encode %{ 13942 Label* L = $labl$$label; 13943 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13944 if (cond == Assembler::EQ || cond == Assembler::LS) 13945 __ cbz($op1$$Register, *L); 13946 else 13947 __ cbnz($op1$$Register, *L); 13948 %} 13949 ins_pipe(pipe_cmp_branch); 13950 %} 13951 13952 // Test bit and Branch 13953 13954 // Patterns for short (< 32KiB) variants 13955 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 13956 match(If cmp (CmpL op1 op2)); 13957 effect(USE labl); 13958 13959 ins_cost(BRANCH_COST); 13960 format %{ "cb$cmp $op1, $labl # long" %} 13961 ins_encode %{ 13962 Label* L = $labl$$label; 13963 Assembler::Condition cond = 13964 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 13965 __ tbr(cond, $op1$$Register, 63, *L); 13966 %} 13967 ins_pipe(pipe_cmp_branch); 13968 ins_short_branch(1); 13969 %} 13970 13971 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 13972 match(If cmp (CmpI op1 op2)); 13973 effect(USE labl); 13974 13975 ins_cost(BRANCH_COST); 13976 format %{ "cb$cmp $op1, $labl # int" %} 13977 ins_encode %{ 13978 Label* L = $labl$$label; 13979 Assembler::Condition cond = 13980 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 13981 __ tbr(cond, $op1$$Register, 31, *L); 13982 %} 13983 ins_pipe(pipe_cmp_branch); 13984 ins_short_branch(1); 13985 %} 13986 13987 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 13988 match(If cmp (CmpL (AndL op1 op2) op3)); 13989 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 13990 effect(USE labl); 13991 13992 ins_cost(BRANCH_COST); 13993 format %{ "tb$cmp $op1, $op2, $labl" %} 13994 ins_encode %{ 13995 Label* L = $labl$$label; 13996 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13997 int bit = exact_log2($op2$$constant); 13998 __ tbr(cond, $op1$$Register, bit, *L); 13999 %} 14000 ins_pipe(pipe_cmp_branch); 14001 ins_short_branch(1); 14002 %} 14003 14004 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14005 match(If cmp (CmpI (AndI op1 op2) op3)); 14006 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14007 effect(USE labl); 14008 14009 ins_cost(BRANCH_COST); 14010 format %{ "tb$cmp $op1, $op2, $labl" %} 14011 ins_encode %{ 14012 Label* L = $labl$$label; 14013 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14014 int bit = exact_log2($op2$$constant); 14015 __ tbr(cond, $op1$$Register, bit, *L); 14016 %} 14017 ins_pipe(pipe_cmp_branch); 14018 ins_short_branch(1); 14019 %} 14020 14021 // And far variants 14022 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14023 match(If cmp (CmpL op1 op2)); 14024 effect(USE labl); 14025 14026 ins_cost(BRANCH_COST); 14027 format %{ "cb$cmp $op1, $labl # long" %} 14028 ins_encode %{ 14029 Label* L = $labl$$label; 14030 Assembler::Condition cond = 14031 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14032 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14033 %} 14034 ins_pipe(pipe_cmp_branch); 14035 %} 14036 14037 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14038 match(If cmp (CmpI op1 op2)); 14039 effect(USE labl); 14040 14041 ins_cost(BRANCH_COST); 14042 format %{ "cb$cmp $op1, $labl # int" %} 14043 ins_encode %{ 14044 Label* L = $labl$$label; 14045 Assembler::Condition cond = 14046 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14047 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14048 %} 14049 ins_pipe(pipe_cmp_branch); 14050 %} 14051 14052 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14053 match(If cmp (CmpL (AndL op1 op2) op3)); 14054 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14055 effect(USE labl); 14056 14057 ins_cost(BRANCH_COST); 14058 format %{ "tb$cmp $op1, $op2, $labl" %} 14059 ins_encode %{ 14060 Label* L = $labl$$label; 14061 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14062 int bit = exact_log2($op2$$constant); 14063 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14064 %} 14065 ins_pipe(pipe_cmp_branch); 14066 %} 14067 14068 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14069 match(If cmp (CmpI (AndI op1 op2) op3)); 14070 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14071 effect(USE labl); 14072 14073 ins_cost(BRANCH_COST); 14074 format %{ "tb$cmp $op1, $op2, $labl" %} 14075 ins_encode %{ 14076 Label* L = $labl$$label; 14077 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14078 int bit = exact_log2($op2$$constant); 14079 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14080 %} 14081 ins_pipe(pipe_cmp_branch); 14082 %} 14083 14084 // Test bits 14085 14086 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14087 match(Set cr (CmpL (AndL op1 op2) op3)); 14088 predicate(Assembler::operand_valid_for_logical_immediate 14089 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14090 14091 ins_cost(INSN_COST); 14092 format %{ "tst $op1, $op2 # long" %} 14093 ins_encode %{ 14094 __ tst($op1$$Register, $op2$$constant); 14095 %} 14096 ins_pipe(ialu_reg_reg); 14097 %} 14098 14099 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14100 match(Set cr (CmpI (AndI op1 op2) op3)); 14101 predicate(Assembler::operand_valid_for_logical_immediate 14102 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14103 14104 ins_cost(INSN_COST); 14105 format %{ "tst $op1, $op2 # int" %} 14106 ins_encode %{ 14107 __ tstw($op1$$Register, $op2$$constant); 14108 %} 14109 ins_pipe(ialu_reg_reg); 14110 %} 14111 14112 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14113 match(Set cr (CmpL (AndL op1 op2) op3)); 14114 14115 ins_cost(INSN_COST); 14116 format %{ "tst $op1, $op2 # long" %} 14117 ins_encode %{ 14118 __ tst($op1$$Register, $op2$$Register); 14119 %} 14120 ins_pipe(ialu_reg_reg); 14121 %} 14122 14123 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14124 match(Set cr (CmpI (AndI op1 op2) op3)); 14125 14126 ins_cost(INSN_COST); 14127 format %{ "tstw $op1, $op2 # int" %} 14128 ins_encode %{ 14129 __ tstw($op1$$Register, $op2$$Register); 14130 %} 14131 ins_pipe(ialu_reg_reg); 14132 %} 14133 14134 14135 // Conditional Far Branch 14136 // Conditional Far Branch Unsigned 14137 // TODO: fixme 14138 14139 // counted loop end branch near 14140 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14141 %{ 14142 match(CountedLoopEnd cmp cr); 14143 14144 effect(USE lbl); 14145 14146 ins_cost(BRANCH_COST); 14147 // short variant. 14148 // ins_short_branch(1); 14149 format %{ "b$cmp $lbl \t// counted loop end" %} 14150 14151 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14152 14153 ins_pipe(pipe_branch); 14154 %} 14155 14156 // counted loop end branch near Unsigned 14157 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14158 %{ 14159 match(CountedLoopEnd cmp cr); 14160 14161 effect(USE lbl); 14162 14163 ins_cost(BRANCH_COST); 14164 // short variant. 14165 // ins_short_branch(1); 14166 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14167 14168 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14169 14170 ins_pipe(pipe_branch); 14171 %} 14172 14173 // counted loop end branch far 14174 // counted loop end branch far unsigned 14175 // TODO: fixme 14176 14177 // ============================================================================ 14178 // inlined locking and unlocking 14179 14180 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14181 %{ 14182 match(Set cr (FastLock object box)); 14183 effect(TEMP tmp, TEMP tmp2); 14184 14185 // TODO 14186 // identify correct cost 14187 ins_cost(5 * INSN_COST); 14188 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14189 14190 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14191 14192 ins_pipe(pipe_serial); 14193 %} 14194 14195 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14196 %{ 14197 match(Set cr (FastUnlock object box)); 14198 effect(TEMP tmp, TEMP tmp2); 14199 14200 ins_cost(5 * INSN_COST); 14201 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14202 14203 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14204 14205 ins_pipe(pipe_serial); 14206 %} 14207 14208 14209 // ============================================================================ 14210 // Safepoint Instructions 14211 14212 // TODO 14213 // provide a near and far version of this code 14214 14215 instruct safePoint(iRegP poll) 14216 %{ 14217 match(SafePoint poll); 14218 14219 format %{ 14220 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14221 %} 14222 ins_encode %{ 14223 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14224 %} 14225 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14226 %} 14227 14228 14229 // ============================================================================ 14230 // Procedure Call/Return Instructions 14231 14232 // Call Java Static Instruction 14233 14234 instruct CallStaticJavaDirect(method meth) 14235 %{ 14236 match(CallStaticJava); 14237 14238 effect(USE meth); 14239 14240 ins_cost(CALL_COST); 14241 14242 format %{ "call,static $meth \t// ==> " %} 14243 14244 ins_encode( aarch64_enc_java_static_call(meth), 14245 aarch64_enc_call_epilog ); 14246 14247 ins_pipe(pipe_class_call); 14248 %} 14249 14250 // TO HERE 14251 14252 // Call Java Dynamic Instruction 14253 instruct CallDynamicJavaDirect(method meth) 14254 %{ 14255 match(CallDynamicJava); 14256 14257 effect(USE meth); 14258 14259 ins_cost(CALL_COST); 14260 14261 format %{ "CALL,dynamic $meth \t// ==> " %} 14262 14263 ins_encode( aarch64_enc_java_dynamic_call(meth), 14264 aarch64_enc_call_epilog ); 14265 14266 ins_pipe(pipe_class_call); 14267 %} 14268 14269 // Call Runtime Instruction 14270 14271 instruct CallRuntimeDirect(method meth) 14272 %{ 14273 match(CallRuntime); 14274 14275 effect(USE meth); 14276 14277 ins_cost(CALL_COST); 14278 14279 format %{ "CALL, runtime $meth" %} 14280 14281 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14282 14283 ins_pipe(pipe_class_call); 14284 %} 14285 14286 // Call Runtime Instruction 14287 14288 instruct CallLeafDirect(method meth) 14289 %{ 14290 match(CallLeaf); 14291 14292 effect(USE meth); 14293 14294 ins_cost(CALL_COST); 14295 14296 format %{ "CALL, runtime leaf $meth" %} 14297 14298 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14299 14300 ins_pipe(pipe_class_call); 14301 %} 14302 14303 // Call Runtime Instruction 14304 14305 instruct CallLeafNoFPDirect(method meth) 14306 %{ 14307 match(CallLeafNoFP); 14308 14309 effect(USE meth); 14310 14311 ins_cost(CALL_COST); 14312 14313 format %{ "CALL, runtime leaf nofp $meth" %} 14314 14315 ins_encode( aarch64_enc_java_to_runtime(meth) ); 14316 14317 ins_pipe(pipe_class_call); 14318 %} 14319 14320 // Tail Call; Jump from runtime stub to Java code. 14321 // Also known as an 'interprocedural jump'. 14322 // Target of jump will eventually return to caller. 14323 // TailJump below removes the return address. 14324 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 14325 %{ 14326 match(TailCall jump_target method_oop); 14327 14328 ins_cost(CALL_COST); 14329 14330 format %{ "br $jump_target\t# $method_oop holds method oop" %} 14331 14332 ins_encode(aarch64_enc_tail_call(jump_target)); 14333 14334 ins_pipe(pipe_class_call); 14335 %} 14336 14337 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 14338 %{ 14339 match(TailJump jump_target ex_oop); 14340 14341 ins_cost(CALL_COST); 14342 14343 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 14344 14345 ins_encode(aarch64_enc_tail_jmp(jump_target)); 14346 14347 ins_pipe(pipe_class_call); 14348 %} 14349 14350 // Create exception oop: created by stack-crawling runtime code. 14351 // Created exception is now available to this handler, and is setup 14352 // just prior to jumping to this handler. No code emitted. 14353 // TODO check 14354 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 14355 instruct CreateException(iRegP_R0 ex_oop) 14356 %{ 14357 match(Set ex_oop (CreateEx)); 14358 14359 format %{ " -- \t// exception oop; no code emitted" %} 14360 14361 size(0); 14362 14363 ins_encode( /*empty*/ ); 14364 14365 ins_pipe(pipe_class_empty); 14366 %} 14367 14368 // Rethrow exception: The exception oop will come in the first 14369 // argument position. Then JUMP (not call) to the rethrow stub code. 14370 instruct RethrowException() %{ 14371 match(Rethrow); 14372 ins_cost(CALL_COST); 14373 14374 format %{ "b rethrow_stub" %} 14375 14376 ins_encode( aarch64_enc_rethrow() ); 14377 14378 ins_pipe(pipe_class_call); 14379 %} 14380 14381 14382 // Return Instruction 14383 // epilog node loads ret address into lr as part of frame pop 14384 instruct Ret() 14385 %{ 14386 match(Return); 14387 14388 format %{ "ret\t// return register" %} 14389 14390 ins_encode( aarch64_enc_ret() ); 14391 14392 ins_pipe(pipe_branch); 14393 %} 14394 14395 // Die now. 14396 instruct ShouldNotReachHere() %{ 14397 match(Halt); 14398 14399 ins_cost(CALL_COST); 14400 format %{ "ShouldNotReachHere" %} 14401 14402 ins_encode %{ 14403 // +1 so NativeInstruction::is_sigill_zombie_not_entrant() doesn't 14404 // return true 14405 __ dpcs1(0xdead + 1); 14406 %} 14407 14408 ins_pipe(pipe_class_default); 14409 %} 14410 14411 // ============================================================================ 14412 // Partial Subtype Check 14413 // 14414 // superklass array for an instance of the superklass. Set a hidden 14415 // internal cache on a hit (cache is checked with exposed code in 14416 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14417 // encoding ALSO sets flags. 14418 14419 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 14420 %{ 14421 match(Set result (PartialSubtypeCheck sub super)); 14422 effect(KILL cr, KILL temp); 14423 14424 ins_cost(1100); // slightly larger than the next version 14425 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14426 14427 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14428 14429 opcode(0x1); // Force zero of result reg on hit 14430 14431 ins_pipe(pipe_class_memory); 14432 %} 14433 14434 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 14435 %{ 14436 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 14437 effect(KILL temp, KILL result); 14438 14439 ins_cost(1100); // slightly larger than the next version 14440 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 14441 14442 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 14443 14444 opcode(0x0); // Don't zero result reg on hit 14445 14446 ins_pipe(pipe_class_memory); 14447 %} 14448 14449 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14450 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14451 %{ 14452 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 14453 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14454 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14455 14456 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14457 ins_encode %{ 14458 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14459 __ string_compare($str1$$Register, $str2$$Register, 14460 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14461 $tmp1$$Register, $tmp2$$Register, 14462 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 14463 %} 14464 ins_pipe(pipe_class_memory); 14465 %} 14466 14467 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14468 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 14469 %{ 14470 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 14471 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14472 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14473 14474 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 14475 ins_encode %{ 14476 __ string_compare($str1$$Register, $str2$$Register, 14477 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14478 $tmp1$$Register, $tmp2$$Register, 14479 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 14480 %} 14481 ins_pipe(pipe_class_memory); 14482 %} 14483 14484 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14485 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14486 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14487 %{ 14488 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 14489 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14490 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14491 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14492 14493 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14494 ins_encode %{ 14495 __ string_compare($str1$$Register, $str2$$Register, 14496 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14497 $tmp1$$Register, $tmp2$$Register, 14498 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14499 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 14500 %} 14501 ins_pipe(pipe_class_memory); 14502 %} 14503 14504 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 14505 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 14506 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 14507 %{ 14508 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 14509 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 14510 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 14511 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 14512 14513 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 14514 ins_encode %{ 14515 __ string_compare($str1$$Register, $str2$$Register, 14516 $cnt1$$Register, $cnt2$$Register, $result$$Register, 14517 $tmp1$$Register, $tmp2$$Register, 14518 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 14519 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 14520 %} 14521 ins_pipe(pipe_class_memory); 14522 %} 14523 14524 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14525 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14526 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14527 %{ 14528 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14529 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14530 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14531 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14532 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 14533 14534 ins_encode %{ 14535 __ string_indexof($str1$$Register, $str2$$Register, 14536 $cnt1$$Register, $cnt2$$Register, 14537 $tmp1$$Register, $tmp2$$Register, 14538 $tmp3$$Register, $tmp4$$Register, 14539 $tmp5$$Register, $tmp6$$Register, 14540 -1, $result$$Register, StrIntrinsicNode::UU); 14541 %} 14542 ins_pipe(pipe_class_memory); 14543 %} 14544 14545 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14546 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14547 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14548 %{ 14549 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14550 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14551 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14552 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14553 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 14554 14555 ins_encode %{ 14556 __ string_indexof($str1$$Register, $str2$$Register, 14557 $cnt1$$Register, $cnt2$$Register, 14558 $tmp1$$Register, $tmp2$$Register, 14559 $tmp3$$Register, $tmp4$$Register, 14560 $tmp5$$Register, $tmp6$$Register, 14561 -1, $result$$Register, StrIntrinsicNode::LL); 14562 %} 14563 ins_pipe(pipe_class_memory); 14564 %} 14565 14566 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 14567 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 14568 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 14569 %{ 14570 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14571 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 14572 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 14573 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 14574 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 14575 14576 ins_encode %{ 14577 __ string_indexof($str1$$Register, $str2$$Register, 14578 $cnt1$$Register, $cnt2$$Register, 14579 $tmp1$$Register, $tmp2$$Register, 14580 $tmp3$$Register, $tmp4$$Register, 14581 $tmp5$$Register, $tmp6$$Register, 14582 -1, $result$$Register, StrIntrinsicNode::UL); 14583 %} 14584 ins_pipe(pipe_class_memory); 14585 %} 14586 14587 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14588 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14589 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14590 %{ 14591 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 14592 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14593 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14594 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14595 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 14596 14597 ins_encode %{ 14598 int icnt2 = (int)$int_cnt2$$constant; 14599 __ string_indexof($str1$$Register, $str2$$Register, 14600 $cnt1$$Register, zr, 14601 $tmp1$$Register, $tmp2$$Register, 14602 $tmp3$$Register, $tmp4$$Register, zr, zr, 14603 icnt2, $result$$Register, StrIntrinsicNode::UU); 14604 %} 14605 ins_pipe(pipe_class_memory); 14606 %} 14607 14608 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14609 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14610 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14611 %{ 14612 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 14613 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14614 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14615 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14616 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 14617 14618 ins_encode %{ 14619 int icnt2 = (int)$int_cnt2$$constant; 14620 __ string_indexof($str1$$Register, $str2$$Register, 14621 $cnt1$$Register, zr, 14622 $tmp1$$Register, $tmp2$$Register, 14623 $tmp3$$Register, $tmp4$$Register, zr, zr, 14624 icnt2, $result$$Register, StrIntrinsicNode::LL); 14625 %} 14626 ins_pipe(pipe_class_memory); 14627 %} 14628 14629 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 14630 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14631 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 14632 %{ 14633 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 14634 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 14635 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 14636 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 14637 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 14638 14639 ins_encode %{ 14640 int icnt2 = (int)$int_cnt2$$constant; 14641 __ string_indexof($str1$$Register, $str2$$Register, 14642 $cnt1$$Register, zr, 14643 $tmp1$$Register, $tmp2$$Register, 14644 $tmp3$$Register, $tmp4$$Register, zr, zr, 14645 icnt2, $result$$Register, StrIntrinsicNode::UL); 14646 %} 14647 ins_pipe(pipe_class_memory); 14648 %} 14649 14650 instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 14651 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 14652 iRegINoSp tmp3, rFlagsReg cr) 14653 %{ 14654 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 14655 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 14656 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14657 14658 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 14659 14660 ins_encode %{ 14661 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 14662 $result$$Register, $tmp1$$Register, $tmp2$$Register, 14663 $tmp3$$Register); 14664 %} 14665 ins_pipe(pipe_class_memory); 14666 %} 14667 14668 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14669 iRegI_R0 result, rFlagsReg cr) 14670 %{ 14671 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 14672 match(Set result (StrEquals (Binary str1 str2) cnt)); 14673 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14674 14675 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14676 ins_encode %{ 14677 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14678 __ string_equals($str1$$Register, $str2$$Register, 14679 $result$$Register, $cnt$$Register, 1); 14680 %} 14681 ins_pipe(pipe_class_memory); 14682 %} 14683 14684 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 14685 iRegI_R0 result, rFlagsReg cr) 14686 %{ 14687 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 14688 match(Set result (StrEquals (Binary str1 str2) cnt)); 14689 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 14690 14691 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 14692 ins_encode %{ 14693 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 14694 __ string_equals($str1$$Register, $str2$$Register, 14695 $result$$Register, $cnt$$Register, 2); 14696 %} 14697 ins_pipe(pipe_class_memory); 14698 %} 14699 14700 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14701 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14702 iRegP_R10 tmp, rFlagsReg cr) 14703 %{ 14704 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 14705 match(Set result (AryEq ary1 ary2)); 14706 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14707 14708 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14709 ins_encode %{ 14710 __ arrays_equals($ary1$$Register, $ary2$$Register, 14711 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14712 $result$$Register, $tmp$$Register, 1); 14713 %} 14714 ins_pipe(pipe_class_memory); 14715 %} 14716 14717 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 14718 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 14719 iRegP_R10 tmp, rFlagsReg cr) 14720 %{ 14721 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 14722 match(Set result (AryEq ary1 ary2)); 14723 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 14724 14725 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 14726 ins_encode %{ 14727 __ arrays_equals($ary1$$Register, $ary2$$Register, 14728 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 14729 $result$$Register, $tmp$$Register, 2); 14730 %} 14731 ins_pipe(pipe_class_memory); 14732 %} 14733 14734 instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 14735 %{ 14736 match(Set result (HasNegatives ary1 len)); 14737 effect(USE_KILL ary1, USE_KILL len, KILL cr); 14738 format %{ "has negatives byte[] $ary1,$len -> $result" %} 14739 ins_encode %{ 14740 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 14741 %} 14742 ins_pipe( pipe_slow ); 14743 %} 14744 14745 // fast char[] to byte[] compression 14746 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14747 vRegD_V0 tmp1, vRegD_V1 tmp2, 14748 vRegD_V2 tmp3, vRegD_V3 tmp4, 14749 iRegI_R0 result, rFlagsReg cr) 14750 %{ 14751 match(Set result (StrCompressedCopy src (Binary dst len))); 14752 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14753 14754 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 14755 ins_encode %{ 14756 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 14757 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 14758 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 14759 $result$$Register); 14760 %} 14761 ins_pipe( pipe_slow ); 14762 %} 14763 14764 // fast byte[] to char[] inflation 14765 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 14766 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 14767 %{ 14768 match(Set dummy (StrInflatedCopy src (Binary dst len))); 14769 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 14770 14771 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 14772 ins_encode %{ 14773 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 14774 $tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register); 14775 %} 14776 ins_pipe(pipe_class_memory); 14777 %} 14778 14779 // encode char[] to byte[] in ISO_8859_1 14780 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 14781 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 14782 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 14783 iRegI_R0 result, rFlagsReg cr) 14784 %{ 14785 match(Set result (EncodeISOArray src (Binary dst len))); 14786 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 14787 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 14788 14789 format %{ "Encode array $src,$dst,$len -> $result" %} 14790 ins_encode %{ 14791 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 14792 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 14793 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 14794 %} 14795 ins_pipe( pipe_class_memory ); 14796 %} 14797 14798 // ============================================================================ 14799 // This name is KNOWN by the ADLC and cannot be changed. 14800 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14801 // for this guy. 14802 instruct tlsLoadP(thread_RegP dst) 14803 %{ 14804 match(Set dst (ThreadLocal)); 14805 14806 ins_cost(0); 14807 14808 format %{ " -- \t// $dst=Thread::current(), empty" %} 14809 14810 size(0); 14811 14812 ins_encode( /*empty*/ ); 14813 14814 ins_pipe(pipe_class_empty); 14815 %} 14816 14817 // ====================VECTOR INSTRUCTIONS===================================== 14818 14819 // Load vector (32 bits) 14820 instruct loadV4(vecD dst, vmem4 mem) 14821 %{ 14822 predicate(n->as_LoadVector()->memory_size() == 4); 14823 match(Set dst (LoadVector mem)); 14824 ins_cost(4 * INSN_COST); 14825 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 14826 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 14827 ins_pipe(vload_reg_mem64); 14828 %} 14829 14830 // Load vector (64 bits) 14831 instruct loadV8(vecD dst, vmem8 mem) 14832 %{ 14833 predicate(n->as_LoadVector()->memory_size() == 8); 14834 match(Set dst (LoadVector mem)); 14835 ins_cost(4 * INSN_COST); 14836 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 14837 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 14838 ins_pipe(vload_reg_mem64); 14839 %} 14840 14841 // Load Vector (128 bits) 14842 instruct loadV16(vecX dst, vmem16 mem) 14843 %{ 14844 predicate(n->as_LoadVector()->memory_size() == 16); 14845 match(Set dst (LoadVector mem)); 14846 ins_cost(4 * INSN_COST); 14847 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 14848 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 14849 ins_pipe(vload_reg_mem128); 14850 %} 14851 14852 // Store Vector (32 bits) 14853 instruct storeV4(vecD src, vmem4 mem) 14854 %{ 14855 predicate(n->as_StoreVector()->memory_size() == 4); 14856 match(Set mem (StoreVector mem src)); 14857 ins_cost(4 * INSN_COST); 14858 format %{ "strs $mem,$src\t# vector (32 bits)" %} 14859 ins_encode( aarch64_enc_strvS(src, mem) ); 14860 ins_pipe(vstore_reg_mem64); 14861 %} 14862 14863 // Store Vector (64 bits) 14864 instruct storeV8(vecD src, vmem8 mem) 14865 %{ 14866 predicate(n->as_StoreVector()->memory_size() == 8); 14867 match(Set mem (StoreVector mem src)); 14868 ins_cost(4 * INSN_COST); 14869 format %{ "strd $mem,$src\t# vector (64 bits)" %} 14870 ins_encode( aarch64_enc_strvD(src, mem) ); 14871 ins_pipe(vstore_reg_mem64); 14872 %} 14873 14874 // Store Vector (128 bits) 14875 instruct storeV16(vecX src, vmem16 mem) 14876 %{ 14877 predicate(n->as_StoreVector()->memory_size() == 16); 14878 match(Set mem (StoreVector mem src)); 14879 ins_cost(4 * INSN_COST); 14880 format %{ "strq $mem,$src\t# vector (128 bits)" %} 14881 ins_encode( aarch64_enc_strvQ(src, mem) ); 14882 ins_pipe(vstore_reg_mem128); 14883 %} 14884 14885 instruct replicate8B(vecD dst, iRegIorL2I src) 14886 %{ 14887 predicate(n->as_Vector()->length() == 4 || 14888 n->as_Vector()->length() == 8); 14889 match(Set dst (ReplicateB src)); 14890 ins_cost(INSN_COST); 14891 format %{ "dup $dst, $src\t# vector (8B)" %} 14892 ins_encode %{ 14893 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 14894 %} 14895 ins_pipe(vdup_reg_reg64); 14896 %} 14897 14898 instruct replicate16B(vecX dst, iRegIorL2I src) 14899 %{ 14900 predicate(n->as_Vector()->length() == 16); 14901 match(Set dst (ReplicateB src)); 14902 ins_cost(INSN_COST); 14903 format %{ "dup $dst, $src\t# vector (16B)" %} 14904 ins_encode %{ 14905 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 14906 %} 14907 ins_pipe(vdup_reg_reg128); 14908 %} 14909 14910 instruct replicate8B_imm(vecD dst, immI con) 14911 %{ 14912 predicate(n->as_Vector()->length() == 4 || 14913 n->as_Vector()->length() == 8); 14914 match(Set dst (ReplicateB con)); 14915 ins_cost(INSN_COST); 14916 format %{ "movi $dst, $con\t# vector(8B)" %} 14917 ins_encode %{ 14918 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 14919 %} 14920 ins_pipe(vmovi_reg_imm64); 14921 %} 14922 14923 instruct replicate16B_imm(vecX dst, immI con) 14924 %{ 14925 predicate(n->as_Vector()->length() == 16); 14926 match(Set dst (ReplicateB con)); 14927 ins_cost(INSN_COST); 14928 format %{ "movi $dst, $con\t# vector(16B)" %} 14929 ins_encode %{ 14930 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 14931 %} 14932 ins_pipe(vmovi_reg_imm128); 14933 %} 14934 14935 instruct replicate4S(vecD dst, iRegIorL2I src) 14936 %{ 14937 predicate(n->as_Vector()->length() == 2 || 14938 n->as_Vector()->length() == 4); 14939 match(Set dst (ReplicateS src)); 14940 ins_cost(INSN_COST); 14941 format %{ "dup $dst, $src\t# vector (4S)" %} 14942 ins_encode %{ 14943 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 14944 %} 14945 ins_pipe(vdup_reg_reg64); 14946 %} 14947 14948 instruct replicate8S(vecX dst, iRegIorL2I src) 14949 %{ 14950 predicate(n->as_Vector()->length() == 8); 14951 match(Set dst (ReplicateS src)); 14952 ins_cost(INSN_COST); 14953 format %{ "dup $dst, $src\t# vector (8S)" %} 14954 ins_encode %{ 14955 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 14956 %} 14957 ins_pipe(vdup_reg_reg128); 14958 %} 14959 14960 instruct replicate4S_imm(vecD dst, immI con) 14961 %{ 14962 predicate(n->as_Vector()->length() == 2 || 14963 n->as_Vector()->length() == 4); 14964 match(Set dst (ReplicateS con)); 14965 ins_cost(INSN_COST); 14966 format %{ "movi $dst, $con\t# vector(4H)" %} 14967 ins_encode %{ 14968 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 14969 %} 14970 ins_pipe(vmovi_reg_imm64); 14971 %} 14972 14973 instruct replicate8S_imm(vecX dst, immI con) 14974 %{ 14975 predicate(n->as_Vector()->length() == 8); 14976 match(Set dst (ReplicateS con)); 14977 ins_cost(INSN_COST); 14978 format %{ "movi $dst, $con\t# vector(8H)" %} 14979 ins_encode %{ 14980 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 14981 %} 14982 ins_pipe(vmovi_reg_imm128); 14983 %} 14984 14985 instruct replicate2I(vecD dst, iRegIorL2I src) 14986 %{ 14987 predicate(n->as_Vector()->length() == 2); 14988 match(Set dst (ReplicateI src)); 14989 ins_cost(INSN_COST); 14990 format %{ "dup $dst, $src\t# vector (2I)" %} 14991 ins_encode %{ 14992 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 14993 %} 14994 ins_pipe(vdup_reg_reg64); 14995 %} 14996 14997 instruct replicate4I(vecX dst, iRegIorL2I src) 14998 %{ 14999 predicate(n->as_Vector()->length() == 4); 15000 match(Set dst (ReplicateI src)); 15001 ins_cost(INSN_COST); 15002 format %{ "dup $dst, $src\t# vector (4I)" %} 15003 ins_encode %{ 15004 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15005 %} 15006 ins_pipe(vdup_reg_reg128); 15007 %} 15008 15009 instruct replicate2I_imm(vecD dst, immI con) 15010 %{ 15011 predicate(n->as_Vector()->length() == 2); 15012 match(Set dst (ReplicateI con)); 15013 ins_cost(INSN_COST); 15014 format %{ "movi $dst, $con\t# vector(2I)" %} 15015 ins_encode %{ 15016 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15017 %} 15018 ins_pipe(vmovi_reg_imm64); 15019 %} 15020 15021 instruct replicate4I_imm(vecX dst, immI con) 15022 %{ 15023 predicate(n->as_Vector()->length() == 4); 15024 match(Set dst (ReplicateI con)); 15025 ins_cost(INSN_COST); 15026 format %{ "movi $dst, $con\t# vector(4I)" %} 15027 ins_encode %{ 15028 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15029 %} 15030 ins_pipe(vmovi_reg_imm128); 15031 %} 15032 15033 instruct replicate2L(vecX dst, iRegL src) 15034 %{ 15035 predicate(n->as_Vector()->length() == 2); 15036 match(Set dst (ReplicateL src)); 15037 ins_cost(INSN_COST); 15038 format %{ "dup $dst, $src\t# vector (2L)" %} 15039 ins_encode %{ 15040 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15041 %} 15042 ins_pipe(vdup_reg_reg128); 15043 %} 15044 15045 instruct replicate2L_zero(vecX dst, immI0 zero) 15046 %{ 15047 predicate(n->as_Vector()->length() == 2); 15048 match(Set dst (ReplicateI zero)); 15049 ins_cost(INSN_COST); 15050 format %{ "movi $dst, $zero\t# vector(4I)" %} 15051 ins_encode %{ 15052 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15053 as_FloatRegister($dst$$reg), 15054 as_FloatRegister($dst$$reg)); 15055 %} 15056 ins_pipe(vmovi_reg_imm128); 15057 %} 15058 15059 instruct replicate2F(vecD dst, vRegF src) 15060 %{ 15061 predicate(n->as_Vector()->length() == 2); 15062 match(Set dst (ReplicateF src)); 15063 ins_cost(INSN_COST); 15064 format %{ "dup $dst, $src\t# vector (2F)" %} 15065 ins_encode %{ 15066 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15067 as_FloatRegister($src$$reg)); 15068 %} 15069 ins_pipe(vdup_reg_freg64); 15070 %} 15071 15072 instruct replicate4F(vecX dst, vRegF src) 15073 %{ 15074 predicate(n->as_Vector()->length() == 4); 15075 match(Set dst (ReplicateF src)); 15076 ins_cost(INSN_COST); 15077 format %{ "dup $dst, $src\t# vector (4F)" %} 15078 ins_encode %{ 15079 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15080 as_FloatRegister($src$$reg)); 15081 %} 15082 ins_pipe(vdup_reg_freg128); 15083 %} 15084 15085 instruct replicate2D(vecX dst, vRegD src) 15086 %{ 15087 predicate(n->as_Vector()->length() == 2); 15088 match(Set dst (ReplicateD src)); 15089 ins_cost(INSN_COST); 15090 format %{ "dup $dst, $src\t# vector (2D)" %} 15091 ins_encode %{ 15092 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15093 as_FloatRegister($src$$reg)); 15094 %} 15095 ins_pipe(vdup_reg_dreg128); 15096 %} 15097 15098 // ====================REDUCTION ARITHMETIC==================================== 15099 15100 instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15101 %{ 15102 match(Set dst (AddReductionVI src1 src2)); 15103 ins_cost(INSN_COST); 15104 effect(TEMP tmp, TEMP tmp2); 15105 format %{ "umov $tmp, $src2, S, 0\n\t" 15106 "umov $tmp2, $src2, S, 1\n\t" 15107 "addw $dst, $src1, $tmp\n\t" 15108 "addw $dst, $dst, $tmp2\t add reduction2i" 15109 %} 15110 ins_encode %{ 15111 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15112 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15113 __ addw($dst$$Register, $src1$$Register, $tmp$$Register); 15114 __ addw($dst$$Register, $dst$$Register, $tmp2$$Register); 15115 %} 15116 ins_pipe(pipe_class_default); 15117 %} 15118 15119 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15120 %{ 15121 match(Set dst (AddReductionVI src1 src2)); 15122 ins_cost(INSN_COST); 15123 effect(TEMP tmp, TEMP tmp2); 15124 format %{ "addv $tmp, T4S, $src2\n\t" 15125 "umov $tmp2, $tmp, S, 0\n\t" 15126 "addw $dst, $tmp2, $src1\t add reduction4i" 15127 %} 15128 ins_encode %{ 15129 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15130 as_FloatRegister($src2$$reg)); 15131 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15132 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15133 %} 15134 ins_pipe(pipe_class_default); 15135 %} 15136 15137 instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15138 %{ 15139 match(Set dst (MulReductionVI src1 src2)); 15140 ins_cost(INSN_COST); 15141 effect(TEMP tmp, TEMP dst); 15142 format %{ "umov $tmp, $src2, S, 0\n\t" 15143 "mul $dst, $tmp, $src1\n\t" 15144 "umov $tmp, $src2, S, 1\n\t" 15145 "mul $dst, $tmp, $dst\t mul reduction2i\n\t" 15146 %} 15147 ins_encode %{ 15148 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15149 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15150 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15151 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15152 %} 15153 ins_pipe(pipe_class_default); 15154 %} 15155 15156 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15157 %{ 15158 match(Set dst (MulReductionVI src1 src2)); 15159 ins_cost(INSN_COST); 15160 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15161 format %{ "ins $tmp, $src2, 0, 1\n\t" 15162 "mul $tmp, $tmp, $src2\n\t" 15163 "umov $tmp2, $tmp, S, 0\n\t" 15164 "mul $dst, $tmp2, $src1\n\t" 15165 "umov $tmp2, $tmp, S, 1\n\t" 15166 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 15167 %} 15168 ins_encode %{ 15169 __ ins(as_FloatRegister($tmp$$reg), __ D, 15170 as_FloatRegister($src2$$reg), 0, 1); 15171 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15172 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15173 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15174 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15175 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15176 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15177 %} 15178 ins_pipe(pipe_class_default); 15179 %} 15180 15181 instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15182 %{ 15183 match(Set dst (AddReductionVF src1 src2)); 15184 ins_cost(INSN_COST); 15185 effect(TEMP tmp, TEMP dst); 15186 format %{ "fadds $dst, $src1, $src2\n\t" 15187 "ins $tmp, S, $src2, 0, 1\n\t" 15188 "fadds $dst, $dst, $tmp\t add reduction2f" 15189 %} 15190 ins_encode %{ 15191 __ fadds(as_FloatRegister($dst$$reg), 15192 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15193 __ ins(as_FloatRegister($tmp$$reg), __ S, 15194 as_FloatRegister($src2$$reg), 0, 1); 15195 __ fadds(as_FloatRegister($dst$$reg), 15196 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15197 %} 15198 ins_pipe(pipe_class_default); 15199 %} 15200 15201 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15202 %{ 15203 match(Set dst (AddReductionVF src1 src2)); 15204 ins_cost(INSN_COST); 15205 effect(TEMP tmp, TEMP dst); 15206 format %{ "fadds $dst, $src1, $src2\n\t" 15207 "ins $tmp, S, $src2, 0, 1\n\t" 15208 "fadds $dst, $dst, $tmp\n\t" 15209 "ins $tmp, S, $src2, 0, 2\n\t" 15210 "fadds $dst, $dst, $tmp\n\t" 15211 "ins $tmp, S, $src2, 0, 3\n\t" 15212 "fadds $dst, $dst, $tmp\t add reduction4f" 15213 %} 15214 ins_encode %{ 15215 __ fadds(as_FloatRegister($dst$$reg), 15216 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15217 __ ins(as_FloatRegister($tmp$$reg), __ S, 15218 as_FloatRegister($src2$$reg), 0, 1); 15219 __ fadds(as_FloatRegister($dst$$reg), 15220 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15221 __ ins(as_FloatRegister($tmp$$reg), __ S, 15222 as_FloatRegister($src2$$reg), 0, 2); 15223 __ fadds(as_FloatRegister($dst$$reg), 15224 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15225 __ ins(as_FloatRegister($tmp$$reg), __ S, 15226 as_FloatRegister($src2$$reg), 0, 3); 15227 __ fadds(as_FloatRegister($dst$$reg), 15228 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15229 %} 15230 ins_pipe(pipe_class_default); 15231 %} 15232 15233 instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15234 %{ 15235 match(Set dst (MulReductionVF src1 src2)); 15236 ins_cost(INSN_COST); 15237 effect(TEMP tmp, TEMP dst); 15238 format %{ "fmuls $dst, $src1, $src2\n\t" 15239 "ins $tmp, S, $src2, 0, 1\n\t" 15240 "fmuls $dst, $dst, $tmp\t add reduction4f" 15241 %} 15242 ins_encode %{ 15243 __ fmuls(as_FloatRegister($dst$$reg), 15244 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15245 __ ins(as_FloatRegister($tmp$$reg), __ S, 15246 as_FloatRegister($src2$$reg), 0, 1); 15247 __ fmuls(as_FloatRegister($dst$$reg), 15248 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15249 %} 15250 ins_pipe(pipe_class_default); 15251 %} 15252 15253 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15254 %{ 15255 match(Set dst (MulReductionVF src1 src2)); 15256 ins_cost(INSN_COST); 15257 effect(TEMP tmp, TEMP dst); 15258 format %{ "fmuls $dst, $src1, $src2\n\t" 15259 "ins $tmp, S, $src2, 0, 1\n\t" 15260 "fmuls $dst, $dst, $tmp\n\t" 15261 "ins $tmp, S, $src2, 0, 2\n\t" 15262 "fmuls $dst, $dst, $tmp\n\t" 15263 "ins $tmp, S, $src2, 0, 3\n\t" 15264 "fmuls $dst, $dst, $tmp\t add reduction4f" 15265 %} 15266 ins_encode %{ 15267 __ fmuls(as_FloatRegister($dst$$reg), 15268 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15269 __ ins(as_FloatRegister($tmp$$reg), __ S, 15270 as_FloatRegister($src2$$reg), 0, 1); 15271 __ fmuls(as_FloatRegister($dst$$reg), 15272 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15273 __ ins(as_FloatRegister($tmp$$reg), __ S, 15274 as_FloatRegister($src2$$reg), 0, 2); 15275 __ fmuls(as_FloatRegister($dst$$reg), 15276 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15277 __ ins(as_FloatRegister($tmp$$reg), __ S, 15278 as_FloatRegister($src2$$reg), 0, 3); 15279 __ fmuls(as_FloatRegister($dst$$reg), 15280 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15281 %} 15282 ins_pipe(pipe_class_default); 15283 %} 15284 15285 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15286 %{ 15287 match(Set dst (AddReductionVD src1 src2)); 15288 ins_cost(INSN_COST); 15289 effect(TEMP tmp, TEMP dst); 15290 format %{ "faddd $dst, $src1, $src2\n\t" 15291 "ins $tmp, D, $src2, 0, 1\n\t" 15292 "faddd $dst, $dst, $tmp\t add reduction2d" 15293 %} 15294 ins_encode %{ 15295 __ faddd(as_FloatRegister($dst$$reg), 15296 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15297 __ ins(as_FloatRegister($tmp$$reg), __ D, 15298 as_FloatRegister($src2$$reg), 0, 1); 15299 __ faddd(as_FloatRegister($dst$$reg), 15300 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15301 %} 15302 ins_pipe(pipe_class_default); 15303 %} 15304 15305 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 15306 %{ 15307 match(Set dst (MulReductionVD src1 src2)); 15308 ins_cost(INSN_COST); 15309 effect(TEMP tmp, TEMP dst); 15310 format %{ "fmuld $dst, $src1, $src2\n\t" 15311 "ins $tmp, D, $src2, 0, 1\n\t" 15312 "fmuld $dst, $dst, $tmp\t add reduction2d" 15313 %} 15314 ins_encode %{ 15315 __ fmuld(as_FloatRegister($dst$$reg), 15316 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15317 __ ins(as_FloatRegister($tmp$$reg), __ D, 15318 as_FloatRegister($src2$$reg), 0, 1); 15319 __ fmuld(as_FloatRegister($dst$$reg), 15320 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15321 %} 15322 ins_pipe(pipe_class_default); 15323 %} 15324 15325 // ====================VECTOR ARITHMETIC======================================= 15326 15327 // --------------------------------- ADD -------------------------------------- 15328 15329 instruct vadd8B(vecD dst, vecD src1, vecD src2) 15330 %{ 15331 predicate(n->as_Vector()->length() == 4 || 15332 n->as_Vector()->length() == 8); 15333 match(Set dst (AddVB src1 src2)); 15334 ins_cost(INSN_COST); 15335 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 15336 ins_encode %{ 15337 __ addv(as_FloatRegister($dst$$reg), __ T8B, 15338 as_FloatRegister($src1$$reg), 15339 as_FloatRegister($src2$$reg)); 15340 %} 15341 ins_pipe(vdop64); 15342 %} 15343 15344 instruct vadd16B(vecX dst, vecX src1, vecX src2) 15345 %{ 15346 predicate(n->as_Vector()->length() == 16); 15347 match(Set dst (AddVB src1 src2)); 15348 ins_cost(INSN_COST); 15349 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 15350 ins_encode %{ 15351 __ addv(as_FloatRegister($dst$$reg), __ T16B, 15352 as_FloatRegister($src1$$reg), 15353 as_FloatRegister($src2$$reg)); 15354 %} 15355 ins_pipe(vdop128); 15356 %} 15357 15358 instruct vadd4S(vecD dst, vecD src1, vecD src2) 15359 %{ 15360 predicate(n->as_Vector()->length() == 2 || 15361 n->as_Vector()->length() == 4); 15362 match(Set dst (AddVS src1 src2)); 15363 ins_cost(INSN_COST); 15364 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 15365 ins_encode %{ 15366 __ addv(as_FloatRegister($dst$$reg), __ T4H, 15367 as_FloatRegister($src1$$reg), 15368 as_FloatRegister($src2$$reg)); 15369 %} 15370 ins_pipe(vdop64); 15371 %} 15372 15373 instruct vadd8S(vecX dst, vecX src1, vecX src2) 15374 %{ 15375 predicate(n->as_Vector()->length() == 8); 15376 match(Set dst (AddVS src1 src2)); 15377 ins_cost(INSN_COST); 15378 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 15379 ins_encode %{ 15380 __ addv(as_FloatRegister($dst$$reg), __ T8H, 15381 as_FloatRegister($src1$$reg), 15382 as_FloatRegister($src2$$reg)); 15383 %} 15384 ins_pipe(vdop128); 15385 %} 15386 15387 instruct vadd2I(vecD dst, vecD src1, vecD src2) 15388 %{ 15389 predicate(n->as_Vector()->length() == 2); 15390 match(Set dst (AddVI src1 src2)); 15391 ins_cost(INSN_COST); 15392 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 15393 ins_encode %{ 15394 __ addv(as_FloatRegister($dst$$reg), __ T2S, 15395 as_FloatRegister($src1$$reg), 15396 as_FloatRegister($src2$$reg)); 15397 %} 15398 ins_pipe(vdop64); 15399 %} 15400 15401 instruct vadd4I(vecX dst, vecX src1, vecX src2) 15402 %{ 15403 predicate(n->as_Vector()->length() == 4); 15404 match(Set dst (AddVI src1 src2)); 15405 ins_cost(INSN_COST); 15406 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 15407 ins_encode %{ 15408 __ addv(as_FloatRegister($dst$$reg), __ T4S, 15409 as_FloatRegister($src1$$reg), 15410 as_FloatRegister($src2$$reg)); 15411 %} 15412 ins_pipe(vdop128); 15413 %} 15414 15415 instruct vadd2L(vecX dst, vecX src1, vecX src2) 15416 %{ 15417 predicate(n->as_Vector()->length() == 2); 15418 match(Set dst (AddVL src1 src2)); 15419 ins_cost(INSN_COST); 15420 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 15421 ins_encode %{ 15422 __ addv(as_FloatRegister($dst$$reg), __ T2D, 15423 as_FloatRegister($src1$$reg), 15424 as_FloatRegister($src2$$reg)); 15425 %} 15426 ins_pipe(vdop128); 15427 %} 15428 15429 instruct vadd2F(vecD dst, vecD src1, vecD src2) 15430 %{ 15431 predicate(n->as_Vector()->length() == 2); 15432 match(Set dst (AddVF src1 src2)); 15433 ins_cost(INSN_COST); 15434 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 15435 ins_encode %{ 15436 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 15437 as_FloatRegister($src1$$reg), 15438 as_FloatRegister($src2$$reg)); 15439 %} 15440 ins_pipe(vdop_fp64); 15441 %} 15442 15443 instruct vadd4F(vecX dst, vecX src1, vecX src2) 15444 %{ 15445 predicate(n->as_Vector()->length() == 4); 15446 match(Set dst (AddVF src1 src2)); 15447 ins_cost(INSN_COST); 15448 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 15449 ins_encode %{ 15450 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 15451 as_FloatRegister($src1$$reg), 15452 as_FloatRegister($src2$$reg)); 15453 %} 15454 ins_pipe(vdop_fp128); 15455 %} 15456 15457 instruct vadd2D(vecX dst, vecX src1, vecX src2) 15458 %{ 15459 match(Set dst (AddVD src1 src2)); 15460 ins_cost(INSN_COST); 15461 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 15462 ins_encode %{ 15463 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 15464 as_FloatRegister($src1$$reg), 15465 as_FloatRegister($src2$$reg)); 15466 %} 15467 ins_pipe(vdop_fp128); 15468 %} 15469 15470 // --------------------------------- SUB -------------------------------------- 15471 15472 instruct vsub8B(vecD dst, vecD src1, vecD src2) 15473 %{ 15474 predicate(n->as_Vector()->length() == 4 || 15475 n->as_Vector()->length() == 8); 15476 match(Set dst (SubVB src1 src2)); 15477 ins_cost(INSN_COST); 15478 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 15479 ins_encode %{ 15480 __ subv(as_FloatRegister($dst$$reg), __ T8B, 15481 as_FloatRegister($src1$$reg), 15482 as_FloatRegister($src2$$reg)); 15483 %} 15484 ins_pipe(vdop64); 15485 %} 15486 15487 instruct vsub16B(vecX dst, vecX src1, vecX src2) 15488 %{ 15489 predicate(n->as_Vector()->length() == 16); 15490 match(Set dst (SubVB src1 src2)); 15491 ins_cost(INSN_COST); 15492 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 15493 ins_encode %{ 15494 __ subv(as_FloatRegister($dst$$reg), __ T16B, 15495 as_FloatRegister($src1$$reg), 15496 as_FloatRegister($src2$$reg)); 15497 %} 15498 ins_pipe(vdop128); 15499 %} 15500 15501 instruct vsub4S(vecD dst, vecD src1, vecD src2) 15502 %{ 15503 predicate(n->as_Vector()->length() == 2 || 15504 n->as_Vector()->length() == 4); 15505 match(Set dst (SubVS src1 src2)); 15506 ins_cost(INSN_COST); 15507 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 15508 ins_encode %{ 15509 __ subv(as_FloatRegister($dst$$reg), __ T4H, 15510 as_FloatRegister($src1$$reg), 15511 as_FloatRegister($src2$$reg)); 15512 %} 15513 ins_pipe(vdop64); 15514 %} 15515 15516 instruct vsub8S(vecX dst, vecX src1, vecX src2) 15517 %{ 15518 predicate(n->as_Vector()->length() == 8); 15519 match(Set dst (SubVS src1 src2)); 15520 ins_cost(INSN_COST); 15521 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 15522 ins_encode %{ 15523 __ subv(as_FloatRegister($dst$$reg), __ T8H, 15524 as_FloatRegister($src1$$reg), 15525 as_FloatRegister($src2$$reg)); 15526 %} 15527 ins_pipe(vdop128); 15528 %} 15529 15530 instruct vsub2I(vecD dst, vecD src1, vecD src2) 15531 %{ 15532 predicate(n->as_Vector()->length() == 2); 15533 match(Set dst (SubVI src1 src2)); 15534 ins_cost(INSN_COST); 15535 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 15536 ins_encode %{ 15537 __ subv(as_FloatRegister($dst$$reg), __ T2S, 15538 as_FloatRegister($src1$$reg), 15539 as_FloatRegister($src2$$reg)); 15540 %} 15541 ins_pipe(vdop64); 15542 %} 15543 15544 instruct vsub4I(vecX dst, vecX src1, vecX src2) 15545 %{ 15546 predicate(n->as_Vector()->length() == 4); 15547 match(Set dst (SubVI src1 src2)); 15548 ins_cost(INSN_COST); 15549 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 15550 ins_encode %{ 15551 __ subv(as_FloatRegister($dst$$reg), __ T4S, 15552 as_FloatRegister($src1$$reg), 15553 as_FloatRegister($src2$$reg)); 15554 %} 15555 ins_pipe(vdop128); 15556 %} 15557 15558 instruct vsub2L(vecX dst, vecX src1, vecX src2) 15559 %{ 15560 predicate(n->as_Vector()->length() == 2); 15561 match(Set dst (SubVL src1 src2)); 15562 ins_cost(INSN_COST); 15563 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 15564 ins_encode %{ 15565 __ subv(as_FloatRegister($dst$$reg), __ T2D, 15566 as_FloatRegister($src1$$reg), 15567 as_FloatRegister($src2$$reg)); 15568 %} 15569 ins_pipe(vdop128); 15570 %} 15571 15572 instruct vsub2F(vecD dst, vecD src1, vecD src2) 15573 %{ 15574 predicate(n->as_Vector()->length() == 2); 15575 match(Set dst (SubVF src1 src2)); 15576 ins_cost(INSN_COST); 15577 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 15578 ins_encode %{ 15579 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 15580 as_FloatRegister($src1$$reg), 15581 as_FloatRegister($src2$$reg)); 15582 %} 15583 ins_pipe(vdop_fp64); 15584 %} 15585 15586 instruct vsub4F(vecX dst, vecX src1, vecX src2) 15587 %{ 15588 predicate(n->as_Vector()->length() == 4); 15589 match(Set dst (SubVF src1 src2)); 15590 ins_cost(INSN_COST); 15591 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 15592 ins_encode %{ 15593 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 15594 as_FloatRegister($src1$$reg), 15595 as_FloatRegister($src2$$reg)); 15596 %} 15597 ins_pipe(vdop_fp128); 15598 %} 15599 15600 instruct vsub2D(vecX dst, vecX src1, vecX src2) 15601 %{ 15602 predicate(n->as_Vector()->length() == 2); 15603 match(Set dst (SubVD src1 src2)); 15604 ins_cost(INSN_COST); 15605 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 15606 ins_encode %{ 15607 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 15608 as_FloatRegister($src1$$reg), 15609 as_FloatRegister($src2$$reg)); 15610 %} 15611 ins_pipe(vdop_fp128); 15612 %} 15613 15614 // --------------------------------- MUL -------------------------------------- 15615 15616 instruct vmul4S(vecD dst, vecD src1, vecD src2) 15617 %{ 15618 predicate(n->as_Vector()->length() == 2 || 15619 n->as_Vector()->length() == 4); 15620 match(Set dst (MulVS src1 src2)); 15621 ins_cost(INSN_COST); 15622 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 15623 ins_encode %{ 15624 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 15625 as_FloatRegister($src1$$reg), 15626 as_FloatRegister($src2$$reg)); 15627 %} 15628 ins_pipe(vmul64); 15629 %} 15630 15631 instruct vmul8S(vecX dst, vecX src1, vecX src2) 15632 %{ 15633 predicate(n->as_Vector()->length() == 8); 15634 match(Set dst (MulVS src1 src2)); 15635 ins_cost(INSN_COST); 15636 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 15637 ins_encode %{ 15638 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 15639 as_FloatRegister($src1$$reg), 15640 as_FloatRegister($src2$$reg)); 15641 %} 15642 ins_pipe(vmul128); 15643 %} 15644 15645 instruct vmul2I(vecD dst, vecD src1, vecD src2) 15646 %{ 15647 predicate(n->as_Vector()->length() == 2); 15648 match(Set dst (MulVI src1 src2)); 15649 ins_cost(INSN_COST); 15650 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 15651 ins_encode %{ 15652 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 15653 as_FloatRegister($src1$$reg), 15654 as_FloatRegister($src2$$reg)); 15655 %} 15656 ins_pipe(vmul64); 15657 %} 15658 15659 instruct vmul4I(vecX dst, vecX src1, vecX src2) 15660 %{ 15661 predicate(n->as_Vector()->length() == 4); 15662 match(Set dst (MulVI src1 src2)); 15663 ins_cost(INSN_COST); 15664 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 15665 ins_encode %{ 15666 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 15667 as_FloatRegister($src1$$reg), 15668 as_FloatRegister($src2$$reg)); 15669 %} 15670 ins_pipe(vmul128); 15671 %} 15672 15673 instruct vmul2F(vecD dst, vecD src1, vecD src2) 15674 %{ 15675 predicate(n->as_Vector()->length() == 2); 15676 match(Set dst (MulVF src1 src2)); 15677 ins_cost(INSN_COST); 15678 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 15679 ins_encode %{ 15680 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 15681 as_FloatRegister($src1$$reg), 15682 as_FloatRegister($src2$$reg)); 15683 %} 15684 ins_pipe(vmuldiv_fp64); 15685 %} 15686 15687 instruct vmul4F(vecX dst, vecX src1, vecX src2) 15688 %{ 15689 predicate(n->as_Vector()->length() == 4); 15690 match(Set dst (MulVF src1 src2)); 15691 ins_cost(INSN_COST); 15692 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 15693 ins_encode %{ 15694 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 15695 as_FloatRegister($src1$$reg), 15696 as_FloatRegister($src2$$reg)); 15697 %} 15698 ins_pipe(vmuldiv_fp128); 15699 %} 15700 15701 instruct vmul2D(vecX dst, vecX src1, vecX src2) 15702 %{ 15703 predicate(n->as_Vector()->length() == 2); 15704 match(Set dst (MulVD src1 src2)); 15705 ins_cost(INSN_COST); 15706 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 15707 ins_encode %{ 15708 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 15709 as_FloatRegister($src1$$reg), 15710 as_FloatRegister($src2$$reg)); 15711 %} 15712 ins_pipe(vmuldiv_fp128); 15713 %} 15714 15715 // --------------------------------- MLA -------------------------------------- 15716 15717 instruct vmla4S(vecD dst, vecD src1, vecD src2) 15718 %{ 15719 predicate(n->as_Vector()->length() == 2 || 15720 n->as_Vector()->length() == 4); 15721 match(Set dst (AddVS dst (MulVS src1 src2))); 15722 ins_cost(INSN_COST); 15723 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 15724 ins_encode %{ 15725 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 15726 as_FloatRegister($src1$$reg), 15727 as_FloatRegister($src2$$reg)); 15728 %} 15729 ins_pipe(vmla64); 15730 %} 15731 15732 instruct vmla8S(vecX dst, vecX src1, vecX src2) 15733 %{ 15734 predicate(n->as_Vector()->length() == 8); 15735 match(Set dst (AddVS dst (MulVS src1 src2))); 15736 ins_cost(INSN_COST); 15737 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 15738 ins_encode %{ 15739 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 15740 as_FloatRegister($src1$$reg), 15741 as_FloatRegister($src2$$reg)); 15742 %} 15743 ins_pipe(vmla128); 15744 %} 15745 15746 instruct vmla2I(vecD dst, vecD src1, vecD src2) 15747 %{ 15748 predicate(n->as_Vector()->length() == 2); 15749 match(Set dst (AddVI dst (MulVI src1 src2))); 15750 ins_cost(INSN_COST); 15751 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 15752 ins_encode %{ 15753 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 15754 as_FloatRegister($src1$$reg), 15755 as_FloatRegister($src2$$reg)); 15756 %} 15757 ins_pipe(vmla64); 15758 %} 15759 15760 instruct vmla4I(vecX dst, vecX src1, vecX src2) 15761 %{ 15762 predicate(n->as_Vector()->length() == 4); 15763 match(Set dst (AddVI dst (MulVI src1 src2))); 15764 ins_cost(INSN_COST); 15765 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 15766 ins_encode %{ 15767 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 15768 as_FloatRegister($src1$$reg), 15769 as_FloatRegister($src2$$reg)); 15770 %} 15771 ins_pipe(vmla128); 15772 %} 15773 15774 // dst + src1 * src2 15775 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 15776 predicate(UseFMA && n->as_Vector()->length() == 2); 15777 match(Set dst (FmaVF dst (Binary src1 src2))); 15778 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 15779 ins_cost(INSN_COST); 15780 ins_encode %{ 15781 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 15782 as_FloatRegister($src1$$reg), 15783 as_FloatRegister($src2$$reg)); 15784 %} 15785 ins_pipe(vmuldiv_fp64); 15786 %} 15787 15788 // dst + src1 * src2 15789 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 15790 predicate(UseFMA && n->as_Vector()->length() == 4); 15791 match(Set dst (FmaVF dst (Binary src1 src2))); 15792 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 15793 ins_cost(INSN_COST); 15794 ins_encode %{ 15795 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 15796 as_FloatRegister($src1$$reg), 15797 as_FloatRegister($src2$$reg)); 15798 %} 15799 ins_pipe(vmuldiv_fp128); 15800 %} 15801 15802 // dst + src1 * src2 15803 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 15804 predicate(UseFMA && n->as_Vector()->length() == 2); 15805 match(Set dst (FmaVD dst (Binary src1 src2))); 15806 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 15807 ins_cost(INSN_COST); 15808 ins_encode %{ 15809 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 15810 as_FloatRegister($src1$$reg), 15811 as_FloatRegister($src2$$reg)); 15812 %} 15813 ins_pipe(vmuldiv_fp128); 15814 %} 15815 15816 // --------------------------------- MLS -------------------------------------- 15817 15818 instruct vmls4S(vecD dst, vecD src1, vecD src2) 15819 %{ 15820 predicate(n->as_Vector()->length() == 2 || 15821 n->as_Vector()->length() == 4); 15822 match(Set dst (SubVS dst (MulVS src1 src2))); 15823 ins_cost(INSN_COST); 15824 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 15825 ins_encode %{ 15826 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 15827 as_FloatRegister($src1$$reg), 15828 as_FloatRegister($src2$$reg)); 15829 %} 15830 ins_pipe(vmla64); 15831 %} 15832 15833 instruct vmls8S(vecX dst, vecX src1, vecX src2) 15834 %{ 15835 predicate(n->as_Vector()->length() == 8); 15836 match(Set dst (SubVS dst (MulVS src1 src2))); 15837 ins_cost(INSN_COST); 15838 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 15839 ins_encode %{ 15840 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 15841 as_FloatRegister($src1$$reg), 15842 as_FloatRegister($src2$$reg)); 15843 %} 15844 ins_pipe(vmla128); 15845 %} 15846 15847 instruct vmls2I(vecD dst, vecD src1, vecD src2) 15848 %{ 15849 predicate(n->as_Vector()->length() == 2); 15850 match(Set dst (SubVI dst (MulVI src1 src2))); 15851 ins_cost(INSN_COST); 15852 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 15853 ins_encode %{ 15854 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 15855 as_FloatRegister($src1$$reg), 15856 as_FloatRegister($src2$$reg)); 15857 %} 15858 ins_pipe(vmla64); 15859 %} 15860 15861 instruct vmls4I(vecX dst, vecX src1, vecX src2) 15862 %{ 15863 predicate(n->as_Vector()->length() == 4); 15864 match(Set dst (SubVI dst (MulVI src1 src2))); 15865 ins_cost(INSN_COST); 15866 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 15867 ins_encode %{ 15868 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 15869 as_FloatRegister($src1$$reg), 15870 as_FloatRegister($src2$$reg)); 15871 %} 15872 ins_pipe(vmla128); 15873 %} 15874 15875 // dst - src1 * src2 15876 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 15877 predicate(UseFMA && n->as_Vector()->length() == 2); 15878 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 15879 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 15880 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 15881 ins_cost(INSN_COST); 15882 ins_encode %{ 15883 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 15884 as_FloatRegister($src1$$reg), 15885 as_FloatRegister($src2$$reg)); 15886 %} 15887 ins_pipe(vmuldiv_fp64); 15888 %} 15889 15890 // dst - src1 * src2 15891 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 15892 predicate(UseFMA && n->as_Vector()->length() == 4); 15893 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 15894 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 15895 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 15896 ins_cost(INSN_COST); 15897 ins_encode %{ 15898 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 15899 as_FloatRegister($src1$$reg), 15900 as_FloatRegister($src2$$reg)); 15901 %} 15902 ins_pipe(vmuldiv_fp128); 15903 %} 15904 15905 // dst - src1 * src2 15906 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 15907 predicate(UseFMA && n->as_Vector()->length() == 2); 15908 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 15909 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 15910 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 15911 ins_cost(INSN_COST); 15912 ins_encode %{ 15913 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 15914 as_FloatRegister($src1$$reg), 15915 as_FloatRegister($src2$$reg)); 15916 %} 15917 ins_pipe(vmuldiv_fp128); 15918 %} 15919 15920 // --------------------------------- DIV -------------------------------------- 15921 15922 instruct vdiv2F(vecD dst, vecD src1, vecD src2) 15923 %{ 15924 predicate(n->as_Vector()->length() == 2); 15925 match(Set dst (DivVF src1 src2)); 15926 ins_cost(INSN_COST); 15927 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 15928 ins_encode %{ 15929 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 15930 as_FloatRegister($src1$$reg), 15931 as_FloatRegister($src2$$reg)); 15932 %} 15933 ins_pipe(vmuldiv_fp64); 15934 %} 15935 15936 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 15937 %{ 15938 predicate(n->as_Vector()->length() == 4); 15939 match(Set dst (DivVF src1 src2)); 15940 ins_cost(INSN_COST); 15941 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 15942 ins_encode %{ 15943 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 15944 as_FloatRegister($src1$$reg), 15945 as_FloatRegister($src2$$reg)); 15946 %} 15947 ins_pipe(vmuldiv_fp128); 15948 %} 15949 15950 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 15951 %{ 15952 predicate(n->as_Vector()->length() == 2); 15953 match(Set dst (DivVD src1 src2)); 15954 ins_cost(INSN_COST); 15955 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 15956 ins_encode %{ 15957 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 15958 as_FloatRegister($src1$$reg), 15959 as_FloatRegister($src2$$reg)); 15960 %} 15961 ins_pipe(vmuldiv_fp128); 15962 %} 15963 15964 // --------------------------------- SQRT ------------------------------------- 15965 15966 instruct vsqrt2D(vecX dst, vecX src) 15967 %{ 15968 predicate(n->as_Vector()->length() == 2); 15969 match(Set dst (SqrtVD src)); 15970 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 15971 ins_encode %{ 15972 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 15973 as_FloatRegister($src$$reg)); 15974 %} 15975 ins_pipe(vsqrt_fp128); 15976 %} 15977 15978 // --------------------------------- ABS -------------------------------------- 15979 15980 instruct vabs2F(vecD dst, vecD src) 15981 %{ 15982 predicate(n->as_Vector()->length() == 2); 15983 match(Set dst (AbsVF src)); 15984 ins_cost(INSN_COST * 3); 15985 format %{ "fabs $dst,$src\t# vector (2S)" %} 15986 ins_encode %{ 15987 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 15988 as_FloatRegister($src$$reg)); 15989 %} 15990 ins_pipe(vunop_fp64); 15991 %} 15992 15993 instruct vabs4F(vecX dst, vecX src) 15994 %{ 15995 predicate(n->as_Vector()->length() == 4); 15996 match(Set dst (AbsVF src)); 15997 ins_cost(INSN_COST * 3); 15998 format %{ "fabs $dst,$src\t# vector (4S)" %} 15999 ins_encode %{ 16000 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16001 as_FloatRegister($src$$reg)); 16002 %} 16003 ins_pipe(vunop_fp128); 16004 %} 16005 16006 instruct vabs2D(vecX dst, vecX src) 16007 %{ 16008 predicate(n->as_Vector()->length() == 2); 16009 match(Set dst (AbsVD src)); 16010 ins_cost(INSN_COST * 3); 16011 format %{ "fabs $dst,$src\t# vector (2D)" %} 16012 ins_encode %{ 16013 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 16014 as_FloatRegister($src$$reg)); 16015 %} 16016 ins_pipe(vunop_fp128); 16017 %} 16018 16019 // --------------------------------- NEG -------------------------------------- 16020 16021 instruct vneg2F(vecD dst, vecD src) 16022 %{ 16023 predicate(n->as_Vector()->length() == 2); 16024 match(Set dst (NegVF src)); 16025 ins_cost(INSN_COST * 3); 16026 format %{ "fneg $dst,$src\t# vector (2S)" %} 16027 ins_encode %{ 16028 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 16029 as_FloatRegister($src$$reg)); 16030 %} 16031 ins_pipe(vunop_fp64); 16032 %} 16033 16034 instruct vneg4F(vecX dst, vecX src) 16035 %{ 16036 predicate(n->as_Vector()->length() == 4); 16037 match(Set dst (NegVF src)); 16038 ins_cost(INSN_COST * 3); 16039 format %{ "fneg $dst,$src\t# vector (4S)" %} 16040 ins_encode %{ 16041 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 16042 as_FloatRegister($src$$reg)); 16043 %} 16044 ins_pipe(vunop_fp128); 16045 %} 16046 16047 instruct vneg2D(vecX dst, vecX src) 16048 %{ 16049 predicate(n->as_Vector()->length() == 2); 16050 match(Set dst (NegVD src)); 16051 ins_cost(INSN_COST * 3); 16052 format %{ "fneg $dst,$src\t# vector (2D)" %} 16053 ins_encode %{ 16054 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 16055 as_FloatRegister($src$$reg)); 16056 %} 16057 ins_pipe(vunop_fp128); 16058 %} 16059 16060 // --------------------------------- AND -------------------------------------- 16061 16062 instruct vand8B(vecD dst, vecD src1, vecD src2) 16063 %{ 16064 predicate(n->as_Vector()->length_in_bytes() == 4 || 16065 n->as_Vector()->length_in_bytes() == 8); 16066 match(Set dst (AndV src1 src2)); 16067 ins_cost(INSN_COST); 16068 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16069 ins_encode %{ 16070 __ andr(as_FloatRegister($dst$$reg), __ T8B, 16071 as_FloatRegister($src1$$reg), 16072 as_FloatRegister($src2$$reg)); 16073 %} 16074 ins_pipe(vlogical64); 16075 %} 16076 16077 instruct vand16B(vecX dst, vecX src1, vecX src2) 16078 %{ 16079 predicate(n->as_Vector()->length_in_bytes() == 16); 16080 match(Set dst (AndV src1 src2)); 16081 ins_cost(INSN_COST); 16082 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 16083 ins_encode %{ 16084 __ andr(as_FloatRegister($dst$$reg), __ T16B, 16085 as_FloatRegister($src1$$reg), 16086 as_FloatRegister($src2$$reg)); 16087 %} 16088 ins_pipe(vlogical128); 16089 %} 16090 16091 // --------------------------------- OR --------------------------------------- 16092 16093 instruct vor8B(vecD dst, vecD src1, vecD src2) 16094 %{ 16095 predicate(n->as_Vector()->length_in_bytes() == 4 || 16096 n->as_Vector()->length_in_bytes() == 8); 16097 match(Set dst (OrV src1 src2)); 16098 ins_cost(INSN_COST); 16099 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 16100 ins_encode %{ 16101 __ orr(as_FloatRegister($dst$$reg), __ T8B, 16102 as_FloatRegister($src1$$reg), 16103 as_FloatRegister($src2$$reg)); 16104 %} 16105 ins_pipe(vlogical64); 16106 %} 16107 16108 instruct vor16B(vecX dst, vecX src1, vecX src2) 16109 %{ 16110 predicate(n->as_Vector()->length_in_bytes() == 16); 16111 match(Set dst (OrV src1 src2)); 16112 ins_cost(INSN_COST); 16113 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 16114 ins_encode %{ 16115 __ orr(as_FloatRegister($dst$$reg), __ T16B, 16116 as_FloatRegister($src1$$reg), 16117 as_FloatRegister($src2$$reg)); 16118 %} 16119 ins_pipe(vlogical128); 16120 %} 16121 16122 // --------------------------------- XOR -------------------------------------- 16123 16124 instruct vxor8B(vecD dst, vecD src1, vecD src2) 16125 %{ 16126 predicate(n->as_Vector()->length_in_bytes() == 4 || 16127 n->as_Vector()->length_in_bytes() == 8); 16128 match(Set dst (XorV src1 src2)); 16129 ins_cost(INSN_COST); 16130 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 16131 ins_encode %{ 16132 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16133 as_FloatRegister($src1$$reg), 16134 as_FloatRegister($src2$$reg)); 16135 %} 16136 ins_pipe(vlogical64); 16137 %} 16138 16139 instruct vxor16B(vecX dst, vecX src1, vecX src2) 16140 %{ 16141 predicate(n->as_Vector()->length_in_bytes() == 16); 16142 match(Set dst (XorV src1 src2)); 16143 ins_cost(INSN_COST); 16144 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 16145 ins_encode %{ 16146 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16147 as_FloatRegister($src1$$reg), 16148 as_FloatRegister($src2$$reg)); 16149 %} 16150 ins_pipe(vlogical128); 16151 %} 16152 16153 // ------------------------------ Shift --------------------------------------- 16154 16155 instruct vshiftcntL(vecX dst, iRegIorL2I cnt) %{ 16156 match(Set dst (LShiftCntV cnt)); 16157 format %{ "dup $dst, $cnt\t# shift count (vecX)" %} 16158 ins_encode %{ 16159 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16160 %} 16161 ins_pipe(vdup_reg_reg128); 16162 %} 16163 16164 // Right shifts on aarch64 SIMD are implemented as left shift by -ve amount 16165 instruct vshiftcntR(vecX dst, iRegIorL2I cnt) %{ 16166 match(Set dst (RShiftCntV cnt)); 16167 format %{ "dup $dst, $cnt\t# shift count (vecX)\n\tneg $dst, $dst\t T16B" %} 16168 ins_encode %{ 16169 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 16170 __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg)); 16171 %} 16172 ins_pipe(vdup_reg_reg128); 16173 %} 16174 16175 instruct vsll8B(vecD dst, vecD src, vecX shift) %{ 16176 predicate(n->as_Vector()->length() == 4 || 16177 n->as_Vector()->length() == 8); 16178 match(Set dst (LShiftVB src shift)); 16179 match(Set dst (RShiftVB src shift)); 16180 ins_cost(INSN_COST); 16181 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 16182 ins_encode %{ 16183 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 16184 as_FloatRegister($src$$reg), 16185 as_FloatRegister($shift$$reg)); 16186 %} 16187 ins_pipe(vshift64); 16188 %} 16189 16190 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 16191 predicate(n->as_Vector()->length() == 16); 16192 match(Set dst (LShiftVB src shift)); 16193 match(Set dst (RShiftVB src shift)); 16194 ins_cost(INSN_COST); 16195 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 16196 ins_encode %{ 16197 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 16198 as_FloatRegister($src$$reg), 16199 as_FloatRegister($shift$$reg)); 16200 %} 16201 ins_pipe(vshift128); 16202 %} 16203 16204 instruct vsrl8B(vecD dst, vecD src, vecX shift) %{ 16205 predicate(n->as_Vector()->length() == 4 || 16206 n->as_Vector()->length() == 8); 16207 match(Set dst (URShiftVB src shift)); 16208 ins_cost(INSN_COST); 16209 format %{ "ushl $dst,$src,$shift\t# vector (8B)" %} 16210 ins_encode %{ 16211 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 16212 as_FloatRegister($src$$reg), 16213 as_FloatRegister($shift$$reg)); 16214 %} 16215 ins_pipe(vshift64); 16216 %} 16217 16218 instruct vsrl16B(vecX dst, vecX src, vecX shift) %{ 16219 predicate(n->as_Vector()->length() == 16); 16220 match(Set dst (URShiftVB src shift)); 16221 ins_cost(INSN_COST); 16222 format %{ "ushl $dst,$src,$shift\t# vector (16B)" %} 16223 ins_encode %{ 16224 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 16225 as_FloatRegister($src$$reg), 16226 as_FloatRegister($shift$$reg)); 16227 %} 16228 ins_pipe(vshift128); 16229 %} 16230 16231 instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 16232 predicate(n->as_Vector()->length() == 4 || 16233 n->as_Vector()->length() == 8); 16234 match(Set dst (LShiftVB src shift)); 16235 ins_cost(INSN_COST); 16236 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 16237 ins_encode %{ 16238 int sh = (int)$shift$$constant; 16239 if (sh >= 8) { 16240 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16241 as_FloatRegister($src$$reg), 16242 as_FloatRegister($src$$reg)); 16243 } else { 16244 __ shl(as_FloatRegister($dst$$reg), __ T8B, 16245 as_FloatRegister($src$$reg), sh); 16246 } 16247 %} 16248 ins_pipe(vshift64_imm); 16249 %} 16250 16251 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 16252 predicate(n->as_Vector()->length() == 16); 16253 match(Set dst (LShiftVB src shift)); 16254 ins_cost(INSN_COST); 16255 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 16256 ins_encode %{ 16257 int sh = (int)$shift$$constant; 16258 if (sh >= 8) { 16259 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16260 as_FloatRegister($src$$reg), 16261 as_FloatRegister($src$$reg)); 16262 } else { 16263 __ shl(as_FloatRegister($dst$$reg), __ T16B, 16264 as_FloatRegister($src$$reg), sh); 16265 } 16266 %} 16267 ins_pipe(vshift128_imm); 16268 %} 16269 16270 instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 16271 predicate(n->as_Vector()->length() == 4 || 16272 n->as_Vector()->length() == 8); 16273 match(Set dst (RShiftVB src shift)); 16274 ins_cost(INSN_COST); 16275 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 16276 ins_encode %{ 16277 int sh = (int)$shift$$constant; 16278 if (sh >= 8) sh = 7; 16279 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 16280 as_FloatRegister($src$$reg), sh); 16281 %} 16282 ins_pipe(vshift64_imm); 16283 %} 16284 16285 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 16286 predicate(n->as_Vector()->length() == 16); 16287 match(Set dst (RShiftVB src shift)); 16288 ins_cost(INSN_COST); 16289 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 16290 ins_encode %{ 16291 int sh = (int)$shift$$constant; 16292 if (sh >= 8) sh = 7; 16293 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 16294 as_FloatRegister($src$$reg), sh); 16295 %} 16296 ins_pipe(vshift128_imm); 16297 %} 16298 16299 instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 16300 predicate(n->as_Vector()->length() == 4 || 16301 n->as_Vector()->length() == 8); 16302 match(Set dst (URShiftVB src shift)); 16303 ins_cost(INSN_COST); 16304 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 16305 ins_encode %{ 16306 int sh = (int)$shift$$constant; 16307 if (sh >= 8) { 16308 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16309 as_FloatRegister($src$$reg), 16310 as_FloatRegister($src$$reg)); 16311 } else { 16312 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 16313 as_FloatRegister($src$$reg), sh); 16314 } 16315 %} 16316 ins_pipe(vshift64_imm); 16317 %} 16318 16319 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 16320 predicate(n->as_Vector()->length() == 16); 16321 match(Set dst (URShiftVB src shift)); 16322 ins_cost(INSN_COST); 16323 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 16324 ins_encode %{ 16325 int sh = (int)$shift$$constant; 16326 if (sh >= 8) { 16327 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16328 as_FloatRegister($src$$reg), 16329 as_FloatRegister($src$$reg)); 16330 } else { 16331 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 16332 as_FloatRegister($src$$reg), sh); 16333 } 16334 %} 16335 ins_pipe(vshift128_imm); 16336 %} 16337 16338 instruct vsll4S(vecD dst, vecD src, vecX shift) %{ 16339 predicate(n->as_Vector()->length() == 2 || 16340 n->as_Vector()->length() == 4); 16341 match(Set dst (LShiftVS src shift)); 16342 match(Set dst (RShiftVS src shift)); 16343 ins_cost(INSN_COST); 16344 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 16345 ins_encode %{ 16346 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 16347 as_FloatRegister($src$$reg), 16348 as_FloatRegister($shift$$reg)); 16349 %} 16350 ins_pipe(vshift64); 16351 %} 16352 16353 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 16354 predicate(n->as_Vector()->length() == 8); 16355 match(Set dst (LShiftVS src shift)); 16356 match(Set dst (RShiftVS src shift)); 16357 ins_cost(INSN_COST); 16358 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 16359 ins_encode %{ 16360 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 16361 as_FloatRegister($src$$reg), 16362 as_FloatRegister($shift$$reg)); 16363 %} 16364 ins_pipe(vshift128); 16365 %} 16366 16367 instruct vsrl4S(vecD dst, vecD src, vecX shift) %{ 16368 predicate(n->as_Vector()->length() == 2 || 16369 n->as_Vector()->length() == 4); 16370 match(Set dst (URShiftVS src shift)); 16371 ins_cost(INSN_COST); 16372 format %{ "ushl $dst,$src,$shift\t# vector (4H)" %} 16373 ins_encode %{ 16374 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 16375 as_FloatRegister($src$$reg), 16376 as_FloatRegister($shift$$reg)); 16377 %} 16378 ins_pipe(vshift64); 16379 %} 16380 16381 instruct vsrl8S(vecX dst, vecX src, vecX shift) %{ 16382 predicate(n->as_Vector()->length() == 8); 16383 match(Set dst (URShiftVS src shift)); 16384 ins_cost(INSN_COST); 16385 format %{ "ushl $dst,$src,$shift\t# vector (8H)" %} 16386 ins_encode %{ 16387 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 16388 as_FloatRegister($src$$reg), 16389 as_FloatRegister($shift$$reg)); 16390 %} 16391 ins_pipe(vshift128); 16392 %} 16393 16394 instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 16395 predicate(n->as_Vector()->length() == 2 || 16396 n->as_Vector()->length() == 4); 16397 match(Set dst (LShiftVS src shift)); 16398 ins_cost(INSN_COST); 16399 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 16400 ins_encode %{ 16401 int sh = (int)$shift$$constant; 16402 if (sh >= 16) { 16403 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16404 as_FloatRegister($src$$reg), 16405 as_FloatRegister($src$$reg)); 16406 } else { 16407 __ shl(as_FloatRegister($dst$$reg), __ T4H, 16408 as_FloatRegister($src$$reg), sh); 16409 } 16410 %} 16411 ins_pipe(vshift64_imm); 16412 %} 16413 16414 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 16415 predicate(n->as_Vector()->length() == 8); 16416 match(Set dst (LShiftVS src shift)); 16417 ins_cost(INSN_COST); 16418 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 16419 ins_encode %{ 16420 int sh = (int)$shift$$constant; 16421 if (sh >= 16) { 16422 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16423 as_FloatRegister($src$$reg), 16424 as_FloatRegister($src$$reg)); 16425 } else { 16426 __ shl(as_FloatRegister($dst$$reg), __ T8H, 16427 as_FloatRegister($src$$reg), sh); 16428 } 16429 %} 16430 ins_pipe(vshift128_imm); 16431 %} 16432 16433 instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 16434 predicate(n->as_Vector()->length() == 2 || 16435 n->as_Vector()->length() == 4); 16436 match(Set dst (RShiftVS src shift)); 16437 ins_cost(INSN_COST); 16438 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 16439 ins_encode %{ 16440 int sh = (int)$shift$$constant; 16441 if (sh >= 16) sh = 15; 16442 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 16443 as_FloatRegister($src$$reg), sh); 16444 %} 16445 ins_pipe(vshift64_imm); 16446 %} 16447 16448 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 16449 predicate(n->as_Vector()->length() == 8); 16450 match(Set dst (RShiftVS src shift)); 16451 ins_cost(INSN_COST); 16452 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 16453 ins_encode %{ 16454 int sh = (int)$shift$$constant; 16455 if (sh >= 16) sh = 15; 16456 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 16457 as_FloatRegister($src$$reg), sh); 16458 %} 16459 ins_pipe(vshift128_imm); 16460 %} 16461 16462 instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 16463 predicate(n->as_Vector()->length() == 2 || 16464 n->as_Vector()->length() == 4); 16465 match(Set dst (URShiftVS src shift)); 16466 ins_cost(INSN_COST); 16467 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 16468 ins_encode %{ 16469 int sh = (int)$shift$$constant; 16470 if (sh >= 16) { 16471 __ eor(as_FloatRegister($dst$$reg), __ T8B, 16472 as_FloatRegister($src$$reg), 16473 as_FloatRegister($src$$reg)); 16474 } else { 16475 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 16476 as_FloatRegister($src$$reg), sh); 16477 } 16478 %} 16479 ins_pipe(vshift64_imm); 16480 %} 16481 16482 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 16483 predicate(n->as_Vector()->length() == 8); 16484 match(Set dst (URShiftVS src shift)); 16485 ins_cost(INSN_COST); 16486 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 16487 ins_encode %{ 16488 int sh = (int)$shift$$constant; 16489 if (sh >= 16) { 16490 __ eor(as_FloatRegister($dst$$reg), __ T16B, 16491 as_FloatRegister($src$$reg), 16492 as_FloatRegister($src$$reg)); 16493 } else { 16494 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 16495 as_FloatRegister($src$$reg), sh); 16496 } 16497 %} 16498 ins_pipe(vshift128_imm); 16499 %} 16500 16501 instruct vsll2I(vecD dst, vecD src, vecX shift) %{ 16502 predicate(n->as_Vector()->length() == 2); 16503 match(Set dst (LShiftVI src shift)); 16504 match(Set dst (RShiftVI src shift)); 16505 ins_cost(INSN_COST); 16506 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 16507 ins_encode %{ 16508 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 16509 as_FloatRegister($src$$reg), 16510 as_FloatRegister($shift$$reg)); 16511 %} 16512 ins_pipe(vshift64); 16513 %} 16514 16515 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 16516 predicate(n->as_Vector()->length() == 4); 16517 match(Set dst (LShiftVI src shift)); 16518 match(Set dst (RShiftVI src shift)); 16519 ins_cost(INSN_COST); 16520 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 16521 ins_encode %{ 16522 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 16523 as_FloatRegister($src$$reg), 16524 as_FloatRegister($shift$$reg)); 16525 %} 16526 ins_pipe(vshift128); 16527 %} 16528 16529 instruct vsrl2I(vecD dst, vecD src, vecX shift) %{ 16530 predicate(n->as_Vector()->length() == 2); 16531 match(Set dst (URShiftVI src shift)); 16532 ins_cost(INSN_COST); 16533 format %{ "ushl $dst,$src,$shift\t# vector (2S)" %} 16534 ins_encode %{ 16535 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 16536 as_FloatRegister($src$$reg), 16537 as_FloatRegister($shift$$reg)); 16538 %} 16539 ins_pipe(vshift64); 16540 %} 16541 16542 instruct vsrl4I(vecX dst, vecX src, vecX shift) %{ 16543 predicate(n->as_Vector()->length() == 4); 16544 match(Set dst (URShiftVI src shift)); 16545 ins_cost(INSN_COST); 16546 format %{ "ushl $dst,$src,$shift\t# vector (4S)" %} 16547 ins_encode %{ 16548 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 16549 as_FloatRegister($src$$reg), 16550 as_FloatRegister($shift$$reg)); 16551 %} 16552 ins_pipe(vshift128); 16553 %} 16554 16555 instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 16556 predicate(n->as_Vector()->length() == 2); 16557 match(Set dst (LShiftVI src shift)); 16558 ins_cost(INSN_COST); 16559 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 16560 ins_encode %{ 16561 __ shl(as_FloatRegister($dst$$reg), __ T2S, 16562 as_FloatRegister($src$$reg), 16563 (int)$shift$$constant); 16564 %} 16565 ins_pipe(vshift64_imm); 16566 %} 16567 16568 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 16569 predicate(n->as_Vector()->length() == 4); 16570 match(Set dst (LShiftVI src shift)); 16571 ins_cost(INSN_COST); 16572 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 16573 ins_encode %{ 16574 __ shl(as_FloatRegister($dst$$reg), __ T4S, 16575 as_FloatRegister($src$$reg), 16576 (int)$shift$$constant); 16577 %} 16578 ins_pipe(vshift128_imm); 16579 %} 16580 16581 instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 16582 predicate(n->as_Vector()->length() == 2); 16583 match(Set dst (RShiftVI src shift)); 16584 ins_cost(INSN_COST); 16585 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 16586 ins_encode %{ 16587 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 16588 as_FloatRegister($src$$reg), 16589 (int)$shift$$constant); 16590 %} 16591 ins_pipe(vshift64_imm); 16592 %} 16593 16594 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 16595 predicate(n->as_Vector()->length() == 4); 16596 match(Set dst (RShiftVI src shift)); 16597 ins_cost(INSN_COST); 16598 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 16599 ins_encode %{ 16600 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 16601 as_FloatRegister($src$$reg), 16602 (int)$shift$$constant); 16603 %} 16604 ins_pipe(vshift128_imm); 16605 %} 16606 16607 instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 16608 predicate(n->as_Vector()->length() == 2); 16609 match(Set dst (URShiftVI src shift)); 16610 ins_cost(INSN_COST); 16611 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 16612 ins_encode %{ 16613 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 16614 as_FloatRegister($src$$reg), 16615 (int)$shift$$constant); 16616 %} 16617 ins_pipe(vshift64_imm); 16618 %} 16619 16620 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 16621 predicate(n->as_Vector()->length() == 4); 16622 match(Set dst (URShiftVI src shift)); 16623 ins_cost(INSN_COST); 16624 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 16625 ins_encode %{ 16626 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 16627 as_FloatRegister($src$$reg), 16628 (int)$shift$$constant); 16629 %} 16630 ins_pipe(vshift128_imm); 16631 %} 16632 16633 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 16634 predicate(n->as_Vector()->length() == 2); 16635 match(Set dst (LShiftVL src shift)); 16636 match(Set dst (RShiftVL src shift)); 16637 ins_cost(INSN_COST); 16638 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 16639 ins_encode %{ 16640 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 16641 as_FloatRegister($src$$reg), 16642 as_FloatRegister($shift$$reg)); 16643 %} 16644 ins_pipe(vshift128); 16645 %} 16646 16647 instruct vsrl2L(vecX dst, vecX src, vecX shift) %{ 16648 predicate(n->as_Vector()->length() == 2); 16649 match(Set dst (URShiftVL src shift)); 16650 ins_cost(INSN_COST); 16651 format %{ "ushl $dst,$src,$shift\t# vector (2D)" %} 16652 ins_encode %{ 16653 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 16654 as_FloatRegister($src$$reg), 16655 as_FloatRegister($shift$$reg)); 16656 %} 16657 ins_pipe(vshift128); 16658 %} 16659 16660 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 16661 predicate(n->as_Vector()->length() == 2); 16662 match(Set dst (LShiftVL src shift)); 16663 ins_cost(INSN_COST); 16664 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 16665 ins_encode %{ 16666 __ shl(as_FloatRegister($dst$$reg), __ T2D, 16667 as_FloatRegister($src$$reg), 16668 (int)$shift$$constant); 16669 %} 16670 ins_pipe(vshift128_imm); 16671 %} 16672 16673 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 16674 predicate(n->as_Vector()->length() == 2); 16675 match(Set dst (RShiftVL src shift)); 16676 ins_cost(INSN_COST); 16677 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 16678 ins_encode %{ 16679 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 16680 as_FloatRegister($src$$reg), 16681 (int)$shift$$constant); 16682 %} 16683 ins_pipe(vshift128_imm); 16684 %} 16685 16686 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 16687 predicate(n->as_Vector()->length() == 2); 16688 match(Set dst (URShiftVL src shift)); 16689 ins_cost(INSN_COST); 16690 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 16691 ins_encode %{ 16692 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 16693 as_FloatRegister($src$$reg), 16694 (int)$shift$$constant); 16695 %} 16696 ins_pipe(vshift128_imm); 16697 %} 16698 16699 //----------PEEPHOLE RULES----------------------------------------------------- 16700 // These must follow all instruction definitions as they use the names 16701 // defined in the instructions definitions. 16702 // 16703 // peepmatch ( root_instr_name [preceding_instruction]* ); 16704 // 16705 // peepconstraint %{ 16706 // (instruction_number.operand_name relational_op instruction_number.operand_name 16707 // [, ...] ); 16708 // // instruction numbers are zero-based using left to right order in peepmatch 16709 // 16710 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 16711 // // provide an instruction_number.operand_name for each operand that appears 16712 // // in the replacement instruction's match rule 16713 // 16714 // ---------VM FLAGS--------------------------------------------------------- 16715 // 16716 // All peephole optimizations can be turned off using -XX:-OptoPeephole 16717 // 16718 // Each peephole rule is given an identifying number starting with zero and 16719 // increasing by one in the order seen by the parser. An individual peephole 16720 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 16721 // on the command-line. 16722 // 16723 // ---------CURRENT LIMITATIONS---------------------------------------------- 16724 // 16725 // Only match adjacent instructions in same basic block 16726 // Only equality constraints 16727 // Only constraints between operands, not (0.dest_reg == RAX_enc) 16728 // Only one replacement instruction 16729 // 16730 // ---------EXAMPLE---------------------------------------------------------- 16731 // 16732 // // pertinent parts of existing instructions in architecture description 16733 // instruct movI(iRegINoSp dst, iRegI src) 16734 // %{ 16735 // match(Set dst (CopyI src)); 16736 // %} 16737 // 16738 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 16739 // %{ 16740 // match(Set dst (AddI dst src)); 16741 // effect(KILL cr); 16742 // %} 16743 // 16744 // // Change (inc mov) to lea 16745 // peephole %{ 16746 // // increment preceeded by register-register move 16747 // peepmatch ( incI_iReg movI ); 16748 // // require that the destination register of the increment 16749 // // match the destination register of the move 16750 // peepconstraint ( 0.dst == 1.dst ); 16751 // // construct a replacement instruction that sets 16752 // // the destination to ( move's source register + one ) 16753 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 16754 // %} 16755 // 16756 16757 // Implementation no longer uses movX instructions since 16758 // machine-independent system no longer uses CopyX nodes. 16759 // 16760 // peephole 16761 // %{ 16762 // peepmatch (incI_iReg movI); 16763 // peepconstraint (0.dst == 1.dst); 16764 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16765 // %} 16766 16767 // peephole 16768 // %{ 16769 // peepmatch (decI_iReg movI); 16770 // peepconstraint (0.dst == 1.dst); 16771 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16772 // %} 16773 16774 // peephole 16775 // %{ 16776 // peepmatch (addI_iReg_imm movI); 16777 // peepconstraint (0.dst == 1.dst); 16778 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16779 // %} 16780 16781 // peephole 16782 // %{ 16783 // peepmatch (incL_iReg movL); 16784 // peepconstraint (0.dst == 1.dst); 16785 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16786 // %} 16787 16788 // peephole 16789 // %{ 16790 // peepmatch (decL_iReg movL); 16791 // peepconstraint (0.dst == 1.dst); 16792 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16793 // %} 16794 16795 // peephole 16796 // %{ 16797 // peepmatch (addL_iReg_imm movL); 16798 // peepconstraint (0.dst == 1.dst); 16799 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16800 // %} 16801 16802 // peephole 16803 // %{ 16804 // peepmatch (addP_iReg_imm movP); 16805 // peepconstraint (0.dst == 1.dst); 16806 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 16807 // %} 16808 16809 // // Change load of spilled value to only a spill 16810 // instruct storeI(memory mem, iRegI src) 16811 // %{ 16812 // match(Set mem (StoreI mem src)); 16813 // %} 16814 // 16815 // instruct loadI(iRegINoSp dst, memory mem) 16816 // %{ 16817 // match(Set dst (LoadI mem)); 16818 // %} 16819 // 16820 16821 //----------SMARTSPILL RULES--------------------------------------------------- 16822 // These must follow all instruction definitions as they use the names 16823 // defined in the instructions definitions. 16824 16825 // Local Variables: 16826 // mode: c++ 16827 // End: