1// 2// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. 3// Copyright (c) 2014, 2021, 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 non-allocatable (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 R8 ( NS, SOC, Op_RegI, 8, r8->as_VMReg() ); // rscratch1, non-allocatable 98reg_def R8_H ( NS, SOC, Op_RegI, 8, r8->as_VMReg()->next() ); 99reg_def R9 ( NS, SOC, Op_RegI, 9, r9->as_VMReg() ); // rscratch2, non-allocatable 100reg_def R9_H ( NS, SOC, Op_RegI, 9, r9->as_VMReg()->next() ); 101reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 102reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 103reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 104reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 105reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 106reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 107reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 108reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 109reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 110reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 111reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 112reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 113reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 114reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 115reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 116reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 117reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() ); 118reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next()); 119reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 120reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 121reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 122reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 123reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 124reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 125reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 126reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 127reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 128reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 129reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 130reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 131reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 132reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 133reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 134reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 135reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 136reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 137reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 138reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 139reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 140reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 141reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 142reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 143reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 144reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 145 146// ---------------------------- 147// Float/Double/Vector Registers 148// ---------------------------- 149 150// Double Registers 151 152// The rules of ADL require that double registers be defined in pairs. 153// Each pair must be two 32-bit values, but not necessarily a pair of 154// single float registers. In each pair, ADLC-assigned register numbers 155// must be adjacent, with the lower number even. Finally, when the 156// CPU stores such a register pair to memory, the word associated with 157// the lower ADLC-assigned number must be stored to the lower address. 158 159// AArch64 has 32 floating-point registers. Each can store a vector of 160// single or double precision floating-point values up to 8 * 32 161// floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 162// use the first float or double element of the vector. 163 164// for Java use float registers v0-v15 are always save on call whereas 165// the platform ABI treats v8-v15 as callee save). float registers 166// v16-v31 are SOC as per the platform spec 167 168// For SVE vector registers, we simply extend vector register size to 8 169// 'logical' slots. This is nominally 256 bits but it actually covers 170// all possible 'physical' SVE vector register lengths from 128 ~ 2048 171// bits. The 'physical' SVE vector register length is detected during 172// startup, so the register allocator is able to identify the correct 173// number of bytes needed for an SVE spill/unspill. 174// Note that a vector register with 4 slots denotes a 128-bit NEON 175// register allowing it to be distinguished from the corresponding SVE 176// vector register when the SVE vector length is 128 bits. 177 178 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 179 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 180 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 181 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 182 reg_def V0_L ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(4) ); 183 reg_def V0_M ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(5) ); 184 reg_def V0_N ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(6) ); 185 reg_def V0_O ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(7) ); 186 187 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 188 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 189 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 190 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 191 reg_def V1_L ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(4) ); 192 reg_def V1_M ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(5) ); 193 reg_def V1_N ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(6) ); 194 reg_def V1_O ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(7) ); 195 196 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 197 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 198 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 199 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 200 reg_def V2_L ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(4) ); 201 reg_def V2_M ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(5) ); 202 reg_def V2_N ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(6) ); 203 reg_def V2_O ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(7) ); 204 205 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 206 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 207 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 208 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 209 reg_def V3_L ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(4) ); 210 reg_def V3_M ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(5) ); 211 reg_def V3_N ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(6) ); 212 reg_def V3_O ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(7) ); 213 214 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 215 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 216 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 217 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 218 reg_def V4_L ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(4) ); 219 reg_def V4_M ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(5) ); 220 reg_def V4_N ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(6) ); 221 reg_def V4_O ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(7) ); 222 223 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 224 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 225 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 226 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 227 reg_def V5_L ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(4) ); 228 reg_def V5_M ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(5) ); 229 reg_def V5_N ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(6) ); 230 reg_def V5_O ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(7) ); 231 232 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 233 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 234 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 235 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 236 reg_def V6_L ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(4) ); 237 reg_def V6_M ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(5) ); 238 reg_def V6_N ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(6) ); 239 reg_def V6_O ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(7) ); 240 241 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 242 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 243 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 244 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 245 reg_def V7_L ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(4) ); 246 reg_def V7_M ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(5) ); 247 reg_def V7_N ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(6) ); 248 reg_def V7_O ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(7) ); 249 250 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() ); 251 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() ); 252 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 253 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 254 reg_def V8_L ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(4) ); 255 reg_def V8_M ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(5) ); 256 reg_def V8_N ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(6) ); 257 reg_def V8_O ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(7) ); 258 259 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() ); 260 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() ); 261 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 262 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 263 reg_def V9_L ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(4) ); 264 reg_def V9_M ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(5) ); 265 reg_def V9_N ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(6) ); 266 reg_def V9_O ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(7) ); 267 268 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() ); 269 reg_def V10_H ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next() ); 270 reg_def V10_J ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2) ); 271 reg_def V10_K ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3) ); 272 reg_def V10_L ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(4) ); 273 reg_def V10_M ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(5) ); 274 reg_def V10_N ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(6) ); 275 reg_def V10_O ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(7) ); 276 277 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() ); 278 reg_def V11_H ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next() ); 279 reg_def V11_J ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2) ); 280 reg_def V11_K ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3) ); 281 reg_def V11_L ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(4) ); 282 reg_def V11_M ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(5) ); 283 reg_def V11_N ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(6) ); 284 reg_def V11_O ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(7) ); 285 286 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() ); 287 reg_def V12_H ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next() ); 288 reg_def V12_J ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2) ); 289 reg_def V12_K ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3) ); 290 reg_def V12_L ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(4) ); 291 reg_def V12_M ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(5) ); 292 reg_def V12_N ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(6) ); 293 reg_def V12_O ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(7) ); 294 295 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() ); 296 reg_def V13_H ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next() ); 297 reg_def V13_J ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2) ); 298 reg_def V13_K ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3) ); 299 reg_def V13_L ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(4) ); 300 reg_def V13_M ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(5) ); 301 reg_def V13_N ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(6) ); 302 reg_def V13_O ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(7) ); 303 304 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() ); 305 reg_def V14_H ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next() ); 306 reg_def V14_J ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2) ); 307 reg_def V14_K ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3) ); 308 reg_def V14_L ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(4) ); 309 reg_def V14_M ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(5) ); 310 reg_def V14_N ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(6) ); 311 reg_def V14_O ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(7) ); 312 313 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() ); 314 reg_def V15_H ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next() ); 315 reg_def V15_J ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2) ); 316 reg_def V15_K ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3) ); 317 reg_def V15_L ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(4) ); 318 reg_def V15_M ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(5) ); 319 reg_def V15_N ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(6) ); 320 reg_def V15_O ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(7) ); 321 322 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 323 reg_def V16_H ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 324 reg_def V16_J ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2) ); 325 reg_def V16_K ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3) ); 326 reg_def V16_L ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(4) ); 327 reg_def V16_M ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(5) ); 328 reg_def V16_N ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(6) ); 329 reg_def V16_O ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(7) ); 330 331 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 332 reg_def V17_H ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 333 reg_def V17_J ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2) ); 334 reg_def V17_K ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3) ); 335 reg_def V17_L ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(4) ); 336 reg_def V17_M ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(5) ); 337 reg_def V17_N ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(6) ); 338 reg_def V17_O ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(7) ); 339 340 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 341 reg_def V18_H ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 342 reg_def V18_J ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2) ); 343 reg_def V18_K ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3) ); 344 reg_def V18_L ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(4) ); 345 reg_def V18_M ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(5) ); 346 reg_def V18_N ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(6) ); 347 reg_def V18_O ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(7) ); 348 349 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 350 reg_def V19_H ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 351 reg_def V19_J ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2) ); 352 reg_def V19_K ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3) ); 353 reg_def V19_L ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(4) ); 354 reg_def V19_M ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(5) ); 355 reg_def V19_N ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(6) ); 356 reg_def V19_O ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(7) ); 357 358 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 359 reg_def V20_H ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 360 reg_def V20_J ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2) ); 361 reg_def V20_K ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3) ); 362 reg_def V20_L ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(4) ); 363 reg_def V20_M ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(5) ); 364 reg_def V20_N ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(6) ); 365 reg_def V20_O ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(7) ); 366 367 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 368 reg_def V21_H ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 369 reg_def V21_J ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2) ); 370 reg_def V21_K ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3) ); 371 reg_def V21_L ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(4) ); 372 reg_def V21_M ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(5) ); 373 reg_def V21_N ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(6) ); 374 reg_def V21_O ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(7) ); 375 376 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 377 reg_def V22_H ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 378 reg_def V22_J ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2) ); 379 reg_def V22_K ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3) ); 380 reg_def V22_L ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(4) ); 381 reg_def V22_M ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(5) ); 382 reg_def V22_N ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(6) ); 383 reg_def V22_O ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(7) ); 384 385 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 386 reg_def V23_H ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 387 reg_def V23_J ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2) ); 388 reg_def V23_K ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3) ); 389 reg_def V23_L ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(4) ); 390 reg_def V23_M ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(5) ); 391 reg_def V23_N ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(6) ); 392 reg_def V23_O ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(7) ); 393 394 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 395 reg_def V24_H ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 396 reg_def V24_J ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2) ); 397 reg_def V24_K ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3) ); 398 reg_def V24_L ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(4) ); 399 reg_def V24_M ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(5) ); 400 reg_def V24_N ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(6) ); 401 reg_def V24_O ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(7) ); 402 403 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 404 reg_def V25_H ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 405 reg_def V25_J ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2) ); 406 reg_def V25_K ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3) ); 407 reg_def V25_L ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(4) ); 408 reg_def V25_M ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(5) ); 409 reg_def V25_N ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(6) ); 410 reg_def V25_O ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(7) ); 411 412 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 413 reg_def V26_H ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 414 reg_def V26_J ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2) ); 415 reg_def V26_K ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3) ); 416 reg_def V26_L ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(4) ); 417 reg_def V26_M ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(5) ); 418 reg_def V26_N ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(6) ); 419 reg_def V26_O ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(7) ); 420 421 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 422 reg_def V27_H ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 423 reg_def V27_J ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2) ); 424 reg_def V27_K ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3) ); 425 reg_def V27_L ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(4) ); 426 reg_def V27_M ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(5) ); 427 reg_def V27_N ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(6) ); 428 reg_def V27_O ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(7) ); 429 430 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 431 reg_def V28_H ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 432 reg_def V28_J ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2) ); 433 reg_def V28_K ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3) ); 434 reg_def V28_L ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(4) ); 435 reg_def V28_M ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(5) ); 436 reg_def V28_N ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(6) ); 437 reg_def V28_O ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(7) ); 438 439 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 440 reg_def V29_H ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 441 reg_def V29_J ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2) ); 442 reg_def V29_K ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3) ); 443 reg_def V29_L ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(4) ); 444 reg_def V29_M ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(5) ); 445 reg_def V29_N ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(6) ); 446 reg_def V29_O ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(7) ); 447 448 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 449 reg_def V30_H ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 450 reg_def V30_J ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2) ); 451 reg_def V30_K ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3) ); 452 reg_def V30_L ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(4) ); 453 reg_def V30_M ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(5) ); 454 reg_def V30_N ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(6) ); 455 reg_def V30_O ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(7) ); 456 457 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 458 reg_def V31_H ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 459 reg_def V31_J ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2) ); 460 reg_def V31_K ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3) ); 461 reg_def V31_L ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(4) ); 462 reg_def V31_M ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(5) ); 463 reg_def V31_N ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(6) ); 464 reg_def V31_O ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(7) ); 465 466 467// ---------------------------- 468// SVE Predicate Registers 469// ---------------------------- 470 reg_def P0 (SOC, SOC, Op_RegVectMask, 0, p0->as_VMReg()); 471 reg_def P1 (SOC, SOC, Op_RegVectMask, 1, p1->as_VMReg()); 472 reg_def P2 (SOC, SOC, Op_RegVectMask, 2, p2->as_VMReg()); 473 reg_def P3 (SOC, SOC, Op_RegVectMask, 3, p3->as_VMReg()); 474 reg_def P4 (SOC, SOC, Op_RegVectMask, 4, p4->as_VMReg()); 475 reg_def P5 (SOC, SOC, Op_RegVectMask, 5, p5->as_VMReg()); 476 reg_def P6 (SOC, SOC, Op_RegVectMask, 6, p6->as_VMReg()); 477 reg_def P7 (SOC, SOC, Op_RegVectMask, 7, p7->as_VMReg()); 478 reg_def P8 (SOC, SOC, Op_RegVectMask, 8, p8->as_VMReg()); 479 reg_def P9 (SOC, SOC, Op_RegVectMask, 9, p9->as_VMReg()); 480 reg_def P10 (SOC, SOC, Op_RegVectMask, 10, p10->as_VMReg()); 481 reg_def P11 (SOC, SOC, Op_RegVectMask, 11, p11->as_VMReg()); 482 reg_def P12 (SOC, SOC, Op_RegVectMask, 12, p12->as_VMReg()); 483 reg_def P13 (SOC, SOC, Op_RegVectMask, 13, p13->as_VMReg()); 484 reg_def P14 (SOC, SOC, Op_RegVectMask, 14, p14->as_VMReg()); 485 reg_def P15 (SOC, SOC, Op_RegVectMask, 15, p15->as_VMReg()); 486 487// ---------------------------- 488// Special Registers 489// ---------------------------- 490 491// the AArch64 CSPR status flag register is not directly acessible as 492// instruction operand. the FPSR status flag register is a system 493// register which can be written/read using MSR/MRS but again does not 494// appear as an operand (a code identifying the FSPR occurs as an 495// immediate value in the instruction). 496 497reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 498 499// Specify priority of register selection within phases of register 500// allocation. Highest priority is first. A useful heuristic is to 501// give registers a low priority when they are required by machine 502// instructions, like EAX and EDX on I486, and choose no-save registers 503// before save-on-call, & save-on-call before save-on-entry. Registers 504// which participate in fixed calling sequences should come last. 505// Registers which are used as pairs must fall on an even boundary. 506 507alloc_class chunk0( 508 // volatiles 509 R10, R10_H, 510 R11, R11_H, 511 R12, R12_H, 512 R13, R13_H, 513 R14, R14_H, 514 R15, R15_H, 515 R16, R16_H, 516 R17, R17_H, 517 R18, R18_H, 518 519 // arg registers 520 R0, R0_H, 521 R1, R1_H, 522 R2, R2_H, 523 R3, R3_H, 524 R4, R4_H, 525 R5, R5_H, 526 R6, R6_H, 527 R7, R7_H, 528 529 // non-volatiles 530 R19, R19_H, 531 R20, R20_H, 532 R21, R21_H, 533 R22, R22_H, 534 R23, R23_H, 535 R24, R24_H, 536 R25, R25_H, 537 R26, R26_H, 538 539 // non-allocatable registers 540 541 R27, R27_H, // heapbase 542 R28, R28_H, // thread 543 R29, R29_H, // fp 544 R30, R30_H, // lr 545 R31, R31_H, // sp 546 R8, R8_H, // rscratch1 547 R9, R9_H, // rscratch2 548); 549 550alloc_class chunk1( 551 552 // no save 553 V16, V16_H, V16_J, V16_K, V16_L, V16_M, V16_N, V16_O, 554 V17, V17_H, V17_J, V17_K, V17_L, V17_M, V17_N, V17_O, 555 V18, V18_H, V18_J, V18_K, V18_L, V18_M, V18_N, V18_O, 556 V19, V19_H, V19_J, V19_K, V19_L, V19_M, V19_N, V19_O, 557 V20, V20_H, V20_J, V20_K, V20_L, V20_M, V20_N, V20_O, 558 V21, V21_H, V21_J, V21_K, V21_L, V21_M, V21_N, V21_O, 559 V22, V22_H, V22_J, V22_K, V22_L, V22_M, V22_N, V22_O, 560 V23, V23_H, V23_J, V23_K, V23_L, V23_M, V23_N, V23_O, 561 V24, V24_H, V24_J, V24_K, V24_L, V24_M, V24_N, V24_O, 562 V25, V25_H, V25_J, V25_K, V25_L, V25_M, V25_N, V25_O, 563 V26, V26_H, V26_J, V26_K, V26_L, V26_M, V26_N, V26_O, 564 V27, V27_H, V27_J, V27_K, V27_L, V27_M, V27_N, V27_O, 565 V28, V28_H, V28_J, V28_K, V28_L, V28_M, V28_N, V28_O, 566 V29, V29_H, V29_J, V29_K, V29_L, V29_M, V29_N, V29_O, 567 V30, V30_H, V30_J, V30_K, V30_L, V30_M, V30_N, V30_O, 568 V31, V31_H, V31_J, V31_K, V31_L, V31_M, V31_N, V31_O, 569 570 // arg registers 571 V0, V0_H, V0_J, V0_K, V0_L, V0_M, V0_N, V0_O, 572 V1, V1_H, V1_J, V1_K, V1_L, V1_M, V1_N, V1_O, 573 V2, V2_H, V2_J, V2_K, V2_L, V2_M, V2_N, V2_O, 574 V3, V3_H, V3_J, V3_K, V3_L, V3_M, V3_N, V3_O, 575 V4, V4_H, V4_J, V4_K, V4_L, V4_M, V4_N, V4_O, 576 V5, V5_H, V5_J, V5_K, V5_L, V5_M, V5_N, V5_O, 577 V6, V6_H, V6_J, V6_K, V6_L, V6_M, V6_N, V6_O, 578 V7, V7_H, V7_J, V7_K, V7_L, V7_M, V7_N, V7_O, 579 580 // non-volatiles 581 V8, V8_H, V8_J, V8_K, V8_L, V8_M, V8_N, V8_O, 582 V9, V9_H, V9_J, V9_K, V9_L, V9_M, V9_N, V9_O, 583 V10, V10_H, V10_J, V10_K, V10_L, V10_M, V10_N, V10_O, 584 V11, V11_H, V11_J, V11_K, V11_L, V11_M, V11_N, V11_O, 585 V12, V12_H, V12_J, V12_K, V12_L, V12_M, V12_N, V12_O, 586 V13, V13_H, V13_J, V13_K, V13_L, V13_M, V13_N, V13_O, 587 V14, V14_H, V14_J, V14_K, V14_L, V14_M, V14_N, V14_O, 588 V15, V15_H, V15_J, V15_K, V15_L, V15_M, V15_N, V15_O, 589); 590 591alloc_class chunk2 ( 592 P0, 593 P1, 594 P2, 595 P3, 596 P4, 597 P5, 598 P6, 599 P7, 600 601 P8, 602 P9, 603 P10, 604 P11, 605 P12, 606 P13, 607 P14, 608 P15, 609); 610 611alloc_class chunk3(RFLAGS); 612 613//----------Architecture Description Register Classes-------------------------- 614// Several register classes are automatically defined based upon information in 615// this architecture description. 616// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 617// 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 618// 619 620// Class for all 32 bit general purpose registers 621reg_class all_reg32( 622 R0, 623 R1, 624 R2, 625 R3, 626 R4, 627 R5, 628 R6, 629 R7, 630 R10, 631 R11, 632 R12, 633 R13, 634 R14, 635 R15, 636 R16, 637 R17, 638 R18, 639 R19, 640 R20, 641 R21, 642 R22, 643 R23, 644 R24, 645 R25, 646 R26, 647 R27, 648 R28, 649 R29, 650 R30, 651 R31 652); 653 654 655// Class for all 32 bit integer registers (excluding SP which 656// will never be used as an integer register) 657reg_class any_reg32 %{ 658 return _ANY_REG32_mask; 659%} 660 661// Singleton class for R0 int register 662reg_class int_r0_reg(R0); 663 664// Singleton class for R2 int register 665reg_class int_r2_reg(R2); 666 667// Singleton class for R3 int register 668reg_class int_r3_reg(R3); 669 670// Singleton class for R4 int register 671reg_class int_r4_reg(R4); 672 673// Singleton class for R31 int register 674reg_class int_r31_reg(R31); 675 676// Class for all 64 bit general purpose registers 677reg_class all_reg( 678 R0, R0_H, 679 R1, R1_H, 680 R2, R2_H, 681 R3, R3_H, 682 R4, R4_H, 683 R5, R5_H, 684 R6, R6_H, 685 R7, R7_H, 686 R10, R10_H, 687 R11, R11_H, 688 R12, R12_H, 689 R13, R13_H, 690 R14, R14_H, 691 R15, R15_H, 692 R16, R16_H, 693 R17, R17_H, 694 R18, R18_H, 695 R19, R19_H, 696 R20, R20_H, 697 R21, R21_H, 698 R22, R22_H, 699 R23, R23_H, 700 R24, R24_H, 701 R25, R25_H, 702 R26, R26_H, 703 R27, R27_H, 704 R28, R28_H, 705 R29, R29_H, 706 R30, R30_H, 707 R31, R31_H 708); 709 710// Class for all long integer registers (including SP) 711reg_class any_reg %{ 712 return _ANY_REG_mask; 713%} 714 715// Class for non-allocatable 32 bit registers 716reg_class non_allocatable_reg32( 717#ifdef R18_RESERVED 718 // See comment in register_aarch64.hpp 719 R18, // tls on Windows 720#endif 721 R28, // thread 722 R30, // lr 723 R31 // sp 724); 725 726// Class for non-allocatable 64 bit registers 727reg_class non_allocatable_reg( 728#ifdef R18_RESERVED 729 // See comment in register_aarch64.hpp 730 R18, R18_H, // tls on Windows, platform register on macOS 731#endif 732 R28, R28_H, // thread 733 R30, R30_H, // lr 734 R31, R31_H // sp 735); 736 737// Class for all non-special integer registers 738reg_class no_special_reg32 %{ 739 return _NO_SPECIAL_REG32_mask; 740%} 741 742// Class for all non-special long integer registers 743reg_class no_special_reg %{ 744 return _NO_SPECIAL_REG_mask; 745%} 746 747// Class for 64 bit register r0 748reg_class r0_reg( 749 R0, R0_H 750); 751 752// Class for 64 bit register r1 753reg_class r1_reg( 754 R1, R1_H 755); 756 757// Class for 64 bit register r2 758reg_class r2_reg( 759 R2, R2_H 760); 761 762// Class for 64 bit register r3 763reg_class r3_reg( 764 R3, R3_H 765); 766 767// Class for 64 bit register r4 768reg_class r4_reg( 769 R4, R4_H 770); 771 772// Class for 64 bit register r5 773reg_class r5_reg( 774 R5, R5_H 775); 776 777// Class for 64 bit register r10 778reg_class r10_reg( 779 R10, R10_H 780); 781 782// Class for 64 bit register r11 783reg_class r11_reg( 784 R11, R11_H 785); 786 787// Class for method register 788reg_class method_reg( 789 R12, R12_H 790); 791 792// Class for heapbase register 793reg_class heapbase_reg( 794 R27, R27_H 795); 796 797// Class for thread register 798reg_class thread_reg( 799 R28, R28_H 800); 801 802// Class for frame pointer register 803reg_class fp_reg( 804 R29, R29_H 805); 806 807// Class for link register 808reg_class lr_reg( 809 R30, R30_H 810); 811 812// Class for long sp register 813reg_class sp_reg( 814 R31, R31_H 815); 816 817// Class for all pointer registers 818reg_class ptr_reg %{ 819 return _PTR_REG_mask; 820%} 821 822// Class for all non_special pointer registers 823reg_class no_special_ptr_reg %{ 824 return _NO_SPECIAL_PTR_REG_mask; 825%} 826 827// Class for all float registers 828reg_class float_reg( 829 V0, 830 V1, 831 V2, 832 V3, 833 V4, 834 V5, 835 V6, 836 V7, 837 V8, 838 V9, 839 V10, 840 V11, 841 V12, 842 V13, 843 V14, 844 V15, 845 V16, 846 V17, 847 V18, 848 V19, 849 V20, 850 V21, 851 V22, 852 V23, 853 V24, 854 V25, 855 V26, 856 V27, 857 V28, 858 V29, 859 V30, 860 V31 861); 862 863// Double precision float registers have virtual `high halves' that 864// are needed by the allocator. 865// Class for all double registers 866reg_class double_reg( 867 V0, V0_H, 868 V1, V1_H, 869 V2, V2_H, 870 V3, V3_H, 871 V4, V4_H, 872 V5, V5_H, 873 V6, V6_H, 874 V7, V7_H, 875 V8, V8_H, 876 V9, V9_H, 877 V10, V10_H, 878 V11, V11_H, 879 V12, V12_H, 880 V13, V13_H, 881 V14, V14_H, 882 V15, V15_H, 883 V16, V16_H, 884 V17, V17_H, 885 V18, V18_H, 886 V19, V19_H, 887 V20, V20_H, 888 V21, V21_H, 889 V22, V22_H, 890 V23, V23_H, 891 V24, V24_H, 892 V25, V25_H, 893 V26, V26_H, 894 V27, V27_H, 895 V28, V28_H, 896 V29, V29_H, 897 V30, V30_H, 898 V31, V31_H 899); 900 901// Class for all SVE vector registers. 902reg_class vectora_reg ( 903 V0, V0_H, V0_J, V0_K, V0_L, V0_M, V0_N, V0_O, 904 V1, V1_H, V1_J, V1_K, V1_L, V1_M, V1_N, V1_O, 905 V2, V2_H, V2_J, V2_K, V2_L, V2_M, V2_N, V2_O, 906 V3, V3_H, V3_J, V3_K, V3_L, V3_M, V3_N, V3_O, 907 V4, V4_H, V4_J, V4_K, V4_L, V4_M, V4_N, V4_O, 908 V5, V5_H, V5_J, V5_K, V5_L, V5_M, V5_N, V5_O, 909 V6, V6_H, V6_J, V6_K, V6_L, V6_M, V6_N, V6_O, 910 V7, V7_H, V7_J, V7_K, V7_L, V7_M, V7_N, V7_O, 911 V8, V8_H, V8_J, V8_K, V8_L, V8_M, V8_N, V8_O, 912 V9, V9_H, V9_J, V9_K, V9_L, V9_M, V9_N, V9_O, 913 V10, V10_H, V10_J, V10_K, V10_L, V10_M, V10_N, V10_O, 914 V11, V11_H, V11_J, V11_K, V11_L, V11_M, V11_N, V11_O, 915 V12, V12_H, V12_J, V12_K, V12_L, V12_M, V12_N, V12_O, 916 V13, V13_H, V13_J, V13_K, V13_L, V13_M, V13_N, V13_O, 917 V14, V14_H, V14_J, V14_K, V14_L, V14_M, V14_N, V14_O, 918 V15, V15_H, V15_J, V15_K, V15_L, V15_M, V15_N, V15_O, 919 V16, V16_H, V16_J, V16_K, V16_L, V16_M, V16_N, V16_O, 920 V17, V17_H, V17_J, V17_K, V17_L, V17_M, V17_N, V17_O, 921 V18, V18_H, V18_J, V18_K, V18_L, V18_M, V18_N, V18_O, 922 V19, V19_H, V19_J, V19_K, V19_L, V19_M, V19_N, V19_O, 923 V20, V20_H, V20_J, V20_K, V20_L, V20_M, V20_N, V20_O, 924 V21, V21_H, V21_J, V21_K, V21_L, V21_M, V21_N, V21_O, 925 V22, V22_H, V22_J, V22_K, V22_L, V22_M, V22_N, V22_O, 926 V23, V23_H, V23_J, V23_K, V23_L, V23_M, V23_N, V23_O, 927 V24, V24_H, V24_J, V24_K, V24_L, V24_M, V24_N, V24_O, 928 V25, V25_H, V25_J, V25_K, V25_L, V25_M, V25_N, V25_O, 929 V26, V26_H, V26_J, V26_K, V26_L, V26_M, V26_N, V26_O, 930 V27, V27_H, V27_J, V27_K, V27_L, V27_M, V27_N, V27_O, 931 V28, V28_H, V28_J, V28_K, V28_L, V28_M, V28_N, V28_O, 932 V29, V29_H, V29_J, V29_K, V29_L, V29_M, V29_N, V29_O, 933 V30, V30_H, V30_J, V30_K, V30_L, V30_M, V30_N, V30_O, 934 V31, V31_H, V31_J, V31_K, V31_L, V31_M, V31_N, V31_O, 935); 936 937// Class for all 64bit vector registers 938reg_class vectord_reg( 939 V0, V0_H, 940 V1, V1_H, 941 V2, V2_H, 942 V3, V3_H, 943 V4, V4_H, 944 V5, V5_H, 945 V6, V6_H, 946 V7, V7_H, 947 V8, V8_H, 948 V9, V9_H, 949 V10, V10_H, 950 V11, V11_H, 951 V12, V12_H, 952 V13, V13_H, 953 V14, V14_H, 954 V15, V15_H, 955 V16, V16_H, 956 V17, V17_H, 957 V18, V18_H, 958 V19, V19_H, 959 V20, V20_H, 960 V21, V21_H, 961 V22, V22_H, 962 V23, V23_H, 963 V24, V24_H, 964 V25, V25_H, 965 V26, V26_H, 966 V27, V27_H, 967 V28, V28_H, 968 V29, V29_H, 969 V30, V30_H, 970 V31, V31_H 971); 972 973// Class for all 128bit vector registers 974reg_class vectorx_reg( 975 V0, V0_H, V0_J, V0_K, 976 V1, V1_H, V1_J, V1_K, 977 V2, V2_H, V2_J, V2_K, 978 V3, V3_H, V3_J, V3_K, 979 V4, V4_H, V4_J, V4_K, 980 V5, V5_H, V5_J, V5_K, 981 V6, V6_H, V6_J, V6_K, 982 V7, V7_H, V7_J, V7_K, 983 V8, V8_H, V8_J, V8_K, 984 V9, V9_H, V9_J, V9_K, 985 V10, V10_H, V10_J, V10_K, 986 V11, V11_H, V11_J, V11_K, 987 V12, V12_H, V12_J, V12_K, 988 V13, V13_H, V13_J, V13_K, 989 V14, V14_H, V14_J, V14_K, 990 V15, V15_H, V15_J, V15_K, 991 V16, V16_H, V16_J, V16_K, 992 V17, V17_H, V17_J, V17_K, 993 V18, V18_H, V18_J, V18_K, 994 V19, V19_H, V19_J, V19_K, 995 V20, V20_H, V20_J, V20_K, 996 V21, V21_H, V21_J, V21_K, 997 V22, V22_H, V22_J, V22_K, 998 V23, V23_H, V23_J, V23_K, 999 V24, V24_H, V24_J, V24_K, 1000 V25, V25_H, V25_J, V25_K, 1001 V26, V26_H, V26_J, V26_K, 1002 V27, V27_H, V27_J, V27_K, 1003 V28, V28_H, V28_J, V28_K, 1004 V29, V29_H, V29_J, V29_K, 1005 V30, V30_H, V30_J, V30_K, 1006 V31, V31_H, V31_J, V31_K 1007); 1008 1009// Class for 128 bit register v0 1010reg_class v0_reg( 1011 V0, V0_H 1012); 1013 1014// Class for 128 bit register v1 1015reg_class v1_reg( 1016 V1, V1_H 1017); 1018 1019// Class for 128 bit register v2 1020reg_class v2_reg( 1021 V2, V2_H 1022); 1023 1024// Class for 128 bit register v3 1025reg_class v3_reg( 1026 V3, V3_H 1027); 1028 1029// Class for 128 bit register v4 1030reg_class v4_reg( 1031 V4, V4_H 1032); 1033 1034// Class for 128 bit register v5 1035reg_class v5_reg( 1036 V5, V5_H 1037); 1038 1039// Class for 128 bit register v6 1040reg_class v6_reg( 1041 V6, V6_H 1042); 1043 1044// Class for 128 bit register v7 1045reg_class v7_reg( 1046 V7, V7_H 1047); 1048 1049// Class for 128 bit register v8 1050reg_class v8_reg( 1051 V8, V8_H 1052); 1053 1054// Class for 128 bit register v9 1055reg_class v9_reg( 1056 V9, V9_H 1057); 1058 1059// Class for 128 bit register v10 1060reg_class v10_reg( 1061 V10, V10_H 1062); 1063 1064// Class for 128 bit register v11 1065reg_class v11_reg( 1066 V11, V11_H 1067); 1068 1069// Class for 128 bit register v12 1070reg_class v12_reg( 1071 V12, V12_H 1072); 1073 1074// Class for 128 bit register v13 1075reg_class v13_reg( 1076 V13, V13_H 1077); 1078 1079// Class for 128 bit register v14 1080reg_class v14_reg( 1081 V14, V14_H 1082); 1083 1084// Class for 128 bit register v15 1085reg_class v15_reg( 1086 V15, V15_H 1087); 1088 1089// Class for 128 bit register v16 1090reg_class v16_reg( 1091 V16, V16_H 1092); 1093 1094// Class for 128 bit register v17 1095reg_class v17_reg( 1096 V17, V17_H 1097); 1098 1099// Class for 128 bit register v18 1100reg_class v18_reg( 1101 V18, V18_H 1102); 1103 1104// Class for 128 bit register v19 1105reg_class v19_reg( 1106 V19, V19_H 1107); 1108 1109// Class for 128 bit register v20 1110reg_class v20_reg( 1111 V20, V20_H 1112); 1113 1114// Class for 128 bit register v21 1115reg_class v21_reg( 1116 V21, V21_H 1117); 1118 1119// Class for 128 bit register v22 1120reg_class v22_reg( 1121 V22, V22_H 1122); 1123 1124// Class for 128 bit register v23 1125reg_class v23_reg( 1126 V23, V23_H 1127); 1128 1129// Class for 128 bit register v24 1130reg_class v24_reg( 1131 V24, V24_H 1132); 1133 1134// Class for 128 bit register v25 1135reg_class v25_reg( 1136 V25, V25_H 1137); 1138 1139// Class for 128 bit register v26 1140reg_class v26_reg( 1141 V26, V26_H 1142); 1143 1144// Class for 128 bit register v27 1145reg_class v27_reg( 1146 V27, V27_H 1147); 1148 1149// Class for 128 bit register v28 1150reg_class v28_reg( 1151 V28, V28_H 1152); 1153 1154// Class for 128 bit register v29 1155reg_class v29_reg( 1156 V29, V29_H 1157); 1158 1159// Class for 128 bit register v30 1160reg_class v30_reg( 1161 V30, V30_H 1162); 1163 1164// Class for 128 bit register v31 1165reg_class v31_reg( 1166 V31, V31_H 1167); 1168 1169// Class for all SVE predicate registers. 1170reg_class pr_reg ( 1171 P0, 1172 P1, 1173 P2, 1174 P3, 1175 P4, 1176 P5, 1177 P6, 1178 // P7, non-allocatable, preserved with all elements preset to TRUE. 1179 P8, 1180 P9, 1181 P10, 1182 P11, 1183 P12, 1184 P13, 1185 P14, 1186 P15 1187); 1188 1189// Class for SVE governing predicate registers, which are used 1190// to determine the active elements of a predicated instruction. 1191reg_class gov_pr ( 1192 P0, 1193 P1, 1194 P2, 1195 P3, 1196 P4, 1197 P5, 1198 P6, 1199 // P7, non-allocatable, preserved with all elements preset to TRUE. 1200); 1201 1202// Singleton class for condition codes 1203reg_class int_flags(RFLAGS); 1204 1205%} 1206 1207//----------DEFINITION BLOCK--------------------------------------------------- 1208// Define name --> value mappings to inform the ADLC of an integer valued name 1209// Current support includes integer values in the range [0, 0x7FFFFFFF] 1210// Format: 1211// int_def <name> ( <int_value>, <expression>); 1212// Generated Code in ad_<arch>.hpp 1213// #define <name> (<expression>) 1214// // value == <int_value> 1215// Generated code in ad_<arch>.cpp adlc_verification() 1216// assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 1217// 1218 1219// we follow the ppc-aix port in using a simple cost model which ranks 1220// register operations as cheap, memory ops as more expensive and 1221// branches as most expensive. the first two have a low as well as a 1222// normal cost. huge cost appears to be a way of saying don't do 1223// something 1224 1225definitions %{ 1226 // The default cost (of a register move instruction). 1227 int_def INSN_COST ( 100, 100); 1228 int_def BRANCH_COST ( 200, 2 * INSN_COST); 1229 int_def CALL_COST ( 200, 2 * INSN_COST); 1230 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 1231%} 1232 1233 1234//----------SOURCE BLOCK------------------------------------------------------- 1235// This is a block of C++ code which provides values, functions, and 1236// definitions necessary in the rest of the architecture description 1237 1238source_hpp %{ 1239 1240#include "asm/macroAssembler.hpp" 1241#include "gc/shared/barrierSetAssembler.hpp" 1242#include "gc/shared/cardTable.hpp" 1243#include "gc/shared/cardTableBarrierSet.hpp" 1244#include "gc/shared/collectedHeap.hpp" 1245#include "opto/addnode.hpp" 1246#include "opto/convertnode.hpp" 1247#include "runtime/objectMonitor.hpp" 1248 1249extern RegMask _ANY_REG32_mask; 1250extern RegMask _ANY_REG_mask; 1251extern RegMask _PTR_REG_mask; 1252extern RegMask _NO_SPECIAL_REG32_mask; 1253extern RegMask _NO_SPECIAL_REG_mask; 1254extern RegMask _NO_SPECIAL_PTR_REG_mask; 1255 1256class CallStubImpl { 1257 1258 //-------------------------------------------------------------- 1259 //---< Used for optimization in Compile::shorten_branches >--- 1260 //-------------------------------------------------------------- 1261 1262 public: 1263 // Size of call trampoline stub. 1264 static uint size_call_trampoline() { 1265 return 0; // no call trampolines on this platform 1266 } 1267 1268 // number of relocations needed by a call trampoline stub 1269 static uint reloc_call_trampoline() { 1270 return 0; // no call trampolines on this platform 1271 } 1272}; 1273 1274class HandlerImpl { 1275 1276 public: 1277 1278 static int emit_exception_handler(CodeBuffer &cbuf); 1279 static int emit_deopt_handler(CodeBuffer& cbuf); 1280 1281 static uint size_exception_handler() { 1282 return MacroAssembler::far_branch_size(); 1283 } 1284 1285 static uint size_deopt_handler() { 1286 // count one adr and one far branch instruction 1287 return 4 * NativeInstruction::instruction_size; 1288 } 1289}; 1290 1291class Node::PD { 1292public: 1293 enum NodeFlags { 1294 _last_flag = Node::_last_flag 1295 }; 1296}; 1297 1298 bool is_CAS(int opcode, bool maybe_volatile); 1299 1300 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1301 1302 bool unnecessary_acquire(const Node *barrier); 1303 bool needs_acquiring_load(const Node *load); 1304 1305 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1306 1307 bool unnecessary_release(const Node *barrier); 1308 bool unnecessary_volatile(const Node *barrier); 1309 bool needs_releasing_store(const Node *store); 1310 1311 // predicate controlling translation of CompareAndSwapX 1312 bool needs_acquiring_load_exclusive(const Node *load); 1313 1314 // predicate controlling addressing modes 1315 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1316%} 1317 1318source %{ 1319 1320 // Derived RegMask with conditionally allocatable registers 1321 1322 void PhaseOutput::pd_perform_mach_node_analysis() { 1323 } 1324 1325 int MachNode::pd_alignment_required() const { 1326 return 1; 1327 } 1328 1329 int MachNode::compute_padding(int current_offset) const { 1330 return 0; 1331 } 1332 1333 RegMask _ANY_REG32_mask; 1334 RegMask _ANY_REG_mask; 1335 RegMask _PTR_REG_mask; 1336 RegMask _NO_SPECIAL_REG32_mask; 1337 RegMask _NO_SPECIAL_REG_mask; 1338 RegMask _NO_SPECIAL_PTR_REG_mask; 1339 1340 void reg_mask_init() { 1341 // We derive below RegMask(s) from the ones which are auto-generated from 1342 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1343 // registers conditionally reserved. 1344 1345 _ANY_REG32_mask = _ALL_REG32_mask; 1346 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1347 1348 _ANY_REG_mask = _ALL_REG_mask; 1349 1350 _PTR_REG_mask = _ALL_REG_mask; 1351 1352 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1353 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1354 1355 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1356 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1357 1358 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1359 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1360 1361 // r27 is not allocatable when compressed oops is on and heapbase is not 1362 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1363 if (UseCompressedOops && (CompressedOops::ptrs_base() != NULL)) { 1364 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1365 _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1366 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); 1367 } 1368 1369 // r29 is not allocatable when PreserveFramePointer is on 1370 if (PreserveFramePointer) { 1371 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1372 _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask); 1373 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask); 1374 } 1375 } 1376 1377 // Optimizaton of volatile gets and puts 1378 // ------------------------------------- 1379 // 1380 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1381 // use to implement volatile reads and writes. For a volatile read 1382 // we simply need 1383 // 1384 // ldar<x> 1385 // 1386 // and for a volatile write we need 1387 // 1388 // stlr<x> 1389 // 1390 // Alternatively, we can implement them by pairing a normal 1391 // load/store with a memory barrier. For a volatile read we need 1392 // 1393 // ldr<x> 1394 // dmb ishld 1395 // 1396 // for a volatile write 1397 // 1398 // dmb ish 1399 // str<x> 1400 // dmb ish 1401 // 1402 // We can also use ldaxr and stlxr to implement compare and swap CAS 1403 // sequences. These are normally translated to an instruction 1404 // sequence like the following 1405 // 1406 // dmb ish 1407 // retry: 1408 // ldxr<x> rval raddr 1409 // cmp rval rold 1410 // b.ne done 1411 // stlxr<x> rval, rnew, rold 1412 // cbnz rval retry 1413 // done: 1414 // cset r0, eq 1415 // dmb ishld 1416 // 1417 // Note that the exclusive store is already using an stlxr 1418 // instruction. That is required to ensure visibility to other 1419 // threads of the exclusive write (assuming it succeeds) before that 1420 // of any subsequent writes. 1421 // 1422 // The following instruction sequence is an improvement on the above 1423 // 1424 // retry: 1425 // ldaxr<x> rval raddr 1426 // cmp rval rold 1427 // b.ne done 1428 // stlxr<x> rval, rnew, rold 1429 // cbnz rval retry 1430 // done: 1431 // cset r0, eq 1432 // 1433 // We don't need the leading dmb ish since the stlxr guarantees 1434 // visibility of prior writes in the case that the swap is 1435 // successful. Crucially we don't have to worry about the case where 1436 // the swap is not successful since no valid program should be 1437 // relying on visibility of prior changes by the attempting thread 1438 // in the case where the CAS fails. 1439 // 1440 // Similarly, we don't need the trailing dmb ishld if we substitute 1441 // an ldaxr instruction since that will provide all the guarantees we 1442 // require regarding observation of changes made by other threads 1443 // before any change to the CAS address observed by the load. 1444 // 1445 // In order to generate the desired instruction sequence we need to 1446 // be able to identify specific 'signature' ideal graph node 1447 // sequences which i) occur as a translation of a volatile reads or 1448 // writes or CAS operations and ii) do not occur through any other 1449 // translation or graph transformation. We can then provide 1450 // alternative aldc matching rules which translate these node 1451 // sequences to the desired machine code sequences. Selection of the 1452 // alternative rules can be implemented by predicates which identify 1453 // the relevant node sequences. 1454 // 1455 // The ideal graph generator translates a volatile read to the node 1456 // sequence 1457 // 1458 // LoadX[mo_acquire] 1459 // MemBarAcquire 1460 // 1461 // As a special case when using the compressed oops optimization we 1462 // may also see this variant 1463 // 1464 // LoadN[mo_acquire] 1465 // DecodeN 1466 // MemBarAcquire 1467 // 1468 // A volatile write is translated to the node sequence 1469 // 1470 // MemBarRelease 1471 // StoreX[mo_release] {CardMark}-optional 1472 // MemBarVolatile 1473 // 1474 // n.b. the above node patterns are generated with a strict 1475 // 'signature' configuration of input and output dependencies (see 1476 // the predicates below for exact details). The card mark may be as 1477 // simple as a few extra nodes or, in a few GC configurations, may 1478 // include more complex control flow between the leading and 1479 // trailing memory barriers. However, whatever the card mark 1480 // configuration these signatures are unique to translated volatile 1481 // reads/stores -- they will not appear as a result of any other 1482 // bytecode translation or inlining nor as a consequence of 1483 // optimizing transforms. 1484 // 1485 // We also want to catch inlined unsafe volatile gets and puts and 1486 // be able to implement them using either ldar<x>/stlr<x> or some 1487 // combination of ldr<x>/stlr<x> and dmb instructions. 1488 // 1489 // Inlined unsafe volatiles puts manifest as a minor variant of the 1490 // normal volatile put node sequence containing an extra cpuorder 1491 // membar 1492 // 1493 // MemBarRelease 1494 // MemBarCPUOrder 1495 // StoreX[mo_release] {CardMark}-optional 1496 // MemBarCPUOrder 1497 // MemBarVolatile 1498 // 1499 // n.b. as an aside, a cpuorder membar is not itself subject to 1500 // matching and translation by adlc rules. However, the rule 1501 // predicates need to detect its presence in order to correctly 1502 // select the desired adlc rules. 1503 // 1504 // Inlined unsafe volatile gets manifest as a slightly different 1505 // node sequence to a normal volatile get because of the 1506 // introduction of some CPUOrder memory barriers to bracket the 1507 // Load. However, but the same basic skeleton of a LoadX feeding a 1508 // MemBarAcquire, possibly thorugh an optional DecodeN, is still 1509 // present 1510 // 1511 // MemBarCPUOrder 1512 // || \\ 1513 // MemBarCPUOrder LoadX[mo_acquire] 1514 // || | 1515 // || {DecodeN} optional 1516 // || / 1517 // MemBarAcquire 1518 // 1519 // In this case the acquire membar does not directly depend on the 1520 // load. However, we can be sure that the load is generated from an 1521 // inlined unsafe volatile get if we see it dependent on this unique 1522 // sequence of membar nodes. Similarly, given an acquire membar we 1523 // can know that it was added because of an inlined unsafe volatile 1524 // get if it is fed and feeds a cpuorder membar and if its feed 1525 // membar also feeds an acquiring load. 1526 // 1527 // Finally an inlined (Unsafe) CAS operation is translated to the 1528 // following ideal graph 1529 // 1530 // MemBarRelease 1531 // MemBarCPUOrder 1532 // CompareAndSwapX {CardMark}-optional 1533 // MemBarCPUOrder 1534 // MemBarAcquire 1535 // 1536 // So, where we can identify these volatile read and write 1537 // signatures we can choose to plant either of the above two code 1538 // sequences. For a volatile read we can simply plant a normal 1539 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1540 // also choose to inhibit translation of the MemBarAcquire and 1541 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1542 // 1543 // When we recognise a volatile store signature we can choose to 1544 // plant at a dmb ish as a translation for the MemBarRelease, a 1545 // normal str<x> and then a dmb ish for the MemBarVolatile. 1546 // Alternatively, we can inhibit translation of the MemBarRelease 1547 // and MemBarVolatile and instead plant a simple stlr<x> 1548 // instruction. 1549 // 1550 // when we recognise a CAS signature we can choose to plant a dmb 1551 // ish as a translation for the MemBarRelease, the conventional 1552 // macro-instruction sequence for the CompareAndSwap node (which 1553 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1554 // Alternatively, we can elide generation of the dmb instructions 1555 // and plant the alternative CompareAndSwap macro-instruction 1556 // sequence (which uses ldaxr<x>). 1557 // 1558 // Of course, the above only applies when we see these signature 1559 // configurations. We still want to plant dmb instructions in any 1560 // other cases where we may see a MemBarAcquire, MemBarRelease or 1561 // MemBarVolatile. For example, at the end of a constructor which 1562 // writes final/volatile fields we will see a MemBarRelease 1563 // instruction and this needs a 'dmb ish' lest we risk the 1564 // constructed object being visible without making the 1565 // final/volatile field writes visible. 1566 // 1567 // n.b. the translation rules below which rely on detection of the 1568 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1569 // If we see anything other than the signature configurations we 1570 // always just translate the loads and stores to ldr<x> and str<x> 1571 // and translate acquire, release and volatile membars to the 1572 // relevant dmb instructions. 1573 // 1574 1575 // is_CAS(int opcode, bool maybe_volatile) 1576 // 1577 // return true if opcode is one of the possible CompareAndSwapX 1578 // values otherwise false. 1579 1580 bool is_CAS(int opcode, bool maybe_volatile) 1581 { 1582 switch(opcode) { 1583 // We handle these 1584 case Op_CompareAndSwapI: 1585 case Op_CompareAndSwapL: 1586 case Op_CompareAndSwapP: 1587 case Op_CompareAndSwapN: 1588 case Op_ShenandoahCompareAndSwapP: 1589 case Op_ShenandoahCompareAndSwapN: 1590 case Op_CompareAndSwapB: 1591 case Op_CompareAndSwapS: 1592 case Op_GetAndSetI: 1593 case Op_GetAndSetL: 1594 case Op_GetAndSetP: 1595 case Op_GetAndSetN: 1596 case Op_GetAndAddI: 1597 case Op_GetAndAddL: 1598 return true; 1599 case Op_CompareAndExchangeI: 1600 case Op_CompareAndExchangeN: 1601 case Op_CompareAndExchangeB: 1602 case Op_CompareAndExchangeS: 1603 case Op_CompareAndExchangeL: 1604 case Op_CompareAndExchangeP: 1605 case Op_WeakCompareAndSwapB: 1606 case Op_WeakCompareAndSwapS: 1607 case Op_WeakCompareAndSwapI: 1608 case Op_WeakCompareAndSwapL: 1609 case Op_WeakCompareAndSwapP: 1610 case Op_WeakCompareAndSwapN: 1611 case Op_ShenandoahWeakCompareAndSwapP: 1612 case Op_ShenandoahWeakCompareAndSwapN: 1613 case Op_ShenandoahCompareAndExchangeP: 1614 case Op_ShenandoahCompareAndExchangeN: 1615 return maybe_volatile; 1616 default: 1617 return false; 1618 } 1619 } 1620 1621 // helper to determine the maximum number of Phi nodes we may need to 1622 // traverse when searching from a card mark membar for the merge mem 1623 // feeding a trailing membar or vice versa 1624 1625// predicates controlling emit of ldr<x>/ldar<x> 1626 1627bool unnecessary_acquire(const Node *barrier) 1628{ 1629 assert(barrier->is_MemBar(), "expecting a membar"); 1630 1631 MemBarNode* mb = barrier->as_MemBar(); 1632 1633 if (mb->trailing_load()) { 1634 return true; 1635 } 1636 1637 if (mb->trailing_load_store()) { 1638 Node* load_store = mb->in(MemBarNode::Precedent); 1639 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1640 return is_CAS(load_store->Opcode(), true); 1641 } 1642 1643 return false; 1644} 1645 1646bool needs_acquiring_load(const Node *n) 1647{ 1648 assert(n->is_Load(), "expecting a load"); 1649 LoadNode *ld = n->as_Load(); 1650 return ld->is_acquire(); 1651} 1652 1653bool unnecessary_release(const Node *n) 1654{ 1655 assert((n->is_MemBar() && 1656 n->Opcode() == Op_MemBarRelease), 1657 "expecting a release membar"); 1658 1659 MemBarNode *barrier = n->as_MemBar(); 1660 if (!barrier->leading()) { 1661 return false; 1662 } else { 1663 Node* trailing = barrier->trailing_membar(); 1664 MemBarNode* trailing_mb = trailing->as_MemBar(); 1665 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1666 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1667 1668 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1669 if (mem->is_Store()) { 1670 assert(mem->as_Store()->is_release(), ""); 1671 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1672 return true; 1673 } else { 1674 assert(mem->is_LoadStore(), ""); 1675 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1676 return is_CAS(mem->Opcode(), true); 1677 } 1678 } 1679 return false; 1680} 1681 1682bool unnecessary_volatile(const Node *n) 1683{ 1684 // assert n->is_MemBar(); 1685 MemBarNode *mbvol = n->as_MemBar(); 1686 1687 bool release = mbvol->trailing_store(); 1688 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1689#ifdef ASSERT 1690 if (release) { 1691 Node* leading = mbvol->leading_membar(); 1692 assert(leading->Opcode() == Op_MemBarRelease, ""); 1693 assert(leading->as_MemBar()->leading_store(), ""); 1694 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1695 } 1696#endif 1697 1698 return release; 1699} 1700 1701// predicates controlling emit of str<x>/stlr<x> 1702 1703bool needs_releasing_store(const Node *n) 1704{ 1705 // assert n->is_Store(); 1706 StoreNode *st = n->as_Store(); 1707 return st->trailing_membar() != NULL; 1708} 1709 1710// predicate controlling translation of CAS 1711// 1712// returns true if CAS needs to use an acquiring load otherwise false 1713 1714bool needs_acquiring_load_exclusive(const Node *n) 1715{ 1716 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1717 LoadStoreNode* ldst = n->as_LoadStore(); 1718 if (is_CAS(n->Opcode(), false)) { 1719 assert(ldst->trailing_membar() != NULL, "expected trailing membar"); 1720 } else { 1721 return ldst->trailing_membar() != NULL; 1722 } 1723 1724 // so we can just return true here 1725 return true; 1726} 1727 1728#define __ _masm. 1729 1730// advance declarations for helper functions to convert register 1731// indices to register objects 1732 1733// the ad file has to provide implementations of certain methods 1734// expected by the generic code 1735// 1736// REQUIRED FUNCTIONALITY 1737 1738//============================================================================= 1739 1740// !!!!! Special hack to get all types of calls to specify the byte offset 1741// from the start of the call to the point where the return address 1742// will point. 1743 1744int MachCallStaticJavaNode::ret_addr_offset() 1745{ 1746 // call should be a simple bl 1747 int off = 4; 1748 return off; 1749} 1750 1751int MachCallDynamicJavaNode::ret_addr_offset() 1752{ 1753 return 16; // movz, movk, movk, bl 1754} 1755 1756int MachCallRuntimeNode::ret_addr_offset() { 1757 // for generated stubs the call will be 1758 // bl(addr) 1759 // or with far branches 1760 // bl(trampoline_stub) 1761 // for real runtime callouts it will be six instructions 1762 // see aarch64_enc_java_to_runtime 1763 // adr(rscratch2, retaddr) 1764 // lea(rscratch1, RuntimeAddress(addr) 1765 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1766 // blr(rscratch1) 1767 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1768 if (cb) { 1769 return 1 * NativeInstruction::instruction_size; 1770 } else { 1771 return 6 * NativeInstruction::instruction_size; 1772 } 1773} 1774 1775int MachCallNativeNode::ret_addr_offset() { 1776 // This is implemented using aarch64_enc_java_to_runtime as above. 1777 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1778 if (cb) { 1779 return 1 * NativeInstruction::instruction_size; 1780 } else { 1781 return 6 * NativeInstruction::instruction_size; 1782 } 1783} 1784 1785//============================================================================= 1786 1787#ifndef PRODUCT 1788void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1789 st->print("BREAKPOINT"); 1790} 1791#endif 1792 1793void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1794 C2_MacroAssembler _masm(&cbuf); 1795 __ brk(0); 1796} 1797 1798uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1799 return MachNode::size(ra_); 1800} 1801 1802//============================================================================= 1803 1804#ifndef PRODUCT 1805 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1806 st->print("nop \t# %d bytes pad for loops and calls", _count); 1807 } 1808#endif 1809 1810 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1811 C2_MacroAssembler _masm(&cbuf); 1812 for (int i = 0; i < _count; i++) { 1813 __ nop(); 1814 } 1815 } 1816 1817 uint MachNopNode::size(PhaseRegAlloc*) const { 1818 return _count * NativeInstruction::instruction_size; 1819 } 1820 1821//============================================================================= 1822const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1823 1824int ConstantTable::calculate_table_base_offset() const { 1825 return 0; // absolute addressing, no offset 1826} 1827 1828bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1829void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1830 ShouldNotReachHere(); 1831} 1832 1833void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1834 // Empty encoding 1835} 1836 1837uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1838 return 0; 1839} 1840 1841#ifndef PRODUCT 1842void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1843 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1844} 1845#endif 1846 1847#ifndef PRODUCT 1848void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1849 Compile* C = ra_->C; 1850 1851 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1852 1853 if (C->output()->need_stack_bang(framesize)) 1854 st->print("# stack bang size=%d\n\t", framesize); 1855 1856 if (framesize < ((1 << 9) + 2 * wordSize)) { 1857 st->print("sub sp, sp, #%d\n\t", framesize); 1858 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1859 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1860 } else { 1861 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1862 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1863 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1864 st->print("sub sp, sp, rscratch1"); 1865 } 1866 if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 1867 st->print("\n\t"); 1868 st->print("ldr rscratch1, [guard]\n\t"); 1869 st->print("dmb ishld\n\t"); 1870 st->print("ldr rscratch2, [rthread, #thread_disarmed_offset]\n\t"); 1871 st->print("cmp rscratch1, rscratch2\n\t"); 1872 st->print("b.eq skip"); 1873 st->print("\n\t"); 1874 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1875 st->print("b skip\n\t"); 1876 st->print("guard: int\n\t"); 1877 st->print("\n\t"); 1878 st->print("skip:\n\t"); 1879 } 1880} 1881#endif 1882 1883void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1884 Compile* C = ra_->C; 1885 C2_MacroAssembler _masm(&cbuf); 1886 1887 // n.b. frame size includes space for return pc and rfp 1888 const int framesize = C->output()->frame_size_in_bytes(); 1889 1890 // insert a nop at the start of the prolog so we can patch in a 1891 // branch if we need to invalidate the method later 1892 __ nop(); 1893 1894 if (C->clinit_barrier_on_entry()) { 1895 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1896 1897 Label L_skip_barrier; 1898 1899 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding()); 1900 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier); 1901 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1902 __ bind(L_skip_barrier); 1903 } 1904 1905 if (C->max_vector_size() >= 16) { 1906 __ reinitialize_ptrue(); 1907 } 1908 1909 int bangsize = C->output()->bang_size_in_bytes(); 1910 if (C->output()->need_stack_bang(bangsize)) 1911 __ generate_stack_overflow_check(bangsize); 1912 1913 __ build_frame(framesize); 1914 1915 if (C->stub_function() == NULL) { 1916 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1917 bs->nmethod_entry_barrier(&_masm); 1918 } 1919 1920 if (VerifyStackAtCalls) { 1921 Unimplemented(); 1922 } 1923 1924 C->output()->set_frame_complete(cbuf.insts_size()); 1925 1926 if (C->has_mach_constant_base_node()) { 1927 // NOTE: We set the table base offset here because users might be 1928 // emitted before MachConstantBaseNode. 1929 ConstantTable& constant_table = C->output()->constant_table(); 1930 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1931 } 1932} 1933 1934uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1935{ 1936 return MachNode::size(ra_); // too many variables; just compute it 1937 // the hard way 1938} 1939 1940int MachPrologNode::reloc() const 1941{ 1942 return 0; 1943} 1944 1945//============================================================================= 1946 1947#ifndef PRODUCT 1948void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1949 Compile* C = ra_->C; 1950 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1951 1952 st->print("# pop frame %d\n\t",framesize); 1953 1954 if (framesize == 0) { 1955 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1956 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1957 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1958 st->print("add sp, sp, #%d\n\t", framesize); 1959 } else { 1960 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1961 st->print("add sp, sp, rscratch1\n\t"); 1962 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1963 } 1964 1965 if (do_polling() && C->is_method_compilation()) { 1966 st->print("# test polling word\n\t"); 1967 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset())); 1968 st->print("cmp sp, rscratch1\n\t"); 1969 st->print("bhi #slow_path"); 1970 } 1971} 1972#endif 1973 1974void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1975 Compile* C = ra_->C; 1976 C2_MacroAssembler _masm(&cbuf); 1977 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1978 1979 __ remove_frame(framesize); 1980 1981 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1982 __ reserved_stack_check(); 1983 } 1984 1985 if (do_polling() && C->is_method_compilation()) { 1986 Label dummy_label; 1987 Label* code_stub = &dummy_label; 1988 if (!C->output()->in_scratch_emit_size()) { 1989 code_stub = &C->output()->safepoint_poll_table()->add_safepoint(__ offset()); 1990 } 1991 __ relocate(relocInfo::poll_return_type); 1992 __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); 1993 } 1994} 1995 1996uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1997 // Variable size. Determine dynamically. 1998 return MachNode::size(ra_); 1999} 2000 2001int MachEpilogNode::reloc() const { 2002 // Return number of relocatable values contained in this instruction. 2003 return 1; // 1 for polling page. 2004} 2005 2006const Pipeline * MachEpilogNode::pipeline() const { 2007 return MachNode::pipeline_class(); 2008} 2009 2010//============================================================================= 2011 2012// Figure out which register class each belongs in: rc_int, rc_float or 2013// rc_stack. 2014enum RC { rc_bad, rc_int, rc_float, rc_predicate, rc_stack }; 2015 2016static enum RC rc_class(OptoReg::Name reg) { 2017 2018 if (reg == OptoReg::Bad) { 2019 return rc_bad; 2020 } 2021 2022 // we have 32 int registers * 2 halves 2023 int slots_of_int_registers = RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers; 2024 2025 if (reg < slots_of_int_registers) { 2026 return rc_int; 2027 } 2028 2029 // we have 32 float register * 8 halves 2030 int slots_of_float_registers = FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers; 2031 if (reg < slots_of_int_registers + slots_of_float_registers) { 2032 return rc_float; 2033 } 2034 2035 int slots_of_predicate_registers = PRegisterImpl::max_slots_per_register * PRegisterImpl::number_of_registers; 2036 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) { 2037 return rc_predicate; 2038 } 2039 2040 // Between predicate regs & stack is the flags. 2041 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 2042 2043 return rc_stack; 2044} 2045 2046uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 2047 Compile* C = ra_->C; 2048 2049 // Get registers to move. 2050 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 2051 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 2052 OptoReg::Name dst_hi = ra_->get_reg_second(this); 2053 OptoReg::Name dst_lo = ra_->get_reg_first(this); 2054 2055 enum RC src_hi_rc = rc_class(src_hi); 2056 enum RC src_lo_rc = rc_class(src_lo); 2057 enum RC dst_hi_rc = rc_class(dst_hi); 2058 enum RC dst_lo_rc = rc_class(dst_lo); 2059 2060 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 2061 2062 if (src_hi != OptoReg::Bad) { 2063 assert((src_lo&1)==0 && src_lo+1==src_hi && 2064 (dst_lo&1)==0 && dst_lo+1==dst_hi, 2065 "expected aligned-adjacent pairs"); 2066 } 2067 2068 if (src_lo == dst_lo && src_hi == dst_hi) { 2069 return 0; // Self copy, no move. 2070 } 2071 2072 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 2073 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 2074 int src_offset = ra_->reg2offset(src_lo); 2075 int dst_offset = ra_->reg2offset(dst_lo); 2076 2077 if (bottom_type()->isa_vect() != NULL) { 2078 uint ireg = ideal_reg(); 2079 if (ireg == Op_VecA && cbuf) { 2080 C2_MacroAssembler _masm(cbuf); 2081 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); 2082 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 2083 // stack->stack 2084 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset, 2085 sve_vector_reg_size_in_bytes); 2086 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2087 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 2088 sve_vector_reg_size_in_bytes); 2089 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 2090 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 2091 sve_vector_reg_size_in_bytes); 2092 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2093 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2094 as_FloatRegister(Matcher::_regEncode[src_lo]), 2095 as_FloatRegister(Matcher::_regEncode[src_lo])); 2096 } else { 2097 ShouldNotReachHere(); 2098 } 2099 } else if (cbuf) { 2100 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 2101 C2_MacroAssembler _masm(cbuf); 2102 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 2103 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 2104 // stack->stack 2105 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 2106 if (ireg == Op_VecD) { 2107 __ unspill(rscratch1, true, src_offset); 2108 __ spill(rscratch1, true, dst_offset); 2109 } else { 2110 __ spill_copy128(src_offset, dst_offset); 2111 } 2112 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2113 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2114 ireg == Op_VecD ? __ T8B : __ T16B, 2115 as_FloatRegister(Matcher::_regEncode[src_lo])); 2116 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2117 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2118 ireg == Op_VecD ? __ D : __ Q, 2119 ra_->reg2offset(dst_lo)); 2120 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 2121 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2122 ireg == Op_VecD ? __ D : __ Q, 2123 ra_->reg2offset(src_lo)); 2124 } else { 2125 ShouldNotReachHere(); 2126 } 2127 } 2128 } else if (cbuf) { 2129 C2_MacroAssembler _masm(cbuf); 2130 switch (src_lo_rc) { 2131 case rc_int: 2132 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 2133 if (is64) { 2134 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 2135 as_Register(Matcher::_regEncode[src_lo])); 2136 } else { 2137 C2_MacroAssembler _masm(cbuf); 2138 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 2139 as_Register(Matcher::_regEncode[src_lo])); 2140 } 2141 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 2142 if (is64) { 2143 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2144 as_Register(Matcher::_regEncode[src_lo])); 2145 } else { 2146 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2147 as_Register(Matcher::_regEncode[src_lo])); 2148 } 2149 } else { // gpr --> stack spill 2150 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2151 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 2152 } 2153 break; 2154 case rc_float: 2155 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2156 if (is64) { 2157 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2158 as_FloatRegister(Matcher::_regEncode[src_lo])); 2159 } else { 2160 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2161 as_FloatRegister(Matcher::_regEncode[src_lo])); 2162 } 2163 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2164 if (cbuf) { 2165 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2166 as_FloatRegister(Matcher::_regEncode[src_lo])); 2167 } else { 2168 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2169 as_FloatRegister(Matcher::_regEncode[src_lo])); 2170 } 2171 } else { // fpr --> stack spill 2172 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2173 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2174 is64 ? __ D : __ S, dst_offset); 2175 } 2176 break; 2177 case rc_stack: 2178 if (dst_lo_rc == rc_int) { // stack --> gpr load 2179 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 2180 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2181 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2182 is64 ? __ D : __ S, src_offset); 2183 } else { // stack --> stack copy 2184 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2185 __ unspill(rscratch1, is64, src_offset); 2186 __ spill(rscratch1, is64, dst_offset); 2187 } 2188 break; 2189 default: 2190 assert(false, "bad rc_class for spill"); 2191 ShouldNotReachHere(); 2192 } 2193 } 2194 2195 if (st) { 2196 st->print("spill "); 2197 if (src_lo_rc == rc_stack) { 2198 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2199 } else { 2200 st->print("%s -> ", Matcher::regName[src_lo]); 2201 } 2202 if (dst_lo_rc == rc_stack) { 2203 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2204 } else { 2205 st->print("%s", Matcher::regName[dst_lo]); 2206 } 2207 if (bottom_type()->isa_vect() != NULL) { 2208 int vsize = 0; 2209 switch (ideal_reg()) { 2210 case Op_VecD: 2211 vsize = 64; 2212 break; 2213 case Op_VecX: 2214 vsize = 128; 2215 break; 2216 case Op_VecA: 2217 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; 2218 break; 2219 default: 2220 assert(false, "bad register type for spill"); 2221 ShouldNotReachHere(); 2222 } 2223 st->print("\t# vector spill size = %d", vsize); 2224 } else { 2225 st->print("\t# spill size = %d", is64 ? 64 : 32); 2226 } 2227 } 2228 2229 return 0; 2230 2231} 2232 2233#ifndef PRODUCT 2234void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2235 if (!ra_) 2236 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2237 else 2238 implementation(NULL, ra_, false, st); 2239} 2240#endif 2241 2242void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2243 implementation(&cbuf, ra_, false, NULL); 2244} 2245 2246uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2247 return MachNode::size(ra_); 2248} 2249 2250//============================================================================= 2251 2252#ifndef PRODUCT 2253void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2254 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2255 int reg = ra_->get_reg_first(this); 2256 st->print("add %s, rsp, #%d]\t# box lock", 2257 Matcher::regName[reg], offset); 2258} 2259#endif 2260 2261void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2262 C2_MacroAssembler _masm(&cbuf); 2263 2264 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2265 int reg = ra_->get_encode(this); 2266 2267 // This add will handle any 24-bit signed offset. 24 bits allows an 2268 // 8 megabyte stack frame. 2269 __ add(as_Register(reg), sp, offset); 2270} 2271 2272uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2273 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2274 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2275 2276 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2277 return NativeInstruction::instruction_size; 2278 } else { 2279 return 2 * NativeInstruction::instruction_size; 2280 } 2281} 2282 2283//============================================================================= 2284 2285#ifndef PRODUCT 2286void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2287{ 2288 st->print_cr("# MachUEPNode"); 2289 if (UseCompressedClassPointers) { 2290 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2291 if (CompressedKlassPointers::shift() != 0) { 2292 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2293 } 2294 } else { 2295 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2296 } 2297 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2298 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2299} 2300#endif 2301 2302void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2303{ 2304 // This is the unverified entry point. 2305 C2_MacroAssembler _masm(&cbuf); 2306 2307 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2308 Label skip; 2309 // TODO 2310 // can we avoid this skip and still use a reloc? 2311 __ br(Assembler::EQ, skip); 2312 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2313 __ bind(skip); 2314} 2315 2316uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2317{ 2318 return MachNode::size(ra_); 2319} 2320 2321// REQUIRED EMIT CODE 2322 2323//============================================================================= 2324 2325// Emit exception handler code. 2326int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2327{ 2328 // mov rscratch1 #exception_blob_entry_point 2329 // br rscratch1 2330 // Note that the code buffer's insts_mark is always relative to insts. 2331 // That's why we must use the macroassembler to generate a handler. 2332 C2_MacroAssembler _masm(&cbuf); 2333 address base = __ start_a_stub(size_exception_handler()); 2334 if (base == NULL) { 2335 ciEnv::current()->record_failure("CodeCache is full"); 2336 return 0; // CodeBuffer::expand failed 2337 } 2338 int offset = __ offset(); 2339 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2340 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2341 __ end_a_stub(); 2342 return offset; 2343} 2344 2345// Emit deopt handler code. 2346int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2347{ 2348 // Note that the code buffer's insts_mark is always relative to insts. 2349 // That's why we must use the macroassembler to generate a handler. 2350 C2_MacroAssembler _masm(&cbuf); 2351 address base = __ start_a_stub(size_deopt_handler()); 2352 if (base == NULL) { 2353 ciEnv::current()->record_failure("CodeCache is full"); 2354 return 0; // CodeBuffer::expand failed 2355 } 2356 int offset = __ offset(); 2357 2358 __ adr(lr, __ pc()); 2359 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2360 2361 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2362 __ end_a_stub(); 2363 return offset; 2364} 2365 2366// REQUIRED MATCHER CODE 2367 2368//============================================================================= 2369 2370const bool Matcher::match_rule_supported(int opcode) { 2371 if (!has_match_rule(opcode)) 2372 return false; 2373 2374 bool ret_value = true; 2375 switch (opcode) { 2376 case Op_CacheWB: 2377 case Op_CacheWBPreSync: 2378 case Op_CacheWBPostSync: 2379 if (!VM_Version::supports_data_cache_line_flush()) { 2380 ret_value = false; 2381 } 2382 break; 2383 } 2384 2385 return ret_value; // Per default match rules are supported. 2386} 2387 2388// Identify extra cases that we might want to provide match rules for vector nodes and 2389// other intrinsics guarded with vector length (vlen) and element type (bt). 2390const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2391 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { 2392 return false; 2393 } 2394 int bit_size = vlen * type2aelembytes(bt) * 8; 2395 if (UseSVE == 0 && bit_size > 128) { 2396 return false; 2397 } 2398 if (UseSVE > 0) { 2399 return op_sve_supported(opcode); 2400 } else { // NEON 2401 // Special cases 2402 switch (opcode) { 2403 case Op_VectorMaskCmp: 2404 // We don't have VectorReinterpret with bit_size less than 64 support for 2405 // now, even for byte type. To be refined with fully VectorCast support. 2406 case Op_VectorReinterpret: 2407 if (vlen < 2 || bit_size < 64) { 2408 return false; 2409 } 2410 break; 2411 case Op_MulAddVS2VI: 2412 if (bit_size < 128) { 2413 return false; 2414 } 2415 break; 2416 case Op_MulVL: 2417 return false; 2418 case Op_VectorLoadShuffle: 2419 case Op_VectorRearrange: 2420 if (vlen < 4) { 2421 return false; 2422 } 2423 break; 2424 // Some types of VectorCast are not implemented for now. 2425 case Op_VectorCastI2X: 2426 if (bt == T_BYTE) { 2427 return false; 2428 } 2429 break; 2430 case Op_VectorCastS2X: 2431 if (vlen < 4 || bit_size < 64) { 2432 return false; 2433 } 2434 break; 2435 case Op_VectorCastF2X: 2436 case Op_VectorCastD2X: 2437 if (bt == T_INT || bt == T_SHORT || bt == T_BYTE || bt == T_LONG) { 2438 return false; 2439 } 2440 break; 2441 default: 2442 break; 2443 } 2444 } 2445 return true; // Per default match rules are supported. 2446} 2447 2448const RegMask* Matcher::predicate_reg_mask(void) { 2449 return &_PR_REG_mask; 2450} 2451 2452const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2453 return new TypeVectMask(elemTy, length); 2454} 2455 2456// Vector calling convention not yet implemented. 2457const bool Matcher::supports_vector_calling_convention(void) { 2458 return false; 2459} 2460 2461OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2462 Unimplemented(); 2463 return OptoRegPair(0, 0); 2464} 2465 2466const int Matcher::float_pressure(int default_pressure_threshold) { 2467 return default_pressure_threshold; 2468} 2469 2470// Is this branch offset short enough that a short branch can be used? 2471// 2472// NOTE: If the platform does not provide any short branch variants, then 2473// this method should return false for offset 0. 2474bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2475 // The passed offset is relative to address of the branch. 2476 2477 return (-32768 <= offset && offset < 32768); 2478} 2479 2480// Vector width in bytes. 2481const int Matcher::vector_width_in_bytes(BasicType bt) { 2482 // The MaxVectorSize should have been set by detecting SVE max vector register size. 2483 int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize); 2484 // Minimum 2 values in vector 2485 if (size < 2*type2aelembytes(bt)) size = 0; 2486 // But never < 4 2487 if (size < 4) size = 0; 2488 return size; 2489} 2490 2491// Limits on vector size (number of elements) loaded into vector. 2492const int Matcher::max_vector_size(const BasicType bt) { 2493 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2494} 2495const int Matcher::min_vector_size(const BasicType bt) { 2496 int max_size = max_vector_size(bt); 2497 if ((UseSVE > 0) && (MaxVectorSize >= 16)) { 2498 // Currently vector length less than SVE vector register size is not supported. 2499 return max_size; 2500 } else { // NEON 2501 // Limit the vector size to 8 bytes 2502 int size = 8 / type2aelembytes(bt); 2503 if (bt == T_BYTE) { 2504 // To support vector api shuffle/rearrange. 2505 size = 4; 2506 } else if (bt == T_BOOLEAN) { 2507 // To support vector api load/store mask. 2508 size = 2; 2509 } 2510 if (size < 2) size = 2; 2511 return MIN2(size,max_size); 2512 } 2513} 2514 2515// Actual max scalable vector register length. 2516const int Matcher::scalable_vector_reg_size(const BasicType bt) { 2517 return Matcher::max_vector_size(bt); 2518} 2519 2520// Vector ideal reg. 2521const uint Matcher::vector_ideal_reg(int len) { 2522 if (UseSVE > 0 && 16 <= len && len <= 256) { 2523 return Op_VecA; 2524 } 2525 switch(len) { 2526 // For 16-bit/32-bit mask vector, reuse VecD. 2527 case 2: 2528 case 4: 2529 case 8: return Op_VecD; 2530 case 16: return Op_VecX; 2531 } 2532 ShouldNotReachHere(); 2533 return 0; 2534} 2535 2536MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2537 ShouldNotReachHere(); // generic vector operands not supported 2538 return NULL; 2539} 2540 2541bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2542 ShouldNotReachHere(); // generic vector operands not supported 2543 return false; 2544} 2545 2546bool Matcher::is_generic_vector(MachOper* opnd) { 2547 ShouldNotReachHere(); // generic vector operands not supported 2548 return false; 2549} 2550 2551// Return whether or not this register is ever used as an argument. 2552// This function is used on startup to build the trampoline stubs in 2553// generateOptoStub. Registers not mentioned will be killed by the VM 2554// call in the trampoline, and arguments in those registers not be 2555// available to the callee. 2556bool Matcher::can_be_java_arg(int reg) 2557{ 2558 return 2559 reg == R0_num || reg == R0_H_num || 2560 reg == R1_num || reg == R1_H_num || 2561 reg == R2_num || reg == R2_H_num || 2562 reg == R3_num || reg == R3_H_num || 2563 reg == R4_num || reg == R4_H_num || 2564 reg == R5_num || reg == R5_H_num || 2565 reg == R6_num || reg == R6_H_num || 2566 reg == R7_num || reg == R7_H_num || 2567 reg == V0_num || reg == V0_H_num || 2568 reg == V1_num || reg == V1_H_num || 2569 reg == V2_num || reg == V2_H_num || 2570 reg == V3_num || reg == V3_H_num || 2571 reg == V4_num || reg == V4_H_num || 2572 reg == V5_num || reg == V5_H_num || 2573 reg == V6_num || reg == V6_H_num || 2574 reg == V7_num || reg == V7_H_num; 2575} 2576 2577bool Matcher::is_spillable_arg(int reg) 2578{ 2579 return can_be_java_arg(reg); 2580} 2581 2582bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2583 return false; 2584} 2585 2586RegMask Matcher::divI_proj_mask() { 2587 ShouldNotReachHere(); 2588 return RegMask(); 2589} 2590 2591// Register for MODI projection of divmodI. 2592RegMask Matcher::modI_proj_mask() { 2593 ShouldNotReachHere(); 2594 return RegMask(); 2595} 2596 2597// Register for DIVL projection of divmodL. 2598RegMask Matcher::divL_proj_mask() { 2599 ShouldNotReachHere(); 2600 return RegMask(); 2601} 2602 2603// Register for MODL projection of divmodL. 2604RegMask Matcher::modL_proj_mask() { 2605 ShouldNotReachHere(); 2606 return RegMask(); 2607} 2608 2609const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2610 return FP_REG_mask(); 2611} 2612 2613bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2614 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2615 Node* u = addp->fast_out(i); 2616 if (u->is_Mem()) { 2617 int opsize = u->as_Mem()->memory_size(); 2618 assert(opsize > 0, "unexpected memory operand size"); 2619 if (u->as_Mem()->memory_size() != (1<<shift)) { 2620 return false; 2621 } 2622 } 2623 } 2624 return true; 2625} 2626 2627// Should the matcher clone input 'm' of node 'n'? 2628bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2629 if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con) 2630 mstack.push(m, Visit); // m = ShiftCntV 2631 return true; 2632 } 2633 return false; 2634} 2635 2636// Should the Matcher clone shifts on addressing modes, expecting them 2637// to be subsumed into complex addressing expressions or compute them 2638// into registers? 2639bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2640 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2641 return true; 2642 } 2643 2644 Node *off = m->in(AddPNode::Offset); 2645 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2646 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2647 // Are there other uses besides address expressions? 2648 !is_visited(off)) { 2649 address_visited.set(off->_idx); // Flag as address_visited 2650 mstack.push(off->in(2), Visit); 2651 Node *conv = off->in(1); 2652 if (conv->Opcode() == Op_ConvI2L && 2653 // Are there other uses besides address expressions? 2654 !is_visited(conv)) { 2655 address_visited.set(conv->_idx); // Flag as address_visited 2656 mstack.push(conv->in(1), Pre_Visit); 2657 } else { 2658 mstack.push(conv, Pre_Visit); 2659 } 2660 address_visited.test_set(m->_idx); // Flag as address_visited 2661 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2662 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2663 return true; 2664 } else if (off->Opcode() == Op_ConvI2L && 2665 // Are there other uses besides address expressions? 2666 !is_visited(off)) { 2667 address_visited.test_set(m->_idx); // Flag as address_visited 2668 address_visited.set(off->_idx); // Flag as address_visited 2669 mstack.push(off->in(1), Pre_Visit); 2670 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2671 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2672 return true; 2673 } 2674 return false; 2675} 2676 2677#define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2678 C2_MacroAssembler _masm(&cbuf); \ 2679 { \ 2680 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2681 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2682 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2683 __ INSN(REG, as_Register(BASE)); \ 2684 } 2685 2686 2687static Address mem2address(int opcode, Register base, int index, int size, int disp) 2688 { 2689 Address::extend scale; 2690 2691 // Hooboy, this is fugly. We need a way to communicate to the 2692 // encoder that the index needs to be sign extended, so we have to 2693 // enumerate all the cases. 2694 switch (opcode) { 2695 case INDINDEXSCALEDI2L: 2696 case INDINDEXSCALEDI2LN: 2697 case INDINDEXI2L: 2698 case INDINDEXI2LN: 2699 scale = Address::sxtw(size); 2700 break; 2701 default: 2702 scale = Address::lsl(size); 2703 } 2704 2705 if (index == -1) { 2706 return Address(base, disp); 2707 } else { 2708 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2709 return Address(base, as_Register(index), scale); 2710 } 2711 } 2712 2713 2714typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2715typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2716typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2717typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2718 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2719 2720 // Used for all non-volatile memory accesses. The use of 2721 // $mem->opcode() to discover whether this pattern uses sign-extended 2722 // offsets is something of a kludge. 2723 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2724 Register reg, int opcode, 2725 Register base, int index, int scale, int disp, 2726 int size_in_memory) 2727 { 2728 Address addr = mem2address(opcode, base, index, scale, disp); 2729 if (addr.getMode() == Address::base_plus_offset) { 2730 /* If we get an out-of-range offset it is a bug in the compiler, 2731 so we assert here. */ 2732 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2733 "c2 compiler bug"); 2734 /* Fix up any out-of-range offsets. */ 2735 assert_different_registers(rscratch1, base); 2736 assert_different_registers(rscratch1, reg); 2737 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2738 } 2739 (masm.*insn)(reg, addr); 2740 } 2741 2742 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2743 FloatRegister reg, int opcode, 2744 Register base, int index, int size, int disp, 2745 int size_in_memory) 2746 { 2747 Address::extend scale; 2748 2749 switch (opcode) { 2750 case INDINDEXSCALEDI2L: 2751 case INDINDEXSCALEDI2LN: 2752 scale = Address::sxtw(size); 2753 break; 2754 default: 2755 scale = Address::lsl(size); 2756 } 2757 2758 if (index == -1) { 2759 /* If we get an out-of-range offset it is a bug in the compiler, 2760 so we assert here. */ 2761 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2762 /* Fix up any out-of-range offsets. */ 2763 assert_different_registers(rscratch1, base); 2764 Address addr = Address(base, disp); 2765 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2766 (masm.*insn)(reg, addr); 2767 } else { 2768 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2769 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2770 } 2771 } 2772 2773 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2774 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2775 int opcode, Register base, int index, int size, int disp) 2776 { 2777 if (index == -1) { 2778 (masm.*insn)(reg, T, Address(base, disp)); 2779 } else { 2780 assert(disp == 0, "unsupported address mode"); 2781 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2782 } 2783 } 2784 2785%} 2786 2787 2788 2789//----------ENCODING BLOCK----------------------------------------------------- 2790// This block specifies the encoding classes used by the compiler to 2791// output byte streams. Encoding classes are parameterized macros 2792// used by Machine Instruction Nodes in order to generate the bit 2793// encoding of the instruction. Operands specify their base encoding 2794// interface with the interface keyword. There are currently 2795// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2796// COND_INTER. REG_INTER causes an operand to generate a function 2797// which returns its register number when queried. CONST_INTER causes 2798// an operand to generate a function which returns the value of the 2799// constant when queried. MEMORY_INTER causes an operand to generate 2800// four functions which return the Base Register, the Index Register, 2801// the Scale Value, and the Offset Value of the operand when queried. 2802// COND_INTER causes an operand to generate six functions which return 2803// the encoding code (ie - encoding bits for the instruction) 2804// associated with each basic boolean condition for a conditional 2805// instruction. 2806// 2807// Instructions specify two basic values for encoding. Again, a 2808// function is available to check if the constant displacement is an 2809// oop. They use the ins_encode keyword to specify their encoding 2810// classes (which must be a sequence of enc_class names, and their 2811// parameters, specified in the encoding block), and they use the 2812// opcode keyword to specify, in order, their primary, secondary, and 2813// tertiary opcode. Only the opcode sections which a particular 2814// instruction needs for encoding need to be specified. 2815encode %{ 2816 // Build emit functions for each basic byte or larger field in the 2817 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2818 // from C++ code in the enc_class source block. Emit functions will 2819 // live in the main source block for now. In future, we can 2820 // generalize this by adding a syntax that specifies the sizes of 2821 // fields in an order, so that the adlc can build the emit functions 2822 // automagically 2823 2824 // catch all for unimplemented encodings 2825 enc_class enc_unimplemented %{ 2826 C2_MacroAssembler _masm(&cbuf); 2827 __ unimplemented("C2 catch all"); 2828 %} 2829 2830 // BEGIN Non-volatile memory access 2831 2832 // This encoding class is generated automatically from ad_encode.m4. 2833 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2834 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2835 Register dst_reg = as_Register($dst$$reg); 2836 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2837 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2838 %} 2839 2840 // This encoding class is generated automatically from ad_encode.m4. 2841 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2842 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2843 Register dst_reg = as_Register($dst$$reg); 2844 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2845 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2846 %} 2847 2848 // This encoding class is generated automatically from ad_encode.m4. 2849 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2850 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2851 Register dst_reg = as_Register($dst$$reg); 2852 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2853 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2854 %} 2855 2856 // This encoding class is generated automatically from ad_encode.m4. 2857 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2858 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2859 Register dst_reg = as_Register($dst$$reg); 2860 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2861 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2862 %} 2863 2864 // This encoding class is generated automatically from ad_encode.m4. 2865 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2866 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2867 Register dst_reg = as_Register($dst$$reg); 2868 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2869 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2870 %} 2871 2872 // This encoding class is generated automatically from ad_encode.m4. 2873 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2874 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2875 Register dst_reg = as_Register($dst$$reg); 2876 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2877 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2878 %} 2879 2880 // This encoding class is generated automatically from ad_encode.m4. 2881 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2882 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2883 Register dst_reg = as_Register($dst$$reg); 2884 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2885 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2886 %} 2887 2888 // This encoding class is generated automatically from ad_encode.m4. 2889 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2890 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2891 Register dst_reg = as_Register($dst$$reg); 2892 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2893 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2894 %} 2895 2896 // This encoding class is generated automatically from ad_encode.m4. 2897 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2898 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2899 Register dst_reg = as_Register($dst$$reg); 2900 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2901 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2902 %} 2903 2904 // This encoding class is generated automatically from ad_encode.m4. 2905 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2906 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2907 Register dst_reg = as_Register($dst$$reg); 2908 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2909 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2910 %} 2911 2912 // This encoding class is generated automatically from ad_encode.m4. 2913 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2914 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2915 Register dst_reg = as_Register($dst$$reg); 2916 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2917 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2918 %} 2919 2920 // This encoding class is generated automatically from ad_encode.m4. 2921 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2922 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2923 Register dst_reg = as_Register($dst$$reg); 2924 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2925 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2926 %} 2927 2928 // This encoding class is generated automatically from ad_encode.m4. 2929 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2930 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2931 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2932 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2933 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2934 %} 2935 2936 // This encoding class is generated automatically from ad_encode.m4. 2937 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2938 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2939 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2940 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2941 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2942 %} 2943 2944 // This encoding class is generated automatically from ad_encode.m4. 2945 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2946 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2947 Register src_reg = as_Register($src$$reg); 2948 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2949 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2950 %} 2951 2952 // This encoding class is generated automatically from ad_encode.m4. 2953 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2954 enc_class aarch64_enc_strb0(memory1 mem) %{ 2955 C2_MacroAssembler _masm(&cbuf); 2956 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2957 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2958 %} 2959 2960 // This encoding class is generated automatically from ad_encode.m4. 2961 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2962 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2963 Register src_reg = as_Register($src$$reg); 2964 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2965 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2966 %} 2967 2968 // This encoding class is generated automatically from ad_encode.m4. 2969 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2970 enc_class aarch64_enc_strh0(memory2 mem) %{ 2971 C2_MacroAssembler _masm(&cbuf); 2972 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2973 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2974 %} 2975 2976 // This encoding class is generated automatically from ad_encode.m4. 2977 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2978 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2979 Register src_reg = as_Register($src$$reg); 2980 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2981 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2982 %} 2983 2984 // This encoding class is generated automatically from ad_encode.m4. 2985 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2986 enc_class aarch64_enc_strw0(memory4 mem) %{ 2987 C2_MacroAssembler _masm(&cbuf); 2988 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2989 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2990 %} 2991 2992 // This encoding class is generated automatically from ad_encode.m4. 2993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2994 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2995 Register src_reg = as_Register($src$$reg); 2996 // we sometimes get asked to store the stack pointer into the 2997 // current thread -- we cannot do that directly on AArch64 2998 if (src_reg == r31_sp) { 2999 C2_MacroAssembler _masm(&cbuf); 3000 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3001 __ mov(rscratch2, sp); 3002 src_reg = rscratch2; 3003 } 3004 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 3005 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3006 %} 3007 3008 // This encoding class is generated automatically from ad_encode.m4. 3009 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3010 enc_class aarch64_enc_str0(memory8 mem) %{ 3011 C2_MacroAssembler _masm(&cbuf); 3012 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 3013 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3014 %} 3015 3016 // This encoding class is generated automatically from ad_encode.m4. 3017 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3018 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 3019 FloatRegister src_reg = as_FloatRegister($src$$reg); 3020 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 3021 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3022 %} 3023 3024 // This encoding class is generated automatically from ad_encode.m4. 3025 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3026 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 3027 FloatRegister src_reg = as_FloatRegister($src$$reg); 3028 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 3029 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3030 %} 3031 3032 // This encoding class is generated automatically from ad_encode.m4. 3033 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3034 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 3035 C2_MacroAssembler _masm(&cbuf); 3036 __ membar(Assembler::StoreStore); 3037 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 3038 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 3039 %} 3040 3041 // END Non-volatile memory access 3042 3043 // Vector loads and stores 3044 enc_class aarch64_enc_ldrvH(vecD dst, memory mem) %{ 3045 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3046 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 3047 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3048 %} 3049 3050 enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{ 3051 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3052 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3053 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3054 %} 3055 3056 enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{ 3057 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3058 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3059 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3060 %} 3061 3062 enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{ 3063 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3064 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3065 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3066 %} 3067 3068 enc_class aarch64_enc_strvH(vecD src, memory mem) %{ 3069 FloatRegister src_reg = as_FloatRegister($src$$reg); 3070 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H, 3071 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3072 %} 3073 3074 enc_class aarch64_enc_strvS(vecD src, memory mem) %{ 3075 FloatRegister src_reg = as_FloatRegister($src$$reg); 3076 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 3077 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3078 %} 3079 3080 enc_class aarch64_enc_strvD(vecD src, memory mem) %{ 3081 FloatRegister src_reg = as_FloatRegister($src$$reg); 3082 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 3083 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3084 %} 3085 3086 enc_class aarch64_enc_strvQ(vecX src, memory mem) %{ 3087 FloatRegister src_reg = as_FloatRegister($src$$reg); 3088 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 3089 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3090 %} 3091 3092 // volatile loads and stores 3093 3094 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3095 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3096 rscratch1, stlrb); 3097 %} 3098 3099 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3100 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3101 rscratch1, stlrh); 3102 %} 3103 3104 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3105 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3106 rscratch1, stlrw); 3107 %} 3108 3109 3110 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3111 Register dst_reg = as_Register($dst$$reg); 3112 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3113 rscratch1, ldarb); 3114 __ sxtbw(dst_reg, dst_reg); 3115 %} 3116 3117 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3118 Register dst_reg = as_Register($dst$$reg); 3119 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3120 rscratch1, ldarb); 3121 __ sxtb(dst_reg, dst_reg); 3122 %} 3123 3124 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3125 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3126 rscratch1, ldarb); 3127 %} 3128 3129 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3130 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3131 rscratch1, ldarb); 3132 %} 3133 3134 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3135 Register dst_reg = as_Register($dst$$reg); 3136 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3137 rscratch1, ldarh); 3138 __ sxthw(dst_reg, dst_reg); 3139 %} 3140 3141 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3142 Register dst_reg = as_Register($dst$$reg); 3143 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3144 rscratch1, ldarh); 3145 __ sxth(dst_reg, dst_reg); 3146 %} 3147 3148 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3149 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3150 rscratch1, ldarh); 3151 %} 3152 3153 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3154 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3155 rscratch1, ldarh); 3156 %} 3157 3158 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3159 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3160 rscratch1, ldarw); 3161 %} 3162 3163 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3164 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3165 rscratch1, ldarw); 3166 %} 3167 3168 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3169 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3170 rscratch1, ldar); 3171 %} 3172 3173 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3174 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3175 rscratch1, ldarw); 3176 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3177 %} 3178 3179 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3180 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3181 rscratch1, ldar); 3182 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3183 %} 3184 3185 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3186 Register src_reg = as_Register($src$$reg); 3187 // we sometimes get asked to store the stack pointer into the 3188 // current thread -- we cannot do that directly on AArch64 3189 if (src_reg == r31_sp) { 3190 C2_MacroAssembler _masm(&cbuf); 3191 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3192 __ mov(rscratch2, sp); 3193 src_reg = rscratch2; 3194 } 3195 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3196 rscratch1, stlr); 3197 %} 3198 3199 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3200 { 3201 C2_MacroAssembler _masm(&cbuf); 3202 FloatRegister src_reg = as_FloatRegister($src$$reg); 3203 __ fmovs(rscratch2, src_reg); 3204 } 3205 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3206 rscratch1, stlrw); 3207 %} 3208 3209 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3210 { 3211 C2_MacroAssembler _masm(&cbuf); 3212 FloatRegister src_reg = as_FloatRegister($src$$reg); 3213 __ fmovd(rscratch2, src_reg); 3214 } 3215 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3216 rscratch1, stlr); 3217 %} 3218 3219 // synchronized read/update encodings 3220 3221 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3222 C2_MacroAssembler _masm(&cbuf); 3223 Register dst_reg = as_Register($dst$$reg); 3224 Register base = as_Register($mem$$base); 3225 int index = $mem$$index; 3226 int scale = $mem$$scale; 3227 int disp = $mem$$disp; 3228 if (index == -1) { 3229 if (disp != 0) { 3230 __ lea(rscratch1, Address(base, disp)); 3231 __ ldaxr(dst_reg, rscratch1); 3232 } else { 3233 // TODO 3234 // should we ever get anything other than this case? 3235 __ ldaxr(dst_reg, base); 3236 } 3237 } else { 3238 Register index_reg = as_Register(index); 3239 if (disp == 0) { 3240 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3241 __ ldaxr(dst_reg, rscratch1); 3242 } else { 3243 __ lea(rscratch1, Address(base, disp)); 3244 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3245 __ ldaxr(dst_reg, rscratch1); 3246 } 3247 } 3248 %} 3249 3250 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3251 C2_MacroAssembler _masm(&cbuf); 3252 Register src_reg = as_Register($src$$reg); 3253 Register base = as_Register($mem$$base); 3254 int index = $mem$$index; 3255 int scale = $mem$$scale; 3256 int disp = $mem$$disp; 3257 if (index == -1) { 3258 if (disp != 0) { 3259 __ lea(rscratch2, Address(base, disp)); 3260 __ stlxr(rscratch1, src_reg, rscratch2); 3261 } else { 3262 // TODO 3263 // should we ever get anything other than this case? 3264 __ stlxr(rscratch1, src_reg, base); 3265 } 3266 } else { 3267 Register index_reg = as_Register(index); 3268 if (disp == 0) { 3269 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3270 __ stlxr(rscratch1, src_reg, rscratch2); 3271 } else { 3272 __ lea(rscratch2, Address(base, disp)); 3273 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3274 __ stlxr(rscratch1, src_reg, rscratch2); 3275 } 3276 } 3277 __ cmpw(rscratch1, zr); 3278 %} 3279 3280 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3281 C2_MacroAssembler _masm(&cbuf); 3282 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3283 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3284 Assembler::xword, /*acquire*/ false, /*release*/ true, 3285 /*weak*/ false, noreg); 3286 %} 3287 3288 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3289 C2_MacroAssembler _masm(&cbuf); 3290 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3291 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3292 Assembler::word, /*acquire*/ false, /*release*/ true, 3293 /*weak*/ false, noreg); 3294 %} 3295 3296 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3297 C2_MacroAssembler _masm(&cbuf); 3298 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3299 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3300 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3301 /*weak*/ false, noreg); 3302 %} 3303 3304 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3305 C2_MacroAssembler _masm(&cbuf); 3306 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3307 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3308 Assembler::byte, /*acquire*/ false, /*release*/ true, 3309 /*weak*/ false, noreg); 3310 %} 3311 3312 3313 // The only difference between aarch64_enc_cmpxchg and 3314 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3315 // CompareAndSwap sequence to serve as a barrier on acquiring a 3316 // lock. 3317 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3318 C2_MacroAssembler _masm(&cbuf); 3319 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3320 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3321 Assembler::xword, /*acquire*/ true, /*release*/ true, 3322 /*weak*/ false, noreg); 3323 %} 3324 3325 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3326 C2_MacroAssembler _masm(&cbuf); 3327 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3328 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3329 Assembler::word, /*acquire*/ true, /*release*/ true, 3330 /*weak*/ false, noreg); 3331 %} 3332 3333 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3334 C2_MacroAssembler _masm(&cbuf); 3335 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3336 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3337 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3338 /*weak*/ false, noreg); 3339 %} 3340 3341 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3342 C2_MacroAssembler _masm(&cbuf); 3343 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3344 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3345 Assembler::byte, /*acquire*/ true, /*release*/ true, 3346 /*weak*/ false, noreg); 3347 %} 3348 3349 // auxiliary used for CompareAndSwapX to set result register 3350 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3351 C2_MacroAssembler _masm(&cbuf); 3352 Register res_reg = as_Register($res$$reg); 3353 __ cset(res_reg, Assembler::EQ); 3354 %} 3355 3356 // prefetch encodings 3357 3358 enc_class aarch64_enc_prefetchw(memory mem) %{ 3359 C2_MacroAssembler _masm(&cbuf); 3360 Register base = as_Register($mem$$base); 3361 int index = $mem$$index; 3362 int scale = $mem$$scale; 3363 int disp = $mem$$disp; 3364 if (index == -1) { 3365 __ prfm(Address(base, disp), PSTL1KEEP); 3366 } else { 3367 Register index_reg = as_Register(index); 3368 if (disp == 0) { 3369 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3370 } else { 3371 __ lea(rscratch1, Address(base, disp)); 3372 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3373 } 3374 } 3375 %} 3376 3377 /// mov envcodings 3378 3379 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3380 C2_MacroAssembler _masm(&cbuf); 3381 uint32_t con = (uint32_t)$src$$constant; 3382 Register dst_reg = as_Register($dst$$reg); 3383 if (con == 0) { 3384 __ movw(dst_reg, zr); 3385 } else { 3386 __ movw(dst_reg, con); 3387 } 3388 %} 3389 3390 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3391 C2_MacroAssembler _masm(&cbuf); 3392 Register dst_reg = as_Register($dst$$reg); 3393 uint64_t con = (uint64_t)$src$$constant; 3394 if (con == 0) { 3395 __ mov(dst_reg, zr); 3396 } else { 3397 __ mov(dst_reg, con); 3398 } 3399 %} 3400 3401 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3402 C2_MacroAssembler _masm(&cbuf); 3403 Register dst_reg = as_Register($dst$$reg); 3404 address con = (address)$src$$constant; 3405 if (con == NULL || con == (address)1) { 3406 ShouldNotReachHere(); 3407 } else { 3408 relocInfo::relocType rtype = $src->constant_reloc(); 3409 if (rtype == relocInfo::oop_type) { 3410 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3411 } else if (rtype == relocInfo::metadata_type) { 3412 __ mov_metadata(dst_reg, (Metadata*)con); 3413 } else { 3414 assert(rtype == relocInfo::none, "unexpected reloc type"); 3415 if (con < (address)(uintptr_t)os::vm_page_size()) { 3416 __ mov(dst_reg, con); 3417 } else { 3418 uint64_t offset; 3419 __ adrp(dst_reg, con, offset); 3420 __ add(dst_reg, dst_reg, offset); 3421 } 3422 } 3423 } 3424 %} 3425 3426 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3427 C2_MacroAssembler _masm(&cbuf); 3428 Register dst_reg = as_Register($dst$$reg); 3429 __ mov(dst_reg, zr); 3430 %} 3431 3432 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3433 C2_MacroAssembler _masm(&cbuf); 3434 Register dst_reg = as_Register($dst$$reg); 3435 __ mov(dst_reg, (uint64_t)1); 3436 %} 3437 3438 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3439 C2_MacroAssembler _masm(&cbuf); 3440 __ load_byte_map_base($dst$$Register); 3441 %} 3442 3443 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3444 C2_MacroAssembler _masm(&cbuf); 3445 Register dst_reg = as_Register($dst$$reg); 3446 address con = (address)$src$$constant; 3447 if (con == NULL) { 3448 ShouldNotReachHere(); 3449 } else { 3450 relocInfo::relocType rtype = $src->constant_reloc(); 3451 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3452 __ set_narrow_oop(dst_reg, (jobject)con); 3453 } 3454 %} 3455 3456 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3457 C2_MacroAssembler _masm(&cbuf); 3458 Register dst_reg = as_Register($dst$$reg); 3459 __ mov(dst_reg, zr); 3460 %} 3461 3462 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3463 C2_MacroAssembler _masm(&cbuf); 3464 Register dst_reg = as_Register($dst$$reg); 3465 address con = (address)$src$$constant; 3466 if (con == NULL) { 3467 ShouldNotReachHere(); 3468 } else { 3469 relocInfo::relocType rtype = $src->constant_reloc(); 3470 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3471 __ set_narrow_klass(dst_reg, (Klass *)con); 3472 } 3473 %} 3474 3475 // arithmetic encodings 3476 3477 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3478 C2_MacroAssembler _masm(&cbuf); 3479 Register dst_reg = as_Register($dst$$reg); 3480 Register src_reg = as_Register($src1$$reg); 3481 int32_t con = (int32_t)$src2$$constant; 3482 // add has primary == 0, subtract has primary == 1 3483 if ($primary) { con = -con; } 3484 if (con < 0) { 3485 __ subw(dst_reg, src_reg, -con); 3486 } else { 3487 __ addw(dst_reg, src_reg, con); 3488 } 3489 %} 3490 3491 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3492 C2_MacroAssembler _masm(&cbuf); 3493 Register dst_reg = as_Register($dst$$reg); 3494 Register src_reg = as_Register($src1$$reg); 3495 int32_t con = (int32_t)$src2$$constant; 3496 // add has primary == 0, subtract has primary == 1 3497 if ($primary) { con = -con; } 3498 if (con < 0) { 3499 __ sub(dst_reg, src_reg, -con); 3500 } else { 3501 __ add(dst_reg, src_reg, con); 3502 } 3503 %} 3504 3505 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3506 C2_MacroAssembler _masm(&cbuf); 3507 Register dst_reg = as_Register($dst$$reg); 3508 Register src1_reg = as_Register($src1$$reg); 3509 Register src2_reg = as_Register($src2$$reg); 3510 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3511 %} 3512 3513 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3514 C2_MacroAssembler _masm(&cbuf); 3515 Register dst_reg = as_Register($dst$$reg); 3516 Register src1_reg = as_Register($src1$$reg); 3517 Register src2_reg = as_Register($src2$$reg); 3518 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3519 %} 3520 3521 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3522 C2_MacroAssembler _masm(&cbuf); 3523 Register dst_reg = as_Register($dst$$reg); 3524 Register src1_reg = as_Register($src1$$reg); 3525 Register src2_reg = as_Register($src2$$reg); 3526 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3527 %} 3528 3529 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3530 C2_MacroAssembler _masm(&cbuf); 3531 Register dst_reg = as_Register($dst$$reg); 3532 Register src1_reg = as_Register($src1$$reg); 3533 Register src2_reg = as_Register($src2$$reg); 3534 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3535 %} 3536 3537 // compare instruction encodings 3538 3539 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3540 C2_MacroAssembler _masm(&cbuf); 3541 Register reg1 = as_Register($src1$$reg); 3542 Register reg2 = as_Register($src2$$reg); 3543 __ cmpw(reg1, reg2); 3544 %} 3545 3546 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3547 C2_MacroAssembler _masm(&cbuf); 3548 Register reg = as_Register($src1$$reg); 3549 int32_t val = $src2$$constant; 3550 if (val >= 0) { 3551 __ subsw(zr, reg, val); 3552 } else { 3553 __ addsw(zr, reg, -val); 3554 } 3555 %} 3556 3557 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3558 C2_MacroAssembler _masm(&cbuf); 3559 Register reg1 = as_Register($src1$$reg); 3560 uint32_t val = (uint32_t)$src2$$constant; 3561 __ movw(rscratch1, val); 3562 __ cmpw(reg1, rscratch1); 3563 %} 3564 3565 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3566 C2_MacroAssembler _masm(&cbuf); 3567 Register reg1 = as_Register($src1$$reg); 3568 Register reg2 = as_Register($src2$$reg); 3569 __ cmp(reg1, reg2); 3570 %} 3571 3572 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3573 C2_MacroAssembler _masm(&cbuf); 3574 Register reg = as_Register($src1$$reg); 3575 int64_t val = $src2$$constant; 3576 if (val >= 0) { 3577 __ subs(zr, reg, val); 3578 } else if (val != -val) { 3579 __ adds(zr, reg, -val); 3580 } else { 3581 // aargh, Long.MIN_VALUE is a special case 3582 __ orr(rscratch1, zr, (uint64_t)val); 3583 __ subs(zr, reg, rscratch1); 3584 } 3585 %} 3586 3587 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3588 C2_MacroAssembler _masm(&cbuf); 3589 Register reg1 = as_Register($src1$$reg); 3590 uint64_t val = (uint64_t)$src2$$constant; 3591 __ mov(rscratch1, val); 3592 __ cmp(reg1, rscratch1); 3593 %} 3594 3595 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3596 C2_MacroAssembler _masm(&cbuf); 3597 Register reg1 = as_Register($src1$$reg); 3598 Register reg2 = as_Register($src2$$reg); 3599 __ cmp(reg1, reg2); 3600 %} 3601 3602 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3603 C2_MacroAssembler _masm(&cbuf); 3604 Register reg1 = as_Register($src1$$reg); 3605 Register reg2 = as_Register($src2$$reg); 3606 __ cmpw(reg1, reg2); 3607 %} 3608 3609 enc_class aarch64_enc_testp(iRegP src) %{ 3610 C2_MacroAssembler _masm(&cbuf); 3611 Register reg = as_Register($src$$reg); 3612 __ cmp(reg, zr); 3613 %} 3614 3615 enc_class aarch64_enc_testn(iRegN src) %{ 3616 C2_MacroAssembler _masm(&cbuf); 3617 Register reg = as_Register($src$$reg); 3618 __ cmpw(reg, zr); 3619 %} 3620 3621 enc_class aarch64_enc_b(label lbl) %{ 3622 C2_MacroAssembler _masm(&cbuf); 3623 Label *L = $lbl$$label; 3624 __ b(*L); 3625 %} 3626 3627 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3628 C2_MacroAssembler _masm(&cbuf); 3629 Label *L = $lbl$$label; 3630 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3631 %} 3632 3633 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3634 C2_MacroAssembler _masm(&cbuf); 3635 Label *L = $lbl$$label; 3636 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3637 %} 3638 3639 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3640 %{ 3641 Register sub_reg = as_Register($sub$$reg); 3642 Register super_reg = as_Register($super$$reg); 3643 Register temp_reg = as_Register($temp$$reg); 3644 Register result_reg = as_Register($result$$reg); 3645 3646 Label miss; 3647 C2_MacroAssembler _masm(&cbuf); 3648 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3649 NULL, &miss, 3650 /*set_cond_codes:*/ true); 3651 if ($primary) { 3652 __ mov(result_reg, zr); 3653 } 3654 __ bind(miss); 3655 %} 3656 3657 enc_class aarch64_enc_java_static_call(method meth) %{ 3658 C2_MacroAssembler _masm(&cbuf); 3659 3660 address addr = (address)$meth$$method; 3661 address call; 3662 if (!_method) { 3663 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3664 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3665 if (call == NULL) { 3666 ciEnv::current()->record_failure("CodeCache is full"); 3667 return; 3668 } 3669 } else { 3670 int method_index = resolved_method_index(cbuf); 3671 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3672 : static_call_Relocation::spec(method_index); 3673 call = __ trampoline_call(Address(addr, rspec), &cbuf); 3674 if (call == NULL) { 3675 ciEnv::current()->record_failure("CodeCache is full"); 3676 return; 3677 } 3678 // Emit stub for static call 3679 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3680 if (stub == NULL) { 3681 ciEnv::current()->record_failure("CodeCache is full"); 3682 return; 3683 } 3684 } 3685 3686 // Only non uncommon_trap calls need to reinitialize ptrue. 3687 if (Compile::current()->max_vector_size() >= 16 && uncommon_trap_request() == 0) { 3688 __ reinitialize_ptrue(); 3689 } 3690 %} 3691 3692 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3693 C2_MacroAssembler _masm(&cbuf); 3694 int method_index = resolved_method_index(cbuf); 3695 address call = __ ic_call((address)$meth$$method, method_index); 3696 if (call == NULL) { 3697 ciEnv::current()->record_failure("CodeCache is full"); 3698 return; 3699 } else if (Compile::current()->max_vector_size() >= 16) { 3700 __ reinitialize_ptrue(); 3701 } 3702 %} 3703 3704 enc_class aarch64_enc_call_epilog() %{ 3705 C2_MacroAssembler _masm(&cbuf); 3706 if (VerifyStackAtCalls) { 3707 // Check that stack depth is unchanged: find majik cookie on stack 3708 __ call_Unimplemented(); 3709 } 3710 %} 3711 3712 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3713 C2_MacroAssembler _masm(&cbuf); 3714 3715 // some calls to generated routines (arraycopy code) are scheduled 3716 // by C2 as runtime calls. if so we can call them using a br (they 3717 // will be in a reachable segment) otherwise we have to use a blr 3718 // which loads the absolute address into a register. 3719 address entry = (address)$meth$$method; 3720 CodeBlob *cb = CodeCache::find_blob(entry); 3721 if (cb) { 3722 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3723 if (call == NULL) { 3724 ciEnv::current()->record_failure("CodeCache is full"); 3725 return; 3726 } 3727 } else { 3728 Label retaddr; 3729 __ adr(rscratch2, retaddr); 3730 __ lea(rscratch1, RuntimeAddress(entry)); 3731 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3732 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3733 __ blr(rscratch1); 3734 __ bind(retaddr); 3735 __ add(sp, sp, 2 * wordSize); 3736 } 3737 if (Compile::current()->max_vector_size() >= 16) { 3738 __ reinitialize_ptrue(); 3739 } 3740 %} 3741 3742 enc_class aarch64_enc_rethrow() %{ 3743 C2_MacroAssembler _masm(&cbuf); 3744 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3745 %} 3746 3747 enc_class aarch64_enc_ret() %{ 3748 C2_MacroAssembler _masm(&cbuf); 3749#ifdef ASSERT 3750 if (Compile::current()->max_vector_size() >= 16) { 3751 __ verify_ptrue(); 3752 } 3753#endif 3754 __ ret(lr); 3755 %} 3756 3757 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3758 C2_MacroAssembler _masm(&cbuf); 3759 Register target_reg = as_Register($jump_target$$reg); 3760 __ br(target_reg); 3761 %} 3762 3763 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3764 C2_MacroAssembler _masm(&cbuf); 3765 Register target_reg = as_Register($jump_target$$reg); 3766 // exception oop should be in r0 3767 // ret addr has been popped into lr 3768 // callee expects it in r3 3769 __ mov(r3, lr); 3770 __ br(target_reg); 3771 %} 3772 3773 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3774 C2_MacroAssembler _masm(&cbuf); 3775 Register oop = as_Register($object$$reg); 3776 Register box = as_Register($box$$reg); 3777 Register disp_hdr = as_Register($tmp$$reg); 3778 Register tmp = as_Register($tmp2$$reg); 3779 Label cont; 3780 Label object_has_monitor; 3781 Label cas_failed; 3782 3783 assert_different_registers(oop, box, tmp, disp_hdr); 3784 3785 // Load markWord from object into displaced_header. 3786 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3787 3788 if (DiagnoseSyncOnValueBasedClasses != 0) { 3789 __ load_klass(tmp, oop); 3790 __ ldrw(tmp, Address(tmp, Klass::access_flags_offset())); 3791 __ tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS); 3792 __ br(Assembler::NE, cont); 3793 } 3794 3795 if (UseBiasedLocking && !UseOptoBiasInlining) { 3796 __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont); 3797 } 3798 3799 // Check for existing monitor 3800 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3801 3802 // Set tmp to be (markWord of object | UNLOCK_VALUE). 3803 __ orr(tmp, disp_hdr, markWord::unlocked_value); 3804 3805 // Initialize the box. (Must happen before we update the object mark!) 3806 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3807 3808 // Compare object markWord with an unlocked value (tmp) and if 3809 // equal exchange the stack address of our box with object markWord. 3810 // On failure disp_hdr contains the possibly locked markWord. 3811 __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true, 3812 /*release*/ true, /*weak*/ false, disp_hdr); 3813 __ br(Assembler::EQ, cont); 3814 3815 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3816 3817 // If the compare-and-exchange succeeded, then we found an unlocked 3818 // object, will have now locked it will continue at label cont 3819 3820 __ bind(cas_failed); 3821 // We did not see an unlocked object so try the fast recursive case. 3822 3823 // Check if the owner is self by comparing the value in the 3824 // markWord of object (disp_hdr) with the stack pointer. 3825 __ mov(rscratch1, sp); 3826 __ sub(disp_hdr, disp_hdr, rscratch1); 3827 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); 3828 // If condition is true we are cont and hence we can store 0 as the 3829 // displaced header in the box, which indicates that it is a recursive lock. 3830 __ ands(tmp/*==0?*/, disp_hdr, tmp); // Sets flags for result 3831 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3832 3833 __ b(cont); 3834 3835 // Handle existing monitor. 3836 __ bind(object_has_monitor); 3837 3838 // The object's monitor m is unlocked iff m->owner == NULL, 3839 // otherwise m->owner may contain a thread or a stack address. 3840 // 3841 // Try to CAS m->owner from NULL to current thread. 3842 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value)); 3843 __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true, 3844 /*release*/ true, /*weak*/ false, noreg); // Sets flags for result 3845 3846 // Store a non-null value into the box to avoid looking like a re-entrant 3847 // lock. The fast-path monitor unlock code checks for 3848 // markWord::monitor_value so use markWord::unused_mark which has the 3849 // relevant bit set, and also matches ObjectSynchronizer::enter. 3850 __ mov(tmp, (address)markWord::unused_mark().value()); 3851 __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3852 3853 __ bind(cont); 3854 // flag == EQ indicates success 3855 // flag == NE indicates failure 3856 %} 3857 3858 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3859 C2_MacroAssembler _masm(&cbuf); 3860 Register oop = as_Register($object$$reg); 3861 Register box = as_Register($box$$reg); 3862 Register disp_hdr = as_Register($tmp$$reg); 3863 Register tmp = as_Register($tmp2$$reg); 3864 Label cont; 3865 Label object_has_monitor; 3866 3867 assert_different_registers(oop, box, tmp, disp_hdr); 3868 3869 if (UseBiasedLocking && !UseOptoBiasInlining) { 3870 __ biased_locking_exit(oop, tmp, cont); 3871 } 3872 3873 // Find the lock address and load the displaced header from the stack. 3874 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3875 3876 // If the displaced header is 0, we have a recursive unlock. 3877 __ cmp(disp_hdr, zr); 3878 __ br(Assembler::EQ, cont); 3879 3880 // Handle existing monitor. 3881 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3882 __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor); 3883 3884 // Check if it is still a light weight lock, this is is true if we 3885 // see the stack address of the basicLock in the markWord of the 3886 // object. 3887 3888 __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false, 3889 /*release*/ true, /*weak*/ false, tmp); 3890 __ b(cont); 3891 3892 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3893 3894 // Handle existing monitor. 3895 __ bind(object_has_monitor); 3896 STATIC_ASSERT(markWord::monitor_value <= INT_MAX); 3897 __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor 3898 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3899 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3900 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3901 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3902 __ cmp(rscratch1, zr); // Sets flags for result 3903 __ br(Assembler::NE, cont); 3904 3905 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3906 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3907 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3908 __ cmp(rscratch1, zr); // Sets flags for result 3909 __ cbnz(rscratch1, cont); 3910 // need a release store here 3911 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3912 __ stlr(zr, tmp); // set unowned 3913 3914 __ bind(cont); 3915 // flag == EQ indicates success 3916 // flag == NE indicates failure 3917 %} 3918 3919%} 3920 3921//----------FRAME-------------------------------------------------------------- 3922// Definition of frame structure and management information. 3923// 3924// S T A C K L A Y O U T Allocators stack-slot number 3925// | (to get allocators register number 3926// G Owned by | | v add OptoReg::stack0()) 3927// r CALLER | | 3928// o | +--------+ pad to even-align allocators stack-slot 3929// w V | pad0 | numbers; owned by CALLER 3930// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3931// h ^ | in | 5 3932// | | args | 4 Holes in incoming args owned by SELF 3933// | | | | 3 3934// | | +--------+ 3935// V | | old out| Empty on Intel, window on Sparc 3936// | old |preserve| Must be even aligned. 3937// | SP-+--------+----> Matcher::_old_SP, even aligned 3938// | | in | 3 area for Intel ret address 3939// Owned by |preserve| Empty on Sparc. 3940// SELF +--------+ 3941// | | pad2 | 2 pad to align old SP 3942// | +--------+ 1 3943// | | locks | 0 3944// | +--------+----> OptoReg::stack0(), even aligned 3945// | | pad1 | 11 pad to align new SP 3946// | +--------+ 3947// | | | 10 3948// | | spills | 9 spills 3949// V | | 8 (pad0 slot for callee) 3950// -----------+--------+----> Matcher::_out_arg_limit, unaligned 3951// ^ | out | 7 3952// | | args | 6 Holes in outgoing args owned by CALLEE 3953// Owned by +--------+ 3954// CALLEE | new out| 6 Empty on Intel, window on Sparc 3955// | new |preserve| Must be even-aligned. 3956// | SP-+--------+----> Matcher::_new_SP, even aligned 3957// | | | 3958// 3959// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3960// known from SELF's arguments and the Java calling convention. 3961// Region 6-7 is determined per call site. 3962// Note 2: If the calling convention leaves holes in the incoming argument 3963// area, those holes are owned by SELF. Holes in the outgoing area 3964// are owned by the CALLEE. Holes should not be nessecary in the 3965// incoming area, as the Java calling convention is completely under 3966// the control of the AD file. Doubles can be sorted and packed to 3967// avoid holes. Holes in the outgoing arguments may be nessecary for 3968// varargs C calling conventions. 3969// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3970// even aligned with pad0 as needed. 3971// Region 6 is even aligned. Region 6-7 is NOT even aligned; 3972// (the latter is true on Intel but is it false on AArch64?) 3973// region 6-11 is even aligned; it may be padded out more so that 3974// the region from SP to FP meets the minimum stack alignment. 3975// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3976// alignment. Region 11, pad1, may be dynamically extended so that 3977// SP meets the minimum alignment. 3978 3979frame %{ 3980 // These three registers define part of the calling convention 3981 // between compiled code and the interpreter. 3982 3983 // Inline Cache Register or Method for I2C. 3984 inline_cache_reg(R12); 3985 3986 // Number of stack slots consumed by locking an object 3987 sync_stack_slots(2); 3988 3989 // Compiled code's Frame Pointer 3990 frame_pointer(R31); 3991 3992 // Interpreter stores its frame pointer in a register which is 3993 // stored to the stack by I2CAdaptors. 3994 // I2CAdaptors convert from interpreted java to compiled java. 3995 interpreter_frame_pointer(R29); 3996 3997 // Stack alignment requirement 3998 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3999 4000 // Number of outgoing stack slots killed above the out_preserve_stack_slots 4001 // for calls to C. Supports the var-args backing area for register parms. 4002 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 4003 4004 // The after-PROLOG location of the return address. Location of 4005 // return address specifies a type (REG or STACK) and a number 4006 // representing the register number (i.e. - use a register name) or 4007 // stack slot. 4008 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 4009 // Otherwise, it is above the locks and verification slot and alignment word 4010 // TODO this may well be correct but need to check why that - 2 is there 4011 // ppc port uses 0 but we definitely need to allow for fixed_slots 4012 // which folds in the space used for monitors 4013 return_addr(STACK - 2 + 4014 align_up((Compile::current()->in_preserve_stack_slots() + 4015 Compile::current()->fixed_slots()), 4016 stack_alignment_in_slots())); 4017 4018 // Location of compiled Java return values. Same as C for now. 4019 return_value 4020 %{ 4021 // TODO do we allow ideal_reg == Op_RegN??? 4022 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 4023 "only return normal values"); 4024 4025 static const int lo[Op_RegL + 1] = { // enum name 4026 0, // Op_Node 4027 0, // Op_Set 4028 R0_num, // Op_RegN 4029 R0_num, // Op_RegI 4030 R0_num, // Op_RegP 4031 V0_num, // Op_RegF 4032 V0_num, // Op_RegD 4033 R0_num // Op_RegL 4034 }; 4035 4036 static const int hi[Op_RegL + 1] = { // enum name 4037 0, // Op_Node 4038 0, // Op_Set 4039 OptoReg::Bad, // Op_RegN 4040 OptoReg::Bad, // Op_RegI 4041 R0_H_num, // Op_RegP 4042 OptoReg::Bad, // Op_RegF 4043 V0_H_num, // Op_RegD 4044 R0_H_num // Op_RegL 4045 }; 4046 4047 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4048 %} 4049%} 4050 4051//----------ATTRIBUTES--------------------------------------------------------- 4052//----------Operand Attributes------------------------------------------------- 4053op_attrib op_cost(1); // Required cost attribute 4054 4055//----------Instruction Attributes--------------------------------------------- 4056ins_attrib ins_cost(INSN_COST); // Required cost attribute 4057ins_attrib ins_size(32); // Required size attribute (in bits) 4058ins_attrib ins_short_branch(0); // Required flag: is this instruction 4059 // a non-matching short branch variant 4060 // of some long branch? 4061ins_attrib ins_alignment(4); // Required alignment attribute (must 4062 // be a power of 2) specifies the 4063 // alignment that some part of the 4064 // instruction (not necessarily the 4065 // start) requires. If > 1, a 4066 // compute_padding() function must be 4067 // provided for the instruction 4068 4069//----------OPERANDS----------------------------------------------------------- 4070// Operand definitions must precede instruction definitions for correct parsing 4071// in the ADLC because operands constitute user defined types which are used in 4072// instruction definitions. 4073 4074//----------Simple Operands---------------------------------------------------- 4075 4076// Integer operands 32 bit 4077// 32 bit immediate 4078operand immI() 4079%{ 4080 match(ConI); 4081 4082 op_cost(0); 4083 format %{ %} 4084 interface(CONST_INTER); 4085%} 4086 4087// 32 bit zero 4088operand immI0() 4089%{ 4090 predicate(n->get_int() == 0); 4091 match(ConI); 4092 4093 op_cost(0); 4094 format %{ %} 4095 interface(CONST_INTER); 4096%} 4097 4098// 32 bit unit increment 4099operand immI_1() 4100%{ 4101 predicate(n->get_int() == 1); 4102 match(ConI); 4103 4104 op_cost(0); 4105 format %{ %} 4106 interface(CONST_INTER); 4107%} 4108 4109// 32 bit unit decrement 4110operand immI_M1() 4111%{ 4112 predicate(n->get_int() == -1); 4113 match(ConI); 4114 4115 op_cost(0); 4116 format %{ %} 4117 interface(CONST_INTER); 4118%} 4119 4120// Shift values for add/sub extension shift 4121operand immIExt() 4122%{ 4123 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 4124 match(ConI); 4125 4126 op_cost(0); 4127 format %{ %} 4128 interface(CONST_INTER); 4129%} 4130 4131operand immI_le_4() 4132%{ 4133 predicate(n->get_int() <= 4); 4134 match(ConI); 4135 4136 op_cost(0); 4137 format %{ %} 4138 interface(CONST_INTER); 4139%} 4140 4141operand immI_31() 4142%{ 4143 predicate(n->get_int() == 31); 4144 match(ConI); 4145 4146 op_cost(0); 4147 format %{ %} 4148 interface(CONST_INTER); 4149%} 4150 4151operand immI_2() 4152%{ 4153 predicate(n->get_int() == 2); 4154 match(ConI); 4155 4156 op_cost(0); 4157 format %{ %} 4158 interface(CONST_INTER); 4159%} 4160 4161operand immI_4() 4162%{ 4163 predicate(n->get_int() == 4); 4164 match(ConI); 4165 4166 op_cost(0); 4167 format %{ %} 4168 interface(CONST_INTER); 4169%} 4170 4171operand immI_8() 4172%{ 4173 predicate(n->get_int() == 8); 4174 match(ConI); 4175 4176 op_cost(0); 4177 format %{ %} 4178 interface(CONST_INTER); 4179%} 4180 4181operand immI_16() 4182%{ 4183 predicate(n->get_int() == 16); 4184 match(ConI); 4185 4186 op_cost(0); 4187 format %{ %} 4188 interface(CONST_INTER); 4189%} 4190 4191operand immI_24() 4192%{ 4193 predicate(n->get_int() == 24); 4194 match(ConI); 4195 4196 op_cost(0); 4197 format %{ %} 4198 interface(CONST_INTER); 4199%} 4200 4201operand immI_32() 4202%{ 4203 predicate(n->get_int() == 32); 4204 match(ConI); 4205 4206 op_cost(0); 4207 format %{ %} 4208 interface(CONST_INTER); 4209%} 4210 4211operand immI_48() 4212%{ 4213 predicate(n->get_int() == 48); 4214 match(ConI); 4215 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219%} 4220 4221operand immI_56() 4222%{ 4223 predicate(n->get_int() == 56); 4224 match(ConI); 4225 4226 op_cost(0); 4227 format %{ %} 4228 interface(CONST_INTER); 4229%} 4230 4231operand immI_63() 4232%{ 4233 predicate(n->get_int() == 63); 4234 match(ConI); 4235 4236 op_cost(0); 4237 format %{ %} 4238 interface(CONST_INTER); 4239%} 4240 4241operand immI_64() 4242%{ 4243 predicate(n->get_int() == 64); 4244 match(ConI); 4245 4246 op_cost(0); 4247 format %{ %} 4248 interface(CONST_INTER); 4249%} 4250 4251operand immI_255() 4252%{ 4253 predicate(n->get_int() == 255); 4254 match(ConI); 4255 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259%} 4260 4261operand immI_65535() 4262%{ 4263 predicate(n->get_int() == 65535); 4264 match(ConI); 4265 4266 op_cost(0); 4267 format %{ %} 4268 interface(CONST_INTER); 4269%} 4270 4271operand immL_255() 4272%{ 4273 predicate(n->get_long() == 255L); 4274 match(ConL); 4275 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279%} 4280 4281operand immL_65535() 4282%{ 4283 predicate(n->get_long() == 65535L); 4284 match(ConL); 4285 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289%} 4290 4291operand immL_4294967295() 4292%{ 4293 predicate(n->get_long() == 4294967295L); 4294 match(ConL); 4295 4296 op_cost(0); 4297 format %{ %} 4298 interface(CONST_INTER); 4299%} 4300 4301operand immL_bitmask() 4302%{ 4303 predicate((n->get_long() != 0) 4304 && ((n->get_long() & 0xc000000000000000l) == 0) 4305 && is_power_of_2(n->get_long() + 1)); 4306 match(ConL); 4307 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311%} 4312 4313operand immI_bitmask() 4314%{ 4315 predicate((n->get_int() != 0) 4316 && ((n->get_int() & 0xc0000000) == 0) 4317 && is_power_of_2(n->get_int() + 1)); 4318 match(ConI); 4319 4320 op_cost(0); 4321 format %{ %} 4322 interface(CONST_INTER); 4323%} 4324 4325operand immL_positive_bitmaskI() 4326%{ 4327 predicate((n->get_long() != 0) 4328 && ((julong)n->get_long() < 0x80000000ULL) 4329 && is_power_of_2(n->get_long() + 1)); 4330 match(ConL); 4331 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335%} 4336 4337// Scale values for scaled offset addressing modes (up to long but not quad) 4338operand immIScale() 4339%{ 4340 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4341 match(ConI); 4342 4343 op_cost(0); 4344 format %{ %} 4345 interface(CONST_INTER); 4346%} 4347 4348// 26 bit signed offset -- for pc-relative branches 4349operand immI26() 4350%{ 4351 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4352 match(ConI); 4353 4354 op_cost(0); 4355 format %{ %} 4356 interface(CONST_INTER); 4357%} 4358 4359// 19 bit signed offset -- for pc-relative loads 4360operand immI19() 4361%{ 4362 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4363 match(ConI); 4364 4365 op_cost(0); 4366 format %{ %} 4367 interface(CONST_INTER); 4368%} 4369 4370// 12 bit unsigned offset -- for base plus immediate loads 4371operand immIU12() 4372%{ 4373 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4374 match(ConI); 4375 4376 op_cost(0); 4377 format %{ %} 4378 interface(CONST_INTER); 4379%} 4380 4381operand immLU12() 4382%{ 4383 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4384 match(ConL); 4385 4386 op_cost(0); 4387 format %{ %} 4388 interface(CONST_INTER); 4389%} 4390 4391// Offset for scaled or unscaled immediate loads and stores 4392operand immIOffset() 4393%{ 4394 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4395 match(ConI); 4396 4397 op_cost(0); 4398 format %{ %} 4399 interface(CONST_INTER); 4400%} 4401 4402operand immIOffset1() 4403%{ 4404 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4405 match(ConI); 4406 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410%} 4411 4412operand immIOffset2() 4413%{ 4414 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4415 match(ConI); 4416 4417 op_cost(0); 4418 format %{ %} 4419 interface(CONST_INTER); 4420%} 4421 4422operand immIOffset4() 4423%{ 4424 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4425 match(ConI); 4426 4427 op_cost(0); 4428 format %{ %} 4429 interface(CONST_INTER); 4430%} 4431 4432operand immIOffset8() 4433%{ 4434 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4435 match(ConI); 4436 4437 op_cost(0); 4438 format %{ %} 4439 interface(CONST_INTER); 4440%} 4441 4442operand immIOffset16() 4443%{ 4444 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4445 match(ConI); 4446 4447 op_cost(0); 4448 format %{ %} 4449 interface(CONST_INTER); 4450%} 4451 4452operand immLoffset() 4453%{ 4454 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4455 match(ConL); 4456 4457 op_cost(0); 4458 format %{ %} 4459 interface(CONST_INTER); 4460%} 4461 4462operand immLoffset1() 4463%{ 4464 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4465 match(ConL); 4466 4467 op_cost(0); 4468 format %{ %} 4469 interface(CONST_INTER); 4470%} 4471 4472operand immLoffset2() 4473%{ 4474 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4475 match(ConL); 4476 4477 op_cost(0); 4478 format %{ %} 4479 interface(CONST_INTER); 4480%} 4481 4482operand immLoffset4() 4483%{ 4484 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4485 match(ConL); 4486 4487 op_cost(0); 4488 format %{ %} 4489 interface(CONST_INTER); 4490%} 4491 4492operand immLoffset8() 4493%{ 4494 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4495 match(ConL); 4496 4497 op_cost(0); 4498 format %{ %} 4499 interface(CONST_INTER); 4500%} 4501 4502operand immLoffset16() 4503%{ 4504 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4505 match(ConL); 4506 4507 op_cost(0); 4508 format %{ %} 4509 interface(CONST_INTER); 4510%} 4511 4512// 8 bit signed value. 4513operand immI8() 4514%{ 4515 predicate(n->get_int() <= 127 && n->get_int() >= -128); 4516 match(ConI); 4517 4518 op_cost(0); 4519 format %{ %} 4520 interface(CONST_INTER); 4521%} 4522 4523// 8 bit signed value (simm8), or #simm8 LSL 8. 4524operand immI8_shift8() 4525%{ 4526 predicate((n->get_int() <= 127 && n->get_int() >= -128) || 4527 (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0)); 4528 match(ConI); 4529 4530 op_cost(0); 4531 format %{ %} 4532 interface(CONST_INTER); 4533%} 4534 4535// 8 bit signed value (simm8), or #simm8 LSL 8. 4536operand immL8_shift8() 4537%{ 4538 predicate((n->get_long() <= 127 && n->get_long() >= -128) || 4539 (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0)); 4540 match(ConL); 4541 4542 op_cost(0); 4543 format %{ %} 4544 interface(CONST_INTER); 4545%} 4546 4547// 32 bit integer valid for add sub immediate 4548operand immIAddSub() 4549%{ 4550 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4551 match(ConI); 4552 op_cost(0); 4553 format %{ %} 4554 interface(CONST_INTER); 4555%} 4556 4557// 32 bit unsigned integer valid for logical immediate 4558// TODO -- check this is right when e.g the mask is 0x80000000 4559operand immILog() 4560%{ 4561 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4562 match(ConI); 4563 4564 op_cost(0); 4565 format %{ %} 4566 interface(CONST_INTER); 4567%} 4568 4569// Integer operands 64 bit 4570// 64 bit immediate 4571operand immL() 4572%{ 4573 match(ConL); 4574 4575 op_cost(0); 4576 format %{ %} 4577 interface(CONST_INTER); 4578%} 4579 4580// 64 bit zero 4581operand immL0() 4582%{ 4583 predicate(n->get_long() == 0); 4584 match(ConL); 4585 4586 op_cost(0); 4587 format %{ %} 4588 interface(CONST_INTER); 4589%} 4590 4591// 64 bit unit increment 4592operand immL_1() 4593%{ 4594 predicate(n->get_long() == 1); 4595 match(ConL); 4596 4597 op_cost(0); 4598 format %{ %} 4599 interface(CONST_INTER); 4600%} 4601 4602// 64 bit unit decrement 4603operand immL_M1() 4604%{ 4605 predicate(n->get_long() == -1); 4606 match(ConL); 4607 4608 op_cost(0); 4609 format %{ %} 4610 interface(CONST_INTER); 4611%} 4612 4613// 32 bit offset of pc in thread anchor 4614 4615operand immL_pc_off() 4616%{ 4617 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4618 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4619 match(ConL); 4620 4621 op_cost(0); 4622 format %{ %} 4623 interface(CONST_INTER); 4624%} 4625 4626// 64 bit integer valid for add sub immediate 4627operand immLAddSub() 4628%{ 4629 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4630 match(ConL); 4631 op_cost(0); 4632 format %{ %} 4633 interface(CONST_INTER); 4634%} 4635 4636// 64 bit integer valid for logical immediate 4637operand immLLog() 4638%{ 4639 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4640 match(ConL); 4641 op_cost(0); 4642 format %{ %} 4643 interface(CONST_INTER); 4644%} 4645 4646// Long Immediate: low 32-bit mask 4647operand immL_32bits() 4648%{ 4649 predicate(n->get_long() == 0xFFFFFFFFL); 4650 match(ConL); 4651 op_cost(0); 4652 format %{ %} 4653 interface(CONST_INTER); 4654%} 4655 4656// Pointer operands 4657// Pointer Immediate 4658operand immP() 4659%{ 4660 match(ConP); 4661 4662 op_cost(0); 4663 format %{ %} 4664 interface(CONST_INTER); 4665%} 4666 4667// NULL Pointer Immediate 4668operand immP0() 4669%{ 4670 predicate(n->get_ptr() == 0); 4671 match(ConP); 4672 4673 op_cost(0); 4674 format %{ %} 4675 interface(CONST_INTER); 4676%} 4677 4678// Pointer Immediate One 4679// this is used in object initialization (initial object header) 4680operand immP_1() 4681%{ 4682 predicate(n->get_ptr() == 1); 4683 match(ConP); 4684 4685 op_cost(0); 4686 format %{ %} 4687 interface(CONST_INTER); 4688%} 4689 4690// Card Table Byte Map Base 4691operand immByteMapBase() 4692%{ 4693 // Get base of card map 4694 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4695 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4696 match(ConP); 4697 4698 op_cost(0); 4699 format %{ %} 4700 interface(CONST_INTER); 4701%} 4702 4703// Pointer Immediate Minus One 4704// this is used when we want to write the current PC to the thread anchor 4705operand immP_M1() 4706%{ 4707 predicate(n->get_ptr() == -1); 4708 match(ConP); 4709 4710 op_cost(0); 4711 format %{ %} 4712 interface(CONST_INTER); 4713%} 4714 4715// Pointer Immediate Minus Two 4716// this is used when we want to write the current PC to the thread anchor 4717operand immP_M2() 4718%{ 4719 predicate(n->get_ptr() == -2); 4720 match(ConP); 4721 4722 op_cost(0); 4723 format %{ %} 4724 interface(CONST_INTER); 4725%} 4726 4727// Float and Double operands 4728// Double Immediate 4729operand immD() 4730%{ 4731 match(ConD); 4732 op_cost(0); 4733 format %{ %} 4734 interface(CONST_INTER); 4735%} 4736 4737// Double Immediate: +0.0d 4738operand immD0() 4739%{ 4740 predicate(jlong_cast(n->getd()) == 0); 4741 match(ConD); 4742 4743 op_cost(0); 4744 format %{ %} 4745 interface(CONST_INTER); 4746%} 4747 4748// constant 'double +0.0'. 4749operand immDPacked() 4750%{ 4751 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4752 match(ConD); 4753 op_cost(0); 4754 format %{ %} 4755 interface(CONST_INTER); 4756%} 4757 4758// Float Immediate 4759operand immF() 4760%{ 4761 match(ConF); 4762 op_cost(0); 4763 format %{ %} 4764 interface(CONST_INTER); 4765%} 4766 4767// Float Immediate: +0.0f. 4768operand immF0() 4769%{ 4770 predicate(jint_cast(n->getf()) == 0); 4771 match(ConF); 4772 4773 op_cost(0); 4774 format %{ %} 4775 interface(CONST_INTER); 4776%} 4777 4778// 4779operand immFPacked() 4780%{ 4781 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4782 match(ConF); 4783 op_cost(0); 4784 format %{ %} 4785 interface(CONST_INTER); 4786%} 4787 4788// Narrow pointer operands 4789// Narrow Pointer Immediate 4790operand immN() 4791%{ 4792 match(ConN); 4793 4794 op_cost(0); 4795 format %{ %} 4796 interface(CONST_INTER); 4797%} 4798 4799// Narrow NULL Pointer Immediate 4800operand immN0() 4801%{ 4802 predicate(n->get_narrowcon() == 0); 4803 match(ConN); 4804 4805 op_cost(0); 4806 format %{ %} 4807 interface(CONST_INTER); 4808%} 4809 4810operand immNKlass() 4811%{ 4812 match(ConNKlass); 4813 4814 op_cost(0); 4815 format %{ %} 4816 interface(CONST_INTER); 4817%} 4818 4819// Integer 32 bit Register Operands 4820// Integer 32 bitRegister (excludes SP) 4821operand iRegI() 4822%{ 4823 constraint(ALLOC_IN_RC(any_reg32)); 4824 match(RegI); 4825 match(iRegINoSp); 4826 op_cost(0); 4827 format %{ %} 4828 interface(REG_INTER); 4829%} 4830 4831// Integer 32 bit Register not Special 4832operand iRegINoSp() 4833%{ 4834 constraint(ALLOC_IN_RC(no_special_reg32)); 4835 match(RegI); 4836 op_cost(0); 4837 format %{ %} 4838 interface(REG_INTER); 4839%} 4840 4841// Integer 64 bit Register Operands 4842// Integer 64 bit Register (includes SP) 4843operand iRegL() 4844%{ 4845 constraint(ALLOC_IN_RC(any_reg)); 4846 match(RegL); 4847 match(iRegLNoSp); 4848 op_cost(0); 4849 format %{ %} 4850 interface(REG_INTER); 4851%} 4852 4853// Integer 64 bit Register not Special 4854operand iRegLNoSp() 4855%{ 4856 constraint(ALLOC_IN_RC(no_special_reg)); 4857 match(RegL); 4858 match(iRegL_R0); 4859 format %{ %} 4860 interface(REG_INTER); 4861%} 4862 4863// Pointer Register Operands 4864// Pointer Register 4865operand iRegP() 4866%{ 4867 constraint(ALLOC_IN_RC(ptr_reg)); 4868 match(RegP); 4869 match(iRegPNoSp); 4870 match(iRegP_R0); 4871 //match(iRegP_R2); 4872 //match(iRegP_R4); 4873 //match(iRegP_R5); 4874 match(thread_RegP); 4875 op_cost(0); 4876 format %{ %} 4877 interface(REG_INTER); 4878%} 4879 4880// Pointer 64 bit Register not Special 4881operand iRegPNoSp() 4882%{ 4883 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4884 match(RegP); 4885 // match(iRegP); 4886 // match(iRegP_R0); 4887 // match(iRegP_R2); 4888 // match(iRegP_R4); 4889 // match(iRegP_R5); 4890 // match(thread_RegP); 4891 op_cost(0); 4892 format %{ %} 4893 interface(REG_INTER); 4894%} 4895 4896// Pointer 64 bit Register R0 only 4897operand iRegP_R0() 4898%{ 4899 constraint(ALLOC_IN_RC(r0_reg)); 4900 match(RegP); 4901 // match(iRegP); 4902 match(iRegPNoSp); 4903 op_cost(0); 4904 format %{ %} 4905 interface(REG_INTER); 4906%} 4907 4908// Pointer 64 bit Register R1 only 4909operand iRegP_R1() 4910%{ 4911 constraint(ALLOC_IN_RC(r1_reg)); 4912 match(RegP); 4913 // match(iRegP); 4914 match(iRegPNoSp); 4915 op_cost(0); 4916 format %{ %} 4917 interface(REG_INTER); 4918%} 4919 4920// Pointer 64 bit Register R2 only 4921operand iRegP_R2() 4922%{ 4923 constraint(ALLOC_IN_RC(r2_reg)); 4924 match(RegP); 4925 // match(iRegP); 4926 match(iRegPNoSp); 4927 op_cost(0); 4928 format %{ %} 4929 interface(REG_INTER); 4930%} 4931 4932// Pointer 64 bit Register R3 only 4933operand iRegP_R3() 4934%{ 4935 constraint(ALLOC_IN_RC(r3_reg)); 4936 match(RegP); 4937 // match(iRegP); 4938 match(iRegPNoSp); 4939 op_cost(0); 4940 format %{ %} 4941 interface(REG_INTER); 4942%} 4943 4944// Pointer 64 bit Register R4 only 4945operand iRegP_R4() 4946%{ 4947 constraint(ALLOC_IN_RC(r4_reg)); 4948 match(RegP); 4949 // match(iRegP); 4950 match(iRegPNoSp); 4951 op_cost(0); 4952 format %{ %} 4953 interface(REG_INTER); 4954%} 4955 4956// Pointer 64 bit Register R5 only 4957operand iRegP_R5() 4958%{ 4959 constraint(ALLOC_IN_RC(r5_reg)); 4960 match(RegP); 4961 // match(iRegP); 4962 match(iRegPNoSp); 4963 op_cost(0); 4964 format %{ %} 4965 interface(REG_INTER); 4966%} 4967 4968// Pointer 64 bit Register R10 only 4969operand iRegP_R10() 4970%{ 4971 constraint(ALLOC_IN_RC(r10_reg)); 4972 match(RegP); 4973 // match(iRegP); 4974 match(iRegPNoSp); 4975 op_cost(0); 4976 format %{ %} 4977 interface(REG_INTER); 4978%} 4979 4980// Long 64 bit Register R0 only 4981operand iRegL_R0() 4982%{ 4983 constraint(ALLOC_IN_RC(r0_reg)); 4984 match(RegL); 4985 match(iRegLNoSp); 4986 op_cost(0); 4987 format %{ %} 4988 interface(REG_INTER); 4989%} 4990 4991// Long 64 bit Register R2 only 4992operand iRegL_R2() 4993%{ 4994 constraint(ALLOC_IN_RC(r2_reg)); 4995 match(RegL); 4996 match(iRegLNoSp); 4997 op_cost(0); 4998 format %{ %} 4999 interface(REG_INTER); 5000%} 5001 5002// Long 64 bit Register R3 only 5003operand iRegL_R3() 5004%{ 5005 constraint(ALLOC_IN_RC(r3_reg)); 5006 match(RegL); 5007 match(iRegLNoSp); 5008 op_cost(0); 5009 format %{ %} 5010 interface(REG_INTER); 5011%} 5012 5013// Long 64 bit Register R11 only 5014operand iRegL_R11() 5015%{ 5016 constraint(ALLOC_IN_RC(r11_reg)); 5017 match(RegL); 5018 match(iRegLNoSp); 5019 op_cost(0); 5020 format %{ %} 5021 interface(REG_INTER); 5022%} 5023 5024// Pointer 64 bit Register FP only 5025operand iRegP_FP() 5026%{ 5027 constraint(ALLOC_IN_RC(fp_reg)); 5028 match(RegP); 5029 // match(iRegP); 5030 op_cost(0); 5031 format %{ %} 5032 interface(REG_INTER); 5033%} 5034 5035// Register R0 only 5036operand iRegI_R0() 5037%{ 5038 constraint(ALLOC_IN_RC(int_r0_reg)); 5039 match(RegI); 5040 match(iRegINoSp); 5041 op_cost(0); 5042 format %{ %} 5043 interface(REG_INTER); 5044%} 5045 5046// Register R2 only 5047operand iRegI_R2() 5048%{ 5049 constraint(ALLOC_IN_RC(int_r2_reg)); 5050 match(RegI); 5051 match(iRegINoSp); 5052 op_cost(0); 5053 format %{ %} 5054 interface(REG_INTER); 5055%} 5056 5057// Register R3 only 5058operand iRegI_R3() 5059%{ 5060 constraint(ALLOC_IN_RC(int_r3_reg)); 5061 match(RegI); 5062 match(iRegINoSp); 5063 op_cost(0); 5064 format %{ %} 5065 interface(REG_INTER); 5066%} 5067 5068 5069// Register R4 only 5070operand iRegI_R4() 5071%{ 5072 constraint(ALLOC_IN_RC(int_r4_reg)); 5073 match(RegI); 5074 match(iRegINoSp); 5075 op_cost(0); 5076 format %{ %} 5077 interface(REG_INTER); 5078%} 5079 5080 5081// Pointer Register Operands 5082// Narrow Pointer Register 5083operand iRegN() 5084%{ 5085 constraint(ALLOC_IN_RC(any_reg32)); 5086 match(RegN); 5087 match(iRegNNoSp); 5088 op_cost(0); 5089 format %{ %} 5090 interface(REG_INTER); 5091%} 5092 5093operand iRegN_R0() 5094%{ 5095 constraint(ALLOC_IN_RC(r0_reg)); 5096 match(iRegN); 5097 op_cost(0); 5098 format %{ %} 5099 interface(REG_INTER); 5100%} 5101 5102operand iRegN_R2() 5103%{ 5104 constraint(ALLOC_IN_RC(r2_reg)); 5105 match(iRegN); 5106 op_cost(0); 5107 format %{ %} 5108 interface(REG_INTER); 5109%} 5110 5111operand iRegN_R3() 5112%{ 5113 constraint(ALLOC_IN_RC(r3_reg)); 5114 match(iRegN); 5115 op_cost(0); 5116 format %{ %} 5117 interface(REG_INTER); 5118%} 5119 5120// Integer 64 bit Register not Special 5121operand iRegNNoSp() 5122%{ 5123 constraint(ALLOC_IN_RC(no_special_reg32)); 5124 match(RegN); 5125 op_cost(0); 5126 format %{ %} 5127 interface(REG_INTER); 5128%} 5129 5130// heap base register -- used for encoding immN0 5131 5132operand iRegIHeapbase() 5133%{ 5134 constraint(ALLOC_IN_RC(heapbase_reg)); 5135 match(RegI); 5136 op_cost(0); 5137 format %{ %} 5138 interface(REG_INTER); 5139%} 5140 5141// Float Register 5142// Float register operands 5143operand vRegF() 5144%{ 5145 constraint(ALLOC_IN_RC(float_reg)); 5146 match(RegF); 5147 5148 op_cost(0); 5149 format %{ %} 5150 interface(REG_INTER); 5151%} 5152 5153// Double Register 5154// Double register operands 5155operand vRegD() 5156%{ 5157 constraint(ALLOC_IN_RC(double_reg)); 5158 match(RegD); 5159 5160 op_cost(0); 5161 format %{ %} 5162 interface(REG_INTER); 5163%} 5164 5165// Generic vector class. This will be used for 5166// all vector operands, including NEON and SVE, 5167// but currently only used for SVE VecA. 5168operand vReg() 5169%{ 5170 constraint(ALLOC_IN_RC(vectora_reg)); 5171 match(VecA); 5172 op_cost(0); 5173 format %{ %} 5174 interface(REG_INTER); 5175%} 5176 5177operand vecD() 5178%{ 5179 constraint(ALLOC_IN_RC(vectord_reg)); 5180 match(VecD); 5181 5182 op_cost(0); 5183 format %{ %} 5184 interface(REG_INTER); 5185%} 5186 5187operand vecX() 5188%{ 5189 constraint(ALLOC_IN_RC(vectorx_reg)); 5190 match(VecX); 5191 5192 op_cost(0); 5193 format %{ %} 5194 interface(REG_INTER); 5195%} 5196 5197operand vRegD_V0() 5198%{ 5199 constraint(ALLOC_IN_RC(v0_reg)); 5200 match(RegD); 5201 op_cost(0); 5202 format %{ %} 5203 interface(REG_INTER); 5204%} 5205 5206operand vRegD_V1() 5207%{ 5208 constraint(ALLOC_IN_RC(v1_reg)); 5209 match(RegD); 5210 op_cost(0); 5211 format %{ %} 5212 interface(REG_INTER); 5213%} 5214 5215operand vRegD_V2() 5216%{ 5217 constraint(ALLOC_IN_RC(v2_reg)); 5218 match(RegD); 5219 op_cost(0); 5220 format %{ %} 5221 interface(REG_INTER); 5222%} 5223 5224operand vRegD_V3() 5225%{ 5226 constraint(ALLOC_IN_RC(v3_reg)); 5227 match(RegD); 5228 op_cost(0); 5229 format %{ %} 5230 interface(REG_INTER); 5231%} 5232 5233operand vRegD_V4() 5234%{ 5235 constraint(ALLOC_IN_RC(v4_reg)); 5236 match(RegD); 5237 op_cost(0); 5238 format %{ %} 5239 interface(REG_INTER); 5240%} 5241 5242operand vRegD_V5() 5243%{ 5244 constraint(ALLOC_IN_RC(v5_reg)); 5245 match(RegD); 5246 op_cost(0); 5247 format %{ %} 5248 interface(REG_INTER); 5249%} 5250 5251operand vRegD_V6() 5252%{ 5253 constraint(ALLOC_IN_RC(v6_reg)); 5254 match(RegD); 5255 op_cost(0); 5256 format %{ %} 5257 interface(REG_INTER); 5258%} 5259 5260operand vRegD_V7() 5261%{ 5262 constraint(ALLOC_IN_RC(v7_reg)); 5263 match(RegD); 5264 op_cost(0); 5265 format %{ %} 5266 interface(REG_INTER); 5267%} 5268 5269operand vRegD_V8() 5270%{ 5271 constraint(ALLOC_IN_RC(v8_reg)); 5272 match(RegD); 5273 op_cost(0); 5274 format %{ %} 5275 interface(REG_INTER); 5276%} 5277 5278operand vRegD_V9() 5279%{ 5280 constraint(ALLOC_IN_RC(v9_reg)); 5281 match(RegD); 5282 op_cost(0); 5283 format %{ %} 5284 interface(REG_INTER); 5285%} 5286 5287operand vRegD_V10() 5288%{ 5289 constraint(ALLOC_IN_RC(v10_reg)); 5290 match(RegD); 5291 op_cost(0); 5292 format %{ %} 5293 interface(REG_INTER); 5294%} 5295 5296operand vRegD_V11() 5297%{ 5298 constraint(ALLOC_IN_RC(v11_reg)); 5299 match(RegD); 5300 op_cost(0); 5301 format %{ %} 5302 interface(REG_INTER); 5303%} 5304 5305operand vRegD_V12() 5306%{ 5307 constraint(ALLOC_IN_RC(v12_reg)); 5308 match(RegD); 5309 op_cost(0); 5310 format %{ %} 5311 interface(REG_INTER); 5312%} 5313 5314operand vRegD_V13() 5315%{ 5316 constraint(ALLOC_IN_RC(v13_reg)); 5317 match(RegD); 5318 op_cost(0); 5319 format %{ %} 5320 interface(REG_INTER); 5321%} 5322 5323operand vRegD_V14() 5324%{ 5325 constraint(ALLOC_IN_RC(v14_reg)); 5326 match(RegD); 5327 op_cost(0); 5328 format %{ %} 5329 interface(REG_INTER); 5330%} 5331 5332operand vRegD_V15() 5333%{ 5334 constraint(ALLOC_IN_RC(v15_reg)); 5335 match(RegD); 5336 op_cost(0); 5337 format %{ %} 5338 interface(REG_INTER); 5339%} 5340 5341operand vRegD_V16() 5342%{ 5343 constraint(ALLOC_IN_RC(v16_reg)); 5344 match(RegD); 5345 op_cost(0); 5346 format %{ %} 5347 interface(REG_INTER); 5348%} 5349 5350operand vRegD_V17() 5351%{ 5352 constraint(ALLOC_IN_RC(v17_reg)); 5353 match(RegD); 5354 op_cost(0); 5355 format %{ %} 5356 interface(REG_INTER); 5357%} 5358 5359operand vRegD_V18() 5360%{ 5361 constraint(ALLOC_IN_RC(v18_reg)); 5362 match(RegD); 5363 op_cost(0); 5364 format %{ %} 5365 interface(REG_INTER); 5366%} 5367 5368operand vRegD_V19() 5369%{ 5370 constraint(ALLOC_IN_RC(v19_reg)); 5371 match(RegD); 5372 op_cost(0); 5373 format %{ %} 5374 interface(REG_INTER); 5375%} 5376 5377operand vRegD_V20() 5378%{ 5379 constraint(ALLOC_IN_RC(v20_reg)); 5380 match(RegD); 5381 op_cost(0); 5382 format %{ %} 5383 interface(REG_INTER); 5384%} 5385 5386operand vRegD_V21() 5387%{ 5388 constraint(ALLOC_IN_RC(v21_reg)); 5389 match(RegD); 5390 op_cost(0); 5391 format %{ %} 5392 interface(REG_INTER); 5393%} 5394 5395operand vRegD_V22() 5396%{ 5397 constraint(ALLOC_IN_RC(v22_reg)); 5398 match(RegD); 5399 op_cost(0); 5400 format %{ %} 5401 interface(REG_INTER); 5402%} 5403 5404operand vRegD_V23() 5405%{ 5406 constraint(ALLOC_IN_RC(v23_reg)); 5407 match(RegD); 5408 op_cost(0); 5409 format %{ %} 5410 interface(REG_INTER); 5411%} 5412 5413operand vRegD_V24() 5414%{ 5415 constraint(ALLOC_IN_RC(v24_reg)); 5416 match(RegD); 5417 op_cost(0); 5418 format %{ %} 5419 interface(REG_INTER); 5420%} 5421 5422operand vRegD_V25() 5423%{ 5424 constraint(ALLOC_IN_RC(v25_reg)); 5425 match(RegD); 5426 op_cost(0); 5427 format %{ %} 5428 interface(REG_INTER); 5429%} 5430 5431operand vRegD_V26() 5432%{ 5433 constraint(ALLOC_IN_RC(v26_reg)); 5434 match(RegD); 5435 op_cost(0); 5436 format %{ %} 5437 interface(REG_INTER); 5438%} 5439 5440operand vRegD_V27() 5441%{ 5442 constraint(ALLOC_IN_RC(v27_reg)); 5443 match(RegD); 5444 op_cost(0); 5445 format %{ %} 5446 interface(REG_INTER); 5447%} 5448 5449operand vRegD_V28() 5450%{ 5451 constraint(ALLOC_IN_RC(v28_reg)); 5452 match(RegD); 5453 op_cost(0); 5454 format %{ %} 5455 interface(REG_INTER); 5456%} 5457 5458operand vRegD_V29() 5459%{ 5460 constraint(ALLOC_IN_RC(v29_reg)); 5461 match(RegD); 5462 op_cost(0); 5463 format %{ %} 5464 interface(REG_INTER); 5465%} 5466 5467operand vRegD_V30() 5468%{ 5469 constraint(ALLOC_IN_RC(v30_reg)); 5470 match(RegD); 5471 op_cost(0); 5472 format %{ %} 5473 interface(REG_INTER); 5474%} 5475 5476operand vRegD_V31() 5477%{ 5478 constraint(ALLOC_IN_RC(v31_reg)); 5479 match(RegD); 5480 op_cost(0); 5481 format %{ %} 5482 interface(REG_INTER); 5483%} 5484 5485operand pRegGov() 5486%{ 5487 constraint(ALLOC_IN_RC(gov_pr)); 5488 match(RegVectMask); 5489 op_cost(0); 5490 format %{ %} 5491 interface(REG_INTER); 5492%} 5493 5494// Flags register, used as output of signed compare instructions 5495 5496// note that on AArch64 we also use this register as the output for 5497// for floating point compare instructions (CmpF CmpD). this ensures 5498// that ordered inequality tests use GT, GE, LT or LE none of which 5499// pass through cases where the result is unordered i.e. one or both 5500// inputs to the compare is a NaN. this means that the ideal code can 5501// replace e.g. a GT with an LE and not end up capturing the NaN case 5502// (where the comparison should always fail). EQ and NE tests are 5503// always generated in ideal code so that unordered folds into the NE 5504// case, matching the behaviour of AArch64 NE. 5505// 5506// This differs from x86 where the outputs of FP compares use a 5507// special FP flags registers and where compares based on this 5508// register are distinguished into ordered inequalities (cmpOpUCF) and 5509// EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5510// to explicitly handle the unordered case in branches. x86 also has 5511// to include extra CMoveX rules to accept a cmpOpUCF input. 5512 5513operand rFlagsReg() 5514%{ 5515 constraint(ALLOC_IN_RC(int_flags)); 5516 match(RegFlags); 5517 5518 op_cost(0); 5519 format %{ "RFLAGS" %} 5520 interface(REG_INTER); 5521%} 5522 5523// Flags register, used as output of unsigned compare instructions 5524operand rFlagsRegU() 5525%{ 5526 constraint(ALLOC_IN_RC(int_flags)); 5527 match(RegFlags); 5528 5529 op_cost(0); 5530 format %{ "RFLAGSU" %} 5531 interface(REG_INTER); 5532%} 5533 5534// Special Registers 5535 5536// Method Register 5537operand inline_cache_RegP(iRegP reg) 5538%{ 5539 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5540 match(reg); 5541 match(iRegPNoSp); 5542 op_cost(0); 5543 format %{ %} 5544 interface(REG_INTER); 5545%} 5546 5547// Thread Register 5548operand thread_RegP(iRegP reg) 5549%{ 5550 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5551 match(reg); 5552 op_cost(0); 5553 format %{ %} 5554 interface(REG_INTER); 5555%} 5556 5557operand lr_RegP(iRegP reg) 5558%{ 5559 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5560 match(reg); 5561 op_cost(0); 5562 format %{ %} 5563 interface(REG_INTER); 5564%} 5565 5566//----------Memory Operands---------------------------------------------------- 5567 5568operand indirect(iRegP reg) 5569%{ 5570 constraint(ALLOC_IN_RC(ptr_reg)); 5571 match(reg); 5572 op_cost(0); 5573 format %{ "[$reg]" %} 5574 interface(MEMORY_INTER) %{ 5575 base($reg); 5576 index(0xffffffff); 5577 scale(0x0); 5578 disp(0x0); 5579 %} 5580%} 5581 5582operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5583%{ 5584 constraint(ALLOC_IN_RC(ptr_reg)); 5585 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5586 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5587 op_cost(0); 5588 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5589 interface(MEMORY_INTER) %{ 5590 base($reg); 5591 index($ireg); 5592 scale($scale); 5593 disp(0x0); 5594 %} 5595%} 5596 5597operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5598%{ 5599 constraint(ALLOC_IN_RC(ptr_reg)); 5600 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5601 match(AddP reg (LShiftL lreg scale)); 5602 op_cost(0); 5603 format %{ "$reg, $lreg lsl($scale)" %} 5604 interface(MEMORY_INTER) %{ 5605 base($reg); 5606 index($lreg); 5607 scale($scale); 5608 disp(0x0); 5609 %} 5610%} 5611 5612operand indIndexI2L(iRegP reg, iRegI ireg) 5613%{ 5614 constraint(ALLOC_IN_RC(ptr_reg)); 5615 match(AddP reg (ConvI2L ireg)); 5616 op_cost(0); 5617 format %{ "$reg, $ireg, 0, I2L" %} 5618 interface(MEMORY_INTER) %{ 5619 base($reg); 5620 index($ireg); 5621 scale(0x0); 5622 disp(0x0); 5623 %} 5624%} 5625 5626operand indIndex(iRegP reg, iRegL lreg) 5627%{ 5628 constraint(ALLOC_IN_RC(ptr_reg)); 5629 match(AddP reg lreg); 5630 op_cost(0); 5631 format %{ "$reg, $lreg" %} 5632 interface(MEMORY_INTER) %{ 5633 base($reg); 5634 index($lreg); 5635 scale(0x0); 5636 disp(0x0); 5637 %} 5638%} 5639 5640operand indOffI(iRegP reg, immIOffset off) 5641%{ 5642 constraint(ALLOC_IN_RC(ptr_reg)); 5643 match(AddP reg off); 5644 op_cost(0); 5645 format %{ "[$reg, $off]" %} 5646 interface(MEMORY_INTER) %{ 5647 base($reg); 5648 index(0xffffffff); 5649 scale(0x0); 5650 disp($off); 5651 %} 5652%} 5653 5654operand indOffI1(iRegP reg, immIOffset1 off) 5655%{ 5656 constraint(ALLOC_IN_RC(ptr_reg)); 5657 match(AddP reg off); 5658 op_cost(0); 5659 format %{ "[$reg, $off]" %} 5660 interface(MEMORY_INTER) %{ 5661 base($reg); 5662 index(0xffffffff); 5663 scale(0x0); 5664 disp($off); 5665 %} 5666%} 5667 5668operand indOffI2(iRegP reg, immIOffset2 off) 5669%{ 5670 constraint(ALLOC_IN_RC(ptr_reg)); 5671 match(AddP reg off); 5672 op_cost(0); 5673 format %{ "[$reg, $off]" %} 5674 interface(MEMORY_INTER) %{ 5675 base($reg); 5676 index(0xffffffff); 5677 scale(0x0); 5678 disp($off); 5679 %} 5680%} 5681 5682operand indOffI4(iRegP reg, immIOffset4 off) 5683%{ 5684 constraint(ALLOC_IN_RC(ptr_reg)); 5685 match(AddP reg off); 5686 op_cost(0); 5687 format %{ "[$reg, $off]" %} 5688 interface(MEMORY_INTER) %{ 5689 base($reg); 5690 index(0xffffffff); 5691 scale(0x0); 5692 disp($off); 5693 %} 5694%} 5695 5696operand indOffI8(iRegP reg, immIOffset8 off) 5697%{ 5698 constraint(ALLOC_IN_RC(ptr_reg)); 5699 match(AddP reg off); 5700 op_cost(0); 5701 format %{ "[$reg, $off]" %} 5702 interface(MEMORY_INTER) %{ 5703 base($reg); 5704 index(0xffffffff); 5705 scale(0x0); 5706 disp($off); 5707 %} 5708%} 5709 5710operand indOffI16(iRegP reg, immIOffset16 off) 5711%{ 5712 constraint(ALLOC_IN_RC(ptr_reg)); 5713 match(AddP reg off); 5714 op_cost(0); 5715 format %{ "[$reg, $off]" %} 5716 interface(MEMORY_INTER) %{ 5717 base($reg); 5718 index(0xffffffff); 5719 scale(0x0); 5720 disp($off); 5721 %} 5722%} 5723 5724operand indOffL(iRegP reg, immLoffset off) 5725%{ 5726 constraint(ALLOC_IN_RC(ptr_reg)); 5727 match(AddP reg off); 5728 op_cost(0); 5729 format %{ "[$reg, $off]" %} 5730 interface(MEMORY_INTER) %{ 5731 base($reg); 5732 index(0xffffffff); 5733 scale(0x0); 5734 disp($off); 5735 %} 5736%} 5737 5738operand indOffL1(iRegP reg, immLoffset1 off) 5739%{ 5740 constraint(ALLOC_IN_RC(ptr_reg)); 5741 match(AddP reg off); 5742 op_cost(0); 5743 format %{ "[$reg, $off]" %} 5744 interface(MEMORY_INTER) %{ 5745 base($reg); 5746 index(0xffffffff); 5747 scale(0x0); 5748 disp($off); 5749 %} 5750%} 5751 5752operand indOffL2(iRegP reg, immLoffset2 off) 5753%{ 5754 constraint(ALLOC_IN_RC(ptr_reg)); 5755 match(AddP reg off); 5756 op_cost(0); 5757 format %{ "[$reg, $off]" %} 5758 interface(MEMORY_INTER) %{ 5759 base($reg); 5760 index(0xffffffff); 5761 scale(0x0); 5762 disp($off); 5763 %} 5764%} 5765 5766operand indOffL4(iRegP reg, immLoffset4 off) 5767%{ 5768 constraint(ALLOC_IN_RC(ptr_reg)); 5769 match(AddP reg off); 5770 op_cost(0); 5771 format %{ "[$reg, $off]" %} 5772 interface(MEMORY_INTER) %{ 5773 base($reg); 5774 index(0xffffffff); 5775 scale(0x0); 5776 disp($off); 5777 %} 5778%} 5779 5780operand indOffL8(iRegP reg, immLoffset8 off) 5781%{ 5782 constraint(ALLOC_IN_RC(ptr_reg)); 5783 match(AddP reg off); 5784 op_cost(0); 5785 format %{ "[$reg, $off]" %} 5786 interface(MEMORY_INTER) %{ 5787 base($reg); 5788 index(0xffffffff); 5789 scale(0x0); 5790 disp($off); 5791 %} 5792%} 5793 5794operand indOffL16(iRegP reg, immLoffset16 off) 5795%{ 5796 constraint(ALLOC_IN_RC(ptr_reg)); 5797 match(AddP reg off); 5798 op_cost(0); 5799 format %{ "[$reg, $off]" %} 5800 interface(MEMORY_INTER) %{ 5801 base($reg); 5802 index(0xffffffff); 5803 scale(0x0); 5804 disp($off); 5805 %} 5806%} 5807 5808operand indirectN(iRegN reg) 5809%{ 5810 predicate(CompressedOops::shift() == 0); 5811 constraint(ALLOC_IN_RC(ptr_reg)); 5812 match(DecodeN reg); 5813 op_cost(0); 5814 format %{ "[$reg]\t# narrow" %} 5815 interface(MEMORY_INTER) %{ 5816 base($reg); 5817 index(0xffffffff); 5818 scale(0x0); 5819 disp(0x0); 5820 %} 5821%} 5822 5823operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5824%{ 5825 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5826 constraint(ALLOC_IN_RC(ptr_reg)); 5827 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5828 op_cost(0); 5829 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5830 interface(MEMORY_INTER) %{ 5831 base($reg); 5832 index($ireg); 5833 scale($scale); 5834 disp(0x0); 5835 %} 5836%} 5837 5838operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5839%{ 5840 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5841 constraint(ALLOC_IN_RC(ptr_reg)); 5842 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5843 op_cost(0); 5844 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5845 interface(MEMORY_INTER) %{ 5846 base($reg); 5847 index($lreg); 5848 scale($scale); 5849 disp(0x0); 5850 %} 5851%} 5852 5853operand indIndexI2LN(iRegN reg, iRegI ireg) 5854%{ 5855 predicate(CompressedOops::shift() == 0); 5856 constraint(ALLOC_IN_RC(ptr_reg)); 5857 match(AddP (DecodeN reg) (ConvI2L ireg)); 5858 op_cost(0); 5859 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5860 interface(MEMORY_INTER) %{ 5861 base($reg); 5862 index($ireg); 5863 scale(0x0); 5864 disp(0x0); 5865 %} 5866%} 5867 5868operand indIndexN(iRegN reg, iRegL lreg) 5869%{ 5870 predicate(CompressedOops::shift() == 0); 5871 constraint(ALLOC_IN_RC(ptr_reg)); 5872 match(AddP (DecodeN reg) lreg); 5873 op_cost(0); 5874 format %{ "$reg, $lreg\t# narrow" %} 5875 interface(MEMORY_INTER) %{ 5876 base($reg); 5877 index($lreg); 5878 scale(0x0); 5879 disp(0x0); 5880 %} 5881%} 5882 5883operand indOffIN(iRegN reg, immIOffset off) 5884%{ 5885 predicate(CompressedOops::shift() == 0); 5886 constraint(ALLOC_IN_RC(ptr_reg)); 5887 match(AddP (DecodeN reg) off); 5888 op_cost(0); 5889 format %{ "[$reg, $off]\t# narrow" %} 5890 interface(MEMORY_INTER) %{ 5891 base($reg); 5892 index(0xffffffff); 5893 scale(0x0); 5894 disp($off); 5895 %} 5896%} 5897 5898operand indOffLN(iRegN reg, immLoffset off) 5899%{ 5900 predicate(CompressedOops::shift() == 0); 5901 constraint(ALLOC_IN_RC(ptr_reg)); 5902 match(AddP (DecodeN reg) off); 5903 op_cost(0); 5904 format %{ "[$reg, $off]\t# narrow" %} 5905 interface(MEMORY_INTER) %{ 5906 base($reg); 5907 index(0xffffffff); 5908 scale(0x0); 5909 disp($off); 5910 %} 5911%} 5912 5913 5914 5915// AArch64 opto stubs need to write to the pc slot in the thread anchor 5916operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5917%{ 5918 constraint(ALLOC_IN_RC(ptr_reg)); 5919 match(AddP reg off); 5920 op_cost(0); 5921 format %{ "[$reg, $off]" %} 5922 interface(MEMORY_INTER) %{ 5923 base($reg); 5924 index(0xffffffff); 5925 scale(0x0); 5926 disp($off); 5927 %} 5928%} 5929 5930//----------Special Memory Operands-------------------------------------------- 5931// Stack Slot Operand - This operand is used for loading and storing temporary 5932// values on the stack where a match requires a value to 5933// flow through memory. 5934operand stackSlotP(sRegP reg) 5935%{ 5936 constraint(ALLOC_IN_RC(stack_slots)); 5937 op_cost(100); 5938 // No match rule because this operand is only generated in matching 5939 // match(RegP); 5940 format %{ "[$reg]" %} 5941 interface(MEMORY_INTER) %{ 5942 base(0x1e); // RSP 5943 index(0x0); // No Index 5944 scale(0x0); // No Scale 5945 disp($reg); // Stack Offset 5946 %} 5947%} 5948 5949operand stackSlotI(sRegI reg) 5950%{ 5951 constraint(ALLOC_IN_RC(stack_slots)); 5952 // No match rule because this operand is only generated in matching 5953 // match(RegI); 5954 format %{ "[$reg]" %} 5955 interface(MEMORY_INTER) %{ 5956 base(0x1e); // RSP 5957 index(0x0); // No Index 5958 scale(0x0); // No Scale 5959 disp($reg); // Stack Offset 5960 %} 5961%} 5962 5963operand stackSlotF(sRegF reg) 5964%{ 5965 constraint(ALLOC_IN_RC(stack_slots)); 5966 // No match rule because this operand is only generated in matching 5967 // match(RegF); 5968 format %{ "[$reg]" %} 5969 interface(MEMORY_INTER) %{ 5970 base(0x1e); // RSP 5971 index(0x0); // No Index 5972 scale(0x0); // No Scale 5973 disp($reg); // Stack Offset 5974 %} 5975%} 5976 5977operand stackSlotD(sRegD reg) 5978%{ 5979 constraint(ALLOC_IN_RC(stack_slots)); 5980 // No match rule because this operand is only generated in matching 5981 // match(RegD); 5982 format %{ "[$reg]" %} 5983 interface(MEMORY_INTER) %{ 5984 base(0x1e); // RSP 5985 index(0x0); // No Index 5986 scale(0x0); // No Scale 5987 disp($reg); // Stack Offset 5988 %} 5989%} 5990 5991operand stackSlotL(sRegL reg) 5992%{ 5993 constraint(ALLOC_IN_RC(stack_slots)); 5994 // No match rule because this operand is only generated in matching 5995 // match(RegL); 5996 format %{ "[$reg]" %} 5997 interface(MEMORY_INTER) %{ 5998 base(0x1e); // RSP 5999 index(0x0); // No Index 6000 scale(0x0); // No Scale 6001 disp($reg); // Stack Offset 6002 %} 6003%} 6004 6005// Operands for expressing Control Flow 6006// NOTE: Label is a predefined operand which should not be redefined in 6007// the AD file. It is generically handled within the ADLC. 6008 6009//----------Conditional Branch Operands---------------------------------------- 6010// Comparison Op - This is the operation of the comparison, and is limited to 6011// the following set of codes: 6012// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 6013// 6014// Other attributes of the comparison, such as unsignedness, are specified 6015// by the comparison instruction that sets a condition code flags register. 6016// That result is represented by a flags operand whose subtype is appropriate 6017// to the unsignedness (etc.) of the comparison. 6018// 6019// Later, the instruction which matches both the Comparison Op (a Bool) and 6020// the flags (produced by the Cmp) specifies the coding of the comparison op 6021// by matching a specific subtype of Bool operand below, such as cmpOpU. 6022 6023// used for signed integral comparisons and fp comparisons 6024 6025operand cmpOp() 6026%{ 6027 match(Bool); 6028 6029 format %{ "" %} 6030 interface(COND_INTER) %{ 6031 equal(0x0, "eq"); 6032 not_equal(0x1, "ne"); 6033 less(0xb, "lt"); 6034 greater_equal(0xa, "ge"); 6035 less_equal(0xd, "le"); 6036 greater(0xc, "gt"); 6037 overflow(0x6, "vs"); 6038 no_overflow(0x7, "vc"); 6039 %} 6040%} 6041 6042// used for unsigned integral comparisons 6043 6044operand cmpOpU() 6045%{ 6046 match(Bool); 6047 6048 format %{ "" %} 6049 interface(COND_INTER) %{ 6050 equal(0x0, "eq"); 6051 not_equal(0x1, "ne"); 6052 less(0x3, "lo"); 6053 greater_equal(0x2, "hs"); 6054 less_equal(0x9, "ls"); 6055 greater(0x8, "hi"); 6056 overflow(0x6, "vs"); 6057 no_overflow(0x7, "vc"); 6058 %} 6059%} 6060 6061// used for certain integral comparisons which can be 6062// converted to cbxx or tbxx instructions 6063 6064operand cmpOpEqNe() 6065%{ 6066 match(Bool); 6067 op_cost(0); 6068 predicate(n->as_Bool()->_test._test == BoolTest::ne 6069 || n->as_Bool()->_test._test == BoolTest::eq); 6070 6071 format %{ "" %} 6072 interface(COND_INTER) %{ 6073 equal(0x0, "eq"); 6074 not_equal(0x1, "ne"); 6075 less(0xb, "lt"); 6076 greater_equal(0xa, "ge"); 6077 less_equal(0xd, "le"); 6078 greater(0xc, "gt"); 6079 overflow(0x6, "vs"); 6080 no_overflow(0x7, "vc"); 6081 %} 6082%} 6083 6084// used for certain integral comparisons which can be 6085// converted to cbxx or tbxx instructions 6086 6087operand cmpOpLtGe() 6088%{ 6089 match(Bool); 6090 op_cost(0); 6091 6092 predicate(n->as_Bool()->_test._test == BoolTest::lt 6093 || n->as_Bool()->_test._test == BoolTest::ge); 6094 6095 format %{ "" %} 6096 interface(COND_INTER) %{ 6097 equal(0x0, "eq"); 6098 not_equal(0x1, "ne"); 6099 less(0xb, "lt"); 6100 greater_equal(0xa, "ge"); 6101 less_equal(0xd, "le"); 6102 greater(0xc, "gt"); 6103 overflow(0x6, "vs"); 6104 no_overflow(0x7, "vc"); 6105 %} 6106%} 6107 6108// used for certain unsigned integral comparisons which can be 6109// converted to cbxx or tbxx instructions 6110 6111operand cmpOpUEqNeLtGe() 6112%{ 6113 match(Bool); 6114 op_cost(0); 6115 6116 predicate(n->as_Bool()->_test._test == BoolTest::eq 6117 || n->as_Bool()->_test._test == BoolTest::ne 6118 || n->as_Bool()->_test._test == BoolTest::lt 6119 || n->as_Bool()->_test._test == BoolTest::ge); 6120 6121 format %{ "" %} 6122 interface(COND_INTER) %{ 6123 equal(0x0, "eq"); 6124 not_equal(0x1, "ne"); 6125 less(0xb, "lt"); 6126 greater_equal(0xa, "ge"); 6127 less_equal(0xd, "le"); 6128 greater(0xc, "gt"); 6129 overflow(0x6, "vs"); 6130 no_overflow(0x7, "vc"); 6131 %} 6132%} 6133 6134// Special operand allowing long args to int ops to be truncated for free 6135 6136operand iRegL2I(iRegL reg) %{ 6137 6138 op_cost(0); 6139 6140 match(ConvL2I reg); 6141 6142 format %{ "l2i($reg)" %} 6143 6144 interface(REG_INTER) 6145%} 6146 6147opclass vmem2(indirect, indIndex, indOffI2, indOffL2); 6148opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 6149opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 6150opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 6151 6152//----------OPERAND CLASSES---------------------------------------------------- 6153// Operand Classes are groups of operands that are used as to simplify 6154// instruction definitions by not requiring the AD writer to specify 6155// separate instructions for every form of operand when the 6156// instruction accepts multiple operand types with the same basic 6157// encoding and format. The classic case of this is memory operands. 6158 6159// memory is used to define read/write location for load/store 6160// instruction defs. we can turn a memory op into an Address 6161 6162opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 6163 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6164 6165opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 6166 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6167 6168opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 6169 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6170 6171opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 6172 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6173 6174// All of the memory operands. For the pipeline description. 6175opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 6176 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 6177 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6178 6179 6180// iRegIorL2I is used for src inputs in rules for 32 bit int (I) 6181// operations. it allows the src to be either an iRegI or a (ConvL2I 6182// iRegL). in the latter case the l2i normally planted for a ConvL2I 6183// can be elided because the 32-bit instruction will just employ the 6184// lower 32 bits anyway. 6185// 6186// n.b. this does not elide all L2I conversions. if the truncated 6187// value is consumed by more than one operation then the ConvL2I 6188// cannot be bundled into the consuming nodes so an l2i gets planted 6189// (actually a movw $dst $src) and the downstream instructions consume 6190// the result of the l2i as an iRegI input. That's a shame since the 6191// movw is actually redundant but its not too costly. 6192 6193opclass iRegIorL2I(iRegI, iRegL2I); 6194 6195//----------PIPELINE----------------------------------------------------------- 6196// Rules which define the behavior of the target architectures pipeline. 6197 6198// For specific pipelines, eg A53, define the stages of that pipeline 6199//pipe_desc(ISS, EX1, EX2, WR); 6200#define ISS S0 6201#define EX1 S1 6202#define EX2 S2 6203#define WR S3 6204 6205// Integer ALU reg operation 6206pipeline %{ 6207 6208attributes %{ 6209 // ARM instructions are of fixed length 6210 fixed_size_instructions; // Fixed size instructions TODO does 6211 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 6212 // ARM instructions come in 32-bit word units 6213 instruction_unit_size = 4; // An instruction is 4 bytes long 6214 instruction_fetch_unit_size = 64; // The processor fetches one line 6215 instruction_fetch_units = 1; // of 64 bytes 6216 6217 // List of nop instructions 6218 nops( MachNop ); 6219%} 6220 6221// We don't use an actual pipeline model so don't care about resources 6222// or description. we do use pipeline classes to introduce fixed 6223// latencies 6224 6225//----------RESOURCES---------------------------------------------------------- 6226// Resources are the functional units available to the machine 6227 6228resources( INS0, INS1, INS01 = INS0 | INS1, 6229 ALU0, ALU1, ALU = ALU0 | ALU1, 6230 MAC, 6231 DIV, 6232 BRANCH, 6233 LDST, 6234 NEON_FP); 6235 6236//----------PIPELINE DESCRIPTION----------------------------------------------- 6237// Pipeline Description specifies the stages in the machine's pipeline 6238 6239// Define the pipeline as a generic 6 stage pipeline 6240pipe_desc(S0, S1, S2, S3, S4, S5); 6241 6242//----------PIPELINE CLASSES--------------------------------------------------- 6243// Pipeline Classes describe the stages in which input and output are 6244// referenced by the hardware pipeline. 6245 6246pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 6247%{ 6248 single_instruction; 6249 src1 : S1(read); 6250 src2 : S2(read); 6251 dst : S5(write); 6252 INS01 : ISS; 6253 NEON_FP : S5; 6254%} 6255 6256pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 6257%{ 6258 single_instruction; 6259 src1 : S1(read); 6260 src2 : S2(read); 6261 dst : S5(write); 6262 INS01 : ISS; 6263 NEON_FP : S5; 6264%} 6265 6266pipe_class fp_uop_s(vRegF dst, vRegF src) 6267%{ 6268 single_instruction; 6269 src : S1(read); 6270 dst : S5(write); 6271 INS01 : ISS; 6272 NEON_FP : S5; 6273%} 6274 6275pipe_class fp_uop_d(vRegD dst, vRegD src) 6276%{ 6277 single_instruction; 6278 src : S1(read); 6279 dst : S5(write); 6280 INS01 : ISS; 6281 NEON_FP : S5; 6282%} 6283 6284pipe_class fp_d2f(vRegF dst, vRegD src) 6285%{ 6286 single_instruction; 6287 src : S1(read); 6288 dst : S5(write); 6289 INS01 : ISS; 6290 NEON_FP : S5; 6291%} 6292 6293pipe_class fp_f2d(vRegD dst, vRegF src) 6294%{ 6295 single_instruction; 6296 src : S1(read); 6297 dst : S5(write); 6298 INS01 : ISS; 6299 NEON_FP : S5; 6300%} 6301 6302pipe_class fp_f2i(iRegINoSp dst, vRegF src) 6303%{ 6304 single_instruction; 6305 src : S1(read); 6306 dst : S5(write); 6307 INS01 : ISS; 6308 NEON_FP : S5; 6309%} 6310 6311pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6312%{ 6313 single_instruction; 6314 src : S1(read); 6315 dst : S5(write); 6316 INS01 : ISS; 6317 NEON_FP : S5; 6318%} 6319 6320pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6321%{ 6322 single_instruction; 6323 src : S1(read); 6324 dst : S5(write); 6325 INS01 : ISS; 6326 NEON_FP : S5; 6327%} 6328 6329pipe_class fp_l2f(vRegF dst, iRegL src) 6330%{ 6331 single_instruction; 6332 src : S1(read); 6333 dst : S5(write); 6334 INS01 : ISS; 6335 NEON_FP : S5; 6336%} 6337 6338pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6339%{ 6340 single_instruction; 6341 src : S1(read); 6342 dst : S5(write); 6343 INS01 : ISS; 6344 NEON_FP : S5; 6345%} 6346 6347pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6348%{ 6349 single_instruction; 6350 src : S1(read); 6351 dst : S5(write); 6352 INS01 : ISS; 6353 NEON_FP : S5; 6354%} 6355 6356pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6357%{ 6358 single_instruction; 6359 src : S1(read); 6360 dst : S5(write); 6361 INS01 : ISS; 6362 NEON_FP : S5; 6363%} 6364 6365pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6366%{ 6367 single_instruction; 6368 src : S1(read); 6369 dst : S5(write); 6370 INS01 : ISS; 6371 NEON_FP : S5; 6372%} 6373 6374pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6375%{ 6376 single_instruction; 6377 src1 : S1(read); 6378 src2 : S2(read); 6379 dst : S5(write); 6380 INS0 : ISS; 6381 NEON_FP : S5; 6382%} 6383 6384pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6385%{ 6386 single_instruction; 6387 src1 : S1(read); 6388 src2 : S2(read); 6389 dst : S5(write); 6390 INS0 : ISS; 6391 NEON_FP : S5; 6392%} 6393 6394pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6395%{ 6396 single_instruction; 6397 cr : S1(read); 6398 src1 : S1(read); 6399 src2 : S1(read); 6400 dst : S3(write); 6401 INS01 : ISS; 6402 NEON_FP : S3; 6403%} 6404 6405pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6406%{ 6407 single_instruction; 6408 cr : S1(read); 6409 src1 : S1(read); 6410 src2 : S1(read); 6411 dst : S3(write); 6412 INS01 : ISS; 6413 NEON_FP : S3; 6414%} 6415 6416pipe_class fp_imm_s(vRegF dst) 6417%{ 6418 single_instruction; 6419 dst : S3(write); 6420 INS01 : ISS; 6421 NEON_FP : S3; 6422%} 6423 6424pipe_class fp_imm_d(vRegD dst) 6425%{ 6426 single_instruction; 6427 dst : S3(write); 6428 INS01 : ISS; 6429 NEON_FP : S3; 6430%} 6431 6432pipe_class fp_load_constant_s(vRegF dst) 6433%{ 6434 single_instruction; 6435 dst : S4(write); 6436 INS01 : ISS; 6437 NEON_FP : S4; 6438%} 6439 6440pipe_class fp_load_constant_d(vRegD dst) 6441%{ 6442 single_instruction; 6443 dst : S4(write); 6444 INS01 : ISS; 6445 NEON_FP : S4; 6446%} 6447 6448pipe_class vmul64(vecD dst, vecD src1, vecD src2) 6449%{ 6450 single_instruction; 6451 dst : S5(write); 6452 src1 : S1(read); 6453 src2 : S1(read); 6454 INS01 : ISS; 6455 NEON_FP : S5; 6456%} 6457 6458pipe_class vmul128(vecX dst, vecX src1, vecX src2) 6459%{ 6460 single_instruction; 6461 dst : S5(write); 6462 src1 : S1(read); 6463 src2 : S1(read); 6464 INS0 : ISS; 6465 NEON_FP : S5; 6466%} 6467 6468pipe_class vmla64(vecD dst, vecD src1, vecD src2) 6469%{ 6470 single_instruction; 6471 dst : S5(write); 6472 src1 : S1(read); 6473 src2 : S1(read); 6474 dst : S1(read); 6475 INS01 : ISS; 6476 NEON_FP : S5; 6477%} 6478 6479pipe_class vmla128(vecX dst, vecX src1, vecX src2) 6480%{ 6481 single_instruction; 6482 dst : S5(write); 6483 src1 : S1(read); 6484 src2 : S1(read); 6485 dst : S1(read); 6486 INS0 : ISS; 6487 NEON_FP : S5; 6488%} 6489 6490pipe_class vdop64(vecD dst, vecD src1, vecD src2) 6491%{ 6492 single_instruction; 6493 dst : S4(write); 6494 src1 : S2(read); 6495 src2 : S2(read); 6496 INS01 : ISS; 6497 NEON_FP : S4; 6498%} 6499 6500pipe_class vdop128(vecX dst, vecX src1, vecX src2) 6501%{ 6502 single_instruction; 6503 dst : S4(write); 6504 src1 : S2(read); 6505 src2 : S2(read); 6506 INS0 : ISS; 6507 NEON_FP : S4; 6508%} 6509 6510pipe_class vlogical64(vecD dst, vecD src1, vecD src2) 6511%{ 6512 single_instruction; 6513 dst : S3(write); 6514 src1 : S2(read); 6515 src2 : S2(read); 6516 INS01 : ISS; 6517 NEON_FP : S3; 6518%} 6519 6520pipe_class vlogical128(vecX dst, vecX src1, vecX src2) 6521%{ 6522 single_instruction; 6523 dst : S3(write); 6524 src1 : S2(read); 6525 src2 : S2(read); 6526 INS0 : ISS; 6527 NEON_FP : S3; 6528%} 6529 6530pipe_class vshift64(vecD dst, vecD src, vecX shift) 6531%{ 6532 single_instruction; 6533 dst : S3(write); 6534 src : S1(read); 6535 shift : S1(read); 6536 INS01 : ISS; 6537 NEON_FP : S3; 6538%} 6539 6540pipe_class vshift128(vecX dst, vecX src, vecX shift) 6541%{ 6542 single_instruction; 6543 dst : S3(write); 6544 src : S1(read); 6545 shift : S1(read); 6546 INS0 : ISS; 6547 NEON_FP : S3; 6548%} 6549 6550pipe_class vshift64_imm(vecD dst, vecD src, immI shift) 6551%{ 6552 single_instruction; 6553 dst : S3(write); 6554 src : S1(read); 6555 INS01 : ISS; 6556 NEON_FP : S3; 6557%} 6558 6559pipe_class vshift128_imm(vecX dst, vecX src, immI shift) 6560%{ 6561 single_instruction; 6562 dst : S3(write); 6563 src : S1(read); 6564 INS0 : ISS; 6565 NEON_FP : S3; 6566%} 6567 6568pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2) 6569%{ 6570 single_instruction; 6571 dst : S5(write); 6572 src1 : S1(read); 6573 src2 : S1(read); 6574 INS01 : ISS; 6575 NEON_FP : S5; 6576%} 6577 6578pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2) 6579%{ 6580 single_instruction; 6581 dst : S5(write); 6582 src1 : S1(read); 6583 src2 : S1(read); 6584 INS0 : ISS; 6585 NEON_FP : S5; 6586%} 6587 6588pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2) 6589%{ 6590 single_instruction; 6591 dst : S5(write); 6592 src1 : S1(read); 6593 src2 : S1(read); 6594 INS0 : ISS; 6595 NEON_FP : S5; 6596%} 6597 6598pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2) 6599%{ 6600 single_instruction; 6601 dst : S5(write); 6602 src1 : S1(read); 6603 src2 : S1(read); 6604 INS0 : ISS; 6605 NEON_FP : S5; 6606%} 6607 6608pipe_class vsqrt_fp128(vecX dst, vecX src) 6609%{ 6610 single_instruction; 6611 dst : S5(write); 6612 src : S1(read); 6613 INS0 : ISS; 6614 NEON_FP : S5; 6615%} 6616 6617pipe_class vunop_fp64(vecD dst, vecD src) 6618%{ 6619 single_instruction; 6620 dst : S5(write); 6621 src : S1(read); 6622 INS01 : ISS; 6623 NEON_FP : S5; 6624%} 6625 6626pipe_class vunop_fp128(vecX dst, vecX src) 6627%{ 6628 single_instruction; 6629 dst : S5(write); 6630 src : S1(read); 6631 INS0 : ISS; 6632 NEON_FP : S5; 6633%} 6634 6635pipe_class vdup_reg_reg64(vecD dst, iRegI src) 6636%{ 6637 single_instruction; 6638 dst : S3(write); 6639 src : S1(read); 6640 INS01 : ISS; 6641 NEON_FP : S3; 6642%} 6643 6644pipe_class vdup_reg_reg128(vecX dst, iRegI src) 6645%{ 6646 single_instruction; 6647 dst : S3(write); 6648 src : S1(read); 6649 INS01 : ISS; 6650 NEON_FP : S3; 6651%} 6652 6653pipe_class vdup_reg_freg64(vecD dst, vRegF src) 6654%{ 6655 single_instruction; 6656 dst : S3(write); 6657 src : S1(read); 6658 INS01 : ISS; 6659 NEON_FP : S3; 6660%} 6661 6662pipe_class vdup_reg_freg128(vecX dst, vRegF src) 6663%{ 6664 single_instruction; 6665 dst : S3(write); 6666 src : S1(read); 6667 INS01 : ISS; 6668 NEON_FP : S3; 6669%} 6670 6671pipe_class vdup_reg_dreg128(vecX dst, vRegD src) 6672%{ 6673 single_instruction; 6674 dst : S3(write); 6675 src : S1(read); 6676 INS01 : ISS; 6677 NEON_FP : S3; 6678%} 6679 6680pipe_class vmovi_reg_imm64(vecD dst) 6681%{ 6682 single_instruction; 6683 dst : S3(write); 6684 INS01 : ISS; 6685 NEON_FP : S3; 6686%} 6687 6688pipe_class vmovi_reg_imm128(vecX dst) 6689%{ 6690 single_instruction; 6691 dst : S3(write); 6692 INS0 : ISS; 6693 NEON_FP : S3; 6694%} 6695 6696pipe_class vload_reg_mem64(vecD dst, vmem8 mem) 6697%{ 6698 single_instruction; 6699 dst : S5(write); 6700 mem : ISS(read); 6701 INS01 : ISS; 6702 NEON_FP : S3; 6703%} 6704 6705pipe_class vload_reg_mem128(vecX dst, vmem16 mem) 6706%{ 6707 single_instruction; 6708 dst : S5(write); 6709 mem : ISS(read); 6710 INS01 : ISS; 6711 NEON_FP : S3; 6712%} 6713 6714pipe_class vstore_reg_mem64(vecD src, vmem8 mem) 6715%{ 6716 single_instruction; 6717 mem : ISS(read); 6718 src : S2(read); 6719 INS01 : ISS; 6720 NEON_FP : S3; 6721%} 6722 6723pipe_class vstore_reg_mem128(vecD src, vmem16 mem) 6724%{ 6725 single_instruction; 6726 mem : ISS(read); 6727 src : S2(read); 6728 INS01 : ISS; 6729 NEON_FP : S3; 6730%} 6731 6732//------- Integer ALU operations -------------------------- 6733 6734// Integer ALU reg-reg operation 6735// Operands needed in EX1, result generated in EX2 6736// Eg. ADD x0, x1, x2 6737pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6738%{ 6739 single_instruction; 6740 dst : EX2(write); 6741 src1 : EX1(read); 6742 src2 : EX1(read); 6743 INS01 : ISS; // Dual issue as instruction 0 or 1 6744 ALU : EX2; 6745%} 6746 6747// Integer ALU reg-reg operation with constant shift 6748// Shifted register must be available in LATE_ISS instead of EX1 6749// Eg. ADD x0, x1, x2, LSL #2 6750pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6751%{ 6752 single_instruction; 6753 dst : EX2(write); 6754 src1 : EX1(read); 6755 src2 : ISS(read); 6756 INS01 : ISS; 6757 ALU : EX2; 6758%} 6759 6760// Integer ALU reg operation with constant shift 6761// Eg. LSL x0, x1, #shift 6762pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6763%{ 6764 single_instruction; 6765 dst : EX2(write); 6766 src1 : ISS(read); 6767 INS01 : ISS; 6768 ALU : EX2; 6769%} 6770 6771// Integer ALU reg-reg operation with variable shift 6772// Both operands must be available in LATE_ISS instead of EX1 6773// Result is available in EX1 instead of EX2 6774// Eg. LSLV x0, x1, x2 6775pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6776%{ 6777 single_instruction; 6778 dst : EX1(write); 6779 src1 : ISS(read); 6780 src2 : ISS(read); 6781 INS01 : ISS; 6782 ALU : EX1; 6783%} 6784 6785// Integer ALU reg-reg operation with extract 6786// As for _vshift above, but result generated in EX2 6787// Eg. EXTR x0, x1, x2, #N 6788pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6789%{ 6790 single_instruction; 6791 dst : EX2(write); 6792 src1 : ISS(read); 6793 src2 : ISS(read); 6794 INS1 : ISS; // Can only dual issue as Instruction 1 6795 ALU : EX1; 6796%} 6797 6798// Integer ALU reg operation 6799// Eg. NEG x0, x1 6800pipe_class ialu_reg(iRegI dst, iRegI src) 6801%{ 6802 single_instruction; 6803 dst : EX2(write); 6804 src : EX1(read); 6805 INS01 : ISS; 6806 ALU : EX2; 6807%} 6808 6809// Integer ALU reg mmediate operation 6810// Eg. ADD x0, x1, #N 6811pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6812%{ 6813 single_instruction; 6814 dst : EX2(write); 6815 src1 : EX1(read); 6816 INS01 : ISS; 6817 ALU : EX2; 6818%} 6819 6820// Integer ALU immediate operation (no source operands) 6821// Eg. MOV x0, #N 6822pipe_class ialu_imm(iRegI dst) 6823%{ 6824 single_instruction; 6825 dst : EX1(write); 6826 INS01 : ISS; 6827 ALU : EX1; 6828%} 6829 6830//------- Compare operation ------------------------------- 6831 6832// Compare reg-reg 6833// Eg. CMP x0, x1 6834pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6835%{ 6836 single_instruction; 6837// fixed_latency(16); 6838 cr : EX2(write); 6839 op1 : EX1(read); 6840 op2 : EX1(read); 6841 INS01 : ISS; 6842 ALU : EX2; 6843%} 6844 6845// Compare reg-reg 6846// Eg. CMP x0, #N 6847pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6848%{ 6849 single_instruction; 6850// fixed_latency(16); 6851 cr : EX2(write); 6852 op1 : EX1(read); 6853 INS01 : ISS; 6854 ALU : EX2; 6855%} 6856 6857//------- Conditional instructions ------------------------ 6858 6859// Conditional no operands 6860// Eg. CSINC x0, zr, zr, <cond> 6861pipe_class icond_none(iRegI dst, rFlagsReg cr) 6862%{ 6863 single_instruction; 6864 cr : EX1(read); 6865 dst : EX2(write); 6866 INS01 : ISS; 6867 ALU : EX2; 6868%} 6869 6870// Conditional 2 operand 6871// EG. CSEL X0, X1, X2, <cond> 6872pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6873%{ 6874 single_instruction; 6875 cr : EX1(read); 6876 src1 : EX1(read); 6877 src2 : EX1(read); 6878 dst : EX2(write); 6879 INS01 : ISS; 6880 ALU : EX2; 6881%} 6882 6883// Conditional 2 operand 6884// EG. CSEL X0, X1, X2, <cond> 6885pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6886%{ 6887 single_instruction; 6888 cr : EX1(read); 6889 src : EX1(read); 6890 dst : EX2(write); 6891 INS01 : ISS; 6892 ALU : EX2; 6893%} 6894 6895//------- Multiply pipeline operations -------------------- 6896 6897// Multiply reg-reg 6898// Eg. MUL w0, w1, w2 6899pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6900%{ 6901 single_instruction; 6902 dst : WR(write); 6903 src1 : ISS(read); 6904 src2 : ISS(read); 6905 INS01 : ISS; 6906 MAC : WR; 6907%} 6908 6909// Multiply accumulate 6910// Eg. MADD w0, w1, w2, w3 6911pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6912%{ 6913 single_instruction; 6914 dst : WR(write); 6915 src1 : ISS(read); 6916 src2 : ISS(read); 6917 src3 : ISS(read); 6918 INS01 : ISS; 6919 MAC : WR; 6920%} 6921 6922// Eg. MUL w0, w1, w2 6923pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6924%{ 6925 single_instruction; 6926 fixed_latency(3); // Maximum latency for 64 bit mul 6927 dst : WR(write); 6928 src1 : ISS(read); 6929 src2 : ISS(read); 6930 INS01 : ISS; 6931 MAC : WR; 6932%} 6933 6934// Multiply accumulate 6935// Eg. MADD w0, w1, w2, w3 6936pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6937%{ 6938 single_instruction; 6939 fixed_latency(3); // Maximum latency for 64 bit mul 6940 dst : WR(write); 6941 src1 : ISS(read); 6942 src2 : ISS(read); 6943 src3 : ISS(read); 6944 INS01 : ISS; 6945 MAC : WR; 6946%} 6947 6948//------- Divide pipeline operations -------------------- 6949 6950// Eg. SDIV w0, w1, w2 6951pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6952%{ 6953 single_instruction; 6954 fixed_latency(8); // Maximum latency for 32 bit divide 6955 dst : WR(write); 6956 src1 : ISS(read); 6957 src2 : ISS(read); 6958 INS0 : ISS; // Can only dual issue as instruction 0 6959 DIV : WR; 6960%} 6961 6962// Eg. SDIV x0, x1, x2 6963pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6964%{ 6965 single_instruction; 6966 fixed_latency(16); // Maximum latency for 64 bit divide 6967 dst : WR(write); 6968 src1 : ISS(read); 6969 src2 : ISS(read); 6970 INS0 : ISS; // Can only dual issue as instruction 0 6971 DIV : WR; 6972%} 6973 6974//------- Load pipeline operations ------------------------ 6975 6976// Load - prefetch 6977// Eg. PFRM <mem> 6978pipe_class iload_prefetch(memory mem) 6979%{ 6980 single_instruction; 6981 mem : ISS(read); 6982 INS01 : ISS; 6983 LDST : WR; 6984%} 6985 6986// Load - reg, mem 6987// Eg. LDR x0, <mem> 6988pipe_class iload_reg_mem(iRegI dst, memory mem) 6989%{ 6990 single_instruction; 6991 dst : WR(write); 6992 mem : ISS(read); 6993 INS01 : ISS; 6994 LDST : WR; 6995%} 6996 6997// Load - reg, reg 6998// Eg. LDR x0, [sp, x1] 6999pipe_class iload_reg_reg(iRegI dst, iRegI src) 7000%{ 7001 single_instruction; 7002 dst : WR(write); 7003 src : ISS(read); 7004 INS01 : ISS; 7005 LDST : WR; 7006%} 7007 7008//------- Store pipeline operations ----------------------- 7009 7010// Store - zr, mem 7011// Eg. STR zr, <mem> 7012pipe_class istore_mem(memory mem) 7013%{ 7014 single_instruction; 7015 mem : ISS(read); 7016 INS01 : ISS; 7017 LDST : WR; 7018%} 7019 7020// Store - reg, mem 7021// Eg. STR x0, <mem> 7022pipe_class istore_reg_mem(iRegI src, memory mem) 7023%{ 7024 single_instruction; 7025 mem : ISS(read); 7026 src : EX2(read); 7027 INS01 : ISS; 7028 LDST : WR; 7029%} 7030 7031// Store - reg, reg 7032// Eg. STR x0, [sp, x1] 7033pipe_class istore_reg_reg(iRegI dst, iRegI src) 7034%{ 7035 single_instruction; 7036 dst : ISS(read); 7037 src : EX2(read); 7038 INS01 : ISS; 7039 LDST : WR; 7040%} 7041 7042//------- Store pipeline operations ----------------------- 7043 7044// Branch 7045pipe_class pipe_branch() 7046%{ 7047 single_instruction; 7048 INS01 : ISS; 7049 BRANCH : EX1; 7050%} 7051 7052// Conditional branch 7053pipe_class pipe_branch_cond(rFlagsReg cr) 7054%{ 7055 single_instruction; 7056 cr : EX1(read); 7057 INS01 : ISS; 7058 BRANCH : EX1; 7059%} 7060 7061// Compare & Branch 7062// EG. CBZ/CBNZ 7063pipe_class pipe_cmp_branch(iRegI op1) 7064%{ 7065 single_instruction; 7066 op1 : EX1(read); 7067 INS01 : ISS; 7068 BRANCH : EX1; 7069%} 7070 7071//------- Synchronisation operations ---------------------- 7072 7073// Any operation requiring serialization. 7074// EG. DMB/Atomic Ops/Load Acquire/Str Release 7075pipe_class pipe_serial() 7076%{ 7077 single_instruction; 7078 force_serialization; 7079 fixed_latency(16); 7080 INS01 : ISS(2); // Cannot dual issue with any other instruction 7081 LDST : WR; 7082%} 7083 7084// Generic big/slow expanded idiom - also serialized 7085pipe_class pipe_slow() 7086%{ 7087 instruction_count(10); 7088 multiple_bundles; 7089 force_serialization; 7090 fixed_latency(16); 7091 INS01 : ISS(2); // Cannot dual issue with any other instruction 7092 LDST : WR; 7093%} 7094 7095// Empty pipeline class 7096pipe_class pipe_class_empty() 7097%{ 7098 single_instruction; 7099 fixed_latency(0); 7100%} 7101 7102// Default pipeline class. 7103pipe_class pipe_class_default() 7104%{ 7105 single_instruction; 7106 fixed_latency(2); 7107%} 7108 7109// Pipeline class for compares. 7110pipe_class pipe_class_compare() 7111%{ 7112 single_instruction; 7113 fixed_latency(16); 7114%} 7115 7116// Pipeline class for memory operations. 7117pipe_class pipe_class_memory() 7118%{ 7119 single_instruction; 7120 fixed_latency(16); 7121%} 7122 7123// Pipeline class for call. 7124pipe_class pipe_class_call() 7125%{ 7126 single_instruction; 7127 fixed_latency(100); 7128%} 7129 7130// Define the class for the Nop node. 7131define %{ 7132 MachNop = pipe_class_empty; 7133%} 7134 7135%} 7136//----------INSTRUCTIONS------------------------------------------------------- 7137// 7138// match -- States which machine-independent subtree may be replaced 7139// by this instruction. 7140// ins_cost -- The estimated cost of this instruction is used by instruction 7141// selection to identify a minimum cost tree of machine 7142// instructions that matches a tree of machine-independent 7143// instructions. 7144// format -- A string providing the disassembly for this instruction. 7145// The value of an instruction's operand may be inserted 7146// by referring to it with a '$' prefix. 7147// opcode -- Three instruction opcodes may be provided. These are referred 7148// to within an encode class as $primary, $secondary, and $tertiary 7149// rrspectively. The primary opcode is commonly used to 7150// indicate the type of machine instruction, while secondary 7151// and tertiary are often used for prefix options or addressing 7152// modes. 7153// ins_encode -- A list of encode classes with parameters. The encode class 7154// name must have been defined in an 'enc_class' specification 7155// in the encode section of the architecture description. 7156 7157// ============================================================================ 7158// Memory (Load/Store) Instructions 7159 7160// Load Instructions 7161 7162// Load Byte (8 bit signed) 7163instruct loadB(iRegINoSp dst, memory1 mem) 7164%{ 7165 match(Set dst (LoadB mem)); 7166 predicate(!needs_acquiring_load(n)); 7167 7168 ins_cost(4 * INSN_COST); 7169 format %{ "ldrsbw $dst, $mem\t# byte" %} 7170 7171 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 7172 7173 ins_pipe(iload_reg_mem); 7174%} 7175 7176// Load Byte (8 bit signed) into long 7177instruct loadB2L(iRegLNoSp dst, memory1 mem) 7178%{ 7179 match(Set dst (ConvI2L (LoadB mem))); 7180 predicate(!needs_acquiring_load(n->in(1))); 7181 7182 ins_cost(4 * INSN_COST); 7183 format %{ "ldrsb $dst, $mem\t# byte" %} 7184 7185 ins_encode(aarch64_enc_ldrsb(dst, mem)); 7186 7187 ins_pipe(iload_reg_mem); 7188%} 7189 7190// Load Byte (8 bit unsigned) 7191instruct loadUB(iRegINoSp dst, memory1 mem) 7192%{ 7193 match(Set dst (LoadUB mem)); 7194 predicate(!needs_acquiring_load(n)); 7195 7196 ins_cost(4 * INSN_COST); 7197 format %{ "ldrbw $dst, $mem\t# byte" %} 7198 7199 ins_encode(aarch64_enc_ldrb(dst, mem)); 7200 7201 ins_pipe(iload_reg_mem); 7202%} 7203 7204// Load Byte (8 bit unsigned) into long 7205instruct loadUB2L(iRegLNoSp dst, memory1 mem) 7206%{ 7207 match(Set dst (ConvI2L (LoadUB mem))); 7208 predicate(!needs_acquiring_load(n->in(1))); 7209 7210 ins_cost(4 * INSN_COST); 7211 format %{ "ldrb $dst, $mem\t# byte" %} 7212 7213 ins_encode(aarch64_enc_ldrb(dst, mem)); 7214 7215 ins_pipe(iload_reg_mem); 7216%} 7217 7218// Load Short (16 bit signed) 7219instruct loadS(iRegINoSp dst, memory2 mem) 7220%{ 7221 match(Set dst (LoadS mem)); 7222 predicate(!needs_acquiring_load(n)); 7223 7224 ins_cost(4 * INSN_COST); 7225 format %{ "ldrshw $dst, $mem\t# short" %} 7226 7227 ins_encode(aarch64_enc_ldrshw(dst, mem)); 7228 7229 ins_pipe(iload_reg_mem); 7230%} 7231 7232// Load Short (16 bit signed) into long 7233instruct loadS2L(iRegLNoSp dst, memory2 mem) 7234%{ 7235 match(Set dst (ConvI2L (LoadS mem))); 7236 predicate(!needs_acquiring_load(n->in(1))); 7237 7238 ins_cost(4 * INSN_COST); 7239 format %{ "ldrsh $dst, $mem\t# short" %} 7240 7241 ins_encode(aarch64_enc_ldrsh(dst, mem)); 7242 7243 ins_pipe(iload_reg_mem); 7244%} 7245 7246// Load Char (16 bit unsigned) 7247instruct loadUS(iRegINoSp dst, memory2 mem) 7248%{ 7249 match(Set dst (LoadUS mem)); 7250 predicate(!needs_acquiring_load(n)); 7251 7252 ins_cost(4 * INSN_COST); 7253 format %{ "ldrh $dst, $mem\t# short" %} 7254 7255 ins_encode(aarch64_enc_ldrh(dst, mem)); 7256 7257 ins_pipe(iload_reg_mem); 7258%} 7259 7260// Load Short/Char (16 bit unsigned) into long 7261instruct loadUS2L(iRegLNoSp dst, memory2 mem) 7262%{ 7263 match(Set dst (ConvI2L (LoadUS mem))); 7264 predicate(!needs_acquiring_load(n->in(1))); 7265 7266 ins_cost(4 * INSN_COST); 7267 format %{ "ldrh $dst, $mem\t# short" %} 7268 7269 ins_encode(aarch64_enc_ldrh(dst, mem)); 7270 7271 ins_pipe(iload_reg_mem); 7272%} 7273 7274// Load Integer (32 bit signed) 7275instruct loadI(iRegINoSp dst, memory4 mem) 7276%{ 7277 match(Set dst (LoadI mem)); 7278 predicate(!needs_acquiring_load(n)); 7279 7280 ins_cost(4 * INSN_COST); 7281 format %{ "ldrw $dst, $mem\t# int" %} 7282 7283 ins_encode(aarch64_enc_ldrw(dst, mem)); 7284 7285 ins_pipe(iload_reg_mem); 7286%} 7287 7288// Load Integer (32 bit signed) into long 7289instruct loadI2L(iRegLNoSp dst, memory4 mem) 7290%{ 7291 match(Set dst (ConvI2L (LoadI mem))); 7292 predicate(!needs_acquiring_load(n->in(1))); 7293 7294 ins_cost(4 * INSN_COST); 7295 format %{ "ldrsw $dst, $mem\t# int" %} 7296 7297 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7298 7299 ins_pipe(iload_reg_mem); 7300%} 7301 7302// Load Integer (32 bit unsigned) into long 7303instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7304%{ 7305 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7306 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7307 7308 ins_cost(4 * INSN_COST); 7309 format %{ "ldrw $dst, $mem\t# int" %} 7310 7311 ins_encode(aarch64_enc_ldrw(dst, mem)); 7312 7313 ins_pipe(iload_reg_mem); 7314%} 7315 7316// Load Long (64 bit signed) 7317instruct loadL(iRegLNoSp dst, memory8 mem) 7318%{ 7319 match(Set dst (LoadL mem)); 7320 predicate(!needs_acquiring_load(n)); 7321 7322 ins_cost(4 * INSN_COST); 7323 format %{ "ldr $dst, $mem\t# int" %} 7324 7325 ins_encode(aarch64_enc_ldr(dst, mem)); 7326 7327 ins_pipe(iload_reg_mem); 7328%} 7329 7330// Load Range 7331instruct loadRange(iRegINoSp dst, memory4 mem) 7332%{ 7333 match(Set dst (LoadRange mem)); 7334 7335 ins_cost(4 * INSN_COST); 7336 format %{ "ldrw $dst, $mem\t# range" %} 7337 7338 ins_encode(aarch64_enc_ldrw(dst, mem)); 7339 7340 ins_pipe(iload_reg_mem); 7341%} 7342 7343// Load Pointer 7344instruct loadP(iRegPNoSp dst, memory8 mem) 7345%{ 7346 match(Set dst (LoadP mem)); 7347 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7348 7349 ins_cost(4 * INSN_COST); 7350 format %{ "ldr $dst, $mem\t# ptr" %} 7351 7352 ins_encode(aarch64_enc_ldr(dst, mem)); 7353 7354 ins_pipe(iload_reg_mem); 7355%} 7356 7357// Load Compressed Pointer 7358instruct loadN(iRegNNoSp dst, memory4 mem) 7359%{ 7360 match(Set dst (LoadN mem)); 7361 predicate(!needs_acquiring_load(n)); 7362 7363 ins_cost(4 * INSN_COST); 7364 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7365 7366 ins_encode(aarch64_enc_ldrw(dst, mem)); 7367 7368 ins_pipe(iload_reg_mem); 7369%} 7370 7371// Load Klass Pointer 7372instruct loadKlass(iRegPNoSp dst, memory8 mem) 7373%{ 7374 match(Set dst (LoadKlass mem)); 7375 predicate(!needs_acquiring_load(n)); 7376 7377 ins_cost(4 * INSN_COST); 7378 format %{ "ldr $dst, $mem\t# class" %} 7379 7380 ins_encode(aarch64_enc_ldr(dst, mem)); 7381 7382 ins_pipe(iload_reg_mem); 7383%} 7384 7385// Load Narrow Klass Pointer 7386instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7387%{ 7388 match(Set dst (LoadNKlass mem)); 7389 predicate(!needs_acquiring_load(n)); 7390 7391 ins_cost(4 * INSN_COST); 7392 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7393 7394 ins_encode(aarch64_enc_ldrw(dst, mem)); 7395 7396 ins_pipe(iload_reg_mem); 7397%} 7398 7399// Load Float 7400instruct loadF(vRegF dst, memory4 mem) 7401%{ 7402 match(Set dst (LoadF mem)); 7403 predicate(!needs_acquiring_load(n)); 7404 7405 ins_cost(4 * INSN_COST); 7406 format %{ "ldrs $dst, $mem\t# float" %} 7407 7408 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7409 7410 ins_pipe(pipe_class_memory); 7411%} 7412 7413// Load Double 7414instruct loadD(vRegD dst, memory8 mem) 7415%{ 7416 match(Set dst (LoadD mem)); 7417 predicate(!needs_acquiring_load(n)); 7418 7419 ins_cost(4 * INSN_COST); 7420 format %{ "ldrd $dst, $mem\t# double" %} 7421 7422 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7423 7424 ins_pipe(pipe_class_memory); 7425%} 7426 7427 7428// Load Int Constant 7429instruct loadConI(iRegINoSp dst, immI src) 7430%{ 7431 match(Set dst src); 7432 7433 ins_cost(INSN_COST); 7434 format %{ "mov $dst, $src\t# int" %} 7435 7436 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7437 7438 ins_pipe(ialu_imm); 7439%} 7440 7441// Load Long Constant 7442instruct loadConL(iRegLNoSp dst, immL src) 7443%{ 7444 match(Set dst src); 7445 7446 ins_cost(INSN_COST); 7447 format %{ "mov $dst, $src\t# long" %} 7448 7449 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7450 7451 ins_pipe(ialu_imm); 7452%} 7453 7454// Load Pointer Constant 7455 7456instruct loadConP(iRegPNoSp dst, immP con) 7457%{ 7458 match(Set dst con); 7459 7460 ins_cost(INSN_COST * 4); 7461 format %{ 7462 "mov $dst, $con\t# ptr\n\t" 7463 %} 7464 7465 ins_encode(aarch64_enc_mov_p(dst, con)); 7466 7467 ins_pipe(ialu_imm); 7468%} 7469 7470// Load Null Pointer Constant 7471 7472instruct loadConP0(iRegPNoSp dst, immP0 con) 7473%{ 7474 match(Set dst con); 7475 7476 ins_cost(INSN_COST); 7477 format %{ "mov $dst, $con\t# NULL ptr" %} 7478 7479 ins_encode(aarch64_enc_mov_p0(dst, con)); 7480 7481 ins_pipe(ialu_imm); 7482%} 7483 7484// Load Pointer Constant One 7485 7486instruct loadConP1(iRegPNoSp dst, immP_1 con) 7487%{ 7488 match(Set dst con); 7489 7490 ins_cost(INSN_COST); 7491 format %{ "mov $dst, $con\t# NULL ptr" %} 7492 7493 ins_encode(aarch64_enc_mov_p1(dst, con)); 7494 7495 ins_pipe(ialu_imm); 7496%} 7497 7498// Load Byte Map Base Constant 7499 7500instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7501%{ 7502 match(Set dst con); 7503 7504 ins_cost(INSN_COST); 7505 format %{ "adr $dst, $con\t# Byte Map Base" %} 7506 7507 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7508 7509 ins_pipe(ialu_imm); 7510%} 7511 7512// Load Narrow Pointer Constant 7513 7514instruct loadConN(iRegNNoSp dst, immN con) 7515%{ 7516 match(Set dst con); 7517 7518 ins_cost(INSN_COST * 4); 7519 format %{ "mov $dst, $con\t# compressed ptr" %} 7520 7521 ins_encode(aarch64_enc_mov_n(dst, con)); 7522 7523 ins_pipe(ialu_imm); 7524%} 7525 7526// Load Narrow Null Pointer Constant 7527 7528instruct loadConN0(iRegNNoSp dst, immN0 con) 7529%{ 7530 match(Set dst con); 7531 7532 ins_cost(INSN_COST); 7533 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 7534 7535 ins_encode(aarch64_enc_mov_n0(dst, con)); 7536 7537 ins_pipe(ialu_imm); 7538%} 7539 7540// Load Narrow Klass Constant 7541 7542instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7543%{ 7544 match(Set dst con); 7545 7546 ins_cost(INSN_COST); 7547 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7548 7549 ins_encode(aarch64_enc_mov_nk(dst, con)); 7550 7551 ins_pipe(ialu_imm); 7552%} 7553 7554// Load Packed Float Constant 7555 7556instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7557 match(Set dst con); 7558 ins_cost(INSN_COST * 4); 7559 format %{ "fmovs $dst, $con"%} 7560 ins_encode %{ 7561 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7562 %} 7563 7564 ins_pipe(fp_imm_s); 7565%} 7566 7567// Load Float Constant 7568 7569instruct loadConF(vRegF dst, immF con) %{ 7570 match(Set dst con); 7571 7572 ins_cost(INSN_COST * 4); 7573 7574 format %{ 7575 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7576 %} 7577 7578 ins_encode %{ 7579 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7580 %} 7581 7582 ins_pipe(fp_load_constant_s); 7583%} 7584 7585// Load Packed Double Constant 7586 7587instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7588 match(Set dst con); 7589 ins_cost(INSN_COST); 7590 format %{ "fmovd $dst, $con"%} 7591 ins_encode %{ 7592 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7593 %} 7594 7595 ins_pipe(fp_imm_d); 7596%} 7597 7598// Load Double Constant 7599 7600instruct loadConD(vRegD dst, immD con) %{ 7601 match(Set dst con); 7602 7603 ins_cost(INSN_COST * 5); 7604 format %{ 7605 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7606 %} 7607 7608 ins_encode %{ 7609 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7610 %} 7611 7612 ins_pipe(fp_load_constant_d); 7613%} 7614 7615// Store Instructions 7616 7617// Store CMS card-mark Immediate 7618instruct storeimmCM0(immI0 zero, memory1 mem) 7619%{ 7620 match(Set mem (StoreCM mem zero)); 7621 7622 ins_cost(INSN_COST); 7623 format %{ "storestore (elided)\n\t" 7624 "strb zr, $mem\t# byte" %} 7625 7626 ins_encode(aarch64_enc_strb0(mem)); 7627 7628 ins_pipe(istore_mem); 7629%} 7630 7631// Store CMS card-mark Immediate with intervening StoreStore 7632// needed when using CMS with no conditional card marking 7633instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7634%{ 7635 match(Set mem (StoreCM mem zero)); 7636 7637 ins_cost(INSN_COST * 2); 7638 format %{ "storestore\n\t" 7639 "dmb ishst" 7640 "\n\tstrb zr, $mem\t# byte" %} 7641 7642 ins_encode(aarch64_enc_strb0_ordered(mem)); 7643 7644 ins_pipe(istore_mem); 7645%} 7646 7647// Store Byte 7648instruct storeB(iRegIorL2I src, memory1 mem) 7649%{ 7650 match(Set mem (StoreB mem src)); 7651 predicate(!needs_releasing_store(n)); 7652 7653 ins_cost(INSN_COST); 7654 format %{ "strb $src, $mem\t# byte" %} 7655 7656 ins_encode(aarch64_enc_strb(src, mem)); 7657 7658 ins_pipe(istore_reg_mem); 7659%} 7660 7661 7662instruct storeimmB0(immI0 zero, memory1 mem) 7663%{ 7664 match(Set mem (StoreB mem zero)); 7665 predicate(!needs_releasing_store(n)); 7666 7667 ins_cost(INSN_COST); 7668 format %{ "strb rscractch2, $mem\t# byte" %} 7669 7670 ins_encode(aarch64_enc_strb0(mem)); 7671 7672 ins_pipe(istore_mem); 7673%} 7674 7675// Store Char/Short 7676instruct storeC(iRegIorL2I src, memory2 mem) 7677%{ 7678 match(Set mem (StoreC mem src)); 7679 predicate(!needs_releasing_store(n)); 7680 7681 ins_cost(INSN_COST); 7682 format %{ "strh $src, $mem\t# short" %} 7683 7684 ins_encode(aarch64_enc_strh(src, mem)); 7685 7686 ins_pipe(istore_reg_mem); 7687%} 7688 7689instruct storeimmC0(immI0 zero, memory2 mem) 7690%{ 7691 match(Set mem (StoreC mem zero)); 7692 predicate(!needs_releasing_store(n)); 7693 7694 ins_cost(INSN_COST); 7695 format %{ "strh zr, $mem\t# short" %} 7696 7697 ins_encode(aarch64_enc_strh0(mem)); 7698 7699 ins_pipe(istore_mem); 7700%} 7701 7702// Store Integer 7703 7704instruct storeI(iRegIorL2I src, memory4 mem) 7705%{ 7706 match(Set mem(StoreI mem src)); 7707 predicate(!needs_releasing_store(n)); 7708 7709 ins_cost(INSN_COST); 7710 format %{ "strw $src, $mem\t# int" %} 7711 7712 ins_encode(aarch64_enc_strw(src, mem)); 7713 7714 ins_pipe(istore_reg_mem); 7715%} 7716 7717instruct storeimmI0(immI0 zero, memory4 mem) 7718%{ 7719 match(Set mem(StoreI mem zero)); 7720 predicate(!needs_releasing_store(n)); 7721 7722 ins_cost(INSN_COST); 7723 format %{ "strw zr, $mem\t# int" %} 7724 7725 ins_encode(aarch64_enc_strw0(mem)); 7726 7727 ins_pipe(istore_mem); 7728%} 7729 7730// Store Long (64 bit signed) 7731instruct storeL(iRegL src, memory8 mem) 7732%{ 7733 match(Set mem (StoreL mem src)); 7734 predicate(!needs_releasing_store(n)); 7735 7736 ins_cost(INSN_COST); 7737 format %{ "str $src, $mem\t# int" %} 7738 7739 ins_encode(aarch64_enc_str(src, mem)); 7740 7741 ins_pipe(istore_reg_mem); 7742%} 7743 7744// Store Long (64 bit signed) 7745instruct storeimmL0(immL0 zero, memory8 mem) 7746%{ 7747 match(Set mem (StoreL mem zero)); 7748 predicate(!needs_releasing_store(n)); 7749 7750 ins_cost(INSN_COST); 7751 format %{ "str zr, $mem\t# int" %} 7752 7753 ins_encode(aarch64_enc_str0(mem)); 7754 7755 ins_pipe(istore_mem); 7756%} 7757 7758// Store Pointer 7759instruct storeP(iRegP src, memory8 mem) 7760%{ 7761 match(Set mem (StoreP mem src)); 7762 predicate(!needs_releasing_store(n)); 7763 7764 ins_cost(INSN_COST); 7765 format %{ "str $src, $mem\t# ptr" %} 7766 7767 ins_encode(aarch64_enc_str(src, mem)); 7768 7769 ins_pipe(istore_reg_mem); 7770%} 7771 7772// Store Pointer 7773instruct storeimmP0(immP0 zero, memory8 mem) 7774%{ 7775 match(Set mem (StoreP mem zero)); 7776 predicate(!needs_releasing_store(n)); 7777 7778 ins_cost(INSN_COST); 7779 format %{ "str zr, $mem\t# ptr" %} 7780 7781 ins_encode(aarch64_enc_str0(mem)); 7782 7783 ins_pipe(istore_mem); 7784%} 7785 7786// Store Compressed Pointer 7787instruct storeN(iRegN src, memory4 mem) 7788%{ 7789 match(Set mem (StoreN mem src)); 7790 predicate(!needs_releasing_store(n)); 7791 7792 ins_cost(INSN_COST); 7793 format %{ "strw $src, $mem\t# compressed ptr" %} 7794 7795 ins_encode(aarch64_enc_strw(src, mem)); 7796 7797 ins_pipe(istore_reg_mem); 7798%} 7799 7800instruct storeImmN0(immN0 zero, memory4 mem) 7801%{ 7802 match(Set mem (StoreN mem zero)); 7803 predicate(!needs_releasing_store(n)); 7804 7805 ins_cost(INSN_COST); 7806 format %{ "strw zr, $mem\t# compressed ptr" %} 7807 7808 ins_encode(aarch64_enc_strw0(mem)); 7809 7810 ins_pipe(istore_mem); 7811%} 7812 7813// Store Float 7814instruct storeF(vRegF src, memory4 mem) 7815%{ 7816 match(Set mem (StoreF mem src)); 7817 predicate(!needs_releasing_store(n)); 7818 7819 ins_cost(INSN_COST); 7820 format %{ "strs $src, $mem\t# float" %} 7821 7822 ins_encode( aarch64_enc_strs(src, mem) ); 7823 7824 ins_pipe(pipe_class_memory); 7825%} 7826 7827// TODO 7828// implement storeImmF0 and storeFImmPacked 7829 7830// Store Double 7831instruct storeD(vRegD src, memory8 mem) 7832%{ 7833 match(Set mem (StoreD mem src)); 7834 predicate(!needs_releasing_store(n)); 7835 7836 ins_cost(INSN_COST); 7837 format %{ "strd $src, $mem\t# double" %} 7838 7839 ins_encode( aarch64_enc_strd(src, mem) ); 7840 7841 ins_pipe(pipe_class_memory); 7842%} 7843 7844// Store Compressed Klass Pointer 7845instruct storeNKlass(iRegN src, memory4 mem) 7846%{ 7847 predicate(!needs_releasing_store(n)); 7848 match(Set mem (StoreNKlass mem src)); 7849 7850 ins_cost(INSN_COST); 7851 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7852 7853 ins_encode(aarch64_enc_strw(src, mem)); 7854 7855 ins_pipe(istore_reg_mem); 7856%} 7857 7858// TODO 7859// implement storeImmD0 and storeDImmPacked 7860 7861// prefetch instructions 7862// Must be safe to execute with invalid address (cannot fault). 7863 7864instruct prefetchalloc( memory8 mem ) %{ 7865 match(PrefetchAllocation mem); 7866 7867 ins_cost(INSN_COST); 7868 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7869 7870 ins_encode( aarch64_enc_prefetchw(mem) ); 7871 7872 ins_pipe(iload_prefetch); 7873%} 7874 7875// ---------------- volatile loads and stores ---------------- 7876 7877// Load Byte (8 bit signed) 7878instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7879%{ 7880 match(Set dst (LoadB mem)); 7881 7882 ins_cost(VOLATILE_REF_COST); 7883 format %{ "ldarsb $dst, $mem\t# byte" %} 7884 7885 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7886 7887 ins_pipe(pipe_serial); 7888%} 7889 7890// Load Byte (8 bit signed) into long 7891instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7892%{ 7893 match(Set dst (ConvI2L (LoadB mem))); 7894 7895 ins_cost(VOLATILE_REF_COST); 7896 format %{ "ldarsb $dst, $mem\t# byte" %} 7897 7898 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7899 7900 ins_pipe(pipe_serial); 7901%} 7902 7903// Load Byte (8 bit unsigned) 7904instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7905%{ 7906 match(Set dst (LoadUB mem)); 7907 7908 ins_cost(VOLATILE_REF_COST); 7909 format %{ "ldarb $dst, $mem\t# byte" %} 7910 7911 ins_encode(aarch64_enc_ldarb(dst, mem)); 7912 7913 ins_pipe(pipe_serial); 7914%} 7915 7916// Load Byte (8 bit unsigned) into long 7917instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7918%{ 7919 match(Set dst (ConvI2L (LoadUB mem))); 7920 7921 ins_cost(VOLATILE_REF_COST); 7922 format %{ "ldarb $dst, $mem\t# byte" %} 7923 7924 ins_encode(aarch64_enc_ldarb(dst, mem)); 7925 7926 ins_pipe(pipe_serial); 7927%} 7928 7929// Load Short (16 bit signed) 7930instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7931%{ 7932 match(Set dst (LoadS mem)); 7933 7934 ins_cost(VOLATILE_REF_COST); 7935 format %{ "ldarshw $dst, $mem\t# short" %} 7936 7937 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7938 7939 ins_pipe(pipe_serial); 7940%} 7941 7942instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7943%{ 7944 match(Set dst (LoadUS mem)); 7945 7946 ins_cost(VOLATILE_REF_COST); 7947 format %{ "ldarhw $dst, $mem\t# short" %} 7948 7949 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7950 7951 ins_pipe(pipe_serial); 7952%} 7953 7954// Load Short/Char (16 bit unsigned) into long 7955instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7956%{ 7957 match(Set dst (ConvI2L (LoadUS mem))); 7958 7959 ins_cost(VOLATILE_REF_COST); 7960 format %{ "ldarh $dst, $mem\t# short" %} 7961 7962 ins_encode(aarch64_enc_ldarh(dst, mem)); 7963 7964 ins_pipe(pipe_serial); 7965%} 7966 7967// Load Short/Char (16 bit signed) into long 7968instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7969%{ 7970 match(Set dst (ConvI2L (LoadS mem))); 7971 7972 ins_cost(VOLATILE_REF_COST); 7973 format %{ "ldarh $dst, $mem\t# short" %} 7974 7975 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7976 7977 ins_pipe(pipe_serial); 7978%} 7979 7980// Load Integer (32 bit signed) 7981instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7982%{ 7983 match(Set dst (LoadI mem)); 7984 7985 ins_cost(VOLATILE_REF_COST); 7986 format %{ "ldarw $dst, $mem\t# int" %} 7987 7988 ins_encode(aarch64_enc_ldarw(dst, mem)); 7989 7990 ins_pipe(pipe_serial); 7991%} 7992 7993// Load Integer (32 bit unsigned) into long 7994instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7995%{ 7996 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7997 7998 ins_cost(VOLATILE_REF_COST); 7999 format %{ "ldarw $dst, $mem\t# int" %} 8000 8001 ins_encode(aarch64_enc_ldarw(dst, mem)); 8002 8003 ins_pipe(pipe_serial); 8004%} 8005 8006// Load Long (64 bit signed) 8007instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 8008%{ 8009 match(Set dst (LoadL mem)); 8010 8011 ins_cost(VOLATILE_REF_COST); 8012 format %{ "ldar $dst, $mem\t# int" %} 8013 8014 ins_encode(aarch64_enc_ldar(dst, mem)); 8015 8016 ins_pipe(pipe_serial); 8017%} 8018 8019// Load Pointer 8020instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 8021%{ 8022 match(Set dst (LoadP mem)); 8023 predicate(n->as_Load()->barrier_data() == 0); 8024 8025 ins_cost(VOLATILE_REF_COST); 8026 format %{ "ldar $dst, $mem\t# ptr" %} 8027 8028 ins_encode(aarch64_enc_ldar(dst, mem)); 8029 8030 ins_pipe(pipe_serial); 8031%} 8032 8033// Load Compressed Pointer 8034instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 8035%{ 8036 match(Set dst (LoadN mem)); 8037 8038 ins_cost(VOLATILE_REF_COST); 8039 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 8040 8041 ins_encode(aarch64_enc_ldarw(dst, mem)); 8042 8043 ins_pipe(pipe_serial); 8044%} 8045 8046// Load Float 8047instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 8048%{ 8049 match(Set dst (LoadF mem)); 8050 8051 ins_cost(VOLATILE_REF_COST); 8052 format %{ "ldars $dst, $mem\t# float" %} 8053 8054 ins_encode( aarch64_enc_fldars(dst, mem) ); 8055 8056 ins_pipe(pipe_serial); 8057%} 8058 8059// Load Double 8060instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 8061%{ 8062 match(Set dst (LoadD mem)); 8063 8064 ins_cost(VOLATILE_REF_COST); 8065 format %{ "ldard $dst, $mem\t# double" %} 8066 8067 ins_encode( aarch64_enc_fldard(dst, mem) ); 8068 8069 ins_pipe(pipe_serial); 8070%} 8071 8072// Store Byte 8073instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 8074%{ 8075 match(Set mem (StoreB mem src)); 8076 8077 ins_cost(VOLATILE_REF_COST); 8078 format %{ "stlrb $src, $mem\t# byte" %} 8079 8080 ins_encode(aarch64_enc_stlrb(src, mem)); 8081 8082 ins_pipe(pipe_class_memory); 8083%} 8084 8085// Store Char/Short 8086instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 8087%{ 8088 match(Set mem (StoreC mem src)); 8089 8090 ins_cost(VOLATILE_REF_COST); 8091 format %{ "stlrh $src, $mem\t# short" %} 8092 8093 ins_encode(aarch64_enc_stlrh(src, mem)); 8094 8095 ins_pipe(pipe_class_memory); 8096%} 8097 8098// Store Integer 8099 8100instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 8101%{ 8102 match(Set mem(StoreI mem src)); 8103 8104 ins_cost(VOLATILE_REF_COST); 8105 format %{ "stlrw $src, $mem\t# int" %} 8106 8107 ins_encode(aarch64_enc_stlrw(src, mem)); 8108 8109 ins_pipe(pipe_class_memory); 8110%} 8111 8112// Store Long (64 bit signed) 8113instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 8114%{ 8115 match(Set mem (StoreL mem src)); 8116 8117 ins_cost(VOLATILE_REF_COST); 8118 format %{ "stlr $src, $mem\t# int" %} 8119 8120 ins_encode(aarch64_enc_stlr(src, mem)); 8121 8122 ins_pipe(pipe_class_memory); 8123%} 8124 8125// Store Pointer 8126instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 8127%{ 8128 match(Set mem (StoreP mem src)); 8129 8130 ins_cost(VOLATILE_REF_COST); 8131 format %{ "stlr $src, $mem\t# ptr" %} 8132 8133 ins_encode(aarch64_enc_stlr(src, mem)); 8134 8135 ins_pipe(pipe_class_memory); 8136%} 8137 8138// Store Compressed Pointer 8139instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 8140%{ 8141 match(Set mem (StoreN mem src)); 8142 8143 ins_cost(VOLATILE_REF_COST); 8144 format %{ "stlrw $src, $mem\t# compressed ptr" %} 8145 8146 ins_encode(aarch64_enc_stlrw(src, mem)); 8147 8148 ins_pipe(pipe_class_memory); 8149%} 8150 8151// Store Float 8152instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 8153%{ 8154 match(Set mem (StoreF mem src)); 8155 8156 ins_cost(VOLATILE_REF_COST); 8157 format %{ "stlrs $src, $mem\t# float" %} 8158 8159 ins_encode( aarch64_enc_fstlrs(src, mem) ); 8160 8161 ins_pipe(pipe_class_memory); 8162%} 8163 8164// TODO 8165// implement storeImmF0 and storeFImmPacked 8166 8167// Store Double 8168instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 8169%{ 8170 match(Set mem (StoreD mem src)); 8171 8172 ins_cost(VOLATILE_REF_COST); 8173 format %{ "stlrd $src, $mem\t# double" %} 8174 8175 ins_encode( aarch64_enc_fstlrd(src, mem) ); 8176 8177 ins_pipe(pipe_class_memory); 8178%} 8179 8180// ---------------- end of volatile loads and stores ---------------- 8181 8182instruct cacheWB(indirect addr) 8183%{ 8184 predicate(VM_Version::supports_data_cache_line_flush()); 8185 match(CacheWB addr); 8186 8187 ins_cost(100); 8188 format %{"cache wb $addr" %} 8189 ins_encode %{ 8190 assert($addr->index_position() < 0, "should be"); 8191 assert($addr$$disp == 0, "should be"); 8192 __ cache_wb(Address($addr$$base$$Register, 0)); 8193 %} 8194 ins_pipe(pipe_slow); // XXX 8195%} 8196 8197instruct cacheWBPreSync() 8198%{ 8199 predicate(VM_Version::supports_data_cache_line_flush()); 8200 match(CacheWBPreSync); 8201 8202 ins_cost(100); 8203 format %{"cache wb presync" %} 8204 ins_encode %{ 8205 __ cache_wbsync(true); 8206 %} 8207 ins_pipe(pipe_slow); // XXX 8208%} 8209 8210instruct cacheWBPostSync() 8211%{ 8212 predicate(VM_Version::supports_data_cache_line_flush()); 8213 match(CacheWBPostSync); 8214 8215 ins_cost(100); 8216 format %{"cache wb postsync" %} 8217 ins_encode %{ 8218 __ cache_wbsync(false); 8219 %} 8220 ins_pipe(pipe_slow); // XXX 8221%} 8222 8223// ============================================================================ 8224// BSWAP Instructions 8225 8226instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 8227 match(Set dst (ReverseBytesI src)); 8228 8229 ins_cost(INSN_COST); 8230 format %{ "revw $dst, $src" %} 8231 8232 ins_encode %{ 8233 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 8234 %} 8235 8236 ins_pipe(ialu_reg); 8237%} 8238 8239instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 8240 match(Set dst (ReverseBytesL src)); 8241 8242 ins_cost(INSN_COST); 8243 format %{ "rev $dst, $src" %} 8244 8245 ins_encode %{ 8246 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 8247 %} 8248 8249 ins_pipe(ialu_reg); 8250%} 8251 8252instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 8253 match(Set dst (ReverseBytesUS src)); 8254 8255 ins_cost(INSN_COST); 8256 format %{ "rev16w $dst, $src" %} 8257 8258 ins_encode %{ 8259 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8260 %} 8261 8262 ins_pipe(ialu_reg); 8263%} 8264 8265instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 8266 match(Set dst (ReverseBytesS src)); 8267 8268 ins_cost(INSN_COST); 8269 format %{ "rev16w $dst, $src\n\t" 8270 "sbfmw $dst, $dst, #0, #15" %} 8271 8272 ins_encode %{ 8273 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8274 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 8275 %} 8276 8277 ins_pipe(ialu_reg); 8278%} 8279 8280// ============================================================================ 8281// Zero Count Instructions 8282 8283instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8284 match(Set dst (CountLeadingZerosI src)); 8285 8286 ins_cost(INSN_COST); 8287 format %{ "clzw $dst, $src" %} 8288 ins_encode %{ 8289 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8290 %} 8291 8292 ins_pipe(ialu_reg); 8293%} 8294 8295instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8296 match(Set dst (CountLeadingZerosL src)); 8297 8298 ins_cost(INSN_COST); 8299 format %{ "clz $dst, $src" %} 8300 ins_encode %{ 8301 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8302 %} 8303 8304 ins_pipe(ialu_reg); 8305%} 8306 8307instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8308 match(Set dst (CountTrailingZerosI src)); 8309 8310 ins_cost(INSN_COST * 2); 8311 format %{ "rbitw $dst, $src\n\t" 8312 "clzw $dst, $dst" %} 8313 ins_encode %{ 8314 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8315 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8316 %} 8317 8318 ins_pipe(ialu_reg); 8319%} 8320 8321instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8322 match(Set dst (CountTrailingZerosL src)); 8323 8324 ins_cost(INSN_COST * 2); 8325 format %{ "rbit $dst, $src\n\t" 8326 "clz $dst, $dst" %} 8327 ins_encode %{ 8328 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8329 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8330 %} 8331 8332 ins_pipe(ialu_reg); 8333%} 8334 8335//---------- Population Count Instructions ------------------------------------- 8336// 8337 8338instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8339 predicate(UsePopCountInstruction); 8340 match(Set dst (PopCountI src)); 8341 effect(TEMP tmp); 8342 ins_cost(INSN_COST * 13); 8343 8344 format %{ "movw $src, $src\n\t" 8345 "mov $tmp, $src\t# vector (1D)\n\t" 8346 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8347 "addv $tmp, $tmp\t# vector (8B)\n\t" 8348 "mov $dst, $tmp\t# vector (1D)" %} 8349 ins_encode %{ 8350 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8351 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8352 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8353 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8354 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8355 %} 8356 8357 ins_pipe(pipe_class_default); 8358%} 8359 8360instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8361 predicate(UsePopCountInstruction); 8362 match(Set dst (PopCountI (LoadI mem))); 8363 effect(TEMP tmp); 8364 ins_cost(INSN_COST * 13); 8365 8366 format %{ "ldrs $tmp, $mem\n\t" 8367 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8368 "addv $tmp, $tmp\t# vector (8B)\n\t" 8369 "mov $dst, $tmp\t# vector (1D)" %} 8370 ins_encode %{ 8371 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8372 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8373 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8374 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8375 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8376 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8377 %} 8378 8379 ins_pipe(pipe_class_default); 8380%} 8381 8382// Note: Long.bitCount(long) returns an int. 8383instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8384 predicate(UsePopCountInstruction); 8385 match(Set dst (PopCountL src)); 8386 effect(TEMP tmp); 8387 ins_cost(INSN_COST * 13); 8388 8389 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8390 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8391 "addv $tmp, $tmp\t# vector (8B)\n\t" 8392 "mov $dst, $tmp\t# vector (1D)" %} 8393 ins_encode %{ 8394 __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register); 8395 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8396 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8397 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8398 %} 8399 8400 ins_pipe(pipe_class_default); 8401%} 8402 8403instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8404 predicate(UsePopCountInstruction); 8405 match(Set dst (PopCountL (LoadL mem))); 8406 effect(TEMP tmp); 8407 ins_cost(INSN_COST * 13); 8408 8409 format %{ "ldrd $tmp, $mem\n\t" 8410 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8411 "addv $tmp, $tmp\t# vector (8B)\n\t" 8412 "mov $dst, $tmp\t# vector (1D)" %} 8413 ins_encode %{ 8414 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8415 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8416 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8417 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8418 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8419 __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0); 8420 %} 8421 8422 ins_pipe(pipe_class_default); 8423%} 8424 8425// ============================================================================ 8426// MemBar Instruction 8427 8428instruct load_fence() %{ 8429 match(LoadFence); 8430 ins_cost(VOLATILE_REF_COST); 8431 8432 format %{ "load_fence" %} 8433 8434 ins_encode %{ 8435 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8436 %} 8437 ins_pipe(pipe_serial); 8438%} 8439 8440instruct unnecessary_membar_acquire() %{ 8441 predicate(unnecessary_acquire(n)); 8442 match(MemBarAcquire); 8443 ins_cost(0); 8444 8445 format %{ "membar_acquire (elided)" %} 8446 8447 ins_encode %{ 8448 __ block_comment("membar_acquire (elided)"); 8449 %} 8450 8451 ins_pipe(pipe_class_empty); 8452%} 8453 8454instruct membar_acquire() %{ 8455 match(MemBarAcquire); 8456 ins_cost(VOLATILE_REF_COST); 8457 8458 format %{ "membar_acquire\n\t" 8459 "dmb ish" %} 8460 8461 ins_encode %{ 8462 __ block_comment("membar_acquire"); 8463 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8464 %} 8465 8466 ins_pipe(pipe_serial); 8467%} 8468 8469 8470instruct membar_acquire_lock() %{ 8471 match(MemBarAcquireLock); 8472 ins_cost(VOLATILE_REF_COST); 8473 8474 format %{ "membar_acquire_lock (elided)" %} 8475 8476 ins_encode %{ 8477 __ block_comment("membar_acquire_lock (elided)"); 8478 %} 8479 8480 ins_pipe(pipe_serial); 8481%} 8482 8483instruct store_fence() %{ 8484 match(StoreFence); 8485 ins_cost(VOLATILE_REF_COST); 8486 8487 format %{ "store_fence" %} 8488 8489 ins_encode %{ 8490 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8491 %} 8492 ins_pipe(pipe_serial); 8493%} 8494 8495instruct unnecessary_membar_release() %{ 8496 predicate(unnecessary_release(n)); 8497 match(MemBarRelease); 8498 ins_cost(0); 8499 8500 format %{ "membar_release (elided)" %} 8501 8502 ins_encode %{ 8503 __ block_comment("membar_release (elided)"); 8504 %} 8505 ins_pipe(pipe_serial); 8506%} 8507 8508instruct membar_release() %{ 8509 match(MemBarRelease); 8510 ins_cost(VOLATILE_REF_COST); 8511 8512 format %{ "membar_release\n\t" 8513 "dmb ish" %} 8514 8515 ins_encode %{ 8516 __ block_comment("membar_release"); 8517 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8518 %} 8519 ins_pipe(pipe_serial); 8520%} 8521 8522instruct membar_storestore() %{ 8523 match(MemBarStoreStore); 8524 ins_cost(VOLATILE_REF_COST); 8525 8526 format %{ "MEMBAR-store-store" %} 8527 8528 ins_encode %{ 8529 __ membar(Assembler::StoreStore); 8530 %} 8531 ins_pipe(pipe_serial); 8532%} 8533 8534instruct membar_release_lock() %{ 8535 match(MemBarReleaseLock); 8536 ins_cost(VOLATILE_REF_COST); 8537 8538 format %{ "membar_release_lock (elided)" %} 8539 8540 ins_encode %{ 8541 __ block_comment("membar_release_lock (elided)"); 8542 %} 8543 8544 ins_pipe(pipe_serial); 8545%} 8546 8547instruct unnecessary_membar_volatile() %{ 8548 predicate(unnecessary_volatile(n)); 8549 match(MemBarVolatile); 8550 ins_cost(0); 8551 8552 format %{ "membar_volatile (elided)" %} 8553 8554 ins_encode %{ 8555 __ block_comment("membar_volatile (elided)"); 8556 %} 8557 8558 ins_pipe(pipe_serial); 8559%} 8560 8561instruct membar_volatile() %{ 8562 match(MemBarVolatile); 8563 ins_cost(VOLATILE_REF_COST*100); 8564 8565 format %{ "membar_volatile\n\t" 8566 "dmb ish"%} 8567 8568 ins_encode %{ 8569 __ block_comment("membar_volatile"); 8570 __ membar(Assembler::StoreLoad); 8571 %} 8572 8573 ins_pipe(pipe_serial); 8574%} 8575 8576// ============================================================================ 8577// Cast/Convert Instructions 8578 8579instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8580 match(Set dst (CastX2P src)); 8581 8582 ins_cost(INSN_COST); 8583 format %{ "mov $dst, $src\t# long -> ptr" %} 8584 8585 ins_encode %{ 8586 if ($dst$$reg != $src$$reg) { 8587 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8588 } 8589 %} 8590 8591 ins_pipe(ialu_reg); 8592%} 8593 8594instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8595 match(Set dst (CastP2X src)); 8596 8597 ins_cost(INSN_COST); 8598 format %{ "mov $dst, $src\t# ptr -> long" %} 8599 8600 ins_encode %{ 8601 if ($dst$$reg != $src$$reg) { 8602 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8603 } 8604 %} 8605 8606 ins_pipe(ialu_reg); 8607%} 8608 8609// Convert oop into int for vectors alignment masking 8610instruct convP2I(iRegINoSp dst, iRegP src) %{ 8611 match(Set dst (ConvL2I (CastP2X src))); 8612 8613 ins_cost(INSN_COST); 8614 format %{ "movw $dst, $src\t# ptr -> int" %} 8615 ins_encode %{ 8616 __ movw($dst$$Register, $src$$Register); 8617 %} 8618 8619 ins_pipe(ialu_reg); 8620%} 8621 8622// Convert compressed oop into int for vectors alignment masking 8623// in case of 32bit oops (heap < 4Gb). 8624instruct convN2I(iRegINoSp dst, iRegN src) 8625%{ 8626 predicate(CompressedOops::shift() == 0); 8627 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8628 8629 ins_cost(INSN_COST); 8630 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8631 ins_encode %{ 8632 __ movw($dst$$Register, $src$$Register); 8633 %} 8634 8635 ins_pipe(ialu_reg); 8636%} 8637 8638 8639// Convert oop pointer into compressed form 8640instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8641 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8642 match(Set dst (EncodeP src)); 8643 effect(KILL cr); 8644 ins_cost(INSN_COST * 3); 8645 format %{ "encode_heap_oop $dst, $src" %} 8646 ins_encode %{ 8647 Register s = $src$$Register; 8648 Register d = $dst$$Register; 8649 __ encode_heap_oop(d, s); 8650 %} 8651 ins_pipe(ialu_reg); 8652%} 8653 8654instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8655 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8656 match(Set dst (EncodeP src)); 8657 ins_cost(INSN_COST * 3); 8658 format %{ "encode_heap_oop_not_null $dst, $src" %} 8659 ins_encode %{ 8660 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8661 %} 8662 ins_pipe(ialu_reg); 8663%} 8664 8665instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8666 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8667 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8668 match(Set dst (DecodeN src)); 8669 ins_cost(INSN_COST * 3); 8670 format %{ "decode_heap_oop $dst, $src" %} 8671 ins_encode %{ 8672 Register s = $src$$Register; 8673 Register d = $dst$$Register; 8674 __ decode_heap_oop(d, s); 8675 %} 8676 ins_pipe(ialu_reg); 8677%} 8678 8679instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8680 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8681 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8682 match(Set dst (DecodeN src)); 8683 ins_cost(INSN_COST * 3); 8684 format %{ "decode_heap_oop_not_null $dst, $src" %} 8685 ins_encode %{ 8686 Register s = $src$$Register; 8687 Register d = $dst$$Register; 8688 __ decode_heap_oop_not_null(d, s); 8689 %} 8690 ins_pipe(ialu_reg); 8691%} 8692 8693// n.b. AArch64 implementations of encode_klass_not_null and 8694// decode_klass_not_null do not modify the flags register so, unlike 8695// Intel, we don't kill CR as a side effect here 8696 8697instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8698 match(Set dst (EncodePKlass src)); 8699 8700 ins_cost(INSN_COST * 3); 8701 format %{ "encode_klass_not_null $dst,$src" %} 8702 8703 ins_encode %{ 8704 Register src_reg = as_Register($src$$reg); 8705 Register dst_reg = as_Register($dst$$reg); 8706 __ encode_klass_not_null(dst_reg, src_reg); 8707 %} 8708 8709 ins_pipe(ialu_reg); 8710%} 8711 8712instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8713 match(Set dst (DecodeNKlass src)); 8714 8715 ins_cost(INSN_COST * 3); 8716 format %{ "decode_klass_not_null $dst,$src" %} 8717 8718 ins_encode %{ 8719 Register src_reg = as_Register($src$$reg); 8720 Register dst_reg = as_Register($dst$$reg); 8721 if (dst_reg != src_reg) { 8722 __ decode_klass_not_null(dst_reg, src_reg); 8723 } else { 8724 __ decode_klass_not_null(dst_reg); 8725 } 8726 %} 8727 8728 ins_pipe(ialu_reg); 8729%} 8730 8731instruct checkCastPP(iRegPNoSp dst) 8732%{ 8733 match(Set dst (CheckCastPP dst)); 8734 8735 size(0); 8736 format %{ "# checkcastPP of $dst" %} 8737 ins_encode(/* empty encoding */); 8738 ins_pipe(pipe_class_empty); 8739%} 8740 8741instruct castPP(iRegPNoSp dst) 8742%{ 8743 match(Set dst (CastPP dst)); 8744 8745 size(0); 8746 format %{ "# castPP of $dst" %} 8747 ins_encode(/* empty encoding */); 8748 ins_pipe(pipe_class_empty); 8749%} 8750 8751instruct castII(iRegI dst) 8752%{ 8753 match(Set dst (CastII dst)); 8754 8755 size(0); 8756 format %{ "# castII of $dst" %} 8757 ins_encode(/* empty encoding */); 8758 ins_cost(0); 8759 ins_pipe(pipe_class_empty); 8760%} 8761 8762instruct castLL(iRegL dst) 8763%{ 8764 match(Set dst (CastLL dst)); 8765 8766 size(0); 8767 format %{ "# castLL of $dst" %} 8768 ins_encode(/* empty encoding */); 8769 ins_cost(0); 8770 ins_pipe(pipe_class_empty); 8771%} 8772 8773instruct castFF(vRegF dst) 8774%{ 8775 match(Set dst (CastFF dst)); 8776 8777 size(0); 8778 format %{ "# castFF of $dst" %} 8779 ins_encode(/* empty encoding */); 8780 ins_cost(0); 8781 ins_pipe(pipe_class_empty); 8782%} 8783 8784instruct castDD(vRegD dst) 8785%{ 8786 match(Set dst (CastDD dst)); 8787 8788 size(0); 8789 format %{ "# castDD of $dst" %} 8790 ins_encode(/* empty encoding */); 8791 ins_cost(0); 8792 ins_pipe(pipe_class_empty); 8793%} 8794 8795instruct castVVD(vecD dst) 8796%{ 8797 match(Set dst (CastVV dst)); 8798 8799 size(0); 8800 format %{ "# castVV of $dst" %} 8801 ins_encode(/* empty encoding */); 8802 ins_cost(0); 8803 ins_pipe(pipe_class_empty); 8804%} 8805 8806instruct castVVX(vecX dst) 8807%{ 8808 match(Set dst (CastVV dst)); 8809 8810 size(0); 8811 format %{ "# castVV of $dst" %} 8812 ins_encode(/* empty encoding */); 8813 ins_cost(0); 8814 ins_pipe(pipe_class_empty); 8815%} 8816 8817instruct castVV(vReg dst) 8818%{ 8819 match(Set dst (CastVV dst)); 8820 8821 size(0); 8822 format %{ "# castVV of $dst" %} 8823 ins_encode(/* empty encoding */); 8824 ins_cost(0); 8825 ins_pipe(pipe_class_empty); 8826%} 8827 8828// ============================================================================ 8829// Atomic operation instructions 8830// 8831// Intel and SPARC both implement Ideal Node LoadPLocked and 8832// Store{PIL}Conditional instructions using a normal load for the 8833// LoadPLocked and a CAS for the Store{PIL}Conditional. 8834// 8835// The ideal code appears only to use LoadPLocked/StorePLocked as a 8836// pair to lock object allocations from Eden space when not using 8837// TLABs. 8838// 8839// There does not appear to be a Load{IL}Locked Ideal Node and the 8840// Ideal code appears to use Store{IL}Conditional as an alias for CAS 8841// and to use StoreIConditional only for 32-bit and StoreLConditional 8842// only for 64-bit. 8843// 8844// We implement LoadPLocked and StorePLocked instructions using, 8845// respectively the AArch64 hw load-exclusive and store-conditional 8846// instructions. Whereas we must implement each of 8847// Store{IL}Conditional using a CAS which employs a pair of 8848// instructions comprising a load-exclusive followed by a 8849// store-conditional. 8850 8851 8852// Locked-load (linked load) of the current heap-top 8853// used when updating the eden heap top 8854// implemented using ldaxr on AArch64 8855 8856instruct loadPLocked(iRegPNoSp dst, indirect mem) 8857%{ 8858 match(Set dst (LoadPLocked mem)); 8859 8860 ins_cost(VOLATILE_REF_COST); 8861 8862 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 8863 8864 ins_encode(aarch64_enc_ldaxr(dst, mem)); 8865 8866 ins_pipe(pipe_serial); 8867%} 8868 8869// Conditional-store of the updated heap-top. 8870// Used during allocation of the shared heap. 8871// Sets flag (EQ) on success. 8872// implemented using stlxr on AArch64. 8873 8874instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 8875%{ 8876 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8877 8878 ins_cost(VOLATILE_REF_COST); 8879 8880 // TODO 8881 // do we need to do a store-conditional release or can we just use a 8882 // plain store-conditional? 8883 8884 format %{ 8885 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 8886 "cmpw rscratch1, zr\t# EQ on successful write" 8887 %} 8888 8889 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 8890 8891 ins_pipe(pipe_serial); 8892%} 8893 8894 8895// storeLConditional is used by PhaseMacroExpand::expand_lock_node 8896// when attempting to rebias a lock towards the current thread. We 8897// must use the acquire form of cmpxchg in order to guarantee acquire 8898// semantics in this case. 8899instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 8900%{ 8901 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8902 8903 ins_cost(VOLATILE_REF_COST); 8904 8905 format %{ 8906 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8907 "cmpw rscratch1, zr\t# EQ on successful write" 8908 %} 8909 8910 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); 8911 8912 ins_pipe(pipe_slow); 8913%} 8914 8915// storeIConditional also has acquire semantics, for no better reason 8916// than matching storeLConditional. At the time of writing this 8917// comment storeIConditional was not used anywhere by AArch64. 8918instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 8919%{ 8920 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8921 8922 ins_cost(VOLATILE_REF_COST); 8923 8924 format %{ 8925 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 8926 "cmpw rscratch1, zr\t# EQ on successful write" 8927 %} 8928 8929 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); 8930 8931 ins_pipe(pipe_slow); 8932%} 8933 8934// standard CompareAndSwapX when we are using barriers 8935// these have higher priority than the rules selected by a predicate 8936 8937// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8938// can't match them 8939 8940instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8941 8942 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8943 ins_cost(2 * VOLATILE_REF_COST); 8944 8945 effect(KILL cr); 8946 8947 format %{ 8948 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8949 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8950 %} 8951 8952 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8953 aarch64_enc_cset_eq(res)); 8954 8955 ins_pipe(pipe_slow); 8956%} 8957 8958instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8959 8960 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8961 ins_cost(2 * VOLATILE_REF_COST); 8962 8963 effect(KILL cr); 8964 8965 format %{ 8966 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8967 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8968 %} 8969 8970 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8971 aarch64_enc_cset_eq(res)); 8972 8973 ins_pipe(pipe_slow); 8974%} 8975 8976instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8977 8978 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8979 ins_cost(2 * VOLATILE_REF_COST); 8980 8981 effect(KILL cr); 8982 8983 format %{ 8984 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8985 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8986 %} 8987 8988 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8989 aarch64_enc_cset_eq(res)); 8990 8991 ins_pipe(pipe_slow); 8992%} 8993 8994instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8995 8996 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8997 ins_cost(2 * VOLATILE_REF_COST); 8998 8999 effect(KILL cr); 9000 9001 format %{ 9002 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 9003 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9004 %} 9005 9006 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 9007 aarch64_enc_cset_eq(res)); 9008 9009 ins_pipe(pipe_slow); 9010%} 9011 9012instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9013 9014 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 9015 predicate(n->as_LoadStore()->barrier_data() == 0); 9016 ins_cost(2 * VOLATILE_REF_COST); 9017 9018 effect(KILL cr); 9019 9020 format %{ 9021 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 9022 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9023 %} 9024 9025 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 9026 aarch64_enc_cset_eq(res)); 9027 9028 ins_pipe(pipe_slow); 9029%} 9030 9031instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 9032 9033 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 9034 ins_cost(2 * VOLATILE_REF_COST); 9035 9036 effect(KILL cr); 9037 9038 format %{ 9039 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 9040 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9041 %} 9042 9043 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 9044 aarch64_enc_cset_eq(res)); 9045 9046 ins_pipe(pipe_slow); 9047%} 9048 9049// alternative CompareAndSwapX when we are eliding barriers 9050 9051instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 9052 9053 predicate(needs_acquiring_load_exclusive(n)); 9054 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 9055 ins_cost(VOLATILE_REF_COST); 9056 9057 effect(KILL cr); 9058 9059 format %{ 9060 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 9061 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9062 %} 9063 9064 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 9065 aarch64_enc_cset_eq(res)); 9066 9067 ins_pipe(pipe_slow); 9068%} 9069 9070instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 9071 9072 predicate(needs_acquiring_load_exclusive(n)); 9073 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 9074 ins_cost(VOLATILE_REF_COST); 9075 9076 effect(KILL cr); 9077 9078 format %{ 9079 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 9080 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9081 %} 9082 9083 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 9084 aarch64_enc_cset_eq(res)); 9085 9086 ins_pipe(pipe_slow); 9087%} 9088 9089instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 9090 9091 predicate(needs_acquiring_load_exclusive(n)); 9092 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 9093 ins_cost(VOLATILE_REF_COST); 9094 9095 effect(KILL cr); 9096 9097 format %{ 9098 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 9099 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9100 %} 9101 9102 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 9103 aarch64_enc_cset_eq(res)); 9104 9105 ins_pipe(pipe_slow); 9106%} 9107 9108instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 9109 9110 predicate(needs_acquiring_load_exclusive(n)); 9111 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 9112 ins_cost(VOLATILE_REF_COST); 9113 9114 effect(KILL cr); 9115 9116 format %{ 9117 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 9118 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9119 %} 9120 9121 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 9122 aarch64_enc_cset_eq(res)); 9123 9124 ins_pipe(pipe_slow); 9125%} 9126 9127instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9128 9129 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9130 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 9131 ins_cost(VOLATILE_REF_COST); 9132 9133 effect(KILL cr); 9134 9135 format %{ 9136 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 9137 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9138 %} 9139 9140 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 9141 aarch64_enc_cset_eq(res)); 9142 9143 ins_pipe(pipe_slow); 9144%} 9145 9146instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 9147 9148 predicate(needs_acquiring_load_exclusive(n)); 9149 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 9150 ins_cost(VOLATILE_REF_COST); 9151 9152 effect(KILL cr); 9153 9154 format %{ 9155 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 9156 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9157 %} 9158 9159 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 9160 aarch64_enc_cset_eq(res)); 9161 9162 ins_pipe(pipe_slow); 9163%} 9164 9165 9166// --------------------------------------------------------------------- 9167 9168// BEGIN This section of the file is automatically generated. Do not edit -------------- 9169 9170// Sundry CAS operations. Note that release is always true, 9171// regardless of the memory ordering of the CAS. This is because we 9172// need the volatile case to be sequentially consistent but there is 9173// no trailing StoreLoad barrier emitted by C2. Unfortunately we 9174// can't check the type of memory ordering here, so we always emit a 9175// STLXR. 9176 9177// This section is generated from aarch64_ad_cas.m4 9178 9179 9180 9181// This pattern is generated automatically from cas.m4. 9182// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9183instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9184 9185 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 9186 ins_cost(2 * VOLATILE_REF_COST); 9187 effect(TEMP_DEF res, KILL cr); 9188 format %{ 9189 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9190 %} 9191 ins_encode %{ 9192 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9193 Assembler::byte, /*acquire*/ false, /*release*/ true, 9194 /*weak*/ false, $res$$Register); 9195 __ sxtbw($res$$Register, $res$$Register); 9196 %} 9197 ins_pipe(pipe_slow); 9198%} 9199 9200// This pattern is generated automatically from cas.m4. 9201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9202instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9203 9204 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9205 ins_cost(2 * VOLATILE_REF_COST); 9206 effect(TEMP_DEF res, KILL cr); 9207 format %{ 9208 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9209 %} 9210 ins_encode %{ 9211 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9212 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9213 /*weak*/ false, $res$$Register); 9214 __ sxthw($res$$Register, $res$$Register); 9215 %} 9216 ins_pipe(pipe_slow); 9217%} 9218 9219// This pattern is generated automatically from cas.m4. 9220// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9221instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9222 9223 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9224 ins_cost(2 * VOLATILE_REF_COST); 9225 effect(TEMP_DEF res, KILL cr); 9226 format %{ 9227 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9228 %} 9229 ins_encode %{ 9230 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9231 Assembler::word, /*acquire*/ false, /*release*/ true, 9232 /*weak*/ false, $res$$Register); 9233 %} 9234 ins_pipe(pipe_slow); 9235%} 9236 9237// This pattern is generated automatically from cas.m4. 9238// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9239instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9240 9241 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9242 ins_cost(2 * VOLATILE_REF_COST); 9243 effect(TEMP_DEF res, KILL cr); 9244 format %{ 9245 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9246 %} 9247 ins_encode %{ 9248 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9249 Assembler::xword, /*acquire*/ false, /*release*/ true, 9250 /*weak*/ false, $res$$Register); 9251 %} 9252 ins_pipe(pipe_slow); 9253%} 9254 9255// This pattern is generated automatically from cas.m4. 9256// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9257instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9258 9259 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9260 ins_cost(2 * VOLATILE_REF_COST); 9261 effect(TEMP_DEF res, KILL cr); 9262 format %{ 9263 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9264 %} 9265 ins_encode %{ 9266 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9267 Assembler::word, /*acquire*/ false, /*release*/ true, 9268 /*weak*/ false, $res$$Register); 9269 %} 9270 ins_pipe(pipe_slow); 9271%} 9272 9273// This pattern is generated automatically from cas.m4. 9274// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9275instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9276 predicate(n->as_LoadStore()->barrier_data() == 0); 9277 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9278 ins_cost(2 * VOLATILE_REF_COST); 9279 effect(TEMP_DEF res, KILL cr); 9280 format %{ 9281 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9282 %} 9283 ins_encode %{ 9284 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9285 Assembler::xword, /*acquire*/ false, /*release*/ true, 9286 /*weak*/ false, $res$$Register); 9287 %} 9288 ins_pipe(pipe_slow); 9289%} 9290 9291// This pattern is generated automatically from cas.m4. 9292// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9293instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9294 predicate(needs_acquiring_load_exclusive(n)); 9295 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 9296 ins_cost(VOLATILE_REF_COST); 9297 effect(TEMP_DEF res, KILL cr); 9298 format %{ 9299 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9300 %} 9301 ins_encode %{ 9302 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9303 Assembler::byte, /*acquire*/ true, /*release*/ true, 9304 /*weak*/ false, $res$$Register); 9305 __ sxtbw($res$$Register, $res$$Register); 9306 %} 9307 ins_pipe(pipe_slow); 9308%} 9309 9310// This pattern is generated automatically from cas.m4. 9311// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9312instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9313 predicate(needs_acquiring_load_exclusive(n)); 9314 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9315 ins_cost(VOLATILE_REF_COST); 9316 effect(TEMP_DEF res, KILL cr); 9317 format %{ 9318 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9319 %} 9320 ins_encode %{ 9321 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9322 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9323 /*weak*/ false, $res$$Register); 9324 __ sxthw($res$$Register, $res$$Register); 9325 %} 9326 ins_pipe(pipe_slow); 9327%} 9328 9329// This pattern is generated automatically from cas.m4. 9330// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9331instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9332 predicate(needs_acquiring_load_exclusive(n)); 9333 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9334 ins_cost(VOLATILE_REF_COST); 9335 effect(TEMP_DEF res, KILL cr); 9336 format %{ 9337 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9338 %} 9339 ins_encode %{ 9340 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9341 Assembler::word, /*acquire*/ true, /*release*/ true, 9342 /*weak*/ false, $res$$Register); 9343 %} 9344 ins_pipe(pipe_slow); 9345%} 9346 9347// This pattern is generated automatically from cas.m4. 9348// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9349instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9350 predicate(needs_acquiring_load_exclusive(n)); 9351 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9352 ins_cost(VOLATILE_REF_COST); 9353 effect(TEMP_DEF res, KILL cr); 9354 format %{ 9355 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9356 %} 9357 ins_encode %{ 9358 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9359 Assembler::xword, /*acquire*/ true, /*release*/ true, 9360 /*weak*/ false, $res$$Register); 9361 %} 9362 ins_pipe(pipe_slow); 9363%} 9364 9365// This pattern is generated automatically from cas.m4. 9366// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9367instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9368 predicate(needs_acquiring_load_exclusive(n)); 9369 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9370 ins_cost(VOLATILE_REF_COST); 9371 effect(TEMP_DEF res, KILL cr); 9372 format %{ 9373 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9374 %} 9375 ins_encode %{ 9376 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9377 Assembler::word, /*acquire*/ true, /*release*/ true, 9378 /*weak*/ false, $res$$Register); 9379 %} 9380 ins_pipe(pipe_slow); 9381%} 9382 9383// This pattern is generated automatically from cas.m4. 9384// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9385instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9386 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9387 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9388 ins_cost(VOLATILE_REF_COST); 9389 effect(TEMP_DEF res, KILL cr); 9390 format %{ 9391 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9392 %} 9393 ins_encode %{ 9394 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9395 Assembler::xword, /*acquire*/ true, /*release*/ true, 9396 /*weak*/ false, $res$$Register); 9397 %} 9398 ins_pipe(pipe_slow); 9399%} 9400 9401// This pattern is generated automatically from cas.m4. 9402// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9403instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9404 9405 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9406 ins_cost(2 * VOLATILE_REF_COST); 9407 effect(KILL cr); 9408 format %{ 9409 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9410 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9411 %} 9412 ins_encode %{ 9413 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9414 Assembler::byte, /*acquire*/ false, /*release*/ true, 9415 /*weak*/ true, noreg); 9416 __ csetw($res$$Register, Assembler::EQ); 9417 %} 9418 ins_pipe(pipe_slow); 9419%} 9420 9421// This pattern is generated automatically from cas.m4. 9422// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9423instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9424 9425 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9426 ins_cost(2 * VOLATILE_REF_COST); 9427 effect(KILL cr); 9428 format %{ 9429 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9430 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9431 %} 9432 ins_encode %{ 9433 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9434 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9435 /*weak*/ true, noreg); 9436 __ csetw($res$$Register, Assembler::EQ); 9437 %} 9438 ins_pipe(pipe_slow); 9439%} 9440 9441// This pattern is generated automatically from cas.m4. 9442// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9443instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9444 9445 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9446 ins_cost(2 * VOLATILE_REF_COST); 9447 effect(KILL cr); 9448 format %{ 9449 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9450 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9451 %} 9452 ins_encode %{ 9453 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9454 Assembler::word, /*acquire*/ false, /*release*/ true, 9455 /*weak*/ true, noreg); 9456 __ csetw($res$$Register, Assembler::EQ); 9457 %} 9458 ins_pipe(pipe_slow); 9459%} 9460 9461// This pattern is generated automatically from cas.m4. 9462// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9463instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9464 9465 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9466 ins_cost(2 * VOLATILE_REF_COST); 9467 effect(KILL cr); 9468 format %{ 9469 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9470 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9471 %} 9472 ins_encode %{ 9473 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9474 Assembler::xword, /*acquire*/ false, /*release*/ true, 9475 /*weak*/ true, noreg); 9476 __ csetw($res$$Register, Assembler::EQ); 9477 %} 9478 ins_pipe(pipe_slow); 9479%} 9480 9481// This pattern is generated automatically from cas.m4. 9482// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9483instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9484 9485 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9486 ins_cost(2 * VOLATILE_REF_COST); 9487 effect(KILL cr); 9488 format %{ 9489 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9490 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9491 %} 9492 ins_encode %{ 9493 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9494 Assembler::word, /*acquire*/ false, /*release*/ true, 9495 /*weak*/ true, noreg); 9496 __ csetw($res$$Register, Assembler::EQ); 9497 %} 9498 ins_pipe(pipe_slow); 9499%} 9500 9501// This pattern is generated automatically from cas.m4. 9502// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9503instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9504 predicate(n->as_LoadStore()->barrier_data() == 0); 9505 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9506 ins_cost(2 * VOLATILE_REF_COST); 9507 effect(KILL cr); 9508 format %{ 9509 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9510 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9511 %} 9512 ins_encode %{ 9513 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9514 Assembler::xword, /*acquire*/ false, /*release*/ true, 9515 /*weak*/ true, noreg); 9516 __ csetw($res$$Register, Assembler::EQ); 9517 %} 9518 ins_pipe(pipe_slow); 9519%} 9520 9521// This pattern is generated automatically from cas.m4. 9522// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9523instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9524 predicate(needs_acquiring_load_exclusive(n)); 9525 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9526 ins_cost(VOLATILE_REF_COST); 9527 effect(KILL cr); 9528 format %{ 9529 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9530 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9531 %} 9532 ins_encode %{ 9533 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9534 Assembler::byte, /*acquire*/ true, /*release*/ true, 9535 /*weak*/ true, noreg); 9536 __ csetw($res$$Register, Assembler::EQ); 9537 %} 9538 ins_pipe(pipe_slow); 9539%} 9540 9541// This pattern is generated automatically from cas.m4. 9542// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9543instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9544 predicate(needs_acquiring_load_exclusive(n)); 9545 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9546 ins_cost(VOLATILE_REF_COST); 9547 effect(KILL cr); 9548 format %{ 9549 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9550 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9551 %} 9552 ins_encode %{ 9553 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9554 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9555 /*weak*/ true, noreg); 9556 __ csetw($res$$Register, Assembler::EQ); 9557 %} 9558 ins_pipe(pipe_slow); 9559%} 9560 9561// This pattern is generated automatically from cas.m4. 9562// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9563instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9564 predicate(needs_acquiring_load_exclusive(n)); 9565 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9566 ins_cost(VOLATILE_REF_COST); 9567 effect(KILL cr); 9568 format %{ 9569 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9570 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9571 %} 9572 ins_encode %{ 9573 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9574 Assembler::word, /*acquire*/ true, /*release*/ true, 9575 /*weak*/ true, noreg); 9576 __ csetw($res$$Register, Assembler::EQ); 9577 %} 9578 ins_pipe(pipe_slow); 9579%} 9580 9581// This pattern is generated automatically from cas.m4. 9582// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9583instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9584 predicate(needs_acquiring_load_exclusive(n)); 9585 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9586 ins_cost(VOLATILE_REF_COST); 9587 effect(KILL cr); 9588 format %{ 9589 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9590 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9591 %} 9592 ins_encode %{ 9593 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9594 Assembler::xword, /*acquire*/ true, /*release*/ true, 9595 /*weak*/ true, noreg); 9596 __ csetw($res$$Register, Assembler::EQ); 9597 %} 9598 ins_pipe(pipe_slow); 9599%} 9600 9601// This pattern is generated automatically from cas.m4. 9602// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9603instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9604 predicate(needs_acquiring_load_exclusive(n)); 9605 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9606 ins_cost(VOLATILE_REF_COST); 9607 effect(KILL cr); 9608 format %{ 9609 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9610 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9611 %} 9612 ins_encode %{ 9613 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9614 Assembler::word, /*acquire*/ true, /*release*/ true, 9615 /*weak*/ true, noreg); 9616 __ csetw($res$$Register, Assembler::EQ); 9617 %} 9618 ins_pipe(pipe_slow); 9619%} 9620 9621// This pattern is generated automatically from cas.m4. 9622// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9623instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9624 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9625 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9626 ins_cost(VOLATILE_REF_COST); 9627 effect(KILL cr); 9628 format %{ 9629 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9630 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9631 %} 9632 ins_encode %{ 9633 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9634 Assembler::xword, /*acquire*/ true, /*release*/ true, 9635 /*weak*/ true, noreg); 9636 __ csetw($res$$Register, Assembler::EQ); 9637 %} 9638 ins_pipe(pipe_slow); 9639%} 9640 9641// END This section of the file is automatically generated. Do not edit -------------- 9642// --------------------------------------------------------------------- 9643 9644instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9645 match(Set prev (GetAndSetI mem newv)); 9646 ins_cost(2 * VOLATILE_REF_COST); 9647 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9648 ins_encode %{ 9649 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9650 %} 9651 ins_pipe(pipe_serial); 9652%} 9653 9654instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9655 match(Set prev (GetAndSetL mem newv)); 9656 ins_cost(2 * VOLATILE_REF_COST); 9657 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9658 ins_encode %{ 9659 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9660 %} 9661 ins_pipe(pipe_serial); 9662%} 9663 9664instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9665 match(Set prev (GetAndSetN mem newv)); 9666 ins_cost(2 * VOLATILE_REF_COST); 9667 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9668 ins_encode %{ 9669 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9670 %} 9671 ins_pipe(pipe_serial); 9672%} 9673 9674instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9675 predicate(n->as_LoadStore()->barrier_data() == 0); 9676 match(Set prev (GetAndSetP mem newv)); 9677 ins_cost(2 * VOLATILE_REF_COST); 9678 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9679 ins_encode %{ 9680 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9681 %} 9682 ins_pipe(pipe_serial); 9683%} 9684 9685instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9686 predicate(needs_acquiring_load_exclusive(n)); 9687 match(Set prev (GetAndSetI mem newv)); 9688 ins_cost(VOLATILE_REF_COST); 9689 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9690 ins_encode %{ 9691 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9692 %} 9693 ins_pipe(pipe_serial); 9694%} 9695 9696instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9697 predicate(needs_acquiring_load_exclusive(n)); 9698 match(Set prev (GetAndSetL mem newv)); 9699 ins_cost(VOLATILE_REF_COST); 9700 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9701 ins_encode %{ 9702 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9703 %} 9704 ins_pipe(pipe_serial); 9705%} 9706 9707instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9708 predicate(needs_acquiring_load_exclusive(n)); 9709 match(Set prev (GetAndSetN mem newv)); 9710 ins_cost(VOLATILE_REF_COST); 9711 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9712 ins_encode %{ 9713 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9714 %} 9715 ins_pipe(pipe_serial); 9716%} 9717 9718instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9719 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9720 match(Set prev (GetAndSetP mem newv)); 9721 ins_cost(VOLATILE_REF_COST); 9722 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9723 ins_encode %{ 9724 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9725 %} 9726 ins_pipe(pipe_serial); 9727%} 9728 9729 9730instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9731 match(Set newval (GetAndAddL mem incr)); 9732 ins_cost(2 * VOLATILE_REF_COST + 1); 9733 format %{ "get_and_addL $newval, [$mem], $incr" %} 9734 ins_encode %{ 9735 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9736 %} 9737 ins_pipe(pipe_serial); 9738%} 9739 9740instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9741 predicate(n->as_LoadStore()->result_not_used()); 9742 match(Set dummy (GetAndAddL mem incr)); 9743 ins_cost(2 * VOLATILE_REF_COST); 9744 format %{ "get_and_addL [$mem], $incr" %} 9745 ins_encode %{ 9746 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9747 %} 9748 ins_pipe(pipe_serial); 9749%} 9750 9751instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9752 match(Set newval (GetAndAddL mem incr)); 9753 ins_cost(2 * VOLATILE_REF_COST + 1); 9754 format %{ "get_and_addL $newval, [$mem], $incr" %} 9755 ins_encode %{ 9756 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9757 %} 9758 ins_pipe(pipe_serial); 9759%} 9760 9761instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9762 predicate(n->as_LoadStore()->result_not_used()); 9763 match(Set dummy (GetAndAddL mem incr)); 9764 ins_cost(2 * VOLATILE_REF_COST); 9765 format %{ "get_and_addL [$mem], $incr" %} 9766 ins_encode %{ 9767 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9768 %} 9769 ins_pipe(pipe_serial); 9770%} 9771 9772instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9773 match(Set newval (GetAndAddI mem incr)); 9774 ins_cost(2 * VOLATILE_REF_COST + 1); 9775 format %{ "get_and_addI $newval, [$mem], $incr" %} 9776 ins_encode %{ 9777 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9778 %} 9779 ins_pipe(pipe_serial); 9780%} 9781 9782instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9783 predicate(n->as_LoadStore()->result_not_used()); 9784 match(Set dummy (GetAndAddI mem incr)); 9785 ins_cost(2 * VOLATILE_REF_COST); 9786 format %{ "get_and_addI [$mem], $incr" %} 9787 ins_encode %{ 9788 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9789 %} 9790 ins_pipe(pipe_serial); 9791%} 9792 9793instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9794 match(Set newval (GetAndAddI mem incr)); 9795 ins_cost(2 * VOLATILE_REF_COST + 1); 9796 format %{ "get_and_addI $newval, [$mem], $incr" %} 9797 ins_encode %{ 9798 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9799 %} 9800 ins_pipe(pipe_serial); 9801%} 9802 9803instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9804 predicate(n->as_LoadStore()->result_not_used()); 9805 match(Set dummy (GetAndAddI mem incr)); 9806 ins_cost(2 * VOLATILE_REF_COST); 9807 format %{ "get_and_addI [$mem], $incr" %} 9808 ins_encode %{ 9809 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9810 %} 9811 ins_pipe(pipe_serial); 9812%} 9813 9814instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9815 predicate(needs_acquiring_load_exclusive(n)); 9816 match(Set newval (GetAndAddL mem incr)); 9817 ins_cost(VOLATILE_REF_COST + 1); 9818 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9819 ins_encode %{ 9820 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9821 %} 9822 ins_pipe(pipe_serial); 9823%} 9824 9825instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9826 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9827 match(Set dummy (GetAndAddL mem incr)); 9828 ins_cost(VOLATILE_REF_COST); 9829 format %{ "get_and_addL_acq [$mem], $incr" %} 9830 ins_encode %{ 9831 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9832 %} 9833 ins_pipe(pipe_serial); 9834%} 9835 9836instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9837 predicate(needs_acquiring_load_exclusive(n)); 9838 match(Set newval (GetAndAddL mem incr)); 9839 ins_cost(VOLATILE_REF_COST + 1); 9840 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9841 ins_encode %{ 9842 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9843 %} 9844 ins_pipe(pipe_serial); 9845%} 9846 9847instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9848 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9849 match(Set dummy (GetAndAddL mem incr)); 9850 ins_cost(VOLATILE_REF_COST); 9851 format %{ "get_and_addL_acq [$mem], $incr" %} 9852 ins_encode %{ 9853 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9854 %} 9855 ins_pipe(pipe_serial); 9856%} 9857 9858instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9859 predicate(needs_acquiring_load_exclusive(n)); 9860 match(Set newval (GetAndAddI mem incr)); 9861 ins_cost(VOLATILE_REF_COST + 1); 9862 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9863 ins_encode %{ 9864 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9865 %} 9866 ins_pipe(pipe_serial); 9867%} 9868 9869instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9870 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9871 match(Set dummy (GetAndAddI mem incr)); 9872 ins_cost(VOLATILE_REF_COST); 9873 format %{ "get_and_addI_acq [$mem], $incr" %} 9874 ins_encode %{ 9875 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9876 %} 9877 ins_pipe(pipe_serial); 9878%} 9879 9880instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9881 predicate(needs_acquiring_load_exclusive(n)); 9882 match(Set newval (GetAndAddI mem incr)); 9883 ins_cost(VOLATILE_REF_COST + 1); 9884 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9885 ins_encode %{ 9886 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9887 %} 9888 ins_pipe(pipe_serial); 9889%} 9890 9891instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9892 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9893 match(Set dummy (GetAndAddI mem incr)); 9894 ins_cost(VOLATILE_REF_COST); 9895 format %{ "get_and_addI_acq [$mem], $incr" %} 9896 ins_encode %{ 9897 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9898 %} 9899 ins_pipe(pipe_serial); 9900%} 9901 9902// Manifest a CmpL result in an integer register. 9903// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9904instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9905%{ 9906 match(Set dst (CmpL3 src1 src2)); 9907 effect(KILL flags); 9908 9909 ins_cost(INSN_COST * 6); 9910 format %{ 9911 "cmp $src1, $src2" 9912 "csetw $dst, ne" 9913 "cnegw $dst, lt" 9914 %} 9915 // format %{ "CmpL3 $dst, $src1, $src2" %} 9916 ins_encode %{ 9917 __ cmp($src1$$Register, $src2$$Register); 9918 __ csetw($dst$$Register, Assembler::NE); 9919 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9920 %} 9921 9922 ins_pipe(pipe_class_default); 9923%} 9924 9925instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9926%{ 9927 match(Set dst (CmpL3 src1 src2)); 9928 effect(KILL flags); 9929 9930 ins_cost(INSN_COST * 6); 9931 format %{ 9932 "cmp $src1, $src2" 9933 "csetw $dst, ne" 9934 "cnegw $dst, lt" 9935 %} 9936 ins_encode %{ 9937 int32_t con = (int32_t)$src2$$constant; 9938 if (con < 0) { 9939 __ adds(zr, $src1$$Register, -con); 9940 } else { 9941 __ subs(zr, $src1$$Register, con); 9942 } 9943 __ csetw($dst$$Register, Assembler::NE); 9944 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9945 %} 9946 9947 ins_pipe(pipe_class_default); 9948%} 9949 9950// ============================================================================ 9951// Conditional Move Instructions 9952 9953// n.b. we have identical rules for both a signed compare op (cmpOp) 9954// and an unsigned compare op (cmpOpU). it would be nice if we could 9955// define an op class which merged both inputs and use it to type the 9956// argument to a single rule. unfortunatelyt his fails because the 9957// opclass does not live up to the COND_INTER interface of its 9958// component operands. When the generic code tries to negate the 9959// operand it ends up running the generci Machoper::negate method 9960// which throws a ShouldNotHappen. So, we have to provide two flavours 9961// of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9962 9963instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9964 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9965 9966 ins_cost(INSN_COST * 2); 9967 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9968 9969 ins_encode %{ 9970 __ cselw(as_Register($dst$$reg), 9971 as_Register($src2$$reg), 9972 as_Register($src1$$reg), 9973 (Assembler::Condition)$cmp$$cmpcode); 9974 %} 9975 9976 ins_pipe(icond_reg_reg); 9977%} 9978 9979instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9980 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9981 9982 ins_cost(INSN_COST * 2); 9983 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9984 9985 ins_encode %{ 9986 __ cselw(as_Register($dst$$reg), 9987 as_Register($src2$$reg), 9988 as_Register($src1$$reg), 9989 (Assembler::Condition)$cmp$$cmpcode); 9990 %} 9991 9992 ins_pipe(icond_reg_reg); 9993%} 9994 9995// special cases where one arg is zero 9996 9997// n.b. this is selected in preference to the rule above because it 9998// avoids loading constant 0 into a source register 9999 10000// TODO 10001// we ought only to be able to cull one of these variants as the ideal 10002// transforms ought always to order the zero consistently (to left/right?) 10003 10004instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 10005 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 10006 10007 ins_cost(INSN_COST * 2); 10008 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 10009 10010 ins_encode %{ 10011 __ cselw(as_Register($dst$$reg), 10012 as_Register($src$$reg), 10013 zr, 10014 (Assembler::Condition)$cmp$$cmpcode); 10015 %} 10016 10017 ins_pipe(icond_reg); 10018%} 10019 10020instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 10021 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 10022 10023 ins_cost(INSN_COST * 2); 10024 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 10025 10026 ins_encode %{ 10027 __ cselw(as_Register($dst$$reg), 10028 as_Register($src$$reg), 10029 zr, 10030 (Assembler::Condition)$cmp$$cmpcode); 10031 %} 10032 10033 ins_pipe(icond_reg); 10034%} 10035 10036instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 10037 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 10038 10039 ins_cost(INSN_COST * 2); 10040 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 10041 10042 ins_encode %{ 10043 __ cselw(as_Register($dst$$reg), 10044 zr, 10045 as_Register($src$$reg), 10046 (Assembler::Condition)$cmp$$cmpcode); 10047 %} 10048 10049 ins_pipe(icond_reg); 10050%} 10051 10052instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 10053 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 10054 10055 ins_cost(INSN_COST * 2); 10056 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 10057 10058 ins_encode %{ 10059 __ cselw(as_Register($dst$$reg), 10060 zr, 10061 as_Register($src$$reg), 10062 (Assembler::Condition)$cmp$$cmpcode); 10063 %} 10064 10065 ins_pipe(icond_reg); 10066%} 10067 10068// special case for creating a boolean 0 or 1 10069 10070// n.b. this is selected in preference to the rule above because it 10071// avoids loading constants 0 and 1 into a source register 10072 10073instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 10074 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 10075 10076 ins_cost(INSN_COST * 2); 10077 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 10078 10079 ins_encode %{ 10080 // equivalently 10081 // cset(as_Register($dst$$reg), 10082 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 10083 __ csincw(as_Register($dst$$reg), 10084 zr, 10085 zr, 10086 (Assembler::Condition)$cmp$$cmpcode); 10087 %} 10088 10089 ins_pipe(icond_none); 10090%} 10091 10092instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 10093 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 10094 10095 ins_cost(INSN_COST * 2); 10096 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 10097 10098 ins_encode %{ 10099 // equivalently 10100 // cset(as_Register($dst$$reg), 10101 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 10102 __ csincw(as_Register($dst$$reg), 10103 zr, 10104 zr, 10105 (Assembler::Condition)$cmp$$cmpcode); 10106 %} 10107 10108 ins_pipe(icond_none); 10109%} 10110 10111instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10112 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 10113 10114 ins_cost(INSN_COST * 2); 10115 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 10116 10117 ins_encode %{ 10118 __ csel(as_Register($dst$$reg), 10119 as_Register($src2$$reg), 10120 as_Register($src1$$reg), 10121 (Assembler::Condition)$cmp$$cmpcode); 10122 %} 10123 10124 ins_pipe(icond_reg_reg); 10125%} 10126 10127instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10128 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 10129 10130 ins_cost(INSN_COST * 2); 10131 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 10132 10133 ins_encode %{ 10134 __ csel(as_Register($dst$$reg), 10135 as_Register($src2$$reg), 10136 as_Register($src1$$reg), 10137 (Assembler::Condition)$cmp$$cmpcode); 10138 %} 10139 10140 ins_pipe(icond_reg_reg); 10141%} 10142 10143// special cases where one arg is zero 10144 10145instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 10146 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 10147 10148 ins_cost(INSN_COST * 2); 10149 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 10150 10151 ins_encode %{ 10152 __ csel(as_Register($dst$$reg), 10153 zr, 10154 as_Register($src$$reg), 10155 (Assembler::Condition)$cmp$$cmpcode); 10156 %} 10157 10158 ins_pipe(icond_reg); 10159%} 10160 10161instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 10162 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 10163 10164 ins_cost(INSN_COST * 2); 10165 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 10166 10167 ins_encode %{ 10168 __ csel(as_Register($dst$$reg), 10169 zr, 10170 as_Register($src$$reg), 10171 (Assembler::Condition)$cmp$$cmpcode); 10172 %} 10173 10174 ins_pipe(icond_reg); 10175%} 10176 10177instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 10178 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 10179 10180 ins_cost(INSN_COST * 2); 10181 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 10182 10183 ins_encode %{ 10184 __ csel(as_Register($dst$$reg), 10185 as_Register($src$$reg), 10186 zr, 10187 (Assembler::Condition)$cmp$$cmpcode); 10188 %} 10189 10190 ins_pipe(icond_reg); 10191%} 10192 10193instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 10194 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 10195 10196 ins_cost(INSN_COST * 2); 10197 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 10198 10199 ins_encode %{ 10200 __ csel(as_Register($dst$$reg), 10201 as_Register($src$$reg), 10202 zr, 10203 (Assembler::Condition)$cmp$$cmpcode); 10204 %} 10205 10206 ins_pipe(icond_reg); 10207%} 10208 10209instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10210 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10211 10212 ins_cost(INSN_COST * 2); 10213 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 10214 10215 ins_encode %{ 10216 __ csel(as_Register($dst$$reg), 10217 as_Register($src2$$reg), 10218 as_Register($src1$$reg), 10219 (Assembler::Condition)$cmp$$cmpcode); 10220 %} 10221 10222 ins_pipe(icond_reg_reg); 10223%} 10224 10225instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10226 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10227 10228 ins_cost(INSN_COST * 2); 10229 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 10230 10231 ins_encode %{ 10232 __ csel(as_Register($dst$$reg), 10233 as_Register($src2$$reg), 10234 as_Register($src1$$reg), 10235 (Assembler::Condition)$cmp$$cmpcode); 10236 %} 10237 10238 ins_pipe(icond_reg_reg); 10239%} 10240 10241// special cases where one arg is zero 10242 10243instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10244 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10245 10246 ins_cost(INSN_COST * 2); 10247 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 10248 10249 ins_encode %{ 10250 __ csel(as_Register($dst$$reg), 10251 zr, 10252 as_Register($src$$reg), 10253 (Assembler::Condition)$cmp$$cmpcode); 10254 %} 10255 10256 ins_pipe(icond_reg); 10257%} 10258 10259instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10260 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10261 10262 ins_cost(INSN_COST * 2); 10263 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 10264 10265 ins_encode %{ 10266 __ csel(as_Register($dst$$reg), 10267 zr, 10268 as_Register($src$$reg), 10269 (Assembler::Condition)$cmp$$cmpcode); 10270 %} 10271 10272 ins_pipe(icond_reg); 10273%} 10274 10275instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10276 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10277 10278 ins_cost(INSN_COST * 2); 10279 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 10280 10281 ins_encode %{ 10282 __ csel(as_Register($dst$$reg), 10283 as_Register($src$$reg), 10284 zr, 10285 (Assembler::Condition)$cmp$$cmpcode); 10286 %} 10287 10288 ins_pipe(icond_reg); 10289%} 10290 10291instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10292 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10293 10294 ins_cost(INSN_COST * 2); 10295 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 10296 10297 ins_encode %{ 10298 __ csel(as_Register($dst$$reg), 10299 as_Register($src$$reg), 10300 zr, 10301 (Assembler::Condition)$cmp$$cmpcode); 10302 %} 10303 10304 ins_pipe(icond_reg); 10305%} 10306 10307instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10308 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10309 10310 ins_cost(INSN_COST * 2); 10311 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10312 10313 ins_encode %{ 10314 __ cselw(as_Register($dst$$reg), 10315 as_Register($src2$$reg), 10316 as_Register($src1$$reg), 10317 (Assembler::Condition)$cmp$$cmpcode); 10318 %} 10319 10320 ins_pipe(icond_reg_reg); 10321%} 10322 10323instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10324 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10325 10326 ins_cost(INSN_COST * 2); 10327 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10328 10329 ins_encode %{ 10330 __ cselw(as_Register($dst$$reg), 10331 as_Register($src2$$reg), 10332 as_Register($src1$$reg), 10333 (Assembler::Condition)$cmp$$cmpcode); 10334 %} 10335 10336 ins_pipe(icond_reg_reg); 10337%} 10338 10339// special cases where one arg is zero 10340 10341instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10342 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10343 10344 ins_cost(INSN_COST * 2); 10345 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 10346 10347 ins_encode %{ 10348 __ cselw(as_Register($dst$$reg), 10349 zr, 10350 as_Register($src$$reg), 10351 (Assembler::Condition)$cmp$$cmpcode); 10352 %} 10353 10354 ins_pipe(icond_reg); 10355%} 10356 10357instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10358 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10359 10360 ins_cost(INSN_COST * 2); 10361 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 10362 10363 ins_encode %{ 10364 __ cselw(as_Register($dst$$reg), 10365 zr, 10366 as_Register($src$$reg), 10367 (Assembler::Condition)$cmp$$cmpcode); 10368 %} 10369 10370 ins_pipe(icond_reg); 10371%} 10372 10373instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10374 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10375 10376 ins_cost(INSN_COST * 2); 10377 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 10378 10379 ins_encode %{ 10380 __ cselw(as_Register($dst$$reg), 10381 as_Register($src$$reg), 10382 zr, 10383 (Assembler::Condition)$cmp$$cmpcode); 10384 %} 10385 10386 ins_pipe(icond_reg); 10387%} 10388 10389instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10390 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10391 10392 ins_cost(INSN_COST * 2); 10393 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 10394 10395 ins_encode %{ 10396 __ cselw(as_Register($dst$$reg), 10397 as_Register($src$$reg), 10398 zr, 10399 (Assembler::Condition)$cmp$$cmpcode); 10400 %} 10401 10402 ins_pipe(icond_reg); 10403%} 10404 10405instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10406%{ 10407 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10408 10409 ins_cost(INSN_COST * 3); 10410 10411 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10412 ins_encode %{ 10413 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10414 __ fcsels(as_FloatRegister($dst$$reg), 10415 as_FloatRegister($src2$$reg), 10416 as_FloatRegister($src1$$reg), 10417 cond); 10418 %} 10419 10420 ins_pipe(fp_cond_reg_reg_s); 10421%} 10422 10423instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10424%{ 10425 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10426 10427 ins_cost(INSN_COST * 3); 10428 10429 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10430 ins_encode %{ 10431 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10432 __ fcsels(as_FloatRegister($dst$$reg), 10433 as_FloatRegister($src2$$reg), 10434 as_FloatRegister($src1$$reg), 10435 cond); 10436 %} 10437 10438 ins_pipe(fp_cond_reg_reg_s); 10439%} 10440 10441instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10442%{ 10443 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10444 10445 ins_cost(INSN_COST * 3); 10446 10447 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10448 ins_encode %{ 10449 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10450 __ fcseld(as_FloatRegister($dst$$reg), 10451 as_FloatRegister($src2$$reg), 10452 as_FloatRegister($src1$$reg), 10453 cond); 10454 %} 10455 10456 ins_pipe(fp_cond_reg_reg_d); 10457%} 10458 10459instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10460%{ 10461 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10462 10463 ins_cost(INSN_COST * 3); 10464 10465 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10466 ins_encode %{ 10467 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10468 __ fcseld(as_FloatRegister($dst$$reg), 10469 as_FloatRegister($src2$$reg), 10470 as_FloatRegister($src1$$reg), 10471 cond); 10472 %} 10473 10474 ins_pipe(fp_cond_reg_reg_d); 10475%} 10476 10477// ============================================================================ 10478// Arithmetic Instructions 10479// 10480 10481// Integer Addition 10482 10483// TODO 10484// these currently employ operations which do not set CR and hence are 10485// not flagged as killing CR but we would like to isolate the cases 10486// where we want to set flags from those where we don't. need to work 10487// out how to do that. 10488 10489instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10490 match(Set dst (AddI src1 src2)); 10491 10492 ins_cost(INSN_COST); 10493 format %{ "addw $dst, $src1, $src2" %} 10494 10495 ins_encode %{ 10496 __ addw(as_Register($dst$$reg), 10497 as_Register($src1$$reg), 10498 as_Register($src2$$reg)); 10499 %} 10500 10501 ins_pipe(ialu_reg_reg); 10502%} 10503 10504instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10505 match(Set dst (AddI src1 src2)); 10506 10507 ins_cost(INSN_COST); 10508 format %{ "addw $dst, $src1, $src2" %} 10509 10510 // use opcode to indicate that this is an add not a sub 10511 opcode(0x0); 10512 10513 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10514 10515 ins_pipe(ialu_reg_imm); 10516%} 10517 10518instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10519 match(Set dst (AddI (ConvL2I src1) src2)); 10520 10521 ins_cost(INSN_COST); 10522 format %{ "addw $dst, $src1, $src2" %} 10523 10524 // use opcode to indicate that this is an add not a sub 10525 opcode(0x0); 10526 10527 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10528 10529 ins_pipe(ialu_reg_imm); 10530%} 10531 10532// Pointer Addition 10533instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10534 match(Set dst (AddP src1 src2)); 10535 10536 ins_cost(INSN_COST); 10537 format %{ "add $dst, $src1, $src2\t# ptr" %} 10538 10539 ins_encode %{ 10540 __ add(as_Register($dst$$reg), 10541 as_Register($src1$$reg), 10542 as_Register($src2$$reg)); 10543 %} 10544 10545 ins_pipe(ialu_reg_reg); 10546%} 10547 10548instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10549 match(Set dst (AddP src1 (ConvI2L src2))); 10550 10551 ins_cost(1.9 * INSN_COST); 10552 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10553 10554 ins_encode %{ 10555 __ add(as_Register($dst$$reg), 10556 as_Register($src1$$reg), 10557 as_Register($src2$$reg), ext::sxtw); 10558 %} 10559 10560 ins_pipe(ialu_reg_reg); 10561%} 10562 10563instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10564 match(Set dst (AddP src1 (LShiftL src2 scale))); 10565 10566 ins_cost(1.9 * INSN_COST); 10567 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10568 10569 ins_encode %{ 10570 __ lea(as_Register($dst$$reg), 10571 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10572 Address::lsl($scale$$constant))); 10573 %} 10574 10575 ins_pipe(ialu_reg_reg_shift); 10576%} 10577 10578instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10579 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10580 10581 ins_cost(1.9 * INSN_COST); 10582 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10583 10584 ins_encode %{ 10585 __ lea(as_Register($dst$$reg), 10586 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10587 Address::sxtw($scale$$constant))); 10588 %} 10589 10590 ins_pipe(ialu_reg_reg_shift); 10591%} 10592 10593instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10594 match(Set dst (LShiftL (ConvI2L src) scale)); 10595 10596 ins_cost(INSN_COST); 10597 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10598 10599 ins_encode %{ 10600 __ sbfiz(as_Register($dst$$reg), 10601 as_Register($src$$reg), 10602 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10603 %} 10604 10605 ins_pipe(ialu_reg_shift); 10606%} 10607 10608// Pointer Immediate Addition 10609// n.b. this needs to be more expensive than using an indirect memory 10610// operand 10611instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10612 match(Set dst (AddP src1 src2)); 10613 10614 ins_cost(INSN_COST); 10615 format %{ "add $dst, $src1, $src2\t# ptr" %} 10616 10617 // use opcode to indicate that this is an add not a sub 10618 opcode(0x0); 10619 10620 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10621 10622 ins_pipe(ialu_reg_imm); 10623%} 10624 10625// Long Addition 10626instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10627 10628 match(Set dst (AddL src1 src2)); 10629 10630 ins_cost(INSN_COST); 10631 format %{ "add $dst, $src1, $src2" %} 10632 10633 ins_encode %{ 10634 __ add(as_Register($dst$$reg), 10635 as_Register($src1$$reg), 10636 as_Register($src2$$reg)); 10637 %} 10638 10639 ins_pipe(ialu_reg_reg); 10640%} 10641 10642// No constant pool entries requiredLong Immediate Addition. 10643instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10644 match(Set dst (AddL src1 src2)); 10645 10646 ins_cost(INSN_COST); 10647 format %{ "add $dst, $src1, $src2" %} 10648 10649 // use opcode to indicate that this is an add not a sub 10650 opcode(0x0); 10651 10652 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10653 10654 ins_pipe(ialu_reg_imm); 10655%} 10656 10657// Integer Subtraction 10658instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10659 match(Set dst (SubI src1 src2)); 10660 10661 ins_cost(INSN_COST); 10662 format %{ "subw $dst, $src1, $src2" %} 10663 10664 ins_encode %{ 10665 __ subw(as_Register($dst$$reg), 10666 as_Register($src1$$reg), 10667 as_Register($src2$$reg)); 10668 %} 10669 10670 ins_pipe(ialu_reg_reg); 10671%} 10672 10673// Immediate Subtraction 10674instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10675 match(Set dst (SubI src1 src2)); 10676 10677 ins_cost(INSN_COST); 10678 format %{ "subw $dst, $src1, $src2" %} 10679 10680 // use opcode to indicate that this is a sub not an add 10681 opcode(0x1); 10682 10683 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10684 10685 ins_pipe(ialu_reg_imm); 10686%} 10687 10688// Long Subtraction 10689instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10690 10691 match(Set dst (SubL src1 src2)); 10692 10693 ins_cost(INSN_COST); 10694 format %{ "sub $dst, $src1, $src2" %} 10695 10696 ins_encode %{ 10697 __ sub(as_Register($dst$$reg), 10698 as_Register($src1$$reg), 10699 as_Register($src2$$reg)); 10700 %} 10701 10702 ins_pipe(ialu_reg_reg); 10703%} 10704 10705// No constant pool entries requiredLong Immediate Subtraction. 10706instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10707 match(Set dst (SubL src1 src2)); 10708 10709 ins_cost(INSN_COST); 10710 format %{ "sub$dst, $src1, $src2" %} 10711 10712 // use opcode to indicate that this is a sub not an add 10713 opcode(0x1); 10714 10715 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10716 10717 ins_pipe(ialu_reg_imm); 10718%} 10719 10720// Integer Negation (special case for sub) 10721 10722instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10723 match(Set dst (SubI zero src)); 10724 10725 ins_cost(INSN_COST); 10726 format %{ "negw $dst, $src\t# int" %} 10727 10728 ins_encode %{ 10729 __ negw(as_Register($dst$$reg), 10730 as_Register($src$$reg)); 10731 %} 10732 10733 ins_pipe(ialu_reg); 10734%} 10735 10736// Long Negation 10737 10738instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10739 match(Set dst (SubL zero src)); 10740 10741 ins_cost(INSN_COST); 10742 format %{ "neg $dst, $src\t# long" %} 10743 10744 ins_encode %{ 10745 __ neg(as_Register($dst$$reg), 10746 as_Register($src$$reg)); 10747 %} 10748 10749 ins_pipe(ialu_reg); 10750%} 10751 10752// Integer Multiply 10753 10754instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10755 match(Set dst (MulI src1 src2)); 10756 10757 ins_cost(INSN_COST * 3); 10758 format %{ "mulw $dst, $src1, $src2" %} 10759 10760 ins_encode %{ 10761 __ mulw(as_Register($dst$$reg), 10762 as_Register($src1$$reg), 10763 as_Register($src2$$reg)); 10764 %} 10765 10766 ins_pipe(imul_reg_reg); 10767%} 10768 10769instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10770 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10771 10772 ins_cost(INSN_COST * 3); 10773 format %{ "smull $dst, $src1, $src2" %} 10774 10775 ins_encode %{ 10776 __ smull(as_Register($dst$$reg), 10777 as_Register($src1$$reg), 10778 as_Register($src2$$reg)); 10779 %} 10780 10781 ins_pipe(imul_reg_reg); 10782%} 10783 10784// Long Multiply 10785 10786instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10787 match(Set dst (MulL src1 src2)); 10788 10789 ins_cost(INSN_COST * 5); 10790 format %{ "mul $dst, $src1, $src2" %} 10791 10792 ins_encode %{ 10793 __ mul(as_Register($dst$$reg), 10794 as_Register($src1$$reg), 10795 as_Register($src2$$reg)); 10796 %} 10797 10798 ins_pipe(lmul_reg_reg); 10799%} 10800 10801instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10802%{ 10803 match(Set dst (MulHiL src1 src2)); 10804 10805 ins_cost(INSN_COST * 7); 10806 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 10807 10808 ins_encode %{ 10809 __ smulh(as_Register($dst$$reg), 10810 as_Register($src1$$reg), 10811 as_Register($src2$$reg)); 10812 %} 10813 10814 ins_pipe(lmul_reg_reg); 10815%} 10816 10817// Combined Integer Multiply & Add/Sub 10818 10819instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10820 match(Set dst (AddI src3 (MulI src1 src2))); 10821 10822 ins_cost(INSN_COST * 3); 10823 format %{ "madd $dst, $src1, $src2, $src3" %} 10824 10825 ins_encode %{ 10826 __ maddw(as_Register($dst$$reg), 10827 as_Register($src1$$reg), 10828 as_Register($src2$$reg), 10829 as_Register($src3$$reg)); 10830 %} 10831 10832 ins_pipe(imac_reg_reg); 10833%} 10834 10835instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10836 match(Set dst (SubI src3 (MulI src1 src2))); 10837 10838 ins_cost(INSN_COST * 3); 10839 format %{ "msub $dst, $src1, $src2, $src3" %} 10840 10841 ins_encode %{ 10842 __ msubw(as_Register($dst$$reg), 10843 as_Register($src1$$reg), 10844 as_Register($src2$$reg), 10845 as_Register($src3$$reg)); 10846 %} 10847 10848 ins_pipe(imac_reg_reg); 10849%} 10850 10851// Combined Integer Multiply & Neg 10852 10853instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10854 match(Set dst (MulI (SubI zero src1) src2)); 10855 match(Set dst (MulI src1 (SubI zero src2))); 10856 10857 ins_cost(INSN_COST * 3); 10858 format %{ "mneg $dst, $src1, $src2" %} 10859 10860 ins_encode %{ 10861 __ mnegw(as_Register($dst$$reg), 10862 as_Register($src1$$reg), 10863 as_Register($src2$$reg)); 10864 %} 10865 10866 ins_pipe(imac_reg_reg); 10867%} 10868 10869// Combined Long Multiply & Add/Sub 10870 10871instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10872 match(Set dst (AddL src3 (MulL src1 src2))); 10873 10874 ins_cost(INSN_COST * 5); 10875 format %{ "madd $dst, $src1, $src2, $src3" %} 10876 10877 ins_encode %{ 10878 __ madd(as_Register($dst$$reg), 10879 as_Register($src1$$reg), 10880 as_Register($src2$$reg), 10881 as_Register($src3$$reg)); 10882 %} 10883 10884 ins_pipe(lmac_reg_reg); 10885%} 10886 10887instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10888 match(Set dst (SubL src3 (MulL src1 src2))); 10889 10890 ins_cost(INSN_COST * 5); 10891 format %{ "msub $dst, $src1, $src2, $src3" %} 10892 10893 ins_encode %{ 10894 __ msub(as_Register($dst$$reg), 10895 as_Register($src1$$reg), 10896 as_Register($src2$$reg), 10897 as_Register($src3$$reg)); 10898 %} 10899 10900 ins_pipe(lmac_reg_reg); 10901%} 10902 10903// Combined Long Multiply & Neg 10904 10905instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10906 match(Set dst (MulL (SubL zero src1) src2)); 10907 match(Set dst (MulL src1 (SubL zero src2))); 10908 10909 ins_cost(INSN_COST * 5); 10910 format %{ "mneg $dst, $src1, $src2" %} 10911 10912 ins_encode %{ 10913 __ mneg(as_Register($dst$$reg), 10914 as_Register($src1$$reg), 10915 as_Register($src2$$reg)); 10916 %} 10917 10918 ins_pipe(lmac_reg_reg); 10919%} 10920 10921// Combine Integer Signed Multiply & Add/Sub/Neg Long 10922 10923instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10924 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10925 10926 ins_cost(INSN_COST * 3); 10927 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10928 10929 ins_encode %{ 10930 __ smaddl(as_Register($dst$$reg), 10931 as_Register($src1$$reg), 10932 as_Register($src2$$reg), 10933 as_Register($src3$$reg)); 10934 %} 10935 10936 ins_pipe(imac_reg_reg); 10937%} 10938 10939instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10940 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10941 10942 ins_cost(INSN_COST * 3); 10943 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10944 10945 ins_encode %{ 10946 __ smsubl(as_Register($dst$$reg), 10947 as_Register($src1$$reg), 10948 as_Register($src2$$reg), 10949 as_Register($src3$$reg)); 10950 %} 10951 10952 ins_pipe(imac_reg_reg); 10953%} 10954 10955instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10956 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10957 match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); 10958 10959 ins_cost(INSN_COST * 3); 10960 format %{ "smnegl $dst, $src1, $src2" %} 10961 10962 ins_encode %{ 10963 __ smnegl(as_Register($dst$$reg), 10964 as_Register($src1$$reg), 10965 as_Register($src2$$reg)); 10966 %} 10967 10968 ins_pipe(imac_reg_reg); 10969%} 10970 10971// Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10972 10973instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10974 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10975 10976 ins_cost(INSN_COST * 5); 10977 format %{ "mulw rscratch1, $src1, $src2\n\t" 10978 "maddw $dst, $src3, $src4, rscratch1" %} 10979 10980 ins_encode %{ 10981 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10982 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10983 10984 ins_pipe(imac_reg_reg); 10985%} 10986 10987// Integer Divide 10988 10989instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10990 match(Set dst (DivI src1 src2)); 10991 10992 ins_cost(INSN_COST * 19); 10993 format %{ "sdivw $dst, $src1, $src2" %} 10994 10995 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10996 ins_pipe(idiv_reg_reg); 10997%} 10998 10999// Long Divide 11000 11001instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11002 match(Set dst (DivL src1 src2)); 11003 11004 ins_cost(INSN_COST * 35); 11005 format %{ "sdiv $dst, $src1, $src2" %} 11006 11007 ins_encode(aarch64_enc_div(dst, src1, src2)); 11008 ins_pipe(ldiv_reg_reg); 11009%} 11010 11011// Integer Remainder 11012 11013instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11014 match(Set dst (ModI src1 src2)); 11015 11016 ins_cost(INSN_COST * 22); 11017 format %{ "sdivw rscratch1, $src1, $src2\n\t" 11018 "msubw($dst, rscratch1, $src2, $src1" %} 11019 11020 ins_encode(aarch64_enc_modw(dst, src1, src2)); 11021 ins_pipe(idiv_reg_reg); 11022%} 11023 11024// Long Remainder 11025 11026instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11027 match(Set dst (ModL src1 src2)); 11028 11029 ins_cost(INSN_COST * 38); 11030 format %{ "sdiv rscratch1, $src1, $src2\n" 11031 "msub($dst, rscratch1, $src2, $src1" %} 11032 11033 ins_encode(aarch64_enc_mod(dst, src1, src2)); 11034 ins_pipe(ldiv_reg_reg); 11035%} 11036 11037// Integer Shifts 11038 11039// Shift Left Register 11040instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11041 match(Set dst (LShiftI src1 src2)); 11042 11043 ins_cost(INSN_COST * 2); 11044 format %{ "lslvw $dst, $src1, $src2" %} 11045 11046 ins_encode %{ 11047 __ lslvw(as_Register($dst$$reg), 11048 as_Register($src1$$reg), 11049 as_Register($src2$$reg)); 11050 %} 11051 11052 ins_pipe(ialu_reg_reg_vshift); 11053%} 11054 11055// Shift Left Immediate 11056instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 11057 match(Set dst (LShiftI src1 src2)); 11058 11059 ins_cost(INSN_COST); 11060 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 11061 11062 ins_encode %{ 11063 __ lslw(as_Register($dst$$reg), 11064 as_Register($src1$$reg), 11065 $src2$$constant & 0x1f); 11066 %} 11067 11068 ins_pipe(ialu_reg_shift); 11069%} 11070 11071// Shift Right Logical Register 11072instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11073 match(Set dst (URShiftI src1 src2)); 11074 11075 ins_cost(INSN_COST * 2); 11076 format %{ "lsrvw $dst, $src1, $src2" %} 11077 11078 ins_encode %{ 11079 __ lsrvw(as_Register($dst$$reg), 11080 as_Register($src1$$reg), 11081 as_Register($src2$$reg)); 11082 %} 11083 11084 ins_pipe(ialu_reg_reg_vshift); 11085%} 11086 11087// Shift Right Logical Immediate 11088instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 11089 match(Set dst (URShiftI src1 src2)); 11090 11091 ins_cost(INSN_COST); 11092 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 11093 11094 ins_encode %{ 11095 __ lsrw(as_Register($dst$$reg), 11096 as_Register($src1$$reg), 11097 $src2$$constant & 0x1f); 11098 %} 11099 11100 ins_pipe(ialu_reg_shift); 11101%} 11102 11103// Shift Right Arithmetic Register 11104instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11105 match(Set dst (RShiftI src1 src2)); 11106 11107 ins_cost(INSN_COST * 2); 11108 format %{ "asrvw $dst, $src1, $src2" %} 11109 11110 ins_encode %{ 11111 __ asrvw(as_Register($dst$$reg), 11112 as_Register($src1$$reg), 11113 as_Register($src2$$reg)); 11114 %} 11115 11116 ins_pipe(ialu_reg_reg_vshift); 11117%} 11118 11119// Shift Right Arithmetic Immediate 11120instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 11121 match(Set dst (RShiftI src1 src2)); 11122 11123 ins_cost(INSN_COST); 11124 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 11125 11126 ins_encode %{ 11127 __ asrw(as_Register($dst$$reg), 11128 as_Register($src1$$reg), 11129 $src2$$constant & 0x1f); 11130 %} 11131 11132 ins_pipe(ialu_reg_shift); 11133%} 11134 11135// Combined Int Mask and Right Shift (using UBFM) 11136// TODO 11137 11138// Long Shifts 11139 11140// Shift Left Register 11141instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11142 match(Set dst (LShiftL src1 src2)); 11143 11144 ins_cost(INSN_COST * 2); 11145 format %{ "lslv $dst, $src1, $src2" %} 11146 11147 ins_encode %{ 11148 __ lslv(as_Register($dst$$reg), 11149 as_Register($src1$$reg), 11150 as_Register($src2$$reg)); 11151 %} 11152 11153 ins_pipe(ialu_reg_reg_vshift); 11154%} 11155 11156// Shift Left Immediate 11157instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11158 match(Set dst (LShiftL src1 src2)); 11159 11160 ins_cost(INSN_COST); 11161 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 11162 11163 ins_encode %{ 11164 __ lsl(as_Register($dst$$reg), 11165 as_Register($src1$$reg), 11166 $src2$$constant & 0x3f); 11167 %} 11168 11169 ins_pipe(ialu_reg_shift); 11170%} 11171 11172// Shift Right Logical Register 11173instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11174 match(Set dst (URShiftL src1 src2)); 11175 11176 ins_cost(INSN_COST * 2); 11177 format %{ "lsrv $dst, $src1, $src2" %} 11178 11179 ins_encode %{ 11180 __ lsrv(as_Register($dst$$reg), 11181 as_Register($src1$$reg), 11182 as_Register($src2$$reg)); 11183 %} 11184 11185 ins_pipe(ialu_reg_reg_vshift); 11186%} 11187 11188// Shift Right Logical Immediate 11189instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11190 match(Set dst (URShiftL src1 src2)); 11191 11192 ins_cost(INSN_COST); 11193 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 11194 11195 ins_encode %{ 11196 __ lsr(as_Register($dst$$reg), 11197 as_Register($src1$$reg), 11198 $src2$$constant & 0x3f); 11199 %} 11200 11201 ins_pipe(ialu_reg_shift); 11202%} 11203 11204// A special-case pattern for card table stores. 11205instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 11206 match(Set dst (URShiftL (CastP2X src1) src2)); 11207 11208 ins_cost(INSN_COST); 11209 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 11210 11211 ins_encode %{ 11212 __ lsr(as_Register($dst$$reg), 11213 as_Register($src1$$reg), 11214 $src2$$constant & 0x3f); 11215 %} 11216 11217 ins_pipe(ialu_reg_shift); 11218%} 11219 11220// Shift Right Arithmetic Register 11221instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11222 match(Set dst (RShiftL src1 src2)); 11223 11224 ins_cost(INSN_COST * 2); 11225 format %{ "asrv $dst, $src1, $src2" %} 11226 11227 ins_encode %{ 11228 __ asrv(as_Register($dst$$reg), 11229 as_Register($src1$$reg), 11230 as_Register($src2$$reg)); 11231 %} 11232 11233 ins_pipe(ialu_reg_reg_vshift); 11234%} 11235 11236// Shift Right Arithmetic Immediate 11237instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11238 match(Set dst (RShiftL src1 src2)); 11239 11240 ins_cost(INSN_COST); 11241 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 11242 11243 ins_encode %{ 11244 __ asr(as_Register($dst$$reg), 11245 as_Register($src1$$reg), 11246 $src2$$constant & 0x3f); 11247 %} 11248 11249 ins_pipe(ialu_reg_shift); 11250%} 11251 11252// BEGIN This section of the file is automatically generated. Do not edit -------------- 11253// This section is generated from aarch64_ad.m4 11254 11255 11256// This pattern is automatically generated from aarch64_ad.m4 11257// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11258instruct regL_not_reg(iRegLNoSp dst, 11259 iRegL src1, immL_M1 m1, 11260 rFlagsReg cr) %{ 11261 match(Set dst (XorL src1 m1)); 11262 ins_cost(INSN_COST); 11263 format %{ "eon $dst, $src1, zr" %} 11264 11265 ins_encode %{ 11266 __ eon(as_Register($dst$$reg), 11267 as_Register($src1$$reg), 11268 zr, 11269 Assembler::LSL, 0); 11270 %} 11271 11272 ins_pipe(ialu_reg); 11273%} 11274 11275// This pattern is automatically generated from aarch64_ad.m4 11276// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11277instruct regI_not_reg(iRegINoSp dst, 11278 iRegIorL2I src1, immI_M1 m1, 11279 rFlagsReg cr) %{ 11280 match(Set dst (XorI src1 m1)); 11281 ins_cost(INSN_COST); 11282 format %{ "eonw $dst, $src1, zr" %} 11283 11284 ins_encode %{ 11285 __ eonw(as_Register($dst$$reg), 11286 as_Register($src1$$reg), 11287 zr, 11288 Assembler::LSL, 0); 11289 %} 11290 11291 ins_pipe(ialu_reg); 11292%} 11293 11294// This pattern is automatically generated from aarch64_ad.m4 11295// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11296instruct AndI_reg_not_reg(iRegINoSp dst, 11297 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11298 match(Set dst (AndI src1 (XorI src2 m1))); 11299 ins_cost(INSN_COST); 11300 format %{ "bicw $dst, $src1, $src2" %} 11301 11302 ins_encode %{ 11303 __ bicw(as_Register($dst$$reg), 11304 as_Register($src1$$reg), 11305 as_Register($src2$$reg), 11306 Assembler::LSL, 0); 11307 %} 11308 11309 ins_pipe(ialu_reg_reg); 11310%} 11311 11312// This pattern is automatically generated from aarch64_ad.m4 11313// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11314instruct AndL_reg_not_reg(iRegLNoSp dst, 11315 iRegL src1, iRegL src2, immL_M1 m1) %{ 11316 match(Set dst (AndL src1 (XorL src2 m1))); 11317 ins_cost(INSN_COST); 11318 format %{ "bic $dst, $src1, $src2" %} 11319 11320 ins_encode %{ 11321 __ bic(as_Register($dst$$reg), 11322 as_Register($src1$$reg), 11323 as_Register($src2$$reg), 11324 Assembler::LSL, 0); 11325 %} 11326 11327 ins_pipe(ialu_reg_reg); 11328%} 11329 11330// This pattern is automatically generated from aarch64_ad.m4 11331// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11332instruct OrI_reg_not_reg(iRegINoSp dst, 11333 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11334 match(Set dst (OrI src1 (XorI src2 m1))); 11335 ins_cost(INSN_COST); 11336 format %{ "ornw $dst, $src1, $src2" %} 11337 11338 ins_encode %{ 11339 __ ornw(as_Register($dst$$reg), 11340 as_Register($src1$$reg), 11341 as_Register($src2$$reg), 11342 Assembler::LSL, 0); 11343 %} 11344 11345 ins_pipe(ialu_reg_reg); 11346%} 11347 11348// This pattern is automatically generated from aarch64_ad.m4 11349// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11350instruct OrL_reg_not_reg(iRegLNoSp dst, 11351 iRegL src1, iRegL src2, immL_M1 m1) %{ 11352 match(Set dst (OrL src1 (XorL src2 m1))); 11353 ins_cost(INSN_COST); 11354 format %{ "orn $dst, $src1, $src2" %} 11355 11356 ins_encode %{ 11357 __ orn(as_Register($dst$$reg), 11358 as_Register($src1$$reg), 11359 as_Register($src2$$reg), 11360 Assembler::LSL, 0); 11361 %} 11362 11363 ins_pipe(ialu_reg_reg); 11364%} 11365 11366// This pattern is automatically generated from aarch64_ad.m4 11367// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11368instruct XorI_reg_not_reg(iRegINoSp dst, 11369 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11370 match(Set dst (XorI m1 (XorI src2 src1))); 11371 ins_cost(INSN_COST); 11372 format %{ "eonw $dst, $src1, $src2" %} 11373 11374 ins_encode %{ 11375 __ eonw(as_Register($dst$$reg), 11376 as_Register($src1$$reg), 11377 as_Register($src2$$reg), 11378 Assembler::LSL, 0); 11379 %} 11380 11381 ins_pipe(ialu_reg_reg); 11382%} 11383 11384// This pattern is automatically generated from aarch64_ad.m4 11385// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11386instruct XorL_reg_not_reg(iRegLNoSp dst, 11387 iRegL src1, iRegL src2, immL_M1 m1) %{ 11388 match(Set dst (XorL m1 (XorL src2 src1))); 11389 ins_cost(INSN_COST); 11390 format %{ "eon $dst, $src1, $src2" %} 11391 11392 ins_encode %{ 11393 __ eon(as_Register($dst$$reg), 11394 as_Register($src1$$reg), 11395 as_Register($src2$$reg), 11396 Assembler::LSL, 0); 11397 %} 11398 11399 ins_pipe(ialu_reg_reg); 11400%} 11401 11402// This pattern is automatically generated from aarch64_ad.m4 11403// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11404// val & (-1 ^ (val >>> shift)) ==> bicw 11405instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11406 iRegIorL2I src1, iRegIorL2I src2, 11407 immI src3, immI_M1 src4) %{ 11408 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11409 ins_cost(1.9 * INSN_COST); 11410 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11411 11412 ins_encode %{ 11413 __ bicw(as_Register($dst$$reg), 11414 as_Register($src1$$reg), 11415 as_Register($src2$$reg), 11416 Assembler::LSR, 11417 $src3$$constant & 0x1f); 11418 %} 11419 11420 ins_pipe(ialu_reg_reg_shift); 11421%} 11422 11423// This pattern is automatically generated from aarch64_ad.m4 11424// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11425// val & (-1 ^ (val >>> shift)) ==> bic 11426instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11427 iRegL src1, iRegL src2, 11428 immI src3, immL_M1 src4) %{ 11429 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11430 ins_cost(1.9 * INSN_COST); 11431 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11432 11433 ins_encode %{ 11434 __ bic(as_Register($dst$$reg), 11435 as_Register($src1$$reg), 11436 as_Register($src2$$reg), 11437 Assembler::LSR, 11438 $src3$$constant & 0x3f); 11439 %} 11440 11441 ins_pipe(ialu_reg_reg_shift); 11442%} 11443 11444// This pattern is automatically generated from aarch64_ad.m4 11445// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11446// val & (-1 ^ (val >> shift)) ==> bicw 11447instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11448 iRegIorL2I src1, iRegIorL2I src2, 11449 immI src3, immI_M1 src4) %{ 11450 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11451 ins_cost(1.9 * INSN_COST); 11452 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11453 11454 ins_encode %{ 11455 __ bicw(as_Register($dst$$reg), 11456 as_Register($src1$$reg), 11457 as_Register($src2$$reg), 11458 Assembler::ASR, 11459 $src3$$constant & 0x1f); 11460 %} 11461 11462 ins_pipe(ialu_reg_reg_shift); 11463%} 11464 11465// This pattern is automatically generated from aarch64_ad.m4 11466// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11467// val & (-1 ^ (val >> shift)) ==> bic 11468instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11469 iRegL src1, iRegL src2, 11470 immI src3, immL_M1 src4) %{ 11471 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11472 ins_cost(1.9 * INSN_COST); 11473 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11474 11475 ins_encode %{ 11476 __ bic(as_Register($dst$$reg), 11477 as_Register($src1$$reg), 11478 as_Register($src2$$reg), 11479 Assembler::ASR, 11480 $src3$$constant & 0x3f); 11481 %} 11482 11483 ins_pipe(ialu_reg_reg_shift); 11484%} 11485 11486// This pattern is automatically generated from aarch64_ad.m4 11487// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11488// val & (-1 ^ (val ror shift)) ==> bicw 11489instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst, 11490 iRegIorL2I src1, iRegIorL2I src2, 11491 immI src3, immI_M1 src4) %{ 11492 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4))); 11493 ins_cost(1.9 * INSN_COST); 11494 format %{ "bicw $dst, $src1, $src2, ROR $src3" %} 11495 11496 ins_encode %{ 11497 __ bicw(as_Register($dst$$reg), 11498 as_Register($src1$$reg), 11499 as_Register($src2$$reg), 11500 Assembler::ROR, 11501 $src3$$constant & 0x1f); 11502 %} 11503 11504 ins_pipe(ialu_reg_reg_shift); 11505%} 11506 11507// This pattern is automatically generated from aarch64_ad.m4 11508// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11509// val & (-1 ^ (val ror shift)) ==> bic 11510instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst, 11511 iRegL src1, iRegL src2, 11512 immI src3, immL_M1 src4) %{ 11513 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4))); 11514 ins_cost(1.9 * INSN_COST); 11515 format %{ "bic $dst, $src1, $src2, ROR $src3" %} 11516 11517 ins_encode %{ 11518 __ bic(as_Register($dst$$reg), 11519 as_Register($src1$$reg), 11520 as_Register($src2$$reg), 11521 Assembler::ROR, 11522 $src3$$constant & 0x3f); 11523 %} 11524 11525 ins_pipe(ialu_reg_reg_shift); 11526%} 11527 11528// This pattern is automatically generated from aarch64_ad.m4 11529// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11530// val & (-1 ^ (val << shift)) ==> bicw 11531instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11532 iRegIorL2I src1, iRegIorL2I src2, 11533 immI src3, immI_M1 src4) %{ 11534 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11535 ins_cost(1.9 * INSN_COST); 11536 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11537 11538 ins_encode %{ 11539 __ bicw(as_Register($dst$$reg), 11540 as_Register($src1$$reg), 11541 as_Register($src2$$reg), 11542 Assembler::LSL, 11543 $src3$$constant & 0x1f); 11544 %} 11545 11546 ins_pipe(ialu_reg_reg_shift); 11547%} 11548 11549// This pattern is automatically generated from aarch64_ad.m4 11550// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11551// val & (-1 ^ (val << shift)) ==> bic 11552instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11553 iRegL src1, iRegL src2, 11554 immI src3, immL_M1 src4) %{ 11555 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11556 ins_cost(1.9 * INSN_COST); 11557 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11558 11559 ins_encode %{ 11560 __ bic(as_Register($dst$$reg), 11561 as_Register($src1$$reg), 11562 as_Register($src2$$reg), 11563 Assembler::LSL, 11564 $src3$$constant & 0x3f); 11565 %} 11566 11567 ins_pipe(ialu_reg_reg_shift); 11568%} 11569 11570// This pattern is automatically generated from aarch64_ad.m4 11571// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11572// val ^ (-1 ^ (val >>> shift)) ==> eonw 11573instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11574 iRegIorL2I src1, iRegIorL2I src2, 11575 immI src3, immI_M1 src4) %{ 11576 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11577 ins_cost(1.9 * INSN_COST); 11578 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11579 11580 ins_encode %{ 11581 __ eonw(as_Register($dst$$reg), 11582 as_Register($src1$$reg), 11583 as_Register($src2$$reg), 11584 Assembler::LSR, 11585 $src3$$constant & 0x1f); 11586 %} 11587 11588 ins_pipe(ialu_reg_reg_shift); 11589%} 11590 11591// This pattern is automatically generated from aarch64_ad.m4 11592// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11593// val ^ (-1 ^ (val >>> shift)) ==> eon 11594instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11595 iRegL src1, iRegL src2, 11596 immI src3, immL_M1 src4) %{ 11597 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11598 ins_cost(1.9 * INSN_COST); 11599 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11600 11601 ins_encode %{ 11602 __ eon(as_Register($dst$$reg), 11603 as_Register($src1$$reg), 11604 as_Register($src2$$reg), 11605 Assembler::LSR, 11606 $src3$$constant & 0x3f); 11607 %} 11608 11609 ins_pipe(ialu_reg_reg_shift); 11610%} 11611 11612// This pattern is automatically generated from aarch64_ad.m4 11613// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11614// val ^ (-1 ^ (val >> shift)) ==> eonw 11615instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11616 iRegIorL2I src1, iRegIorL2I src2, 11617 immI src3, immI_M1 src4) %{ 11618 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11619 ins_cost(1.9 * INSN_COST); 11620 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11621 11622 ins_encode %{ 11623 __ eonw(as_Register($dst$$reg), 11624 as_Register($src1$$reg), 11625 as_Register($src2$$reg), 11626 Assembler::ASR, 11627 $src3$$constant & 0x1f); 11628 %} 11629 11630 ins_pipe(ialu_reg_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// val ^ (-1 ^ (val >> shift)) ==> eon 11636instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11637 iRegL src1, iRegL src2, 11638 immI src3, immL_M1 src4) %{ 11639 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11640 ins_cost(1.9 * INSN_COST); 11641 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11642 11643 ins_encode %{ 11644 __ eon(as_Register($dst$$reg), 11645 as_Register($src1$$reg), 11646 as_Register($src2$$reg), 11647 Assembler::ASR, 11648 $src3$$constant & 0x3f); 11649 %} 11650 11651 ins_pipe(ialu_reg_reg_shift); 11652%} 11653 11654// This pattern is automatically generated from aarch64_ad.m4 11655// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11656// val ^ (-1 ^ (val ror shift)) ==> eonw 11657instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst, 11658 iRegIorL2I src1, iRegIorL2I src2, 11659 immI src3, immI_M1 src4) %{ 11660 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1))); 11661 ins_cost(1.9 * INSN_COST); 11662 format %{ "eonw $dst, $src1, $src2, ROR $src3" %} 11663 11664 ins_encode %{ 11665 __ eonw(as_Register($dst$$reg), 11666 as_Register($src1$$reg), 11667 as_Register($src2$$reg), 11668 Assembler::ROR, 11669 $src3$$constant & 0x1f); 11670 %} 11671 11672 ins_pipe(ialu_reg_reg_shift); 11673%} 11674 11675// This pattern is automatically generated from aarch64_ad.m4 11676// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11677// val ^ (-1 ^ (val ror shift)) ==> eon 11678instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst, 11679 iRegL src1, iRegL src2, 11680 immI src3, immL_M1 src4) %{ 11681 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1))); 11682 ins_cost(1.9 * INSN_COST); 11683 format %{ "eon $dst, $src1, $src2, ROR $src3" %} 11684 11685 ins_encode %{ 11686 __ eon(as_Register($dst$$reg), 11687 as_Register($src1$$reg), 11688 as_Register($src2$$reg), 11689 Assembler::ROR, 11690 $src3$$constant & 0x3f); 11691 %} 11692 11693 ins_pipe(ialu_reg_reg_shift); 11694%} 11695 11696// This pattern is automatically generated from aarch64_ad.m4 11697// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11698// val ^ (-1 ^ (val << shift)) ==> eonw 11699instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11700 iRegIorL2I src1, iRegIorL2I src2, 11701 immI src3, immI_M1 src4) %{ 11702 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11703 ins_cost(1.9 * INSN_COST); 11704 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11705 11706 ins_encode %{ 11707 __ eonw(as_Register($dst$$reg), 11708 as_Register($src1$$reg), 11709 as_Register($src2$$reg), 11710 Assembler::LSL, 11711 $src3$$constant & 0x1f); 11712 %} 11713 11714 ins_pipe(ialu_reg_reg_shift); 11715%} 11716 11717// This pattern is automatically generated from aarch64_ad.m4 11718// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11719// val ^ (-1 ^ (val << shift)) ==> eon 11720instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11721 iRegL src1, iRegL src2, 11722 immI src3, immL_M1 src4) %{ 11723 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11724 ins_cost(1.9 * INSN_COST); 11725 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11726 11727 ins_encode %{ 11728 __ eon(as_Register($dst$$reg), 11729 as_Register($src1$$reg), 11730 as_Register($src2$$reg), 11731 Assembler::LSL, 11732 $src3$$constant & 0x3f); 11733 %} 11734 11735 ins_pipe(ialu_reg_reg_shift); 11736%} 11737 11738// This pattern is automatically generated from aarch64_ad.m4 11739// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11740// val | (-1 ^ (val >>> shift)) ==> ornw 11741instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11742 iRegIorL2I src1, iRegIorL2I src2, 11743 immI src3, immI_M1 src4) %{ 11744 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11745 ins_cost(1.9 * INSN_COST); 11746 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11747 11748 ins_encode %{ 11749 __ ornw(as_Register($dst$$reg), 11750 as_Register($src1$$reg), 11751 as_Register($src2$$reg), 11752 Assembler::LSR, 11753 $src3$$constant & 0x1f); 11754 %} 11755 11756 ins_pipe(ialu_reg_reg_shift); 11757%} 11758 11759// This pattern is automatically generated from aarch64_ad.m4 11760// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11761// val | (-1 ^ (val >>> shift)) ==> orn 11762instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11763 iRegL src1, iRegL src2, 11764 immI src3, immL_M1 src4) %{ 11765 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11766 ins_cost(1.9 * INSN_COST); 11767 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11768 11769 ins_encode %{ 11770 __ orn(as_Register($dst$$reg), 11771 as_Register($src1$$reg), 11772 as_Register($src2$$reg), 11773 Assembler::LSR, 11774 $src3$$constant & 0x3f); 11775 %} 11776 11777 ins_pipe(ialu_reg_reg_shift); 11778%} 11779 11780// This pattern is automatically generated from aarch64_ad.m4 11781// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11782// val | (-1 ^ (val >> shift)) ==> ornw 11783instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11784 iRegIorL2I src1, iRegIorL2I src2, 11785 immI src3, immI_M1 src4) %{ 11786 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11787 ins_cost(1.9 * INSN_COST); 11788 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11789 11790 ins_encode %{ 11791 __ ornw(as_Register($dst$$reg), 11792 as_Register($src1$$reg), 11793 as_Register($src2$$reg), 11794 Assembler::ASR, 11795 $src3$$constant & 0x1f); 11796 %} 11797 11798 ins_pipe(ialu_reg_reg_shift); 11799%} 11800 11801// This pattern is automatically generated from aarch64_ad.m4 11802// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11803// val | (-1 ^ (val >> shift)) ==> orn 11804instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11805 iRegL src1, iRegL src2, 11806 immI src3, immL_M1 src4) %{ 11807 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11808 ins_cost(1.9 * INSN_COST); 11809 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11810 11811 ins_encode %{ 11812 __ orn(as_Register($dst$$reg), 11813 as_Register($src1$$reg), 11814 as_Register($src2$$reg), 11815 Assembler::ASR, 11816 $src3$$constant & 0x3f); 11817 %} 11818 11819 ins_pipe(ialu_reg_reg_shift); 11820%} 11821 11822// This pattern is automatically generated from aarch64_ad.m4 11823// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11824// val | (-1 ^ (val ror shift)) ==> ornw 11825instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst, 11826 iRegIorL2I src1, iRegIorL2I src2, 11827 immI src3, immI_M1 src4) %{ 11828 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4))); 11829 ins_cost(1.9 * INSN_COST); 11830 format %{ "ornw $dst, $src1, $src2, ROR $src3" %} 11831 11832 ins_encode %{ 11833 __ ornw(as_Register($dst$$reg), 11834 as_Register($src1$$reg), 11835 as_Register($src2$$reg), 11836 Assembler::ROR, 11837 $src3$$constant & 0x1f); 11838 %} 11839 11840 ins_pipe(ialu_reg_reg_shift); 11841%} 11842 11843// This pattern is automatically generated from aarch64_ad.m4 11844// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11845// val | (-1 ^ (val ror shift)) ==> orn 11846instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst, 11847 iRegL src1, iRegL src2, 11848 immI src3, immL_M1 src4) %{ 11849 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4))); 11850 ins_cost(1.9 * INSN_COST); 11851 format %{ "orn $dst, $src1, $src2, ROR $src3" %} 11852 11853 ins_encode %{ 11854 __ orn(as_Register($dst$$reg), 11855 as_Register($src1$$reg), 11856 as_Register($src2$$reg), 11857 Assembler::ROR, 11858 $src3$$constant & 0x3f); 11859 %} 11860 11861 ins_pipe(ialu_reg_reg_shift); 11862%} 11863 11864// This pattern is automatically generated from aarch64_ad.m4 11865// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11866// val | (-1 ^ (val << shift)) ==> ornw 11867instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11868 iRegIorL2I src1, iRegIorL2I src2, 11869 immI src3, immI_M1 src4) %{ 11870 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11871 ins_cost(1.9 * INSN_COST); 11872 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11873 11874 ins_encode %{ 11875 __ ornw(as_Register($dst$$reg), 11876 as_Register($src1$$reg), 11877 as_Register($src2$$reg), 11878 Assembler::LSL, 11879 $src3$$constant & 0x1f); 11880 %} 11881 11882 ins_pipe(ialu_reg_reg_shift); 11883%} 11884 11885// This pattern is automatically generated from aarch64_ad.m4 11886// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11887// val | (-1 ^ (val << shift)) ==> orn 11888instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11889 iRegL src1, iRegL src2, 11890 immI src3, immL_M1 src4) %{ 11891 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11892 ins_cost(1.9 * INSN_COST); 11893 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11894 11895 ins_encode %{ 11896 __ orn(as_Register($dst$$reg), 11897 as_Register($src1$$reg), 11898 as_Register($src2$$reg), 11899 Assembler::LSL, 11900 $src3$$constant & 0x3f); 11901 %} 11902 11903 ins_pipe(ialu_reg_reg_shift); 11904%} 11905 11906// This pattern is automatically generated from aarch64_ad.m4 11907// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11908instruct AndI_reg_URShift_reg(iRegINoSp dst, 11909 iRegIorL2I src1, iRegIorL2I src2, 11910 immI src3) %{ 11911 match(Set dst (AndI src1 (URShiftI src2 src3))); 11912 11913 ins_cost(1.9 * INSN_COST); 11914 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11915 11916 ins_encode %{ 11917 __ andw(as_Register($dst$$reg), 11918 as_Register($src1$$reg), 11919 as_Register($src2$$reg), 11920 Assembler::LSR, 11921 $src3$$constant & 0x1f); 11922 %} 11923 11924 ins_pipe(ialu_reg_reg_shift); 11925%} 11926 11927// This pattern is automatically generated from aarch64_ad.m4 11928// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11929instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11930 iRegL src1, iRegL src2, 11931 immI src3) %{ 11932 match(Set dst (AndL src1 (URShiftL src2 src3))); 11933 11934 ins_cost(1.9 * INSN_COST); 11935 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11936 11937 ins_encode %{ 11938 __ andr(as_Register($dst$$reg), 11939 as_Register($src1$$reg), 11940 as_Register($src2$$reg), 11941 Assembler::LSR, 11942 $src3$$constant & 0x3f); 11943 %} 11944 11945 ins_pipe(ialu_reg_reg_shift); 11946%} 11947 11948// This pattern is automatically generated from aarch64_ad.m4 11949// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11950instruct AndI_reg_RShift_reg(iRegINoSp dst, 11951 iRegIorL2I src1, iRegIorL2I src2, 11952 immI src3) %{ 11953 match(Set dst (AndI src1 (RShiftI src2 src3))); 11954 11955 ins_cost(1.9 * INSN_COST); 11956 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11957 11958 ins_encode %{ 11959 __ andw(as_Register($dst$$reg), 11960 as_Register($src1$$reg), 11961 as_Register($src2$$reg), 11962 Assembler::ASR, 11963 $src3$$constant & 0x1f); 11964 %} 11965 11966 ins_pipe(ialu_reg_reg_shift); 11967%} 11968 11969// This pattern is automatically generated from aarch64_ad.m4 11970// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11971instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11972 iRegL src1, iRegL src2, 11973 immI src3) %{ 11974 match(Set dst (AndL src1 (RShiftL src2 src3))); 11975 11976 ins_cost(1.9 * INSN_COST); 11977 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11978 11979 ins_encode %{ 11980 __ andr(as_Register($dst$$reg), 11981 as_Register($src1$$reg), 11982 as_Register($src2$$reg), 11983 Assembler::ASR, 11984 $src3$$constant & 0x3f); 11985 %} 11986 11987 ins_pipe(ialu_reg_reg_shift); 11988%} 11989 11990// This pattern is automatically generated from aarch64_ad.m4 11991// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11992instruct AndI_reg_LShift_reg(iRegINoSp dst, 11993 iRegIorL2I src1, iRegIorL2I src2, 11994 immI src3) %{ 11995 match(Set dst (AndI src1 (LShiftI src2 src3))); 11996 11997 ins_cost(1.9 * INSN_COST); 11998 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11999 12000 ins_encode %{ 12001 __ andw(as_Register($dst$$reg), 12002 as_Register($src1$$reg), 12003 as_Register($src2$$reg), 12004 Assembler::LSL, 12005 $src3$$constant & 0x1f); 12006 %} 12007 12008 ins_pipe(ialu_reg_reg_shift); 12009%} 12010 12011// This pattern is automatically generated from aarch64_ad.m4 12012// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12013instruct AndL_reg_LShift_reg(iRegLNoSp dst, 12014 iRegL src1, iRegL src2, 12015 immI src3) %{ 12016 match(Set dst (AndL src1 (LShiftL src2 src3))); 12017 12018 ins_cost(1.9 * INSN_COST); 12019 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 12020 12021 ins_encode %{ 12022 __ andr(as_Register($dst$$reg), 12023 as_Register($src1$$reg), 12024 as_Register($src2$$reg), 12025 Assembler::LSL, 12026 $src3$$constant & 0x3f); 12027 %} 12028 12029 ins_pipe(ialu_reg_reg_shift); 12030%} 12031 12032// This pattern is automatically generated from aarch64_ad.m4 12033// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12034instruct AndI_reg_RotateRight_reg(iRegINoSp dst, 12035 iRegIorL2I src1, iRegIorL2I src2, 12036 immI src3) %{ 12037 match(Set dst (AndI src1 (RotateRight src2 src3))); 12038 12039 ins_cost(1.9 * INSN_COST); 12040 format %{ "andw $dst, $src1, $src2, ROR $src3" %} 12041 12042 ins_encode %{ 12043 __ andw(as_Register($dst$$reg), 12044 as_Register($src1$$reg), 12045 as_Register($src2$$reg), 12046 Assembler::ROR, 12047 $src3$$constant & 0x1f); 12048 %} 12049 12050 ins_pipe(ialu_reg_reg_shift); 12051%} 12052 12053// This pattern is automatically generated from aarch64_ad.m4 12054// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12055instruct AndL_reg_RotateRight_reg(iRegLNoSp dst, 12056 iRegL src1, iRegL src2, 12057 immI src3) %{ 12058 match(Set dst (AndL src1 (RotateRight src2 src3))); 12059 12060 ins_cost(1.9 * INSN_COST); 12061 format %{ "andr $dst, $src1, $src2, ROR $src3" %} 12062 12063 ins_encode %{ 12064 __ andr(as_Register($dst$$reg), 12065 as_Register($src1$$reg), 12066 as_Register($src2$$reg), 12067 Assembler::ROR, 12068 $src3$$constant & 0x3f); 12069 %} 12070 12071 ins_pipe(ialu_reg_reg_shift); 12072%} 12073 12074// This pattern is automatically generated from aarch64_ad.m4 12075// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12076instruct XorI_reg_URShift_reg(iRegINoSp dst, 12077 iRegIorL2I src1, iRegIorL2I src2, 12078 immI src3) %{ 12079 match(Set dst (XorI src1 (URShiftI src2 src3))); 12080 12081 ins_cost(1.9 * INSN_COST); 12082 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 12083 12084 ins_encode %{ 12085 __ eorw(as_Register($dst$$reg), 12086 as_Register($src1$$reg), 12087 as_Register($src2$$reg), 12088 Assembler::LSR, 12089 $src3$$constant & 0x1f); 12090 %} 12091 12092 ins_pipe(ialu_reg_reg_shift); 12093%} 12094 12095// This pattern is automatically generated from aarch64_ad.m4 12096// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12097instruct XorL_reg_URShift_reg(iRegLNoSp dst, 12098 iRegL src1, iRegL src2, 12099 immI src3) %{ 12100 match(Set dst (XorL src1 (URShiftL src2 src3))); 12101 12102 ins_cost(1.9 * INSN_COST); 12103 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 12104 12105 ins_encode %{ 12106 __ eor(as_Register($dst$$reg), 12107 as_Register($src1$$reg), 12108 as_Register($src2$$reg), 12109 Assembler::LSR, 12110 $src3$$constant & 0x3f); 12111 %} 12112 12113 ins_pipe(ialu_reg_reg_shift); 12114%} 12115 12116// This pattern is automatically generated from aarch64_ad.m4 12117// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12118instruct XorI_reg_RShift_reg(iRegINoSp dst, 12119 iRegIorL2I src1, iRegIorL2I src2, 12120 immI src3) %{ 12121 match(Set dst (XorI src1 (RShiftI src2 src3))); 12122 12123 ins_cost(1.9 * INSN_COST); 12124 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 12125 12126 ins_encode %{ 12127 __ eorw(as_Register($dst$$reg), 12128 as_Register($src1$$reg), 12129 as_Register($src2$$reg), 12130 Assembler::ASR, 12131 $src3$$constant & 0x1f); 12132 %} 12133 12134 ins_pipe(ialu_reg_reg_shift); 12135%} 12136 12137// This pattern is automatically generated from aarch64_ad.m4 12138// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12139instruct XorL_reg_RShift_reg(iRegLNoSp dst, 12140 iRegL src1, iRegL src2, 12141 immI src3) %{ 12142 match(Set dst (XorL src1 (RShiftL src2 src3))); 12143 12144 ins_cost(1.9 * INSN_COST); 12145 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 12146 12147 ins_encode %{ 12148 __ eor(as_Register($dst$$reg), 12149 as_Register($src1$$reg), 12150 as_Register($src2$$reg), 12151 Assembler::ASR, 12152 $src3$$constant & 0x3f); 12153 %} 12154 12155 ins_pipe(ialu_reg_reg_shift); 12156%} 12157 12158// This pattern is automatically generated from aarch64_ad.m4 12159// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12160instruct XorI_reg_LShift_reg(iRegINoSp dst, 12161 iRegIorL2I src1, iRegIorL2I src2, 12162 immI src3) %{ 12163 match(Set dst (XorI src1 (LShiftI src2 src3))); 12164 12165 ins_cost(1.9 * INSN_COST); 12166 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 12167 12168 ins_encode %{ 12169 __ eorw(as_Register($dst$$reg), 12170 as_Register($src1$$reg), 12171 as_Register($src2$$reg), 12172 Assembler::LSL, 12173 $src3$$constant & 0x1f); 12174 %} 12175 12176 ins_pipe(ialu_reg_reg_shift); 12177%} 12178 12179// This pattern is automatically generated from aarch64_ad.m4 12180// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12181instruct XorL_reg_LShift_reg(iRegLNoSp dst, 12182 iRegL src1, iRegL src2, 12183 immI src3) %{ 12184 match(Set dst (XorL src1 (LShiftL src2 src3))); 12185 12186 ins_cost(1.9 * INSN_COST); 12187 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 12188 12189 ins_encode %{ 12190 __ eor(as_Register($dst$$reg), 12191 as_Register($src1$$reg), 12192 as_Register($src2$$reg), 12193 Assembler::LSL, 12194 $src3$$constant & 0x3f); 12195 %} 12196 12197 ins_pipe(ialu_reg_reg_shift); 12198%} 12199 12200// This pattern is automatically generated from aarch64_ad.m4 12201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12202instruct XorI_reg_RotateRight_reg(iRegINoSp dst, 12203 iRegIorL2I src1, iRegIorL2I src2, 12204 immI src3) %{ 12205 match(Set dst (XorI src1 (RotateRight src2 src3))); 12206 12207 ins_cost(1.9 * INSN_COST); 12208 format %{ "eorw $dst, $src1, $src2, ROR $src3" %} 12209 12210 ins_encode %{ 12211 __ eorw(as_Register($dst$$reg), 12212 as_Register($src1$$reg), 12213 as_Register($src2$$reg), 12214 Assembler::ROR, 12215 $src3$$constant & 0x1f); 12216 %} 12217 12218 ins_pipe(ialu_reg_reg_shift); 12219%} 12220 12221// This pattern is automatically generated from aarch64_ad.m4 12222// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12223instruct XorL_reg_RotateRight_reg(iRegLNoSp dst, 12224 iRegL src1, iRegL src2, 12225 immI src3) %{ 12226 match(Set dst (XorL src1 (RotateRight src2 src3))); 12227 12228 ins_cost(1.9 * INSN_COST); 12229 format %{ "eor $dst, $src1, $src2, ROR $src3" %} 12230 12231 ins_encode %{ 12232 __ eor(as_Register($dst$$reg), 12233 as_Register($src1$$reg), 12234 as_Register($src2$$reg), 12235 Assembler::ROR, 12236 $src3$$constant & 0x3f); 12237 %} 12238 12239 ins_pipe(ialu_reg_reg_shift); 12240%} 12241 12242// This pattern is automatically generated from aarch64_ad.m4 12243// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12244instruct OrI_reg_URShift_reg(iRegINoSp dst, 12245 iRegIorL2I src1, iRegIorL2I src2, 12246 immI src3) %{ 12247 match(Set dst (OrI src1 (URShiftI src2 src3))); 12248 12249 ins_cost(1.9 * INSN_COST); 12250 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 12251 12252 ins_encode %{ 12253 __ orrw(as_Register($dst$$reg), 12254 as_Register($src1$$reg), 12255 as_Register($src2$$reg), 12256 Assembler::LSR, 12257 $src3$$constant & 0x1f); 12258 %} 12259 12260 ins_pipe(ialu_reg_reg_shift); 12261%} 12262 12263// This pattern is automatically generated from aarch64_ad.m4 12264// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12265instruct OrL_reg_URShift_reg(iRegLNoSp dst, 12266 iRegL src1, iRegL src2, 12267 immI src3) %{ 12268 match(Set dst (OrL src1 (URShiftL src2 src3))); 12269 12270 ins_cost(1.9 * INSN_COST); 12271 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 12272 12273 ins_encode %{ 12274 __ orr(as_Register($dst$$reg), 12275 as_Register($src1$$reg), 12276 as_Register($src2$$reg), 12277 Assembler::LSR, 12278 $src3$$constant & 0x3f); 12279 %} 12280 12281 ins_pipe(ialu_reg_reg_shift); 12282%} 12283 12284// This pattern is automatically generated from aarch64_ad.m4 12285// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12286instruct OrI_reg_RShift_reg(iRegINoSp dst, 12287 iRegIorL2I src1, iRegIorL2I src2, 12288 immI src3) %{ 12289 match(Set dst (OrI src1 (RShiftI src2 src3))); 12290 12291 ins_cost(1.9 * INSN_COST); 12292 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 12293 12294 ins_encode %{ 12295 __ orrw(as_Register($dst$$reg), 12296 as_Register($src1$$reg), 12297 as_Register($src2$$reg), 12298 Assembler::ASR, 12299 $src3$$constant & 0x1f); 12300 %} 12301 12302 ins_pipe(ialu_reg_reg_shift); 12303%} 12304 12305// This pattern is automatically generated from aarch64_ad.m4 12306// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12307instruct OrL_reg_RShift_reg(iRegLNoSp dst, 12308 iRegL src1, iRegL src2, 12309 immI src3) %{ 12310 match(Set dst (OrL src1 (RShiftL src2 src3))); 12311 12312 ins_cost(1.9 * INSN_COST); 12313 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 12314 12315 ins_encode %{ 12316 __ orr(as_Register($dst$$reg), 12317 as_Register($src1$$reg), 12318 as_Register($src2$$reg), 12319 Assembler::ASR, 12320 $src3$$constant & 0x3f); 12321 %} 12322 12323 ins_pipe(ialu_reg_reg_shift); 12324%} 12325 12326// This pattern is automatically generated from aarch64_ad.m4 12327// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12328instruct OrI_reg_LShift_reg(iRegINoSp dst, 12329 iRegIorL2I src1, iRegIorL2I src2, 12330 immI src3) %{ 12331 match(Set dst (OrI src1 (LShiftI src2 src3))); 12332 12333 ins_cost(1.9 * INSN_COST); 12334 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 12335 12336 ins_encode %{ 12337 __ orrw(as_Register($dst$$reg), 12338 as_Register($src1$$reg), 12339 as_Register($src2$$reg), 12340 Assembler::LSL, 12341 $src3$$constant & 0x1f); 12342 %} 12343 12344 ins_pipe(ialu_reg_reg_shift); 12345%} 12346 12347// This pattern is automatically generated from aarch64_ad.m4 12348// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12349instruct OrL_reg_LShift_reg(iRegLNoSp dst, 12350 iRegL src1, iRegL src2, 12351 immI src3) %{ 12352 match(Set dst (OrL src1 (LShiftL src2 src3))); 12353 12354 ins_cost(1.9 * INSN_COST); 12355 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 12356 12357 ins_encode %{ 12358 __ orr(as_Register($dst$$reg), 12359 as_Register($src1$$reg), 12360 as_Register($src2$$reg), 12361 Assembler::LSL, 12362 $src3$$constant & 0x3f); 12363 %} 12364 12365 ins_pipe(ialu_reg_reg_shift); 12366%} 12367 12368// This pattern is automatically generated from aarch64_ad.m4 12369// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12370instruct OrI_reg_RotateRight_reg(iRegINoSp dst, 12371 iRegIorL2I src1, iRegIorL2I src2, 12372 immI src3) %{ 12373 match(Set dst (OrI src1 (RotateRight src2 src3))); 12374 12375 ins_cost(1.9 * INSN_COST); 12376 format %{ "orrw $dst, $src1, $src2, ROR $src3" %} 12377 12378 ins_encode %{ 12379 __ orrw(as_Register($dst$$reg), 12380 as_Register($src1$$reg), 12381 as_Register($src2$$reg), 12382 Assembler::ROR, 12383 $src3$$constant & 0x1f); 12384 %} 12385 12386 ins_pipe(ialu_reg_reg_shift); 12387%} 12388 12389// This pattern is automatically generated from aarch64_ad.m4 12390// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12391instruct OrL_reg_RotateRight_reg(iRegLNoSp dst, 12392 iRegL src1, iRegL src2, 12393 immI src3) %{ 12394 match(Set dst (OrL src1 (RotateRight src2 src3))); 12395 12396 ins_cost(1.9 * INSN_COST); 12397 format %{ "orr $dst, $src1, $src2, ROR $src3" %} 12398 12399 ins_encode %{ 12400 __ orr(as_Register($dst$$reg), 12401 as_Register($src1$$reg), 12402 as_Register($src2$$reg), 12403 Assembler::ROR, 12404 $src3$$constant & 0x3f); 12405 %} 12406 12407 ins_pipe(ialu_reg_reg_shift); 12408%} 12409 12410// This pattern is automatically generated from aarch64_ad.m4 12411// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12412instruct AddI_reg_URShift_reg(iRegINoSp dst, 12413 iRegIorL2I src1, iRegIorL2I src2, 12414 immI src3) %{ 12415 match(Set dst (AddI src1 (URShiftI src2 src3))); 12416 12417 ins_cost(1.9 * INSN_COST); 12418 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 12419 12420 ins_encode %{ 12421 __ addw(as_Register($dst$$reg), 12422 as_Register($src1$$reg), 12423 as_Register($src2$$reg), 12424 Assembler::LSR, 12425 $src3$$constant & 0x1f); 12426 %} 12427 12428 ins_pipe(ialu_reg_reg_shift); 12429%} 12430 12431// This pattern is automatically generated from aarch64_ad.m4 12432// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12433instruct AddL_reg_URShift_reg(iRegLNoSp dst, 12434 iRegL src1, iRegL src2, 12435 immI src3) %{ 12436 match(Set dst (AddL src1 (URShiftL src2 src3))); 12437 12438 ins_cost(1.9 * INSN_COST); 12439 format %{ "add $dst, $src1, $src2, LSR $src3" %} 12440 12441 ins_encode %{ 12442 __ add(as_Register($dst$$reg), 12443 as_Register($src1$$reg), 12444 as_Register($src2$$reg), 12445 Assembler::LSR, 12446 $src3$$constant & 0x3f); 12447 %} 12448 12449 ins_pipe(ialu_reg_reg_shift); 12450%} 12451 12452// This pattern is automatically generated from aarch64_ad.m4 12453// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12454instruct AddI_reg_RShift_reg(iRegINoSp dst, 12455 iRegIorL2I src1, iRegIorL2I src2, 12456 immI src3) %{ 12457 match(Set dst (AddI src1 (RShiftI src2 src3))); 12458 12459 ins_cost(1.9 * INSN_COST); 12460 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 12461 12462 ins_encode %{ 12463 __ addw(as_Register($dst$$reg), 12464 as_Register($src1$$reg), 12465 as_Register($src2$$reg), 12466 Assembler::ASR, 12467 $src3$$constant & 0x1f); 12468 %} 12469 12470 ins_pipe(ialu_reg_reg_shift); 12471%} 12472 12473// This pattern is automatically generated from aarch64_ad.m4 12474// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12475instruct AddL_reg_RShift_reg(iRegLNoSp dst, 12476 iRegL src1, iRegL src2, 12477 immI src3) %{ 12478 match(Set dst (AddL src1 (RShiftL src2 src3))); 12479 12480 ins_cost(1.9 * INSN_COST); 12481 format %{ "add $dst, $src1, $src2, ASR $src3" %} 12482 12483 ins_encode %{ 12484 __ add(as_Register($dst$$reg), 12485 as_Register($src1$$reg), 12486 as_Register($src2$$reg), 12487 Assembler::ASR, 12488 $src3$$constant & 0x3f); 12489 %} 12490 12491 ins_pipe(ialu_reg_reg_shift); 12492%} 12493 12494// This pattern is automatically generated from aarch64_ad.m4 12495// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12496instruct AddI_reg_LShift_reg(iRegINoSp dst, 12497 iRegIorL2I src1, iRegIorL2I src2, 12498 immI src3) %{ 12499 match(Set dst (AddI src1 (LShiftI src2 src3))); 12500 12501 ins_cost(1.9 * INSN_COST); 12502 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 12503 12504 ins_encode %{ 12505 __ addw(as_Register($dst$$reg), 12506 as_Register($src1$$reg), 12507 as_Register($src2$$reg), 12508 Assembler::LSL, 12509 $src3$$constant & 0x1f); 12510 %} 12511 12512 ins_pipe(ialu_reg_reg_shift); 12513%} 12514 12515// This pattern is automatically generated from aarch64_ad.m4 12516// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12517instruct AddL_reg_LShift_reg(iRegLNoSp dst, 12518 iRegL src1, iRegL src2, 12519 immI src3) %{ 12520 match(Set dst (AddL src1 (LShiftL src2 src3))); 12521 12522 ins_cost(1.9 * INSN_COST); 12523 format %{ "add $dst, $src1, $src2, LSL $src3" %} 12524 12525 ins_encode %{ 12526 __ add(as_Register($dst$$reg), 12527 as_Register($src1$$reg), 12528 as_Register($src2$$reg), 12529 Assembler::LSL, 12530 $src3$$constant & 0x3f); 12531 %} 12532 12533 ins_pipe(ialu_reg_reg_shift); 12534%} 12535 12536// This pattern is automatically generated from aarch64_ad.m4 12537// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12538instruct SubI_reg_URShift_reg(iRegINoSp dst, 12539 iRegIorL2I src1, iRegIorL2I src2, 12540 immI src3) %{ 12541 match(Set dst (SubI src1 (URShiftI src2 src3))); 12542 12543 ins_cost(1.9 * INSN_COST); 12544 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 12545 12546 ins_encode %{ 12547 __ subw(as_Register($dst$$reg), 12548 as_Register($src1$$reg), 12549 as_Register($src2$$reg), 12550 Assembler::LSR, 12551 $src3$$constant & 0x1f); 12552 %} 12553 12554 ins_pipe(ialu_reg_reg_shift); 12555%} 12556 12557// This pattern is automatically generated from aarch64_ad.m4 12558// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12559instruct SubL_reg_URShift_reg(iRegLNoSp dst, 12560 iRegL src1, iRegL src2, 12561 immI src3) %{ 12562 match(Set dst (SubL src1 (URShiftL src2 src3))); 12563 12564 ins_cost(1.9 * INSN_COST); 12565 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 12566 12567 ins_encode %{ 12568 __ sub(as_Register($dst$$reg), 12569 as_Register($src1$$reg), 12570 as_Register($src2$$reg), 12571 Assembler::LSR, 12572 $src3$$constant & 0x3f); 12573 %} 12574 12575 ins_pipe(ialu_reg_reg_shift); 12576%} 12577 12578// This pattern is automatically generated from aarch64_ad.m4 12579// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12580instruct SubI_reg_RShift_reg(iRegINoSp dst, 12581 iRegIorL2I src1, iRegIorL2I src2, 12582 immI src3) %{ 12583 match(Set dst (SubI src1 (RShiftI src2 src3))); 12584 12585 ins_cost(1.9 * INSN_COST); 12586 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 12587 12588 ins_encode %{ 12589 __ subw(as_Register($dst$$reg), 12590 as_Register($src1$$reg), 12591 as_Register($src2$$reg), 12592 Assembler::ASR, 12593 $src3$$constant & 0x1f); 12594 %} 12595 12596 ins_pipe(ialu_reg_reg_shift); 12597%} 12598 12599// This pattern is automatically generated from aarch64_ad.m4 12600// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12601instruct SubL_reg_RShift_reg(iRegLNoSp dst, 12602 iRegL src1, iRegL src2, 12603 immI src3) %{ 12604 match(Set dst (SubL src1 (RShiftL src2 src3))); 12605 12606 ins_cost(1.9 * INSN_COST); 12607 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 12608 12609 ins_encode %{ 12610 __ sub(as_Register($dst$$reg), 12611 as_Register($src1$$reg), 12612 as_Register($src2$$reg), 12613 Assembler::ASR, 12614 $src3$$constant & 0x3f); 12615 %} 12616 12617 ins_pipe(ialu_reg_reg_shift); 12618%} 12619 12620// This pattern is automatically generated from aarch64_ad.m4 12621// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12622instruct SubI_reg_LShift_reg(iRegINoSp dst, 12623 iRegIorL2I src1, iRegIorL2I src2, 12624 immI src3) %{ 12625 match(Set dst (SubI src1 (LShiftI src2 src3))); 12626 12627 ins_cost(1.9 * INSN_COST); 12628 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 12629 12630 ins_encode %{ 12631 __ subw(as_Register($dst$$reg), 12632 as_Register($src1$$reg), 12633 as_Register($src2$$reg), 12634 Assembler::LSL, 12635 $src3$$constant & 0x1f); 12636 %} 12637 12638 ins_pipe(ialu_reg_reg_shift); 12639%} 12640 12641// This pattern is automatically generated from aarch64_ad.m4 12642// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12643instruct SubL_reg_LShift_reg(iRegLNoSp dst, 12644 iRegL src1, iRegL src2, 12645 immI src3) %{ 12646 match(Set dst (SubL src1 (LShiftL src2 src3))); 12647 12648 ins_cost(1.9 * INSN_COST); 12649 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 12650 12651 ins_encode %{ 12652 __ sub(as_Register($dst$$reg), 12653 as_Register($src1$$reg), 12654 as_Register($src2$$reg), 12655 Assembler::LSL, 12656 $src3$$constant & 0x3f); 12657 %} 12658 12659 ins_pipe(ialu_reg_reg_shift); 12660%} 12661 12662// This pattern is automatically generated from aarch64_ad.m4 12663// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12664 12665// Shift Left followed by Shift Right. 12666// This idiom is used by the compiler for the i2b bytecode etc. 12667instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12668%{ 12669 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12670 ins_cost(INSN_COST * 2); 12671 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12672 ins_encode %{ 12673 int lshift = $lshift_count$$constant & 63; 12674 int rshift = $rshift_count$$constant & 63; 12675 int s = 63 - lshift; 12676 int r = (rshift - lshift) & 63; 12677 __ sbfm(as_Register($dst$$reg), 12678 as_Register($src$$reg), 12679 r, s); 12680 %} 12681 12682 ins_pipe(ialu_reg_shift); 12683%} 12684 12685// This pattern is automatically generated from aarch64_ad.m4 12686// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12687 12688// Shift Left followed by Shift Right. 12689// This idiom is used by the compiler for the i2b bytecode etc. 12690instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12691%{ 12692 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12693 ins_cost(INSN_COST * 2); 12694 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12695 ins_encode %{ 12696 int lshift = $lshift_count$$constant & 31; 12697 int rshift = $rshift_count$$constant & 31; 12698 int s = 31 - lshift; 12699 int r = (rshift - lshift) & 31; 12700 __ sbfmw(as_Register($dst$$reg), 12701 as_Register($src$$reg), 12702 r, s); 12703 %} 12704 12705 ins_pipe(ialu_reg_shift); 12706%} 12707 12708// This pattern is automatically generated from aarch64_ad.m4 12709// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12710 12711// Shift Left followed by Shift Right. 12712// This idiom is used by the compiler for the i2b bytecode etc. 12713instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12714%{ 12715 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12716 ins_cost(INSN_COST * 2); 12717 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12718 ins_encode %{ 12719 int lshift = $lshift_count$$constant & 63; 12720 int rshift = $rshift_count$$constant & 63; 12721 int s = 63 - lshift; 12722 int r = (rshift - lshift) & 63; 12723 __ ubfm(as_Register($dst$$reg), 12724 as_Register($src$$reg), 12725 r, s); 12726 %} 12727 12728 ins_pipe(ialu_reg_shift); 12729%} 12730 12731// This pattern is automatically generated from aarch64_ad.m4 12732// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12733 12734// Shift Left followed by Shift Right. 12735// This idiom is used by the compiler for the i2b bytecode etc. 12736instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12737%{ 12738 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12739 ins_cost(INSN_COST * 2); 12740 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12741 ins_encode %{ 12742 int lshift = $lshift_count$$constant & 31; 12743 int rshift = $rshift_count$$constant & 31; 12744 int s = 31 - lshift; 12745 int r = (rshift - lshift) & 31; 12746 __ ubfmw(as_Register($dst$$reg), 12747 as_Register($src$$reg), 12748 r, s); 12749 %} 12750 12751 ins_pipe(ialu_reg_shift); 12752%} 12753 12754// Bitfield extract with shift & mask 12755 12756// This pattern is automatically generated from aarch64_ad.m4 12757// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12758instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12759%{ 12760 match(Set dst (AndI (URShiftI src rshift) mask)); 12761 // Make sure we are not going to exceed what ubfxw can do. 12762 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12763 12764 ins_cost(INSN_COST); 12765 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12766 ins_encode %{ 12767 int rshift = $rshift$$constant & 31; 12768 intptr_t mask = $mask$$constant; 12769 int width = exact_log2(mask+1); 12770 __ ubfxw(as_Register($dst$$reg), 12771 as_Register($src$$reg), rshift, width); 12772 %} 12773 ins_pipe(ialu_reg_shift); 12774%} 12775 12776// This pattern is automatically generated from aarch64_ad.m4 12777// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12778instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12779%{ 12780 match(Set dst (AndL (URShiftL src rshift) mask)); 12781 // Make sure we are not going to exceed what ubfx can do. 12782 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12783 12784 ins_cost(INSN_COST); 12785 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12786 ins_encode %{ 12787 int rshift = $rshift$$constant & 63; 12788 intptr_t mask = $mask$$constant; 12789 int width = exact_log2_long(mask+1); 12790 __ ubfx(as_Register($dst$$reg), 12791 as_Register($src$$reg), rshift, width); 12792 %} 12793 ins_pipe(ialu_reg_shift); 12794%} 12795 12796 12797// This pattern is automatically generated from aarch64_ad.m4 12798// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12799 12800// We can use ubfx when extending an And with a mask when we know mask 12801// is positive. We know that because immI_bitmask guarantees it. 12802instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12803%{ 12804 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12805 // Make sure we are not going to exceed what ubfxw can do. 12806 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12807 12808 ins_cost(INSN_COST * 2); 12809 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12810 ins_encode %{ 12811 int rshift = $rshift$$constant & 31; 12812 intptr_t mask = $mask$$constant; 12813 int width = exact_log2(mask+1); 12814 __ ubfx(as_Register($dst$$reg), 12815 as_Register($src$$reg), rshift, width); 12816 %} 12817 ins_pipe(ialu_reg_shift); 12818%} 12819 12820 12821// This pattern is automatically generated from aarch64_ad.m4 12822// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12823 12824// We can use ubfiz when masking by a positive number and then left shifting the result. 12825// We know that the mask is positive because immI_bitmask guarantees it. 12826instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12827%{ 12828 match(Set dst (LShiftI (AndI src mask) lshift)); 12829 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12830 12831 ins_cost(INSN_COST); 12832 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12833 ins_encode %{ 12834 int lshift = $lshift$$constant & 31; 12835 intptr_t mask = $mask$$constant; 12836 int width = exact_log2(mask+1); 12837 __ ubfizw(as_Register($dst$$reg), 12838 as_Register($src$$reg), lshift, width); 12839 %} 12840 ins_pipe(ialu_reg_shift); 12841%} 12842 12843// This pattern is automatically generated from aarch64_ad.m4 12844// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12845 12846// We can use ubfiz when masking by a positive number and then left shifting the result. 12847// We know that the mask is positive because immL_bitmask guarantees it. 12848instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12849%{ 12850 match(Set dst (LShiftL (AndL src mask) lshift)); 12851 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12852 12853 ins_cost(INSN_COST); 12854 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12855 ins_encode %{ 12856 int lshift = $lshift$$constant & 63; 12857 intptr_t mask = $mask$$constant; 12858 int width = exact_log2_long(mask+1); 12859 __ ubfiz(as_Register($dst$$reg), 12860 as_Register($src$$reg), lshift, width); 12861 %} 12862 ins_pipe(ialu_reg_shift); 12863%} 12864 12865// This pattern is automatically generated from aarch64_ad.m4 12866// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12867 12868// We can use ubfiz when masking by a positive number and then left shifting the result. 12869// We know that the mask is positive because immI_bitmask guarantees it. 12870instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12871%{ 12872 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12873 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12874 12875 ins_cost(INSN_COST); 12876 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12877 ins_encode %{ 12878 int lshift = $lshift$$constant & 31; 12879 intptr_t mask = $mask$$constant; 12880 int width = exact_log2(mask+1); 12881 __ ubfizw(as_Register($dst$$reg), 12882 as_Register($src$$reg), lshift, width); 12883 %} 12884 ins_pipe(ialu_reg_shift); 12885%} 12886 12887// This pattern is automatically generated from aarch64_ad.m4 12888// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12889 12890// We can use ubfiz when masking by a positive number and then left shifting the result. 12891// We know that the mask is positive because immL_bitmask guarantees it. 12892instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12893%{ 12894 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12895 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12896 12897 ins_cost(INSN_COST); 12898 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12899 ins_encode %{ 12900 int lshift = $lshift$$constant & 63; 12901 intptr_t mask = $mask$$constant; 12902 int width = exact_log2_long(mask+1); 12903 __ ubfiz(as_Register($dst$$reg), 12904 as_Register($src$$reg), lshift, width); 12905 %} 12906 ins_pipe(ialu_reg_shift); 12907%} 12908 12909 12910// This pattern is automatically generated from aarch64_ad.m4 12911// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12912 12913// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12914instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12915%{ 12916 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12917 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12918 12919 ins_cost(INSN_COST); 12920 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12921 ins_encode %{ 12922 int lshift = $lshift$$constant & 63; 12923 intptr_t mask = $mask$$constant; 12924 int width = exact_log2(mask+1); 12925 __ ubfiz(as_Register($dst$$reg), 12926 as_Register($src$$reg), lshift, width); 12927 %} 12928 ins_pipe(ialu_reg_shift); 12929%} 12930 12931// This pattern is automatically generated from aarch64_ad.m4 12932// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12933 12934// If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12935instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12936%{ 12937 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12938 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12939 12940 ins_cost(INSN_COST); 12941 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12942 ins_encode %{ 12943 int lshift = $lshift$$constant & 31; 12944 intptr_t mask = $mask$$constant; 12945 int width = exact_log2(mask+1); 12946 __ ubfiz(as_Register($dst$$reg), 12947 as_Register($src$$reg), lshift, width); 12948 %} 12949 ins_pipe(ialu_reg_shift); 12950%} 12951 12952// This pattern is automatically generated from aarch64_ad.m4 12953// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12954 12955// Can skip int2long conversions after AND with small bitmask 12956instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12957%{ 12958 match(Set dst (ConvI2L (AndI src msk))); 12959 ins_cost(INSN_COST); 12960 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12961 ins_encode %{ 12962 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12963 %} 12964 ins_pipe(ialu_reg_shift); 12965%} 12966 12967 12968// Rotations 12969// This pattern is automatically generated from aarch64_ad.m4 12970// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12971instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12972%{ 12973 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12974 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12975 12976 ins_cost(INSN_COST); 12977 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12978 12979 ins_encode %{ 12980 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12981 $rshift$$constant & 63); 12982 %} 12983 ins_pipe(ialu_reg_reg_extr); 12984%} 12985 12986 12987// This pattern is automatically generated from aarch64_ad.m4 12988// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12989instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12990%{ 12991 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12992 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12993 12994 ins_cost(INSN_COST); 12995 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12996 12997 ins_encode %{ 12998 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12999 $rshift$$constant & 31); 13000 %} 13001 ins_pipe(ialu_reg_reg_extr); 13002%} 13003 13004 13005// This pattern is automatically generated from aarch64_ad.m4 13006// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13007instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 13008%{ 13009 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 13010 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 13011 13012 ins_cost(INSN_COST); 13013 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13014 13015 ins_encode %{ 13016 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13017 $rshift$$constant & 63); 13018 %} 13019 ins_pipe(ialu_reg_reg_extr); 13020%} 13021 13022 13023// This pattern is automatically generated from aarch64_ad.m4 13024// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13025instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 13026%{ 13027 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 13028 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 13029 13030 ins_cost(INSN_COST); 13031 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13032 13033 ins_encode %{ 13034 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13035 $rshift$$constant & 31); 13036 %} 13037 ins_pipe(ialu_reg_reg_extr); 13038%} 13039 13040 13041// This pattern is automatically generated from aarch64_ad.m4 13042// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13043instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift) 13044%{ 13045 match(Set dst (RotateRight src shift)); 13046 13047 ins_cost(INSN_COST); 13048 format %{ "ror $dst, $src, $shift" %} 13049 13050 ins_encode %{ 13051 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13052 $shift$$constant & 0x1f); 13053 %} 13054 ins_pipe(ialu_reg_reg_vshift); 13055%} 13056 13057// This pattern is automatically generated from aarch64_ad.m4 13058// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13059instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift) 13060%{ 13061 match(Set dst (RotateRight src shift)); 13062 13063 ins_cost(INSN_COST); 13064 format %{ "ror $dst, $src, $shift" %} 13065 13066 ins_encode %{ 13067 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13068 $shift$$constant & 0x3f); 13069 %} 13070 ins_pipe(ialu_reg_reg_vshift); 13071%} 13072 13073// This pattern is automatically generated from aarch64_ad.m4 13074// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13075instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13076%{ 13077 match(Set dst (RotateRight src shift)); 13078 13079 ins_cost(INSN_COST); 13080 format %{ "ror $dst, $src, $shift" %} 13081 13082 ins_encode %{ 13083 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13084 %} 13085 ins_pipe(ialu_reg_reg_vshift); 13086%} 13087 13088// This pattern is automatically generated from aarch64_ad.m4 13089// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13090instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13091%{ 13092 match(Set dst (RotateRight src shift)); 13093 13094 ins_cost(INSN_COST); 13095 format %{ "ror $dst, $src, $shift" %} 13096 13097 ins_encode %{ 13098 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13099 %} 13100 ins_pipe(ialu_reg_reg_vshift); 13101%} 13102 13103// This pattern is automatically generated from aarch64_ad.m4 13104// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13105instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13106%{ 13107 match(Set dst (RotateLeft src shift)); 13108 13109 ins_cost(INSN_COST); 13110 format %{ "rol $dst, $src, $shift" %} 13111 13112 ins_encode %{ 13113 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13114 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13115 %} 13116 ins_pipe(ialu_reg_reg_vshift); 13117%} 13118 13119// This pattern is automatically generated from aarch64_ad.m4 13120// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13121instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13122%{ 13123 match(Set dst (RotateLeft src shift)); 13124 13125 ins_cost(INSN_COST); 13126 format %{ "rol $dst, $src, $shift" %} 13127 13128 ins_encode %{ 13129 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13130 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13131 %} 13132 ins_pipe(ialu_reg_reg_vshift); 13133%} 13134 13135 13136// Add/subtract (extended) 13137 13138// This pattern is automatically generated from aarch64_ad.m4 13139// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13140instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13141%{ 13142 match(Set dst (AddL src1 (ConvI2L src2))); 13143 ins_cost(INSN_COST); 13144 format %{ "add $dst, $src1, $src2, sxtw" %} 13145 13146 ins_encode %{ 13147 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13148 as_Register($src2$$reg), ext::sxtw); 13149 %} 13150 ins_pipe(ialu_reg_reg); 13151%} 13152 13153// This pattern is automatically generated from aarch64_ad.m4 13154// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13155instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13156%{ 13157 match(Set dst (SubL src1 (ConvI2L src2))); 13158 ins_cost(INSN_COST); 13159 format %{ "sub $dst, $src1, $src2, sxtw" %} 13160 13161 ins_encode %{ 13162 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13163 as_Register($src2$$reg), ext::sxtw); 13164 %} 13165 ins_pipe(ialu_reg_reg); 13166%} 13167 13168// This pattern is automatically generated from aarch64_ad.m4 13169// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13170instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 13171%{ 13172 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13173 ins_cost(INSN_COST); 13174 format %{ "add $dst, $src1, $src2, sxth" %} 13175 13176 ins_encode %{ 13177 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13178 as_Register($src2$$reg), ext::sxth); 13179 %} 13180 ins_pipe(ialu_reg_reg); 13181%} 13182 13183// This pattern is automatically generated from aarch64_ad.m4 13184// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13185instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13186%{ 13187 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13188 ins_cost(INSN_COST); 13189 format %{ "add $dst, $src1, $src2, sxtb" %} 13190 13191 ins_encode %{ 13192 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13193 as_Register($src2$$reg), ext::sxtb); 13194 %} 13195 ins_pipe(ialu_reg_reg); 13196%} 13197 13198// This pattern is automatically generated from aarch64_ad.m4 13199// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13200instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13201%{ 13202 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 13203 ins_cost(INSN_COST); 13204 format %{ "add $dst, $src1, $src2, uxtb" %} 13205 13206 ins_encode %{ 13207 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13208 as_Register($src2$$reg), ext::uxtb); 13209 %} 13210 ins_pipe(ialu_reg_reg); 13211%} 13212 13213// This pattern is automatically generated from aarch64_ad.m4 13214// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13215instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 13216%{ 13217 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13218 ins_cost(INSN_COST); 13219 format %{ "add $dst, $src1, $src2, sxth" %} 13220 13221 ins_encode %{ 13222 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13223 as_Register($src2$$reg), ext::sxth); 13224 %} 13225 ins_pipe(ialu_reg_reg); 13226%} 13227 13228// This pattern is automatically generated from aarch64_ad.m4 13229// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13230instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 13231%{ 13232 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13233 ins_cost(INSN_COST); 13234 format %{ "add $dst, $src1, $src2, sxtw" %} 13235 13236 ins_encode %{ 13237 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13238 as_Register($src2$$reg), ext::sxtw); 13239 %} 13240 ins_pipe(ialu_reg_reg); 13241%} 13242 13243// This pattern is automatically generated from aarch64_ad.m4 13244// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13245instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13246%{ 13247 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13248 ins_cost(INSN_COST); 13249 format %{ "add $dst, $src1, $src2, sxtb" %} 13250 13251 ins_encode %{ 13252 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13253 as_Register($src2$$reg), ext::sxtb); 13254 %} 13255 ins_pipe(ialu_reg_reg); 13256%} 13257 13258// This pattern is automatically generated from aarch64_ad.m4 13259// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13260instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13261%{ 13262 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 13263 ins_cost(INSN_COST); 13264 format %{ "add $dst, $src1, $src2, uxtb" %} 13265 13266 ins_encode %{ 13267 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13268 as_Register($src2$$reg), ext::uxtb); 13269 %} 13270 ins_pipe(ialu_reg_reg); 13271%} 13272 13273// This pattern is automatically generated from aarch64_ad.m4 13274// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13275instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13276%{ 13277 match(Set dst (AddI src1 (AndI src2 mask))); 13278 ins_cost(INSN_COST); 13279 format %{ "addw $dst, $src1, $src2, uxtb" %} 13280 13281 ins_encode %{ 13282 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13283 as_Register($src2$$reg), ext::uxtb); 13284 %} 13285 ins_pipe(ialu_reg_reg); 13286%} 13287 13288// This pattern is automatically generated from aarch64_ad.m4 13289// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13290instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13291%{ 13292 match(Set dst (AddI src1 (AndI src2 mask))); 13293 ins_cost(INSN_COST); 13294 format %{ "addw $dst, $src1, $src2, uxth" %} 13295 13296 ins_encode %{ 13297 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13298 as_Register($src2$$reg), ext::uxth); 13299 %} 13300 ins_pipe(ialu_reg_reg); 13301%} 13302 13303// This pattern is automatically generated from aarch64_ad.m4 13304// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13305instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13306%{ 13307 match(Set dst (AddL src1 (AndL src2 mask))); 13308 ins_cost(INSN_COST); 13309 format %{ "add $dst, $src1, $src2, uxtb" %} 13310 13311 ins_encode %{ 13312 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13313 as_Register($src2$$reg), ext::uxtb); 13314 %} 13315 ins_pipe(ialu_reg_reg); 13316%} 13317 13318// This pattern is automatically generated from aarch64_ad.m4 13319// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13320instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13321%{ 13322 match(Set dst (AddL src1 (AndL src2 mask))); 13323 ins_cost(INSN_COST); 13324 format %{ "add $dst, $src1, $src2, uxth" %} 13325 13326 ins_encode %{ 13327 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13328 as_Register($src2$$reg), ext::uxth); 13329 %} 13330 ins_pipe(ialu_reg_reg); 13331%} 13332 13333// This pattern is automatically generated from aarch64_ad.m4 13334// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13335instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13336%{ 13337 match(Set dst (AddL src1 (AndL src2 mask))); 13338 ins_cost(INSN_COST); 13339 format %{ "add $dst, $src1, $src2, uxtw" %} 13340 13341 ins_encode %{ 13342 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13343 as_Register($src2$$reg), ext::uxtw); 13344 %} 13345 ins_pipe(ialu_reg_reg); 13346%} 13347 13348// This pattern is automatically generated from aarch64_ad.m4 13349// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13350instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13351%{ 13352 match(Set dst (SubI src1 (AndI src2 mask))); 13353 ins_cost(INSN_COST); 13354 format %{ "subw $dst, $src1, $src2, uxtb" %} 13355 13356 ins_encode %{ 13357 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13358 as_Register($src2$$reg), ext::uxtb); 13359 %} 13360 ins_pipe(ialu_reg_reg); 13361%} 13362 13363// This pattern is automatically generated from aarch64_ad.m4 13364// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13365instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13366%{ 13367 match(Set dst (SubI src1 (AndI src2 mask))); 13368 ins_cost(INSN_COST); 13369 format %{ "subw $dst, $src1, $src2, uxth" %} 13370 13371 ins_encode %{ 13372 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13373 as_Register($src2$$reg), ext::uxth); 13374 %} 13375 ins_pipe(ialu_reg_reg); 13376%} 13377 13378// This pattern is automatically generated from aarch64_ad.m4 13379// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13380instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13381%{ 13382 match(Set dst (SubL src1 (AndL src2 mask))); 13383 ins_cost(INSN_COST); 13384 format %{ "sub $dst, $src1, $src2, uxtb" %} 13385 13386 ins_encode %{ 13387 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13388 as_Register($src2$$reg), ext::uxtb); 13389 %} 13390 ins_pipe(ialu_reg_reg); 13391%} 13392 13393// This pattern is automatically generated from aarch64_ad.m4 13394// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13395instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13396%{ 13397 match(Set dst (SubL src1 (AndL src2 mask))); 13398 ins_cost(INSN_COST); 13399 format %{ "sub $dst, $src1, $src2, uxth" %} 13400 13401 ins_encode %{ 13402 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13403 as_Register($src2$$reg), ext::uxth); 13404 %} 13405 ins_pipe(ialu_reg_reg); 13406%} 13407 13408// This pattern is automatically generated from aarch64_ad.m4 13409// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13410instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13411%{ 13412 match(Set dst (SubL src1 (AndL src2 mask))); 13413 ins_cost(INSN_COST); 13414 format %{ "sub $dst, $src1, $src2, uxtw" %} 13415 13416 ins_encode %{ 13417 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13418 as_Register($src2$$reg), ext::uxtw); 13419 %} 13420 ins_pipe(ialu_reg_reg); 13421%} 13422 13423 13424// This pattern is automatically generated from aarch64_ad.m4 13425// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13426instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13427%{ 13428 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13429 ins_cost(1.9 * INSN_COST); 13430 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 13431 13432 ins_encode %{ 13433 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13434 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13435 %} 13436 ins_pipe(ialu_reg_reg_shift); 13437%} 13438 13439// This pattern is automatically generated from aarch64_ad.m4 13440// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13441instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13442%{ 13443 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13444 ins_cost(1.9 * INSN_COST); 13445 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 13446 13447 ins_encode %{ 13448 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13449 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13450 %} 13451 ins_pipe(ialu_reg_reg_shift); 13452%} 13453 13454// This pattern is automatically generated from aarch64_ad.m4 13455// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13456instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13457%{ 13458 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13459 ins_cost(1.9 * INSN_COST); 13460 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 13461 13462 ins_encode %{ 13463 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13464 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13465 %} 13466 ins_pipe(ialu_reg_reg_shift); 13467%} 13468 13469// This pattern is automatically generated from aarch64_ad.m4 13470// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13471instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13472%{ 13473 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13474 ins_cost(1.9 * INSN_COST); 13475 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 13476 13477 ins_encode %{ 13478 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13479 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13480 %} 13481 ins_pipe(ialu_reg_reg_shift); 13482%} 13483 13484// This pattern is automatically generated from aarch64_ad.m4 13485// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13486instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13487%{ 13488 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13489 ins_cost(1.9 * INSN_COST); 13490 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 13491 13492 ins_encode %{ 13493 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13494 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13495 %} 13496 ins_pipe(ialu_reg_reg_shift); 13497%} 13498 13499// This pattern is automatically generated from aarch64_ad.m4 13500// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13501instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13502%{ 13503 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13504 ins_cost(1.9 * INSN_COST); 13505 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 13506 13507 ins_encode %{ 13508 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13509 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13510 %} 13511 ins_pipe(ialu_reg_reg_shift); 13512%} 13513 13514// This pattern is automatically generated from aarch64_ad.m4 13515// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13516instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13517%{ 13518 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13519 ins_cost(1.9 * INSN_COST); 13520 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 13521 13522 ins_encode %{ 13523 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13524 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13525 %} 13526 ins_pipe(ialu_reg_reg_shift); 13527%} 13528 13529// This pattern is automatically generated from aarch64_ad.m4 13530// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13531instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13532%{ 13533 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13534 ins_cost(1.9 * INSN_COST); 13535 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 13536 13537 ins_encode %{ 13538 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13539 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13540 %} 13541 ins_pipe(ialu_reg_reg_shift); 13542%} 13543 13544// This pattern is automatically generated from aarch64_ad.m4 13545// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13546instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13547%{ 13548 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13549 ins_cost(1.9 * INSN_COST); 13550 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 13551 13552 ins_encode %{ 13553 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13554 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13555 %} 13556 ins_pipe(ialu_reg_reg_shift); 13557%} 13558 13559// This pattern is automatically generated from aarch64_ad.m4 13560// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13561instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13562%{ 13563 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13564 ins_cost(1.9 * INSN_COST); 13565 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 13566 13567 ins_encode %{ 13568 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13569 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13570 %} 13571 ins_pipe(ialu_reg_reg_shift); 13572%} 13573 13574// This pattern is automatically generated from aarch64_ad.m4 13575// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13576instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13577%{ 13578 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 13579 ins_cost(1.9 * INSN_COST); 13580 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 13581 13582 ins_encode %{ 13583 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13584 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13585 %} 13586 ins_pipe(ialu_reg_reg_shift); 13587%} 13588 13589// This pattern is automatically generated from aarch64_ad.m4 13590// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13591instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13592%{ 13593 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 13594 ins_cost(1.9 * INSN_COST); 13595 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 13596 13597 ins_encode %{ 13598 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13599 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13600 %} 13601 ins_pipe(ialu_reg_reg_shift); 13602%} 13603 13604// This pattern is automatically generated from aarch64_ad.m4 13605// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13606instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13607%{ 13608 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13609 ins_cost(1.9 * INSN_COST); 13610 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 13611 13612 ins_encode %{ 13613 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13614 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13615 %} 13616 ins_pipe(ialu_reg_reg_shift); 13617%} 13618 13619// This pattern is automatically generated from aarch64_ad.m4 13620// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13621instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13622%{ 13623 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13624 ins_cost(1.9 * INSN_COST); 13625 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 13626 13627 ins_encode %{ 13628 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13629 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13630 %} 13631 ins_pipe(ialu_reg_reg_shift); 13632%} 13633 13634// This pattern is automatically generated from aarch64_ad.m4 13635// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13636instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13637%{ 13638 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13639 ins_cost(1.9 * INSN_COST); 13640 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13641 13642 ins_encode %{ 13643 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13644 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13645 %} 13646 ins_pipe(ialu_reg_reg_shift); 13647%} 13648 13649// This pattern is automatically generated from aarch64_ad.m4 13650// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13651instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13652%{ 13653 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13654 ins_cost(1.9 * INSN_COST); 13655 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13656 13657 ins_encode %{ 13658 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13659 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13660 %} 13661 ins_pipe(ialu_reg_reg_shift); 13662%} 13663 13664// This pattern is automatically generated from aarch64_ad.m4 13665// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13666instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13667%{ 13668 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13669 ins_cost(1.9 * INSN_COST); 13670 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13671 13672 ins_encode %{ 13673 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13674 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13675 %} 13676 ins_pipe(ialu_reg_reg_shift); 13677%} 13678 13679// This pattern is automatically generated from aarch64_ad.m4 13680// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13681instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13682%{ 13683 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13684 ins_cost(1.9 * INSN_COST); 13685 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13686 13687 ins_encode %{ 13688 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13689 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13690 %} 13691 ins_pipe(ialu_reg_reg_shift); 13692%} 13693 13694// This pattern is automatically generated from aarch64_ad.m4 13695// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13696instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13697%{ 13698 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13699 ins_cost(1.9 * INSN_COST); 13700 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13701 13702 ins_encode %{ 13703 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13704 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13705 %} 13706 ins_pipe(ialu_reg_reg_shift); 13707%} 13708 13709// This pattern is automatically generated from aarch64_ad.m4 13710// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13711instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13712%{ 13713 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13714 ins_cost(1.9 * INSN_COST); 13715 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13716 13717 ins_encode %{ 13718 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13719 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13720 %} 13721 ins_pipe(ialu_reg_reg_shift); 13722%} 13723 13724// This pattern is automatically generated from aarch64_ad.m4 13725// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13726instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13727%{ 13728 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13729 ins_cost(1.9 * INSN_COST); 13730 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13731 13732 ins_encode %{ 13733 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13734 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13735 %} 13736 ins_pipe(ialu_reg_reg_shift); 13737%} 13738 13739// This pattern is automatically generated from aarch64_ad.m4 13740// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13741instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13742%{ 13743 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13744 ins_cost(1.9 * INSN_COST); 13745 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13746 13747 ins_encode %{ 13748 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13749 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13750 %} 13751 ins_pipe(ialu_reg_reg_shift); 13752%} 13753 13754 13755 13756// END This section of the file is automatically generated. Do not edit -------------- 13757 13758 13759// ============================================================================ 13760// Floating Point Arithmetic Instructions 13761 13762instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13763 match(Set dst (AddF src1 src2)); 13764 13765 ins_cost(INSN_COST * 5); 13766 format %{ "fadds $dst, $src1, $src2" %} 13767 13768 ins_encode %{ 13769 __ fadds(as_FloatRegister($dst$$reg), 13770 as_FloatRegister($src1$$reg), 13771 as_FloatRegister($src2$$reg)); 13772 %} 13773 13774 ins_pipe(fp_dop_reg_reg_s); 13775%} 13776 13777instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13778 match(Set dst (AddD src1 src2)); 13779 13780 ins_cost(INSN_COST * 5); 13781 format %{ "faddd $dst, $src1, $src2" %} 13782 13783 ins_encode %{ 13784 __ faddd(as_FloatRegister($dst$$reg), 13785 as_FloatRegister($src1$$reg), 13786 as_FloatRegister($src2$$reg)); 13787 %} 13788 13789 ins_pipe(fp_dop_reg_reg_d); 13790%} 13791 13792instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13793 match(Set dst (SubF src1 src2)); 13794 13795 ins_cost(INSN_COST * 5); 13796 format %{ "fsubs $dst, $src1, $src2" %} 13797 13798 ins_encode %{ 13799 __ fsubs(as_FloatRegister($dst$$reg), 13800 as_FloatRegister($src1$$reg), 13801 as_FloatRegister($src2$$reg)); 13802 %} 13803 13804 ins_pipe(fp_dop_reg_reg_s); 13805%} 13806 13807instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13808 match(Set dst (SubD src1 src2)); 13809 13810 ins_cost(INSN_COST * 5); 13811 format %{ "fsubd $dst, $src1, $src2" %} 13812 13813 ins_encode %{ 13814 __ fsubd(as_FloatRegister($dst$$reg), 13815 as_FloatRegister($src1$$reg), 13816 as_FloatRegister($src2$$reg)); 13817 %} 13818 13819 ins_pipe(fp_dop_reg_reg_d); 13820%} 13821 13822instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13823 match(Set dst (MulF src1 src2)); 13824 13825 ins_cost(INSN_COST * 6); 13826 format %{ "fmuls $dst, $src1, $src2" %} 13827 13828 ins_encode %{ 13829 __ fmuls(as_FloatRegister($dst$$reg), 13830 as_FloatRegister($src1$$reg), 13831 as_FloatRegister($src2$$reg)); 13832 %} 13833 13834 ins_pipe(fp_dop_reg_reg_s); 13835%} 13836 13837instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 13838 match(Set dst (MulD src1 src2)); 13839 13840 ins_cost(INSN_COST * 6); 13841 format %{ "fmuld $dst, $src1, $src2" %} 13842 13843 ins_encode %{ 13844 __ fmuld(as_FloatRegister($dst$$reg), 13845 as_FloatRegister($src1$$reg), 13846 as_FloatRegister($src2$$reg)); 13847 %} 13848 13849 ins_pipe(fp_dop_reg_reg_d); 13850%} 13851 13852// src1 * src2 + src3 13853instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13854 predicate(UseFMA); 13855 match(Set dst (FmaF src3 (Binary src1 src2))); 13856 13857 format %{ "fmadds $dst, $src1, $src2, $src3" %} 13858 13859 ins_encode %{ 13860 __ fmadds(as_FloatRegister($dst$$reg), 13861 as_FloatRegister($src1$$reg), 13862 as_FloatRegister($src2$$reg), 13863 as_FloatRegister($src3$$reg)); 13864 %} 13865 13866 ins_pipe(pipe_class_default); 13867%} 13868 13869// src1 * src2 + src3 13870instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13871 predicate(UseFMA); 13872 match(Set dst (FmaD src3 (Binary src1 src2))); 13873 13874 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 13875 13876 ins_encode %{ 13877 __ fmaddd(as_FloatRegister($dst$$reg), 13878 as_FloatRegister($src1$$reg), 13879 as_FloatRegister($src2$$reg), 13880 as_FloatRegister($src3$$reg)); 13881 %} 13882 13883 ins_pipe(pipe_class_default); 13884%} 13885 13886// -src1 * src2 + src3 13887instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13888 predicate(UseFMA); 13889 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 13890 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 13891 13892 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 13893 13894 ins_encode %{ 13895 __ fmsubs(as_FloatRegister($dst$$reg), 13896 as_FloatRegister($src1$$reg), 13897 as_FloatRegister($src2$$reg), 13898 as_FloatRegister($src3$$reg)); 13899 %} 13900 13901 ins_pipe(pipe_class_default); 13902%} 13903 13904// -src1 * src2 + src3 13905instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13906 predicate(UseFMA); 13907 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 13908 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 13909 13910 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 13911 13912 ins_encode %{ 13913 __ fmsubd(as_FloatRegister($dst$$reg), 13914 as_FloatRegister($src1$$reg), 13915 as_FloatRegister($src2$$reg), 13916 as_FloatRegister($src3$$reg)); 13917 %} 13918 13919 ins_pipe(pipe_class_default); 13920%} 13921 13922// -src1 * src2 - src3 13923instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 13924 predicate(UseFMA); 13925 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 13926 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 13927 13928 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 13929 13930 ins_encode %{ 13931 __ fnmadds(as_FloatRegister($dst$$reg), 13932 as_FloatRegister($src1$$reg), 13933 as_FloatRegister($src2$$reg), 13934 as_FloatRegister($src3$$reg)); 13935 %} 13936 13937 ins_pipe(pipe_class_default); 13938%} 13939 13940// -src1 * src2 - src3 13941instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 13942 predicate(UseFMA); 13943 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 13944 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 13945 13946 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 13947 13948 ins_encode %{ 13949 __ fnmaddd(as_FloatRegister($dst$$reg), 13950 as_FloatRegister($src1$$reg), 13951 as_FloatRegister($src2$$reg), 13952 as_FloatRegister($src3$$reg)); 13953 %} 13954 13955 ins_pipe(pipe_class_default); 13956%} 13957 13958// src1 * src2 - src3 13959instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 13960 predicate(UseFMA); 13961 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 13962 13963 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 13964 13965 ins_encode %{ 13966 __ fnmsubs(as_FloatRegister($dst$$reg), 13967 as_FloatRegister($src1$$reg), 13968 as_FloatRegister($src2$$reg), 13969 as_FloatRegister($src3$$reg)); 13970 %} 13971 13972 ins_pipe(pipe_class_default); 13973%} 13974 13975// src1 * src2 - src3 13976instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 13977 predicate(UseFMA); 13978 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 13979 13980 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 13981 13982 ins_encode %{ 13983 // n.b. insn name should be fnmsubd 13984 __ fnmsub(as_FloatRegister($dst$$reg), 13985 as_FloatRegister($src1$$reg), 13986 as_FloatRegister($src2$$reg), 13987 as_FloatRegister($src3$$reg)); 13988 %} 13989 13990 ins_pipe(pipe_class_default); 13991%} 13992 13993 13994// Math.max(FF)F 13995instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 13996 match(Set dst (MaxF src1 src2)); 13997 13998 format %{ "fmaxs $dst, $src1, $src2" %} 13999 ins_encode %{ 14000 __ fmaxs(as_FloatRegister($dst$$reg), 14001 as_FloatRegister($src1$$reg), 14002 as_FloatRegister($src2$$reg)); 14003 %} 14004 14005 ins_pipe(fp_dop_reg_reg_s); 14006%} 14007 14008// Math.min(FF)F 14009instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14010 match(Set dst (MinF src1 src2)); 14011 14012 format %{ "fmins $dst, $src1, $src2" %} 14013 ins_encode %{ 14014 __ fmins(as_FloatRegister($dst$$reg), 14015 as_FloatRegister($src1$$reg), 14016 as_FloatRegister($src2$$reg)); 14017 %} 14018 14019 ins_pipe(fp_dop_reg_reg_s); 14020%} 14021 14022// Math.max(DD)D 14023instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14024 match(Set dst (MaxD src1 src2)); 14025 14026 format %{ "fmaxd $dst, $src1, $src2" %} 14027 ins_encode %{ 14028 __ fmaxd(as_FloatRegister($dst$$reg), 14029 as_FloatRegister($src1$$reg), 14030 as_FloatRegister($src2$$reg)); 14031 %} 14032 14033 ins_pipe(fp_dop_reg_reg_d); 14034%} 14035 14036// Math.min(DD)D 14037instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14038 match(Set dst (MinD src1 src2)); 14039 14040 format %{ "fmind $dst, $src1, $src2" %} 14041 ins_encode %{ 14042 __ fmind(as_FloatRegister($dst$$reg), 14043 as_FloatRegister($src1$$reg), 14044 as_FloatRegister($src2$$reg)); 14045 %} 14046 14047 ins_pipe(fp_dop_reg_reg_d); 14048%} 14049 14050 14051instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14052 match(Set dst (DivF src1 src2)); 14053 14054 ins_cost(INSN_COST * 18); 14055 format %{ "fdivs $dst, $src1, $src2" %} 14056 14057 ins_encode %{ 14058 __ fdivs(as_FloatRegister($dst$$reg), 14059 as_FloatRegister($src1$$reg), 14060 as_FloatRegister($src2$$reg)); 14061 %} 14062 14063 ins_pipe(fp_div_s); 14064%} 14065 14066instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14067 match(Set dst (DivD src1 src2)); 14068 14069 ins_cost(INSN_COST * 32); 14070 format %{ "fdivd $dst, $src1, $src2" %} 14071 14072 ins_encode %{ 14073 __ fdivd(as_FloatRegister($dst$$reg), 14074 as_FloatRegister($src1$$reg), 14075 as_FloatRegister($src2$$reg)); 14076 %} 14077 14078 ins_pipe(fp_div_d); 14079%} 14080 14081instruct negF_reg_reg(vRegF dst, vRegF src) %{ 14082 match(Set dst (NegF src)); 14083 14084 ins_cost(INSN_COST * 3); 14085 format %{ "fneg $dst, $src" %} 14086 14087 ins_encode %{ 14088 __ fnegs(as_FloatRegister($dst$$reg), 14089 as_FloatRegister($src$$reg)); 14090 %} 14091 14092 ins_pipe(fp_uop_s); 14093%} 14094 14095instruct negD_reg_reg(vRegD dst, vRegD src) %{ 14096 match(Set dst (NegD src)); 14097 14098 ins_cost(INSN_COST * 3); 14099 format %{ "fnegd $dst, $src" %} 14100 14101 ins_encode %{ 14102 __ fnegd(as_FloatRegister($dst$$reg), 14103 as_FloatRegister($src$$reg)); 14104 %} 14105 14106 ins_pipe(fp_uop_d); 14107%} 14108 14109instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 14110%{ 14111 match(Set dst (AbsI src)); 14112 14113 effect(KILL cr); 14114 ins_cost(INSN_COST * 2); 14115 format %{ "cmpw $src, zr\n\t" 14116 "cnegw $dst, $src, Assembler::LT\t# int abs" 14117 %} 14118 14119 ins_encode %{ 14120 __ cmpw(as_Register($src$$reg), zr); 14121 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14122 %} 14123 ins_pipe(pipe_class_default); 14124%} 14125 14126instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 14127%{ 14128 match(Set dst (AbsL src)); 14129 14130 effect(KILL cr); 14131 ins_cost(INSN_COST * 2); 14132 format %{ "cmp $src, zr\n\t" 14133 "cneg $dst, $src, Assembler::LT\t# long abs" 14134 %} 14135 14136 ins_encode %{ 14137 __ cmp(as_Register($src$$reg), zr); 14138 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14139 %} 14140 ins_pipe(pipe_class_default); 14141%} 14142 14143instruct absF_reg(vRegF dst, vRegF src) %{ 14144 match(Set dst (AbsF src)); 14145 14146 ins_cost(INSN_COST * 3); 14147 format %{ "fabss $dst, $src" %} 14148 ins_encode %{ 14149 __ fabss(as_FloatRegister($dst$$reg), 14150 as_FloatRegister($src$$reg)); 14151 %} 14152 14153 ins_pipe(fp_uop_s); 14154%} 14155 14156instruct absD_reg(vRegD dst, vRegD src) %{ 14157 match(Set dst (AbsD src)); 14158 14159 ins_cost(INSN_COST * 3); 14160 format %{ "fabsd $dst, $src" %} 14161 ins_encode %{ 14162 __ fabsd(as_FloatRegister($dst$$reg), 14163 as_FloatRegister($src$$reg)); 14164 %} 14165 14166 ins_pipe(fp_uop_d); 14167%} 14168 14169instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14170 match(Set dst (AbsF (SubF src1 src2))); 14171 14172 ins_cost(INSN_COST * 3); 14173 format %{ "fabds $dst, $src1, $src2" %} 14174 ins_encode %{ 14175 __ fabds(as_FloatRegister($dst$$reg), 14176 as_FloatRegister($src1$$reg), 14177 as_FloatRegister($src2$$reg)); 14178 %} 14179 14180 ins_pipe(fp_uop_s); 14181%} 14182 14183instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14184 match(Set dst (AbsD (SubD src1 src2))); 14185 14186 ins_cost(INSN_COST * 3); 14187 format %{ "fabdd $dst, $src1, $src2" %} 14188 ins_encode %{ 14189 __ fabdd(as_FloatRegister($dst$$reg), 14190 as_FloatRegister($src1$$reg), 14191 as_FloatRegister($src2$$reg)); 14192 %} 14193 14194 ins_pipe(fp_uop_d); 14195%} 14196 14197instruct sqrtD_reg(vRegD dst, vRegD src) %{ 14198 match(Set dst (SqrtD src)); 14199 14200 ins_cost(INSN_COST * 50); 14201 format %{ "fsqrtd $dst, $src" %} 14202 ins_encode %{ 14203 __ fsqrtd(as_FloatRegister($dst$$reg), 14204 as_FloatRegister($src$$reg)); 14205 %} 14206 14207 ins_pipe(fp_div_s); 14208%} 14209 14210instruct sqrtF_reg(vRegF dst, vRegF src) %{ 14211 match(Set dst (SqrtF src)); 14212 14213 ins_cost(INSN_COST * 50); 14214 format %{ "fsqrts $dst, $src" %} 14215 ins_encode %{ 14216 __ fsqrts(as_FloatRegister($dst$$reg), 14217 as_FloatRegister($src$$reg)); 14218 %} 14219 14220 ins_pipe(fp_div_d); 14221%} 14222 14223// Math.rint, floor, ceil 14224instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 14225 match(Set dst (RoundDoubleMode src rmode)); 14226 format %{ "frint $dst, $src, $rmode" %} 14227 ins_encode %{ 14228 switch ($rmode$$constant) { 14229 case RoundDoubleModeNode::rmode_rint: 14230 __ frintnd(as_FloatRegister($dst$$reg), 14231 as_FloatRegister($src$$reg)); 14232 break; 14233 case RoundDoubleModeNode::rmode_floor: 14234 __ frintmd(as_FloatRegister($dst$$reg), 14235 as_FloatRegister($src$$reg)); 14236 break; 14237 case RoundDoubleModeNode::rmode_ceil: 14238 __ frintpd(as_FloatRegister($dst$$reg), 14239 as_FloatRegister($src$$reg)); 14240 break; 14241 } 14242 %} 14243 ins_pipe(fp_uop_d); 14244%} 14245 14246instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 14247 match(Set dst (CopySignD src1 (Binary src2 zero))); 14248 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 14249 format %{ "CopySignD $dst $src1 $src2" %} 14250 ins_encode %{ 14251 FloatRegister dst = as_FloatRegister($dst$$reg), 14252 src1 = as_FloatRegister($src1$$reg), 14253 src2 = as_FloatRegister($src2$$reg), 14254 zero = as_FloatRegister($zero$$reg); 14255 __ fnegd(dst, zero); 14256 __ bsl(dst, __ T8B, src2, src1); 14257 %} 14258 ins_pipe(fp_uop_d); 14259%} 14260 14261instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14262 match(Set dst (CopySignF src1 src2)); 14263 effect(TEMP_DEF dst, USE src1, USE src2); 14264 format %{ "CopySignF $dst $src1 $src2" %} 14265 ins_encode %{ 14266 FloatRegister dst = as_FloatRegister($dst$$reg), 14267 src1 = as_FloatRegister($src1$$reg), 14268 src2 = as_FloatRegister($src2$$reg); 14269 __ movi(dst, __ T2S, 0x80, 24); 14270 __ bsl(dst, __ T8B, src2, src1); 14271 %} 14272 ins_pipe(fp_uop_d); 14273%} 14274 14275instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 14276 match(Set dst (SignumD src (Binary zero one))); 14277 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14278 format %{ "signumD $dst, $src" %} 14279 ins_encode %{ 14280 FloatRegister src = as_FloatRegister($src$$reg), 14281 dst = as_FloatRegister($dst$$reg), 14282 zero = as_FloatRegister($zero$$reg), 14283 one = as_FloatRegister($one$$reg); 14284 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14285 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14286 // Bit selection instruction gets bit from "one" for each enabled bit in 14287 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14288 // NaN the whole "src" will be copied because "dst" is zero. For all other 14289 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14290 // from "src", and all other bits are copied from 1.0. 14291 __ bsl(dst, __ T8B, one, src); 14292 %} 14293 ins_pipe(fp_uop_d); 14294%} 14295 14296instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 14297 match(Set dst (SignumF src (Binary zero one))); 14298 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14299 format %{ "signumF $dst, $src" %} 14300 ins_encode %{ 14301 FloatRegister src = as_FloatRegister($src$$reg), 14302 dst = as_FloatRegister($dst$$reg), 14303 zero = as_FloatRegister($zero$$reg), 14304 one = as_FloatRegister($one$$reg); 14305 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14306 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14307 // Bit selection instruction gets bit from "one" for each enabled bit in 14308 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14309 // NaN the whole "src" will be copied because "dst" is zero. For all other 14310 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14311 // from "src", and all other bits are copied from 1.0. 14312 __ bsl(dst, __ T8B, one, src); 14313 %} 14314 ins_pipe(fp_uop_d); 14315%} 14316 14317// ============================================================================ 14318// Logical Instructions 14319 14320// Integer Logical Instructions 14321 14322// And Instructions 14323 14324 14325instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 14326 match(Set dst (AndI src1 src2)); 14327 14328 format %{ "andw $dst, $src1, $src2\t# int" %} 14329 14330 ins_cost(INSN_COST); 14331 ins_encode %{ 14332 __ andw(as_Register($dst$$reg), 14333 as_Register($src1$$reg), 14334 as_Register($src2$$reg)); 14335 %} 14336 14337 ins_pipe(ialu_reg_reg); 14338%} 14339 14340instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 14341 match(Set dst (AndI src1 src2)); 14342 14343 format %{ "andsw $dst, $src1, $src2\t# int" %} 14344 14345 ins_cost(INSN_COST); 14346 ins_encode %{ 14347 __ andw(as_Register($dst$$reg), 14348 as_Register($src1$$reg), 14349 (uint64_t)($src2$$constant)); 14350 %} 14351 14352 ins_pipe(ialu_reg_imm); 14353%} 14354 14355// Or Instructions 14356 14357instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14358 match(Set dst (OrI src1 src2)); 14359 14360 format %{ "orrw $dst, $src1, $src2\t# int" %} 14361 14362 ins_cost(INSN_COST); 14363 ins_encode %{ 14364 __ orrw(as_Register($dst$$reg), 14365 as_Register($src1$$reg), 14366 as_Register($src2$$reg)); 14367 %} 14368 14369 ins_pipe(ialu_reg_reg); 14370%} 14371 14372instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14373 match(Set dst (OrI src1 src2)); 14374 14375 format %{ "orrw $dst, $src1, $src2\t# int" %} 14376 14377 ins_cost(INSN_COST); 14378 ins_encode %{ 14379 __ orrw(as_Register($dst$$reg), 14380 as_Register($src1$$reg), 14381 (uint64_t)($src2$$constant)); 14382 %} 14383 14384 ins_pipe(ialu_reg_imm); 14385%} 14386 14387// Xor Instructions 14388 14389instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14390 match(Set dst (XorI src1 src2)); 14391 14392 format %{ "eorw $dst, $src1, $src2\t# int" %} 14393 14394 ins_cost(INSN_COST); 14395 ins_encode %{ 14396 __ eorw(as_Register($dst$$reg), 14397 as_Register($src1$$reg), 14398 as_Register($src2$$reg)); 14399 %} 14400 14401 ins_pipe(ialu_reg_reg); 14402%} 14403 14404instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14405 match(Set dst (XorI src1 src2)); 14406 14407 format %{ "eorw $dst, $src1, $src2\t# int" %} 14408 14409 ins_cost(INSN_COST); 14410 ins_encode %{ 14411 __ eorw(as_Register($dst$$reg), 14412 as_Register($src1$$reg), 14413 (uint64_t)($src2$$constant)); 14414 %} 14415 14416 ins_pipe(ialu_reg_imm); 14417%} 14418 14419// Long Logical Instructions 14420// TODO 14421 14422instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 14423 match(Set dst (AndL src1 src2)); 14424 14425 format %{ "and $dst, $src1, $src2\t# int" %} 14426 14427 ins_cost(INSN_COST); 14428 ins_encode %{ 14429 __ andr(as_Register($dst$$reg), 14430 as_Register($src1$$reg), 14431 as_Register($src2$$reg)); 14432 %} 14433 14434 ins_pipe(ialu_reg_reg); 14435%} 14436 14437instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 14438 match(Set dst (AndL src1 src2)); 14439 14440 format %{ "and $dst, $src1, $src2\t# int" %} 14441 14442 ins_cost(INSN_COST); 14443 ins_encode %{ 14444 __ andr(as_Register($dst$$reg), 14445 as_Register($src1$$reg), 14446 (uint64_t)($src2$$constant)); 14447 %} 14448 14449 ins_pipe(ialu_reg_imm); 14450%} 14451 14452// Or Instructions 14453 14454instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14455 match(Set dst (OrL src1 src2)); 14456 14457 format %{ "orr $dst, $src1, $src2\t# int" %} 14458 14459 ins_cost(INSN_COST); 14460 ins_encode %{ 14461 __ orr(as_Register($dst$$reg), 14462 as_Register($src1$$reg), 14463 as_Register($src2$$reg)); 14464 %} 14465 14466 ins_pipe(ialu_reg_reg); 14467%} 14468 14469instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14470 match(Set dst (OrL src1 src2)); 14471 14472 format %{ "orr $dst, $src1, $src2\t# int" %} 14473 14474 ins_cost(INSN_COST); 14475 ins_encode %{ 14476 __ orr(as_Register($dst$$reg), 14477 as_Register($src1$$reg), 14478 (uint64_t)($src2$$constant)); 14479 %} 14480 14481 ins_pipe(ialu_reg_imm); 14482%} 14483 14484// Xor Instructions 14485 14486instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14487 match(Set dst (XorL src1 src2)); 14488 14489 format %{ "eor $dst, $src1, $src2\t# int" %} 14490 14491 ins_cost(INSN_COST); 14492 ins_encode %{ 14493 __ eor(as_Register($dst$$reg), 14494 as_Register($src1$$reg), 14495 as_Register($src2$$reg)); 14496 %} 14497 14498 ins_pipe(ialu_reg_reg); 14499%} 14500 14501instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14502 match(Set dst (XorL src1 src2)); 14503 14504 ins_cost(INSN_COST); 14505 format %{ "eor $dst, $src1, $src2\t# int" %} 14506 14507 ins_encode %{ 14508 __ eor(as_Register($dst$$reg), 14509 as_Register($src1$$reg), 14510 (uint64_t)($src2$$constant)); 14511 %} 14512 14513 ins_pipe(ialu_reg_imm); 14514%} 14515 14516instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 14517%{ 14518 match(Set dst (ConvI2L src)); 14519 14520 ins_cost(INSN_COST); 14521 format %{ "sxtw $dst, $src\t# i2l" %} 14522 ins_encode %{ 14523 __ sbfm($dst$$Register, $src$$Register, 0, 31); 14524 %} 14525 ins_pipe(ialu_reg_shift); 14526%} 14527 14528// this pattern occurs in bigmath arithmetic 14529instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 14530%{ 14531 match(Set dst (AndL (ConvI2L src) mask)); 14532 14533 ins_cost(INSN_COST); 14534 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 14535 ins_encode %{ 14536 __ ubfm($dst$$Register, $src$$Register, 0, 31); 14537 %} 14538 14539 ins_pipe(ialu_reg_shift); 14540%} 14541 14542instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 14543 match(Set dst (ConvL2I src)); 14544 14545 ins_cost(INSN_COST); 14546 format %{ "movw $dst, $src \t// l2i" %} 14547 14548 ins_encode %{ 14549 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 14550 %} 14551 14552 ins_pipe(ialu_reg); 14553%} 14554 14555instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 14556%{ 14557 match(Set dst (Conv2B src)); 14558 effect(KILL cr); 14559 14560 format %{ 14561 "cmpw $src, zr\n\t" 14562 "cset $dst, ne" 14563 %} 14564 14565 ins_encode %{ 14566 __ cmpw(as_Register($src$$reg), zr); 14567 __ cset(as_Register($dst$$reg), Assembler::NE); 14568 %} 14569 14570 ins_pipe(ialu_reg); 14571%} 14572 14573instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 14574%{ 14575 match(Set dst (Conv2B src)); 14576 effect(KILL cr); 14577 14578 format %{ 14579 "cmp $src, zr\n\t" 14580 "cset $dst, ne" 14581 %} 14582 14583 ins_encode %{ 14584 __ cmp(as_Register($src$$reg), zr); 14585 __ cset(as_Register($dst$$reg), Assembler::NE); 14586 %} 14587 14588 ins_pipe(ialu_reg); 14589%} 14590 14591instruct convD2F_reg(vRegF dst, vRegD src) %{ 14592 match(Set dst (ConvD2F src)); 14593 14594 ins_cost(INSN_COST * 5); 14595 format %{ "fcvtd $dst, $src \t// d2f" %} 14596 14597 ins_encode %{ 14598 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14599 %} 14600 14601 ins_pipe(fp_d2f); 14602%} 14603 14604instruct convF2D_reg(vRegD dst, vRegF src) %{ 14605 match(Set dst (ConvF2D src)); 14606 14607 ins_cost(INSN_COST * 5); 14608 format %{ "fcvts $dst, $src \t// f2d" %} 14609 14610 ins_encode %{ 14611 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14612 %} 14613 14614 ins_pipe(fp_f2d); 14615%} 14616 14617instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14618 match(Set dst (ConvF2I src)); 14619 14620 ins_cost(INSN_COST * 5); 14621 format %{ "fcvtzsw $dst, $src \t// f2i" %} 14622 14623 ins_encode %{ 14624 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14625 %} 14626 14627 ins_pipe(fp_f2i); 14628%} 14629 14630instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 14631 match(Set dst (ConvF2L src)); 14632 14633 ins_cost(INSN_COST * 5); 14634 format %{ "fcvtzs $dst, $src \t// f2l" %} 14635 14636 ins_encode %{ 14637 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14638 %} 14639 14640 ins_pipe(fp_f2l); 14641%} 14642 14643instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 14644 match(Set dst (ConvI2F src)); 14645 14646 ins_cost(INSN_COST * 5); 14647 format %{ "scvtfws $dst, $src \t// i2f" %} 14648 14649 ins_encode %{ 14650 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14651 %} 14652 14653 ins_pipe(fp_i2f); 14654%} 14655 14656instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 14657 match(Set dst (ConvL2F src)); 14658 14659 ins_cost(INSN_COST * 5); 14660 format %{ "scvtfs $dst, $src \t// l2f" %} 14661 14662 ins_encode %{ 14663 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14664 %} 14665 14666 ins_pipe(fp_l2f); 14667%} 14668 14669instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 14670 match(Set dst (ConvD2I src)); 14671 14672 ins_cost(INSN_COST * 5); 14673 format %{ "fcvtzdw $dst, $src \t// d2i" %} 14674 14675 ins_encode %{ 14676 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14677 %} 14678 14679 ins_pipe(fp_d2i); 14680%} 14681 14682instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14683 match(Set dst (ConvD2L src)); 14684 14685 ins_cost(INSN_COST * 5); 14686 format %{ "fcvtzd $dst, $src \t// d2l" %} 14687 14688 ins_encode %{ 14689 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14690 %} 14691 14692 ins_pipe(fp_d2l); 14693%} 14694 14695instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 14696 match(Set dst (ConvI2D src)); 14697 14698 ins_cost(INSN_COST * 5); 14699 format %{ "scvtfwd $dst, $src \t// i2d" %} 14700 14701 ins_encode %{ 14702 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14703 %} 14704 14705 ins_pipe(fp_i2d); 14706%} 14707 14708instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 14709 match(Set dst (ConvL2D src)); 14710 14711 ins_cost(INSN_COST * 5); 14712 format %{ "scvtfd $dst, $src \t// l2d" %} 14713 14714 ins_encode %{ 14715 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14716 %} 14717 14718 ins_pipe(fp_l2d); 14719%} 14720 14721// stack <-> reg and reg <-> reg shuffles with no conversion 14722 14723instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 14724 14725 match(Set dst (MoveF2I src)); 14726 14727 effect(DEF dst, USE src); 14728 14729 ins_cost(4 * INSN_COST); 14730 14731 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 14732 14733 ins_encode %{ 14734 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 14735 %} 14736 14737 ins_pipe(iload_reg_reg); 14738 14739%} 14740 14741instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 14742 14743 match(Set dst (MoveI2F src)); 14744 14745 effect(DEF dst, USE src); 14746 14747 ins_cost(4 * INSN_COST); 14748 14749 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 14750 14751 ins_encode %{ 14752 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14753 %} 14754 14755 ins_pipe(pipe_class_memory); 14756 14757%} 14758 14759instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 14760 14761 match(Set dst (MoveD2L src)); 14762 14763 effect(DEF dst, USE src); 14764 14765 ins_cost(4 * INSN_COST); 14766 14767 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 14768 14769 ins_encode %{ 14770 __ ldr($dst$$Register, Address(sp, $src$$disp)); 14771 %} 14772 14773 ins_pipe(iload_reg_reg); 14774 14775%} 14776 14777instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 14778 14779 match(Set dst (MoveL2D src)); 14780 14781 effect(DEF dst, USE src); 14782 14783 ins_cost(4 * INSN_COST); 14784 14785 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 14786 14787 ins_encode %{ 14788 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 14789 %} 14790 14791 ins_pipe(pipe_class_memory); 14792 14793%} 14794 14795instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 14796 14797 match(Set dst (MoveF2I src)); 14798 14799 effect(DEF dst, USE src); 14800 14801 ins_cost(INSN_COST); 14802 14803 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 14804 14805 ins_encode %{ 14806 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14807 %} 14808 14809 ins_pipe(pipe_class_memory); 14810 14811%} 14812 14813instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 14814 14815 match(Set dst (MoveI2F src)); 14816 14817 effect(DEF dst, USE src); 14818 14819 ins_cost(INSN_COST); 14820 14821 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 14822 14823 ins_encode %{ 14824 __ strw($src$$Register, Address(sp, $dst$$disp)); 14825 %} 14826 14827 ins_pipe(istore_reg_reg); 14828 14829%} 14830 14831instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 14832 14833 match(Set dst (MoveD2L src)); 14834 14835 effect(DEF dst, USE src); 14836 14837 ins_cost(INSN_COST); 14838 14839 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 14840 14841 ins_encode %{ 14842 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 14843 %} 14844 14845 ins_pipe(pipe_class_memory); 14846 14847%} 14848 14849instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 14850 14851 match(Set dst (MoveL2D src)); 14852 14853 effect(DEF dst, USE src); 14854 14855 ins_cost(INSN_COST); 14856 14857 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 14858 14859 ins_encode %{ 14860 __ str($src$$Register, Address(sp, $dst$$disp)); 14861 %} 14862 14863 ins_pipe(istore_reg_reg); 14864 14865%} 14866 14867instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14868 14869 match(Set dst (MoveF2I src)); 14870 14871 effect(DEF dst, USE src); 14872 14873 ins_cost(INSN_COST); 14874 14875 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 14876 14877 ins_encode %{ 14878 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 14879 %} 14880 14881 ins_pipe(fp_f2i); 14882 14883%} 14884 14885instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 14886 14887 match(Set dst (MoveI2F src)); 14888 14889 effect(DEF dst, USE src); 14890 14891 ins_cost(INSN_COST); 14892 14893 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 14894 14895 ins_encode %{ 14896 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 14897 %} 14898 14899 ins_pipe(fp_i2f); 14900 14901%} 14902 14903instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14904 14905 match(Set dst (MoveD2L src)); 14906 14907 effect(DEF dst, USE src); 14908 14909 ins_cost(INSN_COST); 14910 14911 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 14912 14913 ins_encode %{ 14914 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 14915 %} 14916 14917 ins_pipe(fp_d2l); 14918 14919%} 14920 14921instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 14922 14923 match(Set dst (MoveL2D src)); 14924 14925 effect(DEF dst, USE src); 14926 14927 ins_cost(INSN_COST); 14928 14929 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 14930 14931 ins_encode %{ 14932 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 14933 %} 14934 14935 ins_pipe(fp_l2d); 14936 14937%} 14938 14939// ============================================================================ 14940// clearing of an array 14941 14942instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 14943%{ 14944 match(Set dummy (ClearArray cnt base)); 14945 effect(USE_KILL cnt, USE_KILL base, KILL cr); 14946 14947 ins_cost(4 * INSN_COST); 14948 format %{ "ClearArray $cnt, $base" %} 14949 14950 ins_encode %{ 14951 address tpc = __ zero_words($base$$Register, $cnt$$Register); 14952 if (tpc == NULL) { 14953 ciEnv::current()->record_failure("CodeCache is full"); 14954 return; 14955 } 14956 %} 14957 14958 ins_pipe(pipe_class_memory); 14959%} 14960 14961instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 14962%{ 14963 predicate((uint64_t)n->in(2)->get_long() 14964 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 14965 match(Set dummy (ClearArray cnt base)); 14966 effect(USE_KILL base); 14967 14968 ins_cost(4 * INSN_COST); 14969 format %{ "ClearArray $cnt, $base" %} 14970 14971 ins_encode %{ 14972 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 14973 %} 14974 14975 ins_pipe(pipe_class_memory); 14976%} 14977 14978// ============================================================================ 14979// Overflow Math Instructions 14980 14981instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 14982%{ 14983 match(Set cr (OverflowAddI op1 op2)); 14984 14985 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14986 ins_cost(INSN_COST); 14987 ins_encode %{ 14988 __ cmnw($op1$$Register, $op2$$Register); 14989 %} 14990 14991 ins_pipe(icmp_reg_reg); 14992%} 14993 14994instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 14995%{ 14996 match(Set cr (OverflowAddI op1 op2)); 14997 14998 format %{ "cmnw $op1, $op2\t# overflow check int" %} 14999 ins_cost(INSN_COST); 15000 ins_encode %{ 15001 __ cmnw($op1$$Register, $op2$$constant); 15002 %} 15003 15004 ins_pipe(icmp_reg_imm); 15005%} 15006 15007instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15008%{ 15009 match(Set cr (OverflowAddL op1 op2)); 15010 15011 format %{ "cmn $op1, $op2\t# overflow check long" %} 15012 ins_cost(INSN_COST); 15013 ins_encode %{ 15014 __ cmn($op1$$Register, $op2$$Register); 15015 %} 15016 15017 ins_pipe(icmp_reg_reg); 15018%} 15019 15020instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15021%{ 15022 match(Set cr (OverflowAddL op1 op2)); 15023 15024 format %{ "cmn $op1, $op2\t# overflow check long" %} 15025 ins_cost(INSN_COST); 15026 ins_encode %{ 15027 __ cmn($op1$$Register, $op2$$constant); 15028 %} 15029 15030 ins_pipe(icmp_reg_imm); 15031%} 15032 15033instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15034%{ 15035 match(Set cr (OverflowSubI op1 op2)); 15036 15037 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15038 ins_cost(INSN_COST); 15039 ins_encode %{ 15040 __ cmpw($op1$$Register, $op2$$Register); 15041 %} 15042 15043 ins_pipe(icmp_reg_reg); 15044%} 15045 15046instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15047%{ 15048 match(Set cr (OverflowSubI op1 op2)); 15049 15050 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15051 ins_cost(INSN_COST); 15052 ins_encode %{ 15053 __ cmpw($op1$$Register, $op2$$constant); 15054 %} 15055 15056 ins_pipe(icmp_reg_imm); 15057%} 15058 15059instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15060%{ 15061 match(Set cr (OverflowSubL op1 op2)); 15062 15063 format %{ "cmp $op1, $op2\t# overflow check long" %} 15064 ins_cost(INSN_COST); 15065 ins_encode %{ 15066 __ cmp($op1$$Register, $op2$$Register); 15067 %} 15068 15069 ins_pipe(icmp_reg_reg); 15070%} 15071 15072instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15073%{ 15074 match(Set cr (OverflowSubL op1 op2)); 15075 15076 format %{ "cmp $op1, $op2\t# overflow check long" %} 15077 ins_cost(INSN_COST); 15078 ins_encode %{ 15079 __ subs(zr, $op1$$Register, $op2$$constant); 15080 %} 15081 15082 ins_pipe(icmp_reg_imm); 15083%} 15084 15085instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 15086%{ 15087 match(Set cr (OverflowSubI zero op1)); 15088 15089 format %{ "cmpw zr, $op1\t# overflow check int" %} 15090 ins_cost(INSN_COST); 15091 ins_encode %{ 15092 __ cmpw(zr, $op1$$Register); 15093 %} 15094 15095 ins_pipe(icmp_reg_imm); 15096%} 15097 15098instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 15099%{ 15100 match(Set cr (OverflowSubL zero op1)); 15101 15102 format %{ "cmp zr, $op1\t# overflow check long" %} 15103 ins_cost(INSN_COST); 15104 ins_encode %{ 15105 __ cmp(zr, $op1$$Register); 15106 %} 15107 15108 ins_pipe(icmp_reg_imm); 15109%} 15110 15111instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15112%{ 15113 match(Set cr (OverflowMulI op1 op2)); 15114 15115 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15116 "cmp rscratch1, rscratch1, sxtw\n\t" 15117 "movw rscratch1, #0x80000000\n\t" 15118 "cselw rscratch1, rscratch1, zr, NE\n\t" 15119 "cmpw rscratch1, #1" %} 15120 ins_cost(5 * INSN_COST); 15121 ins_encode %{ 15122 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15123 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15124 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15125 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15126 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15127 %} 15128 15129 ins_pipe(pipe_slow); 15130%} 15131 15132instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 15133%{ 15134 match(If cmp (OverflowMulI op1 op2)); 15135 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15136 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15137 effect(USE labl, KILL cr); 15138 15139 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15140 "cmp rscratch1, rscratch1, sxtw\n\t" 15141 "b$cmp $labl" %} 15142 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 15143 ins_encode %{ 15144 Label* L = $labl$$label; 15145 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15146 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15147 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15148 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15149 %} 15150 15151 ins_pipe(pipe_serial); 15152%} 15153 15154instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15155%{ 15156 match(Set cr (OverflowMulL op1 op2)); 15157 15158 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15159 "smulh rscratch2, $op1, $op2\n\t" 15160 "cmp rscratch2, rscratch1, ASR #63\n\t" 15161 "movw rscratch1, #0x80000000\n\t" 15162 "cselw rscratch1, rscratch1, zr, NE\n\t" 15163 "cmpw rscratch1, #1" %} 15164 ins_cost(6 * INSN_COST); 15165 ins_encode %{ 15166 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15167 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15168 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15169 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15170 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15171 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15172 %} 15173 15174 ins_pipe(pipe_slow); 15175%} 15176 15177instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 15178%{ 15179 match(If cmp (OverflowMulL op1 op2)); 15180 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15181 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15182 effect(USE labl, KILL cr); 15183 15184 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15185 "smulh rscratch2, $op1, $op2\n\t" 15186 "cmp rscratch2, rscratch1, ASR #63\n\t" 15187 "b$cmp $labl" %} 15188 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 15189 ins_encode %{ 15190 Label* L = $labl$$label; 15191 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15192 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15193 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15194 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15195 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15196 %} 15197 15198 ins_pipe(pipe_serial); 15199%} 15200 15201// ============================================================================ 15202// Compare Instructions 15203 15204instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 15205%{ 15206 match(Set cr (CmpI op1 op2)); 15207 15208 effect(DEF cr, USE op1, USE op2); 15209 15210 ins_cost(INSN_COST); 15211 format %{ "cmpw $op1, $op2" %} 15212 15213 ins_encode(aarch64_enc_cmpw(op1, op2)); 15214 15215 ins_pipe(icmp_reg_reg); 15216%} 15217 15218instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 15219%{ 15220 match(Set cr (CmpI op1 zero)); 15221 15222 effect(DEF cr, USE op1); 15223 15224 ins_cost(INSN_COST); 15225 format %{ "cmpw $op1, 0" %} 15226 15227 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15228 15229 ins_pipe(icmp_reg_imm); 15230%} 15231 15232instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 15233%{ 15234 match(Set cr (CmpI op1 op2)); 15235 15236 effect(DEF cr, USE op1); 15237 15238 ins_cost(INSN_COST); 15239 format %{ "cmpw $op1, $op2" %} 15240 15241 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15242 15243 ins_pipe(icmp_reg_imm); 15244%} 15245 15246instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 15247%{ 15248 match(Set cr (CmpI op1 op2)); 15249 15250 effect(DEF cr, USE op1); 15251 15252 ins_cost(INSN_COST * 2); 15253 format %{ "cmpw $op1, $op2" %} 15254 15255 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15256 15257 ins_pipe(icmp_reg_imm); 15258%} 15259 15260// Unsigned compare Instructions; really, same as signed compare 15261// except it should only be used to feed an If or a CMovI which takes a 15262// cmpOpU. 15263 15264instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 15265%{ 15266 match(Set cr (CmpU op1 op2)); 15267 15268 effect(DEF cr, USE op1, USE op2); 15269 15270 ins_cost(INSN_COST); 15271 format %{ "cmpw $op1, $op2\t# unsigned" %} 15272 15273 ins_encode(aarch64_enc_cmpw(op1, op2)); 15274 15275 ins_pipe(icmp_reg_reg); 15276%} 15277 15278instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 15279%{ 15280 match(Set cr (CmpU op1 zero)); 15281 15282 effect(DEF cr, USE op1); 15283 15284 ins_cost(INSN_COST); 15285 format %{ "cmpw $op1, #0\t# unsigned" %} 15286 15287 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15288 15289 ins_pipe(icmp_reg_imm); 15290%} 15291 15292instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 15293%{ 15294 match(Set cr (CmpU op1 op2)); 15295 15296 effect(DEF cr, USE op1); 15297 15298 ins_cost(INSN_COST); 15299 format %{ "cmpw $op1, $op2\t# unsigned" %} 15300 15301 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15302 15303 ins_pipe(icmp_reg_imm); 15304%} 15305 15306instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 15307%{ 15308 match(Set cr (CmpU op1 op2)); 15309 15310 effect(DEF cr, USE op1); 15311 15312 ins_cost(INSN_COST * 2); 15313 format %{ "cmpw $op1, $op2\t# unsigned" %} 15314 15315 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15316 15317 ins_pipe(icmp_reg_imm); 15318%} 15319 15320instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15321%{ 15322 match(Set cr (CmpL op1 op2)); 15323 15324 effect(DEF cr, USE op1, USE op2); 15325 15326 ins_cost(INSN_COST); 15327 format %{ "cmp $op1, $op2" %} 15328 15329 ins_encode(aarch64_enc_cmp(op1, op2)); 15330 15331 ins_pipe(icmp_reg_reg); 15332%} 15333 15334instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 15335%{ 15336 match(Set cr (CmpL op1 zero)); 15337 15338 effect(DEF cr, USE op1); 15339 15340 ins_cost(INSN_COST); 15341 format %{ "tst $op1" %} 15342 15343 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15344 15345 ins_pipe(icmp_reg_imm); 15346%} 15347 15348instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 15349%{ 15350 match(Set cr (CmpL op1 op2)); 15351 15352 effect(DEF cr, USE op1); 15353 15354 ins_cost(INSN_COST); 15355 format %{ "cmp $op1, $op2" %} 15356 15357 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15358 15359 ins_pipe(icmp_reg_imm); 15360%} 15361 15362instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 15363%{ 15364 match(Set cr (CmpL op1 op2)); 15365 15366 effect(DEF cr, USE op1); 15367 15368 ins_cost(INSN_COST * 2); 15369 format %{ "cmp $op1, $op2" %} 15370 15371 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15372 15373 ins_pipe(icmp_reg_imm); 15374%} 15375 15376instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 15377%{ 15378 match(Set cr (CmpUL op1 op2)); 15379 15380 effect(DEF cr, USE op1, USE op2); 15381 15382 ins_cost(INSN_COST); 15383 format %{ "cmp $op1, $op2" %} 15384 15385 ins_encode(aarch64_enc_cmp(op1, op2)); 15386 15387 ins_pipe(icmp_reg_reg); 15388%} 15389 15390instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 15391%{ 15392 match(Set cr (CmpUL op1 zero)); 15393 15394 effect(DEF cr, USE op1); 15395 15396 ins_cost(INSN_COST); 15397 format %{ "tst $op1" %} 15398 15399 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15400 15401 ins_pipe(icmp_reg_imm); 15402%} 15403 15404instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 15405%{ 15406 match(Set cr (CmpUL op1 op2)); 15407 15408 effect(DEF cr, USE op1); 15409 15410 ins_cost(INSN_COST); 15411 format %{ "cmp $op1, $op2" %} 15412 15413 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15414 15415 ins_pipe(icmp_reg_imm); 15416%} 15417 15418instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 15419%{ 15420 match(Set cr (CmpUL op1 op2)); 15421 15422 effect(DEF cr, USE op1); 15423 15424 ins_cost(INSN_COST * 2); 15425 format %{ "cmp $op1, $op2" %} 15426 15427 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15428 15429 ins_pipe(icmp_reg_imm); 15430%} 15431 15432instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 15433%{ 15434 match(Set cr (CmpP op1 op2)); 15435 15436 effect(DEF cr, USE op1, USE op2); 15437 15438 ins_cost(INSN_COST); 15439 format %{ "cmp $op1, $op2\t // ptr" %} 15440 15441 ins_encode(aarch64_enc_cmpp(op1, op2)); 15442 15443 ins_pipe(icmp_reg_reg); 15444%} 15445 15446instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 15447%{ 15448 match(Set cr (CmpN op1 op2)); 15449 15450 effect(DEF cr, USE op1, USE op2); 15451 15452 ins_cost(INSN_COST); 15453 format %{ "cmp $op1, $op2\t // compressed ptr" %} 15454 15455 ins_encode(aarch64_enc_cmpn(op1, op2)); 15456 15457 ins_pipe(icmp_reg_reg); 15458%} 15459 15460instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 15461%{ 15462 match(Set cr (CmpP op1 zero)); 15463 15464 effect(DEF cr, USE op1, USE zero); 15465 15466 ins_cost(INSN_COST); 15467 format %{ "cmp $op1, 0\t // ptr" %} 15468 15469 ins_encode(aarch64_enc_testp(op1)); 15470 15471 ins_pipe(icmp_reg_imm); 15472%} 15473 15474instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 15475%{ 15476 match(Set cr (CmpN op1 zero)); 15477 15478 effect(DEF cr, USE op1, USE zero); 15479 15480 ins_cost(INSN_COST); 15481 format %{ "cmp $op1, 0\t // compressed ptr" %} 15482 15483 ins_encode(aarch64_enc_testn(op1)); 15484 15485 ins_pipe(icmp_reg_imm); 15486%} 15487 15488// FP comparisons 15489// 15490// n.b. CmpF/CmpD set a normal flags reg which then gets compared 15491// using normal cmpOp. See declaration of rFlagsReg for details. 15492 15493instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 15494%{ 15495 match(Set cr (CmpF src1 src2)); 15496 15497 ins_cost(3 * INSN_COST); 15498 format %{ "fcmps $src1, $src2" %} 15499 15500 ins_encode %{ 15501 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15502 %} 15503 15504 ins_pipe(pipe_class_compare); 15505%} 15506 15507instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 15508%{ 15509 match(Set cr (CmpF src1 src2)); 15510 15511 ins_cost(3 * INSN_COST); 15512 format %{ "fcmps $src1, 0.0" %} 15513 15514 ins_encode %{ 15515 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 15516 %} 15517 15518 ins_pipe(pipe_class_compare); 15519%} 15520// FROM HERE 15521 15522instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 15523%{ 15524 match(Set cr (CmpD src1 src2)); 15525 15526 ins_cost(3 * INSN_COST); 15527 format %{ "fcmpd $src1, $src2" %} 15528 15529 ins_encode %{ 15530 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15531 %} 15532 15533 ins_pipe(pipe_class_compare); 15534%} 15535 15536instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 15537%{ 15538 match(Set cr (CmpD src1 src2)); 15539 15540 ins_cost(3 * INSN_COST); 15541 format %{ "fcmpd $src1, 0.0" %} 15542 15543 ins_encode %{ 15544 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 15545 %} 15546 15547 ins_pipe(pipe_class_compare); 15548%} 15549 15550instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 15551%{ 15552 match(Set dst (CmpF3 src1 src2)); 15553 effect(KILL cr); 15554 15555 ins_cost(5 * INSN_COST); 15556 format %{ "fcmps $src1, $src2\n\t" 15557 "csinvw($dst, zr, zr, eq\n\t" 15558 "csnegw($dst, $dst, $dst, lt)" 15559 %} 15560 15561 ins_encode %{ 15562 Label done; 15563 FloatRegister s1 = as_FloatRegister($src1$$reg); 15564 FloatRegister s2 = as_FloatRegister($src2$$reg); 15565 Register d = as_Register($dst$$reg); 15566 __ fcmps(s1, s2); 15567 // installs 0 if EQ else -1 15568 __ csinvw(d, zr, zr, Assembler::EQ); 15569 // keeps -1 if less or unordered else installs 1 15570 __ csnegw(d, d, d, Assembler::LT); 15571 __ bind(done); 15572 %} 15573 15574 ins_pipe(pipe_class_default); 15575 15576%} 15577 15578instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 15579%{ 15580 match(Set dst (CmpD3 src1 src2)); 15581 effect(KILL cr); 15582 15583 ins_cost(5 * INSN_COST); 15584 format %{ "fcmpd $src1, $src2\n\t" 15585 "csinvw($dst, zr, zr, eq\n\t" 15586 "csnegw($dst, $dst, $dst, lt)" 15587 %} 15588 15589 ins_encode %{ 15590 Label done; 15591 FloatRegister s1 = as_FloatRegister($src1$$reg); 15592 FloatRegister s2 = as_FloatRegister($src2$$reg); 15593 Register d = as_Register($dst$$reg); 15594 __ fcmpd(s1, s2); 15595 // installs 0 if EQ else -1 15596 __ csinvw(d, zr, zr, Assembler::EQ); 15597 // keeps -1 if less or unordered else installs 1 15598 __ csnegw(d, d, d, Assembler::LT); 15599 __ bind(done); 15600 %} 15601 ins_pipe(pipe_class_default); 15602 15603%} 15604 15605instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 15606%{ 15607 match(Set dst (CmpF3 src1 zero)); 15608 effect(KILL cr); 15609 15610 ins_cost(5 * INSN_COST); 15611 format %{ "fcmps $src1, 0.0\n\t" 15612 "csinvw($dst, zr, zr, eq\n\t" 15613 "csnegw($dst, $dst, $dst, lt)" 15614 %} 15615 15616 ins_encode %{ 15617 Label done; 15618 FloatRegister s1 = as_FloatRegister($src1$$reg); 15619 Register d = as_Register($dst$$reg); 15620 __ fcmps(s1, 0.0); 15621 // installs 0 if EQ else -1 15622 __ csinvw(d, zr, zr, Assembler::EQ); 15623 // keeps -1 if less or unordered else installs 1 15624 __ csnegw(d, d, d, Assembler::LT); 15625 __ bind(done); 15626 %} 15627 15628 ins_pipe(pipe_class_default); 15629 15630%} 15631 15632instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 15633%{ 15634 match(Set dst (CmpD3 src1 zero)); 15635 effect(KILL cr); 15636 15637 ins_cost(5 * INSN_COST); 15638 format %{ "fcmpd $src1, 0.0\n\t" 15639 "csinvw($dst, zr, zr, eq\n\t" 15640 "csnegw($dst, $dst, $dst, lt)" 15641 %} 15642 15643 ins_encode %{ 15644 Label done; 15645 FloatRegister s1 = as_FloatRegister($src1$$reg); 15646 Register d = as_Register($dst$$reg); 15647 __ fcmpd(s1, 0.0); 15648 // installs 0 if EQ else -1 15649 __ csinvw(d, zr, zr, Assembler::EQ); 15650 // keeps -1 if less or unordered else installs 1 15651 __ csnegw(d, d, d, Assembler::LT); 15652 __ bind(done); 15653 %} 15654 ins_pipe(pipe_class_default); 15655 15656%} 15657 15658instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 15659%{ 15660 match(Set dst (CmpLTMask p q)); 15661 effect(KILL cr); 15662 15663 ins_cost(3 * INSN_COST); 15664 15665 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 15666 "csetw $dst, lt\n\t" 15667 "subw $dst, zr, $dst" 15668 %} 15669 15670 ins_encode %{ 15671 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 15672 __ csetw(as_Register($dst$$reg), Assembler::LT); 15673 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 15674 %} 15675 15676 ins_pipe(ialu_reg_reg); 15677%} 15678 15679instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 15680%{ 15681 match(Set dst (CmpLTMask src zero)); 15682 effect(KILL cr); 15683 15684 ins_cost(INSN_COST); 15685 15686 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 15687 15688 ins_encode %{ 15689 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 15690 %} 15691 15692 ins_pipe(ialu_reg_shift); 15693%} 15694 15695// ============================================================================ 15696// Max and Min 15697 15698instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 15699%{ 15700 effect( DEF dst, USE src1, USE src2, USE cr ); 15701 15702 ins_cost(INSN_COST * 2); 15703 format %{ "cselw $dst, $src1, $src2 lt\t" %} 15704 15705 ins_encode %{ 15706 __ cselw(as_Register($dst$$reg), 15707 as_Register($src1$$reg), 15708 as_Register($src2$$reg), 15709 Assembler::LT); 15710 %} 15711 15712 ins_pipe(icond_reg_reg); 15713%} 15714 15715instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 15716%{ 15717 match(Set dst (MinI src1 src2)); 15718 ins_cost(INSN_COST * 3); 15719 15720 expand %{ 15721 rFlagsReg cr; 15722 compI_reg_reg(cr, src1, src2); 15723 cmovI_reg_reg_lt(dst, src1, src2, cr); 15724 %} 15725 15726%} 15727// FROM HERE 15728 15729instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 15730%{ 15731 effect( DEF dst, USE src1, USE src2, USE cr ); 15732 15733 ins_cost(INSN_COST * 2); 15734 format %{ "cselw $dst, $src1, $src2 gt\t" %} 15735 15736 ins_encode %{ 15737 __ cselw(as_Register($dst$$reg), 15738 as_Register($src1$$reg), 15739 as_Register($src2$$reg), 15740 Assembler::GT); 15741 %} 15742 15743 ins_pipe(icond_reg_reg); 15744%} 15745 15746instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 15747%{ 15748 match(Set dst (MaxI src1 src2)); 15749 ins_cost(INSN_COST * 3); 15750 expand %{ 15751 rFlagsReg cr; 15752 compI_reg_reg(cr, src1, src2); 15753 cmovI_reg_reg_gt(dst, src1, src2, cr); 15754 %} 15755%} 15756 15757// ============================================================================ 15758// Branch Instructions 15759 15760// Direct Branch. 15761instruct branch(label lbl) 15762%{ 15763 match(Goto); 15764 15765 effect(USE lbl); 15766 15767 ins_cost(BRANCH_COST); 15768 format %{ "b $lbl" %} 15769 15770 ins_encode(aarch64_enc_b(lbl)); 15771 15772 ins_pipe(pipe_branch); 15773%} 15774 15775// Conditional Near Branch 15776instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 15777%{ 15778 // Same match rule as `branchConFar'. 15779 match(If cmp cr); 15780 15781 effect(USE lbl); 15782 15783 ins_cost(BRANCH_COST); 15784 // If set to 1 this indicates that the current instruction is a 15785 // short variant of a long branch. This avoids using this 15786 // instruction in first-pass matching. It will then only be used in 15787 // the `Shorten_branches' pass. 15788 // ins_short_branch(1); 15789 format %{ "b$cmp $lbl" %} 15790 15791 ins_encode(aarch64_enc_br_con(cmp, lbl)); 15792 15793 ins_pipe(pipe_branch_cond); 15794%} 15795 15796// Conditional Near Branch Unsigned 15797instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 15798%{ 15799 // Same match rule as `branchConFar'. 15800 match(If cmp cr); 15801 15802 effect(USE lbl); 15803 15804 ins_cost(BRANCH_COST); 15805 // If set to 1 this indicates that the current instruction is a 15806 // short variant of a long branch. This avoids using this 15807 // instruction in first-pass matching. It will then only be used in 15808 // the `Shorten_branches' pass. 15809 // ins_short_branch(1); 15810 format %{ "b$cmp $lbl\t# unsigned" %} 15811 15812 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 15813 15814 ins_pipe(pipe_branch_cond); 15815%} 15816 15817// Make use of CBZ and CBNZ. These instructions, as well as being 15818// shorter than (cmp; branch), have the additional benefit of not 15819// killing the flags. 15820 15821instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 15822 match(If cmp (CmpI op1 op2)); 15823 effect(USE labl); 15824 15825 ins_cost(BRANCH_COST); 15826 format %{ "cbw$cmp $op1, $labl" %} 15827 ins_encode %{ 15828 Label* L = $labl$$label; 15829 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15830 if (cond == Assembler::EQ) 15831 __ cbzw($op1$$Register, *L); 15832 else 15833 __ cbnzw($op1$$Register, *L); 15834 %} 15835 ins_pipe(pipe_cmp_branch); 15836%} 15837 15838instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 15839 match(If cmp (CmpL op1 op2)); 15840 effect(USE labl); 15841 15842 ins_cost(BRANCH_COST); 15843 format %{ "cb$cmp $op1, $labl" %} 15844 ins_encode %{ 15845 Label* L = $labl$$label; 15846 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15847 if (cond == Assembler::EQ) 15848 __ cbz($op1$$Register, *L); 15849 else 15850 __ cbnz($op1$$Register, *L); 15851 %} 15852 ins_pipe(pipe_cmp_branch); 15853%} 15854 15855instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 15856 match(If cmp (CmpP op1 op2)); 15857 effect(USE labl); 15858 15859 ins_cost(BRANCH_COST); 15860 format %{ "cb$cmp $op1, $labl" %} 15861 ins_encode %{ 15862 Label* L = $labl$$label; 15863 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15864 if (cond == Assembler::EQ) 15865 __ cbz($op1$$Register, *L); 15866 else 15867 __ cbnz($op1$$Register, *L); 15868 %} 15869 ins_pipe(pipe_cmp_branch); 15870%} 15871 15872instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 15873 match(If cmp (CmpN op1 op2)); 15874 effect(USE labl); 15875 15876 ins_cost(BRANCH_COST); 15877 format %{ "cbw$cmp $op1, $labl" %} 15878 ins_encode %{ 15879 Label* L = $labl$$label; 15880 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15881 if (cond == Assembler::EQ) 15882 __ cbzw($op1$$Register, *L); 15883 else 15884 __ cbnzw($op1$$Register, *L); 15885 %} 15886 ins_pipe(pipe_cmp_branch); 15887%} 15888 15889instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 15890 match(If cmp (CmpP (DecodeN oop) zero)); 15891 effect(USE labl); 15892 15893 ins_cost(BRANCH_COST); 15894 format %{ "cb$cmp $oop, $labl" %} 15895 ins_encode %{ 15896 Label* L = $labl$$label; 15897 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15898 if (cond == Assembler::EQ) 15899 __ cbzw($oop$$Register, *L); 15900 else 15901 __ cbnzw($oop$$Register, *L); 15902 %} 15903 ins_pipe(pipe_cmp_branch); 15904%} 15905 15906instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 15907 match(If cmp (CmpU op1 op2)); 15908 effect(USE labl); 15909 15910 ins_cost(BRANCH_COST); 15911 format %{ "cbw$cmp $op1, $labl" %} 15912 ins_encode %{ 15913 Label* L = $labl$$label; 15914 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15915 if (cond == Assembler::EQ || cond == Assembler::LS) 15916 __ cbzw($op1$$Register, *L); 15917 else 15918 __ cbnzw($op1$$Register, *L); 15919 %} 15920 ins_pipe(pipe_cmp_branch); 15921%} 15922 15923instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 15924 match(If cmp (CmpUL op1 op2)); 15925 effect(USE labl); 15926 15927 ins_cost(BRANCH_COST); 15928 format %{ "cb$cmp $op1, $labl" %} 15929 ins_encode %{ 15930 Label* L = $labl$$label; 15931 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15932 if (cond == Assembler::EQ || cond == Assembler::LS) 15933 __ cbz($op1$$Register, *L); 15934 else 15935 __ cbnz($op1$$Register, *L); 15936 %} 15937 ins_pipe(pipe_cmp_branch); 15938%} 15939 15940// Test bit and Branch 15941 15942// Patterns for short (< 32KiB) variants 15943instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 15944 match(If cmp (CmpL op1 op2)); 15945 effect(USE labl); 15946 15947 ins_cost(BRANCH_COST); 15948 format %{ "cb$cmp $op1, $labl # long" %} 15949 ins_encode %{ 15950 Label* L = $labl$$label; 15951 Assembler::Condition cond = 15952 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15953 __ tbr(cond, $op1$$Register, 63, *L); 15954 %} 15955 ins_pipe(pipe_cmp_branch); 15956 ins_short_branch(1); 15957%} 15958 15959instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 15960 match(If cmp (CmpI op1 op2)); 15961 effect(USE labl); 15962 15963 ins_cost(BRANCH_COST); 15964 format %{ "cb$cmp $op1, $labl # int" %} 15965 ins_encode %{ 15966 Label* L = $labl$$label; 15967 Assembler::Condition cond = 15968 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 15969 __ tbr(cond, $op1$$Register, 31, *L); 15970 %} 15971 ins_pipe(pipe_cmp_branch); 15972 ins_short_branch(1); 15973%} 15974 15975instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 15976 match(If cmp (CmpL (AndL op1 op2) op3)); 15977 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 15978 effect(USE labl); 15979 15980 ins_cost(BRANCH_COST); 15981 format %{ "tb$cmp $op1, $op2, $labl" %} 15982 ins_encode %{ 15983 Label* L = $labl$$label; 15984 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15985 int bit = exact_log2_long($op2$$constant); 15986 __ tbr(cond, $op1$$Register, bit, *L); 15987 %} 15988 ins_pipe(pipe_cmp_branch); 15989 ins_short_branch(1); 15990%} 15991 15992instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 15993 match(If cmp (CmpI (AndI op1 op2) op3)); 15994 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 15995 effect(USE labl); 15996 15997 ins_cost(BRANCH_COST); 15998 format %{ "tb$cmp $op1, $op2, $labl" %} 15999 ins_encode %{ 16000 Label* L = $labl$$label; 16001 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16002 int bit = exact_log2((juint)$op2$$constant); 16003 __ tbr(cond, $op1$$Register, bit, *L); 16004 %} 16005 ins_pipe(pipe_cmp_branch); 16006 ins_short_branch(1); 16007%} 16008 16009// And far variants 16010instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16011 match(If cmp (CmpL op1 op2)); 16012 effect(USE labl); 16013 16014 ins_cost(BRANCH_COST); 16015 format %{ "cb$cmp $op1, $labl # long" %} 16016 ins_encode %{ 16017 Label* L = $labl$$label; 16018 Assembler::Condition cond = 16019 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16020 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 16021 %} 16022 ins_pipe(pipe_cmp_branch); 16023%} 16024 16025instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16026 match(If cmp (CmpI op1 op2)); 16027 effect(USE labl); 16028 16029 ins_cost(BRANCH_COST); 16030 format %{ "cb$cmp $op1, $labl # int" %} 16031 ins_encode %{ 16032 Label* L = $labl$$label; 16033 Assembler::Condition cond = 16034 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16035 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 16036 %} 16037 ins_pipe(pipe_cmp_branch); 16038%} 16039 16040instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16041 match(If cmp (CmpL (AndL op1 op2) op3)); 16042 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16043 effect(USE labl); 16044 16045 ins_cost(BRANCH_COST); 16046 format %{ "tb$cmp $op1, $op2, $labl" %} 16047 ins_encode %{ 16048 Label* L = $labl$$label; 16049 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16050 int bit = exact_log2_long($op2$$constant); 16051 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16052 %} 16053 ins_pipe(pipe_cmp_branch); 16054%} 16055 16056instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16057 match(If cmp (CmpI (AndI op1 op2) op3)); 16058 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16059 effect(USE labl); 16060 16061 ins_cost(BRANCH_COST); 16062 format %{ "tb$cmp $op1, $op2, $labl" %} 16063 ins_encode %{ 16064 Label* L = $labl$$label; 16065 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16066 int bit = exact_log2((juint)$op2$$constant); 16067 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16068 %} 16069 ins_pipe(pipe_cmp_branch); 16070%} 16071 16072// Test bits 16073 16074instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 16075 match(Set cr (CmpL (AndL op1 op2) op3)); 16076 predicate(Assembler::operand_valid_for_logical_immediate 16077 (/*is_32*/false, n->in(1)->in(2)->get_long())); 16078 16079 ins_cost(INSN_COST); 16080 format %{ "tst $op1, $op2 # long" %} 16081 ins_encode %{ 16082 __ tst($op1$$Register, $op2$$constant); 16083 %} 16084 ins_pipe(ialu_reg_reg); 16085%} 16086 16087instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 16088 match(Set cr (CmpI (AndI op1 op2) op3)); 16089 predicate(Assembler::operand_valid_for_logical_immediate 16090 (/*is_32*/true, n->in(1)->in(2)->get_int())); 16091 16092 ins_cost(INSN_COST); 16093 format %{ "tst $op1, $op2 # int" %} 16094 ins_encode %{ 16095 __ tstw($op1$$Register, $op2$$constant); 16096 %} 16097 ins_pipe(ialu_reg_reg); 16098%} 16099 16100instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 16101 match(Set cr (CmpL (AndL op1 op2) op3)); 16102 16103 ins_cost(INSN_COST); 16104 format %{ "tst $op1, $op2 # long" %} 16105 ins_encode %{ 16106 __ tst($op1$$Register, $op2$$Register); 16107 %} 16108 ins_pipe(ialu_reg_reg); 16109%} 16110 16111instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 16112 match(Set cr (CmpI (AndI op1 op2) op3)); 16113 16114 ins_cost(INSN_COST); 16115 format %{ "tstw $op1, $op2 # int" %} 16116 ins_encode %{ 16117 __ tstw($op1$$Register, $op2$$Register); 16118 %} 16119 ins_pipe(ialu_reg_reg); 16120%} 16121 16122 16123// Conditional Far Branch 16124// Conditional Far Branch Unsigned 16125// TODO: fixme 16126 16127// counted loop end branch near 16128instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 16129%{ 16130 match(CountedLoopEnd cmp cr); 16131 16132 effect(USE lbl); 16133 16134 ins_cost(BRANCH_COST); 16135 // short variant. 16136 // ins_short_branch(1); 16137 format %{ "b$cmp $lbl \t// counted loop end" %} 16138 16139 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16140 16141 ins_pipe(pipe_branch); 16142%} 16143 16144// counted loop end branch near Unsigned 16145instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 16146%{ 16147 match(CountedLoopEnd cmp cr); 16148 16149 effect(USE lbl); 16150 16151 ins_cost(BRANCH_COST); 16152 // short variant. 16153 // ins_short_branch(1); 16154 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 16155 16156 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 16157 16158 ins_pipe(pipe_branch); 16159%} 16160 16161// counted loop end branch far 16162// counted loop end branch far unsigned 16163// TODO: fixme 16164 16165// ============================================================================ 16166// inlined locking and unlocking 16167 16168instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16169%{ 16170 match(Set cr (FastLock object box)); 16171 effect(TEMP tmp, TEMP tmp2); 16172 16173 // TODO 16174 // identify correct cost 16175 ins_cost(5 * INSN_COST); 16176 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 16177 16178 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 16179 16180 ins_pipe(pipe_serial); 16181%} 16182 16183instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16184%{ 16185 match(Set cr (FastUnlock object box)); 16186 effect(TEMP tmp, TEMP tmp2); 16187 16188 ins_cost(5 * INSN_COST); 16189 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 16190 16191 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 16192 16193 ins_pipe(pipe_serial); 16194%} 16195 16196 16197// ============================================================================ 16198// Safepoint Instructions 16199 16200// TODO 16201// provide a near and far version of this code 16202 16203instruct safePoint(rFlagsReg cr, iRegP poll) 16204%{ 16205 match(SafePoint poll); 16206 effect(KILL cr); 16207 16208 format %{ 16209 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 16210 %} 16211 ins_encode %{ 16212 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 16213 %} 16214 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 16215%} 16216 16217 16218// ============================================================================ 16219// Procedure Call/Return Instructions 16220 16221// Call Java Static Instruction 16222 16223instruct CallStaticJavaDirect(method meth) 16224%{ 16225 match(CallStaticJava); 16226 16227 effect(USE meth); 16228 16229 ins_cost(CALL_COST); 16230 16231 format %{ "call,static $meth \t// ==> " %} 16232 16233 ins_encode(aarch64_enc_java_static_call(meth), 16234 aarch64_enc_call_epilog); 16235 16236 ins_pipe(pipe_class_call); 16237%} 16238 16239// TO HERE 16240 16241// Call Java Dynamic Instruction 16242instruct CallDynamicJavaDirect(method meth) 16243%{ 16244 match(CallDynamicJava); 16245 16246 effect(USE meth); 16247 16248 ins_cost(CALL_COST); 16249 16250 format %{ "CALL,dynamic $meth \t// ==> " %} 16251 16252 ins_encode(aarch64_enc_java_dynamic_call(meth), 16253 aarch64_enc_call_epilog); 16254 16255 ins_pipe(pipe_class_call); 16256%} 16257 16258// Call Runtime Instruction 16259 16260instruct CallRuntimeDirect(method meth) 16261%{ 16262 match(CallRuntime); 16263 16264 effect(USE meth); 16265 16266 ins_cost(CALL_COST); 16267 16268 format %{ "CALL, runtime $meth" %} 16269 16270 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16271 16272 ins_pipe(pipe_class_call); 16273%} 16274 16275// Call Runtime Instruction 16276 16277instruct CallLeafDirect(method meth) 16278%{ 16279 match(CallLeaf); 16280 16281 effect(USE meth); 16282 16283 ins_cost(CALL_COST); 16284 16285 format %{ "CALL, runtime leaf $meth" %} 16286 16287 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16288 16289 ins_pipe(pipe_class_call); 16290%} 16291 16292// Call Runtime Instruction 16293 16294instruct CallLeafNoFPDirect(method meth) 16295%{ 16296 match(CallLeafNoFP); 16297 16298 effect(USE meth); 16299 16300 ins_cost(CALL_COST); 16301 16302 format %{ "CALL, runtime leaf nofp $meth" %} 16303 16304 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16305 16306 ins_pipe(pipe_class_call); 16307%} 16308 16309instruct CallNativeDirect(method meth) 16310%{ 16311 match(CallNative); 16312 16313 effect(USE meth); 16314 16315 ins_cost(CALL_COST); 16316 16317 format %{ "CALL, native $meth" %} 16318 16319 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16320 16321 ins_pipe(pipe_class_call); 16322%} 16323 16324// Tail Call; Jump from runtime stub to Java code. 16325// Also known as an 'interprocedural jump'. 16326// Target of jump will eventually return to caller. 16327// TailJump below removes the return address. 16328instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr) 16329%{ 16330 match(TailCall jump_target method_ptr); 16331 16332 ins_cost(CALL_COST); 16333 16334 format %{ "br $jump_target\t# $method_ptr holds method" %} 16335 16336 ins_encode(aarch64_enc_tail_call(jump_target)); 16337 16338 ins_pipe(pipe_class_call); 16339%} 16340 16341instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 16342%{ 16343 match(TailJump jump_target ex_oop); 16344 16345 ins_cost(CALL_COST); 16346 16347 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 16348 16349 ins_encode(aarch64_enc_tail_jmp(jump_target)); 16350 16351 ins_pipe(pipe_class_call); 16352%} 16353 16354// Create exception oop: created by stack-crawling runtime code. 16355// Created exception is now available to this handler, and is setup 16356// just prior to jumping to this handler. No code emitted. 16357// TODO check 16358// should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 16359instruct CreateException(iRegP_R0 ex_oop) 16360%{ 16361 match(Set ex_oop (CreateEx)); 16362 16363 format %{ " -- \t// exception oop; no code emitted" %} 16364 16365 size(0); 16366 16367 ins_encode( /*empty*/ ); 16368 16369 ins_pipe(pipe_class_empty); 16370%} 16371 16372// Rethrow exception: The exception oop will come in the first 16373// argument position. Then JUMP (not call) to the rethrow stub code. 16374instruct RethrowException() %{ 16375 match(Rethrow); 16376 ins_cost(CALL_COST); 16377 16378 format %{ "b rethrow_stub" %} 16379 16380 ins_encode( aarch64_enc_rethrow() ); 16381 16382 ins_pipe(pipe_class_call); 16383%} 16384 16385 16386// Return Instruction 16387// epilog node loads ret address into lr as part of frame pop 16388instruct Ret() 16389%{ 16390 match(Return); 16391 16392 format %{ "ret\t// return register" %} 16393 16394 ins_encode( aarch64_enc_ret() ); 16395 16396 ins_pipe(pipe_branch); 16397%} 16398 16399// Die now. 16400instruct ShouldNotReachHere() %{ 16401 match(Halt); 16402 16403 ins_cost(CALL_COST); 16404 format %{ "ShouldNotReachHere" %} 16405 16406 ins_encode %{ 16407 if (is_reachable()) { 16408 __ stop(_halt_reason); 16409 } 16410 %} 16411 16412 ins_pipe(pipe_class_default); 16413%} 16414 16415// ============================================================================ 16416// Partial Subtype Check 16417// 16418// superklass array for an instance of the superklass. Set a hidden 16419// internal cache on a hit (cache is checked with exposed code in 16420// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 16421// encoding ALSO sets flags. 16422 16423instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 16424%{ 16425 match(Set result (PartialSubtypeCheck sub super)); 16426 effect(KILL cr, KILL temp); 16427 16428 ins_cost(1100); // slightly larger than the next version 16429 format %{ "partialSubtypeCheck $result, $sub, $super" %} 16430 16431 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16432 16433 opcode(0x1); // Force zero of result reg on hit 16434 16435 ins_pipe(pipe_class_memory); 16436%} 16437 16438instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 16439%{ 16440 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 16441 effect(KILL temp, KILL result); 16442 16443 ins_cost(1100); // slightly larger than the next version 16444 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 16445 16446 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16447 16448 opcode(0x0); // Don't zero result reg on hit 16449 16450 ins_pipe(pipe_class_memory); 16451%} 16452 16453instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16454 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16455%{ 16456 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 16457 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16458 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16459 16460 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16461 ins_encode %{ 16462 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16463 __ string_compare($str1$$Register, $str2$$Register, 16464 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16465 $tmp1$$Register, $tmp2$$Register, 16466 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU); 16467 %} 16468 ins_pipe(pipe_class_memory); 16469%} 16470 16471instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16472 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16473%{ 16474 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 16475 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16476 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16477 16478 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16479 ins_encode %{ 16480 __ string_compare($str1$$Register, $str2$$Register, 16481 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16482 $tmp1$$Register, $tmp2$$Register, 16483 fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL); 16484 %} 16485 ins_pipe(pipe_class_memory); 16486%} 16487 16488instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16489 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16490 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16491%{ 16492 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 16493 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16494 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16495 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16496 16497 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16498 ins_encode %{ 16499 __ string_compare($str1$$Register, $str2$$Register, 16500 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16501 $tmp1$$Register, $tmp2$$Register, 16502 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16503 $vtmp3$$FloatRegister, StrIntrinsicNode::UL); 16504 %} 16505 ins_pipe(pipe_class_memory); 16506%} 16507 16508instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16509 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16510 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16511%{ 16512 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 16513 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16514 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16515 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16516 16517 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16518 ins_encode %{ 16519 __ string_compare($str1$$Register, $str2$$Register, 16520 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16521 $tmp1$$Register, $tmp2$$Register, 16522 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16523 $vtmp3$$FloatRegister,StrIntrinsicNode::LU); 16524 %} 16525 ins_pipe(pipe_class_memory); 16526%} 16527 16528instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16529 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16530 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 16531%{ 16532 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16533 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16534 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16535 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 16536 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 16537 16538 ins_encode %{ 16539 __ string_indexof($str1$$Register, $str2$$Register, 16540 $cnt1$$Register, $cnt2$$Register, 16541 $tmp1$$Register, $tmp2$$Register, 16542 $tmp3$$Register, $tmp4$$Register, 16543 $tmp5$$Register, $tmp6$$Register, 16544 -1, $result$$Register, StrIntrinsicNode::UU); 16545 %} 16546 ins_pipe(pipe_class_memory); 16547%} 16548 16549instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16550 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16551 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 16552%{ 16553 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16554 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16555 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16556 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 16557 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 16558 16559 ins_encode %{ 16560 __ string_indexof($str1$$Register, $str2$$Register, 16561 $cnt1$$Register, $cnt2$$Register, 16562 $tmp1$$Register, $tmp2$$Register, 16563 $tmp3$$Register, $tmp4$$Register, 16564 $tmp5$$Register, $tmp6$$Register, 16565 -1, $result$$Register, StrIntrinsicNode::LL); 16566 %} 16567 ins_pipe(pipe_class_memory); 16568%} 16569 16570instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16571 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16572 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 16573%{ 16574 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16575 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16576 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16577 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 16578 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 16579 16580 ins_encode %{ 16581 __ string_indexof($str1$$Register, $str2$$Register, 16582 $cnt1$$Register, $cnt2$$Register, 16583 $tmp1$$Register, $tmp2$$Register, 16584 $tmp3$$Register, $tmp4$$Register, 16585 $tmp5$$Register, $tmp6$$Register, 16586 -1, $result$$Register, StrIntrinsicNode::UL); 16587 %} 16588 ins_pipe(pipe_class_memory); 16589%} 16590 16591instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16592 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16593 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16594%{ 16595 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16596 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16597 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16598 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16599 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 16600 16601 ins_encode %{ 16602 int icnt2 = (int)$int_cnt2$$constant; 16603 __ string_indexof($str1$$Register, $str2$$Register, 16604 $cnt1$$Register, zr, 16605 $tmp1$$Register, $tmp2$$Register, 16606 $tmp3$$Register, $tmp4$$Register, zr, zr, 16607 icnt2, $result$$Register, StrIntrinsicNode::UU); 16608 %} 16609 ins_pipe(pipe_class_memory); 16610%} 16611 16612instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16613 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16614 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16615%{ 16616 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16617 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16618 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16619 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16620 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 16621 16622 ins_encode %{ 16623 int icnt2 = (int)$int_cnt2$$constant; 16624 __ string_indexof($str1$$Register, $str2$$Register, 16625 $cnt1$$Register, zr, 16626 $tmp1$$Register, $tmp2$$Register, 16627 $tmp3$$Register, $tmp4$$Register, zr, zr, 16628 icnt2, $result$$Register, StrIntrinsicNode::LL); 16629 %} 16630 ins_pipe(pipe_class_memory); 16631%} 16632 16633instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 16634 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16635 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 16636%{ 16637 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 16638 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 16639 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 16640 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 16641 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 16642 16643 ins_encode %{ 16644 int icnt2 = (int)$int_cnt2$$constant; 16645 __ string_indexof($str1$$Register, $str2$$Register, 16646 $cnt1$$Register, zr, 16647 $tmp1$$Register, $tmp2$$Register, 16648 $tmp3$$Register, $tmp4$$Register, zr, zr, 16649 icnt2, $result$$Register, StrIntrinsicNode::UL); 16650 %} 16651 ins_pipe(pipe_class_memory); 16652%} 16653 16654instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16655 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16656 iRegINoSp tmp3, rFlagsReg cr) 16657%{ 16658 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16659 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 16660 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 16661 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16662 16663 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 16664 16665 ins_encode %{ 16666 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 16667 $result$$Register, $tmp1$$Register, $tmp2$$Register, 16668 $tmp3$$Register); 16669 %} 16670 ins_pipe(pipe_class_memory); 16671%} 16672 16673instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 16674 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16675 iRegINoSp tmp3, rFlagsReg cr) 16676%{ 16677 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 16678 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 16679 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 16680 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16681 16682 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 16683 16684 ins_encode %{ 16685 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 16686 $result$$Register, $tmp1$$Register, $tmp2$$Register, 16687 $tmp3$$Register); 16688 %} 16689 ins_pipe(pipe_class_memory); 16690%} 16691 16692instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 16693 iRegI_R0 result, rFlagsReg cr) 16694%{ 16695 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 16696 match(Set result (StrEquals (Binary str1 str2) cnt)); 16697 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 16698 16699 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 16700 ins_encode %{ 16701 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16702 __ string_equals($str1$$Register, $str2$$Register, 16703 $result$$Register, $cnt$$Register, 1); 16704 %} 16705 ins_pipe(pipe_class_memory); 16706%} 16707 16708instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 16709 iRegI_R0 result, rFlagsReg cr) 16710%{ 16711 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 16712 match(Set result (StrEquals (Binary str1 str2) cnt)); 16713 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 16714 16715 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 16716 ins_encode %{ 16717 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16718 __ string_equals($str1$$Register, $str2$$Register, 16719 $result$$Register, $cnt$$Register, 2); 16720 %} 16721 ins_pipe(pipe_class_memory); 16722%} 16723 16724instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 16725 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 16726 iRegP_R10 tmp, rFlagsReg cr) 16727%{ 16728 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 16729 match(Set result (AryEq ary1 ary2)); 16730 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16731 16732 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 16733 ins_encode %{ 16734 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 16735 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 16736 $result$$Register, $tmp$$Register, 1); 16737 if (tpc == NULL) { 16738 ciEnv::current()->record_failure("CodeCache is full"); 16739 return; 16740 } 16741 %} 16742 ins_pipe(pipe_class_memory); 16743%} 16744 16745instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 16746 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 16747 iRegP_R10 tmp, rFlagsReg cr) 16748%{ 16749 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 16750 match(Set result (AryEq ary1 ary2)); 16751 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 16752 16753 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 16754 ins_encode %{ 16755 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 16756 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 16757 $result$$Register, $tmp$$Register, 2); 16758 if (tpc == NULL) { 16759 ciEnv::current()->record_failure("CodeCache is full"); 16760 return; 16761 } 16762 %} 16763 ins_pipe(pipe_class_memory); 16764%} 16765 16766instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 16767%{ 16768 match(Set result (HasNegatives ary1 len)); 16769 effect(USE_KILL ary1, USE_KILL len, KILL cr); 16770 format %{ "has negatives byte[] $ary1,$len -> $result" %} 16771 ins_encode %{ 16772 address tpc = __ has_negatives($ary1$$Register, $len$$Register, $result$$Register); 16773 if (tpc == NULL) { 16774 ciEnv::current()->record_failure("CodeCache is full"); 16775 return; 16776 } 16777 %} 16778 ins_pipe( pipe_slow ); 16779%} 16780 16781// fast char[] to byte[] compression 16782instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16783 vRegD_V0 tmp1, vRegD_V1 tmp2, 16784 vRegD_V2 tmp3, vRegD_V3 tmp4, 16785 iRegI_R0 result, rFlagsReg cr) 16786%{ 16787 match(Set result (StrCompressedCopy src (Binary dst len))); 16788 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 16789 16790 format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} 16791 ins_encode %{ 16792 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 16793 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 16794 $tmp3$$FloatRegister, $tmp4$$FloatRegister, 16795 $result$$Register); 16796 %} 16797 ins_pipe( pipe_slow ); 16798%} 16799 16800// fast byte[] to char[] inflation 16801instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, 16802 vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) 16803%{ 16804 match(Set dummy (StrInflatedCopy src (Binary dst len))); 16805 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 16806 16807 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 16808 ins_encode %{ 16809 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 16810 $tmp1$$FloatRegister, $tmp2$$FloatRegister, 16811 $tmp3$$FloatRegister, $tmp4$$Register); 16812 if (tpc == NULL) { 16813 ciEnv::current()->record_failure("CodeCache is full"); 16814 return; 16815 } 16816 %} 16817 ins_pipe(pipe_class_memory); 16818%} 16819 16820// encode char[] to byte[] in ISO_8859_1 16821instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 16822 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 16823 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 16824 iRegI_R0 result, rFlagsReg cr) 16825%{ 16826 match(Set result (EncodeISOArray src (Binary dst len))); 16827 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 16828 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 16829 16830 format %{ "Encode array $src,$dst,$len -> $result" %} 16831 ins_encode %{ 16832 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 16833 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 16834 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 16835 %} 16836 ins_pipe( pipe_class_memory ); 16837%} 16838 16839// ============================================================================ 16840// This name is KNOWN by the ADLC and cannot be changed. 16841// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 16842// for this guy. 16843instruct tlsLoadP(thread_RegP dst) 16844%{ 16845 match(Set dst (ThreadLocal)); 16846 16847 ins_cost(0); 16848 16849 format %{ " -- \t// $dst=Thread::current(), empty" %} 16850 16851 size(0); 16852 16853 ins_encode( /*empty*/ ); 16854 16855 ins_pipe(pipe_class_empty); 16856%} 16857 16858//----------PEEPHOLE RULES----------------------------------------------------- 16859// These must follow all instruction definitions as they use the names 16860// defined in the instructions definitions. 16861// 16862// peepmatch ( root_instr_name [preceding_instruction]* ); 16863// 16864// peepconstraint %{ 16865// (instruction_number.operand_name relational_op instruction_number.operand_name 16866// [, ...] ); 16867// // instruction numbers are zero-based using left to right order in peepmatch 16868// 16869// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 16870// // provide an instruction_number.operand_name for each operand that appears 16871// // in the replacement instruction's match rule 16872// 16873// ---------VM FLAGS--------------------------------------------------------- 16874// 16875// All peephole optimizations can be turned off using -XX:-OptoPeephole 16876// 16877// Each peephole rule is given an identifying number starting with zero and 16878// increasing by one in the order seen by the parser. An individual peephole 16879// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 16880// on the command-line. 16881// 16882// ---------CURRENT LIMITATIONS---------------------------------------------- 16883// 16884// Only match adjacent instructions in same basic block 16885// Only equality constraints 16886// Only constraints between operands, not (0.dest_reg == RAX_enc) 16887// Only one replacement instruction 16888// 16889// ---------EXAMPLE---------------------------------------------------------- 16890// 16891// // pertinent parts of existing instructions in architecture description 16892// instruct movI(iRegINoSp dst, iRegI src) 16893// %{ 16894// match(Set dst (CopyI src)); 16895// %} 16896// 16897// instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 16898// %{ 16899// match(Set dst (AddI dst src)); 16900// effect(KILL cr); 16901// %} 16902// 16903// // Change (inc mov) to lea 16904// peephole %{ 16905// // increment preceeded by register-register move 16906// peepmatch ( incI_iReg movI ); 16907// // require that the destination register of the increment 16908// // match the destination register of the move 16909// peepconstraint ( 0.dst == 1.dst ); 16910// // construct a replacement instruction that sets 16911// // the destination to ( move's source register + one ) 16912// peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 16913// %} 16914// 16915 16916// Implementation no longer uses movX instructions since 16917// machine-independent system no longer uses CopyX nodes. 16918// 16919// peephole 16920// %{ 16921// peepmatch (incI_iReg movI); 16922// peepconstraint (0.dst == 1.dst); 16923// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16924// %} 16925 16926// peephole 16927// %{ 16928// peepmatch (decI_iReg movI); 16929// peepconstraint (0.dst == 1.dst); 16930// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16931// %} 16932 16933// peephole 16934// %{ 16935// peepmatch (addI_iReg_imm movI); 16936// peepconstraint (0.dst == 1.dst); 16937// peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 16938// %} 16939 16940// peephole 16941// %{ 16942// peepmatch (incL_iReg movL); 16943// peepconstraint (0.dst == 1.dst); 16944// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16945// %} 16946 16947// peephole 16948// %{ 16949// peepmatch (decL_iReg movL); 16950// peepconstraint (0.dst == 1.dst); 16951// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16952// %} 16953 16954// peephole 16955// %{ 16956// peepmatch (addL_iReg_imm movL); 16957// peepconstraint (0.dst == 1.dst); 16958// peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 16959// %} 16960 16961// peephole 16962// %{ 16963// peepmatch (addP_iReg_imm movP); 16964// peepconstraint (0.dst == 1.dst); 16965// peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 16966// %} 16967 16968// // Change load of spilled value to only a spill 16969// instruct storeI(memory mem, iRegI src) 16970// %{ 16971// match(Set mem (StoreI mem src)); 16972// %} 16973// 16974// instruct loadI(iRegINoSp dst, memory mem) 16975// %{ 16976// match(Set dst (LoadI mem)); 16977// %} 16978// 16979 16980//----------SMARTSPILL RULES--------------------------------------------------- 16981// These must follow all instruction definitions as they use the names 16982// defined in the instructions definitions. 16983 16984// Local Variables: 16985// mode: c++ 16986// End: 16987