1 // 2 // Copyright (c) 2003, 2015, 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 128bit vector registers 869 reg_class vectorx_reg( 870 V0, V0_H, V0_J, V0_K, 871 V1, V1_H, V1_J, V1_K, 872 V2, V2_H, V2_J, V2_K, 873 V3, V3_H, V3_J, V3_K, 874 V4, V4_H, V4_J, V4_K, 875 V5, V5_H, V5_J, V5_K, 876 V6, V6_H, V6_J, V6_K, 877 V7, V7_H, V7_J, V7_K, 878 V8, V8_H, V8_J, V8_K, 879 V9, V9_H, V9_J, V9_K, 880 V10, V10_H, V10_J, V10_K, 881 V11, V11_H, V11_J, V11_K, 882 V12, V12_H, V12_J, V12_K, 883 V13, V13_H, V13_J, V13_K, 884 V14, V14_H, V14_J, V14_K, 885 V15, V15_H, V15_J, V15_K, 886 V16, V16_H, V16_J, V16_K, 887 V17, V17_H, V17_J, V17_K, 888 V18, V18_H, V18_J, V18_K, 889 V19, V19_H, V19_J, V19_K, 890 V20, V20_H, V20_J, V20_K, 891 V21, V21_H, V21_J, V21_K, 892 V22, V22_H, V22_J, V22_K, 893 V23, V23_H, V23_J, V23_K, 894 V24, V24_H, V24_J, V24_K, 895 V25, V25_H, V25_J, V25_K, 896 V26, V26_H, V26_J, V26_K, 897 V27, V27_H, V27_J, V27_K, 898 V28, V28_H, V28_J, V28_K, 899 V29, V29_H, V29_J, V29_K, 900 V30, V30_H, V30_J, V30_K, 901 V31, V31_H, V31_J, V31_K 902 ); 903 904 // Class for 128 bit register v0 905 reg_class v0_reg( 906 V0, V0_H 907 ); 908 909 // Class for 128 bit register v1 910 reg_class v1_reg( 911 V1, V1_H 912 ); 913 914 // Class for 128 bit register v2 915 reg_class v2_reg( 916 V2, V2_H 917 ); 918 919 // Class for 128 bit register v3 920 reg_class v3_reg( 921 V3, V3_H 922 ); 923 924 // Singleton class for condition codes 925 reg_class int_flags(RFLAGS); 926 927 %} 928 929 //----------DEFINITION BLOCK--------------------------------------------------- 930 // Define name --> value mappings to inform the ADLC of an integer valued name 931 // Current support includes integer values in the range [0, 0x7FFFFFFF] 932 // Format: 933 // int_def <name> ( <int_value>, <expression>); 934 // Generated Code in ad_<arch>.hpp 935 // #define <name> (<expression>) 936 // // value == <int_value> 937 // Generated code in ad_<arch>.cpp adlc_verification() 938 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 939 // 940 941 // we follow the ppc-aix port in using a simple cost model which ranks 942 // register operations as cheap, memory ops as more expensive and 943 // branches as most expensive. the first two have a low as well as a 944 // normal cost. huge cost appears to be a way of saying don't do 945 // something 946 947 definitions %{ 948 // The default cost (of a register move instruction). 949 int_def INSN_COST ( 100, 100); 950 int_def BRANCH_COST ( 200, 2 * INSN_COST); 951 int_def CALL_COST ( 200, 2 * INSN_COST); 952 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 953 %} 954 955 956 //----------SOURCE BLOCK------------------------------------------------------- 957 // This is a block of C++ code which provides values, functions, and 958 // definitions necessary in the rest of the architecture description 959 960 source_hpp %{ 961 962 #include "gc/shared/cardTableModRefBS.hpp" 963 964 class CallStubImpl { 965 966 //-------------------------------------------------------------- 967 //---< Used for optimization in Compile::shorten_branches >--- 968 //-------------------------------------------------------------- 969 970 public: 971 // Size of call trampoline stub. 972 static uint size_call_trampoline() { 973 return 0; // no call trampolines on this platform 974 } 975 976 // number of relocations needed by a call trampoline stub 977 static uint reloc_call_trampoline() { 978 return 0; // no call trampolines on this platform 979 } 980 }; 981 982 class HandlerImpl { 983 984 public: 985 986 static int emit_exception_handler(CodeBuffer &cbuf); 987 static int emit_deopt_handler(CodeBuffer& cbuf); 988 989 static uint size_exception_handler() { 990 return MacroAssembler::far_branch_size(); 991 } 992 993 static uint size_deopt_handler() { 994 // count one adr and one far branch instruction 995 return 4 * NativeInstruction::instruction_size; 996 } 997 }; 998 999 // graph traversal helpers 1000 MemBarNode *has_parent_membar(const Node *n, 1001 ProjNode *&ctl, ProjNode *&mem); 1002 MemBarNode *has_child_membar(const MemBarNode *n, 1003 ProjNode *&ctl, ProjNode *&mem); 1004 1005 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1006 bool unnecessary_acquire(const Node *barrier); 1007 bool needs_acquiring_load(const Node *load); 1008 1009 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1010 bool unnecessary_release(const Node *barrier); 1011 bool unnecessary_volatile(const Node *barrier); 1012 bool needs_releasing_store(const Node *store); 1013 1014 // Use barrier instructions for unsafe volatile gets rather than 1015 // trying to identify an exact signature for them 1016 const bool UseBarriersForUnsafeVolatileGet = false; 1017 %} 1018 1019 source %{ 1020 1021 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1022 // use to implement volatile reads and writes. For a volatile read 1023 // we simply need 1024 // 1025 // ldar<x> 1026 // 1027 // and for a volatile write we need 1028 // 1029 // stlr<x> 1030 // 1031 // Alternatively, we can implement them by pairing a normal 1032 // load/store with a memory barrier. For a volatile read we need 1033 // 1034 // ldr<x> 1035 // dmb ishld 1036 // 1037 // for a volatile write 1038 // 1039 // dmb ish 1040 // str<x> 1041 // dmb ish 1042 // 1043 // In order to generate the desired instruction sequence we need to 1044 // be able to identify specific 'signature' ideal graph node 1045 // sequences which i) occur as a translation of a volatile reads or 1046 // writes and ii) do not occur through any other translation or 1047 // graph transformation. We can then provide alternative aldc 1048 // matching rules which translate these node sequences to the 1049 // desired machine code sequences. Selection of the alternative 1050 // rules can be implemented by predicates which identify the 1051 // relevant node sequences. 1052 // 1053 // The ideal graph generator translates a volatile read to the node 1054 // sequence 1055 // 1056 // LoadX[mo_acquire] 1057 // MemBarAcquire 1058 // 1059 // As a special case when using the compressed oops optimization we 1060 // may also see this variant 1061 // 1062 // LoadN[mo_acquire] 1063 // DecodeN 1064 // MemBarAcquire 1065 // 1066 // A volatile write is translated to the node sequence 1067 // 1068 // MemBarRelease 1069 // StoreX[mo_release] 1070 // MemBarVolatile 1071 // 1072 // n.b. the above node patterns are generated with a strict 1073 // 'signature' configuration of input and output dependencies (see 1074 // the predicates below for exact details). The two signatures are 1075 // unique to translated volatile reads/stores -- they will not 1076 // appear as a result of any other bytecode translation or inlining 1077 // nor as a consequence of optimizing transforms. 1078 // 1079 // We also want to catch inlined unsafe volatile gets and puts and 1080 // be able to implement them using either ldar<x>/stlr<x> or some 1081 // combination of ldr<x>/stlr<x> and dmb instructions. 1082 // 1083 // Inlined unsafe volatiles puts manifest as a minor variant of the 1084 // normal volatile put node sequence containing an extra cpuorder 1085 // membar 1086 // 1087 // MemBarRelease 1088 // MemBarCPUOrder 1089 // StoreX[mo_release] 1090 // MemBarVolatile 1091 // 1092 // n.b. as an aside, the cpuorder membar is not itself subject to 1093 // matching and translation by adlc rules. However, the rule 1094 // predicates need to detect its presence in order to correctly 1095 // select the desired adlc rules. 1096 // 1097 // Inlined unsafe volatiles gets manifest as a somewhat different 1098 // node sequence to a normal volatile get 1099 // 1100 // MemBarCPUOrder 1101 // || \\ 1102 // MemBarAcquire LoadX[mo_acquire] 1103 // || 1104 // MemBarCPUOrder 1105 // 1106 // In this case the acquire membar does not directly depend on the 1107 // load. However, we can be sure that the load is generated from an 1108 // inlined unsafe volatile get if we see it dependent on this unique 1109 // sequence of membar nodes. Similarly, given an acquire membar we 1110 // can know that it was added because of an inlined unsafe volatile 1111 // get if it is fed and feeds a cpuorder membar and if its feed 1112 // membar also feeds an acquiring load. 1113 // 1114 // So, where we can identify these volatile read and write 1115 // signatures we can choose to plant either of the above two code 1116 // sequences. For a volatile read we can simply plant a normal 1117 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1118 // also choose to inhibit translation of the MemBarAcquire and 1119 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1120 // 1121 // When we recognise a volatile store signature we can choose to 1122 // plant at a dmb ish as a translation for the MemBarRelease, a 1123 // normal str<x> and then a dmb ish for the MemBarVolatile. 1124 // Alternatively, we can inhibit translation of the MemBarRelease 1125 // and MemBarVolatile and instead plant a simple stlr<x> 1126 // instruction. 1127 // 1128 // Of course, the above only applies when we see these signature 1129 // configurations. We still want to plant dmb instructions in any 1130 // other cases where we may see a MemBarAcquire, MemBarRelease or 1131 // MemBarVolatile. For example, at the end of a constructor which 1132 // writes final/volatile fields we will see a MemBarRelease 1133 // instruction and this needs a 'dmb ish' lest we risk the 1134 // constructed object being visible without making the 1135 // final/volatile field writes visible. 1136 // 1137 // n.b. the translation rules below which rely on detection of the 1138 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1139 // If we see anything other than the signature configurations we 1140 // always just translate the loads and stors to ldr<x> and str<x> 1141 // and translate acquire, release and volatile membars to the 1142 // relevant dmb instructions. 1143 // 1144 // n.b.b as a case in point for the above comment, the current 1145 // predicates don't detect the precise signature for certain types 1146 // of volatile object stores (where the heap_base input type is not 1147 // known at compile-time to be non-NULL). In those cases the 1148 // MemBarRelease and MemBarVolatile bracket an if-then-else sequence 1149 // with a store in each branch (we need a different store depending 1150 // on whether heap_base is actually NULL). In such a case we will 1151 // just plant a dmb both before and after the branch/merge. The 1152 // predicate could (and probably should) be fixed later to also 1153 // detect this case. 1154 1155 // graph traversal helpers 1156 1157 // if node n is linked to a parent MemBarNode by an intervening 1158 // Control or Memory ProjNode return the MemBarNode otherwise return 1159 // NULL. 1160 // 1161 // n may only be a Load or a MemBar. 1162 // 1163 // The ProjNode* references c and m are used to return the relevant 1164 // nodes. 1165 1166 MemBarNode *has_parent_membar(const Node *n, ProjNode *&c, ProjNode *&m) 1167 { 1168 Node *ctl = NULL; 1169 Node *mem = NULL; 1170 Node *membar = NULL; 1171 1172 if (n->is_Load()) { 1173 ctl = n->lookup(LoadNode::Control); 1174 mem = n->lookup(LoadNode::Memory); 1175 } else if (n->is_MemBar()) { 1176 ctl = n->lookup(TypeFunc::Control); 1177 mem = n->lookup(TypeFunc::Memory); 1178 } else { 1179 return NULL; 1180 } 1181 1182 if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj()) 1183 return NULL; 1184 1185 c = ctl->as_Proj(); 1186 1187 membar = ctl->lookup(0); 1188 1189 if (!membar || !membar->is_MemBar()) 1190 return NULL; 1191 1192 m = mem->as_Proj(); 1193 1194 if (mem->lookup(0) != membar) 1195 return NULL; 1196 1197 return membar->as_MemBar(); 1198 } 1199 1200 // if n is linked to a child MemBarNode by intervening Control and 1201 // Memory ProjNodes return the MemBarNode otherwise return NULL. 1202 // 1203 // The ProjNode** arguments c and m are used to return pointers to 1204 // the relevant nodes. A null argument means don't don't return a 1205 // value. 1206 1207 MemBarNode *has_child_membar(const MemBarNode *n, ProjNode *&c, ProjNode *&m) 1208 { 1209 ProjNode *ctl = n->proj_out(TypeFunc::Control); 1210 ProjNode *mem = n->proj_out(TypeFunc::Memory); 1211 1212 // MemBar needs to have both a Ctl and Mem projection 1213 if (! ctl || ! mem) 1214 return NULL; 1215 1216 c = ctl; 1217 m = mem; 1218 1219 MemBarNode *child = NULL; 1220 Node *x; 1221 1222 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1223 x = ctl->fast_out(i); 1224 // if we see a membar we keep hold of it. we may also see a new 1225 // arena copy of the original but it will appear later 1226 if (x->is_MemBar()) { 1227 child = x->as_MemBar(); 1228 break; 1229 } 1230 } 1231 1232 if (child == NULL) 1233 return NULL; 1234 1235 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1236 x = mem->fast_out(i); 1237 // if we see a membar we keep hold of it. we may also see a new 1238 // arena copy of the original but it will appear later 1239 if (x == child) { 1240 return child; 1241 } 1242 } 1243 return NULL; 1244 } 1245 1246 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1247 1248 bool unnecessary_acquire(const Node *barrier) { 1249 // assert barrier->is_MemBar(); 1250 if (UseBarriersForVolatile) 1251 // we need to plant a dmb 1252 return false; 1253 1254 // a volatile read derived from bytecode (or also from an inlined 1255 // SHA field read via LibraryCallKit::load_field_from_object) 1256 // manifests as a LoadX[mo_acquire] followed by an acquire membar 1257 // with a bogus read dependency on it's preceding load. so in those 1258 // cases we will find the load node at the PARMS offset of the 1259 // acquire membar. n.b. there may be an intervening DecodeN node. 1260 // 1261 // a volatile load derived from an inlined unsafe field access 1262 // manifests as a cpuorder membar with Ctl and Mem projections 1263 // feeding both an acquire membar and a LoadX[mo_acquire]. The 1264 // acquire then feeds another cpuorder membar via Ctl and Mem 1265 // projections. The load has no output dependency on these trailing 1266 // membars because subsequent nodes inserted into the graph take 1267 // their control feed from the final membar cpuorder meaning they 1268 // are all ordered after the load. 1269 1270 Node *x = barrier->lookup(TypeFunc::Parms); 1271 if (x) { 1272 // we are starting from an acquire and it has a fake dependency 1273 // 1274 // need to check for 1275 // 1276 // LoadX[mo_acquire] 1277 // { |1 } 1278 // {DecodeN} 1279 // |Parms 1280 // MemBarAcquire* 1281 // 1282 // where * tags node we were passed 1283 // and |k means input k 1284 if (x->is_DecodeNarrowPtr()) 1285 x = x->in(1); 1286 1287 return (x->is_Load() && x->as_Load()->is_acquire()); 1288 } 1289 1290 // only continue if we want to try to match unsafe volatile gets 1291 if (UseBarriersForUnsafeVolatileGet) 1292 return false; 1293 1294 // need to check for 1295 // 1296 // MemBarCPUOrder 1297 // || \\ 1298 // MemBarAcquire* LoadX[mo_acquire] 1299 // || 1300 // MemBarCPUOrder 1301 // 1302 // where * tags node we were passed 1303 // and || or \\ are Ctl+Mem feeds via intermediate Proj Nodes 1304 1305 // check for a parent MemBarCPUOrder 1306 ProjNode *ctl; 1307 ProjNode *mem; 1308 MemBarNode *parent = has_parent_membar(barrier, ctl, mem); 1309 if (!parent || parent->Opcode() != Op_MemBarCPUOrder) 1310 return false; 1311 // ensure the proj nodes both feed a LoadX[mo_acquire] 1312 LoadNode *ld = NULL; 1313 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1314 x = ctl->fast_out(i); 1315 // if we see a load we keep hold of it and stop searching 1316 if (x->is_Load()) { 1317 ld = x->as_Load(); 1318 break; 1319 } 1320 } 1321 // it must be an acquiring load 1322 if (! ld || ! ld->is_acquire()) 1323 return false; 1324 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1325 x = mem->fast_out(i); 1326 // if we see the same load we drop it and stop searching 1327 if (x == ld) { 1328 ld = NULL; 1329 break; 1330 } 1331 } 1332 // we must have dropped the load 1333 if (ld) 1334 return false; 1335 // check for a child cpuorder membar 1336 MemBarNode *child = has_child_membar(barrier->as_MemBar(), ctl, mem); 1337 if (!child || child->Opcode() != Op_MemBarCPUOrder) 1338 return false; 1339 1340 return true; 1341 } 1342 1343 bool needs_acquiring_load(const Node *n) 1344 { 1345 // assert n->is_Load(); 1346 if (UseBarriersForVolatile) 1347 // we use a normal load and a dmb 1348 return false; 1349 1350 LoadNode *ld = n->as_Load(); 1351 1352 if (!ld->is_acquire()) 1353 return false; 1354 1355 // check if this load is feeding an acquire membar 1356 // 1357 // LoadX[mo_acquire] 1358 // { |1 } 1359 // {DecodeN} 1360 // |Parms 1361 // MemBarAcquire* 1362 // 1363 // where * tags node we were passed 1364 // and |k means input k 1365 1366 Node *start = ld; 1367 Node *mbacq = NULL; 1368 1369 // if we hit a DecodeNarrowPtr we reset the start node and restart 1370 // the search through the outputs 1371 restart: 1372 1373 for (DUIterator_Fast imax, i = start->fast_outs(imax); i < imax; i++) { 1374 Node *x = start->fast_out(i); 1375 if (x->is_MemBar() && x->Opcode() == Op_MemBarAcquire) { 1376 mbacq = x; 1377 } else if (!mbacq && 1378 (x->is_DecodeNarrowPtr() || 1379 (x->is_Mach() && x->Opcode() == Op_DecodeN))) { 1380 start = x; 1381 goto restart; 1382 } 1383 } 1384 1385 if (mbacq) { 1386 return true; 1387 } 1388 1389 // only continue if we want to try to match unsafe volatile gets 1390 if (UseBarriersForUnsafeVolatileGet) 1391 return false; 1392 1393 // check if Ctl and Proj feed comes from a MemBarCPUOrder 1394 // 1395 // MemBarCPUOrder 1396 // || \\ 1397 // MemBarAcquire* LoadX[mo_acquire] 1398 // || 1399 // MemBarCPUOrder 1400 1401 MemBarNode *membar; 1402 ProjNode *ctl; 1403 ProjNode *mem; 1404 1405 membar = has_parent_membar(ld, ctl, mem); 1406 1407 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1408 return false; 1409 1410 // ensure that there is a CPUOrder->Acquire->CPUOrder membar chain 1411 1412 membar = has_child_membar(membar, ctl, mem); 1413 1414 if (!membar || !membar->Opcode() == Op_MemBarAcquire) 1415 return false; 1416 1417 membar = has_child_membar(membar, ctl, mem); 1418 1419 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1420 return false; 1421 1422 return true; 1423 } 1424 1425 bool unnecessary_release(const Node *n) { 1426 // assert n->is_MemBar(); 1427 if (UseBarriersForVolatile) 1428 // we need to plant a dmb 1429 return false; 1430 1431 // ok, so we can omit this release barrier if it has been inserted 1432 // as part of a volatile store sequence 1433 // 1434 // MemBarRelease 1435 // { || } 1436 // {MemBarCPUOrder} -- optional 1437 // || \\ 1438 // || StoreX[mo_release] 1439 // | \ / 1440 // | MergeMem 1441 // | / 1442 // MemBarVolatile 1443 // 1444 // where 1445 // || and \\ represent Ctl and Mem feeds via Proj nodes 1446 // | \ and / indicate further routing of the Ctl and Mem feeds 1447 // 1448 // so we need to check that 1449 // 1450 // ia) the release membar (or its dependent cpuorder membar) feeds 1451 // control to a store node (via a Control project node) 1452 // 1453 // ii) the store is ordered release 1454 // 1455 // iii) the release membar (or its dependent cpuorder membar) feeds 1456 // control to a volatile membar (via the same Control project node) 1457 // 1458 // iv) the release membar feeds memory to a merge mem and to the 1459 // same store (both via a single Memory proj node) 1460 // 1461 // v) the store outputs to the merge mem 1462 // 1463 // vi) the merge mem outputs to the same volatile membar 1464 // 1465 // n.b. if this is an inlined unsafe node then the release membar 1466 // may feed its control and memory links via an intervening cpuorder 1467 // membar. this case can be dealt with when we check the release 1468 // membar projections. if they both feed a single cpuorder membar 1469 // node continue to make the same checks as above but with the 1470 // cpuorder membar substituted for the release membar. if they don't 1471 // both feed a cpuorder membar then the check fails. 1472 // 1473 // n.b.b. for an inlined unsafe store of an object in the case where 1474 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1475 // an embedded if then else where we expect the store. this is 1476 // needed to do the right type of store depending on whether 1477 // heap_base is NULL. We could check for that but for now we can 1478 // just take the hit of on inserting a redundant dmb for this 1479 // redundant volatile membar 1480 1481 MemBarNode *barrier = n->as_MemBar(); 1482 ProjNode *ctl; 1483 ProjNode *mem; 1484 // check for an intervening cpuorder membar 1485 MemBarNode *b = has_child_membar(barrier, ctl, mem); 1486 if (b && b->Opcode() == Op_MemBarCPUOrder) { 1487 // ok, so start form the dependent cpuorder barrier 1488 barrier = b; 1489 } 1490 // check the ctl and mem flow 1491 ctl = barrier->proj_out(TypeFunc::Control); 1492 mem = barrier->proj_out(TypeFunc::Memory); 1493 1494 // the barrier needs to have both a Ctl and Mem projection 1495 if (! ctl || ! mem) 1496 return false; 1497 1498 Node *x = NULL; 1499 Node *mbvol = NULL; 1500 StoreNode * st = NULL; 1501 1502 // For a normal volatile write the Ctl ProjNode should have output 1503 // to a MemBarVolatile and a Store marked as releasing 1504 // 1505 // n.b. for an inlined unsafe store of an object in the case where 1506 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1507 // an embedded if then else where we expect the store. this is 1508 // needed to do the right type of store depending on whether 1509 // heap_base is NULL. We could check for that case too but for now 1510 // we can just take the hit of inserting a dmb and a non-volatile 1511 // store to implement the volatile store 1512 1513 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1514 x = ctl->fast_out(i); 1515 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1516 if (mbvol) { 1517 return false; 1518 } 1519 mbvol = x; 1520 } else if (x->is_Store()) { 1521 st = x->as_Store(); 1522 if (! st->is_release()) { 1523 return false; 1524 } 1525 } else if (!x->is_Mach()) { 1526 // we may see mach nodes added during matching but nothing else 1527 return false; 1528 } 1529 } 1530 1531 if (!mbvol || !st) 1532 return false; 1533 1534 // the Mem ProjNode should output to a MergeMem and the same Store 1535 Node *mm = NULL; 1536 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1537 x = mem->fast_out(i); 1538 if (!mm && x->is_MergeMem()) { 1539 mm = x; 1540 } else if (x != st && !x->is_Mach()) { 1541 // we may see mach nodes added during matching but nothing else 1542 return false; 1543 } 1544 } 1545 1546 if (!mm) 1547 return false; 1548 1549 // the MergeMem should output to the MemBarVolatile 1550 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1551 x = mm->fast_out(i); 1552 if (x != mbvol && !x->is_Mach()) { 1553 // we may see mach nodes added during matching but nothing else 1554 return false; 1555 } 1556 } 1557 1558 return true; 1559 } 1560 1561 bool unnecessary_volatile(const Node *n) { 1562 // assert n->is_MemBar(); 1563 if (UseBarriersForVolatile) 1564 // we need to plant a dmb 1565 return false; 1566 1567 // ok, so we can omit this volatile barrier if it has been inserted 1568 // as part of a volatile store sequence 1569 // 1570 // MemBarRelease 1571 // { || } 1572 // {MemBarCPUOrder} -- optional 1573 // || \\ 1574 // || StoreX[mo_release] 1575 // | \ / 1576 // | MergeMem 1577 // | / 1578 // MemBarVolatile 1579 // 1580 // where 1581 // || and \\ represent Ctl and Mem feeds via Proj nodes 1582 // | \ and / indicate further routing of the Ctl and Mem feeds 1583 // 1584 // we need to check that 1585 // 1586 // i) the volatile membar gets its control feed from a release 1587 // membar (or its dependent cpuorder membar) via a Control project 1588 // node 1589 // 1590 // ii) the release membar (or its dependent cpuorder membar) also 1591 // feeds control to a store node via the same proj node 1592 // 1593 // iii) the store is ordered release 1594 // 1595 // iv) the release membar (or its dependent cpuorder membar) feeds 1596 // memory to a merge mem and to the same store (both via a single 1597 // Memory proj node) 1598 // 1599 // v) the store outputs to the merge mem 1600 // 1601 // vi) the merge mem outputs to the volatile membar 1602 // 1603 // n.b. for an inlined unsafe store of an object in the case where 1604 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1605 // an embedded if then else where we expect the store. this is 1606 // needed to do the right type of store depending on whether 1607 // heap_base is NULL. We could check for that but for now we can 1608 // just take the hit of on inserting a redundant dmb for this 1609 // redundant volatile membar 1610 1611 MemBarNode *mbvol = n->as_MemBar(); 1612 Node *x = n->lookup(TypeFunc::Control); 1613 1614 if (! x || !x->is_Proj()) 1615 return false; 1616 1617 ProjNode *proj = x->as_Proj(); 1618 1619 x = proj->lookup(0); 1620 1621 if (!x || !x->is_MemBar()) 1622 return false; 1623 1624 MemBarNode *barrier = x->as_MemBar(); 1625 1626 // if the barrier is a release membar we have what we want. if it is 1627 // a cpuorder membar then we need to ensure that it is fed by a 1628 // release membar in which case we proceed to check the graph below 1629 // this cpuorder membar as the feed 1630 1631 if (x->Opcode() != Op_MemBarRelease) { 1632 if (x->Opcode() != Op_MemBarCPUOrder) 1633 return false; 1634 ProjNode *ctl; 1635 ProjNode *mem; 1636 MemBarNode *b = has_parent_membar(x, ctl, mem); 1637 if (!b || !b->Opcode() == Op_MemBarRelease) 1638 return false; 1639 } 1640 1641 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1642 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1643 1644 // barrier needs to have both a Ctl and Mem projection 1645 // and we need to have reached it via the Ctl projection 1646 if (! ctl || ! mem || ctl != proj) 1647 return false; 1648 1649 StoreNode * st = NULL; 1650 1651 // The Ctl ProjNode should have output to a MemBarVolatile and 1652 // a Store marked as releasing 1653 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1654 x = ctl->fast_out(i); 1655 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1656 if (x != mbvol) { 1657 return false; 1658 } 1659 } else if (x->is_Store()) { 1660 st = x->as_Store(); 1661 if (! st->is_release()) { 1662 return false; 1663 } 1664 } else if (!x->is_Mach()){ 1665 // we may see mach nodes added during matching but nothing else 1666 return false; 1667 } 1668 } 1669 1670 if (!st) 1671 return false; 1672 1673 // the Mem ProjNode should output to a MergeMem and the same Store 1674 Node *mm = NULL; 1675 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1676 x = mem->fast_out(i); 1677 if (!mm && x->is_MergeMem()) { 1678 mm = x; 1679 } else if (x != st && !x->is_Mach()) { 1680 // we may see mach nodes added during matching but nothing else 1681 return false; 1682 } 1683 } 1684 1685 if (!mm) 1686 return false; 1687 1688 // the MergeMem should output to the MemBarVolatile 1689 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1690 x = mm->fast_out(i); 1691 if (x != mbvol && !x->is_Mach()) { 1692 // we may see mach nodes added during matching but nothing else 1693 return false; 1694 } 1695 } 1696 1697 return true; 1698 } 1699 1700 1701 1702 bool needs_releasing_store(const Node *n) 1703 { 1704 // assert n->is_Store(); 1705 if (UseBarriersForVolatile) 1706 // we use a normal store and dmb combination 1707 return false; 1708 1709 StoreNode *st = n->as_Store(); 1710 1711 if (!st->is_release()) 1712 return false; 1713 1714 // check if this store is bracketed by a release (or its dependent 1715 // cpuorder membar) and a volatile membar 1716 // 1717 // MemBarRelease 1718 // { || } 1719 // {MemBarCPUOrder} -- optional 1720 // || \\ 1721 // || StoreX[mo_release] 1722 // | \ / 1723 // | MergeMem 1724 // | / 1725 // MemBarVolatile 1726 // 1727 // where 1728 // || and \\ represent Ctl and Mem feeds via Proj nodes 1729 // | \ and / indicate further routing of the Ctl and Mem feeds 1730 // 1731 1732 1733 Node *x = st->lookup(TypeFunc::Control); 1734 1735 if (! x || !x->is_Proj()) 1736 return false; 1737 1738 ProjNode *proj = x->as_Proj(); 1739 1740 x = proj->lookup(0); 1741 1742 if (!x || !x->is_MemBar()) 1743 return false; 1744 1745 MemBarNode *barrier = x->as_MemBar(); 1746 1747 // if the barrier is a release membar we have what we want. if it is 1748 // a cpuorder membar then we need to ensure that it is fed by a 1749 // release membar in which case we proceed to check the graph below 1750 // this cpuorder membar as the feed 1751 1752 if (x->Opcode() != Op_MemBarRelease) { 1753 if (x->Opcode() != Op_MemBarCPUOrder) 1754 return false; 1755 Node *ctl = x->lookup(TypeFunc::Control); 1756 Node *mem = x->lookup(TypeFunc::Memory); 1757 if (!ctl || !ctl->is_Proj() || !mem || !mem->is_Proj()) 1758 return false; 1759 x = ctl->lookup(0); 1760 if (!x || !x->is_MemBar() || !x->Opcode() == Op_MemBarRelease) 1761 return false; 1762 Node *y = mem->lookup(0); 1763 if (!y || y != x) 1764 return false; 1765 } 1766 1767 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1768 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1769 1770 // MemBarRelease needs to have both a Ctl and Mem projection 1771 // and we need to have reached it via the Ctl projection 1772 if (! ctl || ! mem || ctl != proj) 1773 return false; 1774 1775 MemBarNode *mbvol = NULL; 1776 1777 // The Ctl ProjNode should have output to a MemBarVolatile and 1778 // a Store marked as releasing 1779 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1780 x = ctl->fast_out(i); 1781 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1782 mbvol = x->as_MemBar(); 1783 } else if (x->is_Store()) { 1784 if (x != st) { 1785 return false; 1786 } 1787 } else if (!x->is_Mach()){ 1788 return false; 1789 } 1790 } 1791 1792 if (!mbvol) 1793 return false; 1794 1795 // the Mem ProjNode should output to a MergeMem and the same Store 1796 Node *mm = NULL; 1797 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1798 x = mem->fast_out(i); 1799 if (!mm && x->is_MergeMem()) { 1800 mm = x; 1801 } else if (x != st && !x->is_Mach()) { 1802 return false; 1803 } 1804 } 1805 1806 if (!mm) 1807 return false; 1808 1809 // the MergeMem should output to the MemBarVolatile 1810 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1811 x = mm->fast_out(i); 1812 if (x != mbvol && !x->is_Mach()) { 1813 return false; 1814 } 1815 } 1816 1817 return true; 1818 } 1819 1820 1821 1822 #define __ _masm. 1823 1824 // advance declarations for helper functions to convert register 1825 // indices to register objects 1826 1827 // the ad file has to provide implementations of certain methods 1828 // expected by the generic code 1829 // 1830 // REQUIRED FUNCTIONALITY 1831 1832 //============================================================================= 1833 1834 // !!!!! Special hack to get all types of calls to specify the byte offset 1835 // from the start of the call to the point where the return address 1836 // will point. 1837 1838 int MachCallStaticJavaNode::ret_addr_offset() 1839 { 1840 // call should be a simple bl 1841 int off = 4; 1842 return off; 1843 } 1844 1845 int MachCallDynamicJavaNode::ret_addr_offset() 1846 { 1847 return 16; // movz, movk, movk, bl 1848 } 1849 1850 int MachCallRuntimeNode::ret_addr_offset() { 1851 // for generated stubs the call will be 1852 // far_call(addr) 1853 // for real runtime callouts it will be six instructions 1854 // see aarch64_enc_java_to_runtime 1855 // adr(rscratch2, retaddr) 1856 // lea(rscratch1, RuntimeAddress(addr) 1857 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1858 // blrt rscratch1 1859 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1860 if (cb) { 1861 return MacroAssembler::far_branch_size(); 1862 } else { 1863 return 6 * NativeInstruction::instruction_size; 1864 } 1865 } 1866 1867 // Indicate if the safepoint node needs the polling page as an input 1868 1869 // the shared code plants the oop data at the start of the generated 1870 // code for the safepoint node and that needs ot be at the load 1871 // instruction itself. so we cannot plant a mov of the safepoint poll 1872 // address followed by a load. setting this to true means the mov is 1873 // scheduled as a prior instruction. that's better for scheduling 1874 // anyway. 1875 1876 bool SafePointNode::needs_polling_address_input() 1877 { 1878 return true; 1879 } 1880 1881 //============================================================================= 1882 1883 #ifndef PRODUCT 1884 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1885 st->print("BREAKPOINT"); 1886 } 1887 #endif 1888 1889 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1890 MacroAssembler _masm(&cbuf); 1891 __ brk(0); 1892 } 1893 1894 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1895 return MachNode::size(ra_); 1896 } 1897 1898 //============================================================================= 1899 1900 #ifndef PRODUCT 1901 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1902 st->print("nop \t# %d bytes pad for loops and calls", _count); 1903 } 1904 #endif 1905 1906 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1907 MacroAssembler _masm(&cbuf); 1908 for (int i = 0; i < _count; i++) { 1909 __ nop(); 1910 } 1911 } 1912 1913 uint MachNopNode::size(PhaseRegAlloc*) const { 1914 return _count * NativeInstruction::instruction_size; 1915 } 1916 1917 //============================================================================= 1918 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1919 1920 int Compile::ConstantTable::calculate_table_base_offset() const { 1921 return 0; // absolute addressing, no offset 1922 } 1923 1924 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1925 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1926 ShouldNotReachHere(); 1927 } 1928 1929 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1930 // Empty encoding 1931 } 1932 1933 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1934 return 0; 1935 } 1936 1937 #ifndef PRODUCT 1938 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1939 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1940 } 1941 #endif 1942 1943 #ifndef PRODUCT 1944 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1945 Compile* C = ra_->C; 1946 1947 int framesize = C->frame_slots() << LogBytesPerInt; 1948 1949 if (C->need_stack_bang(framesize)) 1950 st->print("# stack bang size=%d\n\t", framesize); 1951 1952 if (framesize < ((1 << 9) + 2 * wordSize)) { 1953 st->print("sub sp, sp, #%d\n\t", framesize); 1954 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1955 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1956 } else { 1957 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1958 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1959 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1960 st->print("sub sp, sp, rscratch1"); 1961 } 1962 } 1963 #endif 1964 1965 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1966 Compile* C = ra_->C; 1967 MacroAssembler _masm(&cbuf); 1968 1969 // n.b. frame size includes space for return pc and rfp 1970 const long framesize = C->frame_size_in_bytes(); 1971 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1972 1973 // insert a nop at the start of the prolog so we can patch in a 1974 // branch if we need to invalidate the method later 1975 __ nop(); 1976 1977 int bangsize = C->bang_size_in_bytes(); 1978 if (C->need_stack_bang(bangsize) && UseStackBanging) 1979 __ generate_stack_overflow_check(bangsize); 1980 1981 __ build_frame(framesize); 1982 1983 if (NotifySimulator) { 1984 __ notify(Assembler::method_entry); 1985 } 1986 1987 if (VerifyStackAtCalls) { 1988 Unimplemented(); 1989 } 1990 1991 C->set_frame_complete(cbuf.insts_size()); 1992 1993 if (C->has_mach_constant_base_node()) { 1994 // NOTE: We set the table base offset here because users might be 1995 // emitted before MachConstantBaseNode. 1996 Compile::ConstantTable& constant_table = C->constant_table(); 1997 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1998 } 1999 } 2000 2001 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 2002 { 2003 return MachNode::size(ra_); // too many variables; just compute it 2004 // the hard way 2005 } 2006 2007 int MachPrologNode::reloc() const 2008 { 2009 return 0; 2010 } 2011 2012 //============================================================================= 2013 2014 #ifndef PRODUCT 2015 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2016 Compile* C = ra_->C; 2017 int framesize = C->frame_slots() << LogBytesPerInt; 2018 2019 st->print("# pop frame %d\n\t",framesize); 2020 2021 if (framesize == 0) { 2022 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 2023 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 2024 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 2025 st->print("add sp, sp, #%d\n\t", framesize); 2026 } else { 2027 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 2028 st->print("add sp, sp, rscratch1\n\t"); 2029 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 2030 } 2031 2032 if (do_polling() && C->is_method_compilation()) { 2033 st->print("# touch polling page\n\t"); 2034 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 2035 st->print("ldr zr, [rscratch1]"); 2036 } 2037 } 2038 #endif 2039 2040 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2041 Compile* C = ra_->C; 2042 MacroAssembler _masm(&cbuf); 2043 int framesize = C->frame_slots() << LogBytesPerInt; 2044 2045 __ remove_frame(framesize); 2046 2047 if (NotifySimulator) { 2048 __ notify(Assembler::method_reentry); 2049 } 2050 2051 if (do_polling() && C->is_method_compilation()) { 2052 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 2053 } 2054 } 2055 2056 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 2057 // Variable size. Determine dynamically. 2058 return MachNode::size(ra_); 2059 } 2060 2061 int MachEpilogNode::reloc() const { 2062 // Return number of relocatable values contained in this instruction. 2063 return 1; // 1 for polling page. 2064 } 2065 2066 const Pipeline * MachEpilogNode::pipeline() const { 2067 return MachNode::pipeline_class(); 2068 } 2069 2070 // This method seems to be obsolete. It is declared in machnode.hpp 2071 // and defined in all *.ad files, but it is never called. Should we 2072 // get rid of it? 2073 int MachEpilogNode::safepoint_offset() const { 2074 assert(do_polling(), "no return for this epilog node"); 2075 return 4; 2076 } 2077 2078 //============================================================================= 2079 2080 // Figure out which register class each belongs in: rc_int, rc_float or 2081 // rc_stack. 2082 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 2083 2084 static enum RC rc_class(OptoReg::Name reg) { 2085 2086 if (reg == OptoReg::Bad) { 2087 return rc_bad; 2088 } 2089 2090 // we have 30 int registers * 2 halves 2091 // (rscratch1 and rscratch2 are omitted) 2092 2093 if (reg < 60) { 2094 return rc_int; 2095 } 2096 2097 // we have 32 float register * 2 halves 2098 if (reg < 60 + 128) { 2099 return rc_float; 2100 } 2101 2102 // Between float regs & stack is the flags regs. 2103 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 2104 2105 return rc_stack; 2106 } 2107 2108 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 2109 Compile* C = ra_->C; 2110 2111 // Get registers to move. 2112 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 2113 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 2114 OptoReg::Name dst_hi = ra_->get_reg_second(this); 2115 OptoReg::Name dst_lo = ra_->get_reg_first(this); 2116 2117 enum RC src_hi_rc = rc_class(src_hi); 2118 enum RC src_lo_rc = rc_class(src_lo); 2119 enum RC dst_hi_rc = rc_class(dst_hi); 2120 enum RC dst_lo_rc = rc_class(dst_lo); 2121 2122 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 2123 2124 if (src_hi != OptoReg::Bad) { 2125 assert((src_lo&1)==0 && src_lo+1==src_hi && 2126 (dst_lo&1)==0 && dst_lo+1==dst_hi, 2127 "expected aligned-adjacent pairs"); 2128 } 2129 2130 if (src_lo == dst_lo && src_hi == dst_hi) { 2131 return 0; // Self copy, no move. 2132 } 2133 2134 if (bottom_type()->isa_vect() != NULL) { 2135 uint len = 4; 2136 if (cbuf) { 2137 MacroAssembler _masm(cbuf); 2138 uint ireg = ideal_reg(); 2139 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 2140 assert(ireg == Op_VecX, "sanity"); 2141 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 2142 // stack->stack 2143 int src_offset = ra_->reg2offset(src_lo); 2144 int dst_offset = ra_->reg2offset(dst_lo); 2145 assert((src_offset & 7) && (dst_offset & 7), "unaligned stack offset"); 2146 len = 8; 2147 if (src_offset < 512) { 2148 __ ldp(rscratch1, rscratch2, Address(sp, src_offset)); 2149 } else { 2150 __ ldr(rscratch1, Address(sp, src_offset)); 2151 __ ldr(rscratch2, Address(sp, src_offset+4)); 2152 len += 4; 2153 } 2154 if (dst_offset < 512) { 2155 __ stp(rscratch1, rscratch2, Address(sp, dst_offset)); 2156 } else { 2157 __ str(rscratch1, Address(sp, dst_offset)); 2158 __ str(rscratch2, Address(sp, dst_offset+4)); 2159 len += 4; 2160 } 2161 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2162 __ orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), __ T16B, 2163 as_FloatRegister(Matcher::_regEncode[src_lo]), 2164 as_FloatRegister(Matcher::_regEncode[src_lo])); 2165 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2166 __ str(as_FloatRegister(Matcher::_regEncode[src_lo]), __ Q, 2167 Address(sp, ra_->reg2offset(dst_lo))); 2168 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 2169 __ ldr(as_FloatRegister(Matcher::_regEncode[dst_lo]), __ Q, 2170 Address(sp, ra_->reg2offset(src_lo))); 2171 } else { 2172 ShouldNotReachHere(); 2173 } 2174 } else if (st) { 2175 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 2176 // stack->stack 2177 int src_offset = ra_->reg2offset(src_lo); 2178 int dst_offset = ra_->reg2offset(dst_lo); 2179 if (src_offset < 512) { 2180 st->print("ldp rscratch1, rscratch2, [sp, #%d]", src_offset); 2181 } else { 2182 st->print("ldr rscratch1, [sp, #%d]", src_offset); 2183 st->print("\nldr rscratch2, [sp, #%d]", src_offset+4); 2184 } 2185 if (dst_offset < 512) { 2186 st->print("\nstp rscratch1, rscratch2, [sp, #%d]", dst_offset); 2187 } else { 2188 st->print("\nstr rscratch1, [sp, #%d]", dst_offset); 2189 st->print("\nstr rscratch2, [sp, #%d]", dst_offset+4); 2190 } 2191 st->print("\t# vector spill, stack to stack"); 2192 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2193 st->print("mov %s, %s\t# vector spill, reg to reg", 2194 Matcher::regName[dst_lo], Matcher::regName[src_lo]); 2195 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2196 st->print("str %s, [sp, #%d]\t# vector spill, reg to stack", 2197 Matcher::regName[src_lo], ra_->reg2offset(dst_lo)); 2198 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 2199 st->print("ldr %s, [sp, #%d]\t# vector spill, stack to reg", 2200 Matcher::regName[dst_lo], ra_->reg2offset(src_lo)); 2201 } 2202 } 2203 return len; 2204 } 2205 2206 switch (src_lo_rc) { 2207 case rc_int: 2208 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 2209 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2210 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2211 // 64 bit 2212 if (cbuf) { 2213 MacroAssembler _masm(cbuf); 2214 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 2215 as_Register(Matcher::_regEncode[src_lo])); 2216 } else if (st) { 2217 st->print("mov %s, %s\t# shuffle", 2218 Matcher::regName[dst_lo], 2219 Matcher::regName[src_lo]); 2220 } 2221 } else { 2222 // 32 bit 2223 if (cbuf) { 2224 MacroAssembler _masm(cbuf); 2225 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 2226 as_Register(Matcher::_regEncode[src_lo])); 2227 } else if (st) { 2228 st->print("movw %s, %s\t# shuffle", 2229 Matcher::regName[dst_lo], 2230 Matcher::regName[src_lo]); 2231 } 2232 } 2233 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 2234 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2235 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2236 // 64 bit 2237 if (cbuf) { 2238 MacroAssembler _masm(cbuf); 2239 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2240 as_Register(Matcher::_regEncode[src_lo])); 2241 } else if (st) { 2242 st->print("fmovd %s, %s\t# shuffle", 2243 Matcher::regName[dst_lo], 2244 Matcher::regName[src_lo]); 2245 } 2246 } else { 2247 // 32 bit 2248 if (cbuf) { 2249 MacroAssembler _masm(cbuf); 2250 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2251 as_Register(Matcher::_regEncode[src_lo])); 2252 } else if (st) { 2253 st->print("fmovs %s, %s\t# shuffle", 2254 Matcher::regName[dst_lo], 2255 Matcher::regName[src_lo]); 2256 } 2257 } 2258 } else { // gpr --> stack spill 2259 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2260 int dst_offset = ra_->reg2offset(dst_lo); 2261 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2262 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2263 // 64 bit 2264 if (cbuf) { 2265 MacroAssembler _masm(cbuf); 2266 __ str(as_Register(Matcher::_regEncode[src_lo]), 2267 Address(sp, dst_offset)); 2268 } else if (st) { 2269 st->print("str %s, [sp, #%d]\t# spill", 2270 Matcher::regName[src_lo], 2271 dst_offset); 2272 } 2273 } else { 2274 // 32 bit 2275 if (cbuf) { 2276 MacroAssembler _masm(cbuf); 2277 __ strw(as_Register(Matcher::_regEncode[src_lo]), 2278 Address(sp, dst_offset)); 2279 } else if (st) { 2280 st->print("strw %s, [sp, #%d]\t# spill", 2281 Matcher::regName[src_lo], 2282 dst_offset); 2283 } 2284 } 2285 } 2286 return 4; 2287 case rc_float: 2288 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2289 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2290 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2291 // 64 bit 2292 if (cbuf) { 2293 MacroAssembler _masm(cbuf); 2294 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2295 as_FloatRegister(Matcher::_regEncode[src_lo])); 2296 } else if (st) { 2297 st->print("fmovd %s, %s\t# shuffle", 2298 Matcher::regName[dst_lo], 2299 Matcher::regName[src_lo]); 2300 } 2301 } else { 2302 // 32 bit 2303 if (cbuf) { 2304 MacroAssembler _masm(cbuf); 2305 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2306 as_FloatRegister(Matcher::_regEncode[src_lo])); 2307 } else if (st) { 2308 st->print("fmovs %s, %s\t# shuffle", 2309 Matcher::regName[dst_lo], 2310 Matcher::regName[src_lo]); 2311 } 2312 } 2313 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2314 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2315 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2316 // 64 bit 2317 if (cbuf) { 2318 MacroAssembler _masm(cbuf); 2319 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2320 as_FloatRegister(Matcher::_regEncode[src_lo])); 2321 } else if (st) { 2322 st->print("fmovd %s, %s\t# shuffle", 2323 Matcher::regName[dst_lo], 2324 Matcher::regName[src_lo]); 2325 } 2326 } else { 2327 // 32 bit 2328 if (cbuf) { 2329 MacroAssembler _masm(cbuf); 2330 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2331 as_FloatRegister(Matcher::_regEncode[src_lo])); 2332 } else if (st) { 2333 st->print("fmovs %s, %s\t# shuffle", 2334 Matcher::regName[dst_lo], 2335 Matcher::regName[src_lo]); 2336 } 2337 } 2338 } else { // fpr --> stack spill 2339 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2340 int dst_offset = ra_->reg2offset(dst_lo); 2341 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2342 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2343 // 64 bit 2344 if (cbuf) { 2345 MacroAssembler _masm(cbuf); 2346 __ strd(as_FloatRegister(Matcher::_regEncode[src_lo]), 2347 Address(sp, dst_offset)); 2348 } else if (st) { 2349 st->print("strd %s, [sp, #%d]\t# spill", 2350 Matcher::regName[src_lo], 2351 dst_offset); 2352 } 2353 } else { 2354 // 32 bit 2355 if (cbuf) { 2356 MacroAssembler _masm(cbuf); 2357 __ strs(as_FloatRegister(Matcher::_regEncode[src_lo]), 2358 Address(sp, dst_offset)); 2359 } else if (st) { 2360 st->print("strs %s, [sp, #%d]\t# spill", 2361 Matcher::regName[src_lo], 2362 dst_offset); 2363 } 2364 } 2365 } 2366 return 4; 2367 case rc_stack: 2368 int src_offset = ra_->reg2offset(src_lo); 2369 if (dst_lo_rc == rc_int) { // stack --> gpr load 2370 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2371 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2372 // 64 bit 2373 if (cbuf) { 2374 MacroAssembler _masm(cbuf); 2375 __ ldr(as_Register(Matcher::_regEncode[dst_lo]), 2376 Address(sp, src_offset)); 2377 } else if (st) { 2378 st->print("ldr %s, [sp, %d]\t# restore", 2379 Matcher::regName[dst_lo], 2380 src_offset); 2381 } 2382 } else { 2383 // 32 bit 2384 if (cbuf) { 2385 MacroAssembler _masm(cbuf); 2386 __ ldrw(as_Register(Matcher::_regEncode[dst_lo]), 2387 Address(sp, src_offset)); 2388 } else if (st) { 2389 st->print("ldr %s, [sp, %d]\t# restore", 2390 Matcher::regName[dst_lo], 2391 src_offset); 2392 } 2393 } 2394 return 4; 2395 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2396 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2397 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2398 // 64 bit 2399 if (cbuf) { 2400 MacroAssembler _masm(cbuf); 2401 __ ldrd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2402 Address(sp, src_offset)); 2403 } else if (st) { 2404 st->print("ldrd %s, [sp, %d]\t# restore", 2405 Matcher::regName[dst_lo], 2406 src_offset); 2407 } 2408 } else { 2409 // 32 bit 2410 if (cbuf) { 2411 MacroAssembler _masm(cbuf); 2412 __ ldrs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2413 Address(sp, src_offset)); 2414 } else if (st) { 2415 st->print("ldrs %s, [sp, %d]\t# restore", 2416 Matcher::regName[dst_lo], 2417 src_offset); 2418 } 2419 } 2420 return 4; 2421 } else { // stack --> stack copy 2422 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2423 int dst_offset = ra_->reg2offset(dst_lo); 2424 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2425 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2426 // 64 bit 2427 if (cbuf) { 2428 MacroAssembler _masm(cbuf); 2429 __ ldr(rscratch1, Address(sp, src_offset)); 2430 __ str(rscratch1, Address(sp, dst_offset)); 2431 } else if (st) { 2432 st->print("ldr rscratch1, [sp, %d]\t# mem-mem spill", 2433 src_offset); 2434 st->print("\n\t"); 2435 st->print("str rscratch1, [sp, %d]", 2436 dst_offset); 2437 } 2438 } else { 2439 // 32 bit 2440 if (cbuf) { 2441 MacroAssembler _masm(cbuf); 2442 __ ldrw(rscratch1, Address(sp, src_offset)); 2443 __ strw(rscratch1, Address(sp, dst_offset)); 2444 } else if (st) { 2445 st->print("ldrw rscratch1, [sp, %d]\t# mem-mem spill", 2446 src_offset); 2447 st->print("\n\t"); 2448 st->print("strw rscratch1, [sp, %d]", 2449 dst_offset); 2450 } 2451 } 2452 return 8; 2453 } 2454 } 2455 2456 assert(false," bad rc_class for spill "); 2457 Unimplemented(); 2458 return 0; 2459 2460 } 2461 2462 #ifndef PRODUCT 2463 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2464 if (!ra_) 2465 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2466 else 2467 implementation(NULL, ra_, false, st); 2468 } 2469 #endif 2470 2471 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2472 implementation(&cbuf, ra_, false, NULL); 2473 } 2474 2475 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2476 return implementation(NULL, ra_, true, NULL); 2477 } 2478 2479 //============================================================================= 2480 2481 #ifndef PRODUCT 2482 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2483 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2484 int reg = ra_->get_reg_first(this); 2485 st->print("add %s, rsp, #%d]\t# box lock", 2486 Matcher::regName[reg], offset); 2487 } 2488 #endif 2489 2490 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2491 MacroAssembler _masm(&cbuf); 2492 2493 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2494 int reg = ra_->get_encode(this); 2495 2496 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2497 __ add(as_Register(reg), sp, offset); 2498 } else { 2499 ShouldNotReachHere(); 2500 } 2501 } 2502 2503 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2504 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2505 return 4; 2506 } 2507 2508 //============================================================================= 2509 2510 #ifndef PRODUCT 2511 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2512 { 2513 st->print_cr("# MachUEPNode"); 2514 if (UseCompressedClassPointers) { 2515 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2516 if (Universe::narrow_klass_shift() != 0) { 2517 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2518 } 2519 } else { 2520 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2521 } 2522 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2523 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2524 } 2525 #endif 2526 2527 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2528 { 2529 // This is the unverified entry point. 2530 MacroAssembler _masm(&cbuf); 2531 2532 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2533 Label skip; 2534 // TODO 2535 // can we avoid this skip and still use a reloc? 2536 __ br(Assembler::EQ, skip); 2537 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2538 __ bind(skip); 2539 } 2540 2541 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2542 { 2543 return MachNode::size(ra_); 2544 } 2545 2546 // REQUIRED EMIT CODE 2547 2548 //============================================================================= 2549 2550 // Emit exception handler code. 2551 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2552 { 2553 // mov rscratch1 #exception_blob_entry_point 2554 // br rscratch1 2555 // Note that the code buffer's insts_mark is always relative to insts. 2556 // That's why we must use the macroassembler to generate a handler. 2557 MacroAssembler _masm(&cbuf); 2558 address base = 2559 __ start_a_stub(size_exception_handler()); 2560 if (base == NULL) return 0; // CodeBuffer::expand failed 2561 int offset = __ offset(); 2562 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2563 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2564 __ end_a_stub(); 2565 return offset; 2566 } 2567 2568 // Emit deopt handler code. 2569 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2570 { 2571 // Note that the code buffer's insts_mark is always relative to insts. 2572 // That's why we must use the macroassembler to generate a handler. 2573 MacroAssembler _masm(&cbuf); 2574 address base = 2575 __ start_a_stub(size_deopt_handler()); 2576 if (base == NULL) return 0; // CodeBuffer::expand failed 2577 int offset = __ offset(); 2578 2579 __ adr(lr, __ pc()); 2580 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2581 2582 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2583 __ end_a_stub(); 2584 return offset; 2585 } 2586 2587 // REQUIRED MATCHER CODE 2588 2589 //============================================================================= 2590 2591 const bool Matcher::match_rule_supported(int opcode) { 2592 2593 // TODO 2594 // identify extra cases that we might want to provide match rules for 2595 // e.g. Op_StrEquals and other intrinsics 2596 if (!has_match_rule(opcode)) { 2597 return false; 2598 } 2599 2600 return true; // Per default match rules are supported. 2601 } 2602 2603 int Matcher::regnum_to_fpu_offset(int regnum) 2604 { 2605 Unimplemented(); 2606 return 0; 2607 } 2608 2609 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) 2610 { 2611 Unimplemented(); 2612 return false; 2613 } 2614 2615 const bool Matcher::isSimpleConstant64(jlong value) { 2616 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2617 // Probably always true, even if a temp register is required. 2618 return true; 2619 } 2620 2621 // true just means we have fast l2f conversion 2622 const bool Matcher::convL2FSupported(void) { 2623 return true; 2624 } 2625 2626 // Vector width in bytes. 2627 const int Matcher::vector_width_in_bytes(BasicType bt) { 2628 int size = MIN2(16,(int)MaxVectorSize); 2629 // Minimum 2 values in vector 2630 if (size < 2*type2aelembytes(bt)) size = 0; 2631 // But never < 4 2632 if (size < 4) size = 0; 2633 return size; 2634 } 2635 2636 // Limits on vector size (number of elements) loaded into vector. 2637 const int Matcher::max_vector_size(const BasicType bt) { 2638 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2639 } 2640 const int Matcher::min_vector_size(const BasicType bt) { 2641 //return (type2aelembytes(bt) == 1) ? 4 : 2; 2642 // For the moment, only support 1 vector size, 128 bits 2643 return max_vector_size(bt); 2644 } 2645 2646 // Vector ideal reg. 2647 const int Matcher::vector_ideal_reg(int len) { 2648 return Op_VecX; 2649 } 2650 2651 // Only lowest bits of xmm reg are used for vector shift count. 2652 const int Matcher::vector_shift_count_ideal_reg(int size) { 2653 return Op_VecX; 2654 } 2655 2656 // AES support not yet implemented 2657 const bool Matcher::pass_original_key_for_aes() { 2658 return false; 2659 } 2660 2661 // x86 supports misaligned vectors store/load. 2662 const bool Matcher::misaligned_vectors_ok() { 2663 // TODO fixme 2664 // return !AlignVector; // can be changed by flag 2665 return false; 2666 } 2667 2668 // false => size gets scaled to BytesPerLong, ok. 2669 const bool Matcher::init_array_count_is_in_bytes = false; 2670 2671 // Threshold size for cleararray. 2672 const int Matcher::init_array_short_size = 18 * BytesPerLong; 2673 2674 // Use conditional move (CMOVL) 2675 const int Matcher::long_cmove_cost() { 2676 // long cmoves are no more expensive than int cmoves 2677 return 0; 2678 } 2679 2680 const int Matcher::float_cmove_cost() { 2681 // float cmoves are no more expensive than int cmoves 2682 return 0; 2683 } 2684 2685 // Does the CPU require late expand (see block.cpp for description of late expand)? 2686 const bool Matcher::require_postalloc_expand = false; 2687 2688 // Should the Matcher clone shifts on addressing modes, expecting them 2689 // to be subsumed into complex addressing expressions or compute them 2690 // into registers? True for Intel but false for most RISCs 2691 const bool Matcher::clone_shift_expressions = false; 2692 2693 // Do we need to mask the count passed to shift instructions or does 2694 // the cpu only look at the lower 5/6 bits anyway? 2695 const bool Matcher::need_masked_shift_count = false; 2696 2697 // This affects two different things: 2698 // - how Decode nodes are matched 2699 // - how ImplicitNullCheck opportunities are recognized 2700 // If true, the matcher will try to remove all Decodes and match them 2701 // (as operands) into nodes. NullChecks are not prepared to deal with 2702 // Decodes by final_graph_reshaping(). 2703 // If false, final_graph_reshaping() forces the decode behind the Cmp 2704 // for a NullCheck. The matcher matches the Decode node into a register. 2705 // Implicit_null_check optimization moves the Decode along with the 2706 // memory operation back up before the NullCheck. 2707 bool Matcher::narrow_oop_use_complex_address() { 2708 return Universe::narrow_oop_shift() == 0; 2709 } 2710 2711 bool Matcher::narrow_klass_use_complex_address() { 2712 // TODO 2713 // decide whether we need to set this to true 2714 return false; 2715 } 2716 2717 // Is it better to copy float constants, or load them directly from 2718 // memory? Intel can load a float constant from a direct address, 2719 // requiring no extra registers. Most RISCs will have to materialize 2720 // an address into a register first, so they would do better to copy 2721 // the constant from stack. 2722 const bool Matcher::rematerialize_float_constants = false; 2723 2724 // If CPU can load and store mis-aligned doubles directly then no 2725 // fixup is needed. Else we split the double into 2 integer pieces 2726 // and move it piece-by-piece. Only happens when passing doubles into 2727 // C code as the Java calling convention forces doubles to be aligned. 2728 const bool Matcher::misaligned_doubles_ok = true; 2729 2730 // No-op on amd64 2731 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2732 Unimplemented(); 2733 } 2734 2735 // Advertise here if the CPU requires explicit rounding operations to 2736 // implement the UseStrictFP mode. 2737 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2738 2739 // Are floats converted to double when stored to stack during 2740 // deoptimization? 2741 bool Matcher::float_in_double() { return true; } 2742 2743 // Do ints take an entire long register or just half? 2744 // The relevant question is how the int is callee-saved: 2745 // the whole long is written but de-opt'ing will have to extract 2746 // the relevant 32 bits. 2747 const bool Matcher::int_in_long = true; 2748 2749 // Return whether or not this register is ever used as an argument. 2750 // This function is used on startup to build the trampoline stubs in 2751 // generateOptoStub. Registers not mentioned will be killed by the VM 2752 // call in the trampoline, and arguments in those registers not be 2753 // available to the callee. 2754 bool Matcher::can_be_java_arg(int reg) 2755 { 2756 return 2757 reg == R0_num || reg == R0_H_num || 2758 reg == R1_num || reg == R1_H_num || 2759 reg == R2_num || reg == R2_H_num || 2760 reg == R3_num || reg == R3_H_num || 2761 reg == R4_num || reg == R4_H_num || 2762 reg == R5_num || reg == R5_H_num || 2763 reg == R6_num || reg == R6_H_num || 2764 reg == R7_num || reg == R7_H_num || 2765 reg == V0_num || reg == V0_H_num || 2766 reg == V1_num || reg == V1_H_num || 2767 reg == V2_num || reg == V2_H_num || 2768 reg == V3_num || reg == V3_H_num || 2769 reg == V4_num || reg == V4_H_num || 2770 reg == V5_num || reg == V5_H_num || 2771 reg == V6_num || reg == V6_H_num || 2772 reg == V7_num || reg == V7_H_num; 2773 } 2774 2775 bool Matcher::is_spillable_arg(int reg) 2776 { 2777 return can_be_java_arg(reg); 2778 } 2779 2780 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2781 return false; 2782 } 2783 2784 RegMask Matcher::divI_proj_mask() { 2785 ShouldNotReachHere(); 2786 return RegMask(); 2787 } 2788 2789 // Register for MODI projection of divmodI. 2790 RegMask Matcher::modI_proj_mask() { 2791 ShouldNotReachHere(); 2792 return RegMask(); 2793 } 2794 2795 // Register for DIVL projection of divmodL. 2796 RegMask Matcher::divL_proj_mask() { 2797 ShouldNotReachHere(); 2798 return RegMask(); 2799 } 2800 2801 // Register for MODL projection of divmodL. 2802 RegMask Matcher::modL_proj_mask() { 2803 ShouldNotReachHere(); 2804 return RegMask(); 2805 } 2806 2807 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2808 return FP_REG_mask(); 2809 } 2810 2811 // helper for encoding java_to_runtime calls on sim 2812 // 2813 // this is needed to compute the extra arguments required when 2814 // planting a call to the simulator blrt instruction. the TypeFunc 2815 // can be queried to identify the counts for integral, and floating 2816 // arguments and the return type 2817 2818 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2819 { 2820 int gps = 0; 2821 int fps = 0; 2822 const TypeTuple *domain = tf->domain(); 2823 int max = domain->cnt(); 2824 for (int i = TypeFunc::Parms; i < max; i++) { 2825 const Type *t = domain->field_at(i); 2826 switch(t->basic_type()) { 2827 case T_FLOAT: 2828 case T_DOUBLE: 2829 fps++; 2830 default: 2831 gps++; 2832 } 2833 } 2834 gpcnt = gps; 2835 fpcnt = fps; 2836 BasicType rt = tf->return_type(); 2837 switch (rt) { 2838 case T_VOID: 2839 rtype = MacroAssembler::ret_type_void; 2840 break; 2841 default: 2842 rtype = MacroAssembler::ret_type_integral; 2843 break; 2844 case T_FLOAT: 2845 rtype = MacroAssembler::ret_type_float; 2846 break; 2847 case T_DOUBLE: 2848 rtype = MacroAssembler::ret_type_double; 2849 break; 2850 } 2851 } 2852 2853 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2854 MacroAssembler _masm(&cbuf); \ 2855 { \ 2856 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2857 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2858 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2859 __ INSN(REG, as_Register(BASE)); \ 2860 } 2861 2862 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2863 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2864 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2865 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2866 2867 // Used for all non-volatile memory accesses. The use of 2868 // $mem->opcode() to discover whether this pattern uses sign-extended 2869 // offsets is something of a kludge. 2870 static void loadStore(MacroAssembler masm, mem_insn insn, 2871 Register reg, int opcode, 2872 Register base, int index, int size, int disp) 2873 { 2874 Address::extend scale; 2875 2876 // Hooboy, this is fugly. We need a way to communicate to the 2877 // encoder that the index needs to be sign extended, so we have to 2878 // enumerate all the cases. 2879 switch (opcode) { 2880 case INDINDEXSCALEDOFFSETI2L: 2881 case INDINDEXSCALEDI2L: 2882 case INDINDEXSCALEDOFFSETI2LN: 2883 case INDINDEXSCALEDI2LN: 2884 case INDINDEXOFFSETI2L: 2885 case INDINDEXOFFSETI2LN: 2886 scale = Address::sxtw(size); 2887 break; 2888 default: 2889 scale = Address::lsl(size); 2890 } 2891 2892 if (index == -1) { 2893 (masm.*insn)(reg, Address(base, disp)); 2894 } else { 2895 if (disp == 0) { 2896 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2897 } else { 2898 masm.lea(rscratch1, Address(base, disp)); 2899 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2900 } 2901 } 2902 } 2903 2904 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2905 FloatRegister reg, int opcode, 2906 Register base, int index, int size, int disp) 2907 { 2908 Address::extend scale; 2909 2910 switch (opcode) { 2911 case INDINDEXSCALEDOFFSETI2L: 2912 case INDINDEXSCALEDI2L: 2913 case INDINDEXSCALEDOFFSETI2LN: 2914 case INDINDEXSCALEDI2LN: 2915 scale = Address::sxtw(size); 2916 break; 2917 default: 2918 scale = Address::lsl(size); 2919 } 2920 2921 if (index == -1) { 2922 (masm.*insn)(reg, Address(base, disp)); 2923 } else { 2924 if (disp == 0) { 2925 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2926 } else { 2927 masm.lea(rscratch1, Address(base, disp)); 2928 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2929 } 2930 } 2931 } 2932 2933 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2934 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2935 int opcode, Register base, int index, int size, int disp) 2936 { 2937 if (index == -1) { 2938 (masm.*insn)(reg, T, Address(base, disp)); 2939 } else { 2940 assert(disp == 0, "unsupported address mode"); 2941 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2942 } 2943 } 2944 2945 %} 2946 2947 2948 2949 //----------ENCODING BLOCK----------------------------------------------------- 2950 // This block specifies the encoding classes used by the compiler to 2951 // output byte streams. Encoding classes are parameterized macros 2952 // used by Machine Instruction Nodes in order to generate the bit 2953 // encoding of the instruction. Operands specify their base encoding 2954 // interface with the interface keyword. There are currently 2955 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2956 // COND_INTER. REG_INTER causes an operand to generate a function 2957 // which returns its register number when queried. CONST_INTER causes 2958 // an operand to generate a function which returns the value of the 2959 // constant when queried. MEMORY_INTER causes an operand to generate 2960 // four functions which return the Base Register, the Index Register, 2961 // the Scale Value, and the Offset Value of the operand when queried. 2962 // COND_INTER causes an operand to generate six functions which return 2963 // the encoding code (ie - encoding bits for the instruction) 2964 // associated with each basic boolean condition for a conditional 2965 // instruction. 2966 // 2967 // Instructions specify two basic values for encoding. Again, a 2968 // function is available to check if the constant displacement is an 2969 // oop. They use the ins_encode keyword to specify their encoding 2970 // classes (which must be a sequence of enc_class names, and their 2971 // parameters, specified in the encoding block), and they use the 2972 // opcode keyword to specify, in order, their primary, secondary, and 2973 // tertiary opcode. Only the opcode sections which a particular 2974 // instruction needs for encoding need to be specified. 2975 encode %{ 2976 // Build emit functions for each basic byte or larger field in the 2977 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2978 // from C++ code in the enc_class source block. Emit functions will 2979 // live in the main source block for now. In future, we can 2980 // generalize this by adding a syntax that specifies the sizes of 2981 // fields in an order, so that the adlc can build the emit functions 2982 // automagically 2983 2984 // catch all for unimplemented encodings 2985 enc_class enc_unimplemented %{ 2986 MacroAssembler _masm(&cbuf); 2987 __ unimplemented("C2 catch all"); 2988 %} 2989 2990 // BEGIN Non-volatile memory access 2991 2992 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2993 Register dst_reg = as_Register($dst$$reg); 2994 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2995 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2996 %} 2997 2998 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2999 Register dst_reg = as_Register($dst$$reg); 3000 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 3001 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3002 %} 3003 3004 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 3005 Register dst_reg = as_Register($dst$$reg); 3006 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 3007 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3008 %} 3009 3010 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 3011 Register dst_reg = as_Register($dst$$reg); 3012 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 3013 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3014 %} 3015 3016 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 3017 Register dst_reg = as_Register($dst$$reg); 3018 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 3019 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3020 %} 3021 3022 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 3023 Register dst_reg = as_Register($dst$$reg); 3024 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 3025 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3026 %} 3027 3028 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 3029 Register dst_reg = as_Register($dst$$reg); 3030 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 3031 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3032 %} 3033 3034 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 3035 Register dst_reg = as_Register($dst$$reg); 3036 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 3037 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3038 %} 3039 3040 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 3041 Register dst_reg = as_Register($dst$$reg); 3042 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 3043 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3044 %} 3045 3046 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 3047 Register dst_reg = as_Register($dst$$reg); 3048 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 3049 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3050 %} 3051 3052 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 3053 Register dst_reg = as_Register($dst$$reg); 3054 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 3055 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3056 %} 3057 3058 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 3059 Register dst_reg = as_Register($dst$$reg); 3060 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 3061 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3062 %} 3063 3064 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 3065 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3066 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 3067 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3068 %} 3069 3070 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 3071 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3072 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 3073 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3074 %} 3075 3076 enc_class aarch64_enc_ldrvS(vecX dst, memory mem) %{ 3077 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3078 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3079 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3080 %} 3081 3082 enc_class aarch64_enc_ldrvD(vecX dst, memory mem) %{ 3083 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3084 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3085 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3086 %} 3087 3088 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 3089 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3090 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3091 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3092 %} 3093 3094 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 3095 Register src_reg = as_Register($src$$reg); 3096 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 3097 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3098 %} 3099 3100 enc_class aarch64_enc_strb0(memory mem) %{ 3101 MacroAssembler _masm(&cbuf); 3102 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 3103 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3104 %} 3105 3106 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 3107 Register src_reg = as_Register($src$$reg); 3108 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 3109 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3110 %} 3111 3112 enc_class aarch64_enc_strh0(memory mem) %{ 3113 MacroAssembler _masm(&cbuf); 3114 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 3115 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3116 %} 3117 3118 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 3119 Register src_reg = as_Register($src$$reg); 3120 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 3121 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3122 %} 3123 3124 enc_class aarch64_enc_strw0(memory mem) %{ 3125 MacroAssembler _masm(&cbuf); 3126 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 3127 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3128 %} 3129 3130 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 3131 Register src_reg = as_Register($src$$reg); 3132 // we sometimes get asked to store the stack pointer into the 3133 // current thread -- we cannot do that directly on AArch64 3134 if (src_reg == r31_sp) { 3135 MacroAssembler _masm(&cbuf); 3136 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3137 __ mov(rscratch2, sp); 3138 src_reg = rscratch2; 3139 } 3140 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 3141 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3142 %} 3143 3144 enc_class aarch64_enc_str0(memory mem) %{ 3145 MacroAssembler _masm(&cbuf); 3146 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 3147 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3148 %} 3149 3150 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 3151 FloatRegister src_reg = as_FloatRegister($src$$reg); 3152 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 3153 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3154 %} 3155 3156 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 3157 FloatRegister src_reg = as_FloatRegister($src$$reg); 3158 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 3159 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3160 %} 3161 3162 enc_class aarch64_enc_strvS(vecX src, memory mem) %{ 3163 FloatRegister src_reg = as_FloatRegister($src$$reg); 3164 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 3165 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3166 %} 3167 3168 enc_class aarch64_enc_strvD(vecX src, memory mem) %{ 3169 FloatRegister src_reg = as_FloatRegister($src$$reg); 3170 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 3171 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3172 %} 3173 3174 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 3175 FloatRegister src_reg = as_FloatRegister($src$$reg); 3176 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 3177 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3178 %} 3179 3180 // END Non-volatile memory access 3181 3182 // volatile loads and stores 3183 3184 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3185 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3186 rscratch1, stlrb); 3187 %} 3188 3189 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3190 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3191 rscratch1, stlrh); 3192 %} 3193 3194 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3195 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3196 rscratch1, stlrw); 3197 %} 3198 3199 3200 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3201 Register dst_reg = as_Register($dst$$reg); 3202 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3203 rscratch1, ldarb); 3204 __ sxtbw(dst_reg, dst_reg); 3205 %} 3206 3207 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3208 Register dst_reg = as_Register($dst$$reg); 3209 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3210 rscratch1, ldarb); 3211 __ sxtb(dst_reg, dst_reg); 3212 %} 3213 3214 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3215 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3216 rscratch1, ldarb); 3217 %} 3218 3219 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3220 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3221 rscratch1, ldarb); 3222 %} 3223 3224 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3225 Register dst_reg = as_Register($dst$$reg); 3226 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3227 rscratch1, ldarh); 3228 __ sxthw(dst_reg, dst_reg); 3229 %} 3230 3231 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3232 Register dst_reg = as_Register($dst$$reg); 3233 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3234 rscratch1, ldarh); 3235 __ sxth(dst_reg, dst_reg); 3236 %} 3237 3238 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3239 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3240 rscratch1, ldarh); 3241 %} 3242 3243 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3244 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3245 rscratch1, ldarh); 3246 %} 3247 3248 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3249 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3250 rscratch1, ldarw); 3251 %} 3252 3253 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3254 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3255 rscratch1, ldarw); 3256 %} 3257 3258 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3259 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3260 rscratch1, ldar); 3261 %} 3262 3263 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3264 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3265 rscratch1, ldarw); 3266 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3267 %} 3268 3269 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3270 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3271 rscratch1, ldar); 3272 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3273 %} 3274 3275 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3276 Register src_reg = as_Register($src$$reg); 3277 // we sometimes get asked to store the stack pointer into the 3278 // current thread -- we cannot do that directly on AArch64 3279 if (src_reg == r31_sp) { 3280 MacroAssembler _masm(&cbuf); 3281 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3282 __ mov(rscratch2, sp); 3283 src_reg = rscratch2; 3284 } 3285 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3286 rscratch1, stlr); 3287 %} 3288 3289 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3290 { 3291 MacroAssembler _masm(&cbuf); 3292 FloatRegister src_reg = as_FloatRegister($src$$reg); 3293 __ fmovs(rscratch2, src_reg); 3294 } 3295 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3296 rscratch1, stlrw); 3297 %} 3298 3299 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3300 { 3301 MacroAssembler _masm(&cbuf); 3302 FloatRegister src_reg = as_FloatRegister($src$$reg); 3303 __ fmovd(rscratch2, src_reg); 3304 } 3305 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3306 rscratch1, stlr); 3307 %} 3308 3309 // synchronized read/update encodings 3310 3311 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 3312 MacroAssembler _masm(&cbuf); 3313 Register dst_reg = as_Register($dst$$reg); 3314 Register base = as_Register($mem$$base); 3315 int index = $mem$$index; 3316 int scale = $mem$$scale; 3317 int disp = $mem$$disp; 3318 if (index == -1) { 3319 if (disp != 0) { 3320 __ lea(rscratch1, Address(base, disp)); 3321 __ ldaxr(dst_reg, rscratch1); 3322 } else { 3323 // TODO 3324 // should we ever get anything other than this case? 3325 __ ldaxr(dst_reg, base); 3326 } 3327 } else { 3328 Register index_reg = as_Register(index); 3329 if (disp == 0) { 3330 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3331 __ ldaxr(dst_reg, rscratch1); 3332 } else { 3333 __ lea(rscratch1, Address(base, disp)); 3334 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3335 __ ldaxr(dst_reg, rscratch1); 3336 } 3337 } 3338 %} 3339 3340 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 3341 MacroAssembler _masm(&cbuf); 3342 Register src_reg = as_Register($src$$reg); 3343 Register base = as_Register($mem$$base); 3344 int index = $mem$$index; 3345 int scale = $mem$$scale; 3346 int disp = $mem$$disp; 3347 if (index == -1) { 3348 if (disp != 0) { 3349 __ lea(rscratch2, Address(base, disp)); 3350 __ stlxr(rscratch1, src_reg, rscratch2); 3351 } else { 3352 // TODO 3353 // should we ever get anything other than this case? 3354 __ stlxr(rscratch1, src_reg, base); 3355 } 3356 } else { 3357 Register index_reg = as_Register(index); 3358 if (disp == 0) { 3359 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3360 __ stlxr(rscratch1, src_reg, rscratch2); 3361 } else { 3362 __ lea(rscratch2, Address(base, disp)); 3363 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3364 __ stlxr(rscratch1, src_reg, rscratch2); 3365 } 3366 } 3367 __ cmpw(rscratch1, zr); 3368 %} 3369 3370 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3371 MacroAssembler _masm(&cbuf); 3372 Register old_reg = as_Register($oldval$$reg); 3373 Register new_reg = as_Register($newval$$reg); 3374 Register base = as_Register($mem$$base); 3375 Register addr_reg; 3376 int index = $mem$$index; 3377 int scale = $mem$$scale; 3378 int disp = $mem$$disp; 3379 if (index == -1) { 3380 if (disp != 0) { 3381 __ lea(rscratch2, Address(base, disp)); 3382 addr_reg = rscratch2; 3383 } else { 3384 // TODO 3385 // should we ever get anything other than this case? 3386 addr_reg = base; 3387 } 3388 } else { 3389 Register index_reg = as_Register(index); 3390 if (disp == 0) { 3391 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3392 addr_reg = rscratch2; 3393 } else { 3394 __ lea(rscratch2, Address(base, disp)); 3395 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3396 addr_reg = rscratch2; 3397 } 3398 } 3399 Label retry_load, done; 3400 __ bind(retry_load); 3401 __ ldxr(rscratch1, addr_reg); 3402 __ cmp(rscratch1, old_reg); 3403 __ br(Assembler::NE, done); 3404 __ stlxr(rscratch1, new_reg, addr_reg); 3405 __ cbnzw(rscratch1, retry_load); 3406 __ bind(done); 3407 %} 3408 3409 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3410 MacroAssembler _masm(&cbuf); 3411 Register old_reg = as_Register($oldval$$reg); 3412 Register new_reg = as_Register($newval$$reg); 3413 Register base = as_Register($mem$$base); 3414 Register addr_reg; 3415 int index = $mem$$index; 3416 int scale = $mem$$scale; 3417 int disp = $mem$$disp; 3418 if (index == -1) { 3419 if (disp != 0) { 3420 __ lea(rscratch2, Address(base, disp)); 3421 addr_reg = rscratch2; 3422 } else { 3423 // TODO 3424 // should we ever get anything other than this case? 3425 addr_reg = base; 3426 } 3427 } else { 3428 Register index_reg = as_Register(index); 3429 if (disp == 0) { 3430 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3431 addr_reg = rscratch2; 3432 } else { 3433 __ lea(rscratch2, Address(base, disp)); 3434 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3435 addr_reg = rscratch2; 3436 } 3437 } 3438 Label retry_load, done; 3439 __ bind(retry_load); 3440 __ ldxrw(rscratch1, addr_reg); 3441 __ cmpw(rscratch1, old_reg); 3442 __ br(Assembler::NE, done); 3443 __ stlxrw(rscratch1, new_reg, addr_reg); 3444 __ cbnzw(rscratch1, retry_load); 3445 __ bind(done); 3446 %} 3447 3448 // auxiliary used for CompareAndSwapX to set result register 3449 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3450 MacroAssembler _masm(&cbuf); 3451 Register res_reg = as_Register($res$$reg); 3452 __ cset(res_reg, Assembler::EQ); 3453 %} 3454 3455 // prefetch encodings 3456 3457 enc_class aarch64_enc_prefetchw(memory mem) %{ 3458 MacroAssembler _masm(&cbuf); 3459 Register base = as_Register($mem$$base); 3460 int index = $mem$$index; 3461 int scale = $mem$$scale; 3462 int disp = $mem$$disp; 3463 if (index == -1) { 3464 __ prfm(Address(base, disp), PSTL1KEEP); 3465 __ nop(); 3466 } else { 3467 Register index_reg = as_Register(index); 3468 if (disp == 0) { 3469 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3470 } else { 3471 __ lea(rscratch1, Address(base, disp)); 3472 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3473 } 3474 } 3475 %} 3476 3477 enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{ 3478 MacroAssembler _masm(&cbuf); 3479 Register cnt_reg = as_Register($cnt$$reg); 3480 Register base_reg = as_Register($base$$reg); 3481 // base is word aligned 3482 // cnt is count of words 3483 3484 Label loop; 3485 Label entry; 3486 3487 // Algorithm: 3488 // 3489 // scratch1 = cnt & 7; 3490 // cnt -= scratch1; 3491 // p += scratch1; 3492 // switch (scratch1) { 3493 // do { 3494 // cnt -= 8; 3495 // p[-8] = 0; 3496 // case 7: 3497 // p[-7] = 0; 3498 // case 6: 3499 // p[-6] = 0; 3500 // // ... 3501 // case 1: 3502 // p[-1] = 0; 3503 // case 0: 3504 // p += 8; 3505 // } while (cnt); 3506 // } 3507 3508 const int unroll = 8; // Number of str(zr) instructions we'll unroll 3509 3510 __ andr(rscratch1, cnt_reg, unroll - 1); // tmp1 = cnt % unroll 3511 __ sub(cnt_reg, cnt_reg, rscratch1); // cnt -= unroll 3512 // base_reg always points to the end of the region we're about to zero 3513 __ add(base_reg, base_reg, rscratch1, Assembler::LSL, exact_log2(wordSize)); 3514 __ adr(rscratch2, entry); 3515 __ sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); 3516 __ br(rscratch2); 3517 __ bind(loop); 3518 __ sub(cnt_reg, cnt_reg, unroll); 3519 for (int i = -unroll; i < 0; i++) 3520 __ str(zr, Address(base_reg, i * wordSize)); 3521 __ bind(entry); 3522 __ add(base_reg, base_reg, unroll * wordSize); 3523 __ cbnz(cnt_reg, loop); 3524 %} 3525 3526 /// mov envcodings 3527 3528 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3529 MacroAssembler _masm(&cbuf); 3530 u_int32_t con = (u_int32_t)$src$$constant; 3531 Register dst_reg = as_Register($dst$$reg); 3532 if (con == 0) { 3533 __ movw(dst_reg, zr); 3534 } else { 3535 __ movw(dst_reg, con); 3536 } 3537 %} 3538 3539 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3540 MacroAssembler _masm(&cbuf); 3541 Register dst_reg = as_Register($dst$$reg); 3542 u_int64_t con = (u_int64_t)$src$$constant; 3543 if (con == 0) { 3544 __ mov(dst_reg, zr); 3545 } else { 3546 __ mov(dst_reg, con); 3547 } 3548 %} 3549 3550 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3551 MacroAssembler _masm(&cbuf); 3552 Register dst_reg = as_Register($dst$$reg); 3553 address con = (address)$src$$constant; 3554 if (con == NULL || con == (address)1) { 3555 ShouldNotReachHere(); 3556 } else { 3557 relocInfo::relocType rtype = $src->constant_reloc(); 3558 if (rtype == relocInfo::oop_type) { 3559 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3560 } else if (rtype == relocInfo::metadata_type) { 3561 __ mov_metadata(dst_reg, (Metadata*)con); 3562 } else { 3563 assert(rtype == relocInfo::none, "unexpected reloc type"); 3564 if (con < (address)(uintptr_t)os::vm_page_size()) { 3565 __ mov(dst_reg, con); 3566 } else { 3567 unsigned long offset; 3568 __ adrp(dst_reg, con, offset); 3569 __ add(dst_reg, dst_reg, offset); 3570 } 3571 } 3572 } 3573 %} 3574 3575 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3576 MacroAssembler _masm(&cbuf); 3577 Register dst_reg = as_Register($dst$$reg); 3578 __ mov(dst_reg, zr); 3579 %} 3580 3581 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3582 MacroAssembler _masm(&cbuf); 3583 Register dst_reg = as_Register($dst$$reg); 3584 __ mov(dst_reg, (u_int64_t)1); 3585 %} 3586 3587 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3588 MacroAssembler _masm(&cbuf); 3589 address page = (address)$src$$constant; 3590 Register dst_reg = as_Register($dst$$reg); 3591 unsigned long off; 3592 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3593 assert(off == 0, "assumed offset == 0"); 3594 %} 3595 3596 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3597 MacroAssembler _masm(&cbuf); 3598 address page = (address)$src$$constant; 3599 Register dst_reg = as_Register($dst$$reg); 3600 unsigned long off; 3601 __ adrp(dst_reg, ExternalAddress(page), off); 3602 assert(off == 0, "assumed offset == 0"); 3603 %} 3604 3605 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3606 MacroAssembler _masm(&cbuf); 3607 Register dst_reg = as_Register($dst$$reg); 3608 address con = (address)$src$$constant; 3609 if (con == NULL) { 3610 ShouldNotReachHere(); 3611 } else { 3612 relocInfo::relocType rtype = $src->constant_reloc(); 3613 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3614 __ set_narrow_oop(dst_reg, (jobject)con); 3615 } 3616 %} 3617 3618 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3619 MacroAssembler _masm(&cbuf); 3620 Register dst_reg = as_Register($dst$$reg); 3621 __ mov(dst_reg, zr); 3622 %} 3623 3624 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3625 MacroAssembler _masm(&cbuf); 3626 Register dst_reg = as_Register($dst$$reg); 3627 address con = (address)$src$$constant; 3628 if (con == NULL) { 3629 ShouldNotReachHere(); 3630 } else { 3631 relocInfo::relocType rtype = $src->constant_reloc(); 3632 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3633 __ set_narrow_klass(dst_reg, (Klass *)con); 3634 } 3635 %} 3636 3637 // arithmetic encodings 3638 3639 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3640 MacroAssembler _masm(&cbuf); 3641 Register dst_reg = as_Register($dst$$reg); 3642 Register src_reg = as_Register($src1$$reg); 3643 int32_t con = (int32_t)$src2$$constant; 3644 // add has primary == 0, subtract has primary == 1 3645 if ($primary) { con = -con; } 3646 if (con < 0) { 3647 __ subw(dst_reg, src_reg, -con); 3648 } else { 3649 __ addw(dst_reg, src_reg, con); 3650 } 3651 %} 3652 3653 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3654 MacroAssembler _masm(&cbuf); 3655 Register dst_reg = as_Register($dst$$reg); 3656 Register src_reg = as_Register($src1$$reg); 3657 int32_t con = (int32_t)$src2$$constant; 3658 // add has primary == 0, subtract has primary == 1 3659 if ($primary) { con = -con; } 3660 if (con < 0) { 3661 __ sub(dst_reg, src_reg, -con); 3662 } else { 3663 __ add(dst_reg, src_reg, con); 3664 } 3665 %} 3666 3667 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3668 MacroAssembler _masm(&cbuf); 3669 Register dst_reg = as_Register($dst$$reg); 3670 Register src1_reg = as_Register($src1$$reg); 3671 Register src2_reg = as_Register($src2$$reg); 3672 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3673 %} 3674 3675 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3676 MacroAssembler _masm(&cbuf); 3677 Register dst_reg = as_Register($dst$$reg); 3678 Register src1_reg = as_Register($src1$$reg); 3679 Register src2_reg = as_Register($src2$$reg); 3680 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3681 %} 3682 3683 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3684 MacroAssembler _masm(&cbuf); 3685 Register dst_reg = as_Register($dst$$reg); 3686 Register src1_reg = as_Register($src1$$reg); 3687 Register src2_reg = as_Register($src2$$reg); 3688 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3689 %} 3690 3691 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3692 MacroAssembler _masm(&cbuf); 3693 Register dst_reg = as_Register($dst$$reg); 3694 Register src1_reg = as_Register($src1$$reg); 3695 Register src2_reg = as_Register($src2$$reg); 3696 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3697 %} 3698 3699 // compare instruction encodings 3700 3701 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3702 MacroAssembler _masm(&cbuf); 3703 Register reg1 = as_Register($src1$$reg); 3704 Register reg2 = as_Register($src2$$reg); 3705 __ cmpw(reg1, reg2); 3706 %} 3707 3708 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3709 MacroAssembler _masm(&cbuf); 3710 Register reg = as_Register($src1$$reg); 3711 int32_t val = $src2$$constant; 3712 if (val >= 0) { 3713 __ subsw(zr, reg, val); 3714 } else { 3715 __ addsw(zr, reg, -val); 3716 } 3717 %} 3718 3719 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3720 MacroAssembler _masm(&cbuf); 3721 Register reg1 = as_Register($src1$$reg); 3722 u_int32_t val = (u_int32_t)$src2$$constant; 3723 __ movw(rscratch1, val); 3724 __ cmpw(reg1, rscratch1); 3725 %} 3726 3727 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3728 MacroAssembler _masm(&cbuf); 3729 Register reg1 = as_Register($src1$$reg); 3730 Register reg2 = as_Register($src2$$reg); 3731 __ cmp(reg1, reg2); 3732 %} 3733 3734 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3735 MacroAssembler _masm(&cbuf); 3736 Register reg = as_Register($src1$$reg); 3737 int64_t val = $src2$$constant; 3738 if (val >= 0) { 3739 __ subs(zr, reg, val); 3740 } else if (val != -val) { 3741 __ adds(zr, reg, -val); 3742 } else { 3743 // aargh, Long.MIN_VALUE is a special case 3744 __ orr(rscratch1, zr, (u_int64_t)val); 3745 __ subs(zr, reg, rscratch1); 3746 } 3747 %} 3748 3749 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3750 MacroAssembler _masm(&cbuf); 3751 Register reg1 = as_Register($src1$$reg); 3752 u_int64_t val = (u_int64_t)$src2$$constant; 3753 __ mov(rscratch1, val); 3754 __ cmp(reg1, rscratch1); 3755 %} 3756 3757 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3758 MacroAssembler _masm(&cbuf); 3759 Register reg1 = as_Register($src1$$reg); 3760 Register reg2 = as_Register($src2$$reg); 3761 __ cmp(reg1, reg2); 3762 %} 3763 3764 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3765 MacroAssembler _masm(&cbuf); 3766 Register reg1 = as_Register($src1$$reg); 3767 Register reg2 = as_Register($src2$$reg); 3768 __ cmpw(reg1, reg2); 3769 %} 3770 3771 enc_class aarch64_enc_testp(iRegP src) %{ 3772 MacroAssembler _masm(&cbuf); 3773 Register reg = as_Register($src$$reg); 3774 __ cmp(reg, zr); 3775 %} 3776 3777 enc_class aarch64_enc_testn(iRegN src) %{ 3778 MacroAssembler _masm(&cbuf); 3779 Register reg = as_Register($src$$reg); 3780 __ cmpw(reg, zr); 3781 %} 3782 3783 enc_class aarch64_enc_b(label lbl) %{ 3784 MacroAssembler _masm(&cbuf); 3785 Label *L = $lbl$$label; 3786 __ b(*L); 3787 %} 3788 3789 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3790 MacroAssembler _masm(&cbuf); 3791 Label *L = $lbl$$label; 3792 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3793 %} 3794 3795 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3796 MacroAssembler _masm(&cbuf); 3797 Label *L = $lbl$$label; 3798 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3799 %} 3800 3801 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3802 %{ 3803 Register sub_reg = as_Register($sub$$reg); 3804 Register super_reg = as_Register($super$$reg); 3805 Register temp_reg = as_Register($temp$$reg); 3806 Register result_reg = as_Register($result$$reg); 3807 3808 Label miss; 3809 MacroAssembler _masm(&cbuf); 3810 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3811 NULL, &miss, 3812 /*set_cond_codes:*/ true); 3813 if ($primary) { 3814 __ mov(result_reg, zr); 3815 } 3816 __ bind(miss); 3817 %} 3818 3819 enc_class aarch64_enc_java_static_call(method meth) %{ 3820 MacroAssembler _masm(&cbuf); 3821 3822 address addr = (address)$meth$$method; 3823 if (!_method) { 3824 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3825 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3826 } else if (_optimized_virtual) { 3827 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 3828 } else { 3829 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 3830 } 3831 3832 if (_method) { 3833 // Emit stub for static call 3834 CompiledStaticCall::emit_to_interp_stub(cbuf); 3835 } 3836 %} 3837 3838 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3839 MacroAssembler _masm(&cbuf); 3840 __ ic_call((address)$meth$$method); 3841 %} 3842 3843 enc_class aarch64_enc_call_epilog() %{ 3844 MacroAssembler _masm(&cbuf); 3845 if (VerifyStackAtCalls) { 3846 // Check that stack depth is unchanged: find majik cookie on stack 3847 __ call_Unimplemented(); 3848 } 3849 %} 3850 3851 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3852 MacroAssembler _masm(&cbuf); 3853 3854 // some calls to generated routines (arraycopy code) are scheduled 3855 // by C2 as runtime calls. if so we can call them using a br (they 3856 // will be in a reachable segment) otherwise we have to use a blrt 3857 // which loads the absolute address into a register. 3858 address entry = (address)$meth$$method; 3859 CodeBlob *cb = CodeCache::find_blob(entry); 3860 if (cb) { 3861 __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3862 } else { 3863 int gpcnt; 3864 int fpcnt; 3865 int rtype; 3866 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3867 Label retaddr; 3868 __ adr(rscratch2, retaddr); 3869 __ lea(rscratch1, RuntimeAddress(entry)); 3870 // Leave a breadcrumb for JavaThread::pd_last_frame(). 3871 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3872 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3873 __ bind(retaddr); 3874 __ add(sp, sp, 2 * wordSize); 3875 } 3876 %} 3877 3878 enc_class aarch64_enc_rethrow() %{ 3879 MacroAssembler _masm(&cbuf); 3880 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3881 %} 3882 3883 enc_class aarch64_enc_ret() %{ 3884 MacroAssembler _masm(&cbuf); 3885 __ ret(lr); 3886 %} 3887 3888 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3889 MacroAssembler _masm(&cbuf); 3890 Register target_reg = as_Register($jump_target$$reg); 3891 __ br(target_reg); 3892 %} 3893 3894 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3895 MacroAssembler _masm(&cbuf); 3896 Register target_reg = as_Register($jump_target$$reg); 3897 // exception oop should be in r0 3898 // ret addr has been popped into lr 3899 // callee expects it in r3 3900 __ mov(r3, lr); 3901 __ br(target_reg); 3902 %} 3903 3904 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3905 MacroAssembler _masm(&cbuf); 3906 Register oop = as_Register($object$$reg); 3907 Register box = as_Register($box$$reg); 3908 Register disp_hdr = as_Register($tmp$$reg); 3909 Register tmp = as_Register($tmp2$$reg); 3910 Label cont; 3911 Label object_has_monitor; 3912 Label cas_failed; 3913 3914 assert_different_registers(oop, box, tmp, disp_hdr); 3915 3916 // Load markOop from object into displaced_header. 3917 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3918 3919 // Always do locking in runtime. 3920 if (EmitSync & 0x01) { 3921 __ cmp(oop, zr); 3922 return; 3923 } 3924 3925 if (UseBiasedLocking) { 3926 __ biased_locking_enter(disp_hdr, oop, box, tmp, true, cont); 3927 } 3928 3929 // Handle existing monitor 3930 if (EmitSync & 0x02) { 3931 // we can use AArch64's bit test and branch here but 3932 // markoopDesc does not define a bit index just the bit value 3933 // so assert in case the bit pos changes 3934 # define __monitor_value_log2 1 3935 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 3936 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 3937 # undef __monitor_value_log2 3938 } 3939 3940 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3941 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3942 3943 // Load Compare Value application register. 3944 3945 // Initialize the box. (Must happen before we update the object mark!) 3946 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3947 3948 // Compare object markOop with mark and if equal exchange scratch1 3949 // with object markOop. 3950 // Note that this is simply a CAS: it does not generate any 3951 // barriers. These are separately generated by 3952 // membar_acquire_lock(). 3953 { 3954 Label retry_load; 3955 __ bind(retry_load); 3956 __ ldxr(tmp, oop); 3957 __ cmp(tmp, disp_hdr); 3958 __ br(Assembler::NE, cas_failed); 3959 // use stlxr to ensure update is immediately visible 3960 __ stlxr(tmp, box, oop); 3961 __ cbzw(tmp, cont); 3962 __ b(retry_load); 3963 } 3964 3965 // Formerly: 3966 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3967 // /*newv=*/box, 3968 // /*addr=*/oop, 3969 // /*tmp=*/tmp, 3970 // cont, 3971 // /*fail*/NULL); 3972 3973 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3974 3975 // If the compare-and-exchange succeeded, then we found an unlocked 3976 // object, will have now locked it will continue at label cont 3977 3978 __ bind(cas_failed); 3979 // We did not see an unlocked object so try the fast recursive case. 3980 3981 // Check if the owner is self by comparing the value in the 3982 // markOop of object (disp_hdr) with the stack pointer. 3983 __ mov(rscratch1, sp); 3984 __ sub(disp_hdr, disp_hdr, rscratch1); 3985 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3986 // If condition is true we are cont and hence we can store 0 as the 3987 // displaced header in the box, which indicates that it is a recursive lock. 3988 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3989 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3990 3991 // Handle existing monitor. 3992 if ((EmitSync & 0x02) == 0) { 3993 __ b(cont); 3994 3995 __ bind(object_has_monitor); 3996 // The object's monitor m is unlocked iff m->owner == NULL, 3997 // otherwise m->owner may contain a thread or a stack address. 3998 // 3999 // Try to CAS m->owner from NULL to current thread. 4000 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 4001 __ mov(disp_hdr, zr); 4002 4003 { 4004 Label retry_load, fail; 4005 __ bind(retry_load); 4006 __ ldxr(rscratch1, tmp); 4007 __ cmp(disp_hdr, rscratch1); 4008 __ br(Assembler::NE, fail); 4009 // use stlxr to ensure update is immediately visible 4010 __ stlxr(rscratch1, rthread, tmp); 4011 __ cbnzw(rscratch1, retry_load); 4012 __ bind(fail); 4013 } 4014 4015 // Label next; 4016 // __ cmpxchgptr(/*oldv=*/disp_hdr, 4017 // /*newv=*/rthread, 4018 // /*addr=*/tmp, 4019 // /*tmp=*/rscratch1, 4020 // /*succeed*/next, 4021 // /*fail*/NULL); 4022 // __ bind(next); 4023 4024 // store a non-null value into the box. 4025 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 4026 4027 // PPC port checks the following invariants 4028 // #ifdef ASSERT 4029 // bne(flag, cont); 4030 // We have acquired the monitor, check some invariants. 4031 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 4032 // Invariant 1: _recursions should be 0. 4033 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 4034 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 4035 // "monitor->_recursions should be 0", -1); 4036 // Invariant 2: OwnerIsThread shouldn't be 0. 4037 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 4038 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 4039 // "monitor->OwnerIsThread shouldn't be 0", -1); 4040 // #endif 4041 } 4042 4043 __ bind(cont); 4044 // flag == EQ indicates success 4045 // flag == NE indicates failure 4046 4047 %} 4048 4049 // TODO 4050 // reimplement this with custom cmpxchgptr code 4051 // which avoids some of the unnecessary branching 4052 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 4053 MacroAssembler _masm(&cbuf); 4054 Register oop = as_Register($object$$reg); 4055 Register box = as_Register($box$$reg); 4056 Register disp_hdr = as_Register($tmp$$reg); 4057 Register tmp = as_Register($tmp2$$reg); 4058 Label cont; 4059 Label object_has_monitor; 4060 Label cas_failed; 4061 4062 assert_different_registers(oop, box, tmp, disp_hdr); 4063 4064 // Always do locking in runtime. 4065 if (EmitSync & 0x01) { 4066 __ cmp(oop, zr); // Oop can't be 0 here => always false. 4067 return; 4068 } 4069 4070 if (UseBiasedLocking) { 4071 __ biased_locking_exit(oop, tmp, cont); 4072 } 4073 4074 // Find the lock address and load the displaced header from the stack. 4075 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 4076 4077 // If the displaced header is 0, we have a recursive unlock. 4078 __ cmp(disp_hdr, zr); 4079 __ br(Assembler::EQ, cont); 4080 4081 4082 // Handle existing monitor. 4083 if ((EmitSync & 0x02) == 0) { 4084 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 4085 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 4086 } 4087 4088 // Check if it is still a light weight lock, this is is true if we 4089 // see the stack address of the basicLock in the markOop of the 4090 // object. 4091 4092 { 4093 Label retry_load; 4094 __ bind(retry_load); 4095 __ ldxr(tmp, oop); 4096 __ cmp(box, tmp); 4097 __ br(Assembler::NE, cas_failed); 4098 // use stlxr to ensure update is immediately visible 4099 __ stlxr(tmp, disp_hdr, oop); 4100 __ cbzw(tmp, cont); 4101 __ b(retry_load); 4102 } 4103 4104 // __ cmpxchgptr(/*compare_value=*/box, 4105 // /*exchange_value=*/disp_hdr, 4106 // /*where=*/oop, 4107 // /*result=*/tmp, 4108 // cont, 4109 // /*cas_failed*/NULL); 4110 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 4111 4112 __ bind(cas_failed); 4113 4114 // Handle existing monitor. 4115 if ((EmitSync & 0x02) == 0) { 4116 __ b(cont); 4117 4118 __ bind(object_has_monitor); 4119 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 4120 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 4121 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 4122 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 4123 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 4124 __ cmp(rscratch1, zr); 4125 __ br(Assembler::NE, cont); 4126 4127 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 4128 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 4129 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 4130 __ cmp(rscratch1, zr); 4131 __ cbnz(rscratch1, cont); 4132 // need a release store here 4133 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 4134 __ stlr(rscratch1, tmp); // rscratch1 is zero 4135 } 4136 4137 __ bind(cont); 4138 // flag == EQ indicates success 4139 // flag == NE indicates failure 4140 %} 4141 4142 %} 4143 4144 //----------FRAME-------------------------------------------------------------- 4145 // Definition of frame structure and management information. 4146 // 4147 // S T A C K L A Y O U T Allocators stack-slot number 4148 // | (to get allocators register number 4149 // G Owned by | | v add OptoReg::stack0()) 4150 // r CALLER | | 4151 // o | +--------+ pad to even-align allocators stack-slot 4152 // w V | pad0 | numbers; owned by CALLER 4153 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 4154 // h ^ | in | 5 4155 // | | args | 4 Holes in incoming args owned by SELF 4156 // | | | | 3 4157 // | | +--------+ 4158 // V | | old out| Empty on Intel, window on Sparc 4159 // | old |preserve| Must be even aligned. 4160 // | SP-+--------+----> Matcher::_old_SP, even aligned 4161 // | | in | 3 area for Intel ret address 4162 // Owned by |preserve| Empty on Sparc. 4163 // SELF +--------+ 4164 // | | pad2 | 2 pad to align old SP 4165 // | +--------+ 1 4166 // | | locks | 0 4167 // | +--------+----> OptoReg::stack0(), even aligned 4168 // | | pad1 | 11 pad to align new SP 4169 // | +--------+ 4170 // | | | 10 4171 // | | spills | 9 spills 4172 // V | | 8 (pad0 slot for callee) 4173 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 4174 // ^ | out | 7 4175 // | | args | 6 Holes in outgoing args owned by CALLEE 4176 // Owned by +--------+ 4177 // CALLEE | new out| 6 Empty on Intel, window on Sparc 4178 // | new |preserve| Must be even-aligned. 4179 // | SP-+--------+----> Matcher::_new_SP, even aligned 4180 // | | | 4181 // 4182 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 4183 // known from SELF's arguments and the Java calling convention. 4184 // Region 6-7 is determined per call site. 4185 // Note 2: If the calling convention leaves holes in the incoming argument 4186 // area, those holes are owned by SELF. Holes in the outgoing area 4187 // are owned by the CALLEE. Holes should not be nessecary in the 4188 // incoming area, as the Java calling convention is completely under 4189 // the control of the AD file. Doubles can be sorted and packed to 4190 // avoid holes. Holes in the outgoing arguments may be nessecary for 4191 // varargs C calling conventions. 4192 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 4193 // even aligned with pad0 as needed. 4194 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 4195 // (the latter is true on Intel but is it false on AArch64?) 4196 // region 6-11 is even aligned; it may be padded out more so that 4197 // the region from SP to FP meets the minimum stack alignment. 4198 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 4199 // alignment. Region 11, pad1, may be dynamically extended so that 4200 // SP meets the minimum alignment. 4201 4202 frame %{ 4203 // What direction does stack grow in (assumed to be same for C & Java) 4204 stack_direction(TOWARDS_LOW); 4205 4206 // These three registers define part of the calling convention 4207 // between compiled code and the interpreter. 4208 4209 // Inline Cache Register or methodOop for I2C. 4210 inline_cache_reg(R12); 4211 4212 // Method Oop Register when calling interpreter. 4213 interpreter_method_oop_reg(R12); 4214 4215 // Number of stack slots consumed by locking an object 4216 sync_stack_slots(2); 4217 4218 // Compiled code's Frame Pointer 4219 frame_pointer(R31); 4220 4221 // Interpreter stores its frame pointer in a register which is 4222 // stored to the stack by I2CAdaptors. 4223 // I2CAdaptors convert from interpreted java to compiled java. 4224 interpreter_frame_pointer(R29); 4225 4226 // Stack alignment requirement 4227 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 4228 4229 // Number of stack slots between incoming argument block and the start of 4230 // a new frame. The PROLOG must add this many slots to the stack. The 4231 // EPILOG must remove this many slots. aarch64 needs two slots for 4232 // return address and fp. 4233 // TODO think this is correct but check 4234 in_preserve_stack_slots(4); 4235 4236 // Number of outgoing stack slots killed above the out_preserve_stack_slots 4237 // for calls to C. Supports the var-args backing area for register parms. 4238 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 4239 4240 // The after-PROLOG location of the return address. Location of 4241 // return address specifies a type (REG or STACK) and a number 4242 // representing the register number (i.e. - use a register name) or 4243 // stack slot. 4244 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 4245 // Otherwise, it is above the locks and verification slot and alignment word 4246 // TODO this may well be correct but need to check why that - 2 is there 4247 // ppc port uses 0 but we definitely need to allow for fixed_slots 4248 // which folds in the space used for monitors 4249 return_addr(STACK - 2 + 4250 round_to((Compile::current()->in_preserve_stack_slots() + 4251 Compile::current()->fixed_slots()), 4252 stack_alignment_in_slots())); 4253 4254 // Body of function which returns an integer array locating 4255 // arguments either in registers or in stack slots. Passed an array 4256 // of ideal registers called "sig" and a "length" count. Stack-slot 4257 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4258 // arguments for a CALLEE. Incoming stack arguments are 4259 // automatically biased by the preserve_stack_slots field above. 4260 4261 calling_convention 4262 %{ 4263 // No difference between ingoing/outgoing just pass false 4264 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4265 %} 4266 4267 c_calling_convention 4268 %{ 4269 // This is obviously always outgoing 4270 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 4271 %} 4272 4273 // Location of compiled Java return values. Same as C for now. 4274 return_value 4275 %{ 4276 // TODO do we allow ideal_reg == Op_RegN??? 4277 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 4278 "only return normal values"); 4279 4280 static const int lo[Op_RegL + 1] = { // enum name 4281 0, // Op_Node 4282 0, // Op_Set 4283 R0_num, // Op_RegN 4284 R0_num, // Op_RegI 4285 R0_num, // Op_RegP 4286 V0_num, // Op_RegF 4287 V0_num, // Op_RegD 4288 R0_num // Op_RegL 4289 }; 4290 4291 static const int hi[Op_RegL + 1] = { // enum name 4292 0, // Op_Node 4293 0, // Op_Set 4294 OptoReg::Bad, // Op_RegN 4295 OptoReg::Bad, // Op_RegI 4296 R0_H_num, // Op_RegP 4297 OptoReg::Bad, // Op_RegF 4298 V0_H_num, // Op_RegD 4299 R0_H_num // Op_RegL 4300 }; 4301 4302 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4303 %} 4304 %} 4305 4306 //----------ATTRIBUTES--------------------------------------------------------- 4307 //----------Operand Attributes------------------------------------------------- 4308 op_attrib op_cost(1); // Required cost attribute 4309 4310 //----------Instruction Attributes--------------------------------------------- 4311 ins_attrib ins_cost(INSN_COST); // Required cost attribute 4312 ins_attrib ins_size(32); // Required size attribute (in bits) 4313 ins_attrib ins_short_branch(0); // Required flag: is this instruction 4314 // a non-matching short branch variant 4315 // of some long branch? 4316 ins_attrib ins_alignment(4); // Required alignment attribute (must 4317 // be a power of 2) specifies the 4318 // alignment that some part of the 4319 // instruction (not necessarily the 4320 // start) requires. If > 1, a 4321 // compute_padding() function must be 4322 // provided for the instruction 4323 4324 //----------OPERANDS----------------------------------------------------------- 4325 // Operand definitions must precede instruction definitions for correct parsing 4326 // in the ADLC because operands constitute user defined types which are used in 4327 // instruction definitions. 4328 4329 //----------Simple Operands---------------------------------------------------- 4330 4331 // Integer operands 32 bit 4332 // 32 bit immediate 4333 operand immI() 4334 %{ 4335 match(ConI); 4336 4337 op_cost(0); 4338 format %{ %} 4339 interface(CONST_INTER); 4340 %} 4341 4342 // 32 bit zero 4343 operand immI0() 4344 %{ 4345 predicate(n->get_int() == 0); 4346 match(ConI); 4347 4348 op_cost(0); 4349 format %{ %} 4350 interface(CONST_INTER); 4351 %} 4352 4353 // 32 bit unit increment 4354 operand immI_1() 4355 %{ 4356 predicate(n->get_int() == 1); 4357 match(ConI); 4358 4359 op_cost(0); 4360 format %{ %} 4361 interface(CONST_INTER); 4362 %} 4363 4364 // 32 bit unit decrement 4365 operand immI_M1() 4366 %{ 4367 predicate(n->get_int() == -1); 4368 match(ConI); 4369 4370 op_cost(0); 4371 format %{ %} 4372 interface(CONST_INTER); 4373 %} 4374 4375 operand immI_le_4() 4376 %{ 4377 predicate(n->get_int() <= 4); 4378 match(ConI); 4379 4380 op_cost(0); 4381 format %{ %} 4382 interface(CONST_INTER); 4383 %} 4384 4385 operand immI_31() 4386 %{ 4387 predicate(n->get_int() == 31); 4388 match(ConI); 4389 4390 op_cost(0); 4391 format %{ %} 4392 interface(CONST_INTER); 4393 %} 4394 4395 operand immI_8() 4396 %{ 4397 predicate(n->get_int() == 8); 4398 match(ConI); 4399 4400 op_cost(0); 4401 format %{ %} 4402 interface(CONST_INTER); 4403 %} 4404 4405 operand immI_16() 4406 %{ 4407 predicate(n->get_int() == 16); 4408 match(ConI); 4409 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413 %} 4414 4415 operand immI_24() 4416 %{ 4417 predicate(n->get_int() == 24); 4418 match(ConI); 4419 4420 op_cost(0); 4421 format %{ %} 4422 interface(CONST_INTER); 4423 %} 4424 4425 operand immI_32() 4426 %{ 4427 predicate(n->get_int() == 32); 4428 match(ConI); 4429 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 operand immI_48() 4436 %{ 4437 predicate(n->get_int() == 48); 4438 match(ConI); 4439 4440 op_cost(0); 4441 format %{ %} 4442 interface(CONST_INTER); 4443 %} 4444 4445 operand immI_56() 4446 %{ 4447 predicate(n->get_int() == 56); 4448 match(ConI); 4449 4450 op_cost(0); 4451 format %{ %} 4452 interface(CONST_INTER); 4453 %} 4454 4455 operand immI_64() 4456 %{ 4457 predicate(n->get_int() == 64); 4458 match(ConI); 4459 4460 op_cost(0); 4461 format %{ %} 4462 interface(CONST_INTER); 4463 %} 4464 4465 operand immI_255() 4466 %{ 4467 predicate(n->get_int() == 255); 4468 match(ConI); 4469 4470 op_cost(0); 4471 format %{ %} 4472 interface(CONST_INTER); 4473 %} 4474 4475 operand immI_65535() 4476 %{ 4477 predicate(n->get_int() == 65535); 4478 match(ConI); 4479 4480 op_cost(0); 4481 format %{ %} 4482 interface(CONST_INTER); 4483 %} 4484 4485 operand immL_63() 4486 %{ 4487 predicate(n->get_int() == 63); 4488 match(ConI); 4489 4490 op_cost(0); 4491 format %{ %} 4492 interface(CONST_INTER); 4493 %} 4494 4495 operand immL_255() 4496 %{ 4497 predicate(n->get_int() == 255); 4498 match(ConI); 4499 4500 op_cost(0); 4501 format %{ %} 4502 interface(CONST_INTER); 4503 %} 4504 4505 operand immL_65535() 4506 %{ 4507 predicate(n->get_long() == 65535L); 4508 match(ConL); 4509 4510 op_cost(0); 4511 format %{ %} 4512 interface(CONST_INTER); 4513 %} 4514 4515 operand immL_4294967295() 4516 %{ 4517 predicate(n->get_long() == 4294967295L); 4518 match(ConL); 4519 4520 op_cost(0); 4521 format %{ %} 4522 interface(CONST_INTER); 4523 %} 4524 4525 operand immL_bitmask() 4526 %{ 4527 predicate(((n->get_long() & 0xc000000000000000l) == 0) 4528 && is_power_of_2(n->get_long() + 1)); 4529 match(ConL); 4530 4531 op_cost(0); 4532 format %{ %} 4533 interface(CONST_INTER); 4534 %} 4535 4536 operand immI_bitmask() 4537 %{ 4538 predicate(((n->get_int() & 0xc0000000) == 0) 4539 && is_power_of_2(n->get_int() + 1)); 4540 match(ConI); 4541 4542 op_cost(0); 4543 format %{ %} 4544 interface(CONST_INTER); 4545 %} 4546 4547 // Scale values for scaled offset addressing modes (up to long but not quad) 4548 operand immIScale() 4549 %{ 4550 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4551 match(ConI); 4552 4553 op_cost(0); 4554 format %{ %} 4555 interface(CONST_INTER); 4556 %} 4557 4558 // 26 bit signed offset -- for pc-relative branches 4559 operand immI26() 4560 %{ 4561 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4562 match(ConI); 4563 4564 op_cost(0); 4565 format %{ %} 4566 interface(CONST_INTER); 4567 %} 4568 4569 // 19 bit signed offset -- for pc-relative loads 4570 operand immI19() 4571 %{ 4572 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4573 match(ConI); 4574 4575 op_cost(0); 4576 format %{ %} 4577 interface(CONST_INTER); 4578 %} 4579 4580 // 12 bit unsigned offset -- for base plus immediate loads 4581 operand immIU12() 4582 %{ 4583 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4584 match(ConI); 4585 4586 op_cost(0); 4587 format %{ %} 4588 interface(CONST_INTER); 4589 %} 4590 4591 operand immLU12() 4592 %{ 4593 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4594 match(ConL); 4595 4596 op_cost(0); 4597 format %{ %} 4598 interface(CONST_INTER); 4599 %} 4600 4601 // Offset for scaled or unscaled immediate loads and stores 4602 operand immIOffset() 4603 %{ 4604 predicate(Address::offset_ok_for_immed(n->get_int())); 4605 match(ConI); 4606 4607 op_cost(0); 4608 format %{ %} 4609 interface(CONST_INTER); 4610 %} 4611 4612 operand immLoffset() 4613 %{ 4614 predicate(Address::offset_ok_for_immed(n->get_long())); 4615 match(ConL); 4616 4617 op_cost(0); 4618 format %{ %} 4619 interface(CONST_INTER); 4620 %} 4621 4622 // 32 bit integer valid for add sub immediate 4623 operand immIAddSub() 4624 %{ 4625 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4626 match(ConI); 4627 op_cost(0); 4628 format %{ %} 4629 interface(CONST_INTER); 4630 %} 4631 4632 // 32 bit unsigned integer valid for logical immediate 4633 // TODO -- check this is right when e.g the mask is 0x80000000 4634 operand immILog() 4635 %{ 4636 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4637 match(ConI); 4638 4639 op_cost(0); 4640 format %{ %} 4641 interface(CONST_INTER); 4642 %} 4643 4644 // Integer operands 64 bit 4645 // 64 bit immediate 4646 operand immL() 4647 %{ 4648 match(ConL); 4649 4650 op_cost(0); 4651 format %{ %} 4652 interface(CONST_INTER); 4653 %} 4654 4655 // 64 bit zero 4656 operand immL0() 4657 %{ 4658 predicate(n->get_long() == 0); 4659 match(ConL); 4660 4661 op_cost(0); 4662 format %{ %} 4663 interface(CONST_INTER); 4664 %} 4665 4666 // 64 bit unit increment 4667 operand immL_1() 4668 %{ 4669 predicate(n->get_long() == 1); 4670 match(ConL); 4671 4672 op_cost(0); 4673 format %{ %} 4674 interface(CONST_INTER); 4675 %} 4676 4677 // 64 bit unit decrement 4678 operand immL_M1() 4679 %{ 4680 predicate(n->get_long() == -1); 4681 match(ConL); 4682 4683 op_cost(0); 4684 format %{ %} 4685 interface(CONST_INTER); 4686 %} 4687 4688 // 32 bit offset of pc in thread anchor 4689 4690 operand immL_pc_off() 4691 %{ 4692 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4693 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4694 match(ConL); 4695 4696 op_cost(0); 4697 format %{ %} 4698 interface(CONST_INTER); 4699 %} 4700 4701 // 64 bit integer valid for add sub immediate 4702 operand immLAddSub() 4703 %{ 4704 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4705 match(ConL); 4706 op_cost(0); 4707 format %{ %} 4708 interface(CONST_INTER); 4709 %} 4710 4711 // 64 bit integer valid for logical immediate 4712 operand immLLog() 4713 %{ 4714 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4715 match(ConL); 4716 op_cost(0); 4717 format %{ %} 4718 interface(CONST_INTER); 4719 %} 4720 4721 // Long Immediate: low 32-bit mask 4722 operand immL_32bits() 4723 %{ 4724 predicate(n->get_long() == 0xFFFFFFFFL); 4725 match(ConL); 4726 op_cost(0); 4727 format %{ %} 4728 interface(CONST_INTER); 4729 %} 4730 4731 // Pointer operands 4732 // Pointer Immediate 4733 operand immP() 4734 %{ 4735 match(ConP); 4736 4737 op_cost(0); 4738 format %{ %} 4739 interface(CONST_INTER); 4740 %} 4741 4742 // NULL Pointer Immediate 4743 operand immP0() 4744 %{ 4745 predicate(n->get_ptr() == 0); 4746 match(ConP); 4747 4748 op_cost(0); 4749 format %{ %} 4750 interface(CONST_INTER); 4751 %} 4752 4753 // Pointer Immediate One 4754 // this is used in object initialization (initial object header) 4755 operand immP_1() 4756 %{ 4757 predicate(n->get_ptr() == 1); 4758 match(ConP); 4759 4760 op_cost(0); 4761 format %{ %} 4762 interface(CONST_INTER); 4763 %} 4764 4765 // Polling Page Pointer Immediate 4766 operand immPollPage() 4767 %{ 4768 predicate((address)n->get_ptr() == os::get_polling_page()); 4769 match(ConP); 4770 4771 op_cost(0); 4772 format %{ %} 4773 interface(CONST_INTER); 4774 %} 4775 4776 // Card Table Byte Map Base 4777 operand immByteMapBase() 4778 %{ 4779 // Get base of card map 4780 predicate((jbyte*)n->get_ptr() == 4781 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); 4782 match(ConP); 4783 4784 op_cost(0); 4785 format %{ %} 4786 interface(CONST_INTER); 4787 %} 4788 4789 // Pointer Immediate Minus One 4790 // this is used when we want to write the current PC to the thread anchor 4791 operand immP_M1() 4792 %{ 4793 predicate(n->get_ptr() == -1); 4794 match(ConP); 4795 4796 op_cost(0); 4797 format %{ %} 4798 interface(CONST_INTER); 4799 %} 4800 4801 // Pointer Immediate Minus Two 4802 // this is used when we want to write the current PC to the thread anchor 4803 operand immP_M2() 4804 %{ 4805 predicate(n->get_ptr() == -2); 4806 match(ConP); 4807 4808 op_cost(0); 4809 format %{ %} 4810 interface(CONST_INTER); 4811 %} 4812 4813 // Float and Double operands 4814 // Double Immediate 4815 operand immD() 4816 %{ 4817 match(ConD); 4818 op_cost(0); 4819 format %{ %} 4820 interface(CONST_INTER); 4821 %} 4822 4823 // Double Immediate: +0.0d 4824 operand immD0() 4825 %{ 4826 predicate(jlong_cast(n->getd()) == 0); 4827 match(ConD); 4828 4829 op_cost(0); 4830 format %{ %} 4831 interface(CONST_INTER); 4832 %} 4833 4834 // constant 'double +0.0'. 4835 operand immDPacked() 4836 %{ 4837 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4838 match(ConD); 4839 op_cost(0); 4840 format %{ %} 4841 interface(CONST_INTER); 4842 %} 4843 4844 // Float Immediate 4845 operand immF() 4846 %{ 4847 match(ConF); 4848 op_cost(0); 4849 format %{ %} 4850 interface(CONST_INTER); 4851 %} 4852 4853 // Float Immediate: +0.0f. 4854 operand immF0() 4855 %{ 4856 predicate(jint_cast(n->getf()) == 0); 4857 match(ConF); 4858 4859 op_cost(0); 4860 format %{ %} 4861 interface(CONST_INTER); 4862 %} 4863 4864 // 4865 operand immFPacked() 4866 %{ 4867 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4868 match(ConF); 4869 op_cost(0); 4870 format %{ %} 4871 interface(CONST_INTER); 4872 %} 4873 4874 // Narrow pointer operands 4875 // Narrow Pointer Immediate 4876 operand immN() 4877 %{ 4878 match(ConN); 4879 4880 op_cost(0); 4881 format %{ %} 4882 interface(CONST_INTER); 4883 %} 4884 4885 // Narrow NULL Pointer Immediate 4886 operand immN0() 4887 %{ 4888 predicate(n->get_narrowcon() == 0); 4889 match(ConN); 4890 4891 op_cost(0); 4892 format %{ %} 4893 interface(CONST_INTER); 4894 %} 4895 4896 operand immNKlass() 4897 %{ 4898 match(ConNKlass); 4899 4900 op_cost(0); 4901 format %{ %} 4902 interface(CONST_INTER); 4903 %} 4904 4905 // Integer 32 bit Register Operands 4906 // Integer 32 bitRegister (excludes SP) 4907 operand iRegI() 4908 %{ 4909 constraint(ALLOC_IN_RC(any_reg32)); 4910 match(RegI); 4911 match(iRegINoSp); 4912 op_cost(0); 4913 format %{ %} 4914 interface(REG_INTER); 4915 %} 4916 4917 // Integer 32 bit Register not Special 4918 operand iRegINoSp() 4919 %{ 4920 constraint(ALLOC_IN_RC(no_special_reg32)); 4921 match(RegI); 4922 op_cost(0); 4923 format %{ %} 4924 interface(REG_INTER); 4925 %} 4926 4927 // Integer 64 bit Register Operands 4928 // Integer 64 bit Register (includes SP) 4929 operand iRegL() 4930 %{ 4931 constraint(ALLOC_IN_RC(any_reg)); 4932 match(RegL); 4933 match(iRegLNoSp); 4934 op_cost(0); 4935 format %{ %} 4936 interface(REG_INTER); 4937 %} 4938 4939 // Integer 64 bit Register not Special 4940 operand iRegLNoSp() 4941 %{ 4942 constraint(ALLOC_IN_RC(no_special_reg)); 4943 match(RegL); 4944 format %{ %} 4945 interface(REG_INTER); 4946 %} 4947 4948 // Pointer Register Operands 4949 // Pointer Register 4950 operand iRegP() 4951 %{ 4952 constraint(ALLOC_IN_RC(ptr_reg)); 4953 match(RegP); 4954 match(iRegPNoSp); 4955 match(iRegP_R0); 4956 //match(iRegP_R2); 4957 //match(iRegP_R4); 4958 //match(iRegP_R5); 4959 match(thread_RegP); 4960 op_cost(0); 4961 format %{ %} 4962 interface(REG_INTER); 4963 %} 4964 4965 // Pointer 64 bit Register not Special 4966 operand iRegPNoSp() 4967 %{ 4968 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4969 match(RegP); 4970 // match(iRegP); 4971 // match(iRegP_R0); 4972 // match(iRegP_R2); 4973 // match(iRegP_R4); 4974 // match(iRegP_R5); 4975 // match(thread_RegP); 4976 op_cost(0); 4977 format %{ %} 4978 interface(REG_INTER); 4979 %} 4980 4981 // Pointer 64 bit Register R0 only 4982 operand iRegP_R0() 4983 %{ 4984 constraint(ALLOC_IN_RC(r0_reg)); 4985 match(RegP); 4986 // match(iRegP); 4987 match(iRegPNoSp); 4988 op_cost(0); 4989 format %{ %} 4990 interface(REG_INTER); 4991 %} 4992 4993 // Pointer 64 bit Register R1 only 4994 operand iRegP_R1() 4995 %{ 4996 constraint(ALLOC_IN_RC(r1_reg)); 4997 match(RegP); 4998 // match(iRegP); 4999 match(iRegPNoSp); 5000 op_cost(0); 5001 format %{ %} 5002 interface(REG_INTER); 5003 %} 5004 5005 // Pointer 64 bit Register R2 only 5006 operand iRegP_R2() 5007 %{ 5008 constraint(ALLOC_IN_RC(r2_reg)); 5009 match(RegP); 5010 // match(iRegP); 5011 match(iRegPNoSp); 5012 op_cost(0); 5013 format %{ %} 5014 interface(REG_INTER); 5015 %} 5016 5017 // Pointer 64 bit Register R3 only 5018 operand iRegP_R3() 5019 %{ 5020 constraint(ALLOC_IN_RC(r3_reg)); 5021 match(RegP); 5022 // match(iRegP); 5023 match(iRegPNoSp); 5024 op_cost(0); 5025 format %{ %} 5026 interface(REG_INTER); 5027 %} 5028 5029 // Pointer 64 bit Register R4 only 5030 operand iRegP_R4() 5031 %{ 5032 constraint(ALLOC_IN_RC(r4_reg)); 5033 match(RegP); 5034 // match(iRegP); 5035 match(iRegPNoSp); 5036 op_cost(0); 5037 format %{ %} 5038 interface(REG_INTER); 5039 %} 5040 5041 // Pointer 64 bit Register R5 only 5042 operand iRegP_R5() 5043 %{ 5044 constraint(ALLOC_IN_RC(r5_reg)); 5045 match(RegP); 5046 // match(iRegP); 5047 match(iRegPNoSp); 5048 op_cost(0); 5049 format %{ %} 5050 interface(REG_INTER); 5051 %} 5052 5053 // Pointer 64 bit Register R10 only 5054 operand iRegP_R10() 5055 %{ 5056 constraint(ALLOC_IN_RC(r10_reg)); 5057 match(RegP); 5058 // match(iRegP); 5059 match(iRegPNoSp); 5060 op_cost(0); 5061 format %{ %} 5062 interface(REG_INTER); 5063 %} 5064 5065 // Long 64 bit Register R11 only 5066 operand iRegL_R11() 5067 %{ 5068 constraint(ALLOC_IN_RC(r11_reg)); 5069 match(RegL); 5070 match(iRegLNoSp); 5071 op_cost(0); 5072 format %{ %} 5073 interface(REG_INTER); 5074 %} 5075 5076 // Pointer 64 bit Register FP only 5077 operand iRegP_FP() 5078 %{ 5079 constraint(ALLOC_IN_RC(fp_reg)); 5080 match(RegP); 5081 // match(iRegP); 5082 op_cost(0); 5083 format %{ %} 5084 interface(REG_INTER); 5085 %} 5086 5087 // Register R0 only 5088 operand iRegI_R0() 5089 %{ 5090 constraint(ALLOC_IN_RC(int_r0_reg)); 5091 match(RegI); 5092 match(iRegINoSp); 5093 op_cost(0); 5094 format %{ %} 5095 interface(REG_INTER); 5096 %} 5097 5098 // Register R2 only 5099 operand iRegI_R2() 5100 %{ 5101 constraint(ALLOC_IN_RC(int_r2_reg)); 5102 match(RegI); 5103 match(iRegINoSp); 5104 op_cost(0); 5105 format %{ %} 5106 interface(REG_INTER); 5107 %} 5108 5109 // Register R3 only 5110 operand iRegI_R3() 5111 %{ 5112 constraint(ALLOC_IN_RC(int_r3_reg)); 5113 match(RegI); 5114 match(iRegINoSp); 5115 op_cost(0); 5116 format %{ %} 5117 interface(REG_INTER); 5118 %} 5119 5120 5121 // Register R2 only 5122 operand iRegI_R4() 5123 %{ 5124 constraint(ALLOC_IN_RC(int_r4_reg)); 5125 match(RegI); 5126 match(iRegINoSp); 5127 op_cost(0); 5128 format %{ %} 5129 interface(REG_INTER); 5130 %} 5131 5132 5133 // Pointer Register Operands 5134 // Narrow Pointer Register 5135 operand iRegN() 5136 %{ 5137 constraint(ALLOC_IN_RC(any_reg32)); 5138 match(RegN); 5139 match(iRegNNoSp); 5140 op_cost(0); 5141 format %{ %} 5142 interface(REG_INTER); 5143 %} 5144 5145 // Integer 64 bit Register not Special 5146 operand iRegNNoSp() 5147 %{ 5148 constraint(ALLOC_IN_RC(no_special_reg32)); 5149 match(RegN); 5150 op_cost(0); 5151 format %{ %} 5152 interface(REG_INTER); 5153 %} 5154 5155 // heap base register -- used for encoding immN0 5156 5157 operand iRegIHeapbase() 5158 %{ 5159 constraint(ALLOC_IN_RC(heapbase_reg)); 5160 match(RegI); 5161 op_cost(0); 5162 format %{ %} 5163 interface(REG_INTER); 5164 %} 5165 5166 // Float Register 5167 // Float register operands 5168 operand vRegF() 5169 %{ 5170 constraint(ALLOC_IN_RC(float_reg)); 5171 match(RegF); 5172 5173 op_cost(0); 5174 format %{ %} 5175 interface(REG_INTER); 5176 %} 5177 5178 // Double Register 5179 // Double register operands 5180 operand vRegD() 5181 %{ 5182 constraint(ALLOC_IN_RC(double_reg)); 5183 match(RegD); 5184 5185 op_cost(0); 5186 format %{ %} 5187 interface(REG_INTER); 5188 %} 5189 5190 operand vecX() 5191 %{ 5192 constraint(ALLOC_IN_RC(vectorx_reg)); 5193 match(VecX); 5194 5195 op_cost(0); 5196 format %{ %} 5197 interface(REG_INTER); 5198 %} 5199 5200 operand vRegD_V0() 5201 %{ 5202 constraint(ALLOC_IN_RC(v0_reg)); 5203 match(RegD); 5204 op_cost(0); 5205 format %{ %} 5206 interface(REG_INTER); 5207 %} 5208 5209 operand vRegD_V1() 5210 %{ 5211 constraint(ALLOC_IN_RC(v1_reg)); 5212 match(RegD); 5213 op_cost(0); 5214 format %{ %} 5215 interface(REG_INTER); 5216 %} 5217 5218 operand vRegD_V2() 5219 %{ 5220 constraint(ALLOC_IN_RC(v2_reg)); 5221 match(RegD); 5222 op_cost(0); 5223 format %{ %} 5224 interface(REG_INTER); 5225 %} 5226 5227 operand vRegD_V3() 5228 %{ 5229 constraint(ALLOC_IN_RC(v3_reg)); 5230 match(RegD); 5231 op_cost(0); 5232 format %{ %} 5233 interface(REG_INTER); 5234 %} 5235 5236 // Flags register, used as output of signed compare instructions 5237 5238 // note that on AArch64 we also use this register as the output for 5239 // for floating point compare instructions (CmpF CmpD). this ensures 5240 // that ordered inequality tests use GT, GE, LT or LE none of which 5241 // pass through cases where the result is unordered i.e. one or both 5242 // inputs to the compare is a NaN. this means that the ideal code can 5243 // replace e.g. a GT with an LE and not end up capturing the NaN case 5244 // (where the comparison should always fail). EQ and NE tests are 5245 // always generated in ideal code so that unordered folds into the NE 5246 // case, matching the behaviour of AArch64 NE. 5247 // 5248 // This differs from x86 where the outputs of FP compares use a 5249 // special FP flags registers and where compares based on this 5250 // register are distinguished into ordered inequalities (cmpOpUCF) and 5251 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5252 // to explicitly handle the unordered case in branches. x86 also has 5253 // to include extra CMoveX rules to accept a cmpOpUCF input. 5254 5255 operand rFlagsReg() 5256 %{ 5257 constraint(ALLOC_IN_RC(int_flags)); 5258 match(RegFlags); 5259 5260 op_cost(0); 5261 format %{ "RFLAGS" %} 5262 interface(REG_INTER); 5263 %} 5264 5265 // Flags register, used as output of unsigned compare instructions 5266 operand rFlagsRegU() 5267 %{ 5268 constraint(ALLOC_IN_RC(int_flags)); 5269 match(RegFlags); 5270 5271 op_cost(0); 5272 format %{ "RFLAGSU" %} 5273 interface(REG_INTER); 5274 %} 5275 5276 // Special Registers 5277 5278 // Method Register 5279 operand inline_cache_RegP(iRegP reg) 5280 %{ 5281 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5282 match(reg); 5283 match(iRegPNoSp); 5284 op_cost(0); 5285 format %{ %} 5286 interface(REG_INTER); 5287 %} 5288 5289 operand interpreter_method_oop_RegP(iRegP reg) 5290 %{ 5291 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5292 match(reg); 5293 match(iRegPNoSp); 5294 op_cost(0); 5295 format %{ %} 5296 interface(REG_INTER); 5297 %} 5298 5299 // Thread Register 5300 operand thread_RegP(iRegP reg) 5301 %{ 5302 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5303 match(reg); 5304 op_cost(0); 5305 format %{ %} 5306 interface(REG_INTER); 5307 %} 5308 5309 operand lr_RegP(iRegP reg) 5310 %{ 5311 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5312 match(reg); 5313 op_cost(0); 5314 format %{ %} 5315 interface(REG_INTER); 5316 %} 5317 5318 //----------Memory Operands---------------------------------------------------- 5319 5320 operand indirect(iRegP reg) 5321 %{ 5322 constraint(ALLOC_IN_RC(ptr_reg)); 5323 match(reg); 5324 op_cost(0); 5325 format %{ "[$reg]" %} 5326 interface(MEMORY_INTER) %{ 5327 base($reg); 5328 index(0xffffffff); 5329 scale(0x0); 5330 disp(0x0); 5331 %} 5332 %} 5333 5334 operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off) 5335 %{ 5336 constraint(ALLOC_IN_RC(ptr_reg)); 5337 match(AddP (AddP reg (LShiftL lreg scale)) off); 5338 op_cost(INSN_COST); 5339 format %{ "$reg, $lreg lsl($scale), $off" %} 5340 interface(MEMORY_INTER) %{ 5341 base($reg); 5342 index($lreg); 5343 scale($scale); 5344 disp($off); 5345 %} 5346 %} 5347 5348 operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off) 5349 %{ 5350 constraint(ALLOC_IN_RC(ptr_reg)); 5351 match(AddP (AddP reg (LShiftL lreg scale)) off); 5352 op_cost(INSN_COST); 5353 format %{ "$reg, $lreg lsl($scale), $off" %} 5354 interface(MEMORY_INTER) %{ 5355 base($reg); 5356 index($lreg); 5357 scale($scale); 5358 disp($off); 5359 %} 5360 %} 5361 5362 operand indIndexOffsetI2L(iRegP reg, iRegI ireg, immLU12 off) 5363 %{ 5364 constraint(ALLOC_IN_RC(ptr_reg)); 5365 match(AddP (AddP reg (ConvI2L ireg)) off); 5366 op_cost(INSN_COST); 5367 format %{ "$reg, $ireg, $off I2L" %} 5368 interface(MEMORY_INTER) %{ 5369 base($reg); 5370 index($ireg); 5371 scale(0x0); 5372 disp($off); 5373 %} 5374 %} 5375 5376 operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off) 5377 %{ 5378 constraint(ALLOC_IN_RC(ptr_reg)); 5379 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off); 5380 op_cost(INSN_COST); 5381 format %{ "$reg, $ireg sxtw($scale), $off I2L" %} 5382 interface(MEMORY_INTER) %{ 5383 base($reg); 5384 index($ireg); 5385 scale($scale); 5386 disp($off); 5387 %} 5388 %} 5389 5390 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5391 %{ 5392 constraint(ALLOC_IN_RC(ptr_reg)); 5393 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5394 op_cost(0); 5395 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5396 interface(MEMORY_INTER) %{ 5397 base($reg); 5398 index($ireg); 5399 scale($scale); 5400 disp(0x0); 5401 %} 5402 %} 5403 5404 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5405 %{ 5406 constraint(ALLOC_IN_RC(ptr_reg)); 5407 match(AddP reg (LShiftL lreg scale)); 5408 op_cost(0); 5409 format %{ "$reg, $lreg lsl($scale)" %} 5410 interface(MEMORY_INTER) %{ 5411 base($reg); 5412 index($lreg); 5413 scale($scale); 5414 disp(0x0); 5415 %} 5416 %} 5417 5418 operand indIndex(iRegP reg, iRegL lreg) 5419 %{ 5420 constraint(ALLOC_IN_RC(ptr_reg)); 5421 match(AddP reg lreg); 5422 op_cost(0); 5423 format %{ "$reg, $lreg" %} 5424 interface(MEMORY_INTER) %{ 5425 base($reg); 5426 index($lreg); 5427 scale(0x0); 5428 disp(0x0); 5429 %} 5430 %} 5431 5432 operand indOffI(iRegP reg, immIOffset off) 5433 %{ 5434 constraint(ALLOC_IN_RC(ptr_reg)); 5435 match(AddP reg off); 5436 op_cost(0); 5437 format %{ "[$reg, $off]" %} 5438 interface(MEMORY_INTER) %{ 5439 base($reg); 5440 index(0xffffffff); 5441 scale(0x0); 5442 disp($off); 5443 %} 5444 %} 5445 5446 operand indOffL(iRegP reg, immLoffset off) 5447 %{ 5448 constraint(ALLOC_IN_RC(ptr_reg)); 5449 match(AddP reg off); 5450 op_cost(0); 5451 format %{ "[$reg, $off]" %} 5452 interface(MEMORY_INTER) %{ 5453 base($reg); 5454 index(0xffffffff); 5455 scale(0x0); 5456 disp($off); 5457 %} 5458 %} 5459 5460 5461 operand indirectN(iRegN reg) 5462 %{ 5463 predicate(Universe::narrow_oop_shift() == 0); 5464 constraint(ALLOC_IN_RC(ptr_reg)); 5465 match(DecodeN reg); 5466 op_cost(0); 5467 format %{ "[$reg]\t# narrow" %} 5468 interface(MEMORY_INTER) %{ 5469 base($reg); 5470 index(0xffffffff); 5471 scale(0x0); 5472 disp(0x0); 5473 %} 5474 %} 5475 5476 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off) 5477 %{ 5478 predicate(Universe::narrow_oop_shift() == 0); 5479 constraint(ALLOC_IN_RC(ptr_reg)); 5480 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5481 op_cost(0); 5482 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5483 interface(MEMORY_INTER) %{ 5484 base($reg); 5485 index($lreg); 5486 scale($scale); 5487 disp($off); 5488 %} 5489 %} 5490 5491 operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off) 5492 %{ 5493 predicate(Universe::narrow_oop_shift() == 0); 5494 constraint(ALLOC_IN_RC(ptr_reg)); 5495 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5496 op_cost(INSN_COST); 5497 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5498 interface(MEMORY_INTER) %{ 5499 base($reg); 5500 index($lreg); 5501 scale($scale); 5502 disp($off); 5503 %} 5504 %} 5505 5506 operand indIndexOffsetI2LN(iRegN reg, iRegI ireg, immLU12 off) 5507 %{ 5508 predicate(Universe::narrow_oop_shift() == 0); 5509 constraint(ALLOC_IN_RC(ptr_reg)); 5510 match(AddP (AddP (DecodeN reg) (ConvI2L ireg)) off); 5511 op_cost(INSN_COST); 5512 format %{ "$reg, $ireg, $off I2L\t# narrow" %} 5513 interface(MEMORY_INTER) %{ 5514 base($reg); 5515 index($ireg); 5516 scale(0x0); 5517 disp($off); 5518 %} 5519 %} 5520 5521 operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off) 5522 %{ 5523 predicate(Universe::narrow_oop_shift() == 0); 5524 constraint(ALLOC_IN_RC(ptr_reg)); 5525 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off); 5526 op_cost(INSN_COST); 5527 format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %} 5528 interface(MEMORY_INTER) %{ 5529 base($reg); 5530 index($ireg); 5531 scale($scale); 5532 disp($off); 5533 %} 5534 %} 5535 5536 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5537 %{ 5538 predicate(Universe::narrow_oop_shift() == 0); 5539 constraint(ALLOC_IN_RC(ptr_reg)); 5540 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5541 op_cost(0); 5542 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5543 interface(MEMORY_INTER) %{ 5544 base($reg); 5545 index($ireg); 5546 scale($scale); 5547 disp(0x0); 5548 %} 5549 %} 5550 5551 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5552 %{ 5553 predicate(Universe::narrow_oop_shift() == 0); 5554 constraint(ALLOC_IN_RC(ptr_reg)); 5555 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5556 op_cost(0); 5557 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5558 interface(MEMORY_INTER) %{ 5559 base($reg); 5560 index($lreg); 5561 scale($scale); 5562 disp(0x0); 5563 %} 5564 %} 5565 5566 operand indIndexN(iRegN reg, iRegL lreg) 5567 %{ 5568 predicate(Universe::narrow_oop_shift() == 0); 5569 constraint(ALLOC_IN_RC(ptr_reg)); 5570 match(AddP (DecodeN reg) lreg); 5571 op_cost(0); 5572 format %{ "$reg, $lreg\t# narrow" %} 5573 interface(MEMORY_INTER) %{ 5574 base($reg); 5575 index($lreg); 5576 scale(0x0); 5577 disp(0x0); 5578 %} 5579 %} 5580 5581 operand indOffIN(iRegN reg, immIOffset off) 5582 %{ 5583 predicate(Universe::narrow_oop_shift() == 0); 5584 constraint(ALLOC_IN_RC(ptr_reg)); 5585 match(AddP (DecodeN reg) off); 5586 op_cost(0); 5587 format %{ "[$reg, $off]\t# narrow" %} 5588 interface(MEMORY_INTER) %{ 5589 base($reg); 5590 index(0xffffffff); 5591 scale(0x0); 5592 disp($off); 5593 %} 5594 %} 5595 5596 operand indOffLN(iRegN reg, immLoffset off) 5597 %{ 5598 predicate(Universe::narrow_oop_shift() == 0); 5599 constraint(ALLOC_IN_RC(ptr_reg)); 5600 match(AddP (DecodeN reg) off); 5601 op_cost(0); 5602 format %{ "[$reg, $off]\t# narrow" %} 5603 interface(MEMORY_INTER) %{ 5604 base($reg); 5605 index(0xffffffff); 5606 scale(0x0); 5607 disp($off); 5608 %} 5609 %} 5610 5611 5612 5613 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5614 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5615 %{ 5616 constraint(ALLOC_IN_RC(ptr_reg)); 5617 match(AddP reg off); 5618 op_cost(0); 5619 format %{ "[$reg, $off]" %} 5620 interface(MEMORY_INTER) %{ 5621 base($reg); 5622 index(0xffffffff); 5623 scale(0x0); 5624 disp($off); 5625 %} 5626 %} 5627 5628 //----------Special Memory Operands-------------------------------------------- 5629 // Stack Slot Operand - This operand is used for loading and storing temporary 5630 // values on the stack where a match requires a value to 5631 // flow through memory. 5632 operand stackSlotP(sRegP reg) 5633 %{ 5634 constraint(ALLOC_IN_RC(stack_slots)); 5635 op_cost(100); 5636 // No match rule because this operand is only generated in matching 5637 // match(RegP); 5638 format %{ "[$reg]" %} 5639 interface(MEMORY_INTER) %{ 5640 base(0x1e); // RSP 5641 index(0x0); // No Index 5642 scale(0x0); // No Scale 5643 disp($reg); // Stack Offset 5644 %} 5645 %} 5646 5647 operand stackSlotI(sRegI reg) 5648 %{ 5649 constraint(ALLOC_IN_RC(stack_slots)); 5650 // No match rule because this operand is only generated in matching 5651 // match(RegI); 5652 format %{ "[$reg]" %} 5653 interface(MEMORY_INTER) %{ 5654 base(0x1e); // RSP 5655 index(0x0); // No Index 5656 scale(0x0); // No Scale 5657 disp($reg); // Stack Offset 5658 %} 5659 %} 5660 5661 operand stackSlotF(sRegF reg) 5662 %{ 5663 constraint(ALLOC_IN_RC(stack_slots)); 5664 // No match rule because this operand is only generated in matching 5665 // match(RegF); 5666 format %{ "[$reg]" %} 5667 interface(MEMORY_INTER) %{ 5668 base(0x1e); // RSP 5669 index(0x0); // No Index 5670 scale(0x0); // No Scale 5671 disp($reg); // Stack Offset 5672 %} 5673 %} 5674 5675 operand stackSlotD(sRegD reg) 5676 %{ 5677 constraint(ALLOC_IN_RC(stack_slots)); 5678 // No match rule because this operand is only generated in matching 5679 // match(RegD); 5680 format %{ "[$reg]" %} 5681 interface(MEMORY_INTER) %{ 5682 base(0x1e); // RSP 5683 index(0x0); // No Index 5684 scale(0x0); // No Scale 5685 disp($reg); // Stack Offset 5686 %} 5687 %} 5688 5689 operand stackSlotL(sRegL reg) 5690 %{ 5691 constraint(ALLOC_IN_RC(stack_slots)); 5692 // No match rule because this operand is only generated in matching 5693 // match(RegL); 5694 format %{ "[$reg]" %} 5695 interface(MEMORY_INTER) %{ 5696 base(0x1e); // RSP 5697 index(0x0); // No Index 5698 scale(0x0); // No Scale 5699 disp($reg); // Stack Offset 5700 %} 5701 %} 5702 5703 // Operands for expressing Control Flow 5704 // NOTE: Label is a predefined operand which should not be redefined in 5705 // the AD file. It is generically handled within the ADLC. 5706 5707 //----------Conditional Branch Operands---------------------------------------- 5708 // Comparison Op - This is the operation of the comparison, and is limited to 5709 // the following set of codes: 5710 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5711 // 5712 // Other attributes of the comparison, such as unsignedness, are specified 5713 // by the comparison instruction that sets a condition code flags register. 5714 // That result is represented by a flags operand whose subtype is appropriate 5715 // to the unsignedness (etc.) of the comparison. 5716 // 5717 // Later, the instruction which matches both the Comparison Op (a Bool) and 5718 // the flags (produced by the Cmp) specifies the coding of the comparison op 5719 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5720 5721 // used for signed integral comparisons and fp comparisons 5722 5723 operand cmpOp() 5724 %{ 5725 match(Bool); 5726 5727 format %{ "" %} 5728 interface(COND_INTER) %{ 5729 equal(0x0, "eq"); 5730 not_equal(0x1, "ne"); 5731 less(0xb, "lt"); 5732 greater_equal(0xa, "ge"); 5733 less_equal(0xd, "le"); 5734 greater(0xc, "gt"); 5735 overflow(0x6, "vs"); 5736 no_overflow(0x7, "vc"); 5737 %} 5738 %} 5739 5740 // used for unsigned integral comparisons 5741 5742 operand cmpOpU() 5743 %{ 5744 match(Bool); 5745 5746 format %{ "" %} 5747 interface(COND_INTER) %{ 5748 equal(0x0, "eq"); 5749 not_equal(0x1, "ne"); 5750 less(0x3, "lo"); 5751 greater_equal(0x2, "hs"); 5752 less_equal(0x9, "ls"); 5753 greater(0x8, "hi"); 5754 overflow(0x6, "vs"); 5755 no_overflow(0x7, "vc"); 5756 %} 5757 %} 5758 5759 // Special operand allowing long args to int ops to be truncated for free 5760 5761 operand iRegL2I(iRegL reg) %{ 5762 5763 op_cost(0); 5764 5765 match(ConvL2I reg); 5766 5767 format %{ "l2i($reg)" %} 5768 5769 interface(REG_INTER) 5770 %} 5771 5772 opclass vmem(indirect, indIndex, indOffI, indOffL); 5773 5774 //----------OPERAND CLASSES---------------------------------------------------- 5775 // Operand Classes are groups of operands that are used as to simplify 5776 // instruction definitions by not requiring the AD writer to specify 5777 // separate instructions for every form of operand when the 5778 // instruction accepts multiple operand types with the same basic 5779 // encoding and format. The classic case of this is memory operands. 5780 5781 // memory is used to define read/write location for load/store 5782 // instruction defs. we can turn a memory op into an Address 5783 5784 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL, 5785 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN); 5786 5787 5788 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5789 // operations. it allows the src to be either an iRegI or a (ConvL2I 5790 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5791 // can be elided because the 32-bit instruction will just employ the 5792 // lower 32 bits anyway. 5793 // 5794 // n.b. this does not elide all L2I conversions. if the truncated 5795 // value is consumed by more than one operation then the ConvL2I 5796 // cannot be bundled into the consuming nodes so an l2i gets planted 5797 // (actually a movw $dst $src) and the downstream instructions consume 5798 // the result of the l2i as an iRegI input. That's a shame since the 5799 // movw is actually redundant but its not too costly. 5800 5801 opclass iRegIorL2I(iRegI, iRegL2I); 5802 5803 //----------PIPELINE----------------------------------------------------------- 5804 // Rules which define the behavior of the target architectures pipeline. 5805 // Integer ALU reg operation 5806 pipeline %{ 5807 5808 attributes %{ 5809 // ARM instructions are of fixed length 5810 fixed_size_instructions; // Fixed size instructions TODO does 5811 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5812 // ARM instructions come in 32-bit word units 5813 instruction_unit_size = 4; // An instruction is 4 bytes long 5814 instruction_fetch_unit_size = 64; // The processor fetches one line 5815 instruction_fetch_units = 1; // of 64 bytes 5816 5817 // List of nop instructions 5818 nops( MachNop ); 5819 %} 5820 5821 // We don't use an actual pipeline model so don't care about resources 5822 // or description. we do use pipeline classes to introduce fixed 5823 // latencies 5824 5825 //----------RESOURCES---------------------------------------------------------- 5826 // Resources are the functional units available to the machine 5827 5828 resources( INS0, INS1, INS01 = INS0 | INS1, 5829 ALU0, ALU1, ALU = ALU0 | ALU1, 5830 MAC, 5831 DIV, 5832 BRANCH, 5833 LDST, 5834 NEON_FP); 5835 5836 //----------PIPELINE DESCRIPTION----------------------------------------------- 5837 // Pipeline Description specifies the stages in the machine's pipeline 5838 5839 pipe_desc(ISS, EX1, EX2, WR); 5840 5841 //----------PIPELINE CLASSES--------------------------------------------------- 5842 // Pipeline Classes describe the stages in which input and output are 5843 // referenced by the hardware pipeline. 5844 5845 //------- Integer ALU operations -------------------------- 5846 5847 // Integer ALU reg-reg operation 5848 // Operands needed in EX1, result generated in EX2 5849 // Eg. ADD x0, x1, x2 5850 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5851 %{ 5852 single_instruction; 5853 dst : EX2(write); 5854 src1 : EX1(read); 5855 src2 : EX1(read); 5856 INS01 : ISS; // Dual issue as instruction 0 or 1 5857 ALU : EX2; 5858 %} 5859 5860 // Integer ALU reg-reg operation with constant shift 5861 // Shifted register must be available in LATE_ISS instead of EX1 5862 // Eg. ADD x0, x1, x2, LSL #2 5863 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5864 %{ 5865 single_instruction; 5866 dst : EX2(write); 5867 src1 : EX1(read); 5868 src2 : ISS(read); 5869 INS01 : ISS; 5870 ALU : EX2; 5871 %} 5872 5873 // Integer ALU reg operation with constant shift 5874 // Eg. LSL x0, x1, #shift 5875 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5876 %{ 5877 single_instruction; 5878 dst : EX2(write); 5879 src1 : ISS(read); 5880 INS01 : ISS; 5881 ALU : EX2; 5882 %} 5883 5884 // Integer ALU reg-reg operation with variable shift 5885 // Both operands must be available in LATE_ISS instead of EX1 5886 // Result is available in EX1 instead of EX2 5887 // Eg. LSLV x0, x1, x2 5888 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5889 %{ 5890 single_instruction; 5891 dst : EX1(write); 5892 src1 : ISS(read); 5893 src2 : ISS(read); 5894 INS01 : ISS; 5895 ALU : EX1; 5896 %} 5897 5898 // Integer ALU reg-reg operation with extract 5899 // As for _vshift above, but result generated in EX2 5900 // Eg. EXTR x0, x1, x2, #N 5901 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 5902 %{ 5903 single_instruction; 5904 dst : EX2(write); 5905 src1 : ISS(read); 5906 src2 : ISS(read); 5907 INS1 : ISS; // Can only dual issue as Instruction 1 5908 ALU : EX1; 5909 %} 5910 5911 // Integer ALU reg operation 5912 // Eg. NEG x0, x1 5913 pipe_class ialu_reg(iRegI dst, iRegI src) 5914 %{ 5915 single_instruction; 5916 dst : EX2(write); 5917 src : EX1(read); 5918 INS01 : ISS; 5919 ALU : EX2; 5920 %} 5921 5922 // Integer ALU reg mmediate operation 5923 // Eg. ADD x0, x1, #N 5924 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 5925 %{ 5926 single_instruction; 5927 dst : EX2(write); 5928 src1 : EX1(read); 5929 INS01 : ISS; 5930 ALU : EX2; 5931 %} 5932 5933 // Integer ALU immediate operation (no source operands) 5934 // Eg. MOV x0, #N 5935 pipe_class ialu_imm(iRegI dst) 5936 %{ 5937 single_instruction; 5938 dst : EX1(write); 5939 INS01 : ISS; 5940 ALU : EX1; 5941 %} 5942 5943 //------- Compare operation ------------------------------- 5944 5945 // Compare reg-reg 5946 // Eg. CMP x0, x1 5947 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 5948 %{ 5949 single_instruction; 5950 // fixed_latency(16); 5951 cr : EX2(write); 5952 op1 : EX1(read); 5953 op2 : EX1(read); 5954 INS01 : ISS; 5955 ALU : EX2; 5956 %} 5957 5958 // Compare reg-reg 5959 // Eg. CMP x0, #N 5960 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 5961 %{ 5962 single_instruction; 5963 // fixed_latency(16); 5964 cr : EX2(write); 5965 op1 : EX1(read); 5966 INS01 : ISS; 5967 ALU : EX2; 5968 %} 5969 5970 //------- Conditional instructions ------------------------ 5971 5972 // Conditional no operands 5973 // Eg. CSINC x0, zr, zr, <cond> 5974 pipe_class icond_none(iRegI dst, rFlagsReg cr) 5975 %{ 5976 single_instruction; 5977 cr : EX1(read); 5978 dst : EX2(write); 5979 INS01 : ISS; 5980 ALU : EX2; 5981 %} 5982 5983 // Conditional 2 operand 5984 // EG. CSEL X0, X1, X2, <cond> 5985 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 5986 %{ 5987 single_instruction; 5988 cr : EX1(read); 5989 src1 : EX1(read); 5990 src2 : EX1(read); 5991 dst : EX2(write); 5992 INS01 : ISS; 5993 ALU : EX2; 5994 %} 5995 5996 // Conditional 2 operand 5997 // EG. CSEL X0, X1, X2, <cond> 5998 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 5999 %{ 6000 single_instruction; 6001 cr : EX1(read); 6002 src : EX1(read); 6003 dst : EX2(write); 6004 INS01 : ISS; 6005 ALU : EX2; 6006 %} 6007 6008 //------- Multiply pipeline operations -------------------- 6009 6010 // Multiply reg-reg 6011 // Eg. MUL w0, w1, w2 6012 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6013 %{ 6014 single_instruction; 6015 dst : WR(write); 6016 src1 : ISS(read); 6017 src2 : ISS(read); 6018 INS01 : ISS; 6019 MAC : WR; 6020 %} 6021 6022 // Multiply accumulate 6023 // Eg. MADD w0, w1, w2, w3 6024 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6025 %{ 6026 single_instruction; 6027 dst : WR(write); 6028 src1 : ISS(read); 6029 src2 : ISS(read); 6030 src3 : ISS(read); 6031 INS01 : ISS; 6032 MAC : WR; 6033 %} 6034 6035 // Eg. MUL w0, w1, w2 6036 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6037 %{ 6038 single_instruction; 6039 fixed_latency(3); // Maximum latency for 64 bit mul 6040 dst : WR(write); 6041 src1 : ISS(read); 6042 src2 : ISS(read); 6043 INS01 : ISS; 6044 MAC : WR; 6045 %} 6046 6047 // Multiply accumulate 6048 // Eg. MADD w0, w1, w2, w3 6049 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6050 %{ 6051 single_instruction; 6052 fixed_latency(3); // Maximum latency for 64 bit mul 6053 dst : WR(write); 6054 src1 : ISS(read); 6055 src2 : ISS(read); 6056 src3 : ISS(read); 6057 INS01 : ISS; 6058 MAC : WR; 6059 %} 6060 6061 //------- Divide pipeline operations -------------------- 6062 6063 // Eg. SDIV w0, w1, w2 6064 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6065 %{ 6066 single_instruction; 6067 fixed_latency(8); // Maximum latency for 32 bit divide 6068 dst : WR(write); 6069 src1 : ISS(read); 6070 src2 : ISS(read); 6071 INS0 : ISS; // Can only dual issue as instruction 0 6072 DIV : WR; 6073 %} 6074 6075 // Eg. SDIV x0, x1, x2 6076 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6077 %{ 6078 single_instruction; 6079 fixed_latency(16); // Maximum latency for 64 bit divide 6080 dst : WR(write); 6081 src1 : ISS(read); 6082 src2 : ISS(read); 6083 INS0 : ISS; // Can only dual issue as instruction 0 6084 DIV : WR; 6085 %} 6086 6087 //------- Load pipeline operations ------------------------ 6088 6089 // Load - prefetch 6090 // Eg. PFRM <mem> 6091 pipe_class iload_prefetch(memory mem) 6092 %{ 6093 single_instruction; 6094 mem : ISS(read); 6095 INS01 : ISS; 6096 LDST : WR; 6097 %} 6098 6099 // Load - reg, mem 6100 // Eg. LDR x0, <mem> 6101 pipe_class iload_reg_mem(iRegI dst, memory mem) 6102 %{ 6103 single_instruction; 6104 dst : WR(write); 6105 mem : ISS(read); 6106 INS01 : ISS; 6107 LDST : WR; 6108 %} 6109 6110 // Load - reg, reg 6111 // Eg. LDR x0, [sp, x1] 6112 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6113 %{ 6114 single_instruction; 6115 dst : WR(write); 6116 src : ISS(read); 6117 INS01 : ISS; 6118 LDST : WR; 6119 %} 6120 6121 //------- Store pipeline operations ----------------------- 6122 6123 // Store - zr, mem 6124 // Eg. STR zr, <mem> 6125 pipe_class istore_mem(memory mem) 6126 %{ 6127 single_instruction; 6128 mem : ISS(read); 6129 INS01 : ISS; 6130 LDST : WR; 6131 %} 6132 6133 // Store - reg, mem 6134 // Eg. STR x0, <mem> 6135 pipe_class istore_reg_mem(iRegI src, memory mem) 6136 %{ 6137 single_instruction; 6138 mem : ISS(read); 6139 src : EX2(read); 6140 INS01 : ISS; 6141 LDST : WR; 6142 %} 6143 6144 // Store - reg, reg 6145 // Eg. STR x0, [sp, x1] 6146 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6147 %{ 6148 single_instruction; 6149 dst : ISS(read); 6150 src : EX2(read); 6151 INS01 : ISS; 6152 LDST : WR; 6153 %} 6154 6155 //------- Store pipeline operations ----------------------- 6156 6157 // Branch 6158 pipe_class pipe_branch() 6159 %{ 6160 single_instruction; 6161 INS01 : ISS; 6162 BRANCH : EX1; 6163 %} 6164 6165 // Conditional branch 6166 pipe_class pipe_branch_cond(rFlagsReg cr) 6167 %{ 6168 single_instruction; 6169 cr : EX1(read); 6170 INS01 : ISS; 6171 BRANCH : EX1; 6172 %} 6173 6174 // Compare & Branch 6175 // EG. CBZ/CBNZ 6176 pipe_class pipe_cmp_branch(iRegI op1) 6177 %{ 6178 single_instruction; 6179 op1 : EX1(read); 6180 INS01 : ISS; 6181 BRANCH : EX1; 6182 %} 6183 6184 //------- Synchronisation operations ---------------------- 6185 6186 // Any operation requiring serialization. 6187 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6188 pipe_class pipe_serial() 6189 %{ 6190 single_instruction; 6191 force_serialization; 6192 fixed_latency(16); 6193 INS01 : ISS(2); // Cannot dual issue with any other instruction 6194 LDST : WR; 6195 %} 6196 6197 // Generic big/slow expanded idiom - also serialized 6198 pipe_class pipe_slow() 6199 %{ 6200 instruction_count(10); 6201 multiple_bundles; 6202 force_serialization; 6203 fixed_latency(16); 6204 INS01 : ISS(2); // Cannot dual issue with any other instruction 6205 LDST : WR; 6206 %} 6207 6208 // Empty pipeline class 6209 pipe_class pipe_class_empty() 6210 %{ 6211 single_instruction; 6212 fixed_latency(0); 6213 %} 6214 6215 // Default pipeline class. 6216 pipe_class pipe_class_default() 6217 %{ 6218 single_instruction; 6219 fixed_latency(2); 6220 %} 6221 6222 // Pipeline class for compares. 6223 pipe_class pipe_class_compare() 6224 %{ 6225 single_instruction; 6226 fixed_latency(16); 6227 %} 6228 6229 // Pipeline class for memory operations. 6230 pipe_class pipe_class_memory() 6231 %{ 6232 single_instruction; 6233 fixed_latency(16); 6234 %} 6235 6236 // Pipeline class for call. 6237 pipe_class pipe_class_call() 6238 %{ 6239 single_instruction; 6240 fixed_latency(100); 6241 %} 6242 6243 // Define the class for the Nop node. 6244 define %{ 6245 MachNop = pipe_class_empty; 6246 %} 6247 6248 %} 6249 //----------INSTRUCTIONS------------------------------------------------------- 6250 // 6251 // match -- States which machine-independent subtree may be replaced 6252 // by this instruction. 6253 // ins_cost -- The estimated cost of this instruction is used by instruction 6254 // selection to identify a minimum cost tree of machine 6255 // instructions that matches a tree of machine-independent 6256 // instructions. 6257 // format -- A string providing the disassembly for this instruction. 6258 // The value of an instruction's operand may be inserted 6259 // by referring to it with a '$' prefix. 6260 // opcode -- Three instruction opcodes may be provided. These are referred 6261 // to within an encode class as $primary, $secondary, and $tertiary 6262 // rrspectively. The primary opcode is commonly used to 6263 // indicate the type of machine instruction, while secondary 6264 // and tertiary are often used for prefix options or addressing 6265 // modes. 6266 // ins_encode -- A list of encode classes with parameters. The encode class 6267 // name must have been defined in an 'enc_class' specification 6268 // in the encode section of the architecture description. 6269 6270 // ============================================================================ 6271 // Memory (Load/Store) Instructions 6272 6273 // Load Instructions 6274 6275 // Load Byte (8 bit signed) 6276 instruct loadB(iRegINoSp dst, memory mem) 6277 %{ 6278 match(Set dst (LoadB mem)); 6279 predicate(!needs_acquiring_load(n)); 6280 6281 ins_cost(4 * INSN_COST); 6282 format %{ "ldrsbw $dst, $mem\t# byte" %} 6283 6284 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6285 6286 ins_pipe(iload_reg_mem); 6287 %} 6288 6289 // Load Byte (8 bit signed) into long 6290 instruct loadB2L(iRegLNoSp dst, memory mem) 6291 %{ 6292 match(Set dst (ConvI2L (LoadB mem))); 6293 predicate(!needs_acquiring_load(n->in(1))); 6294 6295 ins_cost(4 * INSN_COST); 6296 format %{ "ldrsb $dst, $mem\t# byte" %} 6297 6298 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6299 6300 ins_pipe(iload_reg_mem); 6301 %} 6302 6303 // Load Byte (8 bit unsigned) 6304 instruct loadUB(iRegINoSp dst, memory mem) 6305 %{ 6306 match(Set dst (LoadUB mem)); 6307 predicate(!needs_acquiring_load(n)); 6308 6309 ins_cost(4 * INSN_COST); 6310 format %{ "ldrbw $dst, $mem\t# byte" %} 6311 6312 ins_encode(aarch64_enc_ldrb(dst, mem)); 6313 6314 ins_pipe(iload_reg_mem); 6315 %} 6316 6317 // Load Byte (8 bit unsigned) into long 6318 instruct loadUB2L(iRegLNoSp dst, memory mem) 6319 %{ 6320 match(Set dst (ConvI2L (LoadUB mem))); 6321 predicate(!needs_acquiring_load(n->in(1))); 6322 6323 ins_cost(4 * INSN_COST); 6324 format %{ "ldrb $dst, $mem\t# byte" %} 6325 6326 ins_encode(aarch64_enc_ldrb(dst, mem)); 6327 6328 ins_pipe(iload_reg_mem); 6329 %} 6330 6331 // Load Short (16 bit signed) 6332 instruct loadS(iRegINoSp dst, memory mem) 6333 %{ 6334 match(Set dst (LoadS mem)); 6335 predicate(!needs_acquiring_load(n)); 6336 6337 ins_cost(4 * INSN_COST); 6338 format %{ "ldrshw $dst, $mem\t# short" %} 6339 6340 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6341 6342 ins_pipe(iload_reg_mem); 6343 %} 6344 6345 // Load Short (16 bit signed) into long 6346 instruct loadS2L(iRegLNoSp dst, memory mem) 6347 %{ 6348 match(Set dst (ConvI2L (LoadS mem))); 6349 predicate(!needs_acquiring_load(n->in(1))); 6350 6351 ins_cost(4 * INSN_COST); 6352 format %{ "ldrsh $dst, $mem\t# short" %} 6353 6354 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6355 6356 ins_pipe(iload_reg_mem); 6357 %} 6358 6359 // Load Char (16 bit unsigned) 6360 instruct loadUS(iRegINoSp dst, memory mem) 6361 %{ 6362 match(Set dst (LoadUS mem)); 6363 predicate(!needs_acquiring_load(n)); 6364 6365 ins_cost(4 * INSN_COST); 6366 format %{ "ldrh $dst, $mem\t# short" %} 6367 6368 ins_encode(aarch64_enc_ldrh(dst, mem)); 6369 6370 ins_pipe(iload_reg_mem); 6371 %} 6372 6373 // Load Short/Char (16 bit unsigned) into long 6374 instruct loadUS2L(iRegLNoSp dst, memory mem) 6375 %{ 6376 match(Set dst (ConvI2L (LoadUS mem))); 6377 predicate(!needs_acquiring_load(n->in(1))); 6378 6379 ins_cost(4 * INSN_COST); 6380 format %{ "ldrh $dst, $mem\t# short" %} 6381 6382 ins_encode(aarch64_enc_ldrh(dst, mem)); 6383 6384 ins_pipe(iload_reg_mem); 6385 %} 6386 6387 // Load Integer (32 bit signed) 6388 instruct loadI(iRegINoSp dst, memory mem) 6389 %{ 6390 match(Set dst (LoadI mem)); 6391 predicate(!needs_acquiring_load(n)); 6392 6393 ins_cost(4 * INSN_COST); 6394 format %{ "ldrw $dst, $mem\t# int" %} 6395 6396 ins_encode(aarch64_enc_ldrw(dst, mem)); 6397 6398 ins_pipe(iload_reg_mem); 6399 %} 6400 6401 // Load Integer (32 bit signed) into long 6402 instruct loadI2L(iRegLNoSp dst, memory mem) 6403 %{ 6404 match(Set dst (ConvI2L (LoadI mem))); 6405 predicate(!needs_acquiring_load(n->in(1))); 6406 6407 ins_cost(4 * INSN_COST); 6408 format %{ "ldrsw $dst, $mem\t# int" %} 6409 6410 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6411 6412 ins_pipe(iload_reg_mem); 6413 %} 6414 6415 // Load Integer (32 bit unsigned) into long 6416 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6417 %{ 6418 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6419 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6420 6421 ins_cost(4 * INSN_COST); 6422 format %{ "ldrw $dst, $mem\t# int" %} 6423 6424 ins_encode(aarch64_enc_ldrw(dst, mem)); 6425 6426 ins_pipe(iload_reg_mem); 6427 %} 6428 6429 // Load Long (64 bit signed) 6430 instruct loadL(iRegLNoSp dst, memory mem) 6431 %{ 6432 match(Set dst (LoadL mem)); 6433 predicate(!needs_acquiring_load(n)); 6434 6435 ins_cost(4 * INSN_COST); 6436 format %{ "ldr $dst, $mem\t# int" %} 6437 6438 ins_encode(aarch64_enc_ldr(dst, mem)); 6439 6440 ins_pipe(iload_reg_mem); 6441 %} 6442 6443 // Load Range 6444 instruct loadRange(iRegINoSp dst, memory mem) 6445 %{ 6446 match(Set dst (LoadRange mem)); 6447 6448 ins_cost(4 * INSN_COST); 6449 format %{ "ldrw $dst, $mem\t# range" %} 6450 6451 ins_encode(aarch64_enc_ldrw(dst, mem)); 6452 6453 ins_pipe(iload_reg_mem); 6454 %} 6455 6456 // Load Pointer 6457 instruct loadP(iRegPNoSp dst, memory mem) 6458 %{ 6459 match(Set dst (LoadP mem)); 6460 predicate(!needs_acquiring_load(n)); 6461 6462 ins_cost(4 * INSN_COST); 6463 format %{ "ldr $dst, $mem\t# ptr" %} 6464 6465 ins_encode(aarch64_enc_ldr(dst, mem)); 6466 6467 ins_pipe(iload_reg_mem); 6468 %} 6469 6470 // Load Compressed Pointer 6471 instruct loadN(iRegNNoSp dst, memory mem) 6472 %{ 6473 match(Set dst (LoadN mem)); 6474 predicate(!needs_acquiring_load(n)); 6475 6476 ins_cost(4 * INSN_COST); 6477 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6478 6479 ins_encode(aarch64_enc_ldrw(dst, mem)); 6480 6481 ins_pipe(iload_reg_mem); 6482 %} 6483 6484 // Load Klass Pointer 6485 instruct loadKlass(iRegPNoSp dst, memory mem) 6486 %{ 6487 match(Set dst (LoadKlass mem)); 6488 predicate(!needs_acquiring_load(n)); 6489 6490 ins_cost(4 * INSN_COST); 6491 format %{ "ldr $dst, $mem\t# class" %} 6492 6493 ins_encode(aarch64_enc_ldr(dst, mem)); 6494 6495 ins_pipe(iload_reg_mem); 6496 %} 6497 6498 // Load Narrow Klass Pointer 6499 instruct loadNKlass(iRegNNoSp dst, memory mem) 6500 %{ 6501 match(Set dst (LoadNKlass mem)); 6502 predicate(!needs_acquiring_load(n)); 6503 6504 ins_cost(4 * INSN_COST); 6505 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6506 6507 ins_encode(aarch64_enc_ldrw(dst, mem)); 6508 6509 ins_pipe(iload_reg_mem); 6510 %} 6511 6512 // Load Float 6513 instruct loadF(vRegF dst, memory mem) 6514 %{ 6515 match(Set dst (LoadF mem)); 6516 predicate(!needs_acquiring_load(n)); 6517 6518 ins_cost(4 * INSN_COST); 6519 format %{ "ldrs $dst, $mem\t# float" %} 6520 6521 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6522 6523 ins_pipe(pipe_class_memory); 6524 %} 6525 6526 // Load Double 6527 instruct loadD(vRegD dst, memory mem) 6528 %{ 6529 match(Set dst (LoadD mem)); 6530 predicate(!needs_acquiring_load(n)); 6531 6532 ins_cost(4 * INSN_COST); 6533 format %{ "ldrd $dst, $mem\t# double" %} 6534 6535 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6536 6537 ins_pipe(pipe_class_memory); 6538 %} 6539 6540 6541 // Load Int Constant 6542 instruct loadConI(iRegINoSp dst, immI src) 6543 %{ 6544 match(Set dst src); 6545 6546 ins_cost(INSN_COST); 6547 format %{ "mov $dst, $src\t# int" %} 6548 6549 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6550 6551 ins_pipe(ialu_imm); 6552 %} 6553 6554 // Load Long Constant 6555 instruct loadConL(iRegLNoSp dst, immL src) 6556 %{ 6557 match(Set dst src); 6558 6559 ins_cost(INSN_COST); 6560 format %{ "mov $dst, $src\t# long" %} 6561 6562 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6563 6564 ins_pipe(ialu_imm); 6565 %} 6566 6567 // Load Pointer Constant 6568 6569 instruct loadConP(iRegPNoSp dst, immP con) 6570 %{ 6571 match(Set dst con); 6572 6573 ins_cost(INSN_COST * 4); 6574 format %{ 6575 "mov $dst, $con\t# ptr\n\t" 6576 %} 6577 6578 ins_encode(aarch64_enc_mov_p(dst, con)); 6579 6580 ins_pipe(ialu_imm); 6581 %} 6582 6583 // Load Null Pointer Constant 6584 6585 instruct loadConP0(iRegPNoSp dst, immP0 con) 6586 %{ 6587 match(Set dst con); 6588 6589 ins_cost(INSN_COST); 6590 format %{ "mov $dst, $con\t# NULL ptr" %} 6591 6592 ins_encode(aarch64_enc_mov_p0(dst, con)); 6593 6594 ins_pipe(ialu_imm); 6595 %} 6596 6597 // Load Pointer Constant One 6598 6599 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6600 %{ 6601 match(Set dst con); 6602 6603 ins_cost(INSN_COST); 6604 format %{ "mov $dst, $con\t# NULL ptr" %} 6605 6606 ins_encode(aarch64_enc_mov_p1(dst, con)); 6607 6608 ins_pipe(ialu_imm); 6609 %} 6610 6611 // Load Poll Page Constant 6612 6613 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6614 %{ 6615 match(Set dst con); 6616 6617 ins_cost(INSN_COST); 6618 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6619 6620 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6621 6622 ins_pipe(ialu_imm); 6623 %} 6624 6625 // Load Byte Map Base Constant 6626 6627 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6628 %{ 6629 match(Set dst con); 6630 6631 ins_cost(INSN_COST); 6632 format %{ "adr $dst, $con\t# Byte Map Base" %} 6633 6634 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6635 6636 ins_pipe(ialu_imm); 6637 %} 6638 6639 // Load Narrow Pointer Constant 6640 6641 instruct loadConN(iRegNNoSp dst, immN con) 6642 %{ 6643 match(Set dst con); 6644 6645 ins_cost(INSN_COST * 4); 6646 format %{ "mov $dst, $con\t# compressed ptr" %} 6647 6648 ins_encode(aarch64_enc_mov_n(dst, con)); 6649 6650 ins_pipe(ialu_imm); 6651 %} 6652 6653 // Load Narrow Null Pointer Constant 6654 6655 instruct loadConN0(iRegNNoSp dst, immN0 con) 6656 %{ 6657 match(Set dst con); 6658 6659 ins_cost(INSN_COST); 6660 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6661 6662 ins_encode(aarch64_enc_mov_n0(dst, con)); 6663 6664 ins_pipe(ialu_imm); 6665 %} 6666 6667 // Load Narrow Klass Constant 6668 6669 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6670 %{ 6671 match(Set dst con); 6672 6673 ins_cost(INSN_COST); 6674 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6675 6676 ins_encode(aarch64_enc_mov_nk(dst, con)); 6677 6678 ins_pipe(ialu_imm); 6679 %} 6680 6681 // Load Packed Float Constant 6682 6683 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6684 match(Set dst con); 6685 ins_cost(INSN_COST * 4); 6686 format %{ "fmovs $dst, $con"%} 6687 ins_encode %{ 6688 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6689 %} 6690 6691 ins_pipe(pipe_class_default); 6692 %} 6693 6694 // Load Float Constant 6695 6696 instruct loadConF(vRegF dst, immF con) %{ 6697 match(Set dst con); 6698 6699 ins_cost(INSN_COST * 4); 6700 6701 format %{ 6702 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6703 %} 6704 6705 ins_encode %{ 6706 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6707 %} 6708 6709 ins_pipe(pipe_class_default); 6710 %} 6711 6712 // Load Packed Double Constant 6713 6714 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6715 match(Set dst con); 6716 ins_cost(INSN_COST); 6717 format %{ "fmovd $dst, $con"%} 6718 ins_encode %{ 6719 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6720 %} 6721 6722 ins_pipe(pipe_class_default); 6723 %} 6724 6725 // Load Double Constant 6726 6727 instruct loadConD(vRegD dst, immD con) %{ 6728 match(Set dst con); 6729 6730 ins_cost(INSN_COST * 5); 6731 format %{ 6732 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6733 %} 6734 6735 ins_encode %{ 6736 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6737 %} 6738 6739 ins_pipe(pipe_class_default); 6740 %} 6741 6742 // Store Instructions 6743 6744 // Store CMS card-mark Immediate 6745 instruct storeimmCM0(immI0 zero, memory mem) 6746 %{ 6747 match(Set mem (StoreCM mem zero)); 6748 6749 ins_cost(INSN_COST); 6750 format %{ "strb zr, $mem\t# byte" %} 6751 6752 ins_encode(aarch64_enc_strb0(mem)); 6753 6754 ins_pipe(istore_mem); 6755 %} 6756 6757 // Store Byte 6758 instruct storeB(iRegIorL2I src, memory mem) 6759 %{ 6760 match(Set mem (StoreB mem src)); 6761 predicate(!needs_releasing_store(n)); 6762 6763 ins_cost(INSN_COST); 6764 format %{ "strb $src, $mem\t# byte" %} 6765 6766 ins_encode(aarch64_enc_strb(src, mem)); 6767 6768 ins_pipe(istore_reg_mem); 6769 %} 6770 6771 6772 instruct storeimmB0(immI0 zero, memory mem) 6773 %{ 6774 match(Set mem (StoreB mem zero)); 6775 predicate(!needs_releasing_store(n)); 6776 6777 ins_cost(INSN_COST); 6778 format %{ "strb zr, $mem\t# byte" %} 6779 6780 ins_encode(aarch64_enc_strb0(mem)); 6781 6782 ins_pipe(istore_mem); 6783 %} 6784 6785 // Store Char/Short 6786 instruct storeC(iRegIorL2I src, memory mem) 6787 %{ 6788 match(Set mem (StoreC mem src)); 6789 predicate(!needs_releasing_store(n)); 6790 6791 ins_cost(INSN_COST); 6792 format %{ "strh $src, $mem\t# short" %} 6793 6794 ins_encode(aarch64_enc_strh(src, mem)); 6795 6796 ins_pipe(istore_reg_mem); 6797 %} 6798 6799 instruct storeimmC0(immI0 zero, memory mem) 6800 %{ 6801 match(Set mem (StoreC mem zero)); 6802 predicate(!needs_releasing_store(n)); 6803 6804 ins_cost(INSN_COST); 6805 format %{ "strh zr, $mem\t# short" %} 6806 6807 ins_encode(aarch64_enc_strh0(mem)); 6808 6809 ins_pipe(istore_mem); 6810 %} 6811 6812 // Store Integer 6813 6814 instruct storeI(iRegIorL2I src, memory mem) 6815 %{ 6816 match(Set mem(StoreI mem src)); 6817 predicate(!needs_releasing_store(n)); 6818 6819 ins_cost(INSN_COST); 6820 format %{ "strw $src, $mem\t# int" %} 6821 6822 ins_encode(aarch64_enc_strw(src, mem)); 6823 6824 ins_pipe(istore_reg_mem); 6825 %} 6826 6827 instruct storeimmI0(immI0 zero, memory mem) 6828 %{ 6829 match(Set mem(StoreI mem zero)); 6830 predicate(!needs_releasing_store(n)); 6831 6832 ins_cost(INSN_COST); 6833 format %{ "strw zr, $mem\t# int" %} 6834 6835 ins_encode(aarch64_enc_strw0(mem)); 6836 6837 ins_pipe(istore_mem); 6838 %} 6839 6840 // Store Long (64 bit signed) 6841 instruct storeL(iRegL src, memory mem) 6842 %{ 6843 match(Set mem (StoreL mem src)); 6844 predicate(!needs_releasing_store(n)); 6845 6846 ins_cost(INSN_COST); 6847 format %{ "str $src, $mem\t# int" %} 6848 6849 ins_encode(aarch64_enc_str(src, mem)); 6850 6851 ins_pipe(istore_reg_mem); 6852 %} 6853 6854 // Store Long (64 bit signed) 6855 instruct storeimmL0(immL0 zero, memory mem) 6856 %{ 6857 match(Set mem (StoreL mem zero)); 6858 predicate(!needs_releasing_store(n)); 6859 6860 ins_cost(INSN_COST); 6861 format %{ "str zr, $mem\t# int" %} 6862 6863 ins_encode(aarch64_enc_str0(mem)); 6864 6865 ins_pipe(istore_mem); 6866 %} 6867 6868 // Store Pointer 6869 instruct storeP(iRegP src, memory mem) 6870 %{ 6871 match(Set mem (StoreP mem src)); 6872 predicate(!needs_releasing_store(n)); 6873 6874 ins_cost(INSN_COST); 6875 format %{ "str $src, $mem\t# ptr" %} 6876 6877 ins_encode(aarch64_enc_str(src, mem)); 6878 6879 ins_pipe(istore_reg_mem); 6880 %} 6881 6882 // Store Pointer 6883 instruct storeimmP0(immP0 zero, memory mem) 6884 %{ 6885 match(Set mem (StoreP mem zero)); 6886 predicate(!needs_releasing_store(n)); 6887 6888 ins_cost(INSN_COST); 6889 format %{ "str zr, $mem\t# ptr" %} 6890 6891 ins_encode(aarch64_enc_str0(mem)); 6892 6893 ins_pipe(istore_mem); 6894 %} 6895 6896 // Store Compressed Pointer 6897 instruct storeN(iRegN src, memory mem) 6898 %{ 6899 match(Set mem (StoreN mem src)); 6900 predicate(!needs_releasing_store(n)); 6901 6902 ins_cost(INSN_COST); 6903 format %{ "strw $src, $mem\t# compressed ptr" %} 6904 6905 ins_encode(aarch64_enc_strw(src, mem)); 6906 6907 ins_pipe(istore_reg_mem); 6908 %} 6909 6910 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 6911 %{ 6912 match(Set mem (StoreN mem zero)); 6913 predicate(Universe::narrow_oop_base() == NULL && 6914 Universe::narrow_klass_base() == NULL && 6915 (!needs_releasing_store(n))); 6916 6917 ins_cost(INSN_COST); 6918 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 6919 6920 ins_encode(aarch64_enc_strw(heapbase, mem)); 6921 6922 ins_pipe(istore_reg_mem); 6923 %} 6924 6925 // Store Float 6926 instruct storeF(vRegF src, memory mem) 6927 %{ 6928 match(Set mem (StoreF mem src)); 6929 predicate(!needs_releasing_store(n)); 6930 6931 ins_cost(INSN_COST); 6932 format %{ "strs $src, $mem\t# float" %} 6933 6934 ins_encode( aarch64_enc_strs(src, mem) ); 6935 6936 ins_pipe(pipe_class_memory); 6937 %} 6938 6939 // TODO 6940 // implement storeImmF0 and storeFImmPacked 6941 6942 // Store Double 6943 instruct storeD(vRegD src, memory mem) 6944 %{ 6945 match(Set mem (StoreD mem src)); 6946 predicate(!needs_releasing_store(n)); 6947 6948 ins_cost(INSN_COST); 6949 format %{ "strd $src, $mem\t# double" %} 6950 6951 ins_encode( aarch64_enc_strd(src, mem) ); 6952 6953 ins_pipe(pipe_class_memory); 6954 %} 6955 6956 // Store Compressed Klass Pointer 6957 instruct storeNKlass(iRegN src, memory mem) 6958 %{ 6959 predicate(!needs_releasing_store(n)); 6960 match(Set mem (StoreNKlass mem src)); 6961 6962 ins_cost(INSN_COST); 6963 format %{ "strw $src, $mem\t# compressed klass ptr" %} 6964 6965 ins_encode(aarch64_enc_strw(src, mem)); 6966 6967 ins_pipe(istore_reg_mem); 6968 %} 6969 6970 // TODO 6971 // implement storeImmD0 and storeDImmPacked 6972 6973 // prefetch instructions 6974 // Must be safe to execute with invalid address (cannot fault). 6975 6976 instruct prefetchalloc( memory mem ) %{ 6977 match(PrefetchAllocation mem); 6978 6979 ins_cost(INSN_COST); 6980 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 6981 6982 ins_encode( aarch64_enc_prefetchw(mem) ); 6983 6984 ins_pipe(iload_prefetch); 6985 %} 6986 6987 // ---------------- volatile loads and stores ---------------- 6988 6989 // Load Byte (8 bit signed) 6990 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6991 %{ 6992 match(Set dst (LoadB mem)); 6993 6994 ins_cost(VOLATILE_REF_COST); 6995 format %{ "ldarsb $dst, $mem\t# byte" %} 6996 6997 ins_encode(aarch64_enc_ldarsb(dst, mem)); 6998 6999 ins_pipe(pipe_serial); 7000 %} 7001 7002 // Load Byte (8 bit signed) into long 7003 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7004 %{ 7005 match(Set dst (ConvI2L (LoadB mem))); 7006 7007 ins_cost(VOLATILE_REF_COST); 7008 format %{ "ldarsb $dst, $mem\t# byte" %} 7009 7010 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7011 7012 ins_pipe(pipe_serial); 7013 %} 7014 7015 // Load Byte (8 bit unsigned) 7016 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7017 %{ 7018 match(Set dst (LoadUB mem)); 7019 7020 ins_cost(VOLATILE_REF_COST); 7021 format %{ "ldarb $dst, $mem\t# byte" %} 7022 7023 ins_encode(aarch64_enc_ldarb(dst, mem)); 7024 7025 ins_pipe(pipe_serial); 7026 %} 7027 7028 // Load Byte (8 bit unsigned) into long 7029 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7030 %{ 7031 match(Set dst (ConvI2L (LoadUB mem))); 7032 7033 ins_cost(VOLATILE_REF_COST); 7034 format %{ "ldarb $dst, $mem\t# byte" %} 7035 7036 ins_encode(aarch64_enc_ldarb(dst, mem)); 7037 7038 ins_pipe(pipe_serial); 7039 %} 7040 7041 // Load Short (16 bit signed) 7042 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7043 %{ 7044 match(Set dst (LoadS mem)); 7045 7046 ins_cost(VOLATILE_REF_COST); 7047 format %{ "ldarshw $dst, $mem\t# short" %} 7048 7049 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7050 7051 ins_pipe(pipe_serial); 7052 %} 7053 7054 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7055 %{ 7056 match(Set dst (LoadUS mem)); 7057 7058 ins_cost(VOLATILE_REF_COST); 7059 format %{ "ldarhw $dst, $mem\t# short" %} 7060 7061 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7062 7063 ins_pipe(pipe_serial); 7064 %} 7065 7066 // Load Short/Char (16 bit unsigned) into long 7067 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7068 %{ 7069 match(Set dst (ConvI2L (LoadUS mem))); 7070 7071 ins_cost(VOLATILE_REF_COST); 7072 format %{ "ldarh $dst, $mem\t# short" %} 7073 7074 ins_encode(aarch64_enc_ldarh(dst, mem)); 7075 7076 ins_pipe(pipe_serial); 7077 %} 7078 7079 // Load Short/Char (16 bit signed) into long 7080 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7081 %{ 7082 match(Set dst (ConvI2L (LoadS mem))); 7083 7084 ins_cost(VOLATILE_REF_COST); 7085 format %{ "ldarh $dst, $mem\t# short" %} 7086 7087 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7088 7089 ins_pipe(pipe_serial); 7090 %} 7091 7092 // Load Integer (32 bit signed) 7093 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7094 %{ 7095 match(Set dst (LoadI mem)); 7096 7097 ins_cost(VOLATILE_REF_COST); 7098 format %{ "ldarw $dst, $mem\t# int" %} 7099 7100 ins_encode(aarch64_enc_ldarw(dst, mem)); 7101 7102 ins_pipe(pipe_serial); 7103 %} 7104 7105 // Load Integer (32 bit unsigned) into long 7106 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7107 %{ 7108 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7109 7110 ins_cost(VOLATILE_REF_COST); 7111 format %{ "ldarw $dst, $mem\t# int" %} 7112 7113 ins_encode(aarch64_enc_ldarw(dst, mem)); 7114 7115 ins_pipe(pipe_serial); 7116 %} 7117 7118 // Load Long (64 bit signed) 7119 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7120 %{ 7121 match(Set dst (LoadL mem)); 7122 7123 ins_cost(VOLATILE_REF_COST); 7124 format %{ "ldar $dst, $mem\t# int" %} 7125 7126 ins_encode(aarch64_enc_ldar(dst, mem)); 7127 7128 ins_pipe(pipe_serial); 7129 %} 7130 7131 // Load Pointer 7132 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7133 %{ 7134 match(Set dst (LoadP mem)); 7135 7136 ins_cost(VOLATILE_REF_COST); 7137 format %{ "ldar $dst, $mem\t# ptr" %} 7138 7139 ins_encode(aarch64_enc_ldar(dst, mem)); 7140 7141 ins_pipe(pipe_serial); 7142 %} 7143 7144 // Load Compressed Pointer 7145 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7146 %{ 7147 match(Set dst (LoadN mem)); 7148 7149 ins_cost(VOLATILE_REF_COST); 7150 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7151 7152 ins_encode(aarch64_enc_ldarw(dst, mem)); 7153 7154 ins_pipe(pipe_serial); 7155 %} 7156 7157 // Load Float 7158 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7159 %{ 7160 match(Set dst (LoadF mem)); 7161 7162 ins_cost(VOLATILE_REF_COST); 7163 format %{ "ldars $dst, $mem\t# float" %} 7164 7165 ins_encode( aarch64_enc_fldars(dst, mem) ); 7166 7167 ins_pipe(pipe_serial); 7168 %} 7169 7170 // Load Double 7171 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7172 %{ 7173 match(Set dst (LoadD mem)); 7174 7175 ins_cost(VOLATILE_REF_COST); 7176 format %{ "ldard $dst, $mem\t# double" %} 7177 7178 ins_encode( aarch64_enc_fldard(dst, mem) ); 7179 7180 ins_pipe(pipe_serial); 7181 %} 7182 7183 // Store Byte 7184 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7185 %{ 7186 match(Set mem (StoreB mem src)); 7187 7188 ins_cost(VOLATILE_REF_COST); 7189 format %{ "stlrb $src, $mem\t# byte" %} 7190 7191 ins_encode(aarch64_enc_stlrb(src, mem)); 7192 7193 ins_pipe(pipe_class_memory); 7194 %} 7195 7196 // Store Char/Short 7197 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7198 %{ 7199 match(Set mem (StoreC mem src)); 7200 7201 ins_cost(VOLATILE_REF_COST); 7202 format %{ "stlrh $src, $mem\t# short" %} 7203 7204 ins_encode(aarch64_enc_stlrh(src, mem)); 7205 7206 ins_pipe(pipe_class_memory); 7207 %} 7208 7209 // Store Integer 7210 7211 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7212 %{ 7213 match(Set mem(StoreI mem src)); 7214 7215 ins_cost(VOLATILE_REF_COST); 7216 format %{ "stlrw $src, $mem\t# int" %} 7217 7218 ins_encode(aarch64_enc_stlrw(src, mem)); 7219 7220 ins_pipe(pipe_class_memory); 7221 %} 7222 7223 // Store Long (64 bit signed) 7224 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7225 %{ 7226 match(Set mem (StoreL mem src)); 7227 7228 ins_cost(VOLATILE_REF_COST); 7229 format %{ "stlr $src, $mem\t# int" %} 7230 7231 ins_encode(aarch64_enc_stlr(src, mem)); 7232 7233 ins_pipe(pipe_class_memory); 7234 %} 7235 7236 // Store Pointer 7237 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7238 %{ 7239 match(Set mem (StoreP mem src)); 7240 7241 ins_cost(VOLATILE_REF_COST); 7242 format %{ "stlr $src, $mem\t# ptr" %} 7243 7244 ins_encode(aarch64_enc_stlr(src, mem)); 7245 7246 ins_pipe(pipe_class_memory); 7247 %} 7248 7249 // Store Compressed Pointer 7250 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7251 %{ 7252 match(Set mem (StoreN mem src)); 7253 7254 ins_cost(VOLATILE_REF_COST); 7255 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7256 7257 ins_encode(aarch64_enc_stlrw(src, mem)); 7258 7259 ins_pipe(pipe_class_memory); 7260 %} 7261 7262 // Store Float 7263 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7264 %{ 7265 match(Set mem (StoreF mem src)); 7266 7267 ins_cost(VOLATILE_REF_COST); 7268 format %{ "stlrs $src, $mem\t# float" %} 7269 7270 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7271 7272 ins_pipe(pipe_class_memory); 7273 %} 7274 7275 // TODO 7276 // implement storeImmF0 and storeFImmPacked 7277 7278 // Store Double 7279 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7280 %{ 7281 match(Set mem (StoreD mem src)); 7282 7283 ins_cost(VOLATILE_REF_COST); 7284 format %{ "stlrd $src, $mem\t# double" %} 7285 7286 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7287 7288 ins_pipe(pipe_class_memory); 7289 %} 7290 7291 // ---------------- end of volatile loads and stores ---------------- 7292 7293 // ============================================================================ 7294 // BSWAP Instructions 7295 7296 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7297 match(Set dst (ReverseBytesI src)); 7298 7299 ins_cost(INSN_COST); 7300 format %{ "revw $dst, $src" %} 7301 7302 ins_encode %{ 7303 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7304 %} 7305 7306 ins_pipe(ialu_reg); 7307 %} 7308 7309 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7310 match(Set dst (ReverseBytesL src)); 7311 7312 ins_cost(INSN_COST); 7313 format %{ "rev $dst, $src" %} 7314 7315 ins_encode %{ 7316 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7317 %} 7318 7319 ins_pipe(ialu_reg); 7320 %} 7321 7322 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7323 match(Set dst (ReverseBytesUS src)); 7324 7325 ins_cost(INSN_COST); 7326 format %{ "rev16w $dst, $src" %} 7327 7328 ins_encode %{ 7329 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7330 %} 7331 7332 ins_pipe(ialu_reg); 7333 %} 7334 7335 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7336 match(Set dst (ReverseBytesS src)); 7337 7338 ins_cost(INSN_COST); 7339 format %{ "rev16w $dst, $src\n\t" 7340 "sbfmw $dst, $dst, #0, #15" %} 7341 7342 ins_encode %{ 7343 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7344 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7345 %} 7346 7347 ins_pipe(ialu_reg); 7348 %} 7349 7350 // ============================================================================ 7351 // Zero Count Instructions 7352 7353 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7354 match(Set dst (CountLeadingZerosI src)); 7355 7356 ins_cost(INSN_COST); 7357 format %{ "clzw $dst, $src" %} 7358 ins_encode %{ 7359 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7360 %} 7361 7362 ins_pipe(ialu_reg); 7363 %} 7364 7365 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7366 match(Set dst (CountLeadingZerosL src)); 7367 7368 ins_cost(INSN_COST); 7369 format %{ "clz $dst, $src" %} 7370 ins_encode %{ 7371 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7372 %} 7373 7374 ins_pipe(ialu_reg); 7375 %} 7376 7377 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7378 match(Set dst (CountTrailingZerosI src)); 7379 7380 ins_cost(INSN_COST * 2); 7381 format %{ "rbitw $dst, $src\n\t" 7382 "clzw $dst, $dst" %} 7383 ins_encode %{ 7384 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7385 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7386 %} 7387 7388 ins_pipe(ialu_reg); 7389 %} 7390 7391 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7392 match(Set dst (CountTrailingZerosL src)); 7393 7394 ins_cost(INSN_COST * 2); 7395 format %{ "rbit $dst, $src\n\t" 7396 "clz $dst, $dst" %} 7397 ins_encode %{ 7398 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7399 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7400 %} 7401 7402 ins_pipe(ialu_reg); 7403 %} 7404 7405 //---------- Population Count Instructions ------------------------------------- 7406 // 7407 7408 instruct popCountI(iRegINoSp dst, iRegI src, vRegD tmp) %{ 7409 predicate(UsePopCountInstruction); 7410 match(Set dst (PopCountI src)); 7411 effect(TEMP tmp); 7412 ins_cost(INSN_COST * 13); 7413 7414 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7415 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7416 "addv $tmp, $tmp\t# vector (8B)\n\t" 7417 "mov $dst, $tmp\t# vector (1D)" %} 7418 ins_encode %{ 7419 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7420 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7421 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7422 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7423 %} 7424 7425 ins_pipe(pipe_class_default); 7426 %} 7427 7428 // Note: Long.bitCount(long) returns an int. 7429 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7430 predicate(UsePopCountInstruction); 7431 match(Set dst (PopCountL src)); 7432 effect(TEMP tmp); 7433 ins_cost(INSN_COST * 13); 7434 7435 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7436 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7437 "addv $tmp, $tmp\t# vector (8B)\n\t" 7438 "mov $dst, $tmp\t# vector (1D)" %} 7439 ins_encode %{ 7440 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7441 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7442 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7443 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7444 %} 7445 7446 ins_pipe(pipe_class_default); 7447 %} 7448 7449 // ============================================================================ 7450 // MemBar Instruction 7451 7452 instruct load_fence() %{ 7453 match(LoadFence); 7454 ins_cost(VOLATILE_REF_COST); 7455 7456 format %{ "load_fence" %} 7457 7458 ins_encode %{ 7459 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7460 %} 7461 ins_pipe(pipe_serial); 7462 %} 7463 7464 instruct unnecessary_membar_acquire() %{ 7465 predicate(unnecessary_acquire(n)); 7466 match(MemBarAcquire); 7467 ins_cost(0); 7468 7469 format %{ "membar_acquire (elided)" %} 7470 7471 ins_encode %{ 7472 __ block_comment("membar_acquire (elided)"); 7473 %} 7474 7475 ins_pipe(pipe_class_empty); 7476 %} 7477 7478 instruct membar_acquire() %{ 7479 match(MemBarAcquire); 7480 ins_cost(VOLATILE_REF_COST); 7481 7482 format %{ "membar_acquire" %} 7483 7484 ins_encode %{ 7485 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7486 %} 7487 7488 ins_pipe(pipe_serial); 7489 %} 7490 7491 7492 instruct membar_acquire_lock() %{ 7493 match(MemBarAcquireLock); 7494 ins_cost(VOLATILE_REF_COST); 7495 7496 format %{ "membar_acquire_lock" %} 7497 7498 ins_encode %{ 7499 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7500 %} 7501 7502 ins_pipe(pipe_serial); 7503 %} 7504 7505 instruct store_fence() %{ 7506 match(StoreFence); 7507 ins_cost(VOLATILE_REF_COST); 7508 7509 format %{ "store_fence" %} 7510 7511 ins_encode %{ 7512 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7513 %} 7514 ins_pipe(pipe_serial); 7515 %} 7516 7517 instruct unnecessary_membar_release() %{ 7518 predicate(unnecessary_release(n)); 7519 match(MemBarRelease); 7520 ins_cost(0); 7521 7522 format %{ "membar_release (elided)" %} 7523 7524 ins_encode %{ 7525 __ block_comment("membar_release (elided)"); 7526 %} 7527 ins_pipe(pipe_serial); 7528 %} 7529 7530 instruct membar_release() %{ 7531 match(MemBarRelease); 7532 ins_cost(VOLATILE_REF_COST); 7533 7534 format %{ "membar_release" %} 7535 7536 ins_encode %{ 7537 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7538 %} 7539 ins_pipe(pipe_serial); 7540 %} 7541 7542 instruct membar_storestore() %{ 7543 match(MemBarStoreStore); 7544 ins_cost(VOLATILE_REF_COST); 7545 7546 format %{ "MEMBAR-store-store" %} 7547 7548 ins_encode %{ 7549 __ membar(Assembler::StoreStore); 7550 %} 7551 ins_pipe(pipe_serial); 7552 %} 7553 7554 instruct membar_release_lock() %{ 7555 match(MemBarReleaseLock); 7556 ins_cost(VOLATILE_REF_COST); 7557 7558 format %{ "membar_release_lock" %} 7559 7560 ins_encode %{ 7561 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7562 %} 7563 7564 ins_pipe(pipe_serial); 7565 %} 7566 7567 instruct unnecessary_membar_volatile() %{ 7568 predicate(unnecessary_volatile(n)); 7569 match(MemBarVolatile); 7570 ins_cost(0); 7571 7572 format %{ "membar_volatile (elided)" %} 7573 7574 ins_encode %{ 7575 __ block_comment("membar_volatile (elided)"); 7576 %} 7577 7578 ins_pipe(pipe_serial); 7579 %} 7580 7581 instruct membar_volatile() %{ 7582 match(MemBarVolatile); 7583 ins_cost(VOLATILE_REF_COST*100); 7584 7585 format %{ "membar_volatile" %} 7586 7587 ins_encode %{ 7588 __ membar(Assembler::StoreLoad); 7589 %} 7590 7591 ins_pipe(pipe_serial); 7592 %} 7593 7594 // ============================================================================ 7595 // Cast/Convert Instructions 7596 7597 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7598 match(Set dst (CastX2P src)); 7599 7600 ins_cost(INSN_COST); 7601 format %{ "mov $dst, $src\t# long -> ptr" %} 7602 7603 ins_encode %{ 7604 if ($dst$$reg != $src$$reg) { 7605 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7606 } 7607 %} 7608 7609 ins_pipe(ialu_reg); 7610 %} 7611 7612 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7613 match(Set dst (CastP2X src)); 7614 7615 ins_cost(INSN_COST); 7616 format %{ "mov $dst, $src\t# ptr -> long" %} 7617 7618 ins_encode %{ 7619 if ($dst$$reg != $src$$reg) { 7620 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7621 } 7622 %} 7623 7624 ins_pipe(ialu_reg); 7625 %} 7626 7627 // Convert oop into int for vectors alignment masking 7628 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7629 match(Set dst (ConvL2I (CastP2X src))); 7630 7631 ins_cost(INSN_COST); 7632 format %{ "movw $dst, $src\t# ptr -> int" %} 7633 ins_encode %{ 7634 __ movw($dst$$Register, $src$$Register); 7635 %} 7636 7637 ins_pipe(ialu_reg); 7638 %} 7639 7640 // Convert compressed oop into int for vectors alignment masking 7641 // in case of 32bit oops (heap < 4Gb). 7642 instruct convN2I(iRegINoSp dst, iRegN src) 7643 %{ 7644 predicate(Universe::narrow_oop_shift() == 0); 7645 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7646 7647 ins_cost(INSN_COST); 7648 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7649 ins_encode %{ 7650 __ movw($dst$$Register, $src$$Register); 7651 %} 7652 7653 ins_pipe(ialu_reg); 7654 %} 7655 7656 7657 // Convert oop pointer into compressed form 7658 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7659 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7660 match(Set dst (EncodeP src)); 7661 effect(KILL cr); 7662 ins_cost(INSN_COST * 3); 7663 format %{ "encode_heap_oop $dst, $src" %} 7664 ins_encode %{ 7665 Register s = $src$$Register; 7666 Register d = $dst$$Register; 7667 __ encode_heap_oop(d, s); 7668 %} 7669 ins_pipe(ialu_reg); 7670 %} 7671 7672 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7673 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7674 match(Set dst (EncodeP src)); 7675 ins_cost(INSN_COST * 3); 7676 format %{ "encode_heap_oop_not_null $dst, $src" %} 7677 ins_encode %{ 7678 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7679 %} 7680 ins_pipe(ialu_reg); 7681 %} 7682 7683 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7684 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7685 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7686 match(Set dst (DecodeN src)); 7687 ins_cost(INSN_COST * 3); 7688 format %{ "decode_heap_oop $dst, $src" %} 7689 ins_encode %{ 7690 Register s = $src$$Register; 7691 Register d = $dst$$Register; 7692 __ decode_heap_oop(d, s); 7693 %} 7694 ins_pipe(ialu_reg); 7695 %} 7696 7697 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7698 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7699 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7700 match(Set dst (DecodeN src)); 7701 ins_cost(INSN_COST * 3); 7702 format %{ "decode_heap_oop_not_null $dst, $src" %} 7703 ins_encode %{ 7704 Register s = $src$$Register; 7705 Register d = $dst$$Register; 7706 __ decode_heap_oop_not_null(d, s); 7707 %} 7708 ins_pipe(ialu_reg); 7709 %} 7710 7711 // n.b. AArch64 implementations of encode_klass_not_null and 7712 // decode_klass_not_null do not modify the flags register so, unlike 7713 // Intel, we don't kill CR as a side effect here 7714 7715 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7716 match(Set dst (EncodePKlass src)); 7717 7718 ins_cost(INSN_COST * 3); 7719 format %{ "encode_klass_not_null $dst,$src" %} 7720 7721 ins_encode %{ 7722 Register src_reg = as_Register($src$$reg); 7723 Register dst_reg = as_Register($dst$$reg); 7724 __ encode_klass_not_null(dst_reg, src_reg); 7725 %} 7726 7727 ins_pipe(ialu_reg); 7728 %} 7729 7730 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7731 match(Set dst (DecodeNKlass src)); 7732 7733 ins_cost(INSN_COST * 3); 7734 format %{ "decode_klass_not_null $dst,$src" %} 7735 7736 ins_encode %{ 7737 Register src_reg = as_Register($src$$reg); 7738 Register dst_reg = as_Register($dst$$reg); 7739 if (dst_reg != src_reg) { 7740 __ decode_klass_not_null(dst_reg, src_reg); 7741 } else { 7742 __ decode_klass_not_null(dst_reg); 7743 } 7744 %} 7745 7746 ins_pipe(ialu_reg); 7747 %} 7748 7749 instruct checkCastPP(iRegPNoSp dst) 7750 %{ 7751 match(Set dst (CheckCastPP dst)); 7752 7753 size(0); 7754 format %{ "# checkcastPP of $dst" %} 7755 ins_encode(/* empty encoding */); 7756 ins_pipe(pipe_class_empty); 7757 %} 7758 7759 instruct castPP(iRegPNoSp dst) 7760 %{ 7761 match(Set dst (CastPP dst)); 7762 7763 size(0); 7764 format %{ "# castPP of $dst" %} 7765 ins_encode(/* empty encoding */); 7766 ins_pipe(pipe_class_empty); 7767 %} 7768 7769 instruct castII(iRegI dst) 7770 %{ 7771 match(Set dst (CastII dst)); 7772 7773 size(0); 7774 format %{ "# castII of $dst" %} 7775 ins_encode(/* empty encoding */); 7776 ins_cost(0); 7777 ins_pipe(pipe_class_empty); 7778 %} 7779 7780 // ============================================================================ 7781 // Atomic operation instructions 7782 // 7783 // Intel and SPARC both implement Ideal Node LoadPLocked and 7784 // Store{PIL}Conditional instructions using a normal load for the 7785 // LoadPLocked and a CAS for the Store{PIL}Conditional. 7786 // 7787 // The ideal code appears only to use LoadPLocked/StorePLocked as a 7788 // pair to lock object allocations from Eden space when not using 7789 // TLABs. 7790 // 7791 // There does not appear to be a Load{IL}Locked Ideal Node and the 7792 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 7793 // and to use StoreIConditional only for 32-bit and StoreLConditional 7794 // only for 64-bit. 7795 // 7796 // We implement LoadPLocked and StorePLocked instructions using, 7797 // respectively the AArch64 hw load-exclusive and store-conditional 7798 // instructions. Whereas we must implement each of 7799 // Store{IL}Conditional using a CAS which employs a pair of 7800 // instructions comprising a load-exclusive followed by a 7801 // store-conditional. 7802 7803 7804 // Locked-load (linked load) of the current heap-top 7805 // used when updating the eden heap top 7806 // implemented using ldaxr on AArch64 7807 7808 instruct loadPLocked(iRegPNoSp dst, indirect mem) 7809 %{ 7810 match(Set dst (LoadPLocked mem)); 7811 7812 ins_cost(VOLATILE_REF_COST); 7813 7814 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7815 7816 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7817 7818 ins_pipe(pipe_serial); 7819 %} 7820 7821 // Conditional-store of the updated heap-top. 7822 // Used during allocation of the shared heap. 7823 // Sets flag (EQ) on success. 7824 // implemented using stlxr on AArch64. 7825 7826 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7827 %{ 7828 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7829 7830 ins_cost(VOLATILE_REF_COST); 7831 7832 // TODO 7833 // do we need to do a store-conditional release or can we just use a 7834 // plain store-conditional? 7835 7836 format %{ 7837 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 7838 "cmpw rscratch1, zr\t# EQ on successful write" 7839 %} 7840 7841 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 7842 7843 ins_pipe(pipe_serial); 7844 %} 7845 7846 // this has to be implemented as a CAS 7847 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 7848 %{ 7849 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7850 7851 ins_cost(VOLATILE_REF_COST); 7852 7853 format %{ 7854 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7855 "cmpw rscratch1, zr\t# EQ on successful write" 7856 %} 7857 7858 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); 7859 7860 ins_pipe(pipe_slow); 7861 %} 7862 7863 // this has to be implemented as a CAS 7864 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 7865 %{ 7866 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7867 7868 ins_cost(VOLATILE_REF_COST); 7869 7870 format %{ 7871 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7872 "cmpw rscratch1, zr\t# EQ on successful write" 7873 %} 7874 7875 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); 7876 7877 ins_pipe(pipe_slow); 7878 %} 7879 7880 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 7881 // can't match them 7882 7883 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 7884 7885 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 7886 7887 effect(KILL cr); 7888 7889 format %{ 7890 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 7891 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7892 %} 7893 7894 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7895 aarch64_enc_cset_eq(res)); 7896 7897 ins_pipe(pipe_slow); 7898 %} 7899 7900 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 7901 7902 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 7903 7904 effect(KILL cr); 7905 7906 format %{ 7907 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 7908 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7909 %} 7910 7911 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7912 aarch64_enc_cset_eq(res)); 7913 7914 ins_pipe(pipe_slow); 7915 %} 7916 7917 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 7918 7919 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 7920 7921 effect(KILL cr); 7922 7923 format %{ 7924 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 7925 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7926 %} 7927 7928 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7929 aarch64_enc_cset_eq(res)); 7930 7931 ins_pipe(pipe_slow); 7932 %} 7933 7934 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 7935 7936 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 7937 7938 effect(KILL cr); 7939 7940 format %{ 7941 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 7942 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7943 %} 7944 7945 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7946 aarch64_enc_cset_eq(res)); 7947 7948 ins_pipe(pipe_slow); 7949 %} 7950 7951 7952 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ 7953 match(Set prev (GetAndSetI mem newv)); 7954 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7955 ins_encode %{ 7956 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7957 %} 7958 ins_pipe(pipe_serial); 7959 %} 7960 7961 instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{ 7962 match(Set prev (GetAndSetL mem newv)); 7963 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7964 ins_encode %{ 7965 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7966 %} 7967 ins_pipe(pipe_serial); 7968 %} 7969 7970 instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{ 7971 match(Set prev (GetAndSetN mem newv)); 7972 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7973 ins_encode %{ 7974 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7975 %} 7976 ins_pipe(pipe_serial); 7977 %} 7978 7979 instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{ 7980 match(Set prev (GetAndSetP mem newv)); 7981 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7982 ins_encode %{ 7983 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7984 %} 7985 ins_pipe(pipe_serial); 7986 %} 7987 7988 7989 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 7990 match(Set newval (GetAndAddL mem incr)); 7991 ins_cost(INSN_COST * 10); 7992 format %{ "get_and_addL $newval, [$mem], $incr" %} 7993 ins_encode %{ 7994 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 7995 %} 7996 ins_pipe(pipe_serial); 7997 %} 7998 7999 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8000 predicate(n->as_LoadStore()->result_not_used()); 8001 match(Set dummy (GetAndAddL mem incr)); 8002 ins_cost(INSN_COST * 9); 8003 format %{ "get_and_addL [$mem], $incr" %} 8004 ins_encode %{ 8005 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8006 %} 8007 ins_pipe(pipe_serial); 8008 %} 8009 8010 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8011 match(Set newval (GetAndAddL mem incr)); 8012 ins_cost(INSN_COST * 10); 8013 format %{ "get_and_addL $newval, [$mem], $incr" %} 8014 ins_encode %{ 8015 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8016 %} 8017 ins_pipe(pipe_serial); 8018 %} 8019 8020 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8021 predicate(n->as_LoadStore()->result_not_used()); 8022 match(Set dummy (GetAndAddL mem incr)); 8023 ins_cost(INSN_COST * 9); 8024 format %{ "get_and_addL [$mem], $incr" %} 8025 ins_encode %{ 8026 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8027 %} 8028 ins_pipe(pipe_serial); 8029 %} 8030 8031 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8032 match(Set newval (GetAndAddI mem incr)); 8033 ins_cost(INSN_COST * 10); 8034 format %{ "get_and_addI $newval, [$mem], $incr" %} 8035 ins_encode %{ 8036 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8037 %} 8038 ins_pipe(pipe_serial); 8039 %} 8040 8041 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8042 predicate(n->as_LoadStore()->result_not_used()); 8043 match(Set dummy (GetAndAddI mem incr)); 8044 ins_cost(INSN_COST * 9); 8045 format %{ "get_and_addI [$mem], $incr" %} 8046 ins_encode %{ 8047 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8048 %} 8049 ins_pipe(pipe_serial); 8050 %} 8051 8052 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8053 match(Set newval (GetAndAddI mem incr)); 8054 ins_cost(INSN_COST * 10); 8055 format %{ "get_and_addI $newval, [$mem], $incr" %} 8056 ins_encode %{ 8057 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8058 %} 8059 ins_pipe(pipe_serial); 8060 %} 8061 8062 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8063 predicate(n->as_LoadStore()->result_not_used()); 8064 match(Set dummy (GetAndAddI mem incr)); 8065 ins_cost(INSN_COST * 9); 8066 format %{ "get_and_addI [$mem], $incr" %} 8067 ins_encode %{ 8068 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8069 %} 8070 ins_pipe(pipe_serial); 8071 %} 8072 8073 // Manifest a CmpL result in an integer register. 8074 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8075 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8076 %{ 8077 match(Set dst (CmpL3 src1 src2)); 8078 effect(KILL flags); 8079 8080 ins_cost(INSN_COST * 6); 8081 format %{ 8082 "cmp $src1, $src2" 8083 "csetw $dst, ne" 8084 "cnegw $dst, lt" 8085 %} 8086 // format %{ "CmpL3 $dst, $src1, $src2" %} 8087 ins_encode %{ 8088 __ cmp($src1$$Register, $src2$$Register); 8089 __ csetw($dst$$Register, Assembler::NE); 8090 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8091 %} 8092 8093 ins_pipe(pipe_class_default); 8094 %} 8095 8096 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8097 %{ 8098 match(Set dst (CmpL3 src1 src2)); 8099 effect(KILL flags); 8100 8101 ins_cost(INSN_COST * 6); 8102 format %{ 8103 "cmp $src1, $src2" 8104 "csetw $dst, ne" 8105 "cnegw $dst, lt" 8106 %} 8107 ins_encode %{ 8108 int32_t con = (int32_t)$src2$$constant; 8109 if (con < 0) { 8110 __ adds(zr, $src1$$Register, -con); 8111 } else { 8112 __ subs(zr, $src1$$Register, con); 8113 } 8114 __ csetw($dst$$Register, Assembler::NE); 8115 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8116 %} 8117 8118 ins_pipe(pipe_class_default); 8119 %} 8120 8121 // ============================================================================ 8122 // Conditional Move Instructions 8123 8124 // n.b. we have identical rules for both a signed compare op (cmpOp) 8125 // and an unsigned compare op (cmpOpU). it would be nice if we could 8126 // define an op class which merged both inputs and use it to type the 8127 // argument to a single rule. unfortunatelyt his fails because the 8128 // opclass does not live up to the COND_INTER interface of its 8129 // component operands. When the generic code tries to negate the 8130 // operand it ends up running the generci Machoper::negate method 8131 // which throws a ShouldNotHappen. So, we have to provide two flavours 8132 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 8133 8134 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8135 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8136 8137 ins_cost(INSN_COST * 2); 8138 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 8139 8140 ins_encode %{ 8141 __ cselw(as_Register($dst$$reg), 8142 as_Register($src2$$reg), 8143 as_Register($src1$$reg), 8144 (Assembler::Condition)$cmp$$cmpcode); 8145 %} 8146 8147 ins_pipe(icond_reg_reg); 8148 %} 8149 8150 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8151 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 8152 8153 ins_cost(INSN_COST * 2); 8154 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 8155 8156 ins_encode %{ 8157 __ cselw(as_Register($dst$$reg), 8158 as_Register($src2$$reg), 8159 as_Register($src1$$reg), 8160 (Assembler::Condition)$cmp$$cmpcode); 8161 %} 8162 8163 ins_pipe(icond_reg_reg); 8164 %} 8165 8166 // special cases where one arg is zero 8167 8168 // n.b. this is selected in preference to the rule above because it 8169 // avoids loading constant 0 into a source register 8170 8171 // TODO 8172 // we ought only to be able to cull one of these variants as the ideal 8173 // transforms ought always to order the zero consistently (to left/right?) 8174 8175 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8176 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8177 8178 ins_cost(INSN_COST * 2); 8179 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 8180 8181 ins_encode %{ 8182 __ cselw(as_Register($dst$$reg), 8183 as_Register($src$$reg), 8184 zr, 8185 (Assembler::Condition)$cmp$$cmpcode); 8186 %} 8187 8188 ins_pipe(icond_reg); 8189 %} 8190 8191 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 8192 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 8193 8194 ins_cost(INSN_COST * 2); 8195 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 8196 8197 ins_encode %{ 8198 __ cselw(as_Register($dst$$reg), 8199 as_Register($src$$reg), 8200 zr, 8201 (Assembler::Condition)$cmp$$cmpcode); 8202 %} 8203 8204 ins_pipe(icond_reg); 8205 %} 8206 8207 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8208 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8209 8210 ins_cost(INSN_COST * 2); 8211 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 8212 8213 ins_encode %{ 8214 __ cselw(as_Register($dst$$reg), 8215 zr, 8216 as_Register($src$$reg), 8217 (Assembler::Condition)$cmp$$cmpcode); 8218 %} 8219 8220 ins_pipe(icond_reg); 8221 %} 8222 8223 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 8224 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 8225 8226 ins_cost(INSN_COST * 2); 8227 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 8228 8229 ins_encode %{ 8230 __ cselw(as_Register($dst$$reg), 8231 zr, 8232 as_Register($src$$reg), 8233 (Assembler::Condition)$cmp$$cmpcode); 8234 %} 8235 8236 ins_pipe(icond_reg); 8237 %} 8238 8239 // special case for creating a boolean 0 or 1 8240 8241 // n.b. this is selected in preference to the rule above because it 8242 // avoids loading constants 0 and 1 into a source register 8243 8244 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8245 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8246 8247 ins_cost(INSN_COST * 2); 8248 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 8249 8250 ins_encode %{ 8251 // equivalently 8252 // cset(as_Register($dst$$reg), 8253 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8254 __ csincw(as_Register($dst$$reg), 8255 zr, 8256 zr, 8257 (Assembler::Condition)$cmp$$cmpcode); 8258 %} 8259 8260 ins_pipe(icond_none); 8261 %} 8262 8263 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 8264 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 8265 8266 ins_cost(INSN_COST * 2); 8267 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 8268 8269 ins_encode %{ 8270 // equivalently 8271 // cset(as_Register($dst$$reg), 8272 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 8273 __ csincw(as_Register($dst$$reg), 8274 zr, 8275 zr, 8276 (Assembler::Condition)$cmp$$cmpcode); 8277 %} 8278 8279 ins_pipe(icond_none); 8280 %} 8281 8282 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8283 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8284 8285 ins_cost(INSN_COST * 2); 8286 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 8287 8288 ins_encode %{ 8289 __ csel(as_Register($dst$$reg), 8290 as_Register($src2$$reg), 8291 as_Register($src1$$reg), 8292 (Assembler::Condition)$cmp$$cmpcode); 8293 %} 8294 8295 ins_pipe(icond_reg_reg); 8296 %} 8297 8298 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8299 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 8300 8301 ins_cost(INSN_COST * 2); 8302 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 8303 8304 ins_encode %{ 8305 __ csel(as_Register($dst$$reg), 8306 as_Register($src2$$reg), 8307 as_Register($src1$$reg), 8308 (Assembler::Condition)$cmp$$cmpcode); 8309 %} 8310 8311 ins_pipe(icond_reg_reg); 8312 %} 8313 8314 // special cases where one arg is zero 8315 8316 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8317 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8318 8319 ins_cost(INSN_COST * 2); 8320 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 8321 8322 ins_encode %{ 8323 __ csel(as_Register($dst$$reg), 8324 zr, 8325 as_Register($src$$reg), 8326 (Assembler::Condition)$cmp$$cmpcode); 8327 %} 8328 8329 ins_pipe(icond_reg); 8330 %} 8331 8332 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8333 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8334 8335 ins_cost(INSN_COST * 2); 8336 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 8337 8338 ins_encode %{ 8339 __ csel(as_Register($dst$$reg), 8340 zr, 8341 as_Register($src$$reg), 8342 (Assembler::Condition)$cmp$$cmpcode); 8343 %} 8344 8345 ins_pipe(icond_reg); 8346 %} 8347 8348 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8349 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8350 8351 ins_cost(INSN_COST * 2); 8352 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 8353 8354 ins_encode %{ 8355 __ csel(as_Register($dst$$reg), 8356 as_Register($src$$reg), 8357 zr, 8358 (Assembler::Condition)$cmp$$cmpcode); 8359 %} 8360 8361 ins_pipe(icond_reg); 8362 %} 8363 8364 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8365 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8366 8367 ins_cost(INSN_COST * 2); 8368 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 8369 8370 ins_encode %{ 8371 __ csel(as_Register($dst$$reg), 8372 as_Register($src$$reg), 8373 zr, 8374 (Assembler::Condition)$cmp$$cmpcode); 8375 %} 8376 8377 ins_pipe(icond_reg); 8378 %} 8379 8380 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8381 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8382 8383 ins_cost(INSN_COST * 2); 8384 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 8385 8386 ins_encode %{ 8387 __ csel(as_Register($dst$$reg), 8388 as_Register($src2$$reg), 8389 as_Register($src1$$reg), 8390 (Assembler::Condition)$cmp$$cmpcode); 8391 %} 8392 8393 ins_pipe(icond_reg_reg); 8394 %} 8395 8396 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8397 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8398 8399 ins_cost(INSN_COST * 2); 8400 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 8401 8402 ins_encode %{ 8403 __ csel(as_Register($dst$$reg), 8404 as_Register($src2$$reg), 8405 as_Register($src1$$reg), 8406 (Assembler::Condition)$cmp$$cmpcode); 8407 %} 8408 8409 ins_pipe(icond_reg_reg); 8410 %} 8411 8412 // special cases where one arg is zero 8413 8414 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8415 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8416 8417 ins_cost(INSN_COST * 2); 8418 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 8419 8420 ins_encode %{ 8421 __ csel(as_Register($dst$$reg), 8422 zr, 8423 as_Register($src$$reg), 8424 (Assembler::Condition)$cmp$$cmpcode); 8425 %} 8426 8427 ins_pipe(icond_reg); 8428 %} 8429 8430 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8431 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8432 8433 ins_cost(INSN_COST * 2); 8434 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 8435 8436 ins_encode %{ 8437 __ csel(as_Register($dst$$reg), 8438 zr, 8439 as_Register($src$$reg), 8440 (Assembler::Condition)$cmp$$cmpcode); 8441 %} 8442 8443 ins_pipe(icond_reg); 8444 %} 8445 8446 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8447 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8448 8449 ins_cost(INSN_COST * 2); 8450 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 8451 8452 ins_encode %{ 8453 __ csel(as_Register($dst$$reg), 8454 as_Register($src$$reg), 8455 zr, 8456 (Assembler::Condition)$cmp$$cmpcode); 8457 %} 8458 8459 ins_pipe(icond_reg); 8460 %} 8461 8462 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8463 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8464 8465 ins_cost(INSN_COST * 2); 8466 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 8467 8468 ins_encode %{ 8469 __ csel(as_Register($dst$$reg), 8470 as_Register($src$$reg), 8471 zr, 8472 (Assembler::Condition)$cmp$$cmpcode); 8473 %} 8474 8475 ins_pipe(icond_reg); 8476 %} 8477 8478 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8479 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8480 8481 ins_cost(INSN_COST * 2); 8482 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8483 8484 ins_encode %{ 8485 __ cselw(as_Register($dst$$reg), 8486 as_Register($src2$$reg), 8487 as_Register($src1$$reg), 8488 (Assembler::Condition)$cmp$$cmpcode); 8489 %} 8490 8491 ins_pipe(icond_reg_reg); 8492 %} 8493 8494 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8495 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8496 8497 ins_cost(INSN_COST * 2); 8498 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8499 8500 ins_encode %{ 8501 __ cselw(as_Register($dst$$reg), 8502 as_Register($src2$$reg), 8503 as_Register($src1$$reg), 8504 (Assembler::Condition)$cmp$$cmpcode); 8505 %} 8506 8507 ins_pipe(icond_reg_reg); 8508 %} 8509 8510 // special cases where one arg is zero 8511 8512 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8513 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8514 8515 ins_cost(INSN_COST * 2); 8516 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 8517 8518 ins_encode %{ 8519 __ cselw(as_Register($dst$$reg), 8520 zr, 8521 as_Register($src$$reg), 8522 (Assembler::Condition)$cmp$$cmpcode); 8523 %} 8524 8525 ins_pipe(icond_reg); 8526 %} 8527 8528 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8529 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8530 8531 ins_cost(INSN_COST * 2); 8532 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 8533 8534 ins_encode %{ 8535 __ cselw(as_Register($dst$$reg), 8536 zr, 8537 as_Register($src$$reg), 8538 (Assembler::Condition)$cmp$$cmpcode); 8539 %} 8540 8541 ins_pipe(icond_reg); 8542 %} 8543 8544 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8545 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8546 8547 ins_cost(INSN_COST * 2); 8548 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 8549 8550 ins_encode %{ 8551 __ cselw(as_Register($dst$$reg), 8552 as_Register($src$$reg), 8553 zr, 8554 (Assembler::Condition)$cmp$$cmpcode); 8555 %} 8556 8557 ins_pipe(icond_reg); 8558 %} 8559 8560 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8561 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8562 8563 ins_cost(INSN_COST * 2); 8564 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 8565 8566 ins_encode %{ 8567 __ cselw(as_Register($dst$$reg), 8568 as_Register($src$$reg), 8569 zr, 8570 (Assembler::Condition)$cmp$$cmpcode); 8571 %} 8572 8573 ins_pipe(icond_reg); 8574 %} 8575 8576 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 8577 %{ 8578 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8579 8580 ins_cost(INSN_COST * 3); 8581 8582 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8583 ins_encode %{ 8584 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8585 __ fcsels(as_FloatRegister($dst$$reg), 8586 as_FloatRegister($src2$$reg), 8587 as_FloatRegister($src1$$reg), 8588 cond); 8589 %} 8590 8591 ins_pipe(pipe_class_default); 8592 %} 8593 8594 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 8595 %{ 8596 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8597 8598 ins_cost(INSN_COST * 3); 8599 8600 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8601 ins_encode %{ 8602 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8603 __ fcsels(as_FloatRegister($dst$$reg), 8604 as_FloatRegister($src2$$reg), 8605 as_FloatRegister($src1$$reg), 8606 cond); 8607 %} 8608 8609 ins_pipe(pipe_class_default); 8610 %} 8611 8612 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 8613 %{ 8614 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8615 8616 ins_cost(INSN_COST * 3); 8617 8618 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8619 ins_encode %{ 8620 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8621 __ fcseld(as_FloatRegister($dst$$reg), 8622 as_FloatRegister($src2$$reg), 8623 as_FloatRegister($src1$$reg), 8624 cond); 8625 %} 8626 8627 ins_pipe(pipe_class_default); 8628 %} 8629 8630 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 8631 %{ 8632 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8633 8634 ins_cost(INSN_COST * 3); 8635 8636 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8637 ins_encode %{ 8638 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8639 __ fcseld(as_FloatRegister($dst$$reg), 8640 as_FloatRegister($src2$$reg), 8641 as_FloatRegister($src1$$reg), 8642 cond); 8643 %} 8644 8645 ins_pipe(pipe_class_default); 8646 %} 8647 8648 // ============================================================================ 8649 // Arithmetic Instructions 8650 // 8651 8652 // Integer Addition 8653 8654 // TODO 8655 // these currently employ operations which do not set CR and hence are 8656 // not flagged as killing CR but we would like to isolate the cases 8657 // where we want to set flags from those where we don't. need to work 8658 // out how to do that. 8659 8660 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8661 match(Set dst (AddI src1 src2)); 8662 8663 ins_cost(INSN_COST); 8664 format %{ "addw $dst, $src1, $src2" %} 8665 8666 ins_encode %{ 8667 __ addw(as_Register($dst$$reg), 8668 as_Register($src1$$reg), 8669 as_Register($src2$$reg)); 8670 %} 8671 8672 ins_pipe(ialu_reg_reg); 8673 %} 8674 8675 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8676 match(Set dst (AddI src1 src2)); 8677 8678 ins_cost(INSN_COST); 8679 format %{ "addw $dst, $src1, $src2" %} 8680 8681 // use opcode to indicate that this is an add not a sub 8682 opcode(0x0); 8683 8684 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8685 8686 ins_pipe(ialu_reg_imm); 8687 %} 8688 8689 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 8690 match(Set dst (AddI (ConvL2I src1) src2)); 8691 8692 ins_cost(INSN_COST); 8693 format %{ "addw $dst, $src1, $src2" %} 8694 8695 // use opcode to indicate that this is an add not a sub 8696 opcode(0x0); 8697 8698 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8699 8700 ins_pipe(ialu_reg_imm); 8701 %} 8702 8703 // Pointer Addition 8704 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 8705 match(Set dst (AddP src1 src2)); 8706 8707 ins_cost(INSN_COST); 8708 format %{ "add $dst, $src1, $src2\t# ptr" %} 8709 8710 ins_encode %{ 8711 __ add(as_Register($dst$$reg), 8712 as_Register($src1$$reg), 8713 as_Register($src2$$reg)); 8714 %} 8715 8716 ins_pipe(ialu_reg_reg); 8717 %} 8718 8719 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 8720 match(Set dst (AddP src1 (ConvI2L src2))); 8721 8722 ins_cost(1.9 * INSN_COST); 8723 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 8724 8725 ins_encode %{ 8726 __ add(as_Register($dst$$reg), 8727 as_Register($src1$$reg), 8728 as_Register($src2$$reg), ext::sxtw); 8729 %} 8730 8731 ins_pipe(ialu_reg_reg); 8732 %} 8733 8734 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 8735 match(Set dst (AddP src1 (LShiftL src2 scale))); 8736 8737 ins_cost(1.9 * INSN_COST); 8738 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 8739 8740 ins_encode %{ 8741 __ lea(as_Register($dst$$reg), 8742 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8743 Address::lsl($scale$$constant))); 8744 %} 8745 8746 ins_pipe(ialu_reg_reg_shift); 8747 %} 8748 8749 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 8750 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 8751 8752 ins_cost(1.9 * INSN_COST); 8753 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 8754 8755 ins_encode %{ 8756 __ lea(as_Register($dst$$reg), 8757 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8758 Address::sxtw($scale$$constant))); 8759 %} 8760 8761 ins_pipe(ialu_reg_reg_shift); 8762 %} 8763 8764 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 8765 match(Set dst (LShiftL (ConvI2L src) scale)); 8766 8767 ins_cost(INSN_COST); 8768 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 8769 8770 ins_encode %{ 8771 __ sbfiz(as_Register($dst$$reg), 8772 as_Register($src$$reg), 8773 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 8774 %} 8775 8776 ins_pipe(ialu_reg_shift); 8777 %} 8778 8779 // Pointer Immediate Addition 8780 // n.b. this needs to be more expensive than using an indirect memory 8781 // operand 8782 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 8783 match(Set dst (AddP src1 src2)); 8784 8785 ins_cost(INSN_COST); 8786 format %{ "add $dst, $src1, $src2\t# ptr" %} 8787 8788 // use opcode to indicate that this is an add not a sub 8789 opcode(0x0); 8790 8791 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8792 8793 ins_pipe(ialu_reg_imm); 8794 %} 8795 8796 // Long Addition 8797 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8798 8799 match(Set dst (AddL src1 src2)); 8800 8801 ins_cost(INSN_COST); 8802 format %{ "add $dst, $src1, $src2" %} 8803 8804 ins_encode %{ 8805 __ add(as_Register($dst$$reg), 8806 as_Register($src1$$reg), 8807 as_Register($src2$$reg)); 8808 %} 8809 8810 ins_pipe(ialu_reg_reg); 8811 %} 8812 8813 // No constant pool entries requiredLong Immediate Addition. 8814 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8815 match(Set dst (AddL src1 src2)); 8816 8817 ins_cost(INSN_COST); 8818 format %{ "add $dst, $src1, $src2" %} 8819 8820 // use opcode to indicate that this is an add not a sub 8821 opcode(0x0); 8822 8823 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8824 8825 ins_pipe(ialu_reg_imm); 8826 %} 8827 8828 // Integer Subtraction 8829 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8830 match(Set dst (SubI src1 src2)); 8831 8832 ins_cost(INSN_COST); 8833 format %{ "subw $dst, $src1, $src2" %} 8834 8835 ins_encode %{ 8836 __ subw(as_Register($dst$$reg), 8837 as_Register($src1$$reg), 8838 as_Register($src2$$reg)); 8839 %} 8840 8841 ins_pipe(ialu_reg_reg); 8842 %} 8843 8844 // Immediate Subtraction 8845 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8846 match(Set dst (SubI src1 src2)); 8847 8848 ins_cost(INSN_COST); 8849 format %{ "subw $dst, $src1, $src2" %} 8850 8851 // use opcode to indicate that this is a sub not an add 8852 opcode(0x1); 8853 8854 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8855 8856 ins_pipe(ialu_reg_imm); 8857 %} 8858 8859 // Long Subtraction 8860 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8861 8862 match(Set dst (SubL src1 src2)); 8863 8864 ins_cost(INSN_COST); 8865 format %{ "sub $dst, $src1, $src2" %} 8866 8867 ins_encode %{ 8868 __ sub(as_Register($dst$$reg), 8869 as_Register($src1$$reg), 8870 as_Register($src2$$reg)); 8871 %} 8872 8873 ins_pipe(ialu_reg_reg); 8874 %} 8875 8876 // No constant pool entries requiredLong Immediate Subtraction. 8877 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8878 match(Set dst (SubL src1 src2)); 8879 8880 ins_cost(INSN_COST); 8881 format %{ "sub$dst, $src1, $src2" %} 8882 8883 // use opcode to indicate that this is a sub not an add 8884 opcode(0x1); 8885 8886 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8887 8888 ins_pipe(ialu_reg_imm); 8889 %} 8890 8891 // Integer Negation (special case for sub) 8892 8893 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 8894 match(Set dst (SubI zero src)); 8895 8896 ins_cost(INSN_COST); 8897 format %{ "negw $dst, $src\t# int" %} 8898 8899 ins_encode %{ 8900 __ negw(as_Register($dst$$reg), 8901 as_Register($src$$reg)); 8902 %} 8903 8904 ins_pipe(ialu_reg); 8905 %} 8906 8907 // Long Negation 8908 8909 instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{ 8910 match(Set dst (SubL zero src)); 8911 8912 ins_cost(INSN_COST); 8913 format %{ "neg $dst, $src\t# long" %} 8914 8915 ins_encode %{ 8916 __ neg(as_Register($dst$$reg), 8917 as_Register($src$$reg)); 8918 %} 8919 8920 ins_pipe(ialu_reg); 8921 %} 8922 8923 // Integer Multiply 8924 8925 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8926 match(Set dst (MulI src1 src2)); 8927 8928 ins_cost(INSN_COST * 3); 8929 format %{ "mulw $dst, $src1, $src2" %} 8930 8931 ins_encode %{ 8932 __ mulw(as_Register($dst$$reg), 8933 as_Register($src1$$reg), 8934 as_Register($src2$$reg)); 8935 %} 8936 8937 ins_pipe(imul_reg_reg); 8938 %} 8939 8940 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8941 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 8942 8943 ins_cost(INSN_COST * 3); 8944 format %{ "smull $dst, $src1, $src2" %} 8945 8946 ins_encode %{ 8947 __ smull(as_Register($dst$$reg), 8948 as_Register($src1$$reg), 8949 as_Register($src2$$reg)); 8950 %} 8951 8952 ins_pipe(imul_reg_reg); 8953 %} 8954 8955 // Long Multiply 8956 8957 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8958 match(Set dst (MulL src1 src2)); 8959 8960 ins_cost(INSN_COST * 5); 8961 format %{ "mul $dst, $src1, $src2" %} 8962 8963 ins_encode %{ 8964 __ mul(as_Register($dst$$reg), 8965 as_Register($src1$$reg), 8966 as_Register($src2$$reg)); 8967 %} 8968 8969 ins_pipe(lmul_reg_reg); 8970 %} 8971 8972 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 8973 %{ 8974 match(Set dst (MulHiL src1 src2)); 8975 8976 ins_cost(INSN_COST * 7); 8977 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 8978 8979 ins_encode %{ 8980 __ smulh(as_Register($dst$$reg), 8981 as_Register($src1$$reg), 8982 as_Register($src2$$reg)); 8983 %} 8984 8985 ins_pipe(lmul_reg_reg); 8986 %} 8987 8988 // Combined Integer Multiply & Add/Sub 8989 8990 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 8991 match(Set dst (AddI src3 (MulI src1 src2))); 8992 8993 ins_cost(INSN_COST * 3); 8994 format %{ "madd $dst, $src1, $src2, $src3" %} 8995 8996 ins_encode %{ 8997 __ maddw(as_Register($dst$$reg), 8998 as_Register($src1$$reg), 8999 as_Register($src2$$reg), 9000 as_Register($src3$$reg)); 9001 %} 9002 9003 ins_pipe(imac_reg_reg); 9004 %} 9005 9006 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9007 match(Set dst (SubI src3 (MulI src1 src2))); 9008 9009 ins_cost(INSN_COST * 3); 9010 format %{ "msub $dst, $src1, $src2, $src3" %} 9011 9012 ins_encode %{ 9013 __ msubw(as_Register($dst$$reg), 9014 as_Register($src1$$reg), 9015 as_Register($src2$$reg), 9016 as_Register($src3$$reg)); 9017 %} 9018 9019 ins_pipe(imac_reg_reg); 9020 %} 9021 9022 // Combined Long Multiply & Add/Sub 9023 9024 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9025 match(Set dst (AddL src3 (MulL src1 src2))); 9026 9027 ins_cost(INSN_COST * 5); 9028 format %{ "madd $dst, $src1, $src2, $src3" %} 9029 9030 ins_encode %{ 9031 __ madd(as_Register($dst$$reg), 9032 as_Register($src1$$reg), 9033 as_Register($src2$$reg), 9034 as_Register($src3$$reg)); 9035 %} 9036 9037 ins_pipe(lmac_reg_reg); 9038 %} 9039 9040 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9041 match(Set dst (SubL src3 (MulL src1 src2))); 9042 9043 ins_cost(INSN_COST * 5); 9044 format %{ "msub $dst, $src1, $src2, $src3" %} 9045 9046 ins_encode %{ 9047 __ msub(as_Register($dst$$reg), 9048 as_Register($src1$$reg), 9049 as_Register($src2$$reg), 9050 as_Register($src3$$reg)); 9051 %} 9052 9053 ins_pipe(lmac_reg_reg); 9054 %} 9055 9056 // Integer Divide 9057 9058 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9059 match(Set dst (DivI src1 src2)); 9060 9061 ins_cost(INSN_COST * 19); 9062 format %{ "sdivw $dst, $src1, $src2" %} 9063 9064 ins_encode(aarch64_enc_divw(dst, src1, src2)); 9065 ins_pipe(idiv_reg_reg); 9066 %} 9067 9068 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 9069 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 9070 ins_cost(INSN_COST); 9071 format %{ "lsrw $dst, $src1, $div1" %} 9072 ins_encode %{ 9073 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 9074 %} 9075 ins_pipe(ialu_reg_shift); 9076 %} 9077 9078 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 9079 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 9080 ins_cost(INSN_COST); 9081 format %{ "addw $dst, $src, LSR $div1" %} 9082 9083 ins_encode %{ 9084 __ addw(as_Register($dst$$reg), 9085 as_Register($src$$reg), 9086 as_Register($src$$reg), 9087 Assembler::LSR, 31); 9088 %} 9089 ins_pipe(ialu_reg); 9090 %} 9091 9092 // Long Divide 9093 9094 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9095 match(Set dst (DivL src1 src2)); 9096 9097 ins_cost(INSN_COST * 35); 9098 format %{ "sdiv $dst, $src1, $src2" %} 9099 9100 ins_encode(aarch64_enc_div(dst, src1, src2)); 9101 ins_pipe(ldiv_reg_reg); 9102 %} 9103 9104 instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{ 9105 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 9106 ins_cost(INSN_COST); 9107 format %{ "lsr $dst, $src1, $div1" %} 9108 ins_encode %{ 9109 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 9110 %} 9111 ins_pipe(ialu_reg_shift); 9112 %} 9113 9114 instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{ 9115 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 9116 ins_cost(INSN_COST); 9117 format %{ "add $dst, $src, $div1" %} 9118 9119 ins_encode %{ 9120 __ add(as_Register($dst$$reg), 9121 as_Register($src$$reg), 9122 as_Register($src$$reg), 9123 Assembler::LSR, 63); 9124 %} 9125 ins_pipe(ialu_reg); 9126 %} 9127 9128 // Integer Remainder 9129 9130 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9131 match(Set dst (ModI src1 src2)); 9132 9133 ins_cost(INSN_COST * 22); 9134 format %{ "sdivw rscratch1, $src1, $src2\n\t" 9135 "msubw($dst, rscratch1, $src2, $src1" %} 9136 9137 ins_encode(aarch64_enc_modw(dst, src1, src2)); 9138 ins_pipe(idiv_reg_reg); 9139 %} 9140 9141 // Long Remainder 9142 9143 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9144 match(Set dst (ModL src1 src2)); 9145 9146 ins_cost(INSN_COST * 38); 9147 format %{ "sdiv rscratch1, $src1, $src2\n" 9148 "msub($dst, rscratch1, $src2, $src1" %} 9149 9150 ins_encode(aarch64_enc_mod(dst, src1, src2)); 9151 ins_pipe(ldiv_reg_reg); 9152 %} 9153 9154 // Integer Shifts 9155 9156 // Shift Left Register 9157 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9158 match(Set dst (LShiftI src1 src2)); 9159 9160 ins_cost(INSN_COST * 2); 9161 format %{ "lslvw $dst, $src1, $src2" %} 9162 9163 ins_encode %{ 9164 __ lslvw(as_Register($dst$$reg), 9165 as_Register($src1$$reg), 9166 as_Register($src2$$reg)); 9167 %} 9168 9169 ins_pipe(ialu_reg_reg_vshift); 9170 %} 9171 9172 // Shift Left Immediate 9173 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9174 match(Set dst (LShiftI src1 src2)); 9175 9176 ins_cost(INSN_COST); 9177 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 9178 9179 ins_encode %{ 9180 __ lslw(as_Register($dst$$reg), 9181 as_Register($src1$$reg), 9182 $src2$$constant & 0x1f); 9183 %} 9184 9185 ins_pipe(ialu_reg_shift); 9186 %} 9187 9188 // Shift Right Logical Register 9189 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9190 match(Set dst (URShiftI src1 src2)); 9191 9192 ins_cost(INSN_COST * 2); 9193 format %{ "lsrvw $dst, $src1, $src2" %} 9194 9195 ins_encode %{ 9196 __ lsrvw(as_Register($dst$$reg), 9197 as_Register($src1$$reg), 9198 as_Register($src2$$reg)); 9199 %} 9200 9201 ins_pipe(ialu_reg_reg_vshift); 9202 %} 9203 9204 // Shift Right Logical Immediate 9205 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9206 match(Set dst (URShiftI src1 src2)); 9207 9208 ins_cost(INSN_COST); 9209 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 9210 9211 ins_encode %{ 9212 __ lsrw(as_Register($dst$$reg), 9213 as_Register($src1$$reg), 9214 $src2$$constant & 0x1f); 9215 %} 9216 9217 ins_pipe(ialu_reg_shift); 9218 %} 9219 9220 // Shift Right Arithmetic Register 9221 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9222 match(Set dst (RShiftI src1 src2)); 9223 9224 ins_cost(INSN_COST * 2); 9225 format %{ "asrvw $dst, $src1, $src2" %} 9226 9227 ins_encode %{ 9228 __ asrvw(as_Register($dst$$reg), 9229 as_Register($src1$$reg), 9230 as_Register($src2$$reg)); 9231 %} 9232 9233 ins_pipe(ialu_reg_reg_vshift); 9234 %} 9235 9236 // Shift Right Arithmetic Immediate 9237 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 9238 match(Set dst (RShiftI src1 src2)); 9239 9240 ins_cost(INSN_COST); 9241 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 9242 9243 ins_encode %{ 9244 __ asrw(as_Register($dst$$reg), 9245 as_Register($src1$$reg), 9246 $src2$$constant & 0x1f); 9247 %} 9248 9249 ins_pipe(ialu_reg_shift); 9250 %} 9251 9252 // Combined Int Mask and Right Shift (using UBFM) 9253 // TODO 9254 9255 // Long Shifts 9256 9257 // Shift Left Register 9258 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9259 match(Set dst (LShiftL src1 src2)); 9260 9261 ins_cost(INSN_COST * 2); 9262 format %{ "lslv $dst, $src1, $src2" %} 9263 9264 ins_encode %{ 9265 __ lslv(as_Register($dst$$reg), 9266 as_Register($src1$$reg), 9267 as_Register($src2$$reg)); 9268 %} 9269 9270 ins_pipe(ialu_reg_reg_vshift); 9271 %} 9272 9273 // Shift Left Immediate 9274 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9275 match(Set dst (LShiftL src1 src2)); 9276 9277 ins_cost(INSN_COST); 9278 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 9279 9280 ins_encode %{ 9281 __ lsl(as_Register($dst$$reg), 9282 as_Register($src1$$reg), 9283 $src2$$constant & 0x3f); 9284 %} 9285 9286 ins_pipe(ialu_reg_shift); 9287 %} 9288 9289 // Shift Right Logical Register 9290 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9291 match(Set dst (URShiftL src1 src2)); 9292 9293 ins_cost(INSN_COST * 2); 9294 format %{ "lsrv $dst, $src1, $src2" %} 9295 9296 ins_encode %{ 9297 __ lsrv(as_Register($dst$$reg), 9298 as_Register($src1$$reg), 9299 as_Register($src2$$reg)); 9300 %} 9301 9302 ins_pipe(ialu_reg_reg_vshift); 9303 %} 9304 9305 // Shift Right Logical Immediate 9306 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9307 match(Set dst (URShiftL src1 src2)); 9308 9309 ins_cost(INSN_COST); 9310 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 9311 9312 ins_encode %{ 9313 __ lsr(as_Register($dst$$reg), 9314 as_Register($src1$$reg), 9315 $src2$$constant & 0x3f); 9316 %} 9317 9318 ins_pipe(ialu_reg_shift); 9319 %} 9320 9321 // A special-case pattern for card table stores. 9322 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 9323 match(Set dst (URShiftL (CastP2X src1) src2)); 9324 9325 ins_cost(INSN_COST); 9326 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 9327 9328 ins_encode %{ 9329 __ lsr(as_Register($dst$$reg), 9330 as_Register($src1$$reg), 9331 $src2$$constant & 0x3f); 9332 %} 9333 9334 ins_pipe(ialu_reg_shift); 9335 %} 9336 9337 // Shift Right Arithmetic Register 9338 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9339 match(Set dst (RShiftL src1 src2)); 9340 9341 ins_cost(INSN_COST * 2); 9342 format %{ "asrv $dst, $src1, $src2" %} 9343 9344 ins_encode %{ 9345 __ asrv(as_Register($dst$$reg), 9346 as_Register($src1$$reg), 9347 as_Register($src2$$reg)); 9348 %} 9349 9350 ins_pipe(ialu_reg_reg_vshift); 9351 %} 9352 9353 // Shift Right Arithmetic Immediate 9354 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9355 match(Set dst (RShiftL src1 src2)); 9356 9357 ins_cost(INSN_COST); 9358 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 9359 9360 ins_encode %{ 9361 __ asr(as_Register($dst$$reg), 9362 as_Register($src1$$reg), 9363 $src2$$constant & 0x3f); 9364 %} 9365 9366 ins_pipe(ialu_reg_shift); 9367 %} 9368 9369 // BEGIN This section of the file is automatically generated. Do not edit -------------- 9370 9371 instruct regL_not_reg(iRegLNoSp dst, 9372 iRegL src1, immL_M1 m1, 9373 rFlagsReg cr) %{ 9374 match(Set dst (XorL src1 m1)); 9375 ins_cost(INSN_COST); 9376 format %{ "eon $dst, $src1, zr" %} 9377 9378 ins_encode %{ 9379 __ eon(as_Register($dst$$reg), 9380 as_Register($src1$$reg), 9381 zr, 9382 Assembler::LSL, 0); 9383 %} 9384 9385 ins_pipe(ialu_reg); 9386 %} 9387 instruct regI_not_reg(iRegINoSp dst, 9388 iRegIorL2I src1, immI_M1 m1, 9389 rFlagsReg cr) %{ 9390 match(Set dst (XorI src1 m1)); 9391 ins_cost(INSN_COST); 9392 format %{ "eonw $dst, $src1, zr" %} 9393 9394 ins_encode %{ 9395 __ eonw(as_Register($dst$$reg), 9396 as_Register($src1$$reg), 9397 zr, 9398 Assembler::LSL, 0); 9399 %} 9400 9401 ins_pipe(ialu_reg); 9402 %} 9403 9404 instruct AndI_reg_not_reg(iRegINoSp dst, 9405 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9406 rFlagsReg cr) %{ 9407 match(Set dst (AndI src1 (XorI src2 m1))); 9408 ins_cost(INSN_COST); 9409 format %{ "bicw $dst, $src1, $src2" %} 9410 9411 ins_encode %{ 9412 __ bicw(as_Register($dst$$reg), 9413 as_Register($src1$$reg), 9414 as_Register($src2$$reg), 9415 Assembler::LSL, 0); 9416 %} 9417 9418 ins_pipe(ialu_reg_reg); 9419 %} 9420 9421 instruct AndL_reg_not_reg(iRegLNoSp dst, 9422 iRegL src1, iRegL src2, immL_M1 m1, 9423 rFlagsReg cr) %{ 9424 match(Set dst (AndL src1 (XorL src2 m1))); 9425 ins_cost(INSN_COST); 9426 format %{ "bic $dst, $src1, $src2" %} 9427 9428 ins_encode %{ 9429 __ bic(as_Register($dst$$reg), 9430 as_Register($src1$$reg), 9431 as_Register($src2$$reg), 9432 Assembler::LSL, 0); 9433 %} 9434 9435 ins_pipe(ialu_reg_reg); 9436 %} 9437 9438 instruct OrI_reg_not_reg(iRegINoSp dst, 9439 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9440 rFlagsReg cr) %{ 9441 match(Set dst (OrI src1 (XorI src2 m1))); 9442 ins_cost(INSN_COST); 9443 format %{ "ornw $dst, $src1, $src2" %} 9444 9445 ins_encode %{ 9446 __ ornw(as_Register($dst$$reg), 9447 as_Register($src1$$reg), 9448 as_Register($src2$$reg), 9449 Assembler::LSL, 0); 9450 %} 9451 9452 ins_pipe(ialu_reg_reg); 9453 %} 9454 9455 instruct OrL_reg_not_reg(iRegLNoSp dst, 9456 iRegL src1, iRegL src2, immL_M1 m1, 9457 rFlagsReg cr) %{ 9458 match(Set dst (OrL src1 (XorL src2 m1))); 9459 ins_cost(INSN_COST); 9460 format %{ "orn $dst, $src1, $src2" %} 9461 9462 ins_encode %{ 9463 __ orn(as_Register($dst$$reg), 9464 as_Register($src1$$reg), 9465 as_Register($src2$$reg), 9466 Assembler::LSL, 0); 9467 %} 9468 9469 ins_pipe(ialu_reg_reg); 9470 %} 9471 9472 instruct XorI_reg_not_reg(iRegINoSp dst, 9473 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9474 rFlagsReg cr) %{ 9475 match(Set dst (XorI m1 (XorI src2 src1))); 9476 ins_cost(INSN_COST); 9477 format %{ "eonw $dst, $src1, $src2" %} 9478 9479 ins_encode %{ 9480 __ eonw(as_Register($dst$$reg), 9481 as_Register($src1$$reg), 9482 as_Register($src2$$reg), 9483 Assembler::LSL, 0); 9484 %} 9485 9486 ins_pipe(ialu_reg_reg); 9487 %} 9488 9489 instruct XorL_reg_not_reg(iRegLNoSp dst, 9490 iRegL src1, iRegL src2, immL_M1 m1, 9491 rFlagsReg cr) %{ 9492 match(Set dst (XorL m1 (XorL src2 src1))); 9493 ins_cost(INSN_COST); 9494 format %{ "eon $dst, $src1, $src2" %} 9495 9496 ins_encode %{ 9497 __ eon(as_Register($dst$$reg), 9498 as_Register($src1$$reg), 9499 as_Register($src2$$reg), 9500 Assembler::LSL, 0); 9501 %} 9502 9503 ins_pipe(ialu_reg_reg); 9504 %} 9505 9506 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 9507 iRegIorL2I src1, iRegIorL2I src2, 9508 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9509 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 9510 ins_cost(1.9 * INSN_COST); 9511 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 9512 9513 ins_encode %{ 9514 __ bicw(as_Register($dst$$reg), 9515 as_Register($src1$$reg), 9516 as_Register($src2$$reg), 9517 Assembler::LSR, 9518 $src3$$constant & 0x3f); 9519 %} 9520 9521 ins_pipe(ialu_reg_reg_shift); 9522 %} 9523 9524 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 9525 iRegL src1, iRegL src2, 9526 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9527 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 9528 ins_cost(1.9 * INSN_COST); 9529 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 9530 9531 ins_encode %{ 9532 __ bic(as_Register($dst$$reg), 9533 as_Register($src1$$reg), 9534 as_Register($src2$$reg), 9535 Assembler::LSR, 9536 $src3$$constant & 0x3f); 9537 %} 9538 9539 ins_pipe(ialu_reg_reg_shift); 9540 %} 9541 9542 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 9543 iRegIorL2I src1, iRegIorL2I src2, 9544 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9545 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 9546 ins_cost(1.9 * INSN_COST); 9547 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 9548 9549 ins_encode %{ 9550 __ bicw(as_Register($dst$$reg), 9551 as_Register($src1$$reg), 9552 as_Register($src2$$reg), 9553 Assembler::ASR, 9554 $src3$$constant & 0x3f); 9555 %} 9556 9557 ins_pipe(ialu_reg_reg_shift); 9558 %} 9559 9560 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 9561 iRegL src1, iRegL src2, 9562 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9563 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 9564 ins_cost(1.9 * INSN_COST); 9565 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 9566 9567 ins_encode %{ 9568 __ bic(as_Register($dst$$reg), 9569 as_Register($src1$$reg), 9570 as_Register($src2$$reg), 9571 Assembler::ASR, 9572 $src3$$constant & 0x3f); 9573 %} 9574 9575 ins_pipe(ialu_reg_reg_shift); 9576 %} 9577 9578 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 9579 iRegIorL2I src1, iRegIorL2I src2, 9580 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9581 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 9582 ins_cost(1.9 * INSN_COST); 9583 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 9584 9585 ins_encode %{ 9586 __ bicw(as_Register($dst$$reg), 9587 as_Register($src1$$reg), 9588 as_Register($src2$$reg), 9589 Assembler::LSL, 9590 $src3$$constant & 0x3f); 9591 %} 9592 9593 ins_pipe(ialu_reg_reg_shift); 9594 %} 9595 9596 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 9597 iRegL src1, iRegL src2, 9598 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9599 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 9600 ins_cost(1.9 * INSN_COST); 9601 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 9602 9603 ins_encode %{ 9604 __ bic(as_Register($dst$$reg), 9605 as_Register($src1$$reg), 9606 as_Register($src2$$reg), 9607 Assembler::LSL, 9608 $src3$$constant & 0x3f); 9609 %} 9610 9611 ins_pipe(ialu_reg_reg_shift); 9612 %} 9613 9614 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 9615 iRegIorL2I src1, iRegIorL2I src2, 9616 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9617 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 9618 ins_cost(1.9 * INSN_COST); 9619 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 9620 9621 ins_encode %{ 9622 __ eonw(as_Register($dst$$reg), 9623 as_Register($src1$$reg), 9624 as_Register($src2$$reg), 9625 Assembler::LSR, 9626 $src3$$constant & 0x3f); 9627 %} 9628 9629 ins_pipe(ialu_reg_reg_shift); 9630 %} 9631 9632 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 9633 iRegL src1, iRegL src2, 9634 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9635 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 9636 ins_cost(1.9 * INSN_COST); 9637 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 9638 9639 ins_encode %{ 9640 __ eon(as_Register($dst$$reg), 9641 as_Register($src1$$reg), 9642 as_Register($src2$$reg), 9643 Assembler::LSR, 9644 $src3$$constant & 0x3f); 9645 %} 9646 9647 ins_pipe(ialu_reg_reg_shift); 9648 %} 9649 9650 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 9651 iRegIorL2I src1, iRegIorL2I src2, 9652 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9653 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 9654 ins_cost(1.9 * INSN_COST); 9655 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 9656 9657 ins_encode %{ 9658 __ eonw(as_Register($dst$$reg), 9659 as_Register($src1$$reg), 9660 as_Register($src2$$reg), 9661 Assembler::ASR, 9662 $src3$$constant & 0x3f); 9663 %} 9664 9665 ins_pipe(ialu_reg_reg_shift); 9666 %} 9667 9668 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 9669 iRegL src1, iRegL src2, 9670 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9671 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 9672 ins_cost(1.9 * INSN_COST); 9673 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 9674 9675 ins_encode %{ 9676 __ eon(as_Register($dst$$reg), 9677 as_Register($src1$$reg), 9678 as_Register($src2$$reg), 9679 Assembler::ASR, 9680 $src3$$constant & 0x3f); 9681 %} 9682 9683 ins_pipe(ialu_reg_reg_shift); 9684 %} 9685 9686 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 9687 iRegIorL2I src1, iRegIorL2I src2, 9688 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9689 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 9690 ins_cost(1.9 * INSN_COST); 9691 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 9692 9693 ins_encode %{ 9694 __ eonw(as_Register($dst$$reg), 9695 as_Register($src1$$reg), 9696 as_Register($src2$$reg), 9697 Assembler::LSL, 9698 $src3$$constant & 0x3f); 9699 %} 9700 9701 ins_pipe(ialu_reg_reg_shift); 9702 %} 9703 9704 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 9705 iRegL src1, iRegL src2, 9706 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9707 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 9708 ins_cost(1.9 * INSN_COST); 9709 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 9710 9711 ins_encode %{ 9712 __ eon(as_Register($dst$$reg), 9713 as_Register($src1$$reg), 9714 as_Register($src2$$reg), 9715 Assembler::LSL, 9716 $src3$$constant & 0x3f); 9717 %} 9718 9719 ins_pipe(ialu_reg_reg_shift); 9720 %} 9721 9722 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 9723 iRegIorL2I src1, iRegIorL2I src2, 9724 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9725 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 9726 ins_cost(1.9 * INSN_COST); 9727 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 9728 9729 ins_encode %{ 9730 __ ornw(as_Register($dst$$reg), 9731 as_Register($src1$$reg), 9732 as_Register($src2$$reg), 9733 Assembler::LSR, 9734 $src3$$constant & 0x3f); 9735 %} 9736 9737 ins_pipe(ialu_reg_reg_shift); 9738 %} 9739 9740 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 9741 iRegL src1, iRegL src2, 9742 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9743 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 9744 ins_cost(1.9 * INSN_COST); 9745 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 9746 9747 ins_encode %{ 9748 __ orn(as_Register($dst$$reg), 9749 as_Register($src1$$reg), 9750 as_Register($src2$$reg), 9751 Assembler::LSR, 9752 $src3$$constant & 0x3f); 9753 %} 9754 9755 ins_pipe(ialu_reg_reg_shift); 9756 %} 9757 9758 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 9759 iRegIorL2I src1, iRegIorL2I src2, 9760 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9761 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 9762 ins_cost(1.9 * INSN_COST); 9763 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 9764 9765 ins_encode %{ 9766 __ ornw(as_Register($dst$$reg), 9767 as_Register($src1$$reg), 9768 as_Register($src2$$reg), 9769 Assembler::ASR, 9770 $src3$$constant & 0x3f); 9771 %} 9772 9773 ins_pipe(ialu_reg_reg_shift); 9774 %} 9775 9776 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 9777 iRegL src1, iRegL src2, 9778 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9779 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 9780 ins_cost(1.9 * INSN_COST); 9781 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 9782 9783 ins_encode %{ 9784 __ orn(as_Register($dst$$reg), 9785 as_Register($src1$$reg), 9786 as_Register($src2$$reg), 9787 Assembler::ASR, 9788 $src3$$constant & 0x3f); 9789 %} 9790 9791 ins_pipe(ialu_reg_reg_shift); 9792 %} 9793 9794 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 9795 iRegIorL2I src1, iRegIorL2I src2, 9796 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9797 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 9798 ins_cost(1.9 * INSN_COST); 9799 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 9800 9801 ins_encode %{ 9802 __ ornw(as_Register($dst$$reg), 9803 as_Register($src1$$reg), 9804 as_Register($src2$$reg), 9805 Assembler::LSL, 9806 $src3$$constant & 0x3f); 9807 %} 9808 9809 ins_pipe(ialu_reg_reg_shift); 9810 %} 9811 9812 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 9813 iRegL src1, iRegL src2, 9814 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9815 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 9816 ins_cost(1.9 * INSN_COST); 9817 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 9818 9819 ins_encode %{ 9820 __ orn(as_Register($dst$$reg), 9821 as_Register($src1$$reg), 9822 as_Register($src2$$reg), 9823 Assembler::LSL, 9824 $src3$$constant & 0x3f); 9825 %} 9826 9827 ins_pipe(ialu_reg_reg_shift); 9828 %} 9829 9830 instruct AndI_reg_URShift_reg(iRegINoSp dst, 9831 iRegIorL2I src1, iRegIorL2I src2, 9832 immI src3, rFlagsReg cr) %{ 9833 match(Set dst (AndI src1 (URShiftI src2 src3))); 9834 9835 ins_cost(1.9 * INSN_COST); 9836 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 9837 9838 ins_encode %{ 9839 __ andw(as_Register($dst$$reg), 9840 as_Register($src1$$reg), 9841 as_Register($src2$$reg), 9842 Assembler::LSR, 9843 $src3$$constant & 0x3f); 9844 %} 9845 9846 ins_pipe(ialu_reg_reg_shift); 9847 %} 9848 9849 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 9850 iRegL src1, iRegL src2, 9851 immI src3, rFlagsReg cr) %{ 9852 match(Set dst (AndL src1 (URShiftL src2 src3))); 9853 9854 ins_cost(1.9 * INSN_COST); 9855 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 9856 9857 ins_encode %{ 9858 __ andr(as_Register($dst$$reg), 9859 as_Register($src1$$reg), 9860 as_Register($src2$$reg), 9861 Assembler::LSR, 9862 $src3$$constant & 0x3f); 9863 %} 9864 9865 ins_pipe(ialu_reg_reg_shift); 9866 %} 9867 9868 instruct AndI_reg_RShift_reg(iRegINoSp dst, 9869 iRegIorL2I src1, iRegIorL2I src2, 9870 immI src3, rFlagsReg cr) %{ 9871 match(Set dst (AndI src1 (RShiftI src2 src3))); 9872 9873 ins_cost(1.9 * INSN_COST); 9874 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 9875 9876 ins_encode %{ 9877 __ andw(as_Register($dst$$reg), 9878 as_Register($src1$$reg), 9879 as_Register($src2$$reg), 9880 Assembler::ASR, 9881 $src3$$constant & 0x3f); 9882 %} 9883 9884 ins_pipe(ialu_reg_reg_shift); 9885 %} 9886 9887 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 9888 iRegL src1, iRegL src2, 9889 immI src3, rFlagsReg cr) %{ 9890 match(Set dst (AndL src1 (RShiftL src2 src3))); 9891 9892 ins_cost(1.9 * INSN_COST); 9893 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 9894 9895 ins_encode %{ 9896 __ andr(as_Register($dst$$reg), 9897 as_Register($src1$$reg), 9898 as_Register($src2$$reg), 9899 Assembler::ASR, 9900 $src3$$constant & 0x3f); 9901 %} 9902 9903 ins_pipe(ialu_reg_reg_shift); 9904 %} 9905 9906 instruct AndI_reg_LShift_reg(iRegINoSp dst, 9907 iRegIorL2I src1, iRegIorL2I src2, 9908 immI src3, rFlagsReg cr) %{ 9909 match(Set dst (AndI src1 (LShiftI src2 src3))); 9910 9911 ins_cost(1.9 * INSN_COST); 9912 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 9913 9914 ins_encode %{ 9915 __ andw(as_Register($dst$$reg), 9916 as_Register($src1$$reg), 9917 as_Register($src2$$reg), 9918 Assembler::LSL, 9919 $src3$$constant & 0x3f); 9920 %} 9921 9922 ins_pipe(ialu_reg_reg_shift); 9923 %} 9924 9925 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 9926 iRegL src1, iRegL src2, 9927 immI src3, rFlagsReg cr) %{ 9928 match(Set dst (AndL src1 (LShiftL src2 src3))); 9929 9930 ins_cost(1.9 * INSN_COST); 9931 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 9932 9933 ins_encode %{ 9934 __ andr(as_Register($dst$$reg), 9935 as_Register($src1$$reg), 9936 as_Register($src2$$reg), 9937 Assembler::LSL, 9938 $src3$$constant & 0x3f); 9939 %} 9940 9941 ins_pipe(ialu_reg_reg_shift); 9942 %} 9943 9944 instruct XorI_reg_URShift_reg(iRegINoSp dst, 9945 iRegIorL2I src1, iRegIorL2I src2, 9946 immI src3, rFlagsReg cr) %{ 9947 match(Set dst (XorI src1 (URShiftI src2 src3))); 9948 9949 ins_cost(1.9 * INSN_COST); 9950 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 9951 9952 ins_encode %{ 9953 __ eorw(as_Register($dst$$reg), 9954 as_Register($src1$$reg), 9955 as_Register($src2$$reg), 9956 Assembler::LSR, 9957 $src3$$constant & 0x3f); 9958 %} 9959 9960 ins_pipe(ialu_reg_reg_shift); 9961 %} 9962 9963 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 9964 iRegL src1, iRegL src2, 9965 immI src3, rFlagsReg cr) %{ 9966 match(Set dst (XorL src1 (URShiftL src2 src3))); 9967 9968 ins_cost(1.9 * INSN_COST); 9969 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 9970 9971 ins_encode %{ 9972 __ eor(as_Register($dst$$reg), 9973 as_Register($src1$$reg), 9974 as_Register($src2$$reg), 9975 Assembler::LSR, 9976 $src3$$constant & 0x3f); 9977 %} 9978 9979 ins_pipe(ialu_reg_reg_shift); 9980 %} 9981 9982 instruct XorI_reg_RShift_reg(iRegINoSp dst, 9983 iRegIorL2I src1, iRegIorL2I src2, 9984 immI src3, rFlagsReg cr) %{ 9985 match(Set dst (XorI src1 (RShiftI src2 src3))); 9986 9987 ins_cost(1.9 * INSN_COST); 9988 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 9989 9990 ins_encode %{ 9991 __ eorw(as_Register($dst$$reg), 9992 as_Register($src1$$reg), 9993 as_Register($src2$$reg), 9994 Assembler::ASR, 9995 $src3$$constant & 0x3f); 9996 %} 9997 9998 ins_pipe(ialu_reg_reg_shift); 9999 %} 10000 10001 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10002 iRegL src1, iRegL src2, 10003 immI src3, rFlagsReg cr) %{ 10004 match(Set dst (XorL src1 (RShiftL src2 src3))); 10005 10006 ins_cost(1.9 * INSN_COST); 10007 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10008 10009 ins_encode %{ 10010 __ eor(as_Register($dst$$reg), 10011 as_Register($src1$$reg), 10012 as_Register($src2$$reg), 10013 Assembler::ASR, 10014 $src3$$constant & 0x3f); 10015 %} 10016 10017 ins_pipe(ialu_reg_reg_shift); 10018 %} 10019 10020 instruct XorI_reg_LShift_reg(iRegINoSp dst, 10021 iRegIorL2I src1, iRegIorL2I src2, 10022 immI src3, rFlagsReg cr) %{ 10023 match(Set dst (XorI src1 (LShiftI src2 src3))); 10024 10025 ins_cost(1.9 * INSN_COST); 10026 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10027 10028 ins_encode %{ 10029 __ eorw(as_Register($dst$$reg), 10030 as_Register($src1$$reg), 10031 as_Register($src2$$reg), 10032 Assembler::LSL, 10033 $src3$$constant & 0x3f); 10034 %} 10035 10036 ins_pipe(ialu_reg_reg_shift); 10037 %} 10038 10039 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 10040 iRegL src1, iRegL src2, 10041 immI src3, rFlagsReg cr) %{ 10042 match(Set dst (XorL src1 (LShiftL src2 src3))); 10043 10044 ins_cost(1.9 * INSN_COST); 10045 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 10046 10047 ins_encode %{ 10048 __ eor(as_Register($dst$$reg), 10049 as_Register($src1$$reg), 10050 as_Register($src2$$reg), 10051 Assembler::LSL, 10052 $src3$$constant & 0x3f); 10053 %} 10054 10055 ins_pipe(ialu_reg_reg_shift); 10056 %} 10057 10058 instruct OrI_reg_URShift_reg(iRegINoSp dst, 10059 iRegIorL2I src1, iRegIorL2I src2, 10060 immI src3, rFlagsReg cr) %{ 10061 match(Set dst (OrI src1 (URShiftI src2 src3))); 10062 10063 ins_cost(1.9 * INSN_COST); 10064 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 10065 10066 ins_encode %{ 10067 __ orrw(as_Register($dst$$reg), 10068 as_Register($src1$$reg), 10069 as_Register($src2$$reg), 10070 Assembler::LSR, 10071 $src3$$constant & 0x3f); 10072 %} 10073 10074 ins_pipe(ialu_reg_reg_shift); 10075 %} 10076 10077 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 10078 iRegL src1, iRegL src2, 10079 immI src3, rFlagsReg cr) %{ 10080 match(Set dst (OrL src1 (URShiftL src2 src3))); 10081 10082 ins_cost(1.9 * INSN_COST); 10083 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 10084 10085 ins_encode %{ 10086 __ orr(as_Register($dst$$reg), 10087 as_Register($src1$$reg), 10088 as_Register($src2$$reg), 10089 Assembler::LSR, 10090 $src3$$constant & 0x3f); 10091 %} 10092 10093 ins_pipe(ialu_reg_reg_shift); 10094 %} 10095 10096 instruct OrI_reg_RShift_reg(iRegINoSp dst, 10097 iRegIorL2I src1, iRegIorL2I src2, 10098 immI src3, rFlagsReg cr) %{ 10099 match(Set dst (OrI src1 (RShiftI src2 src3))); 10100 10101 ins_cost(1.9 * INSN_COST); 10102 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 10103 10104 ins_encode %{ 10105 __ orrw(as_Register($dst$$reg), 10106 as_Register($src1$$reg), 10107 as_Register($src2$$reg), 10108 Assembler::ASR, 10109 $src3$$constant & 0x3f); 10110 %} 10111 10112 ins_pipe(ialu_reg_reg_shift); 10113 %} 10114 10115 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 10116 iRegL src1, iRegL src2, 10117 immI src3, rFlagsReg cr) %{ 10118 match(Set dst (OrL src1 (RShiftL src2 src3))); 10119 10120 ins_cost(1.9 * INSN_COST); 10121 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 10122 10123 ins_encode %{ 10124 __ orr(as_Register($dst$$reg), 10125 as_Register($src1$$reg), 10126 as_Register($src2$$reg), 10127 Assembler::ASR, 10128 $src3$$constant & 0x3f); 10129 %} 10130 10131 ins_pipe(ialu_reg_reg_shift); 10132 %} 10133 10134 instruct OrI_reg_LShift_reg(iRegINoSp dst, 10135 iRegIorL2I src1, iRegIorL2I src2, 10136 immI src3, rFlagsReg cr) %{ 10137 match(Set dst (OrI src1 (LShiftI src2 src3))); 10138 10139 ins_cost(1.9 * INSN_COST); 10140 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 10141 10142 ins_encode %{ 10143 __ orrw(as_Register($dst$$reg), 10144 as_Register($src1$$reg), 10145 as_Register($src2$$reg), 10146 Assembler::LSL, 10147 $src3$$constant & 0x3f); 10148 %} 10149 10150 ins_pipe(ialu_reg_reg_shift); 10151 %} 10152 10153 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 10154 iRegL src1, iRegL src2, 10155 immI src3, rFlagsReg cr) %{ 10156 match(Set dst (OrL src1 (LShiftL src2 src3))); 10157 10158 ins_cost(1.9 * INSN_COST); 10159 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 10160 10161 ins_encode %{ 10162 __ orr(as_Register($dst$$reg), 10163 as_Register($src1$$reg), 10164 as_Register($src2$$reg), 10165 Assembler::LSL, 10166 $src3$$constant & 0x3f); 10167 %} 10168 10169 ins_pipe(ialu_reg_reg_shift); 10170 %} 10171 10172 instruct AddI_reg_URShift_reg(iRegINoSp dst, 10173 iRegIorL2I src1, iRegIorL2I src2, 10174 immI src3, rFlagsReg cr) %{ 10175 match(Set dst (AddI src1 (URShiftI src2 src3))); 10176 10177 ins_cost(1.9 * INSN_COST); 10178 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 10179 10180 ins_encode %{ 10181 __ addw(as_Register($dst$$reg), 10182 as_Register($src1$$reg), 10183 as_Register($src2$$reg), 10184 Assembler::LSR, 10185 $src3$$constant & 0x3f); 10186 %} 10187 10188 ins_pipe(ialu_reg_reg_shift); 10189 %} 10190 10191 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 10192 iRegL src1, iRegL src2, 10193 immI src3, rFlagsReg cr) %{ 10194 match(Set dst (AddL src1 (URShiftL src2 src3))); 10195 10196 ins_cost(1.9 * INSN_COST); 10197 format %{ "add $dst, $src1, $src2, LSR $src3" %} 10198 10199 ins_encode %{ 10200 __ add(as_Register($dst$$reg), 10201 as_Register($src1$$reg), 10202 as_Register($src2$$reg), 10203 Assembler::LSR, 10204 $src3$$constant & 0x3f); 10205 %} 10206 10207 ins_pipe(ialu_reg_reg_shift); 10208 %} 10209 10210 instruct AddI_reg_RShift_reg(iRegINoSp dst, 10211 iRegIorL2I src1, iRegIorL2I src2, 10212 immI src3, rFlagsReg cr) %{ 10213 match(Set dst (AddI src1 (RShiftI src2 src3))); 10214 10215 ins_cost(1.9 * INSN_COST); 10216 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 10217 10218 ins_encode %{ 10219 __ addw(as_Register($dst$$reg), 10220 as_Register($src1$$reg), 10221 as_Register($src2$$reg), 10222 Assembler::ASR, 10223 $src3$$constant & 0x3f); 10224 %} 10225 10226 ins_pipe(ialu_reg_reg_shift); 10227 %} 10228 10229 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 10230 iRegL src1, iRegL src2, 10231 immI src3, rFlagsReg cr) %{ 10232 match(Set dst (AddL src1 (RShiftL src2 src3))); 10233 10234 ins_cost(1.9 * INSN_COST); 10235 format %{ "add $dst, $src1, $src2, ASR $src3" %} 10236 10237 ins_encode %{ 10238 __ add(as_Register($dst$$reg), 10239 as_Register($src1$$reg), 10240 as_Register($src2$$reg), 10241 Assembler::ASR, 10242 $src3$$constant & 0x3f); 10243 %} 10244 10245 ins_pipe(ialu_reg_reg_shift); 10246 %} 10247 10248 instruct AddI_reg_LShift_reg(iRegINoSp dst, 10249 iRegIorL2I src1, iRegIorL2I src2, 10250 immI src3, rFlagsReg cr) %{ 10251 match(Set dst (AddI src1 (LShiftI src2 src3))); 10252 10253 ins_cost(1.9 * INSN_COST); 10254 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 10255 10256 ins_encode %{ 10257 __ addw(as_Register($dst$$reg), 10258 as_Register($src1$$reg), 10259 as_Register($src2$$reg), 10260 Assembler::LSL, 10261 $src3$$constant & 0x3f); 10262 %} 10263 10264 ins_pipe(ialu_reg_reg_shift); 10265 %} 10266 10267 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 10268 iRegL src1, iRegL src2, 10269 immI src3, rFlagsReg cr) %{ 10270 match(Set dst (AddL src1 (LShiftL src2 src3))); 10271 10272 ins_cost(1.9 * INSN_COST); 10273 format %{ "add $dst, $src1, $src2, LSL $src3" %} 10274 10275 ins_encode %{ 10276 __ add(as_Register($dst$$reg), 10277 as_Register($src1$$reg), 10278 as_Register($src2$$reg), 10279 Assembler::LSL, 10280 $src3$$constant & 0x3f); 10281 %} 10282 10283 ins_pipe(ialu_reg_reg_shift); 10284 %} 10285 10286 instruct SubI_reg_URShift_reg(iRegINoSp dst, 10287 iRegIorL2I src1, iRegIorL2I src2, 10288 immI src3, rFlagsReg cr) %{ 10289 match(Set dst (SubI src1 (URShiftI src2 src3))); 10290 10291 ins_cost(1.9 * INSN_COST); 10292 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 10293 10294 ins_encode %{ 10295 __ subw(as_Register($dst$$reg), 10296 as_Register($src1$$reg), 10297 as_Register($src2$$reg), 10298 Assembler::LSR, 10299 $src3$$constant & 0x3f); 10300 %} 10301 10302 ins_pipe(ialu_reg_reg_shift); 10303 %} 10304 10305 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 10306 iRegL src1, iRegL src2, 10307 immI src3, rFlagsReg cr) %{ 10308 match(Set dst (SubL src1 (URShiftL src2 src3))); 10309 10310 ins_cost(1.9 * INSN_COST); 10311 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 10312 10313 ins_encode %{ 10314 __ sub(as_Register($dst$$reg), 10315 as_Register($src1$$reg), 10316 as_Register($src2$$reg), 10317 Assembler::LSR, 10318 $src3$$constant & 0x3f); 10319 %} 10320 10321 ins_pipe(ialu_reg_reg_shift); 10322 %} 10323 10324 instruct SubI_reg_RShift_reg(iRegINoSp dst, 10325 iRegIorL2I src1, iRegIorL2I src2, 10326 immI src3, rFlagsReg cr) %{ 10327 match(Set dst (SubI src1 (RShiftI src2 src3))); 10328 10329 ins_cost(1.9 * INSN_COST); 10330 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 10331 10332 ins_encode %{ 10333 __ subw(as_Register($dst$$reg), 10334 as_Register($src1$$reg), 10335 as_Register($src2$$reg), 10336 Assembler::ASR, 10337 $src3$$constant & 0x3f); 10338 %} 10339 10340 ins_pipe(ialu_reg_reg_shift); 10341 %} 10342 10343 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 10344 iRegL src1, iRegL src2, 10345 immI src3, rFlagsReg cr) %{ 10346 match(Set dst (SubL src1 (RShiftL src2 src3))); 10347 10348 ins_cost(1.9 * INSN_COST); 10349 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 10350 10351 ins_encode %{ 10352 __ sub(as_Register($dst$$reg), 10353 as_Register($src1$$reg), 10354 as_Register($src2$$reg), 10355 Assembler::ASR, 10356 $src3$$constant & 0x3f); 10357 %} 10358 10359 ins_pipe(ialu_reg_reg_shift); 10360 %} 10361 10362 instruct SubI_reg_LShift_reg(iRegINoSp dst, 10363 iRegIorL2I src1, iRegIorL2I src2, 10364 immI src3, rFlagsReg cr) %{ 10365 match(Set dst (SubI src1 (LShiftI src2 src3))); 10366 10367 ins_cost(1.9 * INSN_COST); 10368 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 10369 10370 ins_encode %{ 10371 __ subw(as_Register($dst$$reg), 10372 as_Register($src1$$reg), 10373 as_Register($src2$$reg), 10374 Assembler::LSL, 10375 $src3$$constant & 0x3f); 10376 %} 10377 10378 ins_pipe(ialu_reg_reg_shift); 10379 %} 10380 10381 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 10382 iRegL src1, iRegL src2, 10383 immI src3, rFlagsReg cr) %{ 10384 match(Set dst (SubL src1 (LShiftL src2 src3))); 10385 10386 ins_cost(1.9 * INSN_COST); 10387 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 10388 10389 ins_encode %{ 10390 __ sub(as_Register($dst$$reg), 10391 as_Register($src1$$reg), 10392 as_Register($src2$$reg), 10393 Assembler::LSL, 10394 $src3$$constant & 0x3f); 10395 %} 10396 10397 ins_pipe(ialu_reg_reg_shift); 10398 %} 10399 10400 10401 10402 // Shift Left followed by Shift Right. 10403 // This idiom is used by the compiler for the i2b bytecode etc. 10404 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10405 %{ 10406 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 10407 // Make sure we are not going to exceed what sbfm can do. 10408 predicate((unsigned int)n->in(2)->get_int() <= 63 10409 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10410 10411 ins_cost(INSN_COST * 2); 10412 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10413 ins_encode %{ 10414 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10415 int s = 63 - lshift; 10416 int r = (rshift - lshift) & 63; 10417 __ sbfm(as_Register($dst$$reg), 10418 as_Register($src$$reg), 10419 r, s); 10420 %} 10421 10422 ins_pipe(ialu_reg_shift); 10423 %} 10424 10425 // Shift Left followed by Shift Right. 10426 // This idiom is used by the compiler for the i2b bytecode etc. 10427 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10428 %{ 10429 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 10430 // Make sure we are not going to exceed what sbfmw can do. 10431 predicate((unsigned int)n->in(2)->get_int() <= 31 10432 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10433 10434 ins_cost(INSN_COST * 2); 10435 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10436 ins_encode %{ 10437 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10438 int s = 31 - lshift; 10439 int r = (rshift - lshift) & 31; 10440 __ sbfmw(as_Register($dst$$reg), 10441 as_Register($src$$reg), 10442 r, s); 10443 %} 10444 10445 ins_pipe(ialu_reg_shift); 10446 %} 10447 10448 // Shift Left followed by Shift Right. 10449 // This idiom is used by the compiler for the i2b bytecode etc. 10450 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10451 %{ 10452 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 10453 // Make sure we are not going to exceed what ubfm can do. 10454 predicate((unsigned int)n->in(2)->get_int() <= 63 10455 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10456 10457 ins_cost(INSN_COST * 2); 10458 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10459 ins_encode %{ 10460 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10461 int s = 63 - lshift; 10462 int r = (rshift - lshift) & 63; 10463 __ ubfm(as_Register($dst$$reg), 10464 as_Register($src$$reg), 10465 r, s); 10466 %} 10467 10468 ins_pipe(ialu_reg_shift); 10469 %} 10470 10471 // Shift Left followed by Shift Right. 10472 // This idiom is used by the compiler for the i2b bytecode etc. 10473 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10474 %{ 10475 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 10476 // Make sure we are not going to exceed what ubfmw can do. 10477 predicate((unsigned int)n->in(2)->get_int() <= 31 10478 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10479 10480 ins_cost(INSN_COST * 2); 10481 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10482 ins_encode %{ 10483 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10484 int s = 31 - lshift; 10485 int r = (rshift - lshift) & 31; 10486 __ ubfmw(as_Register($dst$$reg), 10487 as_Register($src$$reg), 10488 r, s); 10489 %} 10490 10491 ins_pipe(ialu_reg_shift); 10492 %} 10493 // Bitfield extract with shift & mask 10494 10495 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10496 %{ 10497 match(Set dst (AndI (URShiftI src rshift) mask)); 10498 10499 ins_cost(INSN_COST); 10500 format %{ "ubfxw $dst, $src, $mask" %} 10501 ins_encode %{ 10502 int rshift = $rshift$$constant; 10503 long mask = $mask$$constant; 10504 int width = exact_log2(mask+1); 10505 __ ubfxw(as_Register($dst$$reg), 10506 as_Register($src$$reg), rshift, width); 10507 %} 10508 ins_pipe(ialu_reg_shift); 10509 %} 10510 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 10511 %{ 10512 match(Set dst (AndL (URShiftL src rshift) mask)); 10513 10514 ins_cost(INSN_COST); 10515 format %{ "ubfx $dst, $src, $mask" %} 10516 ins_encode %{ 10517 int rshift = $rshift$$constant; 10518 long mask = $mask$$constant; 10519 int width = exact_log2(mask+1); 10520 __ ubfx(as_Register($dst$$reg), 10521 as_Register($src$$reg), rshift, width); 10522 %} 10523 ins_pipe(ialu_reg_shift); 10524 %} 10525 10526 // We can use ubfx when extending an And with a mask when we know mask 10527 // is positive. We know that because immI_bitmask guarantees it. 10528 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10529 %{ 10530 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 10531 10532 ins_cost(INSN_COST * 2); 10533 format %{ "ubfx $dst, $src, $mask" %} 10534 ins_encode %{ 10535 int rshift = $rshift$$constant; 10536 long mask = $mask$$constant; 10537 int width = exact_log2(mask+1); 10538 __ ubfx(as_Register($dst$$reg), 10539 as_Register($src$$reg), rshift, width); 10540 %} 10541 ins_pipe(ialu_reg_shift); 10542 %} 10543 10544 // Rotations 10545 10546 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10547 %{ 10548 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10549 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10550 10551 ins_cost(INSN_COST); 10552 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10553 10554 ins_encode %{ 10555 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10556 $rshift$$constant & 63); 10557 %} 10558 ins_pipe(ialu_reg_reg_extr); 10559 %} 10560 10561 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10562 %{ 10563 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10564 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10565 10566 ins_cost(INSN_COST); 10567 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10568 10569 ins_encode %{ 10570 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10571 $rshift$$constant & 31); 10572 %} 10573 ins_pipe(ialu_reg_reg_extr); 10574 %} 10575 10576 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10577 %{ 10578 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10579 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10580 10581 ins_cost(INSN_COST); 10582 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10583 10584 ins_encode %{ 10585 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10586 $rshift$$constant & 63); 10587 %} 10588 ins_pipe(ialu_reg_reg_extr); 10589 %} 10590 10591 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10592 %{ 10593 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10594 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10595 10596 ins_cost(INSN_COST); 10597 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10598 10599 ins_encode %{ 10600 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10601 $rshift$$constant & 31); 10602 %} 10603 ins_pipe(ialu_reg_reg_extr); 10604 %} 10605 10606 10607 // rol expander 10608 10609 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10610 %{ 10611 effect(DEF dst, USE src, USE shift); 10612 10613 format %{ "rol $dst, $src, $shift" %} 10614 ins_cost(INSN_COST * 3); 10615 ins_encode %{ 10616 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10617 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10618 rscratch1); 10619 %} 10620 ins_pipe(ialu_reg_reg_vshift); 10621 %} 10622 10623 // rol expander 10624 10625 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10626 %{ 10627 effect(DEF dst, USE src, USE shift); 10628 10629 format %{ "rol $dst, $src, $shift" %} 10630 ins_cost(INSN_COST * 3); 10631 ins_encode %{ 10632 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10633 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10634 rscratch1); 10635 %} 10636 ins_pipe(ialu_reg_reg_vshift); 10637 %} 10638 10639 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10640 %{ 10641 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 10642 10643 expand %{ 10644 rolL_rReg(dst, src, shift, cr); 10645 %} 10646 %} 10647 10648 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10649 %{ 10650 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 10651 10652 expand %{ 10653 rolL_rReg(dst, src, shift, cr); 10654 %} 10655 %} 10656 10657 instruct rolI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10658 %{ 10659 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 10660 10661 expand %{ 10662 rolL_rReg(dst, src, shift, cr); 10663 %} 10664 %} 10665 10666 instruct rolI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10667 %{ 10668 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 10669 10670 expand %{ 10671 rolL_rReg(dst, src, shift, cr); 10672 %} 10673 %} 10674 10675 // ror expander 10676 10677 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10678 %{ 10679 effect(DEF dst, USE src, USE shift); 10680 10681 format %{ "ror $dst, $src, $shift" %} 10682 ins_cost(INSN_COST); 10683 ins_encode %{ 10684 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10685 as_Register($shift$$reg)); 10686 %} 10687 ins_pipe(ialu_reg_reg_vshift); 10688 %} 10689 10690 // ror expander 10691 10692 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10693 %{ 10694 effect(DEF dst, USE src, USE shift); 10695 10696 format %{ "ror $dst, $src, $shift" %} 10697 ins_cost(INSN_COST); 10698 ins_encode %{ 10699 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10700 as_Register($shift$$reg)); 10701 %} 10702 ins_pipe(ialu_reg_reg_vshift); 10703 %} 10704 10705 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10706 %{ 10707 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 10708 10709 expand %{ 10710 rorL_rReg(dst, src, shift, cr); 10711 %} 10712 %} 10713 10714 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10715 %{ 10716 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 10717 10718 expand %{ 10719 rorL_rReg(dst, src, shift, cr); 10720 %} 10721 %} 10722 10723 instruct rorI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10724 %{ 10725 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 10726 10727 expand %{ 10728 rorL_rReg(dst, src, shift, cr); 10729 %} 10730 %} 10731 10732 instruct rorI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10733 %{ 10734 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 10735 10736 expand %{ 10737 rorL_rReg(dst, src, shift, cr); 10738 %} 10739 %} 10740 10741 // Add/subtract (extended) 10742 10743 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10744 %{ 10745 match(Set dst (AddL src1 (ConvI2L src2))); 10746 ins_cost(INSN_COST); 10747 format %{ "add $dst, $src1, sxtw $src2" %} 10748 10749 ins_encode %{ 10750 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10751 as_Register($src2$$reg), ext::sxtw); 10752 %} 10753 ins_pipe(ialu_reg_reg); 10754 %}; 10755 10756 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10757 %{ 10758 match(Set dst (SubL src1 (ConvI2L src2))); 10759 ins_cost(INSN_COST); 10760 format %{ "sub $dst, $src1, sxtw $src2" %} 10761 10762 ins_encode %{ 10763 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10764 as_Register($src2$$reg), ext::sxtw); 10765 %} 10766 ins_pipe(ialu_reg_reg); 10767 %}; 10768 10769 10770 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 10771 %{ 10772 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10773 ins_cost(INSN_COST); 10774 format %{ "add $dst, $src1, sxth $src2" %} 10775 10776 ins_encode %{ 10777 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10778 as_Register($src2$$reg), ext::sxth); 10779 %} 10780 ins_pipe(ialu_reg_reg); 10781 %} 10782 10783 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10784 %{ 10785 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10786 ins_cost(INSN_COST); 10787 format %{ "add $dst, $src1, sxtb $src2" %} 10788 10789 ins_encode %{ 10790 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10791 as_Register($src2$$reg), ext::sxtb); 10792 %} 10793 ins_pipe(ialu_reg_reg); 10794 %} 10795 10796 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10797 %{ 10798 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 10799 ins_cost(INSN_COST); 10800 format %{ "add $dst, $src1, uxtb $src2" %} 10801 10802 ins_encode %{ 10803 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10804 as_Register($src2$$reg), ext::uxtb); 10805 %} 10806 ins_pipe(ialu_reg_reg); 10807 %} 10808 10809 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 10810 %{ 10811 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10812 ins_cost(INSN_COST); 10813 format %{ "add $dst, $src1, sxth $src2" %} 10814 10815 ins_encode %{ 10816 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10817 as_Register($src2$$reg), ext::sxth); 10818 %} 10819 ins_pipe(ialu_reg_reg); 10820 %} 10821 10822 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 10823 %{ 10824 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10825 ins_cost(INSN_COST); 10826 format %{ "add $dst, $src1, sxtw $src2" %} 10827 10828 ins_encode %{ 10829 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10830 as_Register($src2$$reg), ext::sxtw); 10831 %} 10832 ins_pipe(ialu_reg_reg); 10833 %} 10834 10835 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10836 %{ 10837 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10838 ins_cost(INSN_COST); 10839 format %{ "add $dst, $src1, sxtb $src2" %} 10840 10841 ins_encode %{ 10842 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10843 as_Register($src2$$reg), ext::sxtb); 10844 %} 10845 ins_pipe(ialu_reg_reg); 10846 %} 10847 10848 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10849 %{ 10850 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 10851 ins_cost(INSN_COST); 10852 format %{ "add $dst, $src1, uxtb $src2" %} 10853 10854 ins_encode %{ 10855 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10856 as_Register($src2$$reg), ext::uxtb); 10857 %} 10858 ins_pipe(ialu_reg_reg); 10859 %} 10860 10861 10862 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10863 %{ 10864 match(Set dst (AddI src1 (AndI src2 mask))); 10865 ins_cost(INSN_COST); 10866 format %{ "addw $dst, $src1, $src2, uxtb" %} 10867 10868 ins_encode %{ 10869 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10870 as_Register($src2$$reg), ext::uxtb); 10871 %} 10872 ins_pipe(ialu_reg_reg); 10873 %} 10874 10875 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10876 %{ 10877 match(Set dst (AddI src1 (AndI src2 mask))); 10878 ins_cost(INSN_COST); 10879 format %{ "addw $dst, $src1, $src2, uxth" %} 10880 10881 ins_encode %{ 10882 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10883 as_Register($src2$$reg), ext::uxth); 10884 %} 10885 ins_pipe(ialu_reg_reg); 10886 %} 10887 10888 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10889 %{ 10890 match(Set dst (AddL src1 (AndL src2 mask))); 10891 ins_cost(INSN_COST); 10892 format %{ "add $dst, $src1, $src2, uxtb" %} 10893 10894 ins_encode %{ 10895 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10896 as_Register($src2$$reg), ext::uxtb); 10897 %} 10898 ins_pipe(ialu_reg_reg); 10899 %} 10900 10901 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10902 %{ 10903 match(Set dst (AddL src1 (AndL src2 mask))); 10904 ins_cost(INSN_COST); 10905 format %{ "add $dst, $src1, $src2, uxth" %} 10906 10907 ins_encode %{ 10908 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10909 as_Register($src2$$reg), ext::uxth); 10910 %} 10911 ins_pipe(ialu_reg_reg); 10912 %} 10913 10914 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10915 %{ 10916 match(Set dst (AddL src1 (AndL src2 mask))); 10917 ins_cost(INSN_COST); 10918 format %{ "add $dst, $src1, $src2, uxtw" %} 10919 10920 ins_encode %{ 10921 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10922 as_Register($src2$$reg), ext::uxtw); 10923 %} 10924 ins_pipe(ialu_reg_reg); 10925 %} 10926 10927 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10928 %{ 10929 match(Set dst (SubI src1 (AndI src2 mask))); 10930 ins_cost(INSN_COST); 10931 format %{ "subw $dst, $src1, $src2, uxtb" %} 10932 10933 ins_encode %{ 10934 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10935 as_Register($src2$$reg), ext::uxtb); 10936 %} 10937 ins_pipe(ialu_reg_reg); 10938 %} 10939 10940 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10941 %{ 10942 match(Set dst (SubI src1 (AndI src2 mask))); 10943 ins_cost(INSN_COST); 10944 format %{ "subw $dst, $src1, $src2, uxth" %} 10945 10946 ins_encode %{ 10947 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10948 as_Register($src2$$reg), ext::uxth); 10949 %} 10950 ins_pipe(ialu_reg_reg); 10951 %} 10952 10953 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10954 %{ 10955 match(Set dst (SubL src1 (AndL src2 mask))); 10956 ins_cost(INSN_COST); 10957 format %{ "sub $dst, $src1, $src2, uxtb" %} 10958 10959 ins_encode %{ 10960 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10961 as_Register($src2$$reg), ext::uxtb); 10962 %} 10963 ins_pipe(ialu_reg_reg); 10964 %} 10965 10966 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10967 %{ 10968 match(Set dst (SubL src1 (AndL src2 mask))); 10969 ins_cost(INSN_COST); 10970 format %{ "sub $dst, $src1, $src2, uxth" %} 10971 10972 ins_encode %{ 10973 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10974 as_Register($src2$$reg), ext::uxth); 10975 %} 10976 ins_pipe(ialu_reg_reg); 10977 %} 10978 10979 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10980 %{ 10981 match(Set dst (SubL src1 (AndL src2 mask))); 10982 ins_cost(INSN_COST); 10983 format %{ "sub $dst, $src1, $src2, uxtw" %} 10984 10985 ins_encode %{ 10986 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10987 as_Register($src2$$reg), ext::uxtw); 10988 %} 10989 ins_pipe(ialu_reg_reg); 10990 %} 10991 10992 // END This section of the file is automatically generated. Do not edit -------------- 10993 10994 // ============================================================================ 10995 // Floating Point Arithmetic Instructions 10996 10997 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10998 match(Set dst (AddF src1 src2)); 10999 11000 ins_cost(INSN_COST * 5); 11001 format %{ "fadds $dst, $src1, $src2" %} 11002 11003 ins_encode %{ 11004 __ fadds(as_FloatRegister($dst$$reg), 11005 as_FloatRegister($src1$$reg), 11006 as_FloatRegister($src2$$reg)); 11007 %} 11008 11009 ins_pipe(pipe_class_default); 11010 %} 11011 11012 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 11013 match(Set dst (AddD src1 src2)); 11014 11015 ins_cost(INSN_COST * 5); 11016 format %{ "faddd $dst, $src1, $src2" %} 11017 11018 ins_encode %{ 11019 __ faddd(as_FloatRegister($dst$$reg), 11020 as_FloatRegister($src1$$reg), 11021 as_FloatRegister($src2$$reg)); 11022 %} 11023 11024 ins_pipe(pipe_class_default); 11025 %} 11026 11027 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 11028 match(Set dst (SubF src1 src2)); 11029 11030 ins_cost(INSN_COST * 5); 11031 format %{ "fsubs $dst, $src1, $src2" %} 11032 11033 ins_encode %{ 11034 __ fsubs(as_FloatRegister($dst$$reg), 11035 as_FloatRegister($src1$$reg), 11036 as_FloatRegister($src2$$reg)); 11037 %} 11038 11039 ins_pipe(pipe_class_default); 11040 %} 11041 11042 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 11043 match(Set dst (SubD src1 src2)); 11044 11045 ins_cost(INSN_COST * 5); 11046 format %{ "fsubd $dst, $src1, $src2" %} 11047 11048 ins_encode %{ 11049 __ fsubd(as_FloatRegister($dst$$reg), 11050 as_FloatRegister($src1$$reg), 11051 as_FloatRegister($src2$$reg)); 11052 %} 11053 11054 ins_pipe(pipe_class_default); 11055 %} 11056 11057 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 11058 match(Set dst (MulF src1 src2)); 11059 11060 ins_cost(INSN_COST * 6); 11061 format %{ "fmuls $dst, $src1, $src2" %} 11062 11063 ins_encode %{ 11064 __ fmuls(as_FloatRegister($dst$$reg), 11065 as_FloatRegister($src1$$reg), 11066 as_FloatRegister($src2$$reg)); 11067 %} 11068 11069 ins_pipe(pipe_class_default); 11070 %} 11071 11072 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 11073 match(Set dst (MulD src1 src2)); 11074 11075 ins_cost(INSN_COST * 6); 11076 format %{ "fmuld $dst, $src1, $src2" %} 11077 11078 ins_encode %{ 11079 __ fmuld(as_FloatRegister($dst$$reg), 11080 as_FloatRegister($src1$$reg), 11081 as_FloatRegister($src2$$reg)); 11082 %} 11083 11084 ins_pipe(pipe_class_default); 11085 %} 11086 11087 // We cannot use these fused mul w add/sub ops because they don't 11088 // produce the same result as the equivalent separated ops 11089 // (essentially they don't round the intermediate result). that's a 11090 // shame. leaving them here in case we can idenitfy cases where it is 11091 // legitimate to use them 11092 11093 11094 // instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 11095 // match(Set dst (AddF (MulF src1 src2) src3)); 11096 11097 // format %{ "fmadds $dst, $src1, $src2, $src3" %} 11098 11099 // ins_encode %{ 11100 // __ fmadds(as_FloatRegister($dst$$reg), 11101 // as_FloatRegister($src1$$reg), 11102 // as_FloatRegister($src2$$reg), 11103 // as_FloatRegister($src3$$reg)); 11104 // %} 11105 11106 // ins_pipe(pipe_class_default); 11107 // %} 11108 11109 // instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 11110 // match(Set dst (AddD (MulD src1 src2) src3)); 11111 11112 // format %{ "fmaddd $dst, $src1, $src2, $src3" %} 11113 11114 // ins_encode %{ 11115 // __ fmaddd(as_FloatRegister($dst$$reg), 11116 // as_FloatRegister($src1$$reg), 11117 // as_FloatRegister($src2$$reg), 11118 // as_FloatRegister($src3$$reg)); 11119 // %} 11120 11121 // ins_pipe(pipe_class_default); 11122 // %} 11123 11124 // instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 11125 // match(Set dst (AddF (MulF (NegF src1) src2) src3)); 11126 // match(Set dst (AddF (NegF (MulF src1 src2)) src3)); 11127 11128 // format %{ "fmsubs $dst, $src1, $src2, $src3" %} 11129 11130 // ins_encode %{ 11131 // __ fmsubs(as_FloatRegister($dst$$reg), 11132 // as_FloatRegister($src1$$reg), 11133 // as_FloatRegister($src2$$reg), 11134 // as_FloatRegister($src3$$reg)); 11135 // %} 11136 11137 // ins_pipe(pipe_class_default); 11138 // %} 11139 11140 // instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 11141 // match(Set dst (AddD (MulD (NegD src1) src2) src3)); 11142 // match(Set dst (AddD (NegD (MulD src1 src2)) src3)); 11143 11144 // format %{ "fmsubd $dst, $src1, $src2, $src3" %} 11145 11146 // ins_encode %{ 11147 // __ fmsubd(as_FloatRegister($dst$$reg), 11148 // as_FloatRegister($src1$$reg), 11149 // as_FloatRegister($src2$$reg), 11150 // as_FloatRegister($src3$$reg)); 11151 // %} 11152 11153 // ins_pipe(pipe_class_default); 11154 // %} 11155 11156 // instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 11157 // match(Set dst (SubF (MulF (NegF src1) src2) src3)); 11158 // match(Set dst (SubF (NegF (MulF src1 src2)) src3)); 11159 11160 // format %{ "fnmadds $dst, $src1, $src2, $src3" %} 11161 11162 // ins_encode %{ 11163 // __ fnmadds(as_FloatRegister($dst$$reg), 11164 // as_FloatRegister($src1$$reg), 11165 // as_FloatRegister($src2$$reg), 11166 // as_FloatRegister($src3$$reg)); 11167 // %} 11168 11169 // ins_pipe(pipe_class_default); 11170 // %} 11171 11172 // instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 11173 // match(Set dst (SubD (MulD (NegD src1) src2) src3)); 11174 // match(Set dst (SubD (NegD (MulD src1 src2)) src3)); 11175 11176 // format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 11177 11178 // ins_encode %{ 11179 // __ fnmaddd(as_FloatRegister($dst$$reg), 11180 // as_FloatRegister($src1$$reg), 11181 // as_FloatRegister($src2$$reg), 11182 // as_FloatRegister($src3$$reg)); 11183 // %} 11184 11185 // ins_pipe(pipe_class_default); 11186 // %} 11187 11188 // instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 11189 // match(Set dst (SubF (MulF src1 src2) src3)); 11190 11191 // format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 11192 11193 // ins_encode %{ 11194 // __ fnmsubs(as_FloatRegister($dst$$reg), 11195 // as_FloatRegister($src1$$reg), 11196 // as_FloatRegister($src2$$reg), 11197 // as_FloatRegister($src3$$reg)); 11198 // %} 11199 11200 // ins_pipe(pipe_class_default); 11201 // %} 11202 11203 // instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 11204 // match(Set dst (SubD (MulD src1 src2) src3)); 11205 11206 // format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 11207 11208 // ins_encode %{ 11209 // // n.b. insn name should be fnmsubd 11210 // __ fnmsub(as_FloatRegister($dst$$reg), 11211 // as_FloatRegister($src1$$reg), 11212 // as_FloatRegister($src2$$reg), 11213 // as_FloatRegister($src3$$reg)); 11214 // %} 11215 11216 // ins_pipe(pipe_class_default); 11217 // %} 11218 11219 11220 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 11221 match(Set dst (DivF src1 src2)); 11222 11223 ins_cost(INSN_COST * 18); 11224 format %{ "fdivs $dst, $src1, $src2" %} 11225 11226 ins_encode %{ 11227 __ fdivs(as_FloatRegister($dst$$reg), 11228 as_FloatRegister($src1$$reg), 11229 as_FloatRegister($src2$$reg)); 11230 %} 11231 11232 ins_pipe(pipe_class_default); 11233 %} 11234 11235 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 11236 match(Set dst (DivD src1 src2)); 11237 11238 ins_cost(INSN_COST * 32); 11239 format %{ "fdivd $dst, $src1, $src2" %} 11240 11241 ins_encode %{ 11242 __ fdivd(as_FloatRegister($dst$$reg), 11243 as_FloatRegister($src1$$reg), 11244 as_FloatRegister($src2$$reg)); 11245 %} 11246 11247 ins_pipe(pipe_class_default); 11248 %} 11249 11250 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 11251 match(Set dst (NegF src)); 11252 11253 ins_cost(INSN_COST * 3); 11254 format %{ "fneg $dst, $src" %} 11255 11256 ins_encode %{ 11257 __ fnegs(as_FloatRegister($dst$$reg), 11258 as_FloatRegister($src$$reg)); 11259 %} 11260 11261 ins_pipe(pipe_class_default); 11262 %} 11263 11264 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 11265 match(Set dst (NegD src)); 11266 11267 ins_cost(INSN_COST * 3); 11268 format %{ "fnegd $dst, $src" %} 11269 11270 ins_encode %{ 11271 __ fnegd(as_FloatRegister($dst$$reg), 11272 as_FloatRegister($src$$reg)); 11273 %} 11274 11275 ins_pipe(pipe_class_default); 11276 %} 11277 11278 instruct absF_reg(vRegF dst, vRegF src) %{ 11279 match(Set dst (AbsF src)); 11280 11281 ins_cost(INSN_COST * 3); 11282 format %{ "fabss $dst, $src" %} 11283 ins_encode %{ 11284 __ fabss(as_FloatRegister($dst$$reg), 11285 as_FloatRegister($src$$reg)); 11286 %} 11287 11288 ins_pipe(pipe_class_default); 11289 %} 11290 11291 instruct absD_reg(vRegD dst, vRegD src) %{ 11292 match(Set dst (AbsD src)); 11293 11294 ins_cost(INSN_COST * 3); 11295 format %{ "fabsd $dst, $src" %} 11296 ins_encode %{ 11297 __ fabsd(as_FloatRegister($dst$$reg), 11298 as_FloatRegister($src$$reg)); 11299 %} 11300 11301 ins_pipe(pipe_class_default); 11302 %} 11303 11304 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 11305 match(Set dst (SqrtD src)); 11306 11307 ins_cost(INSN_COST * 50); 11308 format %{ "fsqrtd $dst, $src" %} 11309 ins_encode %{ 11310 __ fsqrtd(as_FloatRegister($dst$$reg), 11311 as_FloatRegister($src$$reg)); 11312 %} 11313 11314 ins_pipe(pipe_class_default); 11315 %} 11316 11317 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 11318 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 11319 11320 ins_cost(INSN_COST * 50); 11321 format %{ "fsqrts $dst, $src" %} 11322 ins_encode %{ 11323 __ fsqrts(as_FloatRegister($dst$$reg), 11324 as_FloatRegister($src$$reg)); 11325 %} 11326 11327 ins_pipe(pipe_class_default); 11328 %} 11329 11330 // ============================================================================ 11331 // Logical Instructions 11332 11333 // Integer Logical Instructions 11334 11335 // And Instructions 11336 11337 11338 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 11339 match(Set dst (AndI src1 src2)); 11340 11341 format %{ "andw $dst, $src1, $src2\t# int" %} 11342 11343 ins_cost(INSN_COST); 11344 ins_encode %{ 11345 __ andw(as_Register($dst$$reg), 11346 as_Register($src1$$reg), 11347 as_Register($src2$$reg)); 11348 %} 11349 11350 ins_pipe(ialu_reg_reg); 11351 %} 11352 11353 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 11354 match(Set dst (AndI src1 src2)); 11355 11356 format %{ "andsw $dst, $src1, $src2\t# int" %} 11357 11358 ins_cost(INSN_COST); 11359 ins_encode %{ 11360 __ andw(as_Register($dst$$reg), 11361 as_Register($src1$$reg), 11362 (unsigned long)($src2$$constant)); 11363 %} 11364 11365 ins_pipe(ialu_reg_imm); 11366 %} 11367 11368 // Or Instructions 11369 11370 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11371 match(Set dst (OrI src1 src2)); 11372 11373 format %{ "orrw $dst, $src1, $src2\t# int" %} 11374 11375 ins_cost(INSN_COST); 11376 ins_encode %{ 11377 __ orrw(as_Register($dst$$reg), 11378 as_Register($src1$$reg), 11379 as_Register($src2$$reg)); 11380 %} 11381 11382 ins_pipe(ialu_reg_reg); 11383 %} 11384 11385 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11386 match(Set dst (OrI src1 src2)); 11387 11388 format %{ "orrw $dst, $src1, $src2\t# int" %} 11389 11390 ins_cost(INSN_COST); 11391 ins_encode %{ 11392 __ orrw(as_Register($dst$$reg), 11393 as_Register($src1$$reg), 11394 (unsigned long)($src2$$constant)); 11395 %} 11396 11397 ins_pipe(ialu_reg_imm); 11398 %} 11399 11400 // Xor Instructions 11401 11402 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11403 match(Set dst (XorI src1 src2)); 11404 11405 format %{ "eorw $dst, $src1, $src2\t# int" %} 11406 11407 ins_cost(INSN_COST); 11408 ins_encode %{ 11409 __ eorw(as_Register($dst$$reg), 11410 as_Register($src1$$reg), 11411 as_Register($src2$$reg)); 11412 %} 11413 11414 ins_pipe(ialu_reg_reg); 11415 %} 11416 11417 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11418 match(Set dst (XorI src1 src2)); 11419 11420 format %{ "eorw $dst, $src1, $src2\t# int" %} 11421 11422 ins_cost(INSN_COST); 11423 ins_encode %{ 11424 __ eorw(as_Register($dst$$reg), 11425 as_Register($src1$$reg), 11426 (unsigned long)($src2$$constant)); 11427 %} 11428 11429 ins_pipe(ialu_reg_imm); 11430 %} 11431 11432 // Long Logical Instructions 11433 // TODO 11434 11435 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 11436 match(Set dst (AndL src1 src2)); 11437 11438 format %{ "and $dst, $src1, $src2\t# int" %} 11439 11440 ins_cost(INSN_COST); 11441 ins_encode %{ 11442 __ andr(as_Register($dst$$reg), 11443 as_Register($src1$$reg), 11444 as_Register($src2$$reg)); 11445 %} 11446 11447 ins_pipe(ialu_reg_reg); 11448 %} 11449 11450 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 11451 match(Set dst (AndL src1 src2)); 11452 11453 format %{ "and $dst, $src1, $src2\t# int" %} 11454 11455 ins_cost(INSN_COST); 11456 ins_encode %{ 11457 __ andr(as_Register($dst$$reg), 11458 as_Register($src1$$reg), 11459 (unsigned long)($src2$$constant)); 11460 %} 11461 11462 ins_pipe(ialu_reg_imm); 11463 %} 11464 11465 // Or Instructions 11466 11467 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11468 match(Set dst (OrL src1 src2)); 11469 11470 format %{ "orr $dst, $src1, $src2\t# int" %} 11471 11472 ins_cost(INSN_COST); 11473 ins_encode %{ 11474 __ orr(as_Register($dst$$reg), 11475 as_Register($src1$$reg), 11476 as_Register($src2$$reg)); 11477 %} 11478 11479 ins_pipe(ialu_reg_reg); 11480 %} 11481 11482 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11483 match(Set dst (OrL src1 src2)); 11484 11485 format %{ "orr $dst, $src1, $src2\t# int" %} 11486 11487 ins_cost(INSN_COST); 11488 ins_encode %{ 11489 __ orr(as_Register($dst$$reg), 11490 as_Register($src1$$reg), 11491 (unsigned long)($src2$$constant)); 11492 %} 11493 11494 ins_pipe(ialu_reg_imm); 11495 %} 11496 11497 // Xor Instructions 11498 11499 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11500 match(Set dst (XorL src1 src2)); 11501 11502 format %{ "eor $dst, $src1, $src2\t# int" %} 11503 11504 ins_cost(INSN_COST); 11505 ins_encode %{ 11506 __ eor(as_Register($dst$$reg), 11507 as_Register($src1$$reg), 11508 as_Register($src2$$reg)); 11509 %} 11510 11511 ins_pipe(ialu_reg_reg); 11512 %} 11513 11514 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11515 match(Set dst (XorL src1 src2)); 11516 11517 ins_cost(INSN_COST); 11518 format %{ "eor $dst, $src1, $src2\t# int" %} 11519 11520 ins_encode %{ 11521 __ eor(as_Register($dst$$reg), 11522 as_Register($src1$$reg), 11523 (unsigned long)($src2$$constant)); 11524 %} 11525 11526 ins_pipe(ialu_reg_imm); 11527 %} 11528 11529 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 11530 %{ 11531 match(Set dst (ConvI2L src)); 11532 11533 ins_cost(INSN_COST); 11534 format %{ "sxtw $dst, $src\t# i2l" %} 11535 ins_encode %{ 11536 __ sbfm($dst$$Register, $src$$Register, 0, 31); 11537 %} 11538 ins_pipe(ialu_reg_shift); 11539 %} 11540 11541 // this pattern occurs in bigmath arithmetic 11542 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 11543 %{ 11544 match(Set dst (AndL (ConvI2L src) mask)); 11545 11546 ins_cost(INSN_COST); 11547 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 11548 ins_encode %{ 11549 __ ubfm($dst$$Register, $src$$Register, 0, 31); 11550 %} 11551 11552 ins_pipe(ialu_reg_shift); 11553 %} 11554 11555 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 11556 match(Set dst (ConvL2I src)); 11557 11558 ins_cost(INSN_COST); 11559 format %{ "movw $dst, $src \t// l2i" %} 11560 11561 ins_encode %{ 11562 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 11563 %} 11564 11565 ins_pipe(ialu_reg); 11566 %} 11567 11568 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 11569 %{ 11570 match(Set dst (Conv2B src)); 11571 effect(KILL cr); 11572 11573 format %{ 11574 "cmpw $src, zr\n\t" 11575 "cset $dst, ne" 11576 %} 11577 11578 ins_encode %{ 11579 __ cmpw(as_Register($src$$reg), zr); 11580 __ cset(as_Register($dst$$reg), Assembler::NE); 11581 %} 11582 11583 ins_pipe(ialu_reg); 11584 %} 11585 11586 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 11587 %{ 11588 match(Set dst (Conv2B src)); 11589 effect(KILL cr); 11590 11591 format %{ 11592 "cmp $src, zr\n\t" 11593 "cset $dst, ne" 11594 %} 11595 11596 ins_encode %{ 11597 __ cmp(as_Register($src$$reg), zr); 11598 __ cset(as_Register($dst$$reg), Assembler::NE); 11599 %} 11600 11601 ins_pipe(ialu_reg); 11602 %} 11603 11604 instruct convD2F_reg(vRegF dst, vRegD src) %{ 11605 match(Set dst (ConvD2F src)); 11606 11607 ins_cost(INSN_COST * 5); 11608 format %{ "fcvtd $dst, $src \t// d2f" %} 11609 11610 ins_encode %{ 11611 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11612 %} 11613 11614 ins_pipe(pipe_class_default); 11615 %} 11616 11617 instruct convF2D_reg(vRegD dst, vRegF src) %{ 11618 match(Set dst (ConvF2D src)); 11619 11620 ins_cost(INSN_COST * 5); 11621 format %{ "fcvts $dst, $src \t// f2d" %} 11622 11623 ins_encode %{ 11624 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11625 %} 11626 11627 ins_pipe(pipe_class_default); 11628 %} 11629 11630 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11631 match(Set dst (ConvF2I src)); 11632 11633 ins_cost(INSN_COST * 5); 11634 format %{ "fcvtzsw $dst, $src \t// f2i" %} 11635 11636 ins_encode %{ 11637 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11638 %} 11639 11640 ins_pipe(pipe_class_default); 11641 %} 11642 11643 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 11644 match(Set dst (ConvF2L src)); 11645 11646 ins_cost(INSN_COST * 5); 11647 format %{ "fcvtzs $dst, $src \t// f2l" %} 11648 11649 ins_encode %{ 11650 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11651 %} 11652 11653 ins_pipe(pipe_class_default); 11654 %} 11655 11656 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 11657 match(Set dst (ConvI2F src)); 11658 11659 ins_cost(INSN_COST * 5); 11660 format %{ "scvtfws $dst, $src \t// i2f" %} 11661 11662 ins_encode %{ 11663 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11664 %} 11665 11666 ins_pipe(pipe_class_default); 11667 %} 11668 11669 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 11670 match(Set dst (ConvL2F src)); 11671 11672 ins_cost(INSN_COST * 5); 11673 format %{ "scvtfs $dst, $src \t// l2f" %} 11674 11675 ins_encode %{ 11676 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11677 %} 11678 11679 ins_pipe(pipe_class_default); 11680 %} 11681 11682 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 11683 match(Set dst (ConvD2I src)); 11684 11685 ins_cost(INSN_COST * 5); 11686 format %{ "fcvtzdw $dst, $src \t// d2i" %} 11687 11688 ins_encode %{ 11689 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11690 %} 11691 11692 ins_pipe(pipe_class_default); 11693 %} 11694 11695 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11696 match(Set dst (ConvD2L src)); 11697 11698 ins_cost(INSN_COST * 5); 11699 format %{ "fcvtzd $dst, $src \t// d2l" %} 11700 11701 ins_encode %{ 11702 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11703 %} 11704 11705 ins_pipe(pipe_class_default); 11706 %} 11707 11708 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 11709 match(Set dst (ConvI2D src)); 11710 11711 ins_cost(INSN_COST * 5); 11712 format %{ "scvtfwd $dst, $src \t// i2d" %} 11713 11714 ins_encode %{ 11715 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11716 %} 11717 11718 ins_pipe(pipe_class_default); 11719 %} 11720 11721 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 11722 match(Set dst (ConvL2D src)); 11723 11724 ins_cost(INSN_COST * 5); 11725 format %{ "scvtfd $dst, $src \t// l2d" %} 11726 11727 ins_encode %{ 11728 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11729 %} 11730 11731 ins_pipe(pipe_class_default); 11732 %} 11733 11734 // stack <-> reg and reg <-> reg shuffles with no conversion 11735 11736 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 11737 11738 match(Set dst (MoveF2I src)); 11739 11740 effect(DEF dst, USE src); 11741 11742 ins_cost(4 * INSN_COST); 11743 11744 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 11745 11746 ins_encode %{ 11747 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 11748 %} 11749 11750 ins_pipe(iload_reg_reg); 11751 11752 %} 11753 11754 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 11755 11756 match(Set dst (MoveI2F src)); 11757 11758 effect(DEF dst, USE src); 11759 11760 ins_cost(4 * INSN_COST); 11761 11762 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 11763 11764 ins_encode %{ 11765 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11766 %} 11767 11768 ins_pipe(pipe_class_memory); 11769 11770 %} 11771 11772 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 11773 11774 match(Set dst (MoveD2L src)); 11775 11776 effect(DEF dst, USE src); 11777 11778 ins_cost(4 * INSN_COST); 11779 11780 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 11781 11782 ins_encode %{ 11783 __ ldr($dst$$Register, Address(sp, $src$$disp)); 11784 %} 11785 11786 ins_pipe(iload_reg_reg); 11787 11788 %} 11789 11790 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 11791 11792 match(Set dst (MoveL2D src)); 11793 11794 effect(DEF dst, USE src); 11795 11796 ins_cost(4 * INSN_COST); 11797 11798 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 11799 11800 ins_encode %{ 11801 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11802 %} 11803 11804 ins_pipe(pipe_class_memory); 11805 11806 %} 11807 11808 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 11809 11810 match(Set dst (MoveF2I src)); 11811 11812 effect(DEF dst, USE src); 11813 11814 ins_cost(INSN_COST); 11815 11816 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 11817 11818 ins_encode %{ 11819 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11820 %} 11821 11822 ins_pipe(pipe_class_memory); 11823 11824 %} 11825 11826 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 11827 11828 match(Set dst (MoveI2F src)); 11829 11830 effect(DEF dst, USE src); 11831 11832 ins_cost(INSN_COST); 11833 11834 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 11835 11836 ins_encode %{ 11837 __ strw($src$$Register, Address(sp, $dst$$disp)); 11838 %} 11839 11840 ins_pipe(istore_reg_reg); 11841 11842 %} 11843 11844 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 11845 11846 match(Set dst (MoveD2L src)); 11847 11848 effect(DEF dst, USE src); 11849 11850 ins_cost(INSN_COST); 11851 11852 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 11853 11854 ins_encode %{ 11855 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11856 %} 11857 11858 ins_pipe(pipe_class_memory); 11859 11860 %} 11861 11862 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 11863 11864 match(Set dst (MoveL2D src)); 11865 11866 effect(DEF dst, USE src); 11867 11868 ins_cost(INSN_COST); 11869 11870 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 11871 11872 ins_encode %{ 11873 __ str($src$$Register, Address(sp, $dst$$disp)); 11874 %} 11875 11876 ins_pipe(istore_reg_reg); 11877 11878 %} 11879 11880 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11881 11882 match(Set dst (MoveF2I src)); 11883 11884 effect(DEF dst, USE src); 11885 11886 ins_cost(INSN_COST); 11887 11888 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 11889 11890 ins_encode %{ 11891 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 11892 %} 11893 11894 ins_pipe(pipe_class_memory); 11895 11896 %} 11897 11898 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 11899 11900 match(Set dst (MoveI2F src)); 11901 11902 effect(DEF dst, USE src); 11903 11904 ins_cost(INSN_COST); 11905 11906 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 11907 11908 ins_encode %{ 11909 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 11910 %} 11911 11912 ins_pipe(pipe_class_memory); 11913 11914 %} 11915 11916 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11917 11918 match(Set dst (MoveD2L src)); 11919 11920 effect(DEF dst, USE src); 11921 11922 ins_cost(INSN_COST); 11923 11924 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 11925 11926 ins_encode %{ 11927 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 11928 %} 11929 11930 ins_pipe(pipe_class_memory); 11931 11932 %} 11933 11934 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 11935 11936 match(Set dst (MoveL2D src)); 11937 11938 effect(DEF dst, USE src); 11939 11940 ins_cost(INSN_COST); 11941 11942 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 11943 11944 ins_encode %{ 11945 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 11946 %} 11947 11948 ins_pipe(pipe_class_memory); 11949 11950 %} 11951 11952 // ============================================================================ 11953 // clearing of an array 11954 11955 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 11956 %{ 11957 match(Set dummy (ClearArray cnt base)); 11958 effect(USE_KILL cnt, USE_KILL base); 11959 11960 ins_cost(4 * INSN_COST); 11961 format %{ "ClearArray $cnt, $base" %} 11962 11963 ins_encode(aarch64_enc_clear_array_reg_reg(cnt, base)); 11964 11965 ins_pipe(pipe_class_memory); 11966 %} 11967 11968 // ============================================================================ 11969 // Overflow Math Instructions 11970 11971 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11972 %{ 11973 match(Set cr (OverflowAddI op1 op2)); 11974 11975 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11976 ins_cost(INSN_COST); 11977 ins_encode %{ 11978 __ cmnw($op1$$Register, $op2$$Register); 11979 %} 11980 11981 ins_pipe(icmp_reg_reg); 11982 %} 11983 11984 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 11985 %{ 11986 match(Set cr (OverflowAddI op1 op2)); 11987 11988 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11989 ins_cost(INSN_COST); 11990 ins_encode %{ 11991 __ cmnw($op1$$Register, $op2$$constant); 11992 %} 11993 11994 ins_pipe(icmp_reg_imm); 11995 %} 11996 11997 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11998 %{ 11999 match(Set cr (OverflowAddL op1 op2)); 12000 12001 format %{ "cmn $op1, $op2\t# overflow check long" %} 12002 ins_cost(INSN_COST); 12003 ins_encode %{ 12004 __ cmn($op1$$Register, $op2$$Register); 12005 %} 12006 12007 ins_pipe(icmp_reg_reg); 12008 %} 12009 12010 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 12011 %{ 12012 match(Set cr (OverflowAddL op1 op2)); 12013 12014 format %{ "cmn $op1, $op2\t# overflow check long" %} 12015 ins_cost(INSN_COST); 12016 ins_encode %{ 12017 __ cmn($op1$$Register, $op2$$constant); 12018 %} 12019 12020 ins_pipe(icmp_reg_imm); 12021 %} 12022 12023 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 12024 %{ 12025 match(Set cr (OverflowSubI op1 op2)); 12026 12027 format %{ "cmpw $op1, $op2\t# overflow check int" %} 12028 ins_cost(INSN_COST); 12029 ins_encode %{ 12030 __ cmpw($op1$$Register, $op2$$Register); 12031 %} 12032 12033 ins_pipe(icmp_reg_reg); 12034 %} 12035 12036 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 12037 %{ 12038 match(Set cr (OverflowSubI op1 op2)); 12039 12040 format %{ "cmpw $op1, $op2\t# overflow check int" %} 12041 ins_cost(INSN_COST); 12042 ins_encode %{ 12043 __ cmpw($op1$$Register, $op2$$constant); 12044 %} 12045 12046 ins_pipe(icmp_reg_imm); 12047 %} 12048 12049 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 12050 %{ 12051 match(Set cr (OverflowSubL op1 op2)); 12052 12053 format %{ "cmp $op1, $op2\t# overflow check long" %} 12054 ins_cost(INSN_COST); 12055 ins_encode %{ 12056 __ cmp($op1$$Register, $op2$$Register); 12057 %} 12058 12059 ins_pipe(icmp_reg_reg); 12060 %} 12061 12062 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 12063 %{ 12064 match(Set cr (OverflowSubL op1 op2)); 12065 12066 format %{ "cmp $op1, $op2\t# overflow check long" %} 12067 ins_cost(INSN_COST); 12068 ins_encode %{ 12069 __ cmp($op1$$Register, $op2$$constant); 12070 %} 12071 12072 ins_pipe(icmp_reg_imm); 12073 %} 12074 12075 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 12076 %{ 12077 match(Set cr (OverflowSubI zero op1)); 12078 12079 format %{ "cmpw zr, $op1\t# overflow check int" %} 12080 ins_cost(INSN_COST); 12081 ins_encode %{ 12082 __ cmpw(zr, $op1$$Register); 12083 %} 12084 12085 ins_pipe(icmp_reg_imm); 12086 %} 12087 12088 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 12089 %{ 12090 match(Set cr (OverflowSubL zero op1)); 12091 12092 format %{ "cmp zr, $op1\t# overflow check long" %} 12093 ins_cost(INSN_COST); 12094 ins_encode %{ 12095 __ cmp(zr, $op1$$Register); 12096 %} 12097 12098 ins_pipe(icmp_reg_imm); 12099 %} 12100 12101 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 12102 %{ 12103 match(Set cr (OverflowMulI op1 op2)); 12104 12105 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 12106 "cmp rscratch1, rscratch1, sxtw\n\t" 12107 "movw rscratch1, #0x80000000\n\t" 12108 "cselw rscratch1, rscratch1, zr, NE\n\t" 12109 "cmpw rscratch1, #1" %} 12110 ins_cost(5 * INSN_COST); 12111 ins_encode %{ 12112 __ smull(rscratch1, $op1$$Register, $op2$$Register); 12113 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 12114 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 12115 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 12116 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 12117 %} 12118 12119 ins_pipe(pipe_slow); 12120 %} 12121 12122 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 12123 %{ 12124 match(If cmp (OverflowMulI op1 op2)); 12125 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 12126 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 12127 effect(USE labl, KILL cr); 12128 12129 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 12130 "cmp rscratch1, rscratch1, sxtw\n\t" 12131 "b$cmp $labl" %} 12132 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 12133 ins_encode %{ 12134 Label* L = $labl$$label; 12135 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12136 __ smull(rscratch1, $op1$$Register, $op2$$Register); 12137 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 12138 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 12139 %} 12140 12141 ins_pipe(pipe_serial); 12142 %} 12143 12144 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 12145 %{ 12146 match(Set cr (OverflowMulL op1 op2)); 12147 12148 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 12149 "smulh rscratch2, $op1, $op2\n\t" 12150 "cmp rscratch2, rscratch1, ASR #31\n\t" 12151 "movw rscratch1, #0x80000000\n\t" 12152 "cselw rscratch1, rscratch1, zr, NE\n\t" 12153 "cmpw rscratch1, #1" %} 12154 ins_cost(6 * INSN_COST); 12155 ins_encode %{ 12156 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 12157 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 12158 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 12159 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 12160 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 12161 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 12162 %} 12163 12164 ins_pipe(pipe_slow); 12165 %} 12166 12167 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 12168 %{ 12169 match(If cmp (OverflowMulL op1 op2)); 12170 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 12171 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 12172 effect(USE labl, KILL cr); 12173 12174 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 12175 "smulh rscratch2, $op1, $op2\n\t" 12176 "cmp rscratch2, rscratch1, ASR #31\n\t" 12177 "b$cmp $labl" %} 12178 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 12179 ins_encode %{ 12180 Label* L = $labl$$label; 12181 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12182 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 12183 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 12184 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 12185 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 12186 %} 12187 12188 ins_pipe(pipe_serial); 12189 %} 12190 12191 // ============================================================================ 12192 // Compare Instructions 12193 12194 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 12195 %{ 12196 match(Set cr (CmpI op1 op2)); 12197 12198 effect(DEF cr, USE op1, USE op2); 12199 12200 ins_cost(INSN_COST); 12201 format %{ "cmpw $op1, $op2" %} 12202 12203 ins_encode(aarch64_enc_cmpw(op1, op2)); 12204 12205 ins_pipe(icmp_reg_reg); 12206 %} 12207 12208 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 12209 %{ 12210 match(Set cr (CmpI op1 zero)); 12211 12212 effect(DEF cr, USE op1); 12213 12214 ins_cost(INSN_COST); 12215 format %{ "cmpw $op1, 0" %} 12216 12217 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 12218 12219 ins_pipe(icmp_reg_imm); 12220 %} 12221 12222 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 12223 %{ 12224 match(Set cr (CmpI op1 op2)); 12225 12226 effect(DEF cr, USE op1); 12227 12228 ins_cost(INSN_COST); 12229 format %{ "cmpw $op1, $op2" %} 12230 12231 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 12232 12233 ins_pipe(icmp_reg_imm); 12234 %} 12235 12236 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 12237 %{ 12238 match(Set cr (CmpI op1 op2)); 12239 12240 effect(DEF cr, USE op1); 12241 12242 ins_cost(INSN_COST * 2); 12243 format %{ "cmpw $op1, $op2" %} 12244 12245 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 12246 12247 ins_pipe(icmp_reg_imm); 12248 %} 12249 12250 // Unsigned compare Instructions; really, same as signed compare 12251 // except it should only be used to feed an If or a CMovI which takes a 12252 // cmpOpU. 12253 12254 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 12255 %{ 12256 match(Set cr (CmpU op1 op2)); 12257 12258 effect(DEF cr, USE op1, USE op2); 12259 12260 ins_cost(INSN_COST); 12261 format %{ "cmpw $op1, $op2\t# unsigned" %} 12262 12263 ins_encode(aarch64_enc_cmpw(op1, op2)); 12264 12265 ins_pipe(icmp_reg_reg); 12266 %} 12267 12268 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 12269 %{ 12270 match(Set cr (CmpU op1 zero)); 12271 12272 effect(DEF cr, USE op1); 12273 12274 ins_cost(INSN_COST); 12275 format %{ "cmpw $op1, #0\t# unsigned" %} 12276 12277 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 12278 12279 ins_pipe(icmp_reg_imm); 12280 %} 12281 12282 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 12283 %{ 12284 match(Set cr (CmpU op1 op2)); 12285 12286 effect(DEF cr, USE op1); 12287 12288 ins_cost(INSN_COST); 12289 format %{ "cmpw $op1, $op2\t# unsigned" %} 12290 12291 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 12292 12293 ins_pipe(icmp_reg_imm); 12294 %} 12295 12296 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 12297 %{ 12298 match(Set cr (CmpU op1 op2)); 12299 12300 effect(DEF cr, USE op1); 12301 12302 ins_cost(INSN_COST * 2); 12303 format %{ "cmpw $op1, $op2\t# unsigned" %} 12304 12305 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 12306 12307 ins_pipe(icmp_reg_imm); 12308 %} 12309 12310 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 12311 %{ 12312 match(Set cr (CmpL op1 op2)); 12313 12314 effect(DEF cr, USE op1, USE op2); 12315 12316 ins_cost(INSN_COST); 12317 format %{ "cmp $op1, $op2" %} 12318 12319 ins_encode(aarch64_enc_cmp(op1, op2)); 12320 12321 ins_pipe(icmp_reg_reg); 12322 %} 12323 12324 instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) 12325 %{ 12326 match(Set cr (CmpL op1 zero)); 12327 12328 effect(DEF cr, USE op1); 12329 12330 ins_cost(INSN_COST); 12331 format %{ "tst $op1" %} 12332 12333 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 12334 12335 ins_pipe(icmp_reg_imm); 12336 %} 12337 12338 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 12339 %{ 12340 match(Set cr (CmpL op1 op2)); 12341 12342 effect(DEF cr, USE op1); 12343 12344 ins_cost(INSN_COST); 12345 format %{ "cmp $op1, $op2" %} 12346 12347 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 12348 12349 ins_pipe(icmp_reg_imm); 12350 %} 12351 12352 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 12353 %{ 12354 match(Set cr (CmpL op1 op2)); 12355 12356 effect(DEF cr, USE op1); 12357 12358 ins_cost(INSN_COST * 2); 12359 format %{ "cmp $op1, $op2" %} 12360 12361 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 12362 12363 ins_pipe(icmp_reg_imm); 12364 %} 12365 12366 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 12367 %{ 12368 match(Set cr (CmpP op1 op2)); 12369 12370 effect(DEF cr, USE op1, USE op2); 12371 12372 ins_cost(INSN_COST); 12373 format %{ "cmp $op1, $op2\t // ptr" %} 12374 12375 ins_encode(aarch64_enc_cmpp(op1, op2)); 12376 12377 ins_pipe(icmp_reg_reg); 12378 %} 12379 12380 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 12381 %{ 12382 match(Set cr (CmpN op1 op2)); 12383 12384 effect(DEF cr, USE op1, USE op2); 12385 12386 ins_cost(INSN_COST); 12387 format %{ "cmp $op1, $op2\t // compressed ptr" %} 12388 12389 ins_encode(aarch64_enc_cmpn(op1, op2)); 12390 12391 ins_pipe(icmp_reg_reg); 12392 %} 12393 12394 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 12395 %{ 12396 match(Set cr (CmpP op1 zero)); 12397 12398 effect(DEF cr, USE op1, USE zero); 12399 12400 ins_cost(INSN_COST); 12401 format %{ "cmp $op1, 0\t // ptr" %} 12402 12403 ins_encode(aarch64_enc_testp(op1)); 12404 12405 ins_pipe(icmp_reg_imm); 12406 %} 12407 12408 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 12409 %{ 12410 match(Set cr (CmpN op1 zero)); 12411 12412 effect(DEF cr, USE op1, USE zero); 12413 12414 ins_cost(INSN_COST); 12415 format %{ "cmp $op1, 0\t // compressed ptr" %} 12416 12417 ins_encode(aarch64_enc_testn(op1)); 12418 12419 ins_pipe(icmp_reg_imm); 12420 %} 12421 12422 // FP comparisons 12423 // 12424 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 12425 // using normal cmpOp. See declaration of rFlagsReg for details. 12426 12427 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 12428 %{ 12429 match(Set cr (CmpF src1 src2)); 12430 12431 ins_cost(3 * INSN_COST); 12432 format %{ "fcmps $src1, $src2" %} 12433 12434 ins_encode %{ 12435 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12436 %} 12437 12438 ins_pipe(pipe_class_compare); 12439 %} 12440 12441 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 12442 %{ 12443 match(Set cr (CmpF src1 src2)); 12444 12445 ins_cost(3 * INSN_COST); 12446 format %{ "fcmps $src1, 0.0" %} 12447 12448 ins_encode %{ 12449 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 12450 %} 12451 12452 ins_pipe(pipe_class_compare); 12453 %} 12454 // FROM HERE 12455 12456 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 12457 %{ 12458 match(Set cr (CmpD src1 src2)); 12459 12460 ins_cost(3 * INSN_COST); 12461 format %{ "fcmpd $src1, $src2" %} 12462 12463 ins_encode %{ 12464 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12465 %} 12466 12467 ins_pipe(pipe_class_compare); 12468 %} 12469 12470 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 12471 %{ 12472 match(Set cr (CmpD src1 src2)); 12473 12474 ins_cost(3 * INSN_COST); 12475 format %{ "fcmpd $src1, 0.0" %} 12476 12477 ins_encode %{ 12478 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 12479 %} 12480 12481 ins_pipe(pipe_class_compare); 12482 %} 12483 12484 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 12485 %{ 12486 match(Set dst (CmpF3 src1 src2)); 12487 effect(KILL cr); 12488 12489 ins_cost(5 * INSN_COST); 12490 format %{ "fcmps $src1, $src2\n\t" 12491 "csinvw($dst, zr, zr, eq\n\t" 12492 "csnegw($dst, $dst, $dst, lt)" 12493 %} 12494 12495 ins_encode %{ 12496 Label done; 12497 FloatRegister s1 = as_FloatRegister($src1$$reg); 12498 FloatRegister s2 = as_FloatRegister($src2$$reg); 12499 Register d = as_Register($dst$$reg); 12500 __ fcmps(s1, s2); 12501 // installs 0 if EQ else -1 12502 __ csinvw(d, zr, zr, Assembler::EQ); 12503 // keeps -1 if less or unordered else installs 1 12504 __ csnegw(d, d, d, Assembler::LT); 12505 __ bind(done); 12506 %} 12507 12508 ins_pipe(pipe_class_default); 12509 12510 %} 12511 12512 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 12513 %{ 12514 match(Set dst (CmpD3 src1 src2)); 12515 effect(KILL cr); 12516 12517 ins_cost(5 * INSN_COST); 12518 format %{ "fcmpd $src1, $src2\n\t" 12519 "csinvw($dst, zr, zr, eq\n\t" 12520 "csnegw($dst, $dst, $dst, lt)" 12521 %} 12522 12523 ins_encode %{ 12524 Label done; 12525 FloatRegister s1 = as_FloatRegister($src1$$reg); 12526 FloatRegister s2 = as_FloatRegister($src2$$reg); 12527 Register d = as_Register($dst$$reg); 12528 __ fcmpd(s1, s2); 12529 // installs 0 if EQ else -1 12530 __ csinvw(d, zr, zr, Assembler::EQ); 12531 // keeps -1 if less or unordered else installs 1 12532 __ csnegw(d, d, d, Assembler::LT); 12533 __ bind(done); 12534 %} 12535 ins_pipe(pipe_class_default); 12536 12537 %} 12538 12539 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 12540 %{ 12541 match(Set dst (CmpF3 src1 zero)); 12542 effect(KILL cr); 12543 12544 ins_cost(5 * INSN_COST); 12545 format %{ "fcmps $src1, 0.0\n\t" 12546 "csinvw($dst, zr, zr, eq\n\t" 12547 "csnegw($dst, $dst, $dst, lt)" 12548 %} 12549 12550 ins_encode %{ 12551 Label done; 12552 FloatRegister s1 = as_FloatRegister($src1$$reg); 12553 Register d = as_Register($dst$$reg); 12554 __ fcmps(s1, 0.0D); 12555 // installs 0 if EQ else -1 12556 __ csinvw(d, zr, zr, Assembler::EQ); 12557 // keeps -1 if less or unordered else installs 1 12558 __ csnegw(d, d, d, Assembler::LT); 12559 __ bind(done); 12560 %} 12561 12562 ins_pipe(pipe_class_default); 12563 12564 %} 12565 12566 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 12567 %{ 12568 match(Set dst (CmpD3 src1 zero)); 12569 effect(KILL cr); 12570 12571 ins_cost(5 * INSN_COST); 12572 format %{ "fcmpd $src1, 0.0\n\t" 12573 "csinvw($dst, zr, zr, eq\n\t" 12574 "csnegw($dst, $dst, $dst, lt)" 12575 %} 12576 12577 ins_encode %{ 12578 Label done; 12579 FloatRegister s1 = as_FloatRegister($src1$$reg); 12580 Register d = as_Register($dst$$reg); 12581 __ fcmpd(s1, 0.0D); 12582 // installs 0 if EQ else -1 12583 __ csinvw(d, zr, zr, Assembler::EQ); 12584 // keeps -1 if less or unordered else installs 1 12585 __ csnegw(d, d, d, Assembler::LT); 12586 __ bind(done); 12587 %} 12588 ins_pipe(pipe_class_default); 12589 12590 %} 12591 12592 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 12593 %{ 12594 match(Set dst (CmpLTMask p q)); 12595 effect(KILL cr); 12596 12597 ins_cost(3 * INSN_COST); 12598 12599 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 12600 "csetw $dst, lt\n\t" 12601 "subw $dst, zr, $dst" 12602 %} 12603 12604 ins_encode %{ 12605 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 12606 __ csetw(as_Register($dst$$reg), Assembler::LT); 12607 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 12608 %} 12609 12610 ins_pipe(ialu_reg_reg); 12611 %} 12612 12613 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 12614 %{ 12615 match(Set dst (CmpLTMask src zero)); 12616 effect(KILL cr); 12617 12618 ins_cost(INSN_COST); 12619 12620 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 12621 12622 ins_encode %{ 12623 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 12624 %} 12625 12626 ins_pipe(ialu_reg_shift); 12627 %} 12628 12629 // ============================================================================ 12630 // Max and Min 12631 12632 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12633 %{ 12634 match(Set dst (MinI src1 src2)); 12635 12636 effect(DEF dst, USE src1, USE src2, KILL cr); 12637 size(8); 12638 12639 ins_cost(INSN_COST * 3); 12640 format %{ 12641 "cmpw $src1 $src2\t signed int\n\t" 12642 "cselw $dst, $src1, $src2 lt\t" 12643 %} 12644 12645 ins_encode %{ 12646 __ cmpw(as_Register($src1$$reg), 12647 as_Register($src2$$reg)); 12648 __ cselw(as_Register($dst$$reg), 12649 as_Register($src1$$reg), 12650 as_Register($src2$$reg), 12651 Assembler::LT); 12652 %} 12653 12654 ins_pipe(ialu_reg_reg); 12655 %} 12656 // FROM HERE 12657 12658 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12659 %{ 12660 match(Set dst (MaxI src1 src2)); 12661 12662 effect(DEF dst, USE src1, USE src2, KILL cr); 12663 size(8); 12664 12665 ins_cost(INSN_COST * 3); 12666 format %{ 12667 "cmpw $src1 $src2\t signed int\n\t" 12668 "cselw $dst, $src1, $src2 gt\t" 12669 %} 12670 12671 ins_encode %{ 12672 __ cmpw(as_Register($src1$$reg), 12673 as_Register($src2$$reg)); 12674 __ cselw(as_Register($dst$$reg), 12675 as_Register($src1$$reg), 12676 as_Register($src2$$reg), 12677 Assembler::GT); 12678 %} 12679 12680 ins_pipe(ialu_reg_reg); 12681 %} 12682 12683 // ============================================================================ 12684 // Branch Instructions 12685 12686 // Direct Branch. 12687 instruct branch(label lbl) 12688 %{ 12689 match(Goto); 12690 12691 effect(USE lbl); 12692 12693 ins_cost(BRANCH_COST); 12694 format %{ "b $lbl" %} 12695 12696 ins_encode(aarch64_enc_b(lbl)); 12697 12698 ins_pipe(pipe_branch); 12699 %} 12700 12701 // Conditional Near Branch 12702 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 12703 %{ 12704 // Same match rule as `branchConFar'. 12705 match(If cmp cr); 12706 12707 effect(USE lbl); 12708 12709 ins_cost(BRANCH_COST); 12710 // If set to 1 this indicates that the current instruction is a 12711 // short variant of a long branch. This avoids using this 12712 // instruction in first-pass matching. It will then only be used in 12713 // the `Shorten_branches' pass. 12714 // ins_short_branch(1); 12715 format %{ "b$cmp $lbl" %} 12716 12717 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12718 12719 ins_pipe(pipe_branch_cond); 12720 %} 12721 12722 // Conditional Near Branch Unsigned 12723 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12724 %{ 12725 // Same match rule as `branchConFar'. 12726 match(If cmp cr); 12727 12728 effect(USE lbl); 12729 12730 ins_cost(BRANCH_COST); 12731 // If set to 1 this indicates that the current instruction is a 12732 // short variant of a long branch. This avoids using this 12733 // instruction in first-pass matching. It will then only be used in 12734 // the `Shorten_branches' pass. 12735 // ins_short_branch(1); 12736 format %{ "b$cmp $lbl\t# unsigned" %} 12737 12738 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12739 12740 ins_pipe(pipe_branch_cond); 12741 %} 12742 12743 // Make use of CBZ and CBNZ. These instructions, as well as being 12744 // shorter than (cmp; branch), have the additional benefit of not 12745 // killing the flags. 12746 12747 instruct cmpI_imm0_branch(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 12748 match(If cmp (CmpI op1 op2)); 12749 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12750 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12751 effect(USE labl); 12752 12753 ins_cost(BRANCH_COST); 12754 format %{ "cbw$cmp $op1, $labl" %} 12755 ins_encode %{ 12756 Label* L = $labl$$label; 12757 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12758 if (cond == Assembler::EQ) 12759 __ cbzw($op1$$Register, *L); 12760 else 12761 __ cbnzw($op1$$Register, *L); 12762 %} 12763 ins_pipe(pipe_cmp_branch); 12764 %} 12765 12766 instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 12767 match(If cmp (CmpL op1 op2)); 12768 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12769 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12770 effect(USE labl); 12771 12772 ins_cost(BRANCH_COST); 12773 format %{ "cb$cmp $op1, $labl" %} 12774 ins_encode %{ 12775 Label* L = $labl$$label; 12776 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12777 if (cond == Assembler::EQ) 12778 __ cbz($op1$$Register, *L); 12779 else 12780 __ cbnz($op1$$Register, *L); 12781 %} 12782 ins_pipe(pipe_cmp_branch); 12783 %} 12784 12785 instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 12786 match(If cmp (CmpP op1 op2)); 12787 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12788 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12789 effect(USE labl); 12790 12791 ins_cost(BRANCH_COST); 12792 format %{ "cb$cmp $op1, $labl" %} 12793 ins_encode %{ 12794 Label* L = $labl$$label; 12795 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12796 if (cond == Assembler::EQ) 12797 __ cbz($op1$$Register, *L); 12798 else 12799 __ cbnz($op1$$Register, *L); 12800 %} 12801 ins_pipe(pipe_cmp_branch); 12802 %} 12803 12804 // Conditional Far Branch 12805 // Conditional Far Branch Unsigned 12806 // TODO: fixme 12807 12808 // counted loop end branch near 12809 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 12810 %{ 12811 match(CountedLoopEnd cmp cr); 12812 12813 effect(USE lbl); 12814 12815 ins_cost(BRANCH_COST); 12816 // short variant. 12817 // ins_short_branch(1); 12818 format %{ "b$cmp $lbl \t// counted loop end" %} 12819 12820 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12821 12822 ins_pipe(pipe_branch); 12823 %} 12824 12825 // counted loop end branch near Unsigned 12826 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12827 %{ 12828 match(CountedLoopEnd cmp cr); 12829 12830 effect(USE lbl); 12831 12832 ins_cost(BRANCH_COST); 12833 // short variant. 12834 // ins_short_branch(1); 12835 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 12836 12837 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12838 12839 ins_pipe(pipe_branch); 12840 %} 12841 12842 // counted loop end branch far 12843 // counted loop end branch far unsigned 12844 // TODO: fixme 12845 12846 // ============================================================================ 12847 // inlined locking and unlocking 12848 12849 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12850 %{ 12851 match(Set cr (FastLock object box)); 12852 effect(TEMP tmp, TEMP tmp2); 12853 12854 // TODO 12855 // identify correct cost 12856 ins_cost(5 * INSN_COST); 12857 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 12858 12859 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 12860 12861 ins_pipe(pipe_serial); 12862 %} 12863 12864 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12865 %{ 12866 match(Set cr (FastUnlock object box)); 12867 effect(TEMP tmp, TEMP tmp2); 12868 12869 ins_cost(5 * INSN_COST); 12870 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 12871 12872 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 12873 12874 ins_pipe(pipe_serial); 12875 %} 12876 12877 12878 // ============================================================================ 12879 // Safepoint Instructions 12880 12881 // TODO 12882 // provide a near and far version of this code 12883 12884 instruct safePoint(iRegP poll) 12885 %{ 12886 match(SafePoint poll); 12887 12888 format %{ 12889 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 12890 %} 12891 ins_encode %{ 12892 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 12893 %} 12894 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 12895 %} 12896 12897 12898 // ============================================================================ 12899 // Procedure Call/Return Instructions 12900 12901 // Call Java Static Instruction 12902 12903 instruct CallStaticJavaDirect(method meth) 12904 %{ 12905 match(CallStaticJava); 12906 12907 effect(USE meth); 12908 12909 ins_cost(CALL_COST); 12910 12911 format %{ "call,static $meth \t// ==> " %} 12912 12913 ins_encode( aarch64_enc_java_static_call(meth), 12914 aarch64_enc_call_epilog ); 12915 12916 ins_pipe(pipe_class_call); 12917 %} 12918 12919 // TO HERE 12920 12921 // Call Java Dynamic Instruction 12922 instruct CallDynamicJavaDirect(method meth) 12923 %{ 12924 match(CallDynamicJava); 12925 12926 effect(USE meth); 12927 12928 ins_cost(CALL_COST); 12929 12930 format %{ "CALL,dynamic $meth \t// ==> " %} 12931 12932 ins_encode( aarch64_enc_java_dynamic_call(meth), 12933 aarch64_enc_call_epilog ); 12934 12935 ins_pipe(pipe_class_call); 12936 %} 12937 12938 // Call Runtime Instruction 12939 12940 instruct CallRuntimeDirect(method meth) 12941 %{ 12942 match(CallRuntime); 12943 12944 effect(USE meth); 12945 12946 ins_cost(CALL_COST); 12947 12948 format %{ "CALL, runtime $meth" %} 12949 12950 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12951 12952 ins_pipe(pipe_class_call); 12953 %} 12954 12955 // Call Runtime Instruction 12956 12957 instruct CallLeafDirect(method meth) 12958 %{ 12959 match(CallLeaf); 12960 12961 effect(USE meth); 12962 12963 ins_cost(CALL_COST); 12964 12965 format %{ "CALL, runtime leaf $meth" %} 12966 12967 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12968 12969 ins_pipe(pipe_class_call); 12970 %} 12971 12972 // Call Runtime Instruction 12973 12974 instruct CallLeafNoFPDirect(method meth) 12975 %{ 12976 match(CallLeafNoFP); 12977 12978 effect(USE meth); 12979 12980 ins_cost(CALL_COST); 12981 12982 format %{ "CALL, runtime leaf nofp $meth" %} 12983 12984 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12985 12986 ins_pipe(pipe_class_call); 12987 %} 12988 12989 // Tail Call; Jump from runtime stub to Java code. 12990 // Also known as an 'interprocedural jump'. 12991 // Target of jump will eventually return to caller. 12992 // TailJump below removes the return address. 12993 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 12994 %{ 12995 match(TailCall jump_target method_oop); 12996 12997 ins_cost(CALL_COST); 12998 12999 format %{ "br $jump_target\t# $method_oop holds method oop" %} 13000 13001 ins_encode(aarch64_enc_tail_call(jump_target)); 13002 13003 ins_pipe(pipe_class_call); 13004 %} 13005 13006 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 13007 %{ 13008 match(TailJump jump_target ex_oop); 13009 13010 ins_cost(CALL_COST); 13011 13012 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 13013 13014 ins_encode(aarch64_enc_tail_jmp(jump_target)); 13015 13016 ins_pipe(pipe_class_call); 13017 %} 13018 13019 // Create exception oop: created by stack-crawling runtime code. 13020 // Created exception is now available to this handler, and is setup 13021 // just prior to jumping to this handler. No code emitted. 13022 // TODO check 13023 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 13024 instruct CreateException(iRegP_R0 ex_oop) 13025 %{ 13026 match(Set ex_oop (CreateEx)); 13027 13028 format %{ " -- \t// exception oop; no code emitted" %} 13029 13030 size(0); 13031 13032 ins_encode( /*empty*/ ); 13033 13034 ins_pipe(pipe_class_empty); 13035 %} 13036 13037 // Rethrow exception: The exception oop will come in the first 13038 // argument position. Then JUMP (not call) to the rethrow stub code. 13039 instruct RethrowException() %{ 13040 match(Rethrow); 13041 ins_cost(CALL_COST); 13042 13043 format %{ "b rethrow_stub" %} 13044 13045 ins_encode( aarch64_enc_rethrow() ); 13046 13047 ins_pipe(pipe_class_call); 13048 %} 13049 13050 13051 // Return Instruction 13052 // epilog node loads ret address into lr as part of frame pop 13053 instruct Ret() 13054 %{ 13055 match(Return); 13056 13057 format %{ "ret\t// return register" %} 13058 13059 ins_encode( aarch64_enc_ret() ); 13060 13061 ins_pipe(pipe_branch); 13062 %} 13063 13064 // Die now. 13065 instruct ShouldNotReachHere() %{ 13066 match(Halt); 13067 13068 ins_cost(CALL_COST); 13069 format %{ "ShouldNotReachHere" %} 13070 13071 ins_encode %{ 13072 // TODO 13073 // implement proper trap call here 13074 __ brk(999); 13075 %} 13076 13077 ins_pipe(pipe_class_default); 13078 %} 13079 13080 // ============================================================================ 13081 // Partial Subtype Check 13082 // 13083 // superklass array for an instance of the superklass. Set a hidden 13084 // internal cache on a hit (cache is checked with exposed code in 13085 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13086 // encoding ALSO sets flags. 13087 13088 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 13089 %{ 13090 match(Set result (PartialSubtypeCheck sub super)); 13091 effect(KILL cr, KILL temp); 13092 13093 ins_cost(1100); // slightly larger than the next version 13094 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13095 13096 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 13097 13098 opcode(0x1); // Force zero of result reg on hit 13099 13100 ins_pipe(pipe_class_memory); 13101 %} 13102 13103 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 13104 %{ 13105 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 13106 effect(KILL temp, KILL result); 13107 13108 ins_cost(1100); // slightly larger than the next version 13109 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 13110 13111 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 13112 13113 opcode(0x0); // Don't zero result reg on hit 13114 13115 ins_pipe(pipe_class_memory); 13116 %} 13117 13118 instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 13119 iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr) 13120 %{ 13121 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 13122 effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 13123 13124 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 13125 ins_encode %{ 13126 __ string_compare($str1$$Register, $str2$$Register, 13127 $cnt1$$Register, $cnt2$$Register, $result$$Register, 13128 $tmp1$$Register); 13129 %} 13130 ins_pipe(pipe_class_memory); 13131 %} 13132 13133 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 13134 iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) 13135 %{ 13136 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 13137 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 13138 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 13139 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} 13140 13141 ins_encode %{ 13142 __ string_indexof($str1$$Register, $str2$$Register, 13143 $cnt1$$Register, $cnt2$$Register, 13144 $tmp1$$Register, $tmp2$$Register, 13145 $tmp3$$Register, $tmp4$$Register, 13146 -1, $result$$Register); 13147 %} 13148 ins_pipe(pipe_class_memory); 13149 %} 13150 13151 instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 13152 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, 13153 iRegI tmp3, iRegI tmp4, rFlagsReg cr) 13154 %{ 13155 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 13156 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 13157 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 13158 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} 13159 13160 ins_encode %{ 13161 int icnt2 = (int)$int_cnt2$$constant; 13162 __ string_indexof($str1$$Register, $str2$$Register, 13163 $cnt1$$Register, zr, 13164 $tmp1$$Register, $tmp2$$Register, 13165 $tmp3$$Register, $tmp4$$Register, 13166 icnt2, $result$$Register); 13167 %} 13168 ins_pipe(pipe_class_memory); 13169 %} 13170 13171 instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 13172 iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr) 13173 %{ 13174 match(Set result (StrEquals (Binary str1 str2) cnt)); 13175 effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 13176 13177 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 13178 ins_encode %{ 13179 __ string_equals($str1$$Register, $str2$$Register, 13180 $cnt$$Register, $result$$Register, 13181 $tmp$$Register); 13182 %} 13183 ins_pipe(pipe_class_memory); 13184 %} 13185 13186 instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 13187 iRegP_R10 tmp, rFlagsReg cr) 13188 %{ 13189 match(Set result (AryEq ary1 ary2)); 13190 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr); 13191 13192 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 13193 ins_encode %{ 13194 __ char_arrays_equals($ary1$$Register, $ary2$$Register, 13195 $result$$Register, $tmp$$Register); 13196 %} 13197 ins_pipe(pipe_class_memory); 13198 %} 13199 13200 // encode char[] to byte[] in ISO_8859_1 13201 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 13202 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 13203 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 13204 iRegI_R0 result, rFlagsReg cr) 13205 %{ 13206 match(Set result (EncodeISOArray src (Binary dst len))); 13207 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 13208 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 13209 13210 format %{ "Encode array $src,$dst,$len -> $result" %} 13211 ins_encode %{ 13212 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13213 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 13214 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 13215 %} 13216 ins_pipe( pipe_class_memory ); 13217 %} 13218 13219 // ============================================================================ 13220 // This name is KNOWN by the ADLC and cannot be changed. 13221 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13222 // for this guy. 13223 instruct tlsLoadP(thread_RegP dst) 13224 %{ 13225 match(Set dst (ThreadLocal)); 13226 13227 ins_cost(0); 13228 13229 format %{ " -- \t// $dst=Thread::current(), empty" %} 13230 13231 size(0); 13232 13233 ins_encode( /*empty*/ ); 13234 13235 ins_pipe(pipe_class_empty); 13236 %} 13237 13238 // ====================VECTOR INSTRUCTIONS===================================== 13239 13240 // Load vector (32 bits) 13241 instruct loadV4(vecX dst, vmem mem) 13242 %{ 13243 predicate(n->as_LoadVector()->memory_size() == 4); 13244 match(Set dst (LoadVector mem)); 13245 ins_cost(4 * INSN_COST); 13246 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 13247 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 13248 ins_pipe(pipe_class_memory); 13249 %} 13250 13251 // Load vector (64 bits) 13252 instruct loadV8(vecX dst, vmem mem) 13253 %{ 13254 predicate(n->as_LoadVector()->memory_size() == 8); 13255 match(Set dst (LoadVector mem)); 13256 ins_cost(4 * INSN_COST); 13257 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 13258 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 13259 ins_pipe(pipe_class_memory); 13260 %} 13261 13262 // Load Vector (128 bits) 13263 instruct loadV16(vecX dst, vmem mem) 13264 %{ 13265 predicate(n->as_LoadVector()->memory_size() == 16); 13266 match(Set dst (LoadVector mem)); 13267 ins_cost(4 * INSN_COST); 13268 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 13269 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 13270 ins_pipe(pipe_class_memory); 13271 %} 13272 13273 // Store Vector (32 bits) 13274 instruct storeV4(vecX src, vmem mem) 13275 %{ 13276 predicate(n->as_StoreVector()->memory_size() == 4); 13277 match(Set mem (StoreVector mem src)); 13278 ins_cost(4 * INSN_COST); 13279 format %{ "strs $mem,$src\t# vector (32 bits)" %} 13280 ins_encode( aarch64_enc_strvS(src, mem) ); 13281 ins_pipe(pipe_class_memory); 13282 %} 13283 13284 // Store Vector (64 bits) 13285 instruct storeV8(vecX src, vmem mem) 13286 %{ 13287 predicate(n->as_StoreVector()->memory_size() == 8); 13288 match(Set mem (StoreVector mem src)); 13289 ins_cost(4 * INSN_COST); 13290 format %{ "strd $mem,$src\t# vector (64 bits)" %} 13291 ins_encode( aarch64_enc_strvD(src, mem) ); 13292 ins_pipe(pipe_class_memory); 13293 %} 13294 13295 // Store Vector (128 bits) 13296 instruct storeV16(vecX src, vmem mem) 13297 %{ 13298 predicate(n->as_StoreVector()->memory_size() == 16); 13299 match(Set mem (StoreVector mem src)); 13300 ins_cost(4 * INSN_COST); 13301 format %{ "strq $mem,$src\t# vector (128 bits)" %} 13302 ins_encode( aarch64_enc_strvQ(src, mem) ); 13303 ins_pipe(pipe_class_memory); 13304 %} 13305 13306 instruct replicate16B(vecX dst, iRegIorL2I src) 13307 %{ 13308 match(Set dst (ReplicateB src)); 13309 ins_cost(INSN_COST); 13310 format %{ "dup $dst, $src\t# vector (16B)" %} 13311 ins_encode %{ 13312 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 13313 %} 13314 ins_pipe(pipe_class_default); 13315 %} 13316 13317 instruct replicate16B_imm(vecX dst, immI con) 13318 %{ 13319 match(Set dst (ReplicateB con)); 13320 ins_cost(INSN_COST); 13321 format %{ "movi $dst, $con\t# vector(16B)" %} 13322 ins_encode %{ 13323 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant); 13324 %} 13325 ins_pipe(pipe_class_default); 13326 %} 13327 13328 instruct replicate8S(vecX dst, iRegIorL2I src) 13329 %{ 13330 match(Set dst (ReplicateS src)); 13331 ins_cost(INSN_COST); 13332 format %{ "dup $dst, $src\t# vector (8S)" %} 13333 ins_encode %{ 13334 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 13335 %} 13336 ins_pipe(pipe_class_default); 13337 %} 13338 13339 instruct replicate8S_imm(vecX dst, immI con) 13340 %{ 13341 match(Set dst (ReplicateS con)); 13342 ins_cost(INSN_COST); 13343 format %{ "movi $dst, $con\t# vector(8H)" %} 13344 ins_encode %{ 13345 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant); 13346 %} 13347 ins_pipe(pipe_class_default); 13348 %} 13349 13350 instruct replicate4I(vecX dst, iRegIorL2I src) 13351 %{ 13352 match(Set dst (ReplicateI src)); 13353 ins_cost(INSN_COST); 13354 format %{ "dup $dst, $src\t# vector (4I)" %} 13355 ins_encode %{ 13356 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 13357 %} 13358 ins_pipe(pipe_class_default); 13359 %} 13360 13361 instruct replicate4I_imm(vecX dst, immI con) 13362 %{ 13363 match(Set dst (ReplicateI con)); 13364 ins_cost(INSN_COST); 13365 format %{ "movi $dst, $con\t# vector(4I)" %} 13366 ins_encode %{ 13367 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 13368 %} 13369 ins_pipe(pipe_class_default); 13370 %} 13371 13372 instruct replicate2L(vecX dst, iRegL src) 13373 %{ 13374 match(Set dst (ReplicateL src)); 13375 ins_cost(INSN_COST); 13376 format %{ "dup $dst, $src\t# vector (2L)" %} 13377 ins_encode %{ 13378 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 13379 %} 13380 ins_pipe(pipe_class_default); 13381 %} 13382 13383 instruct replicate2L_zero(vecX dst, immI0 zero) 13384 %{ 13385 match(Set dst (ReplicateI zero)); 13386 ins_cost(INSN_COST); 13387 format %{ "movi $dst, $zero\t# vector(4I)" %} 13388 ins_encode %{ 13389 __ eor(as_FloatRegister($dst$$reg), __ T16B, 13390 as_FloatRegister($dst$$reg), 13391 as_FloatRegister($dst$$reg)); 13392 %} 13393 ins_pipe(pipe_class_default); 13394 %} 13395 13396 instruct replicate4F(vecX dst, vRegF src) 13397 %{ 13398 match(Set dst (ReplicateF src)); 13399 ins_cost(INSN_COST); 13400 format %{ "dup $dst, $src\t# vector (4F)" %} 13401 ins_encode %{ 13402 __ dup(as_FloatRegister($dst$$reg), __ T4S, 13403 as_FloatRegister($src$$reg)); 13404 %} 13405 ins_pipe(pipe_class_default); 13406 %} 13407 13408 instruct replicate2D(vecX dst, vRegD src) 13409 %{ 13410 match(Set dst (ReplicateD src)); 13411 ins_cost(INSN_COST); 13412 format %{ "dup $dst, $src\t# vector (2D)" %} 13413 ins_encode %{ 13414 __ dup(as_FloatRegister($dst$$reg), __ T2D, 13415 as_FloatRegister($src$$reg)); 13416 %} 13417 ins_pipe(pipe_class_default); 13418 %} 13419 13420 // ====================REDUCTION ARITHMETIC==================================== 13421 13422 instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2) 13423 %{ 13424 match(Set dst (AddReductionVI src1 src2)); 13425 ins_cost(INSN_COST); 13426 effect(TEMP tmp, TEMP tmp2); 13427 format %{ "addv $tmp, T4S, $src2\n\t" 13428 "umov $tmp2, $tmp, S, 0\n\t" 13429 "addw $dst, $tmp2, $src1\t add reduction4i" 13430 %} 13431 ins_encode %{ 13432 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 13433 as_FloatRegister($src2$$reg)); 13434 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 13435 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 13436 %} 13437 ins_pipe(pipe_class_default); 13438 %} 13439 13440 instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegI tmp2) 13441 %{ 13442 match(Set dst (MulReductionVI src1 src2)); 13443 ins_cost(INSN_COST); 13444 effect(TEMP tmp, TEMP tmp2, TEMP dst); 13445 format %{ "ins $tmp, $src2, 0, 1\n\t" 13446 "mul $tmp, $tmp, $src2\n\t" 13447 "umov $tmp2, $tmp, S, 0\n\t" 13448 "mul $dst, $tmp2, $src1\n\t" 13449 "umov $tmp2, $tmp, S, 1\n\t" 13450 "mul $dst, $tmp2, $dst\t mul reduction4i\n\t" 13451 %} 13452 ins_encode %{ 13453 __ ins(as_FloatRegister($tmp$$reg), __ D, 13454 as_FloatRegister($src2$$reg), 0, 1); 13455 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 13456 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 13457 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 13458 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 13459 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 13460 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 13461 %} 13462 ins_pipe(pipe_class_default); 13463 %} 13464 13465 instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 13466 %{ 13467 match(Set dst (AddReductionVF src1 src2)); 13468 ins_cost(INSN_COST); 13469 effect(TEMP tmp, TEMP dst); 13470 format %{ "fadds $dst, $src1, $src2\n\t" 13471 "ins $tmp, S, $src2, 0, 1\n\t" 13472 "fadds $dst, $dst, $tmp\n\t" 13473 "ins $tmp, S, $src2, 0, 2\n\t" 13474 "fadds $dst, $dst, $tmp\n\t" 13475 "ins $tmp, S, $src2, 0, 3\n\t" 13476 "fadds $dst, $dst, $tmp\t add reduction4f" 13477 %} 13478 ins_encode %{ 13479 __ fadds(as_FloatRegister($dst$$reg), 13480 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13481 __ ins(as_FloatRegister($tmp$$reg), __ S, 13482 as_FloatRegister($src2$$reg), 0, 1); 13483 __ fadds(as_FloatRegister($dst$$reg), 13484 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13485 __ ins(as_FloatRegister($tmp$$reg), __ S, 13486 as_FloatRegister($src2$$reg), 0, 2); 13487 __ fadds(as_FloatRegister($dst$$reg), 13488 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13489 __ ins(as_FloatRegister($tmp$$reg), __ S, 13490 as_FloatRegister($src2$$reg), 0, 3); 13491 __ fadds(as_FloatRegister($dst$$reg), 13492 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13493 %} 13494 ins_pipe(pipe_class_default); 13495 %} 13496 13497 instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 13498 %{ 13499 match(Set dst (MulReductionVF src1 src2)); 13500 ins_cost(INSN_COST); 13501 effect(TEMP tmp, TEMP dst); 13502 format %{ "fmuls $dst, $src1, $src2\n\t" 13503 "ins $tmp, S, $src2, 0, 1\n\t" 13504 "fmuls $dst, $dst, $tmp\n\t" 13505 "ins $tmp, S, $src2, 0, 2\n\t" 13506 "fmuls $dst, $dst, $tmp\n\t" 13507 "ins $tmp, S, $src2, 0, 3\n\t" 13508 "fmuls $dst, $dst, $tmp\t add reduction4f" 13509 %} 13510 ins_encode %{ 13511 __ fmuls(as_FloatRegister($dst$$reg), 13512 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13513 __ ins(as_FloatRegister($tmp$$reg), __ S, 13514 as_FloatRegister($src2$$reg), 0, 1); 13515 __ fmuls(as_FloatRegister($dst$$reg), 13516 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13517 __ ins(as_FloatRegister($tmp$$reg), __ S, 13518 as_FloatRegister($src2$$reg), 0, 2); 13519 __ fmuls(as_FloatRegister($dst$$reg), 13520 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13521 __ ins(as_FloatRegister($tmp$$reg), __ S, 13522 as_FloatRegister($src2$$reg), 0, 3); 13523 __ fmuls(as_FloatRegister($dst$$reg), 13524 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13525 %} 13526 ins_pipe(pipe_class_default); 13527 %} 13528 13529 instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 13530 %{ 13531 match(Set dst (AddReductionVD src1 src2)); 13532 ins_cost(INSN_COST); 13533 effect(TEMP tmp, TEMP dst); 13534 format %{ "faddd $dst, $src1, $src2\n\t" 13535 "ins $tmp, D, $src2, 0, 1\n\t" 13536 "faddd $dst, $dst, $tmp\t add reduction2d" 13537 %} 13538 ins_encode %{ 13539 __ faddd(as_FloatRegister($dst$$reg), 13540 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13541 __ ins(as_FloatRegister($tmp$$reg), __ D, 13542 as_FloatRegister($src2$$reg), 0, 1); 13543 __ faddd(as_FloatRegister($dst$$reg), 13544 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13545 %} 13546 ins_pipe(pipe_class_default); 13547 %} 13548 13549 instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 13550 %{ 13551 match(Set dst (MulReductionVD src1 src2)); 13552 ins_cost(INSN_COST); 13553 effect(TEMP tmp, TEMP dst); 13554 format %{ "fmuld $dst, $src1, $src2\n\t" 13555 "ins $tmp, D, $src2, 0, 1\n\t" 13556 "fmuld $dst, $dst, $tmp\t add reduction2d" 13557 %} 13558 ins_encode %{ 13559 __ fmuld(as_FloatRegister($dst$$reg), 13560 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 13561 __ ins(as_FloatRegister($tmp$$reg), __ D, 13562 as_FloatRegister($src2$$reg), 0, 1); 13563 __ fmuld(as_FloatRegister($dst$$reg), 13564 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 13565 %} 13566 ins_pipe(pipe_class_default); 13567 %} 13568 13569 // ====================VECTOR ARITHMETIC======================================= 13570 13571 // --------------------------------- ADD -------------------------------------- 13572 13573 instruct vadd16B(vecX dst, vecX src1, vecX src2) 13574 %{ 13575 match(Set dst (AddVB src1 src2)); 13576 ins_cost(INSN_COST); 13577 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 13578 ins_encode %{ 13579 __ addv(as_FloatRegister($dst$$reg), __ T16B, 13580 as_FloatRegister($src1$$reg), 13581 as_FloatRegister($src2$$reg)); 13582 %} 13583 ins_pipe(pipe_class_default); 13584 %} 13585 13586 instruct vadd8S(vecX dst, vecX src1, vecX src2) 13587 %{ 13588 match(Set dst (AddVS src1 src2)); 13589 ins_cost(INSN_COST); 13590 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 13591 ins_encode %{ 13592 __ addv(as_FloatRegister($dst$$reg), __ T8H, 13593 as_FloatRegister($src1$$reg), 13594 as_FloatRegister($src2$$reg)); 13595 %} 13596 ins_pipe(pipe_class_default); 13597 %} 13598 13599 instruct vadd4I(vecX dst, vecX src1, vecX src2) 13600 %{ 13601 match(Set dst (AddVI src1 src2)); 13602 ins_cost(INSN_COST); 13603 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 13604 ins_encode %{ 13605 __ addv(as_FloatRegister($dst$$reg), __ T4S, 13606 as_FloatRegister($src1$$reg), 13607 as_FloatRegister($src2$$reg)); 13608 %} 13609 ins_pipe(pipe_class_default); 13610 %} 13611 13612 instruct vadd2L(vecX dst, vecX src1, vecX src2) 13613 %{ 13614 match(Set dst (AddVL src1 src2)); 13615 ins_cost(INSN_COST); 13616 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 13617 ins_encode %{ 13618 __ addv(as_FloatRegister($dst$$reg), __ T2D, 13619 as_FloatRegister($src1$$reg), 13620 as_FloatRegister($src2$$reg)); 13621 %} 13622 ins_pipe(pipe_class_default); 13623 %} 13624 13625 instruct vadd4F(vecX dst, vecX src1, vecX src2) 13626 %{ 13627 match(Set dst (AddVF src1 src2)); 13628 ins_cost(INSN_COST); 13629 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 13630 ins_encode %{ 13631 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 13632 as_FloatRegister($src1$$reg), 13633 as_FloatRegister($src2$$reg)); 13634 %} 13635 ins_pipe(pipe_class_default); 13636 %} 13637 13638 instruct vadd2D(vecX dst, vecX src1, vecX src2) 13639 %{ 13640 match(Set dst (AddVD src1 src2)); 13641 ins_cost(INSN_COST); 13642 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 13643 ins_encode %{ 13644 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 13645 as_FloatRegister($src1$$reg), 13646 as_FloatRegister($src2$$reg)); 13647 %} 13648 ins_pipe(pipe_class_default); 13649 %} 13650 13651 // --------------------------------- SUB -------------------------------------- 13652 13653 instruct vsub16B(vecX dst, vecX src1, vecX src2) 13654 %{ 13655 match(Set dst (SubVB src1 src2)); 13656 ins_cost(INSN_COST); 13657 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 13658 ins_encode %{ 13659 __ subv(as_FloatRegister($dst$$reg), __ T16B, 13660 as_FloatRegister($src1$$reg), 13661 as_FloatRegister($src2$$reg)); 13662 %} 13663 ins_pipe(pipe_class_default); 13664 %} 13665 13666 instruct vsub8S(vecX dst, vecX src1, vecX src2) 13667 %{ 13668 match(Set dst (SubVS src1 src2)); 13669 ins_cost(INSN_COST); 13670 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 13671 ins_encode %{ 13672 __ subv(as_FloatRegister($dst$$reg), __ T8H, 13673 as_FloatRegister($src1$$reg), 13674 as_FloatRegister($src2$$reg)); 13675 %} 13676 ins_pipe(pipe_class_default); 13677 %} 13678 13679 instruct vsub4I(vecX dst, vecX src1, vecX src2) 13680 %{ 13681 match(Set dst (SubVI src1 src2)); 13682 ins_cost(INSN_COST); 13683 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 13684 ins_encode %{ 13685 __ subv(as_FloatRegister($dst$$reg), __ T4S, 13686 as_FloatRegister($src1$$reg), 13687 as_FloatRegister($src2$$reg)); 13688 %} 13689 ins_pipe(pipe_class_default); 13690 %} 13691 13692 instruct vsub2L(vecX dst, vecX src1, vecX src2) 13693 %{ 13694 match(Set dst (SubVL src1 src2)); 13695 ins_cost(INSN_COST); 13696 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 13697 ins_encode %{ 13698 __ subv(as_FloatRegister($dst$$reg), __ T2D, 13699 as_FloatRegister($src1$$reg), 13700 as_FloatRegister($src2$$reg)); 13701 %} 13702 ins_pipe(pipe_class_default); 13703 %} 13704 13705 instruct vsub4F(vecX dst, vecX src1, vecX src2) 13706 %{ 13707 match(Set dst (SubVF src1 src2)); 13708 ins_cost(INSN_COST); 13709 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 13710 ins_encode %{ 13711 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 13712 as_FloatRegister($src1$$reg), 13713 as_FloatRegister($src2$$reg)); 13714 %} 13715 ins_pipe(pipe_class_default); 13716 %} 13717 13718 instruct vsub2D(vecX dst, vecX src1, vecX src2) 13719 %{ 13720 match(Set dst (SubVD src1 src2)); 13721 ins_cost(INSN_COST); 13722 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 13723 ins_encode %{ 13724 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 13725 as_FloatRegister($src1$$reg), 13726 as_FloatRegister($src2$$reg)); 13727 %} 13728 ins_pipe(pipe_class_default); 13729 %} 13730 13731 // --------------------------------- MUL -------------------------------------- 13732 13733 instruct vmul8S(vecX dst, vecX src1, vecX src2) 13734 %{ 13735 match(Set dst (MulVS src1 src2)); 13736 ins_cost(INSN_COST); 13737 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 13738 ins_encode %{ 13739 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 13740 as_FloatRegister($src1$$reg), 13741 as_FloatRegister($src2$$reg)); 13742 %} 13743 ins_pipe(pipe_class_default); 13744 %} 13745 13746 instruct vmul4I(vecX dst, vecX src1, vecX src2) 13747 %{ 13748 match(Set dst (MulVI src1 src2)); 13749 ins_cost(INSN_COST); 13750 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 13751 ins_encode %{ 13752 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 13753 as_FloatRegister($src1$$reg), 13754 as_FloatRegister($src2$$reg)); 13755 %} 13756 ins_pipe(pipe_class_default); 13757 %} 13758 13759 instruct vmul4F(vecX dst, vecX src1, vecX src2) 13760 %{ 13761 match(Set dst (MulVF src1 src2)); 13762 ins_cost(INSN_COST); 13763 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 13764 ins_encode %{ 13765 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 13766 as_FloatRegister($src1$$reg), 13767 as_FloatRegister($src2$$reg)); 13768 %} 13769 ins_pipe(pipe_class_default); 13770 %} 13771 13772 instruct vmul2D(vecX dst, vecX src1, vecX src2) 13773 %{ 13774 match(Set dst (MulVD src1 src2)); 13775 ins_cost(INSN_COST); 13776 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 13777 ins_encode %{ 13778 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 13779 as_FloatRegister($src1$$reg), 13780 as_FloatRegister($src2$$reg)); 13781 %} 13782 ins_pipe(pipe_class_default); 13783 %} 13784 13785 // --------------------------------- DIV -------------------------------------- 13786 13787 instruct vdiv4F(vecX dst, vecX src1, vecX src2) 13788 %{ 13789 match(Set dst (DivVF src1 src2)); 13790 ins_cost(INSN_COST); 13791 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 13792 ins_encode %{ 13793 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 13794 as_FloatRegister($src1$$reg), 13795 as_FloatRegister($src2$$reg)); 13796 %} 13797 ins_pipe(pipe_class_default); 13798 %} 13799 13800 instruct vdiv2D(vecX dst, vecX src1, vecX src2) 13801 %{ 13802 match(Set dst (DivVD src1 src2)); 13803 ins_cost(INSN_COST); 13804 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 13805 ins_encode %{ 13806 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 13807 as_FloatRegister($src1$$reg), 13808 as_FloatRegister($src2$$reg)); 13809 %} 13810 ins_pipe(pipe_class_default); 13811 %} 13812 13813 // --------------------------------- AND -------------------------------------- 13814 13815 instruct vand16B(vecX dst, vecX src1, vecX src2) 13816 %{ 13817 match(Set dst (AndV src1 src2)); 13818 ins_cost(INSN_COST); 13819 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 13820 ins_encode %{ 13821 __ andr(as_FloatRegister($dst$$reg), __ T16B, 13822 as_FloatRegister($src1$$reg), 13823 as_FloatRegister($src2$$reg)); 13824 %} 13825 ins_pipe(pipe_class_default); 13826 %} 13827 13828 // --------------------------------- OR --------------------------------------- 13829 13830 instruct vor16B(vecX dst, vecX src1, vecX src2) 13831 %{ 13832 match(Set dst (OrV src1 src2)); 13833 ins_cost(INSN_COST); 13834 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 13835 ins_encode %{ 13836 __ orr(as_FloatRegister($dst$$reg), __ T16B, 13837 as_FloatRegister($src1$$reg), 13838 as_FloatRegister($src2$$reg)); 13839 %} 13840 ins_pipe(pipe_class_default); 13841 %} 13842 13843 // --------------------------------- XOR -------------------------------------- 13844 13845 instruct vxor16B(vecX dst, vecX src1, vecX src2) 13846 %{ 13847 match(Set dst (XorV src1 src2)); 13848 ins_cost(INSN_COST); 13849 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 13850 ins_encode %{ 13851 __ eor(as_FloatRegister($dst$$reg), __ T16B, 13852 as_FloatRegister($src1$$reg), 13853 as_FloatRegister($src2$$reg)); 13854 %} 13855 ins_pipe(pipe_class_default); 13856 %} 13857 13858 // ------------------------------ Shift --------------------------------------- 13859 13860 instruct vshiftcntL(vecX dst, iRegIorL2I cnt) %{ 13861 match(Set dst (LShiftCntV cnt)); 13862 format %{ "dup $dst, $cnt\t# shift count (vecX)" %} 13863 ins_encode %{ 13864 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 13865 %} 13866 ins_pipe(pipe_class_default); 13867 %} 13868 13869 // Right shifts on aarch64 SIMD are implemented as left shift by -ve amount 13870 instruct vshiftcntR(vecX dst, iRegIorL2I cnt) %{ 13871 match(Set dst (RShiftCntV cnt)); 13872 format %{ "dup $dst, $cnt\t# shift count (vecX)\n\tneg $dst, $dst\t T16B" %} 13873 ins_encode %{ 13874 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 13875 __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg)); 13876 %} 13877 ins_pipe(pipe_class_default); 13878 %} 13879 13880 instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 13881 match(Set dst (LShiftVB src shift)); 13882 match(Set dst (RShiftVB src shift)); 13883 ins_cost(INSN_COST); 13884 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 13885 ins_encode %{ 13886 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 13887 as_FloatRegister($src$$reg), 13888 as_FloatRegister($shift$$reg)); 13889 %} 13890 ins_pipe(pipe_class_default); 13891 %} 13892 13893 instruct vsrl16B(vecX dst, vecX src, vecX shift) %{ 13894 match(Set dst (URShiftVB src shift)); 13895 ins_cost(INSN_COST); 13896 format %{ "ushl $dst,$src,$shift\t# vector (16B)" %} 13897 ins_encode %{ 13898 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 13899 as_FloatRegister($src$$reg), 13900 as_FloatRegister($shift$$reg)); 13901 %} 13902 ins_pipe(pipe_class_default); 13903 %} 13904 13905 instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 13906 match(Set dst (LShiftVB src shift)); 13907 ins_cost(INSN_COST); 13908 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 13909 ins_encode %{ 13910 int sh = (int)$shift$$constant & 31; 13911 if (sh >= 8) { 13912 __ eor(as_FloatRegister($dst$$reg), __ T16B, 13913 as_FloatRegister($src$$reg), 13914 as_FloatRegister($src$$reg)); 13915 } else { 13916 __ shl(as_FloatRegister($dst$$reg), __ T16B, 13917 as_FloatRegister($src$$reg), sh); 13918 } 13919 %} 13920 ins_pipe(pipe_class_default); 13921 %} 13922 13923 instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 13924 match(Set dst (RShiftVB src shift)); 13925 ins_cost(INSN_COST); 13926 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 13927 ins_encode %{ 13928 int sh = (int)$shift$$constant & 31; 13929 if (sh >= 8) sh = 7; 13930 sh = -sh & 7; 13931 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 13932 as_FloatRegister($src$$reg), sh); 13933 %} 13934 ins_pipe(pipe_class_default); 13935 %} 13936 13937 instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 13938 match(Set dst (URShiftVB src shift)); 13939 ins_cost(INSN_COST); 13940 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 13941 ins_encode %{ 13942 int sh = (int)$shift$$constant & 31; 13943 if (sh >= 8) { 13944 __ eor(as_FloatRegister($dst$$reg), __ T16B, 13945 as_FloatRegister($src$$reg), 13946 as_FloatRegister($src$$reg)); 13947 } else { 13948 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 13949 as_FloatRegister($src$$reg), -sh & 7); 13950 } 13951 %} 13952 ins_pipe(pipe_class_default); 13953 %} 13954 13955 instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 13956 match(Set dst (LShiftVS src shift)); 13957 match(Set dst (RShiftVS src shift)); 13958 ins_cost(INSN_COST); 13959 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 13960 ins_encode %{ 13961 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 13962 as_FloatRegister($src$$reg), 13963 as_FloatRegister($shift$$reg)); 13964 %} 13965 ins_pipe(pipe_class_default); 13966 %} 13967 13968 instruct vsrl8S(vecX dst, vecX src, vecX shift) %{ 13969 match(Set dst (URShiftVS src shift)); 13970 ins_cost(INSN_COST); 13971 format %{ "ushl $dst,$src,$shift\t# vector (8H)" %} 13972 ins_encode %{ 13973 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 13974 as_FloatRegister($src$$reg), 13975 as_FloatRegister($shift$$reg)); 13976 %} 13977 ins_pipe(pipe_class_default); 13978 %} 13979 13980 instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 13981 match(Set dst (LShiftVS src shift)); 13982 ins_cost(INSN_COST); 13983 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 13984 ins_encode %{ 13985 int sh = (int)$shift$$constant & 31; 13986 if (sh >= 16) { 13987 __ eor(as_FloatRegister($dst$$reg), __ T16B, 13988 as_FloatRegister($src$$reg), 13989 as_FloatRegister($src$$reg)); 13990 } else { 13991 __ shl(as_FloatRegister($dst$$reg), __ T8H, 13992 as_FloatRegister($src$$reg), sh); 13993 } 13994 %} 13995 ins_pipe(pipe_class_default); 13996 %} 13997 13998 instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 13999 match(Set dst (RShiftVS src shift)); 14000 ins_cost(INSN_COST); 14001 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 14002 ins_encode %{ 14003 int sh = (int)$shift$$constant & 31; 14004 if (sh >= 16) sh = 15; 14005 sh = -sh & 15; 14006 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 14007 as_FloatRegister($src$$reg), sh); 14008 %} 14009 ins_pipe(pipe_class_default); 14010 %} 14011 14012 instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 14013 match(Set dst (URShiftVS src shift)); 14014 ins_cost(INSN_COST); 14015 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 14016 ins_encode %{ 14017 int sh = (int)$shift$$constant & 31; 14018 if (sh >= 16) { 14019 __ eor(as_FloatRegister($dst$$reg), __ T16B, 14020 as_FloatRegister($src$$reg), 14021 as_FloatRegister($src$$reg)); 14022 } else { 14023 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 14024 as_FloatRegister($src$$reg), -sh & 15); 14025 } 14026 %} 14027 ins_pipe(pipe_class_default); 14028 %} 14029 14030 instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 14031 match(Set dst (LShiftVI src shift)); 14032 match(Set dst (RShiftVI src shift)); 14033 ins_cost(INSN_COST); 14034 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 14035 ins_encode %{ 14036 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 14037 as_FloatRegister($src$$reg), 14038 as_FloatRegister($shift$$reg)); 14039 %} 14040 ins_pipe(pipe_class_default); 14041 %} 14042 14043 instruct vsrl4I(vecX dst, vecX src, vecX shift) %{ 14044 match(Set dst (URShiftVI src shift)); 14045 ins_cost(INSN_COST); 14046 format %{ "ushl $dst,$src,$shift\t# vector (4S)" %} 14047 ins_encode %{ 14048 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 14049 as_FloatRegister($src$$reg), 14050 as_FloatRegister($shift$$reg)); 14051 %} 14052 ins_pipe(pipe_class_default); 14053 %} 14054 14055 instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 14056 match(Set dst (LShiftVI src shift)); 14057 ins_cost(INSN_COST); 14058 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 14059 ins_encode %{ 14060 __ shl(as_FloatRegister($dst$$reg), __ T4S, 14061 as_FloatRegister($src$$reg), 14062 (int)$shift$$constant & 31); 14063 %} 14064 ins_pipe(pipe_class_default); 14065 %} 14066 14067 instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 14068 match(Set dst (RShiftVI src shift)); 14069 ins_cost(INSN_COST); 14070 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 14071 ins_encode %{ 14072 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 14073 as_FloatRegister($src$$reg), 14074 -(int)$shift$$constant & 31); 14075 %} 14076 ins_pipe(pipe_class_default); 14077 %} 14078 14079 instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 14080 match(Set dst (URShiftVI src shift)); 14081 ins_cost(INSN_COST); 14082 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 14083 ins_encode %{ 14084 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 14085 as_FloatRegister($src$$reg), 14086 -(int)$shift$$constant & 31); 14087 %} 14088 ins_pipe(pipe_class_default); 14089 %} 14090 14091 instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 14092 match(Set dst (LShiftVL src shift)); 14093 match(Set dst (RShiftVL src shift)); 14094 ins_cost(INSN_COST); 14095 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 14096 ins_encode %{ 14097 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 14098 as_FloatRegister($src$$reg), 14099 as_FloatRegister($shift$$reg)); 14100 %} 14101 ins_pipe(pipe_class_default); 14102 %} 14103 14104 instruct vsrl2L(vecX dst, vecX src, vecX shift) %{ 14105 match(Set dst (URShiftVL src shift)); 14106 ins_cost(INSN_COST); 14107 format %{ "ushl $dst,$src,$shift\t# vector (2D)" %} 14108 ins_encode %{ 14109 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 14110 as_FloatRegister($src$$reg), 14111 as_FloatRegister($shift$$reg)); 14112 %} 14113 ins_pipe(pipe_class_default); 14114 %} 14115 14116 instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 14117 match(Set dst (LShiftVL src shift)); 14118 ins_cost(INSN_COST); 14119 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 14120 ins_encode %{ 14121 __ shl(as_FloatRegister($dst$$reg), __ T2D, 14122 as_FloatRegister($src$$reg), 14123 (int)$shift$$constant & 63); 14124 %} 14125 ins_pipe(pipe_class_default); 14126 %} 14127 14128 instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 14129 match(Set dst (RShiftVL src shift)); 14130 ins_cost(INSN_COST); 14131 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 14132 ins_encode %{ 14133 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 14134 as_FloatRegister($src$$reg), 14135 -(int)$shift$$constant & 63); 14136 %} 14137 ins_pipe(pipe_class_default); 14138 %} 14139 14140 instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 14141 match(Set dst (URShiftVL src shift)); 14142 ins_cost(INSN_COST); 14143 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 14144 ins_encode %{ 14145 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 14146 as_FloatRegister($src$$reg), 14147 -(int)$shift$$constant & 63); 14148 %} 14149 ins_pipe(pipe_class_default); 14150 %} 14151 14152 //----------PEEPHOLE RULES----------------------------------------------------- 14153 // These must follow all instruction definitions as they use the names 14154 // defined in the instructions definitions. 14155 // 14156 // peepmatch ( root_instr_name [preceding_instruction]* ); 14157 // 14158 // peepconstraint %{ 14159 // (instruction_number.operand_name relational_op instruction_number.operand_name 14160 // [, ...] ); 14161 // // instruction numbers are zero-based using left to right order in peepmatch 14162 // 14163 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14164 // // provide an instruction_number.operand_name for each operand that appears 14165 // // in the replacement instruction's match rule 14166 // 14167 // ---------VM FLAGS--------------------------------------------------------- 14168 // 14169 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14170 // 14171 // Each peephole rule is given an identifying number starting with zero and 14172 // increasing by one in the order seen by the parser. An individual peephole 14173 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14174 // on the command-line. 14175 // 14176 // ---------CURRENT LIMITATIONS---------------------------------------------- 14177 // 14178 // Only match adjacent instructions in same basic block 14179 // Only equality constraints 14180 // Only constraints between operands, not (0.dest_reg == RAX_enc) 14181 // Only one replacement instruction 14182 // 14183 // ---------EXAMPLE---------------------------------------------------------- 14184 // 14185 // // pertinent parts of existing instructions in architecture description 14186 // instruct movI(iRegINoSp dst, iRegI src) 14187 // %{ 14188 // match(Set dst (CopyI src)); 14189 // %} 14190 // 14191 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 14192 // %{ 14193 // match(Set dst (AddI dst src)); 14194 // effect(KILL cr); 14195 // %} 14196 // 14197 // // Change (inc mov) to lea 14198 // peephole %{ 14199 // // increment preceeded by register-register move 14200 // peepmatch ( incI_iReg movI ); 14201 // // require that the destination register of the increment 14202 // // match the destination register of the move 14203 // peepconstraint ( 0.dst == 1.dst ); 14204 // // construct a replacement instruction that sets 14205 // // the destination to ( move's source register + one ) 14206 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 14207 // %} 14208 // 14209 14210 // Implementation no longer uses movX instructions since 14211 // machine-independent system no longer uses CopyX nodes. 14212 // 14213 // peephole 14214 // %{ 14215 // peepmatch (incI_iReg movI); 14216 // peepconstraint (0.dst == 1.dst); 14217 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 14218 // %} 14219 14220 // peephole 14221 // %{ 14222 // peepmatch (decI_iReg movI); 14223 // peepconstraint (0.dst == 1.dst); 14224 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 14225 // %} 14226 14227 // peephole 14228 // %{ 14229 // peepmatch (addI_iReg_imm movI); 14230 // peepconstraint (0.dst == 1.dst); 14231 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 14232 // %} 14233 14234 // peephole 14235 // %{ 14236 // peepmatch (incL_iReg movL); 14237 // peepconstraint (0.dst == 1.dst); 14238 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 14239 // %} 14240 14241 // peephole 14242 // %{ 14243 // peepmatch (decL_iReg movL); 14244 // peepconstraint (0.dst == 1.dst); 14245 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 14246 // %} 14247 14248 // peephole 14249 // %{ 14250 // peepmatch (addL_iReg_imm movL); 14251 // peepconstraint (0.dst == 1.dst); 14252 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 14253 // %} 14254 14255 // peephole 14256 // %{ 14257 // peepmatch (addP_iReg_imm movP); 14258 // peepconstraint (0.dst == 1.dst); 14259 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 14260 // %} 14261 14262 // // Change load of spilled value to only a spill 14263 // instruct storeI(memory mem, iRegI src) 14264 // %{ 14265 // match(Set mem (StoreI mem src)); 14266 // %} 14267 // 14268 // instruct loadI(iRegINoSp dst, memory mem) 14269 // %{ 14270 // match(Set dst (LoadI mem)); 14271 // %} 14272 // 14273 14274 //----------SMARTSPILL RULES--------------------------------------------------- 14275 // These must follow all instruction definitions as they use the names 14276 // defined in the instructions definitions. 14277 14278 // Local Variables: 14279 // mode: c++ 14280 // End: