1 // 2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, Red Hat Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 167 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 168 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 169 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 170 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 171 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 172 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 173 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 174 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 175 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 176 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 177 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 178 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 179 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 180 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() ); 181 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() ); 182 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() ); 183 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() ); 184 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() ); 185 reg_def V10_H( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next()); 186 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() ); 187 reg_def V11_H( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next()); 188 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() ); 189 reg_def V12_H( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next()); 190 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() ); 191 reg_def V13_H( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next()); 192 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() ); 193 reg_def V14_H( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next()); 194 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() ); 195 reg_def V15_H( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next()); 196 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 197 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next()); 198 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 199 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next()); 200 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 201 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next()); 202 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 203 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next()); 204 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 205 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next()); 206 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 207 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next()); 208 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 209 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next()); 210 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 211 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next()); 212 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 213 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next()); 214 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 215 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next()); 216 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 217 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next()); 218 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 219 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next()); 220 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 221 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next()); 222 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 223 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next()); 224 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 225 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next()); 226 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 227 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // the AArch64 CSPR status flag register is not directly acessible as 234 // instruction operand. the FPSR status flag register is a system 235 // register which can be written/read using MSR/MRS but again does not 236 // appear as an operand (a code identifying the FSPR occurs as an 237 // immediate value in the instruction). 238 239 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 240 241 242 // Specify priority of register selection within phases of register 243 // allocation. Highest priority is first. A useful heuristic is to 244 // give registers a low priority when they are required by machine 245 // instructions, like EAX and EDX on I486, and choose no-save registers 246 // before save-on-call, & save-on-call before save-on-entry. Registers 247 // which participate in fixed calling sequences should come last. 248 // Registers which are used as pairs must fall on an even boundary. 249 250 alloc_class chunk0( 251 // volatiles 252 R10, R10_H, 253 R11, R11_H, 254 R12, R12_H, 255 R13, R13_H, 256 R14, R14_H, 257 R15, R15_H, 258 R16, R16_H, 259 R17, R17_H, 260 R18, R18_H, 261 262 // arg registers 263 R0, R0_H, 264 R1, R1_H, 265 R2, R2_H, 266 R3, R3_H, 267 R4, R4_H, 268 R5, R5_H, 269 R6, R6_H, 270 R7, R7_H, 271 272 // non-volatiles 273 R19, R19_H, 274 R20, R20_H, 275 R21, R21_H, 276 R22, R22_H, 277 R23, R23_H, 278 R24, R24_H, 279 R25, R25_H, 280 R26, R26_H, 281 282 // non-allocatable registers 283 284 R27, R27_H, // heapbase 285 R28, R28_H, // thread 286 R29, R29_H, // fp 287 R30, R30_H, // lr 288 R31, R31_H, // sp 289 ); 290 291 alloc_class chunk1( 292 293 // no save 294 V16, V16_H, 295 V17, V17_H, 296 V18, V18_H, 297 V19, V19_H, 298 V20, V20_H, 299 V21, V21_H, 300 V22, V22_H, 301 V23, V23_H, 302 V24, V24_H, 303 V25, V25_H, 304 V26, V26_H, 305 V27, V27_H, 306 V28, V28_H, 307 V29, V29_H, 308 V30, V30_H, 309 V31, V31_H, 310 311 // arg registers 312 V0, V0_H, 313 V1, V1_H, 314 V2, V2_H, 315 V3, V3_H, 316 V4, V4_H, 317 V5, V5_H, 318 V6, V6_H, 319 V7, V7_H, 320 321 // non-volatiles 322 V8, V8_H, 323 V9, V9_H, 324 V10, V10_H, 325 V11, V11_H, 326 V12, V12_H, 327 V13, V13_H, 328 V14, V14_H, 329 V15, V15_H, 330 ); 331 332 alloc_class chunk2(RFLAGS); 333 334 //----------Architecture Description Register Classes-------------------------- 335 // Several register classes are automatically defined based upon information in 336 // this architecture description. 337 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 338 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 339 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 340 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 341 // 342 343 // Class for all 32 bit integer registers -- excludes SP which will 344 // never be used as an integer register 345 reg_class any_reg32( 346 R0, 347 R1, 348 R2, 349 R3, 350 R4, 351 R5, 352 R6, 353 R7, 354 R10, 355 R11, 356 R12, 357 R13, 358 R14, 359 R15, 360 R16, 361 R17, 362 R18, 363 R19, 364 R20, 365 R21, 366 R22, 367 R23, 368 R24, 369 R25, 370 R26, 371 R27, 372 R28, 373 R29, 374 R30 375 ); 376 377 // Singleton class for R0 int register 378 reg_class int_r0_reg(R0); 379 380 // Singleton class for R2 int register 381 reg_class int_r2_reg(R2); 382 383 // Singleton class for R3 int register 384 reg_class int_r3_reg(R3); 385 386 // Singleton class for R4 int register 387 reg_class int_r4_reg(R4); 388 389 // Class for all long integer registers (including RSP) 390 reg_class any_reg( 391 R0, R0_H, 392 R1, R1_H, 393 R2, R2_H, 394 R3, R3_H, 395 R4, R4_H, 396 R5, R5_H, 397 R6, R6_H, 398 R7, R7_H, 399 R10, R10_H, 400 R11, R11_H, 401 R12, R12_H, 402 R13, R13_H, 403 R14, R14_H, 404 R15, R15_H, 405 R16, R16_H, 406 R17, R17_H, 407 R18, R18_H, 408 R19, R19_H, 409 R20, R20_H, 410 R21, R21_H, 411 R22, R22_H, 412 R23, R23_H, 413 R24, R24_H, 414 R25, R25_H, 415 R26, R26_H, 416 R27, R27_H, 417 R28, R28_H, 418 R29, R29_H, 419 R30, R30_H, 420 R31, R31_H 421 ); 422 423 // Class for all non-special integer registers 424 reg_class no_special_reg32( 425 R0, 426 R1, 427 R2, 428 R3, 429 R4, 430 R5, 431 R6, 432 R7, 433 R10, 434 R11, 435 R12, // rmethod 436 R13, 437 R14, 438 R15, 439 R16, 440 R17, 441 R18, 442 R19, 443 R20, 444 R21, 445 R22, 446 R23, 447 R24, 448 R25, 449 R26 450 /* R27, */ // heapbase 451 /* R28, */ // thread 452 /* R29, */ // fp 453 /* R30, */ // lr 454 /* R31 */ // sp 455 ); 456 457 // Class for all non-special long integer registers 458 reg_class no_special_reg( 459 R0, R0_H, 460 R1, R1_H, 461 R2, R2_H, 462 R3, R3_H, 463 R4, R4_H, 464 R5, R5_H, 465 R6, R6_H, 466 R7, R7_H, 467 R10, R10_H, 468 R11, R11_H, 469 R12, R12_H, // rmethod 470 R13, R13_H, 471 R14, R14_H, 472 R15, R15_H, 473 R16, R16_H, 474 R17, R17_H, 475 R18, R18_H, 476 R19, R19_H, 477 R20, R20_H, 478 R21, R21_H, 479 R22, R22_H, 480 R23, R23_H, 481 R24, R24_H, 482 R25, R25_H, 483 R26, R26_H, 484 /* R27, R27_H, */ // heapbase 485 /* R28, R28_H, */ // thread 486 /* R29, R29_H, */ // fp 487 /* R30, R30_H, */ // lr 488 /* R31, R31_H */ // sp 489 ); 490 491 // Class for 64 bit register r0 492 reg_class r0_reg( 493 R0, R0_H 494 ); 495 496 // Class for 64 bit register r1 497 reg_class r1_reg( 498 R1, R1_H 499 ); 500 501 // Class for 64 bit register r2 502 reg_class r2_reg( 503 R2, R2_H 504 ); 505 506 // Class for 64 bit register r3 507 reg_class r3_reg( 508 R3, R3_H 509 ); 510 511 // Class for 64 bit register r4 512 reg_class r4_reg( 513 R4, R4_H 514 ); 515 516 // Class for 64 bit register r5 517 reg_class r5_reg( 518 R5, R5_H 519 ); 520 521 // Class for 64 bit register r10 522 reg_class r10_reg( 523 R10, R10_H 524 ); 525 526 // Class for 64 bit register r11 527 reg_class r11_reg( 528 R11, R11_H 529 ); 530 531 // Class for method register 532 reg_class method_reg( 533 R12, R12_H 534 ); 535 536 // Class for heapbase register 537 reg_class heapbase_reg( 538 R27, R27_H 539 ); 540 541 // Class for thread register 542 reg_class thread_reg( 543 R28, R28_H 544 ); 545 546 // Class for frame pointer register 547 reg_class fp_reg( 548 R29, R29_H 549 ); 550 551 // Class for link register 552 reg_class lr_reg( 553 R30, R30_H 554 ); 555 556 // Class for long sp register 557 reg_class sp_reg( 558 R31, R31_H 559 ); 560 561 // Class for all pointer registers 562 reg_class ptr_reg( 563 R0, R0_H, 564 R1, R1_H, 565 R2, R2_H, 566 R3, R3_H, 567 R4, R4_H, 568 R5, R5_H, 569 R6, R6_H, 570 R7, R7_H, 571 R10, R10_H, 572 R11, R11_H, 573 R12, R12_H, 574 R13, R13_H, 575 R14, R14_H, 576 R15, R15_H, 577 R16, R16_H, 578 R17, R17_H, 579 R18, R18_H, 580 R19, R19_H, 581 R20, R20_H, 582 R21, R21_H, 583 R22, R22_H, 584 R23, R23_H, 585 R24, R24_H, 586 R25, R25_H, 587 R26, R26_H, 588 R27, R27_H, 589 R28, R28_H, 590 R29, R29_H, 591 R30, R30_H, 592 R31, R31_H 593 ); 594 595 // Class for all non_special pointer registers 596 reg_class no_special_ptr_reg( 597 R0, R0_H, 598 R1, R1_H, 599 R2, R2_H, 600 R3, R3_H, 601 R4, R4_H, 602 R5, R5_H, 603 R6, R6_H, 604 R7, R7_H, 605 R10, R10_H, 606 R11, R11_H, 607 R12, R12_H, 608 R13, R13_H, 609 R14, R14_H, 610 R15, R15_H, 611 R16, R16_H, 612 R17, R17_H, 613 R18, R18_H, 614 R19, R19_H, 615 R20, R20_H, 616 R21, R21_H, 617 R22, R22_H, 618 R23, R23_H, 619 R24, R24_H, 620 R25, R25_H, 621 R26, R26_H, 622 /* R27, R27_H, */ // heapbase 623 /* R28, R28_H, */ // thread 624 /* R29, R29_H, */ // fp 625 /* R30, R30_H, */ // lr 626 /* R31, R31_H */ // sp 627 ); 628 629 // Class for all float registers 630 reg_class float_reg( 631 V0, 632 V1, 633 V2, 634 V3, 635 V4, 636 V5, 637 V6, 638 V7, 639 V8, 640 V9, 641 V10, 642 V11, 643 V12, 644 V13, 645 V14, 646 V15, 647 V16, 648 V17, 649 V18, 650 V19, 651 V20, 652 V21, 653 V22, 654 V23, 655 V24, 656 V25, 657 V26, 658 V27, 659 V28, 660 V29, 661 V30, 662 V31 663 ); 664 665 // Double precision float registers have virtual `high halves' that 666 // are needed by the allocator. 667 // Class for all double registers 668 reg_class double_reg( 669 V0, V0_H, 670 V1, V1_H, 671 V2, V2_H, 672 V3, V3_H, 673 V4, V4_H, 674 V5, V5_H, 675 V6, V6_H, 676 V7, V7_H, 677 V8, V8_H, 678 V9, V9_H, 679 V10, V10_H, 680 V11, V11_H, 681 V12, V12_H, 682 V13, V13_H, 683 V14, V14_H, 684 V15, V15_H, 685 V16, V16_H, 686 V17, V17_H, 687 V18, V18_H, 688 V19, V19_H, 689 V20, V20_H, 690 V21, V21_H, 691 V22, V22_H, 692 V23, V23_H, 693 V24, V24_H, 694 V25, V25_H, 695 V26, V26_H, 696 V27, V27_H, 697 V28, V28_H, 698 V29, V29_H, 699 V30, V30_H, 700 V31, V31_H 701 ); 702 703 // Class for 128 bit register v0 704 reg_class v0_reg( 705 V0, V0_H 706 ); 707 708 // Class for 128 bit register v1 709 reg_class v1_reg( 710 V1, V1_H 711 ); 712 713 // Class for 128 bit register v2 714 reg_class v2_reg( 715 V2, V2_H 716 ); 717 718 // Class for 128 bit register v3 719 reg_class v3_reg( 720 V3, V3_H 721 ); 722 723 // Singleton class for condition codes 724 reg_class int_flags(RFLAGS); 725 726 %} 727 728 //----------DEFINITION BLOCK--------------------------------------------------- 729 // Define name --> value mappings to inform the ADLC of an integer valued name 730 // Current support includes integer values in the range [0, 0x7FFFFFFF] 731 // Format: 732 // int_def <name> ( <int_value>, <expression>); 733 // Generated Code in ad_<arch>.hpp 734 // #define <name> (<expression>) 735 // // value == <int_value> 736 // Generated code in ad_<arch>.cpp adlc_verification() 737 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 738 // 739 740 // we follow the ppc-aix port in using a simple cost model which ranks 741 // register operations as cheap, memory ops as more expensive and 742 // branches as most expensive. the first two have a low as well as a 743 // normal cost. huge cost appears to be a way of saying don't do 744 // something 745 746 definitions %{ 747 // The default cost (of a register move instruction). 748 int_def INSN_COST ( 100, 100); 749 int_def BRANCH_COST ( 200, 2 * INSN_COST); 750 int_def CALL_COST ( 200, 2 * INSN_COST); 751 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 752 %} 753 754 755 //----------SOURCE BLOCK------------------------------------------------------- 756 // This is a block of C++ code which provides values, functions, and 757 // definitions necessary in the rest of the architecture description 758 759 source_hpp %{ 760 761 class CallStubImpl { 762 763 //-------------------------------------------------------------- 764 //---< Used for optimization in Compile::shorten_branches >--- 765 //-------------------------------------------------------------- 766 767 public: 768 // Size of call trampoline stub. 769 static uint size_call_trampoline() { 770 return 0; // no call trampolines on this platform 771 } 772 773 // number of relocations needed by a call trampoline stub 774 static uint reloc_call_trampoline() { 775 return 0; // no call trampolines on this platform 776 } 777 }; 778 779 class HandlerImpl { 780 781 public: 782 783 static int emit_exception_handler(CodeBuffer &cbuf); 784 static int emit_deopt_handler(CodeBuffer& cbuf); 785 786 static uint size_exception_handler() { 787 return MacroAssembler::far_branch_size(); 788 } 789 790 static uint size_deopt_handler() { 791 // count one adr and one far branch instruction 792 return 4 * NativeInstruction::instruction_size; 793 } 794 }; 795 796 bool preceded_by_ordered_load(const Node *barrier); 797 798 // Use barrier instructions rather than load acquire / store 799 // release. 800 const bool UseBarriersForVolatile = true; 801 %} 802 803 source %{ 804 805 // AArch64 has load acquire and store release instructions which we 806 // use for ordered memory accesses, e.g. for volatiles. The ideal 807 // graph generator also inserts memory barriers around volatile 808 // accesses, and we don't want to generate both barriers and acq/rel 809 // instructions. So, when we emit a MemBarAcquire we look back in 810 // the ideal graph for an ordered load and only emit the barrier if 811 // we don't find one. 812 813 bool preceded_by_ordered_load(const Node *barrier) { 814 Node *x = barrier->lookup(TypeFunc::Parms); 815 816 if (! x) 817 return false; 818 819 if (x->is_DecodeNarrowPtr()) 820 x = x->in(1); 821 822 if (x->is_Load()) 823 return ! x->as_Load()->is_unordered(); 824 825 return false; 826 } 827 828 #define __ _masm. 829 830 // advance declarations for helper functions to convert register 831 // indices to register objects 832 833 // the ad file has to provide implementations of certain methods 834 // expected by the generic code 835 // 836 // REQUIRED FUNCTIONALITY 837 838 //============================================================================= 839 840 // !!!!! Special hack to get all types of calls to specify the byte offset 841 // from the start of the call to the point where the return address 842 // will point. 843 844 int MachCallStaticJavaNode::ret_addr_offset() 845 { 846 // call should be a simple bl 847 // unless this is a method handle invoke in which case it is 848 // mov(rfp, sp), bl, mov(sp, rfp) 849 int off = 4; 850 if (_method_handle_invoke) { 851 off += 4; 852 } 853 return off; 854 } 855 856 int MachCallDynamicJavaNode::ret_addr_offset() 857 { 858 return 16; // movz, movk, movk, bl 859 } 860 861 int MachCallRuntimeNode::ret_addr_offset() { 862 // for generated stubs the call will be 863 // far_call(addr) 864 // for real runtime callouts it will be six instructions 865 // see aarch64_enc_java_to_runtime 866 // adr(rscratch2, retaddr) 867 // lea(rscratch1, RuntimeAddress(addr) 868 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 869 // blrt rscratch1 870 CodeBlob *cb = CodeCache::find_blob(_entry_point); 871 if (cb) { 872 return MacroAssembler::far_branch_size(); 873 } else { 874 return 6 * NativeInstruction::instruction_size; 875 } 876 } 877 878 // Indicate if the safepoint node needs the polling page as an input 879 880 // the shared code plants the oop data at the start of the generated 881 // code for the safepoint node and that needs ot be at the load 882 // instruction itself. so we cannot plant a mov of the safepoint poll 883 // address followed by a load. setting this to true means the mov is 884 // scheduled as a prior instruction. that's better for scheduling 885 // anyway. 886 887 bool SafePointNode::needs_polling_address_input() 888 { 889 return true; 890 } 891 892 //============================================================================= 893 894 #ifndef PRODUCT 895 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 896 st->print("BREAKPOINT"); 897 } 898 #endif 899 900 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 901 MacroAssembler _masm(&cbuf); 902 __ brk(0); 903 } 904 905 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 906 return MachNode::size(ra_); 907 } 908 909 //============================================================================= 910 911 #ifndef PRODUCT 912 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 913 st->print("nop \t# %d bytes pad for loops and calls", _count); 914 } 915 #endif 916 917 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 918 MacroAssembler _masm(&cbuf); 919 for (int i = 0; i < _count; i++) { 920 __ nop(); 921 } 922 } 923 924 uint MachNopNode::size(PhaseRegAlloc*) const { 925 return _count * NativeInstruction::instruction_size; 926 } 927 928 //============================================================================= 929 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 930 931 int Compile::ConstantTable::calculate_table_base_offset() const { 932 return 0; // absolute addressing, no offset 933 } 934 935 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 936 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 937 ShouldNotReachHere(); 938 } 939 940 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 941 // Empty encoding 942 } 943 944 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 945 return 0; 946 } 947 948 #ifndef PRODUCT 949 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 950 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 951 } 952 #endif 953 954 #ifndef PRODUCT 955 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 956 Compile* C = ra_->C; 957 958 int framesize = C->frame_slots() << LogBytesPerInt; 959 960 if (C->need_stack_bang(framesize)) 961 st->print("# stack bang size=%d\n\t", framesize); 962 963 if (framesize == 0) { 964 // Is this even possible? 965 st->print("stp lr, rfp, [sp, #%d]!", -(2 * wordSize)); 966 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 967 st->print("sub sp, sp, #%d\n\t", framesize); 968 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 969 } else { 970 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 971 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 972 st->print("sub sp, sp, rscratch1"); 973 } 974 } 975 #endif 976 977 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 978 Compile* C = ra_->C; 979 MacroAssembler _masm(&cbuf); 980 981 // n.b. frame size includes space for return pc and rfp 982 const long framesize = C->frame_size_in_bytes(); 983 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 984 985 // insert a nop at the start of the prolog so we can patch in a 986 // branch if we need to invalidate the method later 987 __ nop(); 988 989 int bangsize = C->bang_size_in_bytes(); 990 if (C->need_stack_bang(bangsize) && UseStackBanging) 991 __ generate_stack_overflow_check(bangsize); 992 993 __ build_frame(framesize); 994 995 if (NotifySimulator) { 996 __ notify(Assembler::method_entry); 997 } 998 999 if (VerifyStackAtCalls) { 1000 Unimplemented(); 1001 } 1002 1003 C->set_frame_complete(cbuf.insts_size()); 1004 1005 if (C->has_mach_constant_base_node()) { 1006 // NOTE: We set the table base offset here because users might be 1007 // emitted before MachConstantBaseNode. 1008 Compile::ConstantTable& constant_table = C->constant_table(); 1009 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1010 } 1011 } 1012 1013 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1014 { 1015 return MachNode::size(ra_); // too many variables; just compute it 1016 // the hard way 1017 } 1018 1019 int MachPrologNode::reloc() const 1020 { 1021 return 0; 1022 } 1023 1024 //============================================================================= 1025 1026 #ifndef PRODUCT 1027 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1028 Compile* C = ra_->C; 1029 int framesize = C->frame_slots() << LogBytesPerInt; 1030 1031 st->print("# pop frame %d\n\t",framesize); 1032 1033 if (framesize == 0) { 1034 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1035 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1036 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1037 st->print("add sp, sp, #%d\n\t", framesize); 1038 } else { 1039 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1040 st->print("add sp, sp, rscratch1\n\t"); 1041 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1042 } 1043 1044 if (do_polling() && C->is_method_compilation()) { 1045 st->print("# touch polling page\n\t"); 1046 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1047 st->print("ldr zr, [rscratch1]"); 1048 } 1049 } 1050 #endif 1051 1052 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1053 Compile* C = ra_->C; 1054 MacroAssembler _masm(&cbuf); 1055 int framesize = C->frame_slots() << LogBytesPerInt; 1056 1057 __ remove_frame(framesize); 1058 1059 if (NotifySimulator) { 1060 __ notify(Assembler::method_reentry); 1061 } 1062 1063 if (do_polling() && C->is_method_compilation()) { 1064 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1065 } 1066 } 1067 1068 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1069 // Variable size. Determine dynamically. 1070 return MachNode::size(ra_); 1071 } 1072 1073 int MachEpilogNode::reloc() const { 1074 // Return number of relocatable values contained in this instruction. 1075 return 1; // 1 for polling page. 1076 } 1077 1078 const Pipeline * MachEpilogNode::pipeline() const { 1079 return MachNode::pipeline_class(); 1080 } 1081 1082 // This method seems to be obsolete. It is declared in machnode.hpp 1083 // and defined in all *.ad files, but it is never called. Should we 1084 // get rid of it? 1085 int MachEpilogNode::safepoint_offset() const { 1086 assert(do_polling(), "no return for this epilog node"); 1087 return 4; 1088 } 1089 1090 //============================================================================= 1091 1092 // Figure out which register class each belongs in: rc_int, rc_float or 1093 // rc_stack. 1094 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1095 1096 static enum RC rc_class(OptoReg::Name reg) { 1097 1098 if (reg == OptoReg::Bad) { 1099 return rc_bad; 1100 } 1101 1102 // we have 30 int registers * 2 halves 1103 // (rscratch1 and rscratch2 are omitted) 1104 1105 if (reg < 60) { 1106 return rc_int; 1107 } 1108 1109 // we have 32 float register * 2 halves 1110 if (reg < 60 + 64) { 1111 return rc_float; 1112 } 1113 1114 // Between float regs & stack is the flags regs. 1115 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1116 1117 return rc_stack; 1118 } 1119 1120 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1121 Compile* C = ra_->C; 1122 1123 // Get registers to move. 1124 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1125 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1126 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1127 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1128 1129 enum RC src_hi_rc = rc_class(src_hi); 1130 enum RC src_lo_rc = rc_class(src_lo); 1131 enum RC dst_hi_rc = rc_class(dst_hi); 1132 enum RC dst_lo_rc = rc_class(dst_lo); 1133 1134 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1135 1136 if (src_hi != OptoReg::Bad) { 1137 assert((src_lo&1)==0 && src_lo+1==src_hi && 1138 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1139 "expected aligned-adjacent pairs"); 1140 } 1141 1142 if (src_lo == dst_lo && src_hi == dst_hi) { 1143 return 0; // Self copy, no move. 1144 } 1145 1146 switch (src_lo_rc) { 1147 case rc_int: 1148 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1149 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1150 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1151 // 64 bit 1152 if (cbuf) { 1153 MacroAssembler _masm(cbuf); 1154 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1155 as_Register(Matcher::_regEncode[src_lo])); 1156 } else if (st) { 1157 st->print("mov %s, %s\t# shuffle", 1158 Matcher::regName[dst_lo], 1159 Matcher::regName[src_lo]); 1160 } 1161 } else { 1162 // 32 bit 1163 if (cbuf) { 1164 MacroAssembler _masm(cbuf); 1165 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1166 as_Register(Matcher::_regEncode[src_lo])); 1167 } else if (st) { 1168 st->print("movw %s, %s\t# shuffle", 1169 Matcher::regName[dst_lo], 1170 Matcher::regName[src_lo]); 1171 } 1172 } 1173 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1174 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1175 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1176 // 64 bit 1177 if (cbuf) { 1178 MacroAssembler _masm(cbuf); 1179 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1180 as_Register(Matcher::_regEncode[src_lo])); 1181 } else if (st) { 1182 st->print("fmovd %s, %s\t# shuffle", 1183 Matcher::regName[dst_lo], 1184 Matcher::regName[src_lo]); 1185 } 1186 } else { 1187 // 32 bit 1188 if (cbuf) { 1189 MacroAssembler _masm(cbuf); 1190 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1191 as_Register(Matcher::_regEncode[src_lo])); 1192 } else if (st) { 1193 st->print("fmovs %s, %s\t# shuffle", 1194 Matcher::regName[dst_lo], 1195 Matcher::regName[src_lo]); 1196 } 1197 } 1198 } else { // gpr --> stack spill 1199 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1200 int dst_offset = ra_->reg2offset(dst_lo); 1201 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1202 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1203 // 64 bit 1204 if (cbuf) { 1205 MacroAssembler _masm(cbuf); 1206 __ str(as_Register(Matcher::_regEncode[src_lo]), 1207 Address(sp, dst_offset)); 1208 } else if (st) { 1209 st->print("str %s, [sp, #%d]\t# spill", 1210 Matcher::regName[src_lo], 1211 dst_offset); 1212 } 1213 } else { 1214 // 32 bit 1215 if (cbuf) { 1216 MacroAssembler _masm(cbuf); 1217 __ strw(as_Register(Matcher::_regEncode[src_lo]), 1218 Address(sp, dst_offset)); 1219 } else if (st) { 1220 st->print("strw %s, [sp, #%d]\t# spill", 1221 Matcher::regName[src_lo], 1222 dst_offset); 1223 } 1224 } 1225 } 1226 return 4; 1227 case rc_float: 1228 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1229 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1230 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1231 // 64 bit 1232 if (cbuf) { 1233 MacroAssembler _masm(cbuf); 1234 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1235 as_FloatRegister(Matcher::_regEncode[src_lo])); 1236 } else if (st) { 1237 st->print("fmovd %s, %s\t# shuffle", 1238 Matcher::regName[dst_lo], 1239 Matcher::regName[src_lo]); 1240 } 1241 } else { 1242 // 32 bit 1243 if (cbuf) { 1244 MacroAssembler _masm(cbuf); 1245 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1246 as_FloatRegister(Matcher::_regEncode[src_lo])); 1247 } else if (st) { 1248 st->print("fmovs %s, %s\t# shuffle", 1249 Matcher::regName[dst_lo], 1250 Matcher::regName[src_lo]); 1251 } 1252 } 1253 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1254 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1255 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1256 // 64 bit 1257 if (cbuf) { 1258 MacroAssembler _masm(cbuf); 1259 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1260 as_FloatRegister(Matcher::_regEncode[src_lo])); 1261 } else if (st) { 1262 st->print("fmovd %s, %s\t# shuffle", 1263 Matcher::regName[dst_lo], 1264 Matcher::regName[src_lo]); 1265 } 1266 } else { 1267 // 32 bit 1268 if (cbuf) { 1269 MacroAssembler _masm(cbuf); 1270 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1271 as_FloatRegister(Matcher::_regEncode[src_lo])); 1272 } else if (st) { 1273 st->print("fmovs %s, %s\t# shuffle", 1274 Matcher::regName[dst_lo], 1275 Matcher::regName[src_lo]); 1276 } 1277 } 1278 } else { // fpr --> stack spill 1279 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1280 int dst_offset = ra_->reg2offset(dst_lo); 1281 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1282 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1283 // 64 bit 1284 if (cbuf) { 1285 MacroAssembler _masm(cbuf); 1286 __ strd(as_FloatRegister(Matcher::_regEncode[src_lo]), 1287 Address(sp, dst_offset)); 1288 } else if (st) { 1289 st->print("strd %s, [sp, #%d]\t# spill", 1290 Matcher::regName[src_lo], 1291 dst_offset); 1292 } 1293 } else { 1294 // 32 bit 1295 if (cbuf) { 1296 MacroAssembler _masm(cbuf); 1297 __ strs(as_FloatRegister(Matcher::_regEncode[src_lo]), 1298 Address(sp, dst_offset)); 1299 } else if (st) { 1300 st->print("strs %s, [sp, #%d]\t# spill", 1301 Matcher::regName[src_lo], 1302 dst_offset); 1303 } 1304 } 1305 } 1306 return 4; 1307 case rc_stack: 1308 int src_offset = ra_->reg2offset(src_lo); 1309 if (dst_lo_rc == rc_int) { // stack --> gpr load 1310 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1311 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1312 // 64 bit 1313 if (cbuf) { 1314 MacroAssembler _masm(cbuf); 1315 __ ldr(as_Register(Matcher::_regEncode[dst_lo]), 1316 Address(sp, src_offset)); 1317 } else if (st) { 1318 st->print("ldr %s, [sp, %d]\t# restore", 1319 Matcher::regName[dst_lo], 1320 src_offset); 1321 } 1322 } else { 1323 // 32 bit 1324 if (cbuf) { 1325 MacroAssembler _masm(cbuf); 1326 __ ldrw(as_Register(Matcher::_regEncode[dst_lo]), 1327 Address(sp, src_offset)); 1328 } else if (st) { 1329 st->print("ldr %s, [sp, %d]\t# restore", 1330 Matcher::regName[dst_lo], 1331 src_offset); 1332 } 1333 } 1334 return 4; 1335 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1336 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1337 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1338 // 64 bit 1339 if (cbuf) { 1340 MacroAssembler _masm(cbuf); 1341 __ ldrd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1342 Address(sp, src_offset)); 1343 } else if (st) { 1344 st->print("ldrd %s, [sp, %d]\t# restore", 1345 Matcher::regName[dst_lo], 1346 src_offset); 1347 } 1348 } else { 1349 // 32 bit 1350 if (cbuf) { 1351 MacroAssembler _masm(cbuf); 1352 __ ldrs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1353 Address(sp, src_offset)); 1354 } else if (st) { 1355 st->print("ldrs %s, [sp, %d]\t# restore", 1356 Matcher::regName[dst_lo], 1357 src_offset); 1358 } 1359 } 1360 return 4; 1361 } else { // stack --> stack copy 1362 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1363 int dst_offset = ra_->reg2offset(dst_lo); 1364 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1365 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1366 // 64 bit 1367 if (cbuf) { 1368 MacroAssembler _masm(cbuf); 1369 __ ldr(rscratch1, Address(sp, src_offset)); 1370 __ str(rscratch1, Address(sp, dst_offset)); 1371 } else if (st) { 1372 st->print("ldr rscratch1, [sp, %d]\t# mem-mem spill", 1373 src_offset); 1374 st->print("\n\t"); 1375 st->print("str rscratch1, [sp, %d]", 1376 dst_offset); 1377 } 1378 } else { 1379 // 32 bit 1380 if (cbuf) { 1381 MacroAssembler _masm(cbuf); 1382 __ ldrw(rscratch1, Address(sp, src_offset)); 1383 __ strw(rscratch1, Address(sp, dst_offset)); 1384 } else if (st) { 1385 st->print("ldrw rscratch1, [sp, %d]\t# mem-mem spill", 1386 src_offset); 1387 st->print("\n\t"); 1388 st->print("strw rscratch1, [sp, %d]", 1389 dst_offset); 1390 } 1391 } 1392 return 8; 1393 } 1394 } 1395 1396 assert(false," bad rc_class for spill "); 1397 Unimplemented(); 1398 return 0; 1399 1400 } 1401 1402 #ifndef PRODUCT 1403 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1404 if (!ra_) 1405 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1406 else 1407 implementation(NULL, ra_, false, st); 1408 } 1409 #endif 1410 1411 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1412 implementation(&cbuf, ra_, false, NULL); 1413 } 1414 1415 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1416 return implementation(NULL, ra_, true, NULL); 1417 } 1418 1419 //============================================================================= 1420 1421 #ifndef PRODUCT 1422 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1423 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1424 int reg = ra_->get_reg_first(this); 1425 st->print("add %s, rsp, #%d]\t# box lock", 1426 Matcher::regName[reg], offset); 1427 } 1428 #endif 1429 1430 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1431 MacroAssembler _masm(&cbuf); 1432 1433 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1434 int reg = ra_->get_encode(this); 1435 1436 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1437 __ add(as_Register(reg), sp, offset); 1438 } else { 1439 ShouldNotReachHere(); 1440 } 1441 } 1442 1443 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1444 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1445 return 4; 1446 } 1447 1448 //============================================================================= 1449 1450 #ifndef PRODUCT 1451 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1452 { 1453 st->print_cr("# MachUEPNode"); 1454 if (UseCompressedClassPointers) { 1455 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1456 if (Universe::narrow_klass_shift() != 0) { 1457 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1458 } 1459 } else { 1460 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1461 } 1462 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1463 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1464 } 1465 #endif 1466 1467 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1468 { 1469 // This is the unverified entry point. 1470 MacroAssembler _masm(&cbuf); 1471 1472 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1473 Label skip; 1474 // TODO 1475 // can we avoid this skip and still use a reloc? 1476 __ br(Assembler::EQ, skip); 1477 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1478 __ bind(skip); 1479 } 1480 1481 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1482 { 1483 return MachNode::size(ra_); 1484 } 1485 1486 // REQUIRED EMIT CODE 1487 1488 //============================================================================= 1489 1490 // Emit exception handler code. 1491 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1492 { 1493 // mov rscratch1 #exception_blob_entry_point 1494 // br rscratch1 1495 // Note that the code buffer's insts_mark is always relative to insts. 1496 // That's why we must use the macroassembler to generate a handler. 1497 MacroAssembler _masm(&cbuf); 1498 address base = 1499 __ start_a_stub(size_exception_handler()); 1500 if (base == NULL) return 0; // CodeBuffer::expand failed 1501 int offset = __ offset(); 1502 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1503 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1504 __ end_a_stub(); 1505 return offset; 1506 } 1507 1508 // Emit deopt handler code. 1509 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 1510 { 1511 // Note that the code buffer's insts_mark is always relative to insts. 1512 // That's why we must use the macroassembler to generate a handler. 1513 MacroAssembler _masm(&cbuf); 1514 address base = 1515 __ start_a_stub(size_deopt_handler()); 1516 if (base == NULL) return 0; // CodeBuffer::expand failed 1517 int offset = __ offset(); 1518 1519 __ adr(lr, __ pc()); 1520 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1521 1522 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1523 __ end_a_stub(); 1524 return offset; 1525 } 1526 1527 // REQUIRED MATCHER CODE 1528 1529 //============================================================================= 1530 1531 const bool Matcher::match_rule_supported(int opcode) { 1532 1533 // TODO 1534 // identify extra cases that we might want to provide match rules for 1535 // e.g. Op_StrEquals and other intrinsics 1536 if (!has_match_rule(opcode)) { 1537 return false; 1538 } 1539 1540 return true; // Per default match rules are supported. 1541 } 1542 1543 int Matcher::regnum_to_fpu_offset(int regnum) 1544 { 1545 Unimplemented(); 1546 return 0; 1547 } 1548 1549 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) 1550 { 1551 Unimplemented(); 1552 return false; 1553 } 1554 1555 const bool Matcher::isSimpleConstant64(jlong value) { 1556 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1557 // Probably always true, even if a temp register is required. 1558 return true; 1559 } 1560 1561 // true just means we have fast l2f conversion 1562 const bool Matcher::convL2FSupported(void) { 1563 return true; 1564 } 1565 1566 // Vector width in bytes. 1567 const int Matcher::vector_width_in_bytes(BasicType bt) { 1568 // TODO fixme 1569 return 0; 1570 } 1571 1572 // Limits on vector size (number of elements) loaded into vector. 1573 const int Matcher::max_vector_size(const BasicType bt) { 1574 return vector_width_in_bytes(bt)/type2aelembytes(bt); 1575 } 1576 const int Matcher::min_vector_size(const BasicType bt) { 1577 int max_size = max_vector_size(bt); 1578 // Min size which can be loaded into vector is 4 bytes. 1579 int size = (type2aelembytes(bt) == 1) ? 4 : 2; 1580 return MIN2(size,max_size); 1581 } 1582 1583 // Vector ideal reg. 1584 const int Matcher::vector_ideal_reg(int len) { 1585 // TODO fixme 1586 return Op_RegD; 1587 } 1588 1589 // Only lowest bits of xmm reg are used for vector shift count. 1590 const int Matcher::vector_shift_count_ideal_reg(int size) { 1591 // TODO fixme 1592 return Op_RegL; 1593 } 1594 1595 // AES support not yet implemented 1596 const bool Matcher::pass_original_key_for_aes() { 1597 return false; 1598 } 1599 1600 // x86 supports misaligned vectors store/load. 1601 const bool Matcher::misaligned_vectors_ok() { 1602 // TODO fixme 1603 // return !AlignVector; // can be changed by flag 1604 return false; 1605 } 1606 1607 // false => size gets scaled to BytesPerLong, ok. 1608 const bool Matcher::init_array_count_is_in_bytes = false; 1609 1610 // Threshold size for cleararray. 1611 const int Matcher::init_array_short_size = 18 * BytesPerLong; 1612 1613 // Use conditional move (CMOVL) 1614 const int Matcher::long_cmove_cost() { 1615 // long cmoves are no more expensive than int cmoves 1616 return 0; 1617 } 1618 1619 const int Matcher::float_cmove_cost() { 1620 // float cmoves are no more expensive than int cmoves 1621 return 0; 1622 } 1623 1624 // Does the CPU require late expand (see block.cpp for description of late expand)? 1625 const bool Matcher::require_postalloc_expand = false; 1626 1627 // Should the Matcher clone shifts on addressing modes, expecting them 1628 // to be subsumed into complex addressing expressions or compute them 1629 // into registers? True for Intel but false for most RISCs 1630 const bool Matcher::clone_shift_expressions = false; 1631 1632 // Do we need to mask the count passed to shift instructions or does 1633 // the cpu only look at the lower 5/6 bits anyway? 1634 const bool Matcher::need_masked_shift_count = false; 1635 1636 // This affects two different things: 1637 // - how Decode nodes are matched 1638 // - how ImplicitNullCheck opportunities are recognized 1639 // If true, the matcher will try to remove all Decodes and match them 1640 // (as operands) into nodes. NullChecks are not prepared to deal with 1641 // Decodes by final_graph_reshaping(). 1642 // If false, final_graph_reshaping() forces the decode behind the Cmp 1643 // for a NullCheck. The matcher matches the Decode node into a register. 1644 // Implicit_null_check optimization moves the Decode along with the 1645 // memory operation back up before the NullCheck. 1646 bool Matcher::narrow_oop_use_complex_address() { 1647 return Universe::narrow_oop_shift() == 0; 1648 } 1649 1650 bool Matcher::narrow_klass_use_complex_address() { 1651 // TODO 1652 // decide whether we need to set this to true 1653 return false; 1654 } 1655 1656 // Is it better to copy float constants, or load them directly from 1657 // memory? Intel can load a float constant from a direct address, 1658 // requiring no extra registers. Most RISCs will have to materialize 1659 // an address into a register first, so they would do better to copy 1660 // the constant from stack. 1661 const bool Matcher::rematerialize_float_constants = false; 1662 1663 // If CPU can load and store mis-aligned doubles directly then no 1664 // fixup is needed. Else we split the double into 2 integer pieces 1665 // and move it piece-by-piece. Only happens when passing doubles into 1666 // C code as the Java calling convention forces doubles to be aligned. 1667 const bool Matcher::misaligned_doubles_ok = true; 1668 1669 // No-op on amd64 1670 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 1671 Unimplemented(); 1672 } 1673 1674 // Advertise here if the CPU requires explicit rounding operations to 1675 // implement the UseStrictFP mode. 1676 const bool Matcher::strict_fp_requires_explicit_rounding = false; 1677 1678 // Are floats converted to double when stored to stack during 1679 // deoptimization? 1680 bool Matcher::float_in_double() { return true; } 1681 1682 // Do ints take an entire long register or just half? 1683 // The relevant question is how the int is callee-saved: 1684 // the whole long is written but de-opt'ing will have to extract 1685 // the relevant 32 bits. 1686 const bool Matcher::int_in_long = true; 1687 1688 // Return whether or not this register is ever used as an argument. 1689 // This function is used on startup to build the trampoline stubs in 1690 // generateOptoStub. Registers not mentioned will be killed by the VM 1691 // call in the trampoline, and arguments in those registers not be 1692 // available to the callee. 1693 bool Matcher::can_be_java_arg(int reg) 1694 { 1695 return 1696 reg == R0_num || reg == R0_H_num || 1697 reg == R1_num || reg == R1_H_num || 1698 reg == R2_num || reg == R2_H_num || 1699 reg == R3_num || reg == R3_H_num || 1700 reg == R4_num || reg == R4_H_num || 1701 reg == R5_num || reg == R5_H_num || 1702 reg == R6_num || reg == R6_H_num || 1703 reg == R7_num || reg == R7_H_num || 1704 reg == V0_num || reg == V0_H_num || 1705 reg == V1_num || reg == V1_H_num || 1706 reg == V2_num || reg == V2_H_num || 1707 reg == V3_num || reg == V3_H_num || 1708 reg == V4_num || reg == V4_H_num || 1709 reg == V5_num || reg == V5_H_num || 1710 reg == V6_num || reg == V6_H_num || 1711 reg == V7_num || reg == V7_H_num; 1712 } 1713 1714 bool Matcher::is_spillable_arg(int reg) 1715 { 1716 return can_be_java_arg(reg); 1717 } 1718 1719 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 1720 return false; 1721 } 1722 1723 RegMask Matcher::divI_proj_mask() { 1724 ShouldNotReachHere(); 1725 return RegMask(); 1726 } 1727 1728 // Register for MODI projection of divmodI. 1729 RegMask Matcher::modI_proj_mask() { 1730 ShouldNotReachHere(); 1731 return RegMask(); 1732 } 1733 1734 // Register for DIVL projection of divmodL. 1735 RegMask Matcher::divL_proj_mask() { 1736 ShouldNotReachHere(); 1737 return RegMask(); 1738 } 1739 1740 // Register for MODL projection of divmodL. 1741 RegMask Matcher::modL_proj_mask() { 1742 ShouldNotReachHere(); 1743 return RegMask(); 1744 } 1745 1746 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1747 return RegMask(); 1748 } 1749 1750 // helper for encoding java_to_runtime calls on sim 1751 // 1752 // this is needed to compute the extra arguments required when 1753 // planting a call to the simulator blrt instruction. the TypeFunc 1754 // can be queried to identify the counts for integral, and floating 1755 // arguments and the return type 1756 1757 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 1758 { 1759 int gps = 0; 1760 int fps = 0; 1761 const TypeTuple *domain = tf->domain(); 1762 int max = domain->cnt(); 1763 for (int i = TypeFunc::Parms; i < max; i++) { 1764 const Type *t = domain->field_at(i); 1765 switch(t->basic_type()) { 1766 case T_FLOAT: 1767 case T_DOUBLE: 1768 fps++; 1769 default: 1770 gps++; 1771 } 1772 } 1773 gpcnt = gps; 1774 fpcnt = fps; 1775 BasicType rt = tf->return_type(); 1776 switch (rt) { 1777 case T_VOID: 1778 rtype = MacroAssembler::ret_type_void; 1779 break; 1780 default: 1781 rtype = MacroAssembler::ret_type_integral; 1782 break; 1783 case T_FLOAT: 1784 rtype = MacroAssembler::ret_type_float; 1785 break; 1786 case T_DOUBLE: 1787 rtype = MacroAssembler::ret_type_double; 1788 break; 1789 } 1790 } 1791 1792 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 1793 MacroAssembler _masm(&cbuf); \ 1794 { \ 1795 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 1796 guarantee(DISP == 0, "mode not permitted for volatile"); \ 1797 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 1798 __ INSN(REG, as_Register(BASE)); \ 1799 } 1800 1801 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 1802 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 1803 1804 // Used for all non-volatile memory accesses. The use of 1805 // $mem->opcode() to discover whether this pattern uses sign-extended 1806 // offsets is something of a kludge. 1807 static void loadStore(MacroAssembler masm, mem_insn insn, 1808 Register reg, int opcode, 1809 Register base, int index, int size, int disp) 1810 { 1811 Address::extend scale; 1812 1813 // Hooboy, this is fugly. We need a way to communicate to the 1814 // encoder that the index needs to be sign extended, so we have to 1815 // enumerate all the cases. 1816 switch (opcode) { 1817 case INDINDEXSCALEDOFFSETI2L: 1818 case INDINDEXSCALEDI2L: 1819 case INDINDEXSCALEDOFFSETI2LN: 1820 case INDINDEXSCALEDI2LN: 1821 scale = Address::sxtw(size); 1822 break; 1823 default: 1824 scale = Address::lsl(size); 1825 } 1826 1827 if (index == -1) { 1828 (masm.*insn)(reg, Address(base, disp)); 1829 } else { 1830 if (disp == 0) { 1831 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 1832 } else { 1833 masm.lea(rscratch1, Address(base, disp)); 1834 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 1835 } 1836 } 1837 } 1838 1839 static void loadStore(MacroAssembler masm, mem_float_insn insn, 1840 FloatRegister reg, int opcode, 1841 Register base, int index, int size, int disp) 1842 { 1843 Address::extend scale; 1844 1845 switch (opcode) { 1846 case INDINDEXSCALEDOFFSETI2L: 1847 case INDINDEXSCALEDI2L: 1848 case INDINDEXSCALEDOFFSETI2LN: 1849 case INDINDEXSCALEDI2LN: 1850 scale = Address::sxtw(size); 1851 break; 1852 default: 1853 scale = Address::lsl(size); 1854 } 1855 1856 if (index == -1) { 1857 (masm.*insn)(reg, Address(base, disp)); 1858 } else { 1859 if (disp == 0) { 1860 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 1861 } else { 1862 masm.lea(rscratch1, Address(base, disp)); 1863 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 1864 } 1865 } 1866 } 1867 1868 %} 1869 1870 1871 1872 //----------ENCODING BLOCK----------------------------------------------------- 1873 // This block specifies the encoding classes used by the compiler to 1874 // output byte streams. Encoding classes are parameterized macros 1875 // used by Machine Instruction Nodes in order to generate the bit 1876 // encoding of the instruction. Operands specify their base encoding 1877 // interface with the interface keyword. There are currently 1878 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1879 // COND_INTER. REG_INTER causes an operand to generate a function 1880 // which returns its register number when queried. CONST_INTER causes 1881 // an operand to generate a function which returns the value of the 1882 // constant when queried. MEMORY_INTER causes an operand to generate 1883 // four functions which return the Base Register, the Index Register, 1884 // the Scale Value, and the Offset Value of the operand when queried. 1885 // COND_INTER causes an operand to generate six functions which return 1886 // the encoding code (ie - encoding bits for the instruction) 1887 // associated with each basic boolean condition for a conditional 1888 // instruction. 1889 // 1890 // Instructions specify two basic values for encoding. Again, a 1891 // function is available to check if the constant displacement is an 1892 // oop. They use the ins_encode keyword to specify their encoding 1893 // classes (which must be a sequence of enc_class names, and their 1894 // parameters, specified in the encoding block), and they use the 1895 // opcode keyword to specify, in order, their primary, secondary, and 1896 // tertiary opcode. Only the opcode sections which a particular 1897 // instruction needs for encoding need to be specified. 1898 encode %{ 1899 // Build emit functions for each basic byte or larger field in the 1900 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1901 // from C++ code in the enc_class source block. Emit functions will 1902 // live in the main source block for now. In future, we can 1903 // generalize this by adding a syntax that specifies the sizes of 1904 // fields in an order, so that the adlc can build the emit functions 1905 // automagically 1906 1907 // catch all for unimplemented encodings 1908 enc_class enc_unimplemented %{ 1909 MacroAssembler _masm(&cbuf); 1910 __ unimplemented("C2 catch all"); 1911 %} 1912 1913 // BEGIN Non-volatile memory access 1914 1915 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 1916 Register dst_reg = as_Register($dst$$reg); 1917 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 1918 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1919 %} 1920 1921 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 1922 Register dst_reg = as_Register($dst$$reg); 1923 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 1924 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1925 %} 1926 1927 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 1928 Register dst_reg = as_Register($dst$$reg); 1929 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 1930 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1931 %} 1932 1933 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 1934 Register dst_reg = as_Register($dst$$reg); 1935 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 1936 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1937 %} 1938 1939 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 1940 Register dst_reg = as_Register($dst$$reg); 1941 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 1942 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1943 %} 1944 1945 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 1946 Register dst_reg = as_Register($dst$$reg); 1947 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 1948 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1949 %} 1950 1951 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 1952 Register dst_reg = as_Register($dst$$reg); 1953 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 1954 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1955 %} 1956 1957 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 1958 Register dst_reg = as_Register($dst$$reg); 1959 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 1960 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1961 %} 1962 1963 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 1964 Register dst_reg = as_Register($dst$$reg); 1965 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 1966 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1967 %} 1968 1969 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 1970 Register dst_reg = as_Register($dst$$reg); 1971 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 1972 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1973 %} 1974 1975 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 1976 Register dst_reg = as_Register($dst$$reg); 1977 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 1978 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1979 %} 1980 1981 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 1982 Register dst_reg = as_Register($dst$$reg); 1983 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 1984 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1985 %} 1986 1987 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 1988 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 1989 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 1990 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1991 %} 1992 1993 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 1994 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 1995 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 1996 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1997 %} 1998 1999 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2000 Register src_reg = as_Register($src$$reg); 2001 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2002 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2003 %} 2004 2005 enc_class aarch64_enc_strb0(memory mem) %{ 2006 MacroAssembler _masm(&cbuf); 2007 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2008 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2009 %} 2010 2011 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2012 Register src_reg = as_Register($src$$reg); 2013 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2014 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2015 %} 2016 2017 enc_class aarch64_enc_strh0(memory mem) %{ 2018 MacroAssembler _masm(&cbuf); 2019 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2020 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2021 %} 2022 2023 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2024 Register src_reg = as_Register($src$$reg); 2025 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2026 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2027 %} 2028 2029 enc_class aarch64_enc_strw0(memory mem) %{ 2030 MacroAssembler _masm(&cbuf); 2031 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2032 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2033 %} 2034 2035 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2036 Register src_reg = as_Register($src$$reg); 2037 // we sometimes get asked to store the stack pointer into the 2038 // current thread -- we cannot do that directly on AArch64 2039 if (src_reg == r31_sp) { 2040 MacroAssembler _masm(&cbuf); 2041 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2042 __ mov(rscratch2, sp); 2043 src_reg = rscratch2; 2044 } 2045 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2046 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2047 %} 2048 2049 enc_class aarch64_enc_str0(memory mem) %{ 2050 MacroAssembler _masm(&cbuf); 2051 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2052 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2053 %} 2054 2055 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2056 FloatRegister src_reg = as_FloatRegister($src$$reg); 2057 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2058 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2059 %} 2060 2061 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2062 FloatRegister src_reg = as_FloatRegister($src$$reg); 2063 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2064 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2065 %} 2066 2067 // END Non-volatile memory access 2068 2069 // volatile loads and stores 2070 2071 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2072 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2073 rscratch1, stlrb); 2074 %} 2075 2076 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2077 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2078 rscratch1, stlrh); 2079 %} 2080 2081 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2082 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2083 rscratch1, stlrw); 2084 %} 2085 2086 2087 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2088 Register dst_reg = as_Register($dst$$reg); 2089 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2090 rscratch1, ldarb); 2091 __ sxtbw(dst_reg, dst_reg); 2092 %} 2093 2094 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2095 Register dst_reg = as_Register($dst$$reg); 2096 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2097 rscratch1, ldarb); 2098 __ sxtb(dst_reg, dst_reg); 2099 %} 2100 2101 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2102 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2103 rscratch1, ldarb); 2104 %} 2105 2106 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2107 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2108 rscratch1, ldarb); 2109 %} 2110 2111 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2112 Register dst_reg = as_Register($dst$$reg); 2113 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2114 rscratch1, ldarh); 2115 __ sxthw(dst_reg, dst_reg); 2116 %} 2117 2118 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2119 Register dst_reg = as_Register($dst$$reg); 2120 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2121 rscratch1, ldarh); 2122 __ sxth(dst_reg, dst_reg); 2123 %} 2124 2125 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2126 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2127 rscratch1, ldarh); 2128 %} 2129 2130 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2131 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2132 rscratch1, ldarh); 2133 %} 2134 2135 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2136 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2137 rscratch1, ldarw); 2138 %} 2139 2140 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2141 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2142 rscratch1, ldarw); 2143 %} 2144 2145 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2146 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2147 rscratch1, ldar); 2148 %} 2149 2150 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2151 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2152 rscratch1, ldarw); 2153 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2154 %} 2155 2156 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2157 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2158 rscratch1, ldar); 2159 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2160 %} 2161 2162 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2163 Register src_reg = as_Register($src$$reg); 2164 // we sometimes get asked to store the stack pointer into the 2165 // current thread -- we cannot do that directly on AArch64 2166 if (src_reg == r31_sp) { 2167 MacroAssembler _masm(&cbuf); 2168 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2169 __ mov(rscratch2, sp); 2170 src_reg = rscratch2; 2171 } 2172 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2173 rscratch1, stlr); 2174 %} 2175 2176 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2177 { 2178 MacroAssembler _masm(&cbuf); 2179 FloatRegister src_reg = as_FloatRegister($src$$reg); 2180 __ fmovs(rscratch2, src_reg); 2181 } 2182 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2183 rscratch1, stlrw); 2184 %} 2185 2186 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2187 { 2188 MacroAssembler _masm(&cbuf); 2189 FloatRegister src_reg = as_FloatRegister($src$$reg); 2190 __ fmovd(rscratch2, src_reg); 2191 } 2192 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2193 rscratch1, stlr); 2194 %} 2195 2196 // synchronized read/update encodings 2197 2198 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2199 MacroAssembler _masm(&cbuf); 2200 Register dst_reg = as_Register($dst$$reg); 2201 Register base = as_Register($mem$$base); 2202 int index = $mem$$index; 2203 int scale = $mem$$scale; 2204 int disp = $mem$$disp; 2205 if (index == -1) { 2206 if (disp != 0) { 2207 __ lea(rscratch1, Address(base, disp)); 2208 __ ldaxr(dst_reg, rscratch1); 2209 } else { 2210 // TODO 2211 // should we ever get anything other than this case? 2212 __ ldaxr(dst_reg, base); 2213 } 2214 } else { 2215 Register index_reg = as_Register(index); 2216 if (disp == 0) { 2217 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2218 __ ldaxr(dst_reg, rscratch1); 2219 } else { 2220 __ lea(rscratch1, Address(base, disp)); 2221 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2222 __ ldaxr(dst_reg, rscratch1); 2223 } 2224 } 2225 %} 2226 2227 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2228 MacroAssembler _masm(&cbuf); 2229 Register src_reg = as_Register($src$$reg); 2230 Register base = as_Register($mem$$base); 2231 int index = $mem$$index; 2232 int scale = $mem$$scale; 2233 int disp = $mem$$disp; 2234 if (index == -1) { 2235 if (disp != 0) { 2236 __ lea(rscratch2, Address(base, disp)); 2237 __ stlxr(rscratch1, src_reg, rscratch2); 2238 } else { 2239 // TODO 2240 // should we ever get anything other than this case? 2241 __ stlxr(rscratch1, src_reg, base); 2242 } 2243 } else { 2244 Register index_reg = as_Register(index); 2245 if (disp == 0) { 2246 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2247 __ stlxr(rscratch1, src_reg, rscratch2); 2248 } else { 2249 __ lea(rscratch2, Address(base, disp)); 2250 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2251 __ stlxr(rscratch1, src_reg, rscratch2); 2252 } 2253 } 2254 __ cmpw(rscratch1, zr); 2255 %} 2256 2257 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2258 MacroAssembler _masm(&cbuf); 2259 Register old_reg = as_Register($oldval$$reg); 2260 Register new_reg = as_Register($newval$$reg); 2261 Register base = as_Register($mem$$base); 2262 Register addr_reg; 2263 int index = $mem$$index; 2264 int scale = $mem$$scale; 2265 int disp = $mem$$disp; 2266 if (index == -1) { 2267 if (disp != 0) { 2268 __ lea(rscratch2, Address(base, disp)); 2269 addr_reg = rscratch2; 2270 } else { 2271 // TODO 2272 // should we ever get anything other than this case? 2273 addr_reg = base; 2274 } 2275 } else { 2276 Register index_reg = as_Register(index); 2277 if (disp == 0) { 2278 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2279 addr_reg = rscratch2; 2280 } else { 2281 __ lea(rscratch2, Address(base, disp)); 2282 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2283 addr_reg = rscratch2; 2284 } 2285 } 2286 Label retry_load, done; 2287 __ bind(retry_load); 2288 __ ldxr(rscratch1, addr_reg); 2289 __ cmp(rscratch1, old_reg); 2290 __ br(Assembler::NE, done); 2291 __ stlxr(rscratch1, new_reg, addr_reg); 2292 __ cbnzw(rscratch1, retry_load); 2293 __ bind(done); 2294 %} 2295 2296 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2297 MacroAssembler _masm(&cbuf); 2298 Register old_reg = as_Register($oldval$$reg); 2299 Register new_reg = as_Register($newval$$reg); 2300 Register base = as_Register($mem$$base); 2301 Register addr_reg; 2302 int index = $mem$$index; 2303 int scale = $mem$$scale; 2304 int disp = $mem$$disp; 2305 if (index == -1) { 2306 if (disp != 0) { 2307 __ lea(rscratch2, Address(base, disp)); 2308 addr_reg = rscratch2; 2309 } else { 2310 // TODO 2311 // should we ever get anything other than this case? 2312 addr_reg = base; 2313 } 2314 } else { 2315 Register index_reg = as_Register(index); 2316 if (disp == 0) { 2317 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2318 addr_reg = rscratch2; 2319 } else { 2320 __ lea(rscratch2, Address(base, disp)); 2321 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2322 addr_reg = rscratch2; 2323 } 2324 } 2325 Label retry_load, done; 2326 __ bind(retry_load); 2327 __ ldxrw(rscratch1, addr_reg); 2328 __ cmpw(rscratch1, old_reg); 2329 __ br(Assembler::NE, done); 2330 __ stlxrw(rscratch1, new_reg, addr_reg); 2331 __ cbnzw(rscratch1, retry_load); 2332 __ bind(done); 2333 %} 2334 2335 // auxiliary used for CompareAndSwapX to set result register 2336 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2337 MacroAssembler _masm(&cbuf); 2338 Register res_reg = as_Register($res$$reg); 2339 __ cset(res_reg, Assembler::EQ); 2340 %} 2341 2342 // prefetch encodings 2343 2344 enc_class aarch64_enc_prefetchw(memory mem) %{ 2345 MacroAssembler _masm(&cbuf); 2346 Register base = as_Register($mem$$base); 2347 int index = $mem$$index; 2348 int scale = $mem$$scale; 2349 int disp = $mem$$disp; 2350 if (index == -1) { 2351 __ prfm(Address(base, disp), PSTL1KEEP); 2352 __ nop(); 2353 } else { 2354 Register index_reg = as_Register(index); 2355 if (disp == 0) { 2356 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2357 } else { 2358 __ lea(rscratch1, Address(base, disp)); 2359 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2360 } 2361 } 2362 %} 2363 2364 enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{ 2365 MacroAssembler _masm(&cbuf); 2366 Register cnt_reg = as_Register($cnt$$reg); 2367 Register base_reg = as_Register($base$$reg); 2368 // base is word aligned 2369 // cnt is count of words 2370 2371 Label loop; 2372 Label entry; 2373 2374 // Algorithm: 2375 // 2376 // scratch1 = cnt & 7; 2377 // cnt -= scratch1; 2378 // p += scratch1; 2379 // switch (scratch1) { 2380 // do { 2381 // cnt -= 8; 2382 // p[-8] = 0; 2383 // case 7: 2384 // p[-7] = 0; 2385 // case 6: 2386 // p[-6] = 0; 2387 // // ... 2388 // case 1: 2389 // p[-1] = 0; 2390 // case 0: 2391 // p += 8; 2392 // } while (cnt); 2393 // } 2394 2395 const int unroll = 8; // Number of str(zr) instructions we'll unroll 2396 2397 __ andr(rscratch1, cnt_reg, unroll - 1); // tmp1 = cnt % unroll 2398 __ sub(cnt_reg, cnt_reg, rscratch1); // cnt -= unroll 2399 // base_reg always points to the end of the region we're about to zero 2400 __ add(base_reg, base_reg, rscratch1, Assembler::LSL, exact_log2(wordSize)); 2401 __ adr(rscratch2, entry); 2402 __ sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); 2403 __ br(rscratch2); 2404 __ bind(loop); 2405 __ sub(cnt_reg, cnt_reg, unroll); 2406 for (int i = -unroll; i < 0; i++) 2407 __ str(zr, Address(base_reg, i * wordSize)); 2408 __ bind(entry); 2409 __ add(base_reg, base_reg, unroll * wordSize); 2410 __ cbnz(cnt_reg, loop); 2411 %} 2412 2413 /// mov envcodings 2414 2415 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2416 MacroAssembler _masm(&cbuf); 2417 u_int32_t con = (u_int32_t)$src$$constant; 2418 Register dst_reg = as_Register($dst$$reg); 2419 if (con == 0) { 2420 __ movw(dst_reg, zr); 2421 } else { 2422 __ movw(dst_reg, con); 2423 } 2424 %} 2425 2426 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2427 MacroAssembler _masm(&cbuf); 2428 Register dst_reg = as_Register($dst$$reg); 2429 u_int64_t con = (u_int64_t)$src$$constant; 2430 if (con == 0) { 2431 __ mov(dst_reg, zr); 2432 } else { 2433 __ mov(dst_reg, con); 2434 } 2435 %} 2436 2437 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 2438 MacroAssembler _masm(&cbuf); 2439 Register dst_reg = as_Register($dst$$reg); 2440 address con = (address)$src$$constant; 2441 if (con == NULL || con == (address)1) { 2442 ShouldNotReachHere(); 2443 } else { 2444 relocInfo::relocType rtype = $src->constant_reloc(); 2445 if (rtype == relocInfo::oop_type) { 2446 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 2447 } else if (rtype == relocInfo::metadata_type) { 2448 __ mov_metadata(dst_reg, (Metadata*)con); 2449 } else { 2450 assert(rtype == relocInfo::none, "unexpected reloc type"); 2451 if (con < (address)(uintptr_t)os::vm_page_size()) { 2452 __ mov(dst_reg, con); 2453 } else { 2454 unsigned long offset; 2455 __ adrp(dst_reg, con, offset); 2456 __ add(dst_reg, dst_reg, offset); 2457 } 2458 } 2459 } 2460 %} 2461 2462 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 2463 MacroAssembler _masm(&cbuf); 2464 Register dst_reg = as_Register($dst$$reg); 2465 __ mov(dst_reg, zr); 2466 %} 2467 2468 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 2469 MacroAssembler _masm(&cbuf); 2470 Register dst_reg = as_Register($dst$$reg); 2471 __ mov(dst_reg, (u_int64_t)1); 2472 %} 2473 2474 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 2475 MacroAssembler _masm(&cbuf); 2476 address page = (address)$src$$constant; 2477 Register dst_reg = as_Register($dst$$reg); 2478 unsigned long off; 2479 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 2480 assert(off == 0, "assumed offset == 0"); 2481 %} 2482 2483 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 2484 MacroAssembler _masm(&cbuf); 2485 address page = (address)$src$$constant; 2486 Register dst_reg = as_Register($dst$$reg); 2487 unsigned long off; 2488 __ adrp(dst_reg, ExternalAddress(page), off); 2489 assert(off == 0, "assumed offset == 0"); 2490 %} 2491 2492 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 2493 MacroAssembler _masm(&cbuf); 2494 Register dst_reg = as_Register($dst$$reg); 2495 address con = (address)$src$$constant; 2496 if (con == NULL) { 2497 ShouldNotReachHere(); 2498 } else { 2499 relocInfo::relocType rtype = $src->constant_reloc(); 2500 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 2501 __ set_narrow_oop(dst_reg, (jobject)con); 2502 } 2503 %} 2504 2505 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 2506 MacroAssembler _masm(&cbuf); 2507 Register dst_reg = as_Register($dst$$reg); 2508 __ mov(dst_reg, zr); 2509 %} 2510 2511 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 2512 MacroAssembler _masm(&cbuf); 2513 Register dst_reg = as_Register($dst$$reg); 2514 address con = (address)$src$$constant; 2515 if (con == NULL) { 2516 ShouldNotReachHere(); 2517 } else { 2518 relocInfo::relocType rtype = $src->constant_reloc(); 2519 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 2520 __ set_narrow_klass(dst_reg, (Klass *)con); 2521 } 2522 %} 2523 2524 // arithmetic encodings 2525 2526 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 2527 MacroAssembler _masm(&cbuf); 2528 Register dst_reg = as_Register($dst$$reg); 2529 Register src_reg = as_Register($src1$$reg); 2530 int32_t con = (int32_t)$src2$$constant; 2531 // add has primary == 0, subtract has primary == 1 2532 if ($primary) { con = -con; } 2533 if (con < 0) { 2534 __ subw(dst_reg, src_reg, -con); 2535 } else { 2536 __ addw(dst_reg, src_reg, con); 2537 } 2538 %} 2539 2540 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 2541 MacroAssembler _masm(&cbuf); 2542 Register dst_reg = as_Register($dst$$reg); 2543 Register src_reg = as_Register($src1$$reg); 2544 int32_t con = (int32_t)$src2$$constant; 2545 // add has primary == 0, subtract has primary == 1 2546 if ($primary) { con = -con; } 2547 if (con < 0) { 2548 __ sub(dst_reg, src_reg, -con); 2549 } else { 2550 __ add(dst_reg, src_reg, con); 2551 } 2552 %} 2553 2554 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 2555 MacroAssembler _masm(&cbuf); 2556 Register dst_reg = as_Register($dst$$reg); 2557 Register src1_reg = as_Register($src1$$reg); 2558 Register src2_reg = as_Register($src2$$reg); 2559 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 2560 %} 2561 2562 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 2563 MacroAssembler _masm(&cbuf); 2564 Register dst_reg = as_Register($dst$$reg); 2565 Register src1_reg = as_Register($src1$$reg); 2566 Register src2_reg = as_Register($src2$$reg); 2567 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 2568 %} 2569 2570 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 2571 MacroAssembler _masm(&cbuf); 2572 Register dst_reg = as_Register($dst$$reg); 2573 Register src1_reg = as_Register($src1$$reg); 2574 Register src2_reg = as_Register($src2$$reg); 2575 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 2576 %} 2577 2578 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 2579 MacroAssembler _masm(&cbuf); 2580 Register dst_reg = as_Register($dst$$reg); 2581 Register src1_reg = as_Register($src1$$reg); 2582 Register src2_reg = as_Register($src2$$reg); 2583 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 2584 %} 2585 2586 // compare instruction encodings 2587 2588 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 2589 MacroAssembler _masm(&cbuf); 2590 Register reg1 = as_Register($src1$$reg); 2591 Register reg2 = as_Register($src2$$reg); 2592 __ cmpw(reg1, reg2); 2593 %} 2594 2595 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 2596 MacroAssembler _masm(&cbuf); 2597 Register reg = as_Register($src1$$reg); 2598 int32_t val = $src2$$constant; 2599 if (val >= 0) { 2600 __ subsw(zr, reg, val); 2601 } else { 2602 __ addsw(zr, reg, -val); 2603 } 2604 %} 2605 2606 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 2607 MacroAssembler _masm(&cbuf); 2608 Register reg1 = as_Register($src1$$reg); 2609 u_int32_t val = (u_int32_t)$src2$$constant; 2610 __ movw(rscratch1, val); 2611 __ cmpw(reg1, rscratch1); 2612 %} 2613 2614 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 2615 MacroAssembler _masm(&cbuf); 2616 Register reg1 = as_Register($src1$$reg); 2617 Register reg2 = as_Register($src2$$reg); 2618 __ cmp(reg1, reg2); 2619 %} 2620 2621 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 2622 MacroAssembler _masm(&cbuf); 2623 Register reg = as_Register($src1$$reg); 2624 int64_t val = $src2$$constant; 2625 if (val >= 0) { 2626 __ subs(zr, reg, val); 2627 } else if (val != -val) { 2628 __ adds(zr, reg, -val); 2629 } else { 2630 // aargh, Long.MIN_VALUE is a special case 2631 __ orr(rscratch1, zr, (u_int64_t)val); 2632 __ subs(zr, reg, rscratch1); 2633 } 2634 %} 2635 2636 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 2637 MacroAssembler _masm(&cbuf); 2638 Register reg1 = as_Register($src1$$reg); 2639 u_int64_t val = (u_int64_t)$src2$$constant; 2640 __ mov(rscratch1, val); 2641 __ cmp(reg1, rscratch1); 2642 %} 2643 2644 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 2645 MacroAssembler _masm(&cbuf); 2646 Register reg1 = as_Register($src1$$reg); 2647 Register reg2 = as_Register($src2$$reg); 2648 __ cmp(reg1, reg2); 2649 %} 2650 2651 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 2652 MacroAssembler _masm(&cbuf); 2653 Register reg1 = as_Register($src1$$reg); 2654 Register reg2 = as_Register($src2$$reg); 2655 __ cmpw(reg1, reg2); 2656 %} 2657 2658 enc_class aarch64_enc_testp(iRegP src) %{ 2659 MacroAssembler _masm(&cbuf); 2660 Register reg = as_Register($src$$reg); 2661 __ cmp(reg, zr); 2662 %} 2663 2664 enc_class aarch64_enc_testn(iRegN src) %{ 2665 MacroAssembler _masm(&cbuf); 2666 Register reg = as_Register($src$$reg); 2667 __ cmpw(reg, zr); 2668 %} 2669 2670 enc_class aarch64_enc_b(label lbl) %{ 2671 MacroAssembler _masm(&cbuf); 2672 Label *L = $lbl$$label; 2673 __ b(*L); 2674 %} 2675 2676 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 2677 MacroAssembler _masm(&cbuf); 2678 Label *L = $lbl$$label; 2679 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 2680 %} 2681 2682 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 2683 MacroAssembler _masm(&cbuf); 2684 Label *L = $lbl$$label; 2685 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 2686 %} 2687 2688 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 2689 %{ 2690 Register sub_reg = as_Register($sub$$reg); 2691 Register super_reg = as_Register($super$$reg); 2692 Register temp_reg = as_Register($temp$$reg); 2693 Register result_reg = as_Register($result$$reg); 2694 2695 Label miss; 2696 MacroAssembler _masm(&cbuf); 2697 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 2698 NULL, &miss, 2699 /*set_cond_codes:*/ true); 2700 if ($primary) { 2701 __ mov(result_reg, zr); 2702 } 2703 __ bind(miss); 2704 %} 2705 2706 enc_class aarch64_enc_java_static_call(method meth) %{ 2707 MacroAssembler _masm(&cbuf); 2708 2709 address addr = (address)$meth$$method; 2710 if (!_method) { 2711 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 2712 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 2713 } else if (_optimized_virtual) { 2714 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 2715 } else { 2716 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 2717 } 2718 2719 if (_method) { 2720 // Emit stub for static call 2721 CompiledStaticCall::emit_to_interp_stub(cbuf); 2722 } 2723 %} 2724 2725 enc_class aarch64_enc_java_handle_call(method meth) %{ 2726 MacroAssembler _masm(&cbuf); 2727 relocInfo::relocType reloc; 2728 2729 // RFP is preserved across all calls, even compiled calls. 2730 // Use it to preserve SP. 2731 __ mov(rfp, sp); 2732 2733 const int start_offset = __ offset(); 2734 address addr = (address)$meth$$method; 2735 if (!_method) { 2736 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 2737 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 2738 } else if (_optimized_virtual) { 2739 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 2740 } else { 2741 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 2742 } 2743 2744 if (_method) { 2745 // Emit stub for static call 2746 CompiledStaticCall::emit_to_interp_stub(cbuf); 2747 } 2748 2749 // now restore sp 2750 __ mov(sp, rfp); 2751 %} 2752 2753 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 2754 MacroAssembler _masm(&cbuf); 2755 __ ic_call((address)$meth$$method); 2756 %} 2757 2758 enc_class aarch64_enc_call_epilog() %{ 2759 MacroAssembler _masm(&cbuf); 2760 if (VerifyStackAtCalls) { 2761 // Check that stack depth is unchanged: find majik cookie on stack 2762 __ call_Unimplemented(); 2763 } 2764 %} 2765 2766 enc_class aarch64_enc_java_to_runtime(method meth) %{ 2767 MacroAssembler _masm(&cbuf); 2768 2769 // some calls to generated routines (arraycopy code) are scheduled 2770 // by C2 as runtime calls. if so we can call them using a br (they 2771 // will be in a reachable segment) otherwise we have to use a blrt 2772 // which loads the absolute address into a register. 2773 address entry = (address)$meth$$method; 2774 CodeBlob *cb = CodeCache::find_blob(entry); 2775 if (cb) { 2776 __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 2777 } else { 2778 int gpcnt; 2779 int fpcnt; 2780 int rtype; 2781 getCallInfo(tf(), gpcnt, fpcnt, rtype); 2782 Label retaddr; 2783 __ adr(rscratch2, retaddr); 2784 __ lea(rscratch1, RuntimeAddress(entry)); 2785 // Leave a breadcrumb for JavaThread::pd_last_frame(). 2786 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 2787 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 2788 __ bind(retaddr); 2789 __ add(sp, sp, 2 * wordSize); 2790 } 2791 %} 2792 2793 enc_class aarch64_enc_rethrow() %{ 2794 MacroAssembler _masm(&cbuf); 2795 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 2796 %} 2797 2798 enc_class aarch64_enc_ret() %{ 2799 MacroAssembler _masm(&cbuf); 2800 __ ret(lr); 2801 %} 2802 2803 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 2804 MacroAssembler _masm(&cbuf); 2805 Register target_reg = as_Register($jump_target$$reg); 2806 __ br(target_reg); 2807 %} 2808 2809 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 2810 MacroAssembler _masm(&cbuf); 2811 Register target_reg = as_Register($jump_target$$reg); 2812 // exception oop should be in r0 2813 // ret addr has been popped into lr 2814 // callee expects it in r3 2815 __ mov(r3, lr); 2816 __ br(target_reg); 2817 %} 2818 2819 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 2820 MacroAssembler _masm(&cbuf); 2821 Register oop = as_Register($object$$reg); 2822 Register box = as_Register($box$$reg); 2823 Register disp_hdr = as_Register($tmp$$reg); 2824 Register tmp = as_Register($tmp2$$reg); 2825 Label cont; 2826 Label object_has_monitor; 2827 Label cas_failed; 2828 2829 assert_different_registers(oop, box, tmp, disp_hdr); 2830 2831 // Load markOop from object into displaced_header. 2832 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 2833 2834 // Always do locking in runtime. 2835 if (EmitSync & 0x01) { 2836 __ cmp(oop, zr); 2837 return; 2838 } 2839 2840 if (UseBiasedLocking) { 2841 __ biased_locking_enter(disp_hdr, oop, box, tmp, true, cont); 2842 } 2843 2844 // Handle existing monitor 2845 if (EmitSync & 0x02) { 2846 // we can use AArch64's bit test and branch here but 2847 // markoopDesc does not define a bit index just the bit value 2848 // so assert in case the bit pos changes 2849 # define __monitor_value_log2 1 2850 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 2851 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 2852 # undef __monitor_value_log2 2853 } 2854 2855 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 2856 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 2857 2858 // Load Compare Value application register. 2859 2860 // Initialize the box. (Must happen before we update the object mark!) 2861 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2862 2863 // Compare object markOop with mark and if equal exchange scratch1 2864 // with object markOop. 2865 // Note that this is simply a CAS: it does not generate any 2866 // barriers. These are separately generated by 2867 // membar_acquire_lock(). 2868 { 2869 Label retry_load; 2870 __ bind(retry_load); 2871 __ ldxr(tmp, oop); 2872 __ cmp(tmp, disp_hdr); 2873 __ br(Assembler::NE, cas_failed); 2874 // use stlxr to ensure update is immediately visible 2875 __ stlxr(tmp, box, oop); 2876 __ cbzw(tmp, cont); 2877 __ b(retry_load); 2878 } 2879 2880 // Formerly: 2881 // __ cmpxchgptr(/*oldv=*/disp_hdr, 2882 // /*newv=*/box, 2883 // /*addr=*/oop, 2884 // /*tmp=*/tmp, 2885 // cont, 2886 // /*fail*/NULL); 2887 2888 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 2889 2890 // If the compare-and-exchange succeeded, then we found an unlocked 2891 // object, will have now locked it will continue at label cont 2892 2893 __ bind(cas_failed); 2894 // We did not see an unlocked object so try the fast recursive case. 2895 2896 // Check if the owner is self by comparing the value in the 2897 // markOop of object (disp_hdr) with the stack pointer. 2898 __ mov(rscratch1, sp); 2899 __ sub(disp_hdr, disp_hdr, rscratch1); 2900 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 2901 // If condition is true we are cont and hence we can store 0 as the 2902 // displaced header in the box, which indicates that it is a recursive lock. 2903 __ ands(tmp/*==0?*/, disp_hdr, tmp); 2904 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2905 2906 // Handle existing monitor. 2907 if ((EmitSync & 0x02) == 0) { 2908 __ b(cont); 2909 2910 __ bind(object_has_monitor); 2911 // The object's monitor m is unlocked iff m->owner == NULL, 2912 // otherwise m->owner may contain a thread or a stack address. 2913 // 2914 // Try to CAS m->owner from NULL to current thread. 2915 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 2916 __ mov(disp_hdr, zr); 2917 2918 { 2919 Label retry_load, fail; 2920 __ bind(retry_load); 2921 __ ldxr(rscratch1, tmp); 2922 __ cmp(disp_hdr, rscratch1); 2923 __ br(Assembler::NE, fail); 2924 // use stlxr to ensure update is immediately visible 2925 __ stlxr(rscratch1, rthread, tmp); 2926 __ cbnzw(rscratch1, retry_load); 2927 __ bind(fail); 2928 } 2929 2930 // Label next; 2931 // __ cmpxchgptr(/*oldv=*/disp_hdr, 2932 // /*newv=*/rthread, 2933 // /*addr=*/tmp, 2934 // /*tmp=*/rscratch1, 2935 // /*succeed*/next, 2936 // /*fail*/NULL); 2937 // __ bind(next); 2938 2939 // store a non-null value into the box. 2940 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2941 2942 // PPC port checks the following invariants 2943 // #ifdef ASSERT 2944 // bne(flag, cont); 2945 // We have acquired the monitor, check some invariants. 2946 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 2947 // Invariant 1: _recursions should be 0. 2948 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 2949 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 2950 // "monitor->_recursions should be 0", -1); 2951 // Invariant 2: OwnerIsThread shouldn't be 0. 2952 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 2953 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 2954 // "monitor->OwnerIsThread shouldn't be 0", -1); 2955 // #endif 2956 } 2957 2958 __ bind(cont); 2959 // flag == EQ indicates success 2960 // flag == NE indicates failure 2961 2962 %} 2963 2964 // TODO 2965 // reimplement this with custom cmpxchgptr code 2966 // which avoids some of the unnecessary branching 2967 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 2968 MacroAssembler _masm(&cbuf); 2969 Register oop = as_Register($object$$reg); 2970 Register box = as_Register($box$$reg); 2971 Register disp_hdr = as_Register($tmp$$reg); 2972 Register tmp = as_Register($tmp2$$reg); 2973 Label cont; 2974 Label object_has_monitor; 2975 Label cas_failed; 2976 2977 assert_different_registers(oop, box, tmp, disp_hdr); 2978 2979 // Always do locking in runtime. 2980 if (EmitSync & 0x01) { 2981 __ cmp(oop, zr); // Oop can't be 0 here => always false. 2982 return; 2983 } 2984 2985 if (UseBiasedLocking) { 2986 __ biased_locking_exit(oop, tmp, cont); 2987 } 2988 2989 // Find the lock address and load the displaced header from the stack. 2990 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2991 2992 // If the displaced header is 0, we have a recursive unlock. 2993 __ cmp(disp_hdr, zr); 2994 __ br(Assembler::EQ, cont); 2995 2996 2997 // Handle existing monitor. 2998 if ((EmitSync & 0x02) == 0) { 2999 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3000 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3001 } 3002 3003 // Check if it is still a light weight lock, this is is true if we 3004 // see the stack address of the basicLock in the markOop of the 3005 // object. 3006 3007 { 3008 Label retry_load; 3009 __ bind(retry_load); 3010 __ ldxr(tmp, oop); 3011 __ cmp(box, tmp); 3012 __ br(Assembler::NE, cas_failed); 3013 // use stlxr to ensure update is immediately visible 3014 __ stlxr(tmp, disp_hdr, oop); 3015 __ cbzw(tmp, cont); 3016 __ b(retry_load); 3017 } 3018 3019 // __ cmpxchgptr(/*compare_value=*/box, 3020 // /*exchange_value=*/disp_hdr, 3021 // /*where=*/oop, 3022 // /*result=*/tmp, 3023 // cont, 3024 // /*cas_failed*/NULL); 3025 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3026 3027 __ bind(cas_failed); 3028 3029 // Handle existing monitor. 3030 if ((EmitSync & 0x02) == 0) { 3031 __ b(cont); 3032 3033 __ bind(object_has_monitor); 3034 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3035 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3036 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3037 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3038 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3039 __ cmp(rscratch1, zr); 3040 __ br(Assembler::NE, cont); 3041 3042 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3043 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3044 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3045 __ cmp(rscratch1, zr); 3046 __ cbnz(rscratch1, cont); 3047 // need a release store here 3048 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3049 __ stlr(rscratch1, tmp); // rscratch1 is zero 3050 } 3051 3052 __ bind(cont); 3053 // flag == EQ indicates success 3054 // flag == NE indicates failure 3055 %} 3056 3057 %} 3058 3059 //----------FRAME-------------------------------------------------------------- 3060 // Definition of frame structure and management information. 3061 // 3062 // S T A C K L A Y O U T Allocators stack-slot number 3063 // | (to get allocators register number 3064 // G Owned by | | v add OptoReg::stack0()) 3065 // r CALLER | | 3066 // o | +--------+ pad to even-align allocators stack-slot 3067 // w V | pad0 | numbers; owned by CALLER 3068 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3069 // h ^ | in | 5 3070 // | | args | 4 Holes in incoming args owned by SELF 3071 // | | | | 3 3072 // | | +--------+ 3073 // V | | old out| Empty on Intel, window on Sparc 3074 // | old |preserve| Must be even aligned. 3075 // | SP-+--------+----> Matcher::_old_SP, even aligned 3076 // | | in | 3 area for Intel ret address 3077 // Owned by |preserve| Empty on Sparc. 3078 // SELF +--------+ 3079 // | | pad2 | 2 pad to align old SP 3080 // | +--------+ 1 3081 // | | locks | 0 3082 // | +--------+----> OptoReg::stack0(), even aligned 3083 // | | pad1 | 11 pad to align new SP 3084 // | +--------+ 3085 // | | | 10 3086 // | | spills | 9 spills 3087 // V | | 8 (pad0 slot for callee) 3088 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3089 // ^ | out | 7 3090 // | | args | 6 Holes in outgoing args owned by CALLEE 3091 // Owned by +--------+ 3092 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3093 // | new |preserve| Must be even-aligned. 3094 // | SP-+--------+----> Matcher::_new_SP, even aligned 3095 // | | | 3096 // 3097 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3098 // known from SELF's arguments and the Java calling convention. 3099 // Region 6-7 is determined per call site. 3100 // Note 2: If the calling convention leaves holes in the incoming argument 3101 // area, those holes are owned by SELF. Holes in the outgoing area 3102 // are owned by the CALLEE. Holes should not be nessecary in the 3103 // incoming area, as the Java calling convention is completely under 3104 // the control of the AD file. Doubles can be sorted and packed to 3105 // avoid holes. Holes in the outgoing arguments may be nessecary for 3106 // varargs C calling conventions. 3107 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3108 // even aligned with pad0 as needed. 3109 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3110 // (the latter is true on Intel but is it false on AArch64?) 3111 // region 6-11 is even aligned; it may be padded out more so that 3112 // the region from SP to FP meets the minimum stack alignment. 3113 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3114 // alignment. Region 11, pad1, may be dynamically extended so that 3115 // SP meets the minimum alignment. 3116 3117 frame %{ 3118 // What direction does stack grow in (assumed to be same for C & Java) 3119 stack_direction(TOWARDS_LOW); 3120 3121 // These three registers define part of the calling convention 3122 // between compiled code and the interpreter. 3123 3124 // Inline Cache Register or methodOop for I2C. 3125 inline_cache_reg(R12); 3126 3127 // Method Oop Register when calling interpreter. 3128 interpreter_method_oop_reg(R12); 3129 3130 // Number of stack slots consumed by locking an object 3131 sync_stack_slots(2); 3132 3133 // Compiled code's Frame Pointer 3134 frame_pointer(R31); 3135 3136 // Interpreter stores its frame pointer in a register which is 3137 // stored to the stack by I2CAdaptors. 3138 // I2CAdaptors convert from interpreted java to compiled java. 3139 interpreter_frame_pointer(R29); 3140 3141 // Stack alignment requirement 3142 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3143 3144 // Number of stack slots between incoming argument block and the start of 3145 // a new frame. The PROLOG must add this many slots to the stack. The 3146 // EPILOG must remove this many slots. aarch64 needs two slots for 3147 // return address and fp. 3148 // TODO think this is correct but check 3149 in_preserve_stack_slots(4); 3150 3151 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3152 // for calls to C. Supports the var-args backing area for register parms. 3153 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3154 3155 // The after-PROLOG location of the return address. Location of 3156 // return address specifies a type (REG or STACK) and a number 3157 // representing the register number (i.e. - use a register name) or 3158 // stack slot. 3159 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3160 // Otherwise, it is above the locks and verification slot and alignment word 3161 // TODO this may well be correct but need to check why that - 2 is there 3162 // ppc port uses 0 but we definitely need to allow for fixed_slots 3163 // which folds in the space used for monitors 3164 return_addr(STACK - 2 + 3165 round_to((Compile::current()->in_preserve_stack_slots() + 3166 Compile::current()->fixed_slots()), 3167 stack_alignment_in_slots())); 3168 3169 // Body of function which returns an integer array locating 3170 // arguments either in registers or in stack slots. Passed an array 3171 // of ideal registers called "sig" and a "length" count. Stack-slot 3172 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3173 // arguments for a CALLEE. Incoming stack arguments are 3174 // automatically biased by the preserve_stack_slots field above. 3175 3176 calling_convention 3177 %{ 3178 // No difference between ingoing/outgoing just pass false 3179 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3180 %} 3181 3182 c_calling_convention 3183 %{ 3184 // This is obviously always outgoing 3185 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3186 %} 3187 3188 // Location of compiled Java return values. Same as C for now. 3189 return_value 3190 %{ 3191 // TODO do we allow ideal_reg == Op_RegN??? 3192 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3193 "only return normal values"); 3194 3195 static const int lo[Op_RegL + 1] = { // enum name 3196 0, // Op_Node 3197 0, // Op_Set 3198 R0_num, // Op_RegN 3199 R0_num, // Op_RegI 3200 R0_num, // Op_RegP 3201 V0_num, // Op_RegF 3202 V0_num, // Op_RegD 3203 R0_num // Op_RegL 3204 }; 3205 3206 static const int hi[Op_RegL + 1] = { // enum name 3207 0, // Op_Node 3208 0, // Op_Set 3209 OptoReg::Bad, // Op_RegN 3210 OptoReg::Bad, // Op_RegI 3211 R0_H_num, // Op_RegP 3212 OptoReg::Bad, // Op_RegF 3213 V0_H_num, // Op_RegD 3214 R0_H_num // Op_RegL 3215 }; 3216 3217 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3218 %} 3219 %} 3220 3221 //----------ATTRIBUTES--------------------------------------------------------- 3222 //----------Operand Attributes------------------------------------------------- 3223 op_attrib op_cost(1); // Required cost attribute 3224 3225 //----------Instruction Attributes--------------------------------------------- 3226 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3227 ins_attrib ins_size(32); // Required size attribute (in bits) 3228 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3229 // a non-matching short branch variant 3230 // of some long branch? 3231 ins_attrib ins_alignment(4); // Required alignment attribute (must 3232 // be a power of 2) specifies the 3233 // alignment that some part of the 3234 // instruction (not necessarily the 3235 // start) requires. If > 1, a 3236 // compute_padding() function must be 3237 // provided for the instruction 3238 3239 //----------OPERANDS----------------------------------------------------------- 3240 // Operand definitions must precede instruction definitions for correct parsing 3241 // in the ADLC because operands constitute user defined types which are used in 3242 // instruction definitions. 3243 3244 //----------Simple Operands---------------------------------------------------- 3245 3246 // Integer operands 32 bit 3247 // 32 bit immediate 3248 operand immI() 3249 %{ 3250 match(ConI); 3251 3252 op_cost(0); 3253 format %{ %} 3254 interface(CONST_INTER); 3255 %} 3256 3257 // 32 bit zero 3258 operand immI0() 3259 %{ 3260 predicate(n->get_int() == 0); 3261 match(ConI); 3262 3263 op_cost(0); 3264 format %{ %} 3265 interface(CONST_INTER); 3266 %} 3267 3268 // 32 bit unit increment 3269 operand immI_1() 3270 %{ 3271 predicate(n->get_int() == 1); 3272 match(ConI); 3273 3274 op_cost(0); 3275 format %{ %} 3276 interface(CONST_INTER); 3277 %} 3278 3279 // 32 bit unit decrement 3280 operand immI_M1() 3281 %{ 3282 predicate(n->get_int() == -1); 3283 match(ConI); 3284 3285 op_cost(0); 3286 format %{ %} 3287 interface(CONST_INTER); 3288 %} 3289 3290 operand immI_le_4() 3291 %{ 3292 predicate(n->get_int() <= 4); 3293 match(ConI); 3294 3295 op_cost(0); 3296 format %{ %} 3297 interface(CONST_INTER); 3298 %} 3299 3300 operand immI_31() 3301 %{ 3302 predicate(n->get_int() == 31); 3303 match(ConI); 3304 3305 op_cost(0); 3306 format %{ %} 3307 interface(CONST_INTER); 3308 %} 3309 3310 operand immI_8() 3311 %{ 3312 predicate(n->get_int() == 8); 3313 match(ConI); 3314 3315 op_cost(0); 3316 format %{ %} 3317 interface(CONST_INTER); 3318 %} 3319 3320 operand immI_16() 3321 %{ 3322 predicate(n->get_int() == 16); 3323 match(ConI); 3324 3325 op_cost(0); 3326 format %{ %} 3327 interface(CONST_INTER); 3328 %} 3329 3330 operand immI_24() 3331 %{ 3332 predicate(n->get_int() == 24); 3333 match(ConI); 3334 3335 op_cost(0); 3336 format %{ %} 3337 interface(CONST_INTER); 3338 %} 3339 3340 operand immI_32() 3341 %{ 3342 predicate(n->get_int() == 32); 3343 match(ConI); 3344 3345 op_cost(0); 3346 format %{ %} 3347 interface(CONST_INTER); 3348 %} 3349 3350 operand immI_48() 3351 %{ 3352 predicate(n->get_int() == 48); 3353 match(ConI); 3354 3355 op_cost(0); 3356 format %{ %} 3357 interface(CONST_INTER); 3358 %} 3359 3360 operand immI_56() 3361 %{ 3362 predicate(n->get_int() == 56); 3363 match(ConI); 3364 3365 op_cost(0); 3366 format %{ %} 3367 interface(CONST_INTER); 3368 %} 3369 3370 operand immI_64() 3371 %{ 3372 predicate(n->get_int() == 64); 3373 match(ConI); 3374 3375 op_cost(0); 3376 format %{ %} 3377 interface(CONST_INTER); 3378 %} 3379 3380 operand immI_255() 3381 %{ 3382 predicate(n->get_int() == 255); 3383 match(ConI); 3384 3385 op_cost(0); 3386 format %{ %} 3387 interface(CONST_INTER); 3388 %} 3389 3390 operand immI_65535() 3391 %{ 3392 predicate(n->get_int() == 65535); 3393 match(ConI); 3394 3395 op_cost(0); 3396 format %{ %} 3397 interface(CONST_INTER); 3398 %} 3399 3400 operand immL_63() 3401 %{ 3402 predicate(n->get_int() == 63); 3403 match(ConI); 3404 3405 op_cost(0); 3406 format %{ %} 3407 interface(CONST_INTER); 3408 %} 3409 3410 operand immL_255() 3411 %{ 3412 predicate(n->get_int() == 255); 3413 match(ConI); 3414 3415 op_cost(0); 3416 format %{ %} 3417 interface(CONST_INTER); 3418 %} 3419 3420 operand immL_65535() 3421 %{ 3422 predicate(n->get_long() == 65535L); 3423 match(ConL); 3424 3425 op_cost(0); 3426 format %{ %} 3427 interface(CONST_INTER); 3428 %} 3429 3430 operand immL_4294967295() 3431 %{ 3432 predicate(n->get_long() == 4294967295L); 3433 match(ConL); 3434 3435 op_cost(0); 3436 format %{ %} 3437 interface(CONST_INTER); 3438 %} 3439 3440 operand immL_bitmask() 3441 %{ 3442 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3443 && is_power_of_2(n->get_long() + 1)); 3444 match(ConL); 3445 3446 op_cost(0); 3447 format %{ %} 3448 interface(CONST_INTER); 3449 %} 3450 3451 operand immI_bitmask() 3452 %{ 3453 predicate(((n->get_int() & 0xc0000000) == 0) 3454 && is_power_of_2(n->get_int() + 1)); 3455 match(ConI); 3456 3457 op_cost(0); 3458 format %{ %} 3459 interface(CONST_INTER); 3460 %} 3461 3462 // Scale values for scaled offset addressing modes (up to long but not quad) 3463 operand immIScale() 3464 %{ 3465 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3466 match(ConI); 3467 3468 op_cost(0); 3469 format %{ %} 3470 interface(CONST_INTER); 3471 %} 3472 3473 // 26 bit signed offset -- for pc-relative branches 3474 operand immI26() 3475 %{ 3476 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 3477 match(ConI); 3478 3479 op_cost(0); 3480 format %{ %} 3481 interface(CONST_INTER); 3482 %} 3483 3484 // 19 bit signed offset -- for pc-relative loads 3485 operand immI19() 3486 %{ 3487 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 3488 match(ConI); 3489 3490 op_cost(0); 3491 format %{ %} 3492 interface(CONST_INTER); 3493 %} 3494 3495 // 12 bit unsigned offset -- for base plus immediate loads 3496 operand immIU12() 3497 %{ 3498 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 3499 match(ConI); 3500 3501 op_cost(0); 3502 format %{ %} 3503 interface(CONST_INTER); 3504 %} 3505 3506 operand immLU12() 3507 %{ 3508 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 3509 match(ConL); 3510 3511 op_cost(0); 3512 format %{ %} 3513 interface(CONST_INTER); 3514 %} 3515 3516 // Offset for scaled or unscaled immediate loads and stores 3517 operand immIOffset() 3518 %{ 3519 predicate(Address::offset_ok_for_immed(n->get_int())); 3520 match(ConI); 3521 3522 op_cost(0); 3523 format %{ %} 3524 interface(CONST_INTER); 3525 %} 3526 3527 operand immLoffset() 3528 %{ 3529 predicate(Address::offset_ok_for_immed(n->get_long())); 3530 match(ConL); 3531 3532 op_cost(0); 3533 format %{ %} 3534 interface(CONST_INTER); 3535 %} 3536 3537 // 32 bit integer valid for add sub immediate 3538 operand immIAddSub() 3539 %{ 3540 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 3541 match(ConI); 3542 op_cost(0); 3543 format %{ %} 3544 interface(CONST_INTER); 3545 %} 3546 3547 // 32 bit unsigned integer valid for logical immediate 3548 // TODO -- check this is right when e.g the mask is 0x80000000 3549 operand immILog() 3550 %{ 3551 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 3552 match(ConI); 3553 3554 op_cost(0); 3555 format %{ %} 3556 interface(CONST_INTER); 3557 %} 3558 3559 // Integer operands 64 bit 3560 // 64 bit immediate 3561 operand immL() 3562 %{ 3563 match(ConL); 3564 3565 op_cost(0); 3566 format %{ %} 3567 interface(CONST_INTER); 3568 %} 3569 3570 // 64 bit zero 3571 operand immL0() 3572 %{ 3573 predicate(n->get_long() == 0); 3574 match(ConL); 3575 3576 op_cost(0); 3577 format %{ %} 3578 interface(CONST_INTER); 3579 %} 3580 3581 // 64 bit unit increment 3582 operand immL_1() 3583 %{ 3584 predicate(n->get_long() == 1); 3585 match(ConL); 3586 3587 op_cost(0); 3588 format %{ %} 3589 interface(CONST_INTER); 3590 %} 3591 3592 // 64 bit unit decrement 3593 operand immL_M1() 3594 %{ 3595 predicate(n->get_long() == -1); 3596 match(ConL); 3597 3598 op_cost(0); 3599 format %{ %} 3600 interface(CONST_INTER); 3601 %} 3602 3603 // 32 bit offset of pc in thread anchor 3604 3605 operand immL_pc_off() 3606 %{ 3607 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 3608 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 3609 match(ConL); 3610 3611 op_cost(0); 3612 format %{ %} 3613 interface(CONST_INTER); 3614 %} 3615 3616 // 64 bit integer valid for add sub immediate 3617 operand immLAddSub() 3618 %{ 3619 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 3620 match(ConL); 3621 op_cost(0); 3622 format %{ %} 3623 interface(CONST_INTER); 3624 %} 3625 3626 // 64 bit integer valid for logical immediate 3627 operand immLLog() 3628 %{ 3629 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 3630 match(ConL); 3631 op_cost(0); 3632 format %{ %} 3633 interface(CONST_INTER); 3634 %} 3635 3636 // Long Immediate: low 32-bit mask 3637 operand immL_32bits() 3638 %{ 3639 predicate(n->get_long() == 0xFFFFFFFFL); 3640 match(ConL); 3641 op_cost(0); 3642 format %{ %} 3643 interface(CONST_INTER); 3644 %} 3645 3646 // Pointer operands 3647 // Pointer Immediate 3648 operand immP() 3649 %{ 3650 match(ConP); 3651 3652 op_cost(0); 3653 format %{ %} 3654 interface(CONST_INTER); 3655 %} 3656 3657 // NULL Pointer Immediate 3658 operand immP0() 3659 %{ 3660 predicate(n->get_ptr() == 0); 3661 match(ConP); 3662 3663 op_cost(0); 3664 format %{ %} 3665 interface(CONST_INTER); 3666 %} 3667 3668 // Pointer Immediate One 3669 // this is used in object initialization (initial object header) 3670 operand immP_1() 3671 %{ 3672 predicate(n->get_ptr() == 1); 3673 match(ConP); 3674 3675 op_cost(0); 3676 format %{ %} 3677 interface(CONST_INTER); 3678 %} 3679 3680 // Polling Page Pointer Immediate 3681 operand immPollPage() 3682 %{ 3683 predicate((address)n->get_ptr() == os::get_polling_page()); 3684 match(ConP); 3685 3686 op_cost(0); 3687 format %{ %} 3688 interface(CONST_INTER); 3689 %} 3690 3691 // Card Table Byte Map Base 3692 operand immByteMapBase() 3693 %{ 3694 // Get base of card map 3695 predicate((jbyte*)n->get_ptr() == 3696 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); 3697 match(ConP); 3698 3699 op_cost(0); 3700 format %{ %} 3701 interface(CONST_INTER); 3702 %} 3703 3704 // Pointer Immediate Minus One 3705 // this is used when we want to write the current PC to the thread anchor 3706 operand immP_M1() 3707 %{ 3708 predicate(n->get_ptr() == -1); 3709 match(ConP); 3710 3711 op_cost(0); 3712 format %{ %} 3713 interface(CONST_INTER); 3714 %} 3715 3716 // Pointer Immediate Minus Two 3717 // this is used when we want to write the current PC to the thread anchor 3718 operand immP_M2() 3719 %{ 3720 predicate(n->get_ptr() == -2); 3721 match(ConP); 3722 3723 op_cost(0); 3724 format %{ %} 3725 interface(CONST_INTER); 3726 %} 3727 3728 // Float and Double operands 3729 // Double Immediate 3730 operand immD() 3731 %{ 3732 match(ConD); 3733 op_cost(0); 3734 format %{ %} 3735 interface(CONST_INTER); 3736 %} 3737 3738 // Double Immediate: +0.0d 3739 operand immD0() 3740 %{ 3741 predicate(jlong_cast(n->getd()) == 0); 3742 match(ConD); 3743 3744 op_cost(0); 3745 format %{ %} 3746 interface(CONST_INTER); 3747 %} 3748 3749 // constant 'double +0.0'. 3750 operand immDPacked() 3751 %{ 3752 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 3753 match(ConD); 3754 op_cost(0); 3755 format %{ %} 3756 interface(CONST_INTER); 3757 %} 3758 3759 // Float Immediate 3760 operand immF() 3761 %{ 3762 match(ConF); 3763 op_cost(0); 3764 format %{ %} 3765 interface(CONST_INTER); 3766 %} 3767 3768 // Float Immediate: +0.0f. 3769 operand immF0() 3770 %{ 3771 predicate(jint_cast(n->getf()) == 0); 3772 match(ConF); 3773 3774 op_cost(0); 3775 format %{ %} 3776 interface(CONST_INTER); 3777 %} 3778 3779 // 3780 operand immFPacked() 3781 %{ 3782 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 3783 match(ConF); 3784 op_cost(0); 3785 format %{ %} 3786 interface(CONST_INTER); 3787 %} 3788 3789 // Narrow pointer operands 3790 // Narrow Pointer Immediate 3791 operand immN() 3792 %{ 3793 match(ConN); 3794 3795 op_cost(0); 3796 format %{ %} 3797 interface(CONST_INTER); 3798 %} 3799 3800 // Narrow NULL Pointer Immediate 3801 operand immN0() 3802 %{ 3803 predicate(n->get_narrowcon() == 0); 3804 match(ConN); 3805 3806 op_cost(0); 3807 format %{ %} 3808 interface(CONST_INTER); 3809 %} 3810 3811 operand immNKlass() 3812 %{ 3813 match(ConNKlass); 3814 3815 op_cost(0); 3816 format %{ %} 3817 interface(CONST_INTER); 3818 %} 3819 3820 // Integer 32 bit Register Operands 3821 // Integer 32 bitRegister (excludes SP) 3822 operand iRegI() 3823 %{ 3824 constraint(ALLOC_IN_RC(any_reg32)); 3825 match(RegI); 3826 match(iRegINoSp); 3827 op_cost(0); 3828 format %{ %} 3829 interface(REG_INTER); 3830 %} 3831 3832 // Integer 32 bit Register not Special 3833 operand iRegINoSp() 3834 %{ 3835 constraint(ALLOC_IN_RC(no_special_reg32)); 3836 match(RegI); 3837 op_cost(0); 3838 format %{ %} 3839 interface(REG_INTER); 3840 %} 3841 3842 // Integer 64 bit Register Operands 3843 // Integer 64 bit Register (includes SP) 3844 operand iRegL() 3845 %{ 3846 constraint(ALLOC_IN_RC(any_reg)); 3847 match(RegL); 3848 match(iRegLNoSp); 3849 op_cost(0); 3850 format %{ %} 3851 interface(REG_INTER); 3852 %} 3853 3854 // Integer 64 bit Register not Special 3855 operand iRegLNoSp() 3856 %{ 3857 constraint(ALLOC_IN_RC(no_special_reg)); 3858 match(RegL); 3859 format %{ %} 3860 interface(REG_INTER); 3861 %} 3862 3863 // Pointer Register Operands 3864 // Pointer Register 3865 operand iRegP() 3866 %{ 3867 constraint(ALLOC_IN_RC(ptr_reg)); 3868 match(RegP); 3869 match(iRegPNoSp); 3870 match(iRegP_R0); 3871 //match(iRegP_R2); 3872 //match(iRegP_R4); 3873 //match(iRegP_R5); 3874 match(thread_RegP); 3875 op_cost(0); 3876 format %{ %} 3877 interface(REG_INTER); 3878 %} 3879 3880 // Pointer 64 bit Register not Special 3881 operand iRegPNoSp() 3882 %{ 3883 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 3884 match(RegP); 3885 // match(iRegP); 3886 // match(iRegP_R0); 3887 // match(iRegP_R2); 3888 // match(iRegP_R4); 3889 // match(iRegP_R5); 3890 // match(thread_RegP); 3891 op_cost(0); 3892 format %{ %} 3893 interface(REG_INTER); 3894 %} 3895 3896 // Pointer 64 bit Register R0 only 3897 operand iRegP_R0() 3898 %{ 3899 constraint(ALLOC_IN_RC(r0_reg)); 3900 match(RegP); 3901 // match(iRegP); 3902 match(iRegPNoSp); 3903 op_cost(0); 3904 format %{ %} 3905 interface(REG_INTER); 3906 %} 3907 3908 // Pointer 64 bit Register R1 only 3909 operand iRegP_R1() 3910 %{ 3911 constraint(ALLOC_IN_RC(r1_reg)); 3912 match(RegP); 3913 // match(iRegP); 3914 match(iRegPNoSp); 3915 op_cost(0); 3916 format %{ %} 3917 interface(REG_INTER); 3918 %} 3919 3920 // Pointer 64 bit Register R2 only 3921 operand iRegP_R2() 3922 %{ 3923 constraint(ALLOC_IN_RC(r2_reg)); 3924 match(RegP); 3925 // match(iRegP); 3926 match(iRegPNoSp); 3927 op_cost(0); 3928 format %{ %} 3929 interface(REG_INTER); 3930 %} 3931 3932 // Pointer 64 bit Register R3 only 3933 operand iRegP_R3() 3934 %{ 3935 constraint(ALLOC_IN_RC(r3_reg)); 3936 match(RegP); 3937 // match(iRegP); 3938 match(iRegPNoSp); 3939 op_cost(0); 3940 format %{ %} 3941 interface(REG_INTER); 3942 %} 3943 3944 // Pointer 64 bit Register R4 only 3945 operand iRegP_R4() 3946 %{ 3947 constraint(ALLOC_IN_RC(r4_reg)); 3948 match(RegP); 3949 // match(iRegP); 3950 match(iRegPNoSp); 3951 op_cost(0); 3952 format %{ %} 3953 interface(REG_INTER); 3954 %} 3955 3956 // Pointer 64 bit Register R5 only 3957 operand iRegP_R5() 3958 %{ 3959 constraint(ALLOC_IN_RC(r5_reg)); 3960 match(RegP); 3961 // match(iRegP); 3962 match(iRegPNoSp); 3963 op_cost(0); 3964 format %{ %} 3965 interface(REG_INTER); 3966 %} 3967 3968 // Pointer 64 bit Register R10 only 3969 operand iRegP_R10() 3970 %{ 3971 constraint(ALLOC_IN_RC(r10_reg)); 3972 match(RegP); 3973 // match(iRegP); 3974 match(iRegPNoSp); 3975 op_cost(0); 3976 format %{ %} 3977 interface(REG_INTER); 3978 %} 3979 3980 // Long 64 bit Register R11 only 3981 operand iRegL_R11() 3982 %{ 3983 constraint(ALLOC_IN_RC(r11_reg)); 3984 match(RegL); 3985 match(iRegLNoSp); 3986 op_cost(0); 3987 format %{ %} 3988 interface(REG_INTER); 3989 %} 3990 3991 // Pointer 64 bit Register FP only 3992 operand iRegP_FP() 3993 %{ 3994 constraint(ALLOC_IN_RC(fp_reg)); 3995 match(RegP); 3996 // match(iRegP); 3997 op_cost(0); 3998 format %{ %} 3999 interface(REG_INTER); 4000 %} 4001 4002 // Register R0 only 4003 operand iRegI_R0() 4004 %{ 4005 constraint(ALLOC_IN_RC(int_r0_reg)); 4006 match(RegI); 4007 match(iRegINoSp); 4008 op_cost(0); 4009 format %{ %} 4010 interface(REG_INTER); 4011 %} 4012 4013 // Register R2 only 4014 operand iRegI_R2() 4015 %{ 4016 constraint(ALLOC_IN_RC(int_r2_reg)); 4017 match(RegI); 4018 match(iRegINoSp); 4019 op_cost(0); 4020 format %{ %} 4021 interface(REG_INTER); 4022 %} 4023 4024 // Register R3 only 4025 operand iRegI_R3() 4026 %{ 4027 constraint(ALLOC_IN_RC(int_r3_reg)); 4028 match(RegI); 4029 match(iRegINoSp); 4030 op_cost(0); 4031 format %{ %} 4032 interface(REG_INTER); 4033 %} 4034 4035 4036 // Register R2 only 4037 operand iRegI_R4() 4038 %{ 4039 constraint(ALLOC_IN_RC(int_r4_reg)); 4040 match(RegI); 4041 match(iRegINoSp); 4042 op_cost(0); 4043 format %{ %} 4044 interface(REG_INTER); 4045 %} 4046 4047 4048 // Pointer Register Operands 4049 // Narrow Pointer Register 4050 operand iRegN() 4051 %{ 4052 constraint(ALLOC_IN_RC(any_reg32)); 4053 match(RegN); 4054 match(iRegNNoSp); 4055 op_cost(0); 4056 format %{ %} 4057 interface(REG_INTER); 4058 %} 4059 4060 // Integer 64 bit Register not Special 4061 operand iRegNNoSp() 4062 %{ 4063 constraint(ALLOC_IN_RC(no_special_reg32)); 4064 match(RegN); 4065 op_cost(0); 4066 format %{ %} 4067 interface(REG_INTER); 4068 %} 4069 4070 // heap base register -- used for encoding immN0 4071 4072 operand iRegIHeapbase() 4073 %{ 4074 constraint(ALLOC_IN_RC(heapbase_reg)); 4075 match(RegI); 4076 op_cost(0); 4077 format %{ %} 4078 interface(REG_INTER); 4079 %} 4080 4081 // Float Register 4082 // Float register operands 4083 operand vRegF() 4084 %{ 4085 constraint(ALLOC_IN_RC(float_reg)); 4086 match(RegF); 4087 4088 op_cost(0); 4089 format %{ %} 4090 interface(REG_INTER); 4091 %} 4092 4093 // Double Register 4094 // Double register operands 4095 operand vRegD() 4096 %{ 4097 constraint(ALLOC_IN_RC(double_reg)); 4098 match(RegD); 4099 4100 op_cost(0); 4101 format %{ %} 4102 interface(REG_INTER); 4103 %} 4104 4105 operand vRegD_V0() 4106 %{ 4107 constraint(ALLOC_IN_RC(v0_reg)); 4108 match(RegD); 4109 op_cost(0); 4110 format %{ %} 4111 interface(REG_INTER); 4112 %} 4113 4114 operand vRegD_V1() 4115 %{ 4116 constraint(ALLOC_IN_RC(v1_reg)); 4117 match(RegD); 4118 op_cost(0); 4119 format %{ %} 4120 interface(REG_INTER); 4121 %} 4122 4123 operand vRegD_V2() 4124 %{ 4125 constraint(ALLOC_IN_RC(v2_reg)); 4126 match(RegD); 4127 op_cost(0); 4128 format %{ %} 4129 interface(REG_INTER); 4130 %} 4131 4132 operand vRegD_V3() 4133 %{ 4134 constraint(ALLOC_IN_RC(v3_reg)); 4135 match(RegD); 4136 op_cost(0); 4137 format %{ %} 4138 interface(REG_INTER); 4139 %} 4140 4141 // Flags register, used as output of signed compare instructions 4142 4143 // note that on AArch64 we also use this register as the output for 4144 // for floating point compare instructions (CmpF CmpD). this ensures 4145 // that ordered inequality tests use GT, GE, LT or LE none of which 4146 // pass through cases where the result is unordered i.e. one or both 4147 // inputs to the compare is a NaN. this means that the ideal code can 4148 // replace e.g. a GT with an LE and not end up capturing the NaN case 4149 // (where the comparison should always fail). EQ and NE tests are 4150 // always generated in ideal code so that unordered folds into the NE 4151 // case, matching the behaviour of AArch64 NE. 4152 // 4153 // This differs from x86 where the outputs of FP compares use a 4154 // special FP flags registers and where compares based on this 4155 // register are distinguished into ordered inequalities (cmpOpUCF) and 4156 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4157 // to explicitly handle the unordered case in branches. x86 also has 4158 // to include extra CMoveX rules to accept a cmpOpUCF input. 4159 4160 operand rFlagsReg() 4161 %{ 4162 constraint(ALLOC_IN_RC(int_flags)); 4163 match(RegFlags); 4164 4165 op_cost(0); 4166 format %{ "RFLAGS" %} 4167 interface(REG_INTER); 4168 %} 4169 4170 // Flags register, used as output of unsigned compare instructions 4171 operand rFlagsRegU() 4172 %{ 4173 constraint(ALLOC_IN_RC(int_flags)); 4174 match(RegFlags); 4175 4176 op_cost(0); 4177 format %{ "RFLAGSU" %} 4178 interface(REG_INTER); 4179 %} 4180 4181 // Special Registers 4182 4183 // Method Register 4184 operand inline_cache_RegP(iRegP reg) 4185 %{ 4186 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4187 match(reg); 4188 match(iRegPNoSp); 4189 op_cost(0); 4190 format %{ %} 4191 interface(REG_INTER); 4192 %} 4193 4194 operand interpreter_method_oop_RegP(iRegP reg) 4195 %{ 4196 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4197 match(reg); 4198 match(iRegPNoSp); 4199 op_cost(0); 4200 format %{ %} 4201 interface(REG_INTER); 4202 %} 4203 4204 // Thread Register 4205 operand thread_RegP(iRegP reg) 4206 %{ 4207 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4208 match(reg); 4209 op_cost(0); 4210 format %{ %} 4211 interface(REG_INTER); 4212 %} 4213 4214 operand lr_RegP(iRegP reg) 4215 %{ 4216 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4217 match(reg); 4218 op_cost(0); 4219 format %{ %} 4220 interface(REG_INTER); 4221 %} 4222 4223 //----------Memory Operands---------------------------------------------------- 4224 4225 operand indirect(iRegP reg) 4226 %{ 4227 constraint(ALLOC_IN_RC(ptr_reg)); 4228 match(reg); 4229 op_cost(0); 4230 format %{ "[$reg]" %} 4231 interface(MEMORY_INTER) %{ 4232 base($reg); 4233 index(0xffffffff); 4234 scale(0x0); 4235 disp(0x0); 4236 %} 4237 %} 4238 4239 operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off) 4240 %{ 4241 constraint(ALLOC_IN_RC(ptr_reg)); 4242 match(AddP (AddP reg (LShiftL lreg scale)) off); 4243 op_cost(INSN_COST); 4244 format %{ "$reg, $lreg lsl($scale), $off" %} 4245 interface(MEMORY_INTER) %{ 4246 base($reg); 4247 index($lreg); 4248 scale($scale); 4249 disp($off); 4250 %} 4251 %} 4252 4253 operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off) 4254 %{ 4255 constraint(ALLOC_IN_RC(ptr_reg)); 4256 match(AddP (AddP reg (LShiftL lreg scale)) off); 4257 op_cost(INSN_COST); 4258 format %{ "$reg, $lreg lsl($scale), $off" %} 4259 interface(MEMORY_INTER) %{ 4260 base($reg); 4261 index($lreg); 4262 scale($scale); 4263 disp($off); 4264 %} 4265 %} 4266 4267 operand indIndexOffsetI2L(iRegP reg, iRegI ireg, immLU12 off) 4268 %{ 4269 constraint(ALLOC_IN_RC(ptr_reg)); 4270 match(AddP (AddP reg (ConvI2L ireg)) off); 4271 op_cost(10); 4272 format %{ "$reg, $ireg, $off I2L" %} 4273 interface(MEMORY_INTER) %{ 4274 base($reg); 4275 index($ireg); 4276 scale(0x0); 4277 disp($off); 4278 %} 4279 %} 4280 4281 operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off) 4282 %{ 4283 constraint(ALLOC_IN_RC(ptr_reg)); 4284 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off); 4285 op_cost(INSN_COST); 4286 format %{ "$reg, $ireg sxtw($scale), $off I2L" %} 4287 interface(MEMORY_INTER) %{ 4288 base($reg); 4289 index($ireg); 4290 scale($scale); 4291 disp($off); 4292 %} 4293 %} 4294 4295 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4296 %{ 4297 constraint(ALLOC_IN_RC(ptr_reg)); 4298 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4299 op_cost(0); 4300 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4301 interface(MEMORY_INTER) %{ 4302 base($reg); 4303 index($ireg); 4304 scale($scale); 4305 disp(0x0); 4306 %} 4307 %} 4308 4309 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4310 %{ 4311 constraint(ALLOC_IN_RC(ptr_reg)); 4312 match(AddP reg (LShiftL lreg scale)); 4313 op_cost(0); 4314 format %{ "$reg, $lreg lsl($scale)" %} 4315 interface(MEMORY_INTER) %{ 4316 base($reg); 4317 index($lreg); 4318 scale($scale); 4319 disp(0x0); 4320 %} 4321 %} 4322 4323 operand indIndex(iRegP reg, iRegL lreg) 4324 %{ 4325 constraint(ALLOC_IN_RC(ptr_reg)); 4326 match(AddP reg lreg); 4327 op_cost(0); 4328 format %{ "$reg, $lreg" %} 4329 interface(MEMORY_INTER) %{ 4330 base($reg); 4331 index($lreg); 4332 scale(0x0); 4333 disp(0x0); 4334 %} 4335 %} 4336 4337 operand indOffI(iRegP reg, immIOffset off) 4338 %{ 4339 constraint(ALLOC_IN_RC(ptr_reg)); 4340 match(AddP reg off); 4341 op_cost(INSN_COST); 4342 format %{ "[$reg, $off]" %} 4343 interface(MEMORY_INTER) %{ 4344 base($reg); 4345 index(0xffffffff); 4346 scale(0x0); 4347 disp($off); 4348 %} 4349 %} 4350 4351 operand indOffL(iRegP reg, immLoffset off) 4352 %{ 4353 constraint(ALLOC_IN_RC(ptr_reg)); 4354 match(AddP reg off); 4355 op_cost(0); 4356 format %{ "[$reg, $off]" %} 4357 interface(MEMORY_INTER) %{ 4358 base($reg); 4359 index(0xffffffff); 4360 scale(0x0); 4361 disp($off); 4362 %} 4363 %} 4364 4365 4366 operand indirectN(iRegN reg) 4367 %{ 4368 predicate(Universe::narrow_oop_shift() == 0); 4369 constraint(ALLOC_IN_RC(ptr_reg)); 4370 match(DecodeN reg); 4371 op_cost(0); 4372 format %{ "[$reg]\t# narrow" %} 4373 interface(MEMORY_INTER) %{ 4374 base($reg); 4375 index(0xffffffff); 4376 scale(0x0); 4377 disp(0x0); 4378 %} 4379 %} 4380 4381 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off) 4382 %{ 4383 predicate(Universe::narrow_oop_shift() == 0); 4384 constraint(ALLOC_IN_RC(ptr_reg)); 4385 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4386 op_cost(0); 4387 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 4388 interface(MEMORY_INTER) %{ 4389 base($reg); 4390 index($lreg); 4391 scale($scale); 4392 disp($off); 4393 %} 4394 %} 4395 4396 operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off) 4397 %{ 4398 predicate(Universe::narrow_oop_shift() == 0); 4399 constraint(ALLOC_IN_RC(ptr_reg)); 4400 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4401 op_cost(INSN_COST); 4402 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 4403 interface(MEMORY_INTER) %{ 4404 base($reg); 4405 index($lreg); 4406 scale($scale); 4407 disp($off); 4408 %} 4409 %} 4410 4411 operand indIndexOffsetI2LN(iRegN reg, iRegI ireg, immLU12 off) 4412 %{ 4413 predicate(Universe::narrow_oop_shift() == 0); 4414 constraint(ALLOC_IN_RC(ptr_reg)); 4415 match(AddP (AddP (DecodeN reg) (ConvI2L ireg)) off); 4416 op_cost(10); 4417 format %{ "$reg, $ireg, $off I2L\t# narrow" %} 4418 interface(MEMORY_INTER) %{ 4419 base($reg); 4420 index($ireg); 4421 scale(0x0); 4422 disp($off); 4423 %} 4424 %} 4425 4426 operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off) 4427 %{ 4428 predicate(Universe::narrow_oop_shift() == 0); 4429 constraint(ALLOC_IN_RC(ptr_reg)); 4430 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off); 4431 op_cost(INSN_COST); 4432 format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %} 4433 interface(MEMORY_INTER) %{ 4434 base($reg); 4435 index($ireg); 4436 scale($scale); 4437 disp($off); 4438 %} 4439 %} 4440 4441 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 4442 %{ 4443 predicate(Universe::narrow_oop_shift() == 0); 4444 constraint(ALLOC_IN_RC(ptr_reg)); 4445 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 4446 op_cost(0); 4447 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 4448 interface(MEMORY_INTER) %{ 4449 base($reg); 4450 index($ireg); 4451 scale($scale); 4452 disp(0x0); 4453 %} 4454 %} 4455 4456 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 4457 %{ 4458 predicate(Universe::narrow_oop_shift() == 0); 4459 constraint(ALLOC_IN_RC(ptr_reg)); 4460 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4461 op_cost(0); 4462 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 4463 interface(MEMORY_INTER) %{ 4464 base($reg); 4465 index($lreg); 4466 scale($scale); 4467 disp(0x0); 4468 %} 4469 %} 4470 4471 operand indIndexN(iRegN reg, iRegL lreg) 4472 %{ 4473 predicate(Universe::narrow_oop_shift() == 0); 4474 constraint(ALLOC_IN_RC(ptr_reg)); 4475 match(AddP (DecodeN reg) lreg); 4476 op_cost(0); 4477 format %{ "$reg, $lreg\t# narrow" %} 4478 interface(MEMORY_INTER) %{ 4479 base($reg); 4480 index($lreg); 4481 scale(0x0); 4482 disp(0x0); 4483 %} 4484 %} 4485 4486 operand indOffIN(iRegN reg, immIOffset off) 4487 %{ 4488 predicate(Universe::narrow_oop_shift() == 0); 4489 constraint(ALLOC_IN_RC(ptr_reg)); 4490 match(AddP (DecodeN reg) off); 4491 op_cost(0); 4492 format %{ "[$reg, $off]\t# narrow" %} 4493 interface(MEMORY_INTER) %{ 4494 base($reg); 4495 index(0xffffffff); 4496 scale(0x0); 4497 disp($off); 4498 %} 4499 %} 4500 4501 operand indOffLN(iRegN reg, immLoffset off) 4502 %{ 4503 predicate(Universe::narrow_oop_shift() == 0); 4504 constraint(ALLOC_IN_RC(ptr_reg)); 4505 match(AddP (DecodeN reg) off); 4506 op_cost(0); 4507 format %{ "[$reg, $off]\t# narrow" %} 4508 interface(MEMORY_INTER) %{ 4509 base($reg); 4510 index(0xffffffff); 4511 scale(0x0); 4512 disp($off); 4513 %} 4514 %} 4515 4516 4517 4518 // AArch64 opto stubs need to write to the pc slot in the thread anchor 4519 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 4520 %{ 4521 constraint(ALLOC_IN_RC(ptr_reg)); 4522 match(AddP reg off); 4523 op_cost(0); 4524 format %{ "[$reg, $off]" %} 4525 interface(MEMORY_INTER) %{ 4526 base($reg); 4527 index(0xffffffff); 4528 scale(0x0); 4529 disp($off); 4530 %} 4531 %} 4532 4533 //----------Special Memory Operands-------------------------------------------- 4534 // Stack Slot Operand - This operand is used for loading and storing temporary 4535 // values on the stack where a match requires a value to 4536 // flow through memory. 4537 operand stackSlotP(sRegP reg) 4538 %{ 4539 constraint(ALLOC_IN_RC(stack_slots)); 4540 op_cost(100); 4541 // No match rule because this operand is only generated in matching 4542 // match(RegP); 4543 format %{ "[$reg]" %} 4544 interface(MEMORY_INTER) %{ 4545 base(0x1e); // RSP 4546 index(0x0); // No Index 4547 scale(0x0); // No Scale 4548 disp($reg); // Stack Offset 4549 %} 4550 %} 4551 4552 operand stackSlotI(sRegI reg) 4553 %{ 4554 constraint(ALLOC_IN_RC(stack_slots)); 4555 // No match rule because this operand is only generated in matching 4556 // match(RegI); 4557 format %{ "[$reg]" %} 4558 interface(MEMORY_INTER) %{ 4559 base(0x1e); // RSP 4560 index(0x0); // No Index 4561 scale(0x0); // No Scale 4562 disp($reg); // Stack Offset 4563 %} 4564 %} 4565 4566 operand stackSlotF(sRegF reg) 4567 %{ 4568 constraint(ALLOC_IN_RC(stack_slots)); 4569 // No match rule because this operand is only generated in matching 4570 // match(RegF); 4571 format %{ "[$reg]" %} 4572 interface(MEMORY_INTER) %{ 4573 base(0x1e); // RSP 4574 index(0x0); // No Index 4575 scale(0x0); // No Scale 4576 disp($reg); // Stack Offset 4577 %} 4578 %} 4579 4580 operand stackSlotD(sRegD reg) 4581 %{ 4582 constraint(ALLOC_IN_RC(stack_slots)); 4583 // No match rule because this operand is only generated in matching 4584 // match(RegD); 4585 format %{ "[$reg]" %} 4586 interface(MEMORY_INTER) %{ 4587 base(0x1e); // RSP 4588 index(0x0); // No Index 4589 scale(0x0); // No Scale 4590 disp($reg); // Stack Offset 4591 %} 4592 %} 4593 4594 operand stackSlotL(sRegL reg) 4595 %{ 4596 constraint(ALLOC_IN_RC(stack_slots)); 4597 // No match rule because this operand is only generated in matching 4598 // match(RegL); 4599 format %{ "[$reg]" %} 4600 interface(MEMORY_INTER) %{ 4601 base(0x1e); // RSP 4602 index(0x0); // No Index 4603 scale(0x0); // No Scale 4604 disp($reg); // Stack Offset 4605 %} 4606 %} 4607 4608 // Operands for expressing Control Flow 4609 // NOTE: Label is a predefined operand which should not be redefined in 4610 // the AD file. It is generically handled within the ADLC. 4611 4612 //----------Conditional Branch Operands---------------------------------------- 4613 // Comparison Op - This is the operation of the comparison, and is limited to 4614 // the following set of codes: 4615 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4616 // 4617 // Other attributes of the comparison, such as unsignedness, are specified 4618 // by the comparison instruction that sets a condition code flags register. 4619 // That result is represented by a flags operand whose subtype is appropriate 4620 // to the unsignedness (etc.) of the comparison. 4621 // 4622 // Later, the instruction which matches both the Comparison Op (a Bool) and 4623 // the flags (produced by the Cmp) specifies the coding of the comparison op 4624 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4625 4626 // used for signed integral comparisons and fp comparisons 4627 4628 operand cmpOp() 4629 %{ 4630 match(Bool); 4631 4632 format %{ "" %} 4633 interface(COND_INTER) %{ 4634 equal(0x0, "eq"); 4635 not_equal(0x1, "ne"); 4636 less(0xb, "lt"); 4637 greater_equal(0xa, "ge"); 4638 less_equal(0xd, "le"); 4639 greater(0xc, "gt"); 4640 overflow(0x6, "vs"); 4641 no_overflow(0x7, "vc"); 4642 %} 4643 %} 4644 4645 // used for unsigned integral comparisons 4646 4647 operand cmpOpU() 4648 %{ 4649 match(Bool); 4650 4651 format %{ "" %} 4652 interface(COND_INTER) %{ 4653 equal(0x0, "eq"); 4654 not_equal(0x1, "ne"); 4655 less(0x3, "lo"); 4656 greater_equal(0x2, "hs"); 4657 less_equal(0x9, "ls"); 4658 greater(0x8, "hi"); 4659 overflow(0x6, "vs"); 4660 no_overflow(0x7, "vc"); 4661 %} 4662 %} 4663 4664 // Special operand allowing long args to int ops to be truncated for free 4665 4666 operand iRegL2I(iRegL reg) %{ 4667 4668 op_cost(0); 4669 4670 match(ConvL2I reg); 4671 4672 format %{ "l2i($reg)" %} 4673 4674 interface(REG_INTER) 4675 %} 4676 4677 4678 //----------OPERAND CLASSES---------------------------------------------------- 4679 // Operand Classes are groups of operands that are used as to simplify 4680 // instruction definitions by not requiring the AD writer to specify 4681 // separate instructions for every form of operand when the 4682 // instruction accepts multiple operand types with the same basic 4683 // encoding and format. The classic case of this is memory operands. 4684 4685 // memory is used to define read/write location for load/store 4686 // instruction defs. we can turn a memory op into an Address 4687 4688 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL, 4689 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN); 4690 4691 4692 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 4693 // operations. it allows the src to be either an iRegI or a (ConvL2I 4694 // iRegL). in the latter case the l2i normally planted for a ConvL2I 4695 // can be elided because the 32-bit instruction will just employ the 4696 // lower 32 bits anyway. 4697 // 4698 // n.b. this does not elide all L2I conversions. if the truncated 4699 // value is consumed by more than one operation then the ConvL2I 4700 // cannot be bundled into the consuming nodes so an l2i gets planted 4701 // (actually a movw $dst $src) and the downstream instructions consume 4702 // the result of the l2i as an iRegI input. That's a shame since the 4703 // movw is actually redundant but its not too costly. 4704 4705 opclass iRegIorL2I(iRegI, iRegL2I); 4706 4707 //----------PIPELINE----------------------------------------------------------- 4708 // Rules which define the behavior of the target architectures pipeline. 4709 // Integer ALU reg operation 4710 pipeline %{ 4711 4712 attributes %{ 4713 // ARM instructions are of fixed length 4714 fixed_size_instructions; // Fixed size instructions TODO does 4715 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 4716 // ARM instructions come in 32-bit word units 4717 instruction_unit_size = 4; // An instruction is 4 bytes long 4718 instruction_fetch_unit_size = 64; // The processor fetches one line 4719 instruction_fetch_units = 1; // of 64 bytes 4720 4721 // List of nop instructions 4722 nops( MachNop ); 4723 %} 4724 4725 // We don't use an actual pipeline model so don't care about resources 4726 // or description. we do use pipeline classes to introduce fixed 4727 // latencies 4728 4729 //----------RESOURCES---------------------------------------------------------- 4730 // Resources are the functional units available to the machine 4731 4732 resources( INS0, INS1, INS01 = INS0 | INS1, 4733 ALU0, ALU1, ALU = ALU0 | ALU1, 4734 MAC, 4735 DIV, 4736 BRANCH, 4737 LDST, 4738 NEON_FP); 4739 4740 //----------PIPELINE DESCRIPTION----------------------------------------------- 4741 // Pipeline Description specifies the stages in the machine's pipeline 4742 4743 pipe_desc(ISS, EX1, EX2, WR); 4744 4745 //----------PIPELINE CLASSES--------------------------------------------------- 4746 // Pipeline Classes describe the stages in which input and output are 4747 // referenced by the hardware pipeline. 4748 4749 //------- Integer ALU operations -------------------------- 4750 4751 // Integer ALU reg-reg operation 4752 // Operands needed in EX1, result generated in EX2 4753 // Eg. ADD x0, x1, x2 4754 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4755 %{ 4756 single_instruction; 4757 dst : EX2(write); 4758 src1 : EX1(read); 4759 src2 : EX1(read); 4760 INS01 : ISS; // Dual issue as instruction 0 or 1 4761 ALU : EX2; 4762 %} 4763 4764 // Integer ALU reg-reg operation with constant shift 4765 // Shifted register must be available in LATE_ISS instead of EX1 4766 // Eg. ADD x0, x1, x2, LSL #2 4767 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 4768 %{ 4769 single_instruction; 4770 dst : EX2(write); 4771 src1 : EX1(read); 4772 src2 : ISS(read); 4773 INS01 : ISS; 4774 ALU : EX2; 4775 %} 4776 4777 // Integer ALU reg operation with constant shift 4778 // Eg. LSL x0, x1, #shift 4779 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 4780 %{ 4781 single_instruction; 4782 dst : EX2(write); 4783 src1 : ISS(read); 4784 INS01 : ISS; 4785 ALU : EX2; 4786 %} 4787 4788 // Integer ALU reg-reg operation with variable shift 4789 // Both operands must be available in LATE_ISS instead of EX1 4790 // Result is available in EX1 instead of EX2 4791 // Eg. LSLV x0, x1, x2 4792 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 4793 %{ 4794 single_instruction; 4795 dst : EX1(write); 4796 src1 : ISS(read); 4797 src2 : ISS(read); 4798 INS01 : ISS; 4799 ALU : EX1; 4800 %} 4801 4802 // Integer ALU reg-reg operation with extract 4803 // As for _vshift above, but result generated in EX2 4804 // Eg. EXTR x0, x1, x2, #N 4805 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 4806 %{ 4807 single_instruction; 4808 dst : EX2(write); 4809 src1 : ISS(read); 4810 src2 : ISS(read); 4811 INS1 : ISS; // Can only dual issue as Instruction 1 4812 ALU : EX1; 4813 %} 4814 4815 // Integer ALU reg operation 4816 // Eg. NEG x0, x1 4817 pipe_class ialu_reg(iRegI dst, iRegI src) 4818 %{ 4819 single_instruction; 4820 dst : EX2(write); 4821 src : EX1(read); 4822 INS01 : ISS; 4823 ALU : EX2; 4824 %} 4825 4826 // Integer ALU reg mmediate operation 4827 // Eg. ADD x0, x1, #N 4828 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 4829 %{ 4830 single_instruction; 4831 dst : EX2(write); 4832 src1 : EX1(read); 4833 INS01 : ISS; 4834 ALU : EX2; 4835 %} 4836 4837 // Integer ALU immediate operation (no source operands) 4838 // Eg. MOV x0, #N 4839 pipe_class ialu_imm(iRegI dst) 4840 %{ 4841 single_instruction; 4842 dst : EX1(write); 4843 INS01 : ISS; 4844 ALU : EX1; 4845 %} 4846 4847 //------- Compare operation ------------------------------- 4848 4849 // Compare reg-reg 4850 // Eg. CMP x0, x1 4851 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 4852 %{ 4853 single_instruction; 4854 // fixed_latency(16); 4855 cr : EX2(write); 4856 op1 : EX1(read); 4857 op2 : EX1(read); 4858 INS01 : ISS; 4859 ALU : EX2; 4860 %} 4861 4862 // Compare reg-reg 4863 // Eg. CMP x0, #N 4864 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 4865 %{ 4866 single_instruction; 4867 // fixed_latency(16); 4868 cr : EX2(write); 4869 op1 : EX1(read); 4870 INS01 : ISS; 4871 ALU : EX2; 4872 %} 4873 4874 //------- Conditional instructions ------------------------ 4875 4876 // Conditional no operands 4877 // Eg. CSINC x0, zr, zr, <cond> 4878 pipe_class icond_none(iRegI dst, rFlagsReg cr) 4879 %{ 4880 single_instruction; 4881 cr : EX1(read); 4882 dst : EX2(write); 4883 INS01 : ISS; 4884 ALU : EX2; 4885 %} 4886 4887 // Conditional 2 operand 4888 // EG. CSEL X0, X1, X2, <cond> 4889 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 4890 %{ 4891 single_instruction; 4892 cr : EX1(read); 4893 src1 : EX1(read); 4894 src2 : EX1(read); 4895 dst : EX2(write); 4896 INS01 : ISS; 4897 ALU : EX2; 4898 %} 4899 4900 // Conditional 2 operand 4901 // EG. CSEL X0, X1, X2, <cond> 4902 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 4903 %{ 4904 single_instruction; 4905 cr : EX1(read); 4906 src : EX1(read); 4907 dst : EX2(write); 4908 INS01 : ISS; 4909 ALU : EX2; 4910 %} 4911 4912 //------- Multiply pipeline operations -------------------- 4913 4914 // Multiply reg-reg 4915 // Eg. MUL w0, w1, w2 4916 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4917 %{ 4918 single_instruction; 4919 dst : WR(write); 4920 src1 : ISS(read); 4921 src2 : ISS(read); 4922 INS01 : ISS; 4923 MAC : WR; 4924 %} 4925 4926 // Multiply accumulate 4927 // Eg. MADD w0, w1, w2, w3 4928 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 4929 %{ 4930 single_instruction; 4931 dst : WR(write); 4932 src1 : ISS(read); 4933 src2 : ISS(read); 4934 src3 : ISS(read); 4935 INS01 : ISS; 4936 MAC : WR; 4937 %} 4938 4939 // Eg. MUL w0, w1, w2 4940 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4941 %{ 4942 single_instruction; 4943 fixed_latency(3); // Maximum latency for 64 bit mul 4944 dst : WR(write); 4945 src1 : ISS(read); 4946 src2 : ISS(read); 4947 INS01 : ISS; 4948 MAC : WR; 4949 %} 4950 4951 // Multiply accumulate 4952 // Eg. MADD w0, w1, w2, w3 4953 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 4954 %{ 4955 single_instruction; 4956 fixed_latency(3); // Maximum latency for 64 bit mul 4957 dst : WR(write); 4958 src1 : ISS(read); 4959 src2 : ISS(read); 4960 src3 : ISS(read); 4961 INS01 : ISS; 4962 MAC : WR; 4963 %} 4964 4965 //------- Divide pipeline operations -------------------- 4966 4967 // Eg. SDIV w0, w1, w2 4968 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4969 %{ 4970 single_instruction; 4971 fixed_latency(8); // Maximum latency for 32 bit divide 4972 dst : WR(write); 4973 src1 : ISS(read); 4974 src2 : ISS(read); 4975 INS0 : ISS; // Can only dual issue as instruction 0 4976 DIV : WR; 4977 %} 4978 4979 // Eg. SDIV x0, x1, x2 4980 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4981 %{ 4982 single_instruction; 4983 fixed_latency(16); // Maximum latency for 64 bit divide 4984 dst : WR(write); 4985 src1 : ISS(read); 4986 src2 : ISS(read); 4987 INS0 : ISS; // Can only dual issue as instruction 0 4988 DIV : WR; 4989 %} 4990 4991 //------- Load pipeline operations ------------------------ 4992 4993 // Load - prefetch 4994 // Eg. PFRM <mem> 4995 pipe_class iload_prefetch(memory mem) 4996 %{ 4997 single_instruction; 4998 mem : ISS(read); 4999 INS01 : ISS; 5000 LDST : WR; 5001 %} 5002 5003 // Load - reg, mem 5004 // Eg. LDR x0, <mem> 5005 pipe_class iload_reg_mem(iRegI dst, memory mem) 5006 %{ 5007 single_instruction; 5008 dst : WR(write); 5009 mem : ISS(read); 5010 INS01 : ISS; 5011 LDST : WR; 5012 %} 5013 5014 // Load - reg, reg 5015 // Eg. LDR x0, [sp, x1] 5016 pipe_class iload_reg_reg(iRegI dst, iRegI src) 5017 %{ 5018 single_instruction; 5019 dst : WR(write); 5020 src : ISS(read); 5021 INS01 : ISS; 5022 LDST : WR; 5023 %} 5024 5025 //------- Store pipeline operations ----------------------- 5026 5027 // Store - zr, mem 5028 // Eg. STR zr, <mem> 5029 pipe_class istore_mem(memory mem) 5030 %{ 5031 single_instruction; 5032 mem : ISS(read); 5033 INS01 : ISS; 5034 LDST : WR; 5035 %} 5036 5037 // Store - reg, mem 5038 // Eg. STR x0, <mem> 5039 pipe_class istore_reg_mem(iRegI src, memory mem) 5040 %{ 5041 single_instruction; 5042 mem : ISS(read); 5043 src : EX2(read); 5044 INS01 : ISS; 5045 LDST : WR; 5046 %} 5047 5048 // Store - reg, reg 5049 // Eg. STR x0, [sp, x1] 5050 pipe_class istore_reg_reg(iRegI dst, iRegI src) 5051 %{ 5052 single_instruction; 5053 dst : ISS(read); 5054 src : EX2(read); 5055 INS01 : ISS; 5056 LDST : WR; 5057 %} 5058 5059 //------- Store pipeline operations ----------------------- 5060 5061 // Branch 5062 pipe_class pipe_branch() 5063 %{ 5064 single_instruction; 5065 INS01 : ISS; 5066 BRANCH : EX1; 5067 %} 5068 5069 // Conditional branch 5070 pipe_class pipe_branch_cond(rFlagsReg cr) 5071 %{ 5072 single_instruction; 5073 cr : EX1(read); 5074 INS01 : ISS; 5075 BRANCH : EX1; 5076 %} 5077 5078 // Compare & Branch 5079 // EG. CBZ/CBNZ 5080 pipe_class pipe_cmp_branch(iRegI op1) 5081 %{ 5082 single_instruction; 5083 op1 : EX1(read); 5084 INS01 : ISS; 5085 BRANCH : EX1; 5086 %} 5087 5088 //------- Synchronisation operations ---------------------- 5089 5090 // Any operation requiring serialization. 5091 // EG. DMB/Atomic Ops/Load Acquire/Str Release 5092 pipe_class pipe_serial() 5093 %{ 5094 single_instruction; 5095 force_serialization; 5096 fixed_latency(16); 5097 INS01 : ISS(2); // Cannot dual issue with any other instruction 5098 LDST : WR; 5099 %} 5100 5101 // Generic big/slow expanded idiom - also serialized 5102 pipe_class pipe_slow() 5103 %{ 5104 instruction_count(10); 5105 multiple_bundles; 5106 force_serialization; 5107 fixed_latency(16); 5108 INS01 : ISS(2); // Cannot dual issue with any other instruction 5109 LDST : WR; 5110 %} 5111 5112 // Empty pipeline class 5113 pipe_class pipe_class_empty() 5114 %{ 5115 single_instruction; 5116 fixed_latency(0); 5117 %} 5118 5119 // Default pipeline class. 5120 pipe_class pipe_class_default() 5121 %{ 5122 single_instruction; 5123 fixed_latency(2); 5124 %} 5125 5126 // Pipeline class for compares. 5127 pipe_class pipe_class_compare() 5128 %{ 5129 single_instruction; 5130 fixed_latency(16); 5131 %} 5132 5133 // Pipeline class for memory operations. 5134 pipe_class pipe_class_memory() 5135 %{ 5136 single_instruction; 5137 fixed_latency(16); 5138 %} 5139 5140 // Pipeline class for call. 5141 pipe_class pipe_class_call() 5142 %{ 5143 single_instruction; 5144 fixed_latency(100); 5145 %} 5146 5147 // Define the class for the Nop node. 5148 define %{ 5149 MachNop = pipe_class_empty; 5150 %} 5151 5152 %} 5153 //----------INSTRUCTIONS------------------------------------------------------- 5154 // 5155 // match -- States which machine-independent subtree may be replaced 5156 // by this instruction. 5157 // ins_cost -- The estimated cost of this instruction is used by instruction 5158 // selection to identify a minimum cost tree of machine 5159 // instructions that matches a tree of machine-independent 5160 // instructions. 5161 // format -- A string providing the disassembly for this instruction. 5162 // The value of an instruction's operand may be inserted 5163 // by referring to it with a '$' prefix. 5164 // opcode -- Three instruction opcodes may be provided. These are referred 5165 // to within an encode class as $primary, $secondary, and $tertiary 5166 // rrspectively. The primary opcode is commonly used to 5167 // indicate the type of machine instruction, while secondary 5168 // and tertiary are often used for prefix options or addressing 5169 // modes. 5170 // ins_encode -- A list of encode classes with parameters. The encode class 5171 // name must have been defined in an 'enc_class' specification 5172 // in the encode section of the architecture description. 5173 5174 // ============================================================================ 5175 // Memory (Load/Store) Instructions 5176 5177 // Load Instructions 5178 5179 // Load Byte (8 bit signed) 5180 instruct loadB(iRegINoSp dst, memory mem) 5181 %{ 5182 match(Set dst (LoadB mem)); 5183 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5184 5185 ins_cost(4 * INSN_COST); 5186 format %{ "ldrsbw $dst, $mem\t# byte" %} 5187 5188 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 5189 5190 ins_pipe(iload_reg_mem); 5191 %} 5192 5193 // Load Byte (8 bit signed) into long 5194 instruct loadB2L(iRegLNoSp dst, memory mem) 5195 %{ 5196 match(Set dst (ConvI2L (LoadB mem))); 5197 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5198 5199 ins_cost(4 * INSN_COST); 5200 format %{ "ldrsb $dst, $mem\t# byte" %} 5201 5202 ins_encode(aarch64_enc_ldrsb(dst, mem)); 5203 5204 ins_pipe(iload_reg_mem); 5205 %} 5206 5207 // Load Byte (8 bit unsigned) 5208 instruct loadUB(iRegINoSp dst, memory mem) 5209 %{ 5210 match(Set dst (LoadUB mem)); 5211 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5212 5213 ins_cost(4 * INSN_COST); 5214 format %{ "ldrbw $dst, $mem\t# byte" %} 5215 5216 ins_encode(aarch64_enc_ldrb(dst, mem)); 5217 5218 ins_pipe(iload_reg_mem); 5219 %} 5220 5221 // Load Byte (8 bit unsigned) into long 5222 instruct loadUB2L(iRegLNoSp dst, memory mem) 5223 %{ 5224 match(Set dst (ConvI2L (LoadUB mem))); 5225 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5226 5227 ins_cost(4 * INSN_COST); 5228 format %{ "ldrb $dst, $mem\t# byte" %} 5229 5230 ins_encode(aarch64_enc_ldrb(dst, mem)); 5231 5232 ins_pipe(iload_reg_mem); 5233 %} 5234 5235 // Load Short (16 bit signed) 5236 instruct loadS(iRegINoSp dst, memory mem) 5237 %{ 5238 match(Set dst (LoadS mem)); 5239 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5240 5241 ins_cost(4 * INSN_COST); 5242 format %{ "ldrshw $dst, $mem\t# short" %} 5243 5244 ins_encode(aarch64_enc_ldrshw(dst, mem)); 5245 5246 ins_pipe(iload_reg_mem); 5247 %} 5248 5249 // Load Short (16 bit signed) into long 5250 instruct loadS2L(iRegLNoSp dst, memory mem) 5251 %{ 5252 match(Set dst (ConvI2L (LoadS mem))); 5253 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5254 5255 ins_cost(4 * INSN_COST); 5256 format %{ "ldrsh $dst, $mem\t# short" %} 5257 5258 ins_encode(aarch64_enc_ldrsh(dst, mem)); 5259 5260 ins_pipe(iload_reg_mem); 5261 %} 5262 5263 // Load Char (16 bit unsigned) 5264 instruct loadUS(iRegINoSp dst, memory mem) 5265 %{ 5266 match(Set dst (LoadUS mem)); 5267 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5268 5269 ins_cost(4 * INSN_COST); 5270 format %{ "ldrh $dst, $mem\t# short" %} 5271 5272 ins_encode(aarch64_enc_ldrh(dst, mem)); 5273 5274 ins_pipe(iload_reg_mem); 5275 %} 5276 5277 // Load Short/Char (16 bit unsigned) into long 5278 instruct loadUS2L(iRegLNoSp dst, memory mem) 5279 %{ 5280 match(Set dst (ConvI2L (LoadUS mem))); 5281 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5282 5283 ins_cost(4 * INSN_COST); 5284 format %{ "ldrh $dst, $mem\t# short" %} 5285 5286 ins_encode(aarch64_enc_ldrh(dst, mem)); 5287 5288 ins_pipe(iload_reg_mem); 5289 %} 5290 5291 // Load Integer (32 bit signed) 5292 instruct loadI(iRegINoSp dst, memory mem) 5293 %{ 5294 match(Set dst (LoadI mem)); 5295 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5296 5297 ins_cost(4 * INSN_COST); 5298 format %{ "ldrw $dst, $mem\t# int" %} 5299 5300 ins_encode(aarch64_enc_ldrw(dst, mem)); 5301 5302 ins_pipe(iload_reg_mem); 5303 %} 5304 5305 // Load Integer (32 bit signed) into long 5306 instruct loadI2L(iRegLNoSp dst, memory mem) 5307 %{ 5308 match(Set dst (ConvI2L (LoadI mem))); 5309 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5310 5311 ins_cost(4 * INSN_COST); 5312 format %{ "ldrsw $dst, $mem\t# int" %} 5313 5314 ins_encode(aarch64_enc_ldrsw(dst, mem)); 5315 5316 ins_pipe(iload_reg_mem); 5317 %} 5318 5319 // Load Integer (32 bit unsigned) into long 5320 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 5321 %{ 5322 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5323 predicate(UseBarriersForVolatile || n->in(1)->in(1)->as_Load()->is_unordered()); 5324 5325 ins_cost(4 * INSN_COST); 5326 format %{ "ldrw $dst, $mem\t# int" %} 5327 5328 ins_encode(aarch64_enc_ldrw(dst, mem)); 5329 5330 ins_pipe(iload_reg_mem); 5331 %} 5332 5333 // Load Long (64 bit signed) 5334 instruct loadL(iRegLNoSp dst, memory mem) 5335 %{ 5336 match(Set dst (LoadL mem)); 5337 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5338 5339 ins_cost(4 * INSN_COST); 5340 format %{ "ldr $dst, $mem\t# int" %} 5341 5342 ins_encode(aarch64_enc_ldr(dst, mem)); 5343 5344 ins_pipe(iload_reg_mem); 5345 %} 5346 5347 // Load Range 5348 instruct loadRange(iRegINoSp dst, memory mem) 5349 %{ 5350 match(Set dst (LoadRange mem)); 5351 5352 ins_cost(4 * INSN_COST); 5353 format %{ "ldrw $dst, $mem\t# range" %} 5354 5355 ins_encode(aarch64_enc_ldrw(dst, mem)); 5356 5357 ins_pipe(iload_reg_mem); 5358 %} 5359 5360 // Load Pointer 5361 instruct loadP(iRegPNoSp dst, memory mem) 5362 %{ 5363 match(Set dst (LoadP mem)); 5364 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5365 5366 ins_cost(4 * INSN_COST); 5367 format %{ "ldr $dst, $mem\t# ptr" %} 5368 5369 ins_encode(aarch64_enc_ldr(dst, mem)); 5370 5371 ins_pipe(iload_reg_mem); 5372 %} 5373 5374 // Load Compressed Pointer 5375 instruct loadN(iRegNNoSp dst, memory mem) 5376 %{ 5377 match(Set dst (LoadN mem)); 5378 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5379 5380 ins_cost(4 * INSN_COST); 5381 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 5382 5383 ins_encode(aarch64_enc_ldrw(dst, mem)); 5384 5385 ins_pipe(iload_reg_mem); 5386 %} 5387 5388 // Load Klass Pointer 5389 instruct loadKlass(iRegPNoSp dst, memory mem) 5390 %{ 5391 match(Set dst (LoadKlass mem)); 5392 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5393 5394 ins_cost(4 * INSN_COST); 5395 format %{ "ldr $dst, $mem\t# class" %} 5396 5397 ins_encode(aarch64_enc_ldr(dst, mem)); 5398 5399 ins_pipe(iload_reg_mem); 5400 %} 5401 5402 // Load Narrow Klass Pointer 5403 instruct loadNKlass(iRegNNoSp dst, memory mem) 5404 %{ 5405 match(Set dst (LoadNKlass mem)); 5406 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5407 5408 ins_cost(4 * INSN_COST); 5409 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 5410 5411 ins_encode(aarch64_enc_ldrw(dst, mem)); 5412 5413 ins_pipe(iload_reg_mem); 5414 %} 5415 5416 // Load Float 5417 instruct loadF(vRegF dst, memory mem) 5418 %{ 5419 match(Set dst (LoadF mem)); 5420 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5421 5422 ins_cost(4 * INSN_COST); 5423 format %{ "ldrs $dst, $mem\t# float" %} 5424 5425 ins_encode( aarch64_enc_ldrs(dst, mem) ); 5426 5427 ins_pipe(pipe_class_memory); 5428 %} 5429 5430 // Load Double 5431 instruct loadD(vRegD dst, memory mem) 5432 %{ 5433 match(Set dst (LoadD mem)); 5434 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5435 5436 ins_cost(4 * INSN_COST); 5437 format %{ "ldrd $dst, $mem\t# double" %} 5438 5439 ins_encode( aarch64_enc_ldrd(dst, mem) ); 5440 5441 ins_pipe(pipe_class_memory); 5442 %} 5443 5444 5445 // Load Int Constant 5446 instruct loadConI(iRegINoSp dst, immI src) 5447 %{ 5448 match(Set dst src); 5449 5450 ins_cost(INSN_COST); 5451 format %{ "mov $dst, $src\t# int" %} 5452 5453 ins_encode( aarch64_enc_movw_imm(dst, src) ); 5454 5455 ins_pipe(ialu_imm); 5456 %} 5457 5458 // Load Long Constant 5459 instruct loadConL(iRegLNoSp dst, immL src) 5460 %{ 5461 match(Set dst src); 5462 5463 ins_cost(INSN_COST); 5464 format %{ "mov $dst, $src\t# long" %} 5465 5466 ins_encode( aarch64_enc_mov_imm(dst, src) ); 5467 5468 ins_pipe(ialu_imm); 5469 %} 5470 5471 // Load Pointer Constant 5472 5473 instruct loadConP(iRegPNoSp dst, immP con) 5474 %{ 5475 match(Set dst con); 5476 5477 ins_cost(INSN_COST * 4); 5478 format %{ 5479 "mov $dst, $con\t# ptr\n\t" 5480 %} 5481 5482 ins_encode(aarch64_enc_mov_p(dst, con)); 5483 5484 ins_pipe(ialu_imm); 5485 %} 5486 5487 // Load Null Pointer Constant 5488 5489 instruct loadConP0(iRegPNoSp dst, immP0 con) 5490 %{ 5491 match(Set dst con); 5492 5493 ins_cost(INSN_COST); 5494 format %{ "mov $dst, $con\t# NULL ptr" %} 5495 5496 ins_encode(aarch64_enc_mov_p0(dst, con)); 5497 5498 ins_pipe(ialu_imm); 5499 %} 5500 5501 // Load Pointer Constant One 5502 5503 instruct loadConP1(iRegPNoSp dst, immP_1 con) 5504 %{ 5505 match(Set dst con); 5506 5507 ins_cost(INSN_COST); 5508 format %{ "mov $dst, $con\t# NULL ptr" %} 5509 5510 ins_encode(aarch64_enc_mov_p1(dst, con)); 5511 5512 ins_pipe(ialu_imm); 5513 %} 5514 5515 // Load Poll Page Constant 5516 5517 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 5518 %{ 5519 match(Set dst con); 5520 5521 ins_cost(INSN_COST); 5522 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 5523 5524 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 5525 5526 ins_pipe(ialu_imm); 5527 %} 5528 5529 // Load Byte Map Base Constant 5530 5531 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 5532 %{ 5533 match(Set dst con); 5534 5535 ins_cost(INSN_COST); 5536 format %{ "adr $dst, $con\t# Byte Map Base" %} 5537 5538 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 5539 5540 ins_pipe(ialu_imm); 5541 %} 5542 5543 // Load Narrow Pointer Constant 5544 5545 instruct loadConN(iRegNNoSp dst, immN con) 5546 %{ 5547 match(Set dst con); 5548 5549 ins_cost(INSN_COST * 4); 5550 format %{ "mov $dst, $con\t# compressed ptr" %} 5551 5552 ins_encode(aarch64_enc_mov_n(dst, con)); 5553 5554 ins_pipe(ialu_imm); 5555 %} 5556 5557 // Load Narrow Null Pointer Constant 5558 5559 instruct loadConN0(iRegNNoSp dst, immN0 con) 5560 %{ 5561 match(Set dst con); 5562 5563 ins_cost(INSN_COST); 5564 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 5565 5566 ins_encode(aarch64_enc_mov_n0(dst, con)); 5567 5568 ins_pipe(ialu_imm); 5569 %} 5570 5571 // Load Narrow Klass Constant 5572 5573 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 5574 %{ 5575 match(Set dst con); 5576 5577 ins_cost(INSN_COST); 5578 format %{ "mov $dst, $con\t# compressed klass ptr" %} 5579 5580 ins_encode(aarch64_enc_mov_nk(dst, con)); 5581 5582 ins_pipe(ialu_imm); 5583 %} 5584 5585 // Load Packed Float Constant 5586 5587 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 5588 match(Set dst con); 5589 ins_cost(INSN_COST * 4); 5590 format %{ "fmovs $dst, $con"%} 5591 ins_encode %{ 5592 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 5593 %} 5594 5595 ins_pipe(pipe_class_default); 5596 %} 5597 5598 // Load Float Constant 5599 5600 instruct loadConF(vRegF dst, immF con) %{ 5601 match(Set dst con); 5602 5603 ins_cost(INSN_COST * 4); 5604 5605 format %{ 5606 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 5607 %} 5608 5609 ins_encode %{ 5610 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 5611 %} 5612 5613 ins_pipe(pipe_class_default); 5614 %} 5615 5616 // Load Packed Double Constant 5617 5618 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 5619 match(Set dst con); 5620 ins_cost(INSN_COST); 5621 format %{ "fmovd $dst, $con"%} 5622 ins_encode %{ 5623 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 5624 %} 5625 5626 ins_pipe(pipe_class_default); 5627 %} 5628 5629 // Load Double Constant 5630 5631 instruct loadConD(vRegD dst, immD con) %{ 5632 match(Set dst con); 5633 5634 ins_cost(INSN_COST * 5); 5635 format %{ 5636 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 5637 %} 5638 5639 ins_encode %{ 5640 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 5641 %} 5642 5643 ins_pipe(pipe_class_default); 5644 %} 5645 5646 // Store Instructions 5647 5648 // Store CMS card-mark Immediate 5649 instruct storeimmCM0(immI0 zero, memory mem) 5650 %{ 5651 match(Set mem (StoreCM mem zero)); 5652 5653 ins_cost(INSN_COST); 5654 format %{ "strb zr, $mem\t# byte" %} 5655 5656 ins_encode(aarch64_enc_strb0(mem)); 5657 5658 ins_pipe(istore_mem); 5659 %} 5660 5661 // Store Byte 5662 instruct storeB(iRegIorL2I src, memory mem) 5663 %{ 5664 match(Set mem (StoreB mem src)); 5665 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5666 5667 ins_cost(INSN_COST); 5668 format %{ "strb $src, $mem\t# byte" %} 5669 5670 ins_encode(aarch64_enc_strb(src, mem)); 5671 5672 ins_pipe(istore_reg_mem); 5673 %} 5674 5675 5676 instruct storeimmB0(immI0 zero, memory mem) 5677 %{ 5678 match(Set mem (StoreB mem zero)); 5679 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5680 5681 ins_cost(INSN_COST); 5682 format %{ "strb zr, $mem\t# byte" %} 5683 5684 ins_encode(aarch64_enc_strb0(mem)); 5685 5686 ins_pipe(istore_mem); 5687 %} 5688 5689 // Store Char/Short 5690 instruct storeC(iRegIorL2I src, memory mem) 5691 %{ 5692 match(Set mem (StoreC mem src)); 5693 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5694 5695 ins_cost(INSN_COST); 5696 format %{ "strh $src, $mem\t# short" %} 5697 5698 ins_encode(aarch64_enc_strh(src, mem)); 5699 5700 ins_pipe(istore_reg_mem); 5701 %} 5702 5703 instruct storeimmC0(immI0 zero, memory mem) 5704 %{ 5705 match(Set mem (StoreC mem zero)); 5706 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5707 5708 ins_cost(INSN_COST); 5709 format %{ "strh zr, $mem\t# short" %} 5710 5711 ins_encode(aarch64_enc_strh0(mem)); 5712 5713 ins_pipe(istore_mem); 5714 %} 5715 5716 // Store Integer 5717 5718 instruct storeI(iRegIorL2I src, memory mem) 5719 %{ 5720 match(Set mem(StoreI mem src)); 5721 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5722 5723 ins_cost(INSN_COST); 5724 format %{ "strw $src, $mem\t# int" %} 5725 5726 ins_encode(aarch64_enc_strw(src, mem)); 5727 5728 ins_pipe(istore_reg_mem); 5729 %} 5730 5731 instruct storeimmI0(immI0 zero, memory mem) 5732 %{ 5733 match(Set mem(StoreI mem zero)); 5734 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5735 5736 ins_cost(INSN_COST); 5737 format %{ "strw zr, $mem\t# int" %} 5738 5739 ins_encode(aarch64_enc_strw0(mem)); 5740 5741 ins_pipe(istore_mem); 5742 %} 5743 5744 // Store Long (64 bit signed) 5745 instruct storeL(iRegL src, memory mem) 5746 %{ 5747 match(Set mem (StoreL mem src)); 5748 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5749 5750 ins_cost(INSN_COST); 5751 format %{ "str $src, $mem\t# int" %} 5752 5753 ins_encode(aarch64_enc_str(src, mem)); 5754 5755 ins_pipe(istore_reg_mem); 5756 %} 5757 5758 // Store Long (64 bit signed) 5759 instruct storeimmL0(immL0 zero, memory mem) 5760 %{ 5761 match(Set mem (StoreL mem zero)); 5762 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5763 5764 ins_cost(INSN_COST); 5765 format %{ "str zr, $mem\t# int" %} 5766 5767 ins_encode(aarch64_enc_str0(mem)); 5768 5769 ins_pipe(istore_mem); 5770 %} 5771 5772 // Store Pointer 5773 instruct storeP(iRegP src, memory mem) 5774 %{ 5775 match(Set mem (StoreP mem src)); 5776 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5777 5778 ins_cost(INSN_COST); 5779 format %{ "str $src, $mem\t# ptr" %} 5780 5781 ins_encode(aarch64_enc_str(src, mem)); 5782 5783 ins_pipe(istore_reg_mem); 5784 %} 5785 5786 // Store Pointer 5787 instruct storeimmP0(immP0 zero, memory mem) 5788 %{ 5789 match(Set mem (StoreP mem zero)); 5790 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5791 5792 ins_cost(INSN_COST); 5793 format %{ "str zr, $mem\t# ptr" %} 5794 5795 ins_encode(aarch64_enc_str0(mem)); 5796 5797 ins_pipe(istore_mem); 5798 %} 5799 5800 // Store Compressed Pointer 5801 instruct storeN(iRegN src, memory mem) 5802 %{ 5803 match(Set mem (StoreN mem src)); 5804 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5805 5806 ins_cost(INSN_COST); 5807 format %{ "strw $src, $mem\t# compressed ptr" %} 5808 5809 ins_encode(aarch64_enc_strw(src, mem)); 5810 5811 ins_pipe(istore_reg_mem); 5812 %} 5813 5814 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 5815 %{ 5816 match(Set mem (StoreN mem zero)); 5817 predicate(Universe::narrow_oop_base() == NULL && 5818 Universe::narrow_klass_base() == NULL && 5819 (UseBarriersForVolatile || n->as_Store()->is_unordered())); 5820 5821 ins_cost(INSN_COST); 5822 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 5823 5824 ins_encode(aarch64_enc_strw(heapbase, mem)); 5825 5826 ins_pipe(istore_reg_mem); 5827 %} 5828 5829 // Store Float 5830 instruct storeF(vRegF src, memory mem) 5831 %{ 5832 match(Set mem (StoreF mem src)); 5833 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5834 5835 ins_cost(INSN_COST); 5836 format %{ "strs $src, $mem\t# float" %} 5837 5838 ins_encode( aarch64_enc_strs(src, mem) ); 5839 5840 ins_pipe(pipe_class_memory); 5841 %} 5842 5843 // TODO 5844 // implement storeImmF0 and storeFImmPacked 5845 5846 // Store Double 5847 instruct storeD(vRegD src, memory mem) 5848 %{ 5849 match(Set mem (StoreD mem src)); 5850 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5851 5852 ins_cost(INSN_COST); 5853 format %{ "strd $src, $mem\t# double" %} 5854 5855 ins_encode( aarch64_enc_strd(src, mem) ); 5856 5857 ins_pipe(pipe_class_memory); 5858 %} 5859 5860 // Store Compressed Klass Pointer 5861 instruct storeNKlass(iRegN src, memory mem) 5862 %{ 5863 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5864 match(Set mem (StoreNKlass mem src)); 5865 5866 ins_cost(INSN_COST); 5867 format %{ "strw $src, $mem\t# compressed klass ptr" %} 5868 5869 ins_encode(aarch64_enc_strw(src, mem)); 5870 5871 ins_pipe(istore_reg_mem); 5872 %} 5873 5874 // TODO 5875 // implement storeImmD0 and storeDImmPacked 5876 5877 // prefetch instructions 5878 // Must be safe to execute with invalid address (cannot fault). 5879 5880 instruct prefetchalloc( memory mem ) %{ 5881 match(PrefetchAllocation mem); 5882 5883 ins_cost(INSN_COST); 5884 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 5885 5886 ins_encode( aarch64_enc_prefetchw(mem) ); 5887 5888 ins_pipe(iload_prefetch); 5889 %} 5890 5891 // ---------------- volatile loads and stores ---------------- 5892 5893 // Load Byte (8 bit signed) 5894 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5895 %{ 5896 match(Set dst (LoadB mem)); 5897 5898 ins_cost(VOLATILE_REF_COST); 5899 format %{ "ldarsb $dst, $mem\t# byte" %} 5900 5901 ins_encode(aarch64_enc_ldarsb(dst, mem)); 5902 5903 ins_pipe(pipe_serial); 5904 %} 5905 5906 // Load Byte (8 bit signed) into long 5907 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5908 %{ 5909 match(Set dst (ConvI2L (LoadB mem))); 5910 5911 ins_cost(VOLATILE_REF_COST); 5912 format %{ "ldarsb $dst, $mem\t# byte" %} 5913 5914 ins_encode(aarch64_enc_ldarsb(dst, mem)); 5915 5916 ins_pipe(pipe_serial); 5917 %} 5918 5919 // Load Byte (8 bit unsigned) 5920 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5921 %{ 5922 match(Set dst (LoadUB mem)); 5923 5924 ins_cost(VOLATILE_REF_COST); 5925 format %{ "ldarb $dst, $mem\t# byte" %} 5926 5927 ins_encode(aarch64_enc_ldarb(dst, mem)); 5928 5929 ins_pipe(pipe_serial); 5930 %} 5931 5932 // Load Byte (8 bit unsigned) into long 5933 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5934 %{ 5935 match(Set dst (ConvI2L (LoadUB mem))); 5936 5937 ins_cost(VOLATILE_REF_COST); 5938 format %{ "ldarb $dst, $mem\t# byte" %} 5939 5940 ins_encode(aarch64_enc_ldarb(dst, mem)); 5941 5942 ins_pipe(pipe_serial); 5943 %} 5944 5945 // Load Short (16 bit signed) 5946 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5947 %{ 5948 match(Set dst (LoadS mem)); 5949 5950 ins_cost(VOLATILE_REF_COST); 5951 format %{ "ldarshw $dst, $mem\t# short" %} 5952 5953 ins_encode(aarch64_enc_ldarshw(dst, mem)); 5954 5955 ins_pipe(pipe_serial); 5956 %} 5957 5958 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5959 %{ 5960 match(Set dst (LoadUS mem)); 5961 5962 ins_cost(VOLATILE_REF_COST); 5963 format %{ "ldarhw $dst, $mem\t# short" %} 5964 5965 ins_encode(aarch64_enc_ldarhw(dst, mem)); 5966 5967 ins_pipe(pipe_serial); 5968 %} 5969 5970 // Load Short/Char (16 bit unsigned) into long 5971 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5972 %{ 5973 match(Set dst (ConvI2L (LoadUS mem))); 5974 5975 ins_cost(VOLATILE_REF_COST); 5976 format %{ "ldarh $dst, $mem\t# short" %} 5977 5978 ins_encode(aarch64_enc_ldarh(dst, mem)); 5979 5980 ins_pipe(pipe_serial); 5981 %} 5982 5983 // Load Short/Char (16 bit signed) into long 5984 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5985 %{ 5986 match(Set dst (ConvI2L (LoadS mem))); 5987 5988 ins_cost(VOLATILE_REF_COST); 5989 format %{ "ldarh $dst, $mem\t# short" %} 5990 5991 ins_encode(aarch64_enc_ldarsh(dst, mem)); 5992 5993 ins_pipe(pipe_serial); 5994 %} 5995 5996 // Load Integer (32 bit signed) 5997 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5998 %{ 5999 match(Set dst (LoadI mem)); 6000 6001 ins_cost(VOLATILE_REF_COST); 6002 format %{ "ldarw $dst, $mem\t# int" %} 6003 6004 ins_encode(aarch64_enc_ldarw(dst, mem)); 6005 6006 ins_pipe(pipe_serial); 6007 %} 6008 6009 // Load Integer (32 bit unsigned) into long 6010 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 6011 %{ 6012 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6013 6014 ins_cost(VOLATILE_REF_COST); 6015 format %{ "ldarw $dst, $mem\t# int" %} 6016 6017 ins_encode(aarch64_enc_ldarw(dst, mem)); 6018 6019 ins_pipe(pipe_serial); 6020 %} 6021 6022 // Load Long (64 bit signed) 6023 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6024 %{ 6025 match(Set dst (LoadL mem)); 6026 6027 ins_cost(VOLATILE_REF_COST); 6028 format %{ "ldar $dst, $mem\t# int" %} 6029 6030 ins_encode(aarch64_enc_ldar(dst, mem)); 6031 6032 ins_pipe(pipe_serial); 6033 %} 6034 6035 // Load Pointer 6036 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 6037 %{ 6038 match(Set dst (LoadP mem)); 6039 6040 ins_cost(VOLATILE_REF_COST); 6041 format %{ "ldar $dst, $mem\t# ptr" %} 6042 6043 ins_encode(aarch64_enc_ldar(dst, mem)); 6044 6045 ins_pipe(pipe_serial); 6046 %} 6047 6048 // Load Compressed Pointer 6049 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 6050 %{ 6051 match(Set dst (LoadN mem)); 6052 6053 ins_cost(VOLATILE_REF_COST); 6054 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 6055 6056 ins_encode(aarch64_enc_ldarw(dst, mem)); 6057 6058 ins_pipe(pipe_serial); 6059 %} 6060 6061 // Load Float 6062 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 6063 %{ 6064 match(Set dst (LoadF mem)); 6065 6066 ins_cost(VOLATILE_REF_COST); 6067 format %{ "ldars $dst, $mem\t# float" %} 6068 6069 ins_encode( aarch64_enc_fldars(dst, mem) ); 6070 6071 ins_pipe(pipe_serial); 6072 %} 6073 6074 // Load Double 6075 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 6076 %{ 6077 match(Set dst (LoadD mem)); 6078 6079 ins_cost(VOLATILE_REF_COST); 6080 format %{ "ldard $dst, $mem\t# double" %} 6081 6082 ins_encode( aarch64_enc_fldard(dst, mem) ); 6083 6084 ins_pipe(pipe_serial); 6085 %} 6086 6087 // Store Byte 6088 instruct storeB_volatile(iRegI src, /* sync_memory*/indirect mem) 6089 %{ 6090 match(Set mem (StoreB mem src)); 6091 6092 ins_cost(VOLATILE_REF_COST); 6093 format %{ "stlrb $src, $mem\t# byte" %} 6094 6095 ins_encode(aarch64_enc_stlrb(src, mem)); 6096 6097 ins_pipe(pipe_class_memory); 6098 %} 6099 6100 // Store Char/Short 6101 instruct storeC_volatile(iRegI src, /* sync_memory*/indirect mem) 6102 %{ 6103 match(Set mem (StoreC mem src)); 6104 6105 ins_cost(VOLATILE_REF_COST); 6106 format %{ "stlrh $src, $mem\t# short" %} 6107 6108 ins_encode(aarch64_enc_stlrh(src, mem)); 6109 6110 ins_pipe(pipe_class_memory); 6111 %} 6112 6113 // Store Integer 6114 6115 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6116 %{ 6117 match(Set mem(StoreI mem src)); 6118 6119 ins_cost(VOLATILE_REF_COST); 6120 format %{ "stlrw $src, $mem\t# int" %} 6121 6122 ins_encode(aarch64_enc_stlrw(src, mem)); 6123 6124 ins_pipe(pipe_class_memory); 6125 %} 6126 6127 // Store Long (64 bit signed) 6128 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 6129 %{ 6130 match(Set mem (StoreL mem src)); 6131 6132 ins_cost(VOLATILE_REF_COST); 6133 format %{ "stlr $src, $mem\t# int" %} 6134 6135 ins_encode(aarch64_enc_stlr(src, mem)); 6136 6137 ins_pipe(pipe_class_memory); 6138 %} 6139 6140 // Store Pointer 6141 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 6142 %{ 6143 match(Set mem (StoreP mem src)); 6144 6145 ins_cost(VOLATILE_REF_COST); 6146 format %{ "stlr $src, $mem\t# ptr" %} 6147 6148 ins_encode(aarch64_enc_stlr(src, mem)); 6149 6150 ins_pipe(pipe_class_memory); 6151 %} 6152 6153 // Store Compressed Pointer 6154 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 6155 %{ 6156 match(Set mem (StoreN mem src)); 6157 6158 ins_cost(VOLATILE_REF_COST); 6159 format %{ "stlrw $src, $mem\t# compressed ptr" %} 6160 6161 ins_encode(aarch64_enc_stlrw(src, mem)); 6162 6163 ins_pipe(pipe_class_memory); 6164 %} 6165 6166 // Store Float 6167 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 6168 %{ 6169 match(Set mem (StoreF mem src)); 6170 6171 ins_cost(VOLATILE_REF_COST); 6172 format %{ "stlrs $src, $mem\t# float" %} 6173 6174 ins_encode( aarch64_enc_fstlrs(src, mem) ); 6175 6176 ins_pipe(pipe_class_memory); 6177 %} 6178 6179 // TODO 6180 // implement storeImmF0 and storeFImmPacked 6181 6182 // Store Double 6183 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 6184 %{ 6185 match(Set mem (StoreD mem src)); 6186 6187 ins_cost(VOLATILE_REF_COST); 6188 format %{ "stlrd $src, $mem\t# double" %} 6189 6190 ins_encode( aarch64_enc_fstlrd(src, mem) ); 6191 6192 ins_pipe(pipe_class_memory); 6193 %} 6194 6195 // ---------------- end of volatile loads and stores ---------------- 6196 6197 // ============================================================================ 6198 // BSWAP Instructions 6199 6200 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 6201 match(Set dst (ReverseBytesI src)); 6202 6203 ins_cost(INSN_COST); 6204 format %{ "revw $dst, $src" %} 6205 6206 ins_encode %{ 6207 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 6208 %} 6209 6210 ins_pipe(ialu_reg); 6211 %} 6212 6213 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 6214 match(Set dst (ReverseBytesL src)); 6215 6216 ins_cost(INSN_COST); 6217 format %{ "rev $dst, $src" %} 6218 6219 ins_encode %{ 6220 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 6221 %} 6222 6223 ins_pipe(ialu_reg); 6224 %} 6225 6226 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 6227 match(Set dst (ReverseBytesUS src)); 6228 6229 ins_cost(INSN_COST); 6230 format %{ "rev16w $dst, $src" %} 6231 6232 ins_encode %{ 6233 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 6234 %} 6235 6236 ins_pipe(ialu_reg); 6237 %} 6238 6239 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 6240 match(Set dst (ReverseBytesS src)); 6241 6242 ins_cost(INSN_COST); 6243 format %{ "rev16w $dst, $src\n\t" 6244 "sbfmw $dst, $dst, #0, #15" %} 6245 6246 ins_encode %{ 6247 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 6248 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 6249 %} 6250 6251 ins_pipe(ialu_reg); 6252 %} 6253 6254 // ============================================================================ 6255 // Zero Count Instructions 6256 6257 instruct countLeadingZerosI(iRegINoSp dst, iRegI src) %{ 6258 match(Set dst (CountLeadingZerosI src)); 6259 6260 ins_cost(INSN_COST); 6261 format %{ "clzw $dst, $src" %} 6262 ins_encode %{ 6263 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 6264 %} 6265 6266 ins_pipe(ialu_reg); 6267 %} 6268 6269 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 6270 match(Set dst (CountLeadingZerosL src)); 6271 6272 ins_cost(INSN_COST); 6273 format %{ "clz $dst, $src" %} 6274 ins_encode %{ 6275 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 6276 %} 6277 6278 ins_pipe(ialu_reg); 6279 %} 6280 6281 instruct countTrailingZerosI(iRegINoSp dst, iRegI src) %{ 6282 match(Set dst (CountTrailingZerosI src)); 6283 6284 ins_cost(INSN_COST * 2); 6285 format %{ "rbitw $dst, $src\n\t" 6286 "clzw $dst, $dst" %} 6287 ins_encode %{ 6288 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 6289 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 6290 %} 6291 6292 ins_pipe(ialu_reg); 6293 %} 6294 6295 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 6296 match(Set dst (CountTrailingZerosL src)); 6297 6298 ins_cost(INSN_COST * 2); 6299 format %{ "rbit $dst, $src\n\t" 6300 "clz $dst, $dst" %} 6301 ins_encode %{ 6302 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 6303 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 6304 %} 6305 6306 ins_pipe(ialu_reg); 6307 %} 6308 6309 // ============================================================================ 6310 // MemBar Instruction 6311 6312 instruct load_fence() %{ 6313 match(LoadFence); 6314 ins_cost(VOLATILE_REF_COST); 6315 6316 format %{ "load_fence" %} 6317 6318 ins_encode %{ 6319 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6320 %} 6321 ins_pipe(pipe_serial); 6322 %} 6323 6324 instruct unnecessary_membar_acquire() %{ 6325 predicate(! UseBarriersForVolatile && preceded_by_ordered_load(n)); 6326 match(MemBarAcquire); 6327 ins_cost(0); 6328 6329 format %{ "membar_acquire (elided)" %} 6330 6331 ins_encode %{ 6332 __ block_comment("membar_acquire (elided)"); 6333 %} 6334 6335 ins_pipe(pipe_class_empty); 6336 %} 6337 6338 instruct membar_acquire() %{ 6339 match(MemBarAcquire); 6340 ins_cost(VOLATILE_REF_COST); 6341 6342 format %{ "membar_acquire" %} 6343 6344 ins_encode %{ 6345 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6346 %} 6347 6348 ins_pipe(pipe_serial); 6349 %} 6350 6351 6352 instruct membar_acquire_lock() %{ 6353 match(MemBarAcquireLock); 6354 ins_cost(VOLATILE_REF_COST); 6355 6356 format %{ "membar_acquire_lock" %} 6357 6358 ins_encode %{ 6359 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6360 %} 6361 6362 ins_pipe(pipe_serial); 6363 %} 6364 6365 instruct store_fence() %{ 6366 match(StoreFence); 6367 ins_cost(VOLATILE_REF_COST); 6368 6369 format %{ "store_fence" %} 6370 6371 ins_encode %{ 6372 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6373 %} 6374 ins_pipe(pipe_serial); 6375 %} 6376 6377 instruct membar_release() %{ 6378 match(MemBarRelease); 6379 ins_cost(VOLATILE_REF_COST); 6380 6381 format %{ "membar_release" %} 6382 6383 ins_encode %{ 6384 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6385 %} 6386 ins_pipe(pipe_serial); 6387 %} 6388 6389 instruct membar_storestore() %{ 6390 match(MemBarStoreStore); 6391 ins_cost(VOLATILE_REF_COST); 6392 6393 format %{ "MEMBAR-store-store" %} 6394 6395 ins_encode %{ 6396 __ membar(Assembler::StoreStore); 6397 %} 6398 ins_pipe(pipe_serial); 6399 %} 6400 6401 instruct membar_release_lock() %{ 6402 match(MemBarReleaseLock); 6403 ins_cost(VOLATILE_REF_COST); 6404 6405 format %{ "membar_release_lock" %} 6406 6407 ins_encode %{ 6408 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6409 %} 6410 6411 ins_pipe(pipe_serial); 6412 %} 6413 6414 instruct membar_volatile() %{ 6415 match(MemBarVolatile); 6416 ins_cost(VOLATILE_REF_COST*100); 6417 6418 format %{ "membar_volatile" %} 6419 6420 ins_encode %{ 6421 __ membar(Assembler::StoreLoad); 6422 %} 6423 6424 ins_pipe(pipe_serial); 6425 %} 6426 6427 // ============================================================================ 6428 // Cast/Convert Instructions 6429 6430 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 6431 match(Set dst (CastX2P src)); 6432 6433 ins_cost(INSN_COST); 6434 format %{ "mov $dst, $src\t# long -> ptr" %} 6435 6436 ins_encode %{ 6437 if ($dst$$reg != $src$$reg) { 6438 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 6439 } 6440 %} 6441 6442 ins_pipe(ialu_reg); 6443 %} 6444 6445 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 6446 match(Set dst (CastP2X src)); 6447 6448 ins_cost(INSN_COST); 6449 format %{ "mov $dst, $src\t# ptr -> long" %} 6450 6451 ins_encode %{ 6452 if ($dst$$reg != $src$$reg) { 6453 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 6454 } 6455 %} 6456 6457 ins_pipe(ialu_reg); 6458 %} 6459 6460 // Convert oop into int for vectors alignment masking 6461 instruct convP2I(iRegINoSp dst, iRegP src) %{ 6462 match(Set dst (ConvL2I (CastP2X src))); 6463 6464 ins_cost(INSN_COST); 6465 format %{ "movw $dst, $src\t# ptr -> int" %} 6466 ins_encode %{ 6467 __ movw($dst$$Register, $src$$Register); 6468 %} 6469 6470 ins_pipe(ialu_reg); 6471 %} 6472 6473 // Convert compressed oop into int for vectors alignment masking 6474 // in case of 32bit oops (heap < 4Gb). 6475 instruct convN2I(iRegINoSp dst, iRegN src) 6476 %{ 6477 predicate(Universe::narrow_oop_shift() == 0); 6478 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6479 6480 ins_cost(INSN_COST); 6481 format %{ "mov dst, $src\t# compressed ptr -> int" %} 6482 ins_encode %{ 6483 __ movw($dst$$Register, $src$$Register); 6484 %} 6485 6486 ins_pipe(ialu_reg); 6487 %} 6488 6489 6490 // Convert oop pointer into compressed form 6491 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 6492 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6493 match(Set dst (EncodeP src)); 6494 effect(KILL cr); 6495 ins_cost(INSN_COST * 3); 6496 format %{ "encode_heap_oop $dst, $src" %} 6497 ins_encode %{ 6498 Register s = $src$$Register; 6499 Register d = $dst$$Register; 6500 __ encode_heap_oop(d, s); 6501 %} 6502 ins_pipe(ialu_reg); 6503 %} 6504 6505 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 6506 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6507 match(Set dst (EncodeP src)); 6508 ins_cost(INSN_COST * 3); 6509 format %{ "encode_heap_oop_not_null $dst, $src" %} 6510 ins_encode %{ 6511 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6512 %} 6513 ins_pipe(ialu_reg); 6514 %} 6515 6516 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 6517 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6518 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6519 match(Set dst (DecodeN src)); 6520 ins_cost(INSN_COST * 3); 6521 format %{ "decode_heap_oop $dst, $src" %} 6522 ins_encode %{ 6523 Register s = $src$$Register; 6524 Register d = $dst$$Register; 6525 __ decode_heap_oop(d, s); 6526 %} 6527 ins_pipe(ialu_reg); 6528 %} 6529 6530 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 6531 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6532 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6533 match(Set dst (DecodeN src)); 6534 ins_cost(INSN_COST * 3); 6535 format %{ "decode_heap_oop_not_null $dst, $src" %} 6536 ins_encode %{ 6537 Register s = $src$$Register; 6538 Register d = $dst$$Register; 6539 __ decode_heap_oop_not_null(d, s); 6540 %} 6541 ins_pipe(ialu_reg); 6542 %} 6543 6544 // n.b. AArch64 implementations of encode_klass_not_null and 6545 // decode_klass_not_null do not modify the flags register so, unlike 6546 // Intel, we don't kill CR as a side effect here 6547 6548 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 6549 match(Set dst (EncodePKlass src)); 6550 6551 ins_cost(INSN_COST * 3); 6552 format %{ "encode_klass_not_null $dst,$src" %} 6553 6554 ins_encode %{ 6555 Register src_reg = as_Register($src$$reg); 6556 Register dst_reg = as_Register($dst$$reg); 6557 __ encode_klass_not_null(dst_reg, src_reg); 6558 %} 6559 6560 ins_pipe(ialu_reg); 6561 %} 6562 6563 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 6564 match(Set dst (DecodeNKlass src)); 6565 6566 ins_cost(INSN_COST * 3); 6567 format %{ "decode_klass_not_null $dst,$src" %} 6568 6569 ins_encode %{ 6570 Register src_reg = as_Register($src$$reg); 6571 Register dst_reg = as_Register($dst$$reg); 6572 if (dst_reg != src_reg) { 6573 __ decode_klass_not_null(dst_reg, src_reg); 6574 } else { 6575 __ decode_klass_not_null(dst_reg); 6576 } 6577 %} 6578 6579 ins_pipe(ialu_reg); 6580 %} 6581 6582 instruct checkCastPP(iRegPNoSp dst) 6583 %{ 6584 match(Set dst (CheckCastPP dst)); 6585 6586 size(0); 6587 format %{ "# checkcastPP of $dst" %} 6588 ins_encode(/* empty encoding */); 6589 ins_pipe(pipe_class_empty); 6590 %} 6591 6592 instruct castPP(iRegPNoSp dst) 6593 %{ 6594 match(Set dst (CastPP dst)); 6595 6596 size(0); 6597 format %{ "# castPP of $dst" %} 6598 ins_encode(/* empty encoding */); 6599 ins_pipe(pipe_class_empty); 6600 %} 6601 6602 instruct castII(iRegI dst) 6603 %{ 6604 match(Set dst (CastII dst)); 6605 6606 size(0); 6607 format %{ "# castII of $dst" %} 6608 ins_encode(/* empty encoding */); 6609 ins_cost(0); 6610 ins_pipe(pipe_class_empty); 6611 %} 6612 6613 // ============================================================================ 6614 // Atomic operation instructions 6615 // 6616 // Intel and SPARC both implement Ideal Node LoadPLocked and 6617 // Store{PIL}Conditional instructions using a normal load for the 6618 // LoadPLocked and a CAS for the Store{PIL}Conditional. 6619 // 6620 // The ideal code appears only to use LoadPLocked/StorePLocked as a 6621 // pair to lock object allocations from Eden space when not using 6622 // TLABs. 6623 // 6624 // There does not appear to be a Load{IL}Locked Ideal Node and the 6625 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 6626 // and to use StoreIConditional only for 32-bit and StoreLConditional 6627 // only for 64-bit. 6628 // 6629 // We implement LoadPLocked and StorePLocked instructions using, 6630 // respectively the AArch64 hw load-exclusive and store-conditional 6631 // instructions. Whereas we must implement each of 6632 // Store{IL}Conditional using a CAS which employs a pair of 6633 // instructions comprising a load-exclusive followed by a 6634 // store-conditional. 6635 6636 6637 // Locked-load (linked load) of the current heap-top 6638 // used when updating the eden heap top 6639 // implemented using ldaxr on AArch64 6640 6641 instruct loadPLocked(iRegPNoSp dst, indirect mem) 6642 %{ 6643 match(Set dst (LoadPLocked mem)); 6644 6645 ins_cost(VOLATILE_REF_COST); 6646 6647 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 6648 6649 ins_encode(aarch64_enc_ldaxr(dst, mem)); 6650 6651 ins_pipe(pipe_serial); 6652 %} 6653 6654 // Conditional-store of the updated heap-top. 6655 // Used during allocation of the shared heap. 6656 // Sets flag (EQ) on success. 6657 // implemented using stlxr on AArch64. 6658 6659 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 6660 %{ 6661 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 6662 6663 ins_cost(VOLATILE_REF_COST); 6664 6665 // TODO 6666 // do we need to do a store-conditional release or can we just use a 6667 // plain store-conditional? 6668 6669 format %{ 6670 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 6671 "cmpw rscratch1, zr\t# EQ on successful write" 6672 %} 6673 6674 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 6675 6676 ins_pipe(pipe_serial); 6677 %} 6678 6679 // this has to be implemented as a CAS 6680 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 6681 %{ 6682 match(Set cr (StoreLConditional mem (Binary oldval newval))); 6683 6684 ins_cost(VOLATILE_REF_COST); 6685 6686 format %{ 6687 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 6688 "cmpw rscratch1, zr\t# EQ on successful write" 6689 %} 6690 6691 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); 6692 6693 ins_pipe(pipe_slow); 6694 %} 6695 6696 // this has to be implemented as a CAS 6697 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 6698 %{ 6699 match(Set cr (StoreIConditional mem (Binary oldval newval))); 6700 6701 ins_cost(VOLATILE_REF_COST); 6702 6703 format %{ 6704 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 6705 "cmpw rscratch1, zr\t# EQ on successful write" 6706 %} 6707 6708 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); 6709 6710 ins_pipe(pipe_slow); 6711 %} 6712 6713 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 6714 // can't match them 6715 6716 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 6717 6718 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 6719 6720 effect(KILL cr); 6721 6722 format %{ 6723 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 6724 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6725 %} 6726 6727 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 6728 aarch64_enc_cset_eq(res)); 6729 6730 ins_pipe(pipe_slow); 6731 %} 6732 6733 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 6734 6735 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 6736 6737 effect(KILL cr); 6738 6739 format %{ 6740 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 6741 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6742 %} 6743 6744 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 6745 aarch64_enc_cset_eq(res)); 6746 6747 ins_pipe(pipe_slow); 6748 %} 6749 6750 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 6751 6752 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 6753 6754 effect(KILL cr); 6755 6756 format %{ 6757 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 6758 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6759 %} 6760 6761 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 6762 aarch64_enc_cset_eq(res)); 6763 6764 ins_pipe(pipe_slow); 6765 %} 6766 6767 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 6768 6769 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 6770 6771 effect(KILL cr); 6772 6773 format %{ 6774 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 6775 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6776 %} 6777 6778 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 6779 aarch64_enc_cset_eq(res)); 6780 6781 ins_pipe(pipe_slow); 6782 %} 6783 6784 6785 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ 6786 match(Set prev (GetAndSetI mem newv)); 6787 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 6788 ins_encode %{ 6789 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6790 %} 6791 ins_pipe(pipe_serial); 6792 %} 6793 6794 instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{ 6795 match(Set prev (GetAndSetL mem newv)); 6796 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 6797 ins_encode %{ 6798 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6799 %} 6800 ins_pipe(pipe_serial); 6801 %} 6802 6803 instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{ 6804 match(Set prev (GetAndSetN mem newv)); 6805 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 6806 ins_encode %{ 6807 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6808 %} 6809 ins_pipe(pipe_serial); 6810 %} 6811 6812 instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{ 6813 match(Set prev (GetAndSetP mem newv)); 6814 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 6815 ins_encode %{ 6816 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6817 %} 6818 ins_pipe(pipe_serial); 6819 %} 6820 6821 6822 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 6823 match(Set newval (GetAndAddL mem incr)); 6824 ins_cost(INSN_COST * 10); 6825 format %{ "get_and_addL $newval, [$mem], $incr" %} 6826 ins_encode %{ 6827 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6828 %} 6829 ins_pipe(pipe_serial); 6830 %} 6831 6832 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 6833 predicate(n->as_LoadStore()->result_not_used()); 6834 match(Set dummy (GetAndAddL mem incr)); 6835 ins_cost(INSN_COST * 9); 6836 format %{ "get_and_addL [$mem], $incr" %} 6837 ins_encode %{ 6838 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 6839 %} 6840 ins_pipe(pipe_serial); 6841 %} 6842 6843 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 6844 match(Set newval (GetAndAddL mem incr)); 6845 ins_cost(INSN_COST * 10); 6846 format %{ "get_and_addL $newval, [$mem], $incr" %} 6847 ins_encode %{ 6848 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6849 %} 6850 ins_pipe(pipe_serial); 6851 %} 6852 6853 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 6854 predicate(n->as_LoadStore()->result_not_used()); 6855 match(Set dummy (GetAndAddL mem incr)); 6856 ins_cost(INSN_COST * 9); 6857 format %{ "get_and_addL [$mem], $incr" %} 6858 ins_encode %{ 6859 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 6860 %} 6861 ins_pipe(pipe_serial); 6862 %} 6863 6864 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 6865 match(Set newval (GetAndAddI mem incr)); 6866 ins_cost(INSN_COST * 10); 6867 format %{ "get_and_addI $newval, [$mem], $incr" %} 6868 ins_encode %{ 6869 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6870 %} 6871 ins_pipe(pipe_serial); 6872 %} 6873 6874 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 6875 predicate(n->as_LoadStore()->result_not_used()); 6876 match(Set dummy (GetAndAddI mem incr)); 6877 ins_cost(INSN_COST * 9); 6878 format %{ "get_and_addI [$mem], $incr" %} 6879 ins_encode %{ 6880 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 6881 %} 6882 ins_pipe(pipe_serial); 6883 %} 6884 6885 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 6886 match(Set newval (GetAndAddI mem incr)); 6887 ins_cost(INSN_COST * 10); 6888 format %{ "get_and_addI $newval, [$mem], $incr" %} 6889 ins_encode %{ 6890 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6891 %} 6892 ins_pipe(pipe_serial); 6893 %} 6894 6895 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 6896 predicate(n->as_LoadStore()->result_not_used()); 6897 match(Set dummy (GetAndAddI mem incr)); 6898 ins_cost(INSN_COST * 9); 6899 format %{ "get_and_addI [$mem], $incr" %} 6900 ins_encode %{ 6901 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 6902 %} 6903 ins_pipe(pipe_serial); 6904 %} 6905 6906 // Manifest a CmpL result in an integer register. 6907 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 6908 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 6909 %{ 6910 match(Set dst (CmpL3 src1 src2)); 6911 effect(KILL flags); 6912 6913 ins_cost(INSN_COST * 6); 6914 format %{ 6915 "cmp $src1, $src2" 6916 "csetw $dst, ne" 6917 "cnegw $dst, lt" 6918 %} 6919 // format %{ "CmpL3 $dst, $src1, $src2" %} 6920 ins_encode %{ 6921 __ cmp($src1$$Register, $src2$$Register); 6922 __ csetw($dst$$Register, Assembler::NE); 6923 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 6924 %} 6925 6926 ins_pipe(pipe_class_default); 6927 %} 6928 6929 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 6930 %{ 6931 match(Set dst (CmpL3 src1 src2)); 6932 effect(KILL flags); 6933 6934 ins_cost(INSN_COST * 6); 6935 format %{ 6936 "cmp $src1, $src2" 6937 "csetw $dst, ne" 6938 "cnegw $dst, lt" 6939 %} 6940 ins_encode %{ 6941 int32_t con = (int32_t)$src2$$constant; 6942 if (con < 0) { 6943 __ adds(zr, $src1$$Register, -con); 6944 } else { 6945 __ subs(zr, $src1$$Register, con); 6946 } 6947 __ csetw($dst$$Register, Assembler::NE); 6948 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 6949 %} 6950 6951 ins_pipe(pipe_class_default); 6952 %} 6953 6954 // ============================================================================ 6955 // Conditional Move Instructions 6956 6957 // n.b. we have identical rules for both a signed compare op (cmpOp) 6958 // and an unsigned compare op (cmpOpU). it would be nice if we could 6959 // define an op class which merged both inputs and use it to type the 6960 // argument to a single rule. unfortunatelyt his fails because the 6961 // opclass does not live up to the COND_INTER interface of its 6962 // component operands. When the generic code tries to negate the 6963 // operand it ends up running the generci Machoper::negate method 6964 // which throws a ShouldNotHappen. So, we have to provide two flavours 6965 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 6966 6967 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src1, iRegI src2) %{ 6968 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 6969 6970 ins_cost(INSN_COST * 2); 6971 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 6972 6973 ins_encode %{ 6974 __ cselw(as_Register($dst$$reg), 6975 as_Register($src2$$reg), 6976 as_Register($src1$$reg), 6977 (Assembler::Condition)$cmp$$cmpcode); 6978 %} 6979 6980 ins_pipe(icond_reg_reg); 6981 %} 6982 6983 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src1, iRegI src2) %{ 6984 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 6985 6986 ins_cost(INSN_COST * 2); 6987 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 6988 6989 ins_encode %{ 6990 __ cselw(as_Register($dst$$reg), 6991 as_Register($src2$$reg), 6992 as_Register($src1$$reg), 6993 (Assembler::Condition)$cmp$$cmpcode); 6994 %} 6995 6996 ins_pipe(icond_reg_reg); 6997 %} 6998 6999 // special cases where one arg is zero 7000 7001 // n.b. this is selected in preference to the rule above because it 7002 // avoids loading constant 0 into a source register 7003 7004 // TODO 7005 // we ought only to be able to cull one of these variants as the ideal 7006 // transforms ought always to order the zero consistently (to left/right?) 7007 7008 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegI src) %{ 7009 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7010 7011 ins_cost(INSN_COST * 2); 7012 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 7013 7014 ins_encode %{ 7015 __ cselw(as_Register($dst$$reg), 7016 as_Register($src$$reg), 7017 zr, 7018 (Assembler::Condition)$cmp$$cmpcode); 7019 %} 7020 7021 ins_pipe(icond_reg); 7022 %} 7023 7024 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegI src) %{ 7025 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7026 7027 ins_cost(INSN_COST * 2); 7028 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 7029 7030 ins_encode %{ 7031 __ cselw(as_Register($dst$$reg), 7032 as_Register($src$$reg), 7033 zr, 7034 (Assembler::Condition)$cmp$$cmpcode); 7035 %} 7036 7037 ins_pipe(icond_reg); 7038 %} 7039 7040 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src, immI0 zero) %{ 7041 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7042 7043 ins_cost(INSN_COST * 2); 7044 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 7045 7046 ins_encode %{ 7047 __ cselw(as_Register($dst$$reg), 7048 zr, 7049 as_Register($src$$reg), 7050 (Assembler::Condition)$cmp$$cmpcode); 7051 %} 7052 7053 ins_pipe(icond_reg); 7054 %} 7055 7056 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src, immI0 zero) %{ 7057 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7058 7059 ins_cost(INSN_COST * 2); 7060 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 7061 7062 ins_encode %{ 7063 __ cselw(as_Register($dst$$reg), 7064 zr, 7065 as_Register($src$$reg), 7066 (Assembler::Condition)$cmp$$cmpcode); 7067 %} 7068 7069 ins_pipe(icond_reg); 7070 %} 7071 7072 // special case for creating a boolean 0 or 1 7073 7074 // n.b. this is selected in preference to the rule above because it 7075 // avoids loading constants 0 and 1 into a source register 7076 7077 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7078 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7079 7080 ins_cost(INSN_COST * 2); 7081 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 7082 7083 ins_encode %{ 7084 // equivalently 7085 // cset(as_Register($dst$$reg), 7086 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7087 __ csincw(as_Register($dst$$reg), 7088 zr, 7089 zr, 7090 (Assembler::Condition)$cmp$$cmpcode); 7091 %} 7092 7093 ins_pipe(icond_none); 7094 %} 7095 7096 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7097 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7098 7099 ins_cost(INSN_COST * 2); 7100 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 7101 7102 ins_encode %{ 7103 // equivalently 7104 // cset(as_Register($dst$$reg), 7105 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7106 __ csincw(as_Register($dst$$reg), 7107 zr, 7108 zr, 7109 (Assembler::Condition)$cmp$$cmpcode); 7110 %} 7111 7112 ins_pipe(icond_none); 7113 %} 7114 7115 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7116 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7117 7118 ins_cost(INSN_COST * 2); 7119 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 7120 7121 ins_encode %{ 7122 __ csel(as_Register($dst$$reg), 7123 as_Register($src2$$reg), 7124 as_Register($src1$$reg), 7125 (Assembler::Condition)$cmp$$cmpcode); 7126 %} 7127 7128 ins_pipe(icond_reg_reg); 7129 %} 7130 7131 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7132 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7133 7134 ins_cost(INSN_COST * 2); 7135 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 7136 7137 ins_encode %{ 7138 __ csel(as_Register($dst$$reg), 7139 as_Register($src2$$reg), 7140 as_Register($src1$$reg), 7141 (Assembler::Condition)$cmp$$cmpcode); 7142 %} 7143 7144 ins_pipe(icond_reg_reg); 7145 %} 7146 7147 // special cases where one arg is zero 7148 7149 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7150 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7151 7152 ins_cost(INSN_COST * 2); 7153 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 7154 7155 ins_encode %{ 7156 __ csel(as_Register($dst$$reg), 7157 zr, 7158 as_Register($src$$reg), 7159 (Assembler::Condition)$cmp$$cmpcode); 7160 %} 7161 7162 ins_pipe(icond_reg); 7163 %} 7164 7165 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7166 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7167 7168 ins_cost(INSN_COST * 2); 7169 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 7170 7171 ins_encode %{ 7172 __ csel(as_Register($dst$$reg), 7173 zr, 7174 as_Register($src$$reg), 7175 (Assembler::Condition)$cmp$$cmpcode); 7176 %} 7177 7178 ins_pipe(icond_reg); 7179 %} 7180 7181 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7182 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7183 7184 ins_cost(INSN_COST * 2); 7185 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 7186 7187 ins_encode %{ 7188 __ csel(as_Register($dst$$reg), 7189 as_Register($src$$reg), 7190 zr, 7191 (Assembler::Condition)$cmp$$cmpcode); 7192 %} 7193 7194 ins_pipe(icond_reg); 7195 %} 7196 7197 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7198 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7199 7200 ins_cost(INSN_COST * 2); 7201 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 7202 7203 ins_encode %{ 7204 __ csel(as_Register($dst$$reg), 7205 as_Register($src$$reg), 7206 zr, 7207 (Assembler::Condition)$cmp$$cmpcode); 7208 %} 7209 7210 ins_pipe(icond_reg); 7211 %} 7212 7213 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 7214 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 7215 7216 ins_cost(INSN_COST * 2); 7217 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 7218 7219 ins_encode %{ 7220 __ csel(as_Register($dst$$reg), 7221 as_Register($src2$$reg), 7222 as_Register($src1$$reg), 7223 (Assembler::Condition)$cmp$$cmpcode); 7224 %} 7225 7226 ins_pipe(icond_reg_reg); 7227 %} 7228 7229 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 7230 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 7231 7232 ins_cost(INSN_COST * 2); 7233 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 7234 7235 ins_encode %{ 7236 __ csel(as_Register($dst$$reg), 7237 as_Register($src2$$reg), 7238 as_Register($src1$$reg), 7239 (Assembler::Condition)$cmp$$cmpcode); 7240 %} 7241 7242 ins_pipe(icond_reg_reg); 7243 %} 7244 7245 // special cases where one arg is zero 7246 7247 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 7248 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 7249 7250 ins_cost(INSN_COST * 2); 7251 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 7252 7253 ins_encode %{ 7254 __ csel(as_Register($dst$$reg), 7255 zr, 7256 as_Register($src$$reg), 7257 (Assembler::Condition)$cmp$$cmpcode); 7258 %} 7259 7260 ins_pipe(icond_reg); 7261 %} 7262 7263 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 7264 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 7265 7266 ins_cost(INSN_COST * 2); 7267 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 7268 7269 ins_encode %{ 7270 __ csel(as_Register($dst$$reg), 7271 zr, 7272 as_Register($src$$reg), 7273 (Assembler::Condition)$cmp$$cmpcode); 7274 %} 7275 7276 ins_pipe(icond_reg); 7277 %} 7278 7279 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 7280 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 7281 7282 ins_cost(INSN_COST * 2); 7283 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 7284 7285 ins_encode %{ 7286 __ csel(as_Register($dst$$reg), 7287 as_Register($src$$reg), 7288 zr, 7289 (Assembler::Condition)$cmp$$cmpcode); 7290 %} 7291 7292 ins_pipe(icond_reg); 7293 %} 7294 7295 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 7296 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 7297 7298 ins_cost(INSN_COST * 2); 7299 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 7300 7301 ins_encode %{ 7302 __ csel(as_Register($dst$$reg), 7303 as_Register($src$$reg), 7304 zr, 7305 (Assembler::Condition)$cmp$$cmpcode); 7306 %} 7307 7308 ins_pipe(icond_reg); 7309 %} 7310 7311 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 7312 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 7313 7314 ins_cost(INSN_COST * 2); 7315 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 7316 7317 ins_encode %{ 7318 __ cselw(as_Register($dst$$reg), 7319 as_Register($src2$$reg), 7320 as_Register($src1$$reg), 7321 (Assembler::Condition)$cmp$$cmpcode); 7322 %} 7323 7324 ins_pipe(icond_reg_reg); 7325 %} 7326 7327 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 7328 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 7329 7330 ins_cost(INSN_COST * 2); 7331 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 7332 7333 ins_encode %{ 7334 __ cselw(as_Register($dst$$reg), 7335 as_Register($src2$$reg), 7336 as_Register($src1$$reg), 7337 (Assembler::Condition)$cmp$$cmpcode); 7338 %} 7339 7340 ins_pipe(icond_reg_reg); 7341 %} 7342 7343 // special cases where one arg is zero 7344 7345 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 7346 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 7347 7348 ins_cost(INSN_COST * 2); 7349 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 7350 7351 ins_encode %{ 7352 __ cselw(as_Register($dst$$reg), 7353 zr, 7354 as_Register($src$$reg), 7355 (Assembler::Condition)$cmp$$cmpcode); 7356 %} 7357 7358 ins_pipe(icond_reg); 7359 %} 7360 7361 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 7362 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 7363 7364 ins_cost(INSN_COST * 2); 7365 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 7366 7367 ins_encode %{ 7368 __ cselw(as_Register($dst$$reg), 7369 zr, 7370 as_Register($src$$reg), 7371 (Assembler::Condition)$cmp$$cmpcode); 7372 %} 7373 7374 ins_pipe(icond_reg); 7375 %} 7376 7377 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 7378 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 7379 7380 ins_cost(INSN_COST * 2); 7381 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 7382 7383 ins_encode %{ 7384 __ cselw(as_Register($dst$$reg), 7385 as_Register($src$$reg), 7386 zr, 7387 (Assembler::Condition)$cmp$$cmpcode); 7388 %} 7389 7390 ins_pipe(icond_reg); 7391 %} 7392 7393 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 7394 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 7395 7396 ins_cost(INSN_COST * 2); 7397 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 7398 7399 ins_encode %{ 7400 __ cselw(as_Register($dst$$reg), 7401 as_Register($src$$reg), 7402 zr, 7403 (Assembler::Condition)$cmp$$cmpcode); 7404 %} 7405 7406 ins_pipe(icond_reg); 7407 %} 7408 7409 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 7410 %{ 7411 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 7412 7413 ins_cost(INSN_COST * 3); 7414 7415 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 7416 ins_encode %{ 7417 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7418 __ fcsels(as_FloatRegister($dst$$reg), 7419 as_FloatRegister($src2$$reg), 7420 as_FloatRegister($src1$$reg), 7421 cond); 7422 %} 7423 7424 ins_pipe(pipe_class_default); 7425 %} 7426 7427 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 7428 %{ 7429 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 7430 7431 ins_cost(INSN_COST * 3); 7432 7433 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 7434 ins_encode %{ 7435 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7436 __ fcsels(as_FloatRegister($dst$$reg), 7437 as_FloatRegister($src2$$reg), 7438 as_FloatRegister($src1$$reg), 7439 cond); 7440 %} 7441 7442 ins_pipe(pipe_class_default); 7443 %} 7444 7445 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 7446 %{ 7447 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 7448 7449 ins_cost(INSN_COST * 3); 7450 7451 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 7452 ins_encode %{ 7453 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7454 __ fcseld(as_FloatRegister($dst$$reg), 7455 as_FloatRegister($src2$$reg), 7456 as_FloatRegister($src1$$reg), 7457 cond); 7458 %} 7459 7460 ins_pipe(pipe_class_default); 7461 %} 7462 7463 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 7464 %{ 7465 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 7466 7467 ins_cost(INSN_COST * 3); 7468 7469 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 7470 ins_encode %{ 7471 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7472 __ fcseld(as_FloatRegister($dst$$reg), 7473 as_FloatRegister($src2$$reg), 7474 as_FloatRegister($src1$$reg), 7475 cond); 7476 %} 7477 7478 ins_pipe(pipe_class_default); 7479 %} 7480 7481 // ============================================================================ 7482 // Arithmetic Instructions 7483 // 7484 7485 // Integer Addition 7486 7487 // TODO 7488 // these currently employ operations which do not set CR and hence are 7489 // not flagged as killing CR but we would like to isolate the cases 7490 // where we want to set flags from those where we don't. need to work 7491 // out how to do that. 7492 7493 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7494 match(Set dst (AddI src1 src2)); 7495 7496 ins_cost(INSN_COST); 7497 format %{ "addw $dst, $src1, $src2" %} 7498 7499 ins_encode %{ 7500 __ addw(as_Register($dst$$reg), 7501 as_Register($src1$$reg), 7502 as_Register($src2$$reg)); 7503 %} 7504 7505 ins_pipe(ialu_reg_reg); 7506 %} 7507 7508 instruct addI_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2) %{ 7509 match(Set dst (AddI src1 src2)); 7510 7511 ins_cost(INSN_COST); 7512 format %{ "addw $dst, $src1, $src2" %} 7513 7514 // use opcode to indicate that this is an add not a sub 7515 opcode(0x0); 7516 7517 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7518 7519 ins_pipe(ialu_reg_imm); 7520 %} 7521 7522 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 7523 match(Set dst (AddI (ConvL2I src1) src2)); 7524 7525 ins_cost(INSN_COST); 7526 format %{ "addw $dst, $src1, $src2" %} 7527 7528 // use opcode to indicate that this is an add not a sub 7529 opcode(0x0); 7530 7531 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7532 7533 ins_pipe(ialu_reg_imm); 7534 %} 7535 7536 // Pointer Addition 7537 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 7538 match(Set dst (AddP src1 src2)); 7539 7540 ins_cost(INSN_COST); 7541 format %{ "add $dst, $src1, $src2\t# ptr" %} 7542 7543 ins_encode %{ 7544 __ add(as_Register($dst$$reg), 7545 as_Register($src1$$reg), 7546 as_Register($src2$$reg)); 7547 %} 7548 7549 ins_pipe(ialu_reg_reg); 7550 %} 7551 7552 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 7553 match(Set dst (AddP src1 (ConvI2L src2))); 7554 7555 ins_cost(INSN_COST); 7556 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 7557 7558 ins_encode %{ 7559 __ add(as_Register($dst$$reg), 7560 as_Register($src1$$reg), 7561 as_Register($src2$$reg), ext::sxtw); 7562 %} 7563 7564 ins_pipe(ialu_reg_reg); 7565 %} 7566 7567 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 7568 match(Set dst (AddP src1 (LShiftL src2 scale))); 7569 7570 ins_cost(1.9 * INSN_COST); 7571 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 7572 7573 ins_encode %{ 7574 __ lea(as_Register($dst$$reg), 7575 Address(as_Register($src1$$reg), as_Register($src2$$reg), 7576 Address::lsl($scale$$constant))); 7577 %} 7578 7579 ins_pipe(ialu_reg_reg_shift); 7580 %} 7581 7582 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 7583 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 7584 7585 ins_cost(1.9 * INSN_COST); 7586 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 7587 7588 ins_encode %{ 7589 __ lea(as_Register($dst$$reg), 7590 Address(as_Register($src1$$reg), as_Register($src2$$reg), 7591 Address::sxtw($scale$$constant))); 7592 %} 7593 7594 ins_pipe(ialu_reg_reg_shift); 7595 %} 7596 7597 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 7598 match(Set dst (LShiftL (ConvI2L src) scale)); 7599 7600 ins_cost(INSN_COST); 7601 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 7602 7603 ins_encode %{ 7604 __ sbfiz(as_Register($dst$$reg), 7605 as_Register($src$$reg), 7606 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 7607 %} 7608 7609 ins_pipe(ialu_reg_shift); 7610 %} 7611 7612 // Pointer Immediate Addition 7613 // n.b. this needs to be more expensive than using an indirect memory 7614 // operand 7615 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 7616 match(Set dst (AddP src1 src2)); 7617 7618 ins_cost(INSN_COST); 7619 format %{ "add $dst, $src1, $src2\t# ptr" %} 7620 7621 // use opcode to indicate that this is an add not a sub 7622 opcode(0x0); 7623 7624 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7625 7626 ins_pipe(ialu_reg_imm); 7627 %} 7628 7629 // Long Addition 7630 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7631 7632 match(Set dst (AddL src1 src2)); 7633 7634 ins_cost(INSN_COST); 7635 format %{ "add $dst, $src1, $src2" %} 7636 7637 ins_encode %{ 7638 __ add(as_Register($dst$$reg), 7639 as_Register($src1$$reg), 7640 as_Register($src2$$reg)); 7641 %} 7642 7643 ins_pipe(ialu_reg_reg); 7644 %} 7645 7646 // No constant pool entries requiredLong Immediate Addition. 7647 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 7648 match(Set dst (AddL src1 src2)); 7649 7650 ins_cost(INSN_COST); 7651 format %{ "add $dst, $src1, $src2" %} 7652 7653 // use opcode to indicate that this is an add not a sub 7654 opcode(0x0); 7655 7656 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7657 7658 ins_pipe(ialu_reg_imm); 7659 %} 7660 7661 // Integer Subtraction 7662 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7663 match(Set dst (SubI src1 src2)); 7664 7665 ins_cost(INSN_COST); 7666 format %{ "subw $dst, $src1, $src2" %} 7667 7668 ins_encode %{ 7669 __ subw(as_Register($dst$$reg), 7670 as_Register($src1$$reg), 7671 as_Register($src2$$reg)); 7672 %} 7673 7674 ins_pipe(ialu_reg_reg); 7675 %} 7676 7677 // Immediate Subtraction 7678 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 7679 match(Set dst (SubI src1 src2)); 7680 7681 ins_cost(INSN_COST); 7682 format %{ "subw $dst, $src1, $src2" %} 7683 7684 // use opcode to indicate that this is a sub not an add 7685 opcode(0x1); 7686 7687 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7688 7689 ins_pipe(ialu_reg_imm); 7690 %} 7691 7692 // Long Subtraction 7693 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7694 7695 match(Set dst (SubL src1 src2)); 7696 7697 ins_cost(INSN_COST); 7698 format %{ "sub $dst, $src1, $src2" %} 7699 7700 ins_encode %{ 7701 __ sub(as_Register($dst$$reg), 7702 as_Register($src1$$reg), 7703 as_Register($src2$$reg)); 7704 %} 7705 7706 ins_pipe(ialu_reg_reg); 7707 %} 7708 7709 // No constant pool entries requiredLong Immediate Subtraction. 7710 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 7711 match(Set dst (SubL src1 src2)); 7712 7713 ins_cost(INSN_COST); 7714 format %{ "sub$dst, $src1, $src2" %} 7715 7716 // use opcode to indicate that this is a sub not an add 7717 opcode(0x1); 7718 7719 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7720 7721 ins_pipe(ialu_reg_imm); 7722 %} 7723 7724 // Integer Negation (special case for sub) 7725 7726 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 7727 match(Set dst (SubI zero src)); 7728 7729 ins_cost(INSN_COST); 7730 format %{ "negw $dst, $src\t# int" %} 7731 7732 ins_encode %{ 7733 __ negw(as_Register($dst$$reg), 7734 as_Register($src$$reg)); 7735 %} 7736 7737 ins_pipe(ialu_reg); 7738 %} 7739 7740 // Long Negation 7741 7742 instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{ 7743 match(Set dst (SubL zero src)); 7744 7745 ins_cost(INSN_COST); 7746 format %{ "neg $dst, $src\t# long" %} 7747 7748 ins_encode %{ 7749 __ neg(as_Register($dst$$reg), 7750 as_Register($src$$reg)); 7751 %} 7752 7753 ins_pipe(ialu_reg); 7754 %} 7755 7756 // Integer Multiply 7757 7758 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7759 match(Set dst (MulI src1 src2)); 7760 7761 ins_cost(INSN_COST * 3); 7762 format %{ "mulw $dst, $src1, $src2" %} 7763 7764 ins_encode %{ 7765 __ mulw(as_Register($dst$$reg), 7766 as_Register($src1$$reg), 7767 as_Register($src2$$reg)); 7768 %} 7769 7770 ins_pipe(imul_reg_reg); 7771 %} 7772 7773 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7774 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 7775 7776 ins_cost(INSN_COST * 3); 7777 format %{ "smull $dst, $src1, $src2" %} 7778 7779 ins_encode %{ 7780 __ smull(as_Register($dst$$reg), 7781 as_Register($src1$$reg), 7782 as_Register($src2$$reg)); 7783 %} 7784 7785 ins_pipe(imul_reg_reg); 7786 %} 7787 7788 // Long Multiply 7789 7790 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7791 match(Set dst (MulL src1 src2)); 7792 7793 ins_cost(INSN_COST * 5); 7794 format %{ "mul $dst, $src1, $src2" %} 7795 7796 ins_encode %{ 7797 __ mul(as_Register($dst$$reg), 7798 as_Register($src1$$reg), 7799 as_Register($src2$$reg)); 7800 %} 7801 7802 ins_pipe(lmul_reg_reg); 7803 %} 7804 7805 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 7806 %{ 7807 match(Set dst (MulHiL src1 src2)); 7808 7809 ins_cost(INSN_COST * 7); 7810 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 7811 7812 ins_encode %{ 7813 __ smulh(as_Register($dst$$reg), 7814 as_Register($src1$$reg), 7815 as_Register($src2$$reg)); 7816 %} 7817 7818 ins_pipe(lmul_reg_reg); 7819 %} 7820 7821 // Combined Integer Multiply & Add/Sub 7822 7823 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 7824 match(Set dst (AddI src3 (MulI src1 src2))); 7825 7826 ins_cost(INSN_COST * 3); 7827 format %{ "madd $dst, $src1, $src2, $src3" %} 7828 7829 ins_encode %{ 7830 __ maddw(as_Register($dst$$reg), 7831 as_Register($src1$$reg), 7832 as_Register($src2$$reg), 7833 as_Register($src3$$reg)); 7834 %} 7835 7836 ins_pipe(imac_reg_reg); 7837 %} 7838 7839 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 7840 match(Set dst (SubI src3 (MulI src1 src2))); 7841 7842 ins_cost(INSN_COST * 3); 7843 format %{ "msub $dst, $src1, $src2, $src3" %} 7844 7845 ins_encode %{ 7846 __ msubw(as_Register($dst$$reg), 7847 as_Register($src1$$reg), 7848 as_Register($src2$$reg), 7849 as_Register($src3$$reg)); 7850 %} 7851 7852 ins_pipe(imac_reg_reg); 7853 %} 7854 7855 // Combined Long Multiply & Add/Sub 7856 7857 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 7858 match(Set dst (AddL src3 (MulL src1 src2))); 7859 7860 ins_cost(INSN_COST * 5); 7861 format %{ "madd $dst, $src1, $src2, $src3" %} 7862 7863 ins_encode %{ 7864 __ madd(as_Register($dst$$reg), 7865 as_Register($src1$$reg), 7866 as_Register($src2$$reg), 7867 as_Register($src3$$reg)); 7868 %} 7869 7870 ins_pipe(lmac_reg_reg); 7871 %} 7872 7873 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 7874 match(Set dst (SubL src3 (MulL src1 src2))); 7875 7876 ins_cost(INSN_COST * 5); 7877 format %{ "msub $dst, $src1, $src2, $src3" %} 7878 7879 ins_encode %{ 7880 __ msub(as_Register($dst$$reg), 7881 as_Register($src1$$reg), 7882 as_Register($src2$$reg), 7883 as_Register($src3$$reg)); 7884 %} 7885 7886 ins_pipe(lmac_reg_reg); 7887 %} 7888 7889 // Integer Divide 7890 7891 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7892 match(Set dst (DivI src1 src2)); 7893 7894 ins_cost(INSN_COST * 19); 7895 format %{ "sdivw $dst, $src1, $src2" %} 7896 7897 ins_encode(aarch64_enc_divw(dst, src1, src2)); 7898 ins_pipe(idiv_reg_reg); 7899 %} 7900 7901 instruct signExtract(iRegINoSp dst, iRegI src1, immI_31 div1, immI_31 div2) %{ 7902 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 7903 ins_cost(INSN_COST); 7904 format %{ "lsrw $dst, $src1, $div1" %} 7905 ins_encode %{ 7906 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 7907 %} 7908 ins_pipe(ialu_reg_shift); 7909 %} 7910 7911 instruct div2Round(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{ 7912 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 7913 ins_cost(INSN_COST); 7914 format %{ "addw $dst, $src, LSR $div1" %} 7915 7916 ins_encode %{ 7917 __ addw(as_Register($dst$$reg), 7918 as_Register($src$$reg), 7919 as_Register($src$$reg), 7920 Assembler::LSR, 31); 7921 %} 7922 ins_pipe(ialu_reg); 7923 %} 7924 7925 // Long Divide 7926 7927 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7928 match(Set dst (DivL src1 src2)); 7929 7930 ins_cost(INSN_COST * 35); 7931 format %{ "sdiv $dst, $src1, $src2" %} 7932 7933 ins_encode(aarch64_enc_div(dst, src1, src2)); 7934 ins_pipe(ldiv_reg_reg); 7935 %} 7936 7937 instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{ 7938 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 7939 ins_cost(INSN_COST); 7940 format %{ "lsr $dst, $src1, $div1" %} 7941 ins_encode %{ 7942 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 7943 %} 7944 ins_pipe(ialu_reg_shift); 7945 %} 7946 7947 instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{ 7948 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 7949 ins_cost(INSN_COST); 7950 format %{ "add $dst, $src, $div1" %} 7951 7952 ins_encode %{ 7953 __ add(as_Register($dst$$reg), 7954 as_Register($src$$reg), 7955 as_Register($src$$reg), 7956 Assembler::LSR, 63); 7957 %} 7958 ins_pipe(ialu_reg); 7959 %} 7960 7961 // Integer Remainder 7962 7963 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7964 match(Set dst (ModI src1 src2)); 7965 7966 ins_cost(INSN_COST * 22); 7967 format %{ "sdivw rscratch1, $src1, $src2\n\t" 7968 "msubw($dst, rscratch1, $src2, $src1" %} 7969 7970 ins_encode(aarch64_enc_modw(dst, src1, src2)); 7971 ins_pipe(idiv_reg_reg); 7972 %} 7973 7974 // Long Remainder 7975 7976 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7977 match(Set dst (ModL src1 src2)); 7978 7979 ins_cost(INSN_COST * 38); 7980 format %{ "sdiv rscratch1, $src1, $src2\n" 7981 "msub($dst, rscratch1, $src2, $src1" %} 7982 7983 ins_encode(aarch64_enc_mod(dst, src1, src2)); 7984 ins_pipe(ldiv_reg_reg); 7985 %} 7986 7987 // Integer Shifts 7988 7989 // Shift Left Register 7990 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7991 match(Set dst (LShiftI src1 src2)); 7992 7993 ins_cost(INSN_COST * 2); 7994 format %{ "lslvw $dst, $src1, $src2" %} 7995 7996 ins_encode %{ 7997 __ lslvw(as_Register($dst$$reg), 7998 as_Register($src1$$reg), 7999 as_Register($src2$$reg)); 8000 %} 8001 8002 ins_pipe(ialu_reg_reg_vshift); 8003 %} 8004 8005 // Shift Left Immediate 8006 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8007 match(Set dst (LShiftI src1 src2)); 8008 8009 ins_cost(INSN_COST); 8010 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 8011 8012 ins_encode %{ 8013 __ lslw(as_Register($dst$$reg), 8014 as_Register($src1$$reg), 8015 $src2$$constant & 0x1f); 8016 %} 8017 8018 ins_pipe(ialu_reg_shift); 8019 %} 8020 8021 // Shift Right Logical Register 8022 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8023 match(Set dst (URShiftI src1 src2)); 8024 8025 ins_cost(INSN_COST * 2); 8026 format %{ "lsrvw $dst, $src1, $src2" %} 8027 8028 ins_encode %{ 8029 __ lsrvw(as_Register($dst$$reg), 8030 as_Register($src1$$reg), 8031 as_Register($src2$$reg)); 8032 %} 8033 8034 ins_pipe(ialu_reg_reg_vshift); 8035 %} 8036 8037 // Shift Right Logical Immediate 8038 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8039 match(Set dst (URShiftI src1 src2)); 8040 8041 ins_cost(INSN_COST); 8042 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 8043 8044 ins_encode %{ 8045 __ lsrw(as_Register($dst$$reg), 8046 as_Register($src1$$reg), 8047 $src2$$constant & 0x1f); 8048 %} 8049 8050 ins_pipe(ialu_reg_shift); 8051 %} 8052 8053 // Shift Right Arithmetic Register 8054 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8055 match(Set dst (RShiftI src1 src2)); 8056 8057 ins_cost(INSN_COST * 2); 8058 format %{ "asrvw $dst, $src1, $src2" %} 8059 8060 ins_encode %{ 8061 __ asrvw(as_Register($dst$$reg), 8062 as_Register($src1$$reg), 8063 as_Register($src2$$reg)); 8064 %} 8065 8066 ins_pipe(ialu_reg_reg_vshift); 8067 %} 8068 8069 // Shift Right Arithmetic Immediate 8070 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8071 match(Set dst (RShiftI src1 src2)); 8072 8073 ins_cost(INSN_COST); 8074 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 8075 8076 ins_encode %{ 8077 __ asrw(as_Register($dst$$reg), 8078 as_Register($src1$$reg), 8079 $src2$$constant & 0x1f); 8080 %} 8081 8082 ins_pipe(ialu_reg_shift); 8083 %} 8084 8085 // Combined Int Mask and Right Shift (using UBFM) 8086 // TODO 8087 8088 // Long Shifts 8089 8090 // Shift Left Register 8091 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8092 match(Set dst (LShiftL src1 src2)); 8093 8094 ins_cost(INSN_COST * 2); 8095 format %{ "lslv $dst, $src1, $src2" %} 8096 8097 ins_encode %{ 8098 __ lslv(as_Register($dst$$reg), 8099 as_Register($src1$$reg), 8100 as_Register($src2$$reg)); 8101 %} 8102 8103 ins_pipe(ialu_reg_reg_vshift); 8104 %} 8105 8106 // Shift Left Immediate 8107 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8108 match(Set dst (LShiftL src1 src2)); 8109 8110 ins_cost(INSN_COST); 8111 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 8112 8113 ins_encode %{ 8114 __ lsl(as_Register($dst$$reg), 8115 as_Register($src1$$reg), 8116 $src2$$constant & 0x3f); 8117 %} 8118 8119 ins_pipe(ialu_reg_shift); 8120 %} 8121 8122 // Shift Right Logical Register 8123 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8124 match(Set dst (URShiftL src1 src2)); 8125 8126 ins_cost(INSN_COST * 2); 8127 format %{ "lsrv $dst, $src1, $src2" %} 8128 8129 ins_encode %{ 8130 __ lsrv(as_Register($dst$$reg), 8131 as_Register($src1$$reg), 8132 as_Register($src2$$reg)); 8133 %} 8134 8135 ins_pipe(ialu_reg_reg_vshift); 8136 %} 8137 8138 // Shift Right Logical Immediate 8139 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8140 match(Set dst (URShiftL src1 src2)); 8141 8142 ins_cost(INSN_COST); 8143 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 8144 8145 ins_encode %{ 8146 __ lsr(as_Register($dst$$reg), 8147 as_Register($src1$$reg), 8148 $src2$$constant & 0x3f); 8149 %} 8150 8151 ins_pipe(ialu_reg_shift); 8152 %} 8153 8154 // A special-case pattern for card table stores. 8155 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 8156 match(Set dst (URShiftL (CastP2X src1) src2)); 8157 8158 ins_cost(INSN_COST); 8159 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 8160 8161 ins_encode %{ 8162 __ lsr(as_Register($dst$$reg), 8163 as_Register($src1$$reg), 8164 $src2$$constant & 0x3f); 8165 %} 8166 8167 ins_pipe(ialu_reg_shift); 8168 %} 8169 8170 // Shift Right Arithmetic Register 8171 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8172 match(Set dst (RShiftL src1 src2)); 8173 8174 ins_cost(INSN_COST * 2); 8175 format %{ "asrv $dst, $src1, $src2" %} 8176 8177 ins_encode %{ 8178 __ asrv(as_Register($dst$$reg), 8179 as_Register($src1$$reg), 8180 as_Register($src2$$reg)); 8181 %} 8182 8183 ins_pipe(ialu_reg_reg_vshift); 8184 %} 8185 8186 // Shift Right Arithmetic Immediate 8187 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8188 match(Set dst (RShiftL src1 src2)); 8189 8190 ins_cost(INSN_COST); 8191 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 8192 8193 ins_encode %{ 8194 __ asr(as_Register($dst$$reg), 8195 as_Register($src1$$reg), 8196 $src2$$constant & 0x3f); 8197 %} 8198 8199 ins_pipe(ialu_reg_shift); 8200 %} 8201 8202 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8203 8204 instruct regL_not_reg(iRegLNoSp dst, 8205 iRegL src1, immL_M1 m1, 8206 rFlagsReg cr) %{ 8207 match(Set dst (XorL src1 m1)); 8208 ins_cost(INSN_COST); 8209 format %{ "eon $dst, $src1, zr" %} 8210 8211 ins_encode %{ 8212 __ eon(as_Register($dst$$reg), 8213 as_Register($src1$$reg), 8214 zr, 8215 Assembler::LSL, 0); 8216 %} 8217 8218 ins_pipe(ialu_reg); 8219 %} 8220 instruct regI_not_reg(iRegINoSp dst, 8221 iRegI src1, immI_M1 m1, 8222 rFlagsReg cr) %{ 8223 match(Set dst (XorI src1 m1)); 8224 ins_cost(INSN_COST); 8225 format %{ "eonw $dst, $src1, zr" %} 8226 8227 ins_encode %{ 8228 __ eonw(as_Register($dst$$reg), 8229 as_Register($src1$$reg), 8230 zr, 8231 Assembler::LSL, 0); 8232 %} 8233 8234 ins_pipe(ialu_reg); 8235 %} 8236 8237 instruct AndI_reg_not_reg(iRegINoSp dst, 8238 iRegI src1, iRegI src2, immI_M1 m1, 8239 rFlagsReg cr) %{ 8240 match(Set dst (AndI src1 (XorI src2 m1))); 8241 ins_cost(INSN_COST); 8242 format %{ "bic $dst, $src1, $src2" %} 8243 8244 ins_encode %{ 8245 __ bic(as_Register($dst$$reg), 8246 as_Register($src1$$reg), 8247 as_Register($src2$$reg), 8248 Assembler::LSL, 0); 8249 %} 8250 8251 ins_pipe(ialu_reg_reg); 8252 %} 8253 8254 instruct AndL_reg_not_reg(iRegLNoSp dst, 8255 iRegL src1, iRegL src2, immL_M1 m1, 8256 rFlagsReg cr) %{ 8257 match(Set dst (AndL src1 (XorL src2 m1))); 8258 ins_cost(INSN_COST); 8259 format %{ "bic $dst, $src1, $src2" %} 8260 8261 ins_encode %{ 8262 __ bic(as_Register($dst$$reg), 8263 as_Register($src1$$reg), 8264 as_Register($src2$$reg), 8265 Assembler::LSL, 0); 8266 %} 8267 8268 ins_pipe(ialu_reg_reg); 8269 %} 8270 8271 instruct OrI_reg_not_reg(iRegINoSp dst, 8272 iRegI src1, iRegI src2, immI_M1 m1, 8273 rFlagsReg cr) %{ 8274 match(Set dst (OrI src1 (XorI src2 m1))); 8275 ins_cost(INSN_COST); 8276 format %{ "orn $dst, $src1, $src2" %} 8277 8278 ins_encode %{ 8279 __ orn(as_Register($dst$$reg), 8280 as_Register($src1$$reg), 8281 as_Register($src2$$reg), 8282 Assembler::LSL, 0); 8283 %} 8284 8285 ins_pipe(ialu_reg_reg); 8286 %} 8287 8288 instruct OrL_reg_not_reg(iRegLNoSp dst, 8289 iRegL src1, iRegL src2, immL_M1 m1, 8290 rFlagsReg cr) %{ 8291 match(Set dst (OrL src1 (XorL src2 m1))); 8292 ins_cost(INSN_COST); 8293 format %{ "orn $dst, $src1, $src2" %} 8294 8295 ins_encode %{ 8296 __ orn(as_Register($dst$$reg), 8297 as_Register($src1$$reg), 8298 as_Register($src2$$reg), 8299 Assembler::LSL, 0); 8300 %} 8301 8302 ins_pipe(ialu_reg_reg); 8303 %} 8304 8305 instruct XorI_reg_not_reg(iRegINoSp dst, 8306 iRegI src1, iRegI src2, immI_M1 m1, 8307 rFlagsReg cr) %{ 8308 match(Set dst (XorI m1 (XorI src2 src1))); 8309 ins_cost(INSN_COST); 8310 format %{ "eon $dst, $src1, $src2" %} 8311 8312 ins_encode %{ 8313 __ eon(as_Register($dst$$reg), 8314 as_Register($src1$$reg), 8315 as_Register($src2$$reg), 8316 Assembler::LSL, 0); 8317 %} 8318 8319 ins_pipe(ialu_reg_reg); 8320 %} 8321 8322 instruct XorL_reg_not_reg(iRegLNoSp dst, 8323 iRegL src1, iRegL src2, immL_M1 m1, 8324 rFlagsReg cr) %{ 8325 match(Set dst (XorL m1 (XorL src2 src1))); 8326 ins_cost(INSN_COST); 8327 format %{ "eon $dst, $src1, $src2" %} 8328 8329 ins_encode %{ 8330 __ eon(as_Register($dst$$reg), 8331 as_Register($src1$$reg), 8332 as_Register($src2$$reg), 8333 Assembler::LSL, 0); 8334 %} 8335 8336 ins_pipe(ialu_reg_reg); 8337 %} 8338 8339 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 8340 iRegI src1, iRegI src2, 8341 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8342 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 8343 ins_cost(1.9 * INSN_COST); 8344 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 8345 8346 ins_encode %{ 8347 __ bicw(as_Register($dst$$reg), 8348 as_Register($src1$$reg), 8349 as_Register($src2$$reg), 8350 Assembler::LSR, 8351 $src3$$constant & 0x3f); 8352 %} 8353 8354 ins_pipe(ialu_reg_reg_shift); 8355 %} 8356 8357 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 8358 iRegL src1, iRegL src2, 8359 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8360 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 8361 ins_cost(1.9 * INSN_COST); 8362 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 8363 8364 ins_encode %{ 8365 __ bic(as_Register($dst$$reg), 8366 as_Register($src1$$reg), 8367 as_Register($src2$$reg), 8368 Assembler::LSR, 8369 $src3$$constant & 0x3f); 8370 %} 8371 8372 ins_pipe(ialu_reg_reg_shift); 8373 %} 8374 8375 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 8376 iRegI src1, iRegI src2, 8377 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8378 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 8379 ins_cost(1.9 * INSN_COST); 8380 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 8381 8382 ins_encode %{ 8383 __ bicw(as_Register($dst$$reg), 8384 as_Register($src1$$reg), 8385 as_Register($src2$$reg), 8386 Assembler::ASR, 8387 $src3$$constant & 0x3f); 8388 %} 8389 8390 ins_pipe(ialu_reg_reg_shift); 8391 %} 8392 8393 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 8394 iRegL src1, iRegL src2, 8395 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8396 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 8397 ins_cost(1.9 * INSN_COST); 8398 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 8399 8400 ins_encode %{ 8401 __ bic(as_Register($dst$$reg), 8402 as_Register($src1$$reg), 8403 as_Register($src2$$reg), 8404 Assembler::ASR, 8405 $src3$$constant & 0x3f); 8406 %} 8407 8408 ins_pipe(ialu_reg_reg_shift); 8409 %} 8410 8411 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 8412 iRegI src1, iRegI src2, 8413 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8414 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 8415 ins_cost(1.9 * INSN_COST); 8416 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 8417 8418 ins_encode %{ 8419 __ bicw(as_Register($dst$$reg), 8420 as_Register($src1$$reg), 8421 as_Register($src2$$reg), 8422 Assembler::LSL, 8423 $src3$$constant & 0x3f); 8424 %} 8425 8426 ins_pipe(ialu_reg_reg_shift); 8427 %} 8428 8429 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 8430 iRegL src1, iRegL src2, 8431 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8432 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 8433 ins_cost(1.9 * INSN_COST); 8434 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 8435 8436 ins_encode %{ 8437 __ bic(as_Register($dst$$reg), 8438 as_Register($src1$$reg), 8439 as_Register($src2$$reg), 8440 Assembler::LSL, 8441 $src3$$constant & 0x3f); 8442 %} 8443 8444 ins_pipe(ialu_reg_reg_shift); 8445 %} 8446 8447 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 8448 iRegI src1, iRegI src2, 8449 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8450 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 8451 ins_cost(1.9 * INSN_COST); 8452 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 8453 8454 ins_encode %{ 8455 __ eonw(as_Register($dst$$reg), 8456 as_Register($src1$$reg), 8457 as_Register($src2$$reg), 8458 Assembler::LSR, 8459 $src3$$constant & 0x3f); 8460 %} 8461 8462 ins_pipe(ialu_reg_reg_shift); 8463 %} 8464 8465 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 8466 iRegL src1, iRegL src2, 8467 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8468 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 8469 ins_cost(1.9 * INSN_COST); 8470 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 8471 8472 ins_encode %{ 8473 __ eon(as_Register($dst$$reg), 8474 as_Register($src1$$reg), 8475 as_Register($src2$$reg), 8476 Assembler::LSR, 8477 $src3$$constant & 0x3f); 8478 %} 8479 8480 ins_pipe(ialu_reg_reg_shift); 8481 %} 8482 8483 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 8484 iRegI src1, iRegI src2, 8485 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8486 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 8487 ins_cost(1.9 * INSN_COST); 8488 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 8489 8490 ins_encode %{ 8491 __ eonw(as_Register($dst$$reg), 8492 as_Register($src1$$reg), 8493 as_Register($src2$$reg), 8494 Assembler::ASR, 8495 $src3$$constant & 0x3f); 8496 %} 8497 8498 ins_pipe(ialu_reg_reg_shift); 8499 %} 8500 8501 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 8502 iRegL src1, iRegL src2, 8503 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8504 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 8505 ins_cost(1.9 * INSN_COST); 8506 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 8507 8508 ins_encode %{ 8509 __ eon(as_Register($dst$$reg), 8510 as_Register($src1$$reg), 8511 as_Register($src2$$reg), 8512 Assembler::ASR, 8513 $src3$$constant & 0x3f); 8514 %} 8515 8516 ins_pipe(ialu_reg_reg_shift); 8517 %} 8518 8519 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 8520 iRegI src1, iRegI src2, 8521 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8522 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 8523 ins_cost(1.9 * INSN_COST); 8524 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 8525 8526 ins_encode %{ 8527 __ eonw(as_Register($dst$$reg), 8528 as_Register($src1$$reg), 8529 as_Register($src2$$reg), 8530 Assembler::LSL, 8531 $src3$$constant & 0x3f); 8532 %} 8533 8534 ins_pipe(ialu_reg_reg_shift); 8535 %} 8536 8537 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 8538 iRegL src1, iRegL src2, 8539 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8540 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 8541 ins_cost(1.9 * INSN_COST); 8542 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 8543 8544 ins_encode %{ 8545 __ eon(as_Register($dst$$reg), 8546 as_Register($src1$$reg), 8547 as_Register($src2$$reg), 8548 Assembler::LSL, 8549 $src3$$constant & 0x3f); 8550 %} 8551 8552 ins_pipe(ialu_reg_reg_shift); 8553 %} 8554 8555 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 8556 iRegI src1, iRegI src2, 8557 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8558 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 8559 ins_cost(1.9 * INSN_COST); 8560 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 8561 8562 ins_encode %{ 8563 __ ornw(as_Register($dst$$reg), 8564 as_Register($src1$$reg), 8565 as_Register($src2$$reg), 8566 Assembler::LSR, 8567 $src3$$constant & 0x3f); 8568 %} 8569 8570 ins_pipe(ialu_reg_reg_shift); 8571 %} 8572 8573 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 8574 iRegL src1, iRegL src2, 8575 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8576 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 8577 ins_cost(1.9 * INSN_COST); 8578 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 8579 8580 ins_encode %{ 8581 __ orn(as_Register($dst$$reg), 8582 as_Register($src1$$reg), 8583 as_Register($src2$$reg), 8584 Assembler::LSR, 8585 $src3$$constant & 0x3f); 8586 %} 8587 8588 ins_pipe(ialu_reg_reg_shift); 8589 %} 8590 8591 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 8592 iRegI src1, iRegI src2, 8593 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8594 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 8595 ins_cost(1.9 * INSN_COST); 8596 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 8597 8598 ins_encode %{ 8599 __ ornw(as_Register($dst$$reg), 8600 as_Register($src1$$reg), 8601 as_Register($src2$$reg), 8602 Assembler::ASR, 8603 $src3$$constant & 0x3f); 8604 %} 8605 8606 ins_pipe(ialu_reg_reg_shift); 8607 %} 8608 8609 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 8610 iRegL src1, iRegL src2, 8611 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8612 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 8613 ins_cost(1.9 * INSN_COST); 8614 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 8615 8616 ins_encode %{ 8617 __ orn(as_Register($dst$$reg), 8618 as_Register($src1$$reg), 8619 as_Register($src2$$reg), 8620 Assembler::ASR, 8621 $src3$$constant & 0x3f); 8622 %} 8623 8624 ins_pipe(ialu_reg_reg_shift); 8625 %} 8626 8627 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 8628 iRegI src1, iRegI src2, 8629 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8630 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 8631 ins_cost(1.9 * INSN_COST); 8632 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 8633 8634 ins_encode %{ 8635 __ ornw(as_Register($dst$$reg), 8636 as_Register($src1$$reg), 8637 as_Register($src2$$reg), 8638 Assembler::LSL, 8639 $src3$$constant & 0x3f); 8640 %} 8641 8642 ins_pipe(ialu_reg_reg_shift); 8643 %} 8644 8645 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 8646 iRegL src1, iRegL src2, 8647 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8648 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 8649 ins_cost(1.9 * INSN_COST); 8650 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 8651 8652 ins_encode %{ 8653 __ orn(as_Register($dst$$reg), 8654 as_Register($src1$$reg), 8655 as_Register($src2$$reg), 8656 Assembler::LSL, 8657 $src3$$constant & 0x3f); 8658 %} 8659 8660 ins_pipe(ialu_reg_reg_shift); 8661 %} 8662 8663 instruct AndI_reg_URShift_reg(iRegINoSp dst, 8664 iRegI src1, iRegI src2, 8665 immI src3, rFlagsReg cr) %{ 8666 match(Set dst (AndI src1 (URShiftI src2 src3))); 8667 8668 ins_cost(1.9 * INSN_COST); 8669 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 8670 8671 ins_encode %{ 8672 __ andw(as_Register($dst$$reg), 8673 as_Register($src1$$reg), 8674 as_Register($src2$$reg), 8675 Assembler::LSR, 8676 $src3$$constant & 0x3f); 8677 %} 8678 8679 ins_pipe(ialu_reg_reg_shift); 8680 %} 8681 8682 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 8683 iRegL src1, iRegL src2, 8684 immI src3, rFlagsReg cr) %{ 8685 match(Set dst (AndL src1 (URShiftL src2 src3))); 8686 8687 ins_cost(1.9 * INSN_COST); 8688 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 8689 8690 ins_encode %{ 8691 __ andr(as_Register($dst$$reg), 8692 as_Register($src1$$reg), 8693 as_Register($src2$$reg), 8694 Assembler::LSR, 8695 $src3$$constant & 0x3f); 8696 %} 8697 8698 ins_pipe(ialu_reg_reg_shift); 8699 %} 8700 8701 instruct AndI_reg_RShift_reg(iRegINoSp dst, 8702 iRegI src1, iRegI src2, 8703 immI src3, rFlagsReg cr) %{ 8704 match(Set dst (AndI src1 (RShiftI src2 src3))); 8705 8706 ins_cost(1.9 * INSN_COST); 8707 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 8708 8709 ins_encode %{ 8710 __ andw(as_Register($dst$$reg), 8711 as_Register($src1$$reg), 8712 as_Register($src2$$reg), 8713 Assembler::ASR, 8714 $src3$$constant & 0x3f); 8715 %} 8716 8717 ins_pipe(ialu_reg_reg_shift); 8718 %} 8719 8720 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 8721 iRegL src1, iRegL src2, 8722 immI src3, rFlagsReg cr) %{ 8723 match(Set dst (AndL src1 (RShiftL src2 src3))); 8724 8725 ins_cost(1.9 * INSN_COST); 8726 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 8727 8728 ins_encode %{ 8729 __ andr(as_Register($dst$$reg), 8730 as_Register($src1$$reg), 8731 as_Register($src2$$reg), 8732 Assembler::ASR, 8733 $src3$$constant & 0x3f); 8734 %} 8735 8736 ins_pipe(ialu_reg_reg_shift); 8737 %} 8738 8739 instruct AndI_reg_LShift_reg(iRegINoSp dst, 8740 iRegI src1, iRegI src2, 8741 immI src3, rFlagsReg cr) %{ 8742 match(Set dst (AndI src1 (LShiftI src2 src3))); 8743 8744 ins_cost(1.9 * INSN_COST); 8745 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 8746 8747 ins_encode %{ 8748 __ andw(as_Register($dst$$reg), 8749 as_Register($src1$$reg), 8750 as_Register($src2$$reg), 8751 Assembler::LSL, 8752 $src3$$constant & 0x3f); 8753 %} 8754 8755 ins_pipe(ialu_reg_reg_shift); 8756 %} 8757 8758 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 8759 iRegL src1, iRegL src2, 8760 immI src3, rFlagsReg cr) %{ 8761 match(Set dst (AndL src1 (LShiftL src2 src3))); 8762 8763 ins_cost(1.9 * INSN_COST); 8764 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 8765 8766 ins_encode %{ 8767 __ andr(as_Register($dst$$reg), 8768 as_Register($src1$$reg), 8769 as_Register($src2$$reg), 8770 Assembler::LSL, 8771 $src3$$constant & 0x3f); 8772 %} 8773 8774 ins_pipe(ialu_reg_reg_shift); 8775 %} 8776 8777 instruct XorI_reg_URShift_reg(iRegINoSp dst, 8778 iRegI src1, iRegI src2, 8779 immI src3, rFlagsReg cr) %{ 8780 match(Set dst (XorI src1 (URShiftI src2 src3))); 8781 8782 ins_cost(1.9 * INSN_COST); 8783 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 8784 8785 ins_encode %{ 8786 __ eorw(as_Register($dst$$reg), 8787 as_Register($src1$$reg), 8788 as_Register($src2$$reg), 8789 Assembler::LSR, 8790 $src3$$constant & 0x3f); 8791 %} 8792 8793 ins_pipe(ialu_reg_reg_shift); 8794 %} 8795 8796 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 8797 iRegL src1, iRegL src2, 8798 immI src3, rFlagsReg cr) %{ 8799 match(Set dst (XorL src1 (URShiftL src2 src3))); 8800 8801 ins_cost(1.9 * INSN_COST); 8802 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 8803 8804 ins_encode %{ 8805 __ eor(as_Register($dst$$reg), 8806 as_Register($src1$$reg), 8807 as_Register($src2$$reg), 8808 Assembler::LSR, 8809 $src3$$constant & 0x3f); 8810 %} 8811 8812 ins_pipe(ialu_reg_reg_shift); 8813 %} 8814 8815 instruct XorI_reg_RShift_reg(iRegINoSp dst, 8816 iRegI src1, iRegI src2, 8817 immI src3, rFlagsReg cr) %{ 8818 match(Set dst (XorI src1 (RShiftI src2 src3))); 8819 8820 ins_cost(1.9 * INSN_COST); 8821 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 8822 8823 ins_encode %{ 8824 __ eorw(as_Register($dst$$reg), 8825 as_Register($src1$$reg), 8826 as_Register($src2$$reg), 8827 Assembler::ASR, 8828 $src3$$constant & 0x3f); 8829 %} 8830 8831 ins_pipe(ialu_reg_reg_shift); 8832 %} 8833 8834 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 8835 iRegL src1, iRegL src2, 8836 immI src3, rFlagsReg cr) %{ 8837 match(Set dst (XorL src1 (RShiftL src2 src3))); 8838 8839 ins_cost(1.9 * INSN_COST); 8840 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 8841 8842 ins_encode %{ 8843 __ eor(as_Register($dst$$reg), 8844 as_Register($src1$$reg), 8845 as_Register($src2$$reg), 8846 Assembler::ASR, 8847 $src3$$constant & 0x3f); 8848 %} 8849 8850 ins_pipe(ialu_reg_reg_shift); 8851 %} 8852 8853 instruct XorI_reg_LShift_reg(iRegINoSp dst, 8854 iRegI src1, iRegI src2, 8855 immI src3, rFlagsReg cr) %{ 8856 match(Set dst (XorI src1 (LShiftI src2 src3))); 8857 8858 ins_cost(1.9 * INSN_COST); 8859 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 8860 8861 ins_encode %{ 8862 __ eorw(as_Register($dst$$reg), 8863 as_Register($src1$$reg), 8864 as_Register($src2$$reg), 8865 Assembler::LSL, 8866 $src3$$constant & 0x3f); 8867 %} 8868 8869 ins_pipe(ialu_reg_reg_shift); 8870 %} 8871 8872 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 8873 iRegL src1, iRegL src2, 8874 immI src3, rFlagsReg cr) %{ 8875 match(Set dst (XorL src1 (LShiftL src2 src3))); 8876 8877 ins_cost(1.9 * INSN_COST); 8878 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 8879 8880 ins_encode %{ 8881 __ eor(as_Register($dst$$reg), 8882 as_Register($src1$$reg), 8883 as_Register($src2$$reg), 8884 Assembler::LSL, 8885 $src3$$constant & 0x3f); 8886 %} 8887 8888 ins_pipe(ialu_reg_reg_shift); 8889 %} 8890 8891 instruct OrI_reg_URShift_reg(iRegINoSp dst, 8892 iRegI src1, iRegI src2, 8893 immI src3, rFlagsReg cr) %{ 8894 match(Set dst (OrI src1 (URShiftI src2 src3))); 8895 8896 ins_cost(1.9 * INSN_COST); 8897 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 8898 8899 ins_encode %{ 8900 __ orrw(as_Register($dst$$reg), 8901 as_Register($src1$$reg), 8902 as_Register($src2$$reg), 8903 Assembler::LSR, 8904 $src3$$constant & 0x3f); 8905 %} 8906 8907 ins_pipe(ialu_reg_reg_shift); 8908 %} 8909 8910 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 8911 iRegL src1, iRegL src2, 8912 immI src3, rFlagsReg cr) %{ 8913 match(Set dst (OrL src1 (URShiftL src2 src3))); 8914 8915 ins_cost(1.9 * INSN_COST); 8916 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 8917 8918 ins_encode %{ 8919 __ orr(as_Register($dst$$reg), 8920 as_Register($src1$$reg), 8921 as_Register($src2$$reg), 8922 Assembler::LSR, 8923 $src3$$constant & 0x3f); 8924 %} 8925 8926 ins_pipe(ialu_reg_reg_shift); 8927 %} 8928 8929 instruct OrI_reg_RShift_reg(iRegINoSp dst, 8930 iRegI src1, iRegI src2, 8931 immI src3, rFlagsReg cr) %{ 8932 match(Set dst (OrI src1 (RShiftI src2 src3))); 8933 8934 ins_cost(1.9 * INSN_COST); 8935 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 8936 8937 ins_encode %{ 8938 __ orrw(as_Register($dst$$reg), 8939 as_Register($src1$$reg), 8940 as_Register($src2$$reg), 8941 Assembler::ASR, 8942 $src3$$constant & 0x3f); 8943 %} 8944 8945 ins_pipe(ialu_reg_reg_shift); 8946 %} 8947 8948 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 8949 iRegL src1, iRegL src2, 8950 immI src3, rFlagsReg cr) %{ 8951 match(Set dst (OrL src1 (RShiftL src2 src3))); 8952 8953 ins_cost(1.9 * INSN_COST); 8954 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 8955 8956 ins_encode %{ 8957 __ orr(as_Register($dst$$reg), 8958 as_Register($src1$$reg), 8959 as_Register($src2$$reg), 8960 Assembler::ASR, 8961 $src3$$constant & 0x3f); 8962 %} 8963 8964 ins_pipe(ialu_reg_reg_shift); 8965 %} 8966 8967 instruct OrI_reg_LShift_reg(iRegINoSp dst, 8968 iRegI src1, iRegI src2, 8969 immI src3, rFlagsReg cr) %{ 8970 match(Set dst (OrI src1 (LShiftI src2 src3))); 8971 8972 ins_cost(1.9 * INSN_COST); 8973 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 8974 8975 ins_encode %{ 8976 __ orrw(as_Register($dst$$reg), 8977 as_Register($src1$$reg), 8978 as_Register($src2$$reg), 8979 Assembler::LSL, 8980 $src3$$constant & 0x3f); 8981 %} 8982 8983 ins_pipe(ialu_reg_reg_shift); 8984 %} 8985 8986 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 8987 iRegL src1, iRegL src2, 8988 immI src3, rFlagsReg cr) %{ 8989 match(Set dst (OrL src1 (LShiftL src2 src3))); 8990 8991 ins_cost(1.9 * INSN_COST); 8992 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 8993 8994 ins_encode %{ 8995 __ orr(as_Register($dst$$reg), 8996 as_Register($src1$$reg), 8997 as_Register($src2$$reg), 8998 Assembler::LSL, 8999 $src3$$constant & 0x3f); 9000 %} 9001 9002 ins_pipe(ialu_reg_reg_shift); 9003 %} 9004 9005 instruct AddI_reg_URShift_reg(iRegINoSp dst, 9006 iRegI src1, iRegI src2, 9007 immI src3, rFlagsReg cr) %{ 9008 match(Set dst (AddI src1 (URShiftI src2 src3))); 9009 9010 ins_cost(1.9 * INSN_COST); 9011 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 9012 9013 ins_encode %{ 9014 __ addw(as_Register($dst$$reg), 9015 as_Register($src1$$reg), 9016 as_Register($src2$$reg), 9017 Assembler::LSR, 9018 $src3$$constant & 0x3f); 9019 %} 9020 9021 ins_pipe(ialu_reg_reg_shift); 9022 %} 9023 9024 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 9025 iRegL src1, iRegL src2, 9026 immI src3, rFlagsReg cr) %{ 9027 match(Set dst (AddL src1 (URShiftL src2 src3))); 9028 9029 ins_cost(1.9 * INSN_COST); 9030 format %{ "add $dst, $src1, $src2, LSR $src3" %} 9031 9032 ins_encode %{ 9033 __ add(as_Register($dst$$reg), 9034 as_Register($src1$$reg), 9035 as_Register($src2$$reg), 9036 Assembler::LSR, 9037 $src3$$constant & 0x3f); 9038 %} 9039 9040 ins_pipe(ialu_reg_reg_shift); 9041 %} 9042 9043 instruct AddI_reg_RShift_reg(iRegINoSp dst, 9044 iRegI src1, iRegI src2, 9045 immI src3, rFlagsReg cr) %{ 9046 match(Set dst (AddI src1 (RShiftI src2 src3))); 9047 9048 ins_cost(1.9 * INSN_COST); 9049 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 9050 9051 ins_encode %{ 9052 __ addw(as_Register($dst$$reg), 9053 as_Register($src1$$reg), 9054 as_Register($src2$$reg), 9055 Assembler::ASR, 9056 $src3$$constant & 0x3f); 9057 %} 9058 9059 ins_pipe(ialu_reg_reg_shift); 9060 %} 9061 9062 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 9063 iRegL src1, iRegL src2, 9064 immI src3, rFlagsReg cr) %{ 9065 match(Set dst (AddL src1 (RShiftL src2 src3))); 9066 9067 ins_cost(1.9 * INSN_COST); 9068 format %{ "add $dst, $src1, $src2, ASR $src3" %} 9069 9070 ins_encode %{ 9071 __ add(as_Register($dst$$reg), 9072 as_Register($src1$$reg), 9073 as_Register($src2$$reg), 9074 Assembler::ASR, 9075 $src3$$constant & 0x3f); 9076 %} 9077 9078 ins_pipe(ialu_reg_reg_shift); 9079 %} 9080 9081 instruct AddI_reg_LShift_reg(iRegINoSp dst, 9082 iRegI src1, iRegI src2, 9083 immI src3, rFlagsReg cr) %{ 9084 match(Set dst (AddI src1 (LShiftI src2 src3))); 9085 9086 ins_cost(1.9 * INSN_COST); 9087 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 9088 9089 ins_encode %{ 9090 __ addw(as_Register($dst$$reg), 9091 as_Register($src1$$reg), 9092 as_Register($src2$$reg), 9093 Assembler::LSL, 9094 $src3$$constant & 0x3f); 9095 %} 9096 9097 ins_pipe(ialu_reg_reg_shift); 9098 %} 9099 9100 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 9101 iRegL src1, iRegL src2, 9102 immI src3, rFlagsReg cr) %{ 9103 match(Set dst (AddL src1 (LShiftL src2 src3))); 9104 9105 ins_cost(1.9 * INSN_COST); 9106 format %{ "add $dst, $src1, $src2, LSL $src3" %} 9107 9108 ins_encode %{ 9109 __ add(as_Register($dst$$reg), 9110 as_Register($src1$$reg), 9111 as_Register($src2$$reg), 9112 Assembler::LSL, 9113 $src3$$constant & 0x3f); 9114 %} 9115 9116 ins_pipe(ialu_reg_reg_shift); 9117 %} 9118 9119 instruct SubI_reg_URShift_reg(iRegINoSp dst, 9120 iRegI src1, iRegI src2, 9121 immI src3, rFlagsReg cr) %{ 9122 match(Set dst (SubI src1 (URShiftI src2 src3))); 9123 9124 ins_cost(1.9 * INSN_COST); 9125 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 9126 9127 ins_encode %{ 9128 __ subw(as_Register($dst$$reg), 9129 as_Register($src1$$reg), 9130 as_Register($src2$$reg), 9131 Assembler::LSR, 9132 $src3$$constant & 0x3f); 9133 %} 9134 9135 ins_pipe(ialu_reg_reg_shift); 9136 %} 9137 9138 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 9139 iRegL src1, iRegL src2, 9140 immI src3, rFlagsReg cr) %{ 9141 match(Set dst (SubL src1 (URShiftL src2 src3))); 9142 9143 ins_cost(1.9 * INSN_COST); 9144 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 9145 9146 ins_encode %{ 9147 __ sub(as_Register($dst$$reg), 9148 as_Register($src1$$reg), 9149 as_Register($src2$$reg), 9150 Assembler::LSR, 9151 $src3$$constant & 0x3f); 9152 %} 9153 9154 ins_pipe(ialu_reg_reg_shift); 9155 %} 9156 9157 instruct SubI_reg_RShift_reg(iRegINoSp dst, 9158 iRegI src1, iRegI src2, 9159 immI src3, rFlagsReg cr) %{ 9160 match(Set dst (SubI src1 (RShiftI src2 src3))); 9161 9162 ins_cost(1.9 * INSN_COST); 9163 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 9164 9165 ins_encode %{ 9166 __ subw(as_Register($dst$$reg), 9167 as_Register($src1$$reg), 9168 as_Register($src2$$reg), 9169 Assembler::ASR, 9170 $src3$$constant & 0x3f); 9171 %} 9172 9173 ins_pipe(ialu_reg_reg_shift); 9174 %} 9175 9176 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 9177 iRegL src1, iRegL src2, 9178 immI src3, rFlagsReg cr) %{ 9179 match(Set dst (SubL src1 (RShiftL src2 src3))); 9180 9181 ins_cost(1.9 * INSN_COST); 9182 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 9183 9184 ins_encode %{ 9185 __ sub(as_Register($dst$$reg), 9186 as_Register($src1$$reg), 9187 as_Register($src2$$reg), 9188 Assembler::ASR, 9189 $src3$$constant & 0x3f); 9190 %} 9191 9192 ins_pipe(ialu_reg_reg_shift); 9193 %} 9194 9195 instruct SubI_reg_LShift_reg(iRegINoSp dst, 9196 iRegI src1, iRegI src2, 9197 immI src3, rFlagsReg cr) %{ 9198 match(Set dst (SubI src1 (LShiftI src2 src3))); 9199 9200 ins_cost(1.9 * INSN_COST); 9201 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 9202 9203 ins_encode %{ 9204 __ subw(as_Register($dst$$reg), 9205 as_Register($src1$$reg), 9206 as_Register($src2$$reg), 9207 Assembler::LSL, 9208 $src3$$constant & 0x3f); 9209 %} 9210 9211 ins_pipe(ialu_reg_reg_shift); 9212 %} 9213 9214 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 9215 iRegL src1, iRegL src2, 9216 immI src3, rFlagsReg cr) %{ 9217 match(Set dst (SubL src1 (LShiftL src2 src3))); 9218 9219 ins_cost(1.9 * INSN_COST); 9220 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 9221 9222 ins_encode %{ 9223 __ sub(as_Register($dst$$reg), 9224 as_Register($src1$$reg), 9225 as_Register($src2$$reg), 9226 Assembler::LSL, 9227 $src3$$constant & 0x3f); 9228 %} 9229 9230 ins_pipe(ialu_reg_reg_shift); 9231 %} 9232 9233 9234 9235 // Shift Left followed by Shift Right. 9236 // This idiom is used by the compiler for the i2b bytecode etc. 9237 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 9238 %{ 9239 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 9240 // Make sure we are not going to exceed what sbfm can do. 9241 predicate((unsigned int)n->in(2)->get_int() <= 63 9242 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 9243 9244 ins_cost(INSN_COST * 2); 9245 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 9246 ins_encode %{ 9247 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9248 int s = 63 - lshift; 9249 int r = (rshift - lshift) & 63; 9250 __ sbfm(as_Register($dst$$reg), 9251 as_Register($src$$reg), 9252 r, s); 9253 %} 9254 9255 ins_pipe(ialu_reg_shift); 9256 %} 9257 9258 // Shift Left followed by Shift Right. 9259 // This idiom is used by the compiler for the i2b bytecode etc. 9260 instruct sbfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count) 9261 %{ 9262 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 9263 // Make sure we are not going to exceed what sbfmw can do. 9264 predicate((unsigned int)n->in(2)->get_int() <= 31 9265 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 9266 9267 ins_cost(INSN_COST * 2); 9268 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 9269 ins_encode %{ 9270 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9271 int s = 31 - lshift; 9272 int r = (rshift - lshift) & 31; 9273 __ sbfmw(as_Register($dst$$reg), 9274 as_Register($src$$reg), 9275 r, s); 9276 %} 9277 9278 ins_pipe(ialu_reg_shift); 9279 %} 9280 9281 // Shift Left followed by Shift Right. 9282 // This idiom is used by the compiler for the i2b bytecode etc. 9283 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 9284 %{ 9285 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 9286 // Make sure we are not going to exceed what ubfm can do. 9287 predicate((unsigned int)n->in(2)->get_int() <= 63 9288 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 9289 9290 ins_cost(INSN_COST * 2); 9291 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 9292 ins_encode %{ 9293 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9294 int s = 63 - lshift; 9295 int r = (rshift - lshift) & 63; 9296 __ ubfm(as_Register($dst$$reg), 9297 as_Register($src$$reg), 9298 r, s); 9299 %} 9300 9301 ins_pipe(ialu_reg_shift); 9302 %} 9303 9304 // Shift Left followed by Shift Right. 9305 // This idiom is used by the compiler for the i2b bytecode etc. 9306 instruct ubfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count) 9307 %{ 9308 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 9309 // Make sure we are not going to exceed what ubfmw can do. 9310 predicate((unsigned int)n->in(2)->get_int() <= 31 9311 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 9312 9313 ins_cost(INSN_COST * 2); 9314 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 9315 ins_encode %{ 9316 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9317 int s = 31 - lshift; 9318 int r = (rshift - lshift) & 31; 9319 __ ubfmw(as_Register($dst$$reg), 9320 as_Register($src$$reg), 9321 r, s); 9322 %} 9323 9324 ins_pipe(ialu_reg_shift); 9325 %} 9326 // Bitfield extract with shift & mask 9327 9328 instruct ubfxwI(iRegINoSp dst, iRegI src, immI rshift, immI_bitmask mask) 9329 %{ 9330 match(Set dst (AndI (URShiftI src rshift) mask)); 9331 9332 ins_cost(INSN_COST); 9333 format %{ "ubfxw $dst, $src, $mask" %} 9334 ins_encode %{ 9335 int rshift = $rshift$$constant; 9336 long mask = $mask$$constant; 9337 int width = exact_log2(mask+1); 9338 __ ubfxw(as_Register($dst$$reg), 9339 as_Register($src$$reg), rshift, width); 9340 %} 9341 ins_pipe(ialu_reg_shift); 9342 %} 9343 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 9344 %{ 9345 match(Set dst (AndL (URShiftL src rshift) mask)); 9346 9347 ins_cost(INSN_COST); 9348 format %{ "ubfx $dst, $src, $mask" %} 9349 ins_encode %{ 9350 int rshift = $rshift$$constant; 9351 long mask = $mask$$constant; 9352 int width = exact_log2(mask+1); 9353 __ ubfx(as_Register($dst$$reg), 9354 as_Register($src$$reg), rshift, width); 9355 %} 9356 ins_pipe(ialu_reg_shift); 9357 %} 9358 9359 // We can use ubfx when extending an And with a mask when we know mask 9360 // is positive. We know that because immI_bitmask guarantees it. 9361 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 9362 %{ 9363 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 9364 9365 ins_cost(INSN_COST * 2); 9366 format %{ "ubfx $dst, $src, $mask" %} 9367 ins_encode %{ 9368 int rshift = $rshift$$constant; 9369 long mask = $mask$$constant; 9370 int width = exact_log2(mask+1); 9371 __ ubfx(as_Register($dst$$reg), 9372 as_Register($src$$reg), rshift, width); 9373 %} 9374 ins_pipe(ialu_reg_shift); 9375 %} 9376 9377 // Rotations 9378 9379 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 9380 %{ 9381 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 9382 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 9383 9384 ins_cost(INSN_COST); 9385 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9386 9387 ins_encode %{ 9388 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9389 $rshift$$constant & 63); 9390 %} 9391 ins_pipe(ialu_reg_reg_extr); 9392 %} 9393 9394 instruct extrOrI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr) 9395 %{ 9396 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 9397 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 9398 9399 ins_cost(INSN_COST); 9400 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9401 9402 ins_encode %{ 9403 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9404 $rshift$$constant & 31); 9405 %} 9406 ins_pipe(ialu_reg_reg_extr); 9407 %} 9408 9409 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 9410 %{ 9411 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 9412 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 9413 9414 ins_cost(INSN_COST); 9415 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9416 9417 ins_encode %{ 9418 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9419 $rshift$$constant & 63); 9420 %} 9421 ins_pipe(ialu_reg_reg_extr); 9422 %} 9423 9424 instruct extrAddI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr) 9425 %{ 9426 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 9427 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 9428 9429 ins_cost(INSN_COST); 9430 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9431 9432 ins_encode %{ 9433 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9434 $rshift$$constant & 31); 9435 %} 9436 ins_pipe(ialu_reg_reg_extr); 9437 %} 9438 9439 9440 // rol expander 9441 9442 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 9443 %{ 9444 effect(DEF dst, USE src, USE shift); 9445 9446 format %{ "rol $dst, $src, $shift" %} 9447 ins_cost(INSN_COST * 3); 9448 ins_encode %{ 9449 __ subw(rscratch1, zr, as_Register($shift$$reg)); 9450 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 9451 rscratch1); 9452 %} 9453 ins_pipe(ialu_reg_reg_vshift); 9454 %} 9455 9456 // rol expander 9457 9458 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 9459 %{ 9460 effect(DEF dst, USE src, USE shift); 9461 9462 format %{ "rol $dst, $src, $shift" %} 9463 ins_cost(INSN_COST * 3); 9464 ins_encode %{ 9465 __ subw(rscratch1, zr, as_Register($shift$$reg)); 9466 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 9467 rscratch1); 9468 %} 9469 ins_pipe(ialu_reg_reg_vshift); 9470 %} 9471 9472 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 9473 %{ 9474 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 9475 9476 expand %{ 9477 rolL_rReg(dst, src, shift, cr); 9478 %} 9479 %} 9480 9481 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9482 %{ 9483 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 9484 9485 expand %{ 9486 rolL_rReg(dst, src, shift, cr); 9487 %} 9488 %} 9489 9490 instruct rolI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 9491 %{ 9492 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 9493 9494 expand %{ 9495 rolL_rReg(dst, src, shift, cr); 9496 %} 9497 %} 9498 9499 instruct rolI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9500 %{ 9501 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 9502 9503 expand %{ 9504 rolL_rReg(dst, src, shift, cr); 9505 %} 9506 %} 9507 9508 // ror expander 9509 9510 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 9511 %{ 9512 effect(DEF dst, USE src, USE shift); 9513 9514 format %{ "ror $dst, $src, $shift" %} 9515 ins_cost(INSN_COST); 9516 ins_encode %{ 9517 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 9518 as_Register($shift$$reg)); 9519 %} 9520 ins_pipe(ialu_reg_reg_vshift); 9521 %} 9522 9523 // ror expander 9524 9525 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 9526 %{ 9527 effect(DEF dst, USE src, USE shift); 9528 9529 format %{ "ror $dst, $src, $shift" %} 9530 ins_cost(INSN_COST); 9531 ins_encode %{ 9532 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 9533 as_Register($shift$$reg)); 9534 %} 9535 ins_pipe(ialu_reg_reg_vshift); 9536 %} 9537 9538 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 9539 %{ 9540 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 9541 9542 expand %{ 9543 rorL_rReg(dst, src, shift, cr); 9544 %} 9545 %} 9546 9547 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9548 %{ 9549 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 9550 9551 expand %{ 9552 rorL_rReg(dst, src, shift, cr); 9553 %} 9554 %} 9555 9556 instruct rorI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 9557 %{ 9558 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 9559 9560 expand %{ 9561 rorL_rReg(dst, src, shift, cr); 9562 %} 9563 %} 9564 9565 instruct rorI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9566 %{ 9567 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 9568 9569 expand %{ 9570 rorL_rReg(dst, src, shift, cr); 9571 %} 9572 %} 9573 9574 // Add/subtract (extended) 9575 9576 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 9577 %{ 9578 match(Set dst (AddL src1 (ConvI2L src2))); 9579 ins_cost(INSN_COST); 9580 format %{ "add $dst, $src1, sxtw $src2" %} 9581 9582 ins_encode %{ 9583 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9584 as_Register($src2$$reg), ext::sxtw); 9585 %} 9586 ins_pipe(ialu_reg_reg); 9587 %}; 9588 9589 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 9590 %{ 9591 match(Set dst (SubL src1 (ConvI2L src2))); 9592 ins_cost(INSN_COST); 9593 format %{ "sub $dst, $src1, sxtw $src2" %} 9594 9595 ins_encode %{ 9596 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9597 as_Register($src2$$reg), ext::sxtw); 9598 %} 9599 ins_pipe(ialu_reg_reg); 9600 %}; 9601 9602 9603 instruct AddExtI_sxth(iRegINoSp dst, iRegI src1, iRegI src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 9604 %{ 9605 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 9606 ins_cost(INSN_COST); 9607 format %{ "add $dst, $src1, sxth $src2" %} 9608 9609 ins_encode %{ 9610 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9611 as_Register($src2$$reg), ext::sxth); 9612 %} 9613 ins_pipe(ialu_reg_reg); 9614 %} 9615 9616 instruct AddExtI_sxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 9617 %{ 9618 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 9619 ins_cost(INSN_COST); 9620 format %{ "add $dst, $src1, sxtb $src2" %} 9621 9622 ins_encode %{ 9623 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9624 as_Register($src2$$reg), ext::sxtb); 9625 %} 9626 ins_pipe(ialu_reg_reg); 9627 %} 9628 9629 instruct AddExtI_uxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 9630 %{ 9631 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 9632 ins_cost(INSN_COST); 9633 format %{ "add $dst, $src1, uxtb $src2" %} 9634 9635 ins_encode %{ 9636 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9637 as_Register($src2$$reg), ext::uxtb); 9638 %} 9639 ins_pipe(ialu_reg_reg); 9640 %} 9641 9642 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 9643 %{ 9644 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9645 ins_cost(INSN_COST); 9646 format %{ "add $dst, $src1, sxth $src2" %} 9647 9648 ins_encode %{ 9649 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9650 as_Register($src2$$reg), ext::sxth); 9651 %} 9652 ins_pipe(ialu_reg_reg); 9653 %} 9654 9655 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 9656 %{ 9657 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9658 ins_cost(INSN_COST); 9659 format %{ "add $dst, $src1, sxtw $src2" %} 9660 9661 ins_encode %{ 9662 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9663 as_Register($src2$$reg), ext::sxtw); 9664 %} 9665 ins_pipe(ialu_reg_reg); 9666 %} 9667 9668 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 9669 %{ 9670 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9671 ins_cost(INSN_COST); 9672 format %{ "add $dst, $src1, sxtb $src2" %} 9673 9674 ins_encode %{ 9675 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9676 as_Register($src2$$reg), ext::sxtb); 9677 %} 9678 ins_pipe(ialu_reg_reg); 9679 %} 9680 9681 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 9682 %{ 9683 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 9684 ins_cost(INSN_COST); 9685 format %{ "add $dst, $src1, uxtb $src2" %} 9686 9687 ins_encode %{ 9688 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9689 as_Register($src2$$reg), ext::uxtb); 9690 %} 9691 ins_pipe(ialu_reg_reg); 9692 %} 9693 9694 9695 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr) 9696 %{ 9697 match(Set dst (AddI src1 (AndI src2 mask))); 9698 ins_cost(INSN_COST); 9699 format %{ "addw $dst, $src1, $src2, uxtb" %} 9700 9701 ins_encode %{ 9702 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 9703 as_Register($src2$$reg), ext::uxtb); 9704 %} 9705 ins_pipe(ialu_reg_reg); 9706 %} 9707 9708 instruct AddExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr) 9709 %{ 9710 match(Set dst (AddI src1 (AndI src2 mask))); 9711 ins_cost(INSN_COST); 9712 format %{ "addw $dst, $src1, $src2, uxth" %} 9713 9714 ins_encode %{ 9715 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 9716 as_Register($src2$$reg), ext::uxth); 9717 %} 9718 ins_pipe(ialu_reg_reg); 9719 %} 9720 9721 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 9722 %{ 9723 match(Set dst (AddL src1 (AndL src2 mask))); 9724 ins_cost(INSN_COST); 9725 format %{ "add $dst, $src1, $src2, uxtb" %} 9726 9727 ins_encode %{ 9728 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9729 as_Register($src2$$reg), ext::uxtb); 9730 %} 9731 ins_pipe(ialu_reg_reg); 9732 %} 9733 9734 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 9735 %{ 9736 match(Set dst (AddL src1 (AndL src2 mask))); 9737 ins_cost(INSN_COST); 9738 format %{ "add $dst, $src1, $src2, uxth" %} 9739 9740 ins_encode %{ 9741 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9742 as_Register($src2$$reg), ext::uxth); 9743 %} 9744 ins_pipe(ialu_reg_reg); 9745 %} 9746 9747 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 9748 %{ 9749 match(Set dst (AddL src1 (AndL src2 mask))); 9750 ins_cost(INSN_COST); 9751 format %{ "add $dst, $src1, $src2, uxtw" %} 9752 9753 ins_encode %{ 9754 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9755 as_Register($src2$$reg), ext::uxtw); 9756 %} 9757 ins_pipe(ialu_reg_reg); 9758 %} 9759 9760 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr) 9761 %{ 9762 match(Set dst (SubI src1 (AndI src2 mask))); 9763 ins_cost(INSN_COST); 9764 format %{ "subw $dst, $src1, $src2, uxtb" %} 9765 9766 ins_encode %{ 9767 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 9768 as_Register($src2$$reg), ext::uxtb); 9769 %} 9770 ins_pipe(ialu_reg_reg); 9771 %} 9772 9773 instruct SubExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr) 9774 %{ 9775 match(Set dst (SubI src1 (AndI src2 mask))); 9776 ins_cost(INSN_COST); 9777 format %{ "subw $dst, $src1, $src2, uxth" %} 9778 9779 ins_encode %{ 9780 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 9781 as_Register($src2$$reg), ext::uxth); 9782 %} 9783 ins_pipe(ialu_reg_reg); 9784 %} 9785 9786 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 9787 %{ 9788 match(Set dst (SubL src1 (AndL src2 mask))); 9789 ins_cost(INSN_COST); 9790 format %{ "sub $dst, $src1, $src2, uxtb" %} 9791 9792 ins_encode %{ 9793 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9794 as_Register($src2$$reg), ext::uxtb); 9795 %} 9796 ins_pipe(ialu_reg_reg); 9797 %} 9798 9799 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 9800 %{ 9801 match(Set dst (SubL src1 (AndL src2 mask))); 9802 ins_cost(INSN_COST); 9803 format %{ "sub $dst, $src1, $src2, uxth" %} 9804 9805 ins_encode %{ 9806 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9807 as_Register($src2$$reg), ext::uxth); 9808 %} 9809 ins_pipe(ialu_reg_reg); 9810 %} 9811 9812 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 9813 %{ 9814 match(Set dst (SubL src1 (AndL src2 mask))); 9815 ins_cost(INSN_COST); 9816 format %{ "sub $dst, $src1, $src2, uxtw" %} 9817 9818 ins_encode %{ 9819 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9820 as_Register($src2$$reg), ext::uxtw); 9821 %} 9822 ins_pipe(ialu_reg_reg); 9823 %} 9824 9825 // END This section of the file is automatically generated. Do not edit -------------- 9826 9827 // ============================================================================ 9828 // Floating Point Arithmetic Instructions 9829 9830 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9831 match(Set dst (AddF src1 src2)); 9832 9833 ins_cost(INSN_COST * 5); 9834 format %{ "fadds $dst, $src1, $src2" %} 9835 9836 ins_encode %{ 9837 __ fadds(as_FloatRegister($dst$$reg), 9838 as_FloatRegister($src1$$reg), 9839 as_FloatRegister($src2$$reg)); 9840 %} 9841 9842 ins_pipe(pipe_class_default); 9843 %} 9844 9845 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9846 match(Set dst (AddD src1 src2)); 9847 9848 ins_cost(INSN_COST * 5); 9849 format %{ "faddd $dst, $src1, $src2" %} 9850 9851 ins_encode %{ 9852 __ faddd(as_FloatRegister($dst$$reg), 9853 as_FloatRegister($src1$$reg), 9854 as_FloatRegister($src2$$reg)); 9855 %} 9856 9857 ins_pipe(pipe_class_default); 9858 %} 9859 9860 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9861 match(Set dst (SubF src1 src2)); 9862 9863 ins_cost(INSN_COST * 5); 9864 format %{ "fsubs $dst, $src1, $src2" %} 9865 9866 ins_encode %{ 9867 __ fsubs(as_FloatRegister($dst$$reg), 9868 as_FloatRegister($src1$$reg), 9869 as_FloatRegister($src2$$reg)); 9870 %} 9871 9872 ins_pipe(pipe_class_default); 9873 %} 9874 9875 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9876 match(Set dst (SubD src1 src2)); 9877 9878 ins_cost(INSN_COST * 5); 9879 format %{ "fsubd $dst, $src1, $src2" %} 9880 9881 ins_encode %{ 9882 __ fsubd(as_FloatRegister($dst$$reg), 9883 as_FloatRegister($src1$$reg), 9884 as_FloatRegister($src2$$reg)); 9885 %} 9886 9887 ins_pipe(pipe_class_default); 9888 %} 9889 9890 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9891 match(Set dst (MulF src1 src2)); 9892 9893 ins_cost(INSN_COST * 6); 9894 format %{ "fmuls $dst, $src1, $src2" %} 9895 9896 ins_encode %{ 9897 __ fmuls(as_FloatRegister($dst$$reg), 9898 as_FloatRegister($src1$$reg), 9899 as_FloatRegister($src2$$reg)); 9900 %} 9901 9902 ins_pipe(pipe_class_default); 9903 %} 9904 9905 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9906 match(Set dst (MulD src1 src2)); 9907 9908 ins_cost(INSN_COST * 6); 9909 format %{ "fmuld $dst, $src1, $src2" %} 9910 9911 ins_encode %{ 9912 __ fmuld(as_FloatRegister($dst$$reg), 9913 as_FloatRegister($src1$$reg), 9914 as_FloatRegister($src2$$reg)); 9915 %} 9916 9917 ins_pipe(pipe_class_default); 9918 %} 9919 9920 // We cannot use these fused mul w add/sub ops because they don't 9921 // produce the same result as the equivalent separated ops 9922 // (essentially they don't round the intermediate result). that's a 9923 // shame. leaving them here in case we can idenitfy cases where it is 9924 // legitimate to use them 9925 9926 9927 // instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 9928 // match(Set dst (AddF (MulF src1 src2) src3)); 9929 9930 // format %{ "fmadds $dst, $src1, $src2, $src3" %} 9931 9932 // ins_encode %{ 9933 // __ fmadds(as_FloatRegister($dst$$reg), 9934 // as_FloatRegister($src1$$reg), 9935 // as_FloatRegister($src2$$reg), 9936 // as_FloatRegister($src3$$reg)); 9937 // %} 9938 9939 // ins_pipe(pipe_class_default); 9940 // %} 9941 9942 // instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 9943 // match(Set dst (AddD (MulD src1 src2) src3)); 9944 9945 // format %{ "fmaddd $dst, $src1, $src2, $src3" %} 9946 9947 // ins_encode %{ 9948 // __ fmaddd(as_FloatRegister($dst$$reg), 9949 // as_FloatRegister($src1$$reg), 9950 // as_FloatRegister($src2$$reg), 9951 // as_FloatRegister($src3$$reg)); 9952 // %} 9953 9954 // ins_pipe(pipe_class_default); 9955 // %} 9956 9957 // instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 9958 // match(Set dst (AddF (MulF (NegF src1) src2) src3)); 9959 // match(Set dst (AddF (NegF (MulF src1 src2)) src3)); 9960 9961 // format %{ "fmsubs $dst, $src1, $src2, $src3" %} 9962 9963 // ins_encode %{ 9964 // __ fmsubs(as_FloatRegister($dst$$reg), 9965 // as_FloatRegister($src1$$reg), 9966 // as_FloatRegister($src2$$reg), 9967 // as_FloatRegister($src3$$reg)); 9968 // %} 9969 9970 // ins_pipe(pipe_class_default); 9971 // %} 9972 9973 // instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 9974 // match(Set dst (AddD (MulD (NegD src1) src2) src3)); 9975 // match(Set dst (AddD (NegD (MulD src1 src2)) src3)); 9976 9977 // format %{ "fmsubd $dst, $src1, $src2, $src3" %} 9978 9979 // ins_encode %{ 9980 // __ fmsubd(as_FloatRegister($dst$$reg), 9981 // as_FloatRegister($src1$$reg), 9982 // as_FloatRegister($src2$$reg), 9983 // as_FloatRegister($src3$$reg)); 9984 // %} 9985 9986 // ins_pipe(pipe_class_default); 9987 // %} 9988 9989 // instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 9990 // match(Set dst (SubF (MulF (NegF src1) src2) src3)); 9991 // match(Set dst (SubF (NegF (MulF src1 src2)) src3)); 9992 9993 // format %{ "fnmadds $dst, $src1, $src2, $src3" %} 9994 9995 // ins_encode %{ 9996 // __ fnmadds(as_FloatRegister($dst$$reg), 9997 // as_FloatRegister($src1$$reg), 9998 // as_FloatRegister($src2$$reg), 9999 // as_FloatRegister($src3$$reg)); 10000 // %} 10001 10002 // ins_pipe(pipe_class_default); 10003 // %} 10004 10005 // instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10006 // match(Set dst (SubD (MulD (NegD src1) src2) src3)); 10007 // match(Set dst (SubD (NegD (MulD src1 src2)) src3)); 10008 10009 // format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 10010 10011 // ins_encode %{ 10012 // __ fnmaddd(as_FloatRegister($dst$$reg), 10013 // as_FloatRegister($src1$$reg), 10014 // as_FloatRegister($src2$$reg), 10015 // as_FloatRegister($src3$$reg)); 10016 // %} 10017 10018 // ins_pipe(pipe_class_default); 10019 // %} 10020 10021 // instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 10022 // match(Set dst (SubF (MulF src1 src2) src3)); 10023 10024 // format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 10025 10026 // ins_encode %{ 10027 // __ fnmsubs(as_FloatRegister($dst$$reg), 10028 // as_FloatRegister($src1$$reg), 10029 // as_FloatRegister($src2$$reg), 10030 // as_FloatRegister($src3$$reg)); 10031 // %} 10032 10033 // ins_pipe(pipe_class_default); 10034 // %} 10035 10036 // instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 10037 // match(Set dst (SubD (MulD src1 src2) src3)); 10038 10039 // format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 10040 10041 // ins_encode %{ 10042 // // n.b. insn name should be fnmsubd 10043 // __ fnmsub(as_FloatRegister($dst$$reg), 10044 // as_FloatRegister($src1$$reg), 10045 // as_FloatRegister($src2$$reg), 10046 // as_FloatRegister($src3$$reg)); 10047 // %} 10048 10049 // ins_pipe(pipe_class_default); 10050 // %} 10051 10052 10053 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10054 match(Set dst (DivF src1 src2)); 10055 10056 ins_cost(INSN_COST * 18); 10057 format %{ "fdivs $dst, $src1, $src2" %} 10058 10059 ins_encode %{ 10060 __ fdivs(as_FloatRegister($dst$$reg), 10061 as_FloatRegister($src1$$reg), 10062 as_FloatRegister($src2$$reg)); 10063 %} 10064 10065 ins_pipe(pipe_class_default); 10066 %} 10067 10068 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10069 match(Set dst (DivD src1 src2)); 10070 10071 ins_cost(INSN_COST * 32); 10072 format %{ "fdivd $dst, $src1, $src2" %} 10073 10074 ins_encode %{ 10075 __ fdivd(as_FloatRegister($dst$$reg), 10076 as_FloatRegister($src1$$reg), 10077 as_FloatRegister($src2$$reg)); 10078 %} 10079 10080 ins_pipe(pipe_class_default); 10081 %} 10082 10083 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 10084 match(Set dst (NegF src)); 10085 10086 ins_cost(INSN_COST * 3); 10087 format %{ "fneg $dst, $src" %} 10088 10089 ins_encode %{ 10090 __ fnegs(as_FloatRegister($dst$$reg), 10091 as_FloatRegister($src$$reg)); 10092 %} 10093 10094 ins_pipe(pipe_class_default); 10095 %} 10096 10097 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 10098 match(Set dst (NegD src)); 10099 10100 ins_cost(INSN_COST * 3); 10101 format %{ "fnegd $dst, $src" %} 10102 10103 ins_encode %{ 10104 __ fnegd(as_FloatRegister($dst$$reg), 10105 as_FloatRegister($src$$reg)); 10106 %} 10107 10108 ins_pipe(pipe_class_default); 10109 %} 10110 10111 instruct absF_reg(vRegF dst, vRegF src) %{ 10112 match(Set dst (AbsF src)); 10113 10114 ins_cost(INSN_COST * 3); 10115 format %{ "fabss $dst, $src" %} 10116 ins_encode %{ 10117 __ fabss(as_FloatRegister($dst$$reg), 10118 as_FloatRegister($src$$reg)); 10119 %} 10120 10121 ins_pipe(pipe_class_default); 10122 %} 10123 10124 instruct absD_reg(vRegD dst, vRegD src) %{ 10125 match(Set dst (AbsD src)); 10126 10127 ins_cost(INSN_COST * 3); 10128 format %{ "fabsd $dst, $src" %} 10129 ins_encode %{ 10130 __ fabsd(as_FloatRegister($dst$$reg), 10131 as_FloatRegister($src$$reg)); 10132 %} 10133 10134 ins_pipe(pipe_class_default); 10135 %} 10136 10137 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 10138 match(Set dst (SqrtD src)); 10139 10140 ins_cost(INSN_COST * 50); 10141 format %{ "fsqrtd $dst, $src" %} 10142 ins_encode %{ 10143 __ fsqrtd(as_FloatRegister($dst$$reg), 10144 as_FloatRegister($src$$reg)); 10145 %} 10146 10147 ins_pipe(pipe_class_default); 10148 %} 10149 10150 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 10151 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10152 10153 ins_cost(INSN_COST * 50); 10154 format %{ "fsqrts $dst, $src" %} 10155 ins_encode %{ 10156 __ fsqrts(as_FloatRegister($dst$$reg), 10157 as_FloatRegister($src$$reg)); 10158 %} 10159 10160 ins_pipe(pipe_class_default); 10161 %} 10162 10163 // ============================================================================ 10164 // Logical Instructions 10165 10166 // Integer Logical Instructions 10167 10168 // And Instructions 10169 10170 10171 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 10172 match(Set dst (AndI src1 src2)); 10173 10174 format %{ "andw $dst, $src1, $src2\t# int" %} 10175 10176 ins_cost(INSN_COST); 10177 ins_encode %{ 10178 __ andw(as_Register($dst$$reg), 10179 as_Register($src1$$reg), 10180 as_Register($src2$$reg)); 10181 %} 10182 10183 ins_pipe(ialu_reg_reg); 10184 %} 10185 10186 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 10187 match(Set dst (AndI src1 src2)); 10188 10189 format %{ "andsw $dst, $src1, $src2\t# int" %} 10190 10191 ins_cost(INSN_COST); 10192 ins_encode %{ 10193 __ andw(as_Register($dst$$reg), 10194 as_Register($src1$$reg), 10195 (unsigned long)($src2$$constant)); 10196 %} 10197 10198 ins_pipe(ialu_reg_imm); 10199 %} 10200 10201 // Or Instructions 10202 10203 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10204 match(Set dst (OrI src1 src2)); 10205 10206 format %{ "orrw $dst, $src1, $src2\t# int" %} 10207 10208 ins_cost(INSN_COST); 10209 ins_encode %{ 10210 __ orrw(as_Register($dst$$reg), 10211 as_Register($src1$$reg), 10212 as_Register($src2$$reg)); 10213 %} 10214 10215 ins_pipe(ialu_reg_reg); 10216 %} 10217 10218 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 10219 match(Set dst (OrI src1 src2)); 10220 10221 format %{ "orrw $dst, $src1, $src2\t# int" %} 10222 10223 ins_cost(INSN_COST); 10224 ins_encode %{ 10225 __ orrw(as_Register($dst$$reg), 10226 as_Register($src1$$reg), 10227 (unsigned long)($src2$$constant)); 10228 %} 10229 10230 ins_pipe(ialu_reg_imm); 10231 %} 10232 10233 // Xor Instructions 10234 10235 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10236 match(Set dst (XorI src1 src2)); 10237 10238 format %{ "eorw $dst, $src1, $src2\t# int" %} 10239 10240 ins_cost(INSN_COST); 10241 ins_encode %{ 10242 __ eorw(as_Register($dst$$reg), 10243 as_Register($src1$$reg), 10244 as_Register($src2$$reg)); 10245 %} 10246 10247 ins_pipe(ialu_reg_reg); 10248 %} 10249 10250 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 10251 match(Set dst (XorI src1 src2)); 10252 10253 format %{ "eorw $dst, $src1, $src2\t# int" %} 10254 10255 ins_cost(INSN_COST); 10256 ins_encode %{ 10257 __ eorw(as_Register($dst$$reg), 10258 as_Register($src1$$reg), 10259 (unsigned long)($src2$$constant)); 10260 %} 10261 10262 ins_pipe(ialu_reg_imm); 10263 %} 10264 10265 // Long Logical Instructions 10266 // TODO 10267 10268 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 10269 match(Set dst (AndL src1 src2)); 10270 10271 format %{ "and $dst, $src1, $src2\t# int" %} 10272 10273 ins_cost(INSN_COST); 10274 ins_encode %{ 10275 __ andr(as_Register($dst$$reg), 10276 as_Register($src1$$reg), 10277 as_Register($src2$$reg)); 10278 %} 10279 10280 ins_pipe(ialu_reg_reg); 10281 %} 10282 10283 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 10284 match(Set dst (AndL src1 src2)); 10285 10286 format %{ "and $dst, $src1, $src2\t# int" %} 10287 10288 ins_cost(INSN_COST); 10289 ins_encode %{ 10290 __ andr(as_Register($dst$$reg), 10291 as_Register($src1$$reg), 10292 (unsigned long)($src2$$constant)); 10293 %} 10294 10295 ins_pipe(ialu_reg_imm); 10296 %} 10297 10298 // Or Instructions 10299 10300 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10301 match(Set dst (OrL src1 src2)); 10302 10303 format %{ "orr $dst, $src1, $src2\t# int" %} 10304 10305 ins_cost(INSN_COST); 10306 ins_encode %{ 10307 __ orr(as_Register($dst$$reg), 10308 as_Register($src1$$reg), 10309 as_Register($src2$$reg)); 10310 %} 10311 10312 ins_pipe(ialu_reg_reg); 10313 %} 10314 10315 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 10316 match(Set dst (OrL src1 src2)); 10317 10318 format %{ "orr $dst, $src1, $src2\t# int" %} 10319 10320 ins_cost(INSN_COST); 10321 ins_encode %{ 10322 __ orr(as_Register($dst$$reg), 10323 as_Register($src1$$reg), 10324 (unsigned long)($src2$$constant)); 10325 %} 10326 10327 ins_pipe(ialu_reg_imm); 10328 %} 10329 10330 // Xor Instructions 10331 10332 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10333 match(Set dst (XorL src1 src2)); 10334 10335 format %{ "eor $dst, $src1, $src2\t# int" %} 10336 10337 ins_cost(INSN_COST); 10338 ins_encode %{ 10339 __ eor(as_Register($dst$$reg), 10340 as_Register($src1$$reg), 10341 as_Register($src2$$reg)); 10342 %} 10343 10344 ins_pipe(ialu_reg_reg); 10345 %} 10346 10347 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 10348 match(Set dst (XorL src1 src2)); 10349 10350 ins_cost(INSN_COST); 10351 format %{ "eor $dst, $src1, $src2\t# int" %} 10352 10353 ins_encode %{ 10354 __ eor(as_Register($dst$$reg), 10355 as_Register($src1$$reg), 10356 (unsigned long)($src2$$constant)); 10357 %} 10358 10359 ins_pipe(ialu_reg_imm); 10360 %} 10361 10362 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 10363 %{ 10364 match(Set dst (ConvI2L src)); 10365 10366 ins_cost(INSN_COST); 10367 format %{ "sxtw $dst, $src\t# i2l" %} 10368 ins_encode %{ 10369 __ sbfm($dst$$Register, $src$$Register, 0, 31); 10370 %} 10371 ins_pipe(ialu_reg_shift); 10372 %} 10373 10374 // this pattern occurs in bigmath arithmetic 10375 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegI src, immL_32bits mask) 10376 %{ 10377 match(Set dst (AndL (ConvI2L src) mask)); 10378 10379 ins_cost(INSN_COST); 10380 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 10381 ins_encode %{ 10382 __ ubfm($dst$$Register, $src$$Register, 0, 31); 10383 %} 10384 10385 ins_pipe(ialu_reg_shift); 10386 %} 10387 10388 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 10389 match(Set dst (ConvL2I src)); 10390 10391 ins_cost(INSN_COST); 10392 format %{ "movw $dst, $src \t// l2i" %} 10393 10394 ins_encode %{ 10395 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 10396 %} 10397 10398 ins_pipe(ialu_reg); 10399 %} 10400 10401 instruct convI2B(iRegINoSp dst, iRegI src, rFlagsReg cr) 10402 %{ 10403 match(Set dst (Conv2B src)); 10404 effect(KILL cr); 10405 10406 format %{ 10407 "cmpw $src, zr\n\t" 10408 "cset $dst, ne" 10409 %} 10410 10411 ins_encode %{ 10412 __ cmpw(as_Register($src$$reg), zr); 10413 __ cset(as_Register($dst$$reg), Assembler::NE); 10414 %} 10415 10416 ins_pipe(ialu_reg); 10417 %} 10418 10419 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 10420 %{ 10421 match(Set dst (Conv2B src)); 10422 effect(KILL cr); 10423 10424 format %{ 10425 "cmp $src, zr\n\t" 10426 "cset $dst, ne" 10427 %} 10428 10429 ins_encode %{ 10430 __ cmp(as_Register($src$$reg), zr); 10431 __ cset(as_Register($dst$$reg), Assembler::NE); 10432 %} 10433 10434 ins_pipe(ialu_reg); 10435 %} 10436 10437 instruct convD2F_reg(vRegF dst, vRegD src) %{ 10438 match(Set dst (ConvD2F src)); 10439 10440 ins_cost(INSN_COST * 5); 10441 format %{ "fcvtd $dst, $src \t// d2f" %} 10442 10443 ins_encode %{ 10444 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 10445 %} 10446 10447 ins_pipe(pipe_class_default); 10448 %} 10449 10450 instruct convF2D_reg(vRegD dst, vRegF src) %{ 10451 match(Set dst (ConvF2D src)); 10452 10453 ins_cost(INSN_COST * 5); 10454 format %{ "fcvts $dst, $src \t// f2d" %} 10455 10456 ins_encode %{ 10457 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 10458 %} 10459 10460 ins_pipe(pipe_class_default); 10461 %} 10462 10463 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 10464 match(Set dst (ConvF2I src)); 10465 10466 ins_cost(INSN_COST * 5); 10467 format %{ "fcvtzsw $dst, $src \t// f2i" %} 10468 10469 ins_encode %{ 10470 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10471 %} 10472 10473 ins_pipe(pipe_class_default); 10474 %} 10475 10476 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 10477 match(Set dst (ConvF2L src)); 10478 10479 ins_cost(INSN_COST * 5); 10480 format %{ "fcvtzs $dst, $src \t// f2l" %} 10481 10482 ins_encode %{ 10483 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10484 %} 10485 10486 ins_pipe(pipe_class_default); 10487 %} 10488 10489 instruct convI2F_reg_reg(vRegF dst, iRegI src) %{ 10490 match(Set dst (ConvI2F src)); 10491 10492 ins_cost(INSN_COST * 5); 10493 format %{ "scvtfws $dst, $src \t// i2f" %} 10494 10495 ins_encode %{ 10496 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10497 %} 10498 10499 ins_pipe(pipe_class_default); 10500 %} 10501 10502 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 10503 match(Set dst (ConvL2F src)); 10504 10505 ins_cost(INSN_COST * 5); 10506 format %{ "scvtfs $dst, $src \t// l2f" %} 10507 10508 ins_encode %{ 10509 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10510 %} 10511 10512 ins_pipe(pipe_class_default); 10513 %} 10514 10515 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 10516 match(Set dst (ConvD2I src)); 10517 10518 ins_cost(INSN_COST * 5); 10519 format %{ "fcvtzdw $dst, $src \t// d2i" %} 10520 10521 ins_encode %{ 10522 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10523 %} 10524 10525 ins_pipe(pipe_class_default); 10526 %} 10527 10528 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 10529 match(Set dst (ConvD2L src)); 10530 10531 ins_cost(INSN_COST * 5); 10532 format %{ "fcvtzd $dst, $src \t// d2l" %} 10533 10534 ins_encode %{ 10535 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10536 %} 10537 10538 ins_pipe(pipe_class_default); 10539 %} 10540 10541 instruct convI2D_reg_reg(vRegD dst, iRegI src) %{ 10542 match(Set dst (ConvI2D src)); 10543 10544 ins_cost(INSN_COST * 5); 10545 format %{ "scvtfwd $dst, $src \t// i2d" %} 10546 10547 ins_encode %{ 10548 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10549 %} 10550 10551 ins_pipe(pipe_class_default); 10552 %} 10553 10554 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 10555 match(Set dst (ConvL2D src)); 10556 10557 ins_cost(INSN_COST * 5); 10558 format %{ "scvtfd $dst, $src \t// l2d" %} 10559 10560 ins_encode %{ 10561 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10562 %} 10563 10564 ins_pipe(pipe_class_default); 10565 %} 10566 10567 // stack <-> reg and reg <-> reg shuffles with no conversion 10568 10569 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 10570 10571 match(Set dst (MoveF2I src)); 10572 10573 effect(DEF dst, USE src); 10574 10575 ins_cost(4 * INSN_COST); 10576 10577 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 10578 10579 ins_encode %{ 10580 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 10581 %} 10582 10583 ins_pipe(iload_reg_reg); 10584 10585 %} 10586 10587 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 10588 10589 match(Set dst (MoveI2F src)); 10590 10591 effect(DEF dst, USE src); 10592 10593 ins_cost(4 * INSN_COST); 10594 10595 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 10596 10597 ins_encode %{ 10598 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 10599 %} 10600 10601 ins_pipe(pipe_class_memory); 10602 10603 %} 10604 10605 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 10606 10607 match(Set dst (MoveD2L src)); 10608 10609 effect(DEF dst, USE src); 10610 10611 ins_cost(4 * INSN_COST); 10612 10613 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 10614 10615 ins_encode %{ 10616 __ ldr($dst$$Register, Address(sp, $src$$disp)); 10617 %} 10618 10619 ins_pipe(iload_reg_reg); 10620 10621 %} 10622 10623 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 10624 10625 match(Set dst (MoveL2D src)); 10626 10627 effect(DEF dst, USE src); 10628 10629 ins_cost(4 * INSN_COST); 10630 10631 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 10632 10633 ins_encode %{ 10634 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 10635 %} 10636 10637 ins_pipe(pipe_class_memory); 10638 10639 %} 10640 10641 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 10642 10643 match(Set dst (MoveF2I src)); 10644 10645 effect(DEF dst, USE src); 10646 10647 ins_cost(INSN_COST); 10648 10649 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 10650 10651 ins_encode %{ 10652 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 10653 %} 10654 10655 ins_pipe(pipe_class_memory); 10656 10657 %} 10658 10659 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 10660 10661 match(Set dst (MoveI2F src)); 10662 10663 effect(DEF dst, USE src); 10664 10665 ins_cost(INSN_COST); 10666 10667 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 10668 10669 ins_encode %{ 10670 __ strw($src$$Register, Address(sp, $dst$$disp)); 10671 %} 10672 10673 ins_pipe(istore_reg_reg); 10674 10675 %} 10676 10677 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 10678 10679 match(Set dst (MoveD2L src)); 10680 10681 effect(DEF dst, USE src); 10682 10683 ins_cost(INSN_COST); 10684 10685 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 10686 10687 ins_encode %{ 10688 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 10689 %} 10690 10691 ins_pipe(pipe_class_memory); 10692 10693 %} 10694 10695 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 10696 10697 match(Set dst (MoveL2D src)); 10698 10699 effect(DEF dst, USE src); 10700 10701 ins_cost(INSN_COST); 10702 10703 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 10704 10705 ins_encode %{ 10706 __ str($src$$Register, Address(sp, $dst$$disp)); 10707 %} 10708 10709 ins_pipe(istore_reg_reg); 10710 10711 %} 10712 10713 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 10714 10715 match(Set dst (MoveF2I src)); 10716 10717 effect(DEF dst, USE src); 10718 10719 ins_cost(INSN_COST); 10720 10721 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 10722 10723 ins_encode %{ 10724 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 10725 %} 10726 10727 ins_pipe(pipe_class_memory); 10728 10729 %} 10730 10731 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 10732 10733 match(Set dst (MoveI2F src)); 10734 10735 effect(DEF dst, USE src); 10736 10737 ins_cost(INSN_COST); 10738 10739 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 10740 10741 ins_encode %{ 10742 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 10743 %} 10744 10745 ins_pipe(pipe_class_memory); 10746 10747 %} 10748 10749 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 10750 10751 match(Set dst (MoveD2L src)); 10752 10753 effect(DEF dst, USE src); 10754 10755 ins_cost(INSN_COST); 10756 10757 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 10758 10759 ins_encode %{ 10760 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 10761 %} 10762 10763 ins_pipe(pipe_class_memory); 10764 10765 %} 10766 10767 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 10768 10769 match(Set dst (MoveL2D src)); 10770 10771 effect(DEF dst, USE src); 10772 10773 ins_cost(INSN_COST); 10774 10775 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 10776 10777 ins_encode %{ 10778 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 10779 %} 10780 10781 ins_pipe(pipe_class_memory); 10782 10783 %} 10784 10785 // ============================================================================ 10786 // clearing of an array 10787 10788 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 10789 %{ 10790 match(Set dummy (ClearArray cnt base)); 10791 effect(USE_KILL cnt, USE_KILL base); 10792 10793 ins_cost(4 * INSN_COST); 10794 format %{ "ClearArray $cnt, $base" %} 10795 10796 ins_encode(aarch64_enc_clear_array_reg_reg(cnt, base)); 10797 10798 ins_pipe(pipe_class_memory); 10799 %} 10800 10801 // ============================================================================ 10802 // Overflow Math Instructions 10803 10804 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10805 %{ 10806 match(Set cr (OverflowAddI op1 op2)); 10807 10808 format %{ "cmnw $op1, $op2\t# overflow check int" %} 10809 ins_cost(INSN_COST); 10810 ins_encode %{ 10811 __ cmnw($op1$$Register, $op2$$Register); 10812 %} 10813 10814 ins_pipe(icmp_reg_reg); 10815 %} 10816 10817 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2) 10818 %{ 10819 match(Set cr (OverflowAddI op1 op2)); 10820 10821 format %{ "cmnw $op1, $op2\t# overflow check int" %} 10822 ins_cost(INSN_COST); 10823 ins_encode %{ 10824 __ cmnw($op1$$Register, $op2$$constant); 10825 %} 10826 10827 ins_pipe(icmp_reg_imm); 10828 %} 10829 10830 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 10831 %{ 10832 match(Set cr (OverflowAddL op1 op2)); 10833 10834 format %{ "cmn $op1, $op2\t# overflow check long" %} 10835 ins_cost(INSN_COST); 10836 ins_encode %{ 10837 __ cmn($op1$$Register, $op2$$Register); 10838 %} 10839 10840 ins_pipe(icmp_reg_reg); 10841 %} 10842 10843 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 10844 %{ 10845 match(Set cr (OverflowAddL op1 op2)); 10846 10847 format %{ "cmn $op1, $op2\t# overflow check long" %} 10848 ins_cost(INSN_COST); 10849 ins_encode %{ 10850 __ cmn($op1$$Register, $op2$$constant); 10851 %} 10852 10853 ins_pipe(icmp_reg_imm); 10854 %} 10855 10856 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10857 %{ 10858 match(Set cr (OverflowSubI op1 op2)); 10859 10860 format %{ "cmpw $op1, $op2\t# overflow check int" %} 10861 ins_cost(INSN_COST); 10862 ins_encode %{ 10863 __ cmpw($op1$$Register, $op2$$Register); 10864 %} 10865 10866 ins_pipe(icmp_reg_reg); 10867 %} 10868 10869 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2) 10870 %{ 10871 match(Set cr (OverflowSubI op1 op2)); 10872 10873 format %{ "cmpw $op1, $op2\t# overflow check int" %} 10874 ins_cost(INSN_COST); 10875 ins_encode %{ 10876 __ cmpw($op1$$Register, $op2$$constant); 10877 %} 10878 10879 ins_pipe(icmp_reg_imm); 10880 %} 10881 10882 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 10883 %{ 10884 match(Set cr (OverflowSubL op1 op2)); 10885 10886 format %{ "cmp $op1, $op2\t# overflow check long" %} 10887 ins_cost(INSN_COST); 10888 ins_encode %{ 10889 __ cmp($op1$$Register, $op2$$Register); 10890 %} 10891 10892 ins_pipe(icmp_reg_reg); 10893 %} 10894 10895 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 10896 %{ 10897 match(Set cr (OverflowSubL op1 op2)); 10898 10899 format %{ "cmp $op1, $op2\t# overflow check long" %} 10900 ins_cost(INSN_COST); 10901 ins_encode %{ 10902 __ cmp($op1$$Register, $op2$$constant); 10903 %} 10904 10905 ins_pipe(icmp_reg_imm); 10906 %} 10907 10908 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegI op1) 10909 %{ 10910 match(Set cr (OverflowSubI zero op1)); 10911 10912 format %{ "cmpw zr, $op1\t# overflow check int" %} 10913 ins_cost(INSN_COST); 10914 ins_encode %{ 10915 __ cmpw(zr, $op1$$Register); 10916 %} 10917 10918 ins_pipe(icmp_reg_imm); 10919 %} 10920 10921 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 10922 %{ 10923 match(Set cr (OverflowSubL zero op1)); 10924 10925 format %{ "cmp zr, $op1\t# overflow check long" %} 10926 ins_cost(INSN_COST); 10927 ins_encode %{ 10928 __ cmp(zr, $op1$$Register); 10929 %} 10930 10931 ins_pipe(icmp_reg_imm); 10932 %} 10933 10934 instruct overflowMulI_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10935 %{ 10936 match(Set cr (OverflowMulI op1 op2)); 10937 10938 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 10939 "cmp rscratch1, rscratch1, sxtw\n\t" 10940 "movw rscratch1, #0x80000000\n\t" 10941 "cselw rscratch1, rscratch1, zr, NE\n\t" 10942 "cmpw rscratch1, #1" %} 10943 ins_cost(5 * INSN_COST); 10944 ins_encode %{ 10945 __ smull(rscratch1, $op1$$Register, $op2$$Register); 10946 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 10947 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 10948 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 10949 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 10950 %} 10951 10952 ins_pipe(pipe_slow); 10953 %} 10954 10955 instruct overflowMulI_reg_branch(cmpOp cmp, iRegI op1, iRegI op2, label labl, rFlagsReg cr) 10956 %{ 10957 match(If cmp (OverflowMulI op1 op2)); 10958 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 10959 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 10960 effect(USE labl, KILL cr); 10961 10962 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 10963 "cmp rscratch1, rscratch1, sxtw\n\t" 10964 "b$cmp $labl" %} 10965 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 10966 ins_encode %{ 10967 Label* L = $labl$$label; 10968 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10969 __ smull(rscratch1, $op1$$Register, $op2$$Register); 10970 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 10971 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 10972 %} 10973 10974 ins_pipe(pipe_serial); 10975 %} 10976 10977 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 10978 %{ 10979 match(Set cr (OverflowMulL op1 op2)); 10980 10981 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 10982 "smulh rscratch2, $op1, $op2\n\t" 10983 "cmp rscratch2, rscratch1, ASR #31\n\t" 10984 "movw rscratch1, #0x80000000\n\t" 10985 "cselw rscratch1, rscratch1, zr, NE\n\t" 10986 "cmpw rscratch1, #1" %} 10987 ins_cost(6 * INSN_COST); 10988 ins_encode %{ 10989 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 10990 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 10991 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 10992 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 10993 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 10994 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 10995 %} 10996 10997 ins_pipe(pipe_slow); 10998 %} 10999 11000 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 11001 %{ 11002 match(If cmp (OverflowMulL op1 op2)); 11003 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11004 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11005 effect(USE labl, KILL cr); 11006 11007 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11008 "smulh rscratch2, $op1, $op2\n\t" 11009 "cmp rscratch2, rscratch1, ASR #31\n\t" 11010 "b$cmp $labl" %} 11011 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 11012 ins_encode %{ 11013 Label* L = $labl$$label; 11014 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11015 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11016 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11017 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11018 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11019 %} 11020 11021 ins_pipe(pipe_serial); 11022 %} 11023 11024 // ============================================================================ 11025 // Compare Instructions 11026 11027 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 11028 %{ 11029 match(Set cr (CmpI op1 op2)); 11030 11031 effect(DEF cr, USE op1, USE op2); 11032 11033 ins_cost(INSN_COST); 11034 format %{ "cmpw $op1, $op2" %} 11035 11036 ins_encode(aarch64_enc_cmpw(op1, op2)); 11037 11038 ins_pipe(icmp_reg_reg); 11039 %} 11040 11041 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 11042 %{ 11043 match(Set cr (CmpI op1 zero)); 11044 11045 effect(DEF cr, USE op1); 11046 11047 ins_cost(INSN_COST); 11048 format %{ "cmpw $op1, 0" %} 11049 11050 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11051 11052 ins_pipe(icmp_reg_imm); 11053 %} 11054 11055 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 11056 %{ 11057 match(Set cr (CmpI op1 op2)); 11058 11059 effect(DEF cr, USE op1); 11060 11061 ins_cost(INSN_COST); 11062 format %{ "cmpw $op1, $op2" %} 11063 11064 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11065 11066 ins_pipe(icmp_reg_imm); 11067 %} 11068 11069 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 11070 %{ 11071 match(Set cr (CmpI op1 op2)); 11072 11073 effect(DEF cr, USE op1); 11074 11075 ins_cost(INSN_COST * 2); 11076 format %{ "cmpw $op1, $op2" %} 11077 11078 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11079 11080 ins_pipe(icmp_reg_imm); 11081 %} 11082 11083 // Unsigned compare Instructions; really, same as signed compare 11084 // except it should only be used to feed an If or a CMovI which takes a 11085 // cmpOpU. 11086 11087 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 11088 %{ 11089 match(Set cr (CmpU op1 op2)); 11090 11091 effect(DEF cr, USE op1, USE op2); 11092 11093 ins_cost(INSN_COST); 11094 format %{ "cmpw $op1, $op2\t# unsigned" %} 11095 11096 ins_encode(aarch64_enc_cmpw(op1, op2)); 11097 11098 ins_pipe(icmp_reg_reg); 11099 %} 11100 11101 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 11102 %{ 11103 match(Set cr (CmpU op1 zero)); 11104 11105 effect(DEF cr, USE op1); 11106 11107 ins_cost(INSN_COST); 11108 format %{ "cmpw $op1, #0\t# unsigned" %} 11109 11110 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11111 11112 ins_pipe(icmp_reg_imm); 11113 %} 11114 11115 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 11116 %{ 11117 match(Set cr (CmpU op1 op2)); 11118 11119 effect(DEF cr, USE op1); 11120 11121 ins_cost(INSN_COST); 11122 format %{ "cmpw $op1, $op2\t# unsigned" %} 11123 11124 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11125 11126 ins_pipe(icmp_reg_imm); 11127 %} 11128 11129 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 11130 %{ 11131 match(Set cr (CmpU op1 op2)); 11132 11133 effect(DEF cr, USE op1); 11134 11135 ins_cost(INSN_COST * 2); 11136 format %{ "cmpw $op1, $op2\t# unsigned" %} 11137 11138 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11139 11140 ins_pipe(icmp_reg_imm); 11141 %} 11142 11143 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11144 %{ 11145 match(Set cr (CmpL op1 op2)); 11146 11147 effect(DEF cr, USE op1, USE op2); 11148 11149 ins_cost(INSN_COST); 11150 format %{ "cmp $op1, $op2" %} 11151 11152 ins_encode(aarch64_enc_cmp(op1, op2)); 11153 11154 ins_pipe(icmp_reg_reg); 11155 %} 11156 11157 instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) 11158 %{ 11159 match(Set cr (CmpL op1 zero)); 11160 11161 effect(DEF cr, USE op1); 11162 11163 ins_cost(INSN_COST); 11164 format %{ "tst $op1" %} 11165 11166 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 11167 11168 ins_pipe(icmp_reg_imm); 11169 %} 11170 11171 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 11172 %{ 11173 match(Set cr (CmpL op1 op2)); 11174 11175 effect(DEF cr, USE op1); 11176 11177 ins_cost(INSN_COST); 11178 format %{ "cmp $op1, $op2" %} 11179 11180 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 11181 11182 ins_pipe(icmp_reg_imm); 11183 %} 11184 11185 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 11186 %{ 11187 match(Set cr (CmpL op1 op2)); 11188 11189 effect(DEF cr, USE op1); 11190 11191 ins_cost(INSN_COST * 2); 11192 format %{ "cmp $op1, $op2" %} 11193 11194 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 11195 11196 ins_pipe(icmp_reg_imm); 11197 %} 11198 11199 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 11200 %{ 11201 match(Set cr (CmpP op1 op2)); 11202 11203 effect(DEF cr, USE op1, USE op2); 11204 11205 ins_cost(INSN_COST); 11206 format %{ "cmp $op1, $op2\t // ptr" %} 11207 11208 ins_encode(aarch64_enc_cmpp(op1, op2)); 11209 11210 ins_pipe(icmp_reg_reg); 11211 %} 11212 11213 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 11214 %{ 11215 match(Set cr (CmpN op1 op2)); 11216 11217 effect(DEF cr, USE op1, USE op2); 11218 11219 ins_cost(INSN_COST); 11220 format %{ "cmp $op1, $op2\t // compressed ptr" %} 11221 11222 ins_encode(aarch64_enc_cmpn(op1, op2)); 11223 11224 ins_pipe(icmp_reg_reg); 11225 %} 11226 11227 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 11228 %{ 11229 match(Set cr (CmpP op1 zero)); 11230 11231 effect(DEF cr, USE op1, USE zero); 11232 11233 ins_cost(INSN_COST); 11234 format %{ "cmp $op1, 0\t // ptr" %} 11235 11236 ins_encode(aarch64_enc_testp(op1)); 11237 11238 ins_pipe(icmp_reg_imm); 11239 %} 11240 11241 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 11242 %{ 11243 match(Set cr (CmpN op1 zero)); 11244 11245 effect(DEF cr, USE op1, USE zero); 11246 11247 ins_cost(INSN_COST); 11248 format %{ "cmp $op1, 0\t // compressed ptr" %} 11249 11250 ins_encode(aarch64_enc_testn(op1)); 11251 11252 ins_pipe(icmp_reg_imm); 11253 %} 11254 11255 // FP comparisons 11256 // 11257 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 11258 // using normal cmpOp. See declaration of rFlagsReg for details. 11259 11260 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 11261 %{ 11262 match(Set cr (CmpF src1 src2)); 11263 11264 ins_cost(3 * INSN_COST); 11265 format %{ "fcmps $src1, $src2" %} 11266 11267 ins_encode %{ 11268 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 11269 %} 11270 11271 ins_pipe(pipe_class_compare); 11272 %} 11273 11274 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 11275 %{ 11276 match(Set cr (CmpF src1 src2)); 11277 11278 ins_cost(3 * INSN_COST); 11279 format %{ "fcmps $src1, 0.0" %} 11280 11281 ins_encode %{ 11282 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 11283 %} 11284 11285 ins_pipe(pipe_class_compare); 11286 %} 11287 // FROM HERE 11288 11289 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 11290 %{ 11291 match(Set cr (CmpD src1 src2)); 11292 11293 ins_cost(3 * INSN_COST); 11294 format %{ "fcmpd $src1, $src2" %} 11295 11296 ins_encode %{ 11297 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 11298 %} 11299 11300 ins_pipe(pipe_class_compare); 11301 %} 11302 11303 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 11304 %{ 11305 match(Set cr (CmpD src1 src2)); 11306 11307 ins_cost(3 * INSN_COST); 11308 format %{ "fcmpd $src1, 0.0" %} 11309 11310 ins_encode %{ 11311 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 11312 %} 11313 11314 ins_pipe(pipe_class_compare); 11315 %} 11316 11317 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 11318 %{ 11319 match(Set dst (CmpF3 src1 src2)); 11320 effect(KILL cr); 11321 11322 ins_cost(5 * INSN_COST); 11323 format %{ "fcmps $src1, $src2\n\t" 11324 "csinvw($dst, zr, zr, eq\n\t" 11325 "csnegw($dst, $dst, $dst, lt)" 11326 %} 11327 11328 ins_encode %{ 11329 Label done; 11330 FloatRegister s1 = as_FloatRegister($src1$$reg); 11331 FloatRegister s2 = as_FloatRegister($src2$$reg); 11332 Register d = as_Register($dst$$reg); 11333 __ fcmps(s1, s2); 11334 // installs 0 if EQ else -1 11335 __ csinvw(d, zr, zr, Assembler::EQ); 11336 // keeps -1 if less or unordered else installs 1 11337 __ csnegw(d, d, d, Assembler::LT); 11338 __ bind(done); 11339 %} 11340 11341 ins_pipe(pipe_class_default); 11342 11343 %} 11344 11345 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 11346 %{ 11347 match(Set dst (CmpD3 src1 src2)); 11348 effect(KILL cr); 11349 11350 ins_cost(5 * INSN_COST); 11351 format %{ "fcmpd $src1, $src2\n\t" 11352 "csinvw($dst, zr, zr, eq\n\t" 11353 "csnegw($dst, $dst, $dst, lt)" 11354 %} 11355 11356 ins_encode %{ 11357 Label done; 11358 FloatRegister s1 = as_FloatRegister($src1$$reg); 11359 FloatRegister s2 = as_FloatRegister($src2$$reg); 11360 Register d = as_Register($dst$$reg); 11361 __ fcmpd(s1, s2); 11362 // installs 0 if EQ else -1 11363 __ csinvw(d, zr, zr, Assembler::EQ); 11364 // keeps -1 if less or unordered else installs 1 11365 __ csnegw(d, d, d, Assembler::LT); 11366 __ bind(done); 11367 %} 11368 ins_pipe(pipe_class_default); 11369 11370 %} 11371 11372 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 11373 %{ 11374 match(Set dst (CmpF3 src1 zero)); 11375 effect(KILL cr); 11376 11377 ins_cost(5 * INSN_COST); 11378 format %{ "fcmps $src1, 0.0\n\t" 11379 "csinvw($dst, zr, zr, eq\n\t" 11380 "csnegw($dst, $dst, $dst, lt)" 11381 %} 11382 11383 ins_encode %{ 11384 Label done; 11385 FloatRegister s1 = as_FloatRegister($src1$$reg); 11386 Register d = as_Register($dst$$reg); 11387 __ fcmps(s1, 0.0D); 11388 // installs 0 if EQ else -1 11389 __ csinvw(d, zr, zr, Assembler::EQ); 11390 // keeps -1 if less or unordered else installs 1 11391 __ csnegw(d, d, d, Assembler::LT); 11392 __ bind(done); 11393 %} 11394 11395 ins_pipe(pipe_class_default); 11396 11397 %} 11398 11399 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 11400 %{ 11401 match(Set dst (CmpD3 src1 zero)); 11402 effect(KILL cr); 11403 11404 ins_cost(5 * INSN_COST); 11405 format %{ "fcmpd $src1, 0.0\n\t" 11406 "csinvw($dst, zr, zr, eq\n\t" 11407 "csnegw($dst, $dst, $dst, lt)" 11408 %} 11409 11410 ins_encode %{ 11411 Label done; 11412 FloatRegister s1 = as_FloatRegister($src1$$reg); 11413 Register d = as_Register($dst$$reg); 11414 __ fcmpd(s1, 0.0D); 11415 // installs 0 if EQ else -1 11416 __ csinvw(d, zr, zr, Assembler::EQ); 11417 // keeps -1 if less or unordered else installs 1 11418 __ csnegw(d, d, d, Assembler::LT); 11419 __ bind(done); 11420 %} 11421 ins_pipe(pipe_class_default); 11422 11423 %} 11424 11425 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q, rFlagsReg cr) 11426 %{ 11427 match(Set dst (CmpLTMask p q)); 11428 effect(KILL cr); 11429 11430 ins_cost(3 * INSN_COST); 11431 11432 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 11433 "csetw $dst, lt\n\t" 11434 "subw $dst, zr, $dst" 11435 %} 11436 11437 ins_encode %{ 11438 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 11439 __ csetw(as_Register($dst$$reg), Assembler::LT); 11440 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 11441 %} 11442 11443 ins_pipe(ialu_reg_reg); 11444 %} 11445 11446 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegI src, immI0 zero, rFlagsReg cr) 11447 %{ 11448 match(Set dst (CmpLTMask src zero)); 11449 effect(KILL cr); 11450 11451 ins_cost(INSN_COST); 11452 11453 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 11454 11455 ins_encode %{ 11456 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 11457 %} 11458 11459 ins_pipe(ialu_reg_shift); 11460 %} 11461 11462 // ============================================================================ 11463 // Max and Min 11464 11465 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 11466 %{ 11467 match(Set dst (MinI src1 src2)); 11468 11469 effect(DEF dst, USE src1, USE src2, KILL cr); 11470 size(8); 11471 11472 ins_cost(INSN_COST * 3); 11473 format %{ 11474 "cmpw $src1 $src2\t signed int\n\t" 11475 "cselw $dst, $src1, $src2 lt\t" 11476 %} 11477 11478 ins_encode %{ 11479 __ cmpw(as_Register($src1$$reg), 11480 as_Register($src2$$reg)); 11481 __ cselw(as_Register($dst$$reg), 11482 as_Register($src1$$reg), 11483 as_Register($src2$$reg), 11484 Assembler::LT); 11485 %} 11486 11487 ins_pipe(ialu_reg_reg); 11488 %} 11489 // FROM HERE 11490 11491 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 11492 %{ 11493 match(Set dst (MaxI src1 src2)); 11494 11495 effect(DEF dst, USE src1, USE src2, KILL cr); 11496 size(8); 11497 11498 ins_cost(INSN_COST * 3); 11499 format %{ 11500 "cmpw $src1 $src2\t signed int\n\t" 11501 "cselw $dst, $src1, $src2 gt\t" 11502 %} 11503 11504 ins_encode %{ 11505 __ cmpw(as_Register($src1$$reg), 11506 as_Register($src2$$reg)); 11507 __ cselw(as_Register($dst$$reg), 11508 as_Register($src1$$reg), 11509 as_Register($src2$$reg), 11510 Assembler::GT); 11511 %} 11512 11513 ins_pipe(ialu_reg_reg); 11514 %} 11515 11516 // ============================================================================ 11517 // Branch Instructions 11518 11519 // Direct Branch. 11520 instruct branch(label lbl) 11521 %{ 11522 match(Goto); 11523 11524 effect(USE lbl); 11525 11526 ins_cost(BRANCH_COST); 11527 format %{ "b $lbl" %} 11528 11529 ins_encode(aarch64_enc_b(lbl)); 11530 11531 ins_pipe(pipe_branch); 11532 %} 11533 11534 // Conditional Near Branch 11535 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 11536 %{ 11537 // Same match rule as `branchConFar'. 11538 match(If cmp cr); 11539 11540 effect(USE lbl); 11541 11542 ins_cost(BRANCH_COST); 11543 // If set to 1 this indicates that the current instruction is a 11544 // short variant of a long branch. This avoids using this 11545 // instruction in first-pass matching. It will then only be used in 11546 // the `Shorten_branches' pass. 11547 // ins_short_branch(1); 11548 format %{ "b$cmp $lbl" %} 11549 11550 ins_encode(aarch64_enc_br_con(cmp, lbl)); 11551 11552 ins_pipe(pipe_branch_cond); 11553 %} 11554 11555 // Conditional Near Branch Unsigned 11556 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 11557 %{ 11558 // Same match rule as `branchConFar'. 11559 match(If cmp cr); 11560 11561 effect(USE lbl); 11562 11563 ins_cost(BRANCH_COST); 11564 // If set to 1 this indicates that the current instruction is a 11565 // short variant of a long branch. This avoids using this 11566 // instruction in first-pass matching. It will then only be used in 11567 // the `Shorten_branches' pass. 11568 // ins_short_branch(1); 11569 format %{ "b$cmp $lbl\t# unsigned" %} 11570 11571 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 11572 11573 ins_pipe(pipe_branch_cond); 11574 %} 11575 11576 // Make use of CBZ and CBNZ. These instructions, as well as being 11577 // shorter than (cmp; branch), have the additional benefit of not 11578 // killing the flags. 11579 11580 instruct cmpI_imm0_branch(cmpOp cmp, iRegI op1, immI0 op2, label labl, rFlagsReg cr) %{ 11581 match(If cmp (CmpI op1 op2)); 11582 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11583 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11584 effect(USE labl); 11585 11586 ins_cost(BRANCH_COST); 11587 format %{ "cbw$cmp $op1, $labl" %} 11588 ins_encode %{ 11589 Label* L = $labl$$label; 11590 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11591 if (cond == Assembler::EQ) 11592 __ cbzw($op1$$Register, *L); 11593 else 11594 __ cbnzw($op1$$Register, *L); 11595 %} 11596 ins_pipe(pipe_cmp_branch); 11597 %} 11598 11599 instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 11600 match(If cmp (CmpL op1 op2)); 11601 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11602 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11603 effect(USE labl); 11604 11605 ins_cost(BRANCH_COST); 11606 format %{ "cb$cmp $op1, $labl" %} 11607 ins_encode %{ 11608 Label* L = $labl$$label; 11609 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11610 if (cond == Assembler::EQ) 11611 __ cbz($op1$$Register, *L); 11612 else 11613 __ cbnz($op1$$Register, *L); 11614 %} 11615 ins_pipe(pipe_cmp_branch); 11616 %} 11617 11618 instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 11619 match(If cmp (CmpP op1 op2)); 11620 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11621 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11622 effect(USE labl); 11623 11624 ins_cost(BRANCH_COST); 11625 format %{ "cb$cmp $op1, $labl" %} 11626 ins_encode %{ 11627 Label* L = $labl$$label; 11628 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11629 if (cond == Assembler::EQ) 11630 __ cbz($op1$$Register, *L); 11631 else 11632 __ cbnz($op1$$Register, *L); 11633 %} 11634 ins_pipe(pipe_cmp_branch); 11635 %} 11636 11637 // Conditional Far Branch 11638 // Conditional Far Branch Unsigned 11639 // TODO: fixme 11640 11641 // counted loop end branch near 11642 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 11643 %{ 11644 match(CountedLoopEnd cmp cr); 11645 11646 effect(USE lbl); 11647 11648 ins_cost(BRANCH_COST); 11649 // short variant. 11650 // ins_short_branch(1); 11651 format %{ "b$cmp $lbl \t// counted loop end" %} 11652 11653 ins_encode(aarch64_enc_br_con(cmp, lbl)); 11654 11655 ins_pipe(pipe_branch); 11656 %} 11657 11658 // counted loop end branch near Unsigned 11659 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 11660 %{ 11661 match(CountedLoopEnd cmp cr); 11662 11663 effect(USE lbl); 11664 11665 ins_cost(BRANCH_COST); 11666 // short variant. 11667 // ins_short_branch(1); 11668 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 11669 11670 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 11671 11672 ins_pipe(pipe_branch); 11673 %} 11674 11675 // counted loop end branch far 11676 // counted loop end branch far unsigned 11677 // TODO: fixme 11678 11679 // ============================================================================ 11680 // inlined locking and unlocking 11681 11682 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 11683 %{ 11684 match(Set cr (FastLock object box)); 11685 effect(TEMP tmp, TEMP tmp2); 11686 11687 // TODO 11688 // identify correct cost 11689 ins_cost(5 * INSN_COST); 11690 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 11691 11692 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 11693 11694 ins_pipe(pipe_serial); 11695 %} 11696 11697 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 11698 %{ 11699 match(Set cr (FastUnlock object box)); 11700 effect(TEMP tmp, TEMP tmp2); 11701 11702 ins_cost(5 * INSN_COST); 11703 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 11704 11705 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 11706 11707 ins_pipe(pipe_serial); 11708 %} 11709 11710 11711 // ============================================================================ 11712 // Safepoint Instructions 11713 11714 // TODO 11715 // provide a near and far version of this code 11716 11717 instruct safePoint(iRegP poll) 11718 %{ 11719 match(SafePoint poll); 11720 11721 format %{ 11722 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 11723 %} 11724 ins_encode %{ 11725 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 11726 %} 11727 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 11728 %} 11729 11730 11731 // ============================================================================ 11732 // Procedure Call/Return Instructions 11733 11734 // Call Java Static Instruction 11735 11736 instruct CallStaticJavaDirect(method meth) 11737 %{ 11738 match(CallStaticJava); 11739 11740 effect(USE meth); 11741 11742 predicate(!((CallStaticJavaNode*)n)->is_method_handle_invoke()); 11743 11744 ins_cost(CALL_COST); 11745 11746 format %{ "call,static $meth \t// ==> " %} 11747 11748 ins_encode( aarch64_enc_java_static_call(meth), 11749 aarch64_enc_call_epilog ); 11750 11751 ins_pipe(pipe_class_call); 11752 %} 11753 11754 // TO HERE 11755 11756 // Call Java Static Instruction (method handle version) 11757 11758 instruct CallStaticJavaDirectHandle(method meth, iRegP_FP reg_mh_save) 11759 %{ 11760 match(CallStaticJava); 11761 11762 effect(USE meth); 11763 11764 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 11765 11766 ins_cost(CALL_COST); 11767 11768 format %{ "call,static $meth \t// (methodhandle) ==> " %} 11769 11770 ins_encode( aarch64_enc_java_handle_call(meth), 11771 aarch64_enc_call_epilog ); 11772 11773 ins_pipe(pipe_class_call); 11774 %} 11775 11776 // Call Java Dynamic Instruction 11777 instruct CallDynamicJavaDirect(method meth) 11778 %{ 11779 match(CallDynamicJava); 11780 11781 effect(USE meth); 11782 11783 ins_cost(CALL_COST); 11784 11785 format %{ "CALL,dynamic $meth \t// ==> " %} 11786 11787 ins_encode( aarch64_enc_java_dynamic_call(meth), 11788 aarch64_enc_call_epilog ); 11789 11790 ins_pipe(pipe_class_call); 11791 %} 11792 11793 // Call Runtime Instruction 11794 11795 instruct CallRuntimeDirect(method meth) 11796 %{ 11797 match(CallRuntime); 11798 11799 effect(USE meth); 11800 11801 ins_cost(CALL_COST); 11802 11803 format %{ "CALL, runtime $meth" %} 11804 11805 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11806 11807 ins_pipe(pipe_class_call); 11808 %} 11809 11810 // Call Runtime Instruction 11811 11812 instruct CallLeafDirect(method meth) 11813 %{ 11814 match(CallLeaf); 11815 11816 effect(USE meth); 11817 11818 ins_cost(CALL_COST); 11819 11820 format %{ "CALL, runtime leaf $meth" %} 11821 11822 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11823 11824 ins_pipe(pipe_class_call); 11825 %} 11826 11827 // Call Runtime Instruction 11828 11829 instruct CallLeafNoFPDirect(method meth) 11830 %{ 11831 match(CallLeafNoFP); 11832 11833 effect(USE meth); 11834 11835 ins_cost(CALL_COST); 11836 11837 format %{ "CALL, runtime leaf nofp $meth" %} 11838 11839 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11840 11841 ins_pipe(pipe_class_call); 11842 %} 11843 11844 // Tail Call; Jump from runtime stub to Java code. 11845 // Also known as an 'interprocedural jump'. 11846 // Target of jump will eventually return to caller. 11847 // TailJump below removes the return address. 11848 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 11849 %{ 11850 match(TailCall jump_target method_oop); 11851 11852 ins_cost(CALL_COST); 11853 11854 format %{ "br $jump_target\t# $method_oop holds method oop" %} 11855 11856 ins_encode(aarch64_enc_tail_call(jump_target)); 11857 11858 ins_pipe(pipe_class_call); 11859 %} 11860 11861 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 11862 %{ 11863 match(TailJump jump_target ex_oop); 11864 11865 ins_cost(CALL_COST); 11866 11867 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 11868 11869 ins_encode(aarch64_enc_tail_jmp(jump_target)); 11870 11871 ins_pipe(pipe_class_call); 11872 %} 11873 11874 // Create exception oop: created by stack-crawling runtime code. 11875 // Created exception is now available to this handler, and is setup 11876 // just prior to jumping to this handler. No code emitted. 11877 // TODO check 11878 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 11879 instruct CreateException(iRegP_R0 ex_oop) 11880 %{ 11881 match(Set ex_oop (CreateEx)); 11882 11883 format %{ " -- \t// exception oop; no code emitted" %} 11884 11885 size(0); 11886 11887 ins_encode( /*empty*/ ); 11888 11889 ins_pipe(pipe_class_empty); 11890 %} 11891 11892 // Rethrow exception: The exception oop will come in the first 11893 // argument position. Then JUMP (not call) to the rethrow stub code. 11894 instruct RethrowException() %{ 11895 match(Rethrow); 11896 ins_cost(CALL_COST); 11897 11898 format %{ "b rethrow_stub" %} 11899 11900 ins_encode( aarch64_enc_rethrow() ); 11901 11902 ins_pipe(pipe_class_call); 11903 %} 11904 11905 11906 // Return Instruction 11907 // epilog node loads ret address into lr as part of frame pop 11908 instruct Ret() 11909 %{ 11910 match(Return); 11911 11912 format %{ "ret\t// return register" %} 11913 11914 ins_encode( aarch64_enc_ret() ); 11915 11916 ins_pipe(pipe_branch); 11917 %} 11918 11919 // Die now. 11920 instruct ShouldNotReachHere() %{ 11921 match(Halt); 11922 11923 ins_cost(CALL_COST); 11924 format %{ "ShouldNotReachHere" %} 11925 11926 ins_encode %{ 11927 // TODO 11928 // implement proper trap call here 11929 __ brk(999); 11930 %} 11931 11932 ins_pipe(pipe_class_default); 11933 %} 11934 11935 // ============================================================================ 11936 // Partial Subtype Check 11937 // 11938 // superklass array for an instance of the superklass. Set a hidden 11939 // internal cache on a hit (cache is checked with exposed code in 11940 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11941 // encoding ALSO sets flags. 11942 11943 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 11944 %{ 11945 match(Set result (PartialSubtypeCheck sub super)); 11946 effect(KILL cr, KILL temp); 11947 11948 ins_cost(1100); // slightly larger than the next version 11949 format %{ "partialSubtypeCheck $result, $sub, $super" %} 11950 11951 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 11952 11953 opcode(0x1); // Force zero of result reg on hit 11954 11955 ins_pipe(pipe_class_memory); 11956 %} 11957 11958 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 11959 %{ 11960 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11961 effect(KILL temp, KILL result); 11962 11963 ins_cost(1100); // slightly larger than the next version 11964 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 11965 11966 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 11967 11968 opcode(0x0); // Don't zero result reg on hit 11969 11970 ins_pipe(pipe_class_memory); 11971 %} 11972 11973 instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 11974 iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr) 11975 %{ 11976 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11977 effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11978 11979 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 11980 ins_encode %{ 11981 __ string_compare($str1$$Register, $str2$$Register, 11982 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11983 $tmp1$$Register); 11984 %} 11985 ins_pipe(pipe_class_memory); 11986 %} 11987 11988 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 11989 iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) 11990 %{ 11991 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11992 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 11993 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 11994 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} 11995 11996 ins_encode %{ 11997 __ string_indexof($str1$$Register, $str2$$Register, 11998 $cnt1$$Register, $cnt2$$Register, 11999 $tmp1$$Register, $tmp2$$Register, 12000 $tmp3$$Register, $tmp4$$Register, 12001 -1, $result$$Register); 12002 %} 12003 ins_pipe(pipe_class_memory); 12004 %} 12005 12006 instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 12007 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, 12008 iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12009 %{ 12010 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12011 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 12012 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12013 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} 12014 12015 ins_encode %{ 12016 int icnt2 = (int)$int_cnt2$$constant; 12017 __ string_indexof($str1$$Register, $str2$$Register, 12018 $cnt1$$Register, zr, 12019 $tmp1$$Register, $tmp2$$Register, 12020 $tmp3$$Register, $tmp4$$Register, 12021 icnt2, $result$$Register); 12022 %} 12023 ins_pipe(pipe_class_memory); 12024 %} 12025 12026 instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 12027 iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr) 12028 %{ 12029 match(Set result (StrEquals (Binary str1 str2) cnt)); 12030 effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 12031 12032 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 12033 ins_encode %{ 12034 __ string_equals($str1$$Register, $str2$$Register, 12035 $cnt$$Register, $result$$Register, 12036 $tmp$$Register); 12037 %} 12038 ins_pipe(pipe_class_memory); 12039 %} 12040 12041 instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 12042 iRegP_R10 tmp, rFlagsReg cr) 12043 %{ 12044 match(Set result (AryEq ary1 ary2)); 12045 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr); 12046 12047 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 12048 ins_encode %{ 12049 __ char_arrays_equals($ary1$$Register, $ary2$$Register, 12050 $result$$Register, $tmp$$Register); 12051 %} 12052 ins_pipe(pipe_class_memory); 12053 %} 12054 12055 // encode char[] to byte[] in ISO_8859_1 12056 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 12057 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 12058 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 12059 iRegI_R0 result, rFlagsReg cr) 12060 %{ 12061 match(Set result (EncodeISOArray src (Binary dst len))); 12062 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 12063 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 12064 12065 format %{ "Encode array $src,$dst,$len -> $result" %} 12066 ins_encode %{ 12067 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12068 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 12069 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 12070 %} 12071 ins_pipe( pipe_class_memory ); 12072 %} 12073 12074 // ============================================================================ 12075 // This name is KNOWN by the ADLC and cannot be changed. 12076 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12077 // for this guy. 12078 instruct tlsLoadP(thread_RegP dst) 12079 %{ 12080 match(Set dst (ThreadLocal)); 12081 12082 ins_cost(0); 12083 12084 format %{ " -- \t// $dst=Thread::current(), empty" %} 12085 12086 size(0); 12087 12088 ins_encode( /*empty*/ ); 12089 12090 ins_pipe(pipe_class_empty); 12091 %} 12092 12093 12094 12095 //----------PEEPHOLE RULES----------------------------------------------------- 12096 // These must follow all instruction definitions as they use the names 12097 // defined in the instructions definitions. 12098 // 12099 // peepmatch ( root_instr_name [preceding_instruction]* ); 12100 // 12101 // peepconstraint %{ 12102 // (instruction_number.operand_name relational_op instruction_number.operand_name 12103 // [, ...] ); 12104 // // instruction numbers are zero-based using left to right order in peepmatch 12105 // 12106 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12107 // // provide an instruction_number.operand_name for each operand that appears 12108 // // in the replacement instruction's match rule 12109 // 12110 // ---------VM FLAGS--------------------------------------------------------- 12111 // 12112 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12113 // 12114 // Each peephole rule is given an identifying number starting with zero and 12115 // increasing by one in the order seen by the parser. An individual peephole 12116 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12117 // on the command-line. 12118 // 12119 // ---------CURRENT LIMITATIONS---------------------------------------------- 12120 // 12121 // Only match adjacent instructions in same basic block 12122 // Only equality constraints 12123 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12124 // Only one replacement instruction 12125 // 12126 // ---------EXAMPLE---------------------------------------------------------- 12127 // 12128 // // pertinent parts of existing instructions in architecture description 12129 // instruct movI(iRegINoSp dst, iRegI src) 12130 // %{ 12131 // match(Set dst (CopyI src)); 12132 // %} 12133 // 12134 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 12135 // %{ 12136 // match(Set dst (AddI dst src)); 12137 // effect(KILL cr); 12138 // %} 12139 // 12140 // // Change (inc mov) to lea 12141 // peephole %{ 12142 // // increment preceeded by register-register move 12143 // peepmatch ( incI_iReg movI ); 12144 // // require that the destination register of the increment 12145 // // match the destination register of the move 12146 // peepconstraint ( 0.dst == 1.dst ); 12147 // // construct a replacement instruction that sets 12148 // // the destination to ( move's source register + one ) 12149 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 12150 // %} 12151 // 12152 12153 // Implementation no longer uses movX instructions since 12154 // machine-independent system no longer uses CopyX nodes. 12155 // 12156 // peephole 12157 // %{ 12158 // peepmatch (incI_iReg movI); 12159 // peepconstraint (0.dst == 1.dst); 12160 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12161 // %} 12162 12163 // peephole 12164 // %{ 12165 // peepmatch (decI_iReg movI); 12166 // peepconstraint (0.dst == 1.dst); 12167 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12168 // %} 12169 12170 // peephole 12171 // %{ 12172 // peepmatch (addI_iReg_imm movI); 12173 // peepconstraint (0.dst == 1.dst); 12174 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12175 // %} 12176 12177 // peephole 12178 // %{ 12179 // peepmatch (incL_iReg movL); 12180 // peepconstraint (0.dst == 1.dst); 12181 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12182 // %} 12183 12184 // peephole 12185 // %{ 12186 // peepmatch (decL_iReg movL); 12187 // peepconstraint (0.dst == 1.dst); 12188 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12189 // %} 12190 12191 // peephole 12192 // %{ 12193 // peepmatch (addL_iReg_imm movL); 12194 // peepconstraint (0.dst == 1.dst); 12195 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12196 // %} 12197 12198 // peephole 12199 // %{ 12200 // peepmatch (addP_iReg_imm movP); 12201 // peepconstraint (0.dst == 1.dst); 12202 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 12203 // %} 12204 12205 // // Change load of spilled value to only a spill 12206 // instruct storeI(memory mem, iRegI src) 12207 // %{ 12208 // match(Set mem (StoreI mem src)); 12209 // %} 12210 // 12211 // instruct loadI(iRegINoSp dst, memory mem) 12212 // %{ 12213 // match(Set dst (LoadI mem)); 12214 // %} 12215 // 12216 12217 //----------SMARTSPILL RULES--------------------------------------------------- 12218 // These must follow all instruction definitions as they use the names 12219 // defined in the instructions definitions. 12220 12221 // Local Variables: 12222 // mode: c++ 12223 // End: