1// 2// Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3// Copyright (c) 2014, 2019, Red Hat, Inc. All rights reserved. 4// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5// 6// This code is free software; you can redistribute it and/or modify it 7// under the terms of the GNU General Public License version 2 only, as 8// published by the Free Software Foundation. 9// 10// This code is distributed in the hope that it will be useful, but WITHOUT 11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13// version 2 for more details (a copy is included in the LICENSE file that 14// accompanied this code). 15// 16// You should have received a copy of the GNU General Public License version 17// 2 along with this work; if not, write to the Free Software Foundation, 18// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19// 20// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21// or visit www.oracle.com if you need additional information or have any 22// questions. 23// 24// 25 26// AArch64 Architecture Description File 27 28//----------REGISTER DEFINITION BLOCK------------------------------------------ 29// This information is used by the matcher and the register allocator to 30// describe individual registers and classes of registers within the target 31// archtecture. 32 33register %{ 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 81reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140reg_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, SOE, Op_RegF, 8, v8->as_VMReg() ); 205 reg_def V8_H ( SOC, SOE, 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, SOE, Op_RegF, 9, v9->as_VMReg() ); 210 reg_def V9_H ( SOC, SOE, 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, SOE, Op_RegF, 10, v10->as_VMReg() ); 215 reg_def V10_H( SOC, SOE, 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, SOE, Op_RegF, 11, v11->as_VMReg() ); 220 reg_def V11_H( SOC, SOE, 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, SOE, Op_RegF, 12, v12->as_VMReg() ); 225 reg_def V12_H( SOC, SOE, 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, SOE, Op_RegF, 13, v13->as_VMReg() ); 230 reg_def V13_H( SOC, SOE, 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, SOE, Op_RegF, 14, v14->as_VMReg() ); 235 reg_def V14_H( SOC, SOE, 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, SOE, Op_RegF, 15, v15->as_VMReg() ); 240 reg_def V15_H( SOC, SOE, 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 334reg_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 345alloc_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 386alloc_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 427alloc_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 440reg_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 473reg_class int_r0_reg(R0); 474 475// Singleton class for R2 int register 476reg_class int_r2_reg(R2); 477 478// Singleton class for R3 int register 479reg_class int_r3_reg(R3); 480 481// Singleton class for R4 int register 482reg_class int_r4_reg(R4); 483 484// Class for all long integer registers (including RSP) 485reg_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 519reg_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 552reg_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 585reg_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 588reg_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 621reg_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 654reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 655 656// Class for 64 bit register r0 657reg_class r0_reg( 658 R0, R0_H 659); 660 661// Class for 64 bit register r1 662reg_class r1_reg( 663 R1, R1_H 664); 665 666// Class for 64 bit register r2 667reg_class r2_reg( 668 R2, R2_H 669); 670 671// Class for 64 bit register r3 672reg_class r3_reg( 673 R3, R3_H 674); 675 676// Class for 64 bit register r4 677reg_class r4_reg( 678 R4, R4_H 679); 680 681// Class for 64 bit register r5 682reg_class r5_reg( 683 R5, R5_H 684); 685 686// Class for 64 bit register r10 687reg_class r10_reg( 688 R10, R10_H 689); 690 691// Class for 64 bit register r11 692reg_class r11_reg( 693 R11, R11_H 694); 695 696// Class for method register 697reg_class method_reg( 698 R12, R12_H 699); 700 701// Class for heapbase register 702reg_class heapbase_reg( 703 R27, R27_H 704); 705 706// Class for thread register 707reg_class thread_reg( 708 R28, R28_H 709); 710 711// Class for frame pointer register 712reg_class fp_reg( 713 R29, R29_H 714); 715 716// Class for link register 717reg_class lr_reg( 718 R30, R30_H 719); 720 721// Class for long sp register 722reg_class sp_reg( 723 R31, R31_H 724); 725 726// Class for all pointer registers 727reg_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 761reg_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 795reg_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 833reg_class double_reg( 834 V0, V0_H, 835 V1, V1_H, 836 V2, V2_H, 837 V3, V3_H, 838 V4, V4_H, 839 V5, V5_H, 840 V6, V6_H, 841 V7, V7_H, 842 V8, V8_H, 843 V9, V9_H, 844 V10, V10_H, 845 V11, V11_H, 846 V12, V12_H, 847 V13, V13_H, 848 V14, V14_H, 849 V15, V15_H, 850 V16, V16_H, 851 V17, V17_H, 852 V18, V18_H, 853 V19, V19_H, 854 V20, V20_H, 855 V21, V21_H, 856 V22, V22_H, 857 V23, V23_H, 858 V24, V24_H, 859 V25, V25_H, 860 V26, V26_H, 861 V27, V27_H, 862 V28, V28_H, 863 V29, V29_H, 864 V30, V30_H, 865 V31, V31_H 866); 867 868// Class for all 64bit vector registers 869reg_class vectord_reg( 870 V0, V0_H, 871 V1, V1_H, 872 V2, V2_H, 873 V3, V3_H, 874 V4, V4_H, 875 V5, V5_H, 876 V6, V6_H, 877 V7, V7_H, 878 V8, V8_H, 879 V9, V9_H, 880 V10, V10_H, 881 V11, V11_H, 882 V12, V12_H, 883 V13, V13_H, 884 V14, V14_H, 885 V15, V15_H, 886 V16, V16_H, 887 V17, V17_H, 888 V18, V18_H, 889 V19, V19_H, 890 V20, V20_H, 891 V21, V21_H, 892 V22, V22_H, 893 V23, V23_H, 894 V24, V24_H, 895 V25, V25_H, 896 V26, V26_H, 897 V27, V27_H, 898 V28, V28_H, 899 V29, V29_H, 900 V30, V30_H, 901 V31, V31_H 902); 903 904// Class for all 128bit vector registers 905reg_class vectorx_reg( 906 V0, V0_H, V0_J, V0_K, 907 V1, V1_H, V1_J, V1_K, 908 V2, V2_H, V2_J, V2_K, 909 V3, V3_H, V3_J, V3_K, 910 V4, V4_H, V4_J, V4_K, 911 V5, V5_H, V5_J, V5_K, 912 V6, V6_H, V6_J, V6_K, 913 V7, V7_H, V7_J, V7_K, 914 V8, V8_H, V8_J, V8_K, 915 V9, V9_H, V9_J, V9_K, 916 V10, V10_H, V10_J, V10_K, 917 V11, V11_H, V11_J, V11_K, 918 V12, V12_H, V12_J, V12_K, 919 V13, V13_H, V13_J, V13_K, 920 V14, V14_H, V14_J, V14_K, 921 V15, V15_H, V15_J, V15_K, 922 V16, V16_H, V16_J, V16_K, 923 V17, V17_H, V17_J, V17_K, 924 V18, V18_H, V18_J, V18_K, 925 V19, V19_H, V19_J, V19_K, 926 V20, V20_H, V20_J, V20_K, 927 V21, V21_H, V21_J, V21_K, 928 V22, V22_H, V22_J, V22_K, 929 V23, V23_H, V23_J, V23_K, 930 V24, V24_H, V24_J, V24_K, 931 V25, V25_H, V25_J, V25_K, 932 V26, V26_H, V26_J, V26_K, 933 V27, V27_H, V27_J, V27_K, 934 V28, V28_H, V28_J, V28_K, 935 V29, V29_H, V29_J, V29_K, 936 V30, V30_H, V30_J, V30_K, 937 V31, V31_H, V31_J, V31_K 938); 939 940// Class for 128 bit register v0 941reg_class v0_reg( 942 V0, V0_H 943); 944 945// Class for 128 bit register v1 946reg_class v1_reg( 947 V1, V1_H 948); 949 950// Class for 128 bit register v2 951reg_class v2_reg( 952 V2, V2_H 953); 954 955// Class for 128 bit register v3 956reg_class v3_reg( 957 V3, V3_H 958); 959 960// Singleton class for condition codes 961reg_class int_flags(RFLAGS); 962 963%} 964 965//----------DEFINITION BLOCK--------------------------------------------------- 966// Define name --> value mappings to inform the ADLC of an integer valued name 967// Current support includes integer values in the range [0, 0x7FFFFFFF] 968// Format: 969// int_def <name> ( <int_value>, <expression>); 970// Generated Code in ad_<arch>.hpp 971// #define <name> (<expression>) 972// // value == <int_value> 973// Generated code in ad_<arch>.cpp adlc_verification() 974// assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 975// 976 977// we follow the ppc-aix port in using a simple cost model which ranks 978// register operations as cheap, memory ops as more expensive and 979// branches as most expensive. the first two have a low as well as a 980// normal cost. huge cost appears to be a way of saying don't do 981// something 982 983definitions %{ 984 // The default cost (of a register move instruction). 985 int_def INSN_COST ( 100, 100); 986 int_def BRANCH_COST ( 200, 2 * INSN_COST); 987 int_def CALL_COST ( 200, 2 * INSN_COST); 988 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 989%} 990 991 992//----------SOURCE BLOCK------------------------------------------------------- 993// This is a block of C++ code which provides values, functions, and 994// definitions necessary in the rest of the architecture description 995 996source_hpp %{ 997 998#include "asm/macroAssembler.hpp" 999#include "gc/shared/barrierSetAssembler.hpp" 1000#include "gc/shared/cardTable.hpp" 1001#include "gc/shared/cardTableBarrierSet.hpp" 1002#include "gc/shared/collectedHeap.hpp" 1003#include "opto/addnode.hpp" 1004 1005class CallStubImpl { 1006 1007 //-------------------------------------------------------------- 1008 //---< Used for optimization in Compile::shorten_branches >--- 1009 //-------------------------------------------------------------- 1010 1011 public: 1012 // Size of call trampoline stub. 1013 static uint size_call_trampoline() { 1014 return 0; // no call trampolines on this platform 1015 } 1016 1017 // number of relocations needed by a call trampoline stub 1018 static uint reloc_call_trampoline() { 1019 return 0; // no call trampolines on this platform 1020 } 1021}; 1022 1023class HandlerImpl { 1024 1025 public: 1026 1027 static int emit_exception_handler(CodeBuffer &cbuf); 1028 static int emit_deopt_handler(CodeBuffer& cbuf); 1029 1030 static uint size_exception_handler() { 1031 return MacroAssembler::far_branch_size(); 1032 } 1033 1034 static uint size_deopt_handler() { 1035 // count one adr and one far branch instruction 1036 return 4 * NativeInstruction::instruction_size; 1037 } 1038}; 1039 1040 bool is_CAS(int opcode, bool maybe_volatile); 1041 1042 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1043 1044 bool unnecessary_acquire(const Node *barrier); 1045 bool needs_acquiring_load(const Node *load); 1046 1047 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1048 1049 bool unnecessary_release(const Node *barrier); 1050 bool unnecessary_volatile(const Node *barrier); 1051 bool needs_releasing_store(const Node *store); 1052 1053 // predicate controlling translation of CompareAndSwapX 1054 bool needs_acquiring_load_exclusive(const Node *load); 1055 1056 // predicate controlling translation of StoreCM 1057 bool unnecessary_storestore(const Node *storecm); 1058 1059 // predicate controlling addressing modes 1060 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1061%} 1062 1063source %{ 1064 1065 // Optimizaton of volatile gets and puts 1066 // ------------------------------------- 1067 // 1068 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1069 // use to implement volatile reads and writes. For a volatile read 1070 // we simply need 1071 // 1072 // ldar<x> 1073 // 1074 // and for a volatile write we need 1075 // 1076 // stlr<x> 1077 // 1078 // Alternatively, we can implement them by pairing a normal 1079 // load/store with a memory barrier. For a volatile read we need 1080 // 1081 // ldr<x> 1082 // dmb ishld 1083 // 1084 // for a volatile write 1085 // 1086 // dmb ish 1087 // str<x> 1088 // dmb ish 1089 // 1090 // We can also use ldaxr and stlxr to implement compare and swap CAS 1091 // sequences. These are normally translated to an instruction 1092 // sequence like the following 1093 // 1094 // dmb ish 1095 // retry: 1096 // ldxr<x> rval raddr 1097 // cmp rval rold 1098 // b.ne done 1099 // stlxr<x> rval, rnew, rold 1100 // cbnz rval retry 1101 // done: 1102 // cset r0, eq 1103 // dmb ishld 1104 // 1105 // Note that the exclusive store is already using an stlxr 1106 // instruction. That is required to ensure visibility to other 1107 // threads of the exclusive write (assuming it succeeds) before that 1108 // of any subsequent writes. 1109 // 1110 // The following instruction sequence is an improvement on the above 1111 // 1112 // retry: 1113 // ldaxr<x> rval raddr 1114 // cmp rval rold 1115 // b.ne done 1116 // stlxr<x> rval, rnew, rold 1117 // cbnz rval retry 1118 // done: 1119 // cset r0, eq 1120 // 1121 // We don't need the leading dmb ish since the stlxr guarantees 1122 // visibility of prior writes in the case that the swap is 1123 // successful. Crucially we don't have to worry about the case where 1124 // the swap is not successful since no valid program should be 1125 // relying on visibility of prior changes by the attempting thread 1126 // in the case where the CAS fails. 1127 // 1128 // Similarly, we don't need the trailing dmb ishld if we substitute 1129 // an ldaxr instruction since that will provide all the guarantees we 1130 // require regarding observation of changes made by other threads 1131 // before any change to the CAS address observed by the load. 1132 // 1133 // In order to generate the desired instruction sequence we need to 1134 // be able to identify specific 'signature' ideal graph node 1135 // sequences which i) occur as a translation of a volatile reads or 1136 // writes or CAS operations and ii) do not occur through any other 1137 // translation or graph transformation. We can then provide 1138 // alternative aldc matching rules which translate these node 1139 // sequences to the desired machine code sequences. Selection of the 1140 // alternative rules can be implemented by predicates which identify 1141 // the relevant node sequences. 1142 // 1143 // The ideal graph generator translates a volatile read to the node 1144 // sequence 1145 // 1146 // LoadX[mo_acquire] 1147 // MemBarAcquire 1148 // 1149 // As a special case when using the compressed oops optimization we 1150 // may also see this variant 1151 // 1152 // LoadN[mo_acquire] 1153 // DecodeN 1154 // MemBarAcquire 1155 // 1156 // A volatile write is translated to the node sequence 1157 // 1158 // MemBarRelease 1159 // StoreX[mo_release] {CardMark}-optional 1160 // MemBarVolatile 1161 // 1162 // n.b. the above node patterns are generated with a strict 1163 // 'signature' configuration of input and output dependencies (see 1164 // the predicates below for exact details). The card mark may be as 1165 // simple as a few extra nodes or, in a few GC configurations, may 1166 // include more complex control flow between the leading and 1167 // trailing memory barriers. However, whatever the card mark 1168 // configuration these signatures are unique to translated volatile 1169 // reads/stores -- they will not appear as a result of any other 1170 // bytecode translation or inlining nor as a consequence of 1171 // optimizing transforms. 1172 // 1173 // We also want to catch inlined unsafe volatile gets and puts and 1174 // be able to implement them using either ldar<x>/stlr<x> or some 1175 // combination of ldr<x>/stlr<x> and dmb instructions. 1176 // 1177 // Inlined unsafe volatiles puts manifest as a minor variant of the 1178 // normal volatile put node sequence containing an extra cpuorder 1179 // membar 1180 // 1181 // MemBarRelease 1182 // MemBarCPUOrder 1183 // StoreX[mo_release] {CardMark}-optional 1184 // MemBarCPUOrder 1185 // MemBarVolatile 1186 // 1187 // n.b. as an aside, a cpuorder membar is not itself subject to 1188 // matching and translation by adlc rules. However, the rule 1189 // predicates need to detect its presence in order to correctly 1190 // select the desired adlc rules. 1191 // 1192 // Inlined unsafe volatile gets manifest as a slightly different 1193 // node sequence to a normal volatile get because of the 1194 // introduction of some CPUOrder memory barriers to bracket the 1195 // Load. However, but the same basic skeleton of a LoadX feeding a 1196 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1197 // present 1198 // 1199 // MemBarCPUOrder 1200 // || \\ 1201 // MemBarCPUOrder LoadX[mo_acquire] 1202 // || | 1203 // || {DecodeN} optional 1204 // || / 1205 // MemBarAcquire 1206 // 1207 // In this case the acquire membar does not directly depend on the 1208 // load. However, we can be sure that the load is generated from an 1209 // inlined unsafe volatile get if we see it dependent on this unique 1210 // sequence of membar nodes. Similarly, given an acquire membar we 1211 // can know that it was added because of an inlined unsafe volatile 1212 // get if it is fed and feeds a cpuorder membar and if its feed 1213 // membar also feeds an acquiring load. 1214 // 1215 // Finally an inlined (Unsafe) CAS operation is translated to the 1216 // following ideal graph 1217 // 1218 // MemBarRelease 1219 // MemBarCPUOrder 1220 // CompareAndSwapX {CardMark}-optional 1221 // MemBarCPUOrder 1222 // MemBarAcquire 1223 // 1224 // So, where we can identify these volatile read and write 1225 // signatures we can choose to plant either of the above two code 1226 // sequences. For a volatile read we can simply plant a normal 1227 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1228 // also choose to inhibit translation of the MemBarAcquire and 1229 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1230 // 1231 // When we recognise a volatile store signature we can choose to 1232 // plant at a dmb ish as a translation for the MemBarRelease, a 1233 // normal str<x> and then a dmb ish for the MemBarVolatile. 1234 // Alternatively, we can inhibit translation of the MemBarRelease 1235 // and MemBarVolatile and instead plant a simple stlr<x> 1236 // instruction. 1237 // 1238 // when we recognise a CAS signature we can choose to plant a dmb 1239 // ish as a translation for the MemBarRelease, the conventional 1240 // macro-instruction sequence for the CompareAndSwap node (which 1241 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1242 // Alternatively, we can elide generation of the dmb instructions 1243 // and plant the alternative CompareAndSwap macro-instruction 1244 // sequence (which uses ldaxr<x>). 1245 // 1246 // Of course, the above only applies when we see these signature 1247 // configurations. We still want to plant dmb instructions in any 1248 // other cases where we may see a MemBarAcquire, MemBarRelease or 1249 // MemBarVolatile. For example, at the end of a constructor which 1250 // writes final/volatile fields we will see a MemBarRelease 1251 // instruction and this needs a 'dmb ish' lest we risk the 1252 // constructed object being visible without making the 1253 // final/volatile field writes visible. 1254 // 1255 // n.b. the translation rules below which rely on detection of the 1256 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1257 // If we see anything other than the signature configurations we 1258 // always just translate the loads and stores to ldr<x> and str<x> 1259 // and translate acquire, release and volatile membars to the 1260 // relevant dmb instructions. 1261 // 1262 1263 // is_CAS(int opcode, bool maybe_volatile) 1264 // 1265 // return true if opcode is one of the possible CompareAndSwapX 1266 // values otherwise false. 1267 1268 bool is_CAS(int opcode, bool maybe_volatile) 1269 { 1270 switch(opcode) { 1271 // We handle these 1272 case Op_CompareAndSwapI: 1273 case Op_CompareAndSwapL: 1274 case Op_CompareAndSwapP: 1275 case Op_CompareAndSwapN: 1276 case Op_CompareAndSwapB: 1277 case Op_CompareAndSwapS: 1278 case Op_GetAndSetI: 1279 case Op_GetAndSetL: 1280 case Op_GetAndSetP: 1281 case Op_GetAndSetN: 1282 case Op_GetAndAddI: 1283 case Op_GetAndAddL: 1284#if INCLUDE_SHENANDOAHGC 1285 case Op_ShenandoahCompareAndSwapP: 1286 case Op_ShenandoahCompareAndSwapN: 1287#endif 1288 return true; 1289 case Op_CompareAndExchangeI: 1290 case Op_CompareAndExchangeN: 1291 case Op_CompareAndExchangeB: 1292 case Op_CompareAndExchangeS: 1293 case Op_CompareAndExchangeL: 1294 case Op_CompareAndExchangeP: 1295 case Op_WeakCompareAndSwapB: 1296 case Op_WeakCompareAndSwapS: 1297 case Op_WeakCompareAndSwapI: 1298 case Op_WeakCompareAndSwapL: 1299 case Op_WeakCompareAndSwapP: 1300 case Op_WeakCompareAndSwapN: 1301 return maybe_volatile; 1302 default: 1303 return false; 1304 } 1305 } 1306 1307 // helper to determine the maximum number of Phi nodes we may need to 1308 // traverse when searching from a card mark membar for the merge mem 1309 // feeding a trailing membar or vice versa 1310 1311// predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1312 1313bool unnecessary_acquire(const Node *barrier) 1314{ 1315 assert(barrier->is_MemBar(), "expecting a membar"); 1316 1317 if (UseBarriersForVolatile) { 1318 // we need to plant a dmb 1319 return false; 1320 } 1321 1322 MemBarNode* mb = barrier->as_MemBar(); 1323 1324 if (mb->trailing_load()) { 1325 return true; 1326 } 1327 1328 if (mb->trailing_load_store()) { 1329 Node* load_store = mb->in(MemBarNode::Precedent); 1330 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1331 return is_CAS(load_store->Opcode(), true); 1332 } 1333 1334 return false; 1335} 1336 1337bool needs_acquiring_load(const Node *n) 1338{ 1339 assert(n->is_Load(), "expecting a load"); 1340 if (UseBarriersForVolatile) { 1341 // we use a normal load and a dmb 1342 return false; 1343 } 1344 1345 LoadNode *ld = n->as_Load(); 1346 1347 return ld->is_acquire(); 1348} 1349 1350bool unnecessary_release(const Node *n) 1351{ 1352 assert((n->is_MemBar() && 1353 n->Opcode() == Op_MemBarRelease), 1354 "expecting a release membar"); 1355 1356 if (UseBarriersForVolatile) { 1357 // we need to plant a dmb 1358 return false; 1359 } 1360 1361 MemBarNode *barrier = n->as_MemBar(); 1362 if (!barrier->leading()) { 1363 return false; 1364 } else { 1365 Node* trailing = barrier->trailing_membar(); 1366 MemBarNode* trailing_mb = trailing->as_MemBar(); 1367 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1368 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1369 1370 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1371 if (mem->is_Store()) { 1372 assert(mem->as_Store()->is_release(), ""); 1373 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1374 return true; 1375 } else { 1376 assert(mem->is_LoadStore(), ""); 1377 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1378 return is_CAS(mem->Opcode(), true); 1379 } 1380 } 1381 return false; 1382} 1383 1384bool unnecessary_volatile(const Node *n) 1385{ 1386 // assert n->is_MemBar(); 1387 if (UseBarriersForVolatile) { 1388 // we need to plant a dmb 1389 return false; 1390 } 1391 1392 MemBarNode *mbvol = n->as_MemBar(); 1393 1394 bool release = mbvol->trailing_store(); 1395 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1396#ifdef ASSERT 1397 if (release) { 1398 Node* leading = mbvol->leading_membar(); 1399 assert(leading->Opcode() == Op_MemBarRelease, ""); 1400 assert(leading->as_MemBar()->leading_store(), ""); 1401 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1402 } 1403#endif 1404 1405 return release; 1406} 1407 1408// predicates controlling emit of str<x>/stlr<x> and associated dmbs 1409 1410bool needs_releasing_store(const Node *n) 1411{ 1412 // assert n->is_Store(); 1413 if (UseBarriersForVolatile) { 1414 // we use a normal store and dmb combination 1415 return false; 1416 } 1417 1418 StoreNode *st = n->as_Store(); 1419 1420 return st->trailing_membar() != NULL; 1421} 1422 1423// predicate controlling translation of CAS 1424// 1425// returns true if CAS needs to use an acquiring load otherwise false 1426 1427bool needs_acquiring_load_exclusive(const Node *n) 1428{ 1429 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1430 if (UseBarriersForVolatile) { 1431 return false; 1432 } 1433 1434 LoadStoreNode* ldst = n->as_LoadStore(); 1435 if (is_CAS(n->Opcode(), false)) { 1436 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1437 } else { 1438 return ldst->trailing_membar() != NULL; 1439 } 1440 1441 // so we can just return true here 1442 return true; 1443} 1444 1445// predicate controlling translation of StoreCM 1446// 1447// returns true if a StoreStore must precede the card write otherwise 1448// false 1449 1450bool unnecessary_storestore(const Node *storecm) 1451{ 1452 assert(storecm->Opcode() == Op_StoreCM, "expecting a StoreCM"); 1453 1454 // we need to generate a dmb ishst between an object put and the 1455 // associated card mark when we are using CMS without conditional 1456 // card marking 1457 1458 if (UseConcMarkSweepGC && !UseCondCardMark) { 1459 return false; 1460 } 1461 1462 // a storestore is unnecesary in all other cases 1463 1464 return true; 1465} 1466 1467 1468#define __ _masm. 1469 1470// advance declarations for helper functions to convert register 1471// indices to register objects 1472 1473// the ad file has to provide implementations of certain methods 1474// expected by the generic code 1475// 1476// REQUIRED FUNCTIONALITY 1477 1478//============================================================================= 1479 1480// !!!!! Special hack to get all types of calls to specify the byte offset 1481// from the start of the call to the point where the return address 1482// will point. 1483 1484int MachCallStaticJavaNode::ret_addr_offset() 1485{ 1486 // call should be a simple bl 1487 int off = 4; 1488 return off; 1489} 1490 1491int MachCallDynamicJavaNode::ret_addr_offset() 1492{ 1493 return 16; // movz, movk, movk, bl 1494} 1495 1496int MachCallRuntimeNode::ret_addr_offset() { 1497 // for generated stubs the call will be 1498 // bl(addr) 1499 // or with far branches 1500 // bl(trampoline_stub) 1501 // for real runtime callouts it will be six instructions 1502 // see aarch64_enc_java_to_runtime 1503 // adr(rscratch2, retaddr) 1504 // lea(rscratch1, RuntimeAddress(addr) 1505 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1506 // blr(rscratch1) 1507 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1508 if (cb) { 1509 return 1 * NativeInstruction::instruction_size; 1510 } else { 1511 return 6 * NativeInstruction::instruction_size; 1512 } 1513} 1514 1515// Indicate if the safepoint node needs the polling page as an input 1516 1517// the shared code plants the oop data at the start of the generated 1518// code for the safepoint node and that needs ot be at the load 1519// instruction itself. so we cannot plant a mov of the safepoint poll 1520// address followed by a load. setting this to true means the mov is 1521// scheduled as a prior instruction. that's better for scheduling 1522// anyway. 1523 1524bool SafePointNode::needs_polling_address_input() 1525{ 1526 return true; 1527} 1528 1529//============================================================================= 1530 1531#ifndef PRODUCT 1532void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1533 st->print("BREAKPOINT"); 1534} 1535#endif 1536 1537void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1538 MacroAssembler _masm(&cbuf); 1539 __ brk(0); 1540} 1541 1542uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1543 return MachNode::size(ra_); 1544} 1545 1546//============================================================================= 1547 1548#ifndef PRODUCT 1549 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1550 st->print("nop \t# %d bytes pad for loops and calls", _count); 1551 } 1552#endif 1553 1554 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1555 MacroAssembler _masm(&cbuf); 1556 for (int i = 0; i < _count; i++) { 1557 __ nop(); 1558 } 1559 } 1560 1561 uint MachNopNode::size(PhaseRegAlloc*) const { 1562 return _count * NativeInstruction::instruction_size; 1563 } 1564 1565//============================================================================= 1566const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1567 1568int Compile::ConstantTable::calculate_table_base_offset() const { 1569 return 0; // absolute addressing, no offset 1570} 1571 1572bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1573void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1574 ShouldNotReachHere(); 1575} 1576 1577void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1578 // Empty encoding 1579} 1580 1581uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1582 return 0; 1583} 1584 1585#ifndef PRODUCT 1586void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1587 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1588} 1589#endif 1590 1591#ifndef PRODUCT 1592void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1593 Compile* C = ra_->C; 1594 1595 int framesize = C->frame_slots() << LogBytesPerInt; 1596 1597 if (C->need_stack_bang(framesize)) 1598 st->print("# stack bang size=%d\n\t", framesize); 1599 1600 if (framesize < ((1 << 9) + 2 * wordSize)) { 1601 st->print("sub sp, sp, #%d\n\t", framesize); 1602 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1603 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1604 } else { 1605 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1606 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1607 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1608 st->print("sub sp, sp, rscratch1"); 1609 } 1610} 1611#endif 1612 1613void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1614 Compile* C = ra_->C; 1615 MacroAssembler _masm(&cbuf); 1616 1617 // n.b. frame size includes space for return pc and rfp 1618 const int framesize = C->frame_size_in_bytes(); 1619 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1620 1621 // insert a nop at the start of the prolog so we can patch in a 1622 // branch if we need to invalidate the method later 1623 __ nop(); 1624 1625 int bangsize = C->bang_size_in_bytes(); 1626 if (C->need_stack_bang(bangsize) && UseStackBanging) 1627 __ generate_stack_overflow_check(bangsize); 1628 1629 __ build_frame(framesize); 1630 1631 if (VerifyStackAtCalls) { 1632 Unimplemented(); 1633 } 1634 1635 C->set_frame_complete(cbuf.insts_size()); 1636 1637 if (C->has_mach_constant_base_node()) { 1638 // NOTE: We set the table base offset here because users might be 1639 // emitted before MachConstantBaseNode. 1640 Compile::ConstantTable& constant_table = C->constant_table(); 1641 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1642 } 1643} 1644 1645uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1646{ 1647 return MachNode::size(ra_); // too many variables; just compute it 1648 // the hard way 1649} 1650 1651int MachPrologNode::reloc() const 1652{ 1653 return 0; 1654} 1655 1656//============================================================================= 1657 1658#ifndef PRODUCT 1659void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1660 Compile* C = ra_->C; 1661 int framesize = C->frame_slots() << LogBytesPerInt; 1662 1663 st->print("# pop frame %d\n\t",framesize); 1664 1665 if (framesize == 0) { 1666 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1667 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1668 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1669 st->print("add sp, sp, #%d\n\t", framesize); 1670 } else { 1671 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1672 st->print("add sp, sp, rscratch1\n\t"); 1673 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1674 } 1675 1676 if (do_polling() && C->is_method_compilation()) { 1677 st->print("# touch polling page\n\t"); 1678 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1679 st->print("ldr zr, [rscratch1]"); 1680 } 1681} 1682#endif 1683 1684void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1685 Compile* C = ra_->C; 1686 MacroAssembler _masm(&cbuf); 1687 int framesize = C->frame_slots() << LogBytesPerInt; 1688 1689 __ remove_frame(framesize); 1690 1691 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1692 __ reserved_stack_check(); 1693 } 1694 1695 if (do_polling() && C->is_method_compilation()) { 1696 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1697 } 1698} 1699 1700uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1701 // Variable size. Determine dynamically. 1702 return MachNode::size(ra_); 1703} 1704 1705int MachEpilogNode::reloc() const { 1706 // Return number of relocatable values contained in this instruction. 1707 return 1; // 1 for polling page. 1708} 1709 1710const Pipeline * MachEpilogNode::pipeline() const { 1711 return MachNode::pipeline_class(); 1712} 1713 1714// This method seems to be obsolete. It is declared in machnode.hpp 1715// and defined in all *.ad files, but it is never called. Should we 1716// get rid of it? 1717int MachEpilogNode::safepoint_offset() const { 1718 assert(do_polling(), "no return for this epilog node"); 1719 return 4; 1720} 1721 1722//============================================================================= 1723 1724// Figure out which register class each belongs in: rc_int, rc_float or 1725// rc_stack. 1726enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1727 1728static enum RC rc_class(OptoReg::Name reg) { 1729 1730 if (reg == OptoReg::Bad) { 1731 return rc_bad; 1732 } 1733 1734 // we have 30 int registers * 2 halves 1735 // (rscratch1 and rscratch2 are omitted) 1736 int slots_of_int_registers = RegisterImpl::max_slots_per_register * (RegisterImpl::number_of_registers - 2); 1737 1738 if (reg < slots_of_int_registers) { 1739 return rc_int; 1740 } 1741 1742 // we have 32 float register * 4 halves 1743 if (reg < slots_of_int_registers + FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers) { 1744 return rc_float; 1745 } 1746 1747 // Between float regs & stack is the flags regs. 1748 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1749 1750 return rc_stack; 1751} 1752 1753uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1754 Compile* C = ra_->C; 1755 1756 // Get registers to move. 1757 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1758 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1759 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1760 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1761 1762 enum RC src_hi_rc = rc_class(src_hi); 1763 enum RC src_lo_rc = rc_class(src_lo); 1764 enum RC dst_hi_rc = rc_class(dst_hi); 1765 enum RC dst_lo_rc = rc_class(dst_lo); 1766 1767 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1768 1769 if (src_hi != OptoReg::Bad) { 1770 assert((src_lo&1)==0 && src_lo+1==src_hi && 1771 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1772 "expected aligned-adjacent pairs"); 1773 } 1774 1775 if (src_lo == dst_lo && src_hi == dst_hi) { 1776 return 0; // Self copy, no move. 1777 } 1778 1779 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1780 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1781 int src_offset = ra_->reg2offset(src_lo); 1782 int dst_offset = ra_->reg2offset(dst_lo); 1783 1784 if (bottom_type()->isa_vect() != NULL) { 1785 uint ireg = ideal_reg(); 1786 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1787 if (cbuf) { 1788 MacroAssembler _masm(cbuf); 1789 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1790 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1791 // stack->stack 1792 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1793 if (ireg == Op_VecD) { 1794 __ unspill(rscratch1, true, src_offset); 1795 __ spill(rscratch1, true, dst_offset); 1796 } else { 1797 __ spill_copy128(src_offset, dst_offset); 1798 } 1799 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1800 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1801 ireg == Op_VecD ? __ T8B : __ T16B, 1802 as_FloatRegister(Matcher::_regEncode[src_lo])); 1803 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1804 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1805 ireg == Op_VecD ? __ D : __ Q, 1806 ra_->reg2offset(dst_lo)); 1807 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1808 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1809 ireg == Op_VecD ? __ D : __ Q, 1810 ra_->reg2offset(src_lo)); 1811 } else { 1812 ShouldNotReachHere(); 1813 } 1814 } 1815 } else if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 switch (src_lo_rc) { 1818 case rc_int: 1819 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1820 if (is64) { 1821 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1822 as_Register(Matcher::_regEncode[src_lo])); 1823 } else { 1824 MacroAssembler _masm(cbuf); 1825 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1826 as_Register(Matcher::_regEncode[src_lo])); 1827 } 1828 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1829 if (is64) { 1830 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1831 as_Register(Matcher::_regEncode[src_lo])); 1832 } else { 1833 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1834 as_Register(Matcher::_regEncode[src_lo])); 1835 } 1836 } else { // gpr --> stack spill 1837 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1838 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1839 } 1840 break; 1841 case rc_float: 1842 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1843 if (is64) { 1844 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1845 as_FloatRegister(Matcher::_regEncode[src_lo])); 1846 } else { 1847 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1848 as_FloatRegister(Matcher::_regEncode[src_lo])); 1849 } 1850 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1851 if (cbuf) { 1852 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1853 as_FloatRegister(Matcher::_regEncode[src_lo])); 1854 } else { 1855 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1856 as_FloatRegister(Matcher::_regEncode[src_lo])); 1857 } 1858 } else { // fpr --> stack spill 1859 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1860 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1861 is64 ? __ D : __ S, dst_offset); 1862 } 1863 break; 1864 case rc_stack: 1865 if (dst_lo_rc == rc_int) { // stack --> gpr load 1866 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1867 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1868 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1869 is64 ? __ D : __ S, src_offset); 1870 } else { // stack --> stack copy 1871 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1872 __ unspill(rscratch1, is64, src_offset); 1873 __ spill(rscratch1, is64, dst_offset); 1874 } 1875 break; 1876 default: 1877 assert(false, "bad rc_class for spill"); 1878 ShouldNotReachHere(); 1879 } 1880 } 1881 1882 if (st) { 1883 st->print("spill "); 1884 if (src_lo_rc == rc_stack) { 1885 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 1886 } else { 1887 st->print("%s -> ", Matcher::regName[src_lo]); 1888 } 1889 if (dst_lo_rc == rc_stack) { 1890 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 1891 } else { 1892 st->print("%s", Matcher::regName[dst_lo]); 1893 } 1894 if (bottom_type()->isa_vect() != NULL) { 1895 st->print("\t# vector spill size = %d", ideal_reg()==Op_VecD ? 64:128); 1896 } else { 1897 st->print("\t# spill size = %d", is64 ? 64:32); 1898 } 1899 } 1900 1901 return 0; 1902 1903} 1904 1905#ifndef PRODUCT 1906void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1907 if (!ra_) 1908 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1909 else 1910 implementation(NULL, ra_, false, st); 1911} 1912#endif 1913 1914void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1915 implementation(&cbuf, ra_, false, NULL); 1916} 1917 1918uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1919 return MachNode::size(ra_); 1920} 1921 1922//============================================================================= 1923 1924#ifndef PRODUCT 1925void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1926 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1927 int reg = ra_->get_reg_first(this); 1928 st->print("add %s, rsp, #%d]\t# box lock", 1929 Matcher::regName[reg], offset); 1930} 1931#endif 1932 1933void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1934 MacroAssembler _masm(&cbuf); 1935 1936 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1937 int reg = ra_->get_encode(this); 1938 1939 // This add will handle any 24-bit signed offset. 24 bits allows an 1940 // 8 megabyte stack frame. 1941 __ add(as_Register(reg), sp, offset); 1942} 1943 1944uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1945 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1946 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1947 1948 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1949 return NativeInstruction::instruction_size; 1950 } else { 1951 return 2 * NativeInstruction::instruction_size; 1952 } 1953} 1954 1955//============================================================================= 1956 1957#ifndef PRODUCT 1958void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1959{ 1960 st->print_cr("# MachUEPNode"); 1961 if (UseCompressedClassPointers) { 1962 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1963 if (Universe::narrow_klass_shift() != 0) { 1964 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1965 } 1966 } else { 1967 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1968 } 1969 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1970 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1971} 1972#endif 1973 1974void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1975{ 1976 // This is the unverified entry point. 1977 MacroAssembler _masm(&cbuf); 1978 1979 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1980 Label skip; 1981 // TODO 1982 // can we avoid this skip and still use a reloc? 1983 __ br(Assembler::EQ, skip); 1984 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1985 __ bind(skip); 1986} 1987 1988uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1989{ 1990 return MachNode::size(ra_); 1991} 1992 1993// REQUIRED EMIT CODE 1994 1995//============================================================================= 1996 1997// Emit exception handler code. 1998int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1999{ 2000 // mov rscratch1 #exception_blob_entry_point 2001 // br rscratch1 2002 // Note that the code buffer's insts_mark is always relative to insts. 2003 // That's why we must use the macroassembler to generate a handler. 2004 MacroAssembler _masm(&cbuf); 2005 address base = __ start_a_stub(size_exception_handler()); 2006 if (base == NULL) { 2007 ciEnv::current()->record_failure("CodeCache is full"); 2008 return 0; // CodeBuffer::expand failed 2009 } 2010 int offset = __ offset(); 2011 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2012 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2013 __ end_a_stub(); 2014 return offset; 2015} 2016 2017// Emit deopt handler code. 2018int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2019{ 2020 // Note that the code buffer's insts_mark is always relative to insts. 2021 // That's why we must use the macroassembler to generate a handler. 2022 MacroAssembler _masm(&cbuf); 2023 address base = __ start_a_stub(size_deopt_handler()); 2024 if (base == NULL) { 2025 ciEnv::current()->record_failure("CodeCache is full"); 2026 return 0; // CodeBuffer::expand failed 2027 } 2028 int offset = __ offset(); 2029 2030 __ adr(lr, __ pc()); 2031 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2032 2033 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2034 __ end_a_stub(); 2035 return offset; 2036} 2037 2038// REQUIRED MATCHER CODE 2039 2040//============================================================================= 2041 2042const bool Matcher::match_rule_supported(int opcode) { 2043 2044 switch (opcode) { 2045 default: 2046 break; 2047 } 2048 2049 if (!has_match_rule(opcode)) { 2050 return false; 2051 } 2052 2053 return true; // Per default match rules are supported. 2054} 2055 2056const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2057 2058 // TODO 2059 // identify extra cases that we might want to provide match rules for 2060 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2061 bool ret_value = match_rule_supported(opcode); 2062 // Add rules here. 2063 2064 return ret_value; // Per default match rules are supported. 2065} 2066 2067const bool Matcher::has_predicated_vectors(void) { 2068 return false; 2069} 2070 2071const int Matcher::float_pressure(int default_pressure_threshold) { 2072 return default_pressure_threshold; 2073} 2074 2075int Matcher::regnum_to_fpu_offset(int regnum) 2076{ 2077 Unimplemented(); 2078 return 0; 2079} 2080 2081// Is this branch offset short enough that a short branch can be used? 2082// 2083// NOTE: If the platform does not provide any short branch variants, then 2084// this method should return false for offset 0. 2085bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2086 // The passed offset is relative to address of the branch. 2087 2088 return (-32768 <= offset && offset < 32768); 2089} 2090 2091const bool Matcher::isSimpleConstant64(jlong value) { 2092 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2093 // Probably always true, even if a temp register is required. 2094 return true; 2095} 2096 2097// true just means we have fast l2f conversion 2098const bool Matcher::convL2FSupported(void) { 2099 return true; 2100} 2101 2102// Vector width in bytes. 2103const int Matcher::vector_width_in_bytes(BasicType bt) { 2104 int size = MIN2(16,(int)MaxVectorSize); 2105 // Minimum 2 values in vector 2106 if (size < 2*type2aelembytes(bt)) size = 0; 2107 // But never < 4 2108 if (size < 4) size = 0; 2109 return size; 2110} 2111 2112// Limits on vector size (number of elements) loaded into vector. 2113const int Matcher::max_vector_size(const BasicType bt) { 2114 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2115} 2116const int Matcher::min_vector_size(const BasicType bt) { 2117// For the moment limit the vector size to 8 bytes 2118 int size = 8 / type2aelembytes(bt); 2119 if (size < 2) size = 2; 2120 return size; 2121} 2122 2123// Vector ideal reg. 2124const uint Matcher::vector_ideal_reg(int len) { 2125 switch(len) { 2126 case 8: return Op_VecD; 2127 case 16: return Op_VecX; 2128 } 2129 ShouldNotReachHere(); 2130 return 0; 2131} 2132 2133const uint Matcher::vector_shift_count_ideal_reg(int size) { 2134 switch(size) { 2135 case 8: return Op_VecD; 2136 case 16: return Op_VecX; 2137 } 2138 ShouldNotReachHere(); 2139 return 0; 2140} 2141 2142// AES support not yet implemented 2143const bool Matcher::pass_original_key_for_aes() { 2144 return false; 2145} 2146 2147// aarch64 supports misaligned vectors store/load. 2148const bool Matcher::misaligned_vectors_ok() { 2149 return true; 2150} 2151 2152// false => size gets scaled to BytesPerLong, ok. 2153const bool Matcher::init_array_count_is_in_bytes = false; 2154 2155// Use conditional move (CMOVL) 2156const int Matcher::long_cmove_cost() { 2157 // long cmoves are no more expensive than int cmoves 2158 return 0; 2159} 2160 2161const int Matcher::float_cmove_cost() { 2162 // float cmoves are no more expensive than int cmoves 2163 return 0; 2164} 2165 2166// Does the CPU require late expand (see block.cpp for description of late expand)? 2167const bool Matcher::require_postalloc_expand = false; 2168 2169// Do we need to mask the count passed to shift instructions or does 2170// the cpu only look at the lower 5/6 bits anyway? 2171const bool Matcher::need_masked_shift_count = false; 2172 2173// This affects two different things: 2174// - how Decode nodes are matched 2175// - how ImplicitNullCheck opportunities are recognized 2176// If true, the matcher will try to remove all Decodes and match them 2177// (as operands) into nodes. NullChecks are not prepared to deal with 2178// Decodes by final_graph_reshaping(). 2179// If false, final_graph_reshaping() forces the decode behind the Cmp 2180// for a NullCheck. The matcher matches the Decode node into a register. 2181// Implicit_null_check optimization moves the Decode along with the 2182// memory operation back up before the NullCheck. 2183bool Matcher::narrow_oop_use_complex_address() { 2184 return Universe::narrow_oop_shift() == 0; 2185} 2186 2187bool Matcher::narrow_klass_use_complex_address() { 2188// TODO 2189// decide whether we need to set this to true 2190 return false; 2191} 2192 2193bool Matcher::const_oop_prefer_decode() { 2194 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2195 return Universe::narrow_oop_base() == NULL; 2196} 2197 2198bool Matcher::const_klass_prefer_decode() { 2199 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2200 return Universe::narrow_klass_base() == NULL; 2201} 2202 2203// Is it better to copy float constants, or load them directly from 2204// memory? Intel can load a float constant from a direct address, 2205// requiring no extra registers. Most RISCs will have to materialize 2206// an address into a register first, so they would do better to copy 2207// the constant from stack. 2208const bool Matcher::rematerialize_float_constants = false; 2209 2210// If CPU can load and store mis-aligned doubles directly then no 2211// fixup is needed. Else we split the double into 2 integer pieces 2212// and move it piece-by-piece. Only happens when passing doubles into 2213// C code as the Java calling convention forces doubles to be aligned. 2214const bool Matcher::misaligned_doubles_ok = true; 2215 2216// No-op on amd64 2217void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2218 Unimplemented(); 2219} 2220 2221// Advertise here if the CPU requires explicit rounding operations to 2222// implement the UseStrictFP mode. 2223const bool Matcher::strict_fp_requires_explicit_rounding = false; 2224 2225// Are floats converted to double when stored to stack during 2226// deoptimization? 2227bool Matcher::float_in_double() { return false; } 2228 2229// Do ints take an entire long register or just half? 2230// The relevant question is how the int is callee-saved: 2231// the whole long is written but de-opt'ing will have to extract 2232// the relevant 32 bits. 2233const bool Matcher::int_in_long = true; 2234 2235// Return whether or not this register is ever used as an argument. 2236// This function is used on startup to build the trampoline stubs in 2237// generateOptoStub. Registers not mentioned will be killed by the VM 2238// call in the trampoline, and arguments in those registers not be 2239// available to the callee. 2240bool Matcher::can_be_java_arg(int reg) 2241{ 2242 return 2243 reg == R0_num || reg == R0_H_num || 2244 reg == R1_num || reg == R1_H_num || 2245 reg == R2_num || reg == R2_H_num || 2246 reg == R3_num || reg == R3_H_num || 2247 reg == R4_num || reg == R4_H_num || 2248 reg == R5_num || reg == R5_H_num || 2249 reg == R6_num || reg == R6_H_num || 2250 reg == R7_num || reg == R7_H_num || 2251 reg == V0_num || reg == V0_H_num || 2252 reg == V1_num || reg == V1_H_num || 2253 reg == V2_num || reg == V2_H_num || 2254 reg == V3_num || reg == V3_H_num || 2255 reg == V4_num || reg == V4_H_num || 2256 reg == V5_num || reg == V5_H_num || 2257 reg == V6_num || reg == V6_H_num || 2258 reg == V7_num || reg == V7_H_num; 2259} 2260 2261bool Matcher::is_spillable_arg(int reg) 2262{ 2263 return can_be_java_arg(reg); 2264} 2265 2266bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2267 return false; 2268} 2269 2270RegMask Matcher::divI_proj_mask() { 2271 ShouldNotReachHere(); 2272 return RegMask(); 2273} 2274 2275// Register for MODI projection of divmodI. 2276RegMask Matcher::modI_proj_mask() { 2277 ShouldNotReachHere(); 2278 return RegMask(); 2279} 2280 2281// Register for DIVL projection of divmodL. 2282RegMask Matcher::divL_proj_mask() { 2283 ShouldNotReachHere(); 2284 return RegMask(); 2285} 2286 2287// Register for MODL projection of divmodL. 2288RegMask Matcher::modL_proj_mask() { 2289 ShouldNotReachHere(); 2290 return RegMask(); 2291} 2292 2293const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2294 return FP_REG_mask(); 2295} 2296 2297bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2298 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2299 Node* u = addp->fast_out(i); 2300 if (u->is_Mem()) { 2301 int opsize = u->as_Mem()->memory_size(); 2302 assert(opsize > 0, "unexpected memory operand size"); 2303 if (u->as_Mem()->memory_size() != (1<<shift)) { 2304 return false; 2305 } 2306 } 2307 } 2308 return true; 2309} 2310 2311const bool Matcher::convi2l_type_required = false; 2312 2313// Should the Matcher clone shifts on addressing modes, expecting them 2314// to be subsumed into complex addressing expressions or compute them 2315// into registers? 2316bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2317 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2318 return true; 2319 } 2320 2321 Node *off = m->in(AddPNode::Offset); 2322 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2323 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2324 // Are there other uses besides address expressions? 2325 !is_visited(off)) { 2326 address_visited.set(off->_idx); // Flag as address_visited 2327 mstack.push(off->in(2), Visit); 2328 Node *conv = off->in(1); 2329 if (conv->Opcode() == Op_ConvI2L && 2330 // Are there other uses besides address expressions? 2331 !is_visited(conv)) { 2332 address_visited.set(conv->_idx); // Flag as address_visited 2333 mstack.push(conv->in(1), Pre_Visit); 2334 } else { 2335 mstack.push(conv, Pre_Visit); 2336 } 2337 address_visited.test_set(m->_idx); // Flag as address_visited 2338 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2339 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2340 return true; 2341 } else if (off->Opcode() == Op_ConvI2L && 2342 // Are there other uses besides address expressions? 2343 !is_visited(off)) { 2344 address_visited.test_set(m->_idx); // Flag as address_visited 2345 address_visited.set(off->_idx); // Flag as address_visited 2346 mstack.push(off->in(1), Pre_Visit); 2347 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2348 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2349 return true; 2350 } 2351 return false; 2352} 2353 2354void Compile::reshape_address(AddPNode* addp) { 2355} 2356 2357 2358#define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2359 MacroAssembler _masm(&cbuf); \ 2360 { \ 2361 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2362 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2363 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2364 __ INSN(REG, as_Register(BASE)); \ 2365 } 2366 2367typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2368typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2369typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2370 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2371 2372 // Used for all non-volatile memory accesses. The use of 2373 // $mem->opcode() to discover whether this pattern uses sign-extended 2374 // offsets is something of a kludge. 2375 static void loadStore(MacroAssembler masm, mem_insn insn, 2376 Register reg, int opcode, 2377 Register base, int index, int size, int disp) 2378 { 2379 Address::extend scale; 2380 2381 // Hooboy, this is fugly. We need a way to communicate to the 2382 // encoder that the index needs to be sign extended, so we have to 2383 // enumerate all the cases. 2384 switch (opcode) { 2385 case INDINDEXSCALEDI2L: 2386 case INDINDEXSCALEDI2LN: 2387 case INDINDEXI2L: 2388 case INDINDEXI2LN: 2389 scale = Address::sxtw(size); 2390 break; 2391 default: 2392 scale = Address::lsl(size); 2393 } 2394 2395 if (index == -1) { 2396 (masm.*insn)(reg, Address(base, disp)); 2397 } else { 2398 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2399 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2400 } 2401 } 2402 2403 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2404 FloatRegister reg, int opcode, 2405 Register base, int index, int size, int disp) 2406 { 2407 Address::extend scale; 2408 2409 switch (opcode) { 2410 case INDINDEXSCALEDI2L: 2411 case INDINDEXSCALEDI2LN: 2412 scale = Address::sxtw(size); 2413 break; 2414 default: 2415 scale = Address::lsl(size); 2416 } 2417 2418 if (index == -1) { 2419 (masm.*insn)(reg, Address(base, disp)); 2420 } else { 2421 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2422 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2423 } 2424 } 2425 2426 static void loadStore(MacroAssembler masm, mem_vector_insn insn, 2427 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2428 int opcode, Register base, int index, int size, int disp) 2429 { 2430 if (index == -1) { 2431 (masm.*insn)(reg, T, Address(base, disp)); 2432 } else { 2433 assert(disp == 0, "unsupported address mode"); 2434 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2435 } 2436 } 2437 2438%} 2439 2440 2441 2442//----------ENCODING BLOCK----------------------------------------------------- 2443// This block specifies the encoding classes used by the compiler to 2444// output byte streams. Encoding classes are parameterized macros 2445// used by Machine Instruction Nodes in order to generate the bit 2446// encoding of the instruction. Operands specify their base encoding 2447// interface with the interface keyword. There are currently 2448// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2449// COND_INTER. REG_INTER causes an operand to generate a function 2450// which returns its register number when queried. CONST_INTER causes 2451// an operand to generate a function which returns the value of the 2452// constant when queried. MEMORY_INTER causes an operand to generate 2453// four functions which return the Base Register, the Index Register, 2454// the Scale Value, and the Offset Value of the operand when queried. 2455// COND_INTER causes an operand to generate six functions which return 2456// the encoding code (ie - encoding bits for the instruction) 2457// associated with each basic boolean condition for a conditional 2458// instruction. 2459// 2460// Instructions specify two basic values for encoding. Again, a 2461// function is available to check if the constant displacement is an 2462// oop. They use the ins_encode keyword to specify their encoding 2463// classes (which must be a sequence of enc_class names, and their 2464// parameters, specified in the encoding block), and they use the 2465// opcode keyword to specify, in order, their primary, secondary, and 2466// tertiary opcode. Only the opcode sections which a particular 2467// instruction needs for encoding need to be specified. 2468encode %{ 2469 // Build emit functions for each basic byte or larger field in the 2470 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2471 // from C++ code in the enc_class source block. Emit functions will 2472 // live in the main source block for now. In future, we can 2473 // generalize this by adding a syntax that specifies the sizes of 2474 // fields in an order, so that the adlc can build the emit functions 2475 // automagically 2476 2477 // catch all for unimplemented encodings 2478 enc_class enc_unimplemented %{ 2479 MacroAssembler _masm(&cbuf); 2480 __ unimplemented("C2 catch all"); 2481 %} 2482 2483 // BEGIN Non-volatile memory access 2484 2485 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2486 Register dst_reg = as_Register($dst$$reg); 2487 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2488 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2489 %} 2490 2491 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2492 Register dst_reg = as_Register($dst$$reg); 2493 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2494 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2495 %} 2496 2497 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2498 Register dst_reg = as_Register($dst$$reg); 2499 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2500 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2501 %} 2502 2503 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2504 Register dst_reg = as_Register($dst$$reg); 2505 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2506 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2507 %} 2508 2509 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2510 Register dst_reg = as_Register($dst$$reg); 2511 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2512 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2513 %} 2514 2515 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2516 Register dst_reg = as_Register($dst$$reg); 2517 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2518 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2519 %} 2520 2521 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2522 Register dst_reg = as_Register($dst$$reg); 2523 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2524 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2525 %} 2526 2527 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2528 Register dst_reg = as_Register($dst$$reg); 2529 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2530 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2531 %} 2532 2533 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2534 Register dst_reg = as_Register($dst$$reg); 2535 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2536 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2537 %} 2538 2539 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2540 Register dst_reg = as_Register($dst$$reg); 2541 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2542 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2543 %} 2544 2545 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2546 Register dst_reg = as_Register($dst$$reg); 2547 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2548 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2549 %} 2550 2551 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2552 Register dst_reg = as_Register($dst$$reg); 2553 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2554 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2555 %} 2556 2557 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2558 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2559 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2560 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2561 %} 2562 2563 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2564 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2565 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2566 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2567 %} 2568 2569 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 2570 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2571 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 2572 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2573 %} 2574 2575 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 2576 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2577 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 2578 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2579 %} 2580 2581 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 2582 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2583 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 2584 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2585 %} 2586 2587 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2588 Register src_reg = as_Register($src$$reg); 2589 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2590 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2591 %} 2592 2593 enc_class aarch64_enc_strb0(memory mem) %{ 2594 MacroAssembler _masm(&cbuf); 2595 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2596 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2597 %} 2598 2599 enc_class aarch64_enc_strb0_ordered(memory mem) %{ 2600 MacroAssembler _masm(&cbuf); 2601 __ membar(Assembler::StoreStore); 2602 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2603 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2604 %} 2605 2606 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2607 Register src_reg = as_Register($src$$reg); 2608 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2609 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2610 %} 2611 2612 enc_class aarch64_enc_strh0(memory mem) %{ 2613 MacroAssembler _masm(&cbuf); 2614 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2615 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2616 %} 2617 2618 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2619 Register src_reg = as_Register($src$$reg); 2620 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2621 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2622 %} 2623 2624 enc_class aarch64_enc_strw0(memory mem) %{ 2625 MacroAssembler _masm(&cbuf); 2626 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2627 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2628 %} 2629 2630 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2631 Register src_reg = as_Register($src$$reg); 2632 // we sometimes get asked to store the stack pointer into the 2633 // current thread -- we cannot do that directly on AArch64 2634 if (src_reg == r31_sp) { 2635 MacroAssembler _masm(&cbuf); 2636 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2637 __ mov(rscratch2, sp); 2638 src_reg = rscratch2; 2639 } 2640 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2641 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2642 %} 2643 2644 enc_class aarch64_enc_str0(memory mem) %{ 2645 MacroAssembler _masm(&cbuf); 2646 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2647 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2648 %} 2649 2650 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2651 FloatRegister src_reg = as_FloatRegister($src$$reg); 2652 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2653 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2654 %} 2655 2656 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2657 FloatRegister src_reg = as_FloatRegister($src$$reg); 2658 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2659 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2660 %} 2661 2662 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 2663 FloatRegister src_reg = as_FloatRegister($src$$reg); 2664 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 2665 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2666 %} 2667 2668 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 2669 FloatRegister src_reg = as_FloatRegister($src$$reg); 2670 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 2671 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2672 %} 2673 2674 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 2675 FloatRegister src_reg = as_FloatRegister($src$$reg); 2676 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 2677 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2678 %} 2679 2680 // END Non-volatile memory access 2681 2682 // volatile loads and stores 2683 2684 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2685 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2686 rscratch1, stlrb); 2687 %} 2688 2689 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2690 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2691 rscratch1, stlrh); 2692 %} 2693 2694 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2695 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2696 rscratch1, stlrw); 2697 %} 2698 2699 2700 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2701 Register dst_reg = as_Register($dst$$reg); 2702 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2703 rscratch1, ldarb); 2704 __ sxtbw(dst_reg, dst_reg); 2705 %} 2706 2707 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2708 Register dst_reg = as_Register($dst$$reg); 2709 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2710 rscratch1, ldarb); 2711 __ sxtb(dst_reg, dst_reg); 2712 %} 2713 2714 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2715 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2716 rscratch1, ldarb); 2717 %} 2718 2719 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2720 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2721 rscratch1, ldarb); 2722 %} 2723 2724 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2725 Register dst_reg = as_Register($dst$$reg); 2726 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2727 rscratch1, ldarh); 2728 __ sxthw(dst_reg, dst_reg); 2729 %} 2730 2731 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2732 Register dst_reg = as_Register($dst$$reg); 2733 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2734 rscratch1, ldarh); 2735 __ sxth(dst_reg, dst_reg); 2736 %} 2737 2738 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2739 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2740 rscratch1, ldarh); 2741 %} 2742 2743 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2744 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2745 rscratch1, ldarh); 2746 %} 2747 2748 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2749 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2750 rscratch1, ldarw); 2751 %} 2752 2753 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2754 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2755 rscratch1, ldarw); 2756 %} 2757 2758 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2759 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2760 rscratch1, ldar); 2761 %} 2762 2763 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2764 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2765 rscratch1, ldarw); 2766 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2767 %} 2768 2769 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2770 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2771 rscratch1, ldar); 2772 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2773 %} 2774 2775 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2776 Register src_reg = as_Register($src$$reg); 2777 // we sometimes get asked to store the stack pointer into the 2778 // current thread -- we cannot do that directly on AArch64 2779 if (src_reg == r31_sp) { 2780 MacroAssembler _masm(&cbuf); 2781 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2782 __ mov(rscratch2, sp); 2783 src_reg = rscratch2; 2784 } 2785 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2786 rscratch1, stlr); 2787 %} 2788 2789 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2790 { 2791 MacroAssembler _masm(&cbuf); 2792 FloatRegister src_reg = as_FloatRegister($src$$reg); 2793 __ fmovs(rscratch2, src_reg); 2794 } 2795 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2796 rscratch1, stlrw); 2797 %} 2798 2799 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2800 { 2801 MacroAssembler _masm(&cbuf); 2802 FloatRegister src_reg = as_FloatRegister($src$$reg); 2803 __ fmovd(rscratch2, src_reg); 2804 } 2805 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2806 rscratch1, stlr); 2807 %} 2808 2809 // synchronized read/update encodings 2810 2811 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2812 MacroAssembler _masm(&cbuf); 2813 Register dst_reg = as_Register($dst$$reg); 2814 Register base = as_Register($mem$$base); 2815 int index = $mem$$index; 2816 int scale = $mem$$scale; 2817 int disp = $mem$$disp; 2818 if (index == -1) { 2819 if (disp != 0) { 2820 __ lea(rscratch1, Address(base, disp)); 2821 __ ldaxr(dst_reg, rscratch1); 2822 } else { 2823 // TODO 2824 // should we ever get anything other than this case? 2825 __ ldaxr(dst_reg, base); 2826 } 2827 } else { 2828 Register index_reg = as_Register(index); 2829 if (disp == 0) { 2830 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2831 __ ldaxr(dst_reg, rscratch1); 2832 } else { 2833 __ lea(rscratch1, Address(base, disp)); 2834 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2835 __ ldaxr(dst_reg, rscratch1); 2836 } 2837 } 2838 %} 2839 2840 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2841 MacroAssembler _masm(&cbuf); 2842 Register src_reg = as_Register($src$$reg); 2843 Register base = as_Register($mem$$base); 2844 int index = $mem$$index; 2845 int scale = $mem$$scale; 2846 int disp = $mem$$disp; 2847 if (index == -1) { 2848 if (disp != 0) { 2849 __ lea(rscratch2, Address(base, disp)); 2850 __ stlxr(rscratch1, src_reg, rscratch2); 2851 } else { 2852 // TODO 2853 // should we ever get anything other than this case? 2854 __ stlxr(rscratch1, src_reg, base); 2855 } 2856 } else { 2857 Register index_reg = as_Register(index); 2858 if (disp == 0) { 2859 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2860 __ stlxr(rscratch1, src_reg, rscratch2); 2861 } else { 2862 __ lea(rscratch2, Address(base, disp)); 2863 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2864 __ stlxr(rscratch1, src_reg, rscratch2); 2865 } 2866 } 2867 __ cmpw(rscratch1, zr); 2868 %} 2869 2870 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2871 MacroAssembler _masm(&cbuf); 2872 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2873 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2874 Assembler::xword, /*acquire*/ false, /*release*/ true, 2875 /*weak*/ false, noreg); 2876 %} 2877 2878 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2879 MacroAssembler _masm(&cbuf); 2880 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2881 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2882 Assembler::word, /*acquire*/ false, /*release*/ true, 2883 /*weak*/ false, noreg); 2884 %} 2885 2886 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2887 MacroAssembler _masm(&cbuf); 2888 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2889 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2890 Assembler::halfword, /*acquire*/ false, /*release*/ true, 2891 /*weak*/ false, noreg); 2892 %} 2893 2894 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2895 MacroAssembler _masm(&cbuf); 2896 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2897 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2898 Assembler::byte, /*acquire*/ false, /*release*/ true, 2899 /*weak*/ false, noreg); 2900 %} 2901 2902 2903 // The only difference between aarch64_enc_cmpxchg and 2904 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 2905 // CompareAndSwap sequence to serve as a barrier on acquiring a 2906 // lock. 2907 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2908 MacroAssembler _masm(&cbuf); 2909 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2910 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2911 Assembler::xword, /*acquire*/ true, /*release*/ true, 2912 /*weak*/ false, noreg); 2913 %} 2914 2915 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2916 MacroAssembler _masm(&cbuf); 2917 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2918 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2919 Assembler::word, /*acquire*/ true, /*release*/ true, 2920 /*weak*/ false, noreg); 2921 %} 2922 2923 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2924 MacroAssembler _masm(&cbuf); 2925 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2926 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2927 Assembler::halfword, /*acquire*/ true, /*release*/ true, 2928 /*weak*/ false, noreg); 2929 %} 2930 2931 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2932 MacroAssembler _masm(&cbuf); 2933 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 2934 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 2935 Assembler::byte, /*acquire*/ true, /*release*/ true, 2936 /*weak*/ false, noreg); 2937 %} 2938 2939 // auxiliary used for CompareAndSwapX to set result register 2940 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2941 MacroAssembler _masm(&cbuf); 2942 Register res_reg = as_Register($res$$reg); 2943 __ cset(res_reg, Assembler::EQ); 2944 %} 2945 2946 // prefetch encodings 2947 2948 enc_class aarch64_enc_prefetchw(memory mem) %{ 2949 MacroAssembler _masm(&cbuf); 2950 Register base = as_Register($mem$$base); 2951 int index = $mem$$index; 2952 int scale = $mem$$scale; 2953 int disp = $mem$$disp; 2954 if (index == -1) { 2955 __ prfm(Address(base, disp), PSTL1KEEP); 2956 } else { 2957 Register index_reg = as_Register(index); 2958 if (disp == 0) { 2959 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2960 } else { 2961 __ lea(rscratch1, Address(base, disp)); 2962 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2963 } 2964 } 2965 %} 2966 2967 /// mov envcodings 2968 2969 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2970 MacroAssembler _masm(&cbuf); 2971 uint32_t con = (uint32_t)$src$$constant; 2972 Register dst_reg = as_Register($dst$$reg); 2973 if (con == 0) { 2974 __ movw(dst_reg, zr); 2975 } else { 2976 __ movw(dst_reg, con); 2977 } 2978 %} 2979 2980 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2981 MacroAssembler _masm(&cbuf); 2982 Register dst_reg = as_Register($dst$$reg); 2983 uint64_t con = (uint64_t)$src$$constant; 2984 if (con == 0) { 2985 __ mov(dst_reg, zr); 2986 } else { 2987 __ mov(dst_reg, con); 2988 } 2989 %} 2990 2991 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 2992 MacroAssembler _masm(&cbuf); 2993 Register dst_reg = as_Register($dst$$reg); 2994 address con = (address)$src$$constant; 2995 if (con == NULL || con == (address)1) { 2996 ShouldNotReachHere(); 2997 } else { 2998 relocInfo::relocType rtype = $src->constant_reloc(); 2999 if (rtype == relocInfo::oop_type) { 3000 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3001 } else if (rtype == relocInfo::metadata_type) { 3002 __ mov_metadata(dst_reg, (Metadata*)con); 3003 } else { 3004 assert(rtype == relocInfo::none, "unexpected reloc type"); 3005 if (con < (address)(uintptr_t)os::vm_page_size()) { 3006 __ mov(dst_reg, con); 3007 } else { 3008 uintptr_t offset; 3009 __ adrp(dst_reg, con, offset); 3010 __ add(dst_reg, dst_reg, offset); 3011 } 3012 } 3013 } 3014 %} 3015 3016 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3017 MacroAssembler _masm(&cbuf); 3018 Register dst_reg = as_Register($dst$$reg); 3019 __ mov(dst_reg, zr); 3020 %} 3021 3022 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3023 MacroAssembler _masm(&cbuf); 3024 Register dst_reg = as_Register($dst$$reg); 3025 __ mov(dst_reg, (uint64_t)1); 3026 %} 3027 3028 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3029 MacroAssembler _masm(&cbuf); 3030 address page = (address)$src$$constant; 3031 Register dst_reg = as_Register($dst$$reg); 3032 uint64_t off; 3033 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3034 assert(off == 0, "assumed offset == 0"); 3035 %} 3036 3037 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3038 MacroAssembler _masm(&cbuf); 3039 __ load_byte_map_base($dst$$Register); 3040 %} 3041 3042 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3043 MacroAssembler _masm(&cbuf); 3044 Register dst_reg = as_Register($dst$$reg); 3045 address con = (address)$src$$constant; 3046 if (con == NULL) { 3047 ShouldNotReachHere(); 3048 } else { 3049 relocInfo::relocType rtype = $src->constant_reloc(); 3050 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3051 __ set_narrow_oop(dst_reg, (jobject)con); 3052 } 3053 %} 3054 3055 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3056 MacroAssembler _masm(&cbuf); 3057 Register dst_reg = as_Register($dst$$reg); 3058 __ mov(dst_reg, zr); 3059 %} 3060 3061 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3062 MacroAssembler _masm(&cbuf); 3063 Register dst_reg = as_Register($dst$$reg); 3064 address con = (address)$src$$constant; 3065 if (con == NULL) { 3066 ShouldNotReachHere(); 3067 } else { 3068 relocInfo::relocType rtype = $src->constant_reloc(); 3069 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3070 __ set_narrow_klass(dst_reg, (Klass *)con); 3071 } 3072 %} 3073 3074 // arithmetic encodings 3075 3076 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3077 MacroAssembler _masm(&cbuf); 3078 Register dst_reg = as_Register($dst$$reg); 3079 Register src_reg = as_Register($src1$$reg); 3080 int32_t con = (int32_t)$src2$$constant; 3081 // add has primary == 0, subtract has primary == 1 3082 if ($primary) { con = -con; } 3083 if (con < 0) { 3084 __ subw(dst_reg, src_reg, -con); 3085 } else { 3086 __ addw(dst_reg, src_reg, con); 3087 } 3088 %} 3089 3090 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3091 MacroAssembler _masm(&cbuf); 3092 Register dst_reg = as_Register($dst$$reg); 3093 Register src_reg = as_Register($src1$$reg); 3094 int32_t con = (int32_t)$src2$$constant; 3095 // add has primary == 0, subtract has primary == 1 3096 if ($primary) { con = -con; } 3097 if (con < 0) { 3098 __ sub(dst_reg, src_reg, -con); 3099 } else { 3100 __ add(dst_reg, src_reg, con); 3101 } 3102 %} 3103 3104 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3105 MacroAssembler _masm(&cbuf); 3106 Register dst_reg = as_Register($dst$$reg); 3107 Register src1_reg = as_Register($src1$$reg); 3108 Register src2_reg = as_Register($src2$$reg); 3109 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3110 %} 3111 3112 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3113 MacroAssembler _masm(&cbuf); 3114 Register dst_reg = as_Register($dst$$reg); 3115 Register src1_reg = as_Register($src1$$reg); 3116 Register src2_reg = as_Register($src2$$reg); 3117 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3118 %} 3119 3120 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3121 MacroAssembler _masm(&cbuf); 3122 Register dst_reg = as_Register($dst$$reg); 3123 Register src1_reg = as_Register($src1$$reg); 3124 Register src2_reg = as_Register($src2$$reg); 3125 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3126 %} 3127 3128 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3129 MacroAssembler _masm(&cbuf); 3130 Register dst_reg = as_Register($dst$$reg); 3131 Register src1_reg = as_Register($src1$$reg); 3132 Register src2_reg = as_Register($src2$$reg); 3133 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3134 %} 3135 3136 // compare instruction encodings 3137 3138 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3139 MacroAssembler _masm(&cbuf); 3140 Register reg1 = as_Register($src1$$reg); 3141 Register reg2 = as_Register($src2$$reg); 3142 __ cmpw(reg1, reg2); 3143 %} 3144 3145 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3146 MacroAssembler _masm(&cbuf); 3147 Register reg = as_Register($src1$$reg); 3148 int32_t val = $src2$$constant; 3149 if (val >= 0) { 3150 __ subsw(zr, reg, val); 3151 } else { 3152 __ addsw(zr, reg, -val); 3153 } 3154 %} 3155 3156 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3157 MacroAssembler _masm(&cbuf); 3158 Register reg1 = as_Register($src1$$reg); 3159 uint32_t val = (uint32_t)$src2$$constant; 3160 __ movw(rscratch1, val); 3161 __ cmpw(reg1, rscratch1); 3162 %} 3163 3164 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3165 MacroAssembler _masm(&cbuf); 3166 Register reg1 = as_Register($src1$$reg); 3167 Register reg2 = as_Register($src2$$reg); 3168 __ cmp(reg1, reg2); 3169 %} 3170 3171 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3172 MacroAssembler _masm(&cbuf); 3173 Register reg = as_Register($src1$$reg); 3174 int64_t val = $src2$$constant; 3175 if (val >= 0) { 3176 __ subs(zr, reg, val); 3177 } else if (val != -val) { 3178 __ adds(zr, reg, -val); 3179 } else { 3180 // aargh, Long.MIN_VALUE is a special case 3181 __ orr(rscratch1, zr, (uint64_t)val); 3182 __ subs(zr, reg, rscratch1); 3183 } 3184 %} 3185 3186 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3187 MacroAssembler _masm(&cbuf); 3188 Register reg1 = as_Register($src1$$reg); 3189 uint64_t val = (uint64_t)$src2$$constant; 3190 __ mov(rscratch1, val); 3191 __ cmp(reg1, rscratch1); 3192 %} 3193 3194 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3195 MacroAssembler _masm(&cbuf); 3196 Register reg1 = as_Register($src1$$reg); 3197 Register reg2 = as_Register($src2$$reg); 3198 __ cmp(reg1, reg2); 3199 %} 3200 3201 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3202 MacroAssembler _masm(&cbuf); 3203 Register reg1 = as_Register($src1$$reg); 3204 Register reg2 = as_Register($src2$$reg); 3205 __ cmpw(reg1, reg2); 3206 %} 3207 3208 enc_class aarch64_enc_testp(iRegP src) %{ 3209 MacroAssembler _masm(&cbuf); 3210 Register reg = as_Register($src$$reg); 3211 __ cmp(reg, zr); 3212 %} 3213 3214 enc_class aarch64_enc_testn(iRegN src) %{ 3215 MacroAssembler _masm(&cbuf); 3216 Register reg = as_Register($src$$reg); 3217 __ cmpw(reg, zr); 3218 %} 3219 3220 enc_class aarch64_enc_b(label lbl) %{ 3221 MacroAssembler _masm(&cbuf); 3222 Label *L = $lbl$$label; 3223 __ b(*L); 3224 %} 3225 3226 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3227 MacroAssembler _masm(&cbuf); 3228 Label *L = $lbl$$label; 3229 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3230 %} 3231 3232 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3233 MacroAssembler _masm(&cbuf); 3234 Label *L = $lbl$$label; 3235 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3236 %} 3237 3238 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3239 %{ 3240 Register sub_reg = as_Register($sub$$reg); 3241 Register super_reg = as_Register($super$$reg); 3242 Register temp_reg = as_Register($temp$$reg); 3243 Register result_reg = as_Register($result$$reg); 3244 3245 Label miss; 3246 MacroAssembler _masm(&cbuf); 3247 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3248 NULL, &miss, 3249 /*set_cond_codes:*/ true); 3250 if ($primary) { 3251 __ mov(result_reg, zr); 3252 } 3253 __ bind(miss); 3254 %} 3255 3256 enc_class aarch64_enc_java_static_call(method meth) %{ 3257 MacroAssembler _masm(&cbuf); 3258 3259 address addr = (address)$meth$$method; 3260 address call; 3261 if (!_method) { 3262 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3263 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3264 if (call == NULL) { 3265 ciEnv::current()->record_failure("CodeCache is full"); 3266 return; 3267 } 3268 } else { 3269 int method_index = resolved_method_index(cbuf); 3270 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3271 : static_call_Relocation::spec(method_index); 3272 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3273 if (call == NULL) { 3274 ciEnv::current()->record_failure("CodeCache is full"); 3275 return; 3276 } 3277 // Emit stub for static call 3278 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3279 if (stub == NULL) { 3280 ciEnv::current()->record_failure("CodeCache is full"); 3281 return; 3282 } 3283 } 3284 %} 3285 3286 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3287 MacroAssembler _masm(&cbuf); 3288 int method_index = resolved_method_index(cbuf); 3289 address call = __ ic_call((address)$meth$$method, method_index); 3290 if (call == NULL) { 3291 ciEnv::current()->record_failure("CodeCache is full"); 3292 return; 3293 } 3294 %} 3295 3296 enc_class aarch64_enc_call_epilog() %{ 3297 MacroAssembler _masm(&cbuf); 3298 if (VerifyStackAtCalls) { 3299 // Check that stack depth is unchanged: find majik cookie on stack 3300 __ call_Unimplemented(); 3301 } 3302 %} 3303 3304 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3305 MacroAssembler _masm(&cbuf); 3306 3307 // some calls to generated routines (arraycopy code) are scheduled 3308 // by C2 as runtime calls. if so we can call them using a br (they 3309 // will be in a reachable segment) otherwise we have to use a blr 3310 // which loads the absolute address into a register. 3311 address entry = (address)$meth$$method; 3312 CodeBlob *cb = CodeCache::find_blob(entry); 3313 if (cb) { 3314 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3315 if (call == NULL) { 3316 ciEnv::current()->record_failure("CodeCache is full"); 3317 return; 3318 } 3319 } else { 3320 Label retaddr; 3321 __ adr(rscratch2, retaddr); 3322 __ lea(rscratch1, RuntimeAddress(entry)); 3323 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3324 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3325 __ blr(rscratch1); 3326 __ bind(retaddr); 3327 __ add(sp, sp, 2 * wordSize); 3328 } 3329 %} 3330 3331 enc_class aarch64_enc_rethrow() %{ 3332 MacroAssembler _masm(&cbuf); 3333 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3334 %} 3335 3336 enc_class aarch64_enc_ret() %{ 3337 MacroAssembler _masm(&cbuf); 3338 __ ret(lr); 3339 %} 3340 3341 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3342 MacroAssembler _masm(&cbuf); 3343 Register target_reg = as_Register($jump_target$$reg); 3344 __ br(target_reg); 3345 %} 3346 3347 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3348 MacroAssembler _masm(&cbuf); 3349 Register target_reg = as_Register($jump_target$$reg); 3350 // exception oop should be in r0 3351 // ret addr has been popped into lr 3352 // callee expects it in r3 3353 __ mov(r3, lr); 3354 __ br(target_reg); 3355 %} 3356 3357 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3358 MacroAssembler _masm(&cbuf); 3359 Register oop = as_Register($object$$reg); 3360 Register box = as_Register($box$$reg); 3361 Register disp_hdr = as_Register($tmp$$reg); 3362 Register tmp = as_Register($tmp2$$reg); 3363 Label cont; 3364 Label object_has_monitor; 3365 Label cas_failed; 3366 3367 assert_different_registers(oop, box, tmp, disp_hdr); 3368 3369 // Load markOop from object into displaced_header. 3370 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3371 3372 // Always do locking in runtime. 3373 if (EmitSync & 0x01) { 3374 __ cmp(oop, zr); 3375 return; 3376 } 3377 3378 if (UseBiasedLocking && !UseOptoBiasInlining) { 3379 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3380 } 3381 3382 // Check for existing monitor 3383 if ((EmitSync & 0x02) == 0) { 3384 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3385 } 3386 3387 // Set tmp to be (markOop of object | UNLOCK_VALUE). 3388 __ orr(tmp, disp_hdr, markOopDesc::unlocked_value); 3389 3390 // Initialize the box. (Must happen before we update the object mark!) 3391 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3392 3393 // Compare object markOop with an unlocked value (tmp) and if 3394 // equal exchange the stack address of our box with object markOop. 3395 // On failure disp_hdr contains the possibly locked markOop. 3396 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3397 /*release*/ true, /*weak*/ false, disp_hdr); 3398 __ br(Assembler::EQ, cont); 3399 3400 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3401 3402 // If the compare-and-exchange succeeded, then we found an unlocked 3403 // object, will have now locked it will continue at label cont 3404 3405 __ bind(cas_failed); 3406 // We did not see an unlocked object so try the fast recursive case. 3407 3408 // Check if the owner is self by comparing the value in the 3409 // markOop of object (disp_hdr) with the stack pointer. 3410 __ mov(rscratch1, sp); 3411 __ sub(disp_hdr, disp_hdr, rscratch1); 3412 __ mov(tmp, (address) (~(os::vm_page_size()-1) | (uintptr_t)markOopDesc::lock_mask_in_place)); 3413 // If condition is true we are cont and hence we can store 0 as the 3414 // displaced header in the box, which indicates that it is a recursive lock. 3415 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3416 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3417 3418 if ((EmitSync & 0x02) == 0) { 3419 __ b(cont); 3420 3421 // Handle existing monitor. 3422 __ bind(object_has_monitor); 3423 // The object's monitor m is unlocked iff m->owner == NULL, 3424 // otherwise m->owner may contain a thread or a stack address. 3425 // 3426 // Try to CAS m->owner from NULL to current thread. 3427 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3428 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3429 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3430 3431 // Store a non-null value into the box to avoid looking like a re-entrant 3432 // lock. The fast-path monitor unlock code checks for 3433 // markOopDesc::monitor_value so use markOopDesc::unused_mark which has the 3434 // relevant bit set, and also matches ObjectSynchronizer::slow_enter. 3435 __ mov(tmp, (address)markOopDesc::unused_mark()); 3436 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3437 } 3438 3439 __ bind(cont); 3440 // flag == EQ indicates success 3441 // flag == NE indicates failure 3442 %} 3443 3444 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3445 MacroAssembler _masm(&cbuf); 3446 Register oop = as_Register($object$$reg); 3447 Register box = as_Register($box$$reg); 3448 Register disp_hdr = as_Register($tmp$$reg); 3449 Register tmp = as_Register($tmp2$$reg); 3450 Label cont; 3451 Label object_has_monitor; 3452 3453 assert_different_registers(oop, box, tmp, disp_hdr); 3454 3455 // Always do locking in runtime. 3456 if (EmitSync & 0x01) { 3457 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3458 return; 3459 } 3460 3461 if (UseBiasedLocking && !UseOptoBiasInlining) { 3462 __ biased_locking_exit(oop, tmp, cont); 3463 } 3464 3465 // Find the lock address and load the displaced header from the stack. 3466 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3467 3468 // If the displaced header is 0, we have a recursive unlock. 3469 __ cmp(disp_hdr, zr); 3470 __ br(Assembler::EQ, cont); 3471 3472 // Handle existing monitor. 3473 if ((EmitSync & 0x02) == 0) { 3474 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3475 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3476 } 3477 3478 // Check if it is still a light weight lock, this is is true if we 3479 // see the stack address of the basicLock in the markOop of the 3480 // object. 3481 3482 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3483 /*release*/ true, /*weak*/ false, tmp); 3484 __ b(cont); 3485 3486 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3487 3488 // Handle existing monitor. 3489 if ((EmitSync & 0x02) == 0) { 3490 __ bind(object_has_monitor); 3491 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3492 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3493 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3494 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3495 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3496 __ cmp(rscratch1, zr); // Sets flags for result 3497 __ br(Assembler::NE, cont); 3498 3499 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3500 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3501 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3502 __ cmp(rscratch1, zr); // Sets flags for result 3503 __ cbnz(rscratch1, cont); 3504 // need a release store here 3505 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3506 __ stlr(zr, tmp); // set unowned 3507 } 3508 3509 __ bind(cont); 3510 // flag == EQ indicates success 3511 // flag == NE indicates failure 3512 %} 3513 3514%} 3515 3516//----------FRAME-------------------------------------------------------------- 3517// Definition of frame structure and management information. 3518// 3519// S T A C K L A Y O U T Allocators stack-slot number 3520// | (to get allocators register number 3521// G Owned by | | v add OptoReg::stack0()) 3522// r CALLER | | 3523// o | +--------+ pad to even-align allocators stack-slot 3524// w V | pad0 | numbers; owned by CALLER 3525// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3526// h ^ | in | 5 3527// | | args | 4 Holes in incoming args owned by SELF 3528// | | | | 3 3529// | | +--------+ 3530// V | | old out| Empty on Intel, window on Sparc 3531// | old |preserve| Must be even aligned. 3532// | SP-+--------+----> Matcher::_old_SP, even aligned 3533// | | in | 3 area for Intel ret address 3534// Owned by |preserve| Empty on Sparc. 3535// SELF +--------+ 3536// | | pad2 | 2 pad to align old SP 3537// | +--------+ 1 3538// | | locks | 0 3539// | +--------+----> OptoReg::stack0(), even aligned 3540// | | pad1 | 11 pad to align new SP 3541// | +--------+ 3542// | | | 10 3543// | | spills | 9 spills 3544// V | | 8 (pad0 slot for callee) 3545// -----------+--------+----> Matcher::_out_arg_limit, unaligned 3546// ^ | out | 7 3547// | | args | 6 Holes in outgoing args owned by CALLEE 3548// Owned by +--------+ 3549// CALLEE | new out| 6 Empty on Intel, window on Sparc 3550// | new |preserve| Must be even-aligned. 3551// | SP-+--------+----> Matcher::_new_SP, even aligned 3552// | | | 3553// 3554// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3555// known from SELF's arguments and the Java calling convention. 3556// Region 6-7 is determined per call site. 3557// Note 2: If the calling convention leaves holes in the incoming argument 3558// area, those holes are owned by SELF. Holes in the outgoing area 3559// are owned by the CALLEE. Holes should not be nessecary in the 3560// incoming area, as the Java calling convention is completely under 3561// the control of the AD file. Doubles can be sorted and packed to 3562// avoid holes. Holes in the outgoing arguments may be nessecary for 3563// varargs C calling conventions. 3564// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3565// even aligned with pad0 as needed. 3566// Region 6 is even aligned. Region 6-7 is NOT even aligned; 3567// (the latter is true on Intel but is it false on AArch64?) 3568// region 6-11 is even aligned; it may be padded out more so that 3569// the region from SP to FP meets the minimum stack alignment. 3570// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3571// alignment. Region 11, pad1, may be dynamically extended so that 3572// SP meets the minimum alignment. 3573 3574frame %{ 3575 // What direction does stack grow in (assumed to be same for C & Java) 3576 stack_direction(TOWARDS_LOW); 3577 3578 // These three registers define part of the calling convention 3579 // between compiled code and the interpreter. 3580 3581 // Inline Cache Register or methodOop for I2C. 3582 inline_cache_reg(R12); 3583 3584 // Method Oop Register when calling interpreter. 3585 interpreter_method_oop_reg(R12); 3586 3587 // Number of stack slots consumed by locking an object 3588 sync_stack_slots(2); 3589 3590 // Compiled code's Frame Pointer 3591 frame_pointer(R31); 3592 3593 // Interpreter stores its frame pointer in a register which is 3594 // stored to the stack by I2CAdaptors. 3595 // I2CAdaptors convert from interpreted java to compiled java. 3596 interpreter_frame_pointer(R29); 3597 3598 // Stack alignment requirement 3599 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3600 3601 // Number of stack slots between incoming argument block and the start of 3602 // a new frame. The PROLOG must add this many slots to the stack. The 3603 // EPILOG must remove this many slots. aarch64 needs two slots for 3604 // return address and fp. 3605 // TODO think this is correct but check 3606 in_preserve_stack_slots(4); 3607 3608 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3609 // for calls to C. Supports the var-args backing area for register parms. 3610 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3611 3612 // The after-PROLOG location of the return address. Location of 3613 // return address specifies a type (REG or STACK) and a number 3614 // representing the register number (i.e. - use a register name) or 3615 // stack slot. 3616 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3617 // Otherwise, it is above the locks and verification slot and alignment word 3618 // TODO this may well be correct but need to check why that - 2 is there 3619 // ppc port uses 0 but we definitely need to allow for fixed_slots 3620 // which folds in the space used for monitors 3621 return_addr(STACK - 2 + 3622 align_up((Compile::current()->in_preserve_stack_slots() + 3623 Compile::current()->fixed_slots()), 3624 stack_alignment_in_slots())); 3625 3626 // Body of function which returns an integer array locating 3627 // arguments either in registers or in stack slots. Passed an array 3628 // of ideal registers called "sig" and a "length" count. Stack-slot 3629 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3630 // arguments for a CALLEE. Incoming stack arguments are 3631 // automatically biased by the preserve_stack_slots field above. 3632 3633 calling_convention 3634 %{ 3635 // No difference between ingoing/outgoing just pass false 3636 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3637 %} 3638 3639 c_calling_convention 3640 %{ 3641 // This is obviously always outgoing 3642 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3643 %} 3644 3645 // Location of compiled Java return values. Same as C for now. 3646 return_value 3647 %{ 3648 // TODO do we allow ideal_reg == Op_RegN??? 3649 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3650 "only return normal values"); 3651 3652 static const int lo[Op_RegL + 1] = { // enum name 3653 0, // Op_Node 3654 0, // Op_Set 3655 R0_num, // Op_RegN 3656 R0_num, // Op_RegI 3657 R0_num, // Op_RegP 3658 V0_num, // Op_RegF 3659 V0_num, // Op_RegD 3660 R0_num // Op_RegL 3661 }; 3662 3663 static const int hi[Op_RegL + 1] = { // enum name 3664 0, // Op_Node 3665 0, // Op_Set 3666 OptoReg::Bad, // Op_RegN 3667 OptoReg::Bad, // Op_RegI 3668 R0_H_num, // Op_RegP 3669 OptoReg::Bad, // Op_RegF 3670 V0_H_num, // Op_RegD 3671 R0_H_num // Op_RegL 3672 }; 3673 3674 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3675 %} 3676%} 3677 3678//----------ATTRIBUTES--------------------------------------------------------- 3679//----------Operand Attributes------------------------------------------------- 3680op_attrib op_cost(1); // Required cost attribute 3681 3682//----------Instruction Attributes--------------------------------------------- 3683ins_attrib ins_cost(INSN_COST); // Required cost attribute 3684ins_attrib ins_size(32); // Required size attribute (in bits) 3685ins_attrib ins_short_branch(0); // Required flag: is this instruction 3686 // a non-matching short branch variant 3687 // of some long branch? 3688ins_attrib ins_alignment(4); // Required alignment attribute (must 3689 // be a power of 2) specifies the 3690 // alignment that some part of the 3691 // instruction (not necessarily the 3692 // start) requires. If > 1, a 3693 // compute_padding() function must be 3694 // provided for the instruction 3695 3696//----------OPERANDS----------------------------------------------------------- 3697// Operand definitions must precede instruction definitions for correct parsing 3698// in the ADLC because operands constitute user defined types which are used in 3699// instruction definitions. 3700 3701//----------Simple Operands---------------------------------------------------- 3702 3703// Integer operands 32 bit 3704// 32 bit immediate 3705operand immI() 3706%{ 3707 match(ConI); 3708 3709 op_cost(0); 3710 format %{ %} 3711 interface(CONST_INTER); 3712%} 3713 3714// 32 bit zero 3715operand immI0() 3716%{ 3717 predicate(n->get_int() == 0); 3718 match(ConI); 3719 3720 op_cost(0); 3721 format %{ %} 3722 interface(CONST_INTER); 3723%} 3724 3725// 32 bit unit increment 3726operand immI_1() 3727%{ 3728 predicate(n->get_int() == 1); 3729 match(ConI); 3730 3731 op_cost(0); 3732 format %{ %} 3733 interface(CONST_INTER); 3734%} 3735 3736// 32 bit unit decrement 3737operand immI_M1() 3738%{ 3739 predicate(n->get_int() == -1); 3740 match(ConI); 3741 3742 op_cost(0); 3743 format %{ %} 3744 interface(CONST_INTER); 3745%} 3746 3747// Shift values for add/sub extension shift 3748operand immIExt() 3749%{ 3750 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 3751 match(ConI); 3752 3753 op_cost(0); 3754 format %{ %} 3755 interface(CONST_INTER); 3756%} 3757 3758operand immI_le_4() 3759%{ 3760 predicate(n->get_int() <= 4); 3761 match(ConI); 3762 3763 op_cost(0); 3764 format %{ %} 3765 interface(CONST_INTER); 3766%} 3767 3768operand immI_31() 3769%{ 3770 predicate(n->get_int() == 31); 3771 match(ConI); 3772 3773 op_cost(0); 3774 format %{ %} 3775 interface(CONST_INTER); 3776%} 3777 3778operand immI_8() 3779%{ 3780 predicate(n->get_int() == 8); 3781 match(ConI); 3782 3783 op_cost(0); 3784 format %{ %} 3785 interface(CONST_INTER); 3786%} 3787 3788operand immI_16() 3789%{ 3790 predicate(n->get_int() == 16); 3791 match(ConI); 3792 3793 op_cost(0); 3794 format %{ %} 3795 interface(CONST_INTER); 3796%} 3797 3798operand immI_24() 3799%{ 3800 predicate(n->get_int() == 24); 3801 match(ConI); 3802 3803 op_cost(0); 3804 format %{ %} 3805 interface(CONST_INTER); 3806%} 3807 3808operand immI_32() 3809%{ 3810 predicate(n->get_int() == 32); 3811 match(ConI); 3812 3813 op_cost(0); 3814 format %{ %} 3815 interface(CONST_INTER); 3816%} 3817 3818operand immI_48() 3819%{ 3820 predicate(n->get_int() == 48); 3821 match(ConI); 3822 3823 op_cost(0); 3824 format %{ %} 3825 interface(CONST_INTER); 3826%} 3827 3828operand immI_56() 3829%{ 3830 predicate(n->get_int() == 56); 3831 match(ConI); 3832 3833 op_cost(0); 3834 format %{ %} 3835 interface(CONST_INTER); 3836%} 3837 3838operand immI_63() 3839%{ 3840 predicate(n->get_int() == 63); 3841 match(ConI); 3842 3843 op_cost(0); 3844 format %{ %} 3845 interface(CONST_INTER); 3846%} 3847 3848operand immI_64() 3849%{ 3850 predicate(n->get_int() == 64); 3851 match(ConI); 3852 3853 op_cost(0); 3854 format %{ %} 3855 interface(CONST_INTER); 3856%} 3857 3858operand immI_255() 3859%{ 3860 predicate(n->get_int() == 255); 3861 match(ConI); 3862 3863 op_cost(0); 3864 format %{ %} 3865 interface(CONST_INTER); 3866%} 3867 3868operand immI_65535() 3869%{ 3870 predicate(n->get_int() == 65535); 3871 match(ConI); 3872 3873 op_cost(0); 3874 format %{ %} 3875 interface(CONST_INTER); 3876%} 3877 3878operand immL_255() 3879%{ 3880 predicate(n->get_long() == 255L); 3881 match(ConL); 3882 3883 op_cost(0); 3884 format %{ %} 3885 interface(CONST_INTER); 3886%} 3887 3888operand immL_65535() 3889%{ 3890 predicate(n->get_long() == 65535L); 3891 match(ConL); 3892 3893 op_cost(0); 3894 format %{ %} 3895 interface(CONST_INTER); 3896%} 3897 3898operand immL_4294967295() 3899%{ 3900 predicate(n->get_long() == 4294967295L); 3901 match(ConL); 3902 3903 op_cost(0); 3904 format %{ %} 3905 interface(CONST_INTER); 3906%} 3907 3908operand immL_bitmask() 3909%{ 3910 predicate((n->get_long() != 0) 3911 && ((n->get_long() & 0xc000000000000000l) == 0) 3912 && is_power_of_2(n->get_long() + 1)); 3913 match(ConL); 3914 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918%} 3919 3920operand immI_bitmask() 3921%{ 3922 predicate((n->get_int() != 0) 3923 && ((n->get_int() & 0xc0000000) == 0) 3924 && is_power_of_2(n->get_int() + 1)); 3925 match(ConI); 3926 3927 op_cost(0); 3928 format %{ %} 3929 interface(CONST_INTER); 3930%} 3931 3932operand immL_positive_bitmaskI() 3933%{ 3934 predicate((n->get_long() != 0) 3935 && ((julong)n->get_long() < 0x80000000ULL) 3936 && is_power_of_2(n->get_long() + 1)); 3937 match(ConL); 3938 3939 op_cost(0); 3940 format %{ %} 3941 interface(CONST_INTER); 3942%} 3943 3944// Scale values for scaled offset addressing modes (up to long but not quad) 3945operand immIScale() 3946%{ 3947 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3948 match(ConI); 3949 3950 op_cost(0); 3951 format %{ %} 3952 interface(CONST_INTER); 3953%} 3954 3955// 26 bit signed offset -- for pc-relative branches 3956operand immI26() 3957%{ 3958 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 3959 match(ConI); 3960 3961 op_cost(0); 3962 format %{ %} 3963 interface(CONST_INTER); 3964%} 3965 3966// 19 bit signed offset -- for pc-relative loads 3967operand immI19() 3968%{ 3969 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 3970 match(ConI); 3971 3972 op_cost(0); 3973 format %{ %} 3974 interface(CONST_INTER); 3975%} 3976 3977// 12 bit unsigned offset -- for base plus immediate loads 3978operand immIU12() 3979%{ 3980 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 3981 match(ConI); 3982 3983 op_cost(0); 3984 format %{ %} 3985 interface(CONST_INTER); 3986%} 3987 3988operand immLU12() 3989%{ 3990 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 3991 match(ConL); 3992 3993 op_cost(0); 3994 format %{ %} 3995 interface(CONST_INTER); 3996%} 3997 3998// Offset for scaled or unscaled immediate loads and stores 3999operand immIOffset() 4000%{ 4001 predicate(Address::offset_ok_for_immed(n->get_int())); 4002 match(ConI); 4003 4004 op_cost(0); 4005 format %{ %} 4006 interface(CONST_INTER); 4007%} 4008 4009operand immIOffset4() 4010%{ 4011 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4012 match(ConI); 4013 4014 op_cost(0); 4015 format %{ %} 4016 interface(CONST_INTER); 4017%} 4018 4019operand immIOffset8() 4020%{ 4021 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4022 match(ConI); 4023 4024 op_cost(0); 4025 format %{ %} 4026 interface(CONST_INTER); 4027%} 4028 4029operand immIOffset16() 4030%{ 4031 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4032 match(ConI); 4033 4034 op_cost(0); 4035 format %{ %} 4036 interface(CONST_INTER); 4037%} 4038 4039operand immLoffset() 4040%{ 4041 predicate(Address::offset_ok_for_immed(n->get_long())); 4042 match(ConL); 4043 4044 op_cost(0); 4045 format %{ %} 4046 interface(CONST_INTER); 4047%} 4048 4049operand immLoffset4() 4050%{ 4051 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4052 match(ConL); 4053 4054 op_cost(0); 4055 format %{ %} 4056 interface(CONST_INTER); 4057%} 4058 4059operand immLoffset8() 4060%{ 4061 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4062 match(ConL); 4063 4064 op_cost(0); 4065 format %{ %} 4066 interface(CONST_INTER); 4067%} 4068 4069operand immLoffset16() 4070%{ 4071 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4072 match(ConL); 4073 4074 op_cost(0); 4075 format %{ %} 4076 interface(CONST_INTER); 4077%} 4078 4079// 32 bit integer valid for add sub immediate 4080operand immIAddSub() 4081%{ 4082 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4083 match(ConI); 4084 op_cost(0); 4085 format %{ %} 4086 interface(CONST_INTER); 4087%} 4088 4089// 32 bit unsigned integer valid for logical immediate 4090// TODO -- check this is right when e.g the mask is 0x80000000 4091operand immILog() 4092%{ 4093 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4094 match(ConI); 4095 4096 op_cost(0); 4097 format %{ %} 4098 interface(CONST_INTER); 4099%} 4100 4101// Integer operands 64 bit 4102// 64 bit immediate 4103operand immL() 4104%{ 4105 match(ConL); 4106 4107 op_cost(0); 4108 format %{ %} 4109 interface(CONST_INTER); 4110%} 4111 4112// 64 bit zero 4113operand immL0() 4114%{ 4115 predicate(n->get_long() == 0); 4116 match(ConL); 4117 4118 op_cost(0); 4119 format %{ %} 4120 interface(CONST_INTER); 4121%} 4122 4123// 64 bit unit increment 4124operand immL_1() 4125%{ 4126 predicate(n->get_long() == 1); 4127 match(ConL); 4128 4129 op_cost(0); 4130 format %{ %} 4131 interface(CONST_INTER); 4132%} 4133 4134// 64 bit unit decrement 4135operand immL_M1() 4136%{ 4137 predicate(n->get_long() == -1); 4138 match(ConL); 4139 4140 op_cost(0); 4141 format %{ %} 4142 interface(CONST_INTER); 4143%} 4144 4145// 32 bit offset of pc in thread anchor 4146 4147operand immL_pc_off() 4148%{ 4149 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4150 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4151 match(ConL); 4152 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156%} 4157 4158// 64 bit integer valid for add sub immediate 4159operand immLAddSub() 4160%{ 4161 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4162 match(ConL); 4163 op_cost(0); 4164 format %{ %} 4165 interface(CONST_INTER); 4166%} 4167 4168// 64 bit integer valid for logical immediate 4169operand immLLog() 4170%{ 4171 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4172 match(ConL); 4173 op_cost(0); 4174 format %{ %} 4175 interface(CONST_INTER); 4176%} 4177 4178// Long Immediate: low 32-bit mask 4179operand immL_32bits() 4180%{ 4181 predicate(n->get_long() == 0xFFFFFFFFL); 4182 match(ConL); 4183 op_cost(0); 4184 format %{ %} 4185 interface(CONST_INTER); 4186%} 4187 4188// Pointer operands 4189// Pointer Immediate 4190operand immP() 4191%{ 4192 match(ConP); 4193 4194 op_cost(0); 4195 format %{ %} 4196 interface(CONST_INTER); 4197%} 4198 4199// NULL Pointer Immediate 4200operand immP0() 4201%{ 4202 predicate(n->get_ptr() == 0); 4203 match(ConP); 4204 4205 op_cost(0); 4206 format %{ %} 4207 interface(CONST_INTER); 4208%} 4209 4210// Pointer Immediate One 4211// this is used in object initialization (initial object header) 4212operand immP_1() 4213%{ 4214 predicate(n->get_ptr() == 1); 4215 match(ConP); 4216 4217 op_cost(0); 4218 format %{ %} 4219 interface(CONST_INTER); 4220%} 4221 4222// Polling Page Pointer Immediate 4223operand immPollPage() 4224%{ 4225 predicate((address)n->get_ptr() == os::get_polling_page()); 4226 match(ConP); 4227 4228 op_cost(0); 4229 format %{ %} 4230 interface(CONST_INTER); 4231%} 4232 4233// Card Table Byte Map Base 4234operand immByteMapBase() 4235%{ 4236 // Get base of card map 4237 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4238 (jbyte*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4239 match(ConP); 4240 4241 op_cost(0); 4242 format %{ %} 4243 interface(CONST_INTER); 4244%} 4245 4246// Pointer Immediate Minus One 4247// this is used when we want to write the current PC to the thread anchor 4248operand immP_M1() 4249%{ 4250 predicate(n->get_ptr() == -1); 4251 match(ConP); 4252 4253 op_cost(0); 4254 format %{ %} 4255 interface(CONST_INTER); 4256%} 4257 4258// Pointer Immediate Minus Two 4259// this is used when we want to write the current PC to the thread anchor 4260operand immP_M2() 4261%{ 4262 predicate(n->get_ptr() == -2); 4263 match(ConP); 4264 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268%} 4269 4270// Float and Double operands 4271// Double Immediate 4272operand immD() 4273%{ 4274 match(ConD); 4275 op_cost(0); 4276 format %{ %} 4277 interface(CONST_INTER); 4278%} 4279 4280// Double Immediate: +0.0d 4281operand immD0() 4282%{ 4283 predicate(jlong_cast(n->getd()) == 0); 4284 match(ConD); 4285 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289%} 4290 4291// constant 'double +0.0'. 4292operand immDPacked() 4293%{ 4294 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4295 match(ConD); 4296 op_cost(0); 4297 format %{ %} 4298 interface(CONST_INTER); 4299%} 4300 4301// Float Immediate 4302operand immF() 4303%{ 4304 match(ConF); 4305 op_cost(0); 4306 format %{ %} 4307 interface(CONST_INTER); 4308%} 4309 4310// Float Immediate: +0.0f. 4311operand immF0() 4312%{ 4313 predicate(jint_cast(n->getf()) == 0); 4314 match(ConF); 4315 4316 op_cost(0); 4317 format %{ %} 4318 interface(CONST_INTER); 4319%} 4320 4321// 4322operand immFPacked() 4323%{ 4324 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4325 match(ConF); 4326 op_cost(0); 4327 format %{ %} 4328 interface(CONST_INTER); 4329%} 4330 4331// Narrow pointer operands 4332// Narrow Pointer Immediate 4333operand immN() 4334%{ 4335 match(ConN); 4336 4337 op_cost(0); 4338 format %{ %} 4339 interface(CONST_INTER); 4340%} 4341 4342// Narrow NULL Pointer Immediate 4343operand immN0() 4344%{ 4345 predicate(n->get_narrowcon() == 0); 4346 match(ConN); 4347 4348 op_cost(0); 4349 format %{ %} 4350 interface(CONST_INTER); 4351%} 4352 4353operand immNKlass() 4354%{ 4355 match(ConNKlass); 4356 4357 op_cost(0); 4358 format %{ %} 4359 interface(CONST_INTER); 4360%} 4361 4362// Integer 32 bit Register Operands 4363// Integer 32 bitRegister (excludes SP) 4364operand iRegI() 4365%{ 4366 constraint(ALLOC_IN_RC(any_reg32)); 4367 match(RegI); 4368 match(iRegINoSp); 4369 op_cost(0); 4370 format %{ %} 4371 interface(REG_INTER); 4372%} 4373 4374// Integer 32 bit Register not Special 4375operand iRegINoSp() 4376%{ 4377 constraint(ALLOC_IN_RC(no_special_reg32)); 4378 match(RegI); 4379 op_cost(0); 4380 format %{ %} 4381 interface(REG_INTER); 4382%} 4383 4384// Integer 64 bit Register Operands 4385// Integer 64 bit Register (includes SP) 4386operand iRegL() 4387%{ 4388 constraint(ALLOC_IN_RC(any_reg)); 4389 match(RegL); 4390 match(iRegLNoSp); 4391 op_cost(0); 4392 format %{ %} 4393 interface(REG_INTER); 4394%} 4395 4396// Integer 64 bit Register not Special 4397operand iRegLNoSp() 4398%{ 4399 constraint(ALLOC_IN_RC(no_special_reg)); 4400 match(RegL); 4401 match(iRegL_R0); 4402 format %{ %} 4403 interface(REG_INTER); 4404%} 4405 4406// Pointer Register Operands 4407// Pointer Register 4408operand iRegP() 4409%{ 4410 constraint(ALLOC_IN_RC(ptr_reg)); 4411 match(RegP); 4412 match(iRegPNoSp); 4413 match(iRegP_R0); 4414 //match(iRegP_R2); 4415 //match(iRegP_R4); 4416 //match(iRegP_R5); 4417 match(thread_RegP); 4418 op_cost(0); 4419 format %{ %} 4420 interface(REG_INTER); 4421%} 4422 4423// Pointer 64 bit Register not Special 4424operand iRegPNoSp() 4425%{ 4426 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4427 match(RegP); 4428 // match(iRegP); 4429 // match(iRegP_R0); 4430 // match(iRegP_R2); 4431 // match(iRegP_R4); 4432 // match(iRegP_R5); 4433 // match(thread_RegP); 4434 op_cost(0); 4435 format %{ %} 4436 interface(REG_INTER); 4437%} 4438 4439// Pointer 64 bit Register R0 only 4440operand iRegP_R0() 4441%{ 4442 constraint(ALLOC_IN_RC(r0_reg)); 4443 match(RegP); 4444 // match(iRegP); 4445 match(iRegPNoSp); 4446 op_cost(0); 4447 format %{ %} 4448 interface(REG_INTER); 4449%} 4450 4451// Pointer 64 bit Register R1 only 4452operand iRegP_R1() 4453%{ 4454 constraint(ALLOC_IN_RC(r1_reg)); 4455 match(RegP); 4456 // match(iRegP); 4457 match(iRegPNoSp); 4458 op_cost(0); 4459 format %{ %} 4460 interface(REG_INTER); 4461%} 4462 4463// Pointer 64 bit Register R2 only 4464operand iRegP_R2() 4465%{ 4466 constraint(ALLOC_IN_RC(r2_reg)); 4467 match(RegP); 4468 // match(iRegP); 4469 match(iRegPNoSp); 4470 op_cost(0); 4471 format %{ %} 4472 interface(REG_INTER); 4473%} 4474 4475// Pointer 64 bit Register R3 only 4476operand iRegP_R3() 4477%{ 4478 constraint(ALLOC_IN_RC(r3_reg)); 4479 match(RegP); 4480 // match(iRegP); 4481 match(iRegPNoSp); 4482 op_cost(0); 4483 format %{ %} 4484 interface(REG_INTER); 4485%} 4486 4487// Pointer 64 bit Register R4 only 4488operand iRegP_R4() 4489%{ 4490 constraint(ALLOC_IN_RC(r4_reg)); 4491 match(RegP); 4492 // match(iRegP); 4493 match(iRegPNoSp); 4494 op_cost(0); 4495 format %{ %} 4496 interface(REG_INTER); 4497%} 4498 4499// Pointer 64 bit Register R5 only 4500operand iRegP_R5() 4501%{ 4502 constraint(ALLOC_IN_RC(r5_reg)); 4503 match(RegP); 4504 // match(iRegP); 4505 match(iRegPNoSp); 4506 op_cost(0); 4507 format %{ %} 4508 interface(REG_INTER); 4509%} 4510 4511// Pointer 64 bit Register R10 only 4512operand iRegP_R10() 4513%{ 4514 constraint(ALLOC_IN_RC(r10_reg)); 4515 match(RegP); 4516 // match(iRegP); 4517 match(iRegPNoSp); 4518 op_cost(0); 4519 format %{ %} 4520 interface(REG_INTER); 4521%} 4522 4523// Long 64 bit Register R0 only 4524operand iRegL_R0() 4525%{ 4526 constraint(ALLOC_IN_RC(r0_reg)); 4527 match(RegL); 4528 match(iRegLNoSp); 4529 op_cost(0); 4530 format %{ %} 4531 interface(REG_INTER); 4532%} 4533 4534// Long 64 bit Register R2 only 4535operand iRegL_R2() 4536%{ 4537 constraint(ALLOC_IN_RC(r2_reg)); 4538 match(RegL); 4539 match(iRegLNoSp); 4540 op_cost(0); 4541 format %{ %} 4542 interface(REG_INTER); 4543%} 4544 4545// Long 64 bit Register R3 only 4546operand iRegL_R3() 4547%{ 4548 constraint(ALLOC_IN_RC(r3_reg)); 4549 match(RegL); 4550 match(iRegLNoSp); 4551 op_cost(0); 4552 format %{ %} 4553 interface(REG_INTER); 4554%} 4555 4556// Long 64 bit Register R11 only 4557operand iRegL_R11() 4558%{ 4559 constraint(ALLOC_IN_RC(r11_reg)); 4560 match(RegL); 4561 match(iRegLNoSp); 4562 op_cost(0); 4563 format %{ %} 4564 interface(REG_INTER); 4565%} 4566 4567// Pointer 64 bit Register FP only 4568operand iRegP_FP() 4569%{ 4570 constraint(ALLOC_IN_RC(fp_reg)); 4571 match(RegP); 4572 // match(iRegP); 4573 op_cost(0); 4574 format %{ %} 4575 interface(REG_INTER); 4576%} 4577 4578// Register R0 only 4579operand iRegI_R0() 4580%{ 4581 constraint(ALLOC_IN_RC(int_r0_reg)); 4582 match(RegI); 4583 match(iRegINoSp); 4584 op_cost(0); 4585 format %{ %} 4586 interface(REG_INTER); 4587%} 4588 4589// Register R2 only 4590operand iRegI_R2() 4591%{ 4592 constraint(ALLOC_IN_RC(int_r2_reg)); 4593 match(RegI); 4594 match(iRegINoSp); 4595 op_cost(0); 4596 format %{ %} 4597 interface(REG_INTER); 4598%} 4599 4600// Register R3 only 4601operand iRegI_R3() 4602%{ 4603 constraint(ALLOC_IN_RC(int_r3_reg)); 4604 match(RegI); 4605 match(iRegINoSp); 4606 op_cost(0); 4607 format %{ %} 4608 interface(REG_INTER); 4609%} 4610 4611 4612// Register R4 only 4613operand iRegI_R4() 4614%{ 4615 constraint(ALLOC_IN_RC(int_r4_reg)); 4616 match(RegI); 4617 match(iRegINoSp); 4618 op_cost(0); 4619 format %{ %} 4620 interface(REG_INTER); 4621%} 4622 4623 4624// Pointer Register Operands 4625// Narrow Pointer Register 4626operand iRegN() 4627%{ 4628 constraint(ALLOC_IN_RC(any_reg32)); 4629 match(RegN); 4630 match(iRegNNoSp); 4631 op_cost(0); 4632 format %{ %} 4633 interface(REG_INTER); 4634%} 4635 4636operand iRegN_R0() 4637%{ 4638 constraint(ALLOC_IN_RC(r0_reg)); 4639 match(iRegN); 4640 op_cost(0); 4641 format %{ %} 4642 interface(REG_INTER); 4643%} 4644 4645operand iRegN_R2() 4646%{ 4647 constraint(ALLOC_IN_RC(r2_reg)); 4648 match(iRegN); 4649 op_cost(0); 4650 format %{ %} 4651 interface(REG_INTER); 4652%} 4653 4654operand iRegN_R3() 4655%{ 4656 constraint(ALLOC_IN_RC(r3_reg)); 4657 match(iRegN); 4658 op_cost(0); 4659 format %{ %} 4660 interface(REG_INTER); 4661%} 4662 4663// Integer 64 bit Register not Special 4664operand iRegNNoSp() 4665%{ 4666 constraint(ALLOC_IN_RC(no_special_reg32)); 4667 match(RegN); 4668 op_cost(0); 4669 format %{ %} 4670 interface(REG_INTER); 4671%} 4672 4673// heap base register -- used for encoding immN0 4674 4675operand iRegIHeapbase() 4676%{ 4677 constraint(ALLOC_IN_RC(heapbase_reg)); 4678 match(RegI); 4679 op_cost(0); 4680 format %{ %} 4681 interface(REG_INTER); 4682%} 4683 4684// Float Register 4685// Float register operands 4686operand vRegF() 4687%{ 4688 constraint(ALLOC_IN_RC(float_reg)); 4689 match(RegF); 4690 4691 op_cost(0); 4692 format %{ %} 4693 interface(REG_INTER); 4694%} 4695 4696// Double Register 4697// Double register operands 4698operand vRegD() 4699%{ 4700 constraint(ALLOC_IN_RC(double_reg)); 4701 match(RegD); 4702 4703 op_cost(0); 4704 format %{ %} 4705 interface(REG_INTER); 4706%} 4707 4708operand vecD() 4709%{ 4710 constraint(ALLOC_IN_RC(vectord_reg)); 4711 match(VecD); 4712 4713 op_cost(0); 4714 format %{ %} 4715 interface(REG_INTER); 4716%} 4717 4718operand vecX() 4719%{ 4720 constraint(ALLOC_IN_RC(vectorx_reg)); 4721 match(VecX); 4722 4723 op_cost(0); 4724 format %{ %} 4725 interface(REG_INTER); 4726%} 4727 4728operand vRegD_V0() 4729%{ 4730 constraint(ALLOC_IN_RC(v0_reg)); 4731 match(RegD); 4732 op_cost(0); 4733 format %{ %} 4734 interface(REG_INTER); 4735%} 4736 4737operand vRegD_V1() 4738%{ 4739 constraint(ALLOC_IN_RC(v1_reg)); 4740 match(RegD); 4741 op_cost(0); 4742 format %{ %} 4743 interface(REG_INTER); 4744%} 4745 4746operand vRegD_V2() 4747%{ 4748 constraint(ALLOC_IN_RC(v2_reg)); 4749 match(RegD); 4750 op_cost(0); 4751 format %{ %} 4752 interface(REG_INTER); 4753%} 4754 4755operand vRegD_V3() 4756%{ 4757 constraint(ALLOC_IN_RC(v3_reg)); 4758 match(RegD); 4759 op_cost(0); 4760 format %{ %} 4761 interface(REG_INTER); 4762%} 4763 4764// Flags register, used as output of signed compare instructions 4765 4766// note that on AArch64 we also use this register as the output for 4767// for floating point compare instructions (CmpF CmpD). this ensures 4768// that ordered inequality tests use GT, GE, LT or LE none of which 4769// pass through cases where the result is unordered i.e. one or both 4770// inputs to the compare is a NaN. this means that the ideal code can 4771// replace e.g. a GT with an LE and not end up capturing the NaN case 4772// (where the comparison should always fail). EQ and NE tests are 4773// always generated in ideal code so that unordered folds into the NE 4774// case, matching the behaviour of AArch64 NE. 4775// 4776// This differs from x86 where the outputs of FP compares use a 4777// special FP flags registers and where compares based on this 4778// register are distinguished into ordered inequalities (cmpOpUCF) and 4779// EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4780// to explicitly handle the unordered case in branches. x86 also has 4781// to include extra CMoveX rules to accept a cmpOpUCF input. 4782 4783operand rFlagsReg() 4784%{ 4785 constraint(ALLOC_IN_RC(int_flags)); 4786 match(RegFlags); 4787 4788 op_cost(0); 4789 format %{ "RFLAGS" %} 4790 interface(REG_INTER); 4791%} 4792 4793// Flags register, used as output of unsigned compare instructions 4794operand rFlagsRegU() 4795%{ 4796 constraint(ALLOC_IN_RC(int_flags)); 4797 match(RegFlags); 4798 4799 op_cost(0); 4800 format %{ "RFLAGSU" %} 4801 interface(REG_INTER); 4802%} 4803 4804// Special Registers 4805 4806// Method Register 4807operand inline_cache_RegP(iRegP reg) 4808%{ 4809 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4810 match(reg); 4811 match(iRegPNoSp); 4812 op_cost(0); 4813 format %{ %} 4814 interface(REG_INTER); 4815%} 4816 4817operand interpreter_method_oop_RegP(iRegP reg) 4818%{ 4819 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4820 match(reg); 4821 match(iRegPNoSp); 4822 op_cost(0); 4823 format %{ %} 4824 interface(REG_INTER); 4825%} 4826 4827// Thread Register 4828operand thread_RegP(iRegP reg) 4829%{ 4830 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4831 match(reg); 4832 op_cost(0); 4833 format %{ %} 4834 interface(REG_INTER); 4835%} 4836 4837operand lr_RegP(iRegP reg) 4838%{ 4839 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4840 match(reg); 4841 op_cost(0); 4842 format %{ %} 4843 interface(REG_INTER); 4844%} 4845 4846//----------Memory Operands---------------------------------------------------- 4847 4848operand indirect(iRegP reg) 4849%{ 4850 constraint(ALLOC_IN_RC(ptr_reg)); 4851 match(reg); 4852 op_cost(0); 4853 format %{ "[$reg]" %} 4854 interface(MEMORY_INTER) %{ 4855 base($reg); 4856 index(0xffffffff); 4857 scale(0x0); 4858 disp(0x0); 4859 %} 4860%} 4861 4862operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4863%{ 4864 constraint(ALLOC_IN_RC(ptr_reg)); 4865 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4866 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4867 op_cost(0); 4868 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4869 interface(MEMORY_INTER) %{ 4870 base($reg); 4871 index($ireg); 4872 scale($scale); 4873 disp(0x0); 4874 %} 4875%} 4876 4877operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4878%{ 4879 constraint(ALLOC_IN_RC(ptr_reg)); 4880 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 4881 match(AddP reg (LShiftL lreg scale)); 4882 op_cost(0); 4883 format %{ "$reg, $lreg lsl($scale)" %} 4884 interface(MEMORY_INTER) %{ 4885 base($reg); 4886 index($lreg); 4887 scale($scale); 4888 disp(0x0); 4889 %} 4890%} 4891 4892operand indIndexI2L(iRegP reg, iRegI ireg) 4893%{ 4894 constraint(ALLOC_IN_RC(ptr_reg)); 4895 match(AddP reg (ConvI2L ireg)); 4896 op_cost(0); 4897 format %{ "$reg, $ireg, 0, I2L" %} 4898 interface(MEMORY_INTER) %{ 4899 base($reg); 4900 index($ireg); 4901 scale(0x0); 4902 disp(0x0); 4903 %} 4904%} 4905 4906operand indIndex(iRegP reg, iRegL lreg) 4907%{ 4908 constraint(ALLOC_IN_RC(ptr_reg)); 4909 match(AddP reg lreg); 4910 op_cost(0); 4911 format %{ "$reg, $lreg" %} 4912 interface(MEMORY_INTER) %{ 4913 base($reg); 4914 index($lreg); 4915 scale(0x0); 4916 disp(0x0); 4917 %} 4918%} 4919 4920operand indOffI(iRegP reg, immIOffset off) 4921%{ 4922 constraint(ALLOC_IN_RC(ptr_reg)); 4923 match(AddP reg off); 4924 op_cost(0); 4925 format %{ "[$reg, $off]" %} 4926 interface(MEMORY_INTER) %{ 4927 base($reg); 4928 index(0xffffffff); 4929 scale(0x0); 4930 disp($off); 4931 %} 4932%} 4933 4934operand indOffI4(iRegP reg, immIOffset4 off) 4935%{ 4936 constraint(ALLOC_IN_RC(ptr_reg)); 4937 match(AddP reg off); 4938 op_cost(0); 4939 format %{ "[$reg, $off]" %} 4940 interface(MEMORY_INTER) %{ 4941 base($reg); 4942 index(0xffffffff); 4943 scale(0x0); 4944 disp($off); 4945 %} 4946%} 4947 4948operand indOffI8(iRegP reg, immIOffset8 off) 4949%{ 4950 constraint(ALLOC_IN_RC(ptr_reg)); 4951 match(AddP reg off); 4952 op_cost(0); 4953 format %{ "[$reg, $off]" %} 4954 interface(MEMORY_INTER) %{ 4955 base($reg); 4956 index(0xffffffff); 4957 scale(0x0); 4958 disp($off); 4959 %} 4960%} 4961 4962operand indOffI16(iRegP reg, immIOffset16 off) 4963%{ 4964 constraint(ALLOC_IN_RC(ptr_reg)); 4965 match(AddP reg off); 4966 op_cost(0); 4967 format %{ "[$reg, $off]" %} 4968 interface(MEMORY_INTER) %{ 4969 base($reg); 4970 index(0xffffffff); 4971 scale(0x0); 4972 disp($off); 4973 %} 4974%} 4975 4976operand indOffL(iRegP reg, immLoffset off) 4977%{ 4978 constraint(ALLOC_IN_RC(ptr_reg)); 4979 match(AddP reg off); 4980 op_cost(0); 4981 format %{ "[$reg, $off]" %} 4982 interface(MEMORY_INTER) %{ 4983 base($reg); 4984 index(0xffffffff); 4985 scale(0x0); 4986 disp($off); 4987 %} 4988%} 4989 4990operand indOffL4(iRegP reg, immLoffset4 off) 4991%{ 4992 constraint(ALLOC_IN_RC(ptr_reg)); 4993 match(AddP reg off); 4994 op_cost(0); 4995 format %{ "[$reg, $off]" %} 4996 interface(MEMORY_INTER) %{ 4997 base($reg); 4998 index(0xffffffff); 4999 scale(0x0); 5000 disp($off); 5001 %} 5002%} 5003 5004operand indOffL8(iRegP reg, immLoffset8 off) 5005%{ 5006 constraint(ALLOC_IN_RC(ptr_reg)); 5007 match(AddP reg off); 5008 op_cost(0); 5009 format %{ "[$reg, $off]" %} 5010 interface(MEMORY_INTER) %{ 5011 base($reg); 5012 index(0xffffffff); 5013 scale(0x0); 5014 disp($off); 5015 %} 5016%} 5017 5018operand indOffL16(iRegP reg, immLoffset16 off) 5019%{ 5020 constraint(ALLOC_IN_RC(ptr_reg)); 5021 match(AddP reg off); 5022 op_cost(0); 5023 format %{ "[$reg, $off]" %} 5024 interface(MEMORY_INTER) %{ 5025 base($reg); 5026 index(0xffffffff); 5027 scale(0x0); 5028 disp($off); 5029 %} 5030%} 5031 5032operand indirectN(iRegN reg) 5033%{ 5034 predicate(Universe::narrow_oop_shift() == 0); 5035 constraint(ALLOC_IN_RC(ptr_reg)); 5036 match(DecodeN reg); 5037 op_cost(0); 5038 format %{ "[$reg]\t# narrow" %} 5039 interface(MEMORY_INTER) %{ 5040 base($reg); 5041 index(0xffffffff); 5042 scale(0x0); 5043 disp(0x0); 5044 %} 5045%} 5046 5047operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5048%{ 5049 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5050 constraint(ALLOC_IN_RC(ptr_reg)); 5051 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5052 op_cost(0); 5053 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5054 interface(MEMORY_INTER) %{ 5055 base($reg); 5056 index($ireg); 5057 scale($scale); 5058 disp(0x0); 5059 %} 5060%} 5061 5062operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5063%{ 5064 predicate(Universe::narrow_oop_shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5065 constraint(ALLOC_IN_RC(ptr_reg)); 5066 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5067 op_cost(0); 5068 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5069 interface(MEMORY_INTER) %{ 5070 base($reg); 5071 index($lreg); 5072 scale($scale); 5073 disp(0x0); 5074 %} 5075%} 5076 5077operand indIndexI2LN(iRegN reg, iRegI ireg) 5078%{ 5079 predicate(Universe::narrow_oop_shift() == 0); 5080 constraint(ALLOC_IN_RC(ptr_reg)); 5081 match(AddP (DecodeN reg) (ConvI2L ireg)); 5082 op_cost(0); 5083 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5084 interface(MEMORY_INTER) %{ 5085 base($reg); 5086 index($ireg); 5087 scale(0x0); 5088 disp(0x0); 5089 %} 5090%} 5091 5092operand indIndexN(iRegN reg, iRegL lreg) 5093%{ 5094 predicate(Universe::narrow_oop_shift() == 0); 5095 constraint(ALLOC_IN_RC(ptr_reg)); 5096 match(AddP (DecodeN reg) lreg); 5097 op_cost(0); 5098 format %{ "$reg, $lreg\t# narrow" %} 5099 interface(MEMORY_INTER) %{ 5100 base($reg); 5101 index($lreg); 5102 scale(0x0); 5103 disp(0x0); 5104 %} 5105%} 5106 5107operand indOffIN(iRegN reg, immIOffset off) 5108%{ 5109 predicate(Universe::narrow_oop_shift() == 0); 5110 constraint(ALLOC_IN_RC(ptr_reg)); 5111 match(AddP (DecodeN reg) off); 5112 op_cost(0); 5113 format %{ "[$reg, $off]\t# narrow" %} 5114 interface(MEMORY_INTER) %{ 5115 base($reg); 5116 index(0xffffffff); 5117 scale(0x0); 5118 disp($off); 5119 %} 5120%} 5121 5122operand indOffLN(iRegN reg, immLoffset off) 5123%{ 5124 predicate(Universe::narrow_oop_shift() == 0); 5125 constraint(ALLOC_IN_RC(ptr_reg)); 5126 match(AddP (DecodeN reg) off); 5127 op_cost(0); 5128 format %{ "[$reg, $off]\t# narrow" %} 5129 interface(MEMORY_INTER) %{ 5130 base($reg); 5131 index(0xffffffff); 5132 scale(0x0); 5133 disp($off); 5134 %} 5135%} 5136 5137 5138 5139// AArch64 opto stubs need to write to the pc slot in the thread anchor 5140operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5141%{ 5142 constraint(ALLOC_IN_RC(ptr_reg)); 5143 match(AddP reg off); 5144 op_cost(0); 5145 format %{ "[$reg, $off]" %} 5146 interface(MEMORY_INTER) %{ 5147 base($reg); 5148 index(0xffffffff); 5149 scale(0x0); 5150 disp($off); 5151 %} 5152%} 5153 5154//----------Special Memory Operands-------------------------------------------- 5155// Stack Slot Operand - This operand is used for loading and storing temporary 5156// values on the stack where a match requires a value to 5157// flow through memory. 5158operand stackSlotP(sRegP reg) 5159%{ 5160 constraint(ALLOC_IN_RC(stack_slots)); 5161 op_cost(100); 5162 // No match rule because this operand is only generated in matching 5163 // match(RegP); 5164 format %{ "[$reg]" %} 5165 interface(MEMORY_INTER) %{ 5166 base(0x1e); // RSP 5167 index(0x0); // No Index 5168 scale(0x0); // No Scale 5169 disp($reg); // Stack Offset 5170 %} 5171%} 5172 5173operand stackSlotI(sRegI reg) 5174%{ 5175 constraint(ALLOC_IN_RC(stack_slots)); 5176 // No match rule because this operand is only generated in matching 5177 // match(RegI); 5178 format %{ "[$reg]" %} 5179 interface(MEMORY_INTER) %{ 5180 base(0x1e); // RSP 5181 index(0x0); // No Index 5182 scale(0x0); // No Scale 5183 disp($reg); // Stack Offset 5184 %} 5185%} 5186 5187operand stackSlotF(sRegF reg) 5188%{ 5189 constraint(ALLOC_IN_RC(stack_slots)); 5190 // No match rule because this operand is only generated in matching 5191 // match(RegF); 5192 format %{ "[$reg]" %} 5193 interface(MEMORY_INTER) %{ 5194 base(0x1e); // RSP 5195 index(0x0); // No Index 5196 scale(0x0); // No Scale 5197 disp($reg); // Stack Offset 5198 %} 5199%} 5200 5201operand stackSlotD(sRegD reg) 5202%{ 5203 constraint(ALLOC_IN_RC(stack_slots)); 5204 // No match rule because this operand is only generated in matching 5205 // match(RegD); 5206 format %{ "[$reg]" %} 5207 interface(MEMORY_INTER) %{ 5208 base(0x1e); // RSP 5209 index(0x0); // No Index 5210 scale(0x0); // No Scale 5211 disp($reg); // Stack Offset 5212 %} 5213%} 5214 5215operand stackSlotL(sRegL reg) 5216%{ 5217 constraint(ALLOC_IN_RC(stack_slots)); 5218 // No match rule because this operand is only generated in matching 5219 // match(RegL); 5220 format %{ "[$reg]" %} 5221 interface(MEMORY_INTER) %{ 5222 base(0x1e); // RSP 5223 index(0x0); // No Index 5224 scale(0x0); // No Scale 5225 disp($reg); // Stack Offset 5226 %} 5227%} 5228 5229// Operands for expressing Control Flow 5230// NOTE: Label is a predefined operand which should not be redefined in 5231// the AD file. It is generically handled within the ADLC. 5232 5233//----------Conditional Branch Operands---------------------------------------- 5234// Comparison Op - This is the operation of the comparison, and is limited to 5235// the following set of codes: 5236// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5237// 5238// Other attributes of the comparison, such as unsignedness, are specified 5239// by the comparison instruction that sets a condition code flags register. 5240// That result is represented by a flags operand whose subtype is appropriate 5241// to the unsignedness (etc.) of the comparison. 5242// 5243// Later, the instruction which matches both the Comparison Op (a Bool) and 5244// the flags (produced by the Cmp) specifies the coding of the comparison op 5245// by matching a specific subtype of Bool operand below, such as cmpOpU. 5246 5247// used for signed integral comparisons and fp comparisons 5248 5249operand cmpOp() 5250%{ 5251 match(Bool); 5252 5253 format %{ "" %} 5254 interface(COND_INTER) %{ 5255 equal(0x0, "eq"); 5256 not_equal(0x1, "ne"); 5257 less(0xb, "lt"); 5258 greater_equal(0xa, "ge"); 5259 less_equal(0xd, "le"); 5260 greater(0xc, "gt"); 5261 overflow(0x6, "vs"); 5262 no_overflow(0x7, "vc"); 5263 %} 5264%} 5265 5266// used for unsigned integral comparisons 5267 5268operand cmpOpU() 5269%{ 5270 match(Bool); 5271 5272 format %{ "" %} 5273 interface(COND_INTER) %{ 5274 equal(0x0, "eq"); 5275 not_equal(0x1, "ne"); 5276 less(0x3, "lo"); 5277 greater_equal(0x2, "hs"); 5278 less_equal(0x9, "ls"); 5279 greater(0x8, "hi"); 5280 overflow(0x6, "vs"); 5281 no_overflow(0x7, "vc"); 5282 %} 5283%} 5284 5285// used for certain integral comparisons which can be 5286// converted to cbxx or tbxx instructions 5287 5288operand cmpOpEqNe() 5289%{ 5290 match(Bool); 5291 match(CmpOp); 5292 op_cost(0); 5293 predicate(n->as_Bool()->_test._test == BoolTest::ne 5294 || n->as_Bool()->_test._test == BoolTest::eq); 5295 5296 format %{ "" %} 5297 interface(COND_INTER) %{ 5298 equal(0x0, "eq"); 5299 not_equal(0x1, "ne"); 5300 less(0xb, "lt"); 5301 greater_equal(0xa, "ge"); 5302 less_equal(0xd, "le"); 5303 greater(0xc, "gt"); 5304 overflow(0x6, "vs"); 5305 no_overflow(0x7, "vc"); 5306 %} 5307%} 5308 5309// used for certain integral comparisons which can be 5310// converted to cbxx or tbxx instructions 5311 5312operand cmpOpLtGe() 5313%{ 5314 match(Bool); 5315 match(CmpOp); 5316 op_cost(0); 5317 5318 predicate(n->as_Bool()->_test._test == BoolTest::lt 5319 || n->as_Bool()->_test._test == BoolTest::ge); 5320 5321 format %{ "" %} 5322 interface(COND_INTER) %{ 5323 equal(0x0, "eq"); 5324 not_equal(0x1, "ne"); 5325 less(0xb, "lt"); 5326 greater_equal(0xa, "ge"); 5327 less_equal(0xd, "le"); 5328 greater(0xc, "gt"); 5329 overflow(0x6, "vs"); 5330 no_overflow(0x7, "vc"); 5331 %} 5332%} 5333 5334// used for certain unsigned integral comparisons which can be 5335// converted to cbxx or tbxx instructions 5336 5337operand cmpOpUEqNeLtGe() 5338%{ 5339 match(Bool); 5340 match(CmpOp); 5341 op_cost(0); 5342 5343 predicate(n->as_Bool()->_test._test == BoolTest::eq 5344 || n->as_Bool()->_test._test == BoolTest::ne 5345 || n->as_Bool()->_test._test == BoolTest::lt 5346 || n->as_Bool()->_test._test == BoolTest::ge); 5347 5348 format %{ "" %} 5349 interface(COND_INTER) %{ 5350 equal(0x0, "eq"); 5351 not_equal(0x1, "ne"); 5352 less(0xb, "lt"); 5353 greater_equal(0xa, "ge"); 5354 less_equal(0xd, "le"); 5355 greater(0xc, "gt"); 5356 overflow(0x6, "vs"); 5357 no_overflow(0x7, "vc"); 5358 %} 5359%} 5360 5361// Special operand allowing long args to int ops to be truncated for free 5362 5363operand iRegL2I(iRegL reg) %{ 5364 5365 op_cost(0); 5366 5367 match(ConvL2I reg); 5368 5369 format %{ "l2i($reg)" %} 5370 5371 interface(REG_INTER) 5372%} 5373 5374opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 5375opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 5376opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 5377 5378//----------OPERAND CLASSES---------------------------------------------------- 5379// Operand Classes are groups of operands that are used as to simplify 5380// instruction definitions by not requiring the AD writer to specify 5381// separate instructions for every form of operand when the 5382// instruction accepts multiple operand types with the same basic 5383// encoding and format. The classic case of this is memory operands. 5384 5385// memory is used to define read/write location for load/store 5386// instruction defs. we can turn a memory op into an Address 5387 5388opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI, indOffL, 5389 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 5390 5391// iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5392// operations. it allows the src to be either an iRegI or a (ConvL2I 5393// iRegL). in the latter case the l2i normally planted for a ConvL2I 5394// can be elided because the 32-bit instruction will just employ the 5395// lower 32 bits anyway. 5396// 5397// n.b. this does not elide all L2I conversions. if the truncated 5398// value is consumed by more than one operation then the ConvL2I 5399// cannot be bundled into the consuming nodes so an l2i gets planted 5400// (actually a movw $dst $src) and the downstream instructions consume 5401// the result of the l2i as an iRegI input. That's a shame since the 5402// movw is actually redundant but its not too costly. 5403 5404opclass iRegIorL2I(iRegI, iRegL2I); 5405 5406//----------PIPELINE----------------------------------------------------------- 5407// Rules which define the behavior of the target architectures pipeline. 5408 5409// For specific pipelines, eg A53, define the stages of that pipeline 5410//pipe_desc(ISS, EX1, EX2, WR); 5411#define ISS S0 5412#define EX1 S1 5413#define EX2 S2 5414#define WR S3 5415 5416// Integer ALU reg operation 5417pipeline %{ 5418 5419attributes %{ 5420 // ARM instructions are of fixed length 5421 fixed_size_instructions; // Fixed size instructions TODO does 5422 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5423 // ARM instructions come in 32-bit word units 5424 instruction_unit_size = 4; // An instruction is 4 bytes long 5425 instruction_fetch_unit_size = 64; // The processor fetches one line 5426 instruction_fetch_units = 1; // of 64 bytes 5427 5428 // List of nop instructions 5429 nops( MachNop ); 5430%} 5431 5432// We don't use an actual pipeline model so don't care about resources 5433// or description. we do use pipeline classes to introduce fixed 5434// latencies 5435 5436//----------RESOURCES---------------------------------------------------------- 5437// Resources are the functional units available to the machine 5438 5439resources( INS0, INS1, INS01 = INS0 | INS1, 5440 ALU0, ALU1, ALU = ALU0 | ALU1, 5441 MAC, 5442 DIV, 5443 BRANCH, 5444 LDST, 5445 NEON_FP); 5446 5447//----------PIPELINE DESCRIPTION----------------------------------------------- 5448// Pipeline Description specifies the stages in the machine's pipeline 5449 5450// Define the pipeline as a generic 6 stage pipeline 5451pipe_desc(S0, S1, S2, S3, S4, S5); 5452 5453//----------PIPELINE CLASSES--------------------------------------------------- 5454// Pipeline Classes describe the stages in which input and output are 5455// referenced by the hardware pipeline. 5456 5457pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 5458%{ 5459 single_instruction; 5460 src1 : S1(read); 5461 src2 : S2(read); 5462 dst : S5(write); 5463 INS01 : ISS; 5464 NEON_FP : S5; 5465%} 5466 5467pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 5468%{ 5469 single_instruction; 5470 src1 : S1(read); 5471 src2 : S2(read); 5472 dst : S5(write); 5473 INS01 : ISS; 5474 NEON_FP : S5; 5475%} 5476 5477pipe_class fp_uop_s(vRegF dst, vRegF src) 5478%{ 5479 single_instruction; 5480 src : S1(read); 5481 dst : S5(write); 5482 INS01 : ISS; 5483 NEON_FP : S5; 5484%} 5485 5486pipe_class fp_uop_d(vRegD dst, vRegD src) 5487%{ 5488 single_instruction; 5489 src : S1(read); 5490 dst : S5(write); 5491 INS01 : ISS; 5492 NEON_FP : S5; 5493%} 5494 5495pipe_class fp_d2f(vRegF dst, vRegD src) 5496%{ 5497 single_instruction; 5498 src : S1(read); 5499 dst : S5(write); 5500 INS01 : ISS; 5501 NEON_FP : S5; 5502%} 5503 5504pipe_class fp_f2d(vRegD dst, vRegF src) 5505%{ 5506 single_instruction; 5507 src : S1(read); 5508 dst : S5(write); 5509 INS01 : ISS; 5510 NEON_FP : S5; 5511%} 5512 5513pipe_class fp_f2i(iRegINoSp dst, vRegF src) 5514%{ 5515 single_instruction; 5516 src : S1(read); 5517 dst : S5(write); 5518 INS01 : ISS; 5519 NEON_FP : S5; 5520%} 5521 5522pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 5523%{ 5524 single_instruction; 5525 src : S1(read); 5526 dst : S5(write); 5527 INS01 : ISS; 5528 NEON_FP : S5; 5529%} 5530 5531pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 5532%{ 5533 single_instruction; 5534 src : S1(read); 5535 dst : S5(write); 5536 INS01 : ISS; 5537 NEON_FP : S5; 5538%} 5539 5540pipe_class fp_l2f(vRegF dst, iRegL src) 5541%{ 5542 single_instruction; 5543 src : S1(read); 5544 dst : S5(write); 5545 INS01 : ISS; 5546 NEON_FP : S5; 5547%} 5548 5549pipe_class fp_d2i(iRegINoSp dst, vRegD src) 5550%{ 5551 single_instruction; 5552 src : S1(read); 5553 dst : S5(write); 5554 INS01 : ISS; 5555 NEON_FP : S5; 5556%} 5557 5558pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 5559%{ 5560 single_instruction; 5561 src : S1(read); 5562 dst : S5(write); 5563 INS01 : ISS; 5564 NEON_FP : S5; 5565%} 5566 5567pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 5568%{ 5569 single_instruction; 5570 src : S1(read); 5571 dst : S5(write); 5572 INS01 : ISS; 5573 NEON_FP : S5; 5574%} 5575 5576pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 5577%{ 5578 single_instruction; 5579 src : S1(read); 5580 dst : S5(write); 5581 INS01 : ISS; 5582 NEON_FP : S5; 5583%} 5584 5585pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 5586%{ 5587 single_instruction; 5588 src1 : S1(read); 5589 src2 : S2(read); 5590 dst : S5(write); 5591 INS0 : ISS; 5592 NEON_FP : S5; 5593%} 5594 5595pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 5596%{ 5597 single_instruction; 5598 src1 : S1(read); 5599 src2 : S2(read); 5600 dst : S5(write); 5601 INS0 : ISS; 5602 NEON_FP : S5; 5603%} 5604 5605pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 5606%{ 5607 single_instruction; 5608 cr : S1(read); 5609 src1 : S1(read); 5610 src2 : S1(read); 5611 dst : S3(write); 5612 INS01 : ISS; 5613 NEON_FP : S3; 5614%} 5615 5616pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 5617%{ 5618 single_instruction; 5619 cr : S1(read); 5620 src1 : S1(read); 5621 src2 : S1(read); 5622 dst : S3(write); 5623 INS01 : ISS; 5624 NEON_FP : S3; 5625%} 5626 5627pipe_class fp_imm_s(vRegF dst) 5628%{ 5629 single_instruction; 5630 dst : S3(write); 5631 INS01 : ISS; 5632 NEON_FP : S3; 5633%} 5634 5635pipe_class fp_imm_d(vRegD dst) 5636%{ 5637 single_instruction; 5638 dst : S3(write); 5639 INS01 : ISS; 5640 NEON_FP : S3; 5641%} 5642 5643pipe_class fp_load_constant_s(vRegF dst) 5644%{ 5645 single_instruction; 5646 dst : S4(write); 5647 INS01 : ISS; 5648 NEON_FP : S4; 5649%} 5650 5651pipe_class fp_load_constant_d(vRegD dst) 5652%{ 5653 single_instruction; 5654 dst : S4(write); 5655 INS01 : ISS; 5656 NEON_FP : S4; 5657%} 5658 5659pipe_class vmul64(vecD dst, vecD src1, vecD src2) 5660%{ 5661 single_instruction; 5662 dst : S5(write); 5663 src1 : S1(read); 5664 src2 : S1(read); 5665 INS01 : ISS; 5666 NEON_FP : S5; 5667%} 5668 5669pipe_class vmul128(vecX dst, vecX src1, vecX src2) 5670%{ 5671 single_instruction; 5672 dst : S5(write); 5673 src1 : S1(read); 5674 src2 : S1(read); 5675 INS0 : ISS; 5676 NEON_FP : S5; 5677%} 5678 5679pipe_class vmla64(vecD dst, vecD src1, vecD src2) 5680%{ 5681 single_instruction; 5682 dst : S5(write); 5683 src1 : S1(read); 5684 src2 : S1(read); 5685 dst : S1(read); 5686 INS01 : ISS; 5687 NEON_FP : S5; 5688%} 5689 5690pipe_class vmla128(vecX dst, vecX src1, vecX src2) 5691%{ 5692 single_instruction; 5693 dst : S5(write); 5694 src1 : S1(read); 5695 src2 : S1(read); 5696 dst : S1(read); 5697 INS0 : ISS; 5698 NEON_FP : S5; 5699%} 5700 5701pipe_class vdop64(vecD dst, vecD src1, vecD src2) 5702%{ 5703 single_instruction; 5704 dst : S4(write); 5705 src1 : S2(read); 5706 src2 : S2(read); 5707 INS01 : ISS; 5708 NEON_FP : S4; 5709%} 5710 5711pipe_class vdop128(vecX dst, vecX src1, vecX src2) 5712%{ 5713 single_instruction; 5714 dst : S4(write); 5715 src1 : S2(read); 5716 src2 : S2(read); 5717 INS0 : ISS; 5718 NEON_FP : S4; 5719%} 5720 5721pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 5722%{ 5723 single_instruction; 5724 dst : S3(write); 5725 src1 : S2(read); 5726 src2 : S2(read); 5727 INS01 : ISS; 5728 NEON_FP : S3; 5729%} 5730 5731pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 5732%{ 5733 single_instruction; 5734 dst : S3(write); 5735 src1 : S2(read); 5736 src2 : S2(read); 5737 INS0 : ISS; 5738 NEON_FP : S3; 5739%} 5740 5741pipe_class vshift64(vecD dst, vecD src, vecX shift) 5742%{ 5743 single_instruction; 5744 dst : S3(write); 5745 src : S1(read); 5746 shift : S1(read); 5747 INS01 : ISS; 5748 NEON_FP : S3; 5749%} 5750 5751pipe_class vshift128(vecX dst, vecX src, vecX shift) 5752%{ 5753 single_instruction; 5754 dst : S3(write); 5755 src : S1(read); 5756 shift : S1(read); 5757 INS0 : ISS; 5758 NEON_FP : S3; 5759%} 5760 5761pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 5762%{ 5763 single_instruction; 5764 dst : S3(write); 5765 src : S1(read); 5766 INS01 : ISS; 5767 NEON_FP : S3; 5768%} 5769 5770pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 5771%{ 5772 single_instruction; 5773 dst : S3(write); 5774 src : S1(read); 5775 INS0 : ISS; 5776 NEON_FP : S3; 5777%} 5778 5779pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 5780%{ 5781 single_instruction; 5782 dst : S5(write); 5783 src1 : S1(read); 5784 src2 : S1(read); 5785 INS01 : ISS; 5786 NEON_FP : S5; 5787%} 5788 5789pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 5790%{ 5791 single_instruction; 5792 dst : S5(write); 5793 src1 : S1(read); 5794 src2 : S1(read); 5795 INS0 : ISS; 5796 NEON_FP : S5; 5797%} 5798 5799pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 5800%{ 5801 single_instruction; 5802 dst : S5(write); 5803 src1 : S1(read); 5804 src2 : S1(read); 5805 INS0 : ISS; 5806 NEON_FP : S5; 5807%} 5808 5809pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 5810%{ 5811 single_instruction; 5812 dst : S5(write); 5813 src1 : S1(read); 5814 src2 : S1(read); 5815 INS0 : ISS; 5816 NEON_FP : S5; 5817%} 5818 5819pipe_class vsqrt_fp128(vecX dst, vecX src) 5820%{ 5821 single_instruction; 5822 dst : S5(write); 5823 src : S1(read); 5824 INS0 : ISS; 5825 NEON_FP : S5; 5826%} 5827 5828pipe_class vunop_fp64(vecD dst, vecD src) 5829%{ 5830 single_instruction; 5831 dst : S5(write); 5832 src : S1(read); 5833 INS01 : ISS; 5834 NEON_FP : S5; 5835%} 5836 5837pipe_class vunop_fp128(vecX dst, vecX src) 5838%{ 5839 single_instruction; 5840 dst : S5(write); 5841 src : S1(read); 5842 INS0 : ISS; 5843 NEON_FP : S5; 5844%} 5845 5846pipe_class vdup_reg_reg64(vecD dst, iRegI src) 5847%{ 5848 single_instruction; 5849 dst : S3(write); 5850 src : S1(read); 5851 INS01 : ISS; 5852 NEON_FP : S3; 5853%} 5854 5855pipe_class vdup_reg_reg128(vecX dst, iRegI src) 5856%{ 5857 single_instruction; 5858 dst : S3(write); 5859 src : S1(read); 5860 INS01 : ISS; 5861 NEON_FP : S3; 5862%} 5863 5864pipe_class vdup_reg_freg64(vecD dst, vRegF src) 5865%{ 5866 single_instruction; 5867 dst : S3(write); 5868 src : S1(read); 5869 INS01 : ISS; 5870 NEON_FP : S3; 5871%} 5872 5873pipe_class vdup_reg_freg128(vecX dst, vRegF src) 5874%{ 5875 single_instruction; 5876 dst : S3(write); 5877 src : S1(read); 5878 INS01 : ISS; 5879 NEON_FP : S3; 5880%} 5881 5882pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 5883%{ 5884 single_instruction; 5885 dst : S3(write); 5886 src : S1(read); 5887 INS01 : ISS; 5888 NEON_FP : S3; 5889%} 5890 5891pipe_class vmovi_reg_imm64(vecD dst) 5892%{ 5893 single_instruction; 5894 dst : S3(write); 5895 INS01 : ISS; 5896 NEON_FP : S3; 5897%} 5898 5899pipe_class vmovi_reg_imm128(vecX dst) 5900%{ 5901 single_instruction; 5902 dst : S3(write); 5903 INS0 : ISS; 5904 NEON_FP : S3; 5905%} 5906 5907pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 5908%{ 5909 single_instruction; 5910 dst : S5(write); 5911 mem : ISS(read); 5912 INS01 : ISS; 5913 NEON_FP : S3; 5914%} 5915 5916pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 5917%{ 5918 single_instruction; 5919 dst : S5(write); 5920 mem : ISS(read); 5921 INS01 : ISS; 5922 NEON_FP : S3; 5923%} 5924 5925pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 5926%{ 5927 single_instruction; 5928 mem : ISS(read); 5929 src : S2(read); 5930 INS01 : ISS; 5931 NEON_FP : S3; 5932%} 5933 5934pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 5935%{ 5936 single_instruction; 5937 mem : ISS(read); 5938 src : S2(read); 5939 INS01 : ISS; 5940 NEON_FP : S3; 5941%} 5942 5943//------- Integer ALU operations -------------------------- 5944 5945// Integer ALU reg-reg operation 5946// Operands needed in EX1, result generated in EX2 5947// Eg. ADD x0, x1, x2 5948pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5949%{ 5950 single_instruction; 5951 dst : EX2(write); 5952 src1 : EX1(read); 5953 src2 : EX1(read); 5954 INS01 : ISS; // Dual issue as instruction 0 or 1 5955 ALU : EX2; 5956%} 5957 5958// Integer ALU reg-reg operation with constant shift 5959// Shifted register must be available in LATE_ISS instead of EX1 5960// Eg. ADD x0, x1, x2, LSL #2 5961pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5962%{ 5963 single_instruction; 5964 dst : EX2(write); 5965 src1 : EX1(read); 5966 src2 : ISS(read); 5967 INS01 : ISS; 5968 ALU : EX2; 5969%} 5970 5971// Integer ALU reg operation with constant shift 5972// Eg. LSL x0, x1, #shift 5973pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5974%{ 5975 single_instruction; 5976 dst : EX2(write); 5977 src1 : ISS(read); 5978 INS01 : ISS; 5979 ALU : EX2; 5980%} 5981 5982// Integer ALU reg-reg operation with variable shift 5983// Both operands must be available in LATE_ISS instead of EX1 5984// Result is available in EX1 instead of EX2 5985// Eg. LSLV x0, x1, x2 5986pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5987%{ 5988 single_instruction; 5989 dst : EX1(write); 5990 src1 : ISS(read); 5991 src2 : ISS(read); 5992 INS01 : ISS; 5993 ALU : EX1; 5994%} 5995 5996// Integer ALU reg-reg operation with extract 5997// As for _vshift above, but result generated in EX2 5998// Eg. EXTR x0, x1, x2, #N 5999pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6000%{ 6001 single_instruction; 6002 dst : EX2(write); 6003 src1 : ISS(read); 6004 src2 : ISS(read); 6005 INS1 : ISS; // Can only dual issue as Instruction 1 6006 ALU : EX1; 6007%} 6008 6009// Integer ALU reg operation 6010// Eg. NEG x0, x1 6011pipe_class ialu_reg(iRegI dst, iRegI src) 6012%{ 6013 single_instruction; 6014 dst : EX2(write); 6015 src : EX1(read); 6016 INS01 : ISS; 6017 ALU : EX2; 6018%} 6019 6020// Integer ALU reg mmediate operation 6021// Eg. ADD x0, x1, #N 6022pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6023%{ 6024 single_instruction; 6025 dst : EX2(write); 6026 src1 : EX1(read); 6027 INS01 : ISS; 6028 ALU : EX2; 6029%} 6030 6031// Integer ALU immediate operation (no source operands) 6032// Eg. MOV x0, #N 6033pipe_class ialu_imm(iRegI dst) 6034%{ 6035 single_instruction; 6036 dst : EX1(write); 6037 INS01 : ISS; 6038 ALU : EX1; 6039%} 6040 6041//------- Compare operation ------------------------------- 6042 6043// Compare reg-reg 6044// Eg. CMP x0, x1 6045pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6046%{ 6047 single_instruction; 6048// fixed_latency(16); 6049 cr : EX2(write); 6050 op1 : EX1(read); 6051 op2 : EX1(read); 6052 INS01 : ISS; 6053 ALU : EX2; 6054%} 6055 6056// Compare reg-reg 6057// Eg. CMP x0, #N 6058pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6059%{ 6060 single_instruction; 6061// fixed_latency(16); 6062 cr : EX2(write); 6063 op1 : EX1(read); 6064 INS01 : ISS; 6065 ALU : EX2; 6066%} 6067 6068//------- Conditional instructions ------------------------ 6069 6070// Conditional no operands 6071// Eg. CSINC x0, zr, zr, <cond> 6072pipe_class icond_none(iRegI dst, rFlagsReg cr) 6073%{ 6074 single_instruction; 6075 cr : EX1(read); 6076 dst : EX2(write); 6077 INS01 : ISS; 6078 ALU : EX2; 6079%} 6080 6081// Conditional 2 operand 6082// EG. CSEL X0, X1, X2, <cond> 6083pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6084%{ 6085 single_instruction; 6086 cr : EX1(read); 6087 src1 : EX1(read); 6088 src2 : EX1(read); 6089 dst : EX2(write); 6090 INS01 : ISS; 6091 ALU : EX2; 6092%} 6093 6094// Conditional 2 operand 6095// EG. CSEL X0, X1, X2, <cond> 6096pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6097%{ 6098 single_instruction; 6099 cr : EX1(read); 6100 src : EX1(read); 6101 dst : EX2(write); 6102 INS01 : ISS; 6103 ALU : EX2; 6104%} 6105 6106//------- Multiply pipeline operations -------------------- 6107 6108// Multiply reg-reg 6109// Eg. MUL w0, w1, w2 6110pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6111%{ 6112 single_instruction; 6113 dst : WR(write); 6114 src1 : ISS(read); 6115 src2 : ISS(read); 6116 INS01 : ISS; 6117 MAC : WR; 6118%} 6119 6120// Multiply accumulate 6121// Eg. MADD w0, w1, w2, w3 6122pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6123%{ 6124 single_instruction; 6125 dst : WR(write); 6126 src1 : ISS(read); 6127 src2 : ISS(read); 6128 src3 : ISS(read); 6129 INS01 : ISS; 6130 MAC : WR; 6131%} 6132 6133// Eg. MUL w0, w1, w2 6134pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6135%{ 6136 single_instruction; 6137 fixed_latency(3); // Maximum latency for 64 bit mul 6138 dst : WR(write); 6139 src1 : ISS(read); 6140 src2 : ISS(read); 6141 INS01 : ISS; 6142 MAC : WR; 6143%} 6144 6145// Multiply accumulate 6146// Eg. MADD w0, w1, w2, w3 6147pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6148%{ 6149 single_instruction; 6150 fixed_latency(3); // Maximum latency for 64 bit mul 6151 dst : WR(write); 6152 src1 : ISS(read); 6153 src2 : ISS(read); 6154 src3 : ISS(read); 6155 INS01 : ISS; 6156 MAC : WR; 6157%} 6158 6159//------- Divide pipeline operations -------------------- 6160 6161// Eg. SDIV w0, w1, w2 6162pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6163%{ 6164 single_instruction; 6165 fixed_latency(8); // Maximum latency for 32 bit divide 6166 dst : WR(write); 6167 src1 : ISS(read); 6168 src2 : ISS(read); 6169 INS0 : ISS; // Can only dual issue as instruction 0 6170 DIV : WR; 6171%} 6172 6173// Eg. SDIV x0, x1, x2 6174pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6175%{ 6176 single_instruction; 6177 fixed_latency(16); // Maximum latency for 64 bit divide 6178 dst : WR(write); 6179 src1 : ISS(read); 6180 src2 : ISS(read); 6181 INS0 : ISS; // Can only dual issue as instruction 0 6182 DIV : WR; 6183%} 6184 6185//------- Load pipeline operations ------------------------ 6186 6187// Load - prefetch 6188// Eg. PFRM <mem> 6189pipe_class iload_prefetch(memory mem) 6190%{ 6191 single_instruction; 6192 mem : ISS(read); 6193 INS01 : ISS; 6194 LDST : WR; 6195%} 6196 6197// Load - reg, mem 6198// Eg. LDR x0, <mem> 6199pipe_class iload_reg_mem(iRegI dst, memory mem) 6200%{ 6201 single_instruction; 6202 dst : WR(write); 6203 mem : ISS(read); 6204 INS01 : ISS; 6205 LDST : WR; 6206%} 6207 6208// Load - reg, reg 6209// Eg. LDR x0, [sp, x1] 6210pipe_class iload_reg_reg(iRegI dst, iRegI src) 6211%{ 6212 single_instruction; 6213 dst : WR(write); 6214 src : ISS(read); 6215 INS01 : ISS; 6216 LDST : WR; 6217%} 6218 6219//------- Store pipeline operations ----------------------- 6220 6221// Store - zr, mem 6222// Eg. STR zr, <mem> 6223pipe_class istore_mem(memory mem) 6224%{ 6225 single_instruction; 6226 mem : ISS(read); 6227 INS01 : ISS; 6228 LDST : WR; 6229%} 6230 6231// Store - reg, mem 6232// Eg. STR x0, <mem> 6233pipe_class istore_reg_mem(iRegI src, memory mem) 6234%{ 6235 single_instruction; 6236 mem : ISS(read); 6237 src : EX2(read); 6238 INS01 : ISS; 6239 LDST : WR; 6240%} 6241 6242// Store - reg, reg 6243// Eg. STR x0, [sp, x1] 6244pipe_class istore_reg_reg(iRegI dst, iRegI src) 6245%{ 6246 single_instruction; 6247 dst : ISS(read); 6248 src : EX2(read); 6249 INS01 : ISS; 6250 LDST : WR; 6251%} 6252 6253//------- Store pipeline operations ----------------------- 6254 6255// Branch 6256pipe_class pipe_branch() 6257%{ 6258 single_instruction; 6259 INS01 : ISS; 6260 BRANCH : EX1; 6261%} 6262 6263// Conditional branch 6264pipe_class pipe_branch_cond(rFlagsReg cr) 6265%{ 6266 single_instruction; 6267 cr : EX1(read); 6268 INS01 : ISS; 6269 BRANCH : EX1; 6270%} 6271 6272// Compare & Branch 6273// EG. CBZ/CBNZ 6274pipe_class pipe_cmp_branch(iRegI op1) 6275%{ 6276 single_instruction; 6277 op1 : EX1(read); 6278 INS01 : ISS; 6279 BRANCH : EX1; 6280%} 6281 6282//------- Synchronisation operations ---------------------- 6283 6284// Any operation requiring serialization. 6285// EG. DMB/Atomic Ops/Load Acquire/Str Release 6286pipe_class pipe_serial() 6287%{ 6288 single_instruction; 6289 force_serialization; 6290 fixed_latency(16); 6291 INS01 : ISS(2); // Cannot dual issue with any other instruction 6292 LDST : WR; 6293%} 6294 6295// Generic big/slow expanded idiom - also serialized 6296pipe_class pipe_slow() 6297%{ 6298 instruction_count(10); 6299 multiple_bundles; 6300 force_serialization; 6301 fixed_latency(16); 6302 INS01 : ISS(2); // Cannot dual issue with any other instruction 6303 LDST : WR; 6304%} 6305 6306// Empty pipeline class 6307pipe_class pipe_class_empty() 6308%{ 6309 single_instruction; 6310 fixed_latency(0); 6311%} 6312 6313// Default pipeline class. 6314pipe_class pipe_class_default() 6315%{ 6316 single_instruction; 6317 fixed_latency(2); 6318%} 6319 6320// Pipeline class for compares. 6321pipe_class pipe_class_compare() 6322%{ 6323 single_instruction; 6324 fixed_latency(16); 6325%} 6326 6327// Pipeline class for memory operations. 6328pipe_class pipe_class_memory() 6329%{ 6330 single_instruction; 6331 fixed_latency(16); 6332%} 6333 6334// Pipeline class for call. 6335pipe_class pipe_class_call() 6336%{ 6337 single_instruction; 6338 fixed_latency(100); 6339%} 6340 6341// Define the class for the Nop node. 6342define %{ 6343 MachNop = pipe_class_empty; 6344%} 6345 6346%} 6347//----------INSTRUCTIONS------------------------------------------------------- 6348// 6349// match -- States which machine-independent subtree may be replaced 6350// by this instruction. 6351// ins_cost -- The estimated cost of this instruction is used by instruction 6352// selection to identify a minimum cost tree of machine 6353// instructions that matches a tree of machine-independent 6354// instructions. 6355// format -- A string providing the disassembly for this instruction. 6356// The value of an instruction's operand may be inserted 6357// by referring to it with a '$' prefix. 6358// opcode -- Three instruction opcodes may be provided. These are referred 6359// to within an encode class as $primary, $secondary, and $tertiary 6360// rrspectively. The primary opcode is commonly used to 6361// indicate the type of machine instruction, while secondary 6362// and tertiary are often used for prefix options or addressing 6363// modes. 6364// ins_encode -- A list of encode classes with parameters. The encode class 6365// name must have been defined in an 'enc_class' specification 6366// in the encode section of the architecture description. 6367 6368// ============================================================================ 6369// Memory (Load/Store) Instructions 6370 6371// Load Instructions 6372 6373// Load Byte (8 bit signed) 6374instruct loadB(iRegINoSp dst, memory mem) 6375%{ 6376 match(Set dst (LoadB mem)); 6377 predicate(!needs_acquiring_load(n)); 6378 6379 ins_cost(4 * INSN_COST); 6380 format %{ "ldrsbw $dst, $mem\t# byte" %} 6381 6382 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6383 6384 ins_pipe(iload_reg_mem); 6385%} 6386 6387// Load Byte (8 bit signed) into long 6388instruct loadB2L(iRegLNoSp dst, memory mem) 6389%{ 6390 match(Set dst (ConvI2L (LoadB mem))); 6391 predicate(!needs_acquiring_load(n->in(1))); 6392 6393 ins_cost(4 * INSN_COST); 6394 format %{ "ldrsb $dst, $mem\t# byte" %} 6395 6396 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6397 6398 ins_pipe(iload_reg_mem); 6399%} 6400 6401// Load Byte (8 bit unsigned) 6402instruct loadUB(iRegINoSp dst, memory mem) 6403%{ 6404 match(Set dst (LoadUB mem)); 6405 predicate(!needs_acquiring_load(n)); 6406 6407 ins_cost(4 * INSN_COST); 6408 format %{ "ldrbw $dst, $mem\t# byte" %} 6409 6410 ins_encode(aarch64_enc_ldrb(dst, mem)); 6411 6412 ins_pipe(iload_reg_mem); 6413%} 6414 6415// Load Byte (8 bit unsigned) into long 6416instruct loadUB2L(iRegLNoSp dst, memory mem) 6417%{ 6418 match(Set dst (ConvI2L (LoadUB mem))); 6419 predicate(!needs_acquiring_load(n->in(1))); 6420 6421 ins_cost(4 * INSN_COST); 6422 format %{ "ldrb $dst, $mem\t# byte" %} 6423 6424 ins_encode(aarch64_enc_ldrb(dst, mem)); 6425 6426 ins_pipe(iload_reg_mem); 6427%} 6428 6429// Load Short (16 bit signed) 6430instruct loadS(iRegINoSp dst, memory mem) 6431%{ 6432 match(Set dst (LoadS mem)); 6433 predicate(!needs_acquiring_load(n)); 6434 6435 ins_cost(4 * INSN_COST); 6436 format %{ "ldrshw $dst, $mem\t# short" %} 6437 6438 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6439 6440 ins_pipe(iload_reg_mem); 6441%} 6442 6443// Load Short (16 bit signed) into long 6444instruct loadS2L(iRegLNoSp dst, memory mem) 6445%{ 6446 match(Set dst (ConvI2L (LoadS mem))); 6447 predicate(!needs_acquiring_load(n->in(1))); 6448 6449 ins_cost(4 * INSN_COST); 6450 format %{ "ldrsh $dst, $mem\t# short" %} 6451 6452 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6453 6454 ins_pipe(iload_reg_mem); 6455%} 6456 6457// Load Char (16 bit unsigned) 6458instruct loadUS(iRegINoSp dst, memory mem) 6459%{ 6460 match(Set dst (LoadUS mem)); 6461 predicate(!needs_acquiring_load(n)); 6462 6463 ins_cost(4 * INSN_COST); 6464 format %{ "ldrh $dst, $mem\t# short" %} 6465 6466 ins_encode(aarch64_enc_ldrh(dst, mem)); 6467 6468 ins_pipe(iload_reg_mem); 6469%} 6470 6471// Load Short/Char (16 bit unsigned) into long 6472instruct loadUS2L(iRegLNoSp dst, memory mem) 6473%{ 6474 match(Set dst (ConvI2L (LoadUS mem))); 6475 predicate(!needs_acquiring_load(n->in(1))); 6476 6477 ins_cost(4 * INSN_COST); 6478 format %{ "ldrh $dst, $mem\t# short" %} 6479 6480 ins_encode(aarch64_enc_ldrh(dst, mem)); 6481 6482 ins_pipe(iload_reg_mem); 6483%} 6484 6485// Load Integer (32 bit signed) 6486instruct loadI(iRegINoSp dst, memory mem) 6487%{ 6488 match(Set dst (LoadI mem)); 6489 predicate(!needs_acquiring_load(n)); 6490 6491 ins_cost(4 * INSN_COST); 6492 format %{ "ldrw $dst, $mem\t# int" %} 6493 6494 ins_encode(aarch64_enc_ldrw(dst, mem)); 6495 6496 ins_pipe(iload_reg_mem); 6497%} 6498 6499// Load Integer (32 bit signed) into long 6500instruct loadI2L(iRegLNoSp dst, memory mem) 6501%{ 6502 match(Set dst (ConvI2L (LoadI mem))); 6503 predicate(!needs_acquiring_load(n->in(1))); 6504 6505 ins_cost(4 * INSN_COST); 6506 format %{ "ldrsw $dst, $mem\t# int" %} 6507 6508 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6509 6510 ins_pipe(iload_reg_mem); 6511%} 6512 6513// Load Integer (32 bit unsigned) into long 6514instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6515%{ 6516 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6517 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6518 6519 ins_cost(4 * INSN_COST); 6520 format %{ "ldrw $dst, $mem\t# int" %} 6521 6522 ins_encode(aarch64_enc_ldrw(dst, mem)); 6523 6524 ins_pipe(iload_reg_mem); 6525%} 6526 6527// Load Long (64 bit signed) 6528instruct loadL(iRegLNoSp dst, memory mem) 6529%{ 6530 match(Set dst (LoadL mem)); 6531 predicate(!needs_acquiring_load(n)); 6532 6533 ins_cost(4 * INSN_COST); 6534 format %{ "ldr $dst, $mem\t# int" %} 6535 6536 ins_encode(aarch64_enc_ldr(dst, mem)); 6537 6538 ins_pipe(iload_reg_mem); 6539%} 6540 6541// Load Range 6542instruct loadRange(iRegINoSp dst, memory mem) 6543%{ 6544 match(Set dst (LoadRange mem)); 6545 6546 ins_cost(4 * INSN_COST); 6547 format %{ "ldrw $dst, $mem\t# range" %} 6548 6549 ins_encode(aarch64_enc_ldrw(dst, mem)); 6550 6551 ins_pipe(iload_reg_mem); 6552%} 6553 6554// Load Pointer 6555instruct loadP(iRegPNoSp dst, memory mem) 6556%{ 6557 match(Set dst (LoadP mem)); 6558 predicate(!needs_acquiring_load(n)); 6559 6560 ins_cost(4 * INSN_COST); 6561 format %{ "ldr $dst, $mem\t# ptr" %} 6562 6563 ins_encode(aarch64_enc_ldr(dst, mem)); 6564 6565 ins_pipe(iload_reg_mem); 6566%} 6567 6568// Load Compressed Pointer 6569instruct loadN(iRegNNoSp dst, memory mem) 6570%{ 6571 match(Set dst (LoadN mem)); 6572 predicate(!needs_acquiring_load(n)); 6573 6574 ins_cost(4 * INSN_COST); 6575 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6576 6577 ins_encode(aarch64_enc_ldrw(dst, mem)); 6578 6579 ins_pipe(iload_reg_mem); 6580%} 6581 6582// Load Klass Pointer 6583instruct loadKlass(iRegPNoSp dst, memory mem) 6584%{ 6585 match(Set dst (LoadKlass mem)); 6586 predicate(!needs_acquiring_load(n)); 6587 6588 ins_cost(4 * INSN_COST); 6589 format %{ "ldr $dst, $mem\t# class" %} 6590 6591 ins_encode(aarch64_enc_ldr(dst, mem)); 6592 6593 ins_pipe(iload_reg_mem); 6594%} 6595 6596// Load Narrow Klass Pointer 6597instruct loadNKlass(iRegNNoSp dst, memory mem) 6598%{ 6599 match(Set dst (LoadNKlass mem)); 6600 predicate(!needs_acquiring_load(n)); 6601 6602 ins_cost(4 * INSN_COST); 6603 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6604 6605 ins_encode(aarch64_enc_ldrw(dst, mem)); 6606 6607 ins_pipe(iload_reg_mem); 6608%} 6609 6610// Load Float 6611instruct loadF(vRegF dst, memory mem) 6612%{ 6613 match(Set dst (LoadF mem)); 6614 predicate(!needs_acquiring_load(n)); 6615 6616 ins_cost(4 * INSN_COST); 6617 format %{ "ldrs $dst, $mem\t# float" %} 6618 6619 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6620 6621 ins_pipe(pipe_class_memory); 6622%} 6623 6624// Load Double 6625instruct loadD(vRegD dst, memory mem) 6626%{ 6627 match(Set dst (LoadD mem)); 6628 predicate(!needs_acquiring_load(n)); 6629 6630 ins_cost(4 * INSN_COST); 6631 format %{ "ldrd $dst, $mem\t# double" %} 6632 6633 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6634 6635 ins_pipe(pipe_class_memory); 6636%} 6637 6638 6639// Load Int Constant 6640instruct loadConI(iRegINoSp dst, immI src) 6641%{ 6642 match(Set dst src); 6643 6644 ins_cost(INSN_COST); 6645 format %{ "mov $dst, $src\t# int" %} 6646 6647 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6648 6649 ins_pipe(ialu_imm); 6650%} 6651 6652// Load Long Constant 6653instruct loadConL(iRegLNoSp dst, immL src) 6654%{ 6655 match(Set dst src); 6656 6657 ins_cost(INSN_COST); 6658 format %{ "mov $dst, $src\t# long" %} 6659 6660 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6661 6662 ins_pipe(ialu_imm); 6663%} 6664 6665// Load Pointer Constant 6666 6667instruct loadConP(iRegPNoSp dst, immP con) 6668%{ 6669 match(Set dst con); 6670 6671 ins_cost(INSN_COST * 4); 6672 format %{ 6673 "mov $dst, $con\t# ptr\n\t" 6674 %} 6675 6676 ins_encode(aarch64_enc_mov_p(dst, con)); 6677 6678 ins_pipe(ialu_imm); 6679%} 6680 6681// Load Null Pointer Constant 6682 6683instruct loadConP0(iRegPNoSp dst, immP0 con) 6684%{ 6685 match(Set dst con); 6686 6687 ins_cost(INSN_COST); 6688 format %{ "mov $dst, $con\t# NULL ptr" %} 6689 6690 ins_encode(aarch64_enc_mov_p0(dst, con)); 6691 6692 ins_pipe(ialu_imm); 6693%} 6694 6695// Load Pointer Constant One 6696 6697instruct loadConP1(iRegPNoSp dst, immP_1 con) 6698%{ 6699 match(Set dst con); 6700 6701 ins_cost(INSN_COST); 6702 format %{ "mov $dst, $con\t# NULL ptr" %} 6703 6704 ins_encode(aarch64_enc_mov_p1(dst, con)); 6705 6706 ins_pipe(ialu_imm); 6707%} 6708 6709// Load Poll Page Constant 6710 6711instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6712%{ 6713 match(Set dst con); 6714 6715 ins_cost(INSN_COST); 6716 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6717 6718 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6719 6720 ins_pipe(ialu_imm); 6721%} 6722 6723// Load Byte Map Base Constant 6724 6725instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6726%{ 6727 match(Set dst con); 6728 6729 ins_cost(INSN_COST); 6730 format %{ "adr $dst, $con\t# Byte Map Base" %} 6731 6732 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6733 6734 ins_pipe(ialu_imm); 6735%} 6736 6737// Load Narrow Pointer Constant 6738 6739instruct loadConN(iRegNNoSp dst, immN con) 6740%{ 6741 match(Set dst con); 6742 6743 ins_cost(INSN_COST * 4); 6744 format %{ "mov $dst, $con\t# compressed ptr" %} 6745 6746 ins_encode(aarch64_enc_mov_n(dst, con)); 6747 6748 ins_pipe(ialu_imm); 6749%} 6750 6751// Load Narrow Null Pointer Constant 6752 6753instruct loadConN0(iRegNNoSp dst, immN0 con) 6754%{ 6755 match(Set dst con); 6756 6757 ins_cost(INSN_COST); 6758 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6759 6760 ins_encode(aarch64_enc_mov_n0(dst, con)); 6761 6762 ins_pipe(ialu_imm); 6763%} 6764 6765// Load Narrow Klass Constant 6766 6767instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6768%{ 6769 match(Set dst con); 6770 6771 ins_cost(INSN_COST); 6772 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6773 6774 ins_encode(aarch64_enc_mov_nk(dst, con)); 6775 6776 ins_pipe(ialu_imm); 6777%} 6778 6779// Load Packed Float Constant 6780 6781instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6782 match(Set dst con); 6783 ins_cost(INSN_COST * 4); 6784 format %{ "fmovs $dst, $con"%} 6785 ins_encode %{ 6786 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6787 %} 6788 6789 ins_pipe(fp_imm_s); 6790%} 6791 6792// Load Float Constant 6793 6794instruct loadConF(vRegF dst, immF con) %{ 6795 match(Set dst con); 6796 6797 ins_cost(INSN_COST * 4); 6798 6799 format %{ 6800 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6801 %} 6802 6803 ins_encode %{ 6804 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6805 %} 6806 6807 ins_pipe(fp_load_constant_s); 6808%} 6809 6810// Load Packed Double Constant 6811 6812instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6813 match(Set dst con); 6814 ins_cost(INSN_COST); 6815 format %{ "fmovd $dst, $con"%} 6816 ins_encode %{ 6817 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6818 %} 6819 6820 ins_pipe(fp_imm_d); 6821%} 6822 6823// Load Double Constant 6824 6825instruct loadConD(vRegD dst, immD con) %{ 6826 match(Set dst con); 6827 6828 ins_cost(INSN_COST * 5); 6829 format %{ 6830 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6831 %} 6832 6833 ins_encode %{ 6834 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6835 %} 6836 6837 ins_pipe(fp_load_constant_d); 6838%} 6839 6840// Store Instructions 6841 6842// Store CMS card-mark Immediate 6843instruct storeimmCM0(immI0 zero, memory mem) 6844%{ 6845 match(Set mem (StoreCM mem zero)); 6846 predicate(unnecessary_storestore(n)); 6847 6848 ins_cost(INSN_COST); 6849 format %{ "storestore (elided)\n\t" 6850 "strb zr, $mem\t# byte" %} 6851 6852 ins_encode(aarch64_enc_strb0(mem)); 6853 6854 ins_pipe(istore_mem); 6855%} 6856 6857// Store CMS card-mark Immediate with intervening StoreStore 6858// needed when using CMS with no conditional card marking 6859instruct storeimmCM0_ordered(immI0 zero, memory mem) 6860%{ 6861 match(Set mem (StoreCM mem zero)); 6862 6863 ins_cost(INSN_COST * 2); 6864 format %{ "storestore\n\t" 6865 "dmb ishst" 6866 "\n\tstrb zr, $mem\t# byte" %} 6867 6868 ins_encode(aarch64_enc_strb0_ordered(mem)); 6869 6870 ins_pipe(istore_mem); 6871%} 6872 6873// Store Byte 6874instruct storeB(iRegIorL2I src, memory mem) 6875%{ 6876 match(Set mem (StoreB mem src)); 6877 predicate(!needs_releasing_store(n)); 6878 6879 ins_cost(INSN_COST); 6880 format %{ "strb $src, $mem\t# byte" %} 6881 6882 ins_encode(aarch64_enc_strb(src, mem)); 6883 6884 ins_pipe(istore_reg_mem); 6885%} 6886 6887 6888instruct storeimmB0(immI0 zero, memory mem) 6889%{ 6890 match(Set mem (StoreB mem zero)); 6891 predicate(!needs_releasing_store(n)); 6892 6893 ins_cost(INSN_COST); 6894 format %{ "strb rscractch2, $mem\t# byte" %} 6895 6896 ins_encode(aarch64_enc_strb0(mem)); 6897 6898 ins_pipe(istore_mem); 6899%} 6900 6901// Store Char/Short 6902instruct storeC(iRegIorL2I src, memory mem) 6903%{ 6904 match(Set mem (StoreC mem src)); 6905 predicate(!needs_releasing_store(n)); 6906 6907 ins_cost(INSN_COST); 6908 format %{ "strh $src, $mem\t# short" %} 6909 6910 ins_encode(aarch64_enc_strh(src, mem)); 6911 6912 ins_pipe(istore_reg_mem); 6913%} 6914 6915instruct storeimmC0(immI0 zero, memory mem) 6916%{ 6917 match(Set mem (StoreC mem zero)); 6918 predicate(!needs_releasing_store(n)); 6919 6920 ins_cost(INSN_COST); 6921 format %{ "strh zr, $mem\t# short" %} 6922 6923 ins_encode(aarch64_enc_strh0(mem)); 6924 6925 ins_pipe(istore_mem); 6926%} 6927 6928// Store Integer 6929 6930instruct storeI(iRegIorL2I src, memory mem) 6931%{ 6932 match(Set mem(StoreI mem src)); 6933 predicate(!needs_releasing_store(n)); 6934 6935 ins_cost(INSN_COST); 6936 format %{ "strw $src, $mem\t# int" %} 6937 6938 ins_encode(aarch64_enc_strw(src, mem)); 6939 6940 ins_pipe(istore_reg_mem); 6941%} 6942 6943instruct storeimmI0(immI0 zero, memory mem) 6944%{ 6945 match(Set mem(StoreI mem zero)); 6946 predicate(!needs_releasing_store(n)); 6947 6948 ins_cost(INSN_COST); 6949 format %{ "strw zr, $mem\t# int" %} 6950 6951 ins_encode(aarch64_enc_strw0(mem)); 6952 6953 ins_pipe(istore_mem); 6954%} 6955 6956// Store Long (64 bit signed) 6957instruct storeL(iRegL src, memory mem) 6958%{ 6959 match(Set mem (StoreL mem src)); 6960 predicate(!needs_releasing_store(n)); 6961 6962 ins_cost(INSN_COST); 6963 format %{ "str $src, $mem\t# int" %} 6964 6965 ins_encode(aarch64_enc_str(src, mem)); 6966 6967 ins_pipe(istore_reg_mem); 6968%} 6969 6970// Store Long (64 bit signed) 6971instruct storeimmL0(immL0 zero, memory mem) 6972%{ 6973 match(Set mem (StoreL mem zero)); 6974 predicate(!needs_releasing_store(n)); 6975 6976 ins_cost(INSN_COST); 6977 format %{ "str zr, $mem\t# int" %} 6978 6979 ins_encode(aarch64_enc_str0(mem)); 6980 6981 ins_pipe(istore_mem); 6982%} 6983 6984// Store Pointer 6985instruct storeP(iRegP src, memory mem) 6986%{ 6987 match(Set mem (StoreP mem src)); 6988 predicate(!needs_releasing_store(n)); 6989 6990 ins_cost(INSN_COST); 6991 format %{ "str $src, $mem\t# ptr" %} 6992 6993 ins_encode(aarch64_enc_str(src, mem)); 6994 6995 ins_pipe(istore_reg_mem); 6996%} 6997 6998// Store Pointer 6999instruct storeimmP0(immP0 zero, memory mem) 7000%{ 7001 match(Set mem (StoreP mem zero)); 7002 predicate(!needs_releasing_store(n)); 7003 7004 ins_cost(INSN_COST); 7005 format %{ "str zr, $mem\t# ptr" %} 7006 7007 ins_encode(aarch64_enc_str0(mem)); 7008 7009 ins_pipe(istore_mem); 7010%} 7011 7012// Store Compressed Pointer 7013instruct storeN(iRegN src, memory mem) 7014%{ 7015 match(Set mem (StoreN mem src)); 7016 predicate(!needs_releasing_store(n)); 7017 7018 ins_cost(INSN_COST); 7019 format %{ "strw $src, $mem\t# compressed ptr" %} 7020 7021 ins_encode(aarch64_enc_strw(src, mem)); 7022 7023 ins_pipe(istore_reg_mem); 7024%} 7025 7026instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 7027%{ 7028 match(Set mem (StoreN mem zero)); 7029 predicate(Universe::narrow_oop_base() == NULL && 7030 Universe::narrow_klass_base() == NULL && 7031 (!needs_releasing_store(n))); 7032 7033 ins_cost(INSN_COST); 7034 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 7035 7036 ins_encode(aarch64_enc_strw(heapbase, mem)); 7037 7038 ins_pipe(istore_reg_mem); 7039%} 7040 7041// Store Float 7042instruct storeF(vRegF src, memory mem) 7043%{ 7044 match(Set mem (StoreF mem src)); 7045 predicate(!needs_releasing_store(n)); 7046 7047 ins_cost(INSN_COST); 7048 format %{ "strs $src, $mem\t# float" %} 7049 7050 ins_encode( aarch64_enc_strs(src, mem) ); 7051 7052 ins_pipe(pipe_class_memory); 7053%} 7054 7055// TODO 7056// implement storeImmF0 and storeFImmPacked 7057 7058// Store Double 7059instruct storeD(vRegD src, memory mem) 7060%{ 7061 match(Set mem (StoreD mem src)); 7062 predicate(!needs_releasing_store(n)); 7063 7064 ins_cost(INSN_COST); 7065 format %{ "strd $src, $mem\t# double" %} 7066 7067 ins_encode( aarch64_enc_strd(src, mem) ); 7068 7069 ins_pipe(pipe_class_memory); 7070%} 7071 7072// Store Compressed Klass Pointer 7073instruct storeNKlass(iRegN src, memory mem) 7074%{ 7075 predicate(!needs_releasing_store(n)); 7076 match(Set mem (StoreNKlass mem src)); 7077 7078 ins_cost(INSN_COST); 7079 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7080 7081 ins_encode(aarch64_enc_strw(src, mem)); 7082 7083 ins_pipe(istore_reg_mem); 7084%} 7085 7086// TODO 7087// implement storeImmD0 and storeDImmPacked 7088 7089// prefetch instructions 7090// Must be safe to execute with invalid address (cannot fault). 7091 7092instruct prefetchalloc( memory mem ) %{ 7093 match(PrefetchAllocation mem); 7094 7095 ins_cost(INSN_COST); 7096 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7097 7098 ins_encode( aarch64_enc_prefetchw(mem) ); 7099 7100 ins_pipe(iload_prefetch); 7101%} 7102 7103// ---------------- volatile loads and stores ---------------- 7104 7105// Load Byte (8 bit signed) 7106instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7107%{ 7108 match(Set dst (LoadB mem)); 7109 7110 ins_cost(VOLATILE_REF_COST); 7111 format %{ "ldarsb $dst, $mem\t# byte" %} 7112 7113 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7114 7115 ins_pipe(pipe_serial); 7116%} 7117 7118// Load Byte (8 bit signed) into long 7119instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7120%{ 7121 match(Set dst (ConvI2L (LoadB mem))); 7122 7123 ins_cost(VOLATILE_REF_COST); 7124 format %{ "ldarsb $dst, $mem\t# byte" %} 7125 7126 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7127 7128 ins_pipe(pipe_serial); 7129%} 7130 7131// Load Byte (8 bit unsigned) 7132instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7133%{ 7134 match(Set dst (LoadUB mem)); 7135 7136 ins_cost(VOLATILE_REF_COST); 7137 format %{ "ldarb $dst, $mem\t# byte" %} 7138 7139 ins_encode(aarch64_enc_ldarb(dst, mem)); 7140 7141 ins_pipe(pipe_serial); 7142%} 7143 7144// Load Byte (8 bit unsigned) into long 7145instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7146%{ 7147 match(Set dst (ConvI2L (LoadUB mem))); 7148 7149 ins_cost(VOLATILE_REF_COST); 7150 format %{ "ldarb $dst, $mem\t# byte" %} 7151 7152 ins_encode(aarch64_enc_ldarb(dst, mem)); 7153 7154 ins_pipe(pipe_serial); 7155%} 7156 7157// Load Short (16 bit signed) 7158instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7159%{ 7160 match(Set dst (LoadS mem)); 7161 7162 ins_cost(VOLATILE_REF_COST); 7163 format %{ "ldarshw $dst, $mem\t# short" %} 7164 7165 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7166 7167 ins_pipe(pipe_serial); 7168%} 7169 7170instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7171%{ 7172 match(Set dst (LoadUS mem)); 7173 7174 ins_cost(VOLATILE_REF_COST); 7175 format %{ "ldarhw $dst, $mem\t# short" %} 7176 7177 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7178 7179 ins_pipe(pipe_serial); 7180%} 7181 7182// Load Short/Char (16 bit unsigned) into long 7183instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7184%{ 7185 match(Set dst (ConvI2L (LoadUS mem))); 7186 7187 ins_cost(VOLATILE_REF_COST); 7188 format %{ "ldarh $dst, $mem\t# short" %} 7189 7190 ins_encode(aarch64_enc_ldarh(dst, mem)); 7191 7192 ins_pipe(pipe_serial); 7193%} 7194 7195// Load Short/Char (16 bit signed) into long 7196instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7197%{ 7198 match(Set dst (ConvI2L (LoadS mem))); 7199 7200 ins_cost(VOLATILE_REF_COST); 7201 format %{ "ldarh $dst, $mem\t# short" %} 7202 7203 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7204 7205 ins_pipe(pipe_serial); 7206%} 7207 7208// Load Integer (32 bit signed) 7209instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7210%{ 7211 match(Set dst (LoadI mem)); 7212 7213 ins_cost(VOLATILE_REF_COST); 7214 format %{ "ldarw $dst, $mem\t# int" %} 7215 7216 ins_encode(aarch64_enc_ldarw(dst, mem)); 7217 7218 ins_pipe(pipe_serial); 7219%} 7220 7221// Load Integer (32 bit unsigned) into long 7222instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7223%{ 7224 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7225 7226 ins_cost(VOLATILE_REF_COST); 7227 format %{ "ldarw $dst, $mem\t# int" %} 7228 7229 ins_encode(aarch64_enc_ldarw(dst, mem)); 7230 7231 ins_pipe(pipe_serial); 7232%} 7233 7234// Load Long (64 bit signed) 7235instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7236%{ 7237 match(Set dst (LoadL mem)); 7238 7239 ins_cost(VOLATILE_REF_COST); 7240 format %{ "ldar $dst, $mem\t# int" %} 7241 7242 ins_encode(aarch64_enc_ldar(dst, mem)); 7243 7244 ins_pipe(pipe_serial); 7245%} 7246 7247// Load Pointer 7248instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7249%{ 7250 match(Set dst (LoadP mem)); 7251 7252 ins_cost(VOLATILE_REF_COST); 7253 format %{ "ldar $dst, $mem\t# ptr" %} 7254 7255 ins_encode(aarch64_enc_ldar(dst, mem)); 7256 7257 ins_pipe(pipe_serial); 7258%} 7259 7260// Load Compressed Pointer 7261instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7262%{ 7263 match(Set dst (LoadN mem)); 7264 7265 ins_cost(VOLATILE_REF_COST); 7266 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7267 7268 ins_encode(aarch64_enc_ldarw(dst, mem)); 7269 7270 ins_pipe(pipe_serial); 7271%} 7272 7273// Load Float 7274instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7275%{ 7276 match(Set dst (LoadF mem)); 7277 7278 ins_cost(VOLATILE_REF_COST); 7279 format %{ "ldars $dst, $mem\t# float" %} 7280 7281 ins_encode( aarch64_enc_fldars(dst, mem) ); 7282 7283 ins_pipe(pipe_serial); 7284%} 7285 7286// Load Double 7287instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7288%{ 7289 match(Set dst (LoadD mem)); 7290 7291 ins_cost(VOLATILE_REF_COST); 7292 format %{ "ldard $dst, $mem\t# double" %} 7293 7294 ins_encode( aarch64_enc_fldard(dst, mem) ); 7295 7296 ins_pipe(pipe_serial); 7297%} 7298 7299// Store Byte 7300instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7301%{ 7302 match(Set mem (StoreB mem src)); 7303 7304 ins_cost(VOLATILE_REF_COST); 7305 format %{ "stlrb $src, $mem\t# byte" %} 7306 7307 ins_encode(aarch64_enc_stlrb(src, mem)); 7308 7309 ins_pipe(pipe_class_memory); 7310%} 7311 7312// Store Char/Short 7313instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7314%{ 7315 match(Set mem (StoreC mem src)); 7316 7317 ins_cost(VOLATILE_REF_COST); 7318 format %{ "stlrh $src, $mem\t# short" %} 7319 7320 ins_encode(aarch64_enc_stlrh(src, mem)); 7321 7322 ins_pipe(pipe_class_memory); 7323%} 7324 7325// Store Integer 7326 7327instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7328%{ 7329 match(Set mem(StoreI mem src)); 7330 7331 ins_cost(VOLATILE_REF_COST); 7332 format %{ "stlrw $src, $mem\t# int" %} 7333 7334 ins_encode(aarch64_enc_stlrw(src, mem)); 7335 7336 ins_pipe(pipe_class_memory); 7337%} 7338 7339// Store Long (64 bit signed) 7340instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7341%{ 7342 match(Set mem (StoreL mem src)); 7343 7344 ins_cost(VOLATILE_REF_COST); 7345 format %{ "stlr $src, $mem\t# int" %} 7346 7347 ins_encode(aarch64_enc_stlr(src, mem)); 7348 7349 ins_pipe(pipe_class_memory); 7350%} 7351 7352// Store Pointer 7353instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7354%{ 7355 match(Set mem (StoreP mem src)); 7356 7357 ins_cost(VOLATILE_REF_COST); 7358 format %{ "stlr $src, $mem\t# ptr" %} 7359 7360 ins_encode(aarch64_enc_stlr(src, mem)); 7361 7362 ins_pipe(pipe_class_memory); 7363%} 7364 7365// Store Compressed Pointer 7366instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7367%{ 7368 match(Set mem (StoreN mem src)); 7369 7370 ins_cost(VOLATILE_REF_COST); 7371 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7372 7373 ins_encode(aarch64_enc_stlrw(src, mem)); 7374 7375 ins_pipe(pipe_class_memory); 7376%} 7377 7378// Store Float 7379instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7380%{ 7381 match(Set mem (StoreF mem src)); 7382 7383 ins_cost(VOLATILE_REF_COST); 7384 format %{ "stlrs $src, $mem\t# float" %} 7385 7386 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7387 7388 ins_pipe(pipe_class_memory); 7389%} 7390 7391// TODO 7392// implement storeImmF0 and storeFImmPacked 7393 7394// Store Double 7395instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7396%{ 7397 match(Set mem (StoreD mem src)); 7398 7399 ins_cost(VOLATILE_REF_COST); 7400 format %{ "stlrd $src, $mem\t# double" %} 7401 7402 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7403 7404 ins_pipe(pipe_class_memory); 7405%} 7406 7407// ---------------- end of volatile loads and stores ---------------- 7408 7409// ============================================================================ 7410// BSWAP Instructions 7411 7412instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7413 match(Set dst (ReverseBytesI src)); 7414 7415 ins_cost(INSN_COST); 7416 format %{ "revw $dst, $src" %} 7417 7418 ins_encode %{ 7419 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7420 %} 7421 7422 ins_pipe(ialu_reg); 7423%} 7424 7425instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7426 match(Set dst (ReverseBytesL src)); 7427 7428 ins_cost(INSN_COST); 7429 format %{ "rev $dst, $src" %} 7430 7431 ins_encode %{ 7432 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7433 %} 7434 7435 ins_pipe(ialu_reg); 7436%} 7437 7438instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7439 match(Set dst (ReverseBytesUS src)); 7440 7441 ins_cost(INSN_COST); 7442 format %{ "rev16w $dst, $src" %} 7443 7444 ins_encode %{ 7445 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7446 %} 7447 7448 ins_pipe(ialu_reg); 7449%} 7450 7451instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7452 match(Set dst (ReverseBytesS src)); 7453 7454 ins_cost(INSN_COST); 7455 format %{ "rev16w $dst, $src\n\t" 7456 "sbfmw $dst, $dst, #0, #15" %} 7457 7458 ins_encode %{ 7459 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7460 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7461 %} 7462 7463 ins_pipe(ialu_reg); 7464%} 7465 7466// ============================================================================ 7467// Zero Count Instructions 7468 7469instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7470 match(Set dst (CountLeadingZerosI src)); 7471 7472 ins_cost(INSN_COST); 7473 format %{ "clzw $dst, $src" %} 7474 ins_encode %{ 7475 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7476 %} 7477 7478 ins_pipe(ialu_reg); 7479%} 7480 7481instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7482 match(Set dst (CountLeadingZerosL src)); 7483 7484 ins_cost(INSN_COST); 7485 format %{ "clz $dst, $src" %} 7486 ins_encode %{ 7487 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7488 %} 7489 7490 ins_pipe(ialu_reg); 7491%} 7492 7493instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7494 match(Set dst (CountTrailingZerosI src)); 7495 7496 ins_cost(INSN_COST * 2); 7497 format %{ "rbitw $dst, $src\n\t" 7498 "clzw $dst, $dst" %} 7499 ins_encode %{ 7500 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7501 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7502 %} 7503 7504 ins_pipe(ialu_reg); 7505%} 7506 7507instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7508 match(Set dst (CountTrailingZerosL src)); 7509 7510 ins_cost(INSN_COST * 2); 7511 format %{ "rbit $dst, $src\n\t" 7512 "clz $dst, $dst" %} 7513 ins_encode %{ 7514 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7515 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7516 %} 7517 7518 ins_pipe(ialu_reg); 7519%} 7520 7521//---------- Population Count Instructions ------------------------------------- 7522// 7523 7524instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 7525 predicate(UsePopCountInstruction); 7526 match(Set dst (PopCountI src)); 7527 effect(TEMP tmp); 7528 ins_cost(INSN_COST * 13); 7529 7530 format %{ "movw $src, $src\n\t" 7531 "mov $tmp, $src\t# vector (1D)\n\t" 7532 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7533 "addv $tmp, $tmp\t# vector (8B)\n\t" 7534 "mov $dst, $tmp\t# vector (1D)" %} 7535 ins_encode %{ 7536 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 7537 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7538 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7539 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7540 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7541 %} 7542 7543 ins_pipe(pipe_class_default); 7544%} 7545 7546instruct popCountI_mem(iRegINoSp dst, memory mem, vRegF tmp) %{ 7547 predicate(UsePopCountInstruction); 7548 match(Set dst (PopCountI (LoadI mem))); 7549 effect(TEMP tmp); 7550 ins_cost(INSN_COST * 13); 7551 7552 format %{ "ldrs $tmp, $mem\n\t" 7553 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7554 "addv $tmp, $tmp\t# vector (8B)\n\t" 7555 "mov $dst, $tmp\t# vector (1D)" %} 7556 ins_encode %{ 7557 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7558 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 7559 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7560 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7561 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7562 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7563 %} 7564 7565 ins_pipe(pipe_class_default); 7566%} 7567 7568// Note: Long.bitCount(long) returns an int. 7569instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 7570 predicate(UsePopCountInstruction); 7571 match(Set dst (PopCountL src)); 7572 effect(TEMP tmp); 7573 ins_cost(INSN_COST * 13); 7574 7575 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 7576 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7577 "addv $tmp, $tmp\t# vector (8B)\n\t" 7578 "mov $dst, $tmp\t# vector (1D)" %} 7579 ins_encode %{ 7580 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 7581 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7582 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7583 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7584 %} 7585 7586 ins_pipe(pipe_class_default); 7587%} 7588 7589instruct popCountL_mem(iRegINoSp dst, memory mem, vRegD tmp) %{ 7590 predicate(UsePopCountInstruction); 7591 match(Set dst (PopCountL (LoadL mem))); 7592 effect(TEMP tmp); 7593 ins_cost(INSN_COST * 13); 7594 7595 format %{ "ldrd $tmp, $mem\n\t" 7596 "cnt $tmp, $tmp\t# vector (8B)\n\t" 7597 "addv $tmp, $tmp\t# vector (8B)\n\t" 7598 "mov $dst, $tmp\t# vector (1D)" %} 7599 ins_encode %{ 7600 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 7601 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 7602 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 7603 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7604 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 7605 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 7606 %} 7607 7608 ins_pipe(pipe_class_default); 7609%} 7610 7611// ============================================================================ 7612// MemBar Instruction 7613 7614instruct load_fence() %{ 7615 match(LoadFence); 7616 ins_cost(VOLATILE_REF_COST); 7617 7618 format %{ "load_fence" %} 7619 7620 ins_encode %{ 7621 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7622 %} 7623 ins_pipe(pipe_serial); 7624%} 7625 7626instruct unnecessary_membar_acquire() %{ 7627 predicate(unnecessary_acquire(n)); 7628 match(MemBarAcquire); 7629 ins_cost(0); 7630 7631 format %{ "membar_acquire (elided)" %} 7632 7633 ins_encode %{ 7634 __ block_comment("membar_acquire (elided)"); 7635 %} 7636 7637 ins_pipe(pipe_class_empty); 7638%} 7639 7640instruct membar_acquire() %{ 7641 match(MemBarAcquire); 7642 ins_cost(VOLATILE_REF_COST); 7643 7644 format %{ "membar_acquire\n\t" 7645 "dmb ish" %} 7646 7647 ins_encode %{ 7648 __ block_comment("membar_acquire"); 7649 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7650 %} 7651 7652 ins_pipe(pipe_serial); 7653%} 7654 7655 7656instruct membar_acquire_lock() %{ 7657 match(MemBarAcquireLock); 7658 ins_cost(VOLATILE_REF_COST); 7659 7660 format %{ "membar_acquire_lock (elided)" %} 7661 7662 ins_encode %{ 7663 __ block_comment("membar_acquire_lock (elided)"); 7664 %} 7665 7666 ins_pipe(pipe_serial); 7667%} 7668 7669instruct store_fence() %{ 7670 match(StoreFence); 7671 ins_cost(VOLATILE_REF_COST); 7672 7673 format %{ "store_fence" %} 7674 7675 ins_encode %{ 7676 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7677 %} 7678 ins_pipe(pipe_serial); 7679%} 7680 7681instruct unnecessary_membar_release() %{ 7682 predicate(unnecessary_release(n)); 7683 match(MemBarRelease); 7684 ins_cost(0); 7685 7686 format %{ "membar_release (elided)" %} 7687 7688 ins_encode %{ 7689 __ block_comment("membar_release (elided)"); 7690 %} 7691 ins_pipe(pipe_serial); 7692%} 7693 7694instruct membar_release() %{ 7695 match(MemBarRelease); 7696 ins_cost(VOLATILE_REF_COST); 7697 7698 format %{ "membar_release\n\t" 7699 "dmb ish" %} 7700 7701 ins_encode %{ 7702 __ block_comment("membar_release"); 7703 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7704 %} 7705 ins_pipe(pipe_serial); 7706%} 7707 7708instruct membar_storestore() %{ 7709 match(MemBarStoreStore); 7710 ins_cost(VOLATILE_REF_COST); 7711 7712 format %{ "MEMBAR-store-store" %} 7713 7714 ins_encode %{ 7715 __ membar(Assembler::StoreStore); 7716 %} 7717 ins_pipe(pipe_serial); 7718%} 7719 7720instruct membar_release_lock() %{ 7721 match(MemBarReleaseLock); 7722 ins_cost(VOLATILE_REF_COST); 7723 7724 format %{ "membar_release_lock (elided)" %} 7725 7726 ins_encode %{ 7727 __ block_comment("membar_release_lock (elided)"); 7728 %} 7729 7730 ins_pipe(pipe_serial); 7731%} 7732 7733instruct unnecessary_membar_volatile() %{ 7734 predicate(unnecessary_volatile(n)); 7735 match(MemBarVolatile); 7736 ins_cost(0); 7737 7738 format %{ "membar_volatile (elided)" %} 7739 7740 ins_encode %{ 7741 __ block_comment("membar_volatile (elided)"); 7742 %} 7743 7744 ins_pipe(pipe_serial); 7745%} 7746 7747instruct membar_volatile() %{ 7748 match(MemBarVolatile); 7749 ins_cost(VOLATILE_REF_COST*100); 7750 7751 format %{ "membar_volatile\n\t" 7752 "dmb ish"%} 7753 7754 ins_encode %{ 7755 __ block_comment("membar_volatile"); 7756 __ membar(Assembler::StoreLoad); 7757 %} 7758 7759 ins_pipe(pipe_serial); 7760%} 7761 7762// ============================================================================ 7763// Cast/Convert Instructions 7764 7765instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7766 match(Set dst (CastX2P src)); 7767 7768 ins_cost(INSN_COST); 7769 format %{ "mov $dst, $src\t# long -> ptr" %} 7770 7771 ins_encode %{ 7772 if ($dst$$reg != $src$$reg) { 7773 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7774 } 7775 %} 7776 7777 ins_pipe(ialu_reg); 7778%} 7779 7780instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7781 match(Set dst (CastP2X src)); 7782 7783 ins_cost(INSN_COST); 7784 format %{ "mov $dst, $src\t# ptr -> long" %} 7785 7786 ins_encode %{ 7787 if ($dst$$reg != $src$$reg) { 7788 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7789 } 7790 %} 7791 7792 ins_pipe(ialu_reg); 7793%} 7794 7795// Convert oop into int for vectors alignment masking 7796instruct convP2I(iRegINoSp dst, iRegP src) %{ 7797 match(Set dst (ConvL2I (CastP2X src))); 7798 7799 ins_cost(INSN_COST); 7800 format %{ "movw $dst, $src\t# ptr -> int" %} 7801 ins_encode %{ 7802 __ movw($dst$$Register, $src$$Register); 7803 %} 7804 7805 ins_pipe(ialu_reg); 7806%} 7807 7808// Convert compressed oop into int for vectors alignment masking 7809// in case of 32bit oops (heap < 4Gb). 7810instruct convN2I(iRegINoSp dst, iRegN src) 7811%{ 7812 predicate(Universe::narrow_oop_shift() == 0); 7813 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7814 7815 ins_cost(INSN_COST); 7816 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7817 ins_encode %{ 7818 __ movw($dst$$Register, $src$$Register); 7819 %} 7820 7821 ins_pipe(ialu_reg); 7822%} 7823 7824 7825// Convert oop pointer into compressed form 7826instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7827 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7828 match(Set dst (EncodeP src)); 7829 effect(KILL cr); 7830 ins_cost(INSN_COST * 3); 7831 format %{ "encode_heap_oop $dst, $src" %} 7832 ins_encode %{ 7833 Register s = $src$$Register; 7834 Register d = $dst$$Register; 7835 __ encode_heap_oop(d, s); 7836 %} 7837 ins_pipe(ialu_reg); 7838%} 7839 7840instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7841 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7842 match(Set dst (EncodeP src)); 7843 ins_cost(INSN_COST * 3); 7844 format %{ "encode_heap_oop_not_null $dst, $src" %} 7845 ins_encode %{ 7846 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7847 %} 7848 ins_pipe(ialu_reg); 7849%} 7850 7851instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7852 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7853 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7854 match(Set dst (DecodeN src)); 7855 ins_cost(INSN_COST * 3); 7856 format %{ "decode_heap_oop $dst, $src" %} 7857 ins_encode %{ 7858 Register s = $src$$Register; 7859 Register d = $dst$$Register; 7860 __ decode_heap_oop(d, s); 7861 %} 7862 ins_pipe(ialu_reg); 7863%} 7864 7865instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7866 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7867 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7868 match(Set dst (DecodeN src)); 7869 ins_cost(INSN_COST * 3); 7870 format %{ "decode_heap_oop_not_null $dst, $src" %} 7871 ins_encode %{ 7872 Register s = $src$$Register; 7873 Register d = $dst$$Register; 7874 __ decode_heap_oop_not_null(d, s); 7875 %} 7876 ins_pipe(ialu_reg); 7877%} 7878 7879// n.b. AArch64 implementations of encode_klass_not_null and 7880// decode_klass_not_null do not modify the flags register so, unlike 7881// Intel, we don't kill CR as a side effect here 7882 7883instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7884 match(Set dst (EncodePKlass src)); 7885 7886 ins_cost(INSN_COST * 3); 7887 format %{ "encode_klass_not_null $dst,$src" %} 7888 7889 ins_encode %{ 7890 Register src_reg = as_Register($src$$reg); 7891 Register dst_reg = as_Register($dst$$reg); 7892 __ encode_klass_not_null(dst_reg, src_reg); 7893 %} 7894 7895 ins_pipe(ialu_reg); 7896%} 7897 7898instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7899 match(Set dst (DecodeNKlass src)); 7900 7901 ins_cost(INSN_COST * 3); 7902 format %{ "decode_klass_not_null $dst,$src" %} 7903 7904 ins_encode %{ 7905 Register src_reg = as_Register($src$$reg); 7906 Register dst_reg = as_Register($dst$$reg); 7907 if (dst_reg != src_reg) { 7908 __ decode_klass_not_null(dst_reg, src_reg); 7909 } else { 7910 __ decode_klass_not_null(dst_reg); 7911 } 7912 %} 7913 7914 ins_pipe(ialu_reg); 7915%} 7916 7917instruct checkCastPP(iRegPNoSp dst) 7918%{ 7919 match(Set dst (CheckCastPP dst)); 7920 7921 size(0); 7922 format %{ "# checkcastPP of $dst" %} 7923 ins_encode(/* empty encoding */); 7924 ins_pipe(pipe_class_empty); 7925%} 7926 7927instruct castPP(iRegPNoSp dst) 7928%{ 7929 match(Set dst (CastPP dst)); 7930 7931 size(0); 7932 format %{ "# castPP of $dst" %} 7933 ins_encode(/* empty encoding */); 7934 ins_pipe(pipe_class_empty); 7935%} 7936 7937instruct castII(iRegI dst) 7938%{ 7939 match(Set dst (CastII dst)); 7940 7941 size(0); 7942 format %{ "# castII of $dst" %} 7943 ins_encode(/* empty encoding */); 7944 ins_cost(0); 7945 ins_pipe(pipe_class_empty); 7946%} 7947 7948// ============================================================================ 7949// Atomic operation instructions 7950// 7951// Intel and SPARC both implement Ideal Node LoadPLocked and 7952// Store{PIL}Conditional instructions using a normal load for the 7953// LoadPLocked and a CAS for the Store{PIL}Conditional. 7954// 7955// The ideal code appears only to use LoadPLocked/StorePLocked as a 7956// pair to lock object allocations from Eden space when not using 7957// TLABs. 7958// 7959// There does not appear to be a Load{IL}Locked Ideal Node and the 7960// Ideal code appears to use Store{IL}Conditional as an alias for CAS 7961// and to use StoreIConditional only for 32-bit and StoreLConditional 7962// only for 64-bit. 7963// 7964// We implement LoadPLocked and StorePLocked instructions using, 7965// respectively the AArch64 hw load-exclusive and store-conditional 7966// instructions. Whereas we must implement each of 7967// Store{IL}Conditional using a CAS which employs a pair of 7968// instructions comprising a load-exclusive followed by a 7969// store-conditional. 7970 7971 7972// Locked-load (linked load) of the current heap-top 7973// used when updating the eden heap top 7974// implemented using ldaxr on AArch64 7975 7976instruct loadPLocked(iRegPNoSp dst, indirect mem) 7977%{ 7978 match(Set dst (LoadPLocked mem)); 7979 7980 ins_cost(VOLATILE_REF_COST); 7981 7982 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7983 7984 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7985 7986 ins_pipe(pipe_serial); 7987%} 7988 7989// Conditional-store of the updated heap-top. 7990// Used during allocation of the shared heap. 7991// Sets flag (EQ) on success. 7992// implemented using stlxr on AArch64. 7993 7994instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7995%{ 7996 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7997 7998 ins_cost(VOLATILE_REF_COST); 7999 8000 // TODO 8001 // do we need to do a store-conditional release or can we just use a 8002 // plain store-conditional? 8003 8004 format %{ 8005 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8006 "cmpw rscratch1, zr\t# EQ on successful write" 8007 %} 8008 8009 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8010 8011 ins_pipe(pipe_serial); 8012%} 8013 8014 8015// storeLConditional is used by PhaseMacroExpand::expand_lock_node 8016// when attempting to rebias a lock towards the current thread. We 8017// must use the acquire form of cmpxchg in order to guarantee acquire 8018// semantics in this case. 8019instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8020%{ 8021 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8022 8023 ins_cost(VOLATILE_REF_COST); 8024 8025 format %{ 8026 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8027 "cmpw rscratch1, zr\t# EQ on successful write" 8028 %} 8029 8030 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8031 8032 ins_pipe(pipe_slow); 8033%} 8034 8035// storeIConditional also has acquire semantics, for no better reason 8036// than matching storeLConditional. At the time of writing this 8037// comment storeIConditional was not used anywhere by AArch64. 8038instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8039%{ 8040 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8041 8042 ins_cost(VOLATILE_REF_COST); 8043 8044 format %{ 8045 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8046 "cmpw rscratch1, zr\t# EQ on successful write" 8047 %} 8048 8049 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8050 8051 ins_pipe(pipe_slow); 8052%} 8053 8054// standard CompareAndSwapX when we are using barriers 8055// these have higher priority than the rules selected by a predicate 8056 8057// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8058// can't match them 8059 8060instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8061 8062 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8063 ins_cost(2 * VOLATILE_REF_COST); 8064 8065 effect(KILL cr); 8066 8067 format %{ 8068 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8069 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8070 %} 8071 8072 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8073 aarch64_enc_cset_eq(res)); 8074 8075 ins_pipe(pipe_slow); 8076%} 8077 8078instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8079 8080 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8081 ins_cost(2 * VOLATILE_REF_COST); 8082 8083 effect(KILL cr); 8084 8085 format %{ 8086 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8087 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8088 %} 8089 8090 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8091 aarch64_enc_cset_eq(res)); 8092 8093 ins_pipe(pipe_slow); 8094%} 8095 8096instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8097 8098 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8099 ins_cost(2 * VOLATILE_REF_COST); 8100 8101 effect(KILL cr); 8102 8103 format %{ 8104 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8105 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8106 %} 8107 8108 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8109 aarch64_enc_cset_eq(res)); 8110 8111 ins_pipe(pipe_slow); 8112%} 8113 8114instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8115 8116 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8117 ins_cost(2 * VOLATILE_REF_COST); 8118 8119 effect(KILL cr); 8120 8121 format %{ 8122 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8123 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8124 %} 8125 8126 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8127 aarch64_enc_cset_eq(res)); 8128 8129 ins_pipe(pipe_slow); 8130%} 8131 8132instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8133 8134 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8135 ins_cost(2 * VOLATILE_REF_COST); 8136 8137 effect(KILL cr); 8138 8139 format %{ 8140 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8141 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8142 %} 8143 8144 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8145 aarch64_enc_cset_eq(res)); 8146 8147 ins_pipe(pipe_slow); 8148%} 8149 8150instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8151 8152 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8153 ins_cost(2 * VOLATILE_REF_COST); 8154 8155 effect(KILL cr); 8156 8157 format %{ 8158 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8159 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8160 %} 8161 8162 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8163 aarch64_enc_cset_eq(res)); 8164 8165 ins_pipe(pipe_slow); 8166%} 8167 8168// alternative CompareAndSwapX when we are eliding barriers 8169 8170instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8171 8172 predicate(needs_acquiring_load_exclusive(n)); 8173 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8174 ins_cost(VOLATILE_REF_COST); 8175 8176 effect(KILL cr); 8177 8178 format %{ 8179 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8180 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8181 %} 8182 8183 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8184 aarch64_enc_cset_eq(res)); 8185 8186 ins_pipe(pipe_slow); 8187%} 8188 8189instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8190 8191 predicate(needs_acquiring_load_exclusive(n)); 8192 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8193 ins_cost(VOLATILE_REF_COST); 8194 8195 effect(KILL cr); 8196 8197 format %{ 8198 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8199 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8200 %} 8201 8202 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8203 aarch64_enc_cset_eq(res)); 8204 8205 ins_pipe(pipe_slow); 8206%} 8207 8208instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8209 8210 predicate(needs_acquiring_load_exclusive(n)); 8211 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8212 ins_cost(VOLATILE_REF_COST); 8213 8214 effect(KILL cr); 8215 8216 format %{ 8217 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8218 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8219 %} 8220 8221 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8222 aarch64_enc_cset_eq(res)); 8223 8224 ins_pipe(pipe_slow); 8225%} 8226 8227instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8228 8229 predicate(needs_acquiring_load_exclusive(n)); 8230 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8231 ins_cost(VOLATILE_REF_COST); 8232 8233 effect(KILL cr); 8234 8235 format %{ 8236 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8237 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8238 %} 8239 8240 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8241 aarch64_enc_cset_eq(res)); 8242 8243 ins_pipe(pipe_slow); 8244%} 8245 8246instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8247 8248 predicate(needs_acquiring_load_exclusive(n)); 8249 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8250 ins_cost(VOLATILE_REF_COST); 8251 8252 effect(KILL cr); 8253 8254 format %{ 8255 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8256 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8257 %} 8258 8259 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8260 aarch64_enc_cset_eq(res)); 8261 8262 ins_pipe(pipe_slow); 8263%} 8264 8265instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8266 8267 predicate(needs_acquiring_load_exclusive(n)); 8268 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8269 ins_cost(VOLATILE_REF_COST); 8270 8271 effect(KILL cr); 8272 8273 format %{ 8274 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8275 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8276 %} 8277 8278 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8279 aarch64_enc_cset_eq(res)); 8280 8281 ins_pipe(pipe_slow); 8282%} 8283 8284 8285// --------------------------------------------------------------------- 8286 8287 8288// BEGIN This section of the file is automatically generated. Do not edit -------------- 8289 8290// Sundry CAS operations. Note that release is always true, 8291// regardless of the memory ordering of the CAS. This is because we 8292// need the volatile case to be sequentially consistent but there is 8293// no trailing StoreLoad barrier emitted by C2. Unfortunately we 8294// can't check the type of memory ordering here, so we always emit a 8295// STLXR. 8296 8297// This section is generated from aarch64_ad_cas.m4 8298 8299 8300 8301instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8302 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8303 ins_cost(2 * VOLATILE_REF_COST); 8304 effect(TEMP_DEF res, KILL cr); 8305 format %{ 8306 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8307 %} 8308 ins_encode %{ 8309 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8310 Assembler::byte, /*acquire*/ false, /*release*/ true, 8311 /*weak*/ false, $res$$Register); 8312 __ sxtbw($res$$Register, $res$$Register); 8313 %} 8314 ins_pipe(pipe_slow); 8315%} 8316 8317instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8318 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8319 ins_cost(2 * VOLATILE_REF_COST); 8320 effect(TEMP_DEF res, KILL cr); 8321 format %{ 8322 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8323 %} 8324 ins_encode %{ 8325 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8326 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8327 /*weak*/ false, $res$$Register); 8328 __ sxthw($res$$Register, $res$$Register); 8329 %} 8330 ins_pipe(pipe_slow); 8331%} 8332 8333instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8334 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8335 ins_cost(2 * VOLATILE_REF_COST); 8336 effect(TEMP_DEF res, KILL cr); 8337 format %{ 8338 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8339 %} 8340 ins_encode %{ 8341 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8342 Assembler::word, /*acquire*/ false, /*release*/ true, 8343 /*weak*/ false, $res$$Register); 8344 %} 8345 ins_pipe(pipe_slow); 8346%} 8347 8348instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8349 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8350 ins_cost(2 * VOLATILE_REF_COST); 8351 effect(TEMP_DEF res, KILL cr); 8352 format %{ 8353 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8354 %} 8355 ins_encode %{ 8356 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8357 Assembler::xword, /*acquire*/ false, /*release*/ true, 8358 /*weak*/ false, $res$$Register); 8359 %} 8360 ins_pipe(pipe_slow); 8361%} 8362 8363instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8364 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8365 ins_cost(2 * VOLATILE_REF_COST); 8366 effect(TEMP_DEF res, KILL cr); 8367 format %{ 8368 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8369 %} 8370 ins_encode %{ 8371 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8372 Assembler::word, /*acquire*/ false, /*release*/ true, 8373 /*weak*/ false, $res$$Register); 8374 %} 8375 ins_pipe(pipe_slow); 8376%} 8377 8378instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8379 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8380 ins_cost(2 * VOLATILE_REF_COST); 8381 effect(TEMP_DEF res, KILL cr); 8382 format %{ 8383 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8384 %} 8385 ins_encode %{ 8386 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8387 Assembler::xword, /*acquire*/ false, /*release*/ true, 8388 /*weak*/ false, $res$$Register); 8389 %} 8390 ins_pipe(pipe_slow); 8391%} 8392 8393instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8394 predicate(needs_acquiring_load_exclusive(n)); 8395 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8396 ins_cost(VOLATILE_REF_COST); 8397 effect(TEMP_DEF res, KILL cr); 8398 format %{ 8399 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8400 %} 8401 ins_encode %{ 8402 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8403 Assembler::byte, /*acquire*/ true, /*release*/ true, 8404 /*weak*/ false, $res$$Register); 8405 __ sxtbw($res$$Register, $res$$Register); 8406 %} 8407 ins_pipe(pipe_slow); 8408%} 8409 8410instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8411 predicate(needs_acquiring_load_exclusive(n)); 8412 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8413 ins_cost(VOLATILE_REF_COST); 8414 effect(TEMP_DEF res, KILL cr); 8415 format %{ 8416 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8417 %} 8418 ins_encode %{ 8419 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8420 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8421 /*weak*/ false, $res$$Register); 8422 __ sxthw($res$$Register, $res$$Register); 8423 %} 8424 ins_pipe(pipe_slow); 8425%} 8426 8427 8428instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8429 predicate(needs_acquiring_load_exclusive(n)); 8430 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8431 ins_cost(VOLATILE_REF_COST); 8432 effect(TEMP_DEF res, KILL cr); 8433 format %{ 8434 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8435 %} 8436 ins_encode %{ 8437 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8438 Assembler::word, /*acquire*/ true, /*release*/ true, 8439 /*weak*/ false, $res$$Register); 8440 %} 8441 ins_pipe(pipe_slow); 8442%} 8443 8444instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8445 predicate(needs_acquiring_load_exclusive(n)); 8446 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8447 ins_cost(VOLATILE_REF_COST); 8448 effect(TEMP_DEF res, KILL cr); 8449 format %{ 8450 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8451 %} 8452 ins_encode %{ 8453 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8454 Assembler::xword, /*acquire*/ true, /*release*/ true, 8455 /*weak*/ false, $res$$Register); 8456 %} 8457 ins_pipe(pipe_slow); 8458%} 8459 8460 8461instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8462 predicate(needs_acquiring_load_exclusive(n)); 8463 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 8464 ins_cost(VOLATILE_REF_COST); 8465 effect(TEMP_DEF res, KILL cr); 8466 format %{ 8467 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8468 %} 8469 ins_encode %{ 8470 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8471 Assembler::word, /*acquire*/ true, /*release*/ true, 8472 /*weak*/ false, $res$$Register); 8473 %} 8474 ins_pipe(pipe_slow); 8475%} 8476 8477instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8478 predicate(needs_acquiring_load_exclusive(n)); 8479 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 8480 ins_cost(VOLATILE_REF_COST); 8481 effect(TEMP_DEF res, KILL cr); 8482 format %{ 8483 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8484 %} 8485 ins_encode %{ 8486 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8487 Assembler::xword, /*acquire*/ true, /*release*/ true, 8488 /*weak*/ false, $res$$Register); 8489 %} 8490 ins_pipe(pipe_slow); 8491%} 8492 8493instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8494 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8495 ins_cost(2 * VOLATILE_REF_COST); 8496 effect(KILL cr); 8497 format %{ 8498 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8499 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8500 %} 8501 ins_encode %{ 8502 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8503 Assembler::byte, /*acquire*/ false, /*release*/ true, 8504 /*weak*/ true, noreg); 8505 __ csetw($res$$Register, Assembler::EQ); 8506 %} 8507 ins_pipe(pipe_slow); 8508%} 8509 8510instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8511 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8512 ins_cost(2 * VOLATILE_REF_COST); 8513 effect(KILL cr); 8514 format %{ 8515 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8516 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8517 %} 8518 ins_encode %{ 8519 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8520 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8521 /*weak*/ true, noreg); 8522 __ csetw($res$$Register, Assembler::EQ); 8523 %} 8524 ins_pipe(pipe_slow); 8525%} 8526 8527instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8528 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8529 ins_cost(2 * VOLATILE_REF_COST); 8530 effect(KILL cr); 8531 format %{ 8532 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8533 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8534 %} 8535 ins_encode %{ 8536 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8537 Assembler::word, /*acquire*/ false, /*release*/ true, 8538 /*weak*/ true, noreg); 8539 __ csetw($res$$Register, Assembler::EQ); 8540 %} 8541 ins_pipe(pipe_slow); 8542%} 8543 8544instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8545 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8546 ins_cost(2 * VOLATILE_REF_COST); 8547 effect(KILL cr); 8548 format %{ 8549 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8550 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8551 %} 8552 ins_encode %{ 8553 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8554 Assembler::xword, /*acquire*/ false, /*release*/ true, 8555 /*weak*/ true, noreg); 8556 __ csetw($res$$Register, Assembler::EQ); 8557 %} 8558 ins_pipe(pipe_slow); 8559%} 8560 8561instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8562 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8563 ins_cost(2 * VOLATILE_REF_COST); 8564 effect(KILL cr); 8565 format %{ 8566 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8567 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8568 %} 8569 ins_encode %{ 8570 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8571 Assembler::word, /*acquire*/ false, /*release*/ true, 8572 /*weak*/ true, noreg); 8573 __ csetw($res$$Register, Assembler::EQ); 8574 %} 8575 ins_pipe(pipe_slow); 8576%} 8577 8578instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8579 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8580 ins_cost(2 * VOLATILE_REF_COST); 8581 effect(KILL cr); 8582 format %{ 8583 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8584 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8585 %} 8586 ins_encode %{ 8587 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8588 Assembler::xword, /*acquire*/ false, /*release*/ true, 8589 /*weak*/ true, noreg); 8590 __ csetw($res$$Register, Assembler::EQ); 8591 %} 8592 ins_pipe(pipe_slow); 8593%} 8594 8595instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8596 predicate(needs_acquiring_load_exclusive(n)); 8597 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 8598 ins_cost(VOLATILE_REF_COST); 8599 effect(KILL cr); 8600 format %{ 8601 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8602 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8603 %} 8604 ins_encode %{ 8605 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8606 Assembler::byte, /*acquire*/ true, /*release*/ true, 8607 /*weak*/ true, noreg); 8608 __ csetw($res$$Register, Assembler::EQ); 8609 %} 8610 ins_pipe(pipe_slow); 8611%} 8612 8613instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8614 predicate(needs_acquiring_load_exclusive(n)); 8615 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 8616 ins_cost(VOLATILE_REF_COST); 8617 effect(KILL cr); 8618 format %{ 8619 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8620 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8621 %} 8622 ins_encode %{ 8623 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8624 Assembler::halfword, /*acquire*/ true, /*release*/ true, 8625 /*weak*/ true, noreg); 8626 __ csetw($res$$Register, Assembler::EQ); 8627 %} 8628 ins_pipe(pipe_slow); 8629%} 8630 8631instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8632 predicate(needs_acquiring_load_exclusive(n)); 8633 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 8634 ins_cost(VOLATILE_REF_COST); 8635 effect(KILL cr); 8636 format %{ 8637 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8638 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8639 %} 8640 ins_encode %{ 8641 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8642 Assembler::word, /*acquire*/ true, /*release*/ true, 8643 /*weak*/ true, noreg); 8644 __ csetw($res$$Register, Assembler::EQ); 8645 %} 8646 ins_pipe(pipe_slow); 8647%} 8648 8649instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8650 predicate(needs_acquiring_load_exclusive(n)); 8651 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 8652 ins_cost(VOLATILE_REF_COST); 8653 effect(KILL cr); 8654 format %{ 8655 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8656 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8657 %} 8658 ins_encode %{ 8659 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8660 Assembler::xword, /*acquire*/ true, /*release*/ true, 8661 /*weak*/ true, noreg); 8662 __ csetw($res$$Register, Assembler::EQ); 8663 %} 8664 ins_pipe(pipe_slow); 8665%} 8666 8667instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 8668 predicate(needs_acquiring_load_exclusive(n)); 8669 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 8670 ins_cost(VOLATILE_REF_COST); 8671 effect(KILL cr); 8672 format %{ 8673 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 8674 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8675 %} 8676 ins_encode %{ 8677 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8678 Assembler::word, /*acquire*/ true, /*release*/ true, 8679 /*weak*/ true, noreg); 8680 __ csetw($res$$Register, Assembler::EQ); 8681 %} 8682 ins_pipe(pipe_slow); 8683%} 8684 8685instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8686 predicate(needs_acquiring_load_exclusive(n)); 8687 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 8688 ins_cost(VOLATILE_REF_COST); 8689 effect(KILL cr); 8690 format %{ 8691 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 8692 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8693 %} 8694 ins_encode %{ 8695 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8696 Assembler::xword, /*acquire*/ true, /*release*/ true, 8697 /*weak*/ true, noreg); 8698 __ csetw($res$$Register, Assembler::EQ); 8699 %} 8700 ins_pipe(pipe_slow); 8701%} 8702 8703// END This section of the file is automatically generated. Do not edit -------------- 8704// --------------------------------------------------------------------- 8705 8706instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 8707 match(Set prev (GetAndSetI mem newv)); 8708 ins_cost(2 * VOLATILE_REF_COST); 8709 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8710 ins_encode %{ 8711 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8712 %} 8713 ins_pipe(pipe_serial); 8714%} 8715 8716instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8717 match(Set prev (GetAndSetL mem newv)); 8718 ins_cost(2 * VOLATILE_REF_COST); 8719 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8720 ins_encode %{ 8721 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8722 %} 8723 ins_pipe(pipe_serial); 8724%} 8725 8726instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 8727 match(Set prev (GetAndSetN mem newv)); 8728 ins_cost(2 * VOLATILE_REF_COST); 8729 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 8730 ins_encode %{ 8731 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8732 %} 8733 ins_pipe(pipe_serial); 8734%} 8735 8736instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8737 match(Set prev (GetAndSetP mem newv)); 8738 ins_cost(2 * VOLATILE_REF_COST); 8739 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 8740 ins_encode %{ 8741 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8742 %} 8743 ins_pipe(pipe_serial); 8744%} 8745 8746instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 8747 predicate(needs_acquiring_load_exclusive(n)); 8748 match(Set prev (GetAndSetI mem newv)); 8749 ins_cost(VOLATILE_REF_COST); 8750 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8751 ins_encode %{ 8752 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8753 %} 8754 ins_pipe(pipe_serial); 8755%} 8756 8757instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 8758 predicate(needs_acquiring_load_exclusive(n)); 8759 match(Set prev (GetAndSetL mem newv)); 8760 ins_cost(VOLATILE_REF_COST); 8761 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8762 ins_encode %{ 8763 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8764 %} 8765 ins_pipe(pipe_serial); 8766%} 8767 8768instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 8769 predicate(needs_acquiring_load_exclusive(n)); 8770 match(Set prev (GetAndSetN mem newv)); 8771 ins_cost(VOLATILE_REF_COST); 8772 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 8773 ins_encode %{ 8774 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8775 %} 8776 ins_pipe(pipe_serial); 8777%} 8778 8779instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 8780 predicate(needs_acquiring_load_exclusive(n)); 8781 match(Set prev (GetAndSetP mem newv)); 8782 ins_cost(VOLATILE_REF_COST); 8783 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 8784 ins_encode %{ 8785 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 8786 %} 8787 ins_pipe(pipe_serial); 8788%} 8789 8790 8791instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8792 match(Set newval (GetAndAddL mem incr)); 8793 ins_cost(2 * VOLATILE_REF_COST + 1); 8794 format %{ "get_and_addL $newval, [$mem], $incr" %} 8795 ins_encode %{ 8796 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8797 %} 8798 ins_pipe(pipe_serial); 8799%} 8800 8801instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 8802 predicate(n->as_LoadStore()->result_not_used()); 8803 match(Set dummy (GetAndAddL mem incr)); 8804 ins_cost(2 * VOLATILE_REF_COST); 8805 format %{ "get_and_addL [$mem], $incr" %} 8806 ins_encode %{ 8807 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 8808 %} 8809 ins_pipe(pipe_serial); 8810%} 8811 8812instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8813 match(Set newval (GetAndAddL mem incr)); 8814 ins_cost(2 * VOLATILE_REF_COST + 1); 8815 format %{ "get_and_addL $newval, [$mem], $incr" %} 8816 ins_encode %{ 8817 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8818 %} 8819 ins_pipe(pipe_serial); 8820%} 8821 8822instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 8823 predicate(n->as_LoadStore()->result_not_used()); 8824 match(Set dummy (GetAndAddL mem incr)); 8825 ins_cost(2 * VOLATILE_REF_COST); 8826 format %{ "get_and_addL [$mem], $incr" %} 8827 ins_encode %{ 8828 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 8829 %} 8830 ins_pipe(pipe_serial); 8831%} 8832 8833instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8834 match(Set newval (GetAndAddI mem incr)); 8835 ins_cost(2 * VOLATILE_REF_COST + 1); 8836 format %{ "get_and_addI $newval, [$mem], $incr" %} 8837 ins_encode %{ 8838 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8839 %} 8840 ins_pipe(pipe_serial); 8841%} 8842 8843instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8844 predicate(n->as_LoadStore()->result_not_used()); 8845 match(Set dummy (GetAndAddI mem incr)); 8846 ins_cost(2 * VOLATILE_REF_COST); 8847 format %{ "get_and_addI [$mem], $incr" %} 8848 ins_encode %{ 8849 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 8850 %} 8851 ins_pipe(pipe_serial); 8852%} 8853 8854instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8855 match(Set newval (GetAndAddI mem incr)); 8856 ins_cost(2 * VOLATILE_REF_COST + 1); 8857 format %{ "get_and_addI $newval, [$mem], $incr" %} 8858 ins_encode %{ 8859 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8860 %} 8861 ins_pipe(pipe_serial); 8862%} 8863 8864instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 8865 predicate(n->as_LoadStore()->result_not_used()); 8866 match(Set dummy (GetAndAddI mem incr)); 8867 ins_cost(2 * VOLATILE_REF_COST); 8868 format %{ "get_and_addI [$mem], $incr" %} 8869 ins_encode %{ 8870 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 8871 %} 8872 ins_pipe(pipe_serial); 8873%} 8874 8875instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 8876 predicate(needs_acquiring_load_exclusive(n)); 8877 match(Set newval (GetAndAddL mem incr)); 8878 ins_cost(VOLATILE_REF_COST + 1); 8879 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8880 ins_encode %{ 8881 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8882 %} 8883 ins_pipe(pipe_serial); 8884%} 8885 8886instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 8887 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8888 match(Set dummy (GetAndAddL mem incr)); 8889 ins_cost(VOLATILE_REF_COST); 8890 format %{ "get_and_addL_acq [$mem], $incr" %} 8891 ins_encode %{ 8892 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 8893 %} 8894 ins_pipe(pipe_serial); 8895%} 8896 8897instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 8898 predicate(needs_acquiring_load_exclusive(n)); 8899 match(Set newval (GetAndAddL mem incr)); 8900 ins_cost(VOLATILE_REF_COST + 1); 8901 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 8902 ins_encode %{ 8903 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8904 %} 8905 ins_pipe(pipe_serial); 8906%} 8907 8908instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 8909 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8910 match(Set dummy (GetAndAddL mem incr)); 8911 ins_cost(VOLATILE_REF_COST); 8912 format %{ "get_and_addL_acq [$mem], $incr" %} 8913 ins_encode %{ 8914 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 8915 %} 8916 ins_pipe(pipe_serial); 8917%} 8918 8919instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 8920 predicate(needs_acquiring_load_exclusive(n)); 8921 match(Set newval (GetAndAddI mem incr)); 8922 ins_cost(VOLATILE_REF_COST + 1); 8923 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8924 ins_encode %{ 8925 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 8926 %} 8927 ins_pipe(pipe_serial); 8928%} 8929 8930instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 8931 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8932 match(Set dummy (GetAndAddI mem incr)); 8933 ins_cost(VOLATILE_REF_COST); 8934 format %{ "get_and_addI_acq [$mem], $incr" %} 8935 ins_encode %{ 8936 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 8937 %} 8938 ins_pipe(pipe_serial); 8939%} 8940 8941instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 8942 predicate(needs_acquiring_load_exclusive(n)); 8943 match(Set newval (GetAndAddI mem incr)); 8944 ins_cost(VOLATILE_REF_COST + 1); 8945 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 8946 ins_encode %{ 8947 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 8948 %} 8949 ins_pipe(pipe_serial); 8950%} 8951 8952instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 8953 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 8954 match(Set dummy (GetAndAddI mem incr)); 8955 ins_cost(VOLATILE_REF_COST); 8956 format %{ "get_and_addI_acq [$mem], $incr" %} 8957 ins_encode %{ 8958 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 8959 %} 8960 ins_pipe(pipe_serial); 8961%} 8962 8963// Manifest a CmpL result in an integer register. 8964// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 8965instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 8966%{ 8967 match(Set dst (CmpL3 src1 src2)); 8968 effect(KILL flags); 8969 8970 ins_cost(INSN_COST * 6); 8971 format %{ 8972 "cmp $src1, $src2" 8973 "csetw $dst, ne" 8974 "cnegw $dst, lt" 8975 %} 8976 // format %{ "CmpL3 $dst, $src1, $src2" %} 8977 ins_encode %{ 8978 __ cmp($src1$$Register, $src2$$Register); 8979 __ csetw($dst$$Register, Assembler::NE); 8980 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 8981 %} 8982 8983 ins_pipe(pipe_class_default); 8984%} 8985 8986instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 8987%{ 8988 match(Set dst (CmpL3 src1 src2)); 8989 effect(KILL flags); 8990 8991 ins_cost(INSN_COST * 6); 8992 format %{ 8993 "cmp $src1, $src2" 8994 "csetw $dst, ne" 8995 "cnegw $dst, lt" 8996 %} 8997 ins_encode %{ 8998 int32_t con = (int32_t)$src2$$constant; 8999 if (con < 0) { 9000 __ adds(zr, $src1$$Register, -con); 9001 } else { 9002 __ subs(zr, $src1$$Register, con); 9003 } 9004 __ csetw($dst$$Register, Assembler::NE); 9005 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9006 %} 9007 9008 ins_pipe(pipe_class_default); 9009%} 9010 9011// ============================================================================ 9012// Conditional Move Instructions 9013 9014// n.b. we have identical rules for both a signed compare op (cmpOp) 9015// and an unsigned compare op (cmpOpU). it would be nice if we could 9016// define an op class which merged both inputs and use it to type the 9017// argument to a single rule. unfortunatelyt his fails because the 9018// opclass does not live up to the COND_INTER interface of its 9019// component operands. When the generic code tries to negate the 9020// operand it ends up running the generci Machoper::negate method 9021// which throws a ShouldNotHappen. So, we have to provide two flavours 9022// of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9023 9024instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9025 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9026 9027 ins_cost(INSN_COST * 2); 9028 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9029 9030 ins_encode %{ 9031 __ cselw(as_Register($dst$$reg), 9032 as_Register($src2$$reg), 9033 as_Register($src1$$reg), 9034 (Assembler::Condition)$cmp$$cmpcode); 9035 %} 9036 9037 ins_pipe(icond_reg_reg); 9038%} 9039 9040instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9041 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9042 9043 ins_cost(INSN_COST * 2); 9044 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9045 9046 ins_encode %{ 9047 __ cselw(as_Register($dst$$reg), 9048 as_Register($src2$$reg), 9049 as_Register($src1$$reg), 9050 (Assembler::Condition)$cmp$$cmpcode); 9051 %} 9052 9053 ins_pipe(icond_reg_reg); 9054%} 9055 9056// special cases where one arg is zero 9057 9058// n.b. this is selected in preference to the rule above because it 9059// avoids loading constant 0 into a source register 9060 9061// TODO 9062// we ought only to be able to cull one of these variants as the ideal 9063// transforms ought always to order the zero consistently (to left/right?) 9064 9065instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9066 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9067 9068 ins_cost(INSN_COST * 2); 9069 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9070 9071 ins_encode %{ 9072 __ cselw(as_Register($dst$$reg), 9073 as_Register($src$$reg), 9074 zr, 9075 (Assembler::Condition)$cmp$$cmpcode); 9076 %} 9077 9078 ins_pipe(icond_reg); 9079%} 9080 9081instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9082 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9083 9084 ins_cost(INSN_COST * 2); 9085 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9086 9087 ins_encode %{ 9088 __ cselw(as_Register($dst$$reg), 9089 as_Register($src$$reg), 9090 zr, 9091 (Assembler::Condition)$cmp$$cmpcode); 9092 %} 9093 9094 ins_pipe(icond_reg); 9095%} 9096 9097instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9098 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9099 9100 ins_cost(INSN_COST * 2); 9101 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9102 9103 ins_encode %{ 9104 __ cselw(as_Register($dst$$reg), 9105 zr, 9106 as_Register($src$$reg), 9107 (Assembler::Condition)$cmp$$cmpcode); 9108 %} 9109 9110 ins_pipe(icond_reg); 9111%} 9112 9113instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9114 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9115 9116 ins_cost(INSN_COST * 2); 9117 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9118 9119 ins_encode %{ 9120 __ cselw(as_Register($dst$$reg), 9121 zr, 9122 as_Register($src$$reg), 9123 (Assembler::Condition)$cmp$$cmpcode); 9124 %} 9125 9126 ins_pipe(icond_reg); 9127%} 9128 9129// special case for creating a boolean 0 or 1 9130 9131// n.b. this is selected in preference to the rule above because it 9132// avoids loading constants 0 and 1 into a source register 9133 9134instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9135 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9136 9137 ins_cost(INSN_COST * 2); 9138 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9139 9140 ins_encode %{ 9141 // equivalently 9142 // cset(as_Register($dst$$reg), 9143 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9144 __ csincw(as_Register($dst$$reg), 9145 zr, 9146 zr, 9147 (Assembler::Condition)$cmp$$cmpcode); 9148 %} 9149 9150 ins_pipe(icond_none); 9151%} 9152 9153instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9154 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9155 9156 ins_cost(INSN_COST * 2); 9157 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9158 9159 ins_encode %{ 9160 // equivalently 9161 // cset(as_Register($dst$$reg), 9162 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9163 __ csincw(as_Register($dst$$reg), 9164 zr, 9165 zr, 9166 (Assembler::Condition)$cmp$$cmpcode); 9167 %} 9168 9169 ins_pipe(icond_none); 9170%} 9171 9172instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9173 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9174 9175 ins_cost(INSN_COST * 2); 9176 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9177 9178 ins_encode %{ 9179 __ csel(as_Register($dst$$reg), 9180 as_Register($src2$$reg), 9181 as_Register($src1$$reg), 9182 (Assembler::Condition)$cmp$$cmpcode); 9183 %} 9184 9185 ins_pipe(icond_reg_reg); 9186%} 9187 9188instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9189 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9190 9191 ins_cost(INSN_COST * 2); 9192 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9193 9194 ins_encode %{ 9195 __ csel(as_Register($dst$$reg), 9196 as_Register($src2$$reg), 9197 as_Register($src1$$reg), 9198 (Assembler::Condition)$cmp$$cmpcode); 9199 %} 9200 9201 ins_pipe(icond_reg_reg); 9202%} 9203 9204// special cases where one arg is zero 9205 9206instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9207 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9208 9209 ins_cost(INSN_COST * 2); 9210 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9211 9212 ins_encode %{ 9213 __ csel(as_Register($dst$$reg), 9214 zr, 9215 as_Register($src$$reg), 9216 (Assembler::Condition)$cmp$$cmpcode); 9217 %} 9218 9219 ins_pipe(icond_reg); 9220%} 9221 9222instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9223 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9224 9225 ins_cost(INSN_COST * 2); 9226 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9227 9228 ins_encode %{ 9229 __ csel(as_Register($dst$$reg), 9230 zr, 9231 as_Register($src$$reg), 9232 (Assembler::Condition)$cmp$$cmpcode); 9233 %} 9234 9235 ins_pipe(icond_reg); 9236%} 9237 9238instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9239 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9240 9241 ins_cost(INSN_COST * 2); 9242 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9243 9244 ins_encode %{ 9245 __ csel(as_Register($dst$$reg), 9246 as_Register($src$$reg), 9247 zr, 9248 (Assembler::Condition)$cmp$$cmpcode); 9249 %} 9250 9251 ins_pipe(icond_reg); 9252%} 9253 9254instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9255 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9256 9257 ins_cost(INSN_COST * 2); 9258 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 9259 9260 ins_encode %{ 9261 __ csel(as_Register($dst$$reg), 9262 as_Register($src$$reg), 9263 zr, 9264 (Assembler::Condition)$cmp$$cmpcode); 9265 %} 9266 9267 ins_pipe(icond_reg); 9268%} 9269 9270instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9271 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9272 9273 ins_cost(INSN_COST * 2); 9274 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 9275 9276 ins_encode %{ 9277 __ csel(as_Register($dst$$reg), 9278 as_Register($src2$$reg), 9279 as_Register($src1$$reg), 9280 (Assembler::Condition)$cmp$$cmpcode); 9281 %} 9282 9283 ins_pipe(icond_reg_reg); 9284%} 9285 9286instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 9287 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 9288 9289 ins_cost(INSN_COST * 2); 9290 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 9291 9292 ins_encode %{ 9293 __ csel(as_Register($dst$$reg), 9294 as_Register($src2$$reg), 9295 as_Register($src1$$reg), 9296 (Assembler::Condition)$cmp$$cmpcode); 9297 %} 9298 9299 ins_pipe(icond_reg_reg); 9300%} 9301 9302// special cases where one arg is zero 9303 9304instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9305 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9306 9307 ins_cost(INSN_COST * 2); 9308 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 9309 9310 ins_encode %{ 9311 __ csel(as_Register($dst$$reg), 9312 zr, 9313 as_Register($src$$reg), 9314 (Assembler::Condition)$cmp$$cmpcode); 9315 %} 9316 9317 ins_pipe(icond_reg); 9318%} 9319 9320instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 9321 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 9322 9323 ins_cost(INSN_COST * 2); 9324 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 9325 9326 ins_encode %{ 9327 __ csel(as_Register($dst$$reg), 9328 zr, 9329 as_Register($src$$reg), 9330 (Assembler::Condition)$cmp$$cmpcode); 9331 %} 9332 9333 ins_pipe(icond_reg); 9334%} 9335 9336instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9337 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9338 9339 ins_cost(INSN_COST * 2); 9340 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 9341 9342 ins_encode %{ 9343 __ csel(as_Register($dst$$reg), 9344 as_Register($src$$reg), 9345 zr, 9346 (Assembler::Condition)$cmp$$cmpcode); 9347 %} 9348 9349 ins_pipe(icond_reg); 9350%} 9351 9352instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 9353 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 9354 9355 ins_cost(INSN_COST * 2); 9356 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 9357 9358 ins_encode %{ 9359 __ csel(as_Register($dst$$reg), 9360 as_Register($src$$reg), 9361 zr, 9362 (Assembler::Condition)$cmp$$cmpcode); 9363 %} 9364 9365 ins_pipe(icond_reg); 9366%} 9367 9368instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9369 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9370 9371 ins_cost(INSN_COST * 2); 9372 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9373 9374 ins_encode %{ 9375 __ cselw(as_Register($dst$$reg), 9376 as_Register($src2$$reg), 9377 as_Register($src1$$reg), 9378 (Assembler::Condition)$cmp$$cmpcode); 9379 %} 9380 9381 ins_pipe(icond_reg_reg); 9382%} 9383 9384instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 9385 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 9386 9387 ins_cost(INSN_COST * 2); 9388 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 9389 9390 ins_encode %{ 9391 __ cselw(as_Register($dst$$reg), 9392 as_Register($src2$$reg), 9393 as_Register($src1$$reg), 9394 (Assembler::Condition)$cmp$$cmpcode); 9395 %} 9396 9397 ins_pipe(icond_reg_reg); 9398%} 9399 9400// special cases where one arg is zero 9401 9402instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9403 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9404 9405 ins_cost(INSN_COST * 2); 9406 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 9407 9408 ins_encode %{ 9409 __ cselw(as_Register($dst$$reg), 9410 zr, 9411 as_Register($src$$reg), 9412 (Assembler::Condition)$cmp$$cmpcode); 9413 %} 9414 9415 ins_pipe(icond_reg); 9416%} 9417 9418instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 9419 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 9420 9421 ins_cost(INSN_COST * 2); 9422 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 9423 9424 ins_encode %{ 9425 __ cselw(as_Register($dst$$reg), 9426 zr, 9427 as_Register($src$$reg), 9428 (Assembler::Condition)$cmp$$cmpcode); 9429 %} 9430 9431 ins_pipe(icond_reg); 9432%} 9433 9434instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9435 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9436 9437 ins_cost(INSN_COST * 2); 9438 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 9439 9440 ins_encode %{ 9441 __ cselw(as_Register($dst$$reg), 9442 as_Register($src$$reg), 9443 zr, 9444 (Assembler::Condition)$cmp$$cmpcode); 9445 %} 9446 9447 ins_pipe(icond_reg); 9448%} 9449 9450instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 9451 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 9452 9453 ins_cost(INSN_COST * 2); 9454 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 9455 9456 ins_encode %{ 9457 __ cselw(as_Register($dst$$reg), 9458 as_Register($src$$reg), 9459 zr, 9460 (Assembler::Condition)$cmp$$cmpcode); 9461 %} 9462 9463 ins_pipe(icond_reg); 9464%} 9465 9466instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 9467%{ 9468 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9469 9470 ins_cost(INSN_COST * 3); 9471 9472 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9473 ins_encode %{ 9474 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9475 __ fcsels(as_FloatRegister($dst$$reg), 9476 as_FloatRegister($src2$$reg), 9477 as_FloatRegister($src1$$reg), 9478 cond); 9479 %} 9480 9481 ins_pipe(fp_cond_reg_reg_s); 9482%} 9483 9484instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 9485%{ 9486 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 9487 9488 ins_cost(INSN_COST * 3); 9489 9490 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9491 ins_encode %{ 9492 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9493 __ fcsels(as_FloatRegister($dst$$reg), 9494 as_FloatRegister($src2$$reg), 9495 as_FloatRegister($src1$$reg), 9496 cond); 9497 %} 9498 9499 ins_pipe(fp_cond_reg_reg_s); 9500%} 9501 9502instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 9503%{ 9504 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9505 9506 ins_cost(INSN_COST * 3); 9507 9508 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 9509 ins_encode %{ 9510 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9511 __ fcseld(as_FloatRegister($dst$$reg), 9512 as_FloatRegister($src2$$reg), 9513 as_FloatRegister($src1$$reg), 9514 cond); 9515 %} 9516 9517 ins_pipe(fp_cond_reg_reg_d); 9518%} 9519 9520instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 9521%{ 9522 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 9523 9524 ins_cost(INSN_COST * 3); 9525 9526 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 9527 ins_encode %{ 9528 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 9529 __ fcseld(as_FloatRegister($dst$$reg), 9530 as_FloatRegister($src2$$reg), 9531 as_FloatRegister($src1$$reg), 9532 cond); 9533 %} 9534 9535 ins_pipe(fp_cond_reg_reg_d); 9536%} 9537 9538// ============================================================================ 9539// Arithmetic Instructions 9540// 9541 9542// Integer Addition 9543 9544// TODO 9545// these currently employ operations which do not set CR and hence are 9546// not flagged as killing CR but we would like to isolate the cases 9547// where we want to set flags from those where we don't. need to work 9548// out how to do that. 9549 9550instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9551 match(Set dst (AddI src1 src2)); 9552 9553 ins_cost(INSN_COST); 9554 format %{ "addw $dst, $src1, $src2" %} 9555 9556 ins_encode %{ 9557 __ addw(as_Register($dst$$reg), 9558 as_Register($src1$$reg), 9559 as_Register($src2$$reg)); 9560 %} 9561 9562 ins_pipe(ialu_reg_reg); 9563%} 9564 9565instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9566 match(Set dst (AddI src1 src2)); 9567 9568 ins_cost(INSN_COST); 9569 format %{ "addw $dst, $src1, $src2" %} 9570 9571 // use opcode to indicate that this is an add not a sub 9572 opcode(0x0); 9573 9574 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9575 9576 ins_pipe(ialu_reg_imm); 9577%} 9578 9579instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 9580 match(Set dst (AddI (ConvL2I src1) src2)); 9581 9582 ins_cost(INSN_COST); 9583 format %{ "addw $dst, $src1, $src2" %} 9584 9585 // use opcode to indicate that this is an add not a sub 9586 opcode(0x0); 9587 9588 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9589 9590 ins_pipe(ialu_reg_imm); 9591%} 9592 9593// Pointer Addition 9594instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 9595 match(Set dst (AddP src1 src2)); 9596 9597 ins_cost(INSN_COST); 9598 format %{ "add $dst, $src1, $src2\t# ptr" %} 9599 9600 ins_encode %{ 9601 __ add(as_Register($dst$$reg), 9602 as_Register($src1$$reg), 9603 as_Register($src2$$reg)); 9604 %} 9605 9606 ins_pipe(ialu_reg_reg); 9607%} 9608 9609instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 9610 match(Set dst (AddP src1 (ConvI2L src2))); 9611 9612 ins_cost(1.9 * INSN_COST); 9613 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 9614 9615 ins_encode %{ 9616 __ add(as_Register($dst$$reg), 9617 as_Register($src1$$reg), 9618 as_Register($src2$$reg), ext::sxtw); 9619 %} 9620 9621 ins_pipe(ialu_reg_reg); 9622%} 9623 9624instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 9625 match(Set dst (AddP src1 (LShiftL src2 scale))); 9626 9627 ins_cost(1.9 * INSN_COST); 9628 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 9629 9630 ins_encode %{ 9631 __ lea(as_Register($dst$$reg), 9632 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9633 Address::lsl($scale$$constant))); 9634 %} 9635 9636 ins_pipe(ialu_reg_reg_shift); 9637%} 9638 9639instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 9640 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 9641 9642 ins_cost(1.9 * INSN_COST); 9643 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 9644 9645 ins_encode %{ 9646 __ lea(as_Register($dst$$reg), 9647 Address(as_Register($src1$$reg), as_Register($src2$$reg), 9648 Address::sxtw($scale$$constant))); 9649 %} 9650 9651 ins_pipe(ialu_reg_reg_shift); 9652%} 9653 9654instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 9655 match(Set dst (LShiftL (ConvI2L src) scale)); 9656 9657 ins_cost(INSN_COST); 9658 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 9659 9660 ins_encode %{ 9661 __ sbfiz(as_Register($dst$$reg), 9662 as_Register($src$$reg), 9663 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 9664 %} 9665 9666 ins_pipe(ialu_reg_shift); 9667%} 9668 9669// Pointer Immediate Addition 9670// n.b. this needs to be more expensive than using an indirect memory 9671// operand 9672instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 9673 match(Set dst (AddP src1 src2)); 9674 9675 ins_cost(INSN_COST); 9676 format %{ "add $dst, $src1, $src2\t# ptr" %} 9677 9678 // use opcode to indicate that this is an add not a sub 9679 opcode(0x0); 9680 9681 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9682 9683 ins_pipe(ialu_reg_imm); 9684%} 9685 9686// Long Addition 9687instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9688 9689 match(Set dst (AddL src1 src2)); 9690 9691 ins_cost(INSN_COST); 9692 format %{ "add $dst, $src1, $src2" %} 9693 9694 ins_encode %{ 9695 __ add(as_Register($dst$$reg), 9696 as_Register($src1$$reg), 9697 as_Register($src2$$reg)); 9698 %} 9699 9700 ins_pipe(ialu_reg_reg); 9701%} 9702 9703// No constant pool entries requiredLong Immediate Addition. 9704instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9705 match(Set dst (AddL src1 src2)); 9706 9707 ins_cost(INSN_COST); 9708 format %{ "add $dst, $src1, $src2" %} 9709 9710 // use opcode to indicate that this is an add not a sub 9711 opcode(0x0); 9712 9713 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9714 9715 ins_pipe(ialu_reg_imm); 9716%} 9717 9718// Integer Subtraction 9719instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9720 match(Set dst (SubI src1 src2)); 9721 9722 ins_cost(INSN_COST); 9723 format %{ "subw $dst, $src1, $src2" %} 9724 9725 ins_encode %{ 9726 __ subw(as_Register($dst$$reg), 9727 as_Register($src1$$reg), 9728 as_Register($src2$$reg)); 9729 %} 9730 9731 ins_pipe(ialu_reg_reg); 9732%} 9733 9734// Immediate Subtraction 9735instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 9736 match(Set dst (SubI src1 src2)); 9737 9738 ins_cost(INSN_COST); 9739 format %{ "subw $dst, $src1, $src2" %} 9740 9741 // use opcode to indicate that this is a sub not an add 9742 opcode(0x1); 9743 9744 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 9745 9746 ins_pipe(ialu_reg_imm); 9747%} 9748 9749// Long Subtraction 9750instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9751 9752 match(Set dst (SubL src1 src2)); 9753 9754 ins_cost(INSN_COST); 9755 format %{ "sub $dst, $src1, $src2" %} 9756 9757 ins_encode %{ 9758 __ sub(as_Register($dst$$reg), 9759 as_Register($src1$$reg), 9760 as_Register($src2$$reg)); 9761 %} 9762 9763 ins_pipe(ialu_reg_reg); 9764%} 9765 9766// No constant pool entries requiredLong Immediate Subtraction. 9767instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 9768 match(Set dst (SubL src1 src2)); 9769 9770 ins_cost(INSN_COST); 9771 format %{ "sub$dst, $src1, $src2" %} 9772 9773 // use opcode to indicate that this is a sub not an add 9774 opcode(0x1); 9775 9776 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 9777 9778 ins_pipe(ialu_reg_imm); 9779%} 9780 9781// Integer Negation (special case for sub) 9782 9783instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 9784 match(Set dst (SubI zero src)); 9785 9786 ins_cost(INSN_COST); 9787 format %{ "negw $dst, $src\t# int" %} 9788 9789 ins_encode %{ 9790 __ negw(as_Register($dst$$reg), 9791 as_Register($src$$reg)); 9792 %} 9793 9794 ins_pipe(ialu_reg); 9795%} 9796 9797// Long Negation 9798 9799instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 9800 match(Set dst (SubL zero src)); 9801 9802 ins_cost(INSN_COST); 9803 format %{ "neg $dst, $src\t# long" %} 9804 9805 ins_encode %{ 9806 __ neg(as_Register($dst$$reg), 9807 as_Register($src$$reg)); 9808 %} 9809 9810 ins_pipe(ialu_reg); 9811%} 9812 9813// Integer Multiply 9814 9815instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9816 match(Set dst (MulI src1 src2)); 9817 9818 ins_cost(INSN_COST * 3); 9819 format %{ "mulw $dst, $src1, $src2" %} 9820 9821 ins_encode %{ 9822 __ mulw(as_Register($dst$$reg), 9823 as_Register($src1$$reg), 9824 as_Register($src2$$reg)); 9825 %} 9826 9827 ins_pipe(imul_reg_reg); 9828%} 9829 9830instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9831 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 9832 9833 ins_cost(INSN_COST * 3); 9834 format %{ "smull $dst, $src1, $src2" %} 9835 9836 ins_encode %{ 9837 __ smull(as_Register($dst$$reg), 9838 as_Register($src1$$reg), 9839 as_Register($src2$$reg)); 9840 %} 9841 9842 ins_pipe(imul_reg_reg); 9843%} 9844 9845// Long Multiply 9846 9847instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9848 match(Set dst (MulL src1 src2)); 9849 9850 ins_cost(INSN_COST * 5); 9851 format %{ "mul $dst, $src1, $src2" %} 9852 9853 ins_encode %{ 9854 __ mul(as_Register($dst$$reg), 9855 as_Register($src1$$reg), 9856 as_Register($src2$$reg)); 9857 %} 9858 9859 ins_pipe(lmul_reg_reg); 9860%} 9861 9862instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 9863%{ 9864 match(Set dst (MulHiL src1 src2)); 9865 9866 ins_cost(INSN_COST * 7); 9867 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 9868 9869 ins_encode %{ 9870 __ smulh(as_Register($dst$$reg), 9871 as_Register($src1$$reg), 9872 as_Register($src2$$reg)); 9873 %} 9874 9875 ins_pipe(lmul_reg_reg); 9876%} 9877 9878// Combined Integer Multiply & Add/Sub 9879 9880instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9881 match(Set dst (AddI src3 (MulI src1 src2))); 9882 9883 ins_cost(INSN_COST * 3); 9884 format %{ "madd $dst, $src1, $src2, $src3" %} 9885 9886 ins_encode %{ 9887 __ maddw(as_Register($dst$$reg), 9888 as_Register($src1$$reg), 9889 as_Register($src2$$reg), 9890 as_Register($src3$$reg)); 9891 %} 9892 9893 ins_pipe(imac_reg_reg); 9894%} 9895 9896instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 9897 match(Set dst (SubI src3 (MulI src1 src2))); 9898 9899 ins_cost(INSN_COST * 3); 9900 format %{ "msub $dst, $src1, $src2, $src3" %} 9901 9902 ins_encode %{ 9903 __ msubw(as_Register($dst$$reg), 9904 as_Register($src1$$reg), 9905 as_Register($src2$$reg), 9906 as_Register($src3$$reg)); 9907 %} 9908 9909 ins_pipe(imac_reg_reg); 9910%} 9911 9912// Combined Long Multiply & Add/Sub 9913 9914instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9915 match(Set dst (AddL src3 (MulL src1 src2))); 9916 9917 ins_cost(INSN_COST * 5); 9918 format %{ "madd $dst, $src1, $src2, $src3" %} 9919 9920 ins_encode %{ 9921 __ madd(as_Register($dst$$reg), 9922 as_Register($src1$$reg), 9923 as_Register($src2$$reg), 9924 as_Register($src3$$reg)); 9925 %} 9926 9927 ins_pipe(lmac_reg_reg); 9928%} 9929 9930instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 9931 match(Set dst (SubL src3 (MulL src1 src2))); 9932 9933 ins_cost(INSN_COST * 5); 9934 format %{ "msub $dst, $src1, $src2, $src3" %} 9935 9936 ins_encode %{ 9937 __ msub(as_Register($dst$$reg), 9938 as_Register($src1$$reg), 9939 as_Register($src2$$reg), 9940 as_Register($src3$$reg)); 9941 %} 9942 9943 ins_pipe(lmac_reg_reg); 9944%} 9945 9946// Combine Integer Signed Multiply & Add/Sub/Neg Long 9947 9948instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 9949 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 9950 9951 ins_cost(INSN_COST * 3); 9952 format %{ "smaddl $dst, $src1, $src2, $src3" %} 9953 9954 ins_encode %{ 9955 __ smaddl(as_Register($dst$$reg), 9956 as_Register($src1$$reg), 9957 as_Register($src2$$reg), 9958 as_Register($src3$$reg)); 9959 %} 9960 9961 ins_pipe(imac_reg_reg); 9962%} 9963 9964instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 9965 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 9966 9967 ins_cost(INSN_COST * 3); 9968 format %{ "smsubl $dst, $src1, $src2, $src3" %} 9969 9970 ins_encode %{ 9971 __ smsubl(as_Register($dst$$reg), 9972 as_Register($src1$$reg), 9973 as_Register($src2$$reg), 9974 as_Register($src3$$reg)); 9975 %} 9976 9977 ins_pipe(imac_reg_reg); 9978%} 9979 9980instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 9981 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 9982 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 9983 9984 ins_cost(INSN_COST * 3); 9985 format %{ "smnegl $dst, $src1, $src2" %} 9986 9987 ins_encode %{ 9988 __ smnegl(as_Register($dst$$reg), 9989 as_Register($src1$$reg), 9990 as_Register($src2$$reg)); 9991 %} 9992 9993 ins_pipe(imac_reg_reg); 9994%} 9995 9996// Integer Divide 9997 9998instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9999 match(Set dst (DivI src1 src2)); 10000 10001 ins_cost(INSN_COST * 19); 10002 format %{ "sdivw $dst, $src1, $src2" %} 10003 10004 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10005 ins_pipe(idiv_reg_reg); 10006%} 10007 10008// Long Divide 10009 10010instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10011 match(Set dst (DivL src1 src2)); 10012 10013 ins_cost(INSN_COST * 35); 10014 format %{ "sdiv $dst, $src1, $src2" %} 10015 10016 ins_encode(aarch64_enc_div(dst, src1, src2)); 10017 ins_pipe(ldiv_reg_reg); 10018%} 10019 10020// Integer Remainder 10021 10022instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10023 match(Set dst (ModI src1 src2)); 10024 10025 ins_cost(INSN_COST * 22); 10026 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10027 "msubw($dst, rscratch1, $src2, $src1" %} 10028 10029 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10030 ins_pipe(idiv_reg_reg); 10031%} 10032 10033// Long Remainder 10034 10035instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10036 match(Set dst (ModL src1 src2)); 10037 10038 ins_cost(INSN_COST * 38); 10039 format %{ "sdiv rscratch1, $src1, $src2\n" 10040 "msub($dst, rscratch1, $src2, $src1" %} 10041 10042 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10043 ins_pipe(ldiv_reg_reg); 10044%} 10045 10046// Integer Shifts 10047 10048// Shift Left Register 10049instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10050 match(Set dst (LShiftI src1 src2)); 10051 10052 ins_cost(INSN_COST * 2); 10053 format %{ "lslvw $dst, $src1, $src2" %} 10054 10055 ins_encode %{ 10056 __ lslvw(as_Register($dst$$reg), 10057 as_Register($src1$$reg), 10058 as_Register($src2$$reg)); 10059 %} 10060 10061 ins_pipe(ialu_reg_reg_vshift); 10062%} 10063 10064// Shift Left Immediate 10065instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10066 match(Set dst (LShiftI src1 src2)); 10067 10068 ins_cost(INSN_COST); 10069 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10070 10071 ins_encode %{ 10072 __ lslw(as_Register($dst$$reg), 10073 as_Register($src1$$reg), 10074 $src2$$constant & 0x1f); 10075 %} 10076 10077 ins_pipe(ialu_reg_shift); 10078%} 10079 10080// Shift Right Logical Register 10081instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10082 match(Set dst (URShiftI src1 src2)); 10083 10084 ins_cost(INSN_COST * 2); 10085 format %{ "lsrvw $dst, $src1, $src2" %} 10086 10087 ins_encode %{ 10088 __ lsrvw(as_Register($dst$$reg), 10089 as_Register($src1$$reg), 10090 as_Register($src2$$reg)); 10091 %} 10092 10093 ins_pipe(ialu_reg_reg_vshift); 10094%} 10095 10096// Shift Right Logical Immediate 10097instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10098 match(Set dst (URShiftI src1 src2)); 10099 10100 ins_cost(INSN_COST); 10101 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10102 10103 ins_encode %{ 10104 __ lsrw(as_Register($dst$$reg), 10105 as_Register($src1$$reg), 10106 $src2$$constant & 0x1f); 10107 %} 10108 10109 ins_pipe(ialu_reg_shift); 10110%} 10111 10112// Shift Right Arithmetic Register 10113instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10114 match(Set dst (RShiftI src1 src2)); 10115 10116 ins_cost(INSN_COST * 2); 10117 format %{ "asrvw $dst, $src1, $src2" %} 10118 10119 ins_encode %{ 10120 __ asrvw(as_Register($dst$$reg), 10121 as_Register($src1$$reg), 10122 as_Register($src2$$reg)); 10123 %} 10124 10125 ins_pipe(ialu_reg_reg_vshift); 10126%} 10127 10128// Shift Right Arithmetic Immediate 10129instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10130 match(Set dst (RShiftI src1 src2)); 10131 10132 ins_cost(INSN_COST); 10133 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 10134 10135 ins_encode %{ 10136 __ asrw(as_Register($dst$$reg), 10137 as_Register($src1$$reg), 10138 $src2$$constant & 0x1f); 10139 %} 10140 10141 ins_pipe(ialu_reg_shift); 10142%} 10143 10144// Combined Int Mask and Right Shift (using UBFM) 10145// TODO 10146 10147// Long Shifts 10148 10149// Shift Left Register 10150instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10151 match(Set dst (LShiftL src1 src2)); 10152 10153 ins_cost(INSN_COST * 2); 10154 format %{ "lslv $dst, $src1, $src2" %} 10155 10156 ins_encode %{ 10157 __ lslv(as_Register($dst$$reg), 10158 as_Register($src1$$reg), 10159 as_Register($src2$$reg)); 10160 %} 10161 10162 ins_pipe(ialu_reg_reg_vshift); 10163%} 10164 10165// Shift Left Immediate 10166instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10167 match(Set dst (LShiftL src1 src2)); 10168 10169 ins_cost(INSN_COST); 10170 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 10171 10172 ins_encode %{ 10173 __ lsl(as_Register($dst$$reg), 10174 as_Register($src1$$reg), 10175 $src2$$constant & 0x3f); 10176 %} 10177 10178 ins_pipe(ialu_reg_shift); 10179%} 10180 10181// Shift Right Logical Register 10182instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10183 match(Set dst (URShiftL src1 src2)); 10184 10185 ins_cost(INSN_COST * 2); 10186 format %{ "lsrv $dst, $src1, $src2" %} 10187 10188 ins_encode %{ 10189 __ lsrv(as_Register($dst$$reg), 10190 as_Register($src1$$reg), 10191 as_Register($src2$$reg)); 10192 %} 10193 10194 ins_pipe(ialu_reg_reg_vshift); 10195%} 10196 10197// Shift Right Logical Immediate 10198instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10199 match(Set dst (URShiftL src1 src2)); 10200 10201 ins_cost(INSN_COST); 10202 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 10203 10204 ins_encode %{ 10205 __ lsr(as_Register($dst$$reg), 10206 as_Register($src1$$reg), 10207 $src2$$constant & 0x3f); 10208 %} 10209 10210 ins_pipe(ialu_reg_shift); 10211%} 10212 10213// A special-case pattern for card table stores. 10214instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 10215 match(Set dst (URShiftL (CastP2X src1) src2)); 10216 10217 ins_cost(INSN_COST); 10218 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 10219 10220 ins_encode %{ 10221 __ lsr(as_Register($dst$$reg), 10222 as_Register($src1$$reg), 10223 $src2$$constant & 0x3f); 10224 %} 10225 10226 ins_pipe(ialu_reg_shift); 10227%} 10228 10229// Shift Right Arithmetic Register 10230instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 10231 match(Set dst (RShiftL src1 src2)); 10232 10233 ins_cost(INSN_COST * 2); 10234 format %{ "asrv $dst, $src1, $src2" %} 10235 10236 ins_encode %{ 10237 __ asrv(as_Register($dst$$reg), 10238 as_Register($src1$$reg), 10239 as_Register($src2$$reg)); 10240 %} 10241 10242 ins_pipe(ialu_reg_reg_vshift); 10243%} 10244 10245// Shift Right Arithmetic Immediate 10246instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 10247 match(Set dst (RShiftL src1 src2)); 10248 10249 ins_cost(INSN_COST); 10250 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 10251 10252 ins_encode %{ 10253 __ asr(as_Register($dst$$reg), 10254 as_Register($src1$$reg), 10255 $src2$$constant & 0x3f); 10256 %} 10257 10258 ins_pipe(ialu_reg_shift); 10259%} 10260 10261// BEGIN This section of the file is automatically generated. Do not edit -------------- 10262 10263 10264 10265// This pattern is automatically generated from aarch64_ad.m4 10266// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10267instruct regL_not_reg(iRegLNoSp dst, 10268 iRegL src1, immL_M1 m1, 10269 rFlagsReg cr) %{ 10270 match(Set dst (XorL src1 m1)); 10271 ins_cost(INSN_COST); 10272 format %{ "eon $dst, $src1, zr" %} 10273 10274 ins_encode %{ 10275 __ eon(as_Register($dst$$reg), 10276 as_Register($src1$$reg), 10277 zr, 10278 Assembler::LSL, 0); 10279 %} 10280 10281 ins_pipe(ialu_reg); 10282%} 10283 10284// This pattern is automatically generated from aarch64_ad.m4 10285// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10286instruct regI_not_reg(iRegINoSp dst, 10287 iRegIorL2I src1, immI_M1 m1, 10288 rFlagsReg cr) %{ 10289 match(Set dst (XorI src1 m1)); 10290 ins_cost(INSN_COST); 10291 format %{ "eonw $dst, $src1, zr" %} 10292 10293 ins_encode %{ 10294 __ eonw(as_Register($dst$$reg), 10295 as_Register($src1$$reg), 10296 zr, 10297 Assembler::LSL, 0); 10298 %} 10299 10300 ins_pipe(ialu_reg); 10301%} 10302 10303// This pattern is automatically generated from aarch64_ad.m4 10304// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10305instruct AndI_reg_not_reg(iRegINoSp dst, 10306 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10307 rFlagsReg cr) %{ 10308 match(Set dst (AndI src1 (XorI src2 m1))); 10309 ins_cost(INSN_COST); 10310 format %{ "bicw $dst, $src1, $src2" %} 10311 10312 ins_encode %{ 10313 __ bicw(as_Register($dst$$reg), 10314 as_Register($src1$$reg), 10315 as_Register($src2$$reg), 10316 Assembler::LSL, 0); 10317 %} 10318 10319 ins_pipe(ialu_reg_reg); 10320%} 10321 10322// This pattern is automatically generated from aarch64_ad.m4 10323// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10324instruct AndL_reg_not_reg(iRegLNoSp dst, 10325 iRegL src1, iRegL src2, immL_M1 m1, 10326 rFlagsReg cr) %{ 10327 match(Set dst (AndL src1 (XorL src2 m1))); 10328 ins_cost(INSN_COST); 10329 format %{ "bic $dst, $src1, $src2" %} 10330 10331 ins_encode %{ 10332 __ bic(as_Register($dst$$reg), 10333 as_Register($src1$$reg), 10334 as_Register($src2$$reg), 10335 Assembler::LSL, 0); 10336 %} 10337 10338 ins_pipe(ialu_reg_reg); 10339%} 10340 10341// This pattern is automatically generated from aarch64_ad.m4 10342// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10343instruct OrI_reg_not_reg(iRegINoSp dst, 10344 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10345 rFlagsReg cr) %{ 10346 match(Set dst (OrI src1 (XorI src2 m1))); 10347 ins_cost(INSN_COST); 10348 format %{ "ornw $dst, $src1, $src2" %} 10349 10350 ins_encode %{ 10351 __ ornw(as_Register($dst$$reg), 10352 as_Register($src1$$reg), 10353 as_Register($src2$$reg), 10354 Assembler::LSL, 0); 10355 %} 10356 10357 ins_pipe(ialu_reg_reg); 10358%} 10359 10360// This pattern is automatically generated from aarch64_ad.m4 10361// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10362instruct OrL_reg_not_reg(iRegLNoSp dst, 10363 iRegL src1, iRegL src2, immL_M1 m1, 10364 rFlagsReg cr) %{ 10365 match(Set dst (OrL src1 (XorL src2 m1))); 10366 ins_cost(INSN_COST); 10367 format %{ "orn $dst, $src1, $src2" %} 10368 10369 ins_encode %{ 10370 __ orn(as_Register($dst$$reg), 10371 as_Register($src1$$reg), 10372 as_Register($src2$$reg), 10373 Assembler::LSL, 0); 10374 %} 10375 10376 ins_pipe(ialu_reg_reg); 10377%} 10378 10379// This pattern is automatically generated from aarch64_ad.m4 10380// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10381instruct XorI_reg_not_reg(iRegINoSp dst, 10382 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 10383 rFlagsReg cr) %{ 10384 match(Set dst (XorI m1 (XorI src2 src1))); 10385 ins_cost(INSN_COST); 10386 format %{ "eonw $dst, $src1, $src2" %} 10387 10388 ins_encode %{ 10389 __ eonw(as_Register($dst$$reg), 10390 as_Register($src1$$reg), 10391 as_Register($src2$$reg), 10392 Assembler::LSL, 0); 10393 %} 10394 10395 ins_pipe(ialu_reg_reg); 10396%} 10397 10398// This pattern is automatically generated from aarch64_ad.m4 10399// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10400instruct XorL_reg_not_reg(iRegLNoSp dst, 10401 iRegL src1, iRegL src2, immL_M1 m1, 10402 rFlagsReg cr) %{ 10403 match(Set dst (XorL m1 (XorL src2 src1))); 10404 ins_cost(INSN_COST); 10405 format %{ "eon $dst, $src1, $src2" %} 10406 10407 ins_encode %{ 10408 __ eon(as_Register($dst$$reg), 10409 as_Register($src1$$reg), 10410 as_Register($src2$$reg), 10411 Assembler::LSL, 0); 10412 %} 10413 10414 ins_pipe(ialu_reg_reg); 10415%} 10416 10417// This pattern is automatically generated from aarch64_ad.m4 10418// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10419instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 10420 iRegIorL2I src1, iRegIorL2I src2, 10421 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10422 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 10423 ins_cost(1.9 * INSN_COST); 10424 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 10425 10426 ins_encode %{ 10427 __ bicw(as_Register($dst$$reg), 10428 as_Register($src1$$reg), 10429 as_Register($src2$$reg), 10430 Assembler::LSR, 10431 $src3$$constant & 0x1f); 10432 %} 10433 10434 ins_pipe(ialu_reg_reg_shift); 10435%} 10436 10437// This pattern is automatically generated from aarch64_ad.m4 10438// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10439instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 10440 iRegL src1, iRegL src2, 10441 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10442 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 10443 ins_cost(1.9 * INSN_COST); 10444 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 10445 10446 ins_encode %{ 10447 __ bic(as_Register($dst$$reg), 10448 as_Register($src1$$reg), 10449 as_Register($src2$$reg), 10450 Assembler::LSR, 10451 $src3$$constant & 0x3f); 10452 %} 10453 10454 ins_pipe(ialu_reg_reg_shift); 10455%} 10456 10457// This pattern is automatically generated from aarch64_ad.m4 10458// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10459instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 10460 iRegIorL2I src1, iRegIorL2I src2, 10461 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10462 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 10463 ins_cost(1.9 * INSN_COST); 10464 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 10465 10466 ins_encode %{ 10467 __ bicw(as_Register($dst$$reg), 10468 as_Register($src1$$reg), 10469 as_Register($src2$$reg), 10470 Assembler::ASR, 10471 $src3$$constant & 0x1f); 10472 %} 10473 10474 ins_pipe(ialu_reg_reg_shift); 10475%} 10476 10477// This pattern is automatically generated from aarch64_ad.m4 10478// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10479instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 10480 iRegL src1, iRegL src2, 10481 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10482 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 10483 ins_cost(1.9 * INSN_COST); 10484 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 10485 10486 ins_encode %{ 10487 __ bic(as_Register($dst$$reg), 10488 as_Register($src1$$reg), 10489 as_Register($src2$$reg), 10490 Assembler::ASR, 10491 $src3$$constant & 0x3f); 10492 %} 10493 10494 ins_pipe(ialu_reg_reg_shift); 10495%} 10496 10497// This pattern is automatically generated from aarch64_ad.m4 10498// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10499instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 10500 iRegIorL2I src1, iRegIorL2I src2, 10501 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10502 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 10503 ins_cost(1.9 * INSN_COST); 10504 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 10505 10506 ins_encode %{ 10507 __ bicw(as_Register($dst$$reg), 10508 as_Register($src1$$reg), 10509 as_Register($src2$$reg), 10510 Assembler::LSL, 10511 $src3$$constant & 0x1f); 10512 %} 10513 10514 ins_pipe(ialu_reg_reg_shift); 10515%} 10516 10517// This pattern is automatically generated from aarch64_ad.m4 10518// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10519instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 10520 iRegL src1, iRegL src2, 10521 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10522 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 10523 ins_cost(1.9 * INSN_COST); 10524 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 10525 10526 ins_encode %{ 10527 __ bic(as_Register($dst$$reg), 10528 as_Register($src1$$reg), 10529 as_Register($src2$$reg), 10530 Assembler::LSL, 10531 $src3$$constant & 0x3f); 10532 %} 10533 10534 ins_pipe(ialu_reg_reg_shift); 10535%} 10536 10537// This pattern is automatically generated from aarch64_ad.m4 10538// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10539instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 10540 iRegIorL2I src1, iRegIorL2I src2, 10541 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10542 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 10543 ins_cost(1.9 * INSN_COST); 10544 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 10545 10546 ins_encode %{ 10547 __ eonw(as_Register($dst$$reg), 10548 as_Register($src1$$reg), 10549 as_Register($src2$$reg), 10550 Assembler::LSR, 10551 $src3$$constant & 0x1f); 10552 %} 10553 10554 ins_pipe(ialu_reg_reg_shift); 10555%} 10556 10557// This pattern is automatically generated from aarch64_ad.m4 10558// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10559instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 10560 iRegL src1, iRegL src2, 10561 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10562 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 10563 ins_cost(1.9 * INSN_COST); 10564 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 10565 10566 ins_encode %{ 10567 __ eon(as_Register($dst$$reg), 10568 as_Register($src1$$reg), 10569 as_Register($src2$$reg), 10570 Assembler::LSR, 10571 $src3$$constant & 0x3f); 10572 %} 10573 10574 ins_pipe(ialu_reg_reg_shift); 10575%} 10576 10577// This pattern is automatically generated from aarch64_ad.m4 10578// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10579instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 10580 iRegIorL2I src1, iRegIorL2I src2, 10581 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10582 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 10583 ins_cost(1.9 * INSN_COST); 10584 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 10585 10586 ins_encode %{ 10587 __ eonw(as_Register($dst$$reg), 10588 as_Register($src1$$reg), 10589 as_Register($src2$$reg), 10590 Assembler::ASR, 10591 $src3$$constant & 0x1f); 10592 %} 10593 10594 ins_pipe(ialu_reg_reg_shift); 10595%} 10596 10597// This pattern is automatically generated from aarch64_ad.m4 10598// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10599instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 10600 iRegL src1, iRegL src2, 10601 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10602 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 10603 ins_cost(1.9 * INSN_COST); 10604 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 10605 10606 ins_encode %{ 10607 __ eon(as_Register($dst$$reg), 10608 as_Register($src1$$reg), 10609 as_Register($src2$$reg), 10610 Assembler::ASR, 10611 $src3$$constant & 0x3f); 10612 %} 10613 10614 ins_pipe(ialu_reg_reg_shift); 10615%} 10616 10617// This pattern is automatically generated from aarch64_ad.m4 10618// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10619instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 10620 iRegIorL2I src1, iRegIorL2I src2, 10621 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10622 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 10623 ins_cost(1.9 * INSN_COST); 10624 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 10625 10626 ins_encode %{ 10627 __ eonw(as_Register($dst$$reg), 10628 as_Register($src1$$reg), 10629 as_Register($src2$$reg), 10630 Assembler::LSL, 10631 $src3$$constant & 0x1f); 10632 %} 10633 10634 ins_pipe(ialu_reg_reg_shift); 10635%} 10636 10637// This pattern is automatically generated from aarch64_ad.m4 10638// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10639instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 10640 iRegL src1, iRegL src2, 10641 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10642 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 10643 ins_cost(1.9 * INSN_COST); 10644 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 10645 10646 ins_encode %{ 10647 __ eon(as_Register($dst$$reg), 10648 as_Register($src1$$reg), 10649 as_Register($src2$$reg), 10650 Assembler::LSL, 10651 $src3$$constant & 0x3f); 10652 %} 10653 10654 ins_pipe(ialu_reg_reg_shift); 10655%} 10656 10657// This pattern is automatically generated from aarch64_ad.m4 10658// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10659instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 10660 iRegIorL2I src1, iRegIorL2I src2, 10661 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10662 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 10663 ins_cost(1.9 * INSN_COST); 10664 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 10665 10666 ins_encode %{ 10667 __ ornw(as_Register($dst$$reg), 10668 as_Register($src1$$reg), 10669 as_Register($src2$$reg), 10670 Assembler::LSR, 10671 $src3$$constant & 0x1f); 10672 %} 10673 10674 ins_pipe(ialu_reg_reg_shift); 10675%} 10676 10677// This pattern is automatically generated from aarch64_ad.m4 10678// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10679instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 10680 iRegL src1, iRegL src2, 10681 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10682 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 10683 ins_cost(1.9 * INSN_COST); 10684 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 10685 10686 ins_encode %{ 10687 __ orn(as_Register($dst$$reg), 10688 as_Register($src1$$reg), 10689 as_Register($src2$$reg), 10690 Assembler::LSR, 10691 $src3$$constant & 0x3f); 10692 %} 10693 10694 ins_pipe(ialu_reg_reg_shift); 10695%} 10696 10697// This pattern is automatically generated from aarch64_ad.m4 10698// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10699instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 10700 iRegIorL2I src1, iRegIorL2I src2, 10701 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10702 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 10703 ins_cost(1.9 * INSN_COST); 10704 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 10705 10706 ins_encode %{ 10707 __ ornw(as_Register($dst$$reg), 10708 as_Register($src1$$reg), 10709 as_Register($src2$$reg), 10710 Assembler::ASR, 10711 $src3$$constant & 0x1f); 10712 %} 10713 10714 ins_pipe(ialu_reg_reg_shift); 10715%} 10716 10717// This pattern is automatically generated from aarch64_ad.m4 10718// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10719instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 10720 iRegL src1, iRegL src2, 10721 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10722 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 10723 ins_cost(1.9 * INSN_COST); 10724 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 10725 10726 ins_encode %{ 10727 __ orn(as_Register($dst$$reg), 10728 as_Register($src1$$reg), 10729 as_Register($src2$$reg), 10730 Assembler::ASR, 10731 $src3$$constant & 0x3f); 10732 %} 10733 10734 ins_pipe(ialu_reg_reg_shift); 10735%} 10736 10737// This pattern is automatically generated from aarch64_ad.m4 10738// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10739instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 10740 iRegIorL2I src1, iRegIorL2I src2, 10741 immI src3, immI_M1 src4, rFlagsReg cr) %{ 10742 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 10743 ins_cost(1.9 * INSN_COST); 10744 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 10745 10746 ins_encode %{ 10747 __ ornw(as_Register($dst$$reg), 10748 as_Register($src1$$reg), 10749 as_Register($src2$$reg), 10750 Assembler::LSL, 10751 $src3$$constant & 0x1f); 10752 %} 10753 10754 ins_pipe(ialu_reg_reg_shift); 10755%} 10756 10757// This pattern is automatically generated from aarch64_ad.m4 10758// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10759instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 10760 iRegL src1, iRegL src2, 10761 immI src3, immL_M1 src4, rFlagsReg cr) %{ 10762 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 10763 ins_cost(1.9 * INSN_COST); 10764 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 10765 10766 ins_encode %{ 10767 __ orn(as_Register($dst$$reg), 10768 as_Register($src1$$reg), 10769 as_Register($src2$$reg), 10770 Assembler::LSL, 10771 $src3$$constant & 0x3f); 10772 %} 10773 10774 ins_pipe(ialu_reg_reg_shift); 10775%} 10776 10777// This pattern is automatically generated from aarch64_ad.m4 10778// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10779instruct AndI_reg_URShift_reg(iRegINoSp dst, 10780 iRegIorL2I src1, iRegIorL2I src2, 10781 immI src3, rFlagsReg cr) %{ 10782 match(Set dst (AndI src1 (URShiftI src2 src3))); 10783 10784 ins_cost(1.9 * INSN_COST); 10785 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 10786 10787 ins_encode %{ 10788 __ andw(as_Register($dst$$reg), 10789 as_Register($src1$$reg), 10790 as_Register($src2$$reg), 10791 Assembler::LSR, 10792 $src3$$constant & 0x1f); 10793 %} 10794 10795 ins_pipe(ialu_reg_reg_shift); 10796%} 10797 10798// This pattern is automatically generated from aarch64_ad.m4 10799// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10800instruct AndL_reg_URShift_reg(iRegLNoSp dst, 10801 iRegL src1, iRegL src2, 10802 immI src3, rFlagsReg cr) %{ 10803 match(Set dst (AndL src1 (URShiftL src2 src3))); 10804 10805 ins_cost(1.9 * INSN_COST); 10806 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 10807 10808 ins_encode %{ 10809 __ andr(as_Register($dst$$reg), 10810 as_Register($src1$$reg), 10811 as_Register($src2$$reg), 10812 Assembler::LSR, 10813 $src3$$constant & 0x3f); 10814 %} 10815 10816 ins_pipe(ialu_reg_reg_shift); 10817%} 10818 10819// This pattern is automatically generated from aarch64_ad.m4 10820// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10821instruct AndI_reg_RShift_reg(iRegINoSp dst, 10822 iRegIorL2I src1, iRegIorL2I src2, 10823 immI src3, rFlagsReg cr) %{ 10824 match(Set dst (AndI src1 (RShiftI src2 src3))); 10825 10826 ins_cost(1.9 * INSN_COST); 10827 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 10828 10829 ins_encode %{ 10830 __ andw(as_Register($dst$$reg), 10831 as_Register($src1$$reg), 10832 as_Register($src2$$reg), 10833 Assembler::ASR, 10834 $src3$$constant & 0x1f); 10835 %} 10836 10837 ins_pipe(ialu_reg_reg_shift); 10838%} 10839 10840// This pattern is automatically generated from aarch64_ad.m4 10841// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10842instruct AndL_reg_RShift_reg(iRegLNoSp dst, 10843 iRegL src1, iRegL src2, 10844 immI src3, rFlagsReg cr) %{ 10845 match(Set dst (AndL src1 (RShiftL src2 src3))); 10846 10847 ins_cost(1.9 * INSN_COST); 10848 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 10849 10850 ins_encode %{ 10851 __ andr(as_Register($dst$$reg), 10852 as_Register($src1$$reg), 10853 as_Register($src2$$reg), 10854 Assembler::ASR, 10855 $src3$$constant & 0x3f); 10856 %} 10857 10858 ins_pipe(ialu_reg_reg_shift); 10859%} 10860 10861// This pattern is automatically generated from aarch64_ad.m4 10862// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10863instruct AndI_reg_LShift_reg(iRegINoSp dst, 10864 iRegIorL2I src1, iRegIorL2I src2, 10865 immI src3, rFlagsReg cr) %{ 10866 match(Set dst (AndI src1 (LShiftI src2 src3))); 10867 10868 ins_cost(1.9 * INSN_COST); 10869 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 10870 10871 ins_encode %{ 10872 __ andw(as_Register($dst$$reg), 10873 as_Register($src1$$reg), 10874 as_Register($src2$$reg), 10875 Assembler::LSL, 10876 $src3$$constant & 0x1f); 10877 %} 10878 10879 ins_pipe(ialu_reg_reg_shift); 10880%} 10881 10882// This pattern is automatically generated from aarch64_ad.m4 10883// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10884instruct AndL_reg_LShift_reg(iRegLNoSp dst, 10885 iRegL src1, iRegL src2, 10886 immI src3, rFlagsReg cr) %{ 10887 match(Set dst (AndL src1 (LShiftL src2 src3))); 10888 10889 ins_cost(1.9 * INSN_COST); 10890 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 10891 10892 ins_encode %{ 10893 __ andr(as_Register($dst$$reg), 10894 as_Register($src1$$reg), 10895 as_Register($src2$$reg), 10896 Assembler::LSL, 10897 $src3$$constant & 0x3f); 10898 %} 10899 10900 ins_pipe(ialu_reg_reg_shift); 10901%} 10902 10903// This pattern is automatically generated from aarch64_ad.m4 10904// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10905instruct XorI_reg_URShift_reg(iRegINoSp dst, 10906 iRegIorL2I src1, iRegIorL2I src2, 10907 immI src3, rFlagsReg cr) %{ 10908 match(Set dst (XorI src1 (URShiftI src2 src3))); 10909 10910 ins_cost(1.9 * INSN_COST); 10911 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 10912 10913 ins_encode %{ 10914 __ eorw(as_Register($dst$$reg), 10915 as_Register($src1$$reg), 10916 as_Register($src2$$reg), 10917 Assembler::LSR, 10918 $src3$$constant & 0x1f); 10919 %} 10920 10921 ins_pipe(ialu_reg_reg_shift); 10922%} 10923 10924// This pattern is automatically generated from aarch64_ad.m4 10925// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10926instruct XorL_reg_URShift_reg(iRegLNoSp dst, 10927 iRegL src1, iRegL src2, 10928 immI src3, rFlagsReg cr) %{ 10929 match(Set dst (XorL src1 (URShiftL src2 src3))); 10930 10931 ins_cost(1.9 * INSN_COST); 10932 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 10933 10934 ins_encode %{ 10935 __ eor(as_Register($dst$$reg), 10936 as_Register($src1$$reg), 10937 as_Register($src2$$reg), 10938 Assembler::LSR, 10939 $src3$$constant & 0x3f); 10940 %} 10941 10942 ins_pipe(ialu_reg_reg_shift); 10943%} 10944 10945// This pattern is automatically generated from aarch64_ad.m4 10946// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10947instruct XorI_reg_RShift_reg(iRegINoSp dst, 10948 iRegIorL2I src1, iRegIorL2I src2, 10949 immI src3, rFlagsReg cr) %{ 10950 match(Set dst (XorI src1 (RShiftI src2 src3))); 10951 10952 ins_cost(1.9 * INSN_COST); 10953 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 10954 10955 ins_encode %{ 10956 __ eorw(as_Register($dst$$reg), 10957 as_Register($src1$$reg), 10958 as_Register($src2$$reg), 10959 Assembler::ASR, 10960 $src3$$constant & 0x1f); 10961 %} 10962 10963 ins_pipe(ialu_reg_reg_shift); 10964%} 10965 10966// This pattern is automatically generated from aarch64_ad.m4 10967// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10968instruct XorL_reg_RShift_reg(iRegLNoSp dst, 10969 iRegL src1, iRegL src2, 10970 immI src3, rFlagsReg cr) %{ 10971 match(Set dst (XorL src1 (RShiftL src2 src3))); 10972 10973 ins_cost(1.9 * INSN_COST); 10974 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 10975 10976 ins_encode %{ 10977 __ eor(as_Register($dst$$reg), 10978 as_Register($src1$$reg), 10979 as_Register($src2$$reg), 10980 Assembler::ASR, 10981 $src3$$constant & 0x3f); 10982 %} 10983 10984 ins_pipe(ialu_reg_reg_shift); 10985%} 10986 10987// This pattern is automatically generated from aarch64_ad.m4 10988// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 10989instruct XorI_reg_LShift_reg(iRegINoSp dst, 10990 iRegIorL2I src1, iRegIorL2I src2, 10991 immI src3, rFlagsReg cr) %{ 10992 match(Set dst (XorI src1 (LShiftI src2 src3))); 10993 10994 ins_cost(1.9 * INSN_COST); 10995 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 10996 10997 ins_encode %{ 10998 __ eorw(as_Register($dst$$reg), 10999 as_Register($src1$$reg), 11000 as_Register($src2$$reg), 11001 Assembler::LSL, 11002 $src3$$constant & 0x1f); 11003 %} 11004 11005 ins_pipe(ialu_reg_reg_shift); 11006%} 11007 11008// This pattern is automatically generated from aarch64_ad.m4 11009// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11010instruct XorL_reg_LShift_reg(iRegLNoSp dst, 11011 iRegL src1, iRegL src2, 11012 immI src3, rFlagsReg cr) %{ 11013 match(Set dst (XorL src1 (LShiftL src2 src3))); 11014 11015 ins_cost(1.9 * INSN_COST); 11016 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 11017 11018 ins_encode %{ 11019 __ eor(as_Register($dst$$reg), 11020 as_Register($src1$$reg), 11021 as_Register($src2$$reg), 11022 Assembler::LSL, 11023 $src3$$constant & 0x3f); 11024 %} 11025 11026 ins_pipe(ialu_reg_reg_shift); 11027%} 11028 11029// This pattern is automatically generated from aarch64_ad.m4 11030// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11031instruct OrI_reg_URShift_reg(iRegINoSp dst, 11032 iRegIorL2I src1, iRegIorL2I src2, 11033 immI src3, rFlagsReg cr) %{ 11034 match(Set dst (OrI src1 (URShiftI src2 src3))); 11035 11036 ins_cost(1.9 * INSN_COST); 11037 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 11038 11039 ins_encode %{ 11040 __ orrw(as_Register($dst$$reg), 11041 as_Register($src1$$reg), 11042 as_Register($src2$$reg), 11043 Assembler::LSR, 11044 $src3$$constant & 0x1f); 11045 %} 11046 11047 ins_pipe(ialu_reg_reg_shift); 11048%} 11049 11050// This pattern is automatically generated from aarch64_ad.m4 11051// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11052instruct OrL_reg_URShift_reg(iRegLNoSp dst, 11053 iRegL src1, iRegL src2, 11054 immI src3, rFlagsReg cr) %{ 11055 match(Set dst (OrL src1 (URShiftL src2 src3))); 11056 11057 ins_cost(1.9 * INSN_COST); 11058 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 11059 11060 ins_encode %{ 11061 __ orr(as_Register($dst$$reg), 11062 as_Register($src1$$reg), 11063 as_Register($src2$$reg), 11064 Assembler::LSR, 11065 $src3$$constant & 0x3f); 11066 %} 11067 11068 ins_pipe(ialu_reg_reg_shift); 11069%} 11070 11071// This pattern is automatically generated from aarch64_ad.m4 11072// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11073instruct OrI_reg_RShift_reg(iRegINoSp dst, 11074 iRegIorL2I src1, iRegIorL2I src2, 11075 immI src3, rFlagsReg cr) %{ 11076 match(Set dst (OrI src1 (RShiftI src2 src3))); 11077 11078 ins_cost(1.9 * INSN_COST); 11079 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 11080 11081 ins_encode %{ 11082 __ orrw(as_Register($dst$$reg), 11083 as_Register($src1$$reg), 11084 as_Register($src2$$reg), 11085 Assembler::ASR, 11086 $src3$$constant & 0x1f); 11087 %} 11088 11089 ins_pipe(ialu_reg_reg_shift); 11090%} 11091 11092// This pattern is automatically generated from aarch64_ad.m4 11093// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11094instruct OrL_reg_RShift_reg(iRegLNoSp dst, 11095 iRegL src1, iRegL src2, 11096 immI src3, rFlagsReg cr) %{ 11097 match(Set dst (OrL src1 (RShiftL src2 src3))); 11098 11099 ins_cost(1.9 * INSN_COST); 11100 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 11101 11102 ins_encode %{ 11103 __ orr(as_Register($dst$$reg), 11104 as_Register($src1$$reg), 11105 as_Register($src2$$reg), 11106 Assembler::ASR, 11107 $src3$$constant & 0x3f); 11108 %} 11109 11110 ins_pipe(ialu_reg_reg_shift); 11111%} 11112 11113// This pattern is automatically generated from aarch64_ad.m4 11114// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11115instruct OrI_reg_LShift_reg(iRegINoSp dst, 11116 iRegIorL2I src1, iRegIorL2I src2, 11117 immI src3, rFlagsReg cr) %{ 11118 match(Set dst (OrI src1 (LShiftI src2 src3))); 11119 11120 ins_cost(1.9 * INSN_COST); 11121 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 11122 11123 ins_encode %{ 11124 __ orrw(as_Register($dst$$reg), 11125 as_Register($src1$$reg), 11126 as_Register($src2$$reg), 11127 Assembler::LSL, 11128 $src3$$constant & 0x1f); 11129 %} 11130 11131 ins_pipe(ialu_reg_reg_shift); 11132%} 11133 11134// This pattern is automatically generated from aarch64_ad.m4 11135// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11136instruct OrL_reg_LShift_reg(iRegLNoSp dst, 11137 iRegL src1, iRegL src2, 11138 immI src3, rFlagsReg cr) %{ 11139 match(Set dst (OrL src1 (LShiftL src2 src3))); 11140 11141 ins_cost(1.9 * INSN_COST); 11142 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 11143 11144 ins_encode %{ 11145 __ orr(as_Register($dst$$reg), 11146 as_Register($src1$$reg), 11147 as_Register($src2$$reg), 11148 Assembler::LSL, 11149 $src3$$constant & 0x3f); 11150 %} 11151 11152 ins_pipe(ialu_reg_reg_shift); 11153%} 11154 11155// This pattern is automatically generated from aarch64_ad.m4 11156// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11157instruct AddI_reg_URShift_reg(iRegINoSp dst, 11158 iRegIorL2I src1, iRegIorL2I src2, 11159 immI src3, rFlagsReg cr) %{ 11160 match(Set dst (AddI src1 (URShiftI src2 src3))); 11161 11162 ins_cost(1.9 * INSN_COST); 11163 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 11164 11165 ins_encode %{ 11166 __ addw(as_Register($dst$$reg), 11167 as_Register($src1$$reg), 11168 as_Register($src2$$reg), 11169 Assembler::LSR, 11170 $src3$$constant & 0x1f); 11171 %} 11172 11173 ins_pipe(ialu_reg_reg_shift); 11174%} 11175 11176// This pattern is automatically generated from aarch64_ad.m4 11177// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11178instruct AddL_reg_URShift_reg(iRegLNoSp dst, 11179 iRegL src1, iRegL src2, 11180 immI src3, rFlagsReg cr) %{ 11181 match(Set dst (AddL src1 (URShiftL src2 src3))); 11182 11183 ins_cost(1.9 * INSN_COST); 11184 format %{ "add $dst, $src1, $src2, LSR $src3" %} 11185 11186 ins_encode %{ 11187 __ add(as_Register($dst$$reg), 11188 as_Register($src1$$reg), 11189 as_Register($src2$$reg), 11190 Assembler::LSR, 11191 $src3$$constant & 0x3f); 11192 %} 11193 11194 ins_pipe(ialu_reg_reg_shift); 11195%} 11196 11197// This pattern is automatically generated from aarch64_ad.m4 11198// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11199instruct AddI_reg_RShift_reg(iRegINoSp dst, 11200 iRegIorL2I src1, iRegIorL2I src2, 11201 immI src3, rFlagsReg cr) %{ 11202 match(Set dst (AddI src1 (RShiftI src2 src3))); 11203 11204 ins_cost(1.9 * INSN_COST); 11205 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 11206 11207 ins_encode %{ 11208 __ addw(as_Register($dst$$reg), 11209 as_Register($src1$$reg), 11210 as_Register($src2$$reg), 11211 Assembler::ASR, 11212 $src3$$constant & 0x1f); 11213 %} 11214 11215 ins_pipe(ialu_reg_reg_shift); 11216%} 11217 11218// This pattern is automatically generated from aarch64_ad.m4 11219// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11220instruct AddL_reg_RShift_reg(iRegLNoSp dst, 11221 iRegL src1, iRegL src2, 11222 immI src3, rFlagsReg cr) %{ 11223 match(Set dst (AddL src1 (RShiftL src2 src3))); 11224 11225 ins_cost(1.9 * INSN_COST); 11226 format %{ "add $dst, $src1, $src2, ASR $src3" %} 11227 11228 ins_encode %{ 11229 __ add(as_Register($dst$$reg), 11230 as_Register($src1$$reg), 11231 as_Register($src2$$reg), 11232 Assembler::ASR, 11233 $src3$$constant & 0x3f); 11234 %} 11235 11236 ins_pipe(ialu_reg_reg_shift); 11237%} 11238 11239// This pattern is automatically generated from aarch64_ad.m4 11240// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11241instruct AddI_reg_LShift_reg(iRegINoSp dst, 11242 iRegIorL2I src1, iRegIorL2I src2, 11243 immI src3, rFlagsReg cr) %{ 11244 match(Set dst (AddI src1 (LShiftI src2 src3))); 11245 11246 ins_cost(1.9 * INSN_COST); 11247 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 11248 11249 ins_encode %{ 11250 __ addw(as_Register($dst$$reg), 11251 as_Register($src1$$reg), 11252 as_Register($src2$$reg), 11253 Assembler::LSL, 11254 $src3$$constant & 0x1f); 11255 %} 11256 11257 ins_pipe(ialu_reg_reg_shift); 11258%} 11259 11260// This pattern is automatically generated from aarch64_ad.m4 11261// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11262instruct AddL_reg_LShift_reg(iRegLNoSp dst, 11263 iRegL src1, iRegL src2, 11264 immI src3, rFlagsReg cr) %{ 11265 match(Set dst (AddL src1 (LShiftL src2 src3))); 11266 11267 ins_cost(1.9 * INSN_COST); 11268 format %{ "add $dst, $src1, $src2, LSL $src3" %} 11269 11270 ins_encode %{ 11271 __ add(as_Register($dst$$reg), 11272 as_Register($src1$$reg), 11273 as_Register($src2$$reg), 11274 Assembler::LSL, 11275 $src3$$constant & 0x3f); 11276 %} 11277 11278 ins_pipe(ialu_reg_reg_shift); 11279%} 11280 11281// This pattern is automatically generated from aarch64_ad.m4 11282// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11283instruct SubI_reg_URShift_reg(iRegINoSp dst, 11284 iRegIorL2I src1, iRegIorL2I src2, 11285 immI src3, rFlagsReg cr) %{ 11286 match(Set dst (SubI src1 (URShiftI src2 src3))); 11287 11288 ins_cost(1.9 * INSN_COST); 11289 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 11290 11291 ins_encode %{ 11292 __ subw(as_Register($dst$$reg), 11293 as_Register($src1$$reg), 11294 as_Register($src2$$reg), 11295 Assembler::LSR, 11296 $src3$$constant & 0x1f); 11297 %} 11298 11299 ins_pipe(ialu_reg_reg_shift); 11300%} 11301 11302// This pattern is automatically generated from aarch64_ad.m4 11303// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11304instruct SubL_reg_URShift_reg(iRegLNoSp dst, 11305 iRegL src1, iRegL src2, 11306 immI src3, rFlagsReg cr) %{ 11307 match(Set dst (SubL src1 (URShiftL src2 src3))); 11308 11309 ins_cost(1.9 * INSN_COST); 11310 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 11311 11312 ins_encode %{ 11313 __ sub(as_Register($dst$$reg), 11314 as_Register($src1$$reg), 11315 as_Register($src2$$reg), 11316 Assembler::LSR, 11317 $src3$$constant & 0x3f); 11318 %} 11319 11320 ins_pipe(ialu_reg_reg_shift); 11321%} 11322 11323// This pattern is automatically generated from aarch64_ad.m4 11324// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11325instruct SubI_reg_RShift_reg(iRegINoSp dst, 11326 iRegIorL2I src1, iRegIorL2I src2, 11327 immI src3, rFlagsReg cr) %{ 11328 match(Set dst (SubI src1 (RShiftI src2 src3))); 11329 11330 ins_cost(1.9 * INSN_COST); 11331 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 11332 11333 ins_encode %{ 11334 __ subw(as_Register($dst$$reg), 11335 as_Register($src1$$reg), 11336 as_Register($src2$$reg), 11337 Assembler::ASR, 11338 $src3$$constant & 0x1f); 11339 %} 11340 11341 ins_pipe(ialu_reg_reg_shift); 11342%} 11343 11344// This pattern is automatically generated from aarch64_ad.m4 11345// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11346instruct SubL_reg_RShift_reg(iRegLNoSp dst, 11347 iRegL src1, iRegL src2, 11348 immI src3, rFlagsReg cr) %{ 11349 match(Set dst (SubL src1 (RShiftL src2 src3))); 11350 11351 ins_cost(1.9 * INSN_COST); 11352 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 11353 11354 ins_encode %{ 11355 __ sub(as_Register($dst$$reg), 11356 as_Register($src1$$reg), 11357 as_Register($src2$$reg), 11358 Assembler::ASR, 11359 $src3$$constant & 0x3f); 11360 %} 11361 11362 ins_pipe(ialu_reg_reg_shift); 11363%} 11364 11365// This pattern is automatically generated from aarch64_ad.m4 11366// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11367instruct SubI_reg_LShift_reg(iRegINoSp dst, 11368 iRegIorL2I src1, iRegIorL2I src2, 11369 immI src3, rFlagsReg cr) %{ 11370 match(Set dst (SubI src1 (LShiftI src2 src3))); 11371 11372 ins_cost(1.9 * INSN_COST); 11373 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 11374 11375 ins_encode %{ 11376 __ subw(as_Register($dst$$reg), 11377 as_Register($src1$$reg), 11378 as_Register($src2$$reg), 11379 Assembler::LSL, 11380 $src3$$constant & 0x1f); 11381 %} 11382 11383 ins_pipe(ialu_reg_reg_shift); 11384%} 11385 11386// This pattern is automatically generated from aarch64_ad.m4 11387// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11388instruct SubL_reg_LShift_reg(iRegLNoSp dst, 11389 iRegL src1, iRegL src2, 11390 immI src3, rFlagsReg cr) %{ 11391 match(Set dst (SubL src1 (LShiftL src2 src3))); 11392 11393 ins_cost(1.9 * INSN_COST); 11394 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 11395 11396 ins_encode %{ 11397 __ sub(as_Register($dst$$reg), 11398 as_Register($src1$$reg), 11399 as_Register($src2$$reg), 11400 Assembler::LSL, 11401 $src3$$constant & 0x3f); 11402 %} 11403 11404 ins_pipe(ialu_reg_reg_shift); 11405%} 11406 11407 11408// This pattern is automatically generated from aarch64_ad.m4 11409// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11410 11411// Shift Left followed by Shift Right. 11412// This idiom is used by the compiler for the i2b bytecode etc. 11413instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11414%{ 11415 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 11416 ins_cost(INSN_COST * 2); 11417 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11418 ins_encode %{ 11419 int lshift = $lshift_count$$constant & 63; 11420 int rshift = $rshift_count$$constant & 63; 11421 int s = 63 - lshift; 11422 int r = (rshift - lshift) & 63; 11423 __ sbfm(as_Register($dst$$reg), 11424 as_Register($src$$reg), 11425 r, s); 11426 %} 11427 11428 ins_pipe(ialu_reg_shift); 11429%} 11430 11431// This pattern is automatically generated from aarch64_ad.m4 11432// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11433 11434// Shift Left followed by Shift Right. 11435// This idiom is used by the compiler for the i2b bytecode etc. 11436instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11437%{ 11438 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 11439 ins_cost(INSN_COST * 2); 11440 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11441 ins_encode %{ 11442 int lshift = $lshift_count$$constant & 31; 11443 int rshift = $rshift_count$$constant & 31; 11444 int s = 31 - lshift; 11445 int r = (rshift - lshift) & 31; 11446 __ sbfmw(as_Register($dst$$reg), 11447 as_Register($src$$reg), 11448 r, s); 11449 %} 11450 11451 ins_pipe(ialu_reg_shift); 11452%} 11453 11454// This pattern is automatically generated from aarch64_ad.m4 11455// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11456 11457// Shift Left followed by Shift Right. 11458// This idiom is used by the compiler for the i2b bytecode etc. 11459instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 11460%{ 11461 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 11462 ins_cost(INSN_COST * 2); 11463 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 11464 ins_encode %{ 11465 int lshift = $lshift_count$$constant & 63; 11466 int rshift = $rshift_count$$constant & 63; 11467 int s = 63 - lshift; 11468 int r = (rshift - lshift) & 63; 11469 __ ubfm(as_Register($dst$$reg), 11470 as_Register($src$$reg), 11471 r, s); 11472 %} 11473 11474 ins_pipe(ialu_reg_shift); 11475%} 11476 11477// This pattern is automatically generated from aarch64_ad.m4 11478// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11479 11480// Shift Left followed by Shift Right. 11481// This idiom is used by the compiler for the i2b bytecode etc. 11482instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 11483%{ 11484 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 11485 ins_cost(INSN_COST * 2); 11486 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 11487 ins_encode %{ 11488 int lshift = $lshift_count$$constant & 31; 11489 int rshift = $rshift_count$$constant & 31; 11490 int s = 31 - lshift; 11491 int r = (rshift - lshift) & 31; 11492 __ ubfmw(as_Register($dst$$reg), 11493 as_Register($src$$reg), 11494 r, s); 11495 %} 11496 11497 ins_pipe(ialu_reg_shift); 11498%} 11499 11500// Bitfield extract with shift & mask 11501 11502// This pattern is automatically generated from aarch64_ad.m4 11503// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11504instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11505%{ 11506 match(Set dst (AndI (URShiftI src rshift) mask)); 11507 // Make sure we are not going to exceed what ubfxw can do. 11508 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11509 11510 ins_cost(INSN_COST); 11511 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 11512 ins_encode %{ 11513 int rshift = $rshift$$constant & 31; 11514 intptr_t mask = $mask$$constant; 11515 int width = exact_log2(mask+1); 11516 __ ubfxw(as_Register($dst$$reg), 11517 as_Register($src$$reg), rshift, width); 11518 %} 11519 ins_pipe(ialu_reg_shift); 11520%} 11521 11522// This pattern is automatically generated from aarch64_ad.m4 11523// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11524instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 11525%{ 11526 match(Set dst (AndL (URShiftL src rshift) mask)); 11527 // Make sure we are not going to exceed what ubfx can do. 11528 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 11529 11530 ins_cost(INSN_COST); 11531 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11532 ins_encode %{ 11533 int rshift = $rshift$$constant & 63; 11534 intptr_t mask = $mask$$constant; 11535 int width = exact_log2_long(mask+1); 11536 __ ubfx(as_Register($dst$$reg), 11537 as_Register($src$$reg), rshift, width); 11538 %} 11539 ins_pipe(ialu_reg_shift); 11540%} 11541 11542 11543// This pattern is automatically generated from aarch64_ad.m4 11544// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11545 11546// We can use ubfx when extending an And with a mask when we know mask 11547// is positive. We know that because immI_bitmask guarantees it. 11548instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 11549%{ 11550 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 11551 // Make sure we are not going to exceed what ubfxw can do. 11552 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 11553 11554 ins_cost(INSN_COST * 2); 11555 format %{ "ubfx $dst, $src, $rshift, $mask" %} 11556 ins_encode %{ 11557 int rshift = $rshift$$constant & 31; 11558 intptr_t mask = $mask$$constant; 11559 int width = exact_log2(mask+1); 11560 __ ubfx(as_Register($dst$$reg), 11561 as_Register($src$$reg), rshift, width); 11562 %} 11563 ins_pipe(ialu_reg_shift); 11564%} 11565 11566 11567// This pattern is automatically generated from aarch64_ad.m4 11568// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11569 11570// We can use ubfiz when masking by a positive number and then left shifting the result. 11571// We know that the mask is positive because immI_bitmask guarantees it. 11572instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11573%{ 11574 match(Set dst (LShiftI (AndI src mask) lshift)); 11575 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 11576 11577 ins_cost(INSN_COST); 11578 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11579 ins_encode %{ 11580 int lshift = $lshift$$constant & 31; 11581 intptr_t mask = $mask$$constant; 11582 int width = exact_log2(mask+1); 11583 __ ubfizw(as_Register($dst$$reg), 11584 as_Register($src$$reg), lshift, width); 11585 %} 11586 ins_pipe(ialu_reg_shift); 11587%} 11588 11589// This pattern is automatically generated from aarch64_ad.m4 11590// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11591 11592// We can use ubfiz when masking by a positive number and then left shifting the result. 11593// We know that the mask is positive because immL_bitmask guarantees it. 11594instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 11595%{ 11596 match(Set dst (LShiftL (AndL src mask) lshift)); 11597 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 11598 11599 ins_cost(INSN_COST); 11600 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11601 ins_encode %{ 11602 int lshift = $lshift$$constant & 63; 11603 intptr_t mask = $mask$$constant; 11604 int width = exact_log2_long(mask+1); 11605 __ ubfiz(as_Register($dst$$reg), 11606 as_Register($src$$reg), lshift, width); 11607 %} 11608 ins_pipe(ialu_reg_shift); 11609%} 11610 11611// This pattern is automatically generated from aarch64_ad.m4 11612// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11613 11614// We can use ubfiz when masking by a positive number and then left shifting the result. 11615// We know that the mask is positive because immI_bitmask guarantees it. 11616instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11617%{ 11618 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 11619 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 11620 11621 ins_cost(INSN_COST); 11622 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 11623 ins_encode %{ 11624 int lshift = $lshift$$constant & 31; 11625 intptr_t mask = $mask$$constant; 11626 int width = exact_log2(mask+1); 11627 __ ubfizw(as_Register($dst$$reg), 11628 as_Register($src$$reg), lshift, width); 11629 %} 11630 ins_pipe(ialu_reg_shift); 11631%} 11632 11633// This pattern is automatically generated from aarch64_ad.m4 11634// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11635 11636// We can use ubfiz when masking by a positive number and then left shifting the result. 11637// We know that the mask is positive because immL_bitmask guarantees it. 11638instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 11639%{ 11640 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 11641 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 11642 11643 ins_cost(INSN_COST); 11644 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11645 ins_encode %{ 11646 int lshift = $lshift$$constant & 63; 11647 intptr_t mask = $mask$$constant; 11648 int width = exact_log2_long(mask+1); 11649 __ ubfiz(as_Register($dst$$reg), 11650 as_Register($src$$reg), lshift, width); 11651 %} 11652 ins_pipe(ialu_reg_shift); 11653%} 11654 11655 11656// This pattern is automatically generated from aarch64_ad.m4 11657// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11658 11659// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 11660instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 11661%{ 11662 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 11663 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 11664 11665 ins_cost(INSN_COST); 11666 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11667 ins_encode %{ 11668 int lshift = $lshift$$constant & 63; 11669 intptr_t mask = $mask$$constant; 11670 int width = exact_log2(mask+1); 11671 __ ubfiz(as_Register($dst$$reg), 11672 as_Register($src$$reg), lshift, width); 11673 %} 11674 ins_pipe(ialu_reg_shift); 11675%} 11676 11677// This pattern is automatically generated from aarch64_ad.m4 11678// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11679 11680// If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 11681instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 11682%{ 11683 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 11684 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 11685 11686 ins_cost(INSN_COST); 11687 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 11688 ins_encode %{ 11689 int lshift = $lshift$$constant & 31; 11690 intptr_t mask = $mask$$constant; 11691 int width = exact_log2(mask+1); 11692 __ ubfiz(as_Register($dst$$reg), 11693 as_Register($src$$reg), lshift, width); 11694 %} 11695 ins_pipe(ialu_reg_shift); 11696%} 11697 11698// Can skip int2long conversions after AND with small bitmask 11699instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 11700%{ 11701 match(Set dst (ConvI2L (AndI src msk))); 11702 ins_cost(INSN_COST); 11703 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 11704 ins_encode %{ 11705 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 11706 %} 11707 ins_pipe(ialu_reg_shift); 11708%} 11709 11710 11711// Rotations 11712// This pattern is automatically generated from aarch64_ad.m4 11713// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11714instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11715%{ 11716 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11717 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 11718 11719 ins_cost(INSN_COST); 11720 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11721 11722 ins_encode %{ 11723 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11724 $rshift$$constant & 63); 11725 %} 11726 ins_pipe(ialu_reg_reg_extr); 11727%} 11728 11729 11730// This pattern is automatically generated from aarch64_ad.m4 11731// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11732instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11733%{ 11734 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11735 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 11736 11737 ins_cost(INSN_COST); 11738 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11739 11740 ins_encode %{ 11741 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11742 $rshift$$constant & 31); 11743 %} 11744 ins_pipe(ialu_reg_reg_extr); 11745%} 11746 11747 11748// This pattern is automatically generated from aarch64_ad.m4 11749// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11750instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 11751%{ 11752 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 11753 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 11754 11755 ins_cost(INSN_COST); 11756 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11757 11758 ins_encode %{ 11759 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11760 $rshift$$constant & 63); 11761 %} 11762 ins_pipe(ialu_reg_reg_extr); 11763%} 11764 11765 11766// This pattern is automatically generated from aarch64_ad.m4 11767// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11768instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 11769%{ 11770 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 11771 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 11772 11773 ins_cost(INSN_COST); 11774 format %{ "extr $dst, $src1, $src2, #$rshift" %} 11775 11776 ins_encode %{ 11777 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 11778 $rshift$$constant & 31); 11779 %} 11780 ins_pipe(ialu_reg_reg_extr); 11781%} 11782 11783 11784// This pattern is automatically generated from aarch64_ad.m4 11785// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11786 11787// rol expander 11788instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11789%{ 11790 effect(DEF dst, USE src, USE shift); 11791 11792 format %{ "rol $dst, $src, $shift" %} 11793 ins_cost(INSN_COST * 3); 11794 ins_encode %{ 11795 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11796 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11797 rscratch1); 11798 %} 11799 ins_pipe(ialu_reg_reg_vshift); 11800%} 11801 11802// This pattern is automatically generated from aarch64_ad.m4 11803// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11804 11805// rol expander 11806instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11807%{ 11808 effect(DEF dst, USE src, USE shift); 11809 11810 format %{ "rol $dst, $src, $shift" %} 11811 ins_cost(INSN_COST * 3); 11812 ins_encode %{ 11813 __ subw(rscratch1, zr, as_Register($shift$$reg)); 11814 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11815 rscratch1); 11816 %} 11817 ins_pipe(ialu_reg_reg_vshift); 11818%} 11819 11820// This pattern is automatically generated from aarch64_ad.m4 11821// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11822instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11823%{ 11824 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 11825 11826 expand %{ 11827 rolL_rReg(dst, src, shift, cr); 11828 %} 11829%} 11830 11831// This pattern is automatically generated from aarch64_ad.m4 11832// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11833instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11834%{ 11835 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 11836 11837 expand %{ 11838 rolL_rReg(dst, src, shift, cr); 11839 %} 11840%} 11841 11842// This pattern is automatically generated from aarch64_ad.m4 11843// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11844instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11845%{ 11846 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 11847 11848 expand %{ 11849 rolI_rReg(dst, src, shift, cr); 11850 %} 11851%} 11852 11853// This pattern is automatically generated from aarch64_ad.m4 11854// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11855instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11856%{ 11857 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 11858 11859 expand %{ 11860 rolI_rReg(dst, src, shift, cr); 11861 %} 11862%} 11863 11864// This pattern is automatically generated from aarch64_ad.m4 11865// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11866 11867// ror expander 11868instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 11869%{ 11870 effect(DEF dst, USE src, USE shift); 11871 11872 format %{ "ror $dst, $src, $shift" %} 11873 ins_cost(INSN_COST); 11874 ins_encode %{ 11875 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 11876 as_Register($shift$$reg)); 11877 %} 11878 ins_pipe(ialu_reg_reg_vshift); 11879%} 11880 11881// This pattern is automatically generated from aarch64_ad.m4 11882// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11883 11884// ror expander 11885instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 11886%{ 11887 effect(DEF dst, USE src, USE shift); 11888 11889 format %{ "ror $dst, $src, $shift" %} 11890 ins_cost(INSN_COST); 11891 ins_encode %{ 11892 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 11893 as_Register($shift$$reg)); 11894 %} 11895 ins_pipe(ialu_reg_reg_vshift); 11896%} 11897 11898// This pattern is automatically generated from aarch64_ad.m4 11899// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11900instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 11901%{ 11902 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 11903 11904 expand %{ 11905 rorL_rReg(dst, src, shift, cr); 11906 %} 11907%} 11908 11909// This pattern is automatically generated from aarch64_ad.m4 11910// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11911instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 11912%{ 11913 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 11914 11915 expand %{ 11916 rorL_rReg(dst, src, shift, cr); 11917 %} 11918%} 11919 11920// This pattern is automatically generated from aarch64_ad.m4 11921// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11922instruct rorI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr) 11923%{ 11924 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 11925 11926 expand %{ 11927 rorI_rReg(dst, src, shift, cr); 11928 %} 11929%} 11930 11931// This pattern is automatically generated from aarch64_ad.m4 11932// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11933instruct rorI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr) 11934%{ 11935 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 11936 11937 expand %{ 11938 rorI_rReg(dst, src, shift, cr); 11939 %} 11940%} 11941 11942 11943// Add/subtract (extended) 11944 11945// This pattern is automatically generated from aarch64_ad.m4 11946// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11947instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11948%{ 11949 match(Set dst (AddL src1 (ConvI2L src2))); 11950 ins_cost(INSN_COST); 11951 format %{ "add $dst, $src1, $src2, sxtw" %} 11952 11953 ins_encode %{ 11954 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11955 as_Register($src2$$reg), ext::sxtw); 11956 %} 11957 ins_pipe(ialu_reg_reg); 11958%} 11959 11960// This pattern is automatically generated from aarch64_ad.m4 11961// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11962instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 11963%{ 11964 match(Set dst (SubL src1 (ConvI2L src2))); 11965 ins_cost(INSN_COST); 11966 format %{ "sub $dst, $src1, $src2, sxtw" %} 11967 11968 ins_encode %{ 11969 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 11970 as_Register($src2$$reg), ext::sxtw); 11971 %} 11972 ins_pipe(ialu_reg_reg); 11973%} 11974 11975// This pattern is automatically generated from aarch64_ad.m4 11976// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11977instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 11978%{ 11979 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11980 ins_cost(INSN_COST); 11981 format %{ "add $dst, $src1, $src2, sxth" %} 11982 11983 ins_encode %{ 11984 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 11985 as_Register($src2$$reg), ext::sxth); 11986 %} 11987 ins_pipe(ialu_reg_reg); 11988%} 11989 11990// This pattern is automatically generated from aarch64_ad.m4 11991// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11992instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 11993%{ 11994 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 11995 ins_cost(INSN_COST); 11996 format %{ "add $dst, $src1, $src2, sxtb" %} 11997 11998 ins_encode %{ 11999 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12000 as_Register($src2$$reg), ext::sxtb); 12001 %} 12002 ins_pipe(ialu_reg_reg); 12003%} 12004 12005// This pattern is automatically generated from aarch64_ad.m4 12006// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12007instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 12008%{ 12009 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 12010 ins_cost(INSN_COST); 12011 format %{ "add $dst, $src1, $src2, uxtb" %} 12012 12013 ins_encode %{ 12014 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12015 as_Register($src2$$reg), ext::uxtb); 12016 %} 12017 ins_pipe(ialu_reg_reg); 12018%} 12019 12020// This pattern is automatically generated from aarch64_ad.m4 12021// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12022instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 12023%{ 12024 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12025 ins_cost(INSN_COST); 12026 format %{ "add $dst, $src1, $src2, sxth" %} 12027 12028 ins_encode %{ 12029 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12030 as_Register($src2$$reg), ext::sxth); 12031 %} 12032 ins_pipe(ialu_reg_reg); 12033%} 12034 12035// This pattern is automatically generated from aarch64_ad.m4 12036// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12037instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 12038%{ 12039 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12040 ins_cost(INSN_COST); 12041 format %{ "add $dst, $src1, $src2, sxtw" %} 12042 12043 ins_encode %{ 12044 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12045 as_Register($src2$$reg), ext::sxtw); 12046 %} 12047 ins_pipe(ialu_reg_reg); 12048%} 12049 12050// This pattern is automatically generated from aarch64_ad.m4 12051// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12052instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12053%{ 12054 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 12055 ins_cost(INSN_COST); 12056 format %{ "add $dst, $src1, $src2, sxtb" %} 12057 12058 ins_encode %{ 12059 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12060 as_Register($src2$$reg), ext::sxtb); 12061 %} 12062 ins_pipe(ialu_reg_reg); 12063%} 12064 12065// This pattern is automatically generated from aarch64_ad.m4 12066// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12067instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 12068%{ 12069 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 12070 ins_cost(INSN_COST); 12071 format %{ "add $dst, $src1, $src2, uxtb" %} 12072 12073 ins_encode %{ 12074 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12075 as_Register($src2$$reg), ext::uxtb); 12076 %} 12077 ins_pipe(ialu_reg_reg); 12078%} 12079 12080// This pattern is automatically generated from aarch64_ad.m4 12081// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12082instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12083%{ 12084 match(Set dst (AddI src1 (AndI src2 mask))); 12085 ins_cost(INSN_COST); 12086 format %{ "addw $dst, $src1, $src2, uxtb" %} 12087 12088 ins_encode %{ 12089 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12090 as_Register($src2$$reg), ext::uxtb); 12091 %} 12092 ins_pipe(ialu_reg_reg); 12093%} 12094 12095// This pattern is automatically generated from aarch64_ad.m4 12096// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12097instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12098%{ 12099 match(Set dst (AddI src1 (AndI src2 mask))); 12100 ins_cost(INSN_COST); 12101 format %{ "addw $dst, $src1, $src2, uxth" %} 12102 12103 ins_encode %{ 12104 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12105 as_Register($src2$$reg), ext::uxth); 12106 %} 12107 ins_pipe(ialu_reg_reg); 12108%} 12109 12110// This pattern is automatically generated from aarch64_ad.m4 12111// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12112instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12113%{ 12114 match(Set dst (AddL src1 (AndL src2 mask))); 12115 ins_cost(INSN_COST); 12116 format %{ "add $dst, $src1, $src2, uxtb" %} 12117 12118 ins_encode %{ 12119 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12120 as_Register($src2$$reg), ext::uxtb); 12121 %} 12122 ins_pipe(ialu_reg_reg); 12123%} 12124 12125// This pattern is automatically generated from aarch64_ad.m4 12126// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12127instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12128%{ 12129 match(Set dst (AddL src1 (AndL src2 mask))); 12130 ins_cost(INSN_COST); 12131 format %{ "add $dst, $src1, $src2, uxth" %} 12132 12133 ins_encode %{ 12134 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12135 as_Register($src2$$reg), ext::uxth); 12136 %} 12137 ins_pipe(ialu_reg_reg); 12138%} 12139 12140// This pattern is automatically generated from aarch64_ad.m4 12141// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12142instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12143%{ 12144 match(Set dst (AddL src1 (AndL src2 mask))); 12145 ins_cost(INSN_COST); 12146 format %{ "add $dst, $src1, $src2, uxtw" %} 12147 12148 ins_encode %{ 12149 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12150 as_Register($src2$$reg), ext::uxtw); 12151 %} 12152 ins_pipe(ialu_reg_reg); 12153%} 12154 12155// This pattern is automatically generated from aarch64_ad.m4 12156// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12157instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 12158%{ 12159 match(Set dst (SubI src1 (AndI src2 mask))); 12160 ins_cost(INSN_COST); 12161 format %{ "subw $dst, $src1, $src2, uxtb" %} 12162 12163 ins_encode %{ 12164 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12165 as_Register($src2$$reg), ext::uxtb); 12166 %} 12167 ins_pipe(ialu_reg_reg); 12168%} 12169 12170// This pattern is automatically generated from aarch64_ad.m4 12171// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12172instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 12173%{ 12174 match(Set dst (SubI src1 (AndI src2 mask))); 12175 ins_cost(INSN_COST); 12176 format %{ "subw $dst, $src1, $src2, uxth" %} 12177 12178 ins_encode %{ 12179 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12180 as_Register($src2$$reg), ext::uxth); 12181 %} 12182 ins_pipe(ialu_reg_reg); 12183%} 12184 12185// This pattern is automatically generated from aarch64_ad.m4 12186// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12187instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 12188%{ 12189 match(Set dst (SubL src1 (AndL src2 mask))); 12190 ins_cost(INSN_COST); 12191 format %{ "sub $dst, $src1, $src2, uxtb" %} 12192 12193 ins_encode %{ 12194 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12195 as_Register($src2$$reg), ext::uxtb); 12196 %} 12197 ins_pipe(ialu_reg_reg); 12198%} 12199 12200// This pattern is automatically generated from aarch64_ad.m4 12201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12202instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 12203%{ 12204 match(Set dst (SubL src1 (AndL src2 mask))); 12205 ins_cost(INSN_COST); 12206 format %{ "sub $dst, $src1, $src2, uxth" %} 12207 12208 ins_encode %{ 12209 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12210 as_Register($src2$$reg), ext::uxth); 12211 %} 12212 ins_pipe(ialu_reg_reg); 12213%} 12214 12215// This pattern is automatically generated from aarch64_ad.m4 12216// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12217instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 12218%{ 12219 match(Set dst (SubL src1 (AndL src2 mask))); 12220 ins_cost(INSN_COST); 12221 format %{ "sub $dst, $src1, $src2, uxtw" %} 12222 12223 ins_encode %{ 12224 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12225 as_Register($src2$$reg), ext::uxtw); 12226 %} 12227 ins_pipe(ialu_reg_reg); 12228%} 12229 12230 12231// This pattern is automatically generated from aarch64_ad.m4 12232// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12233instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12234%{ 12235 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12236 ins_cost(1.9 * INSN_COST); 12237 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 12238 12239 ins_encode %{ 12240 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12241 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12242 %} 12243 ins_pipe(ialu_reg_reg_shift); 12244%} 12245 12246// This pattern is automatically generated from aarch64_ad.m4 12247// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12248instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12249%{ 12250 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12251 ins_cost(1.9 * INSN_COST); 12252 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 12253 12254 ins_encode %{ 12255 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12256 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12257 %} 12258 ins_pipe(ialu_reg_reg_shift); 12259%} 12260 12261// This pattern is automatically generated from aarch64_ad.m4 12262// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12263instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12264%{ 12265 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12266 ins_cost(1.9 * INSN_COST); 12267 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 12268 12269 ins_encode %{ 12270 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12271 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12272 %} 12273 ins_pipe(ialu_reg_reg_shift); 12274%} 12275 12276// This pattern is automatically generated from aarch64_ad.m4 12277// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12278instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 12279%{ 12280 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12281 ins_cost(1.9 * INSN_COST); 12282 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 12283 12284 ins_encode %{ 12285 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12286 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12287 %} 12288 ins_pipe(ialu_reg_reg_shift); 12289%} 12290 12291// This pattern is automatically generated from aarch64_ad.m4 12292// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12293instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 12294%{ 12295 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12296 ins_cost(1.9 * INSN_COST); 12297 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 12298 12299 ins_encode %{ 12300 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12301 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12302 %} 12303 ins_pipe(ialu_reg_reg_shift); 12304%} 12305 12306// This pattern is automatically generated from aarch64_ad.m4 12307// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12308instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 12309%{ 12310 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 12311 ins_cost(1.9 * INSN_COST); 12312 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 12313 12314 ins_encode %{ 12315 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12316 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 12317 %} 12318 ins_pipe(ialu_reg_reg_shift); 12319%} 12320 12321// This pattern is automatically generated from aarch64_ad.m4 12322// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12323instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12324%{ 12325 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12326 ins_cost(1.9 * INSN_COST); 12327 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 12328 12329 ins_encode %{ 12330 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12331 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12332 %} 12333 ins_pipe(ialu_reg_reg_shift); 12334%} 12335 12336// This pattern is automatically generated from aarch64_ad.m4 12337// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12338instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12339%{ 12340 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12341 ins_cost(1.9 * INSN_COST); 12342 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 12343 12344 ins_encode %{ 12345 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12346 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12347 %} 12348 ins_pipe(ialu_reg_reg_shift); 12349%} 12350 12351// This pattern is automatically generated from aarch64_ad.m4 12352// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12353instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 12354%{ 12355 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12356 ins_cost(1.9 * INSN_COST); 12357 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 12358 12359 ins_encode %{ 12360 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12361 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 12362 %} 12363 ins_pipe(ialu_reg_reg_shift); 12364%} 12365 12366// This pattern is automatically generated from aarch64_ad.m4 12367// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12368instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 12369%{ 12370 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 12371 ins_cost(1.9 * INSN_COST); 12372 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 12373 12374 ins_encode %{ 12375 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12376 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 12377 %} 12378 ins_pipe(ialu_reg_reg_shift); 12379%} 12380 12381// This pattern is automatically generated from aarch64_ad.m4 12382// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12383instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12384%{ 12385 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 12386 ins_cost(1.9 * INSN_COST); 12387 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 12388 12389 ins_encode %{ 12390 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12391 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12392 %} 12393 ins_pipe(ialu_reg_reg_shift); 12394%} 12395 12396// This pattern is automatically generated from aarch64_ad.m4 12397// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12398instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 12399%{ 12400 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 12401 ins_cost(1.9 * INSN_COST); 12402 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 12403 12404 ins_encode %{ 12405 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12406 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 12407 %} 12408 ins_pipe(ialu_reg_reg_shift); 12409%} 12410 12411// This pattern is automatically generated from aarch64_ad.m4 12412// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12413instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12414%{ 12415 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12416 ins_cost(1.9 * INSN_COST); 12417 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 12418 12419 ins_encode %{ 12420 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12421 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12422 %} 12423 ins_pipe(ialu_reg_reg_shift); 12424%} 12425 12426// This pattern is automatically generated from aarch64_ad.m4 12427// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12428instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12429%{ 12430 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12431 ins_cost(1.9 * INSN_COST); 12432 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 12433 12434 ins_encode %{ 12435 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12436 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12437 %} 12438 ins_pipe(ialu_reg_reg_shift); 12439%} 12440 12441// This pattern is automatically generated from aarch64_ad.m4 12442// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12443instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12444%{ 12445 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 12446 ins_cost(1.9 * INSN_COST); 12447 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 12448 12449 ins_encode %{ 12450 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 12451 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12452 %} 12453 ins_pipe(ialu_reg_reg_shift); 12454%} 12455 12456// This pattern is automatically generated from aarch64_ad.m4 12457// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12458instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 12459%{ 12460 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12461 ins_cost(1.9 * INSN_COST); 12462 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 12463 12464 ins_encode %{ 12465 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12466 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12467 %} 12468 ins_pipe(ialu_reg_reg_shift); 12469%} 12470 12471// This pattern is automatically generated from aarch64_ad.m4 12472// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12473instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 12474%{ 12475 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12476 ins_cost(1.9 * INSN_COST); 12477 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 12478 12479 ins_encode %{ 12480 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12481 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12482 %} 12483 ins_pipe(ialu_reg_reg_shift); 12484%} 12485 12486// This pattern is automatically generated from aarch64_ad.m4 12487// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12488instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 12489%{ 12490 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 12491 ins_cost(1.9 * INSN_COST); 12492 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 12493 12494 ins_encode %{ 12495 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 12496 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 12497 %} 12498 ins_pipe(ialu_reg_reg_shift); 12499%} 12500 12501// This pattern is automatically generated from aarch64_ad.m4 12502// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12503instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12504%{ 12505 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12506 ins_cost(1.9 * INSN_COST); 12507 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 12508 12509 ins_encode %{ 12510 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12511 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12512 %} 12513 ins_pipe(ialu_reg_reg_shift); 12514%} 12515 12516// This pattern is automatically generated from aarch64_ad.m4 12517// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12518instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12519%{ 12520 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 12521 ins_cost(1.9 * INSN_COST); 12522 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 12523 12524 ins_encode %{ 12525 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 12526 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12527 %} 12528 ins_pipe(ialu_reg_reg_shift); 12529%} 12530 12531// This pattern is automatically generated from aarch64_ad.m4 12532// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12533instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 12534%{ 12535 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12536 ins_cost(1.9 * INSN_COST); 12537 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 12538 12539 ins_encode %{ 12540 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12541 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 12542 %} 12543 ins_pipe(ialu_reg_reg_shift); 12544%} 12545 12546// This pattern is automatically generated from aarch64_ad.m4 12547// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12548instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 12549%{ 12550 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 12551 ins_cost(1.9 * INSN_COST); 12552 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 12553 12554 ins_encode %{ 12555 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 12556 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 12557 %} 12558 ins_pipe(ialu_reg_reg_shift); 12559%} 12560 12561 12562 12563// END This section of the file is automatically generated. Do not edit -------------- 12564 12565 12566// ============================================================================ 12567// Floating Point Arithmetic Instructions 12568 12569instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12570 match(Set dst (AddF src1 src2)); 12571 12572 ins_cost(INSN_COST * 5); 12573 format %{ "fadds $dst, $src1, $src2" %} 12574 12575 ins_encode %{ 12576 __ fadds(as_FloatRegister($dst$$reg), 12577 as_FloatRegister($src1$$reg), 12578 as_FloatRegister($src2$$reg)); 12579 %} 12580 12581 ins_pipe(fp_dop_reg_reg_s); 12582%} 12583 12584instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12585 match(Set dst (AddD src1 src2)); 12586 12587 ins_cost(INSN_COST * 5); 12588 format %{ "faddd $dst, $src1, $src2" %} 12589 12590 ins_encode %{ 12591 __ faddd(as_FloatRegister($dst$$reg), 12592 as_FloatRegister($src1$$reg), 12593 as_FloatRegister($src2$$reg)); 12594 %} 12595 12596 ins_pipe(fp_dop_reg_reg_d); 12597%} 12598 12599instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12600 match(Set dst (SubF src1 src2)); 12601 12602 ins_cost(INSN_COST * 5); 12603 format %{ "fsubs $dst, $src1, $src2" %} 12604 12605 ins_encode %{ 12606 __ fsubs(as_FloatRegister($dst$$reg), 12607 as_FloatRegister($src1$$reg), 12608 as_FloatRegister($src2$$reg)); 12609 %} 12610 12611 ins_pipe(fp_dop_reg_reg_s); 12612%} 12613 12614instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12615 match(Set dst (SubD src1 src2)); 12616 12617 ins_cost(INSN_COST * 5); 12618 format %{ "fsubd $dst, $src1, $src2" %} 12619 12620 ins_encode %{ 12621 __ fsubd(as_FloatRegister($dst$$reg), 12622 as_FloatRegister($src1$$reg), 12623 as_FloatRegister($src2$$reg)); 12624 %} 12625 12626 ins_pipe(fp_dop_reg_reg_d); 12627%} 12628 12629instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12630 match(Set dst (MulF src1 src2)); 12631 12632 ins_cost(INSN_COST * 6); 12633 format %{ "fmuls $dst, $src1, $src2" %} 12634 12635 ins_encode %{ 12636 __ fmuls(as_FloatRegister($dst$$reg), 12637 as_FloatRegister($src1$$reg), 12638 as_FloatRegister($src2$$reg)); 12639 %} 12640 12641 ins_pipe(fp_dop_reg_reg_s); 12642%} 12643 12644instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12645 match(Set dst (MulD src1 src2)); 12646 12647 ins_cost(INSN_COST * 6); 12648 format %{ "fmuld $dst, $src1, $src2" %} 12649 12650 ins_encode %{ 12651 __ fmuld(as_FloatRegister($dst$$reg), 12652 as_FloatRegister($src1$$reg), 12653 as_FloatRegister($src2$$reg)); 12654 %} 12655 12656 ins_pipe(fp_dop_reg_reg_d); 12657%} 12658 12659// src1 * src2 + src3 12660instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12661 predicate(UseFMA); 12662 match(Set dst (FmaF src3 (Binary src1 src2))); 12663 12664 format %{ "fmadds $dst, $src1, $src2, $src3" %} 12665 12666 ins_encode %{ 12667 __ fmadds(as_FloatRegister($dst$$reg), 12668 as_FloatRegister($src1$$reg), 12669 as_FloatRegister($src2$$reg), 12670 as_FloatRegister($src3$$reg)); 12671 %} 12672 12673 ins_pipe(pipe_class_default); 12674%} 12675 12676// src1 * src2 + src3 12677instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12678 predicate(UseFMA); 12679 match(Set dst (FmaD src3 (Binary src1 src2))); 12680 12681 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 12682 12683 ins_encode %{ 12684 __ fmaddd(as_FloatRegister($dst$$reg), 12685 as_FloatRegister($src1$$reg), 12686 as_FloatRegister($src2$$reg), 12687 as_FloatRegister($src3$$reg)); 12688 %} 12689 12690 ins_pipe(pipe_class_default); 12691%} 12692 12693// -src1 * src2 + src3 12694instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12695 predicate(UseFMA); 12696 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 12697 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 12698 12699 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 12700 12701 ins_encode %{ 12702 __ fmsubs(as_FloatRegister($dst$$reg), 12703 as_FloatRegister($src1$$reg), 12704 as_FloatRegister($src2$$reg), 12705 as_FloatRegister($src3$$reg)); 12706 %} 12707 12708 ins_pipe(pipe_class_default); 12709%} 12710 12711// -src1 * src2 + src3 12712instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12713 predicate(UseFMA); 12714 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 12715 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 12716 12717 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 12718 12719 ins_encode %{ 12720 __ fmsubd(as_FloatRegister($dst$$reg), 12721 as_FloatRegister($src1$$reg), 12722 as_FloatRegister($src2$$reg), 12723 as_FloatRegister($src3$$reg)); 12724 %} 12725 12726 ins_pipe(pipe_class_default); 12727%} 12728 12729// -src1 * src2 - src3 12730instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 12731 predicate(UseFMA); 12732 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 12733 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 12734 12735 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 12736 12737 ins_encode %{ 12738 __ fnmadds(as_FloatRegister($dst$$reg), 12739 as_FloatRegister($src1$$reg), 12740 as_FloatRegister($src2$$reg), 12741 as_FloatRegister($src3$$reg)); 12742 %} 12743 12744 ins_pipe(pipe_class_default); 12745%} 12746 12747// -src1 * src2 - src3 12748instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 12749 predicate(UseFMA); 12750 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 12751 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 12752 12753 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 12754 12755 ins_encode %{ 12756 __ fnmaddd(as_FloatRegister($dst$$reg), 12757 as_FloatRegister($src1$$reg), 12758 as_FloatRegister($src2$$reg), 12759 as_FloatRegister($src3$$reg)); 12760 %} 12761 12762 ins_pipe(pipe_class_default); 12763%} 12764 12765// src1 * src2 - src3 12766instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 12767 predicate(UseFMA); 12768 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 12769 12770 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 12771 12772 ins_encode %{ 12773 __ fnmsubs(as_FloatRegister($dst$$reg), 12774 as_FloatRegister($src1$$reg), 12775 as_FloatRegister($src2$$reg), 12776 as_FloatRegister($src3$$reg)); 12777 %} 12778 12779 ins_pipe(pipe_class_default); 12780%} 12781 12782// src1 * src2 - src3 12783instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 12784 predicate(UseFMA); 12785 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 12786 12787 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 12788 12789 ins_encode %{ 12790 // n.b. insn name should be fnmsubd 12791 __ fnmsub(as_FloatRegister($dst$$reg), 12792 as_FloatRegister($src1$$reg), 12793 as_FloatRegister($src2$$reg), 12794 as_FloatRegister($src3$$reg)); 12795 %} 12796 12797 ins_pipe(pipe_class_default); 12798%} 12799 12800 12801// Math.max(FF)F 12802instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12803 match(Set dst (MaxF src1 src2)); 12804 12805 format %{ "fmaxs $dst, $src1, $src2" %} 12806 ins_encode %{ 12807 __ fmaxs(as_FloatRegister($dst$$reg), 12808 as_FloatRegister($src1$$reg), 12809 as_FloatRegister($src2$$reg)); 12810 %} 12811 12812 ins_pipe(fp_dop_reg_reg_s); 12813%} 12814 12815// Math.min(FF)F 12816instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12817 match(Set dst (MinF src1 src2)); 12818 12819 format %{ "fmins $dst, $src1, $src2" %} 12820 ins_encode %{ 12821 __ fmins(as_FloatRegister($dst$$reg), 12822 as_FloatRegister($src1$$reg), 12823 as_FloatRegister($src2$$reg)); 12824 %} 12825 12826 ins_pipe(fp_dop_reg_reg_s); 12827%} 12828 12829// Math.max(DD)D 12830instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12831 match(Set dst (MaxD src1 src2)); 12832 12833 format %{ "fmaxd $dst, $src1, $src2" %} 12834 ins_encode %{ 12835 __ fmaxd(as_FloatRegister($dst$$reg), 12836 as_FloatRegister($src1$$reg), 12837 as_FloatRegister($src2$$reg)); 12838 %} 12839 12840 ins_pipe(fp_dop_reg_reg_d); 12841%} 12842 12843// Math.min(DD)D 12844instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12845 match(Set dst (MinD src1 src2)); 12846 12847 format %{ "fmind $dst, $src1, $src2" %} 12848 ins_encode %{ 12849 __ fmind(as_FloatRegister($dst$$reg), 12850 as_FloatRegister($src1$$reg), 12851 as_FloatRegister($src2$$reg)); 12852 %} 12853 12854 ins_pipe(fp_dop_reg_reg_d); 12855%} 12856 12857 12858instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 12859 match(Set dst (DivF src1 src2)); 12860 12861 ins_cost(INSN_COST * 18); 12862 format %{ "fdivs $dst, $src1, $src2" %} 12863 12864 ins_encode %{ 12865 __ fdivs(as_FloatRegister($dst$$reg), 12866 as_FloatRegister($src1$$reg), 12867 as_FloatRegister($src2$$reg)); 12868 %} 12869 12870 ins_pipe(fp_div_s); 12871%} 12872 12873instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 12874 match(Set dst (DivD src1 src2)); 12875 12876 ins_cost(INSN_COST * 32); 12877 format %{ "fdivd $dst, $src1, $src2" %} 12878 12879 ins_encode %{ 12880 __ fdivd(as_FloatRegister($dst$$reg), 12881 as_FloatRegister($src1$$reg), 12882 as_FloatRegister($src2$$reg)); 12883 %} 12884 12885 ins_pipe(fp_div_d); 12886%} 12887 12888instruct negF_reg_reg(vRegF dst, vRegF src) %{ 12889 match(Set dst (NegF src)); 12890 12891 ins_cost(INSN_COST * 3); 12892 format %{ "fneg $dst, $src" %} 12893 12894 ins_encode %{ 12895 __ fnegs(as_FloatRegister($dst$$reg), 12896 as_FloatRegister($src$$reg)); 12897 %} 12898 12899 ins_pipe(fp_uop_s); 12900%} 12901 12902instruct negD_reg_reg(vRegD dst, vRegD src) %{ 12903 match(Set dst (NegD src)); 12904 12905 ins_cost(INSN_COST * 3); 12906 format %{ "fnegd $dst, $src" %} 12907 12908 ins_encode %{ 12909 __ fnegd(as_FloatRegister($dst$$reg), 12910 as_FloatRegister($src$$reg)); 12911 %} 12912 12913 ins_pipe(fp_uop_d); 12914%} 12915 12916instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 12917%{ 12918 match(Set dst (AbsI src)); 12919 12920 effect(KILL cr); 12921 ins_cost(INSN_COST * 2); 12922 format %{ "cmpw $src, zr\n\t" 12923 "cnegw $dst, $src, Assembler::LT\t# int abs" 12924 %} 12925 12926 ins_encode %{ 12927 __ cmpw(as_Register($src$$reg), zr); 12928 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 12929 %} 12930 ins_pipe(pipe_class_default); 12931%} 12932 12933instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 12934%{ 12935 match(Set dst (AbsL src)); 12936 12937 effect(KILL cr); 12938 ins_cost(INSN_COST * 2); 12939 format %{ "cmp $src, zr\n\t" 12940 "cneg $dst, $src, Assembler::LT\t# long abs" 12941 %} 12942 12943 ins_encode %{ 12944 __ cmp(as_Register($src$$reg), zr); 12945 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 12946 %} 12947 ins_pipe(pipe_class_default); 12948%} 12949 12950instruct absF_reg(vRegF dst, vRegF src) %{ 12951 match(Set dst (AbsF src)); 12952 12953 ins_cost(INSN_COST * 3); 12954 format %{ "fabss $dst, $src" %} 12955 ins_encode %{ 12956 __ fabss(as_FloatRegister($dst$$reg), 12957 as_FloatRegister($src$$reg)); 12958 %} 12959 12960 ins_pipe(fp_uop_s); 12961%} 12962 12963instruct absD_reg(vRegD dst, vRegD src) %{ 12964 match(Set dst (AbsD src)); 12965 12966 ins_cost(INSN_COST * 3); 12967 format %{ "fabsd $dst, $src" %} 12968 ins_encode %{ 12969 __ fabsd(as_FloatRegister($dst$$reg), 12970 as_FloatRegister($src$$reg)); 12971 %} 12972 12973 ins_pipe(fp_uop_d); 12974%} 12975 12976instruct sqrtD_reg(vRegD dst, vRegD src) %{ 12977 match(Set dst (SqrtD src)); 12978 12979 ins_cost(INSN_COST * 50); 12980 format %{ "fsqrtd $dst, $src" %} 12981 ins_encode %{ 12982 __ fsqrtd(as_FloatRegister($dst$$reg), 12983 as_FloatRegister($src$$reg)); 12984 %} 12985 12986 ins_pipe(fp_div_s); 12987%} 12988 12989instruct sqrtF_reg(vRegF dst, vRegF src) %{ 12990 match(Set dst (SqrtF src)); 12991 12992 ins_cost(INSN_COST * 50); 12993 format %{ "fsqrts $dst, $src" %} 12994 ins_encode %{ 12995 __ fsqrts(as_FloatRegister($dst$$reg), 12996 as_FloatRegister($src$$reg)); 12997 %} 12998 12999 ins_pipe(fp_div_d); 13000%} 13001 13002instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 13003 match(Set dst (CopySignD src1 (Binary src2 zero))); 13004 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 13005 format %{ "CopySignD $dst $src1 $src2" %} 13006 ins_encode %{ 13007 FloatRegister dst = as_FloatRegister($dst$$reg), 13008 src1 = as_FloatRegister($src1$$reg), 13009 src2 = as_FloatRegister($src2$$reg), 13010 zero = as_FloatRegister($zero$$reg); 13011 __ fnegd(dst, zero); 13012 __ bsl(dst, __ T8B, src2, src1); 13013 %} 13014 ins_pipe(fp_uop_d); 13015%} 13016 13017instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13018 match(Set dst (CopySignF src1 src2)); 13019 effect(TEMP_DEF dst, USE src1, USE src2); 13020 format %{ "CopySignF $dst $src1 $src2" %} 13021 ins_encode %{ 13022 FloatRegister dst = as_FloatRegister($dst$$reg), 13023 src1 = as_FloatRegister($src1$$reg), 13024 src2 = as_FloatRegister($src2$$reg); 13025 __ movi(dst, __ T2S, 0x80, 24); 13026 __ bsl(dst, __ T8B, src2, src1); 13027 %} 13028 ins_pipe(fp_uop_d); 13029%} 13030 13031instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 13032 match(Set dst (SignumD src (Binary zero one))); 13033 effect(TEMP_DEF dst, USE src, USE zero, USE one); 13034 format %{ "signumD $dst, $src" %} 13035 ins_encode %{ 13036 FloatRegister src = as_FloatRegister($src$$reg), 13037 dst = as_FloatRegister($dst$$reg), 13038 zero = as_FloatRegister($zero$$reg), 13039 one = as_FloatRegister($one$$reg); 13040 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 13041 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 13042 // Bit selection instruction gets bit from "one" for each enabled bit in 13043 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 13044 // NaN the whole "src" will be copied because "dst" is zero. For all other 13045 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 13046 // from "src", and all other bits are copied from 1.0. 13047 __ bsl(dst, __ T8B, one, src); 13048 %} 13049 ins_pipe(fp_uop_d); 13050%} 13051 13052instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 13053 match(Set dst (SignumF src (Binary zero one))); 13054 effect(TEMP_DEF dst, USE src, USE zero, USE one); 13055 format %{ "signumF $dst, $src" %} 13056 ins_encode %{ 13057 FloatRegister src = as_FloatRegister($src$$reg), 13058 dst = as_FloatRegister($dst$$reg), 13059 zero = as_FloatRegister($zero$$reg), 13060 one = as_FloatRegister($one$$reg); 13061 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 13062 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 13063 // Bit selection instruction gets bit from "one" for each enabled bit in 13064 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 13065 // NaN the whole "src" will be copied because "dst" is zero. For all other 13066 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 13067 // from "src", and all other bits are copied from 1.0. 13068 __ bsl(dst, __ T8B, one, src); 13069 %} 13070 ins_pipe(fp_uop_d); 13071%} 13072 13073// ============================================================================ 13074// Logical Instructions 13075 13076// Integer Logical Instructions 13077 13078// And Instructions 13079 13080 13081instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 13082 match(Set dst (AndI src1 src2)); 13083 13084 format %{ "andw $dst, $src1, $src2\t# int" %} 13085 13086 ins_cost(INSN_COST); 13087 ins_encode %{ 13088 __ andw(as_Register($dst$$reg), 13089 as_Register($src1$$reg), 13090 as_Register($src2$$reg)); 13091 %} 13092 13093 ins_pipe(ialu_reg_reg); 13094%} 13095 13096instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 13097 match(Set dst (AndI src1 src2)); 13098 13099 format %{ "andsw $dst, $src1, $src2\t# int" %} 13100 13101 ins_cost(INSN_COST); 13102 ins_encode %{ 13103 __ andw(as_Register($dst$$reg), 13104 as_Register($src1$$reg), 13105 (uint64_t)($src2$$constant)); 13106 %} 13107 13108 ins_pipe(ialu_reg_imm); 13109%} 13110 13111// Or Instructions 13112 13113instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13114 match(Set dst (OrI src1 src2)); 13115 13116 format %{ "orrw $dst, $src1, $src2\t# int" %} 13117 13118 ins_cost(INSN_COST); 13119 ins_encode %{ 13120 __ orrw(as_Register($dst$$reg), 13121 as_Register($src1$$reg), 13122 as_Register($src2$$reg)); 13123 %} 13124 13125 ins_pipe(ialu_reg_reg); 13126%} 13127 13128instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13129 match(Set dst (OrI src1 src2)); 13130 13131 format %{ "orrw $dst, $src1, $src2\t# int" %} 13132 13133 ins_cost(INSN_COST); 13134 ins_encode %{ 13135 __ orrw(as_Register($dst$$reg), 13136 as_Register($src1$$reg), 13137 (uint64_t)($src2$$constant)); 13138 %} 13139 13140 ins_pipe(ialu_reg_imm); 13141%} 13142 13143// Xor Instructions 13144 13145instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 13146 match(Set dst (XorI src1 src2)); 13147 13148 format %{ "eorw $dst, $src1, $src2\t# int" %} 13149 13150 ins_cost(INSN_COST); 13151 ins_encode %{ 13152 __ eorw(as_Register($dst$$reg), 13153 as_Register($src1$$reg), 13154 as_Register($src2$$reg)); 13155 %} 13156 13157 ins_pipe(ialu_reg_reg); 13158%} 13159 13160instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 13161 match(Set dst (XorI src1 src2)); 13162 13163 format %{ "eorw $dst, $src1, $src2\t# int" %} 13164 13165 ins_cost(INSN_COST); 13166 ins_encode %{ 13167 __ eorw(as_Register($dst$$reg), 13168 as_Register($src1$$reg), 13169 (uint64_t)($src2$$constant)); 13170 %} 13171 13172 ins_pipe(ialu_reg_imm); 13173%} 13174 13175// Long Logical Instructions 13176// TODO 13177 13178instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 13179 match(Set dst (AndL src1 src2)); 13180 13181 format %{ "and $dst, $src1, $src2\t# int" %} 13182 13183 ins_cost(INSN_COST); 13184 ins_encode %{ 13185 __ andr(as_Register($dst$$reg), 13186 as_Register($src1$$reg), 13187 as_Register($src2$$reg)); 13188 %} 13189 13190 ins_pipe(ialu_reg_reg); 13191%} 13192 13193instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 13194 match(Set dst (AndL src1 src2)); 13195 13196 format %{ "and $dst, $src1, $src2\t# int" %} 13197 13198 ins_cost(INSN_COST); 13199 ins_encode %{ 13200 __ andr(as_Register($dst$$reg), 13201 as_Register($src1$$reg), 13202 (uint64_t)($src2$$constant)); 13203 %} 13204 13205 ins_pipe(ialu_reg_imm); 13206%} 13207 13208// Or Instructions 13209 13210instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13211 match(Set dst (OrL src1 src2)); 13212 13213 format %{ "orr $dst, $src1, $src2\t# int" %} 13214 13215 ins_cost(INSN_COST); 13216 ins_encode %{ 13217 __ orr(as_Register($dst$$reg), 13218 as_Register($src1$$reg), 13219 as_Register($src2$$reg)); 13220 %} 13221 13222 ins_pipe(ialu_reg_reg); 13223%} 13224 13225instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13226 match(Set dst (OrL src1 src2)); 13227 13228 format %{ "orr $dst, $src1, $src2\t# int" %} 13229 13230 ins_cost(INSN_COST); 13231 ins_encode %{ 13232 __ orr(as_Register($dst$$reg), 13233 as_Register($src1$$reg), 13234 (uint64_t)($src2$$constant)); 13235 %} 13236 13237 ins_pipe(ialu_reg_imm); 13238%} 13239 13240// Xor Instructions 13241 13242instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 13243 match(Set dst (XorL src1 src2)); 13244 13245 format %{ "eor $dst, $src1, $src2\t# int" %} 13246 13247 ins_cost(INSN_COST); 13248 ins_encode %{ 13249 __ eor(as_Register($dst$$reg), 13250 as_Register($src1$$reg), 13251 as_Register($src2$$reg)); 13252 %} 13253 13254 ins_pipe(ialu_reg_reg); 13255%} 13256 13257instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 13258 match(Set dst (XorL src1 src2)); 13259 13260 ins_cost(INSN_COST); 13261 format %{ "eor $dst, $src1, $src2\t# int" %} 13262 13263 ins_encode %{ 13264 __ eor(as_Register($dst$$reg), 13265 as_Register($src1$$reg), 13266 (uint64_t)($src2$$constant)); 13267 %} 13268 13269 ins_pipe(ialu_reg_imm); 13270%} 13271 13272instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 13273%{ 13274 match(Set dst (ConvI2L src)); 13275 13276 ins_cost(INSN_COST); 13277 format %{ "sxtw $dst, $src\t# i2l" %} 13278 ins_encode %{ 13279 __ sbfm($dst$$Register, $src$$Register, 0, 31); 13280 %} 13281 ins_pipe(ialu_reg_shift); 13282%} 13283 13284// this pattern occurs in bigmath arithmetic 13285instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 13286%{ 13287 match(Set dst (AndL (ConvI2L src) mask)); 13288 13289 ins_cost(INSN_COST); 13290 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 13291 ins_encode %{ 13292 __ ubfm($dst$$Register, $src$$Register, 0, 31); 13293 %} 13294 13295 ins_pipe(ialu_reg_shift); 13296%} 13297 13298instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 13299 match(Set dst (ConvL2I src)); 13300 13301 ins_cost(INSN_COST); 13302 format %{ "movw $dst, $src \t// l2i" %} 13303 13304 ins_encode %{ 13305 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 13306 %} 13307 13308 ins_pipe(ialu_reg); 13309%} 13310 13311instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 13312%{ 13313 match(Set dst (Conv2B src)); 13314 effect(KILL cr); 13315 13316 format %{ 13317 "cmpw $src, zr\n\t" 13318 "cset $dst, ne" 13319 %} 13320 13321 ins_encode %{ 13322 __ cmpw(as_Register($src$$reg), zr); 13323 __ cset(as_Register($dst$$reg), Assembler::NE); 13324 %} 13325 13326 ins_pipe(ialu_reg); 13327%} 13328 13329instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 13330%{ 13331 match(Set dst (Conv2B src)); 13332 effect(KILL cr); 13333 13334 format %{ 13335 "cmp $src, zr\n\t" 13336 "cset $dst, ne" 13337 %} 13338 13339 ins_encode %{ 13340 __ cmp(as_Register($src$$reg), zr); 13341 __ cset(as_Register($dst$$reg), Assembler::NE); 13342 %} 13343 13344 ins_pipe(ialu_reg); 13345%} 13346 13347instruct convD2F_reg(vRegF dst, vRegD src) %{ 13348 match(Set dst (ConvD2F src)); 13349 13350 ins_cost(INSN_COST * 5); 13351 format %{ "fcvtd $dst, $src \t// d2f" %} 13352 13353 ins_encode %{ 13354 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13355 %} 13356 13357 ins_pipe(fp_d2f); 13358%} 13359 13360instruct convF2D_reg(vRegD dst, vRegF src) %{ 13361 match(Set dst (ConvF2D src)); 13362 13363 ins_cost(INSN_COST * 5); 13364 format %{ "fcvts $dst, $src \t// f2d" %} 13365 13366 ins_encode %{ 13367 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 13368 %} 13369 13370 ins_pipe(fp_f2d); 13371%} 13372 13373instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13374 match(Set dst (ConvF2I src)); 13375 13376 ins_cost(INSN_COST * 5); 13377 format %{ "fcvtzsw $dst, $src \t// f2i" %} 13378 13379 ins_encode %{ 13380 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13381 %} 13382 13383 ins_pipe(fp_f2i); 13384%} 13385 13386instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 13387 match(Set dst (ConvF2L src)); 13388 13389 ins_cost(INSN_COST * 5); 13390 format %{ "fcvtzs $dst, $src \t// f2l" %} 13391 13392 ins_encode %{ 13393 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13394 %} 13395 13396 ins_pipe(fp_f2l); 13397%} 13398 13399instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 13400 match(Set dst (ConvI2F src)); 13401 13402 ins_cost(INSN_COST * 5); 13403 format %{ "scvtfws $dst, $src \t// i2f" %} 13404 13405 ins_encode %{ 13406 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13407 %} 13408 13409 ins_pipe(fp_i2f); 13410%} 13411 13412instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 13413 match(Set dst (ConvL2F src)); 13414 13415 ins_cost(INSN_COST * 5); 13416 format %{ "scvtfs $dst, $src \t// l2f" %} 13417 13418 ins_encode %{ 13419 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13420 %} 13421 13422 ins_pipe(fp_l2f); 13423%} 13424 13425instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 13426 match(Set dst (ConvD2I src)); 13427 13428 ins_cost(INSN_COST * 5); 13429 format %{ "fcvtzdw $dst, $src \t// d2i" %} 13430 13431 ins_encode %{ 13432 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13433 %} 13434 13435 ins_pipe(fp_d2i); 13436%} 13437 13438instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13439 match(Set dst (ConvD2L src)); 13440 13441 ins_cost(INSN_COST * 5); 13442 format %{ "fcvtzd $dst, $src \t// d2l" %} 13443 13444 ins_encode %{ 13445 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 13446 %} 13447 13448 ins_pipe(fp_d2l); 13449%} 13450 13451instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 13452 match(Set dst (ConvI2D src)); 13453 13454 ins_cost(INSN_COST * 5); 13455 format %{ "scvtfwd $dst, $src \t// i2d" %} 13456 13457 ins_encode %{ 13458 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13459 %} 13460 13461 ins_pipe(fp_i2d); 13462%} 13463 13464instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 13465 match(Set dst (ConvL2D src)); 13466 13467 ins_cost(INSN_COST * 5); 13468 format %{ "scvtfd $dst, $src \t// l2d" %} 13469 13470 ins_encode %{ 13471 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 13472 %} 13473 13474 ins_pipe(fp_l2d); 13475%} 13476 13477// stack <-> reg and reg <-> reg shuffles with no conversion 13478 13479instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 13480 13481 match(Set dst (MoveF2I src)); 13482 13483 effect(DEF dst, USE src); 13484 13485 ins_cost(4 * INSN_COST); 13486 13487 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 13488 13489 ins_encode %{ 13490 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 13491 %} 13492 13493 ins_pipe(iload_reg_reg); 13494 13495%} 13496 13497instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 13498 13499 match(Set dst (MoveI2F src)); 13500 13501 effect(DEF dst, USE src); 13502 13503 ins_cost(4 * INSN_COST); 13504 13505 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 13506 13507 ins_encode %{ 13508 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13509 %} 13510 13511 ins_pipe(pipe_class_memory); 13512 13513%} 13514 13515instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 13516 13517 match(Set dst (MoveD2L src)); 13518 13519 effect(DEF dst, USE src); 13520 13521 ins_cost(4 * INSN_COST); 13522 13523 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 13524 13525 ins_encode %{ 13526 __ ldr($dst$$Register, Address(sp, $src$$disp)); 13527 %} 13528 13529 ins_pipe(iload_reg_reg); 13530 13531%} 13532 13533instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 13534 13535 match(Set dst (MoveL2D src)); 13536 13537 effect(DEF dst, USE src); 13538 13539 ins_cost(4 * INSN_COST); 13540 13541 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 13542 13543 ins_encode %{ 13544 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 13545 %} 13546 13547 ins_pipe(pipe_class_memory); 13548 13549%} 13550 13551instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 13552 13553 match(Set dst (MoveF2I src)); 13554 13555 effect(DEF dst, USE src); 13556 13557 ins_cost(INSN_COST); 13558 13559 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 13560 13561 ins_encode %{ 13562 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13563 %} 13564 13565 ins_pipe(pipe_class_memory); 13566 13567%} 13568 13569instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 13570 13571 match(Set dst (MoveI2F src)); 13572 13573 effect(DEF dst, USE src); 13574 13575 ins_cost(INSN_COST); 13576 13577 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 13578 13579 ins_encode %{ 13580 __ strw($src$$Register, Address(sp, $dst$$disp)); 13581 %} 13582 13583 ins_pipe(istore_reg_reg); 13584 13585%} 13586 13587instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 13588 13589 match(Set dst (MoveD2L src)); 13590 13591 effect(DEF dst, USE src); 13592 13593 ins_cost(INSN_COST); 13594 13595 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 13596 13597 ins_encode %{ 13598 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 13599 %} 13600 13601 ins_pipe(pipe_class_memory); 13602 13603%} 13604 13605instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 13606 13607 match(Set dst (MoveL2D src)); 13608 13609 effect(DEF dst, USE src); 13610 13611 ins_cost(INSN_COST); 13612 13613 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 13614 13615 ins_encode %{ 13616 __ str($src$$Register, Address(sp, $dst$$disp)); 13617 %} 13618 13619 ins_pipe(istore_reg_reg); 13620 13621%} 13622 13623instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 13624 13625 match(Set dst (MoveF2I src)); 13626 13627 effect(DEF dst, USE src); 13628 13629 ins_cost(INSN_COST); 13630 13631 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 13632 13633 ins_encode %{ 13634 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 13635 %} 13636 13637 ins_pipe(fp_f2i); 13638 13639%} 13640 13641instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 13642 13643 match(Set dst (MoveI2F src)); 13644 13645 effect(DEF dst, USE src); 13646 13647 ins_cost(INSN_COST); 13648 13649 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 13650 13651 ins_encode %{ 13652 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 13653 %} 13654 13655 ins_pipe(fp_i2f); 13656 13657%} 13658 13659instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 13660 13661 match(Set dst (MoveD2L src)); 13662 13663 effect(DEF dst, USE src); 13664 13665 ins_cost(INSN_COST); 13666 13667 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 13668 13669 ins_encode %{ 13670 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 13671 %} 13672 13673 ins_pipe(fp_d2l); 13674 13675%} 13676 13677instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 13678 13679 match(Set dst (MoveL2D src)); 13680 13681 effect(DEF dst, USE src); 13682 13683 ins_cost(INSN_COST); 13684 13685 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 13686 13687 ins_encode %{ 13688 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 13689 %} 13690 13691 ins_pipe(fp_l2d); 13692 13693%} 13694 13695// ============================================================================ 13696// clearing of an array 13697 13698instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13699%{ 13700 match(Set dummy (ClearArray cnt base)); 13701 effect(USE_KILL cnt, USE_KILL base, KILL cr); 13702 13703 ins_cost(4 * INSN_COST); 13704 format %{ "ClearArray $cnt, $base" %} 13705 13706 ins_encode %{ 13707 address tpc = __ zero_words($base$$Register, $cnt$$Register); 13708 if (tpc == NULL) { 13709 ciEnv::current()->record_failure("CodeCache is full"); 13710 return; 13711 } 13712 %} 13713 13714 ins_pipe(pipe_class_memory); 13715%} 13716 13717instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 13718%{ 13719 predicate((uint64_t)n->in(2)->get_long() 13720 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 13721 match(Set dummy (ClearArray cnt base)); 13722 effect(USE_KILL base); 13723 13724 ins_cost(4 * INSN_COST); 13725 format %{ "ClearArray $cnt, $base" %} 13726 13727 ins_encode %{ 13728 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 13729 %} 13730 13731 ins_pipe(pipe_class_memory); 13732%} 13733 13734// ============================================================================ 13735// Overflow Math Instructions 13736 13737instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13738%{ 13739 match(Set cr (OverflowAddI op1 op2)); 13740 13741 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13742 ins_cost(INSN_COST); 13743 ins_encode %{ 13744 __ cmnw($op1$$Register, $op2$$Register); 13745 %} 13746 13747 ins_pipe(icmp_reg_reg); 13748%} 13749 13750instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13751%{ 13752 match(Set cr (OverflowAddI op1 op2)); 13753 13754 format %{ "cmnw $op1, $op2\t# overflow check int" %} 13755 ins_cost(INSN_COST); 13756 ins_encode %{ 13757 __ cmnw($op1$$Register, $op2$$constant); 13758 %} 13759 13760 ins_pipe(icmp_reg_imm); 13761%} 13762 13763instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13764%{ 13765 match(Set cr (OverflowAddL op1 op2)); 13766 13767 format %{ "cmn $op1, $op2\t# overflow check long" %} 13768 ins_cost(INSN_COST); 13769 ins_encode %{ 13770 __ cmn($op1$$Register, $op2$$Register); 13771 %} 13772 13773 ins_pipe(icmp_reg_reg); 13774%} 13775 13776instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13777%{ 13778 match(Set cr (OverflowAddL op1 op2)); 13779 13780 format %{ "cmn $op1, $op2\t# overflow check long" %} 13781 ins_cost(INSN_COST); 13782 ins_encode %{ 13783 __ cmn($op1$$Register, $op2$$constant); 13784 %} 13785 13786 ins_pipe(icmp_reg_imm); 13787%} 13788 13789instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13790%{ 13791 match(Set cr (OverflowSubI op1 op2)); 13792 13793 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13794 ins_cost(INSN_COST); 13795 ins_encode %{ 13796 __ cmpw($op1$$Register, $op2$$Register); 13797 %} 13798 13799 ins_pipe(icmp_reg_reg); 13800%} 13801 13802instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 13803%{ 13804 match(Set cr (OverflowSubI op1 op2)); 13805 13806 format %{ "cmpw $op1, $op2\t# overflow check int" %} 13807 ins_cost(INSN_COST); 13808 ins_encode %{ 13809 __ cmpw($op1$$Register, $op2$$constant); 13810 %} 13811 13812 ins_pipe(icmp_reg_imm); 13813%} 13814 13815instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13816%{ 13817 match(Set cr (OverflowSubL op1 op2)); 13818 13819 format %{ "cmp $op1, $op2\t# overflow check long" %} 13820 ins_cost(INSN_COST); 13821 ins_encode %{ 13822 __ cmp($op1$$Register, $op2$$Register); 13823 %} 13824 13825 ins_pipe(icmp_reg_reg); 13826%} 13827 13828instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 13829%{ 13830 match(Set cr (OverflowSubL op1 op2)); 13831 13832 format %{ "cmp $op1, $op2\t# overflow check long" %} 13833 ins_cost(INSN_COST); 13834 ins_encode %{ 13835 __ cmp($op1$$Register, $op2$$constant); 13836 %} 13837 13838 ins_pipe(icmp_reg_imm); 13839%} 13840 13841instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 13842%{ 13843 match(Set cr (OverflowSubI zero op1)); 13844 13845 format %{ "cmpw zr, $op1\t# overflow check int" %} 13846 ins_cost(INSN_COST); 13847 ins_encode %{ 13848 __ cmpw(zr, $op1$$Register); 13849 %} 13850 13851 ins_pipe(icmp_reg_imm); 13852%} 13853 13854instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 13855%{ 13856 match(Set cr (OverflowSubL zero op1)); 13857 13858 format %{ "cmp zr, $op1\t# overflow check long" %} 13859 ins_cost(INSN_COST); 13860 ins_encode %{ 13861 __ cmp(zr, $op1$$Register); 13862 %} 13863 13864 ins_pipe(icmp_reg_imm); 13865%} 13866 13867instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 13868%{ 13869 match(Set cr (OverflowMulI op1 op2)); 13870 13871 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13872 "cmp rscratch1, rscratch1, sxtw\n\t" 13873 "movw rscratch1, #0x80000000\n\t" 13874 "cselw rscratch1, rscratch1, zr, NE\n\t" 13875 "cmpw rscratch1, #1" %} 13876 ins_cost(5 * INSN_COST); 13877 ins_encode %{ 13878 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13879 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13880 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13881 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13882 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13883 %} 13884 13885 ins_pipe(pipe_slow); 13886%} 13887 13888instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 13889%{ 13890 match(If cmp (OverflowMulI op1 op2)); 13891 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13892 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13893 effect(USE labl, KILL cr); 13894 13895 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 13896 "cmp rscratch1, rscratch1, sxtw\n\t" 13897 "b$cmp $labl" %} 13898 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 13899 ins_encode %{ 13900 Label* L = $labl$$label; 13901 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13902 __ smull(rscratch1, $op1$$Register, $op2$$Register); 13903 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 13904 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13905 %} 13906 13907 ins_pipe(pipe_serial); 13908%} 13909 13910instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 13911%{ 13912 match(Set cr (OverflowMulL op1 op2)); 13913 13914 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13915 "smulh rscratch2, $op1, $op2\n\t" 13916 "cmp rscratch2, rscratch1, ASR #63\n\t" 13917 "movw rscratch1, #0x80000000\n\t" 13918 "cselw rscratch1, rscratch1, zr, NE\n\t" 13919 "cmpw rscratch1, #1" %} 13920 ins_cost(6 * INSN_COST); 13921 ins_encode %{ 13922 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13923 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13924 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13925 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 13926 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 13927 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 13928 %} 13929 13930 ins_pipe(pipe_slow); 13931%} 13932 13933instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 13934%{ 13935 match(If cmp (OverflowMulL op1 op2)); 13936 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 13937 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 13938 effect(USE labl, KILL cr); 13939 13940 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 13941 "smulh rscratch2, $op1, $op2\n\t" 13942 "cmp rscratch2, rscratch1, ASR #63\n\t" 13943 "b$cmp $labl" %} 13944 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 13945 ins_encode %{ 13946 Label* L = $labl$$label; 13947 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 13948 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 13949 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 13950 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 13951 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 13952 %} 13953 13954 ins_pipe(pipe_serial); 13955%} 13956 13957// ============================================================================ 13958// Compare Instructions 13959 13960instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 13961%{ 13962 match(Set cr (CmpI op1 op2)); 13963 13964 effect(DEF cr, USE op1, USE op2); 13965 13966 ins_cost(INSN_COST); 13967 format %{ "cmpw $op1, $op2" %} 13968 13969 ins_encode(aarch64_enc_cmpw(op1, op2)); 13970 13971 ins_pipe(icmp_reg_reg); 13972%} 13973 13974instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 13975%{ 13976 match(Set cr (CmpI op1 zero)); 13977 13978 effect(DEF cr, USE op1); 13979 13980 ins_cost(INSN_COST); 13981 format %{ "cmpw $op1, 0" %} 13982 13983 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 13984 13985 ins_pipe(icmp_reg_imm); 13986%} 13987 13988instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 13989%{ 13990 match(Set cr (CmpI op1 op2)); 13991 13992 effect(DEF cr, USE op1); 13993 13994 ins_cost(INSN_COST); 13995 format %{ "cmpw $op1, $op2" %} 13996 13997 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 13998 13999 ins_pipe(icmp_reg_imm); 14000%} 14001 14002instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 14003%{ 14004 match(Set cr (CmpI op1 op2)); 14005 14006 effect(DEF cr, USE op1); 14007 14008 ins_cost(INSN_COST * 2); 14009 format %{ "cmpw $op1, $op2" %} 14010 14011 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14012 14013 ins_pipe(icmp_reg_imm); 14014%} 14015 14016// Unsigned compare Instructions; really, same as signed compare 14017// except it should only be used to feed an If or a CMovI which takes a 14018// cmpOpU. 14019 14020instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 14021%{ 14022 match(Set cr (CmpU op1 op2)); 14023 14024 effect(DEF cr, USE op1, USE op2); 14025 14026 ins_cost(INSN_COST); 14027 format %{ "cmpw $op1, $op2\t# unsigned" %} 14028 14029 ins_encode(aarch64_enc_cmpw(op1, op2)); 14030 14031 ins_pipe(icmp_reg_reg); 14032%} 14033 14034instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 14035%{ 14036 match(Set cr (CmpU op1 zero)); 14037 14038 effect(DEF cr, USE op1); 14039 14040 ins_cost(INSN_COST); 14041 format %{ "cmpw $op1, #0\t# unsigned" %} 14042 14043 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 14044 14045 ins_pipe(icmp_reg_imm); 14046%} 14047 14048instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 14049%{ 14050 match(Set cr (CmpU op1 op2)); 14051 14052 effect(DEF cr, USE op1); 14053 14054 ins_cost(INSN_COST); 14055 format %{ "cmpw $op1, $op2\t# unsigned" %} 14056 14057 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 14058 14059 ins_pipe(icmp_reg_imm); 14060%} 14061 14062instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 14063%{ 14064 match(Set cr (CmpU op1 op2)); 14065 14066 effect(DEF cr, USE op1); 14067 14068 ins_cost(INSN_COST * 2); 14069 format %{ "cmpw $op1, $op2\t# unsigned" %} 14070 14071 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 14072 14073 ins_pipe(icmp_reg_imm); 14074%} 14075 14076instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 14077%{ 14078 match(Set cr (CmpL op1 op2)); 14079 14080 effect(DEF cr, USE op1, USE op2); 14081 14082 ins_cost(INSN_COST); 14083 format %{ "cmp $op1, $op2" %} 14084 14085 ins_encode(aarch64_enc_cmp(op1, op2)); 14086 14087 ins_pipe(icmp_reg_reg); 14088%} 14089 14090instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 14091%{ 14092 match(Set cr (CmpL op1 zero)); 14093 14094 effect(DEF cr, USE op1); 14095 14096 ins_cost(INSN_COST); 14097 format %{ "tst $op1" %} 14098 14099 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14100 14101 ins_pipe(icmp_reg_imm); 14102%} 14103 14104instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 14105%{ 14106 match(Set cr (CmpL op1 op2)); 14107 14108 effect(DEF cr, USE op1); 14109 14110 ins_cost(INSN_COST); 14111 format %{ "cmp $op1, $op2" %} 14112 14113 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14114 14115 ins_pipe(icmp_reg_imm); 14116%} 14117 14118instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 14119%{ 14120 match(Set cr (CmpL op1 op2)); 14121 14122 effect(DEF cr, USE op1); 14123 14124 ins_cost(INSN_COST * 2); 14125 format %{ "cmp $op1, $op2" %} 14126 14127 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14128 14129 ins_pipe(icmp_reg_imm); 14130%} 14131 14132instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 14133%{ 14134 match(Set cr (CmpUL op1 op2)); 14135 14136 effect(DEF cr, USE op1, USE op2); 14137 14138 ins_cost(INSN_COST); 14139 format %{ "cmp $op1, $op2" %} 14140 14141 ins_encode(aarch64_enc_cmp(op1, op2)); 14142 14143 ins_pipe(icmp_reg_reg); 14144%} 14145 14146instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 14147%{ 14148 match(Set cr (CmpUL op1 zero)); 14149 14150 effect(DEF cr, USE op1); 14151 14152 ins_cost(INSN_COST); 14153 format %{ "tst $op1" %} 14154 14155 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 14156 14157 ins_pipe(icmp_reg_imm); 14158%} 14159 14160instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 14161%{ 14162 match(Set cr (CmpUL op1 op2)); 14163 14164 effect(DEF cr, USE op1); 14165 14166 ins_cost(INSN_COST); 14167 format %{ "cmp $op1, $op2" %} 14168 14169 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 14170 14171 ins_pipe(icmp_reg_imm); 14172%} 14173 14174instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 14175%{ 14176 match(Set cr (CmpUL op1 op2)); 14177 14178 effect(DEF cr, USE op1); 14179 14180 ins_cost(INSN_COST * 2); 14181 format %{ "cmp $op1, $op2" %} 14182 14183 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 14184 14185 ins_pipe(icmp_reg_imm); 14186%} 14187 14188instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 14189%{ 14190 match(Set cr (CmpP op1 op2)); 14191 14192 effect(DEF cr, USE op1, USE op2); 14193 14194 ins_cost(INSN_COST); 14195 format %{ "cmp $op1, $op2\t // ptr" %} 14196 14197 ins_encode(aarch64_enc_cmpp(op1, op2)); 14198 14199 ins_pipe(icmp_reg_reg); 14200%} 14201 14202instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 14203%{ 14204 match(Set cr (CmpN op1 op2)); 14205 14206 effect(DEF cr, USE op1, USE op2); 14207 14208 ins_cost(INSN_COST); 14209 format %{ "cmp $op1, $op2\t // compressed ptr" %} 14210 14211 ins_encode(aarch64_enc_cmpn(op1, op2)); 14212 14213 ins_pipe(icmp_reg_reg); 14214%} 14215 14216instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 14217%{ 14218 match(Set cr (CmpP op1 zero)); 14219 14220 effect(DEF cr, USE op1, USE zero); 14221 14222 ins_cost(INSN_COST); 14223 format %{ "cmp $op1, 0\t // ptr" %} 14224 14225 ins_encode(aarch64_enc_testp(op1)); 14226 14227 ins_pipe(icmp_reg_imm); 14228%} 14229 14230instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 14231%{ 14232 match(Set cr (CmpN op1 zero)); 14233 14234 effect(DEF cr, USE op1, USE zero); 14235 14236 ins_cost(INSN_COST); 14237 format %{ "cmp $op1, 0\t // compressed ptr" %} 14238 14239 ins_encode(aarch64_enc_testn(op1)); 14240 14241 ins_pipe(icmp_reg_imm); 14242%} 14243 14244// FP comparisons 14245// 14246// n.b. CmpF/CmpD set a normal flags reg which then gets compared 14247// using normal cmpOp. See declaration of rFlagsReg for details. 14248 14249instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 14250%{ 14251 match(Set cr (CmpF src1 src2)); 14252 14253 ins_cost(3 * INSN_COST); 14254 format %{ "fcmps $src1, $src2" %} 14255 14256 ins_encode %{ 14257 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14258 %} 14259 14260 ins_pipe(pipe_class_compare); 14261%} 14262 14263instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 14264%{ 14265 match(Set cr (CmpF src1 src2)); 14266 14267 ins_cost(3 * INSN_COST); 14268 format %{ "fcmps $src1, 0.0" %} 14269 14270 ins_encode %{ 14271 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 14272 %} 14273 14274 ins_pipe(pipe_class_compare); 14275%} 14276// FROM HERE 14277 14278instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 14279%{ 14280 match(Set cr (CmpD src1 src2)); 14281 14282 ins_cost(3 * INSN_COST); 14283 format %{ "fcmpd $src1, $src2" %} 14284 14285 ins_encode %{ 14286 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 14287 %} 14288 14289 ins_pipe(pipe_class_compare); 14290%} 14291 14292instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 14293%{ 14294 match(Set cr (CmpD src1 src2)); 14295 14296 ins_cost(3 * INSN_COST); 14297 format %{ "fcmpd $src1, 0.0" %} 14298 14299 ins_encode %{ 14300 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 14301 %} 14302 14303 ins_pipe(pipe_class_compare); 14304%} 14305 14306instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 14307%{ 14308 match(Set dst (CmpF3 src1 src2)); 14309 effect(KILL cr); 14310 14311 ins_cost(5 * INSN_COST); 14312 format %{ "fcmps $src1, $src2\n\t" 14313 "csinvw($dst, zr, zr, eq\n\t" 14314 "csnegw($dst, $dst, $dst, lt)" 14315 %} 14316 14317 ins_encode %{ 14318 Label done; 14319 FloatRegister s1 = as_FloatRegister($src1$$reg); 14320 FloatRegister s2 = as_FloatRegister($src2$$reg); 14321 Register d = as_Register($dst$$reg); 14322 __ fcmps(s1, s2); 14323 // installs 0 if EQ else -1 14324 __ csinvw(d, zr, zr, Assembler::EQ); 14325 // keeps -1 if less or unordered else installs 1 14326 __ csnegw(d, d, d, Assembler::LT); 14327 __ bind(done); 14328 %} 14329 14330 ins_pipe(pipe_class_default); 14331 14332%} 14333 14334instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 14335%{ 14336 match(Set dst (CmpD3 src1 src2)); 14337 effect(KILL cr); 14338 14339 ins_cost(5 * INSN_COST); 14340 format %{ "fcmpd $src1, $src2\n\t" 14341 "csinvw($dst, zr, zr, eq\n\t" 14342 "csnegw($dst, $dst, $dst, lt)" 14343 %} 14344 14345 ins_encode %{ 14346 Label done; 14347 FloatRegister s1 = as_FloatRegister($src1$$reg); 14348 FloatRegister s2 = as_FloatRegister($src2$$reg); 14349 Register d = as_Register($dst$$reg); 14350 __ fcmpd(s1, s2); 14351 // installs 0 if EQ else -1 14352 __ csinvw(d, zr, zr, Assembler::EQ); 14353 // keeps -1 if less or unordered else installs 1 14354 __ csnegw(d, d, d, Assembler::LT); 14355 __ bind(done); 14356 %} 14357 ins_pipe(pipe_class_default); 14358 14359%} 14360 14361instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 14362%{ 14363 match(Set dst (CmpF3 src1 zero)); 14364 effect(KILL cr); 14365 14366 ins_cost(5 * INSN_COST); 14367 format %{ "fcmps $src1, 0.0\n\t" 14368 "csinvw($dst, zr, zr, eq\n\t" 14369 "csnegw($dst, $dst, $dst, lt)" 14370 %} 14371 14372 ins_encode %{ 14373 Label done; 14374 FloatRegister s1 = as_FloatRegister($src1$$reg); 14375 Register d = as_Register($dst$$reg); 14376 __ fcmps(s1, 0.0); 14377 // installs 0 if EQ else -1 14378 __ csinvw(d, zr, zr, Assembler::EQ); 14379 // keeps -1 if less or unordered else installs 1 14380 __ csnegw(d, d, d, Assembler::LT); 14381 __ bind(done); 14382 %} 14383 14384 ins_pipe(pipe_class_default); 14385 14386%} 14387 14388instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 14389%{ 14390 match(Set dst (CmpD3 src1 zero)); 14391 effect(KILL cr); 14392 14393 ins_cost(5 * INSN_COST); 14394 format %{ "fcmpd $src1, 0.0\n\t" 14395 "csinvw($dst, zr, zr, eq\n\t" 14396 "csnegw($dst, $dst, $dst, lt)" 14397 %} 14398 14399 ins_encode %{ 14400 Label done; 14401 FloatRegister s1 = as_FloatRegister($src1$$reg); 14402 Register d = as_Register($dst$$reg); 14403 __ fcmpd(s1, 0.0); 14404 // installs 0 if EQ else -1 14405 __ csinvw(d, zr, zr, Assembler::EQ); 14406 // keeps -1 if less or unordered else installs 1 14407 __ csnegw(d, d, d, Assembler::LT); 14408 __ bind(done); 14409 %} 14410 ins_pipe(pipe_class_default); 14411 14412%} 14413 14414instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 14415%{ 14416 match(Set dst (CmpLTMask p q)); 14417 effect(KILL cr); 14418 14419 ins_cost(3 * INSN_COST); 14420 14421 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 14422 "csetw $dst, lt\n\t" 14423 "subw $dst, zr, $dst" 14424 %} 14425 14426 ins_encode %{ 14427 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 14428 __ csetw(as_Register($dst$$reg), Assembler::LT); 14429 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 14430 %} 14431 14432 ins_pipe(ialu_reg_reg); 14433%} 14434 14435instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 14436%{ 14437 match(Set dst (CmpLTMask src zero)); 14438 effect(KILL cr); 14439 14440 ins_cost(INSN_COST); 14441 14442 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 14443 14444 ins_encode %{ 14445 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 14446 %} 14447 14448 ins_pipe(ialu_reg_shift); 14449%} 14450 14451// ============================================================================ 14452// Max and Min 14453 14454instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14455%{ 14456 effect( DEF dst, USE src1, USE src2, USE cr ); 14457 14458 ins_cost(INSN_COST * 2); 14459 format %{ "cselw $dst, $src1, $src2 lt\t" %} 14460 14461 ins_encode %{ 14462 __ cselw(as_Register($dst$$reg), 14463 as_Register($src1$$reg), 14464 as_Register($src2$$reg), 14465 Assembler::LT); 14466 %} 14467 14468 ins_pipe(icond_reg_reg); 14469%} 14470 14471instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14472%{ 14473 match(Set dst (MinI src1 src2)); 14474 ins_cost(INSN_COST * 3); 14475 14476 expand %{ 14477 rFlagsReg cr; 14478 compI_reg_reg(cr, src1, src2); 14479 cmovI_reg_reg_lt(dst, src1, src2, cr); 14480 %} 14481 14482%} 14483// FROM HERE 14484 14485instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 14486%{ 14487 effect( DEF dst, USE src1, USE src2, USE cr ); 14488 14489 ins_cost(INSN_COST * 2); 14490 format %{ "cselw $dst, $src1, $src2 gt\t" %} 14491 14492 ins_encode %{ 14493 __ cselw(as_Register($dst$$reg), 14494 as_Register($src1$$reg), 14495 as_Register($src2$$reg), 14496 Assembler::GT); 14497 %} 14498 14499 ins_pipe(icond_reg_reg); 14500%} 14501 14502instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 14503%{ 14504 match(Set dst (MaxI src1 src2)); 14505 ins_cost(INSN_COST * 3); 14506 expand %{ 14507 rFlagsReg cr; 14508 compI_reg_reg(cr, src1, src2); 14509 cmovI_reg_reg_gt(dst, src1, src2, cr); 14510 %} 14511%} 14512 14513// ============================================================================ 14514// Branch Instructions 14515 14516// Direct Branch. 14517instruct branch(label lbl) 14518%{ 14519 match(Goto); 14520 14521 effect(USE lbl); 14522 14523 ins_cost(BRANCH_COST); 14524 format %{ "b $lbl" %} 14525 14526 ins_encode(aarch64_enc_b(lbl)); 14527 14528 ins_pipe(pipe_branch); 14529%} 14530 14531// Conditional Near Branch 14532instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 14533%{ 14534 // Same match rule as `branchConFar'. 14535 match(If cmp cr); 14536 14537 effect(USE lbl); 14538 14539 ins_cost(BRANCH_COST); 14540 // If set to 1 this indicates that the current instruction is a 14541 // short variant of a long branch. This avoids using this 14542 // instruction in first-pass matching. It will then only be used in 14543 // the `Shorten_branches' pass. 14544 // ins_short_branch(1); 14545 format %{ "b$cmp $lbl" %} 14546 14547 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14548 14549 ins_pipe(pipe_branch_cond); 14550%} 14551 14552// Conditional Near Branch Unsigned 14553instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14554%{ 14555 // Same match rule as `branchConFar'. 14556 match(If cmp cr); 14557 14558 effect(USE lbl); 14559 14560 ins_cost(BRANCH_COST); 14561 // If set to 1 this indicates that the current instruction is a 14562 // short variant of a long branch. This avoids using this 14563 // instruction in first-pass matching. It will then only be used in 14564 // the `Shorten_branches' pass. 14565 // ins_short_branch(1); 14566 format %{ "b$cmp $lbl\t# unsigned" %} 14567 14568 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14569 14570 ins_pipe(pipe_branch_cond); 14571%} 14572 14573// Make use of CBZ and CBNZ. These instructions, as well as being 14574// shorter than (cmp; branch), have the additional benefit of not 14575// killing the flags. 14576 14577instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 14578 match(If cmp (CmpI op1 op2)); 14579 effect(USE labl); 14580 14581 ins_cost(BRANCH_COST); 14582 format %{ "cbw$cmp $op1, $labl" %} 14583 ins_encode %{ 14584 Label* L = $labl$$label; 14585 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14586 if (cond == Assembler::EQ) 14587 __ cbzw($op1$$Register, *L); 14588 else 14589 __ cbnzw($op1$$Register, *L); 14590 %} 14591 ins_pipe(pipe_cmp_branch); 14592%} 14593 14594instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 14595 match(If cmp (CmpL op1 op2)); 14596 effect(USE labl); 14597 14598 ins_cost(BRANCH_COST); 14599 format %{ "cb$cmp $op1, $labl" %} 14600 ins_encode %{ 14601 Label* L = $labl$$label; 14602 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14603 if (cond == Assembler::EQ) 14604 __ cbz($op1$$Register, *L); 14605 else 14606 __ cbnz($op1$$Register, *L); 14607 %} 14608 ins_pipe(pipe_cmp_branch); 14609%} 14610 14611instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 14612 match(If cmp (CmpP op1 op2)); 14613 effect(USE labl); 14614 14615 ins_cost(BRANCH_COST); 14616 format %{ "cb$cmp $op1, $labl" %} 14617 ins_encode %{ 14618 Label* L = $labl$$label; 14619 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14620 if (cond == Assembler::EQ) 14621 __ cbz($op1$$Register, *L); 14622 else 14623 __ cbnz($op1$$Register, *L); 14624 %} 14625 ins_pipe(pipe_cmp_branch); 14626%} 14627 14628instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 14629 match(If cmp (CmpN op1 op2)); 14630 effect(USE labl); 14631 14632 ins_cost(BRANCH_COST); 14633 format %{ "cbw$cmp $op1, $labl" %} 14634 ins_encode %{ 14635 Label* L = $labl$$label; 14636 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14637 if (cond == Assembler::EQ) 14638 __ cbzw($op1$$Register, *L); 14639 else 14640 __ cbnzw($op1$$Register, *L); 14641 %} 14642 ins_pipe(pipe_cmp_branch); 14643%} 14644 14645instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 14646 match(If cmp (CmpP (DecodeN oop) zero)); 14647 effect(USE labl); 14648 14649 ins_cost(BRANCH_COST); 14650 format %{ "cb$cmp $oop, $labl" %} 14651 ins_encode %{ 14652 Label* L = $labl$$label; 14653 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14654 if (cond == Assembler::EQ) 14655 __ cbzw($oop$$Register, *L); 14656 else 14657 __ cbnzw($oop$$Register, *L); 14658 %} 14659 ins_pipe(pipe_cmp_branch); 14660%} 14661 14662instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 14663 match(If cmp (CmpU op1 op2)); 14664 effect(USE labl); 14665 14666 ins_cost(BRANCH_COST); 14667 format %{ "cbw$cmp $op1, $labl" %} 14668 ins_encode %{ 14669 Label* L = $labl$$label; 14670 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14671 if (cond == Assembler::EQ || cond == Assembler::LS) 14672 __ cbzw($op1$$Register, *L); 14673 else 14674 __ cbnzw($op1$$Register, *L); 14675 %} 14676 ins_pipe(pipe_cmp_branch); 14677%} 14678 14679instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 14680 match(If cmp (CmpUL op1 op2)); 14681 effect(USE labl); 14682 14683 ins_cost(BRANCH_COST); 14684 format %{ "cb$cmp $op1, $labl" %} 14685 ins_encode %{ 14686 Label* L = $labl$$label; 14687 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14688 if (cond == Assembler::EQ || cond == Assembler::LS) 14689 __ cbz($op1$$Register, *L); 14690 else 14691 __ cbnz($op1$$Register, *L); 14692 %} 14693 ins_pipe(pipe_cmp_branch); 14694%} 14695 14696// Test bit and Branch 14697 14698// Patterns for short (< 32KiB) variants 14699instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14700 match(If cmp (CmpL op1 op2)); 14701 effect(USE labl); 14702 14703 ins_cost(BRANCH_COST); 14704 format %{ "cb$cmp $op1, $labl # long" %} 14705 ins_encode %{ 14706 Label* L = $labl$$label; 14707 Assembler::Condition cond = 14708 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14709 __ tbr(cond, $op1$$Register, 63, *L); 14710 %} 14711 ins_pipe(pipe_cmp_branch); 14712 ins_short_branch(1); 14713%} 14714 14715instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14716 match(If cmp (CmpI op1 op2)); 14717 effect(USE labl); 14718 14719 ins_cost(BRANCH_COST); 14720 format %{ "cb$cmp $op1, $labl # int" %} 14721 ins_encode %{ 14722 Label* L = $labl$$label; 14723 Assembler::Condition cond = 14724 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14725 __ tbr(cond, $op1$$Register, 31, *L); 14726 %} 14727 ins_pipe(pipe_cmp_branch); 14728 ins_short_branch(1); 14729%} 14730 14731instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14732 match(If cmp (CmpL (AndL op1 op2) op3)); 14733 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14734 effect(USE labl); 14735 14736 ins_cost(BRANCH_COST); 14737 format %{ "tb$cmp $op1, $op2, $labl" %} 14738 ins_encode %{ 14739 Label* L = $labl$$label; 14740 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14741 int bit = exact_log2($op2$$constant); 14742 __ tbr(cond, $op1$$Register, bit, *L); 14743 %} 14744 ins_pipe(pipe_cmp_branch); 14745 ins_short_branch(1); 14746%} 14747 14748instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14749 match(If cmp (CmpI (AndI op1 op2) op3)); 14750 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14751 effect(USE labl); 14752 14753 ins_cost(BRANCH_COST); 14754 format %{ "tb$cmp $op1, $op2, $labl" %} 14755 ins_encode %{ 14756 Label* L = $labl$$label; 14757 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14758 int bit = exact_log2($op2$$constant); 14759 __ tbr(cond, $op1$$Register, bit, *L); 14760 %} 14761 ins_pipe(pipe_cmp_branch); 14762 ins_short_branch(1); 14763%} 14764 14765// And far variants 14766instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 14767 match(If cmp (CmpL op1 op2)); 14768 effect(USE labl); 14769 14770 ins_cost(BRANCH_COST); 14771 format %{ "cb$cmp $op1, $labl # long" %} 14772 ins_encode %{ 14773 Label* L = $labl$$label; 14774 Assembler::Condition cond = 14775 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14776 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 14777 %} 14778 ins_pipe(pipe_cmp_branch); 14779%} 14780 14781instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 14782 match(If cmp (CmpI op1 op2)); 14783 effect(USE labl); 14784 14785 ins_cost(BRANCH_COST); 14786 format %{ "cb$cmp $op1, $labl # int" %} 14787 ins_encode %{ 14788 Label* L = $labl$$label; 14789 Assembler::Condition cond = 14790 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 14791 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 14792 %} 14793 ins_pipe(pipe_cmp_branch); 14794%} 14795 14796instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 14797 match(If cmp (CmpL (AndL op1 op2) op3)); 14798 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); 14799 effect(USE labl); 14800 14801 ins_cost(BRANCH_COST); 14802 format %{ "tb$cmp $op1, $op2, $labl" %} 14803 ins_encode %{ 14804 Label* L = $labl$$label; 14805 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14806 int bit = exact_log2($op2$$constant); 14807 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14808 %} 14809 ins_pipe(pipe_cmp_branch); 14810%} 14811 14812instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 14813 match(If cmp (CmpI (AndI op1 op2) op3)); 14814 predicate(is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); 14815 effect(USE labl); 14816 14817 ins_cost(BRANCH_COST); 14818 format %{ "tb$cmp $op1, $op2, $labl" %} 14819 ins_encode %{ 14820 Label* L = $labl$$label; 14821 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 14822 int bit = exact_log2($op2$$constant); 14823 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 14824 %} 14825 ins_pipe(pipe_cmp_branch); 14826%} 14827 14828// Test bits 14829 14830instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 14831 match(Set cr (CmpL (AndL op1 op2) op3)); 14832 predicate(Assembler::operand_valid_for_logical_immediate 14833 (/*is_32*/false, n->in(1)->in(2)->get_long())); 14834 14835 ins_cost(INSN_COST); 14836 format %{ "tst $op1, $op2 # long" %} 14837 ins_encode %{ 14838 __ tst($op1$$Register, $op2$$constant); 14839 %} 14840 ins_pipe(ialu_reg_reg); 14841%} 14842 14843instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 14844 match(Set cr (CmpI (AndI op1 op2) op3)); 14845 predicate(Assembler::operand_valid_for_logical_immediate 14846 (/*is_32*/true, n->in(1)->in(2)->get_int())); 14847 14848 ins_cost(INSN_COST); 14849 format %{ "tst $op1, $op2 # int" %} 14850 ins_encode %{ 14851 __ tstw($op1$$Register, $op2$$constant); 14852 %} 14853 ins_pipe(ialu_reg_reg); 14854%} 14855 14856instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 14857 match(Set cr (CmpL (AndL op1 op2) op3)); 14858 14859 ins_cost(INSN_COST); 14860 format %{ "tst $op1, $op2 # long" %} 14861 ins_encode %{ 14862 __ tst($op1$$Register, $op2$$Register); 14863 %} 14864 ins_pipe(ialu_reg_reg); 14865%} 14866 14867instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 14868 match(Set cr (CmpI (AndI op1 op2) op3)); 14869 14870 ins_cost(INSN_COST); 14871 format %{ "tstw $op1, $op2 # int" %} 14872 ins_encode %{ 14873 __ tstw($op1$$Register, $op2$$Register); 14874 %} 14875 ins_pipe(ialu_reg_reg); 14876%} 14877 14878 14879// Conditional Far Branch 14880// Conditional Far Branch Unsigned 14881// TODO: fixme 14882 14883// counted loop end branch near 14884instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 14885%{ 14886 match(CountedLoopEnd cmp cr); 14887 14888 effect(USE lbl); 14889 14890 ins_cost(BRANCH_COST); 14891 // short variant. 14892 // ins_short_branch(1); 14893 format %{ "b$cmp $lbl \t// counted loop end" %} 14894 14895 ins_encode(aarch64_enc_br_con(cmp, lbl)); 14896 14897 ins_pipe(pipe_branch); 14898%} 14899 14900// counted loop end branch near Unsigned 14901instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 14902%{ 14903 match(CountedLoopEnd cmp cr); 14904 14905 effect(USE lbl); 14906 14907 ins_cost(BRANCH_COST); 14908 // short variant. 14909 // ins_short_branch(1); 14910 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 14911 14912 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 14913 14914 ins_pipe(pipe_branch); 14915%} 14916 14917// counted loop end branch far 14918// counted loop end branch far unsigned 14919// TODO: fixme 14920 14921// ============================================================================ 14922// inlined locking and unlocking 14923 14924instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14925%{ 14926 match(Set cr (FastLock object box)); 14927 effect(TEMP tmp, TEMP tmp2); 14928 14929 // TODO 14930 // identify correct cost 14931 ins_cost(5 * INSN_COST); 14932 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 14933 14934 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 14935 14936 ins_pipe(pipe_serial); 14937%} 14938 14939instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 14940%{ 14941 match(Set cr (FastUnlock object box)); 14942 effect(TEMP tmp, TEMP tmp2); 14943 14944 ins_cost(5 * INSN_COST); 14945 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 14946 14947 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 14948 14949 ins_pipe(pipe_serial); 14950%} 14951 14952 14953// ============================================================================ 14954// Safepoint Instructions 14955 14956// TODO 14957// provide a near and far version of this code 14958 14959instruct safePoint(rFlagsReg cr, iRegP poll) 14960%{ 14961 match(SafePoint poll); 14962 effect(KILL cr); 14963 14964 format %{ 14965 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 14966 %} 14967 ins_encode %{ 14968 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 14969 %} 14970 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 14971%} 14972 14973 14974// ============================================================================ 14975// Procedure Call/Return Instructions 14976 14977// Call Java Static Instruction 14978 14979instruct CallStaticJavaDirect(method meth) 14980%{ 14981 match(CallStaticJava); 14982 14983 effect(USE meth); 14984 14985 ins_cost(CALL_COST); 14986 14987 format %{ "call,static $meth \t// ==> " %} 14988 14989 ins_encode( aarch64_enc_java_static_call(meth), 14990 aarch64_enc_call_epilog ); 14991 14992 ins_pipe(pipe_class_call); 14993%} 14994 14995// TO HERE 14996 14997// Call Java Dynamic Instruction 14998instruct CallDynamicJavaDirect(method meth) 14999%{ 15000 match(CallDynamicJava); 15001 15002 effect(USE meth); 15003 15004 ins_cost(CALL_COST); 15005 15006 format %{ "CALL,dynamic $meth \t// ==> " %} 15007 15008 ins_encode( aarch64_enc_java_dynamic_call(meth), 15009 aarch64_enc_call_epilog ); 15010 15011 ins_pipe(pipe_class_call); 15012%} 15013 15014// Call Runtime Instruction 15015 15016instruct CallRuntimeDirect(method meth) 15017%{ 15018 match(CallRuntime); 15019 15020 effect(USE meth); 15021 15022 ins_cost(CALL_COST); 15023 15024 format %{ "CALL, runtime $meth" %} 15025 15026 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15027 15028 ins_pipe(pipe_class_call); 15029%} 15030 15031// Call Runtime Instruction 15032 15033instruct CallLeafDirect(method meth) 15034%{ 15035 match(CallLeaf); 15036 15037 effect(USE meth); 15038 15039 ins_cost(CALL_COST); 15040 15041 format %{ "CALL, runtime leaf $meth" %} 15042 15043 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15044 15045 ins_pipe(pipe_class_call); 15046%} 15047 15048// Call Runtime Instruction 15049 15050instruct CallLeafNoFPDirect(method meth) 15051%{ 15052 match(CallLeafNoFP); 15053 15054 effect(USE meth); 15055 15056 ins_cost(CALL_COST); 15057 15058 format %{ "CALL, runtime leaf nofp $meth" %} 15059 15060 ins_encode( aarch64_enc_java_to_runtime(meth) ); 15061 15062 ins_pipe(pipe_class_call); 15063%} 15064 15065// Tail Call; Jump from runtime stub to Java code. 15066// Also known as an 'interprocedural jump'. 15067// Target of jump will eventually return to caller. 15068// TailJump below removes the return address. 15069instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 15070%{ 15071 match(TailCall jump_target method_oop); 15072 15073 ins_cost(CALL_COST); 15074 15075 format %{ "br $jump_target\t# $method_oop holds method oop" %} 15076 15077 ins_encode(aarch64_enc_tail_call(jump_target)); 15078 15079 ins_pipe(pipe_class_call); 15080%} 15081 15082instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 15083%{ 15084 match(TailJump jump_target ex_oop); 15085 15086 ins_cost(CALL_COST); 15087 15088 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 15089 15090 ins_encode(aarch64_enc_tail_jmp(jump_target)); 15091 15092 ins_pipe(pipe_class_call); 15093%} 15094 15095// Create exception oop: created by stack-crawling runtime code. 15096// Created exception is now available to this handler, and is setup 15097// just prior to jumping to this handler. No code emitted. 15098// TODO check 15099// should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 15100instruct CreateException(iRegP_R0 ex_oop) 15101%{ 15102 match(Set ex_oop (CreateEx)); 15103 15104 format %{ " -- \t// exception oop; no code emitted" %} 15105 15106 size(0); 15107 15108 ins_encode( /*empty*/ ); 15109 15110 ins_pipe(pipe_class_empty); 15111%} 15112 15113// Rethrow exception: The exception oop will come in the first 15114// argument position. Then JUMP (not call) to the rethrow stub code. 15115instruct RethrowException() %{ 15116 match(Rethrow); 15117 ins_cost(CALL_COST); 15118 15119 format %{ "b rethrow_stub" %} 15120 15121 ins_encode( aarch64_enc_rethrow() ); 15122 15123 ins_pipe(pipe_class_call); 15124%} 15125 15126 15127// Return Instruction 15128// epilog node loads ret address into lr as part of frame pop 15129instruct Ret() 15130%{ 15131 match(Return); 15132 15133 format %{ "ret\t// return register" %} 15134 15135 ins_encode( aarch64_enc_ret() ); 15136 15137 ins_pipe(pipe_branch); 15138%} 15139 15140// Die now. 15141instruct ShouldNotReachHere() %{ 15142 match(Halt); 15143 15144 ins_cost(CALL_COST); 15145 format %{ "ShouldNotReachHere" %} 15146 15147 ins_encode %{ 15148 if (is_reachable()) { 15149 __ dpcs1(0xdead + 1); 15150 } 15151 %} 15152 15153 ins_pipe(pipe_class_default); 15154%} 15155 15156// ============================================================================ 15157// Partial Subtype Check 15158// 15159// superklass array for an instance of the superklass. Set a hidden 15160// internal cache on a hit (cache is checked with exposed code in 15161// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 15162// encoding ALSO sets flags. 15163 15164instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 15165%{ 15166 match(Set result (PartialSubtypeCheck sub super)); 15167 effect(KILL cr, KILL temp); 15168 15169 ins_cost(1100); // slightly larger than the next version 15170 format %{ "partialSubtypeCheck $result, $sub, $super" %} 15171 15172 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15173 15174 opcode(0x1); // Force zero of result reg on hit 15175 15176 ins_pipe(pipe_class_memory); 15177%} 15178 15179instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 15180%{ 15181 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 15182 effect(KILL temp, KILL result); 15183 15184 ins_cost(1100); // slightly larger than the next version 15185 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 15186 15187 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 15188 15189 opcode(0x0); // Don't zero result reg on hit 15190 15191 ins_pipe(pipe_class_memory); 15192%} 15193 15194instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15195 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15196%{ 15197 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 15198 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15199 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15200 15201 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15202 ins_encode %{ 15203 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15204 __ string_compare($str1$$Register, $str2$$Register, 15205 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15206 $tmp1$$Register, $tmp2$$Register, 15207 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 15208 %} 15209 ins_pipe(pipe_class_memory); 15210%} 15211 15212instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15213 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 15214%{ 15215 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 15216 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15217 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15218 15219 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 15220 ins_encode %{ 15221 __ string_compare($str1$$Register, $str2$$Register, 15222 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15223 $tmp1$$Register, $tmp2$$Register, 15224 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 15225 %} 15226 ins_pipe(pipe_class_memory); 15227%} 15228 15229instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15230 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15231 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15232%{ 15233 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 15234 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15235 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15236 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15237 15238 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15239 ins_encode %{ 15240 __ string_compare($str1$$Register, $str2$$Register, 15241 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15242 $tmp1$$Register, $tmp2$$Register, 15243 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15244 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 15245 %} 15246 ins_pipe(pipe_class_memory); 15247%} 15248 15249instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 15250 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 15251 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 15252%{ 15253 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 15254 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 15255 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 15256 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 15257 15258 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 15259 ins_encode %{ 15260 __ string_compare($str1$$Register, $str2$$Register, 15261 $cnt1$$Register, $cnt2$$Register, $result$$Register, 15262 $tmp1$$Register, $tmp2$$Register, 15263 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 15264 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 15265 %} 15266 ins_pipe(pipe_class_memory); 15267%} 15268 15269instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15270 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15271 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15272%{ 15273 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15274 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15275 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15276 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15277 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 15278 15279 ins_encode %{ 15280 __ string_indexof($str1$$Register, $str2$$Register, 15281 $cnt1$$Register, $cnt2$$Register, 15282 $tmp1$$Register, $tmp2$$Register, 15283 $tmp3$$Register, $tmp4$$Register, 15284 $tmp5$$Register, $tmp6$$Register, 15285 -1, $result$$Register, StrIntrinsicNode::UU); 15286 %} 15287 ins_pipe(pipe_class_memory); 15288%} 15289 15290instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15291 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15292 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15293%{ 15294 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15295 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15296 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15297 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15298 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 15299 15300 ins_encode %{ 15301 __ string_indexof($str1$$Register, $str2$$Register, 15302 $cnt1$$Register, $cnt2$$Register, 15303 $tmp1$$Register, $tmp2$$Register, 15304 $tmp3$$Register, $tmp4$$Register, 15305 $tmp5$$Register, $tmp6$$Register, 15306 -1, $result$$Register, StrIntrinsicNode::LL); 15307 %} 15308 ins_pipe(pipe_class_memory); 15309%} 15310 15311instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 15312 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 15313 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 15314%{ 15315 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15316 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 15317 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 15318 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 15319 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 15320 15321 ins_encode %{ 15322 __ string_indexof($str1$$Register, $str2$$Register, 15323 $cnt1$$Register, $cnt2$$Register, 15324 $tmp1$$Register, $tmp2$$Register, 15325 $tmp3$$Register, $tmp4$$Register, 15326 $tmp5$$Register, $tmp6$$Register, 15327 -1, $result$$Register, StrIntrinsicNode::UL); 15328 %} 15329 ins_pipe(pipe_class_memory); 15330%} 15331 15332instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15333 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15334 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15335%{ 15336 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 15337 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15338 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15339 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15340 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 15341 15342 ins_encode %{ 15343 int icnt2 = (int)$int_cnt2$$constant; 15344 __ string_indexof($str1$$Register, $str2$$Register, 15345 $cnt1$$Register, zr, 15346 $tmp1$$Register, $tmp2$$Register, 15347 $tmp3$$Register, $tmp4$$Register, zr, zr, 15348 icnt2, $result$$Register, StrIntrinsicNode::UU); 15349 %} 15350 ins_pipe(pipe_class_memory); 15351%} 15352 15353instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15354 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15355 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15356%{ 15357 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 15358 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15359 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15360 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15361 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 15362 15363 ins_encode %{ 15364 int icnt2 = (int)$int_cnt2$$constant; 15365 __ string_indexof($str1$$Register, $str2$$Register, 15366 $cnt1$$Register, zr, 15367 $tmp1$$Register, $tmp2$$Register, 15368 $tmp3$$Register, $tmp4$$Register, zr, zr, 15369 icnt2, $result$$Register, StrIntrinsicNode::LL); 15370 %} 15371 ins_pipe(pipe_class_memory); 15372%} 15373 15374instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 15375 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15376 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 15377%{ 15378 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 15379 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 15380 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 15381 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 15382 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 15383 15384 ins_encode %{ 15385 int icnt2 = (int)$int_cnt2$$constant; 15386 __ string_indexof($str1$$Register, $str2$$Register, 15387 $cnt1$$Register, zr, 15388 $tmp1$$Register, $tmp2$$Register, 15389 $tmp3$$Register, $tmp4$$Register, zr, zr, 15390 icnt2, $result$$Register, StrIntrinsicNode::UL); 15391 %} 15392 ins_pipe(pipe_class_memory); 15393%} 15394 15395instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 15396 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 15397 iRegINoSp tmp3, rFlagsReg cr) 15398%{ 15399 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 15400 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 15401 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15402 15403 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %} 15404 15405 ins_encode %{ 15406 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 15407 $result$$Register, $tmp1$$Register, $tmp2$$Register, 15408 $tmp3$$Register); 15409 %} 15410 ins_pipe(pipe_class_memory); 15411%} 15412 15413instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15414 iRegI_R0 result, rFlagsReg cr) 15415%{ 15416 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 15417 match(Set result (StrEquals (Binary str1 str2) cnt)); 15418 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15419 15420 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15421 ins_encode %{ 15422 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15423 __ string_equals($str1$$Register, $str2$$Register, 15424 $result$$Register, $cnt$$Register, 1); 15425 %} 15426 ins_pipe(pipe_class_memory); 15427%} 15428 15429instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 15430 iRegI_R0 result, rFlagsReg cr) 15431%{ 15432 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 15433 match(Set result (StrEquals (Binary str1 str2) cnt)); 15434 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 15435 15436 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 15437 ins_encode %{ 15438 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 15439 __ string_equals($str1$$Register, $str2$$Register, 15440 $result$$Register, $cnt$$Register, 2); 15441 %} 15442 ins_pipe(pipe_class_memory); 15443%} 15444 15445instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15446 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15447 iRegP_R10 tmp, rFlagsReg cr) 15448%{ 15449 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 15450 match(Set result (AryEq ary1 ary2)); 15451 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15452 15453 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15454 ins_encode %{ 15455 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 15456 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15457 $result$$Register, $tmp$$Register, 1); 15458 if (tpc == NULL) { 15459 ciEnv::current()->record_failure("CodeCache is full"); 15460 return; 15461 } 15462 %} 15463 ins_pipe(pipe_class_memory); 15464%} 15465 15466instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 15467 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 15468 iRegP_R10 tmp, rFlagsReg cr) 15469%{ 15470 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 15471 match(Set result (AryEq ary1 ary2)); 15472 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 15473 15474 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 15475 ins_encode %{ 15476 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 15477 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 15478 $result$$Register, $tmp$$Register, 2); 15479 if (tpc == NULL) { 15480 ciEnv::current()->record_failure("CodeCache is full"); 15481 return; 15482 } 15483 %} 15484 ins_pipe(pipe_class_memory); 15485%} 15486 15487instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 15488%{ 15489 match(Set result (HasNegatives ary1 len)); 15490 effect(USE_KILL ary1, USE_KILL len, KILL cr); 15491 format %{ "has negatives byte[] $ary1,$len -> $result" %} 15492 ins_encode %{ 15493 address tpc = __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 15494 if (tpc == NULL) { 15495 ciEnv::current()->record_failure("CodeCache is full"); 15496 return; 15497 } 15498 %} 15499 ins_pipe( pipe_slow ); 15500%} 15501 15502// fast char[] to byte[] compression 15503instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15504 vRegD_V0 tmp1, vRegD_V1 tmp2, 15505 vRegD_V2 tmp3, vRegD_V3 tmp4, 15506 iRegI_R0 result, rFlagsReg cr) 15507%{ 15508 match(Set result (StrCompressedCopy src (Binary dst len))); 15509 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15510 15511 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 15512 ins_encode %{ 15513 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 15514 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15515 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 15516 $result$$Register); 15517 %} 15518 ins_pipe( pipe_slow ); 15519%} 15520 15521// fast byte[] to char[] inflation 15522instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 15523 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 15524%{ 15525 match(Set dummy (StrInflatedCopy src (Binary dst len))); 15526 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 15527 15528 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 15529 ins_encode %{ 15530 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 15531 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 15532 $tmp3$$FloatRegister, $tmp4$$Register); 15533 if (tpc == NULL) { 15534 ciEnv::current()->record_failure("CodeCache is full"); 15535 return; 15536 } 15537 %} 15538 ins_pipe(pipe_class_memory); 15539%} 15540 15541// encode char[] to byte[] in ISO_8859_1 15542instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 15543 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 15544 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 15545 iRegI_R0 result, rFlagsReg cr) 15546%{ 15547 match(Set result (EncodeISOArray src (Binary dst len))); 15548 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 15549 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 15550 15551 format %{ "Encode array $src,$dst,$len -> $result" %} 15552 ins_encode %{ 15553 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 15554 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 15555 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 15556 %} 15557 ins_pipe( pipe_class_memory ); 15558%} 15559 15560// ============================================================================ 15561// This name is KNOWN by the ADLC and cannot be changed. 15562// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 15563// for this guy. 15564instruct tlsLoadP(thread_RegP dst) 15565%{ 15566 match(Set dst (ThreadLocal)); 15567 15568 ins_cost(0); 15569 15570 format %{ " -- \t// $dst=Thread::current(), empty" %} 15571 15572 size(0); 15573 15574 ins_encode( /*empty*/ ); 15575 15576 ins_pipe(pipe_class_empty); 15577%} 15578 15579// ====================VECTOR INSTRUCTIONS===================================== 15580 15581// Load vector (32 bits) 15582instruct loadV4(vecD dst, vmem4 mem) 15583%{ 15584 predicate(n->as_LoadVector()->memory_size() == 4); 15585 match(Set dst (LoadVector mem)); 15586 ins_cost(4 * INSN_COST); 15587 format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} 15588 ins_encode( aarch64_enc_ldrvS(dst, mem) ); 15589 ins_pipe(vload_reg_mem64); 15590%} 15591 15592// Load vector (64 bits) 15593instruct loadV8(vecD dst, vmem8 mem) 15594%{ 15595 predicate(n->as_LoadVector()->memory_size() == 8); 15596 match(Set dst (LoadVector mem)); 15597 ins_cost(4 * INSN_COST); 15598 format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} 15599 ins_encode( aarch64_enc_ldrvD(dst, mem) ); 15600 ins_pipe(vload_reg_mem64); 15601%} 15602 15603// Load Vector (128 bits) 15604instruct loadV16(vecX dst, vmem16 mem) 15605%{ 15606 predicate(n->as_LoadVector()->memory_size() == 16); 15607 match(Set dst (LoadVector mem)); 15608 ins_cost(4 * INSN_COST); 15609 format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} 15610 ins_encode( aarch64_enc_ldrvQ(dst, mem) ); 15611 ins_pipe(vload_reg_mem128); 15612%} 15613 15614// Store Vector (32 bits) 15615instruct storeV4(vecD src, vmem4 mem) 15616%{ 15617 predicate(n->as_StoreVector()->memory_size() == 4); 15618 match(Set mem (StoreVector mem src)); 15619 ins_cost(4 * INSN_COST); 15620 format %{ "strs $mem,$src\t# vector (32 bits)" %} 15621 ins_encode( aarch64_enc_strvS(src, mem) ); 15622 ins_pipe(vstore_reg_mem64); 15623%} 15624 15625// Store Vector (64 bits) 15626instruct storeV8(vecD src, vmem8 mem) 15627%{ 15628 predicate(n->as_StoreVector()->memory_size() == 8); 15629 match(Set mem (StoreVector mem src)); 15630 ins_cost(4 * INSN_COST); 15631 format %{ "strd $mem,$src\t# vector (64 bits)" %} 15632 ins_encode( aarch64_enc_strvD(src, mem) ); 15633 ins_pipe(vstore_reg_mem64); 15634%} 15635 15636// Store Vector (128 bits) 15637instruct storeV16(vecX src, vmem16 mem) 15638%{ 15639 predicate(n->as_StoreVector()->memory_size() == 16); 15640 match(Set mem (StoreVector mem src)); 15641 ins_cost(4 * INSN_COST); 15642 format %{ "strq $mem,$src\t# vector (128 bits)" %} 15643 ins_encode( aarch64_enc_strvQ(src, mem) ); 15644 ins_pipe(vstore_reg_mem128); 15645%} 15646 15647instruct replicate8B(vecD dst, iRegIorL2I src) 15648%{ 15649 predicate(n->as_Vector()->length() == 4 || 15650 n->as_Vector()->length() == 8); 15651 match(Set dst (ReplicateB src)); 15652 ins_cost(INSN_COST); 15653 format %{ "dup $dst, $src\t# vector (8B)" %} 15654 ins_encode %{ 15655 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); 15656 %} 15657 ins_pipe(vdup_reg_reg64); 15658%} 15659 15660instruct replicate16B(vecX dst, iRegIorL2I src) 15661%{ 15662 predicate(n->as_Vector()->length() == 16); 15663 match(Set dst (ReplicateB src)); 15664 ins_cost(INSN_COST); 15665 format %{ "dup $dst, $src\t# vector (16B)" %} 15666 ins_encode %{ 15667 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); 15668 %} 15669 ins_pipe(vdup_reg_reg128); 15670%} 15671 15672instruct replicate8B_imm(vecD dst, immI con) 15673%{ 15674 predicate(n->as_Vector()->length() == 4 || 15675 n->as_Vector()->length() == 8); 15676 match(Set dst (ReplicateB con)); 15677 ins_cost(INSN_COST); 15678 format %{ "movi $dst, $con\t# vector(8B)" %} 15679 ins_encode %{ 15680 __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); 15681 %} 15682 ins_pipe(vmovi_reg_imm64); 15683%} 15684 15685instruct replicate16B_imm(vecX dst, immI con) 15686%{ 15687 predicate(n->as_Vector()->length() == 16); 15688 match(Set dst (ReplicateB con)); 15689 ins_cost(INSN_COST); 15690 format %{ "movi $dst, $con\t# vector(16B)" %} 15691 ins_encode %{ 15692 __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); 15693 %} 15694 ins_pipe(vmovi_reg_imm128); 15695%} 15696 15697instruct replicate4S(vecD dst, iRegIorL2I src) 15698%{ 15699 predicate(n->as_Vector()->length() == 2 || 15700 n->as_Vector()->length() == 4); 15701 match(Set dst (ReplicateS src)); 15702 ins_cost(INSN_COST); 15703 format %{ "dup $dst, $src\t# vector (4S)" %} 15704 ins_encode %{ 15705 __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); 15706 %} 15707 ins_pipe(vdup_reg_reg64); 15708%} 15709 15710instruct replicate8S(vecX dst, iRegIorL2I src) 15711%{ 15712 predicate(n->as_Vector()->length() == 8); 15713 match(Set dst (ReplicateS src)); 15714 ins_cost(INSN_COST); 15715 format %{ "dup $dst, $src\t# vector (8S)" %} 15716 ins_encode %{ 15717 __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); 15718 %} 15719 ins_pipe(vdup_reg_reg128); 15720%} 15721 15722instruct replicate4S_imm(vecD dst, immI con) 15723%{ 15724 predicate(n->as_Vector()->length() == 2 || 15725 n->as_Vector()->length() == 4); 15726 match(Set dst (ReplicateS con)); 15727 ins_cost(INSN_COST); 15728 format %{ "movi $dst, $con\t# vector(4H)" %} 15729 ins_encode %{ 15730 __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); 15731 %} 15732 ins_pipe(vmovi_reg_imm64); 15733%} 15734 15735instruct replicate8S_imm(vecX dst, immI con) 15736%{ 15737 predicate(n->as_Vector()->length() == 8); 15738 match(Set dst (ReplicateS con)); 15739 ins_cost(INSN_COST); 15740 format %{ "movi $dst, $con\t# vector(8H)" %} 15741 ins_encode %{ 15742 __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); 15743 %} 15744 ins_pipe(vmovi_reg_imm128); 15745%} 15746 15747instruct replicate2I(vecD dst, iRegIorL2I src) 15748%{ 15749 predicate(n->as_Vector()->length() == 2); 15750 match(Set dst (ReplicateI src)); 15751 ins_cost(INSN_COST); 15752 format %{ "dup $dst, $src\t# vector (2I)" %} 15753 ins_encode %{ 15754 __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); 15755 %} 15756 ins_pipe(vdup_reg_reg64); 15757%} 15758 15759instruct replicate4I(vecX dst, iRegIorL2I src) 15760%{ 15761 predicate(n->as_Vector()->length() == 4); 15762 match(Set dst (ReplicateI src)); 15763 ins_cost(INSN_COST); 15764 format %{ "dup $dst, $src\t# vector (4I)" %} 15765 ins_encode %{ 15766 __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); 15767 %} 15768 ins_pipe(vdup_reg_reg128); 15769%} 15770 15771instruct replicate2I_imm(vecD dst, immI con) 15772%{ 15773 predicate(n->as_Vector()->length() == 2); 15774 match(Set dst (ReplicateI con)); 15775 ins_cost(INSN_COST); 15776 format %{ "movi $dst, $con\t# vector(2I)" %} 15777 ins_encode %{ 15778 __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); 15779 %} 15780 ins_pipe(vmovi_reg_imm64); 15781%} 15782 15783instruct replicate4I_imm(vecX dst, immI con) 15784%{ 15785 predicate(n->as_Vector()->length() == 4); 15786 match(Set dst (ReplicateI con)); 15787 ins_cost(INSN_COST); 15788 format %{ "movi $dst, $con\t# vector(4I)" %} 15789 ins_encode %{ 15790 __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); 15791 %} 15792 ins_pipe(vmovi_reg_imm128); 15793%} 15794 15795instruct replicate2L(vecX dst, iRegL src) 15796%{ 15797 predicate(n->as_Vector()->length() == 2); 15798 match(Set dst (ReplicateL src)); 15799 ins_cost(INSN_COST); 15800 format %{ "dup $dst, $src\t# vector (2L)" %} 15801 ins_encode %{ 15802 __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); 15803 %} 15804 ins_pipe(vdup_reg_reg128); 15805%} 15806 15807instruct replicate2L_zero(vecX dst, immI0 zero) 15808%{ 15809 predicate(n->as_Vector()->length() == 2); 15810 match(Set dst (ReplicateI zero)); 15811 ins_cost(INSN_COST); 15812 format %{ "movi $dst, $zero\t# vector(4I)" %} 15813 ins_encode %{ 15814 __ eor(as_FloatRegister($dst$$reg), __ T16B, 15815 as_FloatRegister($dst$$reg), 15816 as_FloatRegister($dst$$reg)); 15817 %} 15818 ins_pipe(vmovi_reg_imm128); 15819%} 15820 15821instruct replicate2F(vecD dst, vRegF src) 15822%{ 15823 predicate(n->as_Vector()->length() == 2); 15824 match(Set dst (ReplicateF src)); 15825 ins_cost(INSN_COST); 15826 format %{ "dup $dst, $src\t# vector (2F)" %} 15827 ins_encode %{ 15828 __ dup(as_FloatRegister($dst$$reg), __ T2S, 15829 as_FloatRegister($src$$reg)); 15830 %} 15831 ins_pipe(vdup_reg_freg64); 15832%} 15833 15834instruct replicate4F(vecX dst, vRegF src) 15835%{ 15836 predicate(n->as_Vector()->length() == 4); 15837 match(Set dst (ReplicateF src)); 15838 ins_cost(INSN_COST); 15839 format %{ "dup $dst, $src\t# vector (4F)" %} 15840 ins_encode %{ 15841 __ dup(as_FloatRegister($dst$$reg), __ T4S, 15842 as_FloatRegister($src$$reg)); 15843 %} 15844 ins_pipe(vdup_reg_freg128); 15845%} 15846 15847instruct replicate2D(vecX dst, vRegD src) 15848%{ 15849 predicate(n->as_Vector()->length() == 2); 15850 match(Set dst (ReplicateD src)); 15851 ins_cost(INSN_COST); 15852 format %{ "dup $dst, $src\t# vector (2D)" %} 15853 ins_encode %{ 15854 __ dup(as_FloatRegister($dst$$reg), __ T2D, 15855 as_FloatRegister($src$$reg)); 15856 %} 15857 ins_pipe(vdup_reg_dreg128); 15858%} 15859 15860// ====================REDUCTION ARITHMETIC==================================== 15861 15862instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) 15863%{ 15864 match(Set dst (AddReductionVI src1 src2)); 15865 ins_cost(INSN_COST); 15866 effect(TEMP tmp, TEMP tmp2); 15867 format %{ "umov $tmp, $src2, S, 0\n\t" 15868 "umov $tmp2, $src2, S, 1\n\t" 15869 "addw $tmp, $src1, $tmp\n\t" 15870 "addw $dst, $tmp, $tmp2\t# add reduction2I" 15871 %} 15872 ins_encode %{ 15873 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15874 __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15875 __ addw($tmp$$Register, $src1$$Register, $tmp$$Register); 15876 __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); 15877 %} 15878 ins_pipe(pipe_class_default); 15879%} 15880 15881instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15882%{ 15883 match(Set dst (AddReductionVI src1 src2)); 15884 ins_cost(INSN_COST); 15885 effect(TEMP tmp, TEMP tmp2); 15886 format %{ "addv $tmp, T4S, $src2\n\t" 15887 "umov $tmp2, $tmp, S, 0\n\t" 15888 "addw $dst, $tmp2, $src1\t# add reduction4I" 15889 %} 15890 ins_encode %{ 15891 __ addv(as_FloatRegister($tmp$$reg), __ T4S, 15892 as_FloatRegister($src2$$reg)); 15893 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15894 __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); 15895 %} 15896 ins_pipe(pipe_class_default); 15897%} 15898 15899instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) 15900%{ 15901 match(Set dst (MulReductionVI src1 src2)); 15902 ins_cost(INSN_COST); 15903 effect(TEMP tmp, TEMP dst); 15904 format %{ "umov $tmp, $src2, S, 0\n\t" 15905 "mul $dst, $tmp, $src1\n\t" 15906 "umov $tmp, $src2, S, 1\n\t" 15907 "mul $dst, $tmp, $dst\t# mul reduction2I" 15908 %} 15909 ins_encode %{ 15910 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); 15911 __ mul($dst$$Register, $tmp$$Register, $src1$$Register); 15912 __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); 15913 __ mul($dst$$Register, $tmp$$Register, $dst$$Register); 15914 %} 15915 ins_pipe(pipe_class_default); 15916%} 15917 15918instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) 15919%{ 15920 match(Set dst (MulReductionVI src1 src2)); 15921 ins_cost(INSN_COST); 15922 effect(TEMP tmp, TEMP tmp2, TEMP dst); 15923 format %{ "ins $tmp, $src2, 0, 1\n\t" 15924 "mul $tmp, $tmp, $src2\n\t" 15925 "umov $tmp2, $tmp, S, 0\n\t" 15926 "mul $dst, $tmp2, $src1\n\t" 15927 "umov $tmp2, $tmp, S, 1\n\t" 15928 "mul $dst, $tmp2, $dst\t# mul reduction4I" 15929 %} 15930 ins_encode %{ 15931 __ ins(as_FloatRegister($tmp$$reg), __ D, 15932 as_FloatRegister($src2$$reg), 0, 1); 15933 __ mulv(as_FloatRegister($tmp$$reg), __ T2S, 15934 as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); 15935 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); 15936 __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); 15937 __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); 15938 __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); 15939 %} 15940 ins_pipe(pipe_class_default); 15941%} 15942 15943instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15944%{ 15945 match(Set dst (AddReductionVF src1 src2)); 15946 ins_cost(INSN_COST); 15947 effect(TEMP tmp, TEMP dst); 15948 format %{ "fadds $dst, $src1, $src2\n\t" 15949 "ins $tmp, S, $src2, 0, 1\n\t" 15950 "fadds $dst, $dst, $tmp\t# add reduction2F" 15951 %} 15952 ins_encode %{ 15953 __ fadds(as_FloatRegister($dst$$reg), 15954 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15955 __ ins(as_FloatRegister($tmp$$reg), __ S, 15956 as_FloatRegister($src2$$reg), 0, 1); 15957 __ fadds(as_FloatRegister($dst$$reg), 15958 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15959 %} 15960 ins_pipe(pipe_class_default); 15961%} 15962 15963instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 15964%{ 15965 match(Set dst (AddReductionVF src1 src2)); 15966 ins_cost(INSN_COST); 15967 effect(TEMP tmp, TEMP dst); 15968 format %{ "fadds $dst, $src1, $src2\n\t" 15969 "ins $tmp, S, $src2, 0, 1\n\t" 15970 "fadds $dst, $dst, $tmp\n\t" 15971 "ins $tmp, S, $src2, 0, 2\n\t" 15972 "fadds $dst, $dst, $tmp\n\t" 15973 "ins $tmp, S, $src2, 0, 3\n\t" 15974 "fadds $dst, $dst, $tmp\t# add reduction4F" 15975 %} 15976 ins_encode %{ 15977 __ fadds(as_FloatRegister($dst$$reg), 15978 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15979 __ ins(as_FloatRegister($tmp$$reg), __ S, 15980 as_FloatRegister($src2$$reg), 0, 1); 15981 __ fadds(as_FloatRegister($dst$$reg), 15982 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15983 __ ins(as_FloatRegister($tmp$$reg), __ S, 15984 as_FloatRegister($src2$$reg), 0, 2); 15985 __ fadds(as_FloatRegister($dst$$reg), 15986 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15987 __ ins(as_FloatRegister($tmp$$reg), __ S, 15988 as_FloatRegister($src2$$reg), 0, 3); 15989 __ fadds(as_FloatRegister($dst$$reg), 15990 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 15991 %} 15992 ins_pipe(pipe_class_default); 15993%} 15994 15995instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) 15996%{ 15997 match(Set dst (MulReductionVF src1 src2)); 15998 ins_cost(INSN_COST); 15999 effect(TEMP tmp, TEMP dst); 16000 format %{ "fmuls $dst, $src1, $src2\n\t" 16001 "ins $tmp, S, $src2, 0, 1\n\t" 16002 "fmuls $dst, $dst, $tmp\t# mul reduction2F" 16003 %} 16004 ins_encode %{ 16005 __ fmuls(as_FloatRegister($dst$$reg), 16006 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16007 __ ins(as_FloatRegister($tmp$$reg), __ S, 16008 as_FloatRegister($src2$$reg), 0, 1); 16009 __ fmuls(as_FloatRegister($dst$$reg), 16010 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16011 %} 16012 ins_pipe(pipe_class_default); 16013%} 16014 16015instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) 16016%{ 16017 match(Set dst (MulReductionVF src1 src2)); 16018 ins_cost(INSN_COST); 16019 effect(TEMP tmp, TEMP dst); 16020 format %{ "fmuls $dst, $src1, $src2\n\t" 16021 "ins $tmp, S, $src2, 0, 1\n\t" 16022 "fmuls $dst, $dst, $tmp\n\t" 16023 "ins $tmp, S, $src2, 0, 2\n\t" 16024 "fmuls $dst, $dst, $tmp\n\t" 16025 "ins $tmp, S, $src2, 0, 3\n\t" 16026 "fmuls $dst, $dst, $tmp\t# mul reduction4F" 16027 %} 16028 ins_encode %{ 16029 __ fmuls(as_FloatRegister($dst$$reg), 16030 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16031 __ ins(as_FloatRegister($tmp$$reg), __ S, 16032 as_FloatRegister($src2$$reg), 0, 1); 16033 __ fmuls(as_FloatRegister($dst$$reg), 16034 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16035 __ ins(as_FloatRegister($tmp$$reg), __ S, 16036 as_FloatRegister($src2$$reg), 0, 2); 16037 __ fmuls(as_FloatRegister($dst$$reg), 16038 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16039 __ ins(as_FloatRegister($tmp$$reg), __ S, 16040 as_FloatRegister($src2$$reg), 0, 3); 16041 __ fmuls(as_FloatRegister($dst$$reg), 16042 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16043 %} 16044 ins_pipe(pipe_class_default); 16045%} 16046 16047instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16048%{ 16049 match(Set dst (AddReductionVD src1 src2)); 16050 ins_cost(INSN_COST); 16051 effect(TEMP tmp, TEMP dst); 16052 format %{ "faddd $dst, $src1, $src2\n\t" 16053 "ins $tmp, D, $src2, 0, 1\n\t" 16054 "faddd $dst, $dst, $tmp\t# add reduction2D" 16055 %} 16056 ins_encode %{ 16057 __ faddd(as_FloatRegister($dst$$reg), 16058 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16059 __ ins(as_FloatRegister($tmp$$reg), __ D, 16060 as_FloatRegister($src2$$reg), 0, 1); 16061 __ faddd(as_FloatRegister($dst$$reg), 16062 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16063 %} 16064 ins_pipe(pipe_class_default); 16065%} 16066 16067instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) 16068%{ 16069 match(Set dst (MulReductionVD src1 src2)); 16070 ins_cost(INSN_COST); 16071 effect(TEMP tmp, TEMP dst); 16072 format %{ "fmuld $dst, $src1, $src2\n\t" 16073 "ins $tmp, D, $src2, 0, 1\n\t" 16074 "fmuld $dst, $dst, $tmp\t# mul reduction2D" 16075 %} 16076 ins_encode %{ 16077 __ fmuld(as_FloatRegister($dst$$reg), 16078 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16079 __ ins(as_FloatRegister($tmp$$reg), __ D, 16080 as_FloatRegister($src2$$reg), 0, 1); 16081 __ fmuld(as_FloatRegister($dst$$reg), 16082 as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16083 %} 16084 ins_pipe(pipe_class_default); 16085%} 16086 16087instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16088 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16089 match(Set dst (MaxReductionV src1 src2)); 16090 ins_cost(INSN_COST); 16091 effect(TEMP_DEF dst, TEMP tmp); 16092 format %{ "fmaxs $dst, $src1, $src2\n\t" 16093 "ins $tmp, S, $src2, 0, 1\n\t" 16094 "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} 16095 ins_encode %{ 16096 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16097 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16098 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16099 %} 16100 ins_pipe(pipe_class_default); 16101%} 16102 16103instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ 16104 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16105 match(Set dst (MaxReductionV src1 src2)); 16106 ins_cost(INSN_COST); 16107 effect(TEMP_DEF dst); 16108 format %{ "fmaxv $dst, T4S, $src2\n\t" 16109 "fmaxs $dst, $dst, $src1\t# max reduction4F" %} 16110 ins_encode %{ 16111 __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16112 __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16113 %} 16114 ins_pipe(pipe_class_default); 16115%} 16116 16117instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16118 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16119 match(Set dst (MaxReductionV src1 src2)); 16120 ins_cost(INSN_COST); 16121 effect(TEMP_DEF dst, TEMP tmp); 16122 format %{ "fmaxd $dst, $src1, $src2\n\t" 16123 "ins $tmp, D, $src2, 0, 1\n\t" 16124 "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} 16125 ins_encode %{ 16126 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16127 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16128 __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16129 %} 16130 ins_pipe(pipe_class_default); 16131%} 16132 16133instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ 16134 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16135 match(Set dst (MinReductionV src1 src2)); 16136 ins_cost(INSN_COST); 16137 effect(TEMP_DEF dst, TEMP tmp); 16138 format %{ "fmins $dst, $src1, $src2\n\t" 16139 "ins $tmp, S, $src2, 0, 1\n\t" 16140 "fmins $dst, $dst, $tmp\t# min reduction2F" %} 16141 ins_encode %{ 16142 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16143 __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); 16144 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16145 %} 16146 ins_pipe(pipe_class_default); 16147%} 16148 16149instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ 16150 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 16151 match(Set dst (MinReductionV src1 src2)); 16152 ins_cost(INSN_COST); 16153 effect(TEMP_DEF dst); 16154 format %{ "fminv $dst, T4S, $src2\n\t" 16155 "fmins $dst, $dst, $src1\t# min reduction4F" %} 16156 ins_encode %{ 16157 __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); 16158 __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); 16159 %} 16160 ins_pipe(pipe_class_default); 16161%} 16162 16163instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ 16164 predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 16165 match(Set dst (MinReductionV src1 src2)); 16166 ins_cost(INSN_COST); 16167 effect(TEMP_DEF dst, TEMP tmp); 16168 format %{ "fmind $dst, $src1, $src2\n\t" 16169 "ins $tmp, D, $src2, 0, 1\n\t" 16170 "fmind $dst, $dst, $tmp\t# min reduction2D" %} 16171 ins_encode %{ 16172 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 16173 __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); 16174 __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); 16175 %} 16176 ins_pipe(pipe_class_default); 16177%} 16178 16179// ====================VECTOR ARITHMETIC======================================= 16180 16181// --------------------------------- ADD -------------------------------------- 16182 16183instruct vadd8B(vecD dst, vecD src1, vecD src2) 16184%{ 16185 predicate(n->as_Vector()->length() == 4 || 16186 n->as_Vector()->length() == 8); 16187 match(Set dst (AddVB src1 src2)); 16188 ins_cost(INSN_COST); 16189 format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} 16190 ins_encode %{ 16191 __ addv(as_FloatRegister($dst$$reg), __ T8B, 16192 as_FloatRegister($src1$$reg), 16193 as_FloatRegister($src2$$reg)); 16194 %} 16195 ins_pipe(vdop64); 16196%} 16197 16198instruct vadd16B(vecX dst, vecX src1, vecX src2) 16199%{ 16200 predicate(n->as_Vector()->length() == 16); 16201 match(Set dst (AddVB src1 src2)); 16202 ins_cost(INSN_COST); 16203 format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} 16204 ins_encode %{ 16205 __ addv(as_FloatRegister($dst$$reg), __ T16B, 16206 as_FloatRegister($src1$$reg), 16207 as_FloatRegister($src2$$reg)); 16208 %} 16209 ins_pipe(vdop128); 16210%} 16211 16212instruct vadd4S(vecD dst, vecD src1, vecD src2) 16213%{ 16214 predicate(n->as_Vector()->length() == 2 || 16215 n->as_Vector()->length() == 4); 16216 match(Set dst (AddVS src1 src2)); 16217 ins_cost(INSN_COST); 16218 format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} 16219 ins_encode %{ 16220 __ addv(as_FloatRegister($dst$$reg), __ T4H, 16221 as_FloatRegister($src1$$reg), 16222 as_FloatRegister($src2$$reg)); 16223 %} 16224 ins_pipe(vdop64); 16225%} 16226 16227instruct vadd8S(vecX dst, vecX src1, vecX src2) 16228%{ 16229 predicate(n->as_Vector()->length() == 8); 16230 match(Set dst (AddVS src1 src2)); 16231 ins_cost(INSN_COST); 16232 format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} 16233 ins_encode %{ 16234 __ addv(as_FloatRegister($dst$$reg), __ T8H, 16235 as_FloatRegister($src1$$reg), 16236 as_FloatRegister($src2$$reg)); 16237 %} 16238 ins_pipe(vdop128); 16239%} 16240 16241instruct vadd2I(vecD dst, vecD src1, vecD src2) 16242%{ 16243 predicate(n->as_Vector()->length() == 2); 16244 match(Set dst (AddVI src1 src2)); 16245 ins_cost(INSN_COST); 16246 format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} 16247 ins_encode %{ 16248 __ addv(as_FloatRegister($dst$$reg), __ T2S, 16249 as_FloatRegister($src1$$reg), 16250 as_FloatRegister($src2$$reg)); 16251 %} 16252 ins_pipe(vdop64); 16253%} 16254 16255instruct vadd4I(vecX dst, vecX src1, vecX src2) 16256%{ 16257 predicate(n->as_Vector()->length() == 4); 16258 match(Set dst (AddVI src1 src2)); 16259 ins_cost(INSN_COST); 16260 format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} 16261 ins_encode %{ 16262 __ addv(as_FloatRegister($dst$$reg), __ T4S, 16263 as_FloatRegister($src1$$reg), 16264 as_FloatRegister($src2$$reg)); 16265 %} 16266 ins_pipe(vdop128); 16267%} 16268 16269instruct vadd2L(vecX dst, vecX src1, vecX src2) 16270%{ 16271 predicate(n->as_Vector()->length() == 2); 16272 match(Set dst (AddVL src1 src2)); 16273 ins_cost(INSN_COST); 16274 format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} 16275 ins_encode %{ 16276 __ addv(as_FloatRegister($dst$$reg), __ T2D, 16277 as_FloatRegister($src1$$reg), 16278 as_FloatRegister($src2$$reg)); 16279 %} 16280 ins_pipe(vdop128); 16281%} 16282 16283instruct vadd2F(vecD dst, vecD src1, vecD src2) 16284%{ 16285 predicate(n->as_Vector()->length() == 2); 16286 match(Set dst (AddVF src1 src2)); 16287 ins_cost(INSN_COST); 16288 format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} 16289 ins_encode %{ 16290 __ fadd(as_FloatRegister($dst$$reg), __ T2S, 16291 as_FloatRegister($src1$$reg), 16292 as_FloatRegister($src2$$reg)); 16293 %} 16294 ins_pipe(vdop_fp64); 16295%} 16296 16297instruct vadd4F(vecX dst, vecX src1, vecX src2) 16298%{ 16299 predicate(n->as_Vector()->length() == 4); 16300 match(Set dst (AddVF src1 src2)); 16301 ins_cost(INSN_COST); 16302 format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} 16303 ins_encode %{ 16304 __ fadd(as_FloatRegister($dst$$reg), __ T4S, 16305 as_FloatRegister($src1$$reg), 16306 as_FloatRegister($src2$$reg)); 16307 %} 16308 ins_pipe(vdop_fp128); 16309%} 16310 16311instruct vadd2D(vecX dst, vecX src1, vecX src2) 16312%{ 16313 match(Set dst (AddVD src1 src2)); 16314 ins_cost(INSN_COST); 16315 format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} 16316 ins_encode %{ 16317 __ fadd(as_FloatRegister($dst$$reg), __ T2D, 16318 as_FloatRegister($src1$$reg), 16319 as_FloatRegister($src2$$reg)); 16320 %} 16321 ins_pipe(vdop_fp128); 16322%} 16323 16324// --------------------------------- SUB -------------------------------------- 16325 16326instruct vsub8B(vecD dst, vecD src1, vecD src2) 16327%{ 16328 predicate(n->as_Vector()->length() == 4 || 16329 n->as_Vector()->length() == 8); 16330 match(Set dst (SubVB src1 src2)); 16331 ins_cost(INSN_COST); 16332 format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} 16333 ins_encode %{ 16334 __ subv(as_FloatRegister($dst$$reg), __ T8B, 16335 as_FloatRegister($src1$$reg), 16336 as_FloatRegister($src2$$reg)); 16337 %} 16338 ins_pipe(vdop64); 16339%} 16340 16341instruct vsub16B(vecX dst, vecX src1, vecX src2) 16342%{ 16343 predicate(n->as_Vector()->length() == 16); 16344 match(Set dst (SubVB src1 src2)); 16345 ins_cost(INSN_COST); 16346 format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} 16347 ins_encode %{ 16348 __ subv(as_FloatRegister($dst$$reg), __ T16B, 16349 as_FloatRegister($src1$$reg), 16350 as_FloatRegister($src2$$reg)); 16351 %} 16352 ins_pipe(vdop128); 16353%} 16354 16355instruct vsub4S(vecD dst, vecD src1, vecD src2) 16356%{ 16357 predicate(n->as_Vector()->length() == 2 || 16358 n->as_Vector()->length() == 4); 16359 match(Set dst (SubVS src1 src2)); 16360 ins_cost(INSN_COST); 16361 format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} 16362 ins_encode %{ 16363 __ subv(as_FloatRegister($dst$$reg), __ T4H, 16364 as_FloatRegister($src1$$reg), 16365 as_FloatRegister($src2$$reg)); 16366 %} 16367 ins_pipe(vdop64); 16368%} 16369 16370instruct vsub8S(vecX dst, vecX src1, vecX src2) 16371%{ 16372 predicate(n->as_Vector()->length() == 8); 16373 match(Set dst (SubVS src1 src2)); 16374 ins_cost(INSN_COST); 16375 format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} 16376 ins_encode %{ 16377 __ subv(as_FloatRegister($dst$$reg), __ T8H, 16378 as_FloatRegister($src1$$reg), 16379 as_FloatRegister($src2$$reg)); 16380 %} 16381 ins_pipe(vdop128); 16382%} 16383 16384instruct vsub2I(vecD dst, vecD src1, vecD src2) 16385%{ 16386 predicate(n->as_Vector()->length() == 2); 16387 match(Set dst (SubVI src1 src2)); 16388 ins_cost(INSN_COST); 16389 format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} 16390 ins_encode %{ 16391 __ subv(as_FloatRegister($dst$$reg), __ T2S, 16392 as_FloatRegister($src1$$reg), 16393 as_FloatRegister($src2$$reg)); 16394 %} 16395 ins_pipe(vdop64); 16396%} 16397 16398instruct vsub4I(vecX dst, vecX src1, vecX src2) 16399%{ 16400 predicate(n->as_Vector()->length() == 4); 16401 match(Set dst (SubVI src1 src2)); 16402 ins_cost(INSN_COST); 16403 format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} 16404 ins_encode %{ 16405 __ subv(as_FloatRegister($dst$$reg), __ T4S, 16406 as_FloatRegister($src1$$reg), 16407 as_FloatRegister($src2$$reg)); 16408 %} 16409 ins_pipe(vdop128); 16410%} 16411 16412instruct vsub2L(vecX dst, vecX src1, vecX src2) 16413%{ 16414 predicate(n->as_Vector()->length() == 2); 16415 match(Set dst (SubVL src1 src2)); 16416 ins_cost(INSN_COST); 16417 format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} 16418 ins_encode %{ 16419 __ subv(as_FloatRegister($dst$$reg), __ T2D, 16420 as_FloatRegister($src1$$reg), 16421 as_FloatRegister($src2$$reg)); 16422 %} 16423 ins_pipe(vdop128); 16424%} 16425 16426instruct vsub2F(vecD dst, vecD src1, vecD src2) 16427%{ 16428 predicate(n->as_Vector()->length() == 2); 16429 match(Set dst (SubVF src1 src2)); 16430 ins_cost(INSN_COST); 16431 format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} 16432 ins_encode %{ 16433 __ fsub(as_FloatRegister($dst$$reg), __ T2S, 16434 as_FloatRegister($src1$$reg), 16435 as_FloatRegister($src2$$reg)); 16436 %} 16437 ins_pipe(vdop_fp64); 16438%} 16439 16440instruct vsub4F(vecX dst, vecX src1, vecX src2) 16441%{ 16442 predicate(n->as_Vector()->length() == 4); 16443 match(Set dst (SubVF src1 src2)); 16444 ins_cost(INSN_COST); 16445 format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} 16446 ins_encode %{ 16447 __ fsub(as_FloatRegister($dst$$reg), __ T4S, 16448 as_FloatRegister($src1$$reg), 16449 as_FloatRegister($src2$$reg)); 16450 %} 16451 ins_pipe(vdop_fp128); 16452%} 16453 16454instruct vsub2D(vecX dst, vecX src1, vecX src2) 16455%{ 16456 predicate(n->as_Vector()->length() == 2); 16457 match(Set dst (SubVD src1 src2)); 16458 ins_cost(INSN_COST); 16459 format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} 16460 ins_encode %{ 16461 __ fsub(as_FloatRegister($dst$$reg), __ T2D, 16462 as_FloatRegister($src1$$reg), 16463 as_FloatRegister($src2$$reg)); 16464 %} 16465 ins_pipe(vdop_fp128); 16466%} 16467 16468// --------------------------------- MUL -------------------------------------- 16469 16470instruct vmul8B(vecD dst, vecD src1, vecD src2) 16471%{ 16472 predicate(n->as_Vector()->length() == 4 || 16473 n->as_Vector()->length() == 8); 16474 match(Set dst (MulVB src1 src2)); 16475 ins_cost(INSN_COST); 16476 format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %} 16477 ins_encode %{ 16478 __ mulv(as_FloatRegister($dst$$reg), __ T8B, 16479 as_FloatRegister($src1$$reg), 16480 as_FloatRegister($src2$$reg)); 16481 %} 16482 ins_pipe(vmul64); 16483%} 16484 16485instruct vmul16B(vecX dst, vecX src1, vecX src2) 16486%{ 16487 predicate(n->as_Vector()->length() == 16); 16488 match(Set dst (MulVB src1 src2)); 16489 ins_cost(INSN_COST); 16490 format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %} 16491 ins_encode %{ 16492 __ mulv(as_FloatRegister($dst$$reg), __ T16B, 16493 as_FloatRegister($src1$$reg), 16494 as_FloatRegister($src2$$reg)); 16495 %} 16496 ins_pipe(vmul128); 16497%} 16498 16499instruct vmul4S(vecD dst, vecD src1, vecD src2) 16500%{ 16501 predicate(n->as_Vector()->length() == 2 || 16502 n->as_Vector()->length() == 4); 16503 match(Set dst (MulVS src1 src2)); 16504 ins_cost(INSN_COST); 16505 format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} 16506 ins_encode %{ 16507 __ mulv(as_FloatRegister($dst$$reg), __ T4H, 16508 as_FloatRegister($src1$$reg), 16509 as_FloatRegister($src2$$reg)); 16510 %} 16511 ins_pipe(vmul64); 16512%} 16513 16514instruct vmul8S(vecX dst, vecX src1, vecX src2) 16515%{ 16516 predicate(n->as_Vector()->length() == 8); 16517 match(Set dst (MulVS src1 src2)); 16518 ins_cost(INSN_COST); 16519 format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} 16520 ins_encode %{ 16521 __ mulv(as_FloatRegister($dst$$reg), __ T8H, 16522 as_FloatRegister($src1$$reg), 16523 as_FloatRegister($src2$$reg)); 16524 %} 16525 ins_pipe(vmul128); 16526%} 16527 16528instruct vmul2I(vecD dst, vecD src1, vecD src2) 16529%{ 16530 predicate(n->as_Vector()->length() == 2); 16531 match(Set dst (MulVI src1 src2)); 16532 ins_cost(INSN_COST); 16533 format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} 16534 ins_encode %{ 16535 __ mulv(as_FloatRegister($dst$$reg), __ T2S, 16536 as_FloatRegister($src1$$reg), 16537 as_FloatRegister($src2$$reg)); 16538 %} 16539 ins_pipe(vmul64); 16540%} 16541 16542instruct vmul4I(vecX dst, vecX src1, vecX src2) 16543%{ 16544 predicate(n->as_Vector()->length() == 4); 16545 match(Set dst (MulVI src1 src2)); 16546 ins_cost(INSN_COST); 16547 format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} 16548 ins_encode %{ 16549 __ mulv(as_FloatRegister($dst$$reg), __ T4S, 16550 as_FloatRegister($src1$$reg), 16551 as_FloatRegister($src2$$reg)); 16552 %} 16553 ins_pipe(vmul128); 16554%} 16555 16556instruct vmul2F(vecD dst, vecD src1, vecD src2) 16557%{ 16558 predicate(n->as_Vector()->length() == 2); 16559 match(Set dst (MulVF src1 src2)); 16560 ins_cost(INSN_COST); 16561 format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} 16562 ins_encode %{ 16563 __ fmul(as_FloatRegister($dst$$reg), __ T2S, 16564 as_FloatRegister($src1$$reg), 16565 as_FloatRegister($src2$$reg)); 16566 %} 16567 ins_pipe(vmuldiv_fp64); 16568%} 16569 16570instruct vmul4F(vecX dst, vecX src1, vecX src2) 16571%{ 16572 predicate(n->as_Vector()->length() == 4); 16573 match(Set dst (MulVF src1 src2)); 16574 ins_cost(INSN_COST); 16575 format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} 16576 ins_encode %{ 16577 __ fmul(as_FloatRegister($dst$$reg), __ T4S, 16578 as_FloatRegister($src1$$reg), 16579 as_FloatRegister($src2$$reg)); 16580 %} 16581 ins_pipe(vmuldiv_fp128); 16582%} 16583 16584instruct vmul2D(vecX dst, vecX src1, vecX src2) 16585%{ 16586 predicate(n->as_Vector()->length() == 2); 16587 match(Set dst (MulVD src1 src2)); 16588 ins_cost(INSN_COST); 16589 format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} 16590 ins_encode %{ 16591 __ fmul(as_FloatRegister($dst$$reg), __ T2D, 16592 as_FloatRegister($src1$$reg), 16593 as_FloatRegister($src2$$reg)); 16594 %} 16595 ins_pipe(vmuldiv_fp128); 16596%} 16597 16598// --------------------------------- MLA -------------------------------------- 16599 16600instruct vmla4S(vecD dst, vecD src1, vecD src2) 16601%{ 16602 predicate(n->as_Vector()->length() == 2 || 16603 n->as_Vector()->length() == 4); 16604 match(Set dst (AddVS dst (MulVS src1 src2))); 16605 ins_cost(INSN_COST); 16606 format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} 16607 ins_encode %{ 16608 __ mlav(as_FloatRegister($dst$$reg), __ T4H, 16609 as_FloatRegister($src1$$reg), 16610 as_FloatRegister($src2$$reg)); 16611 %} 16612 ins_pipe(vmla64); 16613%} 16614 16615instruct vmla8S(vecX dst, vecX src1, vecX src2) 16616%{ 16617 predicate(n->as_Vector()->length() == 8); 16618 match(Set dst (AddVS dst (MulVS src1 src2))); 16619 ins_cost(INSN_COST); 16620 format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} 16621 ins_encode %{ 16622 __ mlav(as_FloatRegister($dst$$reg), __ T8H, 16623 as_FloatRegister($src1$$reg), 16624 as_FloatRegister($src2$$reg)); 16625 %} 16626 ins_pipe(vmla128); 16627%} 16628 16629instruct vmla2I(vecD dst, vecD src1, vecD src2) 16630%{ 16631 predicate(n->as_Vector()->length() == 2); 16632 match(Set dst (AddVI dst (MulVI src1 src2))); 16633 ins_cost(INSN_COST); 16634 format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} 16635 ins_encode %{ 16636 __ mlav(as_FloatRegister($dst$$reg), __ T2S, 16637 as_FloatRegister($src1$$reg), 16638 as_FloatRegister($src2$$reg)); 16639 %} 16640 ins_pipe(vmla64); 16641%} 16642 16643instruct vmla4I(vecX dst, vecX src1, vecX src2) 16644%{ 16645 predicate(n->as_Vector()->length() == 4); 16646 match(Set dst (AddVI dst (MulVI src1 src2))); 16647 ins_cost(INSN_COST); 16648 format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} 16649 ins_encode %{ 16650 __ mlav(as_FloatRegister($dst$$reg), __ T4S, 16651 as_FloatRegister($src1$$reg), 16652 as_FloatRegister($src2$$reg)); 16653 %} 16654 ins_pipe(vmla128); 16655%} 16656 16657// dst + src1 * src2 16658instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ 16659 predicate(UseFMA && n->as_Vector()->length() == 2); 16660 match(Set dst (FmaVF dst (Binary src1 src2))); 16661 format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} 16662 ins_cost(INSN_COST); 16663 ins_encode %{ 16664 __ fmla(as_FloatRegister($dst$$reg), __ T2S, 16665 as_FloatRegister($src1$$reg), 16666 as_FloatRegister($src2$$reg)); 16667 %} 16668 ins_pipe(vmuldiv_fp64); 16669%} 16670 16671// dst + src1 * src2 16672instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ 16673 predicate(UseFMA && n->as_Vector()->length() == 4); 16674 match(Set dst (FmaVF dst (Binary src1 src2))); 16675 format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} 16676 ins_cost(INSN_COST); 16677 ins_encode %{ 16678 __ fmla(as_FloatRegister($dst$$reg), __ T4S, 16679 as_FloatRegister($src1$$reg), 16680 as_FloatRegister($src2$$reg)); 16681 %} 16682 ins_pipe(vmuldiv_fp128); 16683%} 16684 16685// dst + src1 * src2 16686instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ 16687 predicate(UseFMA && n->as_Vector()->length() == 2); 16688 match(Set dst (FmaVD dst (Binary src1 src2))); 16689 format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} 16690 ins_cost(INSN_COST); 16691 ins_encode %{ 16692 __ fmla(as_FloatRegister($dst$$reg), __ T2D, 16693 as_FloatRegister($src1$$reg), 16694 as_FloatRegister($src2$$reg)); 16695 %} 16696 ins_pipe(vmuldiv_fp128); 16697%} 16698 16699// --------------------------------- MLS -------------------------------------- 16700 16701instruct vmls4S(vecD dst, vecD src1, vecD src2) 16702%{ 16703 predicate(n->as_Vector()->length() == 2 || 16704 n->as_Vector()->length() == 4); 16705 match(Set dst (SubVS dst (MulVS src1 src2))); 16706 ins_cost(INSN_COST); 16707 format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} 16708 ins_encode %{ 16709 __ mlsv(as_FloatRegister($dst$$reg), __ T4H, 16710 as_FloatRegister($src1$$reg), 16711 as_FloatRegister($src2$$reg)); 16712 %} 16713 ins_pipe(vmla64); 16714%} 16715 16716instruct vmls8S(vecX dst, vecX src1, vecX src2) 16717%{ 16718 predicate(n->as_Vector()->length() == 8); 16719 match(Set dst (SubVS dst (MulVS src1 src2))); 16720 ins_cost(INSN_COST); 16721 format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} 16722 ins_encode %{ 16723 __ mlsv(as_FloatRegister($dst$$reg), __ T8H, 16724 as_FloatRegister($src1$$reg), 16725 as_FloatRegister($src2$$reg)); 16726 %} 16727 ins_pipe(vmla128); 16728%} 16729 16730instruct vmls2I(vecD dst, vecD src1, vecD src2) 16731%{ 16732 predicate(n->as_Vector()->length() == 2); 16733 match(Set dst (SubVI dst (MulVI src1 src2))); 16734 ins_cost(INSN_COST); 16735 format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} 16736 ins_encode %{ 16737 __ mlsv(as_FloatRegister($dst$$reg), __ T2S, 16738 as_FloatRegister($src1$$reg), 16739 as_FloatRegister($src2$$reg)); 16740 %} 16741 ins_pipe(vmla64); 16742%} 16743 16744instruct vmls4I(vecX dst, vecX src1, vecX src2) 16745%{ 16746 predicate(n->as_Vector()->length() == 4); 16747 match(Set dst (SubVI dst (MulVI src1 src2))); 16748 ins_cost(INSN_COST); 16749 format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} 16750 ins_encode %{ 16751 __ mlsv(as_FloatRegister($dst$$reg), __ T4S, 16752 as_FloatRegister($src1$$reg), 16753 as_FloatRegister($src2$$reg)); 16754 %} 16755 ins_pipe(vmla128); 16756%} 16757 16758// dst - src1 * src2 16759instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ 16760 predicate(UseFMA && n->as_Vector()->length() == 2); 16761 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16762 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16763 format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} 16764 ins_cost(INSN_COST); 16765 ins_encode %{ 16766 __ fmls(as_FloatRegister($dst$$reg), __ T2S, 16767 as_FloatRegister($src1$$reg), 16768 as_FloatRegister($src2$$reg)); 16769 %} 16770 ins_pipe(vmuldiv_fp64); 16771%} 16772 16773// dst - src1 * src2 16774instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ 16775 predicate(UseFMA && n->as_Vector()->length() == 4); 16776 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 16777 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 16778 format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} 16779 ins_cost(INSN_COST); 16780 ins_encode %{ 16781 __ fmls(as_FloatRegister($dst$$reg), __ T4S, 16782 as_FloatRegister($src1$$reg), 16783 as_FloatRegister($src2$$reg)); 16784 %} 16785 ins_pipe(vmuldiv_fp128); 16786%} 16787 16788// dst - src1 * src2 16789instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ 16790 predicate(UseFMA && n->as_Vector()->length() == 2); 16791 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 16792 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 16793 format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} 16794 ins_cost(INSN_COST); 16795 ins_encode %{ 16796 __ fmls(as_FloatRegister($dst$$reg), __ T2D, 16797 as_FloatRegister($src1$$reg), 16798 as_FloatRegister($src2$$reg)); 16799 %} 16800 ins_pipe(vmuldiv_fp128); 16801%} 16802 16803// --------------------------------- DIV -------------------------------------- 16804 16805instruct vdiv2F(vecD dst, vecD src1, vecD src2) 16806%{ 16807 predicate(n->as_Vector()->length() == 2); 16808 match(Set dst (DivVF src1 src2)); 16809 ins_cost(INSN_COST); 16810 format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} 16811 ins_encode %{ 16812 __ fdiv(as_FloatRegister($dst$$reg), __ T2S, 16813 as_FloatRegister($src1$$reg), 16814 as_FloatRegister($src2$$reg)); 16815 %} 16816 ins_pipe(vmuldiv_fp64); 16817%} 16818 16819instruct vdiv4F(vecX dst, vecX src1, vecX src2) 16820%{ 16821 predicate(n->as_Vector()->length() == 4); 16822 match(Set dst (DivVF src1 src2)); 16823 ins_cost(INSN_COST); 16824 format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} 16825 ins_encode %{ 16826 __ fdiv(as_FloatRegister($dst$$reg), __ T4S, 16827 as_FloatRegister($src1$$reg), 16828 as_FloatRegister($src2$$reg)); 16829 %} 16830 ins_pipe(vmuldiv_fp128); 16831%} 16832 16833instruct vdiv2D(vecX dst, vecX src1, vecX src2) 16834%{ 16835 predicate(n->as_Vector()->length() == 2); 16836 match(Set dst (DivVD src1 src2)); 16837 ins_cost(INSN_COST); 16838 format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} 16839 ins_encode %{ 16840 __ fdiv(as_FloatRegister($dst$$reg), __ T2D, 16841 as_FloatRegister($src1$$reg), 16842 as_FloatRegister($src2$$reg)); 16843 %} 16844 ins_pipe(vmuldiv_fp128); 16845%} 16846 16847// --------------------------------- SQRT ------------------------------------- 16848 16849instruct vsqrt2F(vecD dst, vecD src) 16850%{ 16851 predicate(n->as_Vector()->length() == 2); 16852 match(Set dst (SqrtVF src)); 16853 format %{ "fsqrt $dst, $src\t# vector (2F)" %} 16854 ins_encode %{ 16855 __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 16856 %} 16857 ins_pipe(vunop_fp64); 16858%} 16859 16860instruct vsqrt4F(vecX dst, vecX src) 16861%{ 16862 predicate(n->as_Vector()->length() == 4); 16863 match(Set dst (SqrtVF src)); 16864 format %{ "fsqrt $dst, $src\t# vector (4F)" %} 16865 ins_encode %{ 16866 __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 16867 %} 16868 ins_pipe(vsqrt_fp128); 16869%} 16870 16871instruct vsqrt2D(vecX dst, vecX src) 16872%{ 16873 predicate(n->as_Vector()->length() == 2); 16874 match(Set dst (SqrtVD src)); 16875 format %{ "fsqrt $dst, $src\t# vector (2D)" %} 16876 ins_encode %{ 16877 __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, 16878 as_FloatRegister($src$$reg)); 16879 %} 16880 ins_pipe(vsqrt_fp128); 16881%} 16882 16883// --------------------------------- ABS -------------------------------------- 16884 16885instruct vabs8B(vecD dst, vecD src) 16886%{ 16887 predicate(n->as_Vector()->length() == 4 || 16888 n->as_Vector()->length() == 8); 16889 match(Set dst (AbsVB src)); 16890 ins_cost(INSN_COST); 16891 format %{ "abs $dst, $src\t# vector (8B)" %} 16892 ins_encode %{ 16893 __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); 16894 %} 16895 ins_pipe(vlogical64); 16896%} 16897 16898instruct vabs16B(vecX dst, vecX src) 16899%{ 16900 predicate(n->as_Vector()->length() == 16); 16901 match(Set dst (AbsVB src)); 16902 ins_cost(INSN_COST); 16903 format %{ "abs $dst, $src\t# vector (16B)" %} 16904 ins_encode %{ 16905 __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); 16906 %} 16907 ins_pipe(vlogical128); 16908%} 16909 16910instruct vabs4S(vecD dst, vecD src) 16911%{ 16912 predicate(n->as_Vector()->length() == 4); 16913 match(Set dst (AbsVS src)); 16914 ins_cost(INSN_COST); 16915 format %{ "abs $dst, $src\t# vector (4H)" %} 16916 ins_encode %{ 16917 __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg)); 16918 %} 16919 ins_pipe(vlogical64); 16920%} 16921 16922instruct vabs8S(vecX dst, vecX src) 16923%{ 16924 predicate(n->as_Vector()->length() == 8); 16925 match(Set dst (AbsVS src)); 16926 ins_cost(INSN_COST); 16927 format %{ "abs $dst, $src\t# vector (8H)" %} 16928 ins_encode %{ 16929 __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg)); 16930 %} 16931 ins_pipe(vlogical128); 16932%} 16933 16934instruct vabs2I(vecD dst, vecD src) 16935%{ 16936 predicate(n->as_Vector()->length() == 2); 16937 match(Set dst (AbsVI src)); 16938 ins_cost(INSN_COST); 16939 format %{ "abs $dst, $src\t# vector (2S)" %} 16940 ins_encode %{ 16941 __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); 16942 %} 16943 ins_pipe(vlogical64); 16944%} 16945 16946instruct vabs4I(vecX dst, vecX src) 16947%{ 16948 predicate(n->as_Vector()->length() == 4); 16949 match(Set dst (AbsVI src)); 16950 ins_cost(INSN_COST); 16951 format %{ "abs $dst, $src\t# vector (4S)" %} 16952 ins_encode %{ 16953 __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); 16954 %} 16955 ins_pipe(vlogical128); 16956%} 16957 16958instruct vabs2L(vecX dst, vecX src) 16959%{ 16960 predicate(n->as_Vector()->length() == 2); 16961 match(Set dst (AbsVL src)); 16962 ins_cost(INSN_COST); 16963 format %{ "abs $dst, $src\t# vector (2D)" %} 16964 ins_encode %{ 16965 __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); 16966 %} 16967 ins_pipe(vlogical128); 16968%} 16969 16970instruct vabs2F(vecD dst, vecD src) 16971%{ 16972 predicate(n->as_Vector()->length() == 2); 16973 match(Set dst (AbsVF src)); 16974 ins_cost(INSN_COST * 3); 16975 format %{ "fabs $dst,$src\t# vector (2S)" %} 16976 ins_encode %{ 16977 __ fabs(as_FloatRegister($dst$$reg), __ T2S, 16978 as_FloatRegister($src$$reg)); 16979 %} 16980 ins_pipe(vunop_fp64); 16981%} 16982 16983instruct vabs4F(vecX dst, vecX src) 16984%{ 16985 predicate(n->as_Vector()->length() == 4); 16986 match(Set dst (AbsVF src)); 16987 ins_cost(INSN_COST * 3); 16988 format %{ "fabs $dst,$src\t# vector (4S)" %} 16989 ins_encode %{ 16990 __ fabs(as_FloatRegister($dst$$reg), __ T4S, 16991 as_FloatRegister($src$$reg)); 16992 %} 16993 ins_pipe(vunop_fp128); 16994%} 16995 16996instruct vabs2D(vecX dst, vecX src) 16997%{ 16998 predicate(n->as_Vector()->length() == 2); 16999 match(Set dst (AbsVD src)); 17000 ins_cost(INSN_COST * 3); 17001 format %{ "fabs $dst,$src\t# vector (2D)" %} 17002 ins_encode %{ 17003 __ fabs(as_FloatRegister($dst$$reg), __ T2D, 17004 as_FloatRegister($src$$reg)); 17005 %} 17006 ins_pipe(vunop_fp128); 17007%} 17008 17009// --------------------------------- NEG -------------------------------------- 17010 17011instruct vneg2F(vecD dst, vecD src) 17012%{ 17013 predicate(n->as_Vector()->length() == 2); 17014 match(Set dst (NegVF src)); 17015 ins_cost(INSN_COST * 3); 17016 format %{ "fneg $dst,$src\t# vector (2S)" %} 17017 ins_encode %{ 17018 __ fneg(as_FloatRegister($dst$$reg), __ T2S, 17019 as_FloatRegister($src$$reg)); 17020 %} 17021 ins_pipe(vunop_fp64); 17022%} 17023 17024instruct vneg4F(vecX dst, vecX src) 17025%{ 17026 predicate(n->as_Vector()->length() == 4); 17027 match(Set dst (NegVF src)); 17028 ins_cost(INSN_COST * 3); 17029 format %{ "fneg $dst,$src\t# vector (4S)" %} 17030 ins_encode %{ 17031 __ fneg(as_FloatRegister($dst$$reg), __ T4S, 17032 as_FloatRegister($src$$reg)); 17033 %} 17034 ins_pipe(vunop_fp128); 17035%} 17036 17037instruct vneg2D(vecX dst, vecX src) 17038%{ 17039 predicate(n->as_Vector()->length() == 2); 17040 match(Set dst (NegVD src)); 17041 ins_cost(INSN_COST * 3); 17042 format %{ "fneg $dst,$src\t# vector (2D)" %} 17043 ins_encode %{ 17044 __ fneg(as_FloatRegister($dst$$reg), __ T2D, 17045 as_FloatRegister($src$$reg)); 17046 %} 17047 ins_pipe(vunop_fp128); 17048%} 17049 17050// --------------------------------- AND -------------------------------------- 17051 17052instruct vand8B(vecD dst, vecD src1, vecD src2) 17053%{ 17054 predicate(n->as_Vector()->length_in_bytes() == 4 || 17055 n->as_Vector()->length_in_bytes() == 8); 17056 match(Set dst (AndV src1 src2)); 17057 ins_cost(INSN_COST); 17058 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17059 ins_encode %{ 17060 __ andr(as_FloatRegister($dst$$reg), __ T8B, 17061 as_FloatRegister($src1$$reg), 17062 as_FloatRegister($src2$$reg)); 17063 %} 17064 ins_pipe(vlogical64); 17065%} 17066 17067instruct vand16B(vecX dst, vecX src1, vecX src2) 17068%{ 17069 predicate(n->as_Vector()->length_in_bytes() == 16); 17070 match(Set dst (AndV src1 src2)); 17071 ins_cost(INSN_COST); 17072 format %{ "and $dst,$src1,$src2\t# vector (16B)" %} 17073 ins_encode %{ 17074 __ andr(as_FloatRegister($dst$$reg), __ T16B, 17075 as_FloatRegister($src1$$reg), 17076 as_FloatRegister($src2$$reg)); 17077 %} 17078 ins_pipe(vlogical128); 17079%} 17080 17081// --------------------------------- OR --------------------------------------- 17082 17083instruct vor8B(vecD dst, vecD src1, vecD src2) 17084%{ 17085 predicate(n->as_Vector()->length_in_bytes() == 4 || 17086 n->as_Vector()->length_in_bytes() == 8); 17087 match(Set dst (OrV src1 src2)); 17088 ins_cost(INSN_COST); 17089 format %{ "and $dst,$src1,$src2\t# vector (8B)" %} 17090 ins_encode %{ 17091 __ orr(as_FloatRegister($dst$$reg), __ T8B, 17092 as_FloatRegister($src1$$reg), 17093 as_FloatRegister($src2$$reg)); 17094 %} 17095 ins_pipe(vlogical64); 17096%} 17097 17098instruct vor16B(vecX dst, vecX src1, vecX src2) 17099%{ 17100 predicate(n->as_Vector()->length_in_bytes() == 16); 17101 match(Set dst (OrV src1 src2)); 17102 ins_cost(INSN_COST); 17103 format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} 17104 ins_encode %{ 17105 __ orr(as_FloatRegister($dst$$reg), __ T16B, 17106 as_FloatRegister($src1$$reg), 17107 as_FloatRegister($src2$$reg)); 17108 %} 17109 ins_pipe(vlogical128); 17110%} 17111 17112// --------------------------------- XOR -------------------------------------- 17113 17114instruct vxor8B(vecD dst, vecD src1, vecD src2) 17115%{ 17116 predicate(n->as_Vector()->length_in_bytes() == 4 || 17117 n->as_Vector()->length_in_bytes() == 8); 17118 match(Set dst (XorV src1 src2)); 17119 ins_cost(INSN_COST); 17120 format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} 17121 ins_encode %{ 17122 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17123 as_FloatRegister($src1$$reg), 17124 as_FloatRegister($src2$$reg)); 17125 %} 17126 ins_pipe(vlogical64); 17127%} 17128 17129instruct vxor16B(vecX dst, vecX src1, vecX src2) 17130%{ 17131 predicate(n->as_Vector()->length_in_bytes() == 16); 17132 match(Set dst (XorV src1 src2)); 17133 ins_cost(INSN_COST); 17134 format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} 17135 ins_encode %{ 17136 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17137 as_FloatRegister($src1$$reg), 17138 as_FloatRegister($src2$$reg)); 17139 %} 17140 ins_pipe(vlogical128); 17141%} 17142 17143// ------------------------------ Shift --------------------------------------- 17144instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ 17145 predicate(n->as_Vector()->length_in_bytes() == 8); 17146 match(Set dst (LShiftCntV cnt)); 17147 match(Set dst (RShiftCntV cnt)); 17148 format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} 17149 ins_encode %{ 17150 __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); 17151 %} 17152 ins_pipe(vdup_reg_reg64); 17153%} 17154 17155instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ 17156 predicate(n->as_Vector()->length_in_bytes() == 16); 17157 match(Set dst (LShiftCntV cnt)); 17158 match(Set dst (RShiftCntV cnt)); 17159 format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} 17160 ins_encode %{ 17161 __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); 17162 %} 17163 ins_pipe(vdup_reg_reg128); 17164%} 17165 17166instruct vsll8B(vecD dst, vecD src, vecD shift) %{ 17167 predicate(n->as_Vector()->length() == 4 || 17168 n->as_Vector()->length() == 8); 17169 match(Set dst (LShiftVB src shift)); 17170 ins_cost(INSN_COST); 17171 format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} 17172 ins_encode %{ 17173 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17174 as_FloatRegister($src$$reg), 17175 as_FloatRegister($shift$$reg)); 17176 %} 17177 ins_pipe(vshift64); 17178%} 17179 17180instruct vsll16B(vecX dst, vecX src, vecX shift) %{ 17181 predicate(n->as_Vector()->length() == 16); 17182 match(Set dst (LShiftVB src shift)); 17183 ins_cost(INSN_COST); 17184 format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} 17185 ins_encode %{ 17186 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17187 as_FloatRegister($src$$reg), 17188 as_FloatRegister($shift$$reg)); 17189 %} 17190 ins_pipe(vshift128); 17191%} 17192 17193// Right shifts with vector shift count on aarch64 SIMD are implemented 17194// as left shift by negative shift count. 17195// There are two cases for vector shift count. 17196// 17197// Case 1: The vector shift count is from replication. 17198// | | 17199// LoadVector RShiftCntV 17200// | / 17201// RShiftVI 17202// Note: In inner loop, multiple neg instructions are used, which can be 17203// moved to outer loop and merge into one neg instruction. 17204// 17205// Case 2: The vector shift count is from loading. 17206// This case isn't supported by middle-end now. But it's supported by 17207// panama/vectorIntrinsics(JEP 338: Vector API). 17208// | | 17209// LoadVector LoadVector 17210// | / 17211// RShiftVI 17212// 17213 17214instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17215 predicate(n->as_Vector()->length() == 4 || 17216 n->as_Vector()->length() == 8); 17217 match(Set dst (RShiftVB src shift)); 17218 ins_cost(INSN_COST); 17219 effect(TEMP tmp); 17220 format %{ "negr $tmp,$shift\t" 17221 "sshl $dst,$src,$tmp\t# vector (8B)" %} 17222 ins_encode %{ 17223 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17224 as_FloatRegister($shift$$reg)); 17225 __ sshl(as_FloatRegister($dst$$reg), __ T8B, 17226 as_FloatRegister($src$$reg), 17227 as_FloatRegister($tmp$$reg)); 17228 %} 17229 ins_pipe(vshift64); 17230%} 17231 17232instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17233 predicate(n->as_Vector()->length() == 16); 17234 match(Set dst (RShiftVB src shift)); 17235 ins_cost(INSN_COST); 17236 effect(TEMP tmp); 17237 format %{ "negr $tmp,$shift\t" 17238 "sshl $dst,$src,$tmp\t# vector (16B)" %} 17239 ins_encode %{ 17240 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17241 as_FloatRegister($shift$$reg)); 17242 __ sshl(as_FloatRegister($dst$$reg), __ T16B, 17243 as_FloatRegister($src$$reg), 17244 as_FloatRegister($tmp$$reg)); 17245 %} 17246 ins_pipe(vshift128); 17247%} 17248 17249instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17250 predicate(n->as_Vector()->length() == 4 || 17251 n->as_Vector()->length() == 8); 17252 match(Set dst (URShiftVB src shift)); 17253 ins_cost(INSN_COST); 17254 effect(TEMP tmp); 17255 format %{ "negr $tmp,$shift\t" 17256 "ushl $dst,$src,$tmp\t# vector (8B)" %} 17257 ins_encode %{ 17258 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17259 as_FloatRegister($shift$$reg)); 17260 __ ushl(as_FloatRegister($dst$$reg), __ T8B, 17261 as_FloatRegister($src$$reg), 17262 as_FloatRegister($tmp$$reg)); 17263 %} 17264 ins_pipe(vshift64); 17265%} 17266 17267instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17268 predicate(n->as_Vector()->length() == 16); 17269 match(Set dst (URShiftVB src shift)); 17270 ins_cost(INSN_COST); 17271 effect(TEMP tmp); 17272 format %{ "negr $tmp,$shift\t" 17273 "ushl $dst,$src,$tmp\t# vector (16B)" %} 17274 ins_encode %{ 17275 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17276 as_FloatRegister($shift$$reg)); 17277 __ ushl(as_FloatRegister($dst$$reg), __ T16B, 17278 as_FloatRegister($src$$reg), 17279 as_FloatRegister($tmp$$reg)); 17280 %} 17281 ins_pipe(vshift128); 17282%} 17283 17284instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ 17285 predicate(n->as_Vector()->length() == 4 || 17286 n->as_Vector()->length() == 8); 17287 match(Set dst (LShiftVB src shift)); 17288 ins_cost(INSN_COST); 17289 format %{ "shl $dst, $src, $shift\t# vector (8B)" %} 17290 ins_encode %{ 17291 int sh = (int)$shift$$constant; 17292 if (sh >= 8) { 17293 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17294 as_FloatRegister($src$$reg), 17295 as_FloatRegister($src$$reg)); 17296 } else { 17297 __ shl(as_FloatRegister($dst$$reg), __ T8B, 17298 as_FloatRegister($src$$reg), sh); 17299 } 17300 %} 17301 ins_pipe(vshift64_imm); 17302%} 17303 17304instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ 17305 predicate(n->as_Vector()->length() == 16); 17306 match(Set dst (LShiftVB src shift)); 17307 ins_cost(INSN_COST); 17308 format %{ "shl $dst, $src, $shift\t# vector (16B)" %} 17309 ins_encode %{ 17310 int sh = (int)$shift$$constant; 17311 if (sh >= 8) { 17312 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17313 as_FloatRegister($src$$reg), 17314 as_FloatRegister($src$$reg)); 17315 } else { 17316 __ shl(as_FloatRegister($dst$$reg), __ T16B, 17317 as_FloatRegister($src$$reg), sh); 17318 } 17319 %} 17320 ins_pipe(vshift128_imm); 17321%} 17322 17323instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ 17324 predicate(n->as_Vector()->length() == 4 || 17325 n->as_Vector()->length() == 8); 17326 match(Set dst (RShiftVB src shift)); 17327 ins_cost(INSN_COST); 17328 format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} 17329 ins_encode %{ 17330 int sh = (int)$shift$$constant; 17331 if (sh >= 8) sh = 7; 17332 __ sshr(as_FloatRegister($dst$$reg), __ T8B, 17333 as_FloatRegister($src$$reg), sh); 17334 %} 17335 ins_pipe(vshift64_imm); 17336%} 17337 17338instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ 17339 predicate(n->as_Vector()->length() == 16); 17340 match(Set dst (RShiftVB src shift)); 17341 ins_cost(INSN_COST); 17342 format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} 17343 ins_encode %{ 17344 int sh = (int)$shift$$constant; 17345 if (sh >= 8) sh = 7; 17346 __ sshr(as_FloatRegister($dst$$reg), __ T16B, 17347 as_FloatRegister($src$$reg), sh); 17348 %} 17349 ins_pipe(vshift128_imm); 17350%} 17351 17352instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ 17353 predicate(n->as_Vector()->length() == 4 || 17354 n->as_Vector()->length() == 8); 17355 match(Set dst (URShiftVB src shift)); 17356 ins_cost(INSN_COST); 17357 format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} 17358 ins_encode %{ 17359 int sh = (int)$shift$$constant; 17360 if (sh >= 8) { 17361 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17362 as_FloatRegister($src$$reg), 17363 as_FloatRegister($src$$reg)); 17364 } else { 17365 __ ushr(as_FloatRegister($dst$$reg), __ T8B, 17366 as_FloatRegister($src$$reg), sh); 17367 } 17368 %} 17369 ins_pipe(vshift64_imm); 17370%} 17371 17372instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ 17373 predicate(n->as_Vector()->length() == 16); 17374 match(Set dst (URShiftVB src shift)); 17375 ins_cost(INSN_COST); 17376 format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} 17377 ins_encode %{ 17378 int sh = (int)$shift$$constant; 17379 if (sh >= 8) { 17380 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17381 as_FloatRegister($src$$reg), 17382 as_FloatRegister($src$$reg)); 17383 } else { 17384 __ ushr(as_FloatRegister($dst$$reg), __ T16B, 17385 as_FloatRegister($src$$reg), sh); 17386 } 17387 %} 17388 ins_pipe(vshift128_imm); 17389%} 17390 17391instruct vsll4S(vecD dst, vecD src, vecD shift) %{ 17392 predicate(n->as_Vector()->length() == 2 || 17393 n->as_Vector()->length() == 4); 17394 match(Set dst (LShiftVS src shift)); 17395 ins_cost(INSN_COST); 17396 format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} 17397 ins_encode %{ 17398 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17399 as_FloatRegister($src$$reg), 17400 as_FloatRegister($shift$$reg)); 17401 %} 17402 ins_pipe(vshift64); 17403%} 17404 17405instruct vsll8S(vecX dst, vecX src, vecX shift) %{ 17406 predicate(n->as_Vector()->length() == 8); 17407 match(Set dst (LShiftVS src shift)); 17408 ins_cost(INSN_COST); 17409 format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} 17410 ins_encode %{ 17411 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17412 as_FloatRegister($src$$reg), 17413 as_FloatRegister($shift$$reg)); 17414 %} 17415 ins_pipe(vshift128); 17416%} 17417 17418instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17419 predicate(n->as_Vector()->length() == 2 || 17420 n->as_Vector()->length() == 4); 17421 match(Set dst (RShiftVS src shift)); 17422 ins_cost(INSN_COST); 17423 effect(TEMP tmp); 17424 format %{ "negr $tmp,$shift\t" 17425 "sshl $dst,$src,$tmp\t# vector (4H)" %} 17426 ins_encode %{ 17427 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17428 as_FloatRegister($shift$$reg)); 17429 __ sshl(as_FloatRegister($dst$$reg), __ T4H, 17430 as_FloatRegister($src$$reg), 17431 as_FloatRegister($tmp$$reg)); 17432 %} 17433 ins_pipe(vshift64); 17434%} 17435 17436instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17437 predicate(n->as_Vector()->length() == 8); 17438 match(Set dst (RShiftVS src shift)); 17439 ins_cost(INSN_COST); 17440 effect(TEMP tmp); 17441 format %{ "negr $tmp,$shift\t" 17442 "sshl $dst,$src,$tmp\t# vector (8H)" %} 17443 ins_encode %{ 17444 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17445 as_FloatRegister($shift$$reg)); 17446 __ sshl(as_FloatRegister($dst$$reg), __ T8H, 17447 as_FloatRegister($src$$reg), 17448 as_FloatRegister($tmp$$reg)); 17449 %} 17450 ins_pipe(vshift128); 17451%} 17452 17453instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17454 predicate(n->as_Vector()->length() == 2 || 17455 n->as_Vector()->length() == 4); 17456 match(Set dst (URShiftVS src shift)); 17457 ins_cost(INSN_COST); 17458 effect(TEMP tmp); 17459 format %{ "negr $tmp,$shift\t" 17460 "ushl $dst,$src,$tmp\t# vector (4H)" %} 17461 ins_encode %{ 17462 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17463 as_FloatRegister($shift$$reg)); 17464 __ ushl(as_FloatRegister($dst$$reg), __ T4H, 17465 as_FloatRegister($src$$reg), 17466 as_FloatRegister($tmp$$reg)); 17467 %} 17468 ins_pipe(vshift64); 17469%} 17470 17471instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17472 predicate(n->as_Vector()->length() == 8); 17473 match(Set dst (URShiftVS src shift)); 17474 ins_cost(INSN_COST); 17475 effect(TEMP tmp); 17476 format %{ "negr $tmp,$shift\t" 17477 "ushl $dst,$src,$tmp\t# vector (8H)" %} 17478 ins_encode %{ 17479 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17480 as_FloatRegister($shift$$reg)); 17481 __ ushl(as_FloatRegister($dst$$reg), __ T8H, 17482 as_FloatRegister($src$$reg), 17483 as_FloatRegister($tmp$$reg)); 17484 %} 17485 ins_pipe(vshift128); 17486%} 17487 17488instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ 17489 predicate(n->as_Vector()->length() == 2 || 17490 n->as_Vector()->length() == 4); 17491 match(Set dst (LShiftVS src shift)); 17492 ins_cost(INSN_COST); 17493 format %{ "shl $dst, $src, $shift\t# vector (4H)" %} 17494 ins_encode %{ 17495 int sh = (int)$shift$$constant; 17496 if (sh >= 16) { 17497 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17498 as_FloatRegister($src$$reg), 17499 as_FloatRegister($src$$reg)); 17500 } else { 17501 __ shl(as_FloatRegister($dst$$reg), __ T4H, 17502 as_FloatRegister($src$$reg), sh); 17503 } 17504 %} 17505 ins_pipe(vshift64_imm); 17506%} 17507 17508instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ 17509 predicate(n->as_Vector()->length() == 8); 17510 match(Set dst (LShiftVS src shift)); 17511 ins_cost(INSN_COST); 17512 format %{ "shl $dst, $src, $shift\t# vector (8H)" %} 17513 ins_encode %{ 17514 int sh = (int)$shift$$constant; 17515 if (sh >= 16) { 17516 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17517 as_FloatRegister($src$$reg), 17518 as_FloatRegister($src$$reg)); 17519 } else { 17520 __ shl(as_FloatRegister($dst$$reg), __ T8H, 17521 as_FloatRegister($src$$reg), sh); 17522 } 17523 %} 17524 ins_pipe(vshift128_imm); 17525%} 17526 17527instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ 17528 predicate(n->as_Vector()->length() == 2 || 17529 n->as_Vector()->length() == 4); 17530 match(Set dst (RShiftVS src shift)); 17531 ins_cost(INSN_COST); 17532 format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} 17533 ins_encode %{ 17534 int sh = (int)$shift$$constant; 17535 if (sh >= 16) sh = 15; 17536 __ sshr(as_FloatRegister($dst$$reg), __ T4H, 17537 as_FloatRegister($src$$reg), sh); 17538 %} 17539 ins_pipe(vshift64_imm); 17540%} 17541 17542instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ 17543 predicate(n->as_Vector()->length() == 8); 17544 match(Set dst (RShiftVS src shift)); 17545 ins_cost(INSN_COST); 17546 format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} 17547 ins_encode %{ 17548 int sh = (int)$shift$$constant; 17549 if (sh >= 16) sh = 15; 17550 __ sshr(as_FloatRegister($dst$$reg), __ T8H, 17551 as_FloatRegister($src$$reg), sh); 17552 %} 17553 ins_pipe(vshift128_imm); 17554%} 17555 17556instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ 17557 predicate(n->as_Vector()->length() == 2 || 17558 n->as_Vector()->length() == 4); 17559 match(Set dst (URShiftVS src shift)); 17560 ins_cost(INSN_COST); 17561 format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} 17562 ins_encode %{ 17563 int sh = (int)$shift$$constant; 17564 if (sh >= 16) { 17565 __ eor(as_FloatRegister($dst$$reg), __ T8B, 17566 as_FloatRegister($src$$reg), 17567 as_FloatRegister($src$$reg)); 17568 } else { 17569 __ ushr(as_FloatRegister($dst$$reg), __ T4H, 17570 as_FloatRegister($src$$reg), sh); 17571 } 17572 %} 17573 ins_pipe(vshift64_imm); 17574%} 17575 17576instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ 17577 predicate(n->as_Vector()->length() == 8); 17578 match(Set dst (URShiftVS src shift)); 17579 ins_cost(INSN_COST); 17580 format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} 17581 ins_encode %{ 17582 int sh = (int)$shift$$constant; 17583 if (sh >= 16) { 17584 __ eor(as_FloatRegister($dst$$reg), __ T16B, 17585 as_FloatRegister($src$$reg), 17586 as_FloatRegister($src$$reg)); 17587 } else { 17588 __ ushr(as_FloatRegister($dst$$reg), __ T8H, 17589 as_FloatRegister($src$$reg), sh); 17590 } 17591 %} 17592 ins_pipe(vshift128_imm); 17593%} 17594 17595instruct vsll2I(vecD dst, vecD src, vecD shift) %{ 17596 predicate(n->as_Vector()->length() == 2); 17597 match(Set dst (LShiftVI src shift)); 17598 ins_cost(INSN_COST); 17599 format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} 17600 ins_encode %{ 17601 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17602 as_FloatRegister($src$$reg), 17603 as_FloatRegister($shift$$reg)); 17604 %} 17605 ins_pipe(vshift64); 17606%} 17607 17608instruct vsll4I(vecX dst, vecX src, vecX shift) %{ 17609 predicate(n->as_Vector()->length() == 4); 17610 match(Set dst (LShiftVI src shift)); 17611 ins_cost(INSN_COST); 17612 format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} 17613 ins_encode %{ 17614 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17615 as_FloatRegister($src$$reg), 17616 as_FloatRegister($shift$$reg)); 17617 %} 17618 ins_pipe(vshift128); 17619%} 17620 17621instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17622 predicate(n->as_Vector()->length() == 2); 17623 match(Set dst (RShiftVI src shift)); 17624 ins_cost(INSN_COST); 17625 effect(TEMP tmp); 17626 format %{ "negr $tmp,$shift\t" 17627 "sshl $dst,$src,$tmp\t# vector (2S)" %} 17628 ins_encode %{ 17629 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17630 as_FloatRegister($shift$$reg)); 17631 __ sshl(as_FloatRegister($dst$$reg), __ T2S, 17632 as_FloatRegister($src$$reg), 17633 as_FloatRegister($tmp$$reg)); 17634 %} 17635 ins_pipe(vshift64); 17636%} 17637 17638instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17639 predicate(n->as_Vector()->length() == 4); 17640 match(Set dst (RShiftVI src shift)); 17641 ins_cost(INSN_COST); 17642 effect(TEMP tmp); 17643 format %{ "negr $tmp,$shift\t" 17644 "sshl $dst,$src,$tmp\t# vector (4S)" %} 17645 ins_encode %{ 17646 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17647 as_FloatRegister($shift$$reg)); 17648 __ sshl(as_FloatRegister($dst$$reg), __ T4S, 17649 as_FloatRegister($src$$reg), 17650 as_FloatRegister($tmp$$reg)); 17651 %} 17652 ins_pipe(vshift128); 17653%} 17654 17655instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ 17656 predicate(n->as_Vector()->length() == 2); 17657 match(Set dst (URShiftVI src shift)); 17658 ins_cost(INSN_COST); 17659 effect(TEMP tmp); 17660 format %{ "negr $tmp,$shift\t" 17661 "ushl $dst,$src,$tmp\t# vector (2S)" %} 17662 ins_encode %{ 17663 __ negr(as_FloatRegister($tmp$$reg), __ T8B, 17664 as_FloatRegister($shift$$reg)); 17665 __ ushl(as_FloatRegister($dst$$reg), __ T2S, 17666 as_FloatRegister($src$$reg), 17667 as_FloatRegister($tmp$$reg)); 17668 %} 17669 ins_pipe(vshift64); 17670%} 17671 17672instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17673 predicate(n->as_Vector()->length() == 4); 17674 match(Set dst (URShiftVI src shift)); 17675 ins_cost(INSN_COST); 17676 effect(TEMP tmp); 17677 format %{ "negr $tmp,$shift\t" 17678 "ushl $dst,$src,$tmp\t# vector (4S)" %} 17679 ins_encode %{ 17680 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17681 as_FloatRegister($shift$$reg)); 17682 __ ushl(as_FloatRegister($dst$$reg), __ T4S, 17683 as_FloatRegister($src$$reg), 17684 as_FloatRegister($tmp$$reg)); 17685 %} 17686 ins_pipe(vshift128); 17687%} 17688 17689instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ 17690 predicate(n->as_Vector()->length() == 2); 17691 match(Set dst (LShiftVI src shift)); 17692 ins_cost(INSN_COST); 17693 format %{ "shl $dst, $src, $shift\t# vector (2S)" %} 17694 ins_encode %{ 17695 __ shl(as_FloatRegister($dst$$reg), __ T2S, 17696 as_FloatRegister($src$$reg), 17697 (int)$shift$$constant); 17698 %} 17699 ins_pipe(vshift64_imm); 17700%} 17701 17702instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ 17703 predicate(n->as_Vector()->length() == 4); 17704 match(Set dst (LShiftVI src shift)); 17705 ins_cost(INSN_COST); 17706 format %{ "shl $dst, $src, $shift\t# vector (4S)" %} 17707 ins_encode %{ 17708 __ shl(as_FloatRegister($dst$$reg), __ T4S, 17709 as_FloatRegister($src$$reg), 17710 (int)$shift$$constant); 17711 %} 17712 ins_pipe(vshift128_imm); 17713%} 17714 17715instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ 17716 predicate(n->as_Vector()->length() == 2); 17717 match(Set dst (RShiftVI src shift)); 17718 ins_cost(INSN_COST); 17719 format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} 17720 ins_encode %{ 17721 __ sshr(as_FloatRegister($dst$$reg), __ T2S, 17722 as_FloatRegister($src$$reg), 17723 (int)$shift$$constant); 17724 %} 17725 ins_pipe(vshift64_imm); 17726%} 17727 17728instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ 17729 predicate(n->as_Vector()->length() == 4); 17730 match(Set dst (RShiftVI src shift)); 17731 ins_cost(INSN_COST); 17732 format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} 17733 ins_encode %{ 17734 __ sshr(as_FloatRegister($dst$$reg), __ T4S, 17735 as_FloatRegister($src$$reg), 17736 (int)$shift$$constant); 17737 %} 17738 ins_pipe(vshift128_imm); 17739%} 17740 17741instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ 17742 predicate(n->as_Vector()->length() == 2); 17743 match(Set dst (URShiftVI src shift)); 17744 ins_cost(INSN_COST); 17745 format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} 17746 ins_encode %{ 17747 __ ushr(as_FloatRegister($dst$$reg), __ T2S, 17748 as_FloatRegister($src$$reg), 17749 (int)$shift$$constant); 17750 %} 17751 ins_pipe(vshift64_imm); 17752%} 17753 17754instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ 17755 predicate(n->as_Vector()->length() == 4); 17756 match(Set dst (URShiftVI src shift)); 17757 ins_cost(INSN_COST); 17758 format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} 17759 ins_encode %{ 17760 __ ushr(as_FloatRegister($dst$$reg), __ T4S, 17761 as_FloatRegister($src$$reg), 17762 (int)$shift$$constant); 17763 %} 17764 ins_pipe(vshift128_imm); 17765%} 17766 17767instruct vsll2L(vecX dst, vecX src, vecX shift) %{ 17768 predicate(n->as_Vector()->length() == 2); 17769 match(Set dst (LShiftVL src shift)); 17770 ins_cost(INSN_COST); 17771 format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} 17772 ins_encode %{ 17773 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17774 as_FloatRegister($src$$reg), 17775 as_FloatRegister($shift$$reg)); 17776 %} 17777 ins_pipe(vshift128); 17778%} 17779 17780instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17781 predicate(n->as_Vector()->length() == 2); 17782 match(Set dst (RShiftVL src shift)); 17783 ins_cost(INSN_COST); 17784 effect(TEMP tmp); 17785 format %{ "negr $tmp,$shift\t" 17786 "sshl $dst,$src,$tmp\t# vector (2D)" %} 17787 ins_encode %{ 17788 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17789 as_FloatRegister($shift$$reg)); 17790 __ sshl(as_FloatRegister($dst$$reg), __ T2D, 17791 as_FloatRegister($src$$reg), 17792 as_FloatRegister($tmp$$reg)); 17793 %} 17794 ins_pipe(vshift128); 17795%} 17796 17797instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ 17798 predicate(n->as_Vector()->length() == 2); 17799 match(Set dst (URShiftVL src shift)); 17800 ins_cost(INSN_COST); 17801 effect(TEMP tmp); 17802 format %{ "negr $tmp,$shift\t" 17803 "ushl $dst,$src,$tmp\t# vector (2D)" %} 17804 ins_encode %{ 17805 __ negr(as_FloatRegister($tmp$$reg), __ T16B, 17806 as_FloatRegister($shift$$reg)); 17807 __ ushl(as_FloatRegister($dst$$reg), __ T2D, 17808 as_FloatRegister($src$$reg), 17809 as_FloatRegister($tmp$$reg)); 17810 %} 17811 ins_pipe(vshift128); 17812%} 17813 17814instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ 17815 predicate(n->as_Vector()->length() == 2); 17816 match(Set dst (LShiftVL src shift)); 17817 ins_cost(INSN_COST); 17818 format %{ "shl $dst, $src, $shift\t# vector (2D)" %} 17819 ins_encode %{ 17820 __ shl(as_FloatRegister($dst$$reg), __ T2D, 17821 as_FloatRegister($src$$reg), 17822 (int)$shift$$constant); 17823 %} 17824 ins_pipe(vshift128_imm); 17825%} 17826 17827instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ 17828 predicate(n->as_Vector()->length() == 2); 17829 match(Set dst (RShiftVL src shift)); 17830 ins_cost(INSN_COST); 17831 format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} 17832 ins_encode %{ 17833 __ sshr(as_FloatRegister($dst$$reg), __ T2D, 17834 as_FloatRegister($src$$reg), 17835 (int)$shift$$constant); 17836 %} 17837 ins_pipe(vshift128_imm); 17838%} 17839 17840instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ 17841 predicate(n->as_Vector()->length() == 2); 17842 match(Set dst (URShiftVL src shift)); 17843 ins_cost(INSN_COST); 17844 format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} 17845 ins_encode %{ 17846 __ ushr(as_FloatRegister($dst$$reg), __ T2D, 17847 as_FloatRegister($src$$reg), 17848 (int)$shift$$constant); 17849 %} 17850 ins_pipe(vshift128_imm); 17851%} 17852 17853instruct vmax2F(vecD dst, vecD src1, vecD src2) 17854%{ 17855 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17856 match(Set dst (MaxV src1 src2)); 17857 ins_cost(INSN_COST); 17858 format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} 17859 ins_encode %{ 17860 __ fmax(as_FloatRegister($dst$$reg), __ T2S, 17861 as_FloatRegister($src1$$reg), 17862 as_FloatRegister($src2$$reg)); 17863 %} 17864 ins_pipe(vdop_fp64); 17865%} 17866 17867instruct vmax4F(vecX dst, vecX src1, vecX src2) 17868%{ 17869 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17870 match(Set dst (MaxV src1 src2)); 17871 ins_cost(INSN_COST); 17872 format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} 17873 ins_encode %{ 17874 __ fmax(as_FloatRegister($dst$$reg), __ T4S, 17875 as_FloatRegister($src1$$reg), 17876 as_FloatRegister($src2$$reg)); 17877 %} 17878 ins_pipe(vdop_fp128); 17879%} 17880 17881instruct vmax2D(vecX dst, vecX src1, vecX src2) 17882%{ 17883 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17884 match(Set dst (MaxV src1 src2)); 17885 ins_cost(INSN_COST); 17886 format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} 17887 ins_encode %{ 17888 __ fmax(as_FloatRegister($dst$$reg), __ T2D, 17889 as_FloatRegister($src1$$reg), 17890 as_FloatRegister($src2$$reg)); 17891 %} 17892 ins_pipe(vdop_fp128); 17893%} 17894 17895instruct vmin2F(vecD dst, vecD src1, vecD src2) 17896%{ 17897 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17898 match(Set dst (MinV src1 src2)); 17899 ins_cost(INSN_COST); 17900 format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} 17901 ins_encode %{ 17902 __ fmin(as_FloatRegister($dst$$reg), __ T2S, 17903 as_FloatRegister($src1$$reg), 17904 as_FloatRegister($src2$$reg)); 17905 %} 17906 ins_pipe(vdop_fp64); 17907%} 17908 17909instruct vmin4F(vecX dst, vecX src1, vecX src2) 17910%{ 17911 predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); 17912 match(Set dst (MinV src1 src2)); 17913 ins_cost(INSN_COST); 17914 format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} 17915 ins_encode %{ 17916 __ fmin(as_FloatRegister($dst$$reg), __ T4S, 17917 as_FloatRegister($src1$$reg), 17918 as_FloatRegister($src2$$reg)); 17919 %} 17920 ins_pipe(vdop_fp128); 17921%} 17922 17923instruct vmin2D(vecX dst, vecX src1, vecX src2) 17924%{ 17925 predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); 17926 match(Set dst (MinV src1 src2)); 17927 ins_cost(INSN_COST); 17928 format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} 17929 ins_encode %{ 17930 __ fmin(as_FloatRegister($dst$$reg), __ T2D, 17931 as_FloatRegister($src1$$reg), 17932 as_FloatRegister($src2$$reg)); 17933 %} 17934 ins_pipe(vdop_fp128); 17935%} 17936 17937instruct vpopcount4I(vecX dst, vecX src) %{ 17938 predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); 17939 match(Set dst (PopCountVI src)); 17940 format %{ 17941 "cnt $dst, $src\t# vector (16B)\n\t" 17942 "uaddlp $dst, $dst\t# vector (16B)\n\t" 17943 "uaddlp $dst, $dst\t# vector (8H)" 17944 %} 17945 ins_encode %{ 17946 __ cnt(as_FloatRegister($dst$$reg), __ T16B, 17947 as_FloatRegister($src$$reg)); 17948 __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, 17949 as_FloatRegister($dst$$reg)); 17950 __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, 17951 as_FloatRegister($dst$$reg)); 17952 %} 17953 ins_pipe(pipe_class_default); 17954%} 17955 17956instruct vpopcount2I(vecD dst, vecD src) %{ 17957 predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); 17958 match(Set dst (PopCountVI src)); 17959 format %{ 17960 "cnt $dst, $src\t# vector (8B)\n\t" 17961 "uaddlp $dst, $dst\t# vector (8B)\n\t" 17962 "uaddlp $dst, $dst\t# vector (4H)" 17963 %} 17964 ins_encode %{ 17965 __ cnt(as_FloatRegister($dst$$reg), __ T8B, 17966 as_FloatRegister($src$$reg)); 17967 __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, 17968 as_FloatRegister($dst$$reg)); 17969 __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, 17970 as_FloatRegister($dst$$reg)); 17971 %} 17972 ins_pipe(pipe_class_default); 17973%} 17974 17975//----------PEEPHOLE RULES----------------------------------------------------- 17976// These must follow all instruction definitions as they use the names 17977// defined in the instructions definitions. 17978// 17979// peepmatch ( root_instr_name [preceding_instruction]* ); 17980// 17981// peepconstraint %{ 17982// (instruction_number.operand_name relational_op instruction_number.operand_name 17983// [, ...] ); 17984// // instruction numbers are zero-based using left to right order in peepmatch 17985// 17986// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17987// // provide an instruction_number.operand_name for each operand that appears 17988// // in the replacement instruction's match rule 17989// 17990// ---------VM FLAGS--------------------------------------------------------- 17991// 17992// All peephole optimizations can be turned off using -XX:-OptoPeephole 17993// 17994// Each peephole rule is given an identifying number starting with zero and 17995// increasing by one in the order seen by the parser. An individual peephole 17996// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17997// on the command-line. 17998// 17999// ---------CURRENT LIMITATIONS---------------------------------------------- 18000// 18001// Only match adjacent instructions in same basic block 18002// Only equality constraints 18003// Only constraints between operands, not (0.dest_reg == RAX_enc) 18004// Only one replacement instruction 18005// 18006// ---------EXAMPLE---------------------------------------------------------- 18007// 18008// // pertinent parts of existing instructions in architecture description 18009// instruct movI(iRegINoSp dst, iRegI src) 18010// %{ 18011// match(Set dst (CopyI src)); 18012// %} 18013// 18014// instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 18015// %{ 18016// match(Set dst (AddI dst src)); 18017// effect(KILL cr); 18018// %} 18019// 18020// // Change (inc mov) to lea 18021// peephole %{ 18022// // increment preceeded by register-register move 18023// peepmatch ( incI_iReg movI ); 18024// // require that the destination register of the increment 18025// // match the destination register of the move 18026// peepconstraint ( 0.dst == 1.dst ); 18027// // construct a replacement instruction that sets 18028// // the destination to ( move's source register + one ) 18029// peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 18030// %} 18031// 18032 18033// Implementation no longer uses movX instructions since 18034// machine-independent system no longer uses CopyX nodes. 18035// 18036// peephole 18037// %{ 18038// peepmatch (incI_iReg movI); 18039// peepconstraint (0.dst == 1.dst); 18040// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18041// %} 18042 18043// peephole 18044// %{ 18045// peepmatch (decI_iReg movI); 18046// peepconstraint (0.dst == 1.dst); 18047// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18048// %} 18049 18050// peephole 18051// %{ 18052// peepmatch (addI_iReg_imm movI); 18053// peepconstraint (0.dst == 1.dst); 18054// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 18055// %} 18056 18057// peephole 18058// %{ 18059// peepmatch (incL_iReg movL); 18060// peepconstraint (0.dst == 1.dst); 18061// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18062// %} 18063 18064// peephole 18065// %{ 18066// peepmatch (decL_iReg movL); 18067// peepconstraint (0.dst == 1.dst); 18068// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18069// %} 18070 18071// peephole 18072// %{ 18073// peepmatch (addL_iReg_imm movL); 18074// peepconstraint (0.dst == 1.dst); 18075// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 18076// %} 18077 18078// peephole 18079// %{ 18080// peepmatch (addP_iReg_imm movP); 18081// peepconstraint (0.dst == 1.dst); 18082// peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 18083// %} 18084 18085// // Change load of spilled value to only a spill 18086// instruct storeI(memory mem, iRegI src) 18087// %{ 18088// match(Set mem (StoreI mem src)); 18089// %} 18090// 18091// instruct loadI(iRegINoSp dst, memory mem) 18092// %{ 18093// match(Set dst (LoadI mem)); 18094// %} 18095// 18096 18097//----------SMARTSPILL RULES--------------------------------------------------- 18098// These must follow all instruction definitions as they use the names 18099// defined in the instructions definitions. 18100 18101// Local Variables: 18102// mode: c++ 18103// End: 18104